@stratusagent/provider-codex 0.9.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Stratus Labs
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,96 @@
1
+ # @stratusagent/provider-codex
2
+
3
+ ChatGPT/Codex runtime for Stratus Agent: runs turns through the OpenAI Codex
4
+ harness (`@openai/codex-sdk`), so a ChatGPT subscription covers usage — or an
5
+ OpenAI API key, when one is configured. The third provider shape in the stack:
6
+ a harness with its own inner loop, alongside the stateless OpenAI-compatible
7
+ adapter and the Claude Agent SDK runtime.
8
+
9
+ ## What it does
10
+
11
+ - Runs each turn as a codex thread (`startThread`/`resumeThread` +
12
+ `runStreamed`), recording the thread id in session metadata so later turns
13
+ resume instead of replaying the transcript — the same treatment
14
+ `provider-claude-code` gives its SDK session id, with the same recovery: a
15
+ thread codex no longer has replays kernel history into a fresh one, unless a
16
+ hosted tool already ran that turn.
17
+ - Renders the agent's persona, memory, and skills through the kernel's shared
18
+ `renderSystemPromptSections` and hands them to codex as
19
+ `developer_instructions`.
20
+ - Serves the session's kernel tools to the codex subprocess over a
21
+ **loopback MCP endpoint** (streamable HTTP on `127.0.0.1`, ephemeral port),
22
+ when the host supplies `executeTool`. Every tool call comes back through the
23
+ kernel's registry → approval policy → executor chain and is recorded in
24
+ session history; codex never executes anything itself.
25
+ - Streams item snapshots as kernel deltas: agent-message suffixes as text,
26
+ reasoning as content-free `thinking` progress, MCP tool starts as
27
+ `tool-call` — with wire names translated back to the kernel's own naming.
28
+ - Aborts a wedged subprocess on an inactivity timeout (default 10 minutes),
29
+ suspended while a hosted tool or approval wait is legitimately silent.
30
+ - Enforces the kernel's `maxTurns` as a hosted-tool budget (default 8):
31
+ codex has no native turn cap, so a call past the budget is refused at the
32
+ tool endpoint — a tool error, nothing executed — and the loop finishes
33
+ with what it has.
34
+
35
+ ## Stratus stays authoritative over tool execution
36
+
37
+ Codex ships its own shell, file editing, web search, and approval policy.
38
+ None of that is allowed to act here — the kernel chain is the only gate:
39
+
40
+ - `features.shell_tool = false` removes codex's exec tools entirely (and with
41
+ them file edits, which ride the shell in current codex); `view_image`,
42
+ `sleep_tool`, and lifecycle `hooks` are off; `web_search = "disabled"`; the
43
+ plan tool is off.
44
+ - The sandbox is pinned `read-only` and the approval policy `never`, as belt
45
+ and braces under the disabled tools.
46
+ - `project_doc_max_bytes = 0`: an AGENTS.md in the daemon's working directory
47
+ is repository content, not agent instructions.
48
+
49
+ ## The loopback MCP endpoint
50
+
51
+ Codex takes MCP servers as a spawned command or a streamable-HTTP URL; the
52
+ daemon hosts the URL form, so nothing is spawned and tool calls arrive back
53
+ in-process. What authenticates the socket:
54
+
55
+ - a fresh 256-bit bearer token per turn, carried to the codex subprocess only
56
+ through its environment (`bearer_token_env_var`), never in configuration or
57
+ argv;
58
+ - every request must present it (constant-time comparison), and non-loopback
59
+ connections are refused outright;
60
+ - the server exists only for the duration of the turn and serves only that
61
+ turn's session and tool allowlist, so a leaked URL is useless once the turn
62
+ ends. Reading the token would take reading the subprocess's environment,
63
+ which is owner-only — the same trust boundary as `~/.stratus` itself.
64
+
65
+ ## Billing
66
+
67
+ - **ChatGPT subscription** (default): no `apiKey` configured. The codex
68
+ binary uses the machine's own `codex login` sign-in from its auth store
69
+ under `~/.codex`; Stratus never reads or stores those tokens. An ambient
70
+ `CODEX_API_KEY` is scrubbed from the subprocess in this mode so a
71
+ subscription run can never silently become metered.
72
+ - **OpenAI API key**: pass `apiKey` (an OpenAI platform key); it reaches the
73
+ binary as `CODEX_API_KEY`, which codex's exec mode honors above any other
74
+ auth.
75
+
76
+ ## Usage
77
+
78
+ ```ts
79
+ import { createCodexProvider } from '@stratusagent/provider-codex';
80
+
81
+ const provider = createCodexProvider({
82
+ // apiKey: 'sk-…', // omit to use the machine's codex login
83
+ model: 'gpt-5.5',
84
+ executeTool: (session, call, context) =>
85
+ runner.executeHostedToolCall(session, call, context),
86
+ });
87
+ ```
88
+
89
+ Most hosts never construct it directly: `createRuntimeProvider` in
90
+ `@stratusagent/state` selects it for `provider: "codex"`, and `stratus setup`
91
+ stores the sign-in.
92
+
93
+ Requires the codex binary, which `@openai/codex-sdk` bundles per platform
94
+ (`codexPathOverride` points at a different one). The `runTurn` option is the
95
+ test seam — inject a fake to drive the provider, MCP endpoint included,
96
+ without launching codex.
@@ -0,0 +1,172 @@
1
+ import { type ExecutionContext, type JsonObject, type ModelProvider, type Session, type ToolDescriptor } from '@stratusagent/core';
2
+ import { type HostedToolExecutor } from '@stratusagent/providers';
3
+ /** The codex CLI's own current default model. */
4
+ export declare const DEFAULT_CODEX_MODEL = "gpt-5.5";
5
+ /**
6
+ * The environment variable the codex subprocess reads the MCP bearer token
7
+ * from (`mcp_servers.stratus.bearer_token_env_var`). The token itself is
8
+ * minted per turn and never appears in configuration or on a command line.
9
+ */
10
+ export declare const MCP_TOKEN_ENV_VAR = "STRATUS_CODEX_MCP_TOKEN";
11
+ /**
12
+ * Executes one kernel tool call on behalf of the Codex loop. The host owns
13
+ * approvals, events, allowlists, and the executor —
14
+ * AgentRunner.executeHostedToolCall is the canonical implementation.
15
+ */
16
+ export type CodexToolExecutor = HostedToolExecutor;
17
+ export interface KernelMcpServerOptions {
18
+ descriptors: readonly ToolDescriptor[];
19
+ session: Session;
20
+ executeTool: CodexToolExecutor;
21
+ context?: ExecutionContext;
22
+ instructions?: string;
23
+ }
24
+ export interface KernelMcpServer {
25
+ /** The streamable-HTTP endpoint, bound to 127.0.0.1 on an ephemeral port. */
26
+ url: string;
27
+ /** The bearer token every request must present. */
28
+ token: string;
29
+ close(): Promise<void>;
30
+ }
31
+ /**
32
+ * Serves the session's kernel tools over MCP streamable HTTP for the codex
33
+ * subprocess. Exported for tests, which drive it with plain fetch — the
34
+ * same protocol slice codex's client speaks: JSON-RPC over POST, JSON
35
+ * responses, 202 for notifications.
36
+ */
37
+ export declare const startKernelMcpServer: (options: KernelMcpServerOptions) => Promise<KernelMcpServer>;
38
+ /**
39
+ * The slice of the Codex SDK's thread event stream this provider consumes
40
+ * (`codex exec --json` events). Kept loose so tests can inject a plain
41
+ * async generator.
42
+ */
43
+ export interface CodexThreadEvent {
44
+ type: string;
45
+ /** On `thread.started`: the codex thread id later turns resume. */
46
+ thread_id?: string;
47
+ /** On `turn.failed`. */
48
+ error?: {
49
+ message?: string;
50
+ };
51
+ /** On a top-level `error` event. */
52
+ message?: string;
53
+ item?: {
54
+ id?: string;
55
+ type?: string;
56
+ /** agent_message / reasoning text, a snapshot that grows across updates. */
57
+ text?: string;
58
+ /** mcp_tool_call: the server and wire tool name being invoked. */
59
+ server?: string;
60
+ tool?: string;
61
+ status?: string;
62
+ };
63
+ }
64
+ /** What the provider passes the Codex SDK client for one turn. */
65
+ export interface CodexClientOptions {
66
+ /** Config overrides for the codex binary (flattened to `-c key=value`). */
67
+ config: JsonObject;
68
+ /** OpenAI API key for metered billing (CODEX_API_KEY). Absent = ChatGPT sign-in. */
69
+ apiKey?: string;
70
+ /**
71
+ * The full environment for the codex subprocess — the SDK replaces the
72
+ * child environment rather than merging into it.
73
+ */
74
+ env: Record<string, string>;
75
+ codexPathOverride?: string;
76
+ }
77
+ export interface CodexThreadOptions {
78
+ model: string;
79
+ sandboxMode: 'read-only';
80
+ approvalPolicy: 'never';
81
+ skipGitRepoCheck: true;
82
+ }
83
+ export interface CodexTurnParams {
84
+ input: string;
85
+ /** Codex thread id to resume; absent starts a fresh thread. */
86
+ resumeThreadId?: string;
87
+ clientOptions: CodexClientOptions;
88
+ threadOptions: CodexThreadOptions;
89
+ signal: AbortSignal;
90
+ }
91
+ /**
92
+ * Runs one codex turn and yields its thread events. The default
93
+ * implementation wraps `@openai/codex-sdk`; tests (and embedders pinning
94
+ * their own transport) inject a fake.
95
+ */
96
+ export type CodexRunTurn = (params: CodexTurnParams) => AsyncIterable<CodexThreadEvent>;
97
+ export interface CodexProviderConfig {
98
+ /**
99
+ * OpenAI API key for metered billing, handed to the harness as
100
+ * CODEX_API_KEY. Omit to use the machine's existing `codex login`
101
+ * (ChatGPT subscription) sign-in.
102
+ */
103
+ apiKey?: string;
104
+ /** Defaults to gpt-5.5. */
105
+ model?: string;
106
+ name?: string;
107
+ /** Extra system prompt, rendered before the agent's own persona. */
108
+ systemPrompt?: string;
109
+ /**
110
+ * Executes kernel tool calls for the Codex loop. When set, the request's
111
+ * tools are served to the subprocess over a loopback MCP endpoint;
112
+ * without it runs stay text-only.
113
+ */
114
+ executeTool?: CodexToolExecutor;
115
+ /** Path to a specific codex executable (the SDK's bundled one otherwise). */
116
+ codexPathOverride?: string;
117
+ /**
118
+ * Hosted tool calls allowed per generate. Codex has no native turn cap,
119
+ * so the limit is enforced where the kernel holds the loop anyway — the
120
+ * tool endpoint: a call past the budget is refused as a tool error, not
121
+ * executed, and codex finishes with what it has. Defaults to 8, the same
122
+ * budget the Claude Code runtime gives its inner loop.
123
+ */
124
+ maxTurns?: number;
125
+ /** Test injection point; defaults to the real Codex SDK. */
126
+ runTurn?: CodexRunTurn;
127
+ /**
128
+ * Abort a run when the event stream yields nothing for this long — a
129
+ * wedged subprocess must not pin a turn (and a draining daemon) open
130
+ * forever. Inactivity-based, so a healthy long run that keeps producing
131
+ * events stays alive; suspended while a hosted tool (approval waits
132
+ * included) is executing. 0 disables. Default 10 minutes.
133
+ */
134
+ idleTimeoutMs?: number;
135
+ /**
136
+ * Called when a stored codex thread could not be resumed and the turn is
137
+ * about to replay the kernel's history into a fresh one instead. The
138
+ * conversation continues either way; this exists so a host can say so
139
+ * rather than leave a silently more expensive turn unexplained.
140
+ */
141
+ onResumeFailed?: (error: unknown) => void;
142
+ }
143
+ /**
144
+ * Where a session records the codex thread it is continuing.
145
+ *
146
+ * The kernel's session id is ours and durable; the thread id is codex's
147
+ * and lives beside its transcript under `~/.codex/sessions`. Storing the
148
+ * link in session metadata means it survives tool execution, approval
149
+ * waits, and a daemon restart, and is garbage-collected with the session —
150
+ * the same treatment the Claude Code provider gives its SDK session id.
151
+ */
152
+ export declare const CODEX_THREAD_METADATA_KEY = "codexThreadId";
153
+ /**
154
+ * Runs turns through the OpenAI Codex harness (`@openai/codex-sdk`), so a
155
+ * ChatGPT subscription covers usage instead of per-token API billing — or
156
+ * an OpenAI API key, when one is configured.
157
+ *
158
+ * The agent's persona and memory render as codex developer instructions,
159
+ * and kernel tools are served to the subprocess over a loopback MCP
160
+ * endpoint when the host supplies `executeTool` — approvals, allowlists,
161
+ * and events all run on the host side, so this runtime is the same agent
162
+ * as every other provider.
163
+ *
164
+ * Stratus stays authoritative over tool execution: codex's own shell (and
165
+ * with it file edits), web search, image reads, and lifecycle hooks are
166
+ * disabled outright, its sandbox is pinned read-only and its approval
167
+ * policy to `never`, so the kernel's registry → approval → executor chain
168
+ * is the only thing that can act. AGENTS.md discovery is disabled for the
169
+ * same reason: repository content is not agent instructions.
170
+ */
171
+ export declare const createCodexProvider: ({ apiKey, model, name, systemPrompt, executeTool, codexPathOverride, maxTurns, runTurn, idleTimeoutMs, onResumeFailed, }?: CodexProviderConfig) => ModelProvider;
172
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js ADDED
@@ -0,0 +1,577 @@
1
+ import { randomBytes, randomUUID, timingSafeEqual } from 'node:crypto';
2
+ import { createServer } from 'node:http';
3
+ import { renderSystemPromptSections, } from '@stratusagent/core';
4
+ import { bridgedToolNames, latestUserMessagePrompt, markHostedToolSideEffects, renderTranscriptPrompt, } from '@stratusagent/providers';
5
+ /** The codex CLI's own current default model. */
6
+ export const DEFAULT_CODEX_MODEL = 'gpt-5.5';
7
+ const MCP_SERVER_NAME = 'stratus';
8
+ /**
9
+ * The environment variable the codex subprocess reads the MCP bearer token
10
+ * from (`mcp_servers.stratus.bearer_token_env_var`). The token itself is
11
+ * minted per turn and never appears in configuration or on a command line.
12
+ */
13
+ export const MCP_TOKEN_ENV_VAR = 'STRATUS_CODEX_MCP_TOKEN';
14
+ const DEFAULT_IDLE_TIMEOUT_MS = 600_000;
15
+ /** Hosted tool calls per generate when the host sets no explicit budget. */
16
+ const DEFAULT_TOOL_MAX_TURNS = 8;
17
+ const LOOPBACK_ADDRESSES = new Set(['127.0.0.1', '::1', '::ffff:127.0.0.1']);
18
+ /** Requests larger than this are refused: tool inputs are small. */
19
+ const MAX_MCP_BODY_BYTES = 10 * 1024 * 1024;
20
+ const readBody = (req) => new Promise((resolve, reject) => {
21
+ const chunks = [];
22
+ let size = 0;
23
+ req.on('data', (chunk) => {
24
+ size += chunk.length;
25
+ if (size > MAX_MCP_BODY_BYTES) {
26
+ reject(new Error('MCP request body too large'));
27
+ req.destroy();
28
+ return;
29
+ }
30
+ chunks.push(chunk);
31
+ });
32
+ req.on('end', () => resolve(Buffer.concat(chunks)));
33
+ req.on('error', reject);
34
+ });
35
+ const sendJson = (res, status, body) => {
36
+ const payload = JSON.stringify(body);
37
+ res.writeHead(status, {
38
+ 'content-type': 'application/json',
39
+ 'content-length': Buffer.byteLength(payload),
40
+ });
41
+ res.end(payload);
42
+ };
43
+ const jsonRpcResult = (id, result) => ({
44
+ jsonrpc: '2.0',
45
+ id,
46
+ result,
47
+ });
48
+ const jsonRpcError = (id, code, message) => ({
49
+ jsonrpc: '2.0',
50
+ id,
51
+ error: { code, message },
52
+ });
53
+ const bearerTokenMatches = (header, token) => {
54
+ if (typeof header !== 'string' || !header.startsWith('Bearer ')) {
55
+ return false;
56
+ }
57
+ const presented = Buffer.from(header.slice('Bearer '.length));
58
+ const expected = Buffer.from(token);
59
+ return presented.length === expected.length && timingSafeEqual(presented, expected);
60
+ };
61
+ /**
62
+ * Serves the session's kernel tools over MCP streamable HTTP for the codex
63
+ * subprocess. Exported for tests, which drive it with plain fetch — the
64
+ * same protocol slice codex's client speaks: JSON-RPC over POST, JSON
65
+ * responses, 202 for notifications.
66
+ */
67
+ export const startKernelMcpServer = async (options) => {
68
+ const token = randomBytes(32).toString('hex');
69
+ // The kernel loop executes tools one at a time; hosted execution keeps
70
+ // that contract. Concurrent MCP calls would race a single interactive
71
+ // approval prompt — and each other's side effects.
72
+ let queue = Promise.resolve();
73
+ const serialize = (task) => {
74
+ const run = queue.then(task, task);
75
+ queue = run.then(() => undefined, () => undefined);
76
+ return run;
77
+ };
78
+ const wireNames = bridgedToolNames(options.descriptors);
79
+ const byWireName = new Map();
80
+ for (const descriptor of options.descriptors) {
81
+ const wireName = wireNames.get(descriptor.name);
82
+ if (wireName !== undefined) {
83
+ byWireName.set(wireName, descriptor);
84
+ }
85
+ }
86
+ const handleRequest = async (message) => {
87
+ if (message.method === 'initialize') {
88
+ const requested = message.params?.protocolVersion;
89
+ return jsonRpcResult(message.id, {
90
+ // Echo the client's protocol version: the only client this socket
91
+ // admits is the codex subprocess this daemon just configured.
92
+ protocolVersion: typeof requested === 'string' ? requested : '2025-06-18',
93
+ capabilities: { tools: {} },
94
+ serverInfo: { name: MCP_SERVER_NAME, version: '1.0.0' },
95
+ ...(options.instructions ? { instructions: options.instructions } : {}),
96
+ });
97
+ }
98
+ if (message.method === 'ping') {
99
+ return jsonRpcResult(message.id, {});
100
+ }
101
+ if (message.method === 'tools/list') {
102
+ return jsonRpcResult(message.id, {
103
+ tools: options.descriptors.map((descriptor) => ({
104
+ name: wireNames.get(descriptor.name) ?? descriptor.name,
105
+ description: descriptor.description ?? `Stratus tool ${descriptor.name}`,
106
+ inputSchema: descriptor.parameters ?? { type: 'object', properties: {} },
107
+ })),
108
+ });
109
+ }
110
+ if (message.method === 'tools/call') {
111
+ const wireName = message.params?.name;
112
+ const descriptor = typeof wireName === 'string' ? byWireName.get(wireName) : undefined;
113
+ if (!descriptor) {
114
+ return jsonRpcError(message.id, -32602, `Unknown tool: ${String(wireName)}`);
115
+ }
116
+ const input = message.params?.arguments;
117
+ try {
118
+ const result = await serialize(() => options.executeTool(options.session, {
119
+ id: `codex:${randomUUID()}`,
120
+ toolName: descriptor.name,
121
+ input: (typeof input === 'object' && input !== null && !Array.isArray(input) ? input : {}),
122
+ }, options.context));
123
+ return jsonRpcResult(message.id, {
124
+ content: [
125
+ {
126
+ type: 'text',
127
+ text: JSON.stringify(result.ok ? result.output : { error: result.error ?? 'Tool failed.' }),
128
+ },
129
+ ],
130
+ ...(result.ok ? {} : { isError: true }),
131
+ });
132
+ }
133
+ catch (error) {
134
+ return jsonRpcError(message.id, -32603, error instanceof Error ? error.message : String(error));
135
+ }
136
+ }
137
+ return jsonRpcError(message.id, -32601, `Method not found: ${message.method}`);
138
+ };
139
+ const server = createServer((req, res) => {
140
+ void (async () => {
141
+ if (!LOOPBACK_ADDRESSES.has(req.socket.remoteAddress ?? '')) {
142
+ sendJson(res, 403, jsonRpcError(null, -32000, 'Loopback connections only'));
143
+ return;
144
+ }
145
+ if (!bearerTokenMatches(req.headers.authorization, token)) {
146
+ // No WWW-Authenticate header on purpose: the one legitimate client
147
+ // already holds the token, and an OAuth discovery dance is not on
148
+ // offer here.
149
+ sendJson(res, 401, jsonRpcError(null, -32000, 'Unauthorized'));
150
+ return;
151
+ }
152
+ if (req.method !== 'POST') {
153
+ // The client MAY open a GET SSE stream for server-initiated
154
+ // messages; this server never initiates, so it declines, which the
155
+ // protocol allows.
156
+ sendJson(res, 405, jsonRpcError(null, -32000, 'POST only'));
157
+ return;
158
+ }
159
+ let message;
160
+ try {
161
+ message = JSON.parse((await readBody(req)).toString('utf8'));
162
+ }
163
+ catch {
164
+ sendJson(res, 400, jsonRpcError(null, -32700, 'Parse error'));
165
+ return;
166
+ }
167
+ if (typeof message !== 'object' || message === null || Array.isArray(message)) {
168
+ sendJson(res, 400, jsonRpcError(null, -32600, 'A single JSON-RPC message is required'));
169
+ return;
170
+ }
171
+ const rpc = message;
172
+ if (typeof rpc.method !== 'string') {
173
+ // A response or malformed frame; nothing to do with it.
174
+ res.writeHead(202).end();
175
+ return;
176
+ }
177
+ if (rpc.id === undefined || rpc.id === null) {
178
+ // Notifications (notifications/initialized, cancellations) are
179
+ // acknowledged and otherwise ignored: tool execution state lives
180
+ // in the kernel, which has its own cancellation.
181
+ res.writeHead(202).end();
182
+ return;
183
+ }
184
+ sendJson(res, 200, await handleRequest({ id: rpc.id, method: rpc.method, ...(rpc.params !== undefined ? { params: rpc.params } : {}) }));
185
+ })().catch(() => {
186
+ if (!res.headersSent) {
187
+ sendJson(res, 500, jsonRpcError(null, -32603, 'Internal error'));
188
+ }
189
+ else {
190
+ res.end();
191
+ }
192
+ });
193
+ });
194
+ await new Promise((resolve, reject) => {
195
+ server.once('error', reject);
196
+ server.listen(0, '127.0.0.1', resolve);
197
+ });
198
+ const address = server.address();
199
+ return {
200
+ url: `http://127.0.0.1:${address.port}/mcp`,
201
+ token,
202
+ close: () => new Promise((resolve) => {
203
+ // A wedged subprocess must not be able to hold the daemon's
204
+ // shutdown hostage through a kept-alive connection.
205
+ server.close(() => resolve());
206
+ server.closeAllConnections();
207
+ }),
208
+ };
209
+ };
210
+ const runTurnWithSdk = async function* (params) {
211
+ let sdk;
212
+ try {
213
+ sdk = (await import('@openai/codex-sdk'));
214
+ }
215
+ catch (error) {
216
+ throw new Error(`The Codex SDK could not be loaded (${error instanceof Error ? error.message : String(error)}). Install @openai/codex-sdk where Stratus runs.`);
217
+ }
218
+ const codex = new sdk.Codex({
219
+ config: params.clientOptions.config,
220
+ env: params.clientOptions.env,
221
+ ...(params.clientOptions.apiKey ? { apiKey: params.clientOptions.apiKey } : {}),
222
+ ...(params.clientOptions.codexPathOverride
223
+ ? { codexPathOverride: params.clientOptions.codexPathOverride }
224
+ : {}),
225
+ });
226
+ const thread = params.resumeThreadId
227
+ ? codex.resumeThread(params.resumeThreadId, params.threadOptions)
228
+ : codex.startThread(params.threadOptions);
229
+ const { events } = await thread.runStreamed(params.input, { signal: params.signal });
230
+ yield* events;
231
+ };
232
+ /**
233
+ * Where a session records the codex thread it is continuing.
234
+ *
235
+ * The kernel's session id is ours and durable; the thread id is codex's
236
+ * and lives beside its transcript under `~/.codex/sessions`. Storing the
237
+ * link in session metadata means it survives tool execution, approval
238
+ * waits, and a daemon restart, and is garbage-collected with the session —
239
+ * the same treatment the Claude Code provider gives its SDK session id.
240
+ */
241
+ export const CODEX_THREAD_METADATA_KEY = 'codexThreadId';
242
+ const readThreadId = (session) => {
243
+ const stored = session.metadata?.[CODEX_THREAD_METADATA_KEY];
244
+ return typeof stored === 'string' && stored.length > 0 ? stored : undefined;
245
+ };
246
+ const rememberThreadId = (session, id) => {
247
+ (session.metadata ??= {})[CODEX_THREAD_METADATA_KEY] = id;
248
+ };
249
+ // One shared reading of what an agent is told about itself — persona,
250
+ // memory, skills — rendered by the kernel rather than per provider package.
251
+ // This runtime always sends instructions, so an agent with no persona gets
252
+ // the shared default line.
253
+ const createInstructions = (request, systemPrompt) => renderSystemPromptSections(request, {
254
+ ...(systemPrompt ? { preamble: systemPrompt } : {}),
255
+ fallbackPersona: true,
256
+ }).join('\n\n');
257
+ // Forwards the kernel's abort signal into an AbortController the SDK
258
+ // understands, so aborting a turn kills the underlying subprocess.
259
+ const linkedAbortController = (signal) => {
260
+ const controller = new AbortController();
261
+ if (signal.aborted) {
262
+ controller.abort();
263
+ }
264
+ else {
265
+ signal.addEventListener('abort', () => controller.abort(), { once: true });
266
+ }
267
+ return controller;
268
+ };
269
+ /**
270
+ * The environment for the codex subprocess. The SDK *replaces* the child
271
+ * environment with what it is given, so the daemon's own environment is
272
+ * carried (codex needs HOME/CODEX_HOME to find its sign-in) — and the auth
273
+ * posture is pinned on top: without a configured API key this provider is
274
+ * subscription-billed, so an ambient CODEX_API_KEY must never silently
275
+ * turn a run into metered API usage.
276
+ */
277
+ const buildSubprocessEnv = (apiKeyConfigured, mcpToken) => {
278
+ const env = {};
279
+ for (const [key, value] of Object.entries(process.env)) {
280
+ if (typeof value === 'string') {
281
+ env[key] = value;
282
+ }
283
+ }
284
+ if (!apiKeyConfigured) {
285
+ delete env.CODEX_API_KEY;
286
+ }
287
+ if (mcpToken !== undefined) {
288
+ env[MCP_TOKEN_ENV_VAR] = mcpToken;
289
+ }
290
+ return env;
291
+ };
292
+ /**
293
+ * Runs turns through the OpenAI Codex harness (`@openai/codex-sdk`), so a
294
+ * ChatGPT subscription covers usage instead of per-token API billing — or
295
+ * an OpenAI API key, when one is configured.
296
+ *
297
+ * The agent's persona and memory render as codex developer instructions,
298
+ * and kernel tools are served to the subprocess over a loopback MCP
299
+ * endpoint when the host supplies `executeTool` — approvals, allowlists,
300
+ * and events all run on the host side, so this runtime is the same agent
301
+ * as every other provider.
302
+ *
303
+ * Stratus stays authoritative over tool execution: codex's own shell (and
304
+ * with it file edits), web search, image reads, and lifecycle hooks are
305
+ * disabled outright, its sandbox is pinned read-only and its approval
306
+ * policy to `never`, so the kernel's registry → approval → executor chain
307
+ * is the only thing that can act. AGENTS.md discovery is disabled for the
308
+ * same reason: repository content is not agent instructions.
309
+ */
310
+ export const createCodexProvider = ({ apiKey, model = DEFAULT_CODEX_MODEL, name = 'codex', systemPrompt, executeTool, codexPathOverride, maxTurns, runTurn = runTurnWithSdk, idleTimeoutMs = DEFAULT_IDLE_TIMEOUT_MS, onResumeFailed, } = {}) => ({
311
+ name,
312
+ async generate(request) {
313
+ const controller = request.signal
314
+ ? linkedAbortController(request.signal)
315
+ : new AbortController();
316
+ // A wedged subprocess yields nothing forever; the idle timer cuts it
317
+ // loose. It resets on every event so healthy long runs stay alive, and
318
+ // it suspends entirely while a hosted tool (approval waits included)
319
+ // is executing — those phases legitimately produce no codex output for
320
+ // as long as they need.
321
+ let timedOutIdle = false;
322
+ let idleTimer;
323
+ let activeHostedTools = 0;
324
+ const suspendIdleTimer = () => {
325
+ if (idleTimer) {
326
+ clearTimeout(idleTimer);
327
+ idleTimer = undefined;
328
+ }
329
+ };
330
+ const resetIdleTimer = () => {
331
+ // Never after the abort: the turn is over (or already being cut
332
+ // loose), and a hosted call settling late must not re-arm a timer
333
+ // the finally below has already cleared — a leaked ten-minute timer
334
+ // pins the process for exactly that long.
335
+ if (idleTimeoutMs <= 0 || activeHostedTools > 0 || controller.signal.aborted) {
336
+ return;
337
+ }
338
+ if (idleTimer) {
339
+ clearTimeout(idleTimer);
340
+ }
341
+ idleTimer = setTimeout(() => {
342
+ timedOutIdle = true;
343
+ controller.abort();
344
+ }, idleTimeoutMs);
345
+ };
346
+ let hostedToolRuns = 0;
347
+ const toolBudget = maxTurns ?? DEFAULT_TOOL_MAX_TURNS;
348
+ const countedExecute = executeTool
349
+ ? async (session, call, context) => {
350
+ // The budget is the kernel's max-turns limit, enforced at the one
351
+ // gate every codex tool call passes: past it, the call is refused
352
+ // (a tool error, with nothing executed and no side effects), so
353
+ // the inner loop is bounded the same way the outer runner's is.
354
+ if (hostedToolRuns >= toolBudget) {
355
+ return {
356
+ callId: call.id,
357
+ toolName: call.toolName,
358
+ ok: false,
359
+ output: null,
360
+ error: `Turn budget exhausted: this run already made ${toolBudget} hosted tool call${toolBudget === 1 ? '' : 's'}. Answer with what you have.`,
361
+ };
362
+ }
363
+ hostedToolRuns += 1;
364
+ activeHostedTools += 1;
365
+ suspendIdleTimer();
366
+ try {
367
+ return await executeTool(session, call, context);
368
+ }
369
+ finally {
370
+ activeHostedTools -= 1;
371
+ resetIdleTimer();
372
+ }
373
+ }
374
+ : undefined;
375
+ const markIfSideEffects = (error) => (hostedToolRuns > 0 ? markHostedToolSideEffects(error) : error);
376
+ // The abort signal riding into every hosted tool call is the provider's
377
+ // own controller — the union of the caller's cancellation and the idle
378
+ // timeout — so hosted work never outlives the subprocess around it.
379
+ const mcp = countedExecute && request.tools && request.tools.length > 0
380
+ ? await startKernelMcpServer({
381
+ descriptors: request.tools,
382
+ session: request.session,
383
+ executeTool: countedExecute,
384
+ context: { signal: controller.signal },
385
+ instructions: 'Tools provided by the Stratus Agent runtime. Use them when they help; results return as JSON.',
386
+ })
387
+ : undefined;
388
+ const instructions = createInstructions(request, systemPrompt);
389
+ const clientOptions = {
390
+ config: {
391
+ // Stratus owns the tool surface. `shell_tool` off removes codex's
392
+ // exec tools entirely (and with them file edits, which ride the
393
+ // shell in current codex); web search, the image reader, the plan
394
+ // and sleep tools, and lifecycle hooks are off for the same
395
+ // reason. The read-only sandbox and `approval_policy = never` in
396
+ // the thread options below are belt and braces, not the gate.
397
+ features: { shell_tool: false, view_image: false, sleep_tool: false, hooks: false },
398
+ web_search: 'disabled',
399
+ tools: { update_plan: { enabled: false } },
400
+ // An AGENTS.md in the daemon's working directory is repository
401
+ // content, not agent instructions.
402
+ project_doc_max_bytes: 0,
403
+ developer_instructions: instructions,
404
+ ...(mcp
405
+ ? {
406
+ mcp_servers: {
407
+ [MCP_SERVER_NAME]: {
408
+ url: mcp.url,
409
+ bearer_token_env_var: MCP_TOKEN_ENV_VAR,
410
+ // A tool endpoint that fails to connect must fail the
411
+ // run, not silently strip the agent of its tools.
412
+ required: true,
413
+ },
414
+ },
415
+ }
416
+ : {}),
417
+ },
418
+ env: buildSubprocessEnv(apiKey !== undefined, mcp?.token),
419
+ ...(apiKey ? { apiKey } : {}),
420
+ ...(codexPathOverride ? { codexPathOverride } : {}),
421
+ };
422
+ const threadOptions = {
423
+ model,
424
+ sandboxMode: 'read-only',
425
+ approvalPolicy: 'never',
426
+ skipGitRepoCheck: true,
427
+ };
428
+ // Reply text accumulates across agent messages; deltas stream the
429
+ // growing snapshots as suffixes. Wire tool names are translated back
430
+ // to the kernel's own naming before consumers see them.
431
+ const completedMessages = [];
432
+ const emittedByItemId = new Map();
433
+ const wireToKernel = new Map();
434
+ for (const [kernelName, wireName] of bridgedToolNames(request.tools ?? [])) {
435
+ wireToKernel.set(wireName, kernelName);
436
+ }
437
+ const kernelNameFor = (wireName) => wireToKernel.get(wireName) ?? wireName;
438
+ const forwardEvent = async (event) => {
439
+ if (event.type === 'thread.started' && typeof event.thread_id === 'string' && event.thread_id.length > 0) {
440
+ rememberThreadId(request.session, event.thread_id);
441
+ return;
442
+ }
443
+ if (event.type === 'turn.failed') {
444
+ throw new Error(`Codex run failed${event.error?.message ? `: ${event.error.message}` : ''}`);
445
+ }
446
+ if (event.type === 'error') {
447
+ throw new Error(`Codex run failed${event.message ? `: ${event.message}` : ''}`);
448
+ }
449
+ const item = event.item;
450
+ if (!item || (event.type !== 'item.started' && event.type !== 'item.updated' && event.type !== 'item.completed')) {
451
+ return;
452
+ }
453
+ if (item.type === 'agent_message') {
454
+ const text = typeof item.text === 'string' ? item.text : '';
455
+ if (event.type === 'item.completed') {
456
+ completedMessages.push(text);
457
+ }
458
+ if (request.onDelta && item.id !== undefined) {
459
+ const emitted = emittedByItemId.get(item.id) ?? 0;
460
+ if (text.length > emitted) {
461
+ emittedByItemId.set(item.id, text.length);
462
+ // AWAIT the sink per fragment (backpressure), with the clock
463
+ // stopped: the pause is the consumer's time, not the
464
+ // subprocess's silence.
465
+ suspendIdleTimer();
466
+ try {
467
+ await request.onDelta({ type: 'text', text: text.slice(emitted) });
468
+ }
469
+ finally {
470
+ resetIdleTimer();
471
+ }
472
+ }
473
+ }
474
+ return;
475
+ }
476
+ if (item.type === 'reasoning' && request.onDelta && event.type !== 'item.completed') {
477
+ // Content-free on purpose: a watchdog needs to see reasoning as
478
+ // progress, and the reasoning itself is never carried.
479
+ suspendIdleTimer();
480
+ try {
481
+ await request.onDelta({ type: 'thinking' });
482
+ }
483
+ finally {
484
+ resetIdleTimer();
485
+ }
486
+ return;
487
+ }
488
+ if (item.type === 'mcp_tool_call' && request.onDelta && event.type === 'item.started' && typeof item.tool === 'string') {
489
+ suspendIdleTimer();
490
+ try {
491
+ await request.onDelta({ type: 'tool-call', toolName: kernelNameFor(item.tool) });
492
+ }
493
+ finally {
494
+ resetIdleTimer();
495
+ }
496
+ }
497
+ };
498
+ const attempt = async (resumeThreadId) => {
499
+ resetIdleTimer();
500
+ for await (const event of runTurn({
501
+ input: resumeThreadId ? latestUserMessagePrompt(request) : renderTranscriptPrompt(request),
502
+ ...(resumeThreadId ? { resumeThreadId } : {}),
503
+ clientOptions,
504
+ threadOptions,
505
+ signal: controller.signal,
506
+ })) {
507
+ resetIdleTimer();
508
+ await forwardEvent(event);
509
+ }
510
+ };
511
+ const resumeId = readThreadId(request.session);
512
+ try {
513
+ try {
514
+ await attempt(resumeId);
515
+ }
516
+ catch (error) {
517
+ // A stored thread id codex no longer has — the sessions directory
518
+ // was cleared, or the thread was made on another machine — must
519
+ // not strand the conversation. Start a fresh thread and replay the
520
+ // kernel's history into it. Only when nothing has run yet: once a
521
+ // hosted tool has executed, its side effects are real and already
522
+ // recorded, so replaying the turn would do them twice.
523
+ if (resumeId === undefined || hostedToolRuns > 0 || controller.signal.aborted) {
524
+ throw error;
525
+ }
526
+ onResumeFailed?.(error);
527
+ // The abandoned attempt may already have streamed fragments, and
528
+ // the replay is a different answer to the same question — without
529
+ // a reset an aggregator concatenates the two into one garbled
530
+ // reply. Clock stopped around it like every other awaited sink.
531
+ suspendIdleTimer();
532
+ try {
533
+ await request.onDelta?.({ type: 'reset', reason: 'retry' });
534
+ }
535
+ finally {
536
+ resetIdleTimer();
537
+ }
538
+ completedMessages.length = 0;
539
+ emittedByItemId.clear();
540
+ await attempt(undefined);
541
+ }
542
+ }
543
+ catch (error) {
544
+ if (error.code === 'ENOENT') {
545
+ throw new Error('Codex could not be started. Install @openai/codex-sdk (it bundles the codex binary) where Stratus runs, and sign in with `codex login` or configure an OpenAI API key.');
546
+ }
547
+ if (timedOutIdle && !request.signal?.aborted) {
548
+ throw markIfSideEffects(new Error(`Codex produced no output for ${idleTimeoutMs}ms; the run was aborted as stalled.`));
549
+ }
550
+ const message = error instanceof Error ? error.message : String(error);
551
+ if (/not (?:yet )?logged in|codex login/i.test(message)) {
552
+ throw markIfSideEffects(new Error(`Codex is not signed in on this machine. Run \`codex login\`, or add an OpenAI API key with \`stratus setup\`. (${message})`));
553
+ }
554
+ throw markIfSideEffects(error);
555
+ }
556
+ finally {
557
+ if (idleTimer) {
558
+ clearTimeout(idleTimer);
559
+ }
560
+ // The turn is over, success or failure. Hosted work still in flight —
561
+ // a tools/call the subprocess fired and then died without awaiting —
562
+ // belongs to no turn now, and closing the socket alone would orphan
563
+ // it mid-execution rather than stop it: the HTTP handler is detached
564
+ // from this function, so nothing else ever cancels the executor
565
+ // beneath it. The abort fires first so cancellation reaches that
566
+ // work, then the socket goes away.
567
+ controller.abort();
568
+ await mcp?.close();
569
+ }
570
+ const resultText = completedMessages.filter((text) => text.length > 0).join('\n\n');
571
+ if (resultText.length === 0) {
572
+ throw markIfSideEffects(new Error('Codex returned an empty response.'));
573
+ }
574
+ return { parts: [{ type: 'text', text: resultText }] };
575
+ },
576
+ });
577
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "@stratusagent/provider-codex",
3
+ "version": "0.9.2",
4
+ "type": "module",
5
+ "main": "./dist/index.js",
6
+ "types": "./dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "import": "./dist/index.js"
11
+ }
12
+ },
13
+ "files": [
14
+ "dist"
15
+ ],
16
+ "engines": {
17
+ "node": ">=22.13 <23 || >=23.4"
18
+ },
19
+ "dependencies": {
20
+ "@openai/codex-sdk": "^0.151.0",
21
+ "@stratusagent/core": "0.9.2",
22
+ "@stratusagent/providers": "0.9.2"
23
+ },
24
+ "devDependencies": {
25
+ "@types/node": "^24.6.0",
26
+ "typescript": "^5.9.3"
27
+ },
28
+ "description": "ChatGPT/Codex runtime for Stratus Agent: runs turns through the OpenAI Codex harness with kernel tools served over a loopback MCP endpoint",
29
+ "keywords": [
30
+ "stratus",
31
+ "agent",
32
+ "ai",
33
+ "llm",
34
+ "codex",
35
+ "chatgpt",
36
+ "subscription"
37
+ ],
38
+ "license": "MIT",
39
+ "repository": {
40
+ "type": "git",
41
+ "url": "git+https://github.com/stratuslabs/agent.git",
42
+ "directory": "packages/provider-codex"
43
+ },
44
+ "publishConfig": {
45
+ "access": "public"
46
+ },
47
+ "scripts": {
48
+ "build": "tsc -b",
49
+ "typecheck": "tsc --noEmit --project tsconfig.test.json",
50
+ "test": "node --test --experimental-strip-types"
51
+ }
52
+ }