diff --git a/docs/api/openapi.yaml b/docs/api/openapi.yaml index befef0a1b..a4e4dbcec 100644 --- a/docs/api/openapi.yaml +++ b/docs/api/openapi.yaml @@ -19630,7 +19630,6 @@ components: - type: string enum: - no-provider - - text-only-model - enable-local-ocr - type: "null" pdfSupported: diff --git a/src/app/api/insights/chat/route.ts b/src/app/api/insights/chat/route.ts index f418a1c7e..341476274 100644 --- a/src/app/api/insights/chat/route.ts +++ b/src/app/api/insights/chat/route.ts @@ -549,6 +549,9 @@ Reply now as the assistant, in ${locale === "de" ? "German" : "English"}. Fetch temperature: AI_BUDGETS.coach.temperature, maxTokens: AI_BUDGETS.coach.maxTokens, fallbackWindow: effectiveScope?.window, + // v1.20.1 — thread the abort signal so a mid-generation disconnect tears + // down the per-round provider calls instead of paying the full cost. + signal: request.signal, }); result = loop.result; workingProviderType = loop.workingProviderType; diff --git a/src/lib/ai/coach/tools/loop.ts b/src/lib/ai/coach/tools/loop.ts index 216c29b96..1f0dfb1d6 100644 --- a/src/lib/ai/coach/tools/loop.ts +++ b/src/lib/ai/coach/tools/loop.ts @@ -58,6 +58,8 @@ export async function runCoachToolLoop(args: { maxTokens?: number; fallbackWindow?: CoachScopeWindow; ledger?: ProviderHealthLedger; + /** Aborts the per-round provider calls on client disconnect. */ + signal?: AbortSignal; }): Promise { const { userId, @@ -68,6 +70,7 @@ export async function runCoachToolLoop(args: { maxTokens, fallbackWindow, ledger, + signal, } = args; const messages: AiMessage[] = [...args.messages]; @@ -92,6 +95,7 @@ export async function runCoachToolLoop(args: { messages, temperature, maxTokens, + signal, ...(offerTools ? { tools, toolChoice: "auto" as const } : { toolChoice: "none" as const }),