import os import json import urllib.request CHROMA_URL = os.getenv("CHROMA_URL", "http://localhost:8800") CHROMA_COL_OUT = os.getenv("CHROMA_COL_OUT", "fallout_lore_enriched") CHROMA_SIM_COL = os.getenv("CHROMA_SIM_COL", "fallout_sim_enriched") CHROMA_BASE = f"{CHROMA_URL}/api/v2/tenants/default_tenant/databases/default_database" def _chroma_post(path: str, body: dict) -> dict: data = json.dumps(body).encode() req = urllib.request.Request( f"{CHROMA_BASE}{path}", data=data, method="POST", headers={"Content-Type": "application/json"} ) try: with urllib.request.urlopen(req, timeout=10) as r: return json.loads(r.read()) except Exception: return {} def _get_or_create_col(name: str) -> str | None: try: with urllib.request.urlopen(f"{CHROMA_BASE}/collections", timeout=5) as r: cols = json.loads(r.read()) for c in cols: if c["name"] == name: return c["id"] except Exception: pass res = _chroma_post("/collections", {"name": name, "metadata": {"hnsw:space": "cosine"}}) return res.get("id") def upsert_lore_enriched(proposal: dict): col_id = _get_or_create_col(CHROMA_COL_OUT) if not col_id: return text = proposal.get("modified_text") or proposal.get("proposed_text", "") doc_id = f"lore_proposal_{proposal['id']}" _chroma_post(f"/collections/{col_id}/upsert", { "ids": [doc_id], "documents": [text], "metadatas": [{ "faction_slug": proposal.get("faction_slug", ""), "change_type": proposal.get("change_type", ""), "field_path": proposal.get("field_path") or "", "category": "lore_enriched", "source": doc_id, }], }) def upsert_sim_enriched(proposal: dict): col_id = _get_or_create_col(CHROMA_SIM_COL) if not col_id: return patch_str = json.dumps(proposal.get("json_patch") or {}, ensure_ascii=False) text = ( f"{proposal.get('title','')}\n" f"{proposal.get('description','')}\n" f"Patch: {patch_str}\n" f"Rationale: {proposal.get('rationale','')}" ) doc_id = f"sim_proposal_{proposal['id']}" _chroma_post(f"/collections/{col_id}/upsert", { "ids": [doc_id], "documents": [text], "metadatas": [{ "proposal_type": proposal.get("proposal_type", ""), "title": proposal.get("title", ""), "category": "sim_enriched", "source": doc_id, }], }) def upsert_sim_reject(proposal: dict, reason: str): col_id = _get_or_create_col(CHROMA_SIM_COL + "_rejects") if not col_id: return neg_text = ( f"REJET — {proposal.get('proposal_type','')}: {proposal.get('title','')}\n" f"Motif: {reason}\n" f"Description: {proposal.get('description','')}" ) _chroma_post(f"/collections/{col_id}/upsert", { "ids": [f"reject_{proposal['id']}"], "documents": [neg_text], "metadatas": [{ "proposal_type": proposal.get("proposal_type", ""), "category": "negative_example", "source": f"reject_{proposal['id']}", }], })