@pasko70/pibo 1.16.6 → 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 (145) hide show
  1. package/dist/agent-runtime/auth.js +28 -0
  2. package/dist/agent-runtime/capabilities.js +221 -0
  3. package/dist/agent-runtime/context-build.js +313 -0
  4. package/dist/agent-runtime/contract.js +45 -0
  5. package/dist/agent-runtime/errors.js +57 -0
  6. package/dist/agent-runtime/events.js +1 -0
  7. package/dist/agent-runtime/history.js +1 -0
  8. package/dist/agent-runtime/profile-validation.js +109 -0
  9. package/dist/agent-runtime/registry.js +608 -0
  10. package/dist/agent-runtime/resource-files.js +87 -0
  11. package/dist/agent-runtime/resource-service.js +635 -0
  12. package/dist/agent-runtime/resources.js +1 -0
  13. package/dist/agent-runtime/routed-session.js +931 -0
  14. package/dist/agent-runtime/testing/contract.js +51 -0
  15. package/dist/agent-runtime/testing/fake-adapter.js +192 -0
  16. package/dist/agent-runtime/types.js +3 -0
  17. package/dist/agent-runtimes/codex-native/adapter.js +905 -0
  18. package/dist/agent-runtimes/codex-native/auth.js +476 -0
  19. package/dist/agent-runtimes/codex-native/client.js +734 -0
  20. package/dist/agent-runtimes/codex-native/config.js +152 -0
  21. package/dist/agent-runtimes/codex-native/history.js +283 -0
  22. package/dist/agent-runtimes/codex-native/mcp-stdio-launcher.js +89 -0
  23. package/dist/agent-runtimes/codex-native/models.js +581 -0
  24. package/dist/agent-runtimes/codex-native/process.js +459 -0
  25. package/dist/agent-runtimes/codex-native/protocol-types.js +1 -0
  26. package/dist/agent-runtimes/codex-native/protocol-version.js +7 -0
  27. package/dist/agent-runtimes/codex-native/redaction.js +31 -0
  28. package/dist/agent-runtimes/codex-native/requests.js +378 -0
  29. package/dist/agent-runtimes/codex-native/resource-delivery.js +445 -0
  30. package/dist/agent-runtimes/codex-native/thread.js +388 -0
  31. package/dist/agent-runtimes/codex-native/turn.js +849 -0
  32. package/dist/agent-runtimes/pi/adapter.js +653 -0
  33. package/dist/agent-runtimes/pi/auth.js +455 -0
  34. package/dist/agent-runtimes/pi/history.js +640 -0
  35. package/dist/agent-runtimes/pi/model-catalog.js +87 -0
  36. package/dist/agent-runtimes/pi/routed-session.js +1464 -0
  37. package/dist/agent-runtimes/pi/runtime.js +534 -0
  38. package/dist/agent-runtimes/pi/tool-compiler.js +69 -0
  39. package/dist/apps/chat/agent-profiles.js +40 -23
  40. package/dist/apps/chat/agent-store.js +111 -64
  41. package/dist/apps/chat/chat-api-routes.js +1 -1
  42. package/dist/apps/chat/chat-request-normalizers.js +47 -0
  43. package/dist/apps/chat/data/chat-data-mappers.js +25 -9
  44. package/dist/apps/chat/data/history-query-service.js +108 -0
  45. package/dist/apps/chat/data/session-query-service.js +24 -3
  46. package/dist/apps/chat/data/timeline-query-service.js +3 -3
  47. package/dist/apps/chat/model-catalog.js +1 -55
  48. package/dist/apps/chat/provider-auth-actions.js +171 -23
  49. package/dist/apps/chat/stream.js +12 -0
  50. package/dist/apps/chat/trace-v2.js +1 -0
  51. package/dist/apps/chat/trace.js +126 -415
  52. package/dist/apps/chat/web-app.js +582 -157
  53. package/dist/apps/chat-ui/assets/{dist-BTLtT_Vf.js → dist-9v2ZXT6V.js} +1 -1
  54. package/dist/apps/chat-ui/assets/{dist-CMk1aPug.js → dist-B1LVAytl.js} +1 -1
  55. package/dist/apps/chat-ui/assets/{dist-CcwA_IWN.js → dist-C6LPDFXU.js} +1 -1
  56. package/dist/apps/chat-ui/assets/{dist-DKOthbxr.js → dist-DVtXxfHc.js} +1 -1
  57. package/dist/apps/chat-ui/assets/{dist-ls2I6BIw.js → dist-DW4Qrfbd.js} +1 -1
  58. package/dist/apps/chat-ui/assets/{dist-D1rAtRWs.js → dist-DmbsHdMC.js} +1 -1
  59. package/dist/apps/chat-ui/assets/{dist-C1JQRskW.js → dist-DyvwuSFO.js} +1 -1
  60. package/dist/apps/chat-ui/assets/{dist-DfpaylQ-.js → dist-I26VB0QO.js} +1 -1
  61. package/dist/apps/chat-ui/assets/{dist-D10bTFD5.js → dist-RtHbJRPV.js} +1 -1
  62. package/dist/apps/chat-ui/assets/{dist-5KpmmBBZ.js → dist-sZgJkWZb.js} +1 -1
  63. package/dist/apps/chat-ui/assets/index-BPbNvcZe.css +1 -0
  64. package/dist/apps/chat-ui/assets/index-CIOf2uL2.js +237 -0
  65. package/dist/apps/chat-ui/index.html +2 -2
  66. package/dist/apps/chat-vscode-web/assets/index-1ivRyjFs.js +41 -0
  67. package/dist/apps/chat-vscode-web/index.html +1 -1
  68. package/dist/apps/vscode-artifacts/latest.vsix +0 -0
  69. package/dist/apps/vscode-artifacts/pibo-vscode-ext-2.0.0.vsix +0 -0
  70. package/dist/auth/login-actions.js +5 -251
  71. package/dist/cli-session/localSessionSource.js +8 -1
  72. package/dist/core/context-build.js +124 -20
  73. package/dist/core/default-profile.js +8 -0
  74. package/dist/core/profiles.js +30 -3
  75. package/dist/core/routed-session.js +5 -1446
  76. package/dist/core/runtime.js +5 -561
  77. package/dist/core/session-router.js +637 -83
  78. package/dist/data/cli.js +20 -3
  79. package/dist/data/schema.js +104 -1
  80. package/dist/data/session-store.js +24 -1
  81. package/dist/debug/events.js +25 -10
  82. package/dist/debug/failures.js +23 -3
  83. package/dist/debug/index.js +24 -6
  84. package/dist/debug/messages.js +87 -7
  85. package/dist/debug/persisted-payloads.js +31 -0
  86. package/dist/debug/pty.js +7 -6
  87. package/dist/debug/runtime-binding.js +29 -0
  88. package/dist/debug/session.js +137 -0
  89. package/dist/debug/summary.js +12 -0
  90. package/dist/debug/telemetry.js +28 -0
  91. package/dist/debug/tools.js +12 -2
  92. package/dist/debug/trace.js +154 -76
  93. package/dist/gateway/server.js +87 -2
  94. package/dist/gateway/tool.js +5 -5
  95. package/dist/index.js +21 -2
  96. package/dist/loops/tools.js +13 -12
  97. package/dist/mcp/agent-context.js +13 -4
  98. package/dist/mcp/client.js +10 -6
  99. package/dist/mcp/config.js +5 -2
  100. package/dist/mcp/runtime-session.js +166 -0
  101. package/dist/plugins/builtin.js +191 -53
  102. package/dist/plugins/codex-native.js +29 -0
  103. package/dist/plugins/registry.js +66 -2
  104. package/dist/runs/tools.js +26 -25
  105. package/dist/session-ui/terminalRows.js +2 -2
  106. package/dist/sessions/pibo-data-store.js +125 -16
  107. package/dist/sessions/runtime-binding.js +107 -0
  108. package/dist/sessions/sqlite-store.js +239 -18
  109. package/dist/sessions/store.js +86 -7
  110. package/dist/shared/trace-engine.js +18 -9
  111. package/dist/shared/trace-event-projection.js +29 -11
  112. package/dist/shared/{trace-transcript.js → trace-history.js} +193 -195
  113. package/dist/shared/trace-order.js +9 -4
  114. package/dist/shared/trace-page-merge.js +1 -1
  115. package/dist/signals/projector.js +20 -2
  116. package/dist/signals/registry.js +11 -0
  117. package/dist/subagents/tool.js +8 -6
  118. package/dist/tools/codex-browser.js +20 -19
  119. package/dist/tools/codex-compat.js +10 -9
  120. package/dist/tools/codex-image-generation.js +8 -6
  121. package/dist/tools/contract.js +45 -0
  122. package/dist/tools/credential-registry.js +182 -0
  123. package/dist/tools/mcp-bridge.js +511 -0
  124. package/dist/tools/payload-writer.js +17 -0
  125. package/dist/tools/runtime/tool.js +10 -9
  126. package/dist/tools/schema.js +9 -0
  127. package/dist/tools/session-service.js +193 -0
  128. package/dist/tools/session-tool-set.js +85 -0
  129. package/dist/web-annotations/tools.js +17 -16
  130. package/docs/README.md +11 -0
  131. package/package.json +3 -2
  132. package/skills/builtin/pibo-agent-runtime-adapter/SKILL.md +183 -0
  133. package/skills/builtin/pibo-agent-runtime-adapter/evals/README.md +10 -0
  134. package/skills/builtin/pibo-agent-runtime-adapter/evals/evals.json +45 -0
  135. package/skills/builtin/pibo-agent-runtime-adapter/evals/fixtures/orion-full-harness.md +60 -0
  136. package/skills/builtin/pibo-agent-runtime-adapter/evals/fixtures/relay-partial-harness.md +52 -0
  137. package/skills/builtin/pibo-agent-runtime-adapter/references/capabilities-and-designer.md +194 -0
  138. package/skills/builtin/pibo-agent-runtime-adapter/references/history-debug-and-security.md +213 -0
  139. package/skills/builtin/pibo-agent-runtime-adapter/references/interfaces-and-registration.md +214 -0
  140. package/skills/builtin/pibo-agent-runtime-adapter/references/lifecycle-bindings-and-events.md +193 -0
  141. package/skills/builtin/pibo-agent-runtime-adapter/references/portable-delivery-and-native-behavior.md +226 -0
  142. package/skills/builtin/pibo-agent-runtime-adapter/references/testing-migration-and-validation.md +256 -0
  143. package/dist/apps/chat-ui/assets/index-C2YI0xfw.js +0 -237
  144. package/dist/apps/chat-ui/assets/index-E0RmuCkY.css +0 -1
  145. package/dist/apps/chat-vscode-web/assets/index-D-tSsXLG.js +0 -41
@@ -0,0 +1,905 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { unsupportedAgentRuntimeCapability, } from "../../agent-runtime/capabilities.js";
3
+ import { AgentRuntimeBindingMissingError, AgentRuntimeUnavailableError, } from "../../agent-runtime/errors.js";
4
+ import { selectRequestedFastMode, selectRequestedModelProfile, selectRequestedThinkingLevel, } from "../../core/model-defaults.js";
5
+ import { CODEX_NATIVE_RUNTIME_CONFIG_SCHEMA, defaultCodexNativeRuntimeConfig, parseCodexNativeRuntimeConfig, } from "./config.js";
6
+ import { diagnoseCodexNativeRuntime, startCodexNativeAppServer, } from "./process.js";
7
+ import { inspectCodexThreadHistory, pageCodexThreadHistory, unavailableCodexThreadHistoryInspection, } from "./history.js";
8
+ import { CODEX_NATIVE_ADAPTER_ID, CodexNativeThreadController, CodexNativeThreadMissingError, } from "./thread.js";
9
+ import { CODEX_APP_SERVER_PROTOCOL_NAME, CODEX_APP_SERVER_SUPPORTED_RANGE, CODEX_APP_SERVER_VERSION, } from "./protocol-version.js";
10
+ import { CodexNativeTurnController } from "./turn.js";
11
+ import { CodexNativeRequestController } from "./requests.js";
12
+ import { CodexNativeResourceDelivery } from "./resource-delivery.js";
13
+ import { CODEX_NATIVE_MODEL_OPTIONS_SCHEMA, CODEX_NATIVE_MODEL_PROVIDER_ID, CODEX_NATIVE_REASONING_VALUES, CodexNativeSessionSettingsController, parseCodexNativeProfileOptions, readCodexNativeModelCatalog, readCodexNativePersistedSettings, toAgentRuntimeModelCatalog, } from "./models.js";
14
+ import { CodexNativeAuthController } from "./auth.js";
15
+ export { CODEX_NATIVE_ADAPTER_ID } from "./thread.js";
16
+ export const CODEX_NATIVE_ADAPTER_VERSION = "1.0.0";
17
+ function codexNativeCapabilities(structuredUserInput) {
18
+ return {
19
+ lifecycle: {
20
+ persistent: true,
21
+ lazyBinding: false,
22
+ resume: true,
23
+ attach: true,
24
+ listNativeSessions: true,
25
+ fork: true,
26
+ clone: true,
27
+ tree: false,
28
+ },
29
+ input: {
30
+ text: true,
31
+ images: false,
32
+ audio: false,
33
+ steering: true,
34
+ structuredOutput: false,
35
+ },
36
+ output: {
37
+ assistantDeltas: true,
38
+ reasoning: true,
39
+ toolEvents: true,
40
+ usage: true,
41
+ plans: false,
42
+ diffs: false,
43
+ rawNativeEvents: false,
44
+ },
45
+ tools: {
46
+ piboManaged: { support: "mcp", transports: ["streamable-http"] },
47
+ nativeToolInspection: {
48
+ support: "degraded",
49
+ mode: "observed-runtime-items",
50
+ reason: "Stable Codex App Server 0.147.0 does not expose a complete pre-turn native-tool inventory; Pibo reports selected MCP tools immediately and harness-native tools after stable item notifications prove they are active.",
51
+ },
52
+ nativeToolYielding: unsupportedAgentRuntimeCapability("Codex native tools remain harness-owned and are not wrapped as Pibo yielded tools."),
53
+ },
54
+ mcp: {
55
+ externalServers: { support: "mcp", transports: ["streamable-http", "stdio"] },
56
+ statusInspection: true,
57
+ },
58
+ skills: { support: "materialized", modes: ["codex-extra-roots"] },
59
+ context: { support: "materialized", modes: ["native-project-discovery", "codex-developer-instructions"] },
60
+ auth: {
61
+ status: true,
62
+ methods: [
63
+ { id: "device_code", completion: "notification" },
64
+ { id: "api_key", completion: "immediate" },
65
+ ],
66
+ cancel: true,
67
+ logout: true,
68
+ credentialScope: "runtime-instance",
69
+ },
70
+ models: {
71
+ catalog: true,
72
+ switchInSession: true,
73
+ optionsSchema: CODEX_NATIVE_MODEL_OPTIONS_SCHEMA,
74
+ },
75
+ reasoning: {
76
+ supported: true,
77
+ values: CODEX_NATIVE_REASONING_VALUES,
78
+ },
79
+ approvals: {
80
+ supported: true,
81
+ structuredUserInput,
82
+ },
83
+ maintenance: {
84
+ compaction: false,
85
+ contextUsage: true,
86
+ history: true,
87
+ health: true,
88
+ },
89
+ };
90
+ }
91
+ export const CODEX_NATIVE_THREAD_CAPABILITIES = codexNativeCapabilities(false);
92
+ function timestamp(seconds) {
93
+ return new Date(seconds * 1_000).toISOString();
94
+ }
95
+ function safeThreadMetadata(thread, previous = {}, settings = {}) {
96
+ const { diagnosticCode: _diagnosticCode, diagnosticMessage: _diagnosticMessage, ...metadata } = previous;
97
+ return {
98
+ ...metadata,
99
+ ...settings,
100
+ persistent: true,
101
+ nativePresenceExpected: true,
102
+ threadCreatedAt: timestamp(thread.createdAt),
103
+ threadUpdatedAt: timestamp(thread.updatedAt),
104
+ threadStatus: thread.status.type,
105
+ modelProvider: thread.modelProvider,
106
+ };
107
+ }
108
+ function bindingForThread(input) {
109
+ return {
110
+ ...(input.previous ? structuredClone(input.previous) : {}),
111
+ piboSessionId: input.piboSessionId,
112
+ runtimeInstanceId: input.runtimeInstanceId,
113
+ adapterId: CODEX_NATIVE_ADAPTER_ID,
114
+ nativeSessionId: input.thread.id,
115
+ state: "bound",
116
+ protocol: CODEX_APP_SERVER_PROTOCOL_NAME,
117
+ protocolVersion: CODEX_APP_SERVER_VERSION,
118
+ adapterVersion: CODEX_NATIVE_ADAPTER_VERSION,
119
+ locator: { kind: "adapter-resolved" },
120
+ metadata: safeThreadMetadata(input.thread, input.previous?.metadata, input.settings),
121
+ };
122
+ }
123
+ function validateOpenBinding(input, runtimeInstanceId) {
124
+ const binding = input.binding
125
+ ? structuredClone(input.binding)
126
+ : {
127
+ piboSessionId: input.piboSession.id,
128
+ runtimeInstanceId,
129
+ adapterId: CODEX_NATIVE_ADAPTER_ID,
130
+ state: "unbound",
131
+ };
132
+ if (binding.piboSessionId !== input.piboSession.id) {
133
+ throw new AgentRuntimeUnavailableError(runtimeInstanceId, "The Codex binding belongs to a different Pibo Session.");
134
+ }
135
+ if (binding.runtimeInstanceId !== runtimeInstanceId || binding.adapterId !== CODEX_NATIVE_ADAPTER_ID) {
136
+ throw new AgentRuntimeUnavailableError(runtimeInstanceId, "The Codex binding does not match the configured runtime instance.");
137
+ }
138
+ if (binding.state === "missing") {
139
+ throw new AgentRuntimeBindingMissingError(binding.piboSessionId, runtimeInstanceId, binding.nativeSessionId);
140
+ }
141
+ if (binding.state === "error") {
142
+ throw new AgentRuntimeUnavailableError(runtimeInstanceId, "The persisted Codex binding is in an error state.");
143
+ }
144
+ if (binding.state === "bound" && !binding.nativeSessionId) {
145
+ throw new AgentRuntimeUnavailableError(runtimeInstanceId, "The persisted Codex binding has no native thread id.");
146
+ }
147
+ if (binding.state === "unbound" && binding.nativeSessionId) {
148
+ throw new AgentRuntimeUnavailableError(runtimeInstanceId, "An unbound Codex binding cannot contain a native thread id.");
149
+ }
150
+ return binding;
151
+ }
152
+ const RESOURCE_MAINTENANCE_RETRY_MS = 5_000;
153
+ const MAX_INSPECTED_SELECTED_TOOL_NAMES = 512;
154
+ const MAX_INSPECTED_TOOL_NAMES = 256;
155
+ export class CodexNativeThreadSession {
156
+ runtimeInstanceId;
157
+ settings;
158
+ structuredUserInput;
159
+ reloadProcess;
160
+ productContext;
161
+ adapterId = CODEX_NATIVE_ADAPTER_ID;
162
+ cwd;
163
+ capabilities;
164
+ controls;
165
+ listeners = new Set();
166
+ turns;
167
+ requests;
168
+ process;
169
+ threads;
170
+ resourceDelivery;
171
+ binding;
172
+ disposed = false;
173
+ operationInFlight = false;
174
+ resourceMaintenanceTimer;
175
+ resourceRefresh;
176
+ resourceWarning;
177
+ resourceProcessUnavailable = false;
178
+ recycleProcessAfterInterruptedTurn = false;
179
+ selectedToolNames = new Set();
180
+ observedToolNames = new Set();
181
+ toolInventoryWarning;
182
+ constructor(runtimeInstanceId, process, threads, settings, resourceDelivery, binding, structuredUserInput, reloadProcess, productContext) {
183
+ this.runtimeInstanceId = runtimeInstanceId;
184
+ this.settings = settings;
185
+ this.structuredUserInput = structuredUserInput;
186
+ this.reloadProcess = reloadProcess;
187
+ this.productContext = productContext;
188
+ this.process = process;
189
+ this.threads = threads;
190
+ this.resourceDelivery = resourceDelivery;
191
+ this.updateSelectedToolNames(resourceDelivery);
192
+ this.cwd = threads.thread.cwd;
193
+ this.binding = structuredClone(binding);
194
+ this.capabilities = codexNativeCapabilities(structuredUserInput);
195
+ this.turns = new CodexNativeTurnController(process.client, threads, (event) => this.emit(event));
196
+ this.requests = this.createRequestController(process);
197
+ this.controls = {
198
+ getCurrentSession: () => this.threads.getSnapshot(this.runtimeInstanceId),
199
+ listSessions: () => this.threads.list(this.runtimeInstanceId, this.cwd),
200
+ getForkCandidates: () => this.threads.getForkCandidates(),
201
+ forkSession: async (entryId) => await this.runIdleOperation(async () => {
202
+ const result = await this.threads.fork(this.runtimeInstanceId, this.cwd, entryId, async (threadId) => await this.resourceDelivery.verifyThread(this.process.client, threadId));
203
+ this.settings.attachThread(this.threads.thread.id, this.threads.configuration);
204
+ this.updateBindingFromCurrentThread();
205
+ return result;
206
+ }),
207
+ cloneSession: async () => await this.runIdleOperation(async () => {
208
+ const result = await this.threads.clone(this.runtimeInstanceId, this.cwd, async (threadId) => await this.resourceDelivery.verifyThread(this.process.client, threadId));
209
+ this.settings.attachThread(this.threads.thread.id, this.threads.configuration);
210
+ this.updateBindingFromCurrentThread();
211
+ return result;
212
+ }),
213
+ getReasoning: () => this.settings.reasoning,
214
+ setReasoning: (value) => {
215
+ this.assertIdle();
216
+ return this.settings.setReasoning(value);
217
+ },
218
+ cycleReasoning: () => {
219
+ this.assertIdle();
220
+ return this.settings.cycleReasoning();
221
+ },
222
+ getFastMode: () => this.settings.fastMode,
223
+ setFastMode: (enabled) => {
224
+ this.assertIdle();
225
+ return this.settings.setFastMode(enabled);
226
+ },
227
+ setModel: async (model) => {
228
+ this.assertIdle();
229
+ return this.settings.setModel(model);
230
+ },
231
+ respondToApproval: (requestId, decision) => this.requests.respondToApproval(requestId, decision),
232
+ respondToUserInput: (requestId, answers) => this.requests.respondToUserInput(requestId, answers),
233
+ };
234
+ this.scheduleResourceMaintenance();
235
+ }
236
+ get pendingApproval() {
237
+ return this.requests.pendingApproval;
238
+ }
239
+ get pendingUserInput() {
240
+ return this.requests.pendingUserInput;
241
+ }
242
+ get pendingApprovals() {
243
+ return this.requests.pendingApprovals;
244
+ }
245
+ get pendingUserInputs() {
246
+ return this.requests.pendingUserInputs;
247
+ }
248
+ getBinding() {
249
+ this.updateBindingFromCurrentThread();
250
+ return structuredClone(this.binding);
251
+ }
252
+ subscribe(listener) {
253
+ this.assertActive();
254
+ this.listeners.add(listener);
255
+ return () => this.listeners.delete(listener);
256
+ }
257
+ async prompt(input) {
258
+ this.assertActive();
259
+ await this.ensureFreshResourcesForTurn();
260
+ this.operationInFlight = true;
261
+ try {
262
+ await this.turns.start(input.text, this.productContext?.getActiveMessage?.()?.id ?? randomUUID(), this.settings.turnOptions);
263
+ this.updateBindingFromCurrentThread();
264
+ }
265
+ finally {
266
+ this.operationInFlight = false;
267
+ if (this.recycleProcessAfterInterruptedTurn && !this.disposed) {
268
+ this.recycleProcessAfterInterruptedTurn = false;
269
+ try {
270
+ await this.rolloverResourceProcess();
271
+ }
272
+ catch (error) {
273
+ this.resourceWarning = error instanceof Error
274
+ ? error.message
275
+ : "Native Codex process recycling failed after turn interruption; Pibo will retry while the session remains idle.";
276
+ }
277
+ }
278
+ this.scheduleResourceMaintenance();
279
+ }
280
+ }
281
+ async steer(input) {
282
+ this.assertActive();
283
+ await this.turns.steer(input.text, randomUUID());
284
+ }
285
+ async abort() {
286
+ this.assertActive();
287
+ if (!this.turns.streaming) {
288
+ await this.turns.interrupt();
289
+ return;
290
+ }
291
+ this.recycleProcessAfterInterruptedTurn = true;
292
+ try {
293
+ await this.turns.interrupt();
294
+ }
295
+ catch (error) {
296
+ this.recycleProcessAfterInterruptedTurn = false;
297
+ throw error;
298
+ }
299
+ }
300
+ async dispose() {
301
+ if (this.disposed)
302
+ return;
303
+ this.disposed = true;
304
+ if (this.resourceMaintenanceTimer)
305
+ clearTimeout(this.resourceMaintenanceTimer);
306
+ this.resourceMaintenanceTimer = undefined;
307
+ await this.resourceRefresh?.catch(() => { });
308
+ this.requests.dispose();
309
+ this.turns.dispose();
310
+ this.settings.dispose();
311
+ this.listeners.clear();
312
+ try {
313
+ await this.process.close();
314
+ }
315
+ finally {
316
+ this.resourceDelivery.dispose();
317
+ }
318
+ }
319
+ getStatus() {
320
+ const diagnostics = this.process.client.getDiagnostics();
321
+ return {
322
+ streaming: this.turns.streaming,
323
+ enabledTools: [...new Set([...this.selectedToolNames, ...this.observedToolNames])].sort(),
324
+ cwd: this.cwd,
325
+ activeModel: this.settings.activeModel,
326
+ reasoning: this.settings.reasoning,
327
+ fastMode: this.settings.fastMode,
328
+ contextUsage: this.settings.currentContextUsage,
329
+ warnings: [
330
+ ...diagnostics.filter((entry) => entry.level === "warning").map((entry) => entry.message),
331
+ ...(this.resourceWarning ? [this.resourceWarning] : []),
332
+ ...(this.toolInventoryWarning ? [this.toolInventoryWarning] : []),
333
+ ],
334
+ errors: [
335
+ ...diagnostics.filter((entry) => entry.level === "error").map((entry) => entry.message),
336
+ ...(this.resourceProcessUnavailable
337
+ ? ["Native Codex resource process is unavailable pending a bounded retry."]
338
+ : []),
339
+ ],
340
+ };
341
+ }
342
+ getNativeCompatibilityHandle() {
343
+ return this.process.client;
344
+ }
345
+ createRequestController(process) {
346
+ return new CodexNativeRequestController(process.client, () => this.threads.thread.id, () => this.turns.activeTurnId, this.structuredUserInput, (event) => this.emit(event));
347
+ }
348
+ async runIdleOperation(operation) {
349
+ await this.resourceRefresh;
350
+ this.assertIdle();
351
+ this.operationInFlight = true;
352
+ try {
353
+ return await operation();
354
+ }
355
+ finally {
356
+ this.operationInFlight = false;
357
+ this.scheduleResourceMaintenance();
358
+ }
359
+ }
360
+ scheduleResourceMaintenance(delayMs) {
361
+ if (this.resourceMaintenanceTimer)
362
+ clearTimeout(this.resourceMaintenanceTimer);
363
+ this.resourceMaintenanceTimer = undefined;
364
+ if (this.disposed)
365
+ return;
366
+ const maintenanceAt = this.resourceDelivery.nextCredentialMaintenanceAt;
367
+ if (maintenanceAt === undefined && delayMs === undefined)
368
+ return;
369
+ const delay = delayMs ?? Math.max(25, maintenanceAt - Date.now());
370
+ this.resourceMaintenanceTimer = setTimeout(() => {
371
+ this.resourceMaintenanceTimer = undefined;
372
+ void this.maintainResourceCredential();
373
+ }, Math.max(25, delay));
374
+ this.resourceMaintenanceTimer.unref?.();
375
+ }
376
+ async maintainResourceCredential() {
377
+ if (this.disposed)
378
+ return;
379
+ const busy = this.operationInFlight
380
+ || this.turns.streaming
381
+ || this.requests.pendingApprovals.length > 0
382
+ || this.requests.pendingUserInputs.length > 0;
383
+ try {
384
+ if (this.resourceProcessUnavailable) {
385
+ if (busy) {
386
+ this.scheduleResourceMaintenance(RESOURCE_MAINTENANCE_RETRY_MS);
387
+ return;
388
+ }
389
+ await this.rolloverResourceProcess();
390
+ }
391
+ else if (this.resourceDelivery.shouldRolloverCredential()) {
392
+ if (busy) {
393
+ this.resourceDelivery.renewCredential();
394
+ this.resourceWarning = undefined;
395
+ this.scheduleResourceMaintenance(RESOURCE_MAINTENANCE_RETRY_MS);
396
+ return;
397
+ }
398
+ await this.rolloverResourceProcess();
399
+ }
400
+ else {
401
+ try {
402
+ this.resourceDelivery.renewCredential();
403
+ }
404
+ catch {
405
+ if (busy)
406
+ throw new Error("Native Codex portable-resource credentials could not be renewed during the active turn.");
407
+ await this.rolloverResourceProcess();
408
+ }
409
+ }
410
+ this.resourceWarning = undefined;
411
+ this.scheduleResourceMaintenance();
412
+ }
413
+ catch (error) {
414
+ this.resourceWarning = error instanceof Error
415
+ ? error.message
416
+ : "Native Codex portable-resource credentials could not be refreshed; Pibo will retry while the session remains idle.";
417
+ this.scheduleResourceMaintenance(RESOURCE_MAINTENANCE_RETRY_MS);
418
+ }
419
+ }
420
+ async ensureFreshResourcesForTurn() {
421
+ await this.resourceRefresh;
422
+ this.assertActive();
423
+ if (this.resourceProcessUnavailable || this.resourceDelivery.needsCredentialRolloverForTurn()) {
424
+ await this.rolloverResourceProcess();
425
+ return;
426
+ }
427
+ const maintenanceAt = this.resourceDelivery.nextCredentialMaintenanceAt;
428
+ if (maintenanceAt !== undefined && maintenanceAt <= Date.now()) {
429
+ try {
430
+ this.resourceDelivery.renewCredential();
431
+ this.resourceWarning = undefined;
432
+ }
433
+ catch {
434
+ await this.rolloverResourceProcess();
435
+ }
436
+ }
437
+ this.scheduleResourceMaintenance();
438
+ }
439
+ async rolloverResourceProcess() {
440
+ if (this.resourceRefresh)
441
+ return await this.resourceRefresh;
442
+ const refresh = this.performResourceProcessRollover();
443
+ this.resourceRefresh = refresh;
444
+ try {
445
+ await refresh;
446
+ }
447
+ finally {
448
+ if (this.resourceRefresh === refresh)
449
+ this.resourceRefresh = undefined;
450
+ }
451
+ }
452
+ async performResourceProcessRollover() {
453
+ this.assertActive();
454
+ if (this.operationInFlight || this.turns.streaming || this.requests.pendingApprovals.length > 0 || this.requests.pendingUserInputs.length > 0) {
455
+ throw new Error("Native Codex portable resources can only be refreshed while the session is idle.");
456
+ }
457
+ const previousProcess = this.process;
458
+ const previousThreads = this.threads;
459
+ const previousTurns = this.turns;
460
+ const previousRequests = this.requests;
461
+ const previousDelivery = this.resourceDelivery;
462
+ const previousThread = previousThreads.thread;
463
+ let next;
464
+ let reboundSettings = false;
465
+ let phase = "stopping the previous process";
466
+ try {
467
+ await previousProcess.close();
468
+ this.resourceProcessUnavailable = true;
469
+ phase = "starting the replacement process";
470
+ next = await this.reloadProcess();
471
+ phase = "resuming the native thread";
472
+ this.assertActive();
473
+ this.settings.bindClient(next.process.client);
474
+ reboundSettings = true;
475
+ const selection = {
476
+ ...this.settings.threadSelection,
477
+ ...(next.resourceDelivery.threadConfig ? { config: next.resourceDelivery.threadConfig } : {}),
478
+ ...(next.resourceDelivery.developerInstructions
479
+ ? { developerInstructions: next.resourceDelivery.developerInstructions }
480
+ : {}),
481
+ };
482
+ const nextThreads = previousThread.turns.length === 0 && !previousThread.path
483
+ ? await CodexNativeThreadController.start(next.process.client, this.cwd, selection)
484
+ : await CodexNativeThreadController.resume(next.process.client, previousThread.id, this.cwd, selection);
485
+ this.settings.attachThread(nextThreads.thread.id, nextThreads.configuration);
486
+ phase = "verifying portable resources";
487
+ await next.resourceDelivery.verifyThread(next.process.client, nextThreads.thread.id);
488
+ phase = "activating the replacement process";
489
+ this.assertActive();
490
+ const nextTurns = new CodexNativeTurnController(next.process.client, nextThreads, (event) => this.emit(event));
491
+ this.process = next.process;
492
+ this.threads = nextThreads;
493
+ this.resourceDelivery = next.resourceDelivery;
494
+ this.updateSelectedToolNames(next.resourceDelivery);
495
+ this.turns = nextTurns;
496
+ this.requests = this.createRequestController(next.process);
497
+ previousRequests.dispose();
498
+ previousTurns.dispose();
499
+ this.updateBindingFromCurrentThread();
500
+ this.resourceProcessUnavailable = false;
501
+ this.resourceWarning = undefined;
502
+ next = undefined;
503
+ previousDelivery.dispose();
504
+ }
505
+ catch {
506
+ if (reboundSettings) {
507
+ this.settings.bindClient(previousProcess.client);
508
+ this.settings.attachThread(previousThread.id, previousThreads.configuration);
509
+ }
510
+ if (next) {
511
+ await next.process.close().catch(() => { });
512
+ next.resourceDelivery.dispose();
513
+ }
514
+ throw new Error(`Native Codex portable-resource credential refresh failed while ${phase}; Pibo will retry while the session remains idle.`);
515
+ }
516
+ }
517
+ updateSelectedToolNames(resourceDelivery) {
518
+ const names = [...new Set(resourceDelivery.enabledToolNames)].sort();
519
+ this.selectedToolNames = new Set(names.slice(0, MAX_INSPECTED_SELECTED_TOOL_NAMES));
520
+ this.toolInventoryWarning = names.length > MAX_INSPECTED_SELECTED_TOOL_NAMES
521
+ ? `Native Codex selected-tool status is limited to ${MAX_INSPECTED_SELECTED_TOOL_NAMES} names.`
522
+ : undefined;
523
+ }
524
+ emit(event) {
525
+ if (this.disposed)
526
+ return;
527
+ if (event.type === "tool_call"
528
+ && event.toolName.trim()
529
+ && event.toolName.length <= 512
530
+ && (this.observedToolNames.has(event.toolName) || this.observedToolNames.size < MAX_INSPECTED_TOOL_NAMES)) {
531
+ this.observedToolNames.add(event.toolName);
532
+ }
533
+ for (const listener of [...this.listeners]) {
534
+ try {
535
+ listener(event);
536
+ }
537
+ catch {
538
+ // Runtime listeners are isolated from the owned Codex process lifecycle.
539
+ }
540
+ }
541
+ }
542
+ updateBindingFromCurrentThread() {
543
+ this.binding = bindingForThread({
544
+ piboSessionId: this.binding.piboSessionId,
545
+ runtimeInstanceId: this.runtimeInstanceId,
546
+ previous: this.binding,
547
+ thread: this.threads.thread,
548
+ settings: this.settings.bindingMetadata,
549
+ });
550
+ }
551
+ assertActive() {
552
+ if (this.disposed)
553
+ throw new Error("Codex runtime session is disposed.");
554
+ }
555
+ assertIdle() {
556
+ this.assertActive();
557
+ if (this.turns.streaming || this.resourceRefresh || this.resourceProcessUnavailable) {
558
+ throw new Error("Codex runtime controls can only change while the session is idle.");
559
+ }
560
+ }
561
+ }
562
+ export class CodexNativeAgentRuntimeAdapter {
563
+ instanceId;
564
+ descriptor;
565
+ config;
566
+ displayName;
567
+ enabled;
568
+ modelCatalogCache;
569
+ authController;
570
+ constructor(instanceId, config, displayName, enabled) {
571
+ this.instanceId = instanceId;
572
+ this.config = structuredClone(config);
573
+ this.descriptor = {
574
+ ...CODEX_NATIVE_AGENT_RUNTIME_DRIVER.descriptor,
575
+ capabilities: codexNativeCapabilities(config.experimentalUserInput),
576
+ };
577
+ this.displayName = displayName ?? this.descriptor.displayName;
578
+ this.enabled = enabled;
579
+ this.authController = new CodexNativeAuthController({
580
+ config: this.config,
581
+ startProcess: async (sessionGeneration) => await startCodexNativeAppServer({
582
+ config: this.config,
583
+ runtimeInstanceId: this.instanceId,
584
+ piboSessionId: "runtime-auth",
585
+ sessionGeneration,
586
+ workspace: process.cwd(),
587
+ clientVersion: CODEX_NATIVE_ADAPTER_VERSION,
588
+ }),
589
+ });
590
+ }
591
+ diagnose() {
592
+ return diagnoseCodexNativeRuntime(this.config, this.instanceId);
593
+ }
594
+ async listModels() {
595
+ return toAgentRuntimeModelCatalog(this.instanceId, await this.loadModelCatalog());
596
+ }
597
+ async getAuthStatus() {
598
+ return await this.authController.getStatus();
599
+ }
600
+ async startAuth(input) {
601
+ return await this.authController.start(input);
602
+ }
603
+ async completeAuth(input) {
604
+ return await this.authController.complete(input);
605
+ }
606
+ async cancelAuth(input) {
607
+ return await this.authController.cancel(input);
608
+ }
609
+ async logoutAuth(input) {
610
+ return await this.authController.logout(input);
611
+ }
612
+ async disposeAuth() {
613
+ await this.authController.dispose();
614
+ }
615
+ validateProfile(input) {
616
+ const diagnostics = [];
617
+ if (input.profile.runtimeInstanceId !== this.instanceId) {
618
+ diagnostics.push({
619
+ severity: "error",
620
+ code: "runtime_instance_mismatch",
621
+ message: `Profile "${input.profile.profileName}" selects runtime instance "${input.profile.runtimeInstanceId}", not "${this.instanceId}".`,
622
+ });
623
+ }
624
+ try {
625
+ parseCodexNativeProfileOptions(input.profile.runtimeOptions);
626
+ }
627
+ catch (error) {
628
+ diagnostics.push({
629
+ severity: "error",
630
+ code: "codex_native_runtime_options_invalid",
631
+ message: error instanceof Error ? error.message : "Native Codex runtime options are invalid.",
632
+ path: "runtimeOptions",
633
+ });
634
+ }
635
+ for (const [path, model] of [
636
+ ["model", input.profile.model],
637
+ ["mainModel", input.profile.mainModel],
638
+ ["subagentModel", input.profile.subagentModel],
639
+ ]) {
640
+ if (model && model.provider !== CODEX_NATIVE_MODEL_PROVIDER_ID) {
641
+ diagnostics.push({
642
+ severity: "error",
643
+ code: "codex_native_model_provider_invalid",
644
+ message: `Native Codex models use provider "${CODEX_NATIVE_MODEL_PROVIDER_ID}", not "${model.provider}".`,
645
+ path,
646
+ });
647
+ }
648
+ }
649
+ return diagnostics;
650
+ }
651
+ async resolveBinding(input) {
652
+ const binding = structuredClone(input.binding);
653
+ if (binding.state !== "bound")
654
+ return binding;
655
+ if (!binding.nativeSessionId) {
656
+ return {
657
+ ...binding,
658
+ state: "error",
659
+ metadata: {
660
+ ...(binding.metadata ?? {}),
661
+ diagnosticCode: "codex_native_thread_id_missing",
662
+ diagnosticMessage: "The persisted Codex binding has no native thread id.",
663
+ },
664
+ };
665
+ }
666
+ try {
667
+ const thread = await this.withProcess(binding.piboSessionId, input.workspace, async (process) => await CodexNativeThreadController.read(process.client, binding.nativeSessionId, false));
668
+ return bindingForThread({
669
+ piboSessionId: binding.piboSessionId,
670
+ runtimeInstanceId: this.instanceId,
671
+ previous: binding,
672
+ thread,
673
+ });
674
+ }
675
+ catch (error) {
676
+ if (error instanceof CodexNativeThreadMissingError) {
677
+ return {
678
+ ...binding,
679
+ state: "missing",
680
+ metadata: {
681
+ ...(binding.metadata ?? {}),
682
+ diagnosticCode: "codex_native_thread_missing",
683
+ diagnosticMessage: "The bound Codex thread is no longer available in this configured runtime instance.",
684
+ },
685
+ };
686
+ }
687
+ throw new AgentRuntimeUnavailableError(this.instanceId, `Codex binding inspection failed for runtime instance "${this.instanceId}".`);
688
+ }
689
+ }
690
+ async openSession(input) {
691
+ const binding = validateOpenBinding(input, this.instanceId);
692
+ const sessionGeneration = input.services?.resources?.sessionGeneration
693
+ ?? input.services?.portableTools?.sessionGeneration
694
+ ?? randomUUID();
695
+ const resourceInput = {
696
+ workspace: input.workspace,
697
+ portableTools: input.services?.portableTools,
698
+ resources: input.services?.resources,
699
+ };
700
+ const startProcessBundle = async (processGeneration) => {
701
+ let delivery;
702
+ let ownedProcess;
703
+ try {
704
+ delivery = await CodexNativeResourceDelivery.prepare(resourceInput);
705
+ ownedProcess = await startCodexNativeAppServer({
706
+ config: this.config,
707
+ runtimeInstanceId: this.instanceId,
708
+ piboSessionId: input.piboSession.id,
709
+ sessionGeneration: processGeneration,
710
+ workspace: input.workspace,
711
+ clientVersion: CODEX_NATIVE_ADAPTER_VERSION,
712
+ resourceEnvironment: delivery.environment,
713
+ });
714
+ await delivery.configureProcess(ownedProcess.client, input.workspace);
715
+ return { process: ownedProcess, resourceDelivery: delivery };
716
+ }
717
+ catch (error) {
718
+ await ownedProcess?.close().catch(() => { });
719
+ delivery?.dispose();
720
+ throw error;
721
+ }
722
+ };
723
+ let resourceDelivery;
724
+ let process;
725
+ let settings;
726
+ try {
727
+ const initial = await startProcessBundle(sessionGeneration);
728
+ resourceDelivery = initial.resourceDelivery;
729
+ process = initial.process;
730
+ const compatibility = input.services?.compatibility;
731
+ const catalog = await this.loadModelCatalog(process.client);
732
+ const profileOptions = parseCodexNativeProfileOptions(input.profile.runtimeOptions);
733
+ const persisted = binding.state === "bound"
734
+ ? readCodexNativePersistedSettings(binding.metadata)
735
+ : { profileOptions: {} };
736
+ const persistedOptions = persisted.profileOptions;
737
+ const hasPersistedServiceTier = Object.hasOwn(persistedOptions, "serviceTier");
738
+ settings = new CodexNativeSessionSettingsController(process.client, catalog, {
739
+ activeModel: input.activeModel
740
+ ?? persisted.activeModel
741
+ ?? selectRequestedModelProfile(input.profile, compatibility?.modelDefaults),
742
+ reasoningLevel: persisted.reasoningLevel
743
+ ?? compatibility?.thinkingLevel
744
+ ?? selectRequestedThinkingLevel(input.profile, compatibility?.modelDefaults),
745
+ initialFastMode: hasPersistedServiceTier
746
+ ? undefined
747
+ : compatibility?.initialFastMode
748
+ ?? selectRequestedFastMode(input.profile, compatibility?.modelDefaults),
749
+ profileOptions: {
750
+ serviceTier: hasPersistedServiceTier ? persistedOptions.serviceTier : profileOptions.serviceTier,
751
+ personality: Object.hasOwn(persistedOptions, "personality")
752
+ ? persistedOptions.personality
753
+ : profileOptions.personality,
754
+ reasoningSummary: Object.hasOwn(persistedOptions, "reasoningSummary")
755
+ ? persistedOptions.reasoningSummary
756
+ : profileOptions.reasoningSummary,
757
+ },
758
+ });
759
+ const threadSelection = {
760
+ ...settings.threadSelection,
761
+ ...(resourceDelivery.threadConfig ? { config: resourceDelivery.threadConfig } : {}),
762
+ ...(resourceDelivery.developerInstructions
763
+ ? { developerInstructions: resourceDelivery.developerInstructions }
764
+ : {}),
765
+ };
766
+ let threads;
767
+ try {
768
+ threads = binding.state === "bound"
769
+ ? await CodexNativeThreadController.resume(process.client, binding.nativeSessionId, input.workspace, threadSelection)
770
+ : await CodexNativeThreadController.start(process.client, input.workspace, threadSelection);
771
+ }
772
+ catch (error) {
773
+ if (error instanceof CodexNativeThreadMissingError || !resourceDelivery.hasMcpServers)
774
+ throw error;
775
+ throw new Error("Codex could not initialize every selected MCP server.");
776
+ }
777
+ settings.attachThread(threads.thread.id, threads.configuration);
778
+ await resourceDelivery.verifyThread(process.client, threads.thread.id);
779
+ return new CodexNativeThreadSession(this.instanceId, process, threads, settings, resourceDelivery, bindingForThread({
780
+ piboSessionId: input.piboSession.id,
781
+ runtimeInstanceId: this.instanceId,
782
+ previous: binding,
783
+ thread: threads.thread,
784
+ settings: settings.bindingMetadata,
785
+ }), this.config.experimentalUserInput, async () => await startProcessBundle(`${sessionGeneration}-credential-${randomUUID()}`), input.productContext);
786
+ }
787
+ catch (error) {
788
+ settings?.dispose();
789
+ await process?.close().catch(() => { });
790
+ resourceDelivery?.dispose();
791
+ if (error instanceof CodexNativeThreadMissingError) {
792
+ throw new AgentRuntimeBindingMissingError(input.piboSession.id, this.instanceId, binding.nativeSessionId);
793
+ }
794
+ throw error;
795
+ }
796
+ }
797
+ async inspectHistory(input) {
798
+ const threadId = input.binding.nativeSessionId;
799
+ if (!threadId) {
800
+ return unavailableCodexThreadHistoryInspection(this.instanceId, input.binding, "codex_native_history_thread_id_missing", "The Codex runtime binding has no native thread id for history lookup.");
801
+ }
802
+ try {
803
+ const thread = await this.withProcess(input.binding.piboSessionId, input.workspace, async (process) => await CodexNativeThreadController.read(process.client, threadId, false));
804
+ return inspectCodexThreadHistory(this.instanceId, input.binding, thread);
805
+ }
806
+ catch (error) {
807
+ return unavailableCodexThreadHistoryInspection(this.instanceId, input.binding, error instanceof CodexNativeThreadMissingError ? "codex_native_history_not_found" : "codex_native_history_unavailable", error instanceof CodexNativeThreadMissingError
808
+ ? "The bound Codex thread is unavailable for native history inspection."
809
+ : "Codex native history inspection failed safely.");
810
+ }
811
+ }
812
+ async readHistory(input) {
813
+ const threadId = input.binding.nativeSessionId;
814
+ if (!threadId) {
815
+ const inspection = await this.inspectHistory(input);
816
+ return {
817
+ runtimeInstanceId: this.instanceId,
818
+ adapterId: CODEX_NATIVE_ADAPTER_ID,
819
+ source: "native",
820
+ entries: [],
821
+ hasMore: false,
822
+ inspection,
823
+ };
824
+ }
825
+ try {
826
+ const thread = await this.withProcess(input.binding.piboSessionId, input.workspace, async (process) => await CodexNativeThreadController.read(process.client, threadId, true));
827
+ return pageCodexThreadHistory({
828
+ runtimeInstanceId: this.instanceId,
829
+ binding: input.binding,
830
+ thread,
831
+ cursor: input.cursor,
832
+ beforeTimestamp: input.beforeTimestamp,
833
+ limit: input.limit,
834
+ });
835
+ }
836
+ catch (error) {
837
+ if (error instanceof CodexNativeThreadMissingError) {
838
+ const inspection = unavailableCodexThreadHistoryInspection(this.instanceId, input.binding, "codex_native_history_not_found", "The bound Codex thread is unavailable for native history reads.");
839
+ return {
840
+ runtimeInstanceId: this.instanceId,
841
+ adapterId: CODEX_NATIVE_ADAPTER_ID,
842
+ source: "native",
843
+ entries: [],
844
+ hasMore: false,
845
+ inspection,
846
+ };
847
+ }
848
+ throw new AgentRuntimeUnavailableError(this.instanceId, `Codex native history read failed for runtime instance "${this.instanceId}".`);
849
+ }
850
+ }
851
+ loadModelCatalog(client) {
852
+ const now = Date.now();
853
+ if (this.modelCatalogCache && this.modelCatalogCache.expiresAt > now)
854
+ return this.modelCatalogCache.value;
855
+ const value = client
856
+ ? readCodexNativeModelCatalog(client)
857
+ : this.withProcess("model-catalog", process.cwd(), async (catalogProcess) => await readCodexNativeModelCatalog(catalogProcess.client));
858
+ this.modelCatalogCache = { expiresAt: now + 5_000, value };
859
+ value.catch(() => {
860
+ if (this.modelCatalogCache?.value === value)
861
+ this.modelCatalogCache = undefined;
862
+ });
863
+ return value;
864
+ }
865
+ async withProcess(piboSessionId, workspace, operation) {
866
+ const process = await startCodexNativeAppServer({
867
+ config: this.config,
868
+ runtimeInstanceId: this.instanceId,
869
+ piboSessionId,
870
+ sessionGeneration: `inspection-${randomUUID()}`,
871
+ workspace,
872
+ clientVersion: CODEX_NATIVE_ADAPTER_VERSION,
873
+ });
874
+ try {
875
+ return await operation(process);
876
+ }
877
+ finally {
878
+ await process.close();
879
+ }
880
+ }
881
+ }
882
+ export const CODEX_NATIVE_AGENT_RUNTIME_DRIVER = {
883
+ descriptor: {
884
+ id: CODEX_NATIVE_ADAPTER_ID,
885
+ displayName: "Codex App Server",
886
+ transport: "stdio-rpc",
887
+ configSchema: CODEX_NATIVE_RUNTIME_CONFIG_SCHEMA,
888
+ capabilities: CODEX_NATIVE_THREAD_CAPABILITIES,
889
+ protocol: {
890
+ name: CODEX_APP_SERVER_PROTOCOL_NAME,
891
+ supportedRange: CODEX_APP_SERVER_SUPPORTED_RANGE,
892
+ },
893
+ supportsMultipleInstances: true,
894
+ },
895
+ defaultConfig: defaultCodexNativeRuntimeConfig,
896
+ parseConfig: parseCodexNativeRuntimeConfig,
897
+ create(input) {
898
+ return new CodexNativeAgentRuntimeAdapter(input.instanceId, input.config, input.displayName, input.enabled);
899
+ },
900
+ };
901
+ export function getCodexNativeClient(session) {
902
+ if (session.adapterId !== CODEX_NATIVE_ADAPTER_ID)
903
+ return undefined;
904
+ return session.getNativeCompatibilityHandle?.();
905
+ }