c7ce44d963
Workstream A–C substrate for the Ten31 agentic system: - A1: docs/crm-overview.md; CLAUDE.md conventions + guardrail #9 - A2: additive/reversible core migration (canonical_entities, entity_links, interaction_log, relationship_edges, soft-delete) + ledgered runner - B1/B3: chunking + deterministic entity resolution (backend/ingest) - B2: dense (bge-m3) + BM25 sparse ingest to Qdrant crm_chunks - C: CRM MCP server (reads, retrieval modes, logged writes) — no outbound tools - docs: redaction/re-hydration, Gmail enablement runbook - synthetic test data; .env.example; housekeeping (.gitignore, untrack crm.db, drop legacy files + start9/0.3.5) Verified end-to-end on synthetic data + live Sparks (hybrid > dense on entity queries). Real backfill runs on Ten31 infra; index holds synthetic data only. Branch snapshot also captures pre-existing working-tree changes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
36 lines
1.2 KiB
Python
36 lines
1.2 KiB
Python
"""Tiny stdlib JSON HTTP client (no third-party deps).
|
|
|
|
Handles the Spark Control self-signed cert (verify=False) and plain-HTTP Qdrant.
|
|
"""
|
|
import json
|
|
import ssl
|
|
import urllib.error
|
|
import urllib.request
|
|
|
|
|
|
def _ctx(verify: bool):
|
|
if verify:
|
|
return None
|
|
ctx = ssl.create_default_context()
|
|
ctx.check_hostname = False
|
|
ctx.verify_mode = ssl.CERT_NONE
|
|
return ctx
|
|
|
|
|
|
def request(method: str, url: str, body=None, verify: bool = True, timeout: int = 180):
|
|
data = json.dumps(body).encode("utf-8") if body is not None else None
|
|
req = urllib.request.Request(url, data=data, method=method,
|
|
headers={"Content-Type": "application/json"})
|
|
ctx = _ctx(verify) if url.lower().startswith("https") else None
|
|
try:
|
|
with urllib.request.urlopen(req, timeout=timeout, context=ctx) as resp:
|
|
raw = resp.read()
|
|
return resp.status, (json.loads(raw) if raw else {})
|
|
except urllib.error.HTTPError as exc:
|
|
raw = exc.read()
|
|
try:
|
|
payload = json.loads(raw) if raw else {}
|
|
except Exception:
|
|
payload = {"raw": raw.decode("utf-8", "replace")}
|
|
return exc.code, payload
|