diff --git a/extensions/codex/doctor-contract-api.ts b/extensions/codex/doctor-contract-api.ts index 63acb691d4fe..a89fd2615f79 100644 --- a/extensions/codex/doctor-contract-api.ts +++ b/extensions/codex/doctor-contract-api.ts @@ -1,3 +1,7 @@ +/** + * Doctor contract hooks for Codex plugin config migrations and session-route + * ownership warnings. + */ import type { OpenClawConfig } from "openclaw/plugin-sdk/config-contracts"; import type { DoctorSessionRouteStateOwner } from "openclaw/plugin-sdk/runtime-doctor"; @@ -17,6 +21,7 @@ function hasRetiredDynamicToolsProfile(value: unknown): boolean { return Object.hasOwn(asRecord(value) ?? {}, "codexDynamicToolsProfile"); } +/** Legacy Codex config keys that doctor should report or repair. */ export const legacyConfigRules: LegacyConfigRule[] = [ { path: ["plugins", "entries", "codex", "config"], @@ -26,6 +31,9 @@ export const legacyConfigRules: LegacyConfigRule[] = [ }, ]; +/** + * Removes retired Codex plugin config keys while preserving unrelated config. + */ export function normalizeCompatibilityConfig({ cfg }: { cfg: OpenClawConfig }): { config: OpenClawConfig; changes: string[]; @@ -56,6 +64,7 @@ export function normalizeCompatibilityConfig({ cfg }: { cfg: OpenClawConfig }): }; } +/** Session/auth ownership metadata used by doctor route-state checks. */ export const sessionRouteStateOwners: DoctorSessionRouteStateOwner[] = [ { id: "codex", diff --git a/extensions/codex/harness.ts b/extensions/codex/harness.ts index 9486a5db29d2..0e3164c9293b 100644 --- a/extensions/codex/harness.ts +++ b/extensions/codex/harness.ts @@ -1,3 +1,6 @@ +/** + * Codex app-server agent harness registration and lazy runtime boundaries. + */ import type { AgentHarness, ContextEngineHostCapability, @@ -19,8 +22,13 @@ const CODEX_APP_SERVER_CONTEXT_ENGINE_HOST_CAPABILITIES = [ "thread-bootstrap-projection", ] as const satisfies readonly ContextEngineHostCapability[]; +/** Public model-listing types exposed for Codex app-server catalog callers. */ export type { CodexAppServerListModelsOptions, CodexAppServerModel, CodexAppServerModelListResult }; +/** + * Creates the Codex app-server harness used for attempts, side questions, + * compaction, reset, and disposal. + */ export function createCodexAppServerAgentHarness(options?: { id?: string; label?: string; @@ -51,6 +59,8 @@ export function createCodexAppServerAgentHarness(options?: { }; }, runAttempt: async (params) => { + // Keep app-server runtime code behind lazy imports so plugin discovery and + // cold provider catalog reads do not pull in the whole Codex runtime. const { runCodexAppServerAttempt } = await import("./src/app-server/run-attempt.js"); return runCodexAppServerAttempt(params, { pluginConfig: options?.resolvePluginConfig?.() ?? options?.pluginConfig, diff --git a/extensions/codex/index.ts b/extensions/codex/index.ts index f85666a1b044..c0f43aec939c 100644 --- a/extensions/codex/index.ts +++ b/extensions/codex/index.ts @@ -1,3 +1,7 @@ +/** + * Bundled Codex plugin entry: app-server harness, model provider, media + * understanding, migration provider, CLI-session commands, and binding hooks. + */ import type { OpenClawConfig } from "openclaw/plugin-sdk/config-contracts"; import { mutateConfigFile } from "openclaw/plugin-sdk/config-mutation"; import { resolveLivePluginConfigObject } from "openclaw/plugin-sdk/plugin-config-runtime"; @@ -28,6 +32,8 @@ export default definePluginEntry({ const resolveCurrentConfig = () => api.runtime.config?.current ? (api.runtime.config.current() as OpenClawConfig) : undefined; const resolveCurrentPluginConfig = () => + // Codex plugin config can change at runtime; resolve from live config for + // harness attempts and binding claims instead of keeping startup values. resolveLivePluginConfigObject( resolveCurrentConfig, "codex", @@ -92,6 +98,8 @@ export default definePluginEntry({ mutate: async (update) => { await mutateConfigFile({ mutate: (draft) => { + // Create the nested plugin config path on demand so codex + // plugin commands can enable/update Codex-managed plugins. const root = draft as Record; root.plugins = (root.plugins ?? {}) as Record; const pluginsBlock = root.plugins as Record; diff --git a/extensions/codex/media-understanding-provider.ts b/extensions/codex/media-understanding-provider.ts index 4c78519a0b39..fda294292f14 100644 --- a/extensions/codex/media-understanding-provider.ts +++ b/extensions/codex/media-understanding-provider.ts @@ -1,3 +1,7 @@ +/** + * Codex-backed media understanding provider for bounded image description and + * structured extraction turns. + */ import { type JsonSchemaObject, validateJsonSchemaValue, @@ -39,11 +43,16 @@ const DEFAULT_CODEX_IMAGE_MODEL = FALLBACK_CODEX_MODELS[0]?.id; const DEFAULT_CODEX_IMAGE_PROMPT = "Describe the image."; +/** Dependencies and plugin config for Codex media-understanding calls. */ export type CodexMediaUnderstandingProviderOptions = { pluginConfig?: unknown; clientFactory?: CodexAppServerClientFactory; }; +/** + * Builds the media-understanding provider that delegates image tasks to an + * isolated Codex app-server session. + */ export function buildCodexMediaUnderstandingProvider( options: CodexMediaUnderstandingProviderOptions = {}, ): MediaUnderstandingProvider { @@ -127,6 +136,8 @@ async function runBoundedCodexVisionTurn(params: BoundedCodexVisionTurnParams): }); const timeoutMs = resolveTimerTimeoutMs(params.timeoutMs, 100, 100); const ownsClient = !params.options.clientFactory; + // Tests inject a client factory; production creates an isolated app-server + // client so media tasks cannot reuse the interactive attempt session. const client = params.options.clientFactory ? await params.options.clientFactory(appServer.start, params.profile) : await import("./src/app-server/shared-client.js").then( @@ -160,6 +171,8 @@ async function runBoundedCodexVisionTurn(params: BoundedCodexVisionTurnParams): sandbox: "read-only", serviceName: "OpenClaw", developerInstructions: params.developerInstructions, + // Media workers are bounded read-only turns; native code mode and + // dynamic tools stay disabled to avoid side effects while inspecting media. config: buildCodexRuntimeThreadConfig(undefined, { nativeCodeModeEnabled: false }), environments: [], dynamicTools: [], diff --git a/extensions/codex/prompt-overlay.ts b/extensions/codex/prompt-overlay.ts index 4ed7f60eb055..c38f3d218cbd 100644 --- a/extensions/codex/prompt-overlay.ts +++ b/extensions/codex/prompt-overlay.ts @@ -1,3 +1,6 @@ +/** + * Codex prompt-overlay facade for GPT-5 behavior and heartbeat guidance. + */ import { GPT5_BEHAVIOR_CONTRACT, GPT5_HEARTBEAT_PROMPT_OVERLAY, @@ -5,15 +8,19 @@ import { resolveGpt5SystemPromptContribution, } from "openclaw/plugin-sdk/provider-model-shared"; +/** GPT-5 behavior contract re-exported under the Codex provider namespace. */ export const CODEX_GPT5_BEHAVIOR_CONTRACT = GPT5_BEHAVIOR_CONTRACT; +/** Heartbeat prompt overlay re-exported under the Codex provider namespace. */ export const CODEX_GPT5_HEARTBEAT_PROMPT_OVERLAY = GPT5_HEARTBEAT_PROMPT_OVERLAY; +/** Resolves the Codex system-prompt contribution for GPT-5-family models. */ export function resolveCodexSystemPromptContribution( params: Parameters[0], ) { return resolveGpt5SystemPromptContribution(params); } +/** Renders the Codex prompt overlay text for supported GPT-5-family models. */ export function renderCodexPromptOverlay( params: Parameters[0], ): string | undefined { diff --git a/extensions/codex/provider-catalog.ts b/extensions/codex/provider-catalog.ts index 7b36f5b286d1..0f34c8161fb1 100644 --- a/extensions/codex/provider-catalog.ts +++ b/extensions/codex/provider-catalog.ts @@ -1,16 +1,23 @@ +/** + * Codex provider catalog constants and model definition helpers. + */ import type { ModelDefinitionConfig, ModelProviderConfig, } from "openclaw/plugin-sdk/provider-model-shared"; import type { CodexAppServerModel } from "./src/app-server/models.js"; +/** Provider id used by Codex model refs. */ export const CODEX_PROVIDER_ID = "codex"; +/** Synthetic base URL used to route Codex app-server model requests. */ export const CODEX_BASE_URL = "https://chatgpt.com/backend-api"; +/** Synthetic auth marker understood by Codex app-server runtime paths. */ export const CODEX_APP_SERVER_AUTH_MARKER = "codex-app-server"; const DEFAULT_CONTEXT_WINDOW = 272_000; const DEFAULT_MAX_TOKENS = 128_000; +/** Offline fallback catalog used when live app-server discovery is unavailable. */ export const FALLBACK_CODEX_MODELS = [ { id: "gpt-5.5", @@ -31,6 +38,9 @@ export const FALLBACK_CODEX_MODELS = [ }, ] satisfies CodexAppServerModel[]; +/** + * Converts a Codex app-server model record into OpenClaw provider model config. + */ export function buildCodexModelDefinition(model: { id: string; model: string; @@ -55,6 +65,7 @@ export function buildCodexModelDefinition(model: { }; } +/** Builds the synthetic Codex provider config for a model list. */ export function buildCodexProviderConfig(models: CodexAppServerModel[]): ModelProviderConfig { return { baseUrl: CODEX_BASE_URL, diff --git a/extensions/codex/provider-discovery.ts b/extensions/codex/provider-discovery.ts index 8666fe735629..2692a3639e91 100644 --- a/extensions/codex/provider-discovery.ts +++ b/extensions/codex/provider-discovery.ts @@ -1,3 +1,7 @@ +/** + * Static provider discovery entry for Codex, used before the full plugin entry + * is loaded. + */ import type { ProviderCatalogContext } from "openclaw/plugin-sdk/provider-catalog-shared"; import type { ProviderPlugin } from "openclaw/plugin-sdk/provider-model-shared"; import { @@ -20,6 +24,7 @@ async function runCodexCatalog(ctx: ProviderCatalogContext) { }); } +/** Provider discovery descriptor with static fallback and synthetic auth. */ export const codexProviderDiscovery: ProviderPlugin = { id: CODEX_PROVIDER_ID, label: "Codex", diff --git a/extensions/codex/provider.ts b/extensions/codex/provider.ts index d42d5d3934f5..4d7e6be66b78 100644 --- a/extensions/codex/provider.ts +++ b/extensions/codex/provider.ts @@ -1,3 +1,6 @@ +/** + * Codex provider plugin and live app-server model catalog discovery. + */ import { createSubsystemLogger } from "openclaw/plugin-sdk/core"; import { resolvePluginConfigObject } from "openclaw/plugin-sdk/plugin-config-runtime"; import type { ProviderRuntimeModel } from "openclaw/plugin-sdk/plugin-entry"; @@ -52,6 +55,10 @@ type BuildCatalogOptions = { onDiscoveryFailure?: (error: unknown) => void; }; +/** + * Builds the Codex provider plugin, including setup metadata, catalog discovery, + * dynamic model resolution, and prompt/thinking hooks. + */ export function buildCodexProvider(options: BuildCodexProviderOptions = {}): ProviderPlugin { return { id: CODEX_PROVIDER_ID, @@ -116,6 +123,10 @@ export function buildCodexProvider(options: BuildCodexProviderOptions = {}): Pro }; } +/** + * Builds the Codex model catalog from live app-server discovery, falling back + * to built-in model records when discovery is disabled or unavailable. + */ export async function buildCodexProviderCatalog( options: BuildCatalogOptions = {}, ): Promise<{ provider: ModelProviderConfig }> { @@ -166,6 +177,8 @@ async function listModelsBestEffort(params: { const models: CodexAppServerModel[] = []; let cursor: string | undefined; do { + // App-server model listing is paginated; collect every visible model so + // aliases and picker rows match the current Codex account. const result = await params.listModels({ timeoutMs: params.timeoutMs, limit: MODEL_DISCOVERY_PAGE_LIMIT, @@ -231,10 +244,10 @@ function isKnownXHighCodexModel(modelId: string): boolean { ); } -// Exported so adapter request paths (thread-lifecycle.resolveReasoningEffort) -// can branch on model-family enum support: modern Codex models use the -// none/low/medium/high/xhigh effort enum and reject "minimal", which is the -// CLI default. (#71946) +/** + * Returns true for Codex models that use the modern reasoning effort enum and + * reject the legacy CLI `minimal` default. + */ export function isModernCodexModel(modelId: string): boolean { const lower = modelId.trim().toLowerCase(); return (