codex-openai-proxy 0.1.0-rc.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 (63) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +253 -0
  3. package/dist/app-server/app-server.d.ts +39 -0
  4. package/dist/app-server/app-server.js +261 -0
  5. package/dist/app-server/app-server.js.map +1 -0
  6. package/dist/app-server/auth.d.ts +16 -0
  7. package/dist/app-server/auth.js +102 -0
  8. package/dist/app-server/auth.js.map +1 -0
  9. package/dist/app-server/json-rpc.d.ts +29 -0
  10. package/dist/app-server/json-rpc.js +141 -0
  11. package/dist/app-server/json-rpc.js.map +1 -0
  12. package/dist/bin.d.ts +2 -0
  13. package/dist/bin.js +11 -0
  14. package/dist/bin.js.map +1 -0
  15. package/dist/cli/cli.d.ts +6 -0
  16. package/dist/cli/cli.js +319 -0
  17. package/dist/cli/cli.js.map +1 -0
  18. package/dist/continuation/state.d.ts +71 -0
  19. package/dist/continuation/state.js +460 -0
  20. package/dist/continuation/state.js.map +1 -0
  21. package/dist/core/abort.d.ts +13 -0
  22. package/dist/core/abort.js +74 -0
  23. package/dist/core/abort.js.map +1 -0
  24. package/dist/core/canonical.d.ts +6 -0
  25. package/dist/core/canonical.js +22 -0
  26. package/dist/core/canonical.js.map +1 -0
  27. package/dist/core/config.d.ts +33 -0
  28. package/dist/core/config.js +139 -0
  29. package/dist/core/config.js.map +1 -0
  30. package/dist/core/logger.d.ts +17 -0
  31. package/dist/core/logger.js +44 -0
  32. package/dist/core/logger.js.map +1 -0
  33. package/dist/core/policy.d.ts +98 -0
  34. package/dist/core/policy.js +242 -0
  35. package/dist/core/policy.js.map +1 -0
  36. package/dist/core/redact.d.ts +2 -0
  37. package/dist/core/redact.js +35 -0
  38. package/dist/core/redact.js.map +1 -0
  39. package/dist/http/chat-execute.d.ts +24 -0
  40. package/dist/http/chat-execute.js +491 -0
  41. package/dist/http/chat-execute.js.map +1 -0
  42. package/dist/http/chat-normalize.d.ts +100 -0
  43. package/dist/http/chat-normalize.js +379 -0
  44. package/dist/http/chat-normalize.js.map +1 -0
  45. package/dist/http/chat-sse.d.ts +14 -0
  46. package/dist/http/chat-sse.js +52 -0
  47. package/dist/http/chat-sse.js.map +1 -0
  48. package/dist/http/chat-validate.d.ts +37 -0
  49. package/dist/http/chat-validate.js +190 -0
  50. package/dist/http/chat-validate.js.map +1 -0
  51. package/dist/http/chat.d.ts +8 -0
  52. package/dist/http/chat.js +137 -0
  53. package/dist/http/chat.js.map +1 -0
  54. package/dist/http/errors.d.ts +19 -0
  55. package/dist/http/errors.js +56 -0
  56. package/dist/http/errors.js.map +1 -0
  57. package/dist/http/server.d.ts +19 -0
  58. package/dist/http/server.js +254 -0
  59. package/dist/http/server.js.map +1 -0
  60. package/package.json +67 -0
  61. package/protocol/VERSION.json +10 -0
  62. package/protocol/schemas/response-mapping.schema.json +38 -0
  63. package/protocol/schemas/x-codex.schema.json +12 -0
@@ -0,0 +1,71 @@
1
+ import type { JsonRpcTransport, ServerRequest } from "../app-server/json-rpc.js";
2
+ import { bindingHash, canonicalJson } from "../core/canonical.js";
3
+ export { bindingHash, canonicalJson };
4
+ /** Context that must remain identical over a Codex thread's lifetime. */
5
+ export interface ThreadBinding {
6
+ model: string;
7
+ cwd: string;
8
+ toolsHash: string;
9
+ policyHash: string;
10
+ }
11
+ /** One opaque response-to-thread record persisted by the proxy. */
12
+ export interface ResponseRecord extends ThreadBinding {
13
+ responseId: string;
14
+ threadId: string;
15
+ state: "ready" | "pending_tool" | "expired" | "superseded" | "corrupt";
16
+ createdAt: number;
17
+ expiresAt: number;
18
+ callIds?: string[];
19
+ }
20
+ /** Durable atomic response mapping store with bounded retention. */
21
+ export declare class ResponseStore {
22
+ #private;
23
+ private readonly retentionMs;
24
+ private readonly temporaryPath;
25
+ constructor(directory: string, retentionMs?: number, temporaryPath?: (statePath: string) => string);
26
+ /** Retrieves a record after applying expiry and newest-response rules. */
27
+ get(responseId: string): ResponseRecord | undefined;
28
+ /** Inserts a record and supersedes the prior completed response for its thread. */
29
+ put(record: Omit<ResponseRecord, "createdAt" | "expiresAt">): ResponseRecord;
30
+ /** Changes an existing record without exposing partial disk writes. */
31
+ update(responseId: string, patch: Partial<ResponseRecord>): ResponseRecord | undefined;
32
+ /** Finds durable records containing every requested dynamic-tool call ID. */
33
+ findByCallIds(callIds: readonly string[]): ResponseRecord[];
34
+ }
35
+ /** In-memory responder for one suspended app-server dynamic tool call. */
36
+ export interface PendingToolCall {
37
+ request: ServerRequest;
38
+ callId: string;
39
+ name: string;
40
+ arguments: unknown;
41
+ threadId: string;
42
+ turnId: string;
43
+ }
44
+ /** Coordinates durable mappings, thread ownership, and ephemeral tool responders. */
45
+ export declare class ContinuationCoordinator {
46
+ #private;
47
+ readonly store: ResponseStore;
48
+ private readonly rpc;
49
+ private readonly toolTimeoutMs;
50
+ constructor(store: ResponseStore, rpc: JsonRpcTransport, toolTimeoutMs: number);
51
+ /** Installs the sole dynamic-tool callback owner for a claimed thread. */
52
+ setToolOwner(threadId: string, owner: (request: PendingToolCall) => void): boolean;
53
+ /** Removes a dynamic-tool callback owner if it is still the expected owner. */
54
+ clearToolOwner(threadId: string, owner: (request: PendingToolCall) => void): void;
55
+ /** Claims exclusive use of a thread, returning false rather than queueing. */
56
+ claim(threadId: string): boolean;
57
+ /** Releases exclusive use unless a suspended tool call still owns the thread. */
58
+ release(threadId: string): void;
59
+ /** Persists and keeps the responder for a dynamic-tool suspension. */
60
+ suspend(responseId: string, binding: ThreadBinding, calls: PendingToolCall[]): void;
61
+ /** Returns the live suspension, distinguishing restart tombstones from unknown IDs. */
62
+ pending(responseId: string): PendingToolCall[] | undefined;
63
+ /** Resolves live pending tool IDs to exactly one suspended response. */
64
+ findPendingResponse(callIds: readonly string[]): string;
65
+ /** Answers pending calls in deterministic call order and consumes the suspension. */
66
+ resolve(responseId: string, results: Map<string, string>): PendingToolCall[] | undefined;
67
+ /** Records a completed response only while this transport generation is current. */
68
+ recordReady(responseId: string, threadId: string, binding: ThreadBinding): boolean;
69
+ /** Cancels ephemeral responders and detaches routing before transport replacement. */
70
+ dispose(): void;
71
+ }
@@ -0,0 +1,460 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { chmodSync, lstatSync, mkdirSync, readFileSync, readdirSync, renameSync, unlinkSync, writeFileSync, } from "node:fs";
3
+ import { basename, join } from "node:path";
4
+ import { toolCorrelationErrorForStatus, } from "../http/errors.js";
5
+ import { bindingHash, canonicalJson, record as asRecord, } from "../core/canonical.js";
6
+ export { bindingHash, canonicalJson };
7
+ /** Current on-disk continuation-store schema for the unreleased format. */
8
+ const SCHEMA_VERSION = 0;
9
+ /** Durable atomic response mapping store with bounded retention. */
10
+ export class ResponseStore {
11
+ retentionMs;
12
+ temporaryPath;
13
+ #path;
14
+ #records = new Map();
15
+ constructor(directory, retentionMs = 30 * 24 * 60 * 60_000, temporaryPath = defaultTemporaryPath) {
16
+ this.retentionMs = retentionMs;
17
+ this.temporaryPath = temporaryPath;
18
+ mkdirSync(directory, { recursive: true, mode: 0o700 });
19
+ hardenStatePath(directory, "directory");
20
+ this.#path = join(directory, "continuations.json");
21
+ hardenExistingStateFile(this.#path);
22
+ this.#sweepStaleTemporaries(directory);
23
+ this.#load();
24
+ }
25
+ /** Removes temporaries stranded by a crash between write and atomic rename. */
26
+ #sweepStaleTemporaries(directory) {
27
+ const prefix = `${basename(this.#path)}.`;
28
+ let entries;
29
+ try {
30
+ entries = readdirSync(directory);
31
+ }
32
+ catch {
33
+ return;
34
+ }
35
+ for (const entry of entries) {
36
+ if (!entry.startsWith(prefix) || !entry.endsWith(".tmp"))
37
+ continue;
38
+ try {
39
+ unlinkSync(join(directory, entry));
40
+ }
41
+ catch {
42
+ // A concurrent writer may still hold this temporary; leave it in place.
43
+ }
44
+ }
45
+ }
46
+ /** Retrieves a record after applying expiry and newest-response rules. */
47
+ get(responseId) {
48
+ const record = this.#records.get(responseId);
49
+ if (record &&
50
+ record.expiresAt <= Date.now() &&
51
+ record.state !== "expired") {
52
+ this.#mutateAndSave(() => {
53
+ record.state = "expired";
54
+ });
55
+ }
56
+ return record;
57
+ }
58
+ /** Inserts a record and supersedes the prior completed response for its thread. */
59
+ put(record) {
60
+ const now = Date.now();
61
+ const stored = {
62
+ ...record,
63
+ createdAt: now,
64
+ expiresAt: now + this.retentionMs,
65
+ };
66
+ this.#mutateAndSave(() => {
67
+ for (const prior of this.#records.values()) {
68
+ if (prior.threadId === record.threadId && prior.state === "ready")
69
+ prior.state = "superseded";
70
+ }
71
+ this.#records.set(stored.responseId, stored);
72
+ this.#prune(now);
73
+ });
74
+ return stored;
75
+ }
76
+ /** Changes an existing record without exposing partial disk writes. */
77
+ update(responseId, patch) {
78
+ const current = this.#records.get(responseId);
79
+ if (!current)
80
+ return undefined;
81
+ const updated = {
82
+ ...current,
83
+ ...patch,
84
+ responseId: current.responseId,
85
+ threadId: current.threadId,
86
+ };
87
+ this.#mutateAndSave(() => {
88
+ this.#records.set(responseId, updated);
89
+ });
90
+ return updated;
91
+ }
92
+ /** Finds durable records containing every requested dynamic-tool call ID. */
93
+ findByCallIds(callIds) {
94
+ const requested = new Set(callIds);
95
+ return [...this.#records.values()].filter((record) => record.callIds !== undefined &&
96
+ [...requested].every((id) => record.callIds.includes(id)));
97
+ }
98
+ /** Loads valid records and quarantines an unreadable store logically as empty. */
99
+ #load() {
100
+ try {
101
+ const input = JSON.parse(readFileSync(this.#path, "utf8"));
102
+ const parsed = asRecord(input);
103
+ if (!parsed)
104
+ return;
105
+ const records = parsed.version === SCHEMA_VERSION && Array.isArray(parsed.records)
106
+ ? parsed.records
107
+ : undefined;
108
+ // Other schemas are left untouched and treated as untrusted. There is no
109
+ // compatibility path because this on-disk format has not been released.
110
+ if (!records)
111
+ return;
112
+ for (const record of records)
113
+ if (isResponseRecord(record))
114
+ this.#records.set(record.responseId, { ...record });
115
+ // A responder cannot survive process restart; retain only its safe tombstone.
116
+ for (const record of this.#records.values())
117
+ if (record.state === "pending_tool")
118
+ record.state = "expired";
119
+ this.#prune(Date.now());
120
+ this.#save();
121
+ }
122
+ catch {
123
+ // Missing or corrupt state cannot be trusted for continuation.
124
+ }
125
+ }
126
+ /** Drops records older than the configured retention horizon. */
127
+ #prune(now) {
128
+ for (const [id, record] of this.#records)
129
+ if (record.expiresAt + this.retentionMs < now)
130
+ this.#records.delete(id);
131
+ }
132
+ /** Replaces the state file atomically so abrupt termination preserves the old file. */
133
+ #save() {
134
+ const temporary = this.temporaryPath(this.#path);
135
+ try {
136
+ writeFileSync(temporary, JSON.stringify({
137
+ version: SCHEMA_VERSION,
138
+ records: [...this.#records.values()],
139
+ }), {
140
+ encoding: "utf8",
141
+ mode: 0o600,
142
+ flag: "wx",
143
+ });
144
+ renameSync(temporary, this.#path);
145
+ }
146
+ catch (error) {
147
+ try {
148
+ unlinkSync(temporary);
149
+ }
150
+ catch {
151
+ // The write may have failed before creating its private temporary file.
152
+ }
153
+ throw error;
154
+ }
155
+ }
156
+ /** Commits a mutation durably or restores the exact prior in-memory view. */
157
+ #mutateAndSave(mutate) {
158
+ const snapshot = new Map([...this.#records].map(([id, record]) => [id, { ...record }]));
159
+ try {
160
+ mutate();
161
+ this.#save();
162
+ }
163
+ catch (error) {
164
+ this.#records.clear();
165
+ for (const [id, record] of snapshot)
166
+ this.#records.set(id, record);
167
+ throw error;
168
+ }
169
+ }
170
+ }
171
+ /** Creates an unpredictable same-directory path for one atomic state write. */
172
+ function defaultTemporaryPath(statePath) {
173
+ return `${statePath}.${process.pid}.${randomUUID()}.tmp`;
174
+ }
175
+ /** Tightens and validates the state directory on platforms with POSIX modes. */
176
+ function hardenStatePath(path, kind) {
177
+ const before = lstatSync(path);
178
+ if (before.isSymbolicLink() ||
179
+ (kind === "directory" ? !before.isDirectory() : !before.isFile()))
180
+ throw new Error(`Continuation state ${kind} must be a regular ${kind}.`);
181
+ if (process.platform === "win32")
182
+ return;
183
+ chmodSync(path, kind === "directory" ? 0o700 : 0o600);
184
+ const after = lstatSync(path);
185
+ const unsafe = kind === "directory" ? 0o077 : 0o177;
186
+ if ((after.mode & unsafe) !== 0)
187
+ throw new Error(`Continuation state ${kind} permissions are too broad.`);
188
+ }
189
+ /** Secures an existing state file without creating an empty replacement. */
190
+ function hardenExistingStateFile(path) {
191
+ try {
192
+ hardenStatePath(path, "file");
193
+ }
194
+ catch (error) {
195
+ if (error instanceof Error &&
196
+ "code" in error &&
197
+ error.code === "ENOENT")
198
+ return;
199
+ throw error;
200
+ }
201
+ }
202
+ /** Coordinates durable mappings, thread ownership, and ephemeral tool responders. */
203
+ export class ContinuationCoordinator {
204
+ store;
205
+ rpc;
206
+ toolTimeoutMs;
207
+ #pending = new Map();
208
+ #busy = new Set();
209
+ #toolOwners = new Map();
210
+ #disposed = false;
211
+ constructor(store, rpc, toolTimeoutMs) {
212
+ this.store = store;
213
+ this.rpc = rpc;
214
+ this.toolTimeoutMs = toolTimeoutMs;
215
+ this.rpc.on("request", this.#routeToolRequest);
216
+ this.rpc.once("close", this.#detachRouter);
217
+ }
218
+ /** Detaches the fail-closed router once no more frames can arrive. */
219
+ #detachRouter = () => {
220
+ this.rpc.off("request", this.#routeToolRequest);
221
+ };
222
+ /** Rejects one request while allowing disposal to survive transport closure. */
223
+ #failRequestReplaced(id) {
224
+ try {
225
+ this.rpc.respondError(id, {
226
+ code: -32000,
227
+ message: "App-server transport is being replaced",
228
+ });
229
+ }
230
+ catch {
231
+ // A concurrently closed transport has already failed the request.
232
+ }
233
+ }
234
+ /** Routes one dynamic-tool callback to the sole owner of its thread. */
235
+ #routeToolRequest = (request) => {
236
+ if (request.method !== "item/tool/call")
237
+ return;
238
+ if (this.#disposed) {
239
+ this.#failRequestReplaced(request.id);
240
+ return;
241
+ }
242
+ const params = asRecord(request.params);
243
+ if (!params ||
244
+ typeof params.threadId !== "string" ||
245
+ typeof params.turnId !== "string" ||
246
+ typeof params.callId !== "string" ||
247
+ typeof params.tool !== "string" ||
248
+ (params.namespace !== undefined && params.namespace !== null)) {
249
+ this.rpc.respondError(request.id, {
250
+ code: -32602,
251
+ message: "Invalid dynamic tool request",
252
+ });
253
+ return;
254
+ }
255
+ const owner = this.#toolOwners.get(params.threadId);
256
+ if (!owner) {
257
+ this.rpc.respondError(request.id, {
258
+ code: -32602,
259
+ message: "Dynamic tool correlation mismatch",
260
+ });
261
+ return;
262
+ }
263
+ owner({
264
+ request,
265
+ callId: params.callId,
266
+ name: params.tool,
267
+ arguments: params.arguments,
268
+ threadId: params.threadId,
269
+ turnId: params.turnId,
270
+ });
271
+ };
272
+ /** Installs the sole dynamic-tool callback owner for a claimed thread. */
273
+ setToolOwner(threadId, owner) {
274
+ if (this.#disposed)
275
+ throw new Error("Continuation coordinator is disposed.");
276
+ if (this.#toolOwners.has(threadId))
277
+ return false;
278
+ this.#toolOwners.set(threadId, owner);
279
+ return true;
280
+ }
281
+ /** Removes a dynamic-tool callback owner if it is still the expected owner. */
282
+ clearToolOwner(threadId, owner) {
283
+ if (this.#toolOwners.get(threadId) === owner)
284
+ this.#toolOwners.delete(threadId);
285
+ }
286
+ /** Claims exclusive use of a thread, returning false rather than queueing. */
287
+ claim(threadId) {
288
+ if (this.#busy.has(threadId))
289
+ return false;
290
+ this.#busy.add(threadId);
291
+ return true;
292
+ }
293
+ /** Releases exclusive use unless a suspended tool call still owns the thread. */
294
+ release(threadId) {
295
+ if (![...this.#pending.values()].some((entry) => entry.calls[0]?.threadId === threadId))
296
+ this.#busy.delete(threadId);
297
+ }
298
+ /** Persists and keeps the responder for a dynamic-tool suspension. */
299
+ suspend(responseId, binding, calls) {
300
+ if (this.#disposed)
301
+ throw new Error("Continuation coordinator is disposed.");
302
+ const threadId = calls[0].threadId;
303
+ this.#toolOwners.delete(threadId);
304
+ this.store.put({
305
+ responseId,
306
+ threadId,
307
+ state: "pending_tool",
308
+ ...binding,
309
+ callIds: calls.map((call) => call.callId),
310
+ });
311
+ const timer = setTimeout(() => {
312
+ for (const call of calls) {
313
+ try {
314
+ this.rpc.respondError(call.request.id, {
315
+ code: -32002,
316
+ message: "Dynamic tool result timed out",
317
+ });
318
+ }
319
+ catch {
320
+ // Transport failure must not escape a timer callback.
321
+ }
322
+ }
323
+ this.#pending.delete(responseId);
324
+ this.#busy.delete(threadId);
325
+ this.store.update(responseId, { state: "expired" });
326
+ }, this.toolTimeoutMs);
327
+ timer.unref();
328
+ this.#pending.set(responseId, { calls, timer });
329
+ }
330
+ /** Returns the live suspension, distinguishing restart tombstones from unknown IDs. */
331
+ pending(responseId) {
332
+ return this.#pending.get(responseId)?.calls;
333
+ }
334
+ /** Resolves live pending tool IDs to exactly one suspended response. */
335
+ findPendingResponse(callIds) {
336
+ const requested = new Set(callIds);
337
+ if (requested.size !== callIds.length)
338
+ throw toolLookupFailure(400, "duplicate_tool_call_id");
339
+ const matches = [...this.#pending.entries()].filter(([, entry]) => [...requested].every((id) => entry.calls.some((call) => call.callId === id)));
340
+ if (matches.length === 0) {
341
+ const tombstones = this.store
342
+ .findByCallIds(callIds)
343
+ .filter((record) => record.state === "expired");
344
+ if (tombstones.length === 1)
345
+ throw toolLookupFailure(410, "expired_tool_continuation");
346
+ if (tombstones.length > 1)
347
+ throw toolLookupFailure(409, "ambiguous_tool_call_id");
348
+ throw toolLookupFailure(404, "unknown_tool_call_id");
349
+ }
350
+ if (matches.length > 1)
351
+ throw toolLookupFailure(409, "ambiguous_tool_call_id");
352
+ return matches[0][0];
353
+ }
354
+ /** Answers pending calls in deterministic call order and consumes the suspension. */
355
+ resolve(responseId, results) {
356
+ const entry = this.#pending.get(responseId);
357
+ if (!entry)
358
+ return undefined;
359
+ const threadId = entry.calls[0].threadId;
360
+ // Consume before writing any response so a partial transport failure cannot
361
+ // leave a timerless suspension that may replay already-written results.
362
+ this.#pending.delete(responseId);
363
+ clearTimeout(entry.timer);
364
+ try {
365
+ for (const call of entry.calls) {
366
+ this.rpc.respond(call.request.id, {
367
+ contentItems: [
368
+ { type: "inputText", text: results.get(call.callId) },
369
+ ],
370
+ success: true,
371
+ });
372
+ }
373
+ }
374
+ catch (error) {
375
+ // Some earlier responses may already be on the wire. Expire the whole
376
+ // batch and release ownership; retrying it could duplicate those results.
377
+ this.#busy.delete(threadId);
378
+ this.store.update(responseId, { state: "expired" });
379
+ throw error;
380
+ }
381
+ this.store.update(responseId, { state: "superseded" });
382
+ return entry.calls;
383
+ }
384
+ /** Records a completed response only while this transport generation is current. */
385
+ recordReady(responseId, threadId, binding) {
386
+ if (this.#disposed)
387
+ return false;
388
+ this.store.put({ responseId, threadId, state: "ready", ...binding });
389
+ return true;
390
+ }
391
+ /** Cancels ephemeral responders and detaches routing before transport replacement. */
392
+ dispose() {
393
+ if (this.#disposed)
394
+ return;
395
+ this.#disposed = true;
396
+ // Keep the router installed in fail-closed mode until the transport closes.
397
+ this.#toolOwners.clear();
398
+ this.#busy.clear();
399
+ for (const [responseId, entry] of this.#pending) {
400
+ clearTimeout(entry.timer);
401
+ for (const call of entry.calls)
402
+ this.#failRequestReplaced(call.request.id);
403
+ this.store.update(responseId, { state: "expired" });
404
+ }
405
+ this.#pending.clear();
406
+ }
407
+ }
408
+ /** Validates every persisted field before a record can influence continuation. */
409
+ function isResponseRecord(value) {
410
+ const record = asRecord(value);
411
+ if (!record)
412
+ return false;
413
+ const allowedKeys = new Set([
414
+ "responseId",
415
+ "threadId",
416
+ "state",
417
+ "model",
418
+ "cwd",
419
+ "toolsHash",
420
+ "policyHash",
421
+ "createdAt",
422
+ "expiresAt",
423
+ "callIds",
424
+ ]);
425
+ const validStates = new Set([
426
+ "ready",
427
+ "pending_tool",
428
+ "expired",
429
+ "superseded",
430
+ "corrupt",
431
+ ]);
432
+ const validHash = (hash) => typeof hash === "string" && /^[a-f0-9]{64}$/.test(hash);
433
+ const callIds = record.callIds;
434
+ return (Object.keys(record).every((key) => allowedKeys.has(key)) &&
435
+ typeof record.responseId === "string" &&
436
+ record.responseId.length > 0 &&
437
+ typeof record.threadId === "string" &&
438
+ record.threadId.length > 0 &&
439
+ typeof record.model === "string" &&
440
+ record.model.length > 0 &&
441
+ typeof record.cwd === "string" &&
442
+ record.cwd.length > 0 &&
443
+ validHash(record.toolsHash) &&
444
+ validHash(record.policyHash) &&
445
+ typeof record.state === "string" &&
446
+ validStates.has(record.state) &&
447
+ typeof record.createdAt === "number" &&
448
+ Number.isFinite(record.createdAt) &&
449
+ typeof record.expiresAt === "number" &&
450
+ Number.isFinite(record.expiresAt) &&
451
+ (callIds === undefined ||
452
+ (Array.isArray(callIds) &&
453
+ callIds.every((id) => typeof id === "string") &&
454
+ new Set(callIds).size === callIds.length)));
455
+ }
456
+ /** Builds an OpenAI-shaped failure for implicit tool-call correlation. */
457
+ function toolLookupFailure(status, code) {
458
+ return toolCorrelationErrorForStatus(status, "The tool result could not be correlated to one pending call.", code, "tool_call_id");
459
+ }
460
+ //# sourceMappingURL=state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/continuation/state.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /** Options controlling a derived cancellation deadline. */
2
+ interface DeadlineOptions {
3
+ milliseconds: number;
4
+ timeoutReason: unknown;
5
+ abortReason?: (signal: AbortSignal) => unknown;
6
+ }
7
+ /** Registers one abort listener and returns an idempotent disposer. */
8
+ export declare function listenForAbort(signal: AbortSignal | undefined, listener: (signal: AbortSignal) => void): () => void;
9
+ /** Resolves after a delay or rejects with the signal's exact abort reason. */
10
+ export declare function abortableDelay(milliseconds: number, signal?: AbortSignal): Promise<void>;
11
+ /** Runs work with a derived signal that aborts at a deadline or with its parent. */
12
+ export declare function withDeadline<T>(parentSignal: AbortSignal | undefined, options: DeadlineOptions, run: (signal: AbortSignal) => Promise<T>): Promise<T>;
13
+ export {};
@@ -0,0 +1,74 @@
1
+ /** Registers one abort listener and returns an idempotent disposer. */
2
+ export function listenForAbort(signal, listener) {
3
+ if (signal === undefined)
4
+ return () => undefined;
5
+ if (signal.aborted) {
6
+ listener(signal);
7
+ return () => undefined;
8
+ }
9
+ let disposed = false;
10
+ const onAbort = () => {
11
+ if (disposed)
12
+ return;
13
+ try {
14
+ listener(signal);
15
+ }
16
+ finally {
17
+ dispose();
18
+ }
19
+ };
20
+ signal.addEventListener("abort", onAbort, { once: true });
21
+ const dispose = () => {
22
+ if (disposed)
23
+ return;
24
+ disposed = true;
25
+ signal.removeEventListener("abort", onAbort);
26
+ };
27
+ return dispose;
28
+ }
29
+ /** Resolves after a delay or rejects with the signal's exact abort reason. */
30
+ export function abortableDelay(milliseconds, signal) {
31
+ if (signal?.aborted)
32
+ return Promise.reject(signal.reason);
33
+ return new Promise((resolve, reject) => {
34
+ let settled = false;
35
+ const timer = setTimeout(done, milliseconds);
36
+ timer.unref();
37
+ const disposeAbort = listenForAbort(signal, (abortedSignal) => {
38
+ if (settled)
39
+ return;
40
+ settled = true;
41
+ clearTimeout(timer);
42
+ disposeAbort();
43
+ reject(abortedSignal.reason);
44
+ });
45
+ function done() {
46
+ if (settled)
47
+ return;
48
+ settled = true;
49
+ disposeAbort();
50
+ resolve();
51
+ }
52
+ });
53
+ }
54
+ /** Runs work with a derived signal that aborts at a deadline or with its parent. */
55
+ export async function withDeadline(parentSignal, options, run) {
56
+ const controller = new AbortController();
57
+ const disposeParent = listenForAbort(parentSignal, (abortedSignal) => {
58
+ controller.abort(options.abortReason === undefined
59
+ ? abortedSignal.reason
60
+ : options.abortReason(abortedSignal));
61
+ });
62
+ const timer = setTimeout(() => controller.abort(options.timeoutReason), options.milliseconds);
63
+ timer.unref();
64
+ try {
65
+ // Await the operation itself: aborting the derived signal does not settle an
66
+ // operation that intentionally ignores cancellation.
67
+ return await run(controller.signal);
68
+ }
69
+ finally {
70
+ clearTimeout(timer);
71
+ disposeParent();
72
+ }
73
+ }
74
+ //# sourceMappingURL=abort.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"abort.js","sourceRoot":"","sources":["../../src/core/abort.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /** Canonicalizes JSON values so equivalent structures serialize identically. */
2
+ export declare function canonicalJson(value: unknown): string;
3
+ /** Returns a stable SHA-256 binding for a JSON-compatible value. */
4
+ export declare function bindingHash(value: unknown): string;
5
+ /** Narrows an unknown value to a non-null, non-array object record. */
6
+ export declare function record(value: unknown): Record<string, unknown> | undefined;