@pasko70/pibo 2.2.5 → 2.3.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/dist/agent-runtime/context-build.js +5 -2
- package/dist/agent-runtimes/pi/adapter.js +1 -1
- package/dist/agent-runtimes/pi/runtime.js +25 -16
- package/dist/apps/chat-ui/assets/{dist-BK7eaoLT.js → dist-Byygd1lH.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-fNgdnmyE.js → dist-C9BrS7sL.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-wq3P0LZj.js → dist-CUcAofmV.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-BCRR_a0Z.js → dist-D4RU6xu3.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-CTUT484B.js → dist-DusFwy0L.js} +1 -1
- package/dist/apps/chat-ui/assets/{index-DsFKL_EZ.js → index-Bifi_kjN.js} +90 -90
- package/dist/apps/chat-ui/index.html +1 -1
- package/dist/apps/chat-vscode-web/assets/{index-R4FTxr78.js → index-WsLm1mo3.js} +5 -5
- package/dist/apps/chat-vscode-web/index.html +1 -1
- package/dist/apps/vscode-artifacts/latest.vsix +0 -0
- package/dist/apps/vscode-artifacts/{pibo-vscode-ext-2.2.5.vsix → pibo-vscode-ext-2.3.0.vsix} +0 -0
- package/dist/core/codex-compat.js +1 -3
- package/dist/core/context-build.js +16 -7
- package/dist/core/session-router.js +221 -45
- package/dist/data/ingest-service.js +12 -0
- package/dist/debug/agents.js +391 -0
- package/dist/debug/index.js +7 -0
- package/dist/index.js +1 -1
- package/dist/session-ui/delegation.js +4 -2
- package/dist/shared/trace-async-agent-runs.js +4 -2
- package/dist/shared/trace-event-projection.js +8 -2
- package/dist/shared/trace-subagent-links.js +19 -6
- package/dist/subagents/observations.js +149 -0
- package/dist/subagents/tool.js +177 -46
- package/dist/tools/session-service.js +1 -0
- package/dist/tools/session-tool-set.js +9 -5
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
|
@@ -0,0 +1,391 @@
|
|
|
1
|
+
import { normalizePiboAgentObservationCursor, normalizePiboAgentObservationLimit, normalizePiboAgentObservationOrder, parsePiboAgentObservationTimestamp, piboAgentObservationDetails, piboAgentObservationKind, piboAgentObservationRole, piboAgentObservationText, } from "../subagents/observations.js";
|
|
2
|
+
import { createDebugPayloadStore, hydrateDebugEventRow } from "./persisted-payloads.js";
|
|
3
|
+
import { eventAttributes, eventPayload } from "./payloads.js";
|
|
4
|
+
import { openReadOnlyDebugDatabase, withStorePath } from "./sql.js";
|
|
5
|
+
import { resolveDebugStore } from "./stores.js";
|
|
6
|
+
export async function runDebugAgentsCli(args) {
|
|
7
|
+
if (args.length === 0 || args[0] === "--help" || args[0] === "-h") {
|
|
8
|
+
printDebugAgentsDiscovery();
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
const parentPiboSessionId = args[0];
|
|
12
|
+
const command = args[1];
|
|
13
|
+
if (!command || command === "--help" || command === "-h") {
|
|
14
|
+
printDebugAgentsDiscovery(parentPiboSessionId);
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
if (command !== "list" && command !== "observe") {
|
|
18
|
+
throw new Error(`Unknown pibo debug agents command "${command}". Run pibo debug agents ${parentPiboSessionId} --help.`);
|
|
19
|
+
}
|
|
20
|
+
if (args.slice(2).some((arg) => arg === "--help" || arg === "-h")) {
|
|
21
|
+
printDebugAgentsCommandHelp(parentPiboSessionId, command);
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
const parsed = parseAgentDebugOptions(args.slice(2));
|
|
25
|
+
validateAgentDebugOptions(command, parsed);
|
|
26
|
+
const store = resolveDebugStore("pibo-data");
|
|
27
|
+
if (command === "list") {
|
|
28
|
+
const agents = inspectDebugAgentList(parentPiboSessionId, store, {
|
|
29
|
+
name: parsed.names[0],
|
|
30
|
+
status: parsed.status,
|
|
31
|
+
});
|
|
32
|
+
if (parsed.json)
|
|
33
|
+
console.log(JSON.stringify({ parentPiboSessionId, agents }, null, 2));
|
|
34
|
+
else
|
|
35
|
+
console.log(formatDebugAgentList(parentPiboSessionId, agents));
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
const result = inspectDebugAgentObservations(parentPiboSessionId, store, {
|
|
39
|
+
agentIds: parsed.agentIds.length ? parsed.agentIds : undefined,
|
|
40
|
+
names: parsed.names.length ? parsed.names : undefined,
|
|
41
|
+
threadKeys: parsed.threadKeys.length ? parsed.threadKeys : undefined,
|
|
42
|
+
eventTypes: parsed.eventTypes.length ? parsed.eventTypes : undefined,
|
|
43
|
+
kinds: parsed.kinds.length ? parsed.kinds : undefined,
|
|
44
|
+
since: parsed.since,
|
|
45
|
+
until: parsed.until,
|
|
46
|
+
textContains: parsed.textContains,
|
|
47
|
+
afterSequence: parsed.afterSequence,
|
|
48
|
+
order: parsed.order,
|
|
49
|
+
limit: parsed.limit,
|
|
50
|
+
includeDetails: parsed.details,
|
|
51
|
+
});
|
|
52
|
+
if (parsed.json)
|
|
53
|
+
console.log(JSON.stringify(result, null, 2));
|
|
54
|
+
else
|
|
55
|
+
console.log(formatDebugAgentObservations(result));
|
|
56
|
+
}
|
|
57
|
+
export function inspectDebugAgentList(parentPiboSessionId, store, options = {}) {
|
|
58
|
+
if (!store.exists)
|
|
59
|
+
throw new Error(`Debug store "pibo-data" not found at ${store.path}`);
|
|
60
|
+
const db = openReadOnlyDebugDatabase(store);
|
|
61
|
+
try {
|
|
62
|
+
return readOwnedAgents(db, parentPiboSessionId)
|
|
63
|
+
.filter((agent) => !options.name || agent.name === options.name)
|
|
64
|
+
.filter((agent) => !options.status || agent.status === options.status);
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
throw withStorePath(error, store);
|
|
68
|
+
}
|
|
69
|
+
finally {
|
|
70
|
+
db.close();
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
export function inspectDebugAgentObservations(parentPiboSessionId, store, input = {}) {
|
|
74
|
+
if (!store.exists)
|
|
75
|
+
throw new Error(`Debug store "pibo-data" not found at ${store.path}`);
|
|
76
|
+
const db = openReadOnlyDebugDatabase(store);
|
|
77
|
+
try {
|
|
78
|
+
const order = normalizePiboAgentObservationOrder(input.order);
|
|
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.");
|
|
85
|
+
const owned = readOwnedAgents(db, parentPiboSessionId);
|
|
86
|
+
const ownedById = new Map(owned.map((agent) => [agent.agentId, agent]));
|
|
87
|
+
for (const agentId of input.agentIds ?? []) {
|
|
88
|
+
if (!ownedById.has(agentId))
|
|
89
|
+
throw new Error(`Agent "${agentId}" is not owned by Pibo session "${parentPiboSessionId}".`);
|
|
90
|
+
}
|
|
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
|
+
const payloadStore = createDebugPayloadStore(db, store);
|
|
97
|
+
const clauses = ["s.parent_id = ?", "s.channel = 'pibo.subagents'", "s.kind = 'subagent'", "s.deleted_at IS NULL"];
|
|
98
|
+
const values = [parentPiboSessionId];
|
|
99
|
+
if (afterSequence !== undefined) {
|
|
100
|
+
clauses.push("e.stream_id > ?");
|
|
101
|
+
values.push(afterSequence);
|
|
102
|
+
}
|
|
103
|
+
const scanOrder = afterSequence !== undefined ? "ASC" : order.toUpperCase();
|
|
104
|
+
const statement = db.prepare(`
|
|
105
|
+
SELECT e.stream_id, e.session_id, e.session_sequence, e.event_id, e.type, e.created_at,
|
|
106
|
+
e.payload_ref, e.preview_text, e.attributes_json, s.profile, s.metadata_json
|
|
107
|
+
FROM event_log e
|
|
108
|
+
JOIN sessions s ON s.id = e.session_id
|
|
109
|
+
WHERE ${clauses.join(" AND ")}
|
|
110
|
+
ORDER BY e.stream_id ${scanOrder}
|
|
111
|
+
`);
|
|
112
|
+
const textContains = input.textContains?.toLowerCase();
|
|
113
|
+
const matches = [];
|
|
114
|
+
for (const rawRow of statement.iterate(...values)) {
|
|
115
|
+
const agent = ownedById.get(rawRow.session_id ?? "");
|
|
116
|
+
if (!agent)
|
|
117
|
+
continue;
|
|
118
|
+
if (agentIds && !agentIds.has(agent.agentId))
|
|
119
|
+
continue;
|
|
120
|
+
if (names && !names.has(agent.name))
|
|
121
|
+
continue;
|
|
122
|
+
if (threadKeys && (!agent.threadKey || !threadKeys.has(agent.threadKey)))
|
|
123
|
+
continue;
|
|
124
|
+
if (eventTypes && !eventTypes.has(rawRow.type))
|
|
125
|
+
continue;
|
|
126
|
+
const kind = piboAgentObservationKind(rawRow.type);
|
|
127
|
+
if (kinds && !kinds.has(kind))
|
|
128
|
+
continue;
|
|
129
|
+
const createdAt = Date.parse(rawRow.created_at);
|
|
130
|
+
if (since !== undefined && createdAt < since)
|
|
131
|
+
continue;
|
|
132
|
+
if (until !== undefined && createdAt > until)
|
|
133
|
+
continue;
|
|
134
|
+
const row = hydrateDebugEventRow(rawRow, payloadStore);
|
|
135
|
+
const attributes = eventAttributes(row);
|
|
136
|
+
const payload = { ...attributes, ...eventPayload(row) };
|
|
137
|
+
const source = debugAgentObservationSource(row, attributes);
|
|
138
|
+
const text = piboAgentObservationText(source);
|
|
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;
|
|
159
|
+
}
|
|
160
|
+
const truncated = matches.length > limit;
|
|
161
|
+
const observations = matches.slice(0, limit);
|
|
162
|
+
if (afterSequence !== undefined && order === "desc")
|
|
163
|
+
observations.reverse();
|
|
164
|
+
return {
|
|
165
|
+
parentPiboSessionId,
|
|
166
|
+
filters: {
|
|
167
|
+
...input,
|
|
168
|
+
...(afterSequence !== undefined ? { afterSequence } : {}),
|
|
169
|
+
order,
|
|
170
|
+
limit,
|
|
171
|
+
includeDetails: input.includeDetails === true,
|
|
172
|
+
},
|
|
173
|
+
observations,
|
|
174
|
+
nextAfterSequence: observations.reduce((maximum, observation) => Math.max(maximum, observation.streamId), afterSequence ?? 0),
|
|
175
|
+
truncated,
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
catch (error) {
|
|
179
|
+
throw withStorePath(error, store);
|
|
180
|
+
}
|
|
181
|
+
finally {
|
|
182
|
+
db.close();
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
function readOwnedAgents(db, parentPiboSessionId) {
|
|
186
|
+
const rows = db.prepare(`
|
|
187
|
+
SELECT id, profile, status, metadata_json, active_model_json, created_at, updated_at
|
|
188
|
+
FROM sessions
|
|
189
|
+
WHERE parent_id = ? AND channel = 'pibo.subagents' AND kind = 'subagent' AND deleted_at IS NULL
|
|
190
|
+
ORDER BY updated_at DESC
|
|
191
|
+
`).all(parentPiboSessionId);
|
|
192
|
+
return rows.map((row) => {
|
|
193
|
+
const metadata = parseObject(row.metadata_json);
|
|
194
|
+
const killed = metadata.agentStatus === "killed";
|
|
195
|
+
return {
|
|
196
|
+
agentId: row.id,
|
|
197
|
+
name: typeof metadata.subagentName === "string" ? metadata.subagentName : row.profile,
|
|
198
|
+
profile: row.profile,
|
|
199
|
+
...(typeof metadata.threadKey === "string" ? { threadKey: metadata.threadKey } : {}),
|
|
200
|
+
status: killed ? "killed" : isRunningStatus(row.status) ? "running" : "idle",
|
|
201
|
+
createdAt: row.created_at,
|
|
202
|
+
updatedAt: row.updated_at,
|
|
203
|
+
...(row.active_model_json ? { activeModel: JSON.parse(row.active_model_json) } : {}),
|
|
204
|
+
};
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
function debugAgentObservationSource(row, attributes) {
|
|
208
|
+
const inlinePayload = attributes.inlinePayload;
|
|
209
|
+
const source = {
|
|
210
|
+
eventType: row.type,
|
|
211
|
+
fallbackText: row.preview_text ?? row.type,
|
|
212
|
+
...(typeof attributes.source === "string" ? { source: attributes.source } : {}),
|
|
213
|
+
};
|
|
214
|
+
if (row.type === "message_queued" || row.type === "message_steered" || row.type === "message_started") {
|
|
215
|
+
source.text = typeof attributes.inlineText === "string" ? attributes.inlineText : row.preview_text ?? undefined;
|
|
216
|
+
}
|
|
217
|
+
else if (row.type === "assistant_message" || row.type === "assistant_delta" || row.type === "thinking_delta" || row.type === "thinking_finished") {
|
|
218
|
+
source.text = typeof inlinePayload === "string" ? inlinePayload : row.preview_text ?? undefined;
|
|
219
|
+
}
|
|
220
|
+
else if (row.type === "session_error") {
|
|
221
|
+
source.error = attributes.error;
|
|
222
|
+
}
|
|
223
|
+
else if (row.type === "tool_call" || row.type === "tool_execution_started") {
|
|
224
|
+
source.args = inlinePayload;
|
|
225
|
+
}
|
|
226
|
+
else if (row.type === "tool_execution_updated") {
|
|
227
|
+
source.partialResult = inlinePayload;
|
|
228
|
+
}
|
|
229
|
+
else if (row.type === "tool_execution_finished" || row.type === "execution_result" || row.type === "compaction_end") {
|
|
230
|
+
source.result = inlinePayload;
|
|
231
|
+
}
|
|
232
|
+
if (row.type === "execution_result")
|
|
233
|
+
source.action = attributes.action;
|
|
234
|
+
if (row.type === "compaction_start" || row.type === "compaction_end")
|
|
235
|
+
source.reason = attributes.reason;
|
|
236
|
+
if (row.type === "subagent_session")
|
|
237
|
+
source.subagentName = attributes.subagentName;
|
|
238
|
+
return source;
|
|
239
|
+
}
|
|
240
|
+
function debugAgentObservationDetails(row, payload) {
|
|
241
|
+
return {
|
|
242
|
+
type: row.type,
|
|
243
|
+
...(row.session_id ? { piboSessionId: row.session_id } : {}),
|
|
244
|
+
...(row.event_id ? { eventId: row.event_id } : {}),
|
|
245
|
+
...payload,
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
function parseObject(value) {
|
|
249
|
+
try {
|
|
250
|
+
const parsed = JSON.parse(value);
|
|
251
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
|
|
252
|
+
}
|
|
253
|
+
catch {
|
|
254
|
+
return {};
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
function isRunningStatus(status) {
|
|
258
|
+
return ["running", "streaming", "queued", "starting", "waiting", "blocked", "retrying"].includes(status);
|
|
259
|
+
}
|
|
260
|
+
function formatDebugAgentList(parentPiboSessionId, agents) {
|
|
261
|
+
if (agents.length === 0)
|
|
262
|
+
return `parent: ${parentPiboSessionId}\nagents: 0`;
|
|
263
|
+
return [
|
|
264
|
+
`parent: ${parentPiboSessionId}`,
|
|
265
|
+
"agentId\tname\tprofile\tthreadKey\tstatus\tupdatedAt",
|
|
266
|
+
...agents.map((agent) => `${agent.agentId}\t${agent.name}\t${agent.profile}\t${agent.threadKey ?? ""}\t${agent.status}\t${agent.updatedAt}`),
|
|
267
|
+
`agents: ${agents.length}`,
|
|
268
|
+
].join("\n");
|
|
269
|
+
}
|
|
270
|
+
function formatDebugAgentObservations(result) {
|
|
271
|
+
if (result.observations.length === 0)
|
|
272
|
+
return `parent: ${result.parentPiboSessionId}\nobservations: 0\nnextAfterSequence: ${result.nextAfterSequence}`;
|
|
273
|
+
return [
|
|
274
|
+
`parent: ${result.parentPiboSessionId}`,
|
|
275
|
+
"streamId\tcreatedAt\tagentId\tname\teventType\tkind\ttext",
|
|
276
|
+
...result.observations.map((observation) => `${observation.streamId}\t${observation.createdAt}\t${observation.agentId}\t${observation.name}\t${observation.eventType}\t${observation.kind}\t${(observation.text ?? "").replaceAll("\n", "\\n")}`),
|
|
277
|
+
`observations: ${result.observations.length}${result.truncated ? " (limited)" : ""}`,
|
|
278
|
+
`nextAfterSequence: ${result.nextAfterSequence}`,
|
|
279
|
+
].join("\n");
|
|
280
|
+
}
|
|
281
|
+
function printDebugAgentsDiscovery(parentPiboSessionId = "<parent-session-id>") {
|
|
282
|
+
console.log(`pibo debug agents - inspect delegated child agents
|
|
283
|
+
|
|
284
|
+
Usage:
|
|
285
|
+
pibo debug agents ${parentPiboSessionId} <command>
|
|
286
|
+
|
|
287
|
+
Commands:
|
|
288
|
+
list List child agents owned by the parent session.
|
|
289
|
+
observe Read persisted child-agent observations.
|
|
290
|
+
|
|
291
|
+
Next:
|
|
292
|
+
pibo debug agents ${parentPiboSessionId} list --help
|
|
293
|
+
pibo debug agents ${parentPiboSessionId} observe --help
|
|
294
|
+
`);
|
|
295
|
+
}
|
|
296
|
+
function printDebugAgentsCommandHelp(parentPiboSessionId, command) {
|
|
297
|
+
if (command === "list") {
|
|
298
|
+
console.log(`pibo debug agents ${parentPiboSessionId} list
|
|
299
|
+
|
|
300
|
+
Usage:
|
|
301
|
+
pibo debug agents ${parentPiboSessionId} list [--name name] [--status running|idle|killed] [--json]
|
|
302
|
+
|
|
303
|
+
Filters use exact values. The command inspects only direct pibo.subagents children owned by the parent session.`);
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
console.log(`pibo debug agents ${parentPiboSessionId} observe
|
|
307
|
+
|
|
308
|
+
Usage:
|
|
309
|
+
pibo debug agents ${parentPiboSessionId} observe [--agent-id ps_...] [--name name] [--thread-key key]
|
|
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] [--details] [--json]
|
|
313
|
+
|
|
314
|
+
Repeat --agent-id, --name, --thread-key, --event-type, or --kind for OR within that field.
|
|
315
|
+
Different fields combine with AND. With --after-sequence, pages always consume the oldest unseen rows;
|
|
316
|
+
--order desc reverses only the returned page, so nextAfterSequence remains safe for polling.`);
|
|
317
|
+
}
|
|
318
|
+
function parseAgentDebugOptions(args) {
|
|
319
|
+
const parsed = { json: false, details: false, agentIds: [], names: [], threadKeys: [], eventTypes: [], kinds: [] };
|
|
320
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
321
|
+
const arg = args[index];
|
|
322
|
+
if (arg === "--json") {
|
|
323
|
+
parsed.json = true;
|
|
324
|
+
continue;
|
|
325
|
+
}
|
|
326
|
+
if (arg === "--details") {
|
|
327
|
+
parsed.details = true;
|
|
328
|
+
continue;
|
|
329
|
+
}
|
|
330
|
+
const value = args[index + 1];
|
|
331
|
+
if (!value)
|
|
332
|
+
throw new Error(`${arg} requires a value`);
|
|
333
|
+
if (arg === "--agent-id")
|
|
334
|
+
parsed.agentIds.push(value);
|
|
335
|
+
else if (arg === "--name")
|
|
336
|
+
parsed.names.push(value);
|
|
337
|
+
else if (arg === "--thread-key")
|
|
338
|
+
parsed.threadKeys.push(value);
|
|
339
|
+
else if (arg === "--event-type")
|
|
340
|
+
parsed.eventTypes.push(value);
|
|
341
|
+
else if (arg === "--kind") {
|
|
342
|
+
if (!["message", "thinking", "tool", "error", "lifecycle", "event"].includes(value))
|
|
343
|
+
throw new Error(`Invalid --kind "${value}"`);
|
|
344
|
+
parsed.kinds.push(value);
|
|
345
|
+
}
|
|
346
|
+
else if (arg === "--status") {
|
|
347
|
+
if (!["running", "idle", "killed"].includes(value))
|
|
348
|
+
throw new Error(`Invalid --status "${value}"`);
|
|
349
|
+
parsed.status = value;
|
|
350
|
+
}
|
|
351
|
+
else if (arg === "--since")
|
|
352
|
+
parsed.since = value;
|
|
353
|
+
else if (arg === "--until")
|
|
354
|
+
parsed.until = value;
|
|
355
|
+
else if (arg === "--contains")
|
|
356
|
+
parsed.textContains = value;
|
|
357
|
+
else if (arg === "--after-sequence")
|
|
358
|
+
parsed.afterSequence = parseNonNegativeInteger(value, arg);
|
|
359
|
+
else if (arg === "--order") {
|
|
360
|
+
if (value !== "asc" && value !== "desc")
|
|
361
|
+
throw new Error(`Invalid --order "${value}"`);
|
|
362
|
+
parsed.order = value;
|
|
363
|
+
}
|
|
364
|
+
else if (arg === "--limit")
|
|
365
|
+
parsed.limit = normalizePiboAgentObservationLimit(parseNonNegativeInteger(value, arg));
|
|
366
|
+
else
|
|
367
|
+
throw new Error(`Unknown pibo debug agents option "${arg}"`);
|
|
368
|
+
index += 1;
|
|
369
|
+
}
|
|
370
|
+
return parsed;
|
|
371
|
+
}
|
|
372
|
+
function validateAgentDebugOptions(command, parsed) {
|
|
373
|
+
if (command === "list") {
|
|
374
|
+
if (parsed.names.length > 1)
|
|
375
|
+
throw new Error("pibo debug agents list accepts at most one --name value");
|
|
376
|
+
if (parsed.details || parsed.agentIds.length > 0 || parsed.threadKeys.length > 0 || parsed.eventTypes.length > 0
|
|
377
|
+
|| parsed.kinds.length > 0 || parsed.since !== undefined || parsed.until !== undefined
|
|
378
|
+
|| parsed.textContains !== undefined || parsed.afterSequence !== undefined || parsed.order !== undefined
|
|
379
|
+
|| parsed.limit !== undefined)
|
|
380
|
+
throw new Error("Unsupported option for pibo debug agents list. Run the list command with --help.");
|
|
381
|
+
return;
|
|
382
|
+
}
|
|
383
|
+
if (parsed.status !== undefined)
|
|
384
|
+
throw new Error("--status is supported only by pibo debug agents list");
|
|
385
|
+
}
|
|
386
|
+
function parseNonNegativeInteger(value, option) {
|
|
387
|
+
const parsed = Number(value);
|
|
388
|
+
if (!Number.isInteger(parsed) || parsed < 0)
|
|
389
|
+
throw new Error(`${option} requires a non-negative integer`);
|
|
390
|
+
return parsed;
|
|
391
|
+
}
|
package/dist/debug/index.js
CHANGED
|
@@ -44,6 +44,11 @@ export async function runDebugCli(argv = process.argv) {
|
|
|
44
44
|
await runDebugEvents(args.slice(1));
|
|
45
45
|
return;
|
|
46
46
|
}
|
|
47
|
+
if (args[0] === "agents") {
|
|
48
|
+
const { runDebugAgentsCli } = await import("./agents.js");
|
|
49
|
+
await runDebugAgentsCli(args.slice(1));
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
47
52
|
if (args[0] === "jobs") {
|
|
48
53
|
await runDebugJobs(args.slice(1));
|
|
49
54
|
return;
|
|
@@ -1050,6 +1055,7 @@ Commands:
|
|
|
1050
1055
|
final Show the latest assistant message
|
|
1051
1056
|
trace Rebuild the Chat Web trace view for one Pibo Session
|
|
1052
1057
|
events Inspect compact event payload fields for one Pibo Session
|
|
1058
|
+
agents Inspect delegated child agents and their persisted activity
|
|
1053
1059
|
tool Inspect one grouped tool call
|
|
1054
1060
|
failures List failed tool calls and trace/session errors
|
|
1055
1061
|
jobs Inspect durable Pibo jobs and DLQ
|
|
@@ -1067,6 +1073,7 @@ Next:
|
|
|
1067
1073
|
pibo debug messages <pibo-session-id> list
|
|
1068
1074
|
pibo debug trace <pibo-session-id> --running-only
|
|
1069
1075
|
pibo debug events stream --topic pibo.output
|
|
1076
|
+
pibo debug agents <parent-session-id> list
|
|
1070
1077
|
pibo debug resources --json
|
|
1071
1078
|
pibo debug signals tree ps_...
|
|
1072
1079
|
pibo debug telemetry sessions --active
|
package/dist/index.js
CHANGED
|
@@ -41,7 +41,7 @@ export { runGatewayClient } from "./gateway/client.js";
|
|
|
41
41
|
export { LOCAL_TUI_CHANNEL_NAME, LocalRoutedTuiClient, createLocalRoutedTuiClient, createLocalRoutedTuiExtension, runLocalRoutedTui, } from "./local/tui.js";
|
|
42
42
|
export { createWebHostChannel, DEFAULT_WEB_CHANNEL_HOST, DEFAULT_WEB_CHANNEL_PORT, WEB_CHANNEL_NAME } from "./web/channel.js";
|
|
43
43
|
export { sendGatewayEvent, sendGatewayMessageAndWaitForReply } from "./gateway/request.js";
|
|
44
|
-
export { createSubagentToolDefinitions, createSubagentToolName, } from "./subagents/tool.js";
|
|
44
|
+
export { createAgentToolDefinitions, createSubagentToolDefinitions, createSubagentToolName, formatAvailableAgentsForPrompt, listAvailableAgents, PIBO_AGENT_TOOL_NAMES, } from "./subagents/tool.js";
|
|
45
45
|
export { PiboSteeringUnavailableError } from "./core/events.js";
|
|
46
46
|
export { RuntimeSessionBindingConflictError, RuntimeSessionBindingTransitionError, assertRuntimeSessionBindingTransition, createInitialRuntimeSessionBinding, createLegacyPiRuntimeSessionBinding, nextRuntimeSessionBinding, } from "./sessions/runtime-binding.js";
|
|
47
47
|
export { InMemoryPiboSessionStore, createPiSessionId, createPiboSessionId, createPiboSession, } from "./sessions/store.js";
|
|
@@ -16,7 +16,8 @@ export function resolveAgentDelegationStatus(childSignal, fallbackStatus = "done
|
|
|
16
16
|
}
|
|
17
17
|
export function extractAgentDelegationName(input, title, summary) {
|
|
18
18
|
const record = isRecord(input) ? input : undefined;
|
|
19
|
-
const rawName = stringValue(record?.
|
|
19
|
+
const rawName = stringValue(record?.name)
|
|
20
|
+
?? stringValue(record?.subagentName)
|
|
20
21
|
?? subagentNameFromToolName(title)
|
|
21
22
|
?? stringValue(summary)
|
|
22
23
|
?? stringValue(title)
|
|
@@ -68,10 +69,11 @@ function subagentNameFromToolName(value) {
|
|
|
68
69
|
const name = nonEmpty(value);
|
|
69
70
|
if (!name)
|
|
70
71
|
return undefined;
|
|
71
|
-
return name.replace(/^pibo_subagent_/, "");
|
|
72
|
+
return name === "pibo_agents_send_message" ? undefined : name.replace(/^pibo_subagent_/, "");
|
|
72
73
|
}
|
|
73
74
|
function titleCaseAgentName(value) {
|
|
74
75
|
return value
|
|
76
|
+
.replace(/^pibo_agents_send_message$/, "Agent")
|
|
75
77
|
.replace(/^pibo_subagent_/, "")
|
|
76
78
|
.split(/[\s_-]+/)
|
|
77
79
|
.filter(Boolean)
|
|
@@ -51,10 +51,12 @@ function createAsyncAgentRunNode(parent, piboSessionId, startedAt, delegation) {
|
|
|
51
51
|
const toolName = stringValue(run?.toolName) ?? stringValue(input.toolName) ?? delegation?.title;
|
|
52
52
|
if (!toolName || !isSubagentToolName(toolName))
|
|
53
53
|
return undefined;
|
|
54
|
-
const
|
|
54
|
+
const delegatedArguments = input.arguments;
|
|
55
|
+
const subagentName = stringValue(delegation?.summary)
|
|
56
|
+
?? (isRecord(delegatedArguments) ? stringValue(delegatedArguments.name) : undefined)
|
|
57
|
+
?? subagentNameFromToolName(toolName);
|
|
55
58
|
const runId = stringValue(run?.runId);
|
|
56
59
|
const runStatus = stringValue(run?.status);
|
|
57
|
-
const delegatedArguments = input.arguments;
|
|
58
60
|
const completionPolicy = stringValue(run?.completionPolicy) ?? stringValue(input.completionPolicy);
|
|
59
61
|
return {
|
|
60
62
|
id: `${parent.id}:async-agent`,
|
|
@@ -947,8 +947,14 @@ function findLegacySubagentLinkTarget(nodes, update) {
|
|
|
947
947
|
}
|
|
948
948
|
function delegationAgentName(node) {
|
|
949
949
|
const input = isObjectRecord(node.input) ? node.input : undefined;
|
|
950
|
-
const value = typeof input?.
|
|
951
|
-
|
|
950
|
+
const value = typeof input?.name === "string"
|
|
951
|
+
? input.name
|
|
952
|
+
: typeof input?.subagentName === "string"
|
|
953
|
+
? input.subagentName
|
|
954
|
+
: node.summary ?? node.title;
|
|
955
|
+
return typeof value === "string"
|
|
956
|
+
? value.replace(/^pibo_agents_send_message$/, "agent").replace(/^pibo_subagent_/, "").trim().toLowerCase() || undefined
|
|
957
|
+
: undefined;
|
|
952
958
|
}
|
|
953
959
|
function delegationThreadKey(value) {
|
|
954
960
|
if (!isObjectRecord(value) || typeof value.threadKey !== "string")
|
|
@@ -22,9 +22,16 @@ export function mapTraceSubagentSessionLinks(events) {
|
|
|
22
22
|
export function findLikelyTraceChildSession(piboSessionId, toolName, event, childByParent) {
|
|
23
23
|
if (!isSubagentToolName(toolName))
|
|
24
24
|
return undefined;
|
|
25
|
+
const agentName = toolEventAgentName(event);
|
|
25
26
|
const candidates = childByParent
|
|
26
27
|
.get(piboSessionId)
|
|
27
|
-
?.filter((session) =>
|
|
28
|
+
?.filter((session) => {
|
|
29
|
+
if (toolName === "pibo_agents_send_message") {
|
|
30
|
+
return session.metadata?.subagentToolName === toolName
|
|
31
|
+
&& (!agentName || session.metadata?.subagentName === agentName);
|
|
32
|
+
}
|
|
33
|
+
return session.metadata?.subagentToolName === toolName;
|
|
34
|
+
}) ?? [];
|
|
28
35
|
const threadKey = toolEventThreadKey(event);
|
|
29
36
|
if (threadKey) {
|
|
30
37
|
return candidates.find((session) => session.metadata?.threadKey === threadKey)?.id;
|
|
@@ -32,15 +39,21 @@ export function findLikelyTraceChildSession(piboSessionId, toolName, event, chil
|
|
|
32
39
|
return candidates.length === 1 ? candidates[0].id : undefined;
|
|
33
40
|
}
|
|
34
41
|
export function isSubagentToolName(name) {
|
|
35
|
-
return name.startsWith("pibo_subagent_");
|
|
42
|
+
return name === "pibo_agents_send_message" || name.startsWith("pibo_subagent_");
|
|
36
43
|
}
|
|
37
44
|
export function subagentNameFromToolName(toolName) {
|
|
38
|
-
return toolName.slice("pibo_subagent_".length);
|
|
45
|
+
return toolName === "pibo_agents_send_message" ? "agent" : toolName.slice("pibo_subagent_".length);
|
|
39
46
|
}
|
|
40
|
-
function
|
|
41
|
-
|
|
47
|
+
function toolEventArguments(event) {
|
|
48
|
+
return "args" in event && event.args && typeof event.args === "object" && !Array.isArray(event.args)
|
|
42
49
|
? event.args
|
|
43
50
|
: undefined;
|
|
44
|
-
|
|
51
|
+
}
|
|
52
|
+
function toolEventAgentName(event) {
|
|
53
|
+
const name = toolEventArguments(event)?.name;
|
|
54
|
+
return typeof name === "string" && name.trim() ? name.trim() : undefined;
|
|
55
|
+
}
|
|
56
|
+
function toolEventThreadKey(event) {
|
|
57
|
+
const threadKey = toolEventArguments(event)?.threadKey;
|
|
45
58
|
return typeof threadKey === "string" && threadKey.trim() ? threadKey.trim() : undefined;
|
|
46
59
|
}
|