@agent-native/core 0.114.9 → 0.114.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/corpus/README.md +2 -2
- package/corpus/core/CHANGELOG.md +13 -0
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/agent/engine/ai-sdk-engine.ts +31 -3
- package/corpus/core/src/agent/engine/anthropic-engine.ts +20 -3
- package/corpus/core/src/agent/engine/builder-engine.ts +56 -9
- package/corpus/core/src/agent/engine/first-event-timeout.ts +64 -0
- package/corpus/core/src/cli/pr-visual-recap-workflow.ts +2 -3
- package/corpus/core/src/client/AssistantChat.tsx +7 -3
- package/corpus/core/src/client/resources/ResourcesPanel.tsx +1 -1
- package/corpus/core/src/integrations/computer-supervision-store.ts +4 -4
- package/corpus/core/src/integrations/pending-tasks-store.ts +1 -1
- package/corpus/core/src/integrations/remote-commands-store.ts +5 -5
- package/corpus/core/src/integrations/remote-devices-store.ts +3 -3
- package/corpus/core/src/integrations/remote-push-store.ts +3 -3
- package/corpus/core/src/observability/traces.ts +38 -1
- package/corpus/core/src/server/action-routes.ts +23 -1
- package/corpus/core/src/server/http-response-telemetry.ts +6 -1
- package/corpus/core/src/templates/workspace-core/.agents/skills/observability/SKILL.md +1 -1
- package/corpus/core/src/templates/workspace-core/.agents/skills/tracking/SKILL.md +1 -1
- package/corpus/templates/analytics/actions/account-deep-dive.ts +41 -6
- package/corpus/templates/analytics/changelog/2026-07-20-account-deep-dives-finish-with-partial-data-when-hubspot-lo.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-20-dashboard-email-reports-now-include-an-image-when-a-single-p.md +6 -0
- package/corpus/templates/analytics/server/lib/dashboard-report.ts +11 -3
- package/corpus/templates/calendar/actions/create-event.ts +5 -0
- package/corpus/templates/calendar/app/components/ThemeToggle.tsx +4 -1
- package/corpus/templates/calendar/app/components/calendar/EventDetailPanel.tsx +0 -1
- package/corpus/templates/calendar/app/components/calendar/EventDetailPopover.tsx +309 -421
- package/corpus/templates/calendar/app/components/calendar/InlineEventPickers.tsx +349 -0
- package/corpus/templates/calendar/app/i18n-data.ts +110 -0
- package/corpus/templates/calendar/app/lib/event-form-utils.ts +6 -0
- package/corpus/templates/calendar/app/pages/CalendarView.tsx +3 -0
- package/corpus/templates/calendar/app/root.tsx +4 -2
- package/corpus/templates/calendar/changelog/2026-07-20-events-can-be-updated-inline-with-date-time-timezone-and-rep.md +6 -0
- package/corpus/templates/calendar/changelog/2026-07-20-public-booking-pages-no-longer-hydrate-with-a-theme-mismatch.md +6 -0
- package/corpus/templates/calendar/shared/api.ts +1 -0
- package/corpus/templates/clips/AGENTS.md +7 -0
- package/corpus/templates/clips/actions/create-recording.ts +51 -10
- package/corpus/templates/clips/actions/get-recording-player-data.ts +34 -5
- package/corpus/templates/clips/actions/lib/transcript-preview.ts +48 -0
- package/corpus/templates/clips/actions/list-recordings.ts +15 -4
- package/corpus/templates/clips/actions/regenerate-summary.ts +32 -0
- package/corpus/templates/clips/actions/search-recordings.ts +28 -6
- package/corpus/templates/clips/actions/view-screen.ts +54 -47
- package/corpus/templates/clips/app/components/library/library-grid.tsx +1 -5
- package/corpus/templates/clips/app/components/library/recording-card.tsx +29 -32
- package/corpus/templates/clips/app/components/meetings/quick-ask-sidebar.tsx +13 -0
- package/corpus/templates/clips/changelog/2026-07-20-agent-summaries-use-bounded-transcript-context.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-20-clip-summaries-now-finish-without-sending-a-long-transcript-.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-20-clips-agents-only-discover-recordings-you-own-or-have-alread.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-20-hosted-recordings-no-longer-start-with-an-impossible-buffered-upload.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-20-meeting-recordings-now-offer-a-cleaner-transcript-view-with-.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-20-shared-clips-can-be-shared-with-limited-access-and-cards-sho.md +6 -0
- package/corpus/templates/clips/desktop/src/hooks/useMeetingTranscription.ts +12 -8
- package/corpus/templates/clips/desktop/src/overlays/pill-logo.tsx +2 -15
- package/corpus/templates/clips/desktop/src/overlays/recording-pill.tsx +107 -340
- package/corpus/templates/clips/desktop/src/styles.css +27 -145
- package/corpus/templates/clips/desktop/src-tauri/src/recording_indicator.rs +6 -7
- package/corpus/templates/clips/server/lib/agent-recording-access.ts +73 -0
- package/corpus/templates/clips/server/plugins/agent-chat.ts +5 -2
- package/corpus/templates/plan/app/lib/plan-local-bridge.ts +18 -0
- package/corpus/templates/plan/app/pages/PlansPage.tsx +10 -11
- package/corpus/templates/plan/changelog/2026-07-20-bridged-local-plans-now-load-comments-from-the-local-workspace.md +6 -0
- package/dist/agent/engine/ai-sdk-engine.d.ts.map +1 -1
- package/dist/agent/engine/ai-sdk-engine.js +27 -4
- package/dist/agent/engine/ai-sdk-engine.js.map +1 -1
- package/dist/agent/engine/anthropic-engine.d.ts.map +1 -1
- package/dist/agent/engine/anthropic-engine.js +19 -4
- package/dist/agent/engine/anthropic-engine.js.map +1 -1
- package/dist/agent/engine/builder-engine.d.ts.map +1 -1
- package/dist/agent/engine/builder-engine.js +40 -7
- package/dist/agent/engine/builder-engine.js.map +1 -1
- package/dist/agent/engine/first-event-timeout.d.ts +25 -0
- package/dist/agent/engine/first-event-timeout.d.ts.map +1 -0
- package/dist/agent/engine/first-event-timeout.js +49 -0
- package/dist/agent/engine/first-event-timeout.js.map +1 -0
- package/dist/cli/pr-visual-recap-workflow.d.ts +2 -2
- package/dist/cli/pr-visual-recap-workflow.d.ts.map +1 -1
- package/dist/cli/pr-visual-recap-workflow.js +2 -2
- package/dist/cli/pr-visual-recap-workflow.js.map +1 -1
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +7 -3
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/resources/ResourcesPanel.js +1 -1
- package/dist/client/resources/ResourcesPanel.js.map +1 -1
- package/dist/collab/routes.d.ts +1 -1
- package/dist/integrations/computer-supervision-store.js +4 -4
- package/dist/integrations/computer-supervision-store.js.map +1 -1
- package/dist/integrations/pending-tasks-store.js +1 -1
- package/dist/integrations/pending-tasks-store.js.map +1 -1
- package/dist/integrations/remote-commands-store.js +5 -5
- package/dist/integrations/remote-commands-store.js.map +1 -1
- package/dist/integrations/remote-devices-store.js +3 -3
- package/dist/integrations/remote-devices-store.js.map +1 -1
- package/dist/integrations/remote-push-store.js +3 -3
- package/dist/integrations/remote-push-store.js.map +1 -1
- package/dist/notifications/routes.d.ts +2 -2
- package/dist/observability/routes.d.ts +3 -3
- package/dist/observability/traces.d.ts.map +1 -1
- package/dist/observability/traces.js +23 -1
- package/dist/observability/traces.js.map +1 -1
- package/dist/secrets/routes.d.ts +9 -9
- package/dist/server/action-routes.d.ts.map +1 -1
- package/dist/server/action-routes.js +23 -1
- package/dist/server/action-routes.js.map +1 -1
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/http-response-telemetry.d.ts +2 -0
- package/dist/server/http-response-telemetry.d.ts.map +1 -1
- package/dist/server/http-response-telemetry.js +5 -1
- package/dist/server/http-response-telemetry.js.map +1 -1
- package/dist/templates/workspace-core/.agents/skills/observability/SKILL.md +1 -1
- package/dist/templates/workspace-core/.agents/skills/tracking/SKILL.md +1 -1
- package/package.json +2 -2
- package/src/agent/engine/ai-sdk-engine.ts +31 -3
- package/src/agent/engine/anthropic-engine.ts +20 -3
- package/src/agent/engine/builder-engine.ts +56 -9
- package/src/agent/engine/first-event-timeout.ts +64 -0
- package/src/cli/pr-visual-recap-workflow.ts +2 -3
- package/src/client/AssistantChat.tsx +7 -3
- package/src/client/resources/ResourcesPanel.tsx +1 -1
- package/src/integrations/computer-supervision-store.ts +4 -4
- package/src/integrations/pending-tasks-store.ts +1 -1
- package/src/integrations/remote-commands-store.ts +5 -5
- package/src/integrations/remote-devices-store.ts +3 -3
- package/src/integrations/remote-push-store.ts +3 -3
- package/src/observability/traces.ts +38 -1
- package/src/server/action-routes.ts +23 -1
- package/src/server/http-response-telemetry.ts +6 -1
- package/src/templates/workspace-core/.agents/skills/observability/SKILL.md +1 -1
- package/src/templates/workspace-core/.agents/skills/tracking/SKILL.md +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-sdk-engine.js","sourceRoot":"","sources":["../../../src/agent/engine/ai-sdk-engine.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * AISDKEngine — wraps the Vercel AI SDK (ai package) for multi-provider support.\n *\n * Supports Anthropic, OpenAI, Google Gemini, Groq, and any provider with an\n * @ai-sdk/* package. Provider is selected via the `provider` config option.\n *\n * When provider is \"anthropic\", Anthropic-native features (thinking, cacheControl)\n * are forwarded through the AI SDK's providerOptions mechanism — no fidelity loss\n * compared to the native AnthropicEngine.\n *\n * The ai package is an OPTIONAL peer dependency. This engine uses dynamic import()\n * so the core package remains installable without the AI SDK.\n */\n\nimport {\n clearProviderCredentialAuthFailure,\n readDeployCredentialEnv,\n recordProviderCredentialAuthFailure,\n} from \"../../server/credential-provider.js\";\nimport {\n anthropicManualThinkingBudget,\n normalizeReasoningEffortForModel,\n supportsClaudeAdaptiveThinking,\n} from \"../../shared/reasoning-effort.js\";\nimport { AI_SDK_MODEL_CONFIG, type AISDKProvider } from \"../model-config.js\";\nimport {\n clampThinkingBudgetTokens,\n resolveMaxOutputTokensForEngine,\n} from \"./output-tokens.js\";\nimport {\n engineToolsToAISDK,\n engineMessagesToAISDK,\n aiSdkPartToEngineEvents,\n aiSdkStepToAssistantContent,\n} from \"./translate-ai-sdk.js\";\nimport type {\n AgentEngine,\n EngineCapabilities,\n EngineStreamOptions,\n EngineEvent,\n EngineContentPart,\n} from \"./types.js\";\n\nexport type { AISDKProvider } from \"../model-config.js\";\n\n// ---------------------------------------------------------------------------\n// Provider definitions\n// ---------------------------------------------------------------------------\n\nconst PROVIDER_CAPABILITIES: Record<AISDKProvider, EngineCapabilities> = {\n anthropic: {\n thinking: true,\n promptCaching: true,\n vision: true,\n computerUse: false, // not exposed through AI SDK yet\n parallelToolCalls: true,\n },\n openai: {\n thinking: true,\n promptCaching: false,\n vision: true,\n computerUse: false,\n parallelToolCalls: true,\n },\n openrouter: {\n thinking: true,\n promptCaching: true,\n vision: true,\n computerUse: false,\n parallelToolCalls: true,\n },\n google: {\n thinking: true,\n promptCaching: false,\n vision: true,\n computerUse: false,\n parallelToolCalls: true,\n },\n groq: {\n thinking: false,\n promptCaching: false,\n vision: false,\n computerUse: false,\n parallelToolCalls: true,\n },\n mistral: {\n thinking: false,\n promptCaching: false,\n vision: false,\n computerUse: false,\n parallelToolCalls: true,\n },\n cohere: {\n thinking: false,\n promptCaching: false,\n vision: false,\n computerUse: false,\n parallelToolCalls: true,\n },\n ollama: {\n thinking: false,\n promptCaching: false,\n vision: false,\n computerUse: false,\n parallelToolCalls: false,\n },\n};\n\nconst providerModelEntries = Object.entries(AI_SDK_MODEL_CONFIG) as Array<\n [AISDKProvider, (typeof AI_SDK_MODEL_CONFIG)[AISDKProvider]]\n>;\n\nconst PROVIDER_DEFAULT_MODELS = Object.fromEntries(\n providerModelEntries.map(([provider, config]) => [\n provider,\n config.defaultModel,\n ]),\n) as Record<AISDKProvider, string>;\n\nconst PROVIDER_SUPPORTED_MODELS = Object.fromEntries(\n providerModelEntries.map(([provider, config]) => [\n provider,\n config.supportedModels,\n ]),\n) as unknown as Record<AISDKProvider, readonly string[]>;\n\nconst PROVIDER_ENV_VARS: Record<AISDKProvider, string[]> = {\n anthropic: [\"ANTHROPIC_API_KEY\"],\n openai: [\"OPENAI_API_KEY\"],\n openrouter: [\"OPENROUTER_API_KEY\"],\n google: [\"GOOGLE_GENERATIVE_AI_API_KEY\"],\n groq: [\"GROQ_API_KEY\"],\n mistral: [\"MISTRAL_API_KEY\"],\n cohere: [\"COHERE_API_KEY\"],\n ollama: [], // runs locally\n};\n\nconst PROVIDER_PACKAGES: Record<AISDKProvider, string> = {\n anthropic: \"@ai-sdk/anthropic\",\n openai: \"@ai-sdk/openai\",\n openrouter: \"@openrouter/ai-sdk-provider\",\n google: \"@ai-sdk/google\",\n groq: \"@ai-sdk/groq\",\n mistral: \"@ai-sdk/mistral\",\n cohere: \"@ai-sdk/cohere\",\n ollama: \"ai-sdk-ollama\",\n};\n\n/** Factory export name per provider (not all follow `create<Provider>`). */\nconst PROVIDER_FACTORIES: Record<AISDKProvider, string> = {\n anthropic: \"createAnthropic\",\n openai: \"createOpenAI\",\n openrouter: \"createOpenRouter\",\n google: \"createGoogleGenerativeAI\",\n groq: \"createGroq\",\n mistral: \"createMistral\",\n cohere: \"createCohere\",\n ollama: \"createOllama\",\n};\n\nfunction googleThinkingBudget(effort: string) {\n if (effort === \"low\") return 1024;\n // \"medium\" is a normalized effort for Gemini models; without this case it\n // fell through to the -1 (\"dynamic/unlimited\") fallback, so selecting\n // medium effort silently uncapped the thinking budget.\n if (effort === \"medium\") return 4096;\n if (effort === \"high\") return 8000;\n if (effort === \"xhigh\") return 16_000;\n if (effort === \"max\") return 32_000;\n return -1;\n}\n\n/**\n * Map a reasoning effort level to Gemini 3.x thinkingLevel string.\n * Gemini 3 models (gemini-3.*) reject thinkingBudget and require thinkingLevel\n * with values 'low' | 'medium' | 'high'. Gemini 3.0 only supports 'low'/'high';\n * Gemini 3.1+ adds 'medium'. We always emit 'medium' for medium effort since it\n * is accepted by 3.1+, and 3.0 is expected to be phased out quickly.\n */\nfunction gemini3ThinkingLevel(effort: string): string {\n if (effort === \"low\") return \"low\";\n if (effort === \"medium\") return \"medium\";\n // high/xhigh/max map to the strongest available level for Gemini 3.\n return \"high\";\n}\n\n// ---------------------------------------------------------------------------\n// AISDKEngine implementation\n// ---------------------------------------------------------------------------\n\n/** Config accepted by every `ai-sdk:*` engine. */\nexport interface AISDKEngineConfig {\n /** Override the provider's default model (also becomes the engine's defaultModel). */\n model?: string;\n /** API key — falls back to the provider-specific env var if omitted. */\n apiKey?: string;\n /** Set false in request-scoped multi-tenant runs so provider packages cannot fall back to process.env. */\n allowEnvFallback?: boolean;\n /** Override the provider base URL (useful for proxies or OpenAI-compatible gateways). */\n baseUrl?: string;\n /** OpenRouter: `X-OpenRouter-Title` header for dashboard attribution. */\n appName?: string;\n /** OpenRouter: `HTTP-Referer` header for dashboard attribution. */\n appUrl?: string;\n}\n\nclass AISDKEngine implements AgentEngine {\n readonly name: string;\n readonly label: string;\n readonly defaultModel: string;\n readonly supportedModels: readonly string[];\n readonly preserveCustomModels: boolean;\n readonly capabilities: EngineCapabilities;\n\n private readonly provider: AISDKProvider;\n private readonly apiKey?: string;\n private readonly baseUrl?: string;\n private readonly appName?: string;\n private readonly appUrl?: string;\n\n constructor(provider: AISDKProvider, config: AISDKEngineConfig) {\n this.provider = provider;\n this.name = `ai-sdk:${provider}`;\n this.label = `${capitalize(provider)} (AI SDK)`;\n this.defaultModel = config.model ?? PROVIDER_DEFAULT_MODELS[provider];\n this.supportedModels = PROVIDER_SUPPORTED_MODELS[provider];\n this.preserveCustomModels =\n provider === \"openai\" && Boolean(config.baseUrl);\n this.capabilities = PROVIDER_CAPABILITIES[provider];\n this.apiKey =\n config.apiKey ??\n (config.allowEnvFallback === false ? \"\" : getProviderApiKey(provider));\n this.baseUrl = config.baseUrl;\n this.appName = config.appName;\n this.appUrl = config.appUrl;\n }\n\n async *stream(opts: EngineStreamOptions): AsyncIterable<EngineEvent> {\n let aiModule: any;\n try {\n aiModule = await import(\"ai\");\n } catch {\n yield {\n type: \"stop\",\n reason: \"error\",\n error: `The \"ai\" package is not installed. Run: pnpm add ai ${PROVIDER_PACKAGES[this.provider]}`,\n };\n return;\n }\n\n const { streamText, jsonSchema } = aiModule;\n\n let providerModel: any;\n try {\n providerModel = await this.createProviderModel(opts.model);\n } catch (err: any) {\n yield {\n type: \"stop\",\n reason: \"error\",\n error: err?.message ?? String(err),\n };\n return;\n }\n\n const aiSdkTools =\n opts.tools.length > 0\n ? engineToolsToAISDK(opts.tools, jsonSchema)\n : undefined;\n const messages = engineMessagesToAISDK(opts.messages, {\n // Vision-capable provider translators (anthropic/openai/google/\n // openrouter) map image parts to native blocks; the rest stringify\n // tool-result content arrays, so images degrade to their text notes.\n toolResultImages: this.capabilities.vision,\n });\n\n // Resolved once so both `maxOutputTokens` (below, in the streamText call)\n // and the thinking-budget headroom clamp agree on the same ceiling.\n const resolvedMaxOutputTokens = resolveMaxOutputTokensForEngine(\n this.name,\n opts.maxOutputTokens,\n opts.model,\n );\n\n // Build providerOptions for Anthropic-native features when using Anthropic provider\n const providerOpts: Record<string, unknown> = {};\n if (this.provider === \"anthropic\" && opts.providerOptions?.anthropic) {\n const anthropicOpts = opts.providerOptions.anthropic;\n if (anthropicOpts.thinking) {\n // Only the \"enabled\" config carries a numeric budgetTokens; clamp it\n // so thinking can't consume the entire maxOutputTokens budget and\n // leave zero room for the actual response (\"adaptive\" thinking has\n // no budgetTokens field at all per @ai-sdk/anthropic's schema).\n providerOpts.anthropic = {\n ...((providerOpts.anthropic as object) ?? {}),\n thinking: {\n type: \"enabled\",\n budgetTokens:\n typeof anthropicOpts.thinking.budgetTokens === \"number\"\n ? clampThinkingBudgetTokens(\n anthropicOpts.thinking.budgetTokens,\n resolvedMaxOutputTokens,\n )\n : anthropicOpts.thinking.budgetTokens,\n },\n };\n }\n if (anthropicOpts.cacheControl) {\n providerOpts.anthropic = {\n ...((providerOpts.anthropic as object) ?? {}),\n cacheControl: anthropicOpts.cacheControl,\n };\n }\n }\n const reasoningEffort = normalizeReasoningEffortForModel(\n opts.model,\n opts.reasoningEffort,\n );\n if (reasoningEffort) {\n if (this.provider === \"anthropic\") {\n const explicitThinking = (\n providerOpts.anthropic as { thinking?: unknown } | undefined\n )?.thinking;\n if (explicitThinking || supportsClaudeAdaptiveThinking(opts.model)) {\n providerOpts.anthropic = {\n ...((providerOpts.anthropic as object) ?? {}),\n thinking: explicitThinking ?? { type: \"adaptive\" },\n ...(explicitThinking\n ? {}\n : { outputConfig: { effort: reasoningEffort } }),\n };\n } else {\n const budgetTokens = clampThinkingBudgetTokens(\n anthropicManualThinkingBudget(reasoningEffort),\n resolvedMaxOutputTokens,\n );\n providerOpts.anthropic = {\n ...((providerOpts.anthropic as object) ?? {}),\n ...(budgetTokens === undefined\n ? {}\n : { thinking: { type: \"enabled\", budgetTokens } }),\n };\n }\n } else if (this.provider === \"openai\") {\n providerOpts.openai = {\n ...((providerOpts.openai as object) ?? {}),\n reasoningEffort,\n };\n } else if (this.provider === \"openrouter\") {\n providerOpts.openrouter = {\n ...((providerOpts.openrouter as object) ?? {}),\n reasoning: { effort: reasoningEffort },\n };\n } else if (this.provider === \"google\") {\n // Gemini 3.x models reject thinkingBudget — they require thinkingLevel.\n // Gemini 2.5.x models use thinkingBudget (integer token count or -1).\n const isGemini3 = /^gemini-3/.test(opts.model);\n const thinkingBudget = googleThinkingBudget(reasoningEffort);\n providerOpts.google = {\n ...((providerOpts.google as object) ?? {}),\n thinkingConfig: isGemini3\n ? { thinkingLevel: gemini3ThinkingLevel(reasoningEffort) }\n : {\n // Unlike Anthropic's adaptive thinking, Gemini 2.5's\n // thinkingBudget IS a concrete numeric token count, so the\n // same headroom clamp applies: at \"max\" effort this maps to\n // 32000 tokens, which can equal (or exceed) a small\n // maxOutputTokens cap and leave zero room for the actual\n // response. Preserve Gemini's -1 \"dynamic\" sentinel.\n thinkingBudget:\n thinkingBudget > 0\n ? clampThinkingBudgetTokens(\n thinkingBudget,\n resolvedMaxOutputTokens,\n )\n : thinkingBudget,\n },\n };\n }\n }\n\n let assistantContent: EngineContentPart[] = [];\n\n try {\n const result = streamText({\n model: providerModel,\n system: opts.systemPrompt,\n messages,\n tools: aiSdkTools,\n maxOutputTokens: resolvedMaxOutputTokens,\n ...(opts.temperature !== undefined\n ? { temperature: opts.temperature }\n : {}),\n abortSignal: opts.abortSignal,\n onStepFinish: (step: any) => {\n assistantContent = aiSdkStepToAssistantContent(step);\n },\n ...(Object.keys(providerOpts).length > 0\n ? { providerOptions: providerOpts }\n : {}),\n });\n\n // Buffer the terminal stop so assistant-content can be emitted just\n // before it, regardless of where `finish` arrives in the stream.\n let bufferedStop: EngineEvent | undefined;\n\n for await (const part of result.fullStream) {\n for (const event of aiSdkPartToEngineEvents(part)) {\n if (event.type === \"stop\") {\n bufferedStop = event;\n } else {\n yield event;\n }\n }\n }\n\n yield { type: \"assistant-content\", parts: assistantContent };\n await clearProviderCredentialAuthFailure({\n key: PROVIDER_ENV_VARS[this.provider][0],\n value: this.apiKey,\n });\n yield bufferedStop ?? { type: \"stop\", reason: \"end_turn\" };\n } catch (err: any) {\n // Surface structured fields from AI SDK's APICallError so\n // isRetryableError can check statusCode/providerRetryable directly\n // rather than keyword-matching the message string.\n const statusCode: number | undefined =\n typeof err?.statusCode === \"number\" ? err.statusCode : undefined;\n const errorMessage = err?.message ?? String(err);\n const isConnectionError =\n statusCode === undefined &&\n String(errorMessage).trim().toLowerCase() === \"connection error.\";\n const providerRetryable: boolean | undefined =\n typeof err?.isRetryable === \"boolean\"\n ? err.isRetryable\n : isConnectionError\n ? true\n : undefined;\n if (statusCode === 401) {\n await recordProviderCredentialAuthFailure({\n key: PROVIDER_ENV_VARS[this.provider][0],\n value: this.apiKey,\n status: statusCode,\n code: \"http_401\",\n message: errorMessage,\n });\n }\n yield {\n type: \"stop\",\n reason: \"error\",\n error: errorMessage,\n // Tag every known status with `http_<status>` (not just 401) so a\n // rate limit surfaces as `http_429`. The structured statusCode\n // already drives turn-level retries, but the run-level continuation\n // logic keys off the errorCode, so this lets a rate-limited turn\n // auto-resume too — matching the Builder gateway path.\n ...(statusCode !== undefined\n ? { errorCode: `http_${statusCode}`, statusCode }\n : isConnectionError\n ? { errorCode: \"provider_network_error\" }\n : {}),\n ...(providerRetryable !== undefined ? { providerRetryable } : {}),\n };\n throw err;\n }\n }\n\n private async createProviderModel(model: string): Promise<any> {\n const pkg = PROVIDER_PACKAGES[this.provider];\n let providerModule: any;\n try {\n providerModule = await importProviderPackage(this.provider);\n } catch {\n throw new Error(\n `Provider package \"${pkg}\" is not installed. Run: pnpm add ai ${pkg}`,\n );\n }\n\n const fnName = PROVIDER_FACTORIES[this.provider];\n const createFn = providerModule[fnName] ?? providerModule.default;\n if (typeof createFn !== \"function\") {\n throw new Error(`\"${pkg}\" does not export ${fnName} or default`);\n }\n\n const config: Record<string, unknown> = {};\n if (this.apiKey !== undefined) config.apiKey = this.apiKey;\n if (this.baseUrl) config.baseURL = this.baseUrl;\n // Scoped to openrouter — other providers' factories may reject unknown keys.\n if (this.provider === \"openrouter\") {\n if (this.appName) config.appName = this.appName;\n if (this.appUrl) config.appUrl = this.appUrl;\n }\n\n const provider = createFn(config);\n // Let first-party OpenAI use the AI SDK's default Responses path so newer\n // GPT reasoning models get the API OpenAI recommends. If someone points\n // the OpenAI provider at an OpenAI-compatible gateway, keep using Chat\n // Completions because many gateway base URLs do not implement Responses.\n return this.provider === \"openai\" && this.baseUrl\n ? provider.chat(model)\n : provider(model);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Factory functions\n// ---------------------------------------------------------------------------\n\nexport function createAISDKEngine(\n provider: AISDKProvider,\n config: Record<string, unknown> = {},\n): AgentEngine {\n return new AISDKEngine(provider, config as AISDKEngineConfig);\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n// Static string-literal imports so bundlers (Nitro/Rollup/Vercel) can analyze\n// and include provider packages. A variable-based `import(pkg)` gets skipped.\nasync function importProviderPackage(provider: AISDKProvider): Promise<any> {\n switch (provider) {\n case \"anthropic\":\n return import(\"@ai-sdk/anthropic\");\n case \"openai\":\n return import(\"@ai-sdk/openai\");\n case \"openrouter\":\n return import(\"@openrouter/ai-sdk-provider\");\n case \"google\":\n return import(\"@ai-sdk/google\");\n case \"groq\":\n return import(\"@ai-sdk/groq\");\n case \"mistral\":\n return import(\"@ai-sdk/mistral\");\n case \"cohere\":\n return import(\"@ai-sdk/cohere\");\n case \"ollama\":\n return import(\"ai-sdk-ollama\");\n }\n}\n\nfunction capitalize(s: string): string {\n return s.charAt(0).toUpperCase() + s.slice(1);\n}\n\nfunction getProviderApiKey(provider: AISDKProvider): string | undefined {\n const envVars = PROVIDER_ENV_VARS[provider];\n for (const v of envVars) {\n const value = readDeployCredentialEnv(v);\n if (value) return value;\n }\n return undefined;\n}\n\n// ---------------------------------------------------------------------------\n// Exports for registry registration\n// ---------------------------------------------------------------------------\n\nexport {\n PROVIDER_CAPABILITIES,\n PROVIDER_DEFAULT_MODELS,\n PROVIDER_SUPPORTED_MODELS,\n PROVIDER_ENV_VARS,\n PROVIDER_PACKAGES,\n};\n"]}
|
|
1
|
+
{"version":3,"file":"ai-sdk-engine.js","sourceRoot":"","sources":["../../../src/agent/engine/ai-sdk-engine.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * AISDKEngine — wraps the Vercel AI SDK (ai package) for multi-provider support.\n *\n * Supports Anthropic, OpenAI, Google Gemini, Groq, and any provider with an\n * @ai-sdk/* package. Provider is selected via the `provider` config option.\n *\n * When provider is \"anthropic\", Anthropic-native features (thinking, cacheControl)\n * are forwarded through the AI SDK's providerOptions mechanism — no fidelity loss\n * compared to the native AnthropicEngine.\n *\n * The ai package is an OPTIONAL peer dependency. This engine uses dynamic import()\n * so the core package remains installable without the AI SDK.\n */\n\nimport {\n clearProviderCredentialAuthFailure,\n readDeployCredentialEnv,\n recordProviderCredentialAuthFailure,\n} from \"../../server/credential-provider.js\";\nimport {\n anthropicManualThinkingBudget,\n normalizeReasoningEffortForModel,\n supportsClaudeAdaptiveThinking,\n} from \"../../shared/reasoning-effort.js\";\nimport { AI_SDK_MODEL_CONFIG, type AISDKProvider } from \"../model-config.js\";\nimport {\n createFirstEventAbortController,\n FIRST_STREAM_EVENT_TIMEOUT_MS,\n} from \"./first-event-timeout.js\";\nimport {\n clampThinkingBudgetTokens,\n resolveMaxOutputTokensForEngine,\n} from \"./output-tokens.js\";\nimport {\n engineToolsToAISDK,\n engineMessagesToAISDK,\n aiSdkPartToEngineEvents,\n aiSdkStepToAssistantContent,\n} from \"./translate-ai-sdk.js\";\nimport type {\n AgentEngine,\n EngineCapabilities,\n EngineStreamOptions,\n EngineEvent,\n EngineContentPart,\n} from \"./types.js\";\n\nexport type { AISDKProvider } from \"../model-config.js\";\n\n// ---------------------------------------------------------------------------\n// Provider definitions\n// ---------------------------------------------------------------------------\n\nconst PROVIDER_CAPABILITIES: Record<AISDKProvider, EngineCapabilities> = {\n anthropic: {\n thinking: true,\n promptCaching: true,\n vision: true,\n computerUse: false, // not exposed through AI SDK yet\n parallelToolCalls: true,\n },\n openai: {\n thinking: true,\n promptCaching: false,\n vision: true,\n computerUse: false,\n parallelToolCalls: true,\n },\n openrouter: {\n thinking: true,\n promptCaching: true,\n vision: true,\n computerUse: false,\n parallelToolCalls: true,\n },\n google: {\n thinking: true,\n promptCaching: false,\n vision: true,\n computerUse: false,\n parallelToolCalls: true,\n },\n groq: {\n thinking: false,\n promptCaching: false,\n vision: false,\n computerUse: false,\n parallelToolCalls: true,\n },\n mistral: {\n thinking: false,\n promptCaching: false,\n vision: false,\n computerUse: false,\n parallelToolCalls: true,\n },\n cohere: {\n thinking: false,\n promptCaching: false,\n vision: false,\n computerUse: false,\n parallelToolCalls: true,\n },\n ollama: {\n thinking: false,\n promptCaching: false,\n vision: false,\n computerUse: false,\n parallelToolCalls: false,\n },\n};\n\nconst providerModelEntries = Object.entries(AI_SDK_MODEL_CONFIG) as Array<\n [AISDKProvider, (typeof AI_SDK_MODEL_CONFIG)[AISDKProvider]]\n>;\n\nconst PROVIDER_DEFAULT_MODELS = Object.fromEntries(\n providerModelEntries.map(([provider, config]) => [\n provider,\n config.defaultModel,\n ]),\n) as Record<AISDKProvider, string>;\n\nconst PROVIDER_SUPPORTED_MODELS = Object.fromEntries(\n providerModelEntries.map(([provider, config]) => [\n provider,\n config.supportedModels,\n ]),\n) as unknown as Record<AISDKProvider, readonly string[]>;\n\nconst PROVIDER_ENV_VARS: Record<AISDKProvider, string[]> = {\n anthropic: [\"ANTHROPIC_API_KEY\"],\n openai: [\"OPENAI_API_KEY\"],\n openrouter: [\"OPENROUTER_API_KEY\"],\n google: [\"GOOGLE_GENERATIVE_AI_API_KEY\"],\n groq: [\"GROQ_API_KEY\"],\n mistral: [\"MISTRAL_API_KEY\"],\n cohere: [\"COHERE_API_KEY\"],\n ollama: [], // runs locally\n};\n\nconst PROVIDER_PACKAGES: Record<AISDKProvider, string> = {\n anthropic: \"@ai-sdk/anthropic\",\n openai: \"@ai-sdk/openai\",\n openrouter: \"@openrouter/ai-sdk-provider\",\n google: \"@ai-sdk/google\",\n groq: \"@ai-sdk/groq\",\n mistral: \"@ai-sdk/mistral\",\n cohere: \"@ai-sdk/cohere\",\n ollama: \"ai-sdk-ollama\",\n};\n\n/** Factory export name per provider (not all follow `create<Provider>`). */\nconst PROVIDER_FACTORIES: Record<AISDKProvider, string> = {\n anthropic: \"createAnthropic\",\n openai: \"createOpenAI\",\n openrouter: \"createOpenRouter\",\n google: \"createGoogleGenerativeAI\",\n groq: \"createGroq\",\n mistral: \"createMistral\",\n cohere: \"createCohere\",\n ollama: \"createOllama\",\n};\n\nfunction googleThinkingBudget(effort: string) {\n if (effort === \"low\") return 1024;\n // \"medium\" is a normalized effort for Gemini models; without this case it\n // fell through to the -1 (\"dynamic/unlimited\") fallback, so selecting\n // medium effort silently uncapped the thinking budget.\n if (effort === \"medium\") return 4096;\n if (effort === \"high\") return 8000;\n if (effort === \"xhigh\") return 16_000;\n if (effort === \"max\") return 32_000;\n return -1;\n}\n\n/**\n * Map a reasoning effort level to Gemini 3.x thinkingLevel string.\n * Gemini 3 models (gemini-3.*) reject thinkingBudget and require thinkingLevel\n * with values 'low' | 'medium' | 'high'. Gemini 3.0 only supports 'low'/'high';\n * Gemini 3.1+ adds 'medium'. We always emit 'medium' for medium effort since it\n * is accepted by 3.1+, and 3.0 is expected to be phased out quickly.\n */\nfunction gemini3ThinkingLevel(effort: string): string {\n if (effort === \"low\") return \"low\";\n if (effort === \"medium\") return \"medium\";\n // high/xhigh/max map to the strongest available level for Gemini 3.\n return \"high\";\n}\n\n// ---------------------------------------------------------------------------\n// AISDKEngine implementation\n// ---------------------------------------------------------------------------\n\n/** Config accepted by every `ai-sdk:*` engine. */\nexport interface AISDKEngineConfig {\n /** Override the provider's default model (also becomes the engine's defaultModel). */\n model?: string;\n /** API key — falls back to the provider-specific env var if omitted. */\n apiKey?: string;\n /** Set false in request-scoped multi-tenant runs so provider packages cannot fall back to process.env. */\n allowEnvFallback?: boolean;\n /** Override the provider base URL (useful for proxies or OpenAI-compatible gateways). */\n baseUrl?: string;\n /** OpenRouter: `X-OpenRouter-Title` header for dashboard attribution. */\n appName?: string;\n /** OpenRouter: `HTTP-Referer` header for dashboard attribution. */\n appUrl?: string;\n}\n\nclass AISDKEngine implements AgentEngine {\n readonly name: string;\n readonly label: string;\n readonly defaultModel: string;\n readonly supportedModels: readonly string[];\n readonly preserveCustomModels: boolean;\n readonly capabilities: EngineCapabilities;\n\n private readonly provider: AISDKProvider;\n private readonly apiKey?: string;\n private readonly baseUrl?: string;\n private readonly appName?: string;\n private readonly appUrl?: string;\n\n constructor(provider: AISDKProvider, config: AISDKEngineConfig) {\n this.provider = provider;\n this.name = `ai-sdk:${provider}`;\n this.label = `${capitalize(provider)} (AI SDK)`;\n this.defaultModel = config.model ?? PROVIDER_DEFAULT_MODELS[provider];\n this.supportedModels = PROVIDER_SUPPORTED_MODELS[provider];\n this.preserveCustomModels =\n provider === \"openai\" && Boolean(config.baseUrl);\n this.capabilities = PROVIDER_CAPABILITIES[provider];\n this.apiKey =\n config.apiKey ??\n (config.allowEnvFallback === false ? \"\" : getProviderApiKey(provider));\n this.baseUrl = config.baseUrl;\n this.appName = config.appName;\n this.appUrl = config.appUrl;\n }\n\n async *stream(opts: EngineStreamOptions): AsyncIterable<EngineEvent> {\n let aiModule: any;\n try {\n aiModule = await import(\"ai\");\n } catch {\n yield {\n type: \"stop\",\n reason: \"error\",\n error: `The \"ai\" package is not installed. Run: pnpm add ai ${PROVIDER_PACKAGES[this.provider]}`,\n };\n return;\n }\n\n const { streamText, jsonSchema } = aiModule;\n\n let providerModel: any;\n try {\n providerModel = await this.createProviderModel(opts.model);\n } catch (err: any) {\n yield {\n type: \"stop\",\n reason: \"error\",\n error: err?.message ?? String(err),\n };\n return;\n }\n\n const aiSdkTools =\n opts.tools.length > 0\n ? engineToolsToAISDK(opts.tools, jsonSchema)\n : undefined;\n const messages = engineMessagesToAISDK(opts.messages, {\n // Vision-capable provider translators (anthropic/openai/google/\n // openrouter) map image parts to native blocks; the rest stringify\n // tool-result content arrays, so images degrade to their text notes.\n toolResultImages: this.capabilities.vision,\n });\n\n // Resolved once so both `maxOutputTokens` (below, in the streamText call)\n // and the thinking-budget headroom clamp agree on the same ceiling.\n const resolvedMaxOutputTokens = resolveMaxOutputTokensForEngine(\n this.name,\n opts.maxOutputTokens,\n opts.model,\n );\n\n // Build providerOptions for Anthropic-native features when using Anthropic provider\n const providerOpts: Record<string, unknown> = {};\n if (this.provider === \"anthropic\" && opts.providerOptions?.anthropic) {\n const anthropicOpts = opts.providerOptions.anthropic;\n if (anthropicOpts.thinking) {\n // Only the \"enabled\" config carries a numeric budgetTokens; clamp it\n // so thinking can't consume the entire maxOutputTokens budget and\n // leave zero room for the actual response (\"adaptive\" thinking has\n // no budgetTokens field at all per @ai-sdk/anthropic's schema).\n providerOpts.anthropic = {\n ...((providerOpts.anthropic as object) ?? {}),\n thinking: {\n type: \"enabled\",\n budgetTokens:\n typeof anthropicOpts.thinking.budgetTokens === \"number\"\n ? clampThinkingBudgetTokens(\n anthropicOpts.thinking.budgetTokens,\n resolvedMaxOutputTokens,\n )\n : anthropicOpts.thinking.budgetTokens,\n },\n };\n }\n if (anthropicOpts.cacheControl) {\n providerOpts.anthropic = {\n ...((providerOpts.anthropic as object) ?? {}),\n cacheControl: anthropicOpts.cacheControl,\n };\n }\n }\n const reasoningEffort = normalizeReasoningEffortForModel(\n opts.model,\n opts.reasoningEffort,\n );\n if (reasoningEffort) {\n if (this.provider === \"anthropic\") {\n const explicitThinking = (\n providerOpts.anthropic as { thinking?: unknown } | undefined\n )?.thinking;\n if (explicitThinking || supportsClaudeAdaptiveThinking(opts.model)) {\n providerOpts.anthropic = {\n ...((providerOpts.anthropic as object) ?? {}),\n thinking: explicitThinking ?? { type: \"adaptive\" },\n ...(explicitThinking\n ? {}\n : { outputConfig: { effort: reasoningEffort } }),\n };\n } else {\n const budgetTokens = clampThinkingBudgetTokens(\n anthropicManualThinkingBudget(reasoningEffort),\n resolvedMaxOutputTokens,\n );\n providerOpts.anthropic = {\n ...((providerOpts.anthropic as object) ?? {}),\n ...(budgetTokens === undefined\n ? {}\n : { thinking: { type: \"enabled\", budgetTokens } }),\n };\n }\n } else if (this.provider === \"openai\") {\n providerOpts.openai = {\n ...((providerOpts.openai as object) ?? {}),\n reasoningEffort,\n };\n } else if (this.provider === \"openrouter\") {\n providerOpts.openrouter = {\n ...((providerOpts.openrouter as object) ?? {}),\n reasoning: { effort: reasoningEffort },\n };\n } else if (this.provider === \"google\") {\n // Gemini 3.x models reject thinkingBudget — they require thinkingLevel.\n // Gemini 2.5.x models use thinkingBudget (integer token count or -1).\n const isGemini3 = /^gemini-3/.test(opts.model);\n const thinkingBudget = googleThinkingBudget(reasoningEffort);\n providerOpts.google = {\n ...((providerOpts.google as object) ?? {}),\n thinkingConfig: isGemini3\n ? { thinkingLevel: gemini3ThinkingLevel(reasoningEffort) }\n : {\n // Unlike Anthropic's adaptive thinking, Gemini 2.5's\n // thinkingBudget IS a concrete numeric token count, so the\n // same headroom clamp applies: at \"max\" effort this maps to\n // 32000 tokens, which can equal (or exceed) a small\n // maxOutputTokens cap and leave zero room for the actual\n // response. Preserve Gemini's -1 \"dynamic\" sentinel.\n thinkingBudget:\n thinkingBudget > 0\n ? clampThinkingBudgetTokens(\n thinkingBudget,\n resolvedMaxOutputTokens,\n )\n : thinkingBudget,\n },\n };\n }\n }\n\n let assistantContent: EngineContentPart[] = [];\n const firstEventAbort = createFirstEventAbortController(opts.abortSignal);\n\n try {\n const result = streamText({\n model: providerModel,\n system: opts.systemPrompt,\n messages,\n tools: aiSdkTools,\n maxOutputTokens: resolvedMaxOutputTokens,\n ...(opts.temperature !== undefined\n ? { temperature: opts.temperature }\n : {}),\n abortSignal: firstEventAbort.signal,\n onStepFinish: (step: any) => {\n assistantContent = aiSdkStepToAssistantContent(step);\n },\n ...(Object.keys(providerOpts).length > 0\n ? { providerOptions: providerOpts }\n : {}),\n });\n\n // Buffer the terminal stop so assistant-content can be emitted just\n // before it, regardless of where `finish` arrives in the stream.\n let bufferedStop: EngineEvent | undefined;\n let sawFirstEvent = false;\n\n for await (const part of result.fullStream) {\n // \"start\" is a synthetic lifecycle marker the AI SDK enqueues\n // synchronously when the stream begins — before any provider bytes\n // arrive — so it does not count as real progress. Every other part\n // (including \"start-step\", only enqueued on the step's first real\n // chunk) proves the provider is actually responding.\n if (!sawFirstEvent && part?.type !== \"start\") {\n sawFirstEvent = true;\n firstEventAbort.markFirstEvent();\n }\n for (const event of aiSdkPartToEngineEvents(part)) {\n if (event.type === \"stop\") {\n bufferedStop = event;\n } else {\n yield event;\n }\n }\n }\n\n // AI SDK surfaces an aborted stream as a graceful `{type: \"abort\"}`\n // part rather than a thrown error, so a first-event timeout would\n // otherwise fall through to the normal end_turn completion below.\n if (!sawFirstEvent && firstEventAbort.didTimeout()) {\n throw new Error(\n `Model request produced no stream events within ${FIRST_STREAM_EVENT_TIMEOUT_MS / 1000}s; the connection appears wedged.`,\n );\n }\n\n yield { type: \"assistant-content\", parts: assistantContent };\n await clearProviderCredentialAuthFailure({\n key: PROVIDER_ENV_VARS[this.provider][0],\n value: this.apiKey,\n });\n yield bufferedStop ?? { type: \"stop\", reason: \"end_turn\" };\n } catch (err: any) {\n const timedOut = firstEventAbort.didTimeout();\n // Surface structured fields from AI SDK's APICallError so\n // isRetryableError can check statusCode/providerRetryable directly\n // rather than keyword-matching the message string.\n const statusCode: number | undefined =\n typeof err?.statusCode === \"number\" ? err.statusCode : undefined;\n const errorMessage = err?.message ?? String(err);\n const isConnectionError =\n !timedOut &&\n statusCode === undefined &&\n String(errorMessage).trim().toLowerCase() === \"connection error.\";\n const providerRetryable: boolean | undefined =\n typeof err?.isRetryable === \"boolean\"\n ? err.isRetryable\n : isConnectionError || timedOut\n ? true\n : undefined;\n if (statusCode === 401) {\n await recordProviderCredentialAuthFailure({\n key: PROVIDER_ENV_VARS[this.provider][0],\n value: this.apiKey,\n status: statusCode,\n code: \"http_401\",\n message: errorMessage,\n });\n }\n yield {\n type: \"stop\",\n reason: \"error\",\n error: errorMessage,\n // Tag every known status with `http_<status>` (not just 401) so a\n // rate limit surfaces as `http_429`. The structured statusCode\n // already drives turn-level retries, but the run-level continuation\n // logic keys off the errorCode, so this lets a rate-limited turn\n // auto-resume too — matching the Builder gateway path.\n ...(statusCode !== undefined\n ? { errorCode: `http_${statusCode}`, statusCode }\n : isConnectionError || timedOut\n ? { errorCode: \"provider_network_error\" }\n : {}),\n ...(providerRetryable !== undefined ? { providerRetryable } : {}),\n };\n throw err;\n } finally {\n firstEventAbort.cleanup();\n }\n }\n\n private async createProviderModel(model: string): Promise<any> {\n const pkg = PROVIDER_PACKAGES[this.provider];\n let providerModule: any;\n try {\n providerModule = await importProviderPackage(this.provider);\n } catch {\n throw new Error(\n `Provider package \"${pkg}\" is not installed. Run: pnpm add ai ${pkg}`,\n );\n }\n\n const fnName = PROVIDER_FACTORIES[this.provider];\n const createFn = providerModule[fnName] ?? providerModule.default;\n if (typeof createFn !== \"function\") {\n throw new Error(`\"${pkg}\" does not export ${fnName} or default`);\n }\n\n const config: Record<string, unknown> = {};\n if (this.apiKey !== undefined) config.apiKey = this.apiKey;\n if (this.baseUrl) config.baseURL = this.baseUrl;\n // Scoped to openrouter — other providers' factories may reject unknown keys.\n if (this.provider === \"openrouter\") {\n if (this.appName) config.appName = this.appName;\n if (this.appUrl) config.appUrl = this.appUrl;\n }\n\n const provider = createFn(config);\n // Let first-party OpenAI use the AI SDK's default Responses path so newer\n // GPT reasoning models get the API OpenAI recommends. If someone points\n // the OpenAI provider at an OpenAI-compatible gateway, keep using Chat\n // Completions because many gateway base URLs do not implement Responses.\n return this.provider === \"openai\" && this.baseUrl\n ? provider.chat(model)\n : provider(model);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Factory functions\n// ---------------------------------------------------------------------------\n\nexport function createAISDKEngine(\n provider: AISDKProvider,\n config: Record<string, unknown> = {},\n): AgentEngine {\n return new AISDKEngine(provider, config as AISDKEngineConfig);\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n// Static string-literal imports so bundlers (Nitro/Rollup/Vercel) can analyze\n// and include provider packages. A variable-based `import(pkg)` gets skipped.\nasync function importProviderPackage(provider: AISDKProvider): Promise<any> {\n switch (provider) {\n case \"anthropic\":\n return import(\"@ai-sdk/anthropic\");\n case \"openai\":\n return import(\"@ai-sdk/openai\");\n case \"openrouter\":\n return import(\"@openrouter/ai-sdk-provider\");\n case \"google\":\n return import(\"@ai-sdk/google\");\n case \"groq\":\n return import(\"@ai-sdk/groq\");\n case \"mistral\":\n return import(\"@ai-sdk/mistral\");\n case \"cohere\":\n return import(\"@ai-sdk/cohere\");\n case \"ollama\":\n return import(\"ai-sdk-ollama\");\n }\n}\n\nfunction capitalize(s: string): string {\n return s.charAt(0).toUpperCase() + s.slice(1);\n}\n\nfunction getProviderApiKey(provider: AISDKProvider): string | undefined {\n const envVars = PROVIDER_ENV_VARS[provider];\n for (const v of envVars) {\n const value = readDeployCredentialEnv(v);\n if (value) return value;\n }\n return undefined;\n}\n\n// ---------------------------------------------------------------------------\n// Exports for registry registration\n// ---------------------------------------------------------------------------\n\nexport {\n PROVIDER_CAPABILITIES,\n PROVIDER_DEFAULT_MODELS,\n PROVIDER_SUPPORTED_MODELS,\n PROVIDER_ENV_VARS,\n PROVIDER_PACKAGES,\n};\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"anthropic-engine.d.ts","sourceRoot":"","sources":["../../../src/agent/engine/anthropic-engine.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;
|
|
1
|
+
{"version":3,"file":"anthropic-engine.d.ts","sourceRoot":"","sources":["../../../src/agent/engine/anthropic-engine.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAgCH,OAAO,KAAK,EACV,WAAW,EACX,kBAAkB,EAGnB,MAAM,YAAY,CAAC;AAEpB,eAAO,MAAM,sBAAsB,EAAE,kBAMpC,CAAC;AAEF,eAAO,MAAM,0BAA0B,sHACC,CAAC;AACzC,eAAO,MAAM,uBAAuB,yCAAsC,CAAC;AAwP3E;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GACnC,WAAW,CAyBb"}
|
|
@@ -11,6 +11,7 @@ import { clearProviderCredentialAuthFailure, readDeployCredentialEnv, recordProv
|
|
|
11
11
|
import { anthropicManualThinkingBudget, normalizeReasoningEffortForModel, supportsClaudeAdaptiveThinking, } from "../../shared/reasoning-effort.js";
|
|
12
12
|
import { ANTHROPIC_MODEL_CONFIG } from "../model-config.js";
|
|
13
13
|
import { LLM_MISSING_CREDENTIALS_ERROR_CODE, LLM_MISSING_CREDENTIALS_MESSAGE, } from "./credential-errors.js";
|
|
14
|
+
import { createFirstEventAbortController, FIRST_STREAM_EVENT_TIMEOUT_MS, } from "./first-event-timeout.js";
|
|
14
15
|
import { clampThinkingBudgetTokens, resolveMaxOutputTokensForEngine, } from "./output-tokens.js";
|
|
15
16
|
import { engineToolsToAnthropic, engineMessagesToAnthropic, anthropicContentToEngine, anthropicChunkToEngineEvents, createAnthropicChunkStreamState, } from "./translate-anthropic.js";
|
|
16
17
|
export const ANTHROPIC_CAPABILITIES = {
|
|
@@ -131,8 +132,9 @@ class AnthropicEngine {
|
|
|
131
132
|
// Remove undefined tools to avoid Anthropic API validation errors
|
|
132
133
|
if (!requestParams.tools)
|
|
133
134
|
delete requestParams.tools;
|
|
135
|
+
const firstEventAbort = createFirstEventAbortController(opts.abortSignal);
|
|
134
136
|
const apiStream = client.messages.stream(requestParams, {
|
|
135
|
-
signal:
|
|
137
|
+
signal: firstEventAbort.signal,
|
|
136
138
|
});
|
|
137
139
|
// Per-stream state lets the translator carry each tool-call's id/name from
|
|
138
140
|
// its `content_block_start` onto the streamed `input_json_delta` chunks, so
|
|
@@ -141,6 +143,9 @@ class AnthropicEngine {
|
|
|
141
143
|
const chunkState = createAnthropicChunkStreamState();
|
|
142
144
|
try {
|
|
143
145
|
for await (const chunk of apiStream) {
|
|
146
|
+
// The SDK's SSE parsing already drops `ping` keepalives before they
|
|
147
|
+
// reach this loop, so any chunk here is real provider progress.
|
|
148
|
+
firstEventAbort.markFirstEvent();
|
|
144
149
|
const events = anthropicChunkToEngineEvents(chunk, chunkState);
|
|
145
150
|
for (const event of events) {
|
|
146
151
|
yield event;
|
|
@@ -175,16 +180,23 @@ class AnthropicEngine {
|
|
|
175
180
|
};
|
|
176
181
|
}
|
|
177
182
|
catch (err) {
|
|
183
|
+
const timedOut = firstEventAbort.didTimeout();
|
|
178
184
|
const statusCode = typeof err?.status === "number"
|
|
179
185
|
? err.status
|
|
180
186
|
: typeof err?.statusCode === "number"
|
|
181
187
|
? err.statusCode
|
|
182
188
|
: undefined;
|
|
183
|
-
|
|
189
|
+
// A first-event abort surfaces from the SDK as a generic
|
|
190
|
+
// APIUserAbortError ("Request was aborted.") — replace it with a
|
|
191
|
+
// message that actually explains what happened.
|
|
192
|
+
const errorMessage = timedOut
|
|
193
|
+
? `Model request produced no stream events within ${FIRST_STREAM_EVENT_TIMEOUT_MS / 1000}s; the connection appears wedged.`
|
|
194
|
+
: (err?.message ?? String(err));
|
|
184
195
|
// Anthropic SDK APIConnectionError defaults to "Connection error." with
|
|
185
196
|
// no HTTP status. Tag it so in-run retries and run-level resume treat
|
|
186
197
|
// the failure as a transient network interruption.
|
|
187
|
-
const isConnectionError =
|
|
198
|
+
const isConnectionError = !timedOut &&
|
|
199
|
+
statusCode === undefined &&
|
|
188
200
|
String(errorMessage).trim().toLowerCase() === "connection error.";
|
|
189
201
|
if (statusCode === 401) {
|
|
190
202
|
await recordProviderCredentialAuthFailure({
|
|
@@ -209,7 +221,7 @@ class AnthropicEngine {
|
|
|
209
221
|
// continuation logic auto-resume a rate-limited turn.
|
|
210
222
|
...(statusCode !== undefined
|
|
211
223
|
? { errorCode: `http_${statusCode}`, statusCode }
|
|
212
|
-
: isConnectionError
|
|
224
|
+
: isConnectionError || timedOut
|
|
213
225
|
? {
|
|
214
226
|
errorCode: "provider_network_error",
|
|
215
227
|
providerRetryable: true,
|
|
@@ -218,6 +230,9 @@ class AnthropicEngine {
|
|
|
218
230
|
};
|
|
219
231
|
throw err;
|
|
220
232
|
}
|
|
233
|
+
finally {
|
|
234
|
+
firstEventAbort.cleanup();
|
|
235
|
+
}
|
|
221
236
|
}
|
|
222
237
|
}
|
|
223
238
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"anthropic-engine.js","sourceRoot":"","sources":["../../../src/agent/engine/anthropic-engine.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * AnthropicEngine — wraps @anthropic-ai/sdk for use as an AgentEngine.\n *\n * This is the default, best-in-class engine. It supports all Anthropic-native\n * features: extended thinking, prompt caching, vision, computer use, and\n * parallel tool calls.\n *\n * All providerOptions.anthropic fields are forwarded directly to the SDK.\n */\n\nimport {\n clearProviderCredentialAuthFailure,\n readDeployCredentialEnv,\n recordProviderCredentialAuthFailure,\n} from \"../../server/credential-provider.js\";\nimport {\n anthropicManualThinkingBudget,\n normalizeReasoningEffortForModel,\n supportsClaudeAdaptiveThinking,\n} from \"../../shared/reasoning-effort.js\";\nimport { ANTHROPIC_MODEL_CONFIG } from \"../model-config.js\";\nimport {\n LLM_MISSING_CREDENTIALS_ERROR_CODE,\n LLM_MISSING_CREDENTIALS_MESSAGE,\n} from \"./credential-errors.js\";\nimport {\n clampThinkingBudgetTokens,\n resolveMaxOutputTokensForEngine,\n} from \"./output-tokens.js\";\nimport {\n engineToolsToAnthropic,\n engineMessagesToAnthropic,\n anthropicContentToEngine,\n anthropicChunkToEngineEvents,\n createAnthropicChunkStreamState,\n} from \"./translate-anthropic.js\";\nimport type {\n AgentEngine,\n EngineCapabilities,\n EngineStreamOptions,\n EngineEvent,\n} from \"./types.js\";\n\nexport const ANTHROPIC_CAPABILITIES: EngineCapabilities = {\n thinking: true,\n promptCaching: true,\n vision: true,\n computerUse: true,\n parallelToolCalls: true,\n};\n\nexport const ANTHROPIC_SUPPORTED_MODELS =\n ANTHROPIC_MODEL_CONFIG.supportedModels;\nexport const ANTHROPIC_DEFAULT_MODEL = ANTHROPIC_MODEL_CONFIG.defaultModel;\n\nclass AnthropicEngine implements AgentEngine {\n readonly name = \"anthropic\";\n readonly label = \"Claude (Anthropic SDK)\";\n readonly defaultModel = ANTHROPIC_DEFAULT_MODEL;\n readonly supportedModels = ANTHROPIC_SUPPORTED_MODELS;\n readonly capabilities = ANTHROPIC_CAPABILITIES;\n\n private readonly apiKey: string;\n\n constructor(apiKey: string) {\n this.apiKey = apiKey;\n }\n\n async *stream(opts: EngineStreamOptions): AsyncIterable<EngineEvent> {\n const Anthropic = (await import(\"@anthropic-ai/sdk\")).default;\n const client = new Anthropic({ apiKey: this.apiKey });\n\n const tools = engineToolsToAnthropic(opts.tools);\n const messages = engineMessagesToAnthropic(opts.messages);\n const anthropicOpts = opts.providerOptions?.anthropic;\n\n // Resolved once so both max_tokens and the thinking-budget headroom\n // clamp below agree on the same ceiling.\n const resolvedMaxOutputTokens = resolveMaxOutputTokensForEngine(\n this.name,\n opts.maxOutputTokens,\n opts.model,\n );\n\n // Build extra body params for Anthropic-native features\n const extra: Record<string, unknown> = {};\n if (anthropicOpts?.thinking) {\n extra.thinking = {\n type: anthropicOpts.thinking.type,\n // Only the \"enabled\" config carries a numeric budget_tokens; clamp it\n // so thinking can't consume the entire max_tokens budget and leave\n // zero room for the actual response (\"adaptive\" thinking has no\n // budget_tokens field at all, so it passes through unclamped).\n budget_tokens:\n anthropicOpts.thinking.type === \"enabled\" &&\n typeof anthropicOpts.thinking.budgetTokens === \"number\"\n ? clampThinkingBudgetTokens(\n anthropicOpts.thinking.budgetTokens,\n resolvedMaxOutputTokens,\n )\n : anthropicOpts.thinking.budgetTokens,\n };\n }\n if (anthropicOpts?.topK !== undefined) {\n extra.top_k = anthropicOpts.topK;\n }\n const reasoningEffort = normalizeReasoningEffortForModel(\n opts.model,\n opts.reasoningEffort,\n );\n if (reasoningEffort && !extra.thinking) {\n if (supportsClaudeAdaptiveThinking(opts.model)) {\n extra.thinking = { type: \"adaptive\" };\n extra.output_config = { effort: reasoningEffort };\n } else {\n const budgetTokens = clampThinkingBudgetTokens(\n anthropicManualThinkingBudget(reasoningEffort),\n resolvedMaxOutputTokens,\n );\n if (budgetTokens !== undefined) {\n extra.thinking = { type: \"enabled\", budget_tokens: budgetTokens };\n }\n }\n }\n\n // Apply prompt caching to the system prompt and tools by default.\n // Cache is pure upside: identical prefixes on subsequent turns get ~90%\n // off input cost and much faster time-to-first-token. If the prefix\n // changes turn-to-turn, it's a no-op. Templates can opt out by setting\n // providerOptions.anthropic.cacheControl = false.\n const cacheEnabled = anthropicOpts?.cacheControl !== false;\n const systemBlocks: any[] = [{ type: \"text\", text: opts.systemPrompt }];\n if (cacheEnabled) {\n systemBlocks[0].cache_control = { type: \"ephemeral\" };\n }\n\n // Apply cache_control to the last tool definition when caching is enabled.\n // Anthropic caches the prefix up to and including the last cached block.\n let cachedTools = tools;\n if (cacheEnabled && tools.length > 0) {\n cachedTools = [...tools];\n const last = { ...cachedTools[cachedTools.length - 1] } as any;\n last.cache_control = { type: \"ephemeral\" };\n cachedTools[cachedTools.length - 1] = last;\n }\n\n // Apply a moving cache breakpoint on the last user message's last content\n // block so the entire conversation prefix (system + tools + growing\n // history) is cached turn-over-turn as the thread lengthens. Mirrors the\n // Builder gateway engine's identical handling in builder-engine.ts.\n let cachedMessages = messages;\n if (cacheEnabled && messages.length > 0) {\n let lastUserIdx = -1;\n for (let i = messages.length - 1; i >= 0; i -= 1) {\n if ((messages[i] as any).role === \"user\") {\n lastUserIdx = i;\n break;\n }\n }\n if (lastUserIdx >= 0) {\n cachedMessages = [...messages];\n const lastMsg = { ...cachedMessages[lastUserIdx] } as any;\n if (Array.isArray(lastMsg.content) && lastMsg.content.length > 0) {\n const content = [...lastMsg.content];\n const lastBlock = { ...content[content.length - 1] } as any;\n lastBlock.cache_control = { type: \"ephemeral\" };\n content[content.length - 1] = lastBlock;\n lastMsg.content = content;\n cachedMessages[lastUserIdx] = lastMsg;\n }\n }\n }\n\n const requestParams: any = {\n model: opts.model,\n max_tokens: resolvedMaxOutputTokens,\n system: systemBlocks,\n tools: cachedTools.length > 0 ? cachedTools : undefined,\n messages: cachedMessages,\n ...(opts.temperature !== undefined\n ? { temperature: opts.temperature }\n : {}),\n ...extra,\n };\n\n // Remove undefined tools to avoid Anthropic API validation errors\n if (!requestParams.tools) delete requestParams.tools;\n\n const apiStream = client.messages.stream(requestParams, {\n signal: opts.abortSignal,\n });\n\n // Per-stream state lets the translator carry each tool-call's id/name from\n // its `content_block_start` onto the streamed `input_json_delta` chunks, so\n // long tool-input generation emits countable `tool-input-start` /\n // `tool-input-delta` progress events (mirroring the Builder engine).\n const chunkState = createAnthropicChunkStreamState();\n\n try {\n for await (const chunk of apiStream) {\n const events = anthropicChunkToEngineEvents(chunk, chunkState);\n for (const event of events) {\n yield event;\n }\n }\n\n const finalMessage = await apiStream.finalMessage();\n const assistantContent = anthropicContentToEngine(finalMessage.content);\n\n // Emit usage\n if (finalMessage.usage) {\n yield {\n type: \"usage\",\n inputTokens: finalMessage.usage.input_tokens ?? 0,\n outputTokens: finalMessage.usage.output_tokens ?? 0,\n cacheReadTokens:\n (finalMessage.usage as any).cache_read_input_tokens ?? 0,\n cacheWriteTokens:\n (finalMessage.usage as any).cache_creation_input_tokens ?? 0,\n };\n }\n\n yield { type: \"assistant-content\", parts: assistantContent };\n await clearProviderCredentialAuthFailure({\n key: \"ANTHROPIC_API_KEY\",\n value: this.apiKey,\n });\n\n // Emit stop reason\n const stopReason = finalMessage.stop_reason ?? \"end_turn\";\n yield {\n type: \"stop\",\n reason:\n stopReason === \"tool_use\"\n ? \"tool_use\"\n : stopReason === \"max_tokens\"\n ? \"max_tokens\"\n : \"end_turn\",\n };\n } catch (err: any) {\n const statusCode: number | undefined =\n typeof err?.status === \"number\"\n ? err.status\n : typeof err?.statusCode === \"number\"\n ? err.statusCode\n : undefined;\n const errorMessage = err?.message ?? String(err);\n // Anthropic SDK APIConnectionError defaults to \"Connection error.\" with\n // no HTTP status. Tag it so in-run retries and run-level resume treat\n // the failure as a transient network interruption.\n const isConnectionError =\n statusCode === undefined &&\n String(errorMessage).trim().toLowerCase() === \"connection error.\";\n if (statusCode === 401) {\n await recordProviderCredentialAuthFailure({\n key: \"ANTHROPIC_API_KEY\",\n value: this.apiKey,\n status: statusCode,\n code: \"http_401\",\n message: errorMessage,\n });\n }\n yield {\n type: \"stop\",\n reason: \"error\",\n error: errorMessage,\n // Forward the provider HTTP status for EVERY known status, not just\n // 401. The Anthropic SDK reports empty-body failures as a bare\n // \"429 status code (no body)\" message, so without a structured\n // statusCode/errorCode `isRetryableError` couldn't classify a rate\n // limit (it matches \"529\"/\"502\" substrings but not \"429\") and the\n // run failed hard instead of backing off + retrying like the Builder\n // gateway path does. `http_429`/`http_529` also let the run-level\n // continuation logic auto-resume a rate-limited turn.\n ...(statusCode !== undefined\n ? { errorCode: `http_${statusCode}`, statusCode }\n : isConnectionError\n ? {\n errorCode: \"provider_network_error\",\n providerRetryable: true,\n }\n : {}),\n };\n throw err;\n }\n }\n}\n\n/**\n * Create an AnthropicEngine instance.\n * Falls back to the deployment Anthropic key if no key is provided.\n */\nexport function createAnthropicEngine(\n config: Record<string, unknown> = {},\n): AgentEngine {\n const allowEnvFallback = config.allowEnvFallback !== false;\n const apiKey =\n (config.apiKey as string | undefined) ??\n (allowEnvFallback ? readDeployCredentialEnv(\"ANTHROPIC_API_KEY\") : \"\") ??\n \"\";\n if (!apiKey) {\n // Return a \"missing key\" engine that immediately errors\n return {\n name: \"anthropic\",\n label: \"Claude (Anthropic SDK)\",\n defaultModel: ANTHROPIC_DEFAULT_MODEL,\n supportedModels: ANTHROPIC_SUPPORTED_MODELS,\n capabilities: ANTHROPIC_CAPABILITIES,\n async *stream() {\n yield {\n type: \"stop\" as const,\n reason: \"error\" as const,\n error: LLM_MISSING_CREDENTIALS_MESSAGE,\n errorCode: LLM_MISSING_CREDENTIALS_ERROR_CODE,\n };\n },\n };\n }\n return new AnthropicEngine(apiKey);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"anthropic-engine.js","sourceRoot":"","sources":["../../../src/agent/engine/anthropic-engine.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * AnthropicEngine — wraps @anthropic-ai/sdk for use as an AgentEngine.\n *\n * This is the default, best-in-class engine. It supports all Anthropic-native\n * features: extended thinking, prompt caching, vision, computer use, and\n * parallel tool calls.\n *\n * All providerOptions.anthropic fields are forwarded directly to the SDK.\n */\n\nimport {\n clearProviderCredentialAuthFailure,\n readDeployCredentialEnv,\n recordProviderCredentialAuthFailure,\n} from \"../../server/credential-provider.js\";\nimport {\n anthropicManualThinkingBudget,\n normalizeReasoningEffortForModel,\n supportsClaudeAdaptiveThinking,\n} from \"../../shared/reasoning-effort.js\";\nimport { ANTHROPIC_MODEL_CONFIG } from \"../model-config.js\";\nimport {\n LLM_MISSING_CREDENTIALS_ERROR_CODE,\n LLM_MISSING_CREDENTIALS_MESSAGE,\n} from \"./credential-errors.js\";\nimport {\n createFirstEventAbortController,\n FIRST_STREAM_EVENT_TIMEOUT_MS,\n} from \"./first-event-timeout.js\";\nimport {\n clampThinkingBudgetTokens,\n resolveMaxOutputTokensForEngine,\n} from \"./output-tokens.js\";\nimport {\n engineToolsToAnthropic,\n engineMessagesToAnthropic,\n anthropicContentToEngine,\n anthropicChunkToEngineEvents,\n createAnthropicChunkStreamState,\n} from \"./translate-anthropic.js\";\nimport type {\n AgentEngine,\n EngineCapabilities,\n EngineStreamOptions,\n EngineEvent,\n} from \"./types.js\";\n\nexport const ANTHROPIC_CAPABILITIES: EngineCapabilities = {\n thinking: true,\n promptCaching: true,\n vision: true,\n computerUse: true,\n parallelToolCalls: true,\n};\n\nexport const ANTHROPIC_SUPPORTED_MODELS =\n ANTHROPIC_MODEL_CONFIG.supportedModels;\nexport const ANTHROPIC_DEFAULT_MODEL = ANTHROPIC_MODEL_CONFIG.defaultModel;\n\nclass AnthropicEngine implements AgentEngine {\n readonly name = \"anthropic\";\n readonly label = \"Claude (Anthropic SDK)\";\n readonly defaultModel = ANTHROPIC_DEFAULT_MODEL;\n readonly supportedModels = ANTHROPIC_SUPPORTED_MODELS;\n readonly capabilities = ANTHROPIC_CAPABILITIES;\n\n private readonly apiKey: string;\n\n constructor(apiKey: string) {\n this.apiKey = apiKey;\n }\n\n async *stream(opts: EngineStreamOptions): AsyncIterable<EngineEvent> {\n const Anthropic = (await import(\"@anthropic-ai/sdk\")).default;\n const client = new Anthropic({ apiKey: this.apiKey });\n\n const tools = engineToolsToAnthropic(opts.tools);\n const messages = engineMessagesToAnthropic(opts.messages);\n const anthropicOpts = opts.providerOptions?.anthropic;\n\n // Resolved once so both max_tokens and the thinking-budget headroom\n // clamp below agree on the same ceiling.\n const resolvedMaxOutputTokens = resolveMaxOutputTokensForEngine(\n this.name,\n opts.maxOutputTokens,\n opts.model,\n );\n\n // Build extra body params for Anthropic-native features\n const extra: Record<string, unknown> = {};\n if (anthropicOpts?.thinking) {\n extra.thinking = {\n type: anthropicOpts.thinking.type,\n // Only the \"enabled\" config carries a numeric budget_tokens; clamp it\n // so thinking can't consume the entire max_tokens budget and leave\n // zero room for the actual response (\"adaptive\" thinking has no\n // budget_tokens field at all, so it passes through unclamped).\n budget_tokens:\n anthropicOpts.thinking.type === \"enabled\" &&\n typeof anthropicOpts.thinking.budgetTokens === \"number\"\n ? clampThinkingBudgetTokens(\n anthropicOpts.thinking.budgetTokens,\n resolvedMaxOutputTokens,\n )\n : anthropicOpts.thinking.budgetTokens,\n };\n }\n if (anthropicOpts?.topK !== undefined) {\n extra.top_k = anthropicOpts.topK;\n }\n const reasoningEffort = normalizeReasoningEffortForModel(\n opts.model,\n opts.reasoningEffort,\n );\n if (reasoningEffort && !extra.thinking) {\n if (supportsClaudeAdaptiveThinking(opts.model)) {\n extra.thinking = { type: \"adaptive\" };\n extra.output_config = { effort: reasoningEffort };\n } else {\n const budgetTokens = clampThinkingBudgetTokens(\n anthropicManualThinkingBudget(reasoningEffort),\n resolvedMaxOutputTokens,\n );\n if (budgetTokens !== undefined) {\n extra.thinking = { type: \"enabled\", budget_tokens: budgetTokens };\n }\n }\n }\n\n // Apply prompt caching to the system prompt and tools by default.\n // Cache is pure upside: identical prefixes on subsequent turns get ~90%\n // off input cost and much faster time-to-first-token. If the prefix\n // changes turn-to-turn, it's a no-op. Templates can opt out by setting\n // providerOptions.anthropic.cacheControl = false.\n const cacheEnabled = anthropicOpts?.cacheControl !== false;\n const systemBlocks: any[] = [{ type: \"text\", text: opts.systemPrompt }];\n if (cacheEnabled) {\n systemBlocks[0].cache_control = { type: \"ephemeral\" };\n }\n\n // Apply cache_control to the last tool definition when caching is enabled.\n // Anthropic caches the prefix up to and including the last cached block.\n let cachedTools = tools;\n if (cacheEnabled && tools.length > 0) {\n cachedTools = [...tools];\n const last = { ...cachedTools[cachedTools.length - 1] } as any;\n last.cache_control = { type: \"ephemeral\" };\n cachedTools[cachedTools.length - 1] = last;\n }\n\n // Apply a moving cache breakpoint on the last user message's last content\n // block so the entire conversation prefix (system + tools + growing\n // history) is cached turn-over-turn as the thread lengthens. Mirrors the\n // Builder gateway engine's identical handling in builder-engine.ts.\n let cachedMessages = messages;\n if (cacheEnabled && messages.length > 0) {\n let lastUserIdx = -1;\n for (let i = messages.length - 1; i >= 0; i -= 1) {\n if ((messages[i] as any).role === \"user\") {\n lastUserIdx = i;\n break;\n }\n }\n if (lastUserIdx >= 0) {\n cachedMessages = [...messages];\n const lastMsg = { ...cachedMessages[lastUserIdx] } as any;\n if (Array.isArray(lastMsg.content) && lastMsg.content.length > 0) {\n const content = [...lastMsg.content];\n const lastBlock = { ...content[content.length - 1] } as any;\n lastBlock.cache_control = { type: \"ephemeral\" };\n content[content.length - 1] = lastBlock;\n lastMsg.content = content;\n cachedMessages[lastUserIdx] = lastMsg;\n }\n }\n }\n\n const requestParams: any = {\n model: opts.model,\n max_tokens: resolvedMaxOutputTokens,\n system: systemBlocks,\n tools: cachedTools.length > 0 ? cachedTools : undefined,\n messages: cachedMessages,\n ...(opts.temperature !== undefined\n ? { temperature: opts.temperature }\n : {}),\n ...extra,\n };\n\n // Remove undefined tools to avoid Anthropic API validation errors\n if (!requestParams.tools) delete requestParams.tools;\n\n const firstEventAbort = createFirstEventAbortController(opts.abortSignal);\n const apiStream = client.messages.stream(requestParams, {\n signal: firstEventAbort.signal,\n });\n\n // Per-stream state lets the translator carry each tool-call's id/name from\n // its `content_block_start` onto the streamed `input_json_delta` chunks, so\n // long tool-input generation emits countable `tool-input-start` /\n // `tool-input-delta` progress events (mirroring the Builder engine).\n const chunkState = createAnthropicChunkStreamState();\n\n try {\n for await (const chunk of apiStream) {\n // The SDK's SSE parsing already drops `ping` keepalives before they\n // reach this loop, so any chunk here is real provider progress.\n firstEventAbort.markFirstEvent();\n const events = anthropicChunkToEngineEvents(chunk, chunkState);\n for (const event of events) {\n yield event;\n }\n }\n\n const finalMessage = await apiStream.finalMessage();\n const assistantContent = anthropicContentToEngine(finalMessage.content);\n\n // Emit usage\n if (finalMessage.usage) {\n yield {\n type: \"usage\",\n inputTokens: finalMessage.usage.input_tokens ?? 0,\n outputTokens: finalMessage.usage.output_tokens ?? 0,\n cacheReadTokens:\n (finalMessage.usage as any).cache_read_input_tokens ?? 0,\n cacheWriteTokens:\n (finalMessage.usage as any).cache_creation_input_tokens ?? 0,\n };\n }\n\n yield { type: \"assistant-content\", parts: assistantContent };\n await clearProviderCredentialAuthFailure({\n key: \"ANTHROPIC_API_KEY\",\n value: this.apiKey,\n });\n\n // Emit stop reason\n const stopReason = finalMessage.stop_reason ?? \"end_turn\";\n yield {\n type: \"stop\",\n reason:\n stopReason === \"tool_use\"\n ? \"tool_use\"\n : stopReason === \"max_tokens\"\n ? \"max_tokens\"\n : \"end_turn\",\n };\n } catch (err: any) {\n const timedOut = firstEventAbort.didTimeout();\n const statusCode: number | undefined =\n typeof err?.status === \"number\"\n ? err.status\n : typeof err?.statusCode === \"number\"\n ? err.statusCode\n : undefined;\n // A first-event abort surfaces from the SDK as a generic\n // APIUserAbortError (\"Request was aborted.\") — replace it with a\n // message that actually explains what happened.\n const errorMessage = timedOut\n ? `Model request produced no stream events within ${FIRST_STREAM_EVENT_TIMEOUT_MS / 1000}s; the connection appears wedged.`\n : (err?.message ?? String(err));\n // Anthropic SDK APIConnectionError defaults to \"Connection error.\" with\n // no HTTP status. Tag it so in-run retries and run-level resume treat\n // the failure as a transient network interruption.\n const isConnectionError =\n !timedOut &&\n statusCode === undefined &&\n String(errorMessage).trim().toLowerCase() === \"connection error.\";\n if (statusCode === 401) {\n await recordProviderCredentialAuthFailure({\n key: \"ANTHROPIC_API_KEY\",\n value: this.apiKey,\n status: statusCode,\n code: \"http_401\",\n message: errorMessage,\n });\n }\n yield {\n type: \"stop\",\n reason: \"error\",\n error: errorMessage,\n // Forward the provider HTTP status for EVERY known status, not just\n // 401. The Anthropic SDK reports empty-body failures as a bare\n // \"429 status code (no body)\" message, so without a structured\n // statusCode/errorCode `isRetryableError` couldn't classify a rate\n // limit (it matches \"529\"/\"502\" substrings but not \"429\") and the\n // run failed hard instead of backing off + retrying like the Builder\n // gateway path does. `http_429`/`http_529` also let the run-level\n // continuation logic auto-resume a rate-limited turn.\n ...(statusCode !== undefined\n ? { errorCode: `http_${statusCode}`, statusCode }\n : isConnectionError || timedOut\n ? {\n errorCode: \"provider_network_error\",\n providerRetryable: true,\n }\n : {}),\n };\n throw err;\n } finally {\n firstEventAbort.cleanup();\n }\n }\n}\n\n/**\n * Create an AnthropicEngine instance.\n * Falls back to the deployment Anthropic key if no key is provided.\n */\nexport function createAnthropicEngine(\n config: Record<string, unknown> = {},\n): AgentEngine {\n const allowEnvFallback = config.allowEnvFallback !== false;\n const apiKey =\n (config.apiKey as string | undefined) ??\n (allowEnvFallback ? readDeployCredentialEnv(\"ANTHROPIC_API_KEY\") : \"\") ??\n \"\";\n if (!apiKey) {\n // Return a \"missing key\" engine that immediately errors\n return {\n name: \"anthropic\",\n label: \"Claude (Anthropic SDK)\",\n defaultModel: ANTHROPIC_DEFAULT_MODEL,\n supportedModels: ANTHROPIC_SUPPORTED_MODELS,\n capabilities: ANTHROPIC_CAPABILITIES,\n async *stream() {\n yield {\n type: \"stop\" as const,\n reason: \"error\" as const,\n error: LLM_MISSING_CREDENTIALS_MESSAGE,\n errorCode: LLM_MISSING_CREDENTIALS_ERROR_CODE,\n };\n },\n };\n }\n return new AnthropicEngine(apiKey);\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builder-engine.d.ts","sourceRoot":"","sources":["../../../src/agent/engine/builder-engine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;
|
|
1
|
+
{"version":3,"file":"builder-engine.d.ts","sourceRoot":"","sources":["../../../src/agent/engine/builder-engine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AA0BH,OAAO,KAAK,EACV,WAAW,EACX,kBAAkB,EAInB,MAAM,YAAY,CAAC;AAEpB,eAAO,MAAM,oBAAoB,EAAE,kBAMlC,CAAC;AAEF,eAAO,MAAM,wBAAwB,kLAAuC,CAAC;AAkB7E,eAAO,MAAM,qBAAqB,yCAAoC,CAAC;AA0vBvE,wBAAgB,mBAAmB,CACjC,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GACpC,WAAW,CAEb"}
|
|
@@ -19,6 +19,7 @@ import { isInBackgroundFunctionRuntime } from "../durable-background.js";
|
|
|
19
19
|
import { BUILDER_MODEL_CONFIG } from "../model-config.js";
|
|
20
20
|
import { getBuilderGatewayRequestHeaders } from "./builder-gateway-headers.js";
|
|
21
21
|
import { LLM_MISSING_CREDENTIALS_ERROR_CODE, LLM_MISSING_CREDENTIALS_MESSAGE, } from "./credential-errors.js";
|
|
22
|
+
import { FIRST_STREAM_EVENT_TIMEOUT_MS } from "./first-event-timeout.js";
|
|
22
23
|
import { resolveMaxOutputTokensForEngine } from "./output-tokens.js";
|
|
23
24
|
import { engineMessagesToBuilderGatewayAnthropic, engineToolsToAnthropic, } from "./translate-anthropic.js";
|
|
24
25
|
export const BUILDER_CAPABILITIES = {
|
|
@@ -207,12 +208,12 @@ class BuilderEngine {
|
|
|
207
208
|
phase: "request",
|
|
208
209
|
model: opts.model,
|
|
209
210
|
gatewayUrl,
|
|
210
|
-
timeoutMs:
|
|
211
|
+
timeoutMs: gatewayAbort.effectiveTimeoutMs(),
|
|
211
212
|
timedOut,
|
|
212
213
|
elapsedMs: Date.now() - tStart,
|
|
213
214
|
});
|
|
214
215
|
}
|
|
215
|
-
yield createBuilderGatewayTimeoutStop(err, timedOut,
|
|
216
|
+
yield createBuilderGatewayTimeoutStop(err, timedOut, gatewayAbort.effectiveTimeoutMs());
|
|
216
217
|
return;
|
|
217
218
|
}
|
|
218
219
|
console.log(`[builder-engine] ← ${response.status} ${response.statusText} in ${Date.now() - tStart}ms`);
|
|
@@ -259,7 +260,8 @@ class BuilderEngine {
|
|
|
259
260
|
yield* parseJsonlStream(reader, opts.model, {
|
|
260
261
|
abortSignal: gatewayAbort.signal,
|
|
261
262
|
didGatewayTimeout: gatewayAbort.didTimeout,
|
|
262
|
-
|
|
263
|
+
getGatewayTimeoutMs: gatewayAbort.effectiveTimeoutMs,
|
|
264
|
+
onFirstEvent: gatewayAbort.markFirstEvent,
|
|
263
265
|
gatewayUrl,
|
|
264
266
|
requestStartedAt: tStart,
|
|
265
267
|
});
|
|
@@ -396,7 +398,6 @@ async function* readJsonlLines(reader, abortSignal) {
|
|
|
396
398
|
yield tail;
|
|
397
399
|
}
|
|
398
400
|
async function* parseJsonlStream(reader, model, captureContext = {}) {
|
|
399
|
-
const gatewayTimeoutMs = captureContext.gatewayTimeoutMs ?? DEFAULT_BUILDER_GATEWAY_TIMEOUT_MS;
|
|
400
401
|
const parts = [];
|
|
401
402
|
let pendingText = "";
|
|
402
403
|
let pendingThinking = null;
|
|
@@ -438,6 +439,11 @@ async function* parseJsonlStream(reader, model, captureContext = {}) {
|
|
|
438
439
|
};
|
|
439
440
|
return;
|
|
440
441
|
}
|
|
442
|
+
// Heartbeats are transport-level keepalives, not proof the model is
|
|
443
|
+
// producing output — every other parsed event counts as first progress.
|
|
444
|
+
if (event?.type !== "heartbeat") {
|
|
445
|
+
captureContext.onFirstEvent?.();
|
|
446
|
+
}
|
|
441
447
|
switch (event.type) {
|
|
442
448
|
case "text-delta": {
|
|
443
449
|
const text = event.text ?? "";
|
|
@@ -623,6 +629,8 @@ async function* parseJsonlStream(reader, model, captureContext = {}) {
|
|
|
623
629
|
}
|
|
624
630
|
catch (err) {
|
|
625
631
|
const timedOut = captureContext.didGatewayTimeout?.() ?? false;
|
|
632
|
+
const gatewayTimeoutMs = captureContext.getGatewayTimeoutMs?.() ??
|
|
633
|
+
DEFAULT_BUILDER_GATEWAY_TIMEOUT_MS;
|
|
626
634
|
if (timedOut || isBuilderGatewayNetworkError(err)) {
|
|
627
635
|
captureBuilderGatewayTransportError(err, {
|
|
628
636
|
phase: "stream",
|
|
@@ -748,26 +756,51 @@ function getBuilderGatewayTimeoutMs() {
|
|
|
748
756
|
}
|
|
749
757
|
return Math.min(parsed, maxMs);
|
|
750
758
|
}
|
|
751
|
-
|
|
759
|
+
/**
|
|
760
|
+
* Two-stage abort deadline: until the first real stream event arrives, the
|
|
761
|
+
* effective deadline is min(totalTimeoutMs, FIRST_STREAM_EVENT_TIMEOUT_MS) —
|
|
762
|
+
* a wedged gateway that never streams anything gets cut off in ~2 minutes
|
|
763
|
+
* instead of riding the full flat timeout. Once `markFirstEvent()` fires, the
|
|
764
|
+
* timer reschedules for whatever remains of the original total deadline, so
|
|
765
|
+
* a request that starts streaming still gets the full budget it always did.
|
|
766
|
+
*/
|
|
767
|
+
function createGatewayAbortSignal(parentSignal, totalTimeoutMs) {
|
|
752
768
|
const controller = new AbortController();
|
|
753
769
|
let timedOut = false;
|
|
770
|
+
let firstEventSeen = false;
|
|
771
|
+
const startedAt = Date.now();
|
|
754
772
|
const abortFromParent = () => {
|
|
755
773
|
if (!controller.signal.aborted) {
|
|
756
774
|
controller.abort(parentSignal.reason);
|
|
757
775
|
}
|
|
758
776
|
};
|
|
759
|
-
const
|
|
777
|
+
const fireTimeout = () => {
|
|
760
778
|
timedOut = true;
|
|
761
779
|
if (!controller.signal.aborted) {
|
|
762
780
|
controller.abort(new Error("Builder gateway request timed out"));
|
|
763
781
|
}
|
|
764
|
-
}
|
|
782
|
+
};
|
|
783
|
+
const firstEventDeadlineMs = Math.min(totalTimeoutMs, FIRST_STREAM_EVENT_TIMEOUT_MS);
|
|
784
|
+
let timeout = setTimeout(fireTimeout, firstEventDeadlineMs);
|
|
765
785
|
if (parentSignal.aborted)
|
|
766
786
|
abortFromParent();
|
|
767
787
|
parentSignal.addEventListener("abort", abortFromParent, { once: true });
|
|
768
788
|
return {
|
|
769
789
|
signal: controller.signal,
|
|
770
790
|
didTimeout: () => timedOut,
|
|
791
|
+
effectiveTimeoutMs: () => firstEventSeen ? totalTimeoutMs : firstEventDeadlineMs,
|
|
792
|
+
markFirstEvent: () => {
|
|
793
|
+
if (firstEventSeen || timedOut)
|
|
794
|
+
return;
|
|
795
|
+
firstEventSeen = true;
|
|
796
|
+
// The first-event window was already the binding constraint (total
|
|
797
|
+
// timeout <= it) — nothing to reschedule.
|
|
798
|
+
if (firstEventDeadlineMs >= totalTimeoutMs)
|
|
799
|
+
return;
|
|
800
|
+
clearTimeout(timeout);
|
|
801
|
+
const remainingMs = Math.max(0, totalTimeoutMs - (Date.now() - startedAt));
|
|
802
|
+
timeout = setTimeout(fireTimeout, remainingMs);
|
|
803
|
+
},
|
|
771
804
|
cleanup: () => {
|
|
772
805
|
clearTimeout(timeout);
|
|
773
806
|
parentSignal.removeEventListener("abort", abortFromParent);
|