



























@@ -1,11 +1,27 @@
11import fs from "node:fs/promises";
22import { embeddedAgentLog } from "openclaw/plugin-sdk/agent-harness-runtime";
3+import {
4+ensureAuthProfileStore,
5+resolveOpenClawAgentDir,
6+resolveProviderIdForAuth,
7+type AuthProfileStore,
8+} from "openclaw/plugin-sdk/agent-runtime";
39import type { CodexAppServerApprovalPolicy, CodexAppServerSandboxMode } from "./config.js";
410import type { CodexServiceTier } from "./protocol.js";
511612const CODEX_APP_SERVER_NATIVE_AUTH_PROVIDER = "openai-codex";
713const PUBLIC_OPENAI_MODEL_PROVIDER = "openai";
81415+type ProviderAuthAliasLookupParams = Parameters<typeof resolveProviderIdForAuth>[1];
16+type ProviderAuthAliasConfig = NonNullable<ProviderAuthAliasLookupParams>["config"];
17+18+export type CodexAppServerAuthProfileLookup = {
19+authProfileId?: string;
20+authProfileStore?: AuthProfileStore;
21+agentDir?: string;
22+config?: ProviderAuthAliasConfig;
23+};
24+925export type CodexAppServerThreadBinding = {
1026schemaVersion: 1;
1127threadId: string;
@@ -28,6 +44,7 @@ export function resolveCodexAppServerBindingPath(sessionFile: string): string {
28442945export async function readCodexAppServerBinding(
3046sessionFile: string,
47+lookup: Omit<CodexAppServerAuthProfileLookup, "authProfileId"> = {},
3148): Promise<CodexAppServerThreadBinding | undefined> {
3249const path = resolveCodexAppServerBindingPath(sessionFile);
3350let raw: string;
@@ -45,15 +62,18 @@ export async function readCodexAppServerBinding(
4562if (parsed.schemaVersion !== 1 || typeof parsed.threadId !== "string") {
4663return undefined;
4764}
65+const authProfileId =
66+typeof parsed.authProfileId === "string" ? parsed.authProfileId : undefined;
4867return {
4968schemaVersion: 1,
5069threadId: parsed.threadId,
5170 sessionFile,
5271cwd: typeof parsed.cwd === "string" ? parsed.cwd : "",
53-authProfileId: typeof parsed.authProfileId === "string" ? parsed.authProfileId : undefined,
72+ authProfileId,
5473model: typeof parsed.model === "string" ? parsed.model : undefined,
5574modelProvider: normalizeCodexAppServerBindingModelProvider({
56-authProfileId: typeof parsed.authProfileId === "string" ? parsed.authProfileId : undefined,
75+ ...lookup,
76+ authProfileId,
5777modelProvider: typeof parsed.modelProvider === "string" ? parsed.modelProvider : undefined,
5878}),
5979approvalPolicy: readApprovalPolicy(parsed.approvalPolicy),
@@ -80,6 +100,7 @@ export async function writeCodexAppServerBinding(
80100> & {
81101createdAt?: string;
82102},
103+lookup: Omit<CodexAppServerAuthProfileLookup, "authProfileId"> = {},
83104): Promise<void> {
84105const now = new Date().toISOString();
85106const payload: CodexAppServerThreadBinding = {
@@ -90,6 +111,7 @@ export async function writeCodexAppServerBinding(
90111authProfileId: binding.authProfileId,
91112model: binding.model,
92113modelProvider: normalizeCodexAppServerBindingModelProvider({
114+ ...lookup,
93115authProfileId: binding.authProfileId,
94116modelProvider: binding.modelProvider,
95117}),
@@ -120,32 +142,80 @@ function isNotFound(error: unknown): boolean {
120142return Boolean(error && typeof error === "object" && "code" in error && error.code === "ENOENT");
121143}
122144123-export function isCodexAppServerNativeAuthProfileId(authProfileId: string | undefined): boolean {
124-const normalized = authProfileId?.trim().toLowerCase();
125-return Boolean(
126-normalized &&
127-(normalized === CODEX_APP_SERVER_NATIVE_AUTH_PROVIDER ||
128-normalized.startsWith(`${CODEX_APP_SERVER_NATIVE_AUTH_PROVIDER}:`)),
129-);
145+export function isCodexAppServerNativeAuthProfile(
146+lookup: CodexAppServerAuthProfileLookup,
147+): boolean {
148+const authProfileId = lookup.authProfileId?.trim();
149+if (!authProfileId) {
150+return false;
151+}
152+try {
153+const credential = resolveCodexAppServerAuthProfileCredential({
154+ ...lookup,
155+ authProfileId,
156+});
157+return isCodexAppServerNativeAuthProvider({
158+provider: credential?.provider,
159+config: lookup.config,
160+});
161+} catch (error) {
162+embeddedAgentLog.debug("failed to resolve codex app-server auth profile provider", {
163+ authProfileId,
164+ error,
165+});
166+return false;
167+}
130168}
131169132170export function normalizeCodexAppServerBindingModelProvider(params: {
133171authProfileId?: string;
134172modelProvider?: string;
173+authProfileStore?: AuthProfileStore;
174+agentDir?: string;
175+config?: ProviderAuthAliasConfig;
135176}): string | undefined {
136177const modelProvider = params.modelProvider?.trim();
137178if (!modelProvider) {
138179return undefined;
139180}
140181if (
141-isCodexAppServerNativeAuthProfileId(params.authProfileId) &&
182+isCodexAppServerNativeAuthProfile(params) &&
142183modelProvider.toLowerCase() === PUBLIC_OPENAI_MODEL_PROVIDER
143184) {
144185return undefined;
145186}
146187return modelProvider;
147188}
148189190+function resolveCodexAppServerAuthProfileCredential(
191+lookup: CodexAppServerAuthProfileLookup,
192+): AuthProfileStore["profiles"][string] | undefined {
193+const authProfileId = lookup.authProfileId?.trim();
194+if (!authProfileId) {
195+return undefined;
196+}
197+const store = lookup.authProfileStore ?? loadCodexAppServerAuthProfileStore(lookup.agentDir);
198+return store.profiles[authProfileId];
199+}
200+201+function loadCodexAppServerAuthProfileStore(agentDir: string | undefined): AuthProfileStore {
202+return ensureAuthProfileStore(agentDir?.trim() || resolveOpenClawAgentDir(), {
203+allowKeychainPrompt: false,
204+});
205+}
206+207+function isCodexAppServerNativeAuthProvider(params: {
208+provider?: string;
209+config?: ProviderAuthAliasConfig;
210+}): boolean {
211+const provider = params.provider?.trim();
212+return Boolean(
213+provider &&
214+resolveProviderIdForAuth(provider, { config: params.config }) ===
215+CODEX_APP_SERVER_NATIVE_AUTH_PROVIDER,
216+);
217+}
218+149219function readApprovalPolicy(value: unknown): CodexAppServerApprovalPolicy | undefined {
150220return value === "never" ||
151221value === "on-request" ||
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。