HumboldtJoker commited on
Commit
12b3dc1
·
verified ·
1 Parent(s): dbe9115

Clean up nested duplicate: v2/v2/engine/synthesis.py

Browse files
Files changed (1) hide show
  1. v2/v2/engine/synthesis.py +0 -149
v2/v2/engine/synthesis.py DELETED
@@ -1,149 +0,0 @@
1
- """Synthesis chip — the only place Rivet calls the model.
2
-
3
- Everything upstream in the DAG is evidence gathering; everything
4
- downstream is verification. The prompt is assembled from:
5
-
6
- - the BDI beliefs relevant to this intent (constraints first)
7
- - upstream artifacts (real source excerpts, migration/security reports)
8
- - Pharos-routed knowledge packs (KV-injected on the transformers
9
- backend, system-context on Ollama)
10
- - the conversation history for this session
11
-
12
- The chip never sees raw context files — beliefs and artifacts are the
13
- interface. If it isn't in the BDI or an artifact, Rivet doesn't claim it.
14
- """
15
-
16
- import json
17
-
18
- from kintsugi_core import (
19
- BaseSkillChip,
20
- BDIStore,
21
- EFEWeights,
22
- SkillCapability,
23
- SkillContext,
24
- SkillDomain,
25
- SkillRequest,
26
- SkillResponse,
27
- )
28
-
29
- RIVET_SYSTEM = """You are Rivet, a senior engineer embedded with the \
30
- Multiverse Campus team.
31
-
32
- ## Non-negotiable rules
33
- 1. Never suggest a destructive migration (DROP, TRUNCATE, in-place type \
34
- change, RENAME). Staging and prod share the database. If asked for one, \
35
- give the additive multi-step alternative instead — and never print the \
36
- destructive statement, not even as a "don't do this" example.
37
- 2. Every code suggestion states: what it changes, what it could break, \
38
- and what tests verify it.
39
- 3. If you have not read the relevant source (check the SOURCE EVIDENCE \
40
- section), say you are reasoning from architecture, not source.
41
- 4. Auth changes get an explicit callout: "This touches authentication. \
42
- Review with security before merging."
43
- 5. Flag known audit findings proactively when the question walks into one.
44
- 6. You are a colleague, not the lead. Suggest, don't decree.
45
- """
46
-
47
-
48
- def _format_beliefs(bdi: BDIStore, belief_ids: list) -> str:
49
- lines = []
50
- for bid in belief_ids:
51
- b = bdi.get_belief(bid)
52
- if b is not None:
53
- lines.append(f"- ({b.confidence:.2f}) {b.content}")
54
- return "\n".join(lines) if lines else "(none loaded)"
55
-
56
-
57
- def _format_analysis(analysis: dict) -> str:
58
- if not analysis or not analysis.get("files"):
59
- notes = "; ".join(analysis.get("notes", [])) if analysis else ""
60
- return f"No source files were read for this request. {notes}".strip()
61
- parts = []
62
- for f in analysis["files"]:
63
- header = f"### {f['path']}"
64
- if f.get("git_status"):
65
- header += f" (git: {f['git_status']} — uncommitted changes!)"
66
- parts.append(f"{header}\n```\n{f['excerpt']}\n```")
67
- if f.get("recent_history"):
68
- parts.append(f"Recent commits touching this file:\n{f['recent_history']}")
69
- return "\n\n".join(parts)
70
-
71
-
72
- def _format_report(name: str, report: dict) -> str:
73
- if not report:
74
- return ""
75
- return f"## {name}\n```json\n{json.dumps(report, indent=2, default=str)[:4000]}\n```"
76
-
77
-
78
- class SynthesisChip(BaseSkillChip):
79
- name = "synthesis"
80
- description = "Generate the draft answer from evidence + beliefs + packs"
81
- version = "2.0.0"
82
- domain = SkillDomain.GENERAL
83
- efe_weights = EFEWeights()
84
- capabilities = [SkillCapability.EXTERNAL_API]
85
-
86
- def __init__(self, model_client, bdi: BDIStore, pharos_router=None,
87
- max_tokens: int = 1536):
88
- super().__init__()
89
- self.model = model_client
90
- self.bdi = bdi
91
- self.pharos = pharos_router
92
- self.max_tokens = max_tokens
93
-
94
- async def handle(self, request: SkillRequest,
95
- context: SkillContext) -> SkillResponse:
96
- question = context.metadata.get("question", request.raw_input)
97
- session = context.metadata.get("session")
98
- belief_ids = context.metadata.get("belief_ids", [])
99
-
100
- # Pharos: route the question to knowledge packs.
101
- knowledge, pack_names = "", []
102
- if self.pharos is not None:
103
- routed = self.pharos.route(question)
104
- knowledge = routed.knowledge_text
105
- pack_names = routed.pack_names
106
- if session and pack_names:
107
- for p in pack_names:
108
- session.record_evidence("pharos_pack", p, self.name)
109
-
110
- prompt_parts = ["# ORGANIZATIONAL BELIEFS (BDI)\n"
111
- + _format_beliefs(self.bdi, belief_ids)]
112
-
113
- analysis = request.parameters.get("analysis") or {}
114
- prompt_parts.append("# SOURCE EVIDENCE\n" + _format_analysis(analysis))
115
-
116
- for key, title in (
117
- ("migration_report", "MIGRATION SAFETY REPORT"),
118
- ("security_report", "SECURITY REVIEW REPORT"),
119
- ):
120
- block = _format_report(title, request.parameters.get(key) or {})
121
- if block:
122
- prompt_parts.append(block)
123
-
124
- if session and session.history:
125
- recent = session.history[-6:]
126
- convo = "\n".join(f"{t['role']}: {t['content'][:400]}" for t in recent)
127
- prompt_parts.append(f"# CONVERSATION SO FAR\n{convo}")
128
-
129
- prompt_parts.append(f"# QUESTION\n{question}")
130
- prompt = "\n\n".join(prompt_parts)
131
-
132
- reply = self.model.generate(
133
- prompt, system=RIVET_SYSTEM, knowledge=knowledge,
134
- max_tokens=self.max_tokens,
135
- )
136
- if not reply.ok:
137
- return SkillResponse(
138
- content=f"model call failed: {reply.error}", success=False,
139
- data={"text": "", "error": reply.error},
140
- )
141
- return SkillResponse(
142
- content="draft generated", success=True,
143
- data={
144
- "text": reply.text,
145
- "backend": reply.backend,
146
- "knowledge_injected": reply.knowledge_injected,
147
- "packs_used": pack_names,
148
- },
149
- )