mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 09:50:42 +00:00
fix(openai): hide invalid codex imports in setup
This commit is contained in:
committed by
Val Alexander
parent
a028e63324
commit
eea8b02296
@@ -158,11 +158,11 @@ describe("openai codex provider", () => {
|
||||
"import-codex-cli",
|
||||
]);
|
||||
expect(provider.auth?.find((method) => method.id === "oauth")).toMatchObject({
|
||||
label: "OpenAI Codex Login",
|
||||
hint: "Browser sign-in",
|
||||
label: "OpenAI Codex Browser Login",
|
||||
hint: "Sign in with OpenAI in your browser",
|
||||
wizard: {
|
||||
choiceId: "openai-codex",
|
||||
choiceLabel: "OpenAI Codex Login",
|
||||
choiceLabel: "OpenAI Codex Browser Login",
|
||||
assistantPriority: -30,
|
||||
},
|
||||
});
|
||||
@@ -177,13 +177,14 @@ describe("openai codex provider", () => {
|
||||
},
|
||||
});
|
||||
expect(provider.auth?.find((method) => method.id === "import-codex-cli")).toMatchObject({
|
||||
label: "OpenAI Codex",
|
||||
hint: "Import existing ~/.codex login once",
|
||||
label: "Import Existing Codex Login",
|
||||
hint: "Import an existing ~/.codex login",
|
||||
kind: "oauth",
|
||||
wizard: {
|
||||
choiceId: "openai-codex-import",
|
||||
choiceLabel: "OpenAI Codex",
|
||||
choiceLabel: "Import Existing Codex Login",
|
||||
assistantPriority: -20,
|
||||
assistantVisibility: "manual-only",
|
||||
},
|
||||
});
|
||||
});
|
||||
@@ -194,13 +195,48 @@ describe("openai codex provider", () => {
|
||||
const provider = buildOpenAICodexProviderPlugin();
|
||||
|
||||
expect(provider.auth?.find((method) => method.id === "import-codex-cli")).toMatchObject({
|
||||
label: "OpenAI Codex (~/.codex existing key detected)",
|
||||
label: "Import Existing Codex Login (~/.codex detected)",
|
||||
wizard: {
|
||||
choiceLabel: "OpenAI Codex (~/.codex existing key detected)",
|
||||
choiceLabel: "Import Existing Codex Login (~/.codex detected)",
|
||||
assistantVisibility: "visible",
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it("soft-fails import when no compatible ~/.codex login exists", async () => {
|
||||
const provider = buildOpenAICodexProviderPlugin();
|
||||
const importMethod = provider.auth?.find((method) => method.id === "import-codex-cli");
|
||||
const note = vi.fn(async () => {});
|
||||
const runtime = {
|
||||
log: vi.fn(),
|
||||
error: vi.fn(),
|
||||
exit: vi.fn(),
|
||||
};
|
||||
readOpenAICodexCliOAuthProfileMock.mockReturnValueOnce(null);
|
||||
|
||||
const result = await importMethod?.run({
|
||||
config: {},
|
||||
env: process.env,
|
||||
prompter: {
|
||||
note,
|
||||
progress: vi.fn(),
|
||||
} as never,
|
||||
runtime: runtime as never,
|
||||
isRemote: false,
|
||||
openUrl: async () => {},
|
||||
oauth: { createVpsAwareHandlers: (() => ({})) as never },
|
||||
});
|
||||
|
||||
expect(result).toEqual({ profiles: [] });
|
||||
expect(runtime.error).toHaveBeenCalledWith(
|
||||
"No compatible ~/.codex ChatGPT login found. Use Browser Login or Device Pairing instead.",
|
||||
);
|
||||
expect(note).toHaveBeenCalledWith(
|
||||
"No compatible ~/.codex ChatGPT login found. Use Browser Login or Device Pairing instead.",
|
||||
"Import Existing Codex Login",
|
||||
);
|
||||
});
|
||||
|
||||
it("stores device-code logins as OpenAI Codex oauth profiles", async () => {
|
||||
const provider = buildOpenAICodexProviderPlugin();
|
||||
const deviceCodeMethod = provider.auth?.find((method) => method.id === "device-code");
|
||||
|
||||
@@ -49,10 +49,13 @@ const OPENAI_WIZARD_GROUP = {
|
||||
const OPENAI_CODEX_LOGIN_ASSISTANT_PRIORITY = -30;
|
||||
const OPENAI_CODEX_IMPORT_ASSISTANT_PRIORITY = -20;
|
||||
const OPENAI_CODEX_DEVICE_PAIRING_ASSISTANT_PRIORITY = -10;
|
||||
const OPENAI_CODEX_LOGIN_LABEL = "OpenAI Codex Login";
|
||||
const OPENAI_CODEX_IMPORT_LABEL = "OpenAI Codex";
|
||||
const OPENAI_CODEX_IMPORT_DETECTED_SUFFIX = "~/.codex existing key detected";
|
||||
const OPENAI_CODEX_LOGIN_LABEL = "OpenAI Codex Browser Login";
|
||||
const OPENAI_CODEX_LOGIN_HINT = "Sign in with OpenAI in your browser";
|
||||
const OPENAI_CODEX_IMPORT_LABEL = "Import Existing Codex Login";
|
||||
const OPENAI_CODEX_IMPORT_HINT = "Import an existing ~/.codex login";
|
||||
const OPENAI_CODEX_IMPORT_DETECTED_SUFFIX = "~/.codex detected";
|
||||
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";
|
||||
@@ -378,9 +381,11 @@ async function runImportOpenAICodexCliAuth(ctx: ProviderAuthContext) {
|
||||
store: ensureAuthProfileStoreForLocalUpdate(ctx.agentDir),
|
||||
});
|
||||
if (!profile) {
|
||||
throw new Error(
|
||||
"No compatible Codex CLI OAuth login found. Sign in with `codex` first or use ChatGPT OAuth instead.",
|
||||
);
|
||||
const message =
|
||||
"No compatible ~/.codex ChatGPT login found. Use Browser Login or Device Pairing instead.";
|
||||
ctx.runtime.error(message);
|
||||
await ctx.prompter.note(message, OPENAI_CODEX_IMPORT_LABEL);
|
||||
return { profiles: [] };
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -424,15 +429,16 @@ function buildOpenAICodexAuthDoctorHint(ctx: { profileId?: string }) {
|
||||
return "Deprecated profile. Run `openclaw models auth login --provider openai-codex` or `openclaw configure`.";
|
||||
}
|
||||
|
||||
function buildOpenAICodexImportWizardLabel() {
|
||||
if (!hasOpenAICodexCliOAuthCredential()) {
|
||||
function buildOpenAICodexImportWizardLabel(hasCodexCliCredential: boolean) {
|
||||
if (!hasCodexCliCredential) {
|
||||
return OPENAI_CODEX_IMPORT_LABEL;
|
||||
}
|
||||
return `${OPENAI_CODEX_IMPORT_LABEL} (${OPENAI_CODEX_IMPORT_DETECTED_SUFFIX})`;
|
||||
}
|
||||
|
||||
export function buildOpenAICodexProviderPlugin(): ProviderPlugin {
|
||||
const importWizardLabel = buildOpenAICodexImportWizardLabel();
|
||||
const hasCodexCliCredential = hasOpenAICodexCliOAuthCredential();
|
||||
const importWizardLabel = buildOpenAICodexImportWizardLabel(hasCodexCliCredential);
|
||||
return {
|
||||
id: PROVIDER_ID,
|
||||
label: "OpenAI Codex",
|
||||
@@ -441,12 +447,12 @@ export function buildOpenAICodexProviderPlugin(): ProviderPlugin {
|
||||
{
|
||||
id: "oauth",
|
||||
label: OPENAI_CODEX_LOGIN_LABEL,
|
||||
hint: "Browser sign-in",
|
||||
hint: OPENAI_CODEX_LOGIN_HINT,
|
||||
kind: "oauth",
|
||||
wizard: {
|
||||
choiceId: "openai-codex",
|
||||
choiceLabel: OPENAI_CODEX_LOGIN_LABEL,
|
||||
choiceHint: "Browser sign-in",
|
||||
choiceHint: OPENAI_CODEX_LOGIN_HINT,
|
||||
assistantPriority: OPENAI_CODEX_LOGIN_ASSISTANT_PRIORITY,
|
||||
...OPENAI_WIZARD_GROUP,
|
||||
},
|
||||
@@ -455,12 +461,12 @@ export function buildOpenAICodexProviderPlugin(): ProviderPlugin {
|
||||
{
|
||||
id: "device-code",
|
||||
label: OPENAI_CODEX_DEVICE_PAIRING_LABEL,
|
||||
hint: "Pair in browser with a device code",
|
||||
hint: OPENAI_CODEX_DEVICE_PAIRING_HINT,
|
||||
kind: "device_code",
|
||||
wizard: {
|
||||
choiceId: "openai-codex-device-code",
|
||||
choiceLabel: OPENAI_CODEX_DEVICE_PAIRING_LABEL,
|
||||
choiceHint: "Pair in browser with a device code",
|
||||
choiceHint: OPENAI_CODEX_DEVICE_PAIRING_HINT,
|
||||
assistantPriority: OPENAI_CODEX_DEVICE_PAIRING_ASSISTANT_PRIORITY,
|
||||
...OPENAI_WIZARD_GROUP,
|
||||
},
|
||||
@@ -475,13 +481,14 @@ export function buildOpenAICodexProviderPlugin(): ProviderPlugin {
|
||||
{
|
||||
id: "import-codex-cli",
|
||||
label: importWizardLabel,
|
||||
hint: "Import existing ~/.codex login once",
|
||||
hint: OPENAI_CODEX_IMPORT_HINT,
|
||||
kind: "oauth",
|
||||
wizard: {
|
||||
choiceId: "openai-codex-import",
|
||||
choiceLabel: importWizardLabel,
|
||||
choiceHint: "Import existing ~/.codex login once",
|
||||
choiceHint: OPENAI_CODEX_IMPORT_HINT,
|
||||
assistantPriority: OPENAI_CODEX_IMPORT_ASSISTANT_PRIORITY,
|
||||
assistantVisibility: hasCodexCliCredential ? "visible" : "manual-only",
|
||||
...OPENAI_WIZARD_GROUP,
|
||||
},
|
||||
run: async (ctx) => await runImportOpenAICodexCliAuth(ctx),
|
||||
|
||||
@@ -185,8 +185,8 @@ export function buildOpenAIProvider(): ProviderPlugin {
|
||||
createProviderApiKeyAuthMethod({
|
||||
providerId: PROVIDER_ID,
|
||||
methodId: "api-key",
|
||||
label: "OpenAI API key",
|
||||
hint: "Direct OpenAI API key",
|
||||
label: "OpenAI API Key",
|
||||
hint: "Use your OpenAI API key directly",
|
||||
optionKey: "openaiApiKey",
|
||||
flagName: "--openai-api-key",
|
||||
envVar: "OPENAI_API_KEY",
|
||||
@@ -196,10 +196,10 @@ export function buildOpenAIProvider(): ProviderPlugin {
|
||||
applyConfig: (cfg) => applyOpenAIConfig(cfg),
|
||||
wizard: {
|
||||
choiceId: "openai-api-key",
|
||||
choiceLabel: "OpenAI API key",
|
||||
choiceLabel: "OpenAI API Key",
|
||||
groupId: "openai",
|
||||
groupLabel: "OpenAI",
|
||||
groupHint: "Codex OAuth + API key",
|
||||
groupHint: "API key + Codex auth",
|
||||
},
|
||||
}),
|
||||
],
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
"method": "oauth",
|
||||
"choiceId": "openai-codex",
|
||||
"deprecatedChoiceIds": ["codex-cli"],
|
||||
"choiceLabel": "OpenAI Codex Login",
|
||||
"choiceHint": "Browser sign-in",
|
||||
"choiceLabel": "OpenAI Codex Browser Login",
|
||||
"choiceHint": "Sign in with OpenAI in your browser",
|
||||
"assistantPriority": -30,
|
||||
"groupId": "openai",
|
||||
"groupLabel": "OpenAI",
|
||||
@@ -37,8 +37,8 @@
|
||||
"provider": "openai-codex",
|
||||
"method": "import-codex-cli",
|
||||
"choiceId": "openai-codex-import",
|
||||
"choiceLabel": "OpenAI Codex",
|
||||
"choiceHint": "Import existing ~/.codex login once",
|
||||
"choiceLabel": "Import Existing Codex Login",
|
||||
"choiceHint": "Import an existing ~/.codex login",
|
||||
"assistantPriority": -20,
|
||||
"groupId": "openai",
|
||||
"groupLabel": "OpenAI",
|
||||
@@ -48,7 +48,7 @@
|
||||
"provider": "openai",
|
||||
"method": "api-key",
|
||||
"choiceId": "openai-api-key",
|
||||
"choiceLabel": "OpenAI API key",
|
||||
"choiceLabel": "OpenAI API Key",
|
||||
"assistantPriority": -40,
|
||||
"groupId": "openai",
|
||||
"groupLabel": "OpenAI",
|
||||
@@ -56,7 +56,7 @@
|
||||
"optionKey": "openaiApiKey",
|
||||
"cliFlag": "--openai-api-key",
|
||||
"cliOption": "--openai-api-key <key>",
|
||||
"cliDescription": "OpenAI API key"
|
||||
"cliDescription": "OpenAI API Key"
|
||||
}
|
||||
],
|
||||
"contracts": {
|
||||
|
||||
@@ -16,13 +16,13 @@ export function createOpenAICodexProvider(): ProviderPlugin {
|
||||
{
|
||||
id: "oauth",
|
||||
kind: "oauth",
|
||||
label: "OpenAI Codex Login",
|
||||
hint: "Browser sign-in",
|
||||
label: "OpenAI Codex Browser Login",
|
||||
hint: "Sign in with OpenAI in your browser",
|
||||
run: noopAuth,
|
||||
wizard: {
|
||||
choiceId: "openai-codex",
|
||||
choiceLabel: "OpenAI Codex Login",
|
||||
choiceHint: "Browser sign-in",
|
||||
choiceLabel: "OpenAI Codex Browser Login",
|
||||
choiceHint: "Sign in with OpenAI in your browser",
|
||||
assistantPriority: -30,
|
||||
...OPENAI_WIZARD_GROUP,
|
||||
},
|
||||
@@ -44,13 +44,13 @@ export function createOpenAICodexProvider(): ProviderPlugin {
|
||||
{
|
||||
id: "import-codex-cli",
|
||||
kind: "oauth",
|
||||
label: "OpenAI Codex",
|
||||
hint: "Import existing ~/.codex login once",
|
||||
label: "Import Existing Codex Login",
|
||||
hint: "Import an existing ~/.codex login",
|
||||
run: noopAuth,
|
||||
wizard: {
|
||||
choiceId: "openai-codex-import",
|
||||
choiceLabel: "OpenAI Codex",
|
||||
choiceHint: "Import existing ~/.codex login once",
|
||||
choiceLabel: "Import Existing Codex Login",
|
||||
choiceHint: "Import an existing ~/.codex login",
|
||||
assistantPriority: -20,
|
||||
...OPENAI_WIZARD_GROUP,
|
||||
},
|
||||
@@ -70,12 +70,12 @@ export function createOpenAIProvider(): ProviderPlugin {
|
||||
{
|
||||
id: "api-key",
|
||||
kind: "api_key",
|
||||
label: "OpenAI API key",
|
||||
hint: "Direct OpenAI API key",
|
||||
label: "OpenAI API Key",
|
||||
hint: "Use your OpenAI API key directly",
|
||||
run: noopAuth,
|
||||
wizard: {
|
||||
choiceId: "openai-api-key",
|
||||
choiceLabel: "OpenAI API key",
|
||||
choiceLabel: "OpenAI API Key",
|
||||
assistantPriority: -40,
|
||||
...OPENAI_WIZARD_GROUP,
|
||||
},
|
||||
|
||||
@@ -451,21 +451,21 @@ describe("buildAuthChoiceOptions", () => {
|
||||
resolveProviderWizardOptions.mockReturnValue([
|
||||
{
|
||||
value: "openai-api-key",
|
||||
label: "OpenAI API key",
|
||||
label: "OpenAI API Key",
|
||||
groupId: "openai",
|
||||
groupLabel: "OpenAI",
|
||||
assistantPriority: -40,
|
||||
},
|
||||
{
|
||||
value: "openai-codex",
|
||||
label: "OpenAI Codex Login",
|
||||
label: "OpenAI Codex Browser Login",
|
||||
groupId: "openai",
|
||||
groupLabel: "OpenAI",
|
||||
assistantPriority: -30,
|
||||
},
|
||||
{
|
||||
value: "openai-codex-import",
|
||||
label: "OpenAI Codex (~/.codex existing key detected)",
|
||||
label: "Import Existing Codex Login (~/.codex detected)",
|
||||
groupId: "openai",
|
||||
groupLabel: "OpenAI",
|
||||
assistantPriority: -20,
|
||||
|
||||
Reference in New Issue
Block a user