@oai404iao/pi-codex-minimal-tools 1.4.0 → 2.0.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 (99) hide show
  1. package/README.md +44 -17
  2. package/THIRD_PARTY_NOTICES.md +20 -0
  3. package/config.schema.json +1 -2
  4. package/index.ts +2 -0
  5. package/package.json +14 -13
  6. package/provenance/openai-codex-ddea03ad-astra.json +54 -0
  7. package/src/activation.ts +1 -56
  8. package/src/adapter/compaction/checkpoint.ts +1 -0
  9. package/src/adapter/compaction/collect.ts +1 -0
  10. package/src/adapter/compaction/http.ts +1 -0
  11. package/src/adapter/compaction/request.ts +1 -0
  12. package/src/adapter/compaction/transport.ts +1 -0
  13. package/src/adapter/compaction/websocket.ts +1 -0
  14. package/src/background-image-generation.ts +1 -574
  15. package/src/capabilities.ts +1 -146
  16. package/src/codex-http.ts +1 -133
  17. package/src/codex-identity-extension.ts +1 -339
  18. package/src/codex-request-profile.ts +1 -45
  19. package/src/codex-reserved-tools.ts +1 -323
  20. package/src/codex-wire-identity.ts +1 -596
  21. package/src/extension/prewarm-snapshot.ts +1 -0
  22. package/src/extension/provider-presentation.ts +1 -0
  23. package/src/extension/provider-runtime.ts +1 -0
  24. package/src/extension/register.ts +36 -0
  25. package/src/extension/startup-prewarm.ts +1 -0
  26. package/src/fast-mode.ts +1 -124
  27. package/src/glyphs.ts +1 -70
  28. package/src/index.ts +8 -331
  29. package/src/model-catalog/catalog.ts +1 -636
  30. package/src/model-catalog/default-models.json +8 -0
  31. package/src/model-catalog/runtime.ts +1 -113
  32. package/src/model-catalog/types.ts +1 -95
  33. package/src/native-compaction.ts +1 -393
  34. package/src/patch/apply.ts +1 -338
  35. package/src/patch/parser.ts +1 -224
  36. package/src/patch/render.ts +1 -201
  37. package/src/provider-headers.ts +1 -54
  38. package/src/provider-native-tools.ts +1 -71
  39. package/src/provider-shim.ts +20 -4511
  40. package/src/providers/codex-apply-patch-tool.ts +1 -23
  41. package/src/providers/openai-codex/cache-key.ts +1 -0
  42. package/src/providers/openai-codex/captured-stream.ts +1 -0
  43. package/src/providers/openai-codex/constants.ts +1 -0
  44. package/src/providers/openai-codex/continuation.ts +1 -0
  45. package/src/providers/openai-codex/errors.ts +1 -0
  46. package/src/providers/openai-codex/events.ts +1 -0
  47. package/src/providers/openai-codex/headers.ts +1 -0
  48. package/src/providers/openai-codex/lite.ts +1 -0
  49. package/src/providers/openai-codex/message.ts +1 -0
  50. package/src/providers/openai-codex/prewarm.ts +1 -0
  51. package/src/providers/openai-codex/proxy.ts +1 -0
  52. package/src/providers/openai-codex/reasoning.ts +1 -0
  53. package/src/providers/openai-codex/request-body.ts +1 -0
  54. package/src/providers/openai-codex/request-context.ts +1 -0
  55. package/src/providers/openai-codex/request-metadata.ts +1 -0
  56. package/src/providers/openai-codex/retry.ts +1 -0
  57. package/src/providers/openai-codex/runtime.ts +1 -0
  58. package/src/providers/openai-codex/sse.ts +1 -0
  59. package/src/providers/openai-codex/stream-effects.ts +1 -0
  60. package/src/providers/openai-codex/stream.ts +1 -0
  61. package/src/providers/openai-codex/types.ts +1 -0
  62. package/src/providers/openai-codex/urls.ts +1 -0
  63. package/src/providers/openai-codex/usage.ts +1 -0
  64. package/src/providers/openai-codex/websocket-connection.ts +1 -0
  65. package/src/providers/openai-codex/websocket-events.ts +1 -0
  66. package/src/providers/openai-codex/websocket-session.ts +1 -0
  67. package/src/providers/openai-codex/websocket-socket.ts +1 -0
  68. package/src/providers/openai-codex/websocket-stream.ts +1 -0
  69. package/src/providers/openai-responses-shared.ts +7 -1463
  70. package/src/providers/responses/citations.ts +1 -0
  71. package/src/providers/responses/history.ts +1 -0
  72. package/src/providers/responses/items.ts +1 -0
  73. package/src/providers/responses/markdown.ts +1 -0
  74. package/src/providers/responses/messages.ts +1 -0
  75. package/src/providers/responses/signatures.ts +1 -0
  76. package/src/providers/responses/stream-state.ts +1 -0
  77. package/src/providers/responses/stream.ts +1 -0
  78. package/src/providers/responses/text-renderer.ts +1 -0
  79. package/src/providers/responses/text.ts +1 -0
  80. package/src/providers/responses/tool-identity.ts +1 -0
  81. package/src/providers/responses/tools.ts +1 -0
  82. package/src/providers/responses/types.ts +1 -0
  83. package/src/providers/responses/usage.ts +1 -0
  84. package/src/settings.ts +1 -247
  85. package/src/subagent-inline.ts +1 -8
  86. package/src/tools/apply-patch.ts +1 -84
  87. package/src/tools/image-generation/capture.ts +1 -0
  88. package/src/tools/image-generation/display.ts +1 -0
  89. package/src/tools/image-generation/preview.ts +1 -0
  90. package/src/tools/image-generation/storage.ts +1 -0
  91. package/src/tools/image-generation/types.ts +1 -0
  92. package/src/tools/image-generation.ts +1 -274
  93. package/src/tools/view-image.ts +1 -98
  94. package/src/tools/web-search/activity.ts +1 -0
  95. package/src/tools/web-search/capture.ts +1 -0
  96. package/src/tools/web-search/render.ts +1 -0
  97. package/src/tools/web-search.ts +1 -554
  98. package/src/utils/images.ts +1 -73
  99. package/src/utils/theme.ts +1 -0
@@ -1,596 +1 @@
1
- import { uuidv7 } from "@earendil-works/pi-ai";
2
- import {
3
- mkdirSync,
4
- readFileSync,
5
- renameSync,
6
- writeFileSync,
7
- } from "node:fs";
8
- import { dirname, join } from "node:path";
9
- import { getAgentDir } from "@earendil-works/pi-coding-agent";
10
-
11
- /**
12
- * Persistent Codex identity written by pi-codex-minimal-tools.
13
- *
14
- * `piSessionId` is only the lookup/binding key for Pi's session file. It is
15
- * never emitted on the Codex wire.
16
- */
17
- export interface CodexThreadIdentity {
18
- version: 1;
19
- piSessionId: string;
20
- sessionId: string;
21
- threadId: string;
22
- windowId: string;
23
- firstWindowId: string;
24
- previousWindowId?: string;
25
- windowNumber: number;
26
- parentThreadId?: string;
27
- forkedFromThreadId?: string;
28
- agentName?: string;
29
- subagentKind?: string;
30
- lastCompactionEntryId?: string;
31
- }
32
-
33
- export interface CodexWireIdentity {
34
- sessionId: string;
35
- threadId: string;
36
- windowId: string;
37
- }
38
-
39
- export interface CodexTurnIdentity {
40
- turnId: string;
41
- startedAtMs: number;
42
- parentTurnId?: string;
43
- rootTurnId?: string;
44
- turnState?: string;
45
- }
46
-
47
- export interface CodexRequestIdentity extends CodexWireIdentity {
48
- installationId: string;
49
- turnId: string;
50
- turnStartedAtMs?: number;
51
- requestKind: "turn" | "compaction" | "prewarm";
52
- parentThreadId?: string;
53
- forkedFromThreadId?: string;
54
- parentTurnId?: string;
55
- rootTurnId?: string;
56
- agentName?: string;
57
- subagentKind?: string;
58
- turnState?: string;
59
- }
60
-
61
- interface RuntimeSession {
62
- identity: CodexThreadIdentity;
63
- activeTurn?: CodexTurnIdentity;
64
- pendingTurnState?: string;
65
- extraThreads: Map<string, CodexThreadIdentity>;
66
- }
67
-
68
- interface CodexIdentityRuntime {
69
- sessions: Map<string, RuntimeSession>;
70
- installationId?: string;
71
- installationPath?: string;
72
- }
73
-
74
- const RUNTIME_SYMBOL = Symbol.for("@oai404iao/pi-codex/identity-runtime/v1");
75
- const UUID_PATTERN =
76
- /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
77
- const UUID_V7_PATTERN =
78
- /^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
79
- const INSTALLATION_UUID_V4_PATTERN =
80
- /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
81
-
82
- function runtime(): CodexIdentityRuntime {
83
- const globals = globalThis as typeof globalThis & {
84
- [RUNTIME_SYMBOL]?: CodexIdentityRuntime;
85
- };
86
- if (!globals[RUNTIME_SYMBOL]) {
87
- globals[RUNTIME_SYMBOL] = {
88
- sessions: new Map(),
89
- };
90
- }
91
- return globals[RUNTIME_SYMBOL];
92
- }
93
-
94
- /** Pi-owned identities are generated as RFC 9562 UUIDv7 values. */
95
- export function uuidV7(): string {
96
- return uuidv7();
97
- }
98
-
99
- function uuidV4(): string {
100
- if (typeof globalThis.crypto?.randomUUID === "function") {
101
- return globalThis.crypto.randomUUID();
102
- }
103
- const bytes = new Uint8Array(16);
104
- if (typeof globalThis.crypto?.getRandomValues === "function") {
105
- globalThis.crypto.getRandomValues(bytes);
106
- } else {
107
- for (let index = 0; index < bytes.length; index++) {
108
- bytes[index] = Math.floor(Math.random() * 256);
109
- }
110
- }
111
- bytes[6] = ((bytes[6] ?? 0) & 0x0f) | 0x40;
112
- bytes[8] = ((bytes[8] ?? 0) & 0x3f) | 0x80;
113
- const hex = [...bytes].map((byte) => byte.toString(16).padStart(2, "0")).join("");
114
- return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
115
- }
116
-
117
- export function isUuid(value: unknown): value is string {
118
- return typeof value === "string" && UUID_PATTERN.test(value);
119
- }
120
-
121
- export function isUuidV7(value: unknown): value is string {
122
- return typeof value === "string" && UUID_V7_PATTERN.test(value);
123
- }
124
-
125
- /**
126
- * Codex has one installation id for the installation, not one per Pi session.
127
- *
128
- * It is loaded and repaired synchronously because request payload assembly is
129
- * synchronous at this boundary.
130
- */
131
- function installationIdPath(): string {
132
- return process.env.PI_CODEX_INSTALLATION_ID_PATH
133
- ?? join(
134
- getAgentDir(),
135
- "pi-codex-minimal-tools",
136
- "installation_id",
137
- );
138
- }
139
-
140
- export function codexInstallationIdFor(_sessionKey?: string): string {
141
- const state = runtime();
142
- const path = installationIdPath();
143
- if (state.installationId && state.installationPath === path) {
144
- return state.installationId;
145
- }
146
- try {
147
- const persisted = readFileSync(path, "utf8").trim();
148
- if (INSTALLATION_UUID_V4_PATTERN.test(persisted)) {
149
- state.installationId = persisted;
150
- state.installationPath = path;
151
- return persisted;
152
- }
153
- } catch {
154
- // Missing/unreadable state is repaired below.
155
- }
156
-
157
- const generated = uuidV4();
158
- try {
159
- mkdirSync(dirname(path), { recursive: true });
160
- const temporary = `${path}.${process.pid}.${Date.now()}.tmp`;
161
- writeFileSync(temporary, `${generated}\n`, {
162
- encoding: "utf8",
163
- mode: 0o600,
164
- });
165
- renameSync(temporary, path);
166
- } catch {
167
- // Read-only environments retain the installation id for this process.
168
- }
169
- state.installationId = generated;
170
- state.installationPath = path;
171
- return state.installationId;
172
- }
173
-
174
- export function setCodexInstallationId(value: string): void {
175
- if (!INSTALLATION_UUID_V4_PATTERN.test(value)) {
176
- throw new Error("Codex installation id must be a UUIDv4");
177
- }
178
- runtime().installationId = value;
179
- runtime().installationPath = installationIdPath();
180
- }
181
-
182
- function newRootIdentity(piSessionId: string, forkedFromThreadId?: string): CodexThreadIdentity {
183
- const threadId = uuidV7();
184
- const windowId = uuidV7();
185
- return {
186
- version: 1,
187
- piSessionId,
188
- sessionId: threadId,
189
- threadId,
190
- windowId,
191
- firstWindowId: windowId,
192
- windowNumber: 0,
193
- ...(forkedFromThreadId ? { forkedFromThreadId } : {}),
194
- agentName: "root",
195
- };
196
- }
197
-
198
- export function createCodexRootIdentity(
199
- piSessionId: string,
200
- options: { forkedFromThreadId?: string } = {},
201
- ): CodexThreadIdentity {
202
- return newRootIdentity(piSessionId, options.forkedFromThreadId);
203
- }
204
-
205
- export function createCodexChildIdentity(
206
- piSessionId: string,
207
- parent: CodexThreadIdentity,
208
- options: {
209
- relation: "spawn" | "fork";
210
- agentName?: string;
211
- subagentKind?: string;
212
- },
213
- ): CodexThreadIdentity {
214
- const threadId = uuidV7();
215
- const windowId = uuidV7();
216
- return {
217
- version: 1,
218
- piSessionId,
219
- sessionId: parent.sessionId,
220
- threadId,
221
- windowId,
222
- firstWindowId: windowId,
223
- windowNumber: 0,
224
- parentThreadId: parent.threadId,
225
- ...(options.relation === "fork"
226
- ? { forkedFromThreadId: parent.threadId }
227
- : {}),
228
- ...(options.agentName ? { agentName: options.agentName } : {}),
229
- subagentKind: options.subagentKind ?? "collab_spawn",
230
- };
231
- }
232
-
233
- function cloneIdentity(identity: CodexThreadIdentity): CodexThreadIdentity {
234
- return structuredClone(identity);
235
- }
236
-
237
- export function registerCodexThreadIdentity(identity: CodexThreadIdentity): CodexThreadIdentity {
238
- const parsed = parseCodexThreadIdentity(identity);
239
- const existing = runtime().sessions.get(parsed.piSessionId);
240
- runtime().sessions.set(parsed.piSessionId, {
241
- identity: cloneIdentity(parsed),
242
- activeTurn: existing?.activeTurn,
243
- pendingTurnState: existing?.pendingTurnState,
244
- extraThreads: existing?.extraThreads ?? new Map(),
245
- });
246
- return cloneIdentity(parsed);
247
- }
248
-
249
- export function codexThreadIdentityFor(piSessionId: string | undefined): CodexThreadIdentity | undefined {
250
- if (!piSessionId) return undefined;
251
- const value = runtime().sessions.get(piSessionId)?.identity;
252
- return value ? cloneIdentity(value) : undefined;
253
- }
254
-
255
- function ensureFallbackSession(piSessionId: string): RuntimeSession {
256
- let state = runtime().sessions.get(piSessionId);
257
- if (!state) {
258
- state = {
259
- identity: newRootIdentity(piSessionId),
260
- extraThreads: new Map(),
261
- };
262
- runtime().sessions.set(piSessionId, state);
263
- }
264
- return state;
265
- }
266
-
267
- /**
268
- * Compatibility resolver used by tests and legacy call sites.
269
- *
270
- * A root Codex thread has `sessionId === threadId`. Additional explicit
271
- * thread keys share that root session while receiving their own thread/window.
272
- */
273
- export function resolveCodexWireIdentity(
274
- piSessionId: string,
275
- threadKey?: string,
276
- ): CodexWireIdentity {
277
- const session = ensureFallbackSession(piSessionId);
278
- if (
279
- !threadKey
280
- || threadKey === piSessionId
281
- || threadKey === session.identity.threadId
282
- ) {
283
- return {
284
- sessionId: session.identity.sessionId,
285
- threadId: session.identity.threadId,
286
- windowId: session.identity.windowId,
287
- };
288
- }
289
- let thread = session.extraThreads.get(threadKey);
290
- if (!thread) {
291
- const threadId = uuidV7();
292
- const windowId = uuidV7();
293
- thread = {
294
- version: 1,
295
- piSessionId,
296
- sessionId: session.identity.sessionId,
297
- threadId,
298
- windowId,
299
- firstWindowId: windowId,
300
- windowNumber: 0,
301
- };
302
- session.extraThreads.set(threadKey, thread);
303
- }
304
- return {
305
- sessionId: thread.sessionId,
306
- threadId: thread.threadId,
307
- windowId: thread.windowId,
308
- };
309
- }
310
-
311
- export function rotateCodexWindowId(piSessionId: string, threadKey?: string): void {
312
- const session = ensureFallbackSession(piSessionId);
313
- const identity =
314
- threadKey && threadKey !== piSessionId && threadKey !== session.identity.threadId
315
- ? session.extraThreads.get(threadKey)
316
- : session.identity;
317
- if (!identity) {
318
- resolveCodexWireIdentity(piSessionId, threadKey);
319
- return rotateCodexWindowId(piSessionId, threadKey);
320
- }
321
- identity.previousWindowId = identity.windowId;
322
- identity.windowId = uuidV7();
323
- identity.windowNumber += 1;
324
- }
325
-
326
- export function advanceCodexWindow(
327
- piSessionId: string,
328
- compactionEntryId?: string,
329
- ): CodexThreadIdentity {
330
- const state = ensureFallbackSession(piSessionId);
331
- if (
332
- compactionEntryId
333
- && state.identity.lastCompactionEntryId === compactionEntryId
334
- ) {
335
- return cloneIdentity(state.identity);
336
- }
337
- state.identity.previousWindowId = state.identity.windowId;
338
- state.identity.windowId = uuidV7();
339
- state.identity.windowNumber += 1;
340
- if (compactionEntryId) {
341
- state.identity.lastCompactionEntryId = compactionEntryId;
342
- }
343
- return cloneIdentity(state.identity);
344
- }
345
-
346
- export function beginCodexTurn(
347
- piSessionId: string,
348
- options: {
349
- parentPiSessionId?: string;
350
- turnId?: string;
351
- startedAtMs?: number;
352
- } = {},
353
- ): CodexTurnIdentity {
354
- const state = ensureFallbackSession(piSessionId);
355
- if (state.activeTurn) return structuredClone(state.activeTurn);
356
-
357
- const parentTurn = options.parentPiSessionId
358
- ? runtime().sessions.get(options.parentPiSessionId)?.activeTurn
359
- : undefined;
360
- const turnId = isUuidV7(options.turnId) ? options.turnId : uuidV7();
361
- const turn: CodexTurnIdentity = {
362
- turnId,
363
- startedAtMs: options.startedAtMs ?? Date.now(),
364
- ...(parentTurn ? { parentTurnId: parentTurn.turnId } : {}),
365
- rootTurnId: parentTurn?.rootTurnId ?? parentTurn?.turnId ?? turnId,
366
- ...(state.pendingTurnState
367
- ? { turnState: state.pendingTurnState }
368
- : {}),
369
- };
370
- delete state.pendingTurnState;
371
- state.activeTurn = turn;
372
- return structuredClone(turn);
373
- }
374
-
375
- export function currentCodexTurn(piSessionId: string | undefined): CodexTurnIdentity | undefined {
376
- if (!piSessionId) return undefined;
377
- const turn = runtime().sessions.get(piSessionId)?.activeTurn;
378
- return turn ? structuredClone(turn) : undefined;
379
- }
380
-
381
- export function endCodexTurn(piSessionId: string, turnId?: string): void {
382
- const state = runtime().sessions.get(piSessionId);
383
- if (!state?.activeTurn) return;
384
- if (turnId && state.activeTurn.turnId !== turnId) return;
385
- delete state.activeTurn;
386
- }
387
-
388
- export function codexTurnStateFor(piSessionId: string): string | undefined {
389
- return runtime().sessions.get(piSessionId)?.activeTurn?.turnState;
390
- }
391
-
392
- /** Store the first sticky-routing token for the active logical turn only. */
393
- export function captureCodexTurnState(
394
- piSessionId: string,
395
- token: string | undefined,
396
- ): void {
397
- if (typeof token !== "string" || !token.trim()) return;
398
- const state = ensureFallbackSession(piSessionId);
399
- if (!state.activeTurn) {
400
- if (!state.pendingTurnState) state.pendingTurnState = token.trim();
401
- return;
402
- }
403
- if (state.activeTurn.turnState) return;
404
- state.activeTurn.turnState = token.trim();
405
- }
406
-
407
- function metadataString(
408
- metadata: Record<string, unknown> | undefined,
409
- key: string,
410
- ): string | undefined {
411
- const value = metadata?.[key];
412
- return typeof value === "string" && value.trim() ? value.trim() : undefined;
413
- }
414
-
415
- /**
416
- * Resolve one immutable identity snapshot for an actual provider request.
417
- * Valid explicit UUID values are consumed directly; they are never used as
418
- * derivation keys.
419
- */
420
- export function resolveCodexRequestIdentity(
421
- piSessionId: string | undefined,
422
- metadata: Record<string, unknown> | undefined,
423
- requestKind: CodexRequestIdentity["requestKind"] = "turn",
424
- ): CodexRequestIdentity | undefined {
425
- const explicitSessionId = metadataString(metadata, "session_id");
426
- const explicitThreadId = metadataString(metadata, "thread_id");
427
- const explicitWindowId = metadataString(metadata, "window_id")
428
- ?? metadataString(metadata, "x-codex-window-id");
429
- const state = piSessionId ? ensureFallbackSession(piSessionId) : undefined;
430
- if (
431
- !state
432
- && (!isUuidV7(explicitSessionId) || !isUuidV7(explicitThreadId))
433
- ) {
434
- return undefined;
435
- }
436
- const identity = state?.identity;
437
- const sessionId = isUuidV7(explicitSessionId)
438
- ? explicitSessionId
439
- : identity?.sessionId;
440
- const threadId = isUuidV7(explicitThreadId)
441
- ? explicitThreadId
442
- : identity?.threadId;
443
- const windowId = isUuidV7(explicitWindowId)
444
- ? explicitWindowId
445
- : identity?.windowId;
446
- if (!sessionId || !threadId || !windowId) return undefined;
447
-
448
- let turn = state?.activeTurn;
449
- const explicitTurnId = metadataString(metadata, "turn_id");
450
- if (isUuidV7(explicitTurnId)) {
451
- if (!turn || turn.turnId !== explicitTurnId) {
452
- turn = {
453
- turnId: explicitTurnId,
454
- startedAtMs: Date.now(),
455
- rootTurnId: explicitTurnId,
456
- ...(state?.pendingTurnState
457
- ? { turnState: state.pendingTurnState }
458
- : {}),
459
- };
460
- if (state) {
461
- state.activeTurn = turn;
462
- delete state.pendingTurnState;
463
- }
464
- }
465
- } else if (!turn && requestKind !== "prewarm" && piSessionId) {
466
- turn = beginCodexTurn(piSessionId);
467
- }
468
-
469
- const explicitParentThreadId = metadataString(metadata, "parent_thread_id");
470
- const explicitForkedFromThreadId = metadataString(metadata, "forked_from_thread_id");
471
- const explicitParentTurnId = metadataString(metadata, "parent_turn_id");
472
- const explicitRootTurnId = metadataString(metadata, "root_turn_id");
473
- return {
474
- installationId: codexInstallationIdFor(),
475
- sessionId,
476
- threadId,
477
- windowId,
478
- turnId: turn?.turnId ?? "",
479
- ...(turn ? { turnStartedAtMs: turn.startedAtMs } : {}),
480
- requestKind,
481
- ...(isUuidV7(explicitParentThreadId)
482
- ? { parentThreadId: explicitParentThreadId }
483
- : identity?.parentThreadId
484
- ? { parentThreadId: identity.parentThreadId }
485
- : {}),
486
- ...(isUuidV7(explicitForkedFromThreadId)
487
- ? { forkedFromThreadId: explicitForkedFromThreadId }
488
- : identity?.forkedFromThreadId
489
- ? { forkedFromThreadId: identity.forkedFromThreadId }
490
- : {}),
491
- ...(isUuidV7(explicitParentTurnId)
492
- ? { parentTurnId: explicitParentTurnId }
493
- : turn?.parentTurnId
494
- ? { parentTurnId: turn.parentTurnId }
495
- : {}),
496
- ...(isUuidV7(explicitRootTurnId)
497
- ? { rootTurnId: explicitRootTurnId }
498
- : turn?.rootTurnId
499
- ? { rootTurnId: turn.rootTurnId }
500
- : {}),
501
- ...(identity?.agentName ? { agentName: identity.agentName } : {}),
502
- ...(identity?.subagentKind ? { subagentKind: identity.subagentKind } : {}),
503
- ...(turn?.turnState ? { turnState: turn.turnState } : {}),
504
- };
505
- }
506
-
507
- type UnknownRecord = Record<string, unknown>;
508
-
509
- function asRecord(value: unknown): UnknownRecord | undefined {
510
- return value && typeof value === "object" && !Array.isArray(value)
511
- ? value as UnknownRecord
512
- : undefined;
513
- }
514
-
515
- export function parseCodexThreadIdentity(value: unknown): CodexThreadIdentity {
516
- const input = asRecord(value);
517
- if (!input || input.version !== 1) {
518
- throw new Error("unsupported Codex thread identity version");
519
- }
520
- for (const field of [
521
- "piSessionId",
522
- "sessionId",
523
- "threadId",
524
- "windowId",
525
- "firstWindowId",
526
- ] as const) {
527
- if (typeof input[field] !== "string" || !input[field]) {
528
- throw new Error(`Codex thread identity ${field} must be a non-empty string`);
529
- }
530
- }
531
- for (const field of [
532
- "sessionId",
533
- "threadId",
534
- "windowId",
535
- "firstWindowId",
536
- "previousWindowId",
537
- "parentThreadId",
538
- "forkedFromThreadId",
539
- ] as const) {
540
- if (input[field] !== undefined && !isUuidV7(input[field])) {
541
- throw new Error(`Codex thread identity ${field} must be a UUIDv7`);
542
- }
543
- }
544
- if (
545
- typeof input.windowNumber !== "number"
546
- || !Number.isSafeInteger(input.windowNumber)
547
- || input.windowNumber < 0
548
- ) {
549
- throw new Error("Codex thread identity windowNumber must be a non-negative integer");
550
- }
551
- for (const field of [
552
- "agentName",
553
- "subagentKind",
554
- "lastCompactionEntryId",
555
- ] as const) {
556
- if (input[field] !== undefined && typeof input[field] !== "string") {
557
- throw new Error(`Codex thread identity ${field} must be a string`);
558
- }
559
- }
560
- return {
561
- version: 1,
562
- piSessionId: input.piSessionId as string,
563
- sessionId: input.sessionId as string,
564
- threadId: input.threadId as string,
565
- windowId: input.windowId as string,
566
- firstWindowId: input.firstWindowId as string,
567
- windowNumber: input.windowNumber,
568
- ...(input.previousWindowId
569
- ? { previousWindowId: input.previousWindowId as string }
570
- : {}),
571
- ...(input.parentThreadId
572
- ? { parentThreadId: input.parentThreadId as string }
573
- : {}),
574
- ...(input.forkedFromThreadId
575
- ? { forkedFromThreadId: input.forkedFromThreadId as string }
576
- : {}),
577
- ...(input.agentName ? { agentName: input.agentName as string } : {}),
578
- ...(input.subagentKind
579
- ? { subagentKind: input.subagentKind as string }
580
- : {}),
581
- ...(input.lastCompactionEntryId
582
- ? { lastCompactionEntryId: input.lastCompactionEntryId as string }
583
- : {}),
584
- };
585
- }
586
-
587
- export function resetCodexWireState(): void {
588
- const state = runtime();
589
- state.sessions.clear();
590
- delete state.installationId;
591
- delete state.installationPath;
592
- }
593
-
594
- export function codexWireIdentityCount(): number {
595
- return runtime().sessions.size;
596
- }
1
+ export * from "@oai404iao/pi-codex-runtime/internal/codex-wire-identity";
@@ -0,0 +1 @@
1
+ export * from "@oai404iao/pi-codex-core/internal/extension/prewarm-snapshot";
@@ -0,0 +1 @@
1
+ export * from "@oai404iao/pi-codex-runtime/internal/extension/provider-presentation";
@@ -0,0 +1 @@
1
+ export * from "@oai404iao/pi-codex-core/internal/extension/provider-runtime";
@@ -0,0 +1,36 @@
1
+ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
2
+ import type { OpenAIResponsesProviderController } from "@oai404iao/pi-codex-runtime/internal/providers/openai-codex/types";
3
+ import { createImageCapture } from "@oai404iao/pi-codex-imagegen/internal/tools/image-generation/capture";
4
+ import { createImageDisplay } from "@oai404iao/pi-codex-imagegen/internal/tools/image-generation/display";
5
+ import { createWebSearchCapture } from "@oai404iao/pi-codex-web-search/internal/tools/web-search/capture";
6
+ import { registerWebSearchActivityRenderer } from "@oai404iao/pi-codex-web-search/internal/tools/web-search/render";
7
+ import { registerResponsesProviderRuntime } from "@oai404iao/pi-codex-core/internal/extension/provider-runtime";
8
+
9
+ export function registerOpenAIResponsesProviders(
10
+ pi: ExtensionAPI,
11
+ options: { getCurrentCwd: () => string },
12
+ ): OpenAIResponsesProviderController {
13
+ const images = createImageDisplay(pi);
14
+ return registerResponsesProviderRuntime(pi, options, {
15
+ clear: images.clear,
16
+ flush: images.flush,
17
+ scheduleFlush: images.scheduleFlush,
18
+ registerRenderers() {
19
+ images.registerRenderer();
20
+ registerWebSearchActivityRenderer(pi);
21
+ },
22
+ streamEffects() {
23
+ const imageSink = images.captureSink();
24
+ return {
25
+ createEventObserver(context) {
26
+ const imageCapture = createImageCapture(context, imageSink);
27
+ const webSearchCapture = createWebSearchCapture(context);
28
+ return async (event) => {
29
+ await imageCapture(event);
30
+ webSearchCapture(event);
31
+ };
32
+ },
33
+ };
34
+ },
35
+ });
36
+ }
@@ -0,0 +1 @@
1
+ export * from "@oai404iao/pi-codex-core/internal/extension/startup-prewarm";