Session infrastructure: OpenRouter + tree-split reducer + observer→LLM Team + scrum_applier #11
@ -438,6 +438,46 @@ async fn chat(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Phase 40 part 2 — fire-and-forget /event to observer at :3800.
|
||||||
|
// Same ring-buffer that scrum + scenario events land in, so any
|
||||||
|
// tool-routed-through-our-gateway (Pi, Archon, openai SDK clients)
|
||||||
|
// shows up alongside scrum_master events for KB consolidation +
|
||||||
|
// pathway-memory + bug-fingerprint compounding. Best-effort:
|
||||||
|
// observer being down doesn't block the chat response.
|
||||||
|
{
|
||||||
|
let provider = used_provider.clone();
|
||||||
|
let model = resp.model.clone();
|
||||||
|
let prompt_tokens = resp.usage.prompt_tokens;
|
||||||
|
let completion_tokens = resp.usage.completion_tokens;
|
||||||
|
let success = true;
|
||||||
|
tokio::spawn(async move {
|
||||||
|
let body = serde_json::json!({
|
||||||
|
"endpoint": "/v1/chat",
|
||||||
|
"source": "v1.chat",
|
||||||
|
"event_kind": "chat_completion",
|
||||||
|
"input_summary": format!(
|
||||||
|
"{} {} prompt={}t",
|
||||||
|
provider, model, prompt_tokens
|
||||||
|
),
|
||||||
|
"output_summary": format!(
|
||||||
|
"completion={}t {}ms",
|
||||||
|
completion_tokens, latency_ms
|
||||||
|
),
|
||||||
|
"success": success,
|
||||||
|
"duration_ms": latency_ms,
|
||||||
|
});
|
||||||
|
let client = reqwest::Client::builder()
|
||||||
|
.timeout(std::time::Duration::from_secs(2))
|
||||||
|
.build()
|
||||||
|
.unwrap_or_else(|_| reqwest::Client::new());
|
||||||
|
let _ = client
|
||||||
|
.post("http://localhost:3800/event")
|
||||||
|
.json(&body)
|
||||||
|
.send()
|
||||||
|
.await;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Phase 40: per-provider usage tracking
|
// Phase 40: per-provider usage tracking
|
||||||
{
|
{
|
||||||
let mut u = state.usage.write().await;
|
let mut u = state.usage.write().await;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user