@pasko70/pibo 2.5.1 → 3.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.
- package/context/pibo-native-tooling.md +1 -0
- package/dist/agent-runtime/contract.js +2 -1
- package/dist/agent-runtime/history.js +53 -1
- package/dist/agent-runtime/routed-session.js +100 -26
- package/dist/agent-runtimes/codex-native/adapter.js +307 -31
- package/dist/agent-runtimes/codex-native/client.js +22 -3
- package/dist/agent-runtimes/codex-native/first-use.js +294 -0
- package/dist/agent-runtimes/codex-native/history.js +26 -7
- package/dist/agent-runtimes/codex-native/models.js +48 -1
- package/dist/agent-runtimes/codex-native/process.js +15 -1
- package/dist/agent-runtimes/codex-native/thread.js +75 -31
- package/dist/agent-runtimes/codex-native/turn.js +30 -0
- package/dist/agent-runtimes/history-proof.js +8 -0
- package/dist/agent-runtimes/omp/adapter.js +61 -14
- package/dist/agent-runtimes/omp/history.js +189 -34
- package/dist/agent-runtimes/omp/thread.js +82 -36
- package/dist/agent-runtimes/pi/adapter.js +30 -3
- package/dist/agent-runtimes/pi/history.js +66 -5
- package/dist/agent-runtimes/pi/openai-response-observer.js +102 -0
- package/dist/agent-runtimes/pi/routed-session.js +344 -37
- package/dist/apps/chat/agent-store.js +3 -0
- package/dist/apps/chat/chat-api-routes.js +1 -1
- package/dist/apps/chat/chat-files.js +130 -9
- package/dist/apps/chat/chat-request-normalizers.js +6 -0
- package/dist/apps/chat/chat-settings-routes.js +27 -2
- package/dist/apps/chat/chat-speech.js +100 -0
- package/dist/apps/chat/data/chat-data-mappers.js +25 -5
- package/dist/apps/chat/data/timeline-query-service.js +89 -1
- package/dist/apps/chat/trace-v2.js +210 -8
- package/dist/apps/chat/trace.js +3 -0
- package/dist/apps/chat/web-app.js +108 -3
- package/dist/apps/chat-ui/assets/{dist-GS8xUdfg.js → dist-BBDMeU5-.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-BpVSf6ZV.js → dist-BDIATCQt.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-CRv7fzi3.js → dist-JnW4v8UE.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-CbBXbGVi.js → dist-lRiLP9rr.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-HC0xQ92C.js → dist-mqCviI-c.js} +1 -1
- package/dist/apps/chat-ui/assets/index-0XOOVxLP.js +228 -0
- package/dist/apps/chat-ui/assets/index-DV7_CgsC.css +1 -0
- package/dist/apps/chat-ui/index.html +2 -2
- package/dist/apps/chat-vscode-web/assets/index-Dtw2Z7jz.js +43 -0
- package/dist/apps/chat-vscode-web/assets/{index-CF1-9PKU.css → index-SluZr_-r.css} +1 -1
- package/dist/apps/chat-vscode-web/index.html +2 -2
- package/dist/apps/vscode-artifacts/latest.vsix +0 -0
- package/dist/apps/vscode-artifacts/pibo-vscode-ext-3.0.0.vsix +0 -0
- package/dist/cli.js +49 -5
- package/dist/config/config.js +59 -8
- package/dist/core/preview-server-settings.js +20 -0
- package/dist/core/profiles.js +1 -0
- package/dist/core/session-router.js +476 -44
- package/dist/core/user-settings.js +10 -0
- package/dist/data/payload-store.js +57 -1
- package/dist/data/schema.js +18 -1
- package/dist/debug/trace.js +5 -0
- package/dist/gateway/client.js +368 -65
- package/dist/gateway/protocol.js +2 -0
- package/dist/gateway/server.js +8 -0
- package/dist/gateway/web.js +2 -0
- package/dist/index.js +1 -1
- package/dist/loops/store.js +6 -4
- package/dist/mcp/config.js +89 -17
- package/dist/mcp/daemon-client.js +473 -153
- package/dist/mcp/daemon.js +401 -37
- package/dist/plugins/builtin.js +2 -2
- package/dist/plugins/codex-native.js +2 -0
- package/dist/plugins/registry.js +260 -1
- package/dist/previews/cli.js +345 -0
- package/dist/previews/config.js +61 -0
- package/dist/previews/manager.js +644 -0
- package/dist/previews/network.js +198 -0
- package/dist/previews/plugin.js +11 -0
- package/dist/previews/process-supervisor.js +38 -0
- package/dist/previews/proxy.js +387 -0
- package/dist/previews/store.js +750 -0
- package/dist/previews/types.js +1 -0
- package/dist/previews/web-app.js +446 -0
- package/dist/runs/registry.js +22 -0
- package/dist/runs/tools.js +46 -7
- package/dist/session-ui/terminalRows.js +187 -13
- package/dist/sessions/pibo-data-store.js +37 -0
- package/dist/sessions/runtime-binding-persistence.js +34 -0
- package/dist/sessions/runtime-binding.js +6 -0
- package/dist/sessions/sqlite-store.js +37 -0
- package/dist/shared/trace-engine.js +12 -64
- package/dist/shared/trace-event-projection.js +16 -0
- package/dist/shared/trace-history.js +684 -184
- package/dist/shared/trace-limits.js +7 -0
- package/dist/shared/trace-live-patch.js +61 -0
- package/dist/shared/trace-tool-identity.js +43 -0
- package/dist/speech/openai-codex-realtime-call-proxy.js +248 -0
- package/dist/speech/openai-codex.js +407 -0
- package/dist/speech/types.js +8 -0
- package/dist/subagents/context.js +5 -3
- package/dist/subagents/observations.js +94 -6
- package/dist/subagents/tool.js +103 -20
- package/dist/tools/codex-image-artifacts.js +24 -0
- package/dist/tools/codex-image-generation.js +4 -22
- package/dist/web/channel.js +88 -4
- package/dist/web/http.js +2 -1
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
- package/dist/apps/chat-ui/assets/index-0WZI2phJ.css +0 -1
- package/dist/apps/chat-ui/assets/index-DT5jCQBP.js +0 -228
- package/dist/apps/chat-vscode-web/assets/index-DvTSSvzN.js +0 -43
- package/dist/apps/vscode-artifacts/pibo-vscode-ext-2.5.1.vsix +0 -0
|
@@ -165,17 +165,14 @@ function secondsToIso(seconds) {
|
|
|
165
165
|
const date = new Date(Number(seconds) * 1_000);
|
|
166
166
|
return Number.isNaN(date.getTime()) ? undefined : date.toISOString();
|
|
167
167
|
}
|
|
168
|
-
function
|
|
169
|
-
if (item.type
|
|
170
|
-
return
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
return text || undefined;
|
|
177
|
-
}
|
|
178
|
-
return undefined;
|
|
168
|
+
function userMessageText(item) {
|
|
169
|
+
if (item.type !== "userMessage" || !Array.isArray(item.content))
|
|
170
|
+
return undefined;
|
|
171
|
+
const text = item.content
|
|
172
|
+
.filter((part) => isRecord(part) && part.type === "text" && typeof part.text === "string")
|
|
173
|
+
.map((part) => redactCodexNativeSensitiveText(part.text))
|
|
174
|
+
.join("\n");
|
|
175
|
+
return text || undefined;
|
|
179
176
|
}
|
|
180
177
|
function threadLeafId(thread) {
|
|
181
178
|
return thread.turns.at(-1)?.id ?? null;
|
|
@@ -204,23 +201,32 @@ export function codexThreadInfo(runtimeInstanceId, thread) {
|
|
|
204
201
|
firstMessage: thread.preview ? redactCodexNativeSensitiveText(thread.preview) : undefined,
|
|
205
202
|
};
|
|
206
203
|
}
|
|
207
|
-
|
|
208
|
-
return thread.turns.
|
|
209
|
-
const
|
|
210
|
-
|
|
204
|
+
function codexThreadForkTargets(thread) {
|
|
205
|
+
return thread.turns.flatMap((turn, index) => {
|
|
206
|
+
const userMessage = turn.items.find((item) => item.type === "userMessage");
|
|
207
|
+
if (!userMessage)
|
|
208
|
+
return [];
|
|
209
|
+
return [{
|
|
210
|
+
entryId: userMessage.id,
|
|
211
|
+
text: userMessageText(userMessage) ?? `Codex turn ${turn.id}`,
|
|
212
|
+
...(index > 0 ? { previousTurnId: thread.turns[index - 1].id } : {}),
|
|
213
|
+
}];
|
|
211
214
|
});
|
|
212
215
|
}
|
|
216
|
+
export function codexThreadForkCandidates(thread) {
|
|
217
|
+
return codexThreadForkTargets(thread).map(({ entryId, text }) => ({ entryId, text }));
|
|
218
|
+
}
|
|
213
219
|
export class CodexNativeThreadController {
|
|
214
220
|
client;
|
|
215
221
|
currentThread;
|
|
216
222
|
currentConfiguration;
|
|
217
|
-
|
|
223
|
+
inheritedSelection;
|
|
218
224
|
knownThreads = new Map();
|
|
219
|
-
constructor(client, currentThread, currentConfiguration,
|
|
225
|
+
constructor(client, currentThread, currentConfiguration, inheritedSelection) {
|
|
220
226
|
this.client = client;
|
|
221
227
|
this.currentThread = currentThread;
|
|
222
228
|
this.currentConfiguration = currentConfiguration;
|
|
223
|
-
this.
|
|
229
|
+
this.inheritedSelection = inheritedSelection;
|
|
224
230
|
this.knownThreads.set(currentThread.id, structuredClone(currentThread));
|
|
225
231
|
}
|
|
226
232
|
static async start(client, workspace, selection = {}) {
|
|
@@ -230,13 +236,18 @@ export class CodexNativeThreadController {
|
|
|
230
236
|
...(selection.model ? { model: selection.model } : {}),
|
|
231
237
|
...(selection.serviceTier !== undefined ? { serviceTier: selection.serviceTier } : {}),
|
|
232
238
|
...(selection.personality !== undefined ? { personality: selection.personality } : {}),
|
|
239
|
+
...(selection.approvalPolicy ? { approvalPolicy: selection.approvalPolicy } : {}),
|
|
240
|
+
...(selection.sandbox ? { sandbox: selection.sandbox } : {}),
|
|
233
241
|
...(selection.config ? { config: selection.config } : {}),
|
|
234
242
|
...(selection.developerInstructions ? { developerInstructions: selection.developerInstructions } : {}),
|
|
235
243
|
});
|
|
236
244
|
const selected = threadSessionFromResponse(response, "thread/start");
|
|
237
245
|
return new CodexNativeThreadController(client, selected.thread, selected.configuration, {
|
|
246
|
+
...(selection.approvalPolicy ? { approvalPolicy: selection.approvalPolicy } : {}),
|
|
247
|
+
...(selection.sandbox ? { sandbox: selection.sandbox } : {}),
|
|
238
248
|
...(selection.config ? { config: structuredClone(selection.config) } : {}),
|
|
239
249
|
...(selection.developerInstructions ? { developerInstructions: selection.developerInstructions } : {}),
|
|
250
|
+
...(selection.personality !== undefined ? { personality: selection.personality } : {}),
|
|
240
251
|
});
|
|
241
252
|
}
|
|
242
253
|
static async resume(client, threadId, workspace, selection = {}) {
|
|
@@ -247,6 +258,8 @@ export class CodexNativeThreadController {
|
|
|
247
258
|
...(selection.model ? { model: selection.model } : {}),
|
|
248
259
|
...(selection.serviceTier !== undefined ? { serviceTier: selection.serviceTier } : {}),
|
|
249
260
|
...(selection.personality !== undefined ? { personality: selection.personality } : {}),
|
|
261
|
+
...(selection.approvalPolicy ? { approvalPolicy: selection.approvalPolicy } : {}),
|
|
262
|
+
...(selection.sandbox ? { sandbox: selection.sandbox } : {}),
|
|
250
263
|
...(selection.config ? { config: selection.config } : {}),
|
|
251
264
|
...(selection.developerInstructions ? { developerInstructions: selection.developerInstructions } : {}),
|
|
252
265
|
});
|
|
@@ -255,8 +268,11 @@ export class CodexNativeThreadController {
|
|
|
255
268
|
if (thread.id !== threadId)
|
|
256
269
|
throw new CodexNativeThreadProtocolError("Codex resumed a different thread than requested.");
|
|
257
270
|
return new CodexNativeThreadController(client, thread, selected.configuration, {
|
|
271
|
+
...(selection.approvalPolicy ? { approvalPolicy: selection.approvalPolicy } : {}),
|
|
272
|
+
...(selection.sandbox ? { sandbox: selection.sandbox } : {}),
|
|
258
273
|
...(selection.config ? { config: structuredClone(selection.config) } : {}),
|
|
259
274
|
...(selection.developerInstructions ? { developerInstructions: selection.developerInstructions } : {}),
|
|
275
|
+
...(selection.personality !== undefined ? { personality: selection.personality } : {}),
|
|
260
276
|
});
|
|
261
277
|
}
|
|
262
278
|
catch (error) {
|
|
@@ -337,15 +353,29 @@ export class CodexNativeThreadController {
|
|
|
337
353
|
.sort((left, right) => right.updatedAt - left.updatedAt || right.createdAt - left.createdAt)
|
|
338
354
|
.map((thread) => codexThreadInfo(runtimeInstanceId, thread));
|
|
339
355
|
}
|
|
340
|
-
async fork(runtimeInstanceId, workspace,
|
|
341
|
-
if (!
|
|
342
|
-
throw new Error("Codex thread fork requires a native
|
|
343
|
-
|
|
356
|
+
async fork(runtimeInstanceId, workspace, entryId, validateThread) {
|
|
357
|
+
if (!entryId.trim())
|
|
358
|
+
throw new Error("Codex thread fork requires a native user-message id.");
|
|
359
|
+
const target = codexThreadForkTargets(this.currentThread).find((candidate) => candidate.entryId === entryId);
|
|
360
|
+
if (target) {
|
|
361
|
+
if (!target.previousTurnId) {
|
|
362
|
+
return this.branchBeforeFirstTurn(runtimeInstanceId, workspace, target);
|
|
363
|
+
}
|
|
364
|
+
return await this.forkAt(runtimeInstanceId, workspace, target.previousTurnId, validateThread, target);
|
|
365
|
+
}
|
|
366
|
+
const legacyTurn = this.currentThread.turns.find((turn) => turn.id === entryId);
|
|
367
|
+
if (!legacyTurn)
|
|
368
|
+
throw new Error(`Codex fork target "${entryId}" was not found.`);
|
|
369
|
+
const legacyText = legacyTurn.items.map(userMessageText).find((text) => text?.trim());
|
|
370
|
+
return await this.forkAt(runtimeInstanceId, workspace, entryId, validateThread, {
|
|
371
|
+
entryId,
|
|
372
|
+
text: legacyText ?? `Codex turn ${entryId}`,
|
|
373
|
+
});
|
|
344
374
|
}
|
|
345
375
|
async clone(runtimeInstanceId, workspace, validateThread) {
|
|
346
376
|
return await this.forkAt(runtimeInstanceId, workspace, undefined, validateThread);
|
|
347
377
|
}
|
|
348
|
-
async forkAt(runtimeInstanceId, workspace, lastTurnId, validateThread) {
|
|
378
|
+
async forkAt(runtimeInstanceId, workspace, lastTurnId, validateThread, selectedTarget) {
|
|
349
379
|
const previousThread = this.currentThread;
|
|
350
380
|
const previous = codexThreadSnapshot(runtimeInstanceId, previousThread);
|
|
351
381
|
const params = {
|
|
@@ -353,9 +383,11 @@ export class CodexNativeThreadController {
|
|
|
353
383
|
...(lastTurnId ? { lastTurnId } : {}),
|
|
354
384
|
cwd: workspace,
|
|
355
385
|
ephemeral: false,
|
|
356
|
-
...(this.
|
|
357
|
-
...(this.
|
|
358
|
-
|
|
386
|
+
...(this.inheritedSelection.approvalPolicy ? { approvalPolicy: this.inheritedSelection.approvalPolicy } : {}),
|
|
387
|
+
...(this.inheritedSelection.sandbox ? { sandbox: this.inheritedSelection.sandbox } : {}),
|
|
388
|
+
...(this.inheritedSelection.config ? { config: structuredClone(this.inheritedSelection.config) } : {}),
|
|
389
|
+
...(this.inheritedSelection.developerInstructions
|
|
390
|
+
? { developerInstructions: this.inheritedSelection.developerInstructions }
|
|
359
391
|
: {}),
|
|
360
392
|
};
|
|
361
393
|
try {
|
|
@@ -366,9 +398,6 @@ export class CodexNativeThreadController {
|
|
|
366
398
|
throw new CodexNativeThreadProtocolError("Codex thread/fork returned the source thread id.");
|
|
367
399
|
}
|
|
368
400
|
await validateThread?.(forked.id);
|
|
369
|
-
const selectedText = lastTurnId
|
|
370
|
-
? codexThreadForkCandidates(previousThread).find((candidate) => candidate.entryId === lastTurnId)?.text
|
|
371
|
-
: undefined;
|
|
372
401
|
this.knownThreads.set(previousThread.id, structuredClone(previousThread));
|
|
373
402
|
this.knownThreads.set(forked.id, structuredClone(forked));
|
|
374
403
|
this.currentThread = forked;
|
|
@@ -377,12 +406,27 @@ export class CodexNativeThreadController {
|
|
|
377
406
|
previous,
|
|
378
407
|
current: codexThreadSnapshot(runtimeInstanceId, forked),
|
|
379
408
|
cancelled: false,
|
|
380
|
-
...(
|
|
381
|
-
...(
|
|
409
|
+
...(selectedTarget?.text ? { selectedText: selectedTarget.text } : {}),
|
|
410
|
+
...(selectedTarget ? { summaryEntryId: selectedTarget.entryId } : {}),
|
|
382
411
|
};
|
|
383
412
|
}
|
|
384
413
|
catch (error) {
|
|
385
414
|
return normalizeThreadError(error, previousThread.id);
|
|
386
415
|
}
|
|
387
416
|
}
|
|
417
|
+
branchBeforeFirstTurn(runtimeInstanceId, workspace, target) {
|
|
418
|
+
const previousThread = this.currentThread;
|
|
419
|
+
return {
|
|
420
|
+
previous: codexThreadSnapshot(runtimeInstanceId, previousThread),
|
|
421
|
+
current: {
|
|
422
|
+
adapterId: CODEX_NATIVE_ADAPTER_ID,
|
|
423
|
+
runtimeInstanceId,
|
|
424
|
+
cwd: workspace,
|
|
425
|
+
leafId: null,
|
|
426
|
+
},
|
|
427
|
+
cancelled: false,
|
|
428
|
+
selectedText: target.text,
|
|
429
|
+
summaryEntryId: target.entryId,
|
|
430
|
+
};
|
|
431
|
+
}
|
|
388
432
|
}
|
|
@@ -291,6 +291,9 @@ export class CodexNativeTurnController {
|
|
|
291
291
|
model: modelOptions.model,
|
|
292
292
|
effort: modelOptions.effort,
|
|
293
293
|
serviceTier: modelOptions.serviceTier,
|
|
294
|
+
approvalPolicy: modelOptions.approvalPolicy,
|
|
295
|
+
sandboxPolicy: modelOptions.sandboxPolicy,
|
|
296
|
+
...(modelOptions.collaborationMode ? { collaborationMode: modelOptions.collaborationMode } : {}),
|
|
294
297
|
...(modelOptions.summary !== undefined ? { summary: modelOptions.summary } : {}),
|
|
295
298
|
...(modelOptions.personality !== undefined ? { personality: modelOptions.personality } : {}),
|
|
296
299
|
};
|
|
@@ -316,6 +319,33 @@ export class CodexNativeTurnController {
|
|
|
316
319
|
throw error;
|
|
317
320
|
}
|
|
318
321
|
}
|
|
322
|
+
replayTerminalTurn(turn) {
|
|
323
|
+
if (this.disposed)
|
|
324
|
+
throw new Error("Codex native turn controller is disposed.");
|
|
325
|
+
if (this.pending)
|
|
326
|
+
throw new Error("Codex native session already has an active turn.");
|
|
327
|
+
if (turn.status === "inProgress") {
|
|
328
|
+
throw new CodexNativeTurnProtocolError("Codex cannot replay a non-terminal native turn.");
|
|
329
|
+
}
|
|
330
|
+
const replay = newPendingTurn();
|
|
331
|
+
this.assignTurnId(replay, turn.id);
|
|
332
|
+
replay.started = true;
|
|
333
|
+
for (const item of turn.items)
|
|
334
|
+
this.completeItem(replay, item);
|
|
335
|
+
this.finishIncompleteItems(replay, turn.status);
|
|
336
|
+
if (turn.status === "failed") {
|
|
337
|
+
const message = errorMessage(turn.error);
|
|
338
|
+
this.emit({
|
|
339
|
+
type: "turn_failed",
|
|
340
|
+
message,
|
|
341
|
+
details: providerErrorDetails(turn.error, message, false),
|
|
342
|
+
turnId: turn.id,
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
else {
|
|
346
|
+
this.emit({ type: "turn_completed", status: turn.status, turnId: turn.id });
|
|
347
|
+
}
|
|
348
|
+
}
|
|
319
349
|
async compact() {
|
|
320
350
|
if (this.disposed)
|
|
321
351
|
throw new Error("Codex native turn controller is disposed.");
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { isCodexNativeBuiltInHistoryReconciliationProof } from "./codex-native/adapter.js";
|
|
2
|
+
import { isOmpBuiltInHistoryReconciliationProof } from "./omp/adapter.js";
|
|
3
|
+
import { isPiBuiltInHistoryReconciliationProof } from "./pi/adapter.js";
|
|
4
|
+
export function isBuiltInHistoryReconciliationProof(proof) {
|
|
5
|
+
return proof !== undefined && (isPiBuiltInHistoryReconciliationProof(proof)
|
|
6
|
+
|| isOmpBuiltInHistoryReconciliationProof(proof)
|
|
7
|
+
|| isCodexNativeBuiltInHistoryReconciliationProof(proof));
|
|
8
|
+
}
|
|
@@ -6,6 +6,7 @@ import { OmpRpcClient, OmpRpcResponseError } from "./client.js";
|
|
|
6
6
|
import { defaultOmpRuntimeConfig, OMP_RUNTIME_CONFIG_SCHEMA, parseOmpRuntimeConfig } from "./config.js";
|
|
7
7
|
import { OmpHostToolBridge } from "./host-tools.js";
|
|
8
8
|
import { emptyOmpHistoryPage, inspectOmpHistory, readOmpHistory } from "./history.js";
|
|
9
|
+
import { historyReconciliationDigest, } from "../../agent-runtime/history.js";
|
|
9
10
|
import { OMP_MODEL_OPTIONS_SCHEMA, OMP_MODEL_PROVIDER_ID, OMP_REASONING_VALUES, parseOmpReasoning, readOmpModelCatalog, setOmpModel, } from "./models.js";
|
|
10
11
|
import { buildOmpProcessEnvironment, diagnoseOmpRuntime, disposeOmpSessionPaths, prepareOmpSessionPaths, resetOmpNativeSession, resolveOmpCommand, } from "./process.js";
|
|
11
12
|
import { OmpResourceDelivery } from "./resource-delivery.js";
|
|
@@ -14,6 +15,32 @@ import { OmpRpcTurnController } from "./turn.js";
|
|
|
14
15
|
export { OMP_ADAPTER_ID } from "./thread.js";
|
|
15
16
|
export const OMP_RUNTIME_PROTOCOL_NAME = "omp-rpc";
|
|
16
17
|
export const OMP_RUNTIME_SUPPORTED_RANGE = "2";
|
|
18
|
+
const ompCompleteHistoryProofs = new WeakMap();
|
|
19
|
+
const ompRpcRequestImplementation = OmpRpcClient.prototype.request;
|
|
20
|
+
const ompBuiltInHistoryClients = new WeakMap();
|
|
21
|
+
const ompBuiltInAdapterHistoryClients = new WeakMap();
|
|
22
|
+
function bindOmpCompleteHistoryProof(page) {
|
|
23
|
+
const claim = page.reconciliationProof;
|
|
24
|
+
if (!claim?.complete)
|
|
25
|
+
return page;
|
|
26
|
+
const entries = Object.freeze([...claim.entries]);
|
|
27
|
+
const fullScope = Object.freeze({ entryCount: entries.length, digest: historyReconciliationDigest(entries) });
|
|
28
|
+
const proof = Object.freeze({
|
|
29
|
+
complete: true,
|
|
30
|
+
...(claim.scopeId ? { scopeId: claim.scopeId } : {}),
|
|
31
|
+
fullScope,
|
|
32
|
+
entries,
|
|
33
|
+
});
|
|
34
|
+
ompCompleteHistoryProofs.set(proof, { ...(claim.scopeId ? { scopeId: claim.scopeId } : {}), fullScope });
|
|
35
|
+
return { ...page, reconciliationProof: proof };
|
|
36
|
+
}
|
|
37
|
+
export function isOmpBuiltInHistoryReconciliationProof(proof) {
|
|
38
|
+
const bound = ompCompleteHistoryProofs.get(proof);
|
|
39
|
+
return proof.complete
|
|
40
|
+
&& bound !== undefined
|
|
41
|
+
&& proof.scopeId === bound.scopeId
|
|
42
|
+
&& proof.fullScope === bound.fullScope;
|
|
43
|
+
}
|
|
17
44
|
function ompCapabilities() {
|
|
18
45
|
return {
|
|
19
46
|
lifecycle: {
|
|
@@ -179,6 +206,7 @@ export class OmpSession {
|
|
|
179
206
|
thread;
|
|
180
207
|
hostTools;
|
|
181
208
|
resourceDelivery;
|
|
209
|
+
forkCandidatesRequest;
|
|
182
210
|
constructor(runtimeInstanceId, bundle, config, emitWarning, adapter) {
|
|
183
211
|
this.runtimeInstanceId = runtimeInstanceId;
|
|
184
212
|
this.bundle = bundle;
|
|
@@ -197,12 +225,11 @@ export class OmpSession {
|
|
|
197
225
|
this.controls = {
|
|
198
226
|
getCurrentSession: () => this.thread.getSessionSnapshot(this.runtimeInstanceId),
|
|
199
227
|
listSessions: () => this.thread.listSessions(this.runtimeInstanceId),
|
|
200
|
-
getForkCandidates: () => this.
|
|
228
|
+
getForkCandidates: () => this.getForkCandidates(),
|
|
201
229
|
forkSession: async (entryId) => await this.runIdleOperation(async () => {
|
|
202
|
-
const previous = this.thread.getSessionSnapshot(this.runtimeInstanceId);
|
|
203
230
|
const result = await this.thread.forkSession(this.runtimeInstanceId, entryId);
|
|
204
231
|
this.updateBinding();
|
|
205
|
-
return
|
|
232
|
+
return result;
|
|
206
233
|
}),
|
|
207
234
|
getReasoning: () => parseOmpReasoning(undefined),
|
|
208
235
|
setReasoning: (value) => {
|
|
@@ -245,9 +272,6 @@ export class OmpSession {
|
|
|
245
272
|
adapterId: OMP_ADAPTER_ID,
|
|
246
273
|
};
|
|
247
274
|
}
|
|
248
|
-
forkCandidates() {
|
|
249
|
-
return this.thread.cachedForkCandidates();
|
|
250
|
-
}
|
|
251
275
|
async setOmpModel(provider, modelId) {
|
|
252
276
|
const info = await setOmpModel(this.client, provider, modelId);
|
|
253
277
|
return info;
|
|
@@ -315,7 +339,7 @@ export class OmpSession {
|
|
|
315
339
|
listener(event);
|
|
316
340
|
}
|
|
317
341
|
async prompt(input) {
|
|
318
|
-
this.
|
|
342
|
+
this.assertIdle();
|
|
319
343
|
this.operationInFlight = true;
|
|
320
344
|
try {
|
|
321
345
|
await this.turn.prompt(input.text);
|
|
@@ -369,6 +393,19 @@ export class OmpSession {
|
|
|
369
393
|
if (this.disposed)
|
|
370
394
|
throw new Error("OMP session is disposed.");
|
|
371
395
|
}
|
|
396
|
+
async getForkCandidates() {
|
|
397
|
+
if (this.forkCandidatesRequest)
|
|
398
|
+
return await this.forkCandidatesRequest;
|
|
399
|
+
const request = this.runIdleOperation(async () => await this.thread.loadForkCandidates(this.runtimeInstanceId));
|
|
400
|
+
this.forkCandidatesRequest = request;
|
|
401
|
+
try {
|
|
402
|
+
return await request;
|
|
403
|
+
}
|
|
404
|
+
finally {
|
|
405
|
+
if (this.forkCandidatesRequest === request)
|
|
406
|
+
this.forkCandidatesRequest = undefined;
|
|
407
|
+
}
|
|
408
|
+
}
|
|
372
409
|
async runIdleOperation(operation) {
|
|
373
410
|
this.assertIdle();
|
|
374
411
|
this.operationInFlight = true;
|
|
@@ -380,7 +417,7 @@ export class OmpSession {
|
|
|
380
417
|
}
|
|
381
418
|
}
|
|
382
419
|
}
|
|
383
|
-
|
|
420
|
+
class OmpAgentRuntimeAdapter {
|
|
384
421
|
instanceId;
|
|
385
422
|
descriptor;
|
|
386
423
|
config;
|
|
@@ -473,6 +510,10 @@ export class OmpAgentRuntimeAdapter {
|
|
|
473
510
|
const session = new OmpSession(this.instanceId, bundle, this.parsed, (m) => {
|
|
474
511
|
// Warning surfaced via session events is delivered by the turn controller.
|
|
475
512
|
}, this);
|
|
513
|
+
const historyClient = Object.freeze({
|
|
514
|
+
request: ((...args) => Reflect.apply(ompRpcRequestImplementation, client, args)),
|
|
515
|
+
});
|
|
516
|
+
ompBuiltInHistoryClients.set(session, { owner: this, client: historyClient });
|
|
476
517
|
session.setPiboSessionId(input.piboSession.id);
|
|
477
518
|
// Wire host tools after session construction so the executor is available.
|
|
478
519
|
const portableTools = input.services?.portableTools;
|
|
@@ -521,8 +562,6 @@ export class OmpAgentRuntimeAdapter {
|
|
|
521
562
|
// (bindNativeSessionId below still sets the binding.)
|
|
522
563
|
}
|
|
523
564
|
}
|
|
524
|
-
// Prime fork candidates (get_branch_messages) for the sync SPI.
|
|
525
|
-
void threads.loadForkCandidates(this.instanceId);
|
|
526
565
|
}
|
|
527
566
|
catch (error) {
|
|
528
567
|
await client.dispose();
|
|
@@ -537,11 +576,18 @@ export class OmpAgentRuntimeAdapter {
|
|
|
537
576
|
}
|
|
538
577
|
/** Record the live session so adapter-level reads can route to it. */
|
|
539
578
|
attachLiveSession(session) {
|
|
579
|
+
const history = ompBuiltInHistoryClients.get(session);
|
|
580
|
+
if (!history || history.owner !== this) {
|
|
581
|
+
throw new AgentRuntimeUnavailableError(this.instanceId, "OMP history requires a session created by this built-in adapter instance.");
|
|
582
|
+
}
|
|
540
583
|
this.live = session;
|
|
584
|
+
ompBuiltInAdapterHistoryClients.set(this, history.client);
|
|
541
585
|
}
|
|
542
586
|
detachLiveSession(session) {
|
|
543
|
-
if (this.live
|
|
544
|
-
|
|
587
|
+
if (this.live !== session)
|
|
588
|
+
return;
|
|
589
|
+
this.live = undefined;
|
|
590
|
+
ompBuiltInAdapterHistoryClients.delete(this);
|
|
545
591
|
}
|
|
546
592
|
async listModels() {
|
|
547
593
|
if (this.live) {
|
|
@@ -579,8 +625,9 @@ export class OmpAgentRuntimeAdapter {
|
|
|
579
625
|
return inspectOmpHistory(input, this.instanceId);
|
|
580
626
|
}
|
|
581
627
|
async readHistory(input) {
|
|
582
|
-
|
|
583
|
-
|
|
628
|
+
const historyClient = ompBuiltInAdapterHistoryClients.get(this);
|
|
629
|
+
if (historyClient) {
|
|
630
|
+
return bindOmpCompleteHistoryProof(await readOmpHistory(historyClient, input, this.instanceId, input.binding));
|
|
584
631
|
}
|
|
585
632
|
return emptyOmpHistoryPage(this.instanceId);
|
|
586
633
|
}
|