@usine/agents 0.0.1 → 0.2.0

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.
Files changed (74) hide show
  1. package/README.md +52 -2
  2. package/dist/pi/authentication.d.ts +13 -0
  3. package/dist/pi/authentication.d.ts.map +1 -0
  4. package/dist/pi/authentication.js +14 -0
  5. package/dist/pi/authentication.js.map +1 -0
  6. package/dist/pi/children.d.ts +8 -0
  7. package/dist/pi/children.d.ts.map +1 -0
  8. package/dist/pi/children.js +29 -0
  9. package/dist/pi/children.js.map +1 -0
  10. package/dist/pi/claude.d.ts +36 -0
  11. package/dist/pi/claude.d.ts.map +1 -0
  12. package/dist/pi/claude.js +244 -0
  13. package/dist/pi/claude.js.map +1 -0
  14. package/dist/pi/codex/account.d.ts +11 -0
  15. package/dist/pi/codex/account.d.ts.map +1 -0
  16. package/dist/pi/codex/account.js +43 -0
  17. package/dist/pi/codex/account.js.map +1 -0
  18. package/dist/pi/codex/app-server.d.ts +33 -0
  19. package/dist/pi/codex/app-server.d.ts.map +1 -0
  20. package/dist/pi/codex/app-server.js +227 -0
  21. package/dist/pi/codex/app-server.js.map +1 -0
  22. package/dist/pi/codex/codex.d.ts +7 -0
  23. package/dist/pi/codex/codex.d.ts.map +1 -0
  24. package/dist/pi/codex/codex.js +362 -0
  25. package/dist/pi/codex/codex.js.map +1 -0
  26. package/dist/pi/live.d.ts +4 -0
  27. package/dist/pi/live.d.ts.map +1 -0
  28. package/dist/pi/live.js +11 -0
  29. package/dist/pi/live.js.map +1 -0
  30. package/dist/pi/pi.d.ts +9 -0
  31. package/dist/pi/pi.d.ts.map +1 -0
  32. package/dist/pi/pi.js +311 -0
  33. package/dist/pi/pi.js.map +1 -0
  34. package/dist/pi/sdk.d.ts +71 -0
  35. package/dist/pi/sdk.d.ts.map +1 -0
  36. package/dist/pi/sdk.js +159 -0
  37. package/dist/pi/sdk.js.map +1 -0
  38. package/dist/pi/session.d.ts +45 -0
  39. package/dist/pi/session.d.ts.map +1 -0
  40. package/dist/pi/session.js +179 -0
  41. package/dist/pi/session.js.map +1 -0
  42. package/dist/pi/subagents.d.ts +27 -0
  43. package/dist/pi/subagents.d.ts.map +1 -0
  44. package/dist/pi/subagents.js +113 -0
  45. package/dist/pi/subagents.js.map +1 -0
  46. package/dist/pi/thinking.d.ts +8 -0
  47. package/dist/pi/thinking.d.ts.map +1 -0
  48. package/dist/pi/thinking.js +15 -0
  49. package/dist/pi/thinking.js.map +1 -0
  50. package/dist/preflight/command.d.ts +7 -0
  51. package/dist/preflight/command.d.ts.map +1 -0
  52. package/dist/preflight/command.js +42 -0
  53. package/dist/preflight/command.js.map +1 -0
  54. package/dist/preflight/preflight.d.ts +13 -0
  55. package/dist/preflight/preflight.d.ts.map +1 -0
  56. package/dist/preflight/preflight.js +100 -0
  57. package/dist/preflight/preflight.js.map +1 -0
  58. package/dist/prompt.d.ts +26 -0
  59. package/dist/prompt.d.ts.map +1 -0
  60. package/dist/prompt.js +45 -0
  61. package/dist/prompt.js.map +1 -0
  62. package/dist/protocol/codex.d.ts +70 -0
  63. package/dist/protocol/codex.d.ts.map +1 -0
  64. package/dist/protocol/codex.js +8 -0
  65. package/dist/protocol/codex.js.map +1 -0
  66. package/dist/runtime.d.ts +132 -0
  67. package/dist/runtime.d.ts.map +1 -0
  68. package/dist/runtime.js +109 -0
  69. package/dist/runtime.js.map +1 -0
  70. package/package.json +48 -5
  71. package/dist/index.d.ts +0 -8
  72. package/dist/index.d.ts.map +0 -1
  73. package/dist/index.js +0 -8
  74. package/dist/index.js.map +0 -1
@@ -0,0 +1,227 @@
1
+ import { Cause, Context, Deferred, Effect, Fiber, Layer, Option, Queue, Ref, Schema, Scope, Stream, } from "effect";
2
+ import { ChildProcess, ChildProcessSpawner } from "effect/unstable/process";
3
+ import { homedir } from "node:os";
4
+ import { SessionOperationError } from "../../runtime.js";
5
+ /** Spawns the Codex app-server process and exposes its JSON-RPC connection. */
6
+ export class CodexAppServer extends Context.Service()("@usine/agents/pi/CodexAppServer") {
7
+ }
8
+ const RpcSuccessResponse = Schema.Struct({
9
+ id: Schema.Int,
10
+ result: Schema.Json,
11
+ });
12
+ const RpcErrorResponse = Schema.Struct({
13
+ id: Schema.Int,
14
+ error: Schema.Struct({
15
+ code: Schema.Number,
16
+ message: Schema.String,
17
+ data: Schema.optionalKey(Schema.Json),
18
+ }),
19
+ });
20
+ const RpcResponse = Schema.Union([RpcSuccessResponse, RpcErrorResponse]);
21
+ const RpcMessage = Schema.Struct({
22
+ method: Schema.String,
23
+ params: Schema.optionalKey(Schema.Json),
24
+ id: Schema.optionalKey(Schema.Union([Schema.Number, Schema.String])),
25
+ });
26
+ const decodeLine = Schema.decodeUnknownEffect(Schema.fromJsonString(Schema.Json));
27
+ const encoder = new TextEncoder();
28
+ const RPC_TIMEOUT = "60 seconds";
29
+ const STDERR_TAIL_LINES = 5;
30
+ const preview = (line) => (line.length > 200 ? `${line.slice(0, 200)}…` : line);
31
+ export const operationError = (operation, request, message, cause) => new SessionOperationError({
32
+ operation,
33
+ sessionId: request.sessionId,
34
+ message,
35
+ cause,
36
+ });
37
+ const repositoryTrustOverride = (cwd) => `projects.${JSON.stringify(cwd)}.trust_level="untrusted"`;
38
+ const disableRecursiveAgentsOverride = "features.multi_agent=false";
39
+ export const codexAppServerCommand = (cwd, stdin) => {
40
+ const options = {
41
+ // Start outside the worktree so process startup cannot read
42
+ // repository-owned config before thread trust is set.
43
+ cwd: homedir(),
44
+ // Stay in the run host's process group so the executor's hard kill reaps
45
+ // the app server too; the bounded SIGTERM window is the grace-then-force
46
+ // stop (ADR 0006).
47
+ detached: false,
48
+ forceKillAfter: "5 seconds",
49
+ };
50
+ return ChildProcess.make("codex", [
51
+ "app-server",
52
+ "--stdio",
53
+ "-c",
54
+ repositoryTrustOverride(cwd),
55
+ "-c",
56
+ disableRecursiveAgentsOverride,
57
+ ], stdin === undefined ? options : { ...options, stdin });
58
+ };
59
+ const makeCodexAppServer = Effect.gen(function* () {
60
+ const spawner = yield* ChildProcessSpawner.ChildProcessSpawner;
61
+ const open = Effect.fn("CodexAppServer.open")(function* (request) {
62
+ yield* Effect.annotateCurrentSpan({
63
+ harness: "codex",
64
+ sessionId: Option.getOrUndefined(request.sessionId),
65
+ });
66
+ const input = yield* Queue.make();
67
+ const notifications = yield* Queue.make();
68
+ const pending = yield* Ref.make(new Map());
69
+ const nextId = yield* Ref.make(1);
70
+ const closing = yield* Ref.make(false);
71
+ const failure = yield* Ref.make(Option.none());
72
+ const stderrTail = yield* Ref.make([]);
73
+ const handle = yield* spawner
74
+ .spawn(codexAppServerCommand(request.cwd, {
75
+ stream: Stream.fromQueue(input),
76
+ endOnDone: true,
77
+ }))
78
+ .pipe(Effect.mapError((cause) => operationError("launch", request, "Codex app-server failed to start", cause)));
79
+ const write = (message, operation) => Queue.offer(input, encoder.encode(`${JSON.stringify(message)}\n`)).pipe(Effect.flatMap((accepted) => accepted
80
+ ? Effect.void
81
+ : Effect.fail(operationError(operation, request, "Codex app-server input is closed", new Error("input queue closed")))), Effect.mapError((cause) => cause instanceof SessionOperationError
82
+ ? cause
83
+ : operationError(operation, request, "Could not write to Codex app-server", cause)));
84
+ const failAll = Effect.fn("CodexAppServer.failAll")(function* (error) {
85
+ yield* Ref.update(failure, Option.orElseSome(() => error));
86
+ const waiting = yield* Ref.getAndSet(pending, new Map());
87
+ for (const entry of waiting.values())
88
+ yield* Deferred.fail(entry.response, error);
89
+ yield* Queue.fail(notifications, error);
90
+ });
91
+ // One effect per stdout line, without a span: a line is not an
92
+ // operation. Unrecognized input is logged and skipped so a stray frame
93
+ // cannot fail the session and trigger an infra retry (ADR 0002).
94
+ const routeLine = (line) => Effect.gen(function* () {
95
+ if (line.trim().length === 0)
96
+ return;
97
+ const decoded = yield* decodeLine(line).pipe(Effect.catch((cause) => Effect.logWarning("Skipping a non-JSON Codex app-server line", {
98
+ cause,
99
+ line: preview(line),
100
+ sessionId: Option.getOrUndefined(request.sessionId),
101
+ }).pipe(Effect.as(undefined))));
102
+ if (decoded === undefined)
103
+ return;
104
+ if (Schema.is(RpcResponse)(decoded)) {
105
+ const found = yield* Ref.modify(pending, (entries) => {
106
+ const entry = entries.get(decoded.id);
107
+ if (entry === undefined)
108
+ return [Option.none(), entries];
109
+ const updated = new Map(entries);
110
+ updated.delete(decoded.id);
111
+ return [Option.some(entry), updated];
112
+ });
113
+ if (Option.isNone(found)) {
114
+ return yield* Effect.logDebug("Ignoring a Codex response with no waiting request", {
115
+ id: decoded.id,
116
+ sessionId: Option.getOrUndefined(request.sessionId),
117
+ });
118
+ }
119
+ if (Schema.is(RpcErrorResponse)(decoded)) {
120
+ return yield* Deferred.fail(found.value.response, operationError(found.value.operation, request, `Codex app-server rejected ${decoded.error.message}`, decoded.error));
121
+ }
122
+ return yield* Deferred.succeed(found.value.response, decoded.result);
123
+ }
124
+ if (!Schema.is(RpcMessage)(decoded)) {
125
+ return yield* Effect.logWarning("Skipping an unknown Codex JSON-RPC shape", {
126
+ line: preview(line),
127
+ sessionId: Option.getOrUndefined(request.sessionId),
128
+ });
129
+ }
130
+ if (decoded.id !== undefined) {
131
+ yield* Effect.logWarning("Codex app-server requested unsupported client input", {
132
+ method: decoded.method,
133
+ sessionId: Option.getOrUndefined(request.sessionId),
134
+ });
135
+ return yield* write({
136
+ id: decoded.id,
137
+ error: { code: -32601, message: "usine runs Codex headlessly" },
138
+ }, "stream");
139
+ }
140
+ yield* Queue.offer(notifications, {
141
+ method: decoded.method,
142
+ params: decoded.params ?? null,
143
+ });
144
+ });
145
+ const stdoutReader = yield* handle.stdout.pipe(Stream.decodeText(), Stream.splitLines, Stream.runForEach(routeLine), Effect.flatMap(() => Ref.get(closing).pipe(Effect.flatMap((closed) => closed
146
+ ? Effect.void
147
+ : handle.exitCode.pipe(
148
+ // On process exit, its monitor owns the richer diagnostic.
149
+ // A live process that closes stdout still fails promptly.
150
+ Effect.timeout("5 seconds"), Effect.matchEffect({
151
+ onSuccess: () => Effect.void,
152
+ onFailure: (cause) => failAll(operationError("stream", request, "Codex app-server output closed unexpectedly", cause)),
153
+ }))))), Effect.catch((error) => failAll(error instanceof SessionOperationError
154
+ ? error
155
+ : operationError("stream", request, "Could not read Codex app-server output", error))), Effect.forkScoped);
156
+ const stderrReader = yield* handle.stderr.pipe(Stream.decodeText(), Stream.splitLines, Stream.runForEach((line) => line.trim().length === 0
157
+ ? Effect.void
158
+ : Effect.logDebug("Codex app-server stderr", {
159
+ line: preview(line),
160
+ sessionId: Option.getOrUndefined(request.sessionId),
161
+ }).pipe(Effect.andThen(Ref.update(stderrTail, (tail) => [...tail, line].slice(-STDERR_TAIL_LINES))))), Effect.catch((cause) => failAll(operationError("stream", request, "Could not read Codex app-server diagnostics", cause))), Effect.forkScoped);
162
+ yield* handle.exitCode.pipe(Effect.flatMap((exitCode) => Effect.all([Ref.get(closing), Ref.get(stderrTail)]).pipe(Effect.flatMap(([closed, stderr]) => closed
163
+ ? Effect.void
164
+ : failAll(operationError("stream", request, `Codex app-server exited with code ${String(exitCode)}`, { exitCode, stderr }))))), Effect.catch((cause) => failAll(operationError("stream", request, "Could not monitor Codex app-server", cause))), Effect.forkScoped);
165
+ // Stdio EOF runs Codex's thread shutdown, including background commands.
166
+ // SIGTERM bypasses that cleanup in stdio mode. Share one bounded shutdown
167
+ // across terminal delivery and scope release, even if the caller is canceled.
168
+ const rejectPending = (cause) => Effect.gen(function* () {
169
+ const waiting = yield* Ref.getAndSet(pending, new Map());
170
+ for (const entry of waiting.values())
171
+ yield* Deferred.fail(entry.response, operationError(entry.operation, request, "Codex app-server closed before answering the request", cause));
172
+ });
173
+ const close = yield* Effect.cached(Effect.fn("CodexAppServer.close")(function* () {
174
+ yield* Effect.annotateCurrentSpan({
175
+ sessionId: Option.getOrUndefined(request.sessionId),
176
+ });
177
+ yield* Ref.set(closing, true);
178
+ yield* Queue.end(input);
179
+ const [exitCode] = yield* Effect.all([handle.exitCode, Fiber.join(stdoutReader), Fiber.join(stderrReader)], {
180
+ concurrency: "unbounded",
181
+ }).pipe(Effect.timeout("15 seconds"), Effect.mapError((cause) => operationError("interrupt", request, "Codex app-server did not shut down cleanly", cause)), Effect.tapError(rejectPending));
182
+ yield* rejectPending({ exitCode });
183
+ if (exitCode !== 0)
184
+ return yield* operationError("interrupt", request, `Codex app-server exited with code ${String(exitCode)} during shutdown`, { exitCode, stderr: yield* Ref.get(stderrTail) });
185
+ yield* Queue.end(notifications);
186
+ yield* Effect.logDebug("Codex app-server shutdown completed", { exitCode });
187
+ })().pipe(Effect.tapError(failAll), Effect.uninterruptible));
188
+ yield* Effect.addFinalizer(() => close.pipe(Effect.catch((cause) => Effect.logWarning("Forcing Codex app-server to stop after graceful shutdown failed", {
189
+ cause,
190
+ sessionId: Option.getOrUndefined(request.sessionId),
191
+ }).pipe(Effect.andThen(handle.kill({ forceKillAfter: "5 seconds" })), Effect.catch((cause) => Effect.logWarning("Could not force Codex app-server to stop", {
192
+ cause,
193
+ sessionId: Option.getOrUndefined(request.sessionId),
194
+ }))))));
195
+ const requestRpc = (operation, method, params) => Effect.gen(function* () {
196
+ if (yield* Ref.get(closing))
197
+ return yield* operationError(operation, request, "Codex app-server connection is closing", new Error("connection closed"));
198
+ const failed = yield* Ref.get(failure);
199
+ if (Option.isSome(failed)) {
200
+ return yield* operationError(operation, request, "Codex app-server connection already failed", failed.value);
201
+ }
202
+ const id = yield* Ref.getAndUpdate(nextId, (current) => current + 1);
203
+ const response = yield* Deferred.make();
204
+ yield* Ref.update(pending, (entries) => new Map(entries).set(id, { operation, response }));
205
+ const forget = Ref.update(pending, (entries) => {
206
+ const updated = new Map(entries);
207
+ updated.delete(id);
208
+ return updated;
209
+ });
210
+ yield* write({ id, method, params }, operation).pipe(Effect.tapError(() => forget));
211
+ return yield* Deferred.await(response).pipe(Effect.timeoutOrElse({
212
+ duration: RPC_TIMEOUT,
213
+ orElse: () => forget.pipe(Effect.andThen(operationError(operation, request, `Codex app-server did not answer ${method} within ${RPC_TIMEOUT}`, new Error("request timed out")))),
214
+ }));
215
+ });
216
+ const notify = (operation, method, params) => write({ method, params }, operation);
217
+ return {
218
+ close,
219
+ notifications: Stream.fromQueue(notifications),
220
+ request: requestRpc,
221
+ notify,
222
+ };
223
+ });
224
+ return CodexAppServer.of({ open });
225
+ });
226
+ export const codexAppServerLive = Layer.effect(CodexAppServer, makeCodexAppServer);
227
+ //# sourceMappingURL=app-server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-server.js","sourceRoot":"","sources":["../../../src/pi/codex/app-server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import { Layer } from "effect";
2
+ import { CodexChildBackend } from "../../runtime.ts";
3
+ import { CodexAppServer } from "./app-server.ts";
4
+ export { CodexAppServer, codexAppServerLive, type CodexConnection } from "./app-server.ts";
5
+ /** Provides Codex coding sessions for tasks delegated by a parent. */
6
+ export declare const codexChildBackendLayer: Layer.Layer<CodexChildBackend, never, CodexAppServer>;
7
+ //# sourceMappingURL=codex.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex.d.ts","sourceRoot":"","sources":["../../../src/pi/codex/codex.ts"],"names":[],"mappings":"AAYA,OAAO,EAA8B,KAAK,EAA0B,MAAM,QAAQ,CAAC;AASnF,OAAO,EAGL,iBAAiB,EAKlB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,cAAc,EAAoC,MAAM,iBAAiB,CAAC;AAGnF,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC;AA0e3F,sEAAsE;AACtE,eAAO,MAAM,sBAAsB,uDAAkD,CAAC"}
@@ -0,0 +1,362 @@
1
+ import { BrainSpec, ModelId } from "@usine/core/agent/brain";
2
+ import { AgentSessionId, ChildSession, PoolRateLimitsUpdated, RateLimitsSnapshot, RateLimitWindow as CoreRateLimitWindow, SessionStarted, TextOutput, ToolFinished, ToolStarted, } from "@usine/core/agent/session";
3
+ import { DateTime, Deferred, Effect, Layer, Option, Schema, Stream } from "effect";
4
+ import { AccountUpdated } from "../../protocol/codex.js";
5
+ import { AgentResultError, CodexChildBackend, SessionOperationError, UnknownModelError, UnsupportedEffortError, } from "../../runtime.js";
6
+ import { sessionChannel } from "../session.js";
7
+ import { CodexAppServer, operationError } from "./app-server.js";
8
+ import { codexPoolUnavailable, initializeCodex, verifyCodexAccount } from "./account.js";
9
+ export { CodexAppServer, codexAppServerLive } from "./app-server.js";
10
+ const json = (value) => Schema.decodeUnknownSync(Schema.Json)(JSON.parse(JSON.stringify(value)));
11
+ const ModelListResponse = Schema.Struct({
12
+ data: Schema.Array(Schema.Struct({
13
+ id: Schema.String,
14
+ model: Schema.String,
15
+ supportedReasoningEfforts: Schema.optionalKey(Schema.Array(Schema.Struct({ reasoningEffort: Schema.String }))),
16
+ })),
17
+ nextCursor: Schema.NullOr(Schema.String),
18
+ });
19
+ const ThreadStartResponse = Schema.Struct({
20
+ thread: Schema.Struct({ id: Schema.NonEmptyString }),
21
+ model: Schema.NonEmptyString,
22
+ instructionSources: Schema.Array(Schema.String),
23
+ });
24
+ const TurnStartResponse = Schema.Struct({
25
+ turn: Schema.Struct({ id: Schema.NonEmptyString }),
26
+ });
27
+ const ItemNotification = Schema.Struct({
28
+ item: Schema.Json,
29
+ threadId: Schema.String,
30
+ turnId: Schema.String,
31
+ });
32
+ const AgentMessageItem = Schema.Struct({
33
+ type: Schema.Literal("agentMessage"),
34
+ id: Schema.NonEmptyString,
35
+ text: Schema.String,
36
+ phase: Schema.optionalKey(Schema.NullOr(Schema.String)),
37
+ });
38
+ const ToolItem = Schema.Struct({
39
+ type: Schema.Literals([
40
+ "commandExecution",
41
+ "fileChange",
42
+ "mcpToolCall",
43
+ "dynamicToolCall",
44
+ "webSearch",
45
+ "imageView",
46
+ "imageGeneration",
47
+ ]),
48
+ id: Schema.NonEmptyString,
49
+ status: Schema.optionalKey(Schema.String),
50
+ success: Schema.optionalKey(Schema.NullOr(Schema.Boolean)),
51
+ });
52
+ const TurnCompleted = Schema.Struct({
53
+ turn: Schema.Struct({
54
+ id: Schema.String,
55
+ status: Schema.Literals(["completed", "interrupted", "failed", "inProgress"]),
56
+ error: Schema.NullOr(Schema.Struct({
57
+ message: Schema.String,
58
+ additionalDetails: Schema.NullOr(Schema.String),
59
+ })),
60
+ }),
61
+ });
62
+ // Upstream sends this notification as a sparse rolling update: any account
63
+ // field may be absent, so only the load figure is required.
64
+ const RateLimitWindow = Schema.Struct({
65
+ usedPercent: Schema.Number,
66
+ windowDurationMins: Schema.optionalKey(Schema.NullOr(Schema.Number)),
67
+ resetsAt: Schema.optionalKey(Schema.NullOr(Schema.Number)),
68
+ });
69
+ const RateLimitsUpdated = Schema.Struct({
70
+ rateLimits: Schema.Struct({
71
+ limitId: Schema.optionalKey(Schema.NullOr(Schema.String)),
72
+ limitName: Schema.optionalKey(Schema.NullOr(Schema.String)),
73
+ primary: Schema.optionalKey(Schema.NullOr(RateLimitWindow)),
74
+ secondary: Schema.optionalKey(Schema.NullOr(RateLimitWindow)),
75
+ }),
76
+ });
77
+ const decodeResponse = (schema, operation, client, label, value) => Schema.decodeUnknownEffect(schema)(value).pipe(Effect.mapError((cause) => operationError(operation, client, `Codex returned an invalid ${label}`, cause)));
78
+ /** Decodes one notification payload; an undecodable payload is logged and skipped, never fatal. */
79
+ const decodeNotification = (schema, label, sessionId, value) => Schema.decodeUnknownEffect(schema)(value).pipe(Effect.map(Option.some), Effect.catch((cause) => Effect.logWarning(`Skipping an undecodable Codex ${label}`, { cause, sessionId }).pipe(Effect.as(Option.none()))));
80
+ const toolName = (item) => {
81
+ switch (item.type) {
82
+ case "commandExecution":
83
+ return "command";
84
+ case "fileChange":
85
+ return "file_change";
86
+ case "mcpToolCall":
87
+ return "mcp_tool";
88
+ case "dynamicToolCall":
89
+ return "dynamic_tool";
90
+ case "webSearch":
91
+ return "web_search";
92
+ case "imageView":
93
+ return "image_view";
94
+ case "imageGeneration":
95
+ return "image_generation";
96
+ }
97
+ };
98
+ const rateLimitWindow = (window) => new CoreRateLimitWindow({
99
+ usedPercent: window.usedPercent,
100
+ windowDurationMinutes: Option.fromNullishOr(window.windowDurationMins),
101
+ resetsAt: Option.fromNullishOr(window.resetsAt).pipe(Option.map(DateTime.fromEpochSeconds)),
102
+ });
103
+ /** Server pushes with no session event shape; they still reach the operator's logs. */
104
+ const DIAGNOSTIC_METHODS = new Set([
105
+ "error",
106
+ "warning",
107
+ "configWarning",
108
+ "deprecationNotice",
109
+ "guardianWarning",
110
+ "model/rerouted",
111
+ ]);
112
+ const makeCodexChild = Effect.gen(function* () {
113
+ const appServer = yield* CodexAppServer;
114
+ const launch = Effect.fn("CodexChildBackend.launch")(function* (request) {
115
+ yield* Effect.annotateCurrentSpan({
116
+ agent: request.session.agent,
117
+ effort: request.session.brain.effort,
118
+ harness: request.session.brain.harness,
119
+ model: request.session.brain.model,
120
+ parentSessionId: request.session.parentId,
121
+ sessionId: request.session.id,
122
+ });
123
+ yield* Effect.logInfo("Launching Codex child session");
124
+ const client = { cwd: request.cwd, sessionId: Option.some(request.session.id) };
125
+ const connection = yield* appServer.open(client);
126
+ yield* initializeCodex(connection);
127
+ const pool = yield* verifyCodexAccount(connection, request.session.brain.model);
128
+ const models = [];
129
+ let cursor = null;
130
+ do {
131
+ const params = { cursor, includeHidden: true, limit: 100 };
132
+ const response = yield* connection.request("launch", "model/list", json(params));
133
+ const page = yield* decodeResponse(ModelListResponse, "launch", client, "model list", response);
134
+ models.push(...page.data);
135
+ cursor = page.nextCursor;
136
+ } while (cursor !== null);
137
+ const requestedModel = request.session.brain.model;
138
+ const catalogModel = models.find((model) => model.id === requestedModel || model.model === requestedModel);
139
+ if (catalogModel === undefined) {
140
+ yield* Effect.logError("Codex child rejected an unknown model", { model: requestedModel });
141
+ return yield* new UnknownModelError({
142
+ harness: "codex",
143
+ model: requestedModel,
144
+ message: `Codex does not expose model ${requestedModel}`,
145
+ });
146
+ }
147
+ const effort = request.session.brain.effort === "off" ? "none" : request.session.brain.effort;
148
+ const supportedEfforts = catalogModel.supportedReasoningEfforts;
149
+ if (supportedEfforts !== undefined &&
150
+ supportedEfforts.length > 0 &&
151
+ !supportedEfforts.some((option) => option.reasoningEffort === effort)) {
152
+ yield* Effect.logError("Codex child rejected an unsupported effort", {
153
+ effort: request.session.brain.effort,
154
+ model: requestedModel,
155
+ supported: supportedEfforts.map((option) => option.reasoningEffort),
156
+ });
157
+ return yield* new UnsupportedEffortError({
158
+ harness: "codex",
159
+ model: requestedModel,
160
+ effort: request.session.brain.effort,
161
+ message: `Codex model ${requestedModel} does not support effort ${effort}`,
162
+ });
163
+ }
164
+ const threadParams = {
165
+ model: requestedModel,
166
+ allowProviderModelFallback: false,
167
+ cwd: request.cwd,
168
+ approvalPolicy: "never",
169
+ sandbox: "danger-full-access",
170
+ ephemeral: true,
171
+ serviceName: "usine",
172
+ };
173
+ const threadJson = yield* connection.request("launch", "thread/start", json(threadParams));
174
+ const thread = yield* decodeResponse(ThreadStartResponse, "launch", client, "thread start response", threadJson);
175
+ yield* Effect.logDebug("Codex child started a thread", {
176
+ instructionSources: thread.instructionSources.length,
177
+ model: thread.model,
178
+ sessionId: request.session.id,
179
+ });
180
+ const session = new ChildSession({
181
+ id: request.session.id,
182
+ parentId: request.session.parentId,
183
+ agent: request.session.agent,
184
+ brain: new BrainSpec({
185
+ harness: "codex",
186
+ model: ModelId.make(thread.model),
187
+ effort: request.session.brain.effort,
188
+ }),
189
+ });
190
+ const channel = yield* sessionChannel({
191
+ label: "Codex child session",
192
+ sessionId: session.id,
193
+ });
194
+ yield* channel.emit(new SessionStarted({ session }));
195
+ const turnParams = {
196
+ threadId: thread.thread.id,
197
+ input: [{ type: "text", text: request.prompt, text_elements: [] }],
198
+ cwd: request.cwd,
199
+ approvalPolicy: "never",
200
+ sandboxPolicy: { type: "dangerFullAccess" },
201
+ effort,
202
+ };
203
+ const turnJson = yield* connection.request("stream", "turn/start", json(turnParams));
204
+ const turn = yield* decodeResponse(TurnStartResponse, "stream", client, "turn start response", turnJson);
205
+ let lastText;
206
+ let finalText;
207
+ const fail = Effect.fn("CodexChildBackend.fail")(function* (error) {
208
+ yield* connection.close.pipe(Effect.tapError((cause) => Effect.logWarning("Codex child cleanup failed while reporting its original failure", {
209
+ cause,
210
+ sessionId: session.id,
211
+ })), Effect.ignore);
212
+ yield* channel.fail(error);
213
+ });
214
+ const consume = connection.notifications.pipe(Stream.runForEach(({ method, params }) => Effect.gen(function* () {
215
+ if (method === "item/started") {
216
+ const notification = yield* decodeNotification(ItemNotification, "item notification", session.id, params);
217
+ if (Option.isNone(notification))
218
+ return;
219
+ if (notification.value.turnId !== turn.turn.id) {
220
+ return yield* Effect.logDebug("Skipping a Codex item from another turn", {
221
+ sessionId: session.id,
222
+ turnId: notification.value.turnId,
223
+ });
224
+ }
225
+ if (!Schema.is(ToolItem)(notification.value.item))
226
+ return;
227
+ return yield* channel.emit(new ToolStarted({
228
+ session,
229
+ callId: notification.value.item.id,
230
+ tool: toolName(notification.value.item),
231
+ input: notification.value.item,
232
+ }));
233
+ }
234
+ if (method === "item/completed") {
235
+ const notification = yield* decodeNotification(ItemNotification, "item notification", session.id, params);
236
+ if (Option.isNone(notification))
237
+ return;
238
+ if (notification.value.turnId !== turn.turn.id) {
239
+ return yield* Effect.logDebug("Skipping a Codex item from another turn", {
240
+ sessionId: session.id,
241
+ turnId: notification.value.turnId,
242
+ });
243
+ }
244
+ const item = notification.value.item;
245
+ if (Schema.is(AgentMessageItem)(item)) {
246
+ const text = item.text.trim();
247
+ if (text.length === 0)
248
+ return;
249
+ lastText = text;
250
+ if (item.phase === "final_answer")
251
+ finalText = text;
252
+ return yield* channel.emit(new TextOutput({ session, text }));
253
+ }
254
+ if (!Schema.is(ToolItem)(item))
255
+ return;
256
+ return yield* channel.emit(new ToolFinished({
257
+ session,
258
+ callId: item.id,
259
+ tool: toolName(item),
260
+ output: item,
261
+ isError: item.status === "failed" ||
262
+ item.status === "declined" ||
263
+ item.success === false,
264
+ }));
265
+ }
266
+ if (method === "account/updated") {
267
+ const account = yield* Schema.decodeUnknownEffect(AccountUpdated)(params).pipe(Effect.mapError(() => codexPoolUnavailable(request.session.brain.model)));
268
+ if (account.authMode !== "chatgpt" && account.authMode !== "chatgptAuthTokens") {
269
+ yield* Effect.logError("Codex authentication changed during the session", {
270
+ sessionId: session.id,
271
+ authentication: account.authMode ?? "logged-out",
272
+ requiredPool: pool,
273
+ });
274
+ return yield* codexPoolUnavailable(request.session.brain.model);
275
+ }
276
+ return;
277
+ }
278
+ if (method === "account/rateLimits/updated") {
279
+ const notification = yield* decodeNotification(RateLimitsUpdated, "rate-limit notification", session.id, params);
280
+ if (Option.isNone(notification))
281
+ return;
282
+ const snapshot = notification.value.rateLimits;
283
+ return yield* channel.emit(new PoolRateLimitsUpdated({
284
+ session,
285
+ pool,
286
+ rateLimits: new RateLimitsSnapshot({
287
+ limitId: Option.fromNullishOr(snapshot.limitId),
288
+ limitName: Option.fromNullishOr(snapshot.limitName),
289
+ primary: Option.fromNullishOr(snapshot.primary).pipe(Option.map(rateLimitWindow)),
290
+ secondary: Option.fromNullishOr(snapshot.secondary).pipe(Option.map(rateLimitWindow)),
291
+ }),
292
+ }));
293
+ }
294
+ if (method === "turn/completed") {
295
+ const completed = yield* decodeResponse(TurnCompleted, "stream", client, "turn completion", params);
296
+ if (completed.turn.id !== turn.turn.id) {
297
+ return yield* Effect.logDebug("Skipping another turn's completion", {
298
+ sessionId: session.id,
299
+ turnId: completed.turn.id,
300
+ });
301
+ }
302
+ // A completed turn can leave unified-exec commands alive. Release
303
+ // the owned app server before the result can win a cancellation race.
304
+ yield* connection.close;
305
+ if (completed.turn.status === "completed") {
306
+ return yield* channel.finish(session, finalText ?? lastText ?? "Codex child session completed");
307
+ }
308
+ const detail = completed.turn.error?.message ??
309
+ (completed.turn.status === "interrupted"
310
+ ? "Codex child session was interrupted"
311
+ : "Codex child session failed");
312
+ return yield* channel.fail(new AgentResultError({
313
+ sessionId: Option.some(session.id),
314
+ message: detail,
315
+ }));
316
+ }
317
+ if (DIAGNOSTIC_METHODS.has(method)) {
318
+ return yield* Effect.logWarning("Codex reported a diagnostic", {
319
+ method,
320
+ params,
321
+ sessionId: session.id,
322
+ });
323
+ }
324
+ // Streaming deltas repeat content that the completed items deliver.
325
+ if (method.toLowerCase().includes("delta"))
326
+ return;
327
+ yield* Effect.logDebug("Ignoring an unhandled Codex notification", {
328
+ method,
329
+ sessionId: session.id,
330
+ });
331
+ })), Effect.flatMap(() => channel.isTerminal.pipe(Effect.flatMap((terminal) => terminal
332
+ ? Effect.void
333
+ : channel.fail(operationError("stream", client, "Codex notification stream closed without a result", new Error("unexpected end of notifications")))))), Effect.catch(fail));
334
+ yield* Effect.forkScoped(consume);
335
+ const steer = Effect.fn("CodexChildBackend.steer")((message) => {
336
+ const params = {
337
+ threadId: thread.thread.id,
338
+ expectedTurnId: turn.turn.id,
339
+ input: [{ type: "text", text: message, text_elements: [] }],
340
+ };
341
+ return Effect.logDebug("Steering Codex child session", { sessionId: session.id }).pipe(Effect.andThen(connection.request("steer", "turn/steer", json(params))), Effect.asVoid);
342
+ });
343
+ const interruptParams = {
344
+ threadId: thread.thread.id,
345
+ turnId: turn.turn.id,
346
+ };
347
+ const interrupt = Effect.logInfo("Interrupting Codex child session", {
348
+ sessionId: session.id,
349
+ }).pipe(Effect.andThen(connection.request("interrupt", "turn/interrupt", json(interruptParams))), Effect.asVoid);
350
+ return {
351
+ session,
352
+ events: Stream.fromQueue(channel.events),
353
+ interrupt,
354
+ result: Deferred.await(channel.result),
355
+ steer,
356
+ };
357
+ });
358
+ return CodexChildBackend.of({ launch });
359
+ });
360
+ /** Provides Codex coding sessions for tasks delegated by a parent. */
361
+ export const codexChildBackendLayer = Layer.effect(CodexChildBackend, makeCodexChild);
362
+ //# sourceMappingURL=codex.js.map