fix(auth/session): preserve override reset behavior and repair oauth profile-id drift (openclaw#18820) thanks @Glucksberg

Verified:
- pnpm build
- pnpm check
- pnpm test:macmini

Co-authored-by: Glucksberg <80581902+Glucksberg@users.noreply.github.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
This commit is contained in:
Glucksberg
2026-02-19 23:16:26 -04:00
committed by GitHub
parent f1e1cc4ee3
commit 38b4fb5d55
16 changed files with 376 additions and 46 deletions

View File

@@ -1,4 +1,6 @@
import { resolveAgentDir, resolveSessionAgentId } from "../../agents/agent-scope.js";
import { DEFAULT_MODEL, DEFAULT_PROVIDER } from "../../agents/defaults.js";
import { resolveModelAuthLabel } from "../../agents/model-auth-label.js";
import { loadModelCatalog } from "../../agents/model-catalog.js";
import {
buildAllowedModelSet,
@@ -8,6 +10,7 @@ import {
resolveModelRefFromString,
} from "../../agents/model-selection.js";
import type { OpenClawConfig } from "../../config/config.js";
import type { SessionEntry } from "../../config/sessions.js";
import {
buildModelsKeyboard,
buildProviderKeyboard,
@@ -177,11 +180,47 @@ function parseModelsArgs(raw: string): {
};
}
function resolveProviderLabel(params: {
provider: string;
cfg: OpenClawConfig;
agentDir?: string;
sessionEntry?: SessionEntry;
}): string {
const authLabel = resolveModelAuthLabel({
provider: params.provider,
cfg: params.cfg,
sessionEntry: params.sessionEntry,
agentDir: params.agentDir,
});
if (!authLabel || authLabel === "unknown") {
return params.provider;
}
return `${params.provider} · 🔑 ${authLabel}`;
}
export function formatModelsAvailableHeader(params: {
provider: string;
total: number;
cfg: OpenClawConfig;
agentDir?: string;
sessionEntry?: SessionEntry;
}): string {
const providerLabel = resolveProviderLabel({
provider: params.provider,
cfg: params.cfg,
agentDir: params.agentDir,
sessionEntry: params.sessionEntry,
});
return `Models (${providerLabel}) — ${params.total} available`;
}
export async function resolveModelsCommandReply(params: {
cfg: OpenClawConfig;
commandBodyNormalized: string;
surface?: string;
currentModel?: string;
agentDir?: string;
sessionEntry?: SessionEntry;
}): Promise<ReplyPayload | null> {
const body = params.commandBodyNormalized.trim();
if (!body.startsWith("/models")) {
@@ -237,10 +276,16 @@ export async function resolveModelsCommandReply(params: {
const models = [...(byProvider.get(provider) ?? new Set<string>())].toSorted();
const total = models.length;
const providerLabel = resolveProviderLabel({
provider,
cfg: params.cfg,
agentDir: params.agentDir,
sessionEntry: params.sessionEntry,
});
if (total === 0) {
const lines: string[] = [
`Models (${provider}) — none`,
`Models (${providerLabel}) — none`,
"",
"Browse: /models",
"Switch: /model <provider/model>",
@@ -263,7 +308,13 @@ export async function resolveModelsCommandReply(params: {
pageSize: telegramPageSize,
});
const text = `Models (${provider}) — ${total} available`;
const text = formatModelsAvailableHeader({
provider,
total,
cfg: params.cfg,
agentDir: params.agentDir,
sessionEntry: params.sessionEntry,
});
return {
text,
channelData: { telegram: { buttons } },
@@ -289,7 +340,7 @@ export async function resolveModelsCommandReply(params: {
const endIndexExclusive = Math.min(total, startIndex + effectivePageSize);
const pageModels = models.slice(startIndex, endIndexExclusive);
const header = `Models (${provider}) — showing ${startIndex + 1}-${endIndexExclusive} of ${total} (page ${safePage}/${pageCount})`;
const header = `Models (${providerLabel}) — showing ${startIndex + 1}-${endIndexExclusive} of ${total} (page ${safePage}/${pageCount})`;
const lines: string[] = [header];
for (const id of pageModels) {
@@ -313,11 +364,21 @@ export const handleModelsCommand: CommandHandler = async (params, allowTextComma
return null;
}
const modelsAgentId =
params.agentId ??
resolveSessionAgentId({
sessionKey: params.sessionKey,
config: params.cfg,
});
const modelsAgentDir = resolveAgentDir(params.cfg, modelsAgentId);
const reply = await resolveModelsCommandReply({
cfg: params.cfg,
commandBodyNormalized: params.command.commandBodyNormalized,
surface: params.ctx.Surface,
currentModel: params.model ? `${params.provider}/${params.model}` : undefined,
agentDir: modelsAgentDir,
sessionEntry: params.sessionEntry,
});
if (!reply) {
return null;

View File

@@ -1,6 +1,7 @@
import crypto from "node:crypto";
import { resolveSessionAuthProfileOverride } from "../../agents/auth-profiles/session-override.js";
import type { ExecToolDefaults } from "../../agents/bash-tools.js";
import { resolveModelAuthLabel } from "../../agents/model-auth-label.js";
import {
abortEmbeddedPiRun,
isEmbeddedPiRunActive,
@@ -325,10 +326,18 @@ export async function runPreparedReply(
if (channel && to) {
const modelLabel = `${provider}/${model}`;
const defaultLabel = `${defaultProvider}/${defaultModel}`;
const modelAuthLabel = resolveModelAuthLabel({
provider,
cfg,
sessionEntry,
agentDir,
});
const authSuffix =
modelAuthLabel && modelAuthLabel !== "unknown" ? ` · 🔑 ${modelAuthLabel}` : "";
const text =
modelLabel === defaultLabel
? `✅ New session started · model: ${modelLabel}`
: `✅ New session started · model: ${modelLabel} (default: ${defaultLabel})`;
? `✅ New session started · model: ${modelLabel}${authSuffix}`
: `✅ New session started · model: ${modelLabel} (default: ${defaultLabel})${authSuffix}`;
await routeReply({
payload: { text },
channel,

View File

@@ -13,19 +13,7 @@ type IncrementRunCompactionCountParams = Omit<
};
export async function persistRunSessionUsage(params: PersistRunSessionUsageParams): Promise<void> {
await persistSessionUsageUpdate({
storePath: params.storePath,
sessionKey: params.sessionKey,
usage: params.usage,
lastCallUsage: params.lastCallUsage,
promptTokens: params.promptTokens,
modelUsed: params.modelUsed,
providerUsed: params.providerUsed,
contextTokensUsed: params.contextTokensUsed,
systemPromptReport: params.systemPromptReport,
cliSessionId: params.cliSessionId,
logLabel: params.logLabel,
});
await persistSessionUsageUpdate(params);
}
export async function incrementRunCompactionCount(

View File

@@ -256,6 +256,8 @@ export async function initSessionState(params: {
persistedVerbose = entry.verboseLevel;
persistedReasoning = entry.reasoningLevel;
persistedTtsAuto = entry.ttsAuto;
persistedModelOverride = entry.modelOverride;
persistedProviderOverride = entry.providerOverride;
}
}