| import { sanitizeForLog } from "../../../packages/terminal-core/src/ansi.js"; |
| import { |
| formatThinkingLevels, |
| isThinkingLevelSupported, |
| normalizeThinkLevel, |
| type ThinkLevel, |
| } from "../../auto-reply/thinking.js"; |
| import { resolveChannelModelOverride } from "../../channels/model-overrides.js"; |
| import { hasSessionAutoModelSelection } from "../../config/sessions/model-override-provenance.js"; |
| import type { InternalSessionEntry as SessionEntry } from "../../config/sessions/types.js"; |
| import type { OpenClawConfig } from "../../config/types.openclaw.js"; |
| import type { PluginMetadataSnapshot } from "../../plugins/plugin-metadata-snapshot.types.js"; |
| import { requireActivePluginRegistry } from "../../plugins/runtime.js"; |
| import { isSubagentSessionKey } from "../../routing/session-key.js"; |
| import { isValidAgentHarnessSessionStoreEntry } from "../../sessions/agent-harness-session-key.js"; |
| import { shouldPreserveUnavailableSessionAuthProfileOverride } from "../../sessions/auth-profile-preservation.js"; |
| import { |
| applyModelOverrideToSessionEntry, |
| ModelSelectionLockedError, |
| isModelSelectionLocked, |
| repairProviderWrappedModelOverride, |
| } from "../../sessions/model-overrides.js"; |
| import { resolveStoredModelOverride } from "../../sessions/stored-model-overrides.js"; |
| import { |
| sessionDeliveryChannel, |
| sessionDeliveryOrigin, |
| } from "../../utils/delivery-context.shared.js"; |
| import { isDeliverableMessageChannel } from "../../utils/message-channel.js"; |
| import { |
| clearAutoFallbackPrimaryProbeSelection, |
| hasLegacyAutoFallbackWithoutOrigin, |
| hasSessionAutoModelFallbackProvenance, |
| resolveAutoFallbackPrimaryProbe, |
| resolveAgentConfig, |
| resolveAgentDir, |
| resolveAgentEffectiveModelPrimary, |
| } from "../agent-scope.js"; |
| import { isStoredCredentialCompatibleWithAuthProvider } from "../auth-profiles/order.js"; |
| import { clearSessionAuthProfileOverride } from "../auth-profiles/session-override.js"; |
| import { ensureAuthProfileStore } from "../auth-profiles/store-runtime.js"; |
| import { ensureSelectedAgentHarnessPlugin } from "../harness/runtime-plugin.js"; |
| import { resolveAvailableAgentHarnessPolicy } from "../harness/selection.js"; |
| import { resolveModelProviderAuthConfig } from "../model-auth-provider-route.js"; |
| import { loadManifestModelCatalog } from "../model-catalog.js"; |
| import type { ModelFallbackRouteResolution } from "../model-fallback.types.js"; |
| import { splitTrailingAuthProfile } from "../model-ref-profile.js"; |
| import type { ModelManifestNormalizationContext } from "../model-ref-shared.js"; |
| import { |
| modelKey, |
| resolveDefaultModelForAgent, |
| resolveModelAliasFromPair, |
| resolveThinkingDefault, |
| } from "../model-selection.js"; |
| import { resolveConfiguredThinkingDefault } from "../model-thinking-default.js"; |
| import { |
| createModelVisibilityPolicy, |
| type ModelVisibilityPolicy, |
| } from "../model-visibility-policy.js"; |
| import { listOpenAIAuthProfileProvidersForAgentRuntime } from "../openai-routing.js"; |
| import { resolveProviderIdForAuth } from "../provider-auth-aliases.js"; |
| import { resolveSessionRuntimeOverrideForProvider } from "../session-runtime-compat.js"; |
| import { |
| hasResolvedThinkingCatalogEntry, |
| normalizeThinkingCatalogProviders, |
| resolveEffectiveAgentRuntime, |
| } from "../thinking-runtime.js"; |
| import { persistAgentSession } from "./attempt-execution.shared.js"; |
| import { |
| normalizeAgentCommandDefaultModelRef, |
| normalizeAgentCommandModelRef, |
| parseAgentCommandModelRef, |
| } from "./model-ref.js"; |
| import { normalizeExplicitOverrideInput } from "./prepare.js"; |
| import type { resolveAgentRunContext } from "./run-context.js"; |
| import { loadTranscriptResolveRuntime } from "./runtime-loaders.js"; |
| import type { AgentCommandOpts } from "./types.js"; |
|
|
| type AgentRunContext = ReturnType<typeof resolveAgentRunContext>; |
|
|
| export async function resolveEmbeddedModelSelection(params: { |
| cfg: OpenClawConfig; |
| opts: AgentCommandOpts; |
| sessionEntry?: SessionEntry; |
| sessionStore?: Record<string, SessionEntry>; |
| sessionKey?: string; |
| sessionId: string; |
| storePath: string; |
| sessionAgentId: string; |
| workspaceDir: string; |
| pluginsEnabled: boolean; |
| manifestMetadataSnapshot?: PluginMetadataSnapshot; |
| modelManifestContext: ModelManifestNormalizationContext; |
| configuredThinkingCatalog: ReturnType<typeof loadManifestModelCatalog>; |
| requestedThinkLevel?: ThinkLevel; |
| thinkOverride?: ThinkLevel; |
| thinkOnce?: ThinkLevel; |
| isSubagentLane: boolean; |
| suppressVisibleSessionEffects: boolean; |
| runContext: AgentRunContext; |
| }) { |
| const configuredDefaultRef = resolveDefaultModelForAgent({ |
| cfg: params.cfg, |
| agentId: params.sessionAgentId, |
| allowPluginNormalization: params.pluginsEnabled, |
| ...params.modelManifestContext, |
| }); |
| const configuredDefaultAuthProfileId = splitTrailingAuthProfile( |
| resolveAgentEffectiveModelPrimary(params.cfg, params.sessionAgentId) ?? "", |
| ).profile; |
| const { provider: defaultProvider, model: defaultModel } = normalizeAgentCommandDefaultModelRef( |
| params.cfg, |
| configuredDefaultRef.provider, |
| configuredDefaultRef.model, |
| params.modelManifestContext, |
| ); |
| let provider = defaultProvider; |
| let model = defaultModel; |
| let requestedRouteResolution: ModelFallbackRouteResolution = "resolved"; |
| let sessionEntry = params.sessionEntry; |
| const initialModelOverrideSource = sessionEntry?.modelOverrideSource; |
| const hasStoredOverride = Boolean( |
| initialModelOverrideSource !== "default" && |
| (sessionEntry?.modelOverride || sessionEntry?.providerOverride), |
| ); |
| let storedModelOverrideSource = |
| hasStoredOverride && initialModelOverrideSource !== "default" |
| ? initialModelOverrideSource |
| : undefined; |
| let hasStoredAutoFallbackProvenance = |
| hasStoredOverride && hasSessionAutoModelFallbackProvenance(sessionEntry); |
| let hasLegacyAutoFallbackOverrideWithoutOrigin = |
| hasStoredOverride && hasLegacyAutoFallbackWithoutOrigin(sessionEntry); |
| const explicitProviderOverride = |
| typeof params.opts.provider === "string" |
| ? normalizeExplicitOverrideInput(params.opts.provider, "provider") |
| : undefined; |
| const explicitModelOverride = |
| typeof params.opts.model === "string" |
| ? normalizeExplicitOverrideInput(params.opts.model, "model") |
| : undefined; |
| const hasExplicitRunOverride = Boolean(explicitProviderOverride || explicitModelOverride); |
| if (hasExplicitRunOverride && isModelSelectionLocked(sessionEntry)) { |
| throw new ModelSelectionLockedError(); |
| } |
| if (hasExplicitRunOverride && params.opts.allowModelOverride !== true) { |
| throw new Error("Model override is not authorized for this caller."); |
| } |
|
|
| let allowedModelCatalog: ReturnType<typeof loadManifestModelCatalog> = []; |
| let modelCatalog: ReturnType<typeof loadManifestModelCatalog> | null = null; |
| let visibilityPolicy: ModelVisibilityPolicy = createModelVisibilityPolicy({ |
| cfg: params.cfg, |
| catalog: [], |
| defaultProvider, |
| defaultModel, |
| agentId: params.sessionAgentId, |
| allowManifestNormalization: true, |
| allowPluginNormalization: params.pluginsEnabled, |
| ...params.modelManifestContext, |
| }); |
| const hasAllowlist = !visibilityPolicy.allowAny; |
| const agentModels = resolveAgentConfig(params.cfg, params.sessionAgentId)?.models; |
| const hasConfiguredModels = |
| Object.keys(params.cfg.agents?.defaults?.models ?? {}).length > 0 || |
| Object.keys(agentModels ?? {}).length > 0; |
| if (hasAllowlist || hasConfiguredModels) { |
| modelCatalog = params.pluginsEnabled |
| ? loadManifestModelCatalog({ |
| config: params.cfg, |
| workspaceDir: params.workspaceDir, |
| metadataSnapshot: params.manifestMetadataSnapshot, |
| }) |
| : []; |
| visibilityPolicy = createModelVisibilityPolicy({ |
| cfg: params.cfg, |
| catalog: modelCatalog, |
| defaultProvider, |
| defaultModel, |
| agentId: params.sessionAgentId, |
| allowManifestNormalization: true, |
| allowPluginNormalization: params.pluginsEnabled, |
| ...params.modelManifestContext, |
| }); |
| allowedModelCatalog = visibilityPolicy.allowedCatalog; |
| } |
|
|
| if ( |
| !isModelSelectionLocked(sessionEntry) && |
| sessionEntry && |
| params.sessionStore && |
| params.sessionKey && |
| hasStoredOverride && |
| !isValidAgentHarnessSessionStoreEntry(params.sessionKey, sessionEntry) && |
| !params.suppressVisibleSessionEffects |
| ) { |
| |
| |
| const initialEntry = sessionEntry; |
| const entry = { ...sessionEntry }; |
| let entryUpdated = false; |
| if (hasLegacyAutoFallbackOverrideWithoutOrigin) { |
| const { updated } = applyModelOverrideToSessionEntry({ |
| entry, |
| selection: { provider: defaultProvider, model: defaultModel, isDefault: true }, |
| }); |
| if (updated) { |
| storedModelOverrideSource = undefined; |
| entryUpdated = true; |
| } |
| } |
| const repaired = repairProviderWrappedModelOverride({ entry, defaultProvider, defaultModel }); |
| entryUpdated ||= repaired.updated; |
| const overrideProvider = entry.providerOverride?.trim() || defaultProvider; |
| const overrideModel = entry.modelOverride?.trim(); |
| if (overrideModel) { |
| const normalizedOverride = normalizeAgentCommandModelRef( |
| params.cfg, |
| overrideProvider, |
| overrideModel, |
| params.modelManifestContext, |
| ); |
| if (!hasSessionAutoModelSelection(entry) && !visibilityPolicy.allows(normalizedOverride)) { |
| const { updated } = applyModelOverrideToSessionEntry({ |
| entry, |
| selection: { provider: defaultProvider, model: defaultModel, isDefault: true }, |
| }); |
| entryUpdated ||= updated; |
| } |
| } |
| if (entryUpdated) { |
| sessionEntry = await persistAgentSession({ |
| sessionStore: params.sessionStore, |
| sessionKey: params.sessionKey, |
| storePath: params.storePath, |
| initialEntry, |
| entry, |
| }); |
| const adoptedModelOverrideSource = sessionEntry?.modelOverrideSource; |
| const adoptedHasStoredOverride = Boolean( |
| adoptedModelOverrideSource !== "default" && |
| (sessionEntry?.modelOverride || sessionEntry?.providerOverride), |
| ); |
| storedModelOverrideSource = adoptedHasStoredOverride |
| ? adoptedModelOverrideSource === "default" |
| ? undefined |
| : adoptedModelOverrideSource |
| : undefined; |
| hasStoredAutoFallbackProvenance = |
| adoptedHasStoredOverride && hasSessionAutoModelFallbackProvenance(sessionEntry); |
| hasLegacyAutoFallbackOverrideWithoutOrigin = |
| adoptedHasStoredOverride && hasLegacyAutoFallbackWithoutOrigin(sessionEntry); |
| } |
| } |
|
|
| if (isModelSelectionLocked(sessionEntry)) { |
| hasLegacyAutoFallbackOverrideWithoutOrigin = false; |
| } |
|
|
| const effectiveStoredOverride = hasLegacyAutoFallbackOverrideWithoutOrigin |
| ? null |
| : resolveStoredModelOverride({ |
| sessionEntry, |
| sessionStore: params.sessionStore, |
| sessionKey: params.sessionKey, |
| parentSessionKey: sessionEntry?.parentSessionKey, |
| defaultProvider, |
| }); |
| if (effectiveStoredOverride?.source === "parent") { |
| storedModelOverrideSource = undefined; |
| hasStoredAutoFallbackProvenance = false; |
| } |
| const canUseStoredOverrideFields = sessionEntry?.modelOverrideSource !== "default"; |
| const storedProviderOverride = hasLegacyAutoFallbackOverrideWithoutOrigin |
| ? undefined |
| : (effectiveStoredOverride?.provider ?? |
| (canUseStoredOverrideFields ? sessionEntry?.providerOverride?.trim() : undefined)); |
| const storedModelOverride = hasLegacyAutoFallbackOverrideWithoutOrigin |
| ? undefined |
| : (effectiveStoredOverride?.model ?? |
| (canUseStoredOverrideFields ? sessionEntry?.modelOverride?.trim() : undefined)); |
| const storedModelOverrideRouteResolution = effectiveStoredOverride?.routeResolution; |
| const hasStoredAutomaticSelection = |
| effectiveStoredOverride?.source === "session" && hasSessionAutoModelSelection(sessionEntry); |
| const currentRunModelChannel = [ |
| params.runContext.messageChannel, |
| params.opts.replyChannel, |
| params.opts.channel, |
| ].find((channel): channel is string => Boolean(channel && isDeliverableMessageChannel(channel))); |
| const channelOverrideGroupId = currentRunModelChannel |
| ? (params.runContext.groupId ?? sessionEntry?.groupId ?? params.runContext.currentChannelId) |
| : (sessionEntry?.groupId ?? params.runContext.groupId ?? params.runContext.currentChannelId); |
| const channelModelOverride = |
| params.cfg.channels?.modelByChannel && !hasExplicitRunOverride |
| ? resolveChannelModelOverride({ |
| cfg: params.cfg, |
| channel: currentRunModelChannel ?? sessionDeliveryChannel(sessionEntry), |
| groupId: channelOverrideGroupId, |
| groupChatType: sessionEntry?.chatType ?? sessionDeliveryOrigin(sessionEntry)?.chatType, |
| groupChannel: params.runContext.groupChannel ?? sessionEntry?.groupChannel, |
| groupSubject: sessionEntry?.subject, |
| parentSessionKey: sessionEntry?.parentSessionKey ?? params.sessionKey, |
| directUserIds: [ |
| sessionDeliveryOrigin(sessionEntry)?.nativeDirectUserId, |
| sessionDeliveryOrigin(sessionEntry)?.from, |
| sessionDeliveryOrigin(sessionEntry)?.to, |
| ], |
| }) |
| : null; |
| const normalizedChannelOverride = channelModelOverride |
| ? parseAgentCommandModelRef( |
| params.cfg, |
| params.sessionAgentId, |
| channelModelOverride.model, |
| defaultProvider, |
| params.modelManifestContext, |
| ) |
| : null; |
| const primaryProvider = normalizedChannelOverride?.provider ?? defaultProvider; |
| const primaryModel = normalizedChannelOverride?.model ?? defaultModel; |
| const hasEffectiveStoredOverride = Boolean(storedProviderOverride || storedModelOverride); |
| if (normalizedChannelOverride && !hasEffectiveStoredOverride) { |
| provider = normalizedChannelOverride.provider; |
| model = normalizedChannelOverride.model; |
| requestedRouteResolution = "resolved"; |
| } |
| if (storedModelOverride) { |
| const candidateProvider = storedProviderOverride || defaultProvider; |
| const storedRouteKey = modelKey(candidateProvider, storedModelOverride); |
| const storedRouteCataloged = (modelCatalog ?? allowedModelCatalog).some( |
| (entry) => modelKey(entry.provider, entry.id) === storedRouteKey, |
| ); |
| const storedAlias = |
| storedModelOverrideRouteResolution === "raw" && !storedRouteCataloged |
| ? resolveModelAliasFromPair({ |
| cfg: params.cfg, |
| agentId: params.sessionAgentId, |
| provider: candidateProvider, |
| model: storedModelOverride, |
| defaultProvider, |
| aliasIndex: visibilityPolicy.selectionAliasIndex, |
| allowPluginNormalization: params.pluginsEnabled, |
| ...params.modelManifestContext, |
| }) |
| : null; |
| const normalizedStored = normalizeAgentCommandModelRef( |
| params.cfg, |
| storedAlias?.provider ?? candidateProvider, |
| storedAlias?.model ?? storedModelOverride, |
| params.modelManifestContext, |
| ); |
| if ( |
| isModelSelectionLocked(sessionEntry) || |
| hasStoredAutomaticSelection || |
| visibilityPolicy.allows(normalizedStored) |
| ) { |
| provider = normalizedStored.provider; |
| model = normalizedStored.model; |
| requestedRouteResolution = |
| storedAlias || storedRouteCataloged |
| ? "resolved" |
| : (storedModelOverrideRouteResolution ?? "raw"); |
| } |
| } |
| const autoFallbackPrimaryProbe = |
| !hasExplicitRunOverride && !isModelSelectionLocked(sessionEntry) |
| ? resolveAutoFallbackPrimaryProbe({ |
| entry: sessionEntry, |
| sessionKey: params.sessionKey, |
| primaryProvider, |
| primaryModel, |
| }) |
| : undefined; |
| let autoFallbackPrimaryProbeSessionEntry: SessionEntry | undefined; |
| if (autoFallbackPrimaryProbe && sessionEntry) { |
| provider = autoFallbackPrimaryProbe.provider; |
| model = autoFallbackPrimaryProbe.model; |
| requestedRouteResolution = "resolved"; |
| autoFallbackPrimaryProbeSessionEntry = { ...sessionEntry }; |
| clearAutoFallbackPrimaryProbeSelection(autoFallbackPrimaryProbeSessionEntry); |
| } |
|
|
| if (hasExplicitRunOverride) { |
| const explicitRef = explicitModelOverride |
| ? explicitProviderOverride |
| ? normalizeAgentCommandModelRef( |
| params.cfg, |
| explicitProviderOverride, |
| explicitModelOverride, |
| params.modelManifestContext, |
| ) |
| : parseAgentCommandModelRef( |
| params.cfg, |
| params.sessionAgentId, |
| explicitModelOverride, |
| provider, |
| params.modelManifestContext, |
| ) |
| : explicitProviderOverride |
| ? normalizeAgentCommandModelRef( |
| params.cfg, |
| explicitProviderOverride, |
| model, |
| params.modelManifestContext, |
| ) |
| : null; |
| if (!explicitRef) { |
| throw new Error("Invalid model override."); |
| } |
| if (!visibilityPolicy.allows(explicitRef)) { |
| const rejectedKey = `${sanitizeForLog(explicitRef.provider)}/${sanitizeForLog(explicitRef.model)}`; |
| const policyPath = visibilityPolicy.allowConfigPath ?? "modelPolicy.allow"; |
| const repairPath = visibilityPolicy.allowRepairConfigPath; |
| throw new Error( |
| `Model override "${rejectedKey}" is not allowed for agent "${params.sessionAgentId}" by ${policyPath}. Add "${rejectedKey}" or "${sanitizeForLog(explicitRef.provider)}/*" to ${repairPath}, or remove/empty the list to allow any model.`, |
| ); |
| } |
| provider = explicitRef.provider; |
| model = explicitRef.model; |
| requestedRouteResolution = "resolved"; |
| } |
| const unresolvedSelectionKey = modelKey(provider, model); |
| const allowedInitialSelection = |
| isModelSelectionLocked(sessionEntry) || |
| (hasStoredAutomaticSelection && !hasExplicitRunOverride && !autoFallbackPrimaryProbe) |
| ? { provider, model } |
| : visibilityPolicy.resolveSelection({ provider, model }); |
| if (!allowedInitialSelection) { |
| const policyPath = visibilityPolicy.allowConfigPath ?? "modelPolicy.allow"; |
| throw new Error( |
| `Configured default model "${modelKey(provider, model)}" is not allowed by ${policyPath}, and no allowed model is available.`, |
| ); |
| } |
| provider = allowedInitialSelection.provider; |
| model = allowedInitialSelection.model; |
| if (modelKey(provider, model) !== unresolvedSelectionKey) { |
| requestedRouteResolution = "resolved"; |
| } |
| const providerForAuthProfileValidation = provider; |
| let sessionEntryForAttempt = autoFallbackPrimaryProbeSessionEntry ?? sessionEntry; |
| const initialAgentHarnessRuntimeOverride = resolveSessionRuntimeOverrideForProvider({ |
| provider, |
| entry: sessionEntryForAttempt, |
| cfg: params.cfg, |
| }); |
| await ensureSelectedAgentHarnessPlugin({ |
| config: params.cfg, |
| provider, |
| modelId: model, |
| agentId: params.sessionAgentId, |
| sessionKey: params.sessionKey, |
| agentHarnessRuntimeOverride: initialAgentHarnessRuntimeOverride, |
| workspaceDir: params.workspaceDir, |
| pluginRegistry: requireActivePluginRegistry(), |
| }); |
|
|
| const authProfileId = sessionEntryForAttempt?.authProfileOverride; |
| if (sessionEntryForAttempt && authProfileId) { |
| const entry = sessionEntryForAttempt; |
| const authConfig = resolveModelProviderAuthConfig({ |
| config: params.cfg, |
| provider: providerForAuthProfileValidation, |
| modelId: model, |
| workspaceDir: params.workspaceDir, |
| metadataSnapshot: params.pluginsEnabled ? params.manifestMetadataSnapshot : { plugins: [] }, |
| }); |
| const agentDir = resolveAgentDir(params.cfg, params.sessionAgentId); |
| const store = ensureAuthProfileStore(agentDir, { |
| profileId: authProfileId, |
| config: params.cfg, |
| allowKeychainPrompt: false, |
| }); |
| const profile = store.profiles[authProfileId]; |
| const validationHarnessPolicy = resolveAvailableAgentHarnessPolicy({ |
| provider: providerForAuthProfileValidation, |
| modelId: model, |
| config: params.cfg, |
| agentId: params.sessionAgentId, |
| sessionKey: params.sessionKey, |
| }); |
| const authAliasLookupParams = params.pluginsEnabled |
| ? { |
| config: authConfig, |
| workspaceDir: params.workspaceDir, |
| ...(params.manifestMetadataSnapshot |
| ? { metadataSnapshot: params.manifestMetadataSnapshot } |
| : {}), |
| } |
| : { |
| config: authConfig, |
| workspaceDir: params.workspaceDir, |
| metadataSnapshot: { plugins: [] }, |
| }; |
| const acceptedAuthProviders = listOpenAIAuthProfileProvidersForAgentRuntime({ |
| provider: providerForAuthProfileValidation, |
| harnessRuntime: validationHarnessPolicy.runtime, |
| config: params.cfg, |
| }).map((candidateProvider) => |
| params.pluginsEnabled |
| ? resolveProviderIdForAuth(candidateProvider, authAliasLookupParams) |
| : candidateProvider, |
| ); |
| const profileMatchesRuntime = |
| profile && |
| acceptedAuthProviders.some((candidateProvider) => |
| isStoredCredentialCompatibleWithAuthProvider({ |
| cfg: authConfig, |
| authAliasLookupParams, |
| provider: candidateProvider, |
| credential: profile, |
| }), |
| ); |
| const preserveUnavailableSelection = shouldPreserveUnavailableSessionAuthProfileOverride({ |
| store, |
| cfg: authConfig, |
| agentDir, |
| entry, |
| currentProvider: entry.providerOverride ?? defaultProvider, |
| provider: providerForAuthProfileValidation, |
| metadataSnapshot: params.pluginsEnabled ? params.manifestMetadataSnapshot : { plugins: [] }, |
| }); |
| if (!profileMatchesRuntime && !preserveUnavailableSelection) { |
| if (hasExplicitRunOverride || autoFallbackPrimaryProbe) { |
| sessionEntryForAttempt = { |
| ...entry, |
| authProfileOverride: undefined, |
| authProfileOverrideSource: undefined, |
| authProfileOverrideCompactionCount: undefined, |
| }; |
| } else if ( |
| params.sessionStore && |
| params.sessionKey && |
| !params.suppressVisibleSessionEffects |
| ) { |
| await clearSessionAuthProfileOverride({ |
| sessionEntry: entry, |
| sessionStore: params.sessionStore, |
| sessionKey: params.sessionKey, |
| storePath: params.storePath, |
| }); |
| } |
| } |
| } |
|
|
| const configuredThinkLevel = normalizeThinkLevel( |
| resolveAgentConfig(params.cfg, params.sessionAgentId)?.thinkingDefault, |
| ); |
| const immutableThinkLevel = params.requestedThinkLevel ?? configuredThinkLevel; |
| const primaryConfiguredThinkLevel = |
| immutableThinkLevel ?? |
| resolveConfiguredThinkingDefault({ |
| cfg: params.cfg, |
| provider, |
| model, |
| }); |
| let catalogForThinking = |
| visibilityPolicy.catalog.length > 0 |
| ? visibilityPolicy.catalog |
| : params.configuredThinkingCatalog; |
| if ( |
| params.pluginsEnabled && |
| primaryConfiguredThinkLevel !== "off" && |
| !hasResolvedThinkingCatalogEntry({ catalog: catalogForThinking, provider, model }) |
| ) { |
| |
| const { loadProviderScopedThinkingCatalog } = await import("../model-catalog.runtime.js"); |
| const runtimeCatalog = normalizeThinkingCatalogProviders( |
| await loadProviderScopedThinkingCatalog({ |
| config: params.cfg, |
| provider, |
| model, |
| ...(params.sessionAgentId ? { agentId: params.sessionAgentId } : {}), |
| ...(params.workspaceDir ? { workspaceDir: params.workspaceDir } : {}), |
| }), |
| ); |
| const runtimeThinkingCatalog = createModelVisibilityPolicy({ |
| cfg: params.cfg, |
| catalog: runtimeCatalog, |
| defaultProvider, |
| defaultModel, |
| agentId: params.sessionAgentId, |
| allowManifestNormalization: true, |
| allowPluginNormalization: params.pluginsEnabled, |
| ...params.modelManifestContext, |
| }).catalog; |
| if ( |
| hasResolvedThinkingCatalogEntry({ |
| catalog: runtimeThinkingCatalog, |
| provider, |
| model, |
| }) |
| ) { |
| catalogForThinking = runtimeThinkingCatalog; |
| } |
| } |
| const thinkingCatalog = catalogForThinking.length > 0 ? catalogForThinking : undefined; |
| const thinkingRuntime = resolveEffectiveAgentRuntime({ |
| cfg: params.cfg, |
| provider, |
| modelId: model, |
| agentId: params.sessionAgentId, |
| sessionKey: params.sessionKey, |
| sessionEntry: sessionEntryForAttempt, |
| }); |
| const primaryThinkLevel = |
| primaryConfiguredThinkLevel ?? |
| resolveThinkingDefault({ |
| cfg: params.cfg, |
| provider, |
| model, |
| catalog: thinkingCatalog, |
| agentRuntime: thinkingRuntime, |
| }); |
| if ( |
| !isThinkingLevelSupported({ |
| provider, |
| model, |
| level: primaryThinkLevel, |
| catalog: thinkingCatalog, |
| agentRuntime: thinkingRuntime, |
| }) |
| ) { |
| const explicitThink = Boolean(params.thinkOnce || params.thinkOverride); |
| const isSubagentSpawnRun = params.isSubagentLane && isSubagentSessionKey(params.sessionKey); |
| if (explicitThink && !isSubagentSpawnRun) { |
| throw new Error( |
| `Thinking level "${primaryThinkLevel}" is not supported for ${provider}/${model}. Use one of: ${formatThinkingLevels(provider, model, ", ", thinkingCatalog, thinkingRuntime)}.`, |
| ); |
| } |
| } |
| if ( |
| params.thinkOverride && |
| params.sessionStore && |
| params.sessionKey && |
| !params.suppressVisibleSessionEffects |
| ) { |
| const now = Date.now(); |
| const entry = params.sessionStore[params.sessionKey] ?? |
| sessionEntry ?? { sessionId: params.sessionId, updatedAt: now, sessionStartedAt: now }; |
| const next: SessionEntry = { |
| ...entry, |
| sessionId: params.sessionId, |
| updatedAt: now, |
| sessionStartedAt: entry.sessionStartedAt ?? now, |
| lastInteractionAt: now, |
| thinkingLevel: params.thinkOverride, |
| }; |
| sessionEntry = |
| (await persistAgentSession({ |
| sessionStore: params.sessionStore, |
| sessionKey: params.sessionKey, |
| storePath: params.storePath, |
| initialEntry: entry, |
| entry: next, |
| })) ?? sessionEntry; |
| sessionEntryForAttempt = { |
| ...(sessionEntryForAttempt ?? next), |
| thinkingLevel: params.thinkOverride, |
| }; |
| } |
|
|
| const { resolveSessionTranscriptFile } = await loadTranscriptResolveRuntime(); |
| let sessionFile: string | undefined; |
| if (params.sessionStore && params.sessionKey) { |
| const resolvedSessionFile = await resolveSessionTranscriptFile({ |
| sessionId: params.sessionId, |
| sessionKey: params.sessionKey, |
| sessionStore: params.suppressVisibleSessionEffects ? undefined : params.sessionStore, |
| storePath: params.suppressVisibleSessionEffects ? undefined : params.storePath, |
| sessionEntry, |
| agentId: params.sessionAgentId, |
| threadId: params.opts.threadId, |
| }); |
| sessionFile = resolvedSessionFile.sessionFile; |
| sessionEntry = resolvedSessionFile.sessionEntry; |
| } |
| if (!sessionFile) { |
| const resolvedSessionFile = await resolveSessionTranscriptFile({ |
| sessionId: params.sessionId, |
| sessionKey: params.sessionKey ?? params.sessionId, |
| storePath: params.storePath, |
| sessionEntry, |
| agentId: params.sessionAgentId, |
| threadId: params.opts.threadId, |
| }); |
| sessionFile = resolvedSessionFile.sessionFile; |
| sessionEntry = resolvedSessionFile.sessionEntry; |
| } |
|
|
| return { |
| sessionEntry, |
| provider, |
| model, |
| requestedRouteResolution, |
| defaultProvider, |
| defaultModel, |
| configuredDefaultAuthProfileId, |
| providerForAuthProfileValidation, |
| hasExplicitRunOverride, |
| storedProviderOverride, |
| storedModelOverride, |
| storedModelOverrideSource, |
| hasStoredAutoFallbackProvenance, |
| autoFallbackPrimaryProbe, |
| sessionEntryForAttempt, |
| thinkingCatalog, |
| immutableThinkLevel, |
| effectiveTurnThinkLevel: primaryThinkLevel, |
| sessionFile, |
| }; |
| } |
|
|
| export type EmbeddedModelSelection = Awaited<ReturnType<typeof resolveEmbeddedModelSelection>>; |
|
|