2026-08-18 23:24:27 -04:00
|
|
|
// shre-router client. POST /v1/chat with stream:false.
|
|
|
|
|
// Real model answer lives in .message.content; top-level .content can carry an
|
|
|
|
|
// upstream-down apology — always prefer .message.content.
|
|
|
|
|
|
|
|
|
|
export async function chat({ routerUrl, model, messages, agentId, sessionId, tenantId, timeoutMs }) {
|
|
|
|
|
const res = await fetch(`${routerUrl.replace(/\/$/, '')}/v1/chat`, {
|
|
|
|
|
method: 'POST',
|
|
|
|
|
headers: { 'Content-Type': 'application/json' },
|
2026-08-19 00:00:37 -04:00
|
|
|
// tools:false + raw:true — reviews need pure model reasoning. raw:true is
|
|
|
|
|
// the router's sanctioned _bypassToolRouting flag: without it, keyword
|
|
|
|
|
// fast-paths (current-info briefing, store-resolver, retail dispatch)
|
|
|
|
|
// hijack prompts whose DIFF CONTENT mentions github/sales/store-ish terms
|
|
|
|
|
// and return non-review text. The domain preflight (agent_mismatch 400)
|
|
|
|
|
// still applies per agent tier; the pipeline's attempt-2 fallback agent
|
|
|
|
|
// covers that.
|
|
|
|
|
body: JSON.stringify({ model, messages, agentId, sessionId, tenantId, stream: false, tools: false, raw: true }),
|
2026-08-18 23:24:27 -04:00
|
|
|
signal: AbortSignal.timeout(timeoutMs)
|
|
|
|
|
});
|
|
|
|
|
if (!res.ok) {
|
|
|
|
|
const text = await res.text().catch(() => '');
|
|
|
|
|
throw new Error(`router -> ${res.status}: ${text.slice(0, 300)}`);
|
|
|
|
|
}
|
|
|
|
|
const data = await res.json();
|
2026-08-18 23:35:12 -04:00
|
|
|
// Response shape varies by upstream: prefer .message.content, then
|
|
|
|
|
// OpenAI-style choices, then top-level .content (which can carry an
|
|
|
|
|
// upstream-down apology — hence last).
|
|
|
|
|
const content = data?.message?.content
|
|
|
|
|
?? data?.choices?.[0]?.message?.content
|
|
|
|
|
?? data?.content;
|
2026-08-18 23:24:27 -04:00
|
|
|
if (typeof content !== 'string' || !content.trim()) {
|
|
|
|
|
throw new Error('router returned empty content');
|
|
|
|
|
}
|
2026-08-18 23:35:12 -04:00
|
|
|
return { content, servedModel: data?._shre?.model ?? null };
|
2026-08-18 23:24:27 -04:00
|
|
|
}
|