UNPKG

@sema-agent/core

Version:

Stateless, task-oriented AI agent core

717 lines (716 loc) • 41 kB
import {} from "../internal/llm.js"; import { BrainError } from "./errors.js"; import { startsWithInputTooLongAnchor } from "./input-too-long.js"; import { DEGENERATE_MESSAGE, trimDegenerateTail } from "./repetition.js"; import { STREAM_TORN_WARNING, createRepetitionPoll, noteResponseModel, parseStreamedToolArgs, placeTurnNotes, truncationCauseClause } from "./stream-shared.js"; import { admitToolCallId, providerResultIds, providerToolCallId, responseToolCallIds } from "./tool-call-id.js"; import { emitBrainTelemetry, reportReasoningWireFacts } from "./status-sink.js"; import { errorResultMediaNote, IMAGE_OMITTED_NO_VISION, modelSupportsVision, sendableImages } from "./media-degrade.js"; import { ANTHROPIC_RESERVED, OUTPUT_CAP_KEYS, applyExtraBody, effectiveOutputCap, lockHeader, mergeHeaders, takeHeaderCasefold } from "./request-params.js"; import { adjudicateModelRoute, applyRouteCredentialHeaders, assertServableRequestRoot, createBrainRouteJudge, joinRequestUrl, resolveRequestRoot, resolveRouteCredential, routeRefusalText } from "./route-adjudicator.js"; import { MIN_THINKING_TOKENS, budgetCapSkipsThinking, declaredEffortLevels, reasoningBudgetShare, reasoningRequestCarried, resolveEffort } from "./reasoning.js"; import { runStreamingBrain } from "./stream-engine.js"; import { refuseRetiredTimeoutKnobs } from "./timeout.js"; import { resolveFetch } from "./transport.js"; function thinkingBudget(maxTokens, share, fixed, hardCap = false) { const max = hardCap ? maxTokens : Math.max(maxTokens, MIN_THINKING_TOKENS * 2); const want = fixed ?? Math.floor(max * share); const budget = Math.min(Math.max(MIN_THINKING_TOKENS, want), max - 1); return { max, budget }; } const EPHEMERAL = { type: "ephemeral" }; const DOCUMENT_OMITTED_NO_VISION = "[PDF document omitted: the serving model does not support document input; extract the text via Bash instead (e.g. `pdftotext`).]"; function textOf(content) { return typeof content === "string" ? content : content.filter((c) => c.type === "text" && typeof c.text === "string").map((c) => c.text).join(""); } function toUserBlocks(content, supportsVision = true) { if (typeof content === "string") { return content.length > 0 ? [{ type: "text", text: content }] : []; } const blocks = []; let omitted = 0; for (const c of content) { if (c.type === "text" && typeof c.text === "string" && c.text.length > 0) { blocks.push({ type: "text", text: c.text }); } else if (c.type === "image" && c.data && c.mimeType) { if (supportsVision) blocks.push({ type: "image", source: { type: "base64", media_type: c.mimeType, data: c.data } }); else { omitted++; blocks.push({ type: "text", text: IMAGE_OMITTED_NO_VISION }); } } } if (omitted > 0) emitBrainTelemetry({ kind: "vision_placeholder", count: omitted }); return blocks; } function toAnthropicMessages(ctx, model) { const supportsVision = modelSupportsVision(model); const raw = []; let pendingDocs = []; const flushDocs = () => { if (pendingDocs.length === 0) return; raw.push({ role: "user", content: pendingDocs }); pendingDocs = []; }; const resultWireId = providerResultIds(ctx.messages); for (const m of ctx.messages) { if (m.role !== "toolResult") flushDocs(); if (m.role === "user") { const ub = toUserBlocks(m.content, supportsVision); raw.push({ role: "user", content: ub.length ? ub : [{ type: "text", text: NO_CONTENT }] }); } else if (m.role === "assistant") { const blocks = []; for (const c of m.content) { if (c.type === "thinking") { const tc = c; const sigRaw = tc.thinkingSignature; const sig = typeof sigRaw === "string" && sigRaw.length > 0 ? sigRaw : undefined; if (tc.redacted) { if (sig) blocks.push({ type: "redacted_thinking", data: sig }); } else if (sig) { blocks.push({ type: "thinking", thinking: c.thinking, signature: sig }); } } else if (c.type === "text" && c.text) { blocks.push({ type: "text", text: c.text }); } else if (c.type === "toolCall") { blocks.push({ type: "tool_use", id: providerToolCallId(c), name: c.name, input: c.arguments ?? {} }); } } raw.push({ role: "assistant", content: blocks.length ? blocks : [{ type: "text", text: NO_CONTENT }] }); } else if (m.role === "toolResult") { const parts = Array.isArray(m.content) ? m.content : undefined; const docs = parts ? parts.filter((c) => c.type === "document") : []; const rest = docs.length > 0 && parts ? parts.filter((c) => c.type !== "document") : m.content; const hasImage = !m.isError && Array.isArray(rest) && rest.some((c) => c.type === "image"); let inner = hasImage ? toUserBlocks(rest, supportsVision) : textOf(rest); if (docs.length > 0 && !m.isError) { if (supportsVision) { for (const d of docs) { if (d.data && d.mimeType) pendingDocs.push({ type: "document", source: { type: "base64", media_type: d.mimeType, data: d.data } }); } const pointer = "(PDF document attached below)"; if (typeof inner === "string") inner = inner ? `${inner}\n${pointer}` : pointer; else inner.push({ type: "text", text: pointer }); } else { emitBrainTelemetry({ kind: "document_placeholder", count: docs.length }); const note = DOCUMENT_OMITTED_NO_VISION; if (typeof inner === "string") inner = inner ? `${inner}\n${note}` : note; else inner.push({ type: "text", text: note }); } } if (m.isError) { const note = errorResultMediaNote({ images: sendableImages(Array.isArray(rest) ? rest : []).length, documents: docs.length }); if (note !== undefined) { if (typeof inner === "string") inner = inner ? `${inner}\n${note}` : note; else inner.push({ type: "text", text: note }); } } if (typeof inner === "string" ? inner.length === 0 : inner.length === 0) inner = NO_CONTENT; raw.push({ role: "user", content: [ { type: "tool_result", tool_use_id: resultWireId(m.toolCallId), content: inner, ...(m.isError ? { is_error: true } : {}), }, ], }); } } flushDocs(); const merged = []; for (const msg of raw) { const prev = merged[merged.length - 1]; if (prev && prev.role === msg.role) { prev.content.push(...msg.content); } else { merged.push({ role: msg.role, content: [...msg.content] }); } } return merged; } function toAnthropicTools(ctx, cacheBreakpoints) { if (!ctx.tools || ctx.tools.length === 0) { return undefined; } return ctx.tools.map((t, i) => ({ name: t.name, description: t.description, input_schema: t.parameters, ...(cacheBreakpoints && i === ctx.tools.length - 1 ? { cache_control: EPHEMERAL } : {}), })); } const NO_CONTENT = "(no content)"; function mapStopReason(reason, hadToolUse) { if (hadToolUse || reason === "tool_use") return "toolUse"; if (reason === "max_tokens") return "length"; return "stop"; } function anthropicStreamErrorCode(t) { switch (t) { case "rate_limit_error": return "rate_limit"; case "authentication_error": case "permission_error": return "auth"; case "invalid_request_error": return "invalid_request"; case "request_too_large": return "invalid_request"; default: return "server"; } } function computeUsage(model, u) { const input = u.input_tokens ?? 0; const output = u.output_tokens ?? 0; const cacheRead = u.cache_read_input_tokens ?? 0; const cacheWrite = u.cache_creation_input_tokens ?? 0; const c = model.cost; const costInput = (input / 1e6) * (c?.input ?? 0); const costOutput = (output / 1e6) * (c?.output ?? 0); const costCacheRead = (cacheRead / 1e6) * (c?.cacheRead ?? 0); const costCacheWrite = (cacheWrite / 1e6) * (c?.cacheWrite ?? 0); return { input, output, cacheRead, cacheWrite, totalTokens: input + output + cacheRead + cacheWrite, cost: { input: costInput, output: costOutput, cacheRead: costCacheRead, cacheWrite: costCacheWrite, total: costInput + costOutput + costCacheRead + costCacheWrite, }, }; } function closeToolUseBlock(acc, responseIds) { if (acc.closedTc) return acc.closedTc; if (!acc.toolName) return undefined; const args = parseStreamedToolArgs(acc.toolJson); if (args === undefined) return undefined; const { engineId, wireId } = admitToolCallId(acc.toolId, "toolu_", responseIds); acc.closedTc = { type: "toolCall", id: engineId, ...(wireId !== engineId ? { wireId } : {}), name: acc.toolName, arguments: args }; return acc.closedTc; } export function createAnthropicBrain(config = {}) { assertServableRequestRoot(config.baseUrl, "config.baseUrl"); refuseRetiredTimeoutKnobs(config, "construction", "createAnthropicBrain config"); const doFetch = resolveFetch(config); const cacheBreakpoints = config.cacheBreakpoints !== false; const stream = (model, context, options) => { let thinkingRequested = false; let sentMaxTokens; let sentMaxTokensLane = "config-default"; return runStreamingBrain({ model, doFetch, signal: options?.signal, config, httpLabel: "anthropic", maxRetries: options?.maxRetries, stallTimeouts: options?.stallTimeouts, buildRequest: (overrides) => { const root = resolveRequestRoot(model.baseUrl, config.baseUrl, "https://api.anthropic.com"); const routeCredential = resolveRouteCredential({ optionsApiKey: options?.apiKey, optionsHeaders: options?.headers, modelHeaders: model.headers, configApiKey: config.apiKey, configHeaders: config.headers, }); const routeVerdict = adjudicateModelRoute(model, routeCredential, { baseUrl: config.baseUrl }); if (!routeVerdict.ok) throw new BrainError("invalid_request", routeRefusalText(routeVerdict)); const apiKey = routeCredential.apiKey; const nonEmptyBlocks = context.systemBlocks?.filter((b) => b.text.length > 0); const system = nonEmptyBlocks?.length ? nonEmptyBlocks.map((b) => ({ type: "text", text: b.text, ...(cacheBreakpoints && b.cacheControlBoundary ? { cache_control: EPHEMERAL } : {}), })) : context.systemPrompt ? [{ type: "text", text: context.systemPrompt, ...(cacheBreakpoints ? { cache_control: EPHEMERAL } : {}) }] : undefined; const body = { model: model.id, max_tokens: overrides?.maxOutputTokens ?? options?.maxTokens ?? model.maxTokens ?? config.defaultMaxTokens ?? 4096, messages: toAnthropicMessages(context, model), stream: true, }; if (system) body.system = system; const tools = toAnthropicTools(context, cacheBreakpoints); if (tools) body.tools = tools; const anthCompat = (model.compat ?? {}); if (options?.temperature !== undefined && anthCompat.supportsTemperature !== false) { body.temperature = options.temperature; } let builtReasoningFacts; let thinkingOn = false; if (reasoningRequestCarried(model, options?.reasoning)) { if (anthCompat.thinkingMode === "adaptive") { body.thinking = { type: "adaptive" }; thinkingOn = true; } else { const hardCap = overrides?.maxOutputTokens !== undefined || options?.maxTokens !== undefined; builtReasoningFacts = { outputCapTokens: body.max_tokens, hardOutputCap: hardCap }; if (budgetCapSkipsThinking(builtReasoningFacts.outputCapTokens, builtReasoningFacts.hardOutputCap)) { body.thinking = undefined; delete body.thinking; } else { const share = config.thinkingBudgetShare ?? reasoningBudgetShare(options.reasoning); const { max, budget } = thinkingBudget(body.max_tokens, share, config.thinkingBudgetTokens, hardCap); body.max_tokens = max; body.thinking = { type: "enabled", budget_tokens: budget }; thinkingOn = true; } } if (thinkingOn) delete body.temperature; } else if (model.reasoning && options?.reasoning === "off" && anthCompat.thinkingMode !== "adaptive") { body.thinking = { type: "disabled" }; } const betas = []; let sendEffortBeta = false; const declaredEffort = declaredEffortLevels(anthCompat.effortLevels); if (declaredEffort !== undefined && reasoningRequestCarried(model, options?.reasoning)) { const { effective } = resolveEffort(options.reasoning, declaredEffort); const wireEffort = effective === "minimal" ? "low" : effective; body.output_config = { effort: wireEffort }; sendEffortBeta = true; } if (sendEffortBeta) betas.push("effort-2025-11-24"); if (anthCompat.contextManagement && thinkingOn) { body.context_management = { edits: [{ type: "clear_thinking_20251015", keep: "all" }] }; betas.push("context-management-2025-06-27"); } if (anthCompat.interleavedThinking) { betas.push("interleaved-thinking-2025-05-14"); } const headers = mergeHeaders(model.headers, config.headers, options?.headers); applyRouteCredentialHeaders(headers, routeCredential, { model: model.headers, options: options?.headers }); if (betas.length > 0) { const existing = (takeHeaderCasefold(headers, "anthropic-beta") ?? "").split(",").map((b) => b.trim()).filter(Boolean); for (const beta of betas) { if (!existing.includes(beta)) existing.push(beta); } headers["anthropic-beta"] = existing.join(","); } lockHeader(headers, "content-type", "application/json"); lockHeader(headers, "anthropic-version", config.version ?? "2023-06-01"); if (apiKey) headers["x-api-key"] = apiKey; const builtThinkingRequested = body.thinking !== undefined; const builtMaxTokens = body.max_tokens; const builtMaxTokensLane = overrides?.maxOutputTokens !== undefined ? "engine" : options?.maxTokens !== undefined ? "options" : model.maxTokens !== undefined ? "model" : "config-default"; const wire = applyExtraBody(body, model.extraBody, ANTHROPIC_RESERVED); return { url: joinRequestUrl(root, "/v1/messages"), headers, body: JSON.stringify(wire), outputCapTokens: effectiveOutputCap(wire, OUTPUT_CAP_KEYS.anthropic), capDerivedPaths: [...OUTPUT_CAP_KEYS.anthropic, "thinking.budget_tokens"], onCommitted: () => { thinkingRequested = builtThinkingRequested; sentMaxTokens = builtMaxTokens; sentMaxTokensLane = builtMaxTokensLane; if (builtReasoningFacts !== undefined) reportReasoningWireFacts(builtReasoningFacts); }, }; }, makeParser: (ctrl) => { const { out, partial } = ctrl; const blocks = new Map(); const responseIds = responseToolCallIds(); const usageRaw = {}; let stopReason = null; const terminalFrameSeen = () => stopReason != null; let stopDetails; let nextContentIndex = 0; let malformedFrames = 0; let malformedSample; let degenerate = false; let degenTextBlock; const rep = createRepetitionPoll(); let lastDegenCheck = 0; let lastDegenCheckThinking = 0; const detectRep = config.detectRepetition !== false; const handleEvent = (evt) => { switch (evt.type) { case "message_start": { const msg = evt.message; noteResponseModel(partial, msg?.model, model.id); const u = msg?.usage; if (u) { usageRaw.input_tokens = u.input_tokens; usageRaw.cache_read_input_tokens = u.cache_read_input_tokens; usageRaw.cache_creation_input_tokens = u.cache_creation_input_tokens; } break; } case "content_block_start": { ctrl.sawContentToken(); const idx = evt.index; const cb = evt.content_block; const acc = { type: "text", text: "", signature: "", toolId: "", toolName: "", toolJson: "" }; if (cb.type === "thinking" || cb.type === "redacted_thinking") { acc.type = "thinking"; if (cb.type === "redacted_thinking") { acc.redacted = true; acc.signature = cb.data ?? ""; } else { if (typeof cb.thinking === "string" && cb.thinking !== "") acc.text = cb.thinking; if (typeof cb.signature === "string" && cb.signature !== "") acc.startSignature = cb.signature; } acc.pb = { type: "thinking", thinking: "" }; partial.content = [acc.pb]; out.push({ type: "thinking_start", contentIndex: idx, partial: { ...partial } }); if (acc.text !== "") { acc.pb.thinking = acc.text; out.push({ type: "thinking_delta", contentIndex: idx, delta: acc.text, partial: { ...partial } }); } } else if (cb.type === "tool_use") { acc.type = "tool_use"; acc.toolId = cb.id ?? ""; acc.toolName = cb.name ?? ""; } else { acc.type = "text"; acc.pb = { type: "text", text: "" }; partial.content = [acc.pb]; out.push({ type: "text_start", contentIndex: idx, partial: { ...partial } }); } blocks.set(idx, acc); nextContentIndex = Math.max(nextContentIndex, idx + 1); break; } case "content_block_delta": { ctrl.sawContentToken(); const idx = evt.index; const acc = blocks.get(idx); if (!acc) break; const d = evt.delta; if (d.type === "text_delta" && d.text) { acc.text += d.text; if (acc.pb && acc.pb.type === "text") acc.pb.text = acc.text; out.push({ type: "text_delta", contentIndex: idx, delta: d.text, partial: { ...partial } }); if (detectRep && !degenerate && acc.text.length - lastDegenCheck >= 64) { lastDegenCheck = acc.text.length; if (rep.poll(acc.text)) { degenerate = true; degenTextBlock = acc; ctrl.cancel(); } } } else if (d.type === "thinking_delta" && d.thinking) { acc.startSignature = undefined; acc.text += d.thinking; if (acc.pb && acc.pb.type === "thinking") acc.pb.thinking = acc.text; out.push({ type: "thinking_delta", contentIndex: idx, delta: d.thinking, partial: { ...partial } }); if (detectRep && !degenerate && acc.text.length - lastDegenCheckThinking >= 64) { lastDegenCheckThinking = acc.text.length; if (rep.poll(acc.text)) { degenerate = true; ctrl.cancel(); } } } else if (d.type === "signature_delta" && typeof d.signature === "string" && d.signature.length > 0) { acc.signature += d.signature; } else if (d.type === "input_json_delta" && d.partial_json) { acc.toolJson += d.partial_json; } break; } case "content_block_stop": { const idx = evt.index; const acc = blocks.get(idx); if (acc) acc.stopped = true; if (acc?.type === "thinking") { out.push({ type: "thinking_end", contentIndex: idx, content: acc.text, partial: { ...partial } }); } else if (acc?.type === "text") { out.push({ type: "text_end", contentIndex: idx, content: acc.text, partial: { ...partial } }); } else if (acc?.type === "tool_use") { const tc = closeToolUseBlock(acc, responseIds); if (tc) { out.push({ type: "toolcall_end", contentIndex: idx, toolCall: tc, partial: { ...partial } }); } } break; } case "message_delta": { const d = evt.delta; if (d?.stop_reason) stopReason = d.stop_reason; if (d?.stop_details) stopDetails = d.stop_details; const u = evt.usage; if (u) { if (u.output_tokens !== undefined) usageRaw.output_tokens = u.output_tokens; if (u.input_tokens != null && u.input_tokens > 0) usageRaw.input_tokens = u.input_tokens; if (u.cache_read_input_tokens != null && u.cache_read_input_tokens > 0) { usageRaw.cache_read_input_tokens = u.cache_read_input_tokens; } if (u.cache_creation_input_tokens != null && u.cache_creation_input_tokens > 0) { usageRaw.cache_creation_input_tokens = u.cache_creation_input_tokens; } } break; } case "error": { const rawError = evt.error; const e = typeof rawError === "object" && rawError !== null && !Array.isArray(rawError) ? rawError : undefined; const inputTooLong = e?.type === "request_too_large" || (e?.type === "invalid_request_error" && typeof e.message === "string" && startsWithInputTooLongAnchor(e.message)); throw new BrainError(anthropicStreamErrorCode(e?.type), `anthropic stream error (${e?.type ?? "unknown"}): ${e?.message ?? ""}`, undefined, { apiError: true, ...(e === undefined ? {} : inputTooLong ? { inputTooLong: true } : { inputTooLongRuledOut: true }) }); } default: break; } }; return { snapshot() { const accs = [...blocks.values()]; const hasSubstantiveText = accs.some((a) => a.type === "text" && a.text.trim() !== ""); const hasCompletedToolCall = accs.some((a) => a.closedTc !== undefined); const hasThinking = accs.some((a) => a.type === "thinking" && (a.text.length > 0 || a.redacted === true)); return { hasSubstantiveText, hasCompletedToolCall, hasOnlyThinking: hasThinking && !hasSubstantiveText && !hasCompletedToolCall, terminalFrameSeen: terminalFrameSeen(), }; }, sealForRetry() { for (const [idx, acc] of [...blocks.entries()].sort((a, b) => a[0] - b[0])) { if (acc.type === "thinking" && !acc.stopped) { acc.stopped = true; out.push({ type: "thinking_end", contentIndex: idx, content: acc.text, partial: { ...partial } }); } } }, onLine(rawLine) { const line = rawLine.trim(); if (!line.startsWith("data:")) return; const data = line.slice(5).trim(); if (!data) return; let evt; try { evt = JSON.parse(data); } catch { malformedFrames++; malformedSample ??= data.slice(0, 160); return; } handleEvent(evt); }, finalize(opts) { const finalContent = []; const toolCalls = []; const malformed = []; const unnamed = []; let anyText = false; let reasoningSeen = false; for (const [, acc] of [...blocks.entries()].sort((a, b) => a[0] - b[0])) { if (acc.type === "thinking") { if (acc.text.length > 0 || acc.redacted === true) reasoningSeen = true; const block = { type: "thinking", thinking: acc.text }; const sig = acc.signature || acc.startSignature; if (sig) block.thinkingSignature = sig; if (acc.redacted) block.redacted = true; finalContent.push(block); } else if (acc.type === "text") { const text = acc === degenTextBlock && rep.cut !== undefined ? trimDegenerateTail(acc.text, rep.cut) : acc.text; if (text) { finalContent.push({ type: "text", text }); if (text.trim()) anyText = true; } } else if (acc.type === "tool_use") { if (!acc.toolName) { unnamed.push(`id="${acc.toolId || "?"}"(${acc.toolJson.slice(0, 200)})`); } else { const tc = closeToolUseBlock(acc, responseIds); if (tc) { toolCalls.push(tc); finalContent.push(tc); } else { malformed.push(`${acc.toolName}(${acc.toolJson.slice(0, 200)})`); } } } } const doneReason = mapStopReason(stopReason, toolCalls.length > 0); const noUsableContent = toolCalls.length === 0 && !anyText; const toolErrorParts = []; if (malformed.length > 0) { toolErrorParts.push(`tool call argument(s) not valid JSON (likely truncated, stop_reason="${stopReason ?? "?"}"${truncationCauseClause({ capStop: stopReason === "max_tokens", outputTokens: usageRaw.output_tokens, capTokens: sentMaxTokens, terminalFrameSeen: terminalFrameSeen() })}): ${malformed.join("; ")}`); } if (unnamed.length > 0) { toolErrorParts.push(`tool call(s) arrived with no tool name and cannot be executed (stop_reason="${stopReason ?? "?"}"): ${unnamed.join("; ")}`); } const toolError = toolErrorParts.length > 0 ? toolErrorParts.join(" | ") : undefined; const notes = []; if (malformed.length > 0) { notes.push({ cause: "truncated", count: malformed.length, text: `\n[note: ${malformed.length} tool call(s) were truncated (stop_reason="${stopReason ?? "?"}") and dropped — re-issue them next turn: ${malformed.join("; ")}]` }); } if (unnamed.length > 0) { notes.push({ cause: "unnamed", count: unnamed.length, text: `\n[note: ${unnamed.length} tool call(s) arrived with no tool name and were dropped — re-issue them next turn with an explicit tool name: ${unnamed.join("; ")}]` }); } if (malformedFrames > 0) { notes.push({ cause: "bad_frame", count: malformedFrames, text: `\n[note: ${malformedFrames} provider stream frame(s) were not valid JSON and were dropped — the streamed output may be missing content (first sample: ${JSON.stringify(malformedSample)})]` }); } placeTurnNotes(partial, finalContent, notes); const truncatedEmpty = stopReason === "max_tokens" && noUsableContent && !toolError; const dynamicCut = truncatedEmpty && options?.maxTokensDynamic === true; const staticReasoningCut = truncatedEmpty && !dynamicCut && reasoningSeen && options?.staticReasoningCutDowngrade === true; const safetyCut = stopReason === "refusal"; const contextWindowExceeded = stopReason === "model_context_window_exceeded"; const emptyNoFinish = noUsableContent && stopReason == null && !degenerate; const maxTokensNote = `effective max_tokens=${sentMaxTokens ?? "?"} (from ${sentMaxTokensLane === "options" ? "options.maxTokens" : sentMaxTokensLane === "engine" ? "the engine's context-overflow recovery" : sentMaxTokensLane === "model" ? "model.maxTokens" : "config default"})`; const errorMessage = degenerate ? DEGENERATE_MESSAGE : safetyCut ? `[refusal] response refused by the model (stop_reason="refusal"${stopDetails?.category ? `, category="${stopDetails.category}"` : ""}) — ${stopDetails?.explanation ?? "the output was withheld for policy and is unreliable"}` : contextWindowExceeded ? `[invalid_request] model context window exceeded (stop_reason="model_context_window_exceeded") — the conversation no longer fits the model's context window` : (toolError ?? (truncatedEmpty && !dynamicCut && !staticReasoningCut ? thinkingRequested ? `[length_empty] response truncated at max_tokens with no answer text (${maxTokensNote}) — extended thinking likely consumed the entire budget; raise max_tokens or lower thinkingBudgetShare` : reasoningSeen ? `[length_empty] response truncated at max_tokens with no answer text (${maxTokensNote}) — the model emitted reasoning although no thinking was requested (a budget-ignoring gateway?) and it consumed the entire output budget; raise max_tokens` : `[length_empty] response truncated at max_tokens with no answer text (${maxTokensNote}); raise max_tokens` : emptyNoFinish ? `[stream_torn] model stream ended with no content and no stop_reason — the response was lost (a torn stream or an in-band provider error frame)${malformedFrames > 0 ? ` — ${malformedFrames} unparseable data frame(s) were dropped on this stream (first sample: ${JSON.stringify(malformedSample)})` : ""}` : undefined)); const errored = degenerate || safetyCut || contextWindowExceeded || emptyNoFinish || (toolError !== undefined && noUsableContent) || (truncatedEmpty && !dynamicCut && !staticReasoningCut); const tornWithContent = !errored && opts?.truncated !== true && !terminalFrameSeen() && !noUsableContent && !degenerate; const errorMessageOut = tornWithContent ? (errorMessage ? `${errorMessage}\n${STREAM_TORN_WARNING}` : STREAM_TORN_WARNING) : errorMessage; const errorKind = degenerate ? "degenerate" : !safetyCut && contextWindowExceeded ? "input_too_long" : !safetyCut && toolError === undefined && truncatedEmpty && !dynamicCut && !staticReasoningCut ? "length_empty" : undefined; const finalMessage = { ...partial, content: finalContent.length > 0 ? finalContent : [{ type: "text", text: "" }], stopReason: errored ? "error" : doneReason, usage: computeUsage(model, usageRaw), ...(Object.keys(usageRaw).length === 0 ? { usageMissing: true } : {}), timestamp: Date.now(), ...(errorMessageOut ? { errorMessage: errorMessageOut } : {}), ...(errorKind ? { errorKind } : {}), ...(tornWithContent ? { partialFinalized: true } : {}), ...(rep.cut !== undefined || rep.spared.length > 0 ? { repetition: { ...(rep.cut !== undefined ? { cut: rep.cut } : {}), ...(rep.spared.length > 0 ? { spared: rep.spared } : {}) } } : {}), ...(staticReasoningCut ? { staticReasoningCut: true } : {}), ...(stopDetails ? { diagnostics: [ ...(partial.diagnostics ?? []), { type: "stop_details", timestamp: Date.now(), details: { ...stopDetails } }, ], } : {}), }; if (errored) { out.push({ type: "error", reason: "error", error: finalMessage }); } else { out.push({ type: "done", reason: doneReason, message: finalMessage }); } }, }; }, }); }; return { stream, adjudicateRoute: createBrainRouteJudge(config) }; }