@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
package/dist/data/cli.js CHANGED
@@ -4,9 +4,9 @@ import { DatabaseSync } from "node:sqlite";
4
4
  import { piboHomePath } from "../core/pibo-home.js";
5
5
  import { PiboDataStore } from "./pibo-store.js";
6
6
  const INVENTORY_STORES = [
7
- { name: "v2", file: "pibo.sqlite", tables: ["sessions", "rooms", "chat_messages", "event_log", "observations", "payloads", "session_navigation"] },
8
- { name: "v2-shadow", file: "pibo-chat-v2.sqlite", tables: ["sessions", "rooms", "chat_messages", "event_log", "observations", "payloads", "session_navigation"] },
9
- { name: "legacy-sessions", file: "pibo-sessions.sqlite", tables: ["pibo_sessions"] },
7
+ { name: "v2", file: "pibo.sqlite", tables: ["sessions", "session_runtime_bindings", "rooms", "chat_messages", "event_log", "observations", "payloads", "session_navigation"] },
8
+ { name: "v2-shadow", file: "pibo-chat-v2.sqlite", tables: ["sessions", "session_runtime_bindings", "rooms", "chat_messages", "event_log", "observations", "payloads", "session_navigation"] },
9
+ { name: "legacy-sessions", file: "pibo-sessions.sqlite", tables: ["pibo_sessions", "pibo_session_runtime_bindings"] },
10
10
  { name: "legacy-chat", file: "web-chat.sqlite", tables: ["chat_events", "web_chat_events", "web_chat_sessions", "pibo_rooms", "chat_session_reads"] },
11
11
  { name: "reliability", file: "pibo-events.sqlite", tables: ["pibo_event_stream", "pibo_jobs", "pibo_runs"] },
12
12
  { name: "auth", file: "auth.sqlite", tables: [] },
@@ -121,6 +121,23 @@ function migrateSessionsToV2(input) {
121
121
  else {
122
122
  report.skipped++;
123
123
  }
124
+ target.db.prepare(`
125
+ INSERT INTO session_runtime_bindings (
126
+ pibo_session_id, runtime_instance_id, runtime_adapter_id, native_session_id,
127
+ binding_state, protocol, metadata_json, revision, created_at, updated_at
128
+ ) VALUES (?, 'pi', 'pi', ?, 'bound', 'pi-sdk', '{"migrationSource":"legacy-session-import","nativePresenceExpected":false}', 1, ?, ?)
129
+ ON CONFLICT(pibo_session_id) DO UPDATE SET
130
+ native_session_id = excluded.native_session_id,
131
+ binding_state = 'bound',
132
+ protocol = COALESCE(session_runtime_bindings.protocol, excluded.protocol),
133
+ revision = session_runtime_bindings.revision + 1,
134
+ updated_at = excluded.updated_at
135
+ WHERE session_runtime_bindings.runtime_adapter_id = 'pi'
136
+ AND (
137
+ session_runtime_bindings.native_session_id IS NOT excluded.native_session_id
138
+ OR session_runtime_bindings.binding_state <> 'bound'
139
+ )
140
+ `).run(row.id, row.pi_session_id, row.created_at, row.updated_at);
124
141
  }
125
142
  }
126
143
  finally {
@@ -1,5 +1,9 @@
1
- export const PIBO_DATA_SCHEMA_VERSION = 3;
1
+ export const PIBO_DATA_SCHEMA_VERSION = 5;
2
2
  export function applyPiboDataSchema(db) {
3
+ const previousVersion = Number(db.prepare("PRAGMA user_version").get()?.user_version ?? 0);
4
+ const existingSessionCount = db.prepare("SELECT COUNT(*) AS count FROM sqlite_schema WHERE type = 'table' AND name = 'sessions'").get();
5
+ const hadSessionsBeforeMigration = existingSessionCount.count > 0
6
+ && Number(db.prepare("SELECT COUNT(*) AS count FROM sessions").get().count) > 0;
3
7
  db.exec(`
4
8
  CREATE TABLE IF NOT EXISTS sessions (
5
9
  id TEXT PRIMARY KEY,
@@ -24,6 +28,63 @@ export function applyPiboDataSchema(db) {
24
28
  last_activity_at TEXT NOT NULL
25
29
  );
26
30
 
31
+ CREATE TABLE IF NOT EXISTS session_runtime_bindings (
32
+ pibo_session_id TEXT PRIMARY KEY,
33
+ runtime_instance_id TEXT NOT NULL,
34
+ runtime_adapter_id TEXT NOT NULL,
35
+ native_session_id TEXT,
36
+ binding_state TEXT NOT NULL CHECK(binding_state IN ('unbound', 'bound', 'missing', 'error'))
37
+ CHECK(binding_state NOT IN ('bound', 'missing') OR native_session_id IS NOT NULL),
38
+ protocol TEXT,
39
+ protocol_version TEXT,
40
+ adapter_version TEXT,
41
+ locator_json TEXT,
42
+ metadata_json TEXT NOT NULL DEFAULT '{}',
43
+ revision INTEGER NOT NULL DEFAULT 1 CHECK(revision > 0),
44
+ created_at TEXT NOT NULL,
45
+ updated_at TEXT NOT NULL,
46
+ FOREIGN KEY (pibo_session_id) REFERENCES sessions(id) ON DELETE CASCADE
47
+ );
48
+
49
+ CREATE UNIQUE INDEX IF NOT EXISTS idx_session_runtime_bindings_native
50
+ ON session_runtime_bindings(runtime_adapter_id, native_session_id)
51
+ WHERE native_session_id IS NOT NULL;
52
+ CREATE INDEX IF NOT EXISTS idx_session_runtime_bindings_instance_state
53
+ ON session_runtime_bindings(runtime_instance_id, binding_state, updated_at DESC);
54
+
55
+ CREATE TRIGGER IF NOT EXISTS trg_sessions_runtime_binding_insert
56
+ AFTER INSERT ON sessions
57
+ WHEN NOT EXISTS (
58
+ SELECT 1 FROM session_runtime_bindings WHERE pibo_session_id = NEW.id
59
+ )
60
+ BEGIN
61
+ INSERT INTO session_runtime_bindings (
62
+ pibo_session_id, runtime_instance_id, runtime_adapter_id, native_session_id,
63
+ binding_state, protocol, metadata_json, revision, created_at, updated_at
64
+ ) VALUES (
65
+ NEW.id, 'pi', 'pi', NULLIF(NEW.pi_session_id, ''),
66
+ 'unbound',
67
+ 'pi-sdk', '{}', 1, NEW.created_at, NEW.updated_at
68
+ );
69
+ END;
70
+
71
+ CREATE TRIGGER IF NOT EXISTS trg_sessions_runtime_binding_pi_update
72
+ AFTER UPDATE OF pi_session_id ON sessions
73
+ WHEN EXISTS (
74
+ SELECT 1 FROM session_runtime_bindings
75
+ WHERE pibo_session_id = NEW.id
76
+ AND runtime_adapter_id = 'pi'
77
+ AND COALESCE(native_session_id, '') <> COALESCE(NEW.pi_session_id, '')
78
+ )
79
+ BEGIN
80
+ UPDATE session_runtime_bindings SET
81
+ native_session_id = NULLIF(NEW.pi_session_id, ''),
82
+ binding_state = CASE WHEN NEW.pi_session_id IS NULL OR NEW.pi_session_id = '' THEN 'unbound' ELSE 'bound' END,
83
+ revision = revision + 1,
84
+ updated_at = NEW.updated_at
85
+ WHERE pibo_session_id = NEW.id AND runtime_adapter_id = 'pi';
86
+ END;
87
+
27
88
  CREATE TABLE IF NOT EXISTS rooms (
28
89
  id TEXT PRIMARY KEY,
29
90
  name TEXT NOT NULL,
@@ -438,5 +499,47 @@ export function applyPiboDataSchema(db) {
438
499
  CREATE INDEX IF NOT EXISTS idx_telemetry_tool_calls_retention_updated
439
500
  ON telemetry_tool_calls(retention_class, updated_at);
440
501
  `);
502
+ db.exec(`
503
+ INSERT OR IGNORE INTO session_runtime_bindings (
504
+ pibo_session_id, runtime_instance_id, runtime_adapter_id, native_session_id,
505
+ binding_state, protocol, metadata_json, revision, created_at, updated_at
506
+ )
507
+ SELECT
508
+ id, 'pi', 'pi', NULLIF(pi_session_id, ''),
509
+ CASE WHEN pi_session_id IS NULL OR pi_session_id = '' THEN 'unbound' ELSE 'bound' END,
510
+ 'pi-sdk',
511
+ CASE WHEN EXISTS (SELECT 1 FROM event_log WHERE event_log.session_id = sessions.id LIMIT 1)
512
+ THEN '{"migrationSource":"schema-v4","nativePresenceExpected":true}'
513
+ ELSE '{"migrationSource":"schema-v4","nativePresenceExpected":false}'
514
+ END,
515
+ 1, created_at, updated_at
516
+ FROM sessions
517
+ WHERE NOT EXISTS (
518
+ SELECT 1 FROM session_runtime_bindings existing
519
+ WHERE existing.pibo_session_id = sessions.id
520
+ );
521
+ `);
522
+ if (previousVersion < PIBO_DATA_SCHEMA_VERSION && hadSessionsBeforeMigration) {
523
+ const rows = db.prepare("SELECT pibo_session_id, metadata_json FROM session_runtime_bindings").all();
524
+ const update = db.prepare("UPDATE session_runtime_bindings SET metadata_json = ? WHERE pibo_session_id = ?");
525
+ for (const row of rows) {
526
+ let metadata = {};
527
+ try {
528
+ const parsed = JSON.parse(row.metadata_json);
529
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed))
530
+ metadata = parsed;
531
+ }
532
+ catch {
533
+ // Preserve a valid object even if legacy metadata was malformed.
534
+ }
535
+ if (metadata.nativeHistoryFallback === true)
536
+ continue;
537
+ update.run(JSON.stringify({
538
+ ...metadata,
539
+ nativeHistoryFallback: true,
540
+ historyMigrationSource: "schema-v5",
541
+ }), row.pibo_session_id);
542
+ }
543
+ }
441
544
  db.exec(`PRAGMA user_version = ${PIBO_DATA_SCHEMA_VERSION}`);
442
545
  }
@@ -1,3 +1,4 @@
1
+ import { createLegacyPiRuntimeSessionBinding } from "../sessions/runtime-binding.js";
1
2
  export class SessionStore {
2
3
  db;
3
4
  constructor(db) {
@@ -11,7 +12,7 @@ export class SessionStore {
11
12
  ];
12
13
  const values = [
13
14
  input.session.id,
14
- input.session.piSessionId,
15
+ input.session.piSessionId || null,
15
16
  input.roomId,
16
17
  rootSessionId(input.session),
17
18
  input.session.parentId ?? null,
@@ -52,6 +53,28 @@ export class SessionStore {
52
53
  VALUES (${baseColumns.map(() => "?").join(", ")})
53
54
  ON CONFLICT(id) DO UPDATE SET ${assignments.join(", ")}
54
55
  `).run(...values);
56
+ const binding = input.session.runtimeBinding
57
+ ?? createLegacyPiRuntimeSessionBinding(input.session.id, input.session.piSessionId, input.session.createdAt);
58
+ this.db.prepare(`
59
+ INSERT INTO session_runtime_bindings (
60
+ pibo_session_id, runtime_instance_id, runtime_adapter_id, native_session_id,
61
+ binding_state, protocol, protocol_version, adapter_version, locator_json,
62
+ metadata_json, revision, created_at, updated_at
63
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
64
+ ON CONFLICT(pibo_session_id) DO UPDATE SET
65
+ runtime_instance_id = excluded.runtime_instance_id,
66
+ runtime_adapter_id = excluded.runtime_adapter_id,
67
+ native_session_id = excluded.native_session_id,
68
+ binding_state = excluded.binding_state,
69
+ protocol = excluded.protocol,
70
+ protocol_version = excluded.protocol_version,
71
+ adapter_version = excluded.adapter_version,
72
+ locator_json = excluded.locator_json,
73
+ metadata_json = excluded.metadata_json,
74
+ revision = excluded.revision,
75
+ created_at = excluded.created_at,
76
+ updated_at = excluded.updated_at
77
+ `).run(binding.piboSessionId, binding.runtimeInstanceId, binding.adapterId, binding.nativeSessionId ?? null, binding.state, binding.protocol ?? null, binding.protocolVersion ?? null, binding.adapterVersion ?? null, binding.locator ? JSON.stringify(binding.locator) : null, JSON.stringify(binding.metadata ?? {}), binding.revision ?? 1, binding.createdAt ?? input.session.createdAt, binding.updatedAt ?? now);
55
78
  }
56
79
  }
57
80
  export function rootSessionId(session) {
@@ -2,6 +2,8 @@ import { formatTruncationFooter, sliceTextByBytes } from "./detail-format.js";
2
2
  import { formatNextCommands } from "./next-commands.js";
3
3
  import { compactOneLine, eventPayload, rawEventObject, resolveEventField, sourceRef, stringifyPayloadValue } from "./payloads.js";
4
4
  import { normalizeLimit, openReadOnlyDebugDatabase, withStorePath } from "./sql.js";
5
+ import { createDebugPayloadStore, hydrateDebugEventRow } from "./persisted-payloads.js";
6
+ import { readDebugRuntimeIdentity } from "./runtime-binding.js";
5
7
  export function inspectDebugEvents(piboSessionId, store, options = {}) {
6
8
  if (!store.exists)
7
9
  throw new Error(`Debug store "chat" not found at ${store.path}`);
@@ -16,22 +18,25 @@ export function inspectDebugEvents(piboSessionId, store, options = {}) {
16
18
  clauses.push("type = ?");
17
19
  values.push(options.type);
18
20
  }
21
+ const payloadStore = createDebugPayloadStore(db, store);
19
22
  const rows = db
20
23
  .prepare(`
21
- SELECT stream_id, session_id, session_sequence, event_id, type, created_at, preview_text, attributes_json
24
+ SELECT stream_id, session_id, session_sequence, event_id, type, created_at, payload_ref, preview_text, attributes_json
22
25
  FROM event_log
23
26
  WHERE ${clauses.join(" AND ")}
24
27
  ORDER BY stream_id DESC
25
28
  LIMIT ?
26
29
  `)
27
30
  .all(...values, limit + 1);
28
- const limited = rows.length > limit;
29
- const events = rows.slice(0, limit).map((row) => formatEventRow(row, options.fields ?? []));
31
+ const hydratedRows = rows.map((row) => hydrateDebugEventRow(row, payloadStore));
32
+ const limited = hydratedRows.length > limit;
33
+ const events = hydratedRows.slice(0, limit).map((row) => formatEventRow(row, options.fields ?? []));
30
34
  return {
31
35
  piboSessionId,
36
+ ...readDebugRuntimeIdentity(db, piboSessionId),
32
37
  events,
33
38
  limited,
34
- nextCommands: buildListNextCommands(piboSessionId, rows.slice(0, limit)),
39
+ nextCommands: buildListNextCommands(piboSessionId, hydratedRows.slice(0, limit)),
35
40
  };
36
41
  }
37
42
  catch (error) {
@@ -48,15 +53,17 @@ export function inspectDebugEventShow(piboSessionId, store, selector, options =
48
53
  try {
49
54
  if (!tableExists(db, "event_log"))
50
55
  return { piboSessionId, resultType: "debug.events.show", selector, nextCommands: [] };
51
- const row = findEventRow(db, piboSessionId, selector);
52
- if (!row)
56
+ const found = findEventRow(db, piboSessionId, selector);
57
+ if (!found)
53
58
  return { piboSessionId, resultType: "debug.events.show", selector, nextCommands: [`pibo debug events ${piboSessionId} list`] };
59
+ const row = hydrateDebugEventRow(found, createDebugPayloadStore(db, store));
54
60
  const payload = eventPayload(row);
55
61
  const raw = rawEventObject(row);
56
62
  const shown = options.raw ? raw : payload;
57
63
  const source = sourceRef(row, options.field, options.raw ? "raw" : "event");
58
64
  const result = {
59
65
  piboSessionId,
66
+ ...readDebugRuntimeIdentity(db, piboSessionId),
60
67
  resultType: "debug.events.show",
61
68
  selector,
62
69
  event: formatEventRow(row, []),
@@ -95,10 +102,11 @@ export function inspectDebugEventShow(piboSessionId, store, selector, options =
95
102
  }
96
103
  }
97
104
  export function formatDebugEvents(result) {
105
+ const runtimeLines = formatRuntimeIdentity(result);
98
106
  if (result.events.length === 0)
99
- return ["events: 0", ...formatNextCommands(result.nextCommands ?? [])].join("\n");
107
+ return [...runtimeLines, "events: 0", ...formatNextCommands(result.nextCommands ?? [])].join("\n");
100
108
  const columns = Object.keys(result.events[0] ?? {});
101
- const lines = [columns.join("\t")];
109
+ const lines = [...runtimeLines, columns.join("\t")];
102
110
  for (const event of result.events) {
103
111
  lines.push(columns.map((column) => formatValue(event[column])).join("\t"));
104
112
  }
@@ -168,14 +176,14 @@ function findEventRow(db, piboSessionId, selector) {
168
176
  const numeric = Number(selector);
169
177
  if (Number.isInteger(numeric)) {
170
178
  const row = db.prepare(`
171
- SELECT stream_id, session_id, session_sequence, event_id, type, created_at, preview_text, attributes_json
179
+ SELECT stream_id, session_id, session_sequence, event_id, type, created_at, payload_ref, preview_text, attributes_json
172
180
  FROM event_log WHERE session_id = ? AND stream_id = ?
173
181
  `).get(piboSessionId, numeric);
174
182
  if (row)
175
183
  return row;
176
184
  }
177
185
  return db.prepare(`
178
- SELECT stream_id, session_id, session_sequence, event_id, type, created_at, preview_text, attributes_json
186
+ SELECT stream_id, session_id, session_sequence, event_id, type, created_at, payload_ref, preview_text, attributes_json
179
187
  FROM event_log WHERE session_id = ? AND event_id = ? ORDER BY stream_id DESC LIMIT 1
180
188
  `).get(piboSessionId, selector);
181
189
  }
@@ -203,6 +211,13 @@ function tableExists(db, table) {
203
211
  const row = db.prepare("SELECT name FROM sqlite_schema WHERE type = 'table' AND name = ?").get(table);
204
212
  return row !== undefined;
205
213
  }
214
+ function formatRuntimeIdentity(result) {
215
+ return [
216
+ result.runtimeInstanceId ? `runtimeInstanceId: ${result.runtimeInstanceId}` : undefined,
217
+ result.runtimeAdapterId ? `runtimeAdapterId: ${result.runtimeAdapterId}` : undefined,
218
+ result.runtimeBindingState ? `runtimeBindingState: ${result.runtimeBindingState}` : undefined,
219
+ ].filter((value) => Boolean(value));
220
+ }
206
221
  function formatValue(value) {
207
222
  if (value === null || value === undefined)
208
223
  return "";
@@ -2,6 +2,8 @@ import { formatNextCommands } from "./next-commands.js";
2
2
  import { compactOneLine, eventPayload } from "./payloads.js";
3
3
  import { normalizeLimit, openReadOnlyDebugDatabase, withStorePath } from "./sql.js";
4
4
  import { inspectDebugTrace } from "./trace.js";
5
+ import { createDebugPayloadStore, hydrateDebugEventRow } from "./persisted-payloads.js";
6
+ import { readDebugRuntimeIdentity } from "./runtime-binding.js";
5
7
  export async function inspectDebugFailures(piboSessionId, stores, options = {}) {
6
8
  const limit = normalizeLimit(options.limit);
7
9
  const failures = [];
@@ -19,6 +21,7 @@ export async function inspectDebugFailures(piboSessionId, stores, options = {})
19
21
  const visible = failures.slice(0, limit);
20
22
  return {
21
23
  piboSessionId,
24
+ ...readRuntimeIdentityFromStore(piboSessionId, stores.chat),
22
25
  resultType: "debug.failures",
23
26
  failures: visible,
24
27
  limited,
@@ -30,7 +33,12 @@ export async function inspectDebugFailures(piboSessionId, stores, options = {})
30
33
  };
31
34
  }
32
35
  export function formatDebugFailures(result) {
33
- const lines = [`failures: ${result.failures.length}${result.limited ? " (limited)" : ""}`];
36
+ const lines = [
37
+ ...(result.runtimeInstanceId ? [`runtimeInstanceId: ${result.runtimeInstanceId}`] : []),
38
+ ...(result.runtimeAdapterId ? [`runtimeAdapterId: ${result.runtimeAdapterId}`] : []),
39
+ ...(result.runtimeBindingState ? [`runtimeBindingState: ${result.runtimeBindingState}`] : []),
40
+ `failures: ${result.failures.length}${result.limited ? " (limited)" : ""}`,
41
+ ];
34
42
  result.failures.forEach((failure, index) => {
35
43
  lines.push("");
36
44
  if (failure.kind === "tool") {
@@ -57,6 +65,17 @@ export function formatDebugFailures(result) {
57
65
  lines.push(...formatNextCommands(result.nextCommands));
58
66
  return lines.join("\n");
59
67
  }
68
+ function readRuntimeIdentityFromStore(piboSessionId, store) {
69
+ if (!store.exists)
70
+ return {};
71
+ const db = openReadOnlyDebugDatabase(store);
72
+ try {
73
+ return readDebugRuntimeIdentity(db, piboSessionId);
74
+ }
75
+ finally {
76
+ db.close();
77
+ }
78
+ }
60
79
  function readToolFailures(piboSessionId, store, limit) {
61
80
  if (!store.exists)
62
81
  return [];
@@ -64,13 +83,14 @@ function readToolFailures(piboSessionId, store, limit) {
64
83
  try {
65
84
  if (!tableExists(db, "event_log"))
66
85
  return [];
86
+ const payloadStore = createDebugPayloadStore(db, store);
67
87
  const rows = db.prepare(`
68
- SELECT stream_id, session_id, session_sequence, event_id, type, created_at, preview_text, attributes_json
88
+ SELECT stream_id, session_id, session_sequence, event_id, type, created_at, payload_ref, preview_text, attributes_json
69
89
  FROM event_log
70
90
  WHERE session_id = ? AND type = 'tool_execution_finished'
71
91
  ORDER BY stream_id DESC
72
92
  LIMIT ?
73
- `).all(piboSessionId, limit + 1);
93
+ `).all(piboSessionId, limit + 1).map((row) => hydrateDebugEventRow(row, payloadStore));
74
94
  return rows.flatMap((row) => {
75
95
  const payload = eventPayload(row);
76
96
  const status = statusFromPayload(payload);
@@ -155,11 +155,20 @@ async function runDebugSession(args) {
155
155
  if (!input)
156
156
  throw new Error("pibo debug session requires <url-or-pibo-session-id>");
157
157
  const { formatJson } = await import("./sql.js");
158
- const { formatDebugSessionSummary, inspectDebugSession } = await import("./session.js");
159
- const summary = inspectDebugSession(input, {
158
+ const stores = {
160
159
  sessions: resolveDebugStore("sessions"),
161
160
  chat: resolveDebugStore("chat"),
162
- }, {
161
+ };
162
+ const { formatDebugSessionRuntime, formatDebugSessionSummary, inspectDebugSession, inspectDebugSessionRuntime } = await import("./session.js");
163
+ if (options.positionals[1] === "runtime") {
164
+ const result = inspectDebugSessionRuntime(input, stores);
165
+ if (options.json)
166
+ console.log(formatJson(result));
167
+ else
168
+ console.log(formatDebugSessionRuntime(result));
169
+ return;
170
+ }
171
+ const summary = inspectDebugSession(input, stores, {
163
172
  events: options.events,
164
173
  limit: options.limit,
165
174
  });
@@ -441,6 +450,7 @@ async function runDebugTrace(args) {
441
450
  const result = await inspectDebugTrace(piboSessionId, stores, {
442
451
  runningOnly: options.runningOnly,
443
452
  check: options.check,
453
+ nativeHistory: options.nativeHistory,
444
454
  });
445
455
  if (options.json)
446
456
  console.log(formatJson(result));
@@ -717,7 +727,7 @@ function readCookieHeaderFile(path) {
717
727
  return cookies.join("; ");
718
728
  }
719
729
  function parseOptions(args) {
720
- const parsed = { positionals: [], json: false, events: false, runningOnly: false, check: false, medium: false, destructive: false, apply: false, dryRun: false, full: false, noTruncate: false, plain: false, raw: false, payload: false, args: false, output: false, error: false, active: false, stale: false };
730
+ const parsed = { positionals: [], json: false, events: false, runningOnly: false, nativeHistory: false, check: false, medium: false, destructive: false, apply: false, dryRun: false, full: false, noTruncate: false, plain: false, raw: false, payload: false, args: false, output: false, error: false, active: false, stale: false };
721
731
  for (let index = 0; index < args.length; index += 1) {
722
732
  const arg = args[index];
723
733
  if (arg === "--json") {
@@ -732,6 +742,10 @@ function parseOptions(args) {
732
742
  parsed.runningOnly = true;
733
743
  continue;
734
744
  }
745
+ if (arg === "--native-history") {
746
+ parsed.nativeHistory = true;
747
+ continue;
748
+ }
735
749
  if (arg === "--check") {
736
750
  parsed.check = true;
737
751
  continue;
@@ -1161,6 +1175,7 @@ function printDebugSessionDiscovery() {
1161
1175
 
1162
1176
  Usage:
1163
1177
  pibo debug session <url-or-pibo-session-id> [--events] [--limit n] [--json]
1178
+ pibo debug session <url-or-pibo-session-id> runtime [--json]
1164
1179
 
1165
1180
  Inputs:
1166
1181
  ps_...
@@ -1169,6 +1184,7 @@ Inputs:
1169
1184
 
1170
1185
  Next:
1171
1186
  pibo debug session ps_...
1187
+ pibo debug session ps_... runtime
1172
1188
  `);
1173
1189
  }
1174
1190
  function printDebugSummaryDiscovery() {
@@ -1238,15 +1254,17 @@ function printDebugTraceDiscovery() {
1238
1254
  console.log(`pibo debug trace - rebuild one Chat Web trace view
1239
1255
 
1240
1256
  Usage:
1241
- pibo debug trace <pibo-session-id> [--running-only] [--check] [--medium] [--json]
1257
+ pibo debug trace <pibo-session-id> [--running-only] [--check] [--medium] [--native-history] [--json]
1242
1258
  pibo debug trace <pibo-session-id> show <node-id> [--json]
1243
1259
 
1244
1260
  Output:
1245
- Compact trace nodes from the same buildTraceView logic used by /api/chat/trace.
1261
+ Compact trace nodes from Pibo product history and normalized events.
1262
+ --native-history explicitly asks the selected adapter for harness-native history.
1246
1263
  --check adds consistency diagnostics for ids, parents, ordering, and links.
1247
1264
 
1248
1265
  Next:
1249
1266
  pibo debug trace ps_... --check
1267
+ pibo debug trace ps_... --native-history --check
1250
1268
  pibo debug trace ps_... --medium
1251
1269
  pibo debug trace ps_... show <node-id>
1252
1270
  `);
@@ -2,12 +2,15 @@ import { byteLength, formatTruncationFooter, sliceTextByBytes } from "./detail-f
2
2
  import { formatNextCommands } from "./next-commands.js";
3
3
  import { compactOneLine, messageRole, rawEventObject, resolveMessageContent, sourceRef } from "./payloads.js";
4
4
  import { normalizeLimit, openReadOnlyDebugDatabase, withStorePath } from "./sql.js";
5
+ import { createDebugPayloadStore, hydrateDebugEventRow } from "./persisted-payloads.js";
6
+ import { readDebugRuntimeIdentity } from "./runtime-binding.js";
5
7
  export function inspectDebugMessagesList(piboSessionId, store, options = {}) {
6
8
  const messages = readMessages(piboSessionId, store, normalizeLimit(options.limit));
7
9
  const limited = messages.limited;
8
10
  const rows = messages.rows.map(({ content: _content, ...row }) => row);
9
11
  return {
10
12
  piboSessionId,
13
+ ...messages.runtime,
11
14
  messages: rows,
12
15
  limited,
13
16
  nextCommands: [
@@ -18,11 +21,13 @@ export function inspectDebugMessagesList(piboSessionId, store, options = {}) {
18
21
  };
19
22
  }
20
23
  export function inspectDebugMessageShow(piboSessionId, store, selector, options = {}) {
21
- const messages = readMessages(piboSessionId, store, 1000).rows;
24
+ const read = readMessages(piboSessionId, store, 1000);
25
+ const messages = read.rows;
22
26
  const message = selectMessage(messages, selector);
23
27
  if (!message) {
24
28
  return {
25
29
  piboSessionId,
30
+ ...read.runtime,
26
31
  resultType: options.final ? "debug.final" : "debug.messages.show",
27
32
  selector,
28
33
  nextCommands: [`pibo debug messages ${piboSessionId} list`],
@@ -35,6 +40,7 @@ export function inspectDebugMessageShow(piboSessionId, store, selector, options
35
40
  const { rawEvent: _rawEvent, ...messageForResult } = message;
36
41
  return {
37
42
  piboSessionId,
43
+ ...read.runtime,
38
44
  resultType: options.final ? "debug.final" : "debug.messages.show",
39
45
  selector,
40
46
  message: { ...messageForResult, content: slice.text },
@@ -44,9 +50,10 @@ export function inspectDebugMessageShow(piboSessionId, store, selector, options
44
50
  };
45
51
  }
46
52
  export function formatDebugMessagesList(result) {
53
+ const runtimeLines = formatRuntimeIdentity(result);
47
54
  if (result.messages.length === 0)
48
- return [`messages: 0`, ...formatNextCommands(result.nextCommands)].join("\n");
49
- const lines = ["idx\trole\tstream_id\tevent_id\tbytes\ttruncated\tpreview"];
55
+ return [...runtimeLines, `messages: 0`, ...formatNextCommands(result.nextCommands)].join("\n");
56
+ const lines = [...runtimeLines, "idx\trole\tstream_id\tevent_id\tbytes\ttruncated\tpreview"];
50
57
  for (const message of result.messages) {
51
58
  lines.push([
52
59
  message.idx,
@@ -70,6 +77,7 @@ export function formatDebugMessageShow(result, options = {}) {
70
77
  return result.message.content;
71
78
  const lines = [];
72
79
  lines.push(`piboSessionId: ${result.piboSessionId}`);
80
+ lines.push(...formatRuntimeIdentity(result));
73
81
  lines.push(`selector: ${result.selector}`);
74
82
  lines.push(`role: ${result.message.role}`);
75
83
  lines.push(`stream_id: ${result.message.streamId}`);
@@ -101,17 +109,23 @@ function readMessages(piboSessionId, store, limit) {
101
109
  throw new Error(`Debug store "chat" not found at ${store.path}`);
102
110
  const db = openReadOnlyDebugDatabase(store);
103
111
  try {
112
+ const runtime = readDebugRuntimeIdentity(db, piboSessionId);
113
+ const persistedMessages = readPersistedMessages(db, store, piboSessionId, limit);
114
+ if (persistedMessages.rows.length > 0)
115
+ return { ...persistedMessages, runtime };
104
116
  if (!tableExists(db, "event_log"))
105
- return { rows: [], limited: false };
117
+ return { rows: [], limited: false, runtime };
118
+ const payloadStore = createDebugPayloadStore(db, store);
106
119
  const rows = db.prepare(`
107
- SELECT stream_id, session_id, session_sequence, event_id, type, created_at, preview_text, attributes_json
120
+ SELECT stream_id, session_id, session_sequence, event_id, type, created_at, payload_ref, preview_text, attributes_json
108
121
  FROM event_log
109
122
  WHERE session_id = ?
110
123
  ORDER BY stream_id ASC
111
124
  LIMIT ?
112
125
  `).all(piboSessionId, limit + 1);
113
126
  const messages = [];
114
- for (const row of rows) {
127
+ for (const rawRow of rows) {
128
+ const row = hydrateDebugEventRow(rawRow, payloadStore);
115
129
  const role = messageRole(row);
116
130
  if (!role)
117
131
  continue;
@@ -133,7 +147,7 @@ function readMessages(piboSessionId, store, limit) {
133
147
  rawEvent: rawEventObject(row),
134
148
  });
135
149
  }
136
- return { rows: messages.slice(0, limit), limited: rows.length > limit };
150
+ return { rows: messages.slice(0, limit), limited: rows.length > limit, runtime };
137
151
  }
138
152
  catch (error) {
139
153
  throw withStorePath(error, store);
@@ -142,6 +156,72 @@ function readMessages(piboSessionId, store, limit) {
142
156
  db.close();
143
157
  }
144
158
  }
159
+ function readPersistedMessages(db, store, piboSessionId, limit) {
160
+ if (!tableExists(db, "chat_messages"))
161
+ return { rows: [], limited: false };
162
+ const sourceRows = db.prepare(`
163
+ SELECT id, sequence, turn_id, role, created_at, content_preview, content_payload_ref, source_stream_id, attributes_json
164
+ FROM chat_messages
165
+ WHERE session_id = ? AND role IN ('user', 'assistant', 'system')
166
+ ORDER BY sequence ASC
167
+ LIMIT ?
168
+ `).all(piboSessionId, limit + 1);
169
+ if (sourceRows.length === 0)
170
+ return { rows: [], limited: false };
171
+ const payloadStore = createDebugPayloadStore(db, store);
172
+ const rows = sourceRows.slice(0, limit).map((row, index) => {
173
+ const attributes = parseAttributes(row.attributes_json);
174
+ let content = typeof attributes.inlineText === "string" ? attributes.inlineText : row.content_preview ?? "";
175
+ let previewOnly = typeof attributes.inlineText !== "string";
176
+ if (row.content_payload_ref && payloadStore) {
177
+ try {
178
+ content = payloadStore.readPayloadText(row.content_payload_ref);
179
+ previewOnly = false;
180
+ }
181
+ catch {
182
+ // Keep the stored preview.
183
+ }
184
+ }
185
+ const preview = sliceTextByBytes(content, { maxBytes: 200 }, 200).text;
186
+ return {
187
+ idx: index + 1,
188
+ role: row.role,
189
+ streamId: row.source_stream_id ?? row.sequence,
190
+ eventId: row.turn_id ?? undefined,
191
+ createdAt: row.created_at,
192
+ contentBytes: byteLength(content),
193
+ preview,
194
+ previewOnly,
195
+ source: {
196
+ store: "chat",
197
+ table: "chat_messages",
198
+ rowSelector: { id: row.id },
199
+ path: row.content_payload_ref ? "content_payload_ref" : typeof attributes.inlineText === "string" ? "attributes_json.inlineText" : "content_preview",
200
+ kind: "message",
201
+ byteLength: byteLength(content),
202
+ },
203
+ content,
204
+ rawEvent: { ...row, attributes_json: attributes },
205
+ };
206
+ });
207
+ return { rows, limited: sourceRows.length > limit };
208
+ }
209
+ function parseAttributes(value) {
210
+ try {
211
+ const parsed = JSON.parse(value);
212
+ return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
213
+ }
214
+ catch {
215
+ return {};
216
+ }
217
+ }
218
+ function formatRuntimeIdentity(result) {
219
+ return [
220
+ result.runtimeInstanceId ? `runtimeInstanceId: ${result.runtimeInstanceId}` : undefined,
221
+ result.runtimeAdapterId ? `runtimeAdapterId: ${result.runtimeAdapterId}` : undefined,
222
+ result.runtimeBindingState ? `runtimeBindingState: ${result.runtimeBindingState}` : undefined,
223
+ ].filter((value) => Boolean(value));
224
+ }
145
225
  function selectMessage(messages, selector) {
146
226
  if (selector === "last")
147
227
  return messages[messages.length - 1];
@@ -0,0 +1,31 @@
1
+ import { dirname, join } from "node:path";
2
+ import { PayloadStore } from "../data/payload-store.js";
3
+ import { eventAttributes } from "./payloads.js";
4
+ export function createDebugPayloadStore(db, store) {
5
+ const table = db.prepare("SELECT name FROM sqlite_schema WHERE type = 'table' AND name = 'payloads'").get();
6
+ if (!table)
7
+ return undefined;
8
+ return new PayloadStore(db, join(dirname(store.path), "payloads"));
9
+ }
10
+ export function hydrateDebugEventRow(row, payloadStore) {
11
+ if (!row.payload_ref || !payloadStore)
12
+ return row;
13
+ const attributes = eventAttributes(row);
14
+ if (attributes.inlinePayload !== undefined)
15
+ return row;
16
+ try {
17
+ const metadata = payloadStore.getPayload(row.payload_ref);
18
+ if (!metadata)
19
+ return row;
20
+ const inlinePayload = metadata.contentType.includes("json")
21
+ ? payloadStore.readPayloadJson(row.payload_ref)
22
+ : payloadStore.readPayloadText(row.payload_ref);
23
+ return {
24
+ ...row,
25
+ attributes_json: JSON.stringify({ ...attributes, inlinePayload }),
26
+ };
27
+ }
28
+ catch {
29
+ return row;
30
+ }
31
+ }