UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

266 lines (265 loc) 10.6 kB
import { u as resolveAgentDir } from "./agent-scope-config-DcbEhP0R.js"; import { t as modelKey } from "./model-key-CMdQNkZf.js"; import { A as resolveCollapsedSessionAuthPinSource } from "./agent-scope-DbtJyKUL.js"; import { c as resolveContextConfigProviderForRuntime } from "./openai-routing-Ex_3E9TF.js"; import { a as enqueueSystemEvent } from "./system-events-C03jsM0j.js"; import { f as emitSessionLifecycleEvent } from "./session-history-eviction-C4srftLJ.js"; import { s as isModelSelectionLocked, t as MODEL_SELECTION_LOCKED_MESSAGE } from "./model-overrides-Bm7jo7Di.js"; import { o as resolveSupportedThinkingLevel } from "./thinking-DterdXhr.js"; import { o as resolveEffectiveAgentRuntime } from "./thinking-runtime-BiFbTVdI.js"; import "./model-selection-di2kjKCB.js"; import { c as refreshQueuedFollowupSession } from "./settings-jmDsm5RI.js"; import "./queue-BpaiO3X2.js"; import { t as triggerSessionPatchHook } from "./session-patch-hooks-Bav35gWY.js"; import { t as applyModelOverrideWithAuthProfileCompatibility } from "./auth-profile-preservation-DCNwoc5M.js"; import { n as createModelVisibilityPolicy } from "./model-visibility-policy-mYoB7nkk.js"; import { t as persistStickyModelSelectionBestEffort } from "./sticky-model-selection-BlEz_Ddb.js"; import { a as prepareModelSelectionRuntime, s as applyModelRuntimeDirective, t as findSelectedCatalogEntry } from "./model-runtime-normalization-CVjCcJkR.js"; import { a as sessionModelOverrideChangesApplied, n as adoptPersistedSessionSnapshot, t as SESSION_MODEL_OVERRIDE_TRANSACTION_FIELDS } from "./session-snapshot-merge-Cf1TdJBp.js"; import { t as resolveContextTokens } from "./model-selection-context-BUKuYlr-.js"; import { t as persistReplySessionEntry } from "./session-entry-persistence-Cdz5cLuU.js"; //#region src/model-picker/apply-session-model-selection.ts /** Applies the model transaction field family to one caller-owned snapshot. */ function applySessionModelSelectionToEntry(params) { const modelChange = applyModelOverrideWithAuthProfileCompatibility({ cfg: params.cfg, agentDir: params.agentDir, entry: params.entry, currentProvider: params.currentProvider, selection: params.request, profileOverride: params.request.profileOverride, markLiveSwitchPending: params.markLiveSwitchPending }); const runtimeChange = applyModelRuntimeDirective(params.entry, params.runtime); return { changed: modelChange.updated || runtimeChange.updated, ...params.runtime.kind === "clear" || params.runtime.kind === "set" ? { runtimeChange: params.runtime } : {} }; } function formatModelSwitchEvent(provider, model, alias) { const label = `${provider}/${model}`; return alias ? `Model switched to ${alias} (${label}).` : `Model switched to ${label}.`; } function rejectNotAllowed(provider, model) { return { status: "rejected", reason: "not-allowed", message: `Model ${provider}/${model} is not available for this agent.` }; } /** Applies one validated picker selection to the authoritative live session. */ async function applySessionModelSelection(params) { const startingStoreEntry = params.sessionStore[params.sessionKey]; const startingEntry = params.storePath ? params.sessionEntry : startingStoreEntry ?? params.sessionEntry; const initialEntry = { ...startingEntry }; if (isModelSelectionLocked(startingEntry)) return { status: "rejected", reason: "locked", message: MODEL_SELECTION_LOCKED_MESSAGE }; const normalizedModelKey = modelKey(params.request.provider, params.request.model); if (!(params.modelPolicy ?? createModelVisibilityPolicy({ cfg: params.cfg, catalog: [...params.modelCatalog], defaultProvider: params.defaultProvider, defaultModel: params.defaultModel, agentId: params.agentId })).allows(params.request)) return rejectNotAllowed(params.request.provider, params.request.model); const request = { ...params.request, isDefault: normalizedModelKey === modelKey(params.defaultProvider, params.defaultModel) }; const prepared = await prepareModelSelectionRuntime({ cfg: params.cfg, agentId: params.agentId, sessionEntry: startingEntry, provider: request.provider, model: request.model, catalog: params.thinkingCatalog ?? params.modelCatalog, rawRuntime: request.runtime.kind === "set" ? request.runtime.runtime : request.runtime.kind === "clear" ? "default" : void 0 }); if (prepared.status === "rejected") return prepared; const authProfileError = params.validateAuthProfileSelection?.(); if (authProfileError) return { status: "rejected", reason: "not-allowed", message: authProfileError }; const currentEntry = params.storePath ? startingEntry : params.sessionStore[params.sessionKey] ?? params.sessionEntry; if (isModelSelectionLocked(currentEntry)) return { status: "rejected", reason: "locked", message: MODEL_SELECTION_LOCKED_MESSAGE }; if (!params.storePath && (params.sessionStore[params.sessionKey] !== startingStoreEntry || currentEntry.sessionId !== initialEntry.sessionId)) return { status: "conflict", message: "Model change was not applied because the session changed. Retry." }; const runtime = prepared.runtime; const thinkingCatalog = prepared.catalog; const selectedCatalogEntry = findSelectedCatalogEntry({ catalog: thinkingCatalog, ...request }); const nextEntry = { ...startingEntry }; const applied = applySessionModelSelectionToEntry({ cfg: params.cfg, agentDir: resolveAgentDir(params.cfg, params.agentId), entry: nextEntry, currentProvider: params.currentProvider, request, runtime, markLiveSwitchPending: params.markLiveSwitchPending }); const thinkingRuntime = resolveEffectiveAgentRuntime({ cfg: params.cfg, provider: request.provider, modelId: request.model, modelApi: selectedCatalogEntry?.api, modelBaseUrl: selectedCatalogEntry?.baseUrl, agentId: params.agentId, sessionKey: params.sessionKey, sessionEntry: nextEntry }); const currentThinkingLevel = nextEntry.thinkingLevel; let thinkingRemap; if (currentThinkingLevel) { const remapped = resolveSupportedThinkingLevel({ provider: request.provider, model: request.model, level: currentThinkingLevel, catalog: [...thinkingCatalog], agentRuntime: thinkingRuntime }); if (remapped !== currentThinkingLevel) { nextEntry.thinkingLevel = remapped; thinkingRemap = { from: currentThinkingLevel, to: remapped, provider: request.provider, model: request.model }; } } nextEntry.updatedAt = Date.now(); let persistedEntry; if (params.storePath) { const persistence = await persistReplySessionEntry({ storePath: params.storePath, sessionKey: params.sessionKey, initialEntry, entry: nextEntry, allowCreate: params.allowCreate, reassertLiveModelSwitchPending: applied.changed && nextEntry.liveModelSwitchPending === true, requireModelSelectionUnlocked: true, touchedFields: SESSION_MODEL_OVERRIDE_TRANSACTION_FIELDS, validateCommit: params.validateAuthProfileSelection }); if (persistence.entry) { params.sessionStore[params.sessionKey] = persistence.entry; adoptPersistedSessionSnapshot(params.sessionEntry, persistence.entry); } if (persistence.status === "model-selection-locked") return { status: "rejected", reason: "locked", message: MODEL_SELECTION_LOCKED_MESSAGE }; if (persistence.status === "commit-rejected") return { status: "rejected", reason: "not-allowed", message: persistence.error }; if (persistence.status !== "current" || !sessionModelOverrideChangesApplied({ initial: initialEntry, next: nextEntry, current: persistence.entry, reassertLiveModelSwitchPending: applied.changed && nextEntry.liveModelSwitchPending === true })) return { status: "conflict", message: "Model change was not applied because the session changed. Retry." }; persistedEntry = persistence.entry; } else { adoptPersistedSessionSnapshot(params.sessionEntry, nextEntry); params.sessionStore[params.sessionKey] = params.sessionEntry; persistedEntry = params.sessionEntry; } const agentRuntime = resolveEffectiveAgentRuntime({ cfg: params.cfg, provider: request.provider, modelId: request.model, modelApi: selectedCatalogEntry?.api, modelBaseUrl: selectedCatalogEntry?.baseUrl, agentId: params.agentId, sessionKey: params.sessionKey, sessionEntry: persistedEntry }); const provider = request.provider; const model = request.model; const effectiveModelRef = `${provider}/${model}`; const changed = applied.changed || thinkingRemap !== void 0; const configuredDefaultUpdate = params.canPersistStickyModelSelection === true && (!request.isDefault || params.stickyModelSelectionTarget) ? persistStickyModelSelectionBestEffort({ agentId: params.agentId, model: effectiveModelRef, ...params.stickyModelSelectionTarget ? { target: params.stickyModelSelectionTarget } : {} }) : void 0; if (changed) { emitSessionLifecycleEvent({ sessionKey: params.sessionKey, agentId: params.agentId, reason: "patch" }); triggerSessionPatchHook({ cfg: params.cfg, sessionEntry: persistedEntry, sessionKey: params.sessionKey, patch: { key: params.sessionKey, model: params.patchModel ?? effectiveModelRef } }); refreshQueuedFollowupSession({ key: params.sessionKey, nextProvider: provider, nextModel: model, nextRouteResolution: "resolved", nextModelOverrideSource: request.isDefault ? void 0 : "user", nextAuthProfileId: persistedEntry.authProfileOverride, nextAuthProfileIdSource: resolveCollapsedSessionAuthPinSource(persistedEntry), nextThinking: { level: persistedEntry.thinkingLevel, catalog: [...thinkingCatalog], agentRuntime } }); } if (`${params.currentProvider}/${params.currentModel}` !== effectiveModelRef) enqueueSystemEvent(formatModelSwitchEvent(provider, model, request.alias), { sessionKey: params.sessionKey, contextKey: `model:${effectiveModelRef}` }); const contextProvider = resolveContextConfigProviderForRuntime({ provider, runtimeId: agentRuntime, config: params.cfg }); return { status: "applied", provider, model, effectiveModelRef, agentRuntime, changed, contextTokens: resolveContextTokens({ cfg: params.cfg, provider: contextProvider, model, modelContextWindow: selectedCatalogEntry?.contextWindow, modelContextTokens: selectedCatalogEntry?.contextTokens }), ...configuredDefaultUpdate ? { configuredDefaultUpdate } : {}, ...applied.runtimeChange ? { runtimeChange: applied.runtimeChange } : {}, ...thinkingRemap ? { thinkingRemap } : {} }; } //#endregion export { applySessionModelSelection as t };