refactor(agents): share model auth label resolution

This commit is contained in:
Peter Steinberger
2026-02-17 00:10:19 +00:00
parent ff2e790e03
commit 246bb7f30f
3 changed files with 87 additions and 153 deletions

View File

@@ -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";
}

View File

@@ -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<string, SessionEntry>;
keyRaw: string;

View File

@@ -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,