@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
@@ -5,7 +5,7 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <meta name="theme-color" content="#101d22" />
7
7
  <title>Pibo</title>
8
- <script type="module" crossorigin src="/apps/chat-vscode/assets/index-BpurWVnX.js"></script>
8
+ <script type="module" crossorigin src="/apps/chat-vscode/assets/index-WsLm1mo3.js"></script>
9
9
  <link rel="stylesheet" crossorigin href="/apps/chat-vscode/assets/index-CF1-9PKU.css">
10
10
  </head>
11
11
  <body>
@@ -1,4 +1,3 @@
1
- const CODEX_COMPAT_SUBAGENTS = ["default", "explorer", "worker"];
2
1
  function currentDate() {
3
2
  return new Date().toISOString().slice(0, 10);
4
3
  }
@@ -15,7 +14,7 @@ export function buildCodexCompatSystemPrompt(options) {
15
14
  const compatibilityInstructions = [
16
15
  "# Codex-Compatible Runtime",
17
16
  "You are running in Pibo through the codex-compat profile. Match Codex-style tool use where the exposed Pibo tools support it, while staying truthful about implemented behavior.",
18
- "Use Pibo's pibo_run_* tools and generated pibo_subagent_* tools for parallel work, yielded runs, and child-agent lifecycle management.",
17
+ "Use Pibo's pibo_run_* and pibo_agents_* tools for parallel work, yielded runs, and delegated-agent lifecycle management.",
19
18
  "Use direct execution for normal coding tasks. If a structured planning or user-input tool is not present, ask concise questions in normal chat.",
20
19
  "When web_search is selected by the profile, use it for current or externally sourced information.",
21
20
  childInstructions,
@@ -24,7 +23,6 @@ export function buildCodexCompatSystemPrompt(options) {
24
23
  ` <shell>${options.shell}</shell>`,
25
24
  ` <current_date>${options.currentDate ?? currentDate()}</current_date>`,
26
25
  ` <timezone>${options.timezone ?? currentTimezone()}</timezone>`,
27
- ` <subagents>${CODEX_COMPAT_SUBAGENTS.join(", ")}</subagents>`,
28
26
  "</environment_context>",
29
27
  options.baseSystemPrompt,
30
28
  ];
@@ -139,11 +139,20 @@ function sanitizeNode(input, parentId, order = 0) {
139
139
  function countNodes(nodes) {
140
140
  return nodes.reduce((count, node) => count + 1 + countNodes(node.children ?? []), 0);
141
141
  }
142
- function inspectionSubagentRunner() {
142
+ function inspectionAgentsController() {
143
+ const fail = () => {
144
+ throw new Error("Context build inspection cannot execute delegated-agent tools");
145
+ };
143
146
  return {
144
- async runSubagent() {
145
- throw new Error("Context build inspection cannot execute subagents");
146
- },
147
+ sendMessage: fail,
148
+ listAgents: () => [],
149
+ observe: (input) => ({
150
+ filters: input,
151
+ observations: [],
152
+ nextAfterSequence: input.afterSequence ?? 0,
153
+ truncated: false,
154
+ }),
155
+ killAgent: fail,
147
156
  };
148
157
  }
149
158
  function inspectionRunToolController() {
@@ -196,8 +205,8 @@ function toolDefinitionSchema(definition, toolInfo) {
196
205
  function generatedOriginForTool(name, profile) {
197
206
  if (name === "runtime")
198
207
  return "Generated Pibo runtime tool selected by the profile.";
199
- if (name.startsWith("pibo_subagent_"))
200
- return "Generated subagent tool from the profile's subagent list.";
208
+ if (name.startsWith("pibo_agents_"))
209
+ return "Generated shared agent-management tool from the profile's delegated-agent list.";
201
210
  if (name.startsWith("pibo_run_"))
202
211
  return "Generated run-control tool from the pibo-run-control capability package.";
203
212
  if (PIBO_GOAL_TOOL_NAMES.includes(name))
@@ -298,7 +307,7 @@ export async function inspectPiboContextBuild(options = {}) {
298
307
  profile: inspectionProfile,
299
308
  activeModel: undefined,
300
309
  persistSession: false,
301
- subagentRunner: options.subagentRunner ?? (hasEnabledSubagents ? inspectionSubagentRunner() : undefined),
310
+ agentsController: options.agentsController ?? (hasEnabledSubagents ? inspectionAgentsController() : undefined),
302
311
  runToolController: options.runToolController ?? (hasYieldableTools ? inspectionRunToolController() : undefined),
303
312
  });
304
313
  try {
@@ -3,6 +3,7 @@ import { freemem, totalmem } from "node:os";
3
3
  import { promisify } from "node:util";
4
4
  import { getHeapStatistics } from "node:v8";
5
5
  import { collectYieldedRunHostResourceSnapshot } from "../runs/resource-isolation.js";
6
+ import { DEFAULT_GATEWAY_CONCURRENT_YIELDED_RUNS, DEFAULT_SESSION_CONCURRENT_YIELDED_RUNS, resolvePiboGatewaySettings, } from "./gateway-settings.js";
6
7
  const execFileAsync = promisify(execFile);
7
8
  const DEFAULT_POLICY = Object.freeze({
8
9
  mode: "block",
@@ -10,17 +11,19 @@ const DEFAULT_POLICY = Object.freeze({
10
11
  minHeapAvailableBytes: 64 * 1024 * 1024,
11
12
  maxRssBytes: 1536 * 1024 * 1024,
12
13
  knownDaemonWarningRssBytes: 2 * 1024 * 1024 * 1024,
13
- maxConcurrentYieldedRuns: 1,
14
+ maxConcurrentYieldedRuns: DEFAULT_GATEWAY_CONCURRENT_YIELDED_RUNS,
15
+ sessionConcurrentYieldedRuns: DEFAULT_SESSION_CONCURRENT_YIELDED_RUNS,
14
16
  yieldedRunMemoryReservationBytes: 2 * 1024 * 1024 * 1024,
15
17
  });
16
- export function resolveGatewayResourceGuardPolicy(env = process.env) {
18
+ export function resolveGatewayResourceGuardPolicy(env = process.env, gatewaySettings = resolvePiboGatewaySettings(env)) {
17
19
  return {
18
20
  mode: parseMode(env.PIBO_GATEWAY_RESOURCE_GUARD, DEFAULT_POLICY.mode),
19
21
  minFreeMemoryBytes: parseByteThreshold(env.PIBO_GATEWAY_MIN_FREE_MEMORY_BYTES, DEFAULT_POLICY.minFreeMemoryBytes),
20
22
  minHeapAvailableBytes: parseByteThreshold(env.PIBO_GATEWAY_MIN_HEAP_AVAILABLE_BYTES, DEFAULT_POLICY.minHeapAvailableBytes),
21
23
  maxRssBytes: parseByteThreshold(env.PIBO_GATEWAY_MAX_RSS_BYTES, DEFAULT_POLICY.maxRssBytes),
22
24
  knownDaemonWarningRssBytes: parseByteThreshold(env.PIBO_GATEWAY_KNOWN_DAEMON_WARNING_RSS_BYTES, DEFAULT_POLICY.knownDaemonWarningRssBytes),
23
- maxConcurrentYieldedRuns: parsePositiveInteger(env.PIBO_GATEWAY_MAX_CONCURRENT_YIELDED_RUNS, DEFAULT_POLICY.maxConcurrentYieldedRuns),
25
+ maxConcurrentYieldedRuns: gatewaySettings.maxConcurrentYieldedRuns,
26
+ sessionConcurrentYieldedRuns: gatewaySettings.sessionConcurrentYieldedRuns,
24
27
  yieldedRunMemoryReservationBytes: parseByteThreshold(env.PIBO_GATEWAY_YIELDED_RUN_MEMORY_RESERVATION_BYTES, DEFAULT_POLICY.yieldedRunMemoryReservationBytes),
25
28
  };
26
29
  }
@@ -39,7 +42,7 @@ export function collectGatewayProcessMemory() {
39
42
  };
40
43
  }
41
44
  export function buildGatewayResourceSnapshot(options = {}) {
42
- const policy = resolveGatewayResourceGuardPolicy(options.env);
45
+ const policy = resolveGatewayResourceGuardPolicy(options.env, options.gatewaySettings);
43
46
  const gateway = collectGatewayProcessMemory();
44
47
  const hostResources = options.hostResourceSnapshot ?? collectYieldedRunHostResourceSnapshot({ now: options.now });
45
48
  const host = { freeBytes: hostResources.memoryFreeBytes || freemem(), availableBytes: hostResources.memoryAvailableBytes || freemem(), totalBytes: totalmem() };
@@ -91,15 +94,30 @@ export function assertGatewayResourceAvailableForWork(workLabel, env = process.e
91
94
  }
92
95
  export class GatewayWorkAdmissionController {
93
96
  activeReservations = new Set();
94
- reserve(workLabel, env = process.env) {
95
- const snapshot = buildGatewayResourceSnapshot({ env, includeProcesses: false });
97
+ activeSessionReservations = new Map();
98
+ reserve(workLabel, options = {}) {
99
+ const snapshot = buildGatewayResourceSnapshot({
100
+ env: options.env,
101
+ gatewaySettings: options.gatewaySettings,
102
+ includeProcesses: false,
103
+ });
96
104
  const policy = snapshot.policy;
97
105
  if (snapshot.guardAction === "block") {
98
106
  throwGatewayResourceBlock(workLabel, snapshot.checks.filter((check) => check.severity === "critical").map((check) => check.message));
99
107
  }
100
108
  if (policy.mode === "block" && this.activeReservations.size >= policy.maxConcurrentYieldedRuns) {
101
109
  throwGatewayResourceBlock(workLabel, [
102
- `Active yielded runs ${this.activeReservations.size} reached the configured limit ${policy.maxConcurrentYieldedRuns}. Wait for an active run to settle or raise PIBO_GATEWAY_MAX_CONCURRENT_YIELDED_RUNS explicitly.`,
110
+ `Active yielded runs ${this.activeReservations.size} reached the configured gateway limit ${policy.maxConcurrentYieldedRuns}. Wait for an active run to settle or raise PIBO_GATEWAY_MAX_CONCURRENT_YIELDED_RUNS in Settings or the gateway environment.`,
111
+ ]);
112
+ }
113
+ const activeForSession = options.sessionId
114
+ ? this.activeSessionReservations.get(options.sessionId) ?? 0
115
+ : 0;
116
+ if (policy.mode === "block"
117
+ && options.sessionId
118
+ && activeForSession >= policy.sessionConcurrentYieldedRuns) {
119
+ throwGatewayResourceBlock(workLabel, [
120
+ `Session ${options.sessionId} has ${activeForSession} active yielded runs and reached the configured session limit ${policy.sessionConcurrentYieldedRuns}. Wait for an active run to settle or raise PIBO_SESSION_CONCURRENT_YIELDED_RUNS in Settings or the gateway environment.`,
103
121
  ]);
104
122
  }
105
123
  if (policy.mode === "block" &&
@@ -110,6 +128,8 @@ export class GatewayWorkAdmissionController {
110
128
  }
111
129
  const reservation = Symbol(workLabel);
112
130
  this.activeReservations.add(reservation);
131
+ if (options.sessionId)
132
+ this.activeSessionReservations.set(options.sessionId, activeForSession + 1);
113
133
  let released = false;
114
134
  return {
115
135
  admission: collectYieldedRunHostResourceSnapshot(),
@@ -118,6 +138,13 @@ export class GatewayWorkAdmissionController {
118
138
  return;
119
139
  released = true;
120
140
  this.activeReservations.delete(reservation);
141
+ if (!options.sessionId)
142
+ return;
143
+ const nextSessionCount = (this.activeSessionReservations.get(options.sessionId) ?? 1) - 1;
144
+ if (nextSessionCount > 0)
145
+ this.activeSessionReservations.set(options.sessionId, nextSessionCount);
146
+ else
147
+ this.activeSessionReservations.delete(options.sessionId);
121
148
  },
122
149
  };
123
150
  }
@@ -157,7 +184,7 @@ export function renderGatewayResourceSnapshotText(snapshot) {
157
184
  lines.push(`Gateway PID: ${snapshot.gateway.pid}`);
158
185
  lines.push(`Gateway memory: rss=${snapshot.gateway.rssBytes} heapUsed=${snapshot.gateway.heapUsedBytes} heapAvailable=${snapshot.gateway.heapAvailableBytes} heapLimit=${snapshot.gateway.heapLimitBytes}`);
159
186
  lines.push(`Host memory: free=${snapshot.host.freeBytes} available=${snapshot.host.availableBytes} total=${snapshot.host.totalBytes}`);
160
- lines.push(`Thresholds: minFree=${snapshot.policy.minFreeMemoryBytes} minHeapAvailable=${snapshot.policy.minHeapAvailableBytes} maxRss=${snapshot.policy.maxRssBytes} daemonWarnRss=${snapshot.policy.knownDaemonWarningRssBytes} maxYieldedRuns=${snapshot.policy.maxConcurrentYieldedRuns} yieldedRunReservation=${snapshot.policy.yieldedRunMemoryReservationBytes}`);
187
+ lines.push(`Thresholds: minFree=${snapshot.policy.minFreeMemoryBytes} minHeapAvailable=${snapshot.policy.minHeapAvailableBytes} maxRss=${snapshot.policy.maxRssBytes} daemonWarnRss=${snapshot.policy.knownDaemonWarningRssBytes} maxYieldedRuns=${snapshot.policy.maxConcurrentYieldedRuns} sessionYieldedRuns=${snapshot.policy.sessionConcurrentYieldedRuns} yieldedRunReservation=${snapshot.policy.yieldedRunMemoryReservationBytes}`);
161
188
  lines.push(`Related processes: children=${snapshot.processes.children.length} knownDaemons=${snapshot.processes.knownDaemons.length} processList=${snapshot.processes.available ? "available" : "unavailable"}`);
162
189
  lines.push(`Yielded-run cgroups: units=${snapshot.yieldedRunUnits.units.length} systemdList=${snapshot.yieldedRunUnits.available ? "available" : "unavailable"}`);
163
190
  if (snapshot.processes.error)
@@ -242,12 +269,6 @@ function parseByteThreshold(value, fallback) {
242
269
  const parsed = Number(value);
243
270
  return Number.isFinite(parsed) && parsed >= 0 ? Math.floor(parsed) : fallback;
244
271
  }
245
- function parsePositiveInteger(value, fallback) {
246
- if (value === undefined || value.trim() === "")
247
- return fallback;
248
- const parsed = Number(value);
249
- return Number.isInteger(parsed) && parsed > 0 ? parsed : fallback;
250
- }
251
272
  function throwGatewayResourceBlock(workLabel, reasons) {
252
273
  throw new Error(`Gateway resource guard blocked ${workLabel} before starting: ${reasons.join("; ")}`);
253
274
  }
@@ -0,0 +1,64 @@
1
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
2
+ import { dirname } from "node:path";
3
+ import { piboHomePath } from "./pibo-home.js";
4
+ export const DEFAULT_GATEWAY_CONCURRENT_YIELDED_RUNS = 50;
5
+ export const DEFAULT_SESSION_CONCURRENT_YIELDED_RUNS = 10;
6
+ export const DEFAULT_PIBO_GATEWAY_SETTINGS_PATH = "gateway-settings.json";
7
+ export function loadPiboGatewaySettings(env = process.env) {
8
+ return sanitizePiboGatewaySettings(readState().settings, env);
9
+ }
10
+ export function updatePiboGatewaySettings(patch, env = process.env) {
11
+ const state = readState();
12
+ const current = sanitizePiboGatewaySettings(state.settings, env);
13
+ const next = sanitizePiboGatewaySettings({ ...current, ...patch }, env);
14
+ state.settings = next;
15
+ writeState(state);
16
+ return next;
17
+ }
18
+ export function resolvePiboGatewaySettings(env = process.env) {
19
+ return {
20
+ maxConcurrentYieldedRuns: parsePositiveInteger(env.PIBO_GATEWAY_MAX_CONCURRENT_YIELDED_RUNS, DEFAULT_GATEWAY_CONCURRENT_YIELDED_RUNS),
21
+ sessionConcurrentYieldedRuns: parsePositiveInteger(env.PIBO_SESSION_CONCURRENT_YIELDED_RUNS, DEFAULT_SESSION_CONCURRENT_YIELDED_RUNS),
22
+ };
23
+ }
24
+ export function sanitizePiboGatewaySettings(value, env = process.env) {
25
+ const raw = value && typeof value === "object" && !Array.isArray(value)
26
+ ? value
27
+ : {};
28
+ const defaults = resolvePiboGatewaySettings(env);
29
+ return {
30
+ maxConcurrentYieldedRuns: sanitizeConcurrentYieldedRuns(raw.maxConcurrentYieldedRuns)
31
+ ?? defaults.maxConcurrentYieldedRuns,
32
+ sessionConcurrentYieldedRuns: sanitizeConcurrentYieldedRuns(raw.sessionConcurrentYieldedRuns)
33
+ ?? defaults.sessionConcurrentYieldedRuns,
34
+ };
35
+ }
36
+ export function sanitizeConcurrentYieldedRuns(value) {
37
+ if (typeof value !== "number" && typeof value !== "string")
38
+ return undefined;
39
+ const parsed = typeof value === "number" ? value : Number(value.trim());
40
+ return Number.isSafeInteger(parsed) && parsed > 0 ? parsed : undefined;
41
+ }
42
+ function parsePositiveInteger(value, fallback) {
43
+ return sanitizeConcurrentYieldedRuns(value) ?? fallback;
44
+ }
45
+ function readState() {
46
+ const path = piboHomePath(DEFAULT_PIBO_GATEWAY_SETTINGS_PATH);
47
+ if (!existsSync(path))
48
+ return {};
49
+ try {
50
+ const parsed = JSON.parse(readFileSync(path, "utf-8"));
51
+ const raw = parsed && typeof parsed === "object" && !Array.isArray(parsed)
52
+ ? parsed
53
+ : {};
54
+ return { settings: raw.settings };
55
+ }
56
+ catch {
57
+ return {};
58
+ }
59
+ }
60
+ function writeState(state) {
61
+ const path = piboHomePath(DEFAULT_PIBO_GATEWAY_SETTINGS_PATH);
62
+ mkdirSync(dirname(path), { recursive: true });
63
+ writeFileSync(path, `${JSON.stringify(state, null, 2)}\n`);
64
+ }