Skip to content

Commit 53fe2e4

Browse files
committed
refactor(auth): simplify codex login follow-up
1 parent 26a756e commit 53fe2e4

6 files changed

Lines changed: 14 additions & 41 deletions

File tree

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
5f576203a58926c97b80e2ecab7a44a2021ab487b9ecbb2365bcede01935869b plugin-sdk-api-baseline.json
2-
674bb8dc19ddc39ed5571f38af4646ded5db3fba70eb57f33a8fd2cfe3f4d1bc plugin-sdk-api-baseline.jsonl
1+
1a66a755b98a7d4ff29fe7ccd19cd525c41677eccf1d954b0dc7ed71902e66bf plugin-sdk-api-baseline.json
2+
93efacdebaa86153a980ea0c1db713548aeed91ad6e76b914b899746896b1b32 plugin-sdk-api-baseline.jsonl

scripts/plugin-sdk-surface-report.mjs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -202,8 +202,8 @@ let publicDeprecatedExportsByEntrypointBudget;
202202
try {
203203
budgets = {
204204
publicEntrypoints: readBudgetEnv("OPENCLAW_PLUGIN_SDK_MAX_PUBLIC_ENTRYPOINTS", 323),
205-
publicExports: readBudgetEnv("OPENCLAW_PLUGIN_SDK_MAX_PUBLIC_EXPORTS", 10405),
206-
publicFunctionExports: readBudgetEnv("OPENCLAW_PLUGIN_SDK_MAX_PUBLIC_FUNCTION_EXPORTS", 5223),
205+
publicExports: readBudgetEnv("OPENCLAW_PLUGIN_SDK_MAX_PUBLIC_EXPORTS", 10409),
206+
publicFunctionExports: readBudgetEnv("OPENCLAW_PLUGIN_SDK_MAX_PUBLIC_FUNCTION_EXPORTS", 5224),
207207
publicDeprecatedExports: readBudgetEnv(
208208
"OPENCLAW_PLUGIN_SDK_MAX_PUBLIC_DEPRECATED_EXPORTS",
209209
3261,

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
// Tests channel-native Codex login command routing and pairing-code delivery.
21
import { beforeEach, describe, expect, it, vi } from "vitest";
32
import type { ModelsAuthLoginFlowOptions } from "../../commands/models/auth.js";
43
import type { OpenClawConfig } from "../../config/types.openclaw.js";

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

Lines changed: 10 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
/** Handles channel-native Codex/OpenAI login commands. */
21
import {
32
normalizeLowercaseStringOrEmpty,
43
normalizeOptionalString,
@@ -29,10 +28,6 @@ function parseLoginCommand(commandBodyNormalized: string): { providerInput: stri
2928
return { providerInput };
3029
}
3130

32-
function hasConfiguredCommandOwners(params: HandleCommandsParams): boolean {
33-
return codexChannelLoginRuntime.hasConfiguredCommandOwnerAllowlist(params.cfg);
34-
}
35-
3631
function hasInternalAdminScope(params: HandleCommandsParams): boolean {
3732
return (
3833
Array.isArray(params.ctx.GatewayClientScopes) &&
@@ -44,7 +39,8 @@ function canStartCodexLogin(params: HandleCommandsParams): boolean {
4439
return (
4540
params.command.isAuthorizedSender &&
4641
params.command.senderIsOwner &&
47-
(hasConfiguredCommandOwners(params) || hasInternalAdminScope(params))
42+
(codexChannelLoginRuntime.hasConfiguredCommandOwnerAllowlist(params.cfg) ||
43+
hasInternalAdminScope(params))
4844
);
4945
}
5046

@@ -132,10 +128,6 @@ function resolveLoginAgentId(params: HandleCommandsParams): string | undefined {
132128
);
133129
}
134130

135-
function buildFinalReply(status: string): ReplyPayload {
136-
return { text: status };
137-
}
138-
139131
async function emitLoginMessage(params: HandleCommandsParams, text: string): Promise<void> {
140132
const trimmed = text.trim();
141133
if (!trimmed) {
@@ -157,6 +149,12 @@ async function runChannelCodexLogin(params: {
157149
runtime?: RuntimeEnv;
158150
}): Promise<ReplyPayload> {
159151
const flowKey = buildCodexLoginFlowKey(params.commandParams, params.provider);
152+
if (!params.commandParams.opts?.onBlockReply) {
153+
return {
154+
text: "Codex login needs a live private response path so the code can be shown before it expires. Use the Web UI or a private chat and send `/login codex` again.",
155+
};
156+
}
157+
160158
const reservation = codexChannelLoginRuntime.reserveFlow({
161159
flows: activeCodexLoginFlows,
162160
flowKey,
@@ -166,16 +164,6 @@ async function runChannelCodexLogin(params: {
166164
text: "A Codex login code is already active for this chat or channel. Complete it, or wait for it to expire before requesting a new one.",
167165
};
168166
}
169-
if (!params.commandParams.opts?.onBlockReply) {
170-
codexChannelLoginRuntime.releaseFlow({
171-
flows: activeCodexLoginFlows,
172-
flowKey,
173-
record: reservation.record,
174-
});
175-
return {
176-
text: "Codex login needs a live private response path so the code can be shown before it expires. Use the Web UI or a private chat and send `/login codex` again.",
177-
};
178-
}
179167

180168
try {
181169
await codexChannelLoginRuntime.runDeviceLoginFlow({
@@ -188,11 +176,9 @@ async function runChannelCodexLogin(params: {
188176
unsupportedPromptMessage: "Channel /login supports only fixed Codex device-code auth.",
189177
runLoginFlow: params.runLoginFlow,
190178
});
191-
return buildFinalReply("Codex login complete. Try your request again now.");
179+
return { text: "Codex login complete. Try your request again now." };
192180
} catch {
193-
return buildFinalReply(
194-
"Codex login did not complete. Send `/login codex` to request a new code.",
195-
);
181+
return { text: "Codex login did not complete. Send `/login codex` to request a new code." };
196182
} finally {
197183
codexChannelLoginRuntime.releaseFlow({
198184
flows: activeCodexLoginFlows,

src/commands/models/auth.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -991,7 +991,6 @@ function maybeLogOpenAICodexNativeSearchTip(runtime: RuntimeEnv, providerId: str
991991
);
992992
}
993993

994-
/** Runs interactive provider auth login and persists returned profiles. */
995994
export async function runModelsAuthLoginFlow(
996995
opts: ModelsAuthLoginFlowOptions,
997996
): Promise<ModelsAuthLoginFlowResult> {
@@ -1099,7 +1098,6 @@ export async function runModelsAuthLoginFlow(
10991098
};
11001099
}
11011100

1102-
/** Runs interactive provider auth login and persists returned profiles. */
11031101
export async function modelsAuthLoginCommand(opts: LoginOptions, runtime: RuntimeEnv) {
11041102
if (!process.stdin.isTTY) {
11051103
throw new Error(

src/plugin-sdk/provider-auth-login-flow-runtime.ts

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
// Lazy runtime facade for channel-triggered provider auth login flows.
21
import {
32
normalizeLowercaseStringOrEmpty,
43
normalizeOptionalString,
@@ -37,11 +36,9 @@ const bindProviderAuthLoginFlowRuntime = createLazyRuntimeMethodBinder(
3736
loadProviderAuthLoginFlowRuntime,
3837
);
3938

40-
/** Runs provider login and persists returned auth profiles. Loaded lazily for channel /login. */
4139
export const runModelsAuthLoginFlow: ProviderAuthLoginFlowRuntime["runModelsAuthLoginFlow"] =
4240
bindProviderAuthLoginFlowRuntime((runtime) => runtime.runModelsAuthLoginFlow);
4341

44-
/** Normalizes channel login aliases to the provider that owns Codex ChatGPT auth. */
4542
function resolveCodexLoginProvider(rawProvider: string | undefined): string | null {
4643
const normalized = normalizeLowercaseStringOrEmpty(rawProvider ?? "codex").replace(/_/gu, "-");
4744
if (!normalized) {
@@ -50,13 +47,11 @@ function resolveCodexLoginProvider(rawProvider: string | undefined): string | nu
5047
return CODEX_LOGIN_PROVIDER_ALIASES.has(normalized) ? CODEX_LOGIN_PROVIDER : null;
5148
}
5249

53-
/** Checks whether command-owner login is explicitly configured. */
5450
function hasConfiguredCommandOwnerAllowlist(cfg: OpenClawConfig): boolean {
5551
const owners = cfg.commands?.ownerAllowFrom;
5652
return Array.isArray(owners) && owners.some((owner) => normalizeOptionalString(String(owner)));
5753
}
5854

59-
/** Keeps a pinned auth profile only when it belongs to the requested provider. */
6055
function resolveProviderScopedProfileId(
6156
authProfileOverride: string | undefined,
6257
provider: string,
@@ -71,7 +66,6 @@ function resolveProviderScopedProfileId(
7166
: undefined;
7267
}
7368

74-
/** Reserves a login flow key while preserving active non-expired flow dedupe. */
7569
function reserveCodexLoginFlow(params: {
7670
flows: Map<string, CodexLoginFlowRecord>;
7771
flowKey: string;
@@ -90,7 +84,6 @@ function reserveCodexLoginFlow(params: {
9084
return { status: "reserved", record };
9185
}
9286

93-
/** Releases a reserved login flow only if this caller still owns the reservation. */
9487
function releaseCodexLoginFlow(params: {
9588
flows: Map<string, CodexLoginFlowRecord>;
9689
flowKey: string;
@@ -101,7 +94,6 @@ function releaseCodexLoginFlow(params: {
10194
}
10295
}
10396

104-
/** Builds a fixed device-code prompter that can only emit text to the channel. */
10597
function buildCodexDeviceLoginPrompter(params: {
10698
sendMessage: (message: string) => Promise<void>;
10799
unsupportedPromptMessage: string;
@@ -133,7 +125,6 @@ function buildCodexDeviceLoginPrompter(params: {
133125
};
134126
}
135127

136-
/** Runs fixed Codex device-code login for private channel and Web UI surfaces. */
137128
async function runCodexDeviceLoginFlow(params: {
138129
provider: string;
139130
agentId: string;
@@ -160,7 +151,6 @@ async function runCodexDeviceLoginFlow(params: {
160151
});
161152
}
162153

163-
/** Shared private-channel Codex login helpers for text and native command surfaces. */
164154
export const codexChannelLoginRuntime = {
165155
resolveProvider: resolveCodexLoginProvider,
166156
hasConfiguredCommandOwnerAllowlist,

0 commit comments

Comments
 (0)