@pasko70/pibo 2.5.2 → 3.0.1

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 (100) hide show
  1. package/context/pibo-native-tooling.md +1 -0
  2. package/dist/agent-runtime/contract.js +2 -1
  3. package/dist/agent-runtime/history.js +53 -1
  4. package/dist/agent-runtime/routed-session.js +100 -26
  5. package/dist/agent-runtimes/codex-native/adapter.js +304 -30
  6. package/dist/agent-runtimes/codex-native/client.js +22 -3
  7. package/dist/agent-runtimes/codex-native/first-use.js +294 -0
  8. package/dist/agent-runtimes/codex-native/history.js +26 -7
  9. package/dist/agent-runtimes/codex-native/process.js +14 -0
  10. package/dist/agent-runtimes/codex-native/thread.js +59 -25
  11. package/dist/agent-runtimes/codex-native/turn.js +27 -0
  12. package/dist/agent-runtimes/history-proof.js +8 -0
  13. package/dist/agent-runtimes/omp/adapter.js +61 -14
  14. package/dist/agent-runtimes/omp/history.js +189 -34
  15. package/dist/agent-runtimes/omp/thread.js +82 -36
  16. package/dist/agent-runtimes/pi/adapter.js +30 -3
  17. package/dist/agent-runtimes/pi/history.js +66 -5
  18. package/dist/agent-runtimes/pi/openai-response-observer.js +102 -0
  19. package/dist/agent-runtimes/pi/routed-session.js +344 -37
  20. package/dist/apps/chat/chat-api-routes.js +1 -1
  21. package/dist/apps/chat/chat-files.js +130 -9
  22. package/dist/apps/chat/chat-settings-routes.js +27 -2
  23. package/dist/apps/chat/chat-speech.js +100 -0
  24. package/dist/apps/chat/data/chat-data-mappers.js +25 -5
  25. package/dist/apps/chat/data/timeline-query-service.js +89 -1
  26. package/dist/apps/chat/trace-v2.js +210 -8
  27. package/dist/apps/chat/trace.js +3 -0
  28. package/dist/apps/chat/web-app.js +108 -3
  29. package/dist/apps/chat-ui/assets/{dist-DTWJf37A.js → dist-BBDMeU5-.js} +1 -1
  30. package/dist/apps/chat-ui/assets/{dist-CkYWKnvy.js → dist-BDIATCQt.js} +1 -1
  31. package/dist/apps/chat-ui/assets/{dist-DZ8Wpj-H.js → dist-JnW4v8UE.js} +1 -1
  32. package/dist/apps/chat-ui/assets/{dist-Dmblz15N.js → dist-lRiLP9rr.js} +1 -1
  33. package/dist/apps/chat-ui/assets/{dist-DjcwoyNY.js → dist-mqCviI-c.js} +1 -1
  34. package/dist/apps/chat-ui/assets/index-0XOOVxLP.js +228 -0
  35. package/dist/apps/chat-ui/assets/index-DV7_CgsC.css +1 -0
  36. package/dist/apps/chat-ui/index.html +2 -2
  37. package/dist/apps/chat-vscode-web/assets/index-Dtw2Z7jz.js +43 -0
  38. package/dist/apps/chat-vscode-web/assets/{index-CF1-9PKU.css → index-SluZr_-r.css} +1 -1
  39. package/dist/apps/chat-vscode-web/index.html +2 -2
  40. package/dist/apps/vscode-artifacts/latest.vsix +0 -0
  41. package/dist/apps/vscode-artifacts/pibo-vscode-ext-3.0.1.vsix +0 -0
  42. package/dist/cli.js +49 -5
  43. package/dist/config/config.js +59 -8
  44. package/dist/core/preview-server-settings.js +20 -0
  45. package/dist/core/session-router.js +464 -37
  46. package/dist/core/user-settings.js +10 -0
  47. package/dist/data/payload-store.js +57 -1
  48. package/dist/data/schema.js +18 -1
  49. package/dist/debug/trace.js +5 -0
  50. package/dist/gateway/client.js +368 -65
  51. package/dist/gateway/protocol.js +2 -0
  52. package/dist/gateway/server.js +8 -0
  53. package/dist/gateway/web.js +2 -0
  54. package/dist/index.js +1 -1
  55. package/dist/loops/store.js +6 -4
  56. package/dist/mcp/config.js +89 -17
  57. package/dist/mcp/daemon-client.js +473 -153
  58. package/dist/mcp/daemon.js +401 -37
  59. package/dist/plugins/builtin.js +2 -2
  60. package/dist/plugins/codex-native.js +2 -0
  61. package/dist/plugins/registry.js +259 -1
  62. package/dist/previews/cli.js +345 -0
  63. package/dist/previews/config.js +61 -0
  64. package/dist/previews/manager.js +644 -0
  65. package/dist/previews/network.js +198 -0
  66. package/dist/previews/plugin.js +11 -0
  67. package/dist/previews/process-supervisor.js +38 -0
  68. package/dist/previews/proxy.js +387 -0
  69. package/dist/previews/store.js +750 -0
  70. package/dist/previews/types.js +1 -0
  71. package/dist/previews/web-app.js +446 -0
  72. package/dist/runs/registry.js +22 -0
  73. package/dist/runs/tools.js +46 -7
  74. package/dist/session-ui/terminalRows.js +187 -13
  75. package/dist/sessions/pibo-data-store.js +37 -0
  76. package/dist/sessions/runtime-binding-persistence.js +34 -0
  77. package/dist/sessions/runtime-binding.js +6 -0
  78. package/dist/sessions/sqlite-store.js +37 -0
  79. package/dist/shared/trace-engine.js +12 -64
  80. package/dist/shared/trace-event-projection.js +16 -0
  81. package/dist/shared/trace-history.js +684 -184
  82. package/dist/shared/trace-limits.js +7 -0
  83. package/dist/shared/trace-live-patch.js +61 -0
  84. package/dist/shared/trace-tool-identity.js +43 -0
  85. package/dist/speech/openai-codex-realtime-call-proxy.js +248 -0
  86. package/dist/speech/openai-codex.js +407 -0
  87. package/dist/speech/types.js +8 -0
  88. package/dist/subagents/context.js +5 -3
  89. package/dist/subagents/observations.js +94 -6
  90. package/dist/subagents/tool.js +103 -20
  91. package/dist/tools/codex-image-artifacts.js +24 -0
  92. package/dist/tools/codex-image-generation.js +4 -22
  93. package/dist/web/channel.js +88 -4
  94. package/dist/web/http.js +2 -1
  95. package/npm-shrinkwrap.json +2 -2
  96. package/package.json +1 -1
  97. package/dist/apps/chat-ui/assets/index-0WZI2phJ.css +0 -1
  98. package/dist/apps/chat-ui/assets/index-DsgTm1Aw.js +0 -228
  99. package/dist/apps/chat-vscode-web/assets/index-DvTSSvzN.js +0 -43
  100. package/dist/apps/vscode-artifacts/pibo-vscode-ext-2.5.2.vsix +0 -0
@@ -11,6 +11,7 @@ Use Pibo-owned operator/debug CLI capabilities before ad hoc scripts:
11
11
  - `pibo debug pty ...` for real PTY-backed CLI/TUI smoke tests, scripted input, assertions, and raw/clean artifacts.
12
12
 
13
13
  For fast web research and lightweight navigation, prefer `pibo tools agent-browser`. For web development and UI validation, prefer Browser Use and pair it with Chrome DevTools/CDP or `pibo debug web ...` for console, network, DOM, performance, and render-state evidence. Use a headful Browser Use target for design, layout, responsive, focus, input, and screenshot validation; headless evidence alone is not sufficient for design acceptance. Start with `pibo tools show browser-use`, `pibo tools guide browser-use browser-use`, and `npm run dev -- mcp info chrome-devtools`; use `pibo tools show agent-browser` for the fast research path.
14
+ To start and show a loopback development server without keeping the agent turn active, use `pibo preview expose <port> --session <ps_...> --command '<start-command>'`; do not keep Preview servers in yielded runs. Discover start, stop, restart, and removal with `pibo preview`.
14
15
  For interactive terminal debugging, start with `pibo debug pty --help`; prefer mocked/deterministic scenarios by default and use `--real-provider` only with bounded `--max-iterations`.
15
16
 
16
17
  Use `pibo skills --help` to manage user skills. This CLI covers user-installed skills only, not built-in or plugin-provided skills. Prefer `pibo skills list --json` when another agent will parse the result.
@@ -1,4 +1,5 @@
1
1
  import { AgentRuntimeContractError } from "./errors.js";
2
+ import { hasPendingNativeSession } from "../sessions/runtime-binding.js";
2
3
  export function validateAgentRuntimeSessionContract(session) {
3
4
  const errors = [];
4
5
  const capabilities = session.capabilities;
@@ -32,7 +33,7 @@ export function validateAgentRuntimeSessionContract(session) {
32
33
  if (binding.state === "bound" && !binding.nativeSessionId) {
33
34
  errors.push("a bound session requires binding.nativeSessionId");
34
35
  }
35
- if (binding.state === "unbound" && binding.nativeSessionId) {
36
+ if (binding.state === "unbound" && binding.nativeSessionId && !hasPendingNativeSession(binding)) {
36
37
  errors.push("an unbound session must not expose binding.nativeSessionId");
37
38
  }
38
39
  return errors;
@@ -1 +1,53 @@
1
- export {};
1
+ /**
2
+ * Build a structural complete-history claim for compatibility callers.
3
+ *
4
+ * This function does not grant reconciliation authority. Only an exact built-in
5
+ * adapter can bind a returned claim to its provider-local runtime registry.
6
+ */
7
+ export function createCompleteHistoryReconciliationProof(entries, scopeId) {
8
+ const proofEntries = Object.freeze([...entries]);
9
+ return {
10
+ complete: true,
11
+ ...(scopeId ? { scopeId } : {}),
12
+ fullScope: {
13
+ entryCount: proofEntries.length,
14
+ digest: historyReconciliationDigest(proofEntries),
15
+ },
16
+ entries: proofEntries,
17
+ };
18
+ }
19
+ export function historyReconciliationDigest(entries) {
20
+ const mask = 0xffffffffffffffffn;
21
+ const prime = 0x100000001b3n;
22
+ const hashes = [
23
+ 0xcbf29ce484222325n,
24
+ 0x84222325cbf29ce4n,
25
+ 0x9e3779b97f4a7c15n,
26
+ 0x517cc1b727220a95n,
27
+ ];
28
+ for (const entry of entries) {
29
+ const signature = `${historyReconciliationEntrySignature(entry)}\n`;
30
+ for (let index = 0; index < signature.length; index += 1) {
31
+ const codeUnit = BigInt(signature.charCodeAt(index));
32
+ for (let hashIndex = 0; hashIndex < hashes.length; hashIndex += 1) {
33
+ hashes[hashIndex] = ((hashes[hashIndex] ^ codeUnit) * prime) & mask;
34
+ }
35
+ }
36
+ }
37
+ return hashes.map((hash) => hash.toString(16).padStart(16, "0")).join("");
38
+ }
39
+ export function historyReconciliationEntrySignature(entry) {
40
+ const { sequence: _pageLocalSequence, ...proofContent } = entry;
41
+ return stableHistoryJson(proofContent);
42
+ }
43
+ function stableHistoryJson(value) {
44
+ if (value === null || typeof value !== "object")
45
+ return JSON.stringify(value);
46
+ if (Array.isArray(value))
47
+ return `[${value.map(stableHistoryJson).join(",")}]`;
48
+ return `{${Object.entries(value)
49
+ .filter(([, child]) => child !== undefined)
50
+ .sort(([left], [right]) => left.localeCompare(right))
51
+ .map(([key, child]) => `${JSON.stringify(key)}:${stableHistoryJson(child)}`)
52
+ .join(",")}}`;
53
+ }
@@ -12,7 +12,7 @@ const RUN_REMINDER_CAPABILITY_TOOLS = new Set([
12
12
  // Run reminders are autonomous service wakeups, so their provider/tool loop needs a deterministic boundary.
13
13
  const RUN_REMINDER_MAX_TOOL_EXECUTIONS = 64;
14
14
  const RUN_REMINDER_MAX_PROVIDER_ROUNDS = 64;
15
- const RUN_REMINDER_MAX_TOTAL_TOKENS = 2_000_000;
15
+ const RUN_REMINDER_MAX_ACTIVE_TOKENS = 2_000_000;
16
16
  const RUN_REMINDER_MAX_DURATION_MS = 15 * 60 * 1000;
17
17
  const RUN_REMINDER_MAX_REPEATED_TOOL_CALLS = 12;
18
18
  function serializedToolArgs(value) {
@@ -48,10 +48,23 @@ function nativeSnapshotToPiCompatibility(session, snapshot) {
48
48
  };
49
49
  }
50
50
  function nativeOperationToPiCompatibility(session, piboSessionId, result) {
51
+ // Keep the legacy Pi-shaped result while allowing an adapter-native fork to
52
+ // describe a fresh branch that has no native session yet.
53
+ const current = result.current.nativeSessionId
54
+ ? nativeSnapshotToPiCompatibility(session, result.current)
55
+ : {
56
+ piSessionId: "",
57
+ leafId: result.current.leafId ?? null,
58
+ cwd: result.current.cwd,
59
+ sessionName: result.current.name,
60
+ parentSessionFile: result.current.parentLocator?.kind === "local-file"
61
+ ? result.current.parentLocator.value
62
+ : undefined,
63
+ };
51
64
  return {
52
65
  piboSessionId,
53
66
  previous: nativeSnapshotToPiCompatibility(session, result.previous),
54
- current: nativeSnapshotToPiCompatibility(session, result.current),
67
+ current,
55
68
  cancelled: result.cancelled,
56
69
  selectedText: result.selectedText,
57
70
  editorText: result.editorText,
@@ -105,6 +118,8 @@ export class RuntimeRoutedSession {
105
118
  nextAssistantIndex = 0;
106
119
  activeThinkingIndex;
107
120
  nextThinkingIndex = 0;
121
+ sessionIdentityOperationInFlight = false;
122
+ forkCandidatesRequest;
108
123
  unsubscribe;
109
124
  constructor(piboSessionId, runtimeSession, emit, pluginRegistry, options = {}) {
110
125
  this.piboSessionId = piboSessionId;
@@ -115,8 +130,12 @@ export class RuntimeRoutedSession {
115
130
  this.runtime = runtimeSession.getNativeCompatibilityHandle?.() ?? runtimeSession;
116
131
  this.unsubscribe = runtimeSession.subscribe((event) => this.handleRuntimeEvent(event));
117
132
  }
118
- enqueueMessage(event) {
133
+ enqueueMessage(event, onAccepted = () => { }) {
119
134
  this.assertActive();
135
+ if (this.sessionIdentityOperationInFlight && !this.forkCandidatesRequest) {
136
+ throw new Error("Pibo session cannot accept messages while a session identity operation is in progress.");
137
+ }
138
+ onAccepted();
120
139
  this.queue.push({ kind: "message", event });
121
140
  const output = {
122
141
  type: "message_queued",
@@ -163,18 +182,35 @@ export class RuntimeRoutedSession {
163
182
  this.assertActive();
164
183
  if (event.action === "compact")
165
184
  return this.enqueueCompactAction(event);
166
- const result = await this.runAction(event);
167
- if (isSessionOperationResult(result))
168
- await this.options.onSessionOperation?.(result, event);
169
- const output = {
170
- type: "execution_result",
171
- piboSessionId: this.piboSessionId,
172
- eventId: event.id,
173
- action: event.action,
174
- result,
175
- };
176
- this.emit(output);
177
- return output;
185
+ const changesSessionIdentity = event.action === "session.fork" || event.action === "session.clone";
186
+ if (changesSessionIdentity) {
187
+ this.assertSessionIdentityOperationIdle(event.action === "session.fork" ? "fork" : "clone");
188
+ this.sessionIdentityOperationInFlight = true;
189
+ this.notifyState();
190
+ }
191
+ try {
192
+ if (changesSessionIdentity)
193
+ await this.options.onBeforeSessionIdentityOperation?.(event);
194
+ const result = await this.runAction(event);
195
+ if (isSessionOperationResult(result))
196
+ await this.options.onSessionOperation?.(result, event);
197
+ const output = {
198
+ type: "execution_result",
199
+ piboSessionId: this.piboSessionId,
200
+ eventId: event.id,
201
+ action: event.action,
202
+ result,
203
+ };
204
+ this.emit(output);
205
+ return output;
206
+ }
207
+ finally {
208
+ if (changesSessionIdentity) {
209
+ this.sessionIdentityOperationInFlight = false;
210
+ this.notifyState();
211
+ this.startDrain();
212
+ }
213
+ }
178
214
  }
179
215
  getActiveMessage() {
180
216
  if (!this.activeMessage)
@@ -297,24 +333,54 @@ export class RuntimeRoutedSession {
297
333
  throw runtimeCapabilityError(this.runtimeSession, "native session listing");
298
334
  return (await listSessions()).map((info) => nativeSessionInfoToPiCompatibility(this.runtimeSession, info));
299
335
  }
300
- getForkCandidates() {
336
+ async getForkCandidates() {
337
+ if (this.forkCandidatesRequest)
338
+ return await this.forkCandidatesRequest;
339
+ this.assertSessionIdentityOperationIdle("inspect fork candidates");
301
340
  const getForkCandidates = this.runtimeSession.controls?.getForkCandidates;
302
341
  if (!getForkCandidates)
303
342
  throw runtimeCapabilityError(this.runtimeSession, "native session fork candidates");
304
- return getForkCandidates();
343
+ this.sessionIdentityOperationInFlight = true;
344
+ this.notifyState();
345
+ const request = Promise.resolve().then(async () => await getForkCandidates());
346
+ this.forkCandidatesRequest = request;
347
+ try {
348
+ return await request;
349
+ }
350
+ finally {
351
+ if (this.forkCandidatesRequest === request)
352
+ this.forkCandidatesRequest = undefined;
353
+ this.sessionIdentityOperationInFlight = false;
354
+ this.notifyState();
355
+ this.startDrain();
356
+ }
305
357
  }
306
358
  async forkSession(entryId) {
359
+ this.assertSessionWorkIdle("fork");
307
360
  const forkSession = this.runtimeSession.controls?.forkSession;
308
361
  if (!forkSession)
309
362
  throw runtimeCapabilityError(this.runtimeSession, "native session fork");
310
363
  return nativeOperationToPiCompatibility(this.runtimeSession, this.piboSessionId, await forkSession(entryId));
311
364
  }
312
365
  async cloneSession() {
366
+ this.assertSessionWorkIdle("clone");
313
367
  const cloneSession = this.runtimeSession.controls?.cloneSession;
314
368
  if (!cloneSession)
315
369
  throw runtimeCapabilityError(this.runtimeSession, "native session clone");
316
370
  return nativeOperationToPiCompatibility(this.runtimeSession, this.piboSessionId, await cloneSession());
317
371
  }
372
+ assertSessionIdentityOperationIdle(operation) {
373
+ if (this.sessionIdentityOperationInFlight) {
374
+ throw new Error(`Pibo session already has a session identity operation in progress; cannot ${operation}.`);
375
+ }
376
+ this.assertSessionWorkIdle(operation);
377
+ }
378
+ assertSessionWorkIdle(operation) {
379
+ const status = this.getStatus();
380
+ if (status.processing || status.streaming || status.queuedMessages > 0) {
381
+ throw new Error(`Pibo session must be idle to ${operation}.`);
382
+ }
383
+ }
318
384
  getSessionTree() {
319
385
  const getSessionTree = this.runtimeSession.controls?.getSessionTree;
320
386
  if (!getSessionTree)
@@ -521,7 +587,10 @@ export class RuntimeRoutedSession {
521
587
  costUsd: event.usage.costUsd,
522
588
  provenance: this.activeMessage?.provenance,
523
589
  }));
524
- this.trackRunReminderTurnGuard("usage", { totalTokens: event.usage.totalTokens });
590
+ this.trackRunReminderTurnGuard("usage", {
591
+ totalTokens: event.usage.totalTokens,
592
+ cacheReadTokens: event.usage.cacheReadTokens,
593
+ });
525
594
  return;
526
595
  case "compaction_start":
527
596
  this.emit(this.withActiveMessage({
@@ -605,13 +674,16 @@ export class RuntimeRoutedSession {
605
674
  }));
606
675
  }
607
676
  startDrain() {
608
- if (this.drainPromise)
677
+ if (this.drainPromise || this.sessionIdentityOperationInFlight)
609
678
  return;
610
679
  const drain = this.drain();
611
680
  this.drainPromise = drain;
612
681
  void drain.finally(() => {
613
- if (this.drainPromise === drain)
614
- this.drainPromise = undefined;
682
+ if (this.drainPromise !== drain)
683
+ return;
684
+ this.drainPromise = undefined;
685
+ if (this.queue.length > 0 && !this.disposed)
686
+ this.startDrain();
615
687
  });
616
688
  }
617
689
  async drain() {
@@ -732,7 +804,7 @@ export class RuntimeRoutedSession {
732
804
  eventId: event.id,
733
805
  toolExecutions: 0,
734
806
  providerRounds: 0,
735
- totalTokens: 0,
807
+ activeTokens: 0,
736
808
  toolSignatures: new Map(),
737
809
  tripped: false,
738
810
  };
@@ -755,11 +827,12 @@ export class RuntimeRoutedSession {
755
827
  if (!guard || guard.tripped || guard.eventId !== this.activeMessage?.id)
756
828
  return;
757
829
  if (type === "usage") {
758
- const totalTokens = payload.totalTokens ?? 0;
759
- guard.totalTokens += totalTokens;
830
+ const usage = payload;
831
+ const activeTokens = Math.max(0, (usage.totalTokens ?? 0) - (usage.cacheReadTokens ?? 0));
832
+ guard.activeTokens += activeTokens;
760
833
  guard.providerRounds += 1;
761
- if (guard.totalTokens > RUN_REMINDER_MAX_TOTAL_TOKENS) {
762
- this.tripRunReminderTurnGuard(guard, `exceeded ${RUN_REMINDER_MAX_TOTAL_TOKENS} total tokens`);
834
+ if (guard.activeTokens > RUN_REMINDER_MAX_ACTIVE_TOKENS) {
835
+ this.tripRunReminderTurnGuard(guard, `exceeded ${RUN_REMINDER_MAX_ACTIVE_TOKENS} active tokens`);
763
836
  return;
764
837
  }
765
838
  if (guard.providerRounds > RUN_REMINDER_MAX_PROVIDER_ROUNDS) {
@@ -1007,6 +1080,7 @@ export class RuntimeRoutedSession {
1007
1080
  processing: this.processing,
1008
1081
  queuedMessages: this.queue.length,
1009
1082
  disposed: this.disposed,
1083
+ sessionIdentityOperationInFlight: this.sessionIdentityOperationInFlight,
1010
1084
  });
1011
1085
  }
1012
1086
  resetContentIndices() {