import { resolveAgentConfig } from "../../agents/agent-scope.js"; import { clearSessionAuthProfileOverride } from "../../agents/auth-profiles/session-override.js"; import { resolveContextTokensForModel } from "../../agents/context.js"; import { DEFAULT_CONTEXT_TOKENS } from "../../agents/defaults.js"; import type { ModelCatalogEntry } from "../../agents/model-catalog.js"; import {
buildConfiguredModelCatalog,
buildAllowedModelSet,
modelKey,
normalizeModelRef,
normalizeProviderId,
resolvePersistedOverrideModelRef,
resolveReasoningDefault,
resolveThinkingDefault,
} from "../../agents/model-selection.js"; import type { SessionEntry } from "../../config/sessions/types.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import { applyModelOverrideToSessionEntry } from "../../sessions/model-overrides.js"; import type { ThinkLevel } from "./directives.js";
export {
resolveModelDirectiveSelection,
type ModelDirectiveSelection,
} from "./model-selection-directive.js"; import { resolveStoredModelOverride } from "./stored-model-override.js";
type ModelCatalog = ModelCatalogEntry[];
type ModelSelectionState = {
provider: string;
model: string;
allowedModelKeys: Set<string>;
allowedModelCatalog: ModelCatalog;
resetModelOverride: boolean;
resolveDefaultThinkingLevel: () => Promise<ThinkLevel>; /** Default reasoning level from model capability: "on" if model has reasoning, else "off". */
resolveDefaultReasoningLevel: () => Promise<"on" | "off">;
needsModelCatalog: boolean;
};
// Auto-failover overrides are transient: on this turn, retry the configured // primary so the session self-heals when the primary recovers. The fallback loop // in runWithModelFallback will re-set the override if the primary is still down. // User-selected overrides (/model command) are preserved across turns. // // Clear this before allowlist validation so an old fallback outside the current // agent allowlist does not emit the unrelated "Model override not allowed" event. if (hadDirectAutoSessionOverride && sessionEntry && sessionStore && sessionKey) { const { updated } = applyModelOverrideToSessionEntry({
entry: sessionEntry,
selection: { provider: defaultProvider, model: defaultModel, isDefault: true },
}); if (updated) {
sessionStore[sessionKey] = sessionEntry; if (storePath) {
await (
await loadSessionStoreRuntime()
).updateSessionStore(storePath, (store) => {
store[sessionKey] = sessionEntry;
});
} // Reset in-memory selection to the configured primary. The caller-provided // provider/model may already be set to the fallback by stored-override preload // in get-reply.ts; updating them here ensures this turn retries the primary.
provider = defaultProvider;
model = defaultModel;
}
}
const storedOverride = hadDirectAutoSessionOverride
? undefined
: resolveStoredModelOverride({
sessionEntry,
sessionStore,
sessionKey,
parentSessionKey,
defaultProvider,
}); // Skip stored session model override only when an explicit heartbeat.model // was resolved. Heartbeat runs without heartbeat.model should still inherit // the regular session/parent model override behavior. const skipStoredOverride = params.hasResolvedHeartbeatModelOverride === true;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.