Skip to content

Commit 58153c5

Browse files
committed
fix(models): label picker auth via effective provider order
1 parent 46c622a commit 58153c5

3 files changed

Lines changed: 78 additions & 0 deletions

File tree

src/agents/model-auth-label.test.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,38 @@ describe("resolveModelAuthLabel", () => {
123123
expect(label).toBe("oauth (anthropic:oauth)");
124124
});
125125

126+
it("uses accepted provider ids before falling back to provider env auth", () => {
127+
mocks.ensureAuthProfileStore.mockReturnValue({
128+
version: 1,
129+
profiles: {
130+
"openai-codex:user@example.com": {
131+
type: "oauth",
132+
provider: "openai-codex",
133+
access: "access-token",
134+
refresh: "refresh-token",
135+
expires: Date.now() + 60_000,
136+
},
137+
},
138+
} as never);
139+
mocks.resolveAuthProfileOrder.mockImplementation(({ provider }: { provider?: string }) =>
140+
provider === "openai-codex" ? ["openai-codex:user@example.com"] : [],
141+
);
142+
mocks.resolveAuthProfileDisplayLabel.mockReturnValue("openai-codex:user@example.com");
143+
mocks.resolveEnvApiKey.mockReturnValue({
144+
apiKey: "env-key-placeholder",
145+
source: "env: OPENAI_API_KEY",
146+
});
147+
148+
const label = resolveModelAuthLabel({
149+
provider: "openai",
150+
acceptedProviderIds: ["openai-codex"],
151+
cfg: {},
152+
});
153+
154+
expect(label).toBe("oauth (openai-codex:user@example.com)");
155+
expect(mocks.resolveEnvApiKey).not.toHaveBeenCalled();
156+
});
157+
126158
it("shows codex cli auth for codex provider without auth profiles", () => {
127159
mocks.ensureAuthProfileStore.mockReturnValue({
128160
version: 1,

src/auto-reply/reply/commands-models.test.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -658,6 +658,34 @@ describe("handleModelsCommand", () => {
658658
expect(authLabelParams.workspaceDir).toBe("/tmp");
659659
});
660660

661+
it("labels OpenAI provider pages with the effective Codex auth provider set", async () => {
662+
modelAuthLabelMocks.resolveModelAuthLabel.mockReturnValue(
663+
"oauth (openai-codex:user@example.com)",
664+
);
665+
666+
const result = await handleModelsCommand(
667+
buildParams("/models openai", {
668+
auth: {
669+
order: {
670+
openai: ["openai-codex:user@example.com"],
671+
},
672+
},
673+
}),
674+
true,
675+
);
676+
677+
expect(result?.reply?.text).toContain(
678+
"Models (openai · 🔑 oauth (openai-codex:user@example.com))",
679+
);
680+
const openaiAuthCall = modelAuthLabelMocks.resolveModelAuthLabel.mock.calls.find(
681+
([params]) => (params as { provider?: string }).provider === "openai",
682+
);
683+
expect(openaiAuthCall?.[0]).toMatchObject({
684+
provider: "openai",
685+
acceptedProviderIds: ["openai-codex"],
686+
});
687+
});
688+
661689
it("uses spawned workspace for direct /models provider visibility", async () => {
662690
modelProviderAuthMocks.authenticatedProviders = new Set(["anthropic"]);
663691
const params = buildParams("/models");

src/auto-reply/reply/commands-models.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {
2121
resolveModelRefFromString,
2222
} from "../../agents/model-selection.js";
2323
import { createModelVisibilityPolicy } from "../../agents/model-visibility-policy.js";
24+
import { listOpenAIAuthProfileProvidersForAgentRuntime } from "../../agents/openai-codex-routing.js";
2425
import { resolveDefaultAgentWorkspaceDir } from "../../agents/workspace.js";
2526
import { getChannelPlugin } from "../../channels/plugins/index.js";
2627
import type { SessionEntry } from "../../config/sessions.js";
@@ -387,12 +388,24 @@ function parseModelsArgs(raw: string): ParsedModelsCommand {
387388
function resolveProviderLabel(params: {
388389
provider: string;
389390
cfg: OpenClawConfig;
391+
agentId?: string;
390392
agentDir?: string;
391393
workspaceDir?: string;
392394
sessionEntry?: ModelsCommandSessionEntry;
393395
}): string {
396+
const harnessPolicy = resolveAgentHarnessPolicy({
397+
config: params.cfg,
398+
provider: params.provider,
399+
agentId: params.agentId,
400+
});
401+
const acceptedProviderIds = listOpenAIAuthProfileProvidersForAgentRuntime({
402+
provider: params.provider,
403+
harnessRuntime: harnessPolicy.runtime,
404+
config: params.cfg,
405+
});
394406
const authLabel = resolveModelAuthLabel({
395407
provider: params.provider,
408+
acceptedProviderIds,
396409
cfg: params.cfg,
397410
sessionEntry: params.sessionEntry,
398411
agentDir: params.agentDir,
@@ -408,13 +421,15 @@ export function formatModelsAvailableHeader(params: {
408421
provider: string;
409422
total: number;
410423
cfg: OpenClawConfig;
424+
agentId?: string;
411425
agentDir?: string;
412426
workspaceDir?: string;
413427
sessionEntry?: ModelsCommandSessionEntry;
414428
}): string {
415429
const providerLabel = resolveProviderLabel({
416430
provider: params.provider,
417431
cfg: params.cfg,
432+
agentId: params.agentId,
418433
agentDir: params.agentDir,
419434
workspaceDir: params.workspaceDir,
420435
sessionEntry: params.sessionEntry,
@@ -539,6 +554,7 @@ export async function resolveModelsCommandReply(params: {
539554
const emptyProviderLabel = resolveProviderLabel({
540555
provider,
541556
cfg: params.cfg,
557+
agentId: params.agentId,
542558
agentDir: params.agentDir,
543559
workspaceDir: params.workspaceDir,
544560
sessionEntry: params.sessionEntry,
@@ -571,6 +587,7 @@ export async function resolveModelsCommandReply(params: {
571587
provider,
572588
total,
573589
cfg: params.cfg,
590+
agentId: params.agentId,
574591
agentDir: params.agentDir,
575592
workspaceDir: params.workspaceDir,
576593
sessionEntry: params.sessionEntry,
@@ -600,6 +617,7 @@ export async function resolveModelsCommandReply(params: {
600617
const providerLabel = resolveProviderLabel({
601618
provider,
602619
cfg: params.cfg,
620+
agentId: params.agentId,
603621
agentDir: params.agentDir,
604622
workspaceDir: params.workspaceDir,
605623
sessionEntry: params.sessionEntry,

0 commit comments

Comments
 (0)