mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-08 18:33:39 +02:00
fix(openai): clarify auth routes in picker and docs
This commit is contained in:
@@ -657,6 +657,31 @@ for usage/billing and raise limits as needed.
|
||||
OpenClaw supports **OpenAI Code (Codex)** via OAuth (ChatGPT sign-in). Onboarding can run the OAuth flow and will set the default model to `openai-codex/gpt-5.4` when appropriate. See [Model providers](/concepts/model-providers) and [Onboarding (CLI)](/start/wizard).
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Why does ChatGPT GPT-5.4 not unlock openai/gpt-5.4 in OpenClaw?">
|
||||
OpenClaw treats the two routes separately:
|
||||
|
||||
- `openai-codex/gpt-5.4` = ChatGPT/Codex OAuth
|
||||
- `openai/gpt-5.4` = direct OpenAI Platform API
|
||||
|
||||
In OpenClaw, ChatGPT/Codex sign-in is wired to the `openai-codex/*` route,
|
||||
not the direct `openai/*` route. If you want the direct API path in
|
||||
OpenClaw, set `OPENAI_API_KEY` (or the equivalent OpenAI provider config).
|
||||
If you want ChatGPT/Codex sign-in in OpenClaw, use `openai-codex/*`.
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Why can Codex OAuth limits differ from ChatGPT web?">
|
||||
`openai-codex/*` uses the Codex OAuth route, and its usable quota windows are
|
||||
OpenAI-managed and plan-dependent. In practice, those limits can differ from
|
||||
the ChatGPT website/app experience, even when both are tied to the same account.
|
||||
|
||||
OpenClaw can show the currently visible provider usage/quota windows in
|
||||
`openclaw models status`, but it does not invent or normalize ChatGPT-web
|
||||
entitlements into direct API access. If you want the direct OpenAI Platform
|
||||
billing/limit path, use `openai/*` with an API key.
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Do you support OpenAI subscription auth (Codex OAuth)?">
|
||||
Yes. OpenClaw fully supports **OpenAI Code (Codex) subscription OAuth**.
|
||||
OpenAI explicitly allows subscription OAuth usage in external tools/workflows
|
||||
|
||||
@@ -82,6 +82,12 @@ openclaw config set plugins.entries.openai.config.personality off
|
||||
**Best for:** direct API access and usage-based billing.
|
||||
Get your API key from the OpenAI dashboard.
|
||||
|
||||
Route summary:
|
||||
|
||||
- `openai/gpt-5.4` = direct OpenAI Platform API route
|
||||
- Requires `OPENAI_API_KEY` (or equivalent OpenAI provider config)
|
||||
- In OpenClaw, ChatGPT/Codex sign-in is routed through `openai-codex/*`, not `openai/*`
|
||||
|
||||
### CLI setup
|
||||
|
||||
```bash
|
||||
@@ -172,6 +178,12 @@ parameters, provider selection, and failover behavior.
|
||||
**Best for:** using ChatGPT/Codex subscription access instead of an API key.
|
||||
Codex cloud requires ChatGPT sign-in, while the Codex CLI supports ChatGPT or API key sign-in.
|
||||
|
||||
Route summary:
|
||||
|
||||
- `openai-codex/gpt-5.4` = ChatGPT/Codex OAuth route
|
||||
- Uses ChatGPT/Codex sign-in, not a direct OpenAI Platform API key
|
||||
- Provider-side limits for `openai-codex/*` can differ from the ChatGPT web/app experience
|
||||
|
||||
### CLI setup (Codex OAuth)
|
||||
|
||||
```bash
|
||||
@@ -193,6 +205,10 @@ openclaw models auth login --provider openai-codex
|
||||
OpenAI's current Codex docs list `gpt-5.4` as the current Codex model. OpenClaw
|
||||
maps that to `openai-codex/gpt-5.4` for ChatGPT/Codex OAuth usage.
|
||||
|
||||
This route is intentionally separate from `openai/gpt-5.4`. If you want the
|
||||
direct OpenAI Platform API path, use `openai/*` with an API key. If you want
|
||||
ChatGPT/Codex sign-in, use `openai-codex/*`.
|
||||
|
||||
If onboarding reuses an existing Codex CLI login, those credentials stay
|
||||
managed by Codex CLI. On expiry, OpenClaw re-reads the external Codex source
|
||||
first and, when the provider can refresh it, writes the refreshed credential
|
||||
|
||||
@@ -88,6 +88,46 @@ beforeEach(() => {
|
||||
});
|
||||
|
||||
describe("promptDefaultModel", () => {
|
||||
it("adds auth-route hints for OpenAI API and Codex OAuth models", async () => {
|
||||
loadModelCatalog.mockResolvedValue([
|
||||
{
|
||||
provider: "openai",
|
||||
id: "gpt-5.4",
|
||||
name: "GPT-5.4",
|
||||
},
|
||||
{
|
||||
provider: "openai-codex",
|
||||
id: "gpt-5.4",
|
||||
name: "GPT-5.4",
|
||||
},
|
||||
]);
|
||||
|
||||
const select = vi.fn(async (params) => params.initialValue as never);
|
||||
const prompter = makePrompter({ select });
|
||||
|
||||
await promptDefaultModel({
|
||||
config: { agents: { defaults: {} } } as OpenClawConfig,
|
||||
prompter,
|
||||
allowKeep: false,
|
||||
includeManual: false,
|
||||
ignoreAllowlist: true,
|
||||
});
|
||||
|
||||
const options = select.mock.calls[0]?.[0]?.options ?? [];
|
||||
expect(options).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
value: "openai/gpt-5.4",
|
||||
hint: expect.stringContaining("API key route"),
|
||||
}),
|
||||
expect.objectContaining({
|
||||
value: "openai-codex/gpt-5.4",
|
||||
hint: expect.stringContaining("ChatGPT OAuth route"),
|
||||
}),
|
||||
]),
|
||||
);
|
||||
});
|
||||
|
||||
it("treats byteplus plan models as preferred-provider matches", async () => {
|
||||
loadModelCatalog.mockResolvedValue([
|
||||
{
|
||||
|
||||
@@ -115,6 +115,17 @@ function normalizeModelKeys(values: string[]): string[] {
|
||||
return next;
|
||||
}
|
||||
|
||||
function resolveModelRouteHint(provider: string): string | undefined {
|
||||
const normalized = normalizeProviderId(provider);
|
||||
if (normalized === "openai") {
|
||||
return "API key route";
|
||||
}
|
||||
if (normalized === "openai-codex") {
|
||||
return "ChatGPT OAuth route";
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function addModelSelectOption(params: {
|
||||
entry: {
|
||||
provider: string;
|
||||
@@ -146,6 +157,10 @@ function addModelSelectOption(params: {
|
||||
if (aliases?.length) {
|
||||
hints.push(`alias: ${aliases.join(", ")}`);
|
||||
}
|
||||
const routeHint = resolveModelRouteHint(params.entry.provider);
|
||||
if (routeHint) {
|
||||
hints.push(routeHint);
|
||||
}
|
||||
if (!params.hasAuth(params.entry.provider)) {
|
||||
hints.push("auth missing");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user