@pasko70/pibo 3.0.1 → 3.1.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/README.md +20 -6
- package/compute-image/Dockerfile +47 -0
- package/compute-image/Dockerfile.dockerignore +5 -0
- package/dist/agent-runtime/context-build.js +26 -2
- package/dist/agent-runtime/contract.js +78 -28
- package/dist/agent-runtime/portable-history.js +19 -9
- package/dist/agent-runtime/registry.js +8 -2
- package/dist/agent-runtime/routed-session.js +120 -15
- package/dist/agent-runtimes/codex-native/adapter.js +12 -0
- package/dist/agent-runtimes/codex-native/resource-delivery.js +35 -7
- package/dist/agent-runtimes/omp/adapter.js +3 -7
- package/dist/agent-runtimes/pi/adapter.js +5 -3
- package/dist/agent-runtimes/pi/routed-session.js +59 -12
- package/dist/agent-runtimes/pi/runtime.js +6 -0
- package/dist/apps/chat/agent-profiles.js +31 -2
- package/dist/apps/chat/agent-store.js +98 -6
- package/dist/apps/chat/chat-request-normalizers.js +31 -0
- package/dist/apps/chat/data/chat-data-mappers.js +61 -11
- package/dist/apps/chat/data/project-service.js +119 -15
- package/dist/apps/chat/data/room-service.js +21 -0
- package/dist/apps/chat/data/session-query-service.js +33 -10
- package/dist/apps/chat/data/timeline-query-service.js +60 -35
- package/dist/apps/chat/loop-api.js +10 -2
- package/dist/apps/chat/output-compactor.js +144 -21
- package/dist/apps/chat/output-event-policy.js +179 -2
- package/dist/apps/chat/stream.js +16 -7
- package/dist/apps/chat/trace-v2.js +1 -0
- package/dist/apps/chat/web-app.js +317 -86
- package/dist/apps/chat-ui/assets/{dist-BDIATCQt.js → dist-CUQJqggN.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-mqCviI-c.js → dist-ClUlQWYN.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-JnW4v8UE.js → dist-Djul9BmZ.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-lRiLP9rr.js → dist-GD0JGdCi.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-BBDMeU5-.js → dist-W5HOqHym.js} +1 -1
- package/dist/apps/chat-ui/assets/index-BcjkX-iP.js +228 -0
- package/dist/apps/chat-ui/assets/index-CmqRSbBU.css +1 -0
- package/dist/apps/chat-ui/index.html +2 -2
- package/dist/apps/chat-vscode-web/assets/index-JvrPUGvI.js +43 -0
- package/dist/apps/chat-vscode-web/index.html +1 -1
- package/dist/apps/cli-ui/InkSessionApp.js +111 -12
- package/dist/apps/cli-ui/cliSessionsCommand.js +34 -8
- package/dist/cli-session/localSessionSource.js +153 -161
- package/dist/cli.js +7 -11
- package/dist/compute/cli.js +35 -16
- package/dist/compute/docker.js +341 -94
- package/dist/config/config.js +3 -0
- package/dist/core/context-build.js +7 -16
- package/dist/core/output-persistence-retry.js +484 -0
- package/dist/core/output-render-sequence.js +331 -0
- package/dist/core/profiles.js +24 -0
- package/dist/core/provider-recovery.js +7 -1
- package/dist/core/session-model.js +37 -1
- package/dist/core/session-router.js +78 -110
- package/dist/data/ingest-service.js +91 -9
- package/dist/data/navigation-store.js +5 -5
- package/dist/data/pibo-store.js +8 -1
- package/dist/data/schema.js +243 -3
- package/dist/data/session-store.js +3 -3
- package/dist/debug/agents.js +91 -89
- package/dist/debug/index.js +46 -2
- package/dist/debug/pty.js +127 -48
- package/dist/gateway/cli.js +4 -0
- package/dist/gateway/web.js +8 -8
- package/dist/local/client.js +3 -2
- package/dist/loops/channel.js +3 -1
- package/dist/loops/cli.js +2 -1
- package/dist/loops/service.js +90 -11
- package/dist/loops/store.js +100 -74
- package/dist/mcp/agent-context.js +13 -26
- package/dist/mcp/commands/info.js +3 -1
- package/dist/mcp/config-command.js +46 -2
- package/dist/mcp/config.js +18 -4
- package/dist/plugins/context-files-store.js +36 -6
- package/dist/plugins/context-files.js +52 -1
- package/dist/plugins/registry.js +2 -0
- package/dist/plugins/user-profile-resources.js +22 -0
- package/dist/previews/base-url.js +34 -0
- package/dist/previews/config.js +2 -32
- package/dist/ralph/store.js +5 -0
- package/dist/reliability/store.js +378 -106
- package/dist/session-ui/terminalRows.js +8 -4
- package/dist/sessions/pibo-data-store.js +145 -0
- package/dist/sessions/store.js +42 -0
- package/dist/setup/cli.js +422 -6
- package/dist/setup/installation-profiles.js +464 -0
- package/dist/shared/deterministic-digest.js +94 -0
- package/dist/shared/trace-engine.js +54 -0
- package/dist/shared/trace-event-projection.js +124 -67
- package/dist/shared/trace-history.js +47 -12
- package/dist/shared/trace-live-reducer.js +23 -4
- package/dist/shared/trace-nodes.js +17 -28
- package/dist/shared/trace-order.js +41 -5
- package/dist/shared/trace-page-merge.js +44 -14
- package/dist/shared/trace-patch-nodes.js +2 -0
- package/dist/shared/trace-subagent-links.js +4 -1
- package/dist/shared/trace-tool-identity.js +15 -8
- package/dist/signals/projector.js +28 -6
- package/dist/subagents/observation-query.js +121 -0
- package/dist/subagents/tool.js +7 -3
- package/dist/tools/agent-browser-leases.js +58 -23
- package/dist/tools/agent-browser-wrapper.js +1 -1
- package/dist/tools/browser-use-leases.js +129 -16
- package/dist/tools/browser-use-wrapper.js +1 -1
- package/dist/tools/index.js +27 -11
- package/dist/tools/python-runtime.js +10 -3
- package/dist/tools/registry.js +1 -1
- package/dist/tools/runtime/node-backend.js +16 -5
- package/dist/tools/runtime/node-worker-source.js +112 -33
- package/dist/tools/runtime/python-backend.js +16 -5
- package/dist/tools/runtime/python-worker-source.js +167 -16
- package/dist/tools/runtime/registry.js +23 -10
- package/dist/user-skills/store.js +0 -1
- package/docs/ops/vscode-extension-release.md +9 -1
- package/npm-shrinkwrap.json +9 -2
- package/package.json +9 -2
- package/scripts/docker-entrypoint.sh +46 -0
- package/scripts/prepare-agent-browser-wrapper.sh +70 -0
- package/scripts/prepare-browser-use-wrapper.sh +255 -0
- package/dist/apps/chat-ui/assets/index-0XOOVxLP.js +0 -228
- package/dist/apps/chat-ui/assets/index-DV7_CgsC.css +0 -1
- package/dist/apps/chat-vscode-web/assets/index-Dtw2Z7jz.js +0 -43
- package/dist/apps/vscode-artifacts/latest.vsix +0 -0
- package/dist/apps/vscode-artifacts/pibo-vscode-ext-3.0.1.vsix +0 -0
package/dist/data/schema.js
CHANGED
|
@@ -1,9 +1,155 @@
|
|
|
1
|
-
export const PIBO_DATA_SCHEMA_VERSION =
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
export const PIBO_DATA_SCHEMA_VERSION = 7;
|
|
2
|
+
const retiredScopeColumn = ["owner", "scope"].join("_");
|
|
3
|
+
const retiredScopeTables = [
|
|
4
|
+
{
|
|
5
|
+
name: "sessions",
|
|
6
|
+
columns: [
|
|
7
|
+
"id", "pi_session_id", "room_id", "root_session_id", "parent_id", "origin_id",
|
|
8
|
+
"channel", "kind", "profile", "active_model_json", "workspace", "title",
|
|
9
|
+
"first_message_preview", "status", "archived_at", "deleted_at", "metadata_json",
|
|
10
|
+
"created_at", "updated_at", "last_activity_at",
|
|
11
|
+
],
|
|
12
|
+
definition: `
|
|
13
|
+
id TEXT PRIMARY KEY,
|
|
14
|
+
pi_session_id TEXT UNIQUE,
|
|
15
|
+
room_id TEXT,
|
|
16
|
+
root_session_id TEXT,
|
|
17
|
+
parent_id TEXT,
|
|
18
|
+
origin_id TEXT,
|
|
19
|
+
channel TEXT NOT NULL,
|
|
20
|
+
kind TEXT NOT NULL,
|
|
21
|
+
profile TEXT NOT NULL,
|
|
22
|
+
active_model_json TEXT,
|
|
23
|
+
workspace TEXT,
|
|
24
|
+
title TEXT NOT NULL DEFAULT 'Untitled Session',
|
|
25
|
+
first_message_preview TEXT,
|
|
26
|
+
status TEXT NOT NULL DEFAULT 'idle',
|
|
27
|
+
archived_at TEXT,
|
|
28
|
+
deleted_at TEXT,
|
|
29
|
+
metadata_json TEXT NOT NULL DEFAULT '{}',
|
|
30
|
+
created_at TEXT NOT NULL,
|
|
31
|
+
updated_at TEXT NOT NULL,
|
|
32
|
+
last_activity_at TEXT NOT NULL
|
|
33
|
+
`,
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
name: "rooms",
|
|
37
|
+
columns: [
|
|
38
|
+
"id", "name", "topic", "type", "parent_room_id", "workspace", "archived_at",
|
|
39
|
+
"retention_policy_id", "metadata_json", "created_at", "updated_at",
|
|
40
|
+
],
|
|
41
|
+
definition: `
|
|
42
|
+
id TEXT PRIMARY KEY,
|
|
43
|
+
name TEXT NOT NULL,
|
|
44
|
+
topic TEXT,
|
|
45
|
+
type TEXT NOT NULL,
|
|
46
|
+
parent_room_id TEXT,
|
|
47
|
+
workspace TEXT,
|
|
48
|
+
archived_at TEXT,
|
|
49
|
+
retention_policy_id TEXT,
|
|
50
|
+
metadata_json TEXT NOT NULL DEFAULT '{}',
|
|
51
|
+
created_at TEXT NOT NULL,
|
|
52
|
+
updated_at TEXT NOT NULL
|
|
53
|
+
`,
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
name: "session_navigation",
|
|
57
|
+
columns: [
|
|
58
|
+
"room_id", "session_id", "root_session_id", "parent_id", "origin_id", "title",
|
|
59
|
+
"profile", "status", "archived_at", "last_activity_at", "last_message_preview",
|
|
60
|
+
"child_count", "sort_key", "updated_at",
|
|
61
|
+
],
|
|
62
|
+
definition: `
|
|
63
|
+
room_id TEXT,
|
|
64
|
+
session_id TEXT PRIMARY KEY,
|
|
65
|
+
root_session_id TEXT,
|
|
66
|
+
parent_id TEXT,
|
|
67
|
+
origin_id TEXT,
|
|
68
|
+
title TEXT NOT NULL,
|
|
69
|
+
profile TEXT NOT NULL,
|
|
70
|
+
status TEXT NOT NULL,
|
|
71
|
+
archived_at TEXT,
|
|
72
|
+
last_activity_at TEXT NOT NULL,
|
|
73
|
+
last_message_preview TEXT,
|
|
74
|
+
child_count INTEGER NOT NULL DEFAULT 0,
|
|
75
|
+
sort_key TEXT NOT NULL,
|
|
76
|
+
updated_at TEXT NOT NULL
|
|
77
|
+
`,
|
|
78
|
+
},
|
|
79
|
+
];
|
|
80
|
+
function retiredScopeTablesToRebuild(db) {
|
|
81
|
+
return retiredScopeTables.filter((table) => ((db.prepare(`SELECT 1 FROM pragma_table_info('${table.name}') WHERE name = ?`).get(retiredScopeColumn)) !== undefined));
|
|
82
|
+
}
|
|
83
|
+
function rebuildRetiredScopeTables(db, tablesToRebuild) {
|
|
84
|
+
for (const table of tablesToRebuild) {
|
|
85
|
+
const replacement = `__pibo_schema_v7_${table.name}`;
|
|
86
|
+
const columnList = table.columns.join(", ");
|
|
87
|
+
db.exec(`
|
|
88
|
+
CREATE TABLE ${replacement} (${table.definition});
|
|
89
|
+
INSERT INTO ${replacement} (${columnList}) SELECT ${columnList} FROM ${table.name};
|
|
90
|
+
DROP TABLE ${table.name};
|
|
91
|
+
ALTER TABLE ${replacement} RENAME TO ${table.name};
|
|
92
|
+
`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
export function assertSupportedPiboDataSchemaVersion(db) {
|
|
96
|
+
const version = Number(db.prepare("PRAGMA user_version").get()?.user_version ?? 0);
|
|
97
|
+
if (version > PIBO_DATA_SCHEMA_VERSION) {
|
|
98
|
+
throw new Error(`Pibo database schema version ${version} is newer than supported version ${PIBO_DATA_SCHEMA_VERSION}`);
|
|
99
|
+
}
|
|
100
|
+
return version;
|
|
101
|
+
}
|
|
102
|
+
export const PIBO_DATA_SCHEMA_MIGRATION_STEPS = [
|
|
103
|
+
"schema",
|
|
104
|
+
"runtime-bindings",
|
|
105
|
+
"render-high-water",
|
|
106
|
+
"sequence-repair-selection",
|
|
107
|
+
"sequence-repair-temporary",
|
|
108
|
+
"sequence-repair-backfill",
|
|
109
|
+
"sequence-repair-cleanup",
|
|
110
|
+
"runtime-binding-metadata",
|
|
111
|
+
"user-version",
|
|
112
|
+
];
|
|
113
|
+
export function applyPiboDataSchema(db, hooks = {}) {
|
|
114
|
+
const previousVersion = assertSupportedPiboDataSchemaVersion(db);
|
|
115
|
+
const tablesToRebuild = retiredScopeTablesToRebuild(db);
|
|
116
|
+
const ownsTransaction = !db.isTransaction;
|
|
117
|
+
if (!ownsTransaction && tablesToRebuild.length > 0) {
|
|
118
|
+
throw new Error("Pibo data schema migration requires an independent transaction");
|
|
119
|
+
}
|
|
120
|
+
const foreignKeysEnabled = ownsTransaction
|
|
121
|
+
&& tablesToRebuild.length > 0
|
|
122
|
+
&& Number(db.prepare("PRAGMA foreign_keys").get().foreign_keys ?? 0) === 1;
|
|
123
|
+
if (foreignKeysEnabled)
|
|
124
|
+
db.exec("PRAGMA foreign_keys = OFF");
|
|
125
|
+
try {
|
|
126
|
+
if (ownsTransaction)
|
|
127
|
+
db.exec("BEGIN IMMEDIATE");
|
|
128
|
+
applyPiboDataSchemaInTransaction(db, hooks, previousVersion, tablesToRebuild);
|
|
129
|
+
if (tablesToRebuild.length > 0) {
|
|
130
|
+
const violations = db.prepare("PRAGMA foreign_key_check").all();
|
|
131
|
+
if (violations.length > 0) {
|
|
132
|
+
throw new Error(`Pibo data schema migration would retain ${violations.length} foreign-key violation(s)`);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
if (ownsTransaction)
|
|
136
|
+
db.exec("COMMIT");
|
|
137
|
+
}
|
|
138
|
+
catch (error) {
|
|
139
|
+
if (ownsTransaction && db.isTransaction)
|
|
140
|
+
db.exec("ROLLBACK");
|
|
141
|
+
throw error;
|
|
142
|
+
}
|
|
143
|
+
finally {
|
|
144
|
+
if (foreignKeysEnabled)
|
|
145
|
+
db.exec("PRAGMA foreign_keys = ON");
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
function applyPiboDataSchemaInTransaction(db, hooks, previousVersion, tablesToRebuild) {
|
|
4
149
|
const existingSessionCount = db.prepare("SELECT COUNT(*) AS count FROM sqlite_schema WHERE type = 'table' AND name = 'sessions'").get();
|
|
5
150
|
const hadSessionsBeforeMigration = existingSessionCount.count > 0
|
|
6
151
|
&& Number(db.prepare("SELECT COUNT(*) AS count FROM sessions").get().count) > 0;
|
|
152
|
+
rebuildRetiredScopeTables(db, tablesToRebuild);
|
|
7
153
|
db.exec(`
|
|
8
154
|
CREATE TABLE IF NOT EXISTS sessions (
|
|
9
155
|
id TEXT PRIMARY KEY,
|
|
@@ -46,6 +192,42 @@ export function applyPiboDataSchema(db) {
|
|
|
46
192
|
FOREIGN KEY (pibo_session_id) REFERENCES sessions(id) ON DELETE CASCADE
|
|
47
193
|
);
|
|
48
194
|
|
|
195
|
+
CREATE TABLE IF NOT EXISTS session_output_render_high_water (
|
|
196
|
+
pibo_session_id TEXT PRIMARY KEY,
|
|
197
|
+
high_water INTEGER NOT NULL CHECK(high_water >= 0),
|
|
198
|
+
updated_at TEXT NOT NULL,
|
|
199
|
+
FOREIGN KEY (pibo_session_id) REFERENCES sessions(id) ON DELETE CASCADE
|
|
200
|
+
);
|
|
201
|
+
|
|
202
|
+
CREATE TABLE IF NOT EXISTS session_tool_invocation_counters (
|
|
203
|
+
pibo_session_id TEXT NOT NULL,
|
|
204
|
+
event_id TEXT NOT NULL,
|
|
205
|
+
tool_call_id TEXT NOT NULL,
|
|
206
|
+
next_ordinal INTEGER NOT NULL CHECK(next_ordinal >= 0),
|
|
207
|
+
updated_at TEXT NOT NULL,
|
|
208
|
+
PRIMARY KEY (pibo_session_id, event_id, tool_call_id),
|
|
209
|
+
FOREIGN KEY (pibo_session_id) REFERENCES sessions(id) ON DELETE CASCADE
|
|
210
|
+
);
|
|
211
|
+
|
|
212
|
+
CREATE TABLE IF NOT EXISTS session_tool_invocations (
|
|
213
|
+
pibo_session_id TEXT NOT NULL,
|
|
214
|
+
event_id TEXT NOT NULL,
|
|
215
|
+
tool_call_id TEXT NOT NULL,
|
|
216
|
+
invocation_ordinal INTEGER NOT NULL CHECK(invocation_ordinal >= 0),
|
|
217
|
+
call_fingerprint TEXT,
|
|
218
|
+
status TEXT NOT NULL CHECK(status IN ('open', 'closed')),
|
|
219
|
+
seen_call INTEGER NOT NULL DEFAULT 0 CHECK(seen_call IN (0, 1)),
|
|
220
|
+
seen_started INTEGER NOT NULL DEFAULT 0 CHECK(seen_started IN (0, 1)),
|
|
221
|
+
seen_updated INTEGER NOT NULL DEFAULT 0 CHECK(seen_updated IN (0, 1)),
|
|
222
|
+
seen_finished INTEGER NOT NULL DEFAULT 0 CHECK(seen_finished IN (0, 1)),
|
|
223
|
+
created_at TEXT NOT NULL,
|
|
224
|
+
updated_at TEXT NOT NULL,
|
|
225
|
+
PRIMARY KEY (pibo_session_id, event_id, tool_call_id, invocation_ordinal),
|
|
226
|
+
FOREIGN KEY (pibo_session_id) REFERENCES sessions(id) ON DELETE CASCADE
|
|
227
|
+
);
|
|
228
|
+
CREATE INDEX IF NOT EXISTS idx_session_tool_invocations_open
|
|
229
|
+
ON session_tool_invocations(pibo_session_id, event_id, tool_call_id, status, invocation_ordinal DESC);
|
|
230
|
+
|
|
49
231
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_session_runtime_bindings_native
|
|
50
232
|
ON session_runtime_bindings(runtime_adapter_id, native_session_id)
|
|
51
233
|
WHERE native_session_id IS NOT NULL;
|
|
@@ -516,6 +698,7 @@ export function applyPiboDataSchema(db) {
|
|
|
516
698
|
CREATE INDEX IF NOT EXISTS idx_telemetry_tool_calls_retention_updated
|
|
517
699
|
ON telemetry_tool_calls(retention_class, updated_at);
|
|
518
700
|
`);
|
|
701
|
+
hooks.afterStep?.("schema");
|
|
519
702
|
db.exec(`
|
|
520
703
|
INSERT OR IGNORE INTO session_runtime_bindings (
|
|
521
704
|
pibo_session_id, runtime_instance_id, runtime_adapter_id, native_session_id,
|
|
@@ -536,6 +719,61 @@ export function applyPiboDataSchema(db) {
|
|
|
536
719
|
WHERE existing.pibo_session_id = sessions.id
|
|
537
720
|
);
|
|
538
721
|
`);
|
|
722
|
+
hooks.afterStep?.("runtime-bindings");
|
|
723
|
+
db.exec(`
|
|
724
|
+
INSERT INTO session_output_render_high_water (pibo_session_id, high_water, updated_at)
|
|
725
|
+
SELECT
|
|
726
|
+
id,
|
|
727
|
+
CAST(json_extract(metadata_json, '$.outputRenderSequenceHighWater') AS INTEGER),
|
|
728
|
+
updated_at
|
|
729
|
+
FROM sessions
|
|
730
|
+
WHERE json_type(metadata_json, '$.outputRenderSequenceHighWater') IN ('integer', 'real')
|
|
731
|
+
AND CAST(json_extract(metadata_json, '$.outputRenderSequenceHighWater') AS INTEGER) >= 0
|
|
732
|
+
ON CONFLICT(pibo_session_id) DO UPDATE SET
|
|
733
|
+
high_water = MAX(session_output_render_high_water.high_water, excluded.high_water),
|
|
734
|
+
updated_at = CASE
|
|
735
|
+
WHEN excluded.high_water > session_output_render_high_water.high_water THEN excluded.updated_at
|
|
736
|
+
ELSE session_output_render_high_water.updated_at
|
|
737
|
+
END;
|
|
738
|
+
`);
|
|
739
|
+
hooks.afterStep?.("render-high-water");
|
|
740
|
+
// Always inspect for interrupted pre-atomic v7 repairs. A previous process
|
|
741
|
+
// may have written negative temporary values before setting user_version.
|
|
742
|
+
db.exec(`
|
|
743
|
+
DROP TABLE IF EXISTS temp.pibo_v7_sequence_repair_sessions;
|
|
744
|
+
CREATE TEMP TABLE pibo_v7_sequence_repair_sessions (
|
|
745
|
+
session_id TEXT PRIMARY KEY
|
|
746
|
+
);
|
|
747
|
+
INSERT INTO pibo_v7_sequence_repair_sessions (session_id)
|
|
748
|
+
SELECT DISTINCT session_id
|
|
749
|
+
FROM event_log
|
|
750
|
+
WHERE session_id IS NOT NULL
|
|
751
|
+
AND (session_sequence IS NULL OR session_sequence <= 0);
|
|
752
|
+
`);
|
|
753
|
+
hooks.afterStep?.("sequence-repair-selection");
|
|
754
|
+
db.exec(`
|
|
755
|
+
UPDATE event_log
|
|
756
|
+
SET session_sequence = -stream_id
|
|
757
|
+
WHERE session_id IN (SELECT session_id FROM pibo_v7_sequence_repair_sessions);
|
|
758
|
+
`);
|
|
759
|
+
hooks.afterStep?.("sequence-repair-temporary");
|
|
760
|
+
db.exec(`
|
|
761
|
+
WITH ranked AS (
|
|
762
|
+
SELECT
|
|
763
|
+
stream_id,
|
|
764
|
+
ROW_NUMBER() OVER (PARTITION BY session_id ORDER BY stream_id ASC) AS repaired_sequence
|
|
765
|
+
FROM event_log
|
|
766
|
+
WHERE session_id IN (SELECT session_id FROM pibo_v7_sequence_repair_sessions)
|
|
767
|
+
)
|
|
768
|
+
UPDATE event_log
|
|
769
|
+
SET session_sequence = (
|
|
770
|
+
SELECT repaired_sequence FROM ranked WHERE ranked.stream_id = event_log.stream_id
|
|
771
|
+
)
|
|
772
|
+
WHERE stream_id IN (SELECT stream_id FROM ranked);
|
|
773
|
+
`);
|
|
774
|
+
hooks.afterStep?.("sequence-repair-backfill");
|
|
775
|
+
db.exec("DROP TABLE pibo_v7_sequence_repair_sessions");
|
|
776
|
+
hooks.afterStep?.("sequence-repair-cleanup");
|
|
539
777
|
if (previousVersion < PIBO_DATA_SCHEMA_VERSION && hadSessionsBeforeMigration) {
|
|
540
778
|
const rows = db.prepare("SELECT pibo_session_id, metadata_json FROM session_runtime_bindings").all();
|
|
541
779
|
const update = db.prepare("UPDATE session_runtime_bindings SET metadata_json = ? WHERE pibo_session_id = ?");
|
|
@@ -558,5 +796,7 @@ export function applyPiboDataSchema(db) {
|
|
|
558
796
|
}), row.pibo_session_id);
|
|
559
797
|
}
|
|
560
798
|
}
|
|
799
|
+
hooks.afterStep?.("runtime-binding-metadata");
|
|
561
800
|
db.exec(`PRAGMA user_version = ${PIBO_DATA_SCHEMA_VERSION}`);
|
|
801
|
+
hooks.afterStep?.("user-version");
|
|
562
802
|
}
|
|
@@ -43,10 +43,10 @@ export class SessionStore {
|
|
|
43
43
|
"workspace = excluded.workspace",
|
|
44
44
|
"title = excluded.title",
|
|
45
45
|
"first_message_preview = COALESCE(sessions.first_message_preview, excluded.first_message_preview)",
|
|
46
|
-
"status = excluded.status",
|
|
46
|
+
...(input.status === undefined ? [] : ["status = excluded.status"]),
|
|
47
47
|
"metadata_json = excluded.metadata_json",
|
|
48
|
-
"updated_at = excluded.updated_at",
|
|
49
|
-
"last_activity_at = excluded.last_activity_at",
|
|
48
|
+
"updated_at = MAX(sessions.updated_at, excluded.updated_at)",
|
|
49
|
+
"last_activity_at = MAX(sessions.last_activity_at, excluded.last_activity_at)",
|
|
50
50
|
];
|
|
51
51
|
this.db.prepare(`
|
|
52
52
|
INSERT INTO sessions (${baseColumns.join(", ")})
|
package/dist/debug/agents.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { normalizePiboAgentObservationLimit, piboAgentObservationDetails, piboAgentObservationKind, piboAgentObservationRole, piboAgentObservationText, } from "../subagents/observations.js";
|
|
2
|
+
import { preparePiboAgentObservationQuery, selectPiboAgentObservationPage, } from "../subagents/observation-query.js";
|
|
2
3
|
import { createDebugPayloadStore, hydrateDebugEventRow } from "./persisted-payloads.js";
|
|
3
4
|
import { eventAttributes, eventPayload } from "./payloads.js";
|
|
4
5
|
import { openReadOnlyDebugDatabase, withStorePath } from "./sql.js";
|
|
@@ -36,17 +37,21 @@ export async function runDebugAgentsCli(args) {
|
|
|
36
37
|
return;
|
|
37
38
|
}
|
|
38
39
|
const result = inspectDebugAgentObservations(parentPiboSessionId, store, {
|
|
40
|
+
toolCallIds: parsed.toolCallIds.length ? parsed.toolCallIds : undefined,
|
|
39
41
|
agentIds: parsed.agentIds.length ? parsed.agentIds : undefined,
|
|
40
42
|
names: parsed.names.length ? parsed.names : undefined,
|
|
41
43
|
threadKeys: parsed.threadKeys.length ? parsed.threadKeys : undefined,
|
|
42
44
|
eventTypes: parsed.eventTypes.length ? parsed.eventTypes : undefined,
|
|
43
45
|
kinds: parsed.kinds.length ? parsed.kinds : undefined,
|
|
46
|
+
roles: parsed.roles.length ? parsed.roles : undefined,
|
|
44
47
|
since: parsed.since,
|
|
45
48
|
until: parsed.until,
|
|
46
49
|
textContains: parsed.textContains,
|
|
47
50
|
afterSequence: parsed.afterSequence,
|
|
48
51
|
order: parsed.order,
|
|
49
52
|
limit: parsed.limit,
|
|
53
|
+
includeTools: parsed.includeTools || undefined,
|
|
54
|
+
toolDetail: parsed.toolDetail,
|
|
50
55
|
includeDetails: parsed.details,
|
|
51
56
|
});
|
|
52
57
|
if (parsed.json)
|
|
@@ -75,104 +80,70 @@ export function inspectDebugAgentObservations(parentPiboSessionId, store, input
|
|
|
75
80
|
throw new Error(`Debug store "pibo-data" not found at ${store.path}`);
|
|
76
81
|
const db = openReadOnlyDebugDatabase(store);
|
|
77
82
|
try {
|
|
78
|
-
const
|
|
79
|
-
const limit = normalizePiboAgentObservationLimit(input.limit);
|
|
80
|
-
const afterSequence = normalizePiboAgentObservationCursor(input.afterSequence);
|
|
81
|
-
const since = parsePiboAgentObservationTimestamp(input.since, "since");
|
|
82
|
-
const until = parsePiboAgentObservationTimestamp(input.until, "until");
|
|
83
|
-
if (since !== undefined && until !== undefined && since > until)
|
|
84
|
-
throw new Error("Agent observation since must not be after until.");
|
|
83
|
+
const query = preparePiboAgentObservationQuery(input);
|
|
85
84
|
const owned = readOwnedAgents(db, parentPiboSessionId);
|
|
86
85
|
const ownedById = new Map(owned.map((agent) => [agent.agentId, agent]));
|
|
87
86
|
for (const agentId of input.agentIds ?? []) {
|
|
88
87
|
if (!ownedById.has(agentId))
|
|
89
88
|
throw new Error(`Agent "${agentId}" is not owned by Pibo session "${parentPiboSessionId}".`);
|
|
90
89
|
}
|
|
91
|
-
const agentIds = input.agentIds ? new Set(input.agentIds) : undefined;
|
|
92
|
-
const names = input.names ? new Set(input.names) : undefined;
|
|
93
|
-
const threadKeys = input.threadKeys ? new Set(input.threadKeys) : undefined;
|
|
94
|
-
const eventTypes = input.eventTypes ? new Set(input.eventTypes) : undefined;
|
|
95
|
-
const kinds = input.kinds ? new Set(input.kinds) : undefined;
|
|
96
90
|
const payloadStore = createDebugPayloadStore(db, store);
|
|
97
91
|
const clauses = ["s.parent_id = ?", "s.channel = 'pibo.subagents'", "s.kind = 'subagent'", "s.deleted_at IS NULL"];
|
|
98
92
|
const values = [parentPiboSessionId];
|
|
99
|
-
if (afterSequence !== undefined) {
|
|
93
|
+
if (query.afterSequence !== undefined) {
|
|
100
94
|
clauses.push("e.stream_id > ?");
|
|
101
|
-
values.push(afterSequence);
|
|
95
|
+
values.push(query.afterSequence);
|
|
96
|
+
}
|
|
97
|
+
if (query.scanEventTypes && query.scanEventTypes.length > 0) {
|
|
98
|
+
clauses.push(`e.type IN (${query.scanEventTypes.map(() => "?").join(", ")})`);
|
|
99
|
+
values.push(...query.scanEventTypes);
|
|
102
100
|
}
|
|
103
|
-
const scanOrder = afterSequence !== undefined ? "ASC" : order.toUpperCase();
|
|
104
101
|
const statement = db.prepare(`
|
|
105
102
|
SELECT e.stream_id, e.session_id, e.session_sequence, e.event_id, e.type, e.created_at,
|
|
106
103
|
e.payload_ref, e.preview_text, e.attributes_json, s.profile, s.metadata_json
|
|
107
104
|
FROM event_log e
|
|
108
105
|
JOIN sessions s ON s.id = e.session_id
|
|
109
106
|
WHERE ${clauses.join(" AND ")}
|
|
110
|
-
ORDER BY e.stream_id ${scanOrder}
|
|
107
|
+
ORDER BY e.stream_id ${query.scanOrder.toUpperCase()}
|
|
111
108
|
`);
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
if (textContains && !(text ?? "").toLowerCase().includes(textContains))
|
|
140
|
-
continue;
|
|
141
|
-
const role = piboAgentObservationRole(source);
|
|
142
|
-
matches.push({
|
|
143
|
-
streamId: row.stream_id,
|
|
144
|
-
createdAt: row.created_at,
|
|
145
|
-
agentId: agent.agentId,
|
|
146
|
-
name: agent.name,
|
|
147
|
-
...(agent.threadKey ? { threadKey: agent.threadKey } : {}),
|
|
148
|
-
eventType: row.type,
|
|
149
|
-
kind,
|
|
150
|
-
...(role ? { role } : {}),
|
|
151
|
-
...(text ? { text } : {}),
|
|
152
|
-
...(typeof payload.toolName === "string" ? { toolName: payload.toolName } : {}),
|
|
153
|
-
...(typeof payload.toolCallId === "string" ? { toolCallId: payload.toolCallId } : {}),
|
|
154
|
-
...(row.type === "tool_execution_finished" ? { isError: payload.isError === true } : row.type === "session_error" ? { isError: true } : {}),
|
|
155
|
-
...(input.includeDetails === true ? { details: piboAgentObservationDetails(debugAgentObservationDetails(row, payload)) } : {}),
|
|
156
|
-
});
|
|
157
|
-
if (matches.length > limit)
|
|
158
|
-
break;
|
|
109
|
+
function* normalizedObservations() {
|
|
110
|
+
for (const rawRow of statement.iterate(...values)) {
|
|
111
|
+
const agent = ownedById.get(rawRow.session_id ?? "");
|
|
112
|
+
if (!agent)
|
|
113
|
+
continue;
|
|
114
|
+
const row = hydrateDebugEventRow(rawRow, payloadStore);
|
|
115
|
+
const attributes = eventAttributes(row);
|
|
116
|
+
const payload = { ...attributes, ...eventPayload(row) };
|
|
117
|
+
const source = debugAgentObservationSource(row, attributes);
|
|
118
|
+
const text = piboAgentObservationText(source);
|
|
119
|
+
const role = piboAgentObservationRole(source);
|
|
120
|
+
yield {
|
|
121
|
+
sequence: row.stream_id,
|
|
122
|
+
createdAt: row.created_at,
|
|
123
|
+
agentId: agent.agentId,
|
|
124
|
+
name: agent.name,
|
|
125
|
+
...(agent.threadKey ? { threadKey: agent.threadKey } : {}),
|
|
126
|
+
eventType: row.type,
|
|
127
|
+
kind: piboAgentObservationKind(row.type),
|
|
128
|
+
...(role ? { role } : {}),
|
|
129
|
+
...(text ? { text } : {}),
|
|
130
|
+
...(typeof payload.toolName === "string" ? { toolName: payload.toolName } : {}),
|
|
131
|
+
...(typeof payload.toolCallId === "string" ? { toolCallId: payload.toolCallId } : {}),
|
|
132
|
+
...(row.type === "tool_execution_finished" ? { isError: payload.isError === true } : row.type === "session_error" ? { isError: true } : {}),
|
|
133
|
+
details: piboAgentObservationDetails(debugAgentObservationDetails(row, payload, source)),
|
|
134
|
+
};
|
|
135
|
+
}
|
|
159
136
|
}
|
|
160
|
-
const
|
|
161
|
-
const observations = matches.slice(0, limit);
|
|
162
|
-
if (afterSequence !== undefined && order === "desc")
|
|
163
|
-
observations.reverse();
|
|
137
|
+
const page = selectPiboAgentObservationPage(normalizedObservations(), query);
|
|
164
138
|
return {
|
|
165
139
|
parentPiboSessionId,
|
|
166
|
-
filters:
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
observations,
|
|
174
|
-
nextAfterSequence: observations.reduce((maximum, observation) => Math.max(maximum, observation.streamId), afterSequence ?? 0),
|
|
175
|
-
truncated,
|
|
140
|
+
filters: page.filters,
|
|
141
|
+
observations: page.observations.map(({ sequence, ...observation }) => ({
|
|
142
|
+
streamId: sequence,
|
|
143
|
+
...observation,
|
|
144
|
+
})),
|
|
145
|
+
nextAfterSequence: page.nextAfterSequence,
|
|
146
|
+
truncated: page.truncated,
|
|
176
147
|
};
|
|
177
148
|
}
|
|
178
149
|
catch (error) {
|
|
@@ -237,12 +208,15 @@ function debugAgentObservationSource(row, attributes) {
|
|
|
237
208
|
source.subagentName = attributes.subagentName;
|
|
238
209
|
return source;
|
|
239
210
|
}
|
|
240
|
-
function debugAgentObservationDetails(row, payload) {
|
|
211
|
+
function debugAgentObservationDetails(row, payload, source) {
|
|
241
212
|
return {
|
|
242
213
|
type: row.type,
|
|
243
214
|
...(row.session_id ? { piboSessionId: row.session_id } : {}),
|
|
244
215
|
...(row.event_id ? { eventId: row.event_id } : {}),
|
|
245
216
|
...payload,
|
|
217
|
+
...(source.args !== undefined ? { args: source.args } : {}),
|
|
218
|
+
...(source.partialResult !== undefined ? { partialResult: source.partialResult } : {}),
|
|
219
|
+
...(source.result !== undefined ? { result: source.result } : {}),
|
|
246
220
|
};
|
|
247
221
|
}
|
|
248
222
|
function parseObject(value) {
|
|
@@ -306,17 +280,31 @@ Filters use exact values. The command inspects only direct pibo.subagents childr
|
|
|
306
280
|
console.log(`pibo debug agents ${parentPiboSessionId} observe
|
|
307
281
|
|
|
308
282
|
Usage:
|
|
309
|
-
pibo debug agents ${parentPiboSessionId} observe [--agent-id ps_...] [--name name]
|
|
310
|
-
[--event-type type] [--kind message|thinking|tool|error|lifecycle|event]
|
|
311
|
-
[--since iso] [--until iso] [--contains text] [--after-sequence n]
|
|
312
|
-
[--order asc|desc] [--limit 1..200] [--
|
|
283
|
+
pibo debug agents ${parentPiboSessionId} observe [--tool-call-id id] [--agent-id ps_...] [--name name]
|
|
284
|
+
[--thread-key key] [--event-type type] [--kind message|thinking|tool|error|lifecycle|event]
|
|
285
|
+
[--role role] [--since iso] [--until iso] [--contains text] [--after-sequence n]
|
|
286
|
+
[--order asc|desc] [--limit 1..200] [--include-tools]
|
|
287
|
+
[--tool-detail summary|full] [--details] [--json]
|
|
313
288
|
|
|
314
|
-
|
|
289
|
+
Default: the newest 20 completed assistant messages, with streaming deltas and tools hidden.
|
|
290
|
+
Use --include-tools for compact tool calls and terminal results. Explicit --event-type or --kind
|
|
291
|
+
filters retain access to progress events. Repeat plural filters for OR within that field.
|
|
315
292
|
Different fields combine with AND. With --after-sequence, pages always consume the oldest unseen rows;
|
|
316
293
|
--order desc reverses only the returned page, so nextAfterSequence remains safe for polling.`);
|
|
317
294
|
}
|
|
318
295
|
function parseAgentDebugOptions(args) {
|
|
319
|
-
const parsed = {
|
|
296
|
+
const parsed = {
|
|
297
|
+
json: false,
|
|
298
|
+
details: false,
|
|
299
|
+
includeTools: false,
|
|
300
|
+
toolCallIds: [],
|
|
301
|
+
agentIds: [],
|
|
302
|
+
names: [],
|
|
303
|
+
threadKeys: [],
|
|
304
|
+
eventTypes: [],
|
|
305
|
+
kinds: [],
|
|
306
|
+
roles: [],
|
|
307
|
+
};
|
|
320
308
|
for (let index = 0; index < args.length; index += 1) {
|
|
321
309
|
const arg = args[index];
|
|
322
310
|
if (arg === "--json") {
|
|
@@ -327,10 +315,16 @@ function parseAgentDebugOptions(args) {
|
|
|
327
315
|
parsed.details = true;
|
|
328
316
|
continue;
|
|
329
317
|
}
|
|
318
|
+
if (arg === "--include-tools") {
|
|
319
|
+
parsed.includeTools = true;
|
|
320
|
+
continue;
|
|
321
|
+
}
|
|
330
322
|
const value = args[index + 1];
|
|
331
323
|
if (!value)
|
|
332
324
|
throw new Error(`${arg} requires a value`);
|
|
333
|
-
if (arg === "--
|
|
325
|
+
if (arg === "--tool-call-id")
|
|
326
|
+
parsed.toolCallIds.push(value);
|
|
327
|
+
else if (arg === "--agent-id")
|
|
334
328
|
parsed.agentIds.push(value);
|
|
335
329
|
else if (arg === "--name")
|
|
336
330
|
parsed.names.push(value);
|
|
@@ -343,6 +337,8 @@ function parseAgentDebugOptions(args) {
|
|
|
343
337
|
throw new Error(`Invalid --kind "${value}"`);
|
|
344
338
|
parsed.kinds.push(value);
|
|
345
339
|
}
|
|
340
|
+
else if (arg === "--role")
|
|
341
|
+
parsed.roles.push(value);
|
|
346
342
|
else if (arg === "--status") {
|
|
347
343
|
if (!["running", "idle", "killed"].includes(value))
|
|
348
344
|
throw new Error(`Invalid --status "${value}"`);
|
|
@@ -363,6 +359,11 @@ function parseAgentDebugOptions(args) {
|
|
|
363
359
|
}
|
|
364
360
|
else if (arg === "--limit")
|
|
365
361
|
parsed.limit = normalizePiboAgentObservationLimit(parseNonNegativeInteger(value, arg));
|
|
362
|
+
else if (arg === "--tool-detail") {
|
|
363
|
+
if (value !== "summary" && value !== "full")
|
|
364
|
+
throw new Error(`Invalid --tool-detail "${value}"`);
|
|
365
|
+
parsed.toolDetail = value;
|
|
366
|
+
}
|
|
366
367
|
else
|
|
367
368
|
throw new Error(`Unknown pibo debug agents option "${arg}"`);
|
|
368
369
|
index += 1;
|
|
@@ -373,10 +374,11 @@ function validateAgentDebugOptions(command, parsed) {
|
|
|
373
374
|
if (command === "list") {
|
|
374
375
|
if (parsed.names.length > 1)
|
|
375
376
|
throw new Error("pibo debug agents list accepts at most one --name value");
|
|
376
|
-
if (parsed.details || parsed.
|
|
377
|
-
|| parsed.
|
|
377
|
+
if (parsed.details || parsed.includeTools || parsed.toolCallIds.length > 0 || parsed.agentIds.length > 0
|
|
378
|
+
|| parsed.threadKeys.length > 0 || parsed.eventTypes.length > 0 || parsed.kinds.length > 0
|
|
379
|
+
|| parsed.roles.length > 0 || parsed.since !== undefined || parsed.until !== undefined
|
|
378
380
|
|| parsed.textContains !== undefined || parsed.afterSequence !== undefined || parsed.order !== undefined
|
|
379
|
-
|| parsed.limit !== undefined)
|
|
381
|
+
|| parsed.limit !== undefined || parsed.toolDetail !== undefined)
|
|
380
382
|
throw new Error("Unsupported option for pibo debug agents list. Run the list command with --help.");
|
|
381
383
|
return;
|
|
382
384
|
}
|