mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-09 11:47:41 +00:00
refactor(agents): share model auth label resolution
This commit is contained in:
79
src/agents/model-auth-label.ts
Normal file
79
src/agents/model-auth-label.ts
Normal 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";
|
||||||
|
}
|
||||||
@@ -24,19 +24,13 @@ import {
|
|||||||
} from "../../routing/session-key.js";
|
} from "../../routing/session-key.js";
|
||||||
import { applyModelOverrideToSessionEntry } from "../../sessions/model-overrides.js";
|
import { applyModelOverrideToSessionEntry } from "../../sessions/model-overrides.js";
|
||||||
import { resolveAgentDir } from "../agent-scope.js";
|
import { resolveAgentDir } from "../agent-scope.js";
|
||||||
import {
|
|
||||||
ensureAuthProfileStore,
|
|
||||||
resolveAuthProfileDisplayLabel,
|
|
||||||
resolveAuthProfileOrder,
|
|
||||||
} from "../auth-profiles.js";
|
|
||||||
import { formatUserTime, resolveUserTimeFormat, resolveUserTimezone } from "../date-time.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 { loadModelCatalog } from "../model-catalog.js";
|
||||||
import {
|
import {
|
||||||
buildAllowedModelSet,
|
buildAllowedModelSet,
|
||||||
buildModelAliasIndex,
|
buildModelAliasIndex,
|
||||||
modelKey,
|
modelKey,
|
||||||
normalizeProviderId,
|
|
||||||
resolveDefaultModelForAgent,
|
resolveDefaultModelForAgent,
|
||||||
resolveModelRefFromString,
|
resolveModelRefFromString,
|
||||||
} from "../model-selection.js";
|
} from "../model-selection.js";
|
||||||
@@ -53,76 +47,6 @@ const SessionStatusToolSchema = Type.Object({
|
|||||||
model: Type.Optional(Type.String()),
|
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: {
|
function resolveSessionEntry(params: {
|
||||||
store: Record<string, SessionEntry>;
|
store: Record<string, SessionEntry>;
|
||||||
keyRaw: string;
|
keyRaw: string;
|
||||||
|
|||||||
@@ -9,13 +9,7 @@ import {
|
|||||||
resolveDefaultAgentId,
|
resolveDefaultAgentId,
|
||||||
resolveSessionAgentId,
|
resolveSessionAgentId,
|
||||||
} from "../../agents/agent-scope.js";
|
} from "../../agents/agent-scope.js";
|
||||||
import {
|
import { resolveModelAuthLabel } from "../../agents/model-auth-label.js";
|
||||||
ensureAuthProfileStore,
|
|
||||||
resolveAuthProfileDisplayLabel,
|
|
||||||
resolveAuthProfileOrder,
|
|
||||||
} from "../../agents/auth-profiles.js";
|
|
||||||
import { getCustomProviderApiKey, resolveEnvApiKey } from "../../agents/model-auth.js";
|
|
||||||
import { normalizeProviderId } from "../../agents/model-selection.js";
|
|
||||||
import { listSubagentRunsForRequester } from "../../agents/subagent-registry.js";
|
import { listSubagentRunsForRequester } from "../../agents/subagent-registry.js";
|
||||||
import {
|
import {
|
||||||
resolveInternalSessionKey,
|
resolveInternalSessionKey,
|
||||||
@@ -32,74 +26,6 @@ import { buildStatusMessage, getTranscriptInfo } from "../status.js";
|
|||||||
import { getFollowupQueueDepth, resolveQueueSettings } from "./queue.js";
|
import { getFollowupQueueDepth, resolveQueueSettings } from "./queue.js";
|
||||||
import { resolveSubagentLabel } from "./subagents-utils.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: {
|
export async function buildStatusReply(params: {
|
||||||
cfg: OpenClawConfig;
|
cfg: OpenClawConfig;
|
||||||
command: CommandContext;
|
command: CommandContext;
|
||||||
@@ -234,7 +160,12 @@ export async function buildStatusReply(params: {
|
|||||||
resolvedVerbose: resolvedVerboseLevel,
|
resolvedVerbose: resolvedVerboseLevel,
|
||||||
resolvedReasoning: resolvedReasoningLevel,
|
resolvedReasoning: resolvedReasoningLevel,
|
||||||
resolvedElevated: resolvedElevatedLevel,
|
resolvedElevated: resolvedElevatedLevel,
|
||||||
modelAuth: resolveModelAuthLabel(provider, cfg, sessionEntry, statusAgentDir),
|
modelAuth: resolveModelAuthLabel({
|
||||||
|
provider,
|
||||||
|
cfg,
|
||||||
|
sessionEntry,
|
||||||
|
agentDir: statusAgentDir,
|
||||||
|
}),
|
||||||
usageLine: usageLine ?? undefined,
|
usageLine: usageLine ?? undefined,
|
||||||
queue: {
|
queue: {
|
||||||
mode: queueSettings.mode,
|
mode: queueSettings.mode,
|
||||||
|
|||||||
Reference in New Issue
Block a user