mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 06:50:43 +00:00
fix(openai): align auth picker copy metadata
This commit is contained in:
11
extensions/openai/auth-choice-copy.ts
Normal file
11
extensions/openai/auth-choice-copy.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
export const OPENAI_API_KEY_LABEL = "OpenAI API Key";
|
||||
export const OPENAI_CODEX_LOGIN_LABEL = "OpenAI Codex Browser Login";
|
||||
export const OPENAI_CODEX_LOGIN_HINT = "Sign in with OpenAI in your browser";
|
||||
export const OPENAI_CODEX_DEVICE_PAIRING_LABEL = "OpenAI Codex Device Pairing";
|
||||
export const OPENAI_CODEX_DEVICE_PAIRING_HINT = "Pair in browser with a device code";
|
||||
|
||||
export const OPENAI_WIZARD_GROUP = {
|
||||
groupId: "openai",
|
||||
groupLabel: "OpenAI",
|
||||
groupHint: "API key or Codex sign-in",
|
||||
} as const;
|
||||
@@ -117,11 +117,11 @@ describe("openai codex provider", () => {
|
||||
|
||||
expect(oauth?.wizard).toMatchObject({
|
||||
choiceLabel: "OpenAI Codex Browser Login",
|
||||
groupHint: "API key + Codex auth",
|
||||
groupHint: "API key or Codex sign-in",
|
||||
});
|
||||
expect(deviceCode?.wizard).toMatchObject({
|
||||
choiceLabel: "OpenAI Codex Device Pairing",
|
||||
groupHint: "API key + Codex auth",
|
||||
groupHint: "API key or Codex sign-in",
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -20,6 +20,13 @@ import {
|
||||
} from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import { fetchCodexUsage } from "openclaw/plugin-sdk/provider-usage";
|
||||
import { normalizeLowercaseStringOrEmpty, readStringValue } from "openclaw/plugin-sdk/text-runtime";
|
||||
import {
|
||||
OPENAI_CODEX_DEVICE_PAIRING_HINT,
|
||||
OPENAI_CODEX_DEVICE_PAIRING_LABEL,
|
||||
OPENAI_CODEX_LOGIN_HINT,
|
||||
OPENAI_CODEX_LOGIN_LABEL,
|
||||
OPENAI_WIZARD_GROUP,
|
||||
} from "./auth-choice-copy.js";
|
||||
import { isOpenAIApiBaseUrl, isOpenAICodexBaseUrl } from "./base-url.js";
|
||||
import { OPENAI_CODEX_DEFAULT_MODEL } from "./default-models.js";
|
||||
import { resolveCodexAuthIdentity } from "./openai-codex-auth-identity.js";
|
||||
@@ -35,17 +42,8 @@ import {
|
||||
|
||||
const PROVIDER_ID = "openai-codex";
|
||||
const OPENAI_CODEX_BASE_URL = "https://chatgpt.com/backend-api/codex";
|
||||
const OPENAI_WIZARD_GROUP = {
|
||||
groupId: "openai",
|
||||
groupLabel: "OpenAI",
|
||||
groupHint: "API key + Codex auth",
|
||||
} as const;
|
||||
const OPENAI_CODEX_LOGIN_ASSISTANT_PRIORITY = -30;
|
||||
const OPENAI_CODEX_DEVICE_PAIRING_ASSISTANT_PRIORITY = -10;
|
||||
const OPENAI_CODEX_LOGIN_LABEL = "OpenAI Codex Browser Login";
|
||||
const OPENAI_CODEX_LOGIN_HINT = "Sign in with OpenAI in your browser";
|
||||
const OPENAI_CODEX_DEVICE_PAIRING_LABEL = "OpenAI Codex Device Pairing";
|
||||
const OPENAI_CODEX_DEVICE_PAIRING_HINT = "Pair in browser with a device code";
|
||||
const OPENAI_CODEX_GPT_54_MODEL_ID = "gpt-5.4";
|
||||
const OPENAI_CODEX_GPT_54_LEGACY_MODEL_ID = "gpt-5.4-codex";
|
||||
const OPENAI_CODEX_GPT_54_PRO_MODEL_ID = "gpt-5.4-pro";
|
||||
|
||||
@@ -55,7 +55,7 @@ describe("buildOpenAIProvider", () => {
|
||||
|
||||
expect(apiKey?.wizard).toMatchObject({
|
||||
choiceLabel: "OpenAI API Key",
|
||||
groupHint: "API key + Codex auth",
|
||||
groupHint: "API key or Codex sign-in",
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
type ProviderPlugin,
|
||||
} from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime";
|
||||
import { OPENAI_API_KEY_LABEL, OPENAI_WIZARD_GROUP } from "./auth-choice-copy.js";
|
||||
import { isOpenAIApiBaseUrl } from "./base-url.js";
|
||||
import { applyOpenAIConfig, OPENAI_DEFAULT_MODEL } from "./default-models.js";
|
||||
import {
|
||||
@@ -185,7 +186,7 @@ export function buildOpenAIProvider(): ProviderPlugin {
|
||||
createProviderApiKeyAuthMethod({
|
||||
providerId: PROVIDER_ID,
|
||||
methodId: "api-key",
|
||||
label: "OpenAI API Key",
|
||||
label: OPENAI_API_KEY_LABEL,
|
||||
hint: "Use your OpenAI API key directly",
|
||||
optionKey: "openaiApiKey",
|
||||
flagName: "--openai-api-key",
|
||||
@@ -196,10 +197,8 @@ export function buildOpenAIProvider(): ProviderPlugin {
|
||||
applyConfig: (cfg) => applyOpenAIConfig(cfg),
|
||||
wizard: {
|
||||
choiceId: "openai-api-key",
|
||||
choiceLabel: "OpenAI API Key",
|
||||
groupId: "openai",
|
||||
groupLabel: "OpenAI",
|
||||
groupHint: "API key + Codex auth",
|
||||
choiceLabel: OPENAI_API_KEY_LABEL,
|
||||
...OPENAI_WIZARD_GROUP,
|
||||
},
|
||||
}),
|
||||
],
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
"assistantPriority": -30,
|
||||
"groupId": "openai",
|
||||
"groupLabel": "OpenAI",
|
||||
"groupHint": "API key + Codex auth"
|
||||
"groupHint": "API key or Codex sign-in"
|
||||
},
|
||||
{
|
||||
"provider": "openai-codex",
|
||||
@@ -31,7 +31,7 @@
|
||||
"assistantPriority": -10,
|
||||
"groupId": "openai",
|
||||
"groupLabel": "OpenAI",
|
||||
"groupHint": "API key + Codex auth"
|
||||
"groupHint": "API key or Codex sign-in"
|
||||
},
|
||||
{
|
||||
"provider": "openai",
|
||||
@@ -41,7 +41,7 @@
|
||||
"assistantPriority": -40,
|
||||
"groupId": "openai",
|
||||
"groupLabel": "OpenAI",
|
||||
"groupHint": "API key + Codex auth",
|
||||
"groupHint": "API key or Codex sign-in",
|
||||
"optionKey": "openaiApiKey",
|
||||
"cliFlag": "--openai-api-key",
|
||||
"cliOption": "--openai-api-key <key>",
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { readFileSync } from "node:fs";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { buildOpenAICodexProviderPlugin } from "./openai-codex-provider.js";
|
||||
import { buildOpenAIProvider } from "./openai-provider.js";
|
||||
|
||||
const manifest = JSON.parse(
|
||||
readFileSync(new URL("./openclaw.plugin.json", import.meta.url), "utf8"),
|
||||
@@ -15,6 +17,41 @@ const manifest = JSON.parse(
|
||||
}>;
|
||||
};
|
||||
|
||||
function manifestComparableWizardFields(choice: {
|
||||
choiceId?: string;
|
||||
choiceLabel?: string;
|
||||
choiceHint?: string;
|
||||
groupId?: string;
|
||||
groupLabel?: string;
|
||||
groupHint?: string;
|
||||
}) {
|
||||
return Object.fromEntries(
|
||||
Object.entries({
|
||||
choiceId: choice.choiceId,
|
||||
choiceLabel: choice.choiceLabel,
|
||||
choiceHint: choice.choiceHint,
|
||||
groupId: choice.groupId,
|
||||
groupLabel: choice.groupLabel,
|
||||
groupHint: choice.groupHint,
|
||||
}).filter(([, value]) => value !== undefined),
|
||||
);
|
||||
}
|
||||
|
||||
function providerWizardByKey() {
|
||||
const providers = [buildOpenAIProvider(), buildOpenAICodexProviderPlugin()];
|
||||
const wizards = new Map<string, Record<string, unknown>>();
|
||||
|
||||
for (const provider of providers) {
|
||||
for (const authMethod of provider.auth ?? []) {
|
||||
if (authMethod.wizard) {
|
||||
wizards.set(`${provider.id}:${authMethod.id}`, authMethod.wizard);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return wizards;
|
||||
}
|
||||
|
||||
describe("OpenAI plugin manifest", () => {
|
||||
it("keeps removed Codex CLI import auth choice as a deprecated browser-login alias", () => {
|
||||
const codexBrowserLogin = manifest.providerAuthChoices?.find(
|
||||
@@ -37,20 +74,30 @@ describe("OpenAI plugin manifest", () => {
|
||||
expect(codexBrowserLogin).toMatchObject({
|
||||
choiceLabel: "OpenAI Codex Browser Login",
|
||||
choiceHint: "Sign in with OpenAI in your browser",
|
||||
groupHint: "API key + Codex auth",
|
||||
groupHint: "API key or Codex sign-in",
|
||||
});
|
||||
expect(codexDeviceCode).toMatchObject({
|
||||
choiceLabel: "OpenAI Codex Device Pairing",
|
||||
choiceHint: "Pair in browser with a device code",
|
||||
groupHint: "API key + Codex auth",
|
||||
groupHint: "API key or Codex sign-in",
|
||||
});
|
||||
expect(apiKey).toMatchObject({
|
||||
choiceLabel: "OpenAI API Key",
|
||||
groupHint: "API key + Codex auth",
|
||||
groupHint: "API key or Codex sign-in",
|
||||
});
|
||||
expect(choices.map((choice) => choice.choiceLabel)).not.toContain(
|
||||
"OpenAI Codex (ChatGPT OAuth)",
|
||||
);
|
||||
expect(choices.map((choice) => choice.groupHint)).not.toContain("Codex OAuth + API key");
|
||||
});
|
||||
|
||||
it("keeps auth choice copy aligned with provider wizard metadata", () => {
|
||||
const wizards = providerWizardByKey();
|
||||
|
||||
for (const choice of manifest.providerAuthChoices ?? []) {
|
||||
const key = `${choice.provider}:${choice.method}`;
|
||||
|
||||
expect(wizards.get(key), key).toMatchObject(manifestComparableWizardFields(choice));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
import type { ProviderPlugin } from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import {
|
||||
OPENAI_API_KEY_LABEL,
|
||||
OPENAI_CODEX_DEVICE_PAIRING_HINT,
|
||||
OPENAI_CODEX_DEVICE_PAIRING_LABEL,
|
||||
OPENAI_CODEX_LOGIN_HINT,
|
||||
OPENAI_CODEX_LOGIN_LABEL,
|
||||
OPENAI_WIZARD_GROUP,
|
||||
} from "./auth-choice-copy.js";
|
||||
|
||||
const noopAuth = async () => ({ profiles: [] });
|
||||
const OPENAI_WIZARD_GROUP = {
|
||||
groupId: "openai",
|
||||
groupLabel: "OpenAI",
|
||||
groupHint: "API key + Codex auth",
|
||||
} as const;
|
||||
|
||||
export function createOpenAICodexProvider(): ProviderPlugin {
|
||||
return {
|
||||
@@ -22,13 +25,13 @@ export function createOpenAICodexProvider(): ProviderPlugin {
|
||||
{
|
||||
id: "oauth",
|
||||
kind: "oauth",
|
||||
label: "OpenAI Codex Browser Login",
|
||||
hint: "Sign in with OpenAI in your browser",
|
||||
label: OPENAI_CODEX_LOGIN_LABEL,
|
||||
hint: OPENAI_CODEX_LOGIN_HINT,
|
||||
run: noopAuth,
|
||||
wizard: {
|
||||
choiceId: "openai-codex",
|
||||
choiceLabel: "OpenAI Codex Browser Login",
|
||||
choiceHint: "Sign in with OpenAI in your browser",
|
||||
choiceLabel: OPENAI_CODEX_LOGIN_LABEL,
|
||||
choiceHint: OPENAI_CODEX_LOGIN_HINT,
|
||||
assistantPriority: -30,
|
||||
...OPENAI_WIZARD_GROUP,
|
||||
},
|
||||
@@ -36,13 +39,13 @@ export function createOpenAICodexProvider(): ProviderPlugin {
|
||||
{
|
||||
id: "device-code",
|
||||
kind: "device_code",
|
||||
label: "OpenAI Codex Device Pairing",
|
||||
hint: "Pair in browser with a device code",
|
||||
label: OPENAI_CODEX_DEVICE_PAIRING_LABEL,
|
||||
hint: OPENAI_CODEX_DEVICE_PAIRING_HINT,
|
||||
run: noopAuth,
|
||||
wizard: {
|
||||
choiceId: "openai-codex-device-code",
|
||||
choiceLabel: "OpenAI Codex Device Pairing",
|
||||
choiceHint: "Pair in browser with a device code",
|
||||
choiceLabel: OPENAI_CODEX_DEVICE_PAIRING_LABEL,
|
||||
choiceHint: OPENAI_CODEX_DEVICE_PAIRING_HINT,
|
||||
assistantPriority: -10,
|
||||
...OPENAI_WIZARD_GROUP,
|
||||
},
|
||||
@@ -62,12 +65,12 @@ export function createOpenAIProvider(): ProviderPlugin {
|
||||
{
|
||||
id: "api-key",
|
||||
kind: "api_key",
|
||||
label: "OpenAI API Key",
|
||||
label: OPENAI_API_KEY_LABEL,
|
||||
hint: "Use your OpenAI API key directly",
|
||||
run: noopAuth,
|
||||
wizard: {
|
||||
choiceId: "openai-api-key",
|
||||
choiceLabel: "OpenAI API Key",
|
||||
choiceLabel: OPENAI_API_KEY_LABEL,
|
||||
assistantPriority: -40,
|
||||
...OPENAI_WIZARD_GROUP,
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user