From 246bb7f30f9b2ae4b5d19a5779b233a6c5572b37 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Tue, 17 Feb 2026 00:10:19 +0000 Subject: [PATCH] refactor(agents): share model auth label resolution --- src/agents/model-auth-label.ts | 79 +++++++++++++++++++++++ src/agents/tools/session-status-tool.ts | 78 +---------------------- src/auto-reply/reply/commands-status.ts | 83 +++---------------------- 3 files changed, 87 insertions(+), 153 deletions(-) create mode 100644 src/agents/model-auth-label.ts diff --git a/src/agents/model-auth-label.ts b/src/agents/model-auth-label.ts new file mode 100644 index 0000000000..9781791574 --- /dev/null +++ b/src/agents/model-auth-label.ts @@ -0,0 +1,79 @@ +import type { OpenClawConfig } from "../config/config.js"; +import type { SessionEntry } from "../config/sessions.js"; +import { + ensureAuthProfileStore, + resolveAuthProfileDisplayLabel, + resolveAuthProfileOrder, +} from "./auth-profiles.js"; +import { getCustomProviderApiKey, resolveEnvApiKey } from "./model-auth.js"; +import { normalizeProviderId } from "./model-selection.js"; + +function formatApiKeySnippet(apiKey: string): string { + const compact = apiKey.replace(/\s+/g, ""); + if (!compact) { + return "unknown"; + } + const edge = compact.length >= 12 ? 6 : 4; + const head = compact.slice(0, edge); + const tail = compact.slice(-edge); + return `${head}…${tail}`; +} + +export function resolveModelAuthLabel(params: { + provider?: string; + cfg?: OpenClawConfig; + sessionEntry?: SessionEntry; + agentDir?: string; +}): string | undefined { + const resolvedProvider = params.provider?.trim(); + if (!resolvedProvider) { + return undefined; + } + + const providerKey = normalizeProviderId(resolvedProvider); + const store = ensureAuthProfileStore(params.agentDir, { + allowKeychainPrompt: false, + }); + const profileOverride = params.sessionEntry?.authProfileOverride?.trim(); + const order = resolveAuthProfileOrder({ + cfg: params.cfg, + store, + provider: providerKey, + preferredProfile: profileOverride, + }); + const candidates = [profileOverride, ...order].filter(Boolean) as string[]; + + for (const profileId of candidates) { + const profile = store.profiles[profileId]; + if (!profile || normalizeProviderId(profile.provider) !== providerKey) { + continue; + } + const label = resolveAuthProfileDisplayLabel({ + cfg: params.cfg, + store, + profileId, + }); + if (profile.type === "oauth") { + return `oauth${label ? ` (${label})` : ""}`; + } + if (profile.type === "token") { + return `token ${formatApiKeySnippet(profile.token)}${label ? ` (${label})` : ""}`; + } + return `api-key ${formatApiKeySnippet(profile.key ?? "")}${label ? ` (${label})` : ""}`; + } + + const envKey = resolveEnvApiKey(providerKey); + if (envKey?.apiKey) { + if (envKey.source.includes("OAUTH_TOKEN")) { + return `oauth (${envKey.source})`; + } + return `api-key ${formatApiKeySnippet(envKey.apiKey)} (${envKey.source})`; + } + + const customKey = getCustomProviderApiKey(params.cfg, providerKey); + if (customKey) { + return `api-key ${formatApiKeySnippet(customKey)} (models.json)`; + } + + return "unknown"; +} diff --git a/src/agents/tools/session-status-tool.ts b/src/agents/tools/session-status-tool.ts index 9be2c9f732..c2961412b3 100644 --- a/src/agents/tools/session-status-tool.ts +++ b/src/agents/tools/session-status-tool.ts @@ -24,19 +24,13 @@ import { } from "../../routing/session-key.js"; import { applyModelOverrideToSessionEntry } from "../../sessions/model-overrides.js"; import { resolveAgentDir } from "../agent-scope.js"; -import { - ensureAuthProfileStore, - resolveAuthProfileDisplayLabel, - resolveAuthProfileOrder, -} from "../auth-profiles.js"; import { formatUserTime, resolveUserTimeFormat, resolveUserTimezone } from "../date-time.js"; -import { getCustomProviderApiKey, resolveEnvApiKey } from "../model-auth.js"; +import { resolveModelAuthLabel } from "../model-auth-label.js"; import { loadModelCatalog } from "../model-catalog.js"; import { buildAllowedModelSet, buildModelAliasIndex, modelKey, - normalizeProviderId, resolveDefaultModelForAgent, resolveModelRefFromString, } from "../model-selection.js"; @@ -53,76 +47,6 @@ const SessionStatusToolSchema = Type.Object({ model: Type.Optional(Type.String()), }); -function formatApiKeySnippet(apiKey: string): string { - const compact = apiKey.replace(/\s+/g, ""); - if (!compact) { - return "unknown"; - } - const edge = compact.length >= 12 ? 6 : 4; - const head = compact.slice(0, edge); - const tail = compact.slice(-edge); - return `${head}…${tail}`; -} - -function resolveModelAuthLabel(params: { - provider?: string; - cfg: OpenClawConfig; - sessionEntry?: SessionEntry; - agentDir?: string; -}): string | undefined { - const resolvedProvider = params.provider?.trim(); - if (!resolvedProvider) { - return undefined; - } - - const providerKey = normalizeProviderId(resolvedProvider); - const store = ensureAuthProfileStore(params.agentDir, { - allowKeychainPrompt: false, - }); - const profileOverride = params.sessionEntry?.authProfileOverride?.trim(); - const order = resolveAuthProfileOrder({ - cfg: params.cfg, - store, - provider: providerKey, - preferredProfile: profileOverride, - }); - const candidates = [profileOverride, ...order].filter(Boolean) as string[]; - - for (const profileId of candidates) { - const profile = store.profiles[profileId]; - if (!profile || normalizeProviderId(profile.provider) !== providerKey) { - continue; - } - const label = resolveAuthProfileDisplayLabel({ - cfg: params.cfg, - store, - profileId, - }); - if (profile.type === "oauth") { - return `oauth${label ? ` (${label})` : ""}`; - } - if (profile.type === "token") { - return `token ${formatApiKeySnippet(profile.token)}${label ? ` (${label})` : ""}`; - } - return `api-key ${formatApiKeySnippet(profile.key ?? "")}${label ? ` (${label})` : ""}`; - } - - const envKey = resolveEnvApiKey(providerKey); - if (envKey?.apiKey) { - if (envKey.source.includes("OAUTH_TOKEN")) { - return `oauth (${envKey.source})`; - } - return `api-key ${formatApiKeySnippet(envKey.apiKey)} (${envKey.source})`; - } - - const customKey = getCustomProviderApiKey(params.cfg, providerKey); - if (customKey) { - return `api-key ${formatApiKeySnippet(customKey)} (models.json)`; - } - - return "unknown"; -} - function resolveSessionEntry(params: { store: Record; keyRaw: string; diff --git a/src/auto-reply/reply/commands-status.ts b/src/auto-reply/reply/commands-status.ts index 36714c196c..ea48d3d303 100644 --- a/src/auto-reply/reply/commands-status.ts +++ b/src/auto-reply/reply/commands-status.ts @@ -9,13 +9,7 @@ import { resolveDefaultAgentId, resolveSessionAgentId, } from "../../agents/agent-scope.js"; -import { - ensureAuthProfileStore, - resolveAuthProfileDisplayLabel, - resolveAuthProfileOrder, -} from "../../agents/auth-profiles.js"; -import { getCustomProviderApiKey, resolveEnvApiKey } from "../../agents/model-auth.js"; -import { normalizeProviderId } from "../../agents/model-selection.js"; +import { resolveModelAuthLabel } from "../../agents/model-auth-label.js"; import { listSubagentRunsForRequester } from "../../agents/subagent-registry.js"; import { resolveInternalSessionKey, @@ -32,74 +26,6 @@ import { buildStatusMessage, getTranscriptInfo } from "../status.js"; import { getFollowupQueueDepth, resolveQueueSettings } from "./queue.js"; import { resolveSubagentLabel } from "./subagents-utils.js"; -function formatApiKeySnippet(apiKey: string): string { - const compact = apiKey.replace(/\s+/g, ""); - if (!compact) { - return "unknown"; - } - const edge = compact.length >= 12 ? 6 : 4; - const head = compact.slice(0, edge); - const tail = compact.slice(-edge); - return `${head}…${tail}`; -} - -function resolveModelAuthLabel( - provider?: string, - cfg?: OpenClawConfig, - sessionEntry?: SessionEntry, - agentDir?: string, -): string | undefined { - const resolved = provider?.trim(); - if (!resolved) { - return undefined; - } - - const providerKey = normalizeProviderId(resolved); - const store = ensureAuthProfileStore(agentDir, { - allowKeychainPrompt: false, - }); - const profileOverride = sessionEntry?.authProfileOverride?.trim(); - const order = resolveAuthProfileOrder({ - cfg, - store, - provider: providerKey, - preferredProfile: profileOverride, - }); - const candidates = [profileOverride, ...order].filter(Boolean) as string[]; - - for (const profileId of candidates) { - const profile = store.profiles[profileId]; - if (!profile || normalizeProviderId(profile.provider) !== providerKey) { - continue; - } - const label = resolveAuthProfileDisplayLabel({ cfg, store, profileId }); - if (profile.type === "oauth") { - return `oauth${label ? ` (${label})` : ""}`; - } - if (profile.type === "token") { - const snippet = formatApiKeySnippet(profile.token); - return `token ${snippet}${label ? ` (${label})` : ""}`; - } - const snippet = formatApiKeySnippet(profile.key ?? ""); - return `api-key ${snippet}${label ? ` (${label})` : ""}`; - } - - const envKey = resolveEnvApiKey(providerKey); - if (envKey?.apiKey) { - if (envKey.source.includes("OAUTH_TOKEN")) { - return `oauth (${envKey.source})`; - } - return `api-key ${formatApiKeySnippet(envKey.apiKey)} (${envKey.source})`; - } - - const customKey = getCustomProviderApiKey(cfg, providerKey); - if (customKey) { - return `api-key ${formatApiKeySnippet(customKey)} (models.json)`; - } - - return "unknown"; -} - export async function buildStatusReply(params: { cfg: OpenClawConfig; command: CommandContext; @@ -234,7 +160,12 @@ export async function buildStatusReply(params: { resolvedVerbose: resolvedVerboseLevel, resolvedReasoning: resolvedReasoningLevel, resolvedElevated: resolvedElevatedLevel, - modelAuth: resolveModelAuthLabel(provider, cfg, sessionEntry, statusAgentDir), + modelAuth: resolveModelAuthLabel({ + provider, + cfg, + sessionEntry, + agentDir: statusAgentDir, + }), usageLine: usageLine ?? undefined, queue: { mode: queueSettings.mode,