HumboldtJoker commited on
Commit
2361493
·
verified ·
1 Parent(s): e2921fc

Remove nested duplicate: scaffold/scaffold/rivet_serve.py

Browse files
Files changed (1) hide show
  1. scaffold/scaffold/rivet_serve.py +0 -184
scaffold/scaffold/rivet_serve.py DELETED
@@ -1,184 +0,0 @@
1
- """Rivet Server — the code assistant endpoint.
2
-
3
- Wraps Ollama with the discipline gate and context loader.
4
- Faculty hit this endpoint; Rivet responds with architecture-aware,
5
- discipline-gated suggestions.
6
-
7
- Usage:
8
- python rivet_serve.py # Start server on port 8100
9
- python rivet_serve.py --port 8200 # Custom port
10
- python rivet_serve.py --model qwen3.5:27b # Use fallback model
11
- """
12
-
13
- import argparse
14
- import json
15
- import time
16
- from http.server import HTTPServer, BaseHTTPRequestHandler
17
-
18
- import requests
19
-
20
- from context_loader import load_context
21
- from discipline_gate import run_gate, GateResult
22
-
23
-
24
- # Config
25
- OLLAMA_URL = "http://localhost:11434"
26
- DEFAULT_MODEL = "rivet"
27
- FALLBACK_MODEL = "qwen3.5:27b"
28
-
29
- # Load context once at startup
30
- print("Loading Rivet context...", flush=True)
31
- CONTEXT = load_context()
32
- SYSTEM_PROMPT = CONTEXT.to_system_context() + """
33
-
34
- ---
35
-
36
- # YOUR ROLE
37
-
38
- You are Rivet, a senior engineer embedded with the Multiverse Campus team.
39
-
40
- ## Rules
41
- 1. Never suggest a destructive migration. Staging and prod share the database.
42
- 2. Every code suggestion includes: what it changes, what it could break, and what tests verify it.
43
- 3. State your confidence level: HIGH (traced the full path), MEDIUM (read the code), LOW (reasoning from architecture).
44
- 4. Auth changes require explicit callout: "This touches authentication. Review with security before merging."
45
- 5. Flag known vulnerability patterns proactively.
46
- 6. You are a colleague, not the lead. Suggest, don't decree.
47
- 7. If you cannot verify your suggestion compiles, say so.
48
- """
49
-
50
- print(f"Context loaded: ~{CONTEXT.token_estimate} tokens", flush=True)
51
-
52
-
53
- def query_ollama(prompt: str, model: str = DEFAULT_MODEL) -> str:
54
- """Send a prompt to Ollama and get the response."""
55
- try:
56
- resp = requests.post(
57
- f"{OLLAMA_URL}/api/generate",
58
- json={
59
- "model": model,
60
- "prompt": prompt,
61
- "system": SYSTEM_PROMPT,
62
- "stream": False,
63
- "options": {
64
- "temperature": 0.3,
65
- "top_p": 0.9,
66
- "num_ctx": 32768,
67
- },
68
- },
69
- timeout=120,
70
- )
71
- resp.raise_for_status()
72
- return resp.json().get("response", "")
73
- except requests.exceptions.ConnectionError:
74
- return f"ERROR: Cannot connect to Ollama at {OLLAMA_URL}. Is it running?"
75
- except requests.exceptions.Timeout:
76
- return "ERROR: Ollama request timed out (120s). Try a shorter question or check the model."
77
- except Exception as e:
78
- return f"ERROR: {e}"
79
-
80
-
81
- class RivetHandler(BaseHTTPRequestHandler):
82
- model = DEFAULT_MODEL
83
-
84
- def do_POST(self):
85
- if self.path == "/ask":
86
- content_length = int(self.headers.get("Content-Length", 0))
87
- body = json.loads(self.rfile.read(content_length))
88
- question = body.get("question", "")
89
- user = body.get("user", "anonymous")
90
-
91
- t0 = time.time()
92
-
93
- # Get response from model
94
- response = query_ollama(question, model=self.model)
95
-
96
- # Run discipline gate on the response
97
- gate_result = run_gate(response, context=question)
98
- gate_warnings = gate_result.format_warnings()
99
-
100
- # Compose final response
101
- final_response = response
102
- if gate_warnings:
103
- final_response = gate_warnings + "\n\n---\n\n" + response
104
- if not gate_result.passed:
105
- final_response = (
106
- "🛑 **BLOCKED by Discipline Gate**\n\n"
107
- "The suggested approach was blocked for safety reasons:\n"
108
- + gate_warnings
109
- + "\n\nPlease rephrase your request or ask for a safe alternative."
110
- )
111
-
112
- elapsed = time.time() - t0
113
-
114
- result = {
115
- "response": final_response,
116
- "gate_passed": gate_result.passed,
117
- "flags": gate_result.flags,
118
- "confidence": gate_result.confidence.value,
119
- "user": user,
120
- "elapsed_seconds": round(elapsed, 1),
121
- }
122
-
123
- self.send_response(200)
124
- self.send_header("Content-Type", "application/json")
125
- self.end_headers()
126
- self.wfile.write(json.dumps(result).encode())
127
-
128
- elif self.path == "/health":
129
- self.send_response(200)
130
- self.send_header("Content-Type", "application/json")
131
- self.end_headers()
132
- self.wfile.write(json.dumps({
133
- "status": "ok",
134
- "model": self.model,
135
- "context_tokens": CONTEXT.token_estimate,
136
- }).encode())
137
-
138
- else:
139
- self.send_response(404)
140
- self.end_headers()
141
-
142
- def do_GET(self):
143
- if self.path == "/health":
144
- self.send_response(200)
145
- self.send_header("Content-Type", "application/json")
146
- self.end_headers()
147
- self.wfile.write(json.dumps({
148
- "status": "ok",
149
- "model": self.model,
150
- "context_tokens": CONTEXT.token_estimate,
151
- }).encode())
152
- else:
153
- self.send_response(404)
154
- self.end_headers()
155
-
156
- def log_message(self, format, *args):
157
- print(f"[rivet] {args[0]}", flush=True)
158
-
159
-
160
- def main():
161
- parser = argparse.ArgumentParser(description="Rivet Code Assistant Server")
162
- parser.add_argument("--port", type=int, default=8100)
163
- parser.add_argument("--model", default=DEFAULT_MODEL)
164
- args = parser.parse_args()
165
-
166
- RivetHandler.model = args.model
167
-
168
- server = HTTPServer(("0.0.0.0", args.port), RivetHandler)
169
- print(f"\n🔩 Rivet listening on port {args.port}", flush=True)
170
- print(f" Model: {args.model}", flush=True)
171
- print(f" Context: ~{CONTEXT.token_estimate} tokens loaded", flush=True)
172
- print(f" POST /ask {{\"question\": \"...\", \"user\": \"...\"}}", flush=True)
173
- print(f" GET /health", flush=True)
174
- print(flush=True)
175
-
176
- try:
177
- server.serve_forever()
178
- except KeyboardInterrupt:
179
- print("\n🔩 Rivet shutting down.", flush=True)
180
- server.shutdown()
181
-
182
-
183
- if __name__ == "__main__":
184
- main()