From ecf92a2f78be58f54d5325692b47ce7ce035e7da Mon Sep 17 00:00:00 2001 From: siddseethepalli Date: Sat, 18 Apr 2026 22:53:52 +0000 Subject: [PATCH] fix(llm-callsite): wrap remaining subagent generators + sync self-info fallback model --- assistant/src/daemon/approval-generators.ts | 29 +++++++++++++++-- .../src/daemon/guardian-action-generators.ts | 32 ++++++++++++++++--- .../scripts/self-info.ts | 2 +- 3 files changed, 55 insertions(+), 8 deletions(-) diff --git a/assistant/src/daemon/approval-generators.ts b/assistant/src/daemon/approval-generators.ts index 95ee00601db..46dc9a7d247 100644 --- a/assistant/src/daemon/approval-generators.ts +++ b/assistant/src/daemon/approval-generators.ts @@ -1,5 +1,7 @@ import { loadConfig } from "../config/loader.js"; +import { CallSiteRoutingProvider } from "../providers/call-site-routing.js"; import { getProvider, listProviders } from "../providers/registry.js"; +import type { Provider } from "../providers/types.js"; import { APPROVAL_COPY_MAX_TOKENS, APPROVAL_COPY_SYSTEM_PROMPT, @@ -89,12 +91,15 @@ const VALID_DISPOSITIONS: ReadonlySet = new Set([ export function createApprovalCopyGenerator(): ApprovalCopyGenerator { return async (context, options = {}) => { const config = loadConfig(); - let provider; + let baseProvider: Provider; try { - provider = getProvider(config.llm.default.provider); + baseProvider = getProvider(config.llm.default.provider); } catch { return null; } + // Wrap so per-call `callSite` can route to an alternative provider + // transport when `llm.callSites..provider` overrides the default. + const provider = wrapWithCallSiteRouting(baseProvider); const fallbackText = options.fallbackText?.trim() || getFallbackMessage(context); @@ -145,7 +150,9 @@ export function createApprovalConversationGenerator(): ApprovalConversationGener if (!listProviders().includes(config.llm.default.provider)) { throw new Error("No provider available for approval conversation"); } - const provider = getProvider(config.llm.default.provider); + const provider = wrapWithCallSiteRouting( + getProvider(config.llm.default.provider), + ); const pendingDescription = context.pendingApprovals .map((p) => `- Request ${p.requestId}: tool "${p.toolName}"`) @@ -215,3 +222,19 @@ export function createApprovalConversationGenerator(): ApprovalConversationGener return result; }; } + +/** + * Wrap a base Provider so per-call `callSite` metadata can route the actual + * transport to a different provider when `llm.callSites..provider` + * differs from the default. Without this wrapper, only request metadata + * reflects the callSite — the HTTP transport stays bound to the default. + */ +function wrapWithCallSiteRouting(base: Provider): Provider { + return new CallSiteRoutingProvider(base, (name) => { + try { + return getProvider(name); + } catch { + return undefined; + } + }); +} diff --git a/assistant/src/daemon/guardian-action-generators.ts b/assistant/src/daemon/guardian-action-generators.ts index aa25ab71b09..0a484a2cc97 100644 --- a/assistant/src/daemon/guardian-action-generators.ts +++ b/assistant/src/daemon/guardian-action-generators.ts @@ -1,4 +1,7 @@ +import { CallSiteRoutingProvider } from "../providers/call-site-routing.js"; import { getConfiguredProvider } from "../providers/provider-send-message.js"; +import { getProvider } from "../providers/registry.js"; +import type { Provider } from "../providers/types.js"; import { buildGuardianActionGenerationPrompt, getGuardianActionFallbackMessage, @@ -25,8 +28,12 @@ import type { */ export function createGuardianActionCopyGenerator(): GuardianActionCopyGenerator { return async (context, options = {}) => { - const provider = await getConfiguredProvider("guardianQuestionCopy"); - if (!provider) return null; + const baseProvider = await getConfiguredProvider("guardianQuestionCopy"); + if (!baseProvider) return null; + // Wrap so the per-call `callSite` can route to a different provider + // transport when `llm.callSites.guardianQuestionCopy.provider` overrides + // the default. Without this, callSite only affects request metadata. + const provider = wrapWithCallSiteRouting(baseProvider); const fallbackText = options.fallbackText?.trim() || getGuardianActionFallbackMessage(context); @@ -124,10 +131,11 @@ const VALID_FOLLOWUP_DISPOSITIONS: ReadonlySet = new Set([ */ export function createGuardianFollowUpConversationGenerator(): GuardianFollowUpConversationGenerator { return async (context) => { - const provider = await getConfiguredProvider("guardianQuestionCopy"); - if (!provider) { + const baseProvider = await getConfiguredProvider("guardianQuestionCopy"); + if (!baseProvider) { throw new Error("No configured provider available for follow-up conversation"); } + const provider = wrapWithCallSiteRouting(baseProvider); const userPrompt = [ `Original question from the voice call: "${context.questionText}"`, @@ -184,3 +192,19 @@ export function createGuardianFollowUpConversationGenerator(): GuardianFollowUpC return result; }; } + +/** + * Wrap a base Provider so per-call `callSite` metadata can route the actual + * transport to a different provider when `llm.callSites..provider` + * differs from the default. Without this wrapper, only request metadata + * reflects the callSite — the HTTP transport stays bound to the default. + */ +function wrapWithCallSiteRouting(base: Provider): Provider { + return new CallSiteRoutingProvider(base, (name) => { + try { + return getProvider(name); + } catch { + return undefined; + } + }); +} diff --git a/skills/vellum-self-knowledge/scripts/self-info.ts b/skills/vellum-self-knowledge/scripts/self-info.ts index 556644e0b09..156d7d56f04 100644 --- a/skills/vellum-self-knowledge/scripts/self-info.ts +++ b/skills/vellum-self-knowledge/scripts/self-info.ts @@ -106,7 +106,7 @@ async function main(): Promise { let config: { model?: string; provider?: string; mode?: string }; if (raw === "(not set)" || raw === "") { config = { - model: "claude-opus-4-6", + model: "claude-opus-4-7", provider: "anthropic", mode: "your-own", };