@pasko70/pibo 2.2.4 → 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.
Files changed (61) hide show
  1. package/dist/agent-runtime/capabilities.js +9 -1
  2. package/dist/agent-runtime/context-build.js +5 -2
  3. package/dist/agent-runtimes/codex-native/adapter.js +5 -0
  4. package/dist/agent-runtimes/omp/adapter.js +5 -0
  5. package/dist/agent-runtimes/omp/turn.js +2 -0
  6. package/dist/agent-runtimes/pi/adapter.js +28 -7
  7. package/dist/agent-runtimes/pi/intent-tracing.js +120 -0
  8. package/dist/agent-runtimes/pi/routed-session.js +25 -8
  9. package/dist/agent-runtimes/pi/runtime.js +28 -16
  10. package/dist/apps/chat/chat-settings-routes.js +44 -3
  11. package/dist/apps/chat/chat-transcription.js +85 -0
  12. package/dist/apps/chat/data/chat-data-mappers.js +4 -4
  13. package/dist/apps/chat/stream.js +23 -9
  14. package/dist/apps/chat/trace-v2.js +1 -0
  15. package/dist/apps/chat/web-app.js +49 -0
  16. package/dist/apps/chat-ui/assets/{dist-luJVFsmq.js → dist-Byygd1lH.js} +1 -1
  17. package/dist/apps/chat-ui/assets/{dist-ltfz1vFX.js → dist-C9BrS7sL.js} +1 -1
  18. package/dist/apps/chat-ui/assets/{dist-rf4HYdoa.js → dist-CUcAofmV.js} +1 -1
  19. package/dist/apps/chat-ui/assets/{dist-CImWCF2M.js → dist-D4RU6xu3.js} +1 -1
  20. package/dist/apps/chat-ui/assets/{dist-BFwTuvyi.js → dist-DusFwy0L.js} +1 -1
  21. package/dist/apps/chat-ui/assets/{index-nZQXUpxE.css → index-BJ56TREg.css} +1 -1
  22. package/dist/apps/chat-ui/assets/index-Bifi_kjN.js +228 -0
  23. package/dist/apps/chat-ui/index.html +2 -2
  24. package/dist/apps/chat-vscode-web/assets/index-WsLm1mo3.js +43 -0
  25. package/dist/apps/chat-vscode-web/index.html +1 -1
  26. package/dist/apps/vscode-artifacts/latest.vsix +0 -0
  27. package/dist/apps/vscode-artifacts/pibo-vscode-ext-2.3.0.vsix +0 -0
  28. package/dist/core/codex-compat.js +1 -3
  29. package/dist/core/context-build.js +16 -7
  30. package/dist/core/gateway-resource-guard.js +35 -14
  31. package/dist/core/gateway-settings.js +64 -0
  32. package/dist/core/session-router.js +226 -46
  33. package/dist/core/user-settings.js +20 -0
  34. package/dist/data/ingest-service.js +14 -2
  35. package/dist/debug/agents.js +391 -0
  36. package/dist/debug/index.js +14 -2
  37. package/dist/gateway/server.js +2 -0
  38. package/dist/index.js +6 -1
  39. package/dist/plugins/builtin.js +4 -2
  40. package/dist/plugins/openai-chatgpt-transcription.js +12 -0
  41. package/dist/plugins/openai-transcription.js +12 -0
  42. package/dist/plugins/registry.js +23 -0
  43. package/dist/session-ui/delegation.js +4 -2
  44. package/dist/session-ui/terminalRows.js +51 -1
  45. package/dist/shared/trace-async-agent-runs.js +4 -2
  46. package/dist/shared/trace-event-projection.js +12 -2
  47. package/dist/shared/trace-live-reducer.js +4 -0
  48. package/dist/shared/trace-patch-nodes.js +1 -0
  49. package/dist/shared/trace-subagent-links.js +19 -6
  50. package/dist/subagents/observations.js +149 -0
  51. package/dist/subagents/tool.js +177 -46
  52. package/dist/tools/session-service.js +1 -0
  53. package/dist/tools/session-tool-set.js +9 -5
  54. package/dist/transcription/openai-chatgpt.js +148 -0
  55. package/dist/transcription/openai.js +72 -0
  56. package/dist/transcription/types.js +8 -0
  57. package/npm-shrinkwrap.json +2 -2
  58. package/package.json +1 -1
  59. package/dist/apps/chat-ui/assets/index-D2Maa2v1.js +0 -226
  60. package/dist/apps/chat-vscode-web/assets/index-BpurWVnX.js +0 -41
  61. package/dist/apps/vscode-artifacts/pibo-vscode-ext-2.2.4.vsix +0 -0
@@ -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
+ }
@@ -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;
@@ -88,7 +93,8 @@ async function runDebugResources(args) {
88
93
  }
89
94
  const options = parseOptions(args);
90
95
  const { collectGatewayResourceSnapshot, renderGatewayResourceSnapshotText } = await import("../core/gateway-resource-guard.js");
91
- const snapshot = await collectGatewayResourceSnapshot();
96
+ const { loadPiboGatewaySettings } = await import("../core/gateway-settings.js");
97
+ const snapshot = await collectGatewayResourceSnapshot({ gatewaySettings: loadPiboGatewaySettings() });
92
98
  if (options.json)
93
99
  console.log(JSON.stringify(snapshot, null, 2));
94
100
  else
@@ -1049,6 +1055,7 @@ Commands:
1049
1055
  final Show the latest assistant message
1050
1056
  trace Rebuild the Chat Web trace view for one Pibo Session
1051
1057
  events Inspect compact event payload fields for one Pibo Session
1058
+ agents Inspect delegated child agents and their persisted activity
1052
1059
  tool Inspect one grouped tool call
1053
1060
  failures List failed tool calls and trace/session errors
1054
1061
  jobs Inspect durable Pibo jobs and DLQ
@@ -1066,6 +1073,7 @@ Next:
1066
1073
  pibo debug messages <pibo-session-id> list
1067
1074
  pibo debug trace <pibo-session-id> --running-only
1068
1075
  pibo debug events stream --topic pibo.output
1076
+ pibo debug agents <parent-session-id> list
1069
1077
  pibo debug resources --json
1070
1078
  pibo debug signals tree ps_...
1071
1079
  pibo debug telemetry sessions --active
@@ -1088,9 +1096,13 @@ Environment:
1088
1096
  PIBO_GATEWAY_MIN_HEAP_AVAILABLE_BYTES=<bytes>
1089
1097
  PIBO_GATEWAY_MAX_RSS_BYTES=<bytes>
1090
1098
  PIBO_GATEWAY_KNOWN_DAEMON_WARNING_RSS_BYTES=<bytes>
1091
- PIBO_GATEWAY_MAX_CONCURRENT_YIELDED_RUNS=<count> (default: 1)
1099
+ PIBO_GATEWAY_MAX_CONCURRENT_YIELDED_RUNS=<count> (default: 50)
1100
+ PIBO_SESSION_CONCURRENT_YIELDED_RUNS=<count> (default: 10)
1092
1101
  PIBO_GATEWAY_YIELDED_RUN_MEMORY_RESERVATION_BYTES=<bytes> (default: 2147483648)
1093
1102
 
1103
+ Web settings:
1104
+ Settings -> Concurrency persists overrides that apply to new yielded runs immediately.
1105
+
1094
1106
  Next:
1095
1107
  pibo debug resources --json
1096
1108
  pibo compute health --json
@@ -429,6 +429,8 @@ export class PiboGatewayServer {
429
429
  getProfiles: () => this.pluginRegistry.getProfileInfos(),
430
430
  createProfile: (name) => this.pluginRegistry.createProfile(name),
431
431
  getCapabilityCatalog: () => this.pluginRegistry.getCapabilityCatalog(),
432
+ getTranscriptionProviderInfos: () => this.pluginRegistry.getTranscriptionProviderInfos(),
433
+ transcribe: (providerId, input) => this.pluginRegistry.transcribe(providerId, input),
432
434
  inspectAgentRuntimeInstances: () => this.pluginRegistry.inspectAgentRuntimeInstances(),
433
435
  getAgentRuntimeAuthStatus: (runtimeInstanceId) => this.requireRouter().getAgentRuntimeAuthStatus(runtimeInstanceId),
434
436
  startAgentRuntimeAuth: (runtimeInstanceId, input) => this.requireRouter().startAgentRuntimeAuth(runtimeInstanceId, input),
package/dist/index.js CHANGED
@@ -1,10 +1,15 @@
1
1
  export { createDefaultPiboProfile, createDefaultPiboPluginRegistry, createDefaultPiboPlugins, createGatewayProducerPiboPluginRegistry, createGatewayProducerPiboProfile, CODEX_NATIVE_PROFILE_NAME, CODEX_NATIVE_RUNTIME_INSTANCE_ID, piboCodexNativePlugin, OMP_PROFILE_NAME, OMP_RUNTIME_INSTANCE_ID, piboOmpPlugin, piboCorePlugin, piboGatewayProducerPlugin, } from "./plugins/builtin.js";
2
2
  export { createPiboBetterAuthPlugin } from "./plugins/better-auth.js";
3
3
  export { createPiboChatWebPlugin } from "./plugins/chat-web.js";
4
+ export { createPiboOpenAiChatGptTranscriptionPlugin, piboOpenAiChatGptTranscriptionPlugin } from "./plugins/openai-chatgpt-transcription.js";
5
+ export { createPiboOpenAiTranscriptionPlugin, piboOpenAiTranscriptionPlugin } from "./plugins/openai-transcription.js";
4
6
  export { createPiboContextFilesPlugin } from "./plugins/context-files.js";
5
7
  export { createPiboWebHostPlugin } from "./plugins/web.js";
6
8
  export { createChatWebApp } from "./apps/chat/web-app.js";
7
9
  export { createBetterAuthService } from "./auth/better-auth.js";
10
+ export { DEFAULT_OPENAI_CHATGPT_TRANSCRIPTION_URL, DEFAULT_OPENAI_CHATGPT_USER_AGENT, OPENAI_CHATGPT_TRANSCRIPTION_PROVIDER_ID, OPENAI_CODEX_AUTH_PROVIDER_ID, createOpenAiChatGptTranscriptionProvider, } from "./transcription/openai-chatgpt.js";
11
+ export { DEFAULT_OPENAI_TRANSCRIPTION_MODEL, DEFAULT_OPENAI_TRANSCRIPTION_URL, OPENAI_API_CREDENTIAL_PROVIDER_ID, OPENAI_TRANSCRIPTION_PROVIDER_ID, createOpenAiTranscriptionProvider, } from "./transcription/openai.js";
12
+ export { PiboTranscriptionError } from "./transcription/types.js";
8
13
  export { DEFAULT_AGENT_RUNTIME_INSTANCE_ID, InitialSessionContext, InitialSessionContextBuilder, normalizeToolProfile, } from "./core/profiles.js";
9
14
  export { AgentRuntimeAdapterRegistry } from "./agent-runtime/registry.js";
10
15
  export { validateAgentRuntimeProfileCapabilities } from "./agent-runtime/profile-validation.js";
@@ -36,7 +41,7 @@ export { runGatewayClient } from "./gateway/client.js";
36
41
  export { LOCAL_TUI_CHANNEL_NAME, LocalRoutedTuiClient, createLocalRoutedTuiClient, createLocalRoutedTuiExtension, runLocalRoutedTui, } from "./local/tui.js";
37
42
  export { createWebHostChannel, DEFAULT_WEB_CHANNEL_HOST, DEFAULT_WEB_CHANNEL_PORT, WEB_CHANNEL_NAME } from "./web/channel.js";
38
43
  export { sendGatewayEvent, sendGatewayMessageAndWaitForReply } from "./gateway/request.js";
39
- export { createSubagentToolDefinitions, createSubagentToolName, } from "./subagents/tool.js";
44
+ export { createAgentToolDefinitions, createSubagentToolDefinitions, createSubagentToolName, formatAvailableAgentsForPrompt, listAvailableAgents, PIBO_AGENT_TOOL_NAMES, } from "./subagents/tool.js";
40
45
  export { PiboSteeringUnavailableError } from "./core/events.js";
41
46
  export { RuntimeSessionBindingConflictError, RuntimeSessionBindingTransitionError, assertRuntimeSessionBindingTransition, createInitialRuntimeSessionBinding, createLegacyPiRuntimeSessionBinding, nextRuntimeSessionBinding, } from "./sessions/runtime-binding.js";
42
47
  export { InMemoryPiboSessionStore, createPiSessionId, createPiboSessionId, createPiboSession, } from "./sessions/store.js";
@@ -13,6 +13,8 @@ import { piboCodexNativePlugin } from "./codex-native.js";
13
13
  import { addPiboNativeToolingContext, registerPiboNativeTooling } from "./native-tooling.js";
14
14
  import { piboWebAnnotationsPlugin } from "./web-annotations.js";
15
15
  import { piboOmpPlugin } from "./omp.js";
16
+ import { piboOpenAiChatGptTranscriptionPlugin } from "./openai-chatgpt-transcription.js";
17
+ import { piboOpenAiTranscriptionPlugin } from "./openai-transcription.js";
16
18
  import { definePiboPlugin, PiboPluginRegistry } from "./registry.js";
17
19
  import { PI_AGENT_RUNTIME_DRIVER } from "../agent-runtimes/pi/adapter.js";
18
20
  export { createDefaultPiboProfile, DEFAULT_PIBO_PROFILE_NAME } from "../core/default-profile.js";
@@ -589,11 +591,11 @@ export const piboGatewayProducerPlugin = definePiboPlugin({
589
591
  },
590
592
  });
591
593
  export function createDefaultPiboPlugins() {
592
- return [piboCorePlugin, piboCodexNativePlugin, piboCodexCompatPlugin, piboWebAnnotationsPlugin, piboOmpPlugin];
594
+ return [piboCorePlugin, piboCodexNativePlugin, piboCodexCompatPlugin, piboWebAnnotationsPlugin, piboOmpPlugin, piboOpenAiChatGptTranscriptionPlugin, piboOpenAiTranscriptionPlugin];
593
595
  }
594
596
  export function createGatewayProducerPiboPluginRegistry() {
595
597
  return PiboPluginRegistry.create({
596
- plugins: [piboCorePlugin, piboCodexNativePlugin, piboGatewayProducerPlugin, piboCodexCompatPlugin, piboWebAnnotationsPlugin, piboOmpPlugin],
598
+ plugins: [piboCorePlugin, piboCodexNativePlugin, piboGatewayProducerPlugin, piboCodexCompatPlugin, piboWebAnnotationsPlugin, piboOmpPlugin, piboOpenAiChatGptTranscriptionPlugin, piboOpenAiTranscriptionPlugin],
597
599
  });
598
600
  }
599
601
  export function createDefaultPiboPluginRegistry() {
@@ -0,0 +1,12 @@
1
+ import { createOpenAiChatGptTranscriptionProvider, } from "../transcription/openai-chatgpt.js";
2
+ import { definePiboPlugin } from "./registry.js";
3
+ export function createPiboOpenAiChatGptTranscriptionPlugin(options = {}) {
4
+ return definePiboPlugin({
5
+ id: "pibo.transcription.openai-chatgpt",
6
+ name: "ChatGPT Subscription Transcription",
7
+ register(api) {
8
+ api.registerTranscriptionProvider(createOpenAiChatGptTranscriptionProvider(options));
9
+ },
10
+ });
11
+ }
12
+ export const piboOpenAiChatGptTranscriptionPlugin = createPiboOpenAiChatGptTranscriptionPlugin();
@@ -0,0 +1,12 @@
1
+ import { createOpenAiTranscriptionProvider, } from "../transcription/openai.js";
2
+ import { definePiboPlugin } from "./registry.js";
3
+ export function createPiboOpenAiTranscriptionPlugin(options = {}) {
4
+ return definePiboPlugin({
5
+ id: "pibo.transcription.openai",
6
+ name: "OpenAI Transcription",
7
+ register(api) {
8
+ api.registerTranscriptionProvider(createOpenAiTranscriptionProvider(options));
9
+ },
10
+ });
11
+ }
12
+ export const piboOpenAiTranscriptionPlugin = createPiboOpenAiTranscriptionPlugin();
@@ -44,6 +44,7 @@ export class PiboPluginRegistry {
44
44
  gatewaySlashCommands = new Map();
45
45
  channels = new Map();
46
46
  authService;
47
+ transcriptionProviders = new Map();
47
48
  webApps = new Map();
48
49
  capabilityPackages = new Map();
49
50
  eventListeners = new Set();
@@ -181,6 +182,23 @@ export class PiboPluginRegistry {
181
182
  }
182
183
  this.authService = service;
183
184
  }
185
+ registerTranscriptionProvider(provider) {
186
+ this.addUnique(this.transcriptionProviders, provider.id, provider, "transcription provider");
187
+ }
188
+ async getTranscriptionProviderInfos() {
189
+ return await Promise.all([...this.transcriptionProviders.values()].map(async (provider) => ({
190
+ id: provider.id,
191
+ name: provider.name,
192
+ description: provider.description,
193
+ configured: provider.isConfigured ? await Promise.resolve(provider.isConfigured()).catch(() => false) : true,
194
+ pluginId: provider.pluginId,
195
+ pluginName: provider.pluginId ? this.pluginNames.get(provider.pluginId) : undefined,
196
+ })));
197
+ }
198
+ async transcribe(providerId, input) {
199
+ const provider = this.getRequired(this.transcriptionProviders, providerId, "transcription provider");
200
+ return { providerId, ...await provider.transcribe(input) };
201
+ }
184
202
  registerWebApp(app) {
185
203
  if (this.webApps.has(app.name)) {
186
204
  throw new Error(`Duplicate web app "${app.name}"`);
@@ -414,6 +432,10 @@ export class PiboPluginRegistry {
414
432
  toolNames: [...pkg.toolNames],
415
433
  pluginId: pkg.pluginId ?? pluginId,
416
434
  });
435
+ const withPluginTranscriptionProviderContext = (provider) => ({
436
+ ...provider,
437
+ pluginId: provider.pluginId ?? pluginId,
438
+ });
417
439
  return {
418
440
  registerAgentRuntimeDriver: (driver) => this.registerAgentRuntimeDriver(driver),
419
441
  registerAgentRuntimeInstance: (instance) => this.registerAgentRuntimeInstance(instance),
@@ -430,6 +452,7 @@ export class PiboPluginRegistry {
430
452
  registerGatewayAction: (action) => this.registerGatewayAction(action),
431
453
  registerChannel: (channel) => this.registerChannel(channel),
432
454
  registerAuthService: (service) => this.registerAuthService(service),
455
+ registerTranscriptionProvider: (provider) => this.registerTranscriptionProvider(withPluginTranscriptionProviderContext(provider)),
433
456
  registerWebApp: (app) => this.registerWebApp(app),
434
457
  registerCapabilityPackage: (pkg) => this.registerCapabilityPackage(withPluginPackageContext(pkg)),
435
458
  registerLoopStopCondition: (condition) => this.registerLoopStopCondition(condition, pluginId),
@@ -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?.subagentName)
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)