@pasko70/pibo 1.6.0 → 1.7.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 (31) hide show
  1. package/dist/apps/chat/chat-trace-helpers.js +47 -4
  2. package/dist/apps/chat/trace-v2.js +302 -0
  3. package/dist/apps/chat/trace.js +31 -2
  4. package/dist/apps/chat/web-app.js +368 -8
  5. package/dist/apps/chat-ui/assets/{dist-D87he9he.js → dist-BFmfAHTa.js} +1 -1
  6. package/dist/apps/chat-ui/assets/{dist-Dm6UhVM6.js → dist-BHS5hqHn.js} +1 -1
  7. package/dist/apps/chat-ui/assets/{dist-aLS3alom.js → dist-BKWZVzkX.js} +1 -1
  8. package/dist/apps/chat-ui/assets/{dist-CFoGUjhX.js → dist-BgiyRvMc.js} +1 -1
  9. package/dist/apps/chat-ui/assets/{dist-Yx8i6oQ1.js → dist-C1irMXX8.js} +1 -1
  10. package/dist/apps/chat-ui/assets/{dist-B0i7AU1O.js → dist-C3CzqW75.js} +1 -1
  11. package/dist/apps/chat-ui/assets/{dist-C-UobPQQ.js → dist-DD6PyrDV.js} +1 -1
  12. package/dist/apps/chat-ui/assets/{dist-wyhLeLW6.js → dist-DYHLT66j.js} +1 -1
  13. package/dist/apps/chat-ui/assets/{dist-DYqJWYtm.js → dist-DbMhwIF-.js} +1 -1
  14. package/dist/apps/chat-ui/assets/{dist-BwZj_mI4.js → dist-Dp3T6E_K.js} +1 -1
  15. package/dist/apps/chat-ui/assets/{dist-BbCXk-v9.js → dist-v8XQydKe.js} +1 -1
  16. package/dist/apps/chat-ui/assets/index-D8itqvK_.css +1 -0
  17. package/dist/apps/chat-ui/assets/index-DZdXJmcO.js +166 -0
  18. package/dist/apps/chat-ui/index.html +2 -2
  19. package/dist/apps/chat-vscode-web/assets/index-KKfk8l1P.js +41 -0
  20. package/dist/apps/chat-vscode-web/index.html +1 -1
  21. package/dist/apps/vscode-artifacts/latest.vsix +0 -0
  22. package/dist/apps/vscode-artifacts/pibo-vscode-ext-1.7.0.vsix +0 -0
  23. package/dist/cli.js +10 -0
  24. package/dist/data/payload-store.js +18 -9
  25. package/dist/session-ui/terminalRows.js +5 -0
  26. package/dist/web/http.js +17 -6
  27. package/package.json +1 -1
  28. package/dist/apps/chat-ui/assets/index-CNDX-4Kp.js +0 -166
  29. package/dist/apps/chat-ui/assets/index-DvBWSeIO.css +0 -1
  30. package/dist/apps/chat-vscode-web/assets/index-lA76A7Pc.js +0 -41
  31. package/dist/apps/vscode-artifacts/pibo-vscode-ext-1.6.0.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-lA76A7Pc.js"></script>
8
+ <script type="module" crossorigin src="/apps/chat-vscode/assets/index-KKfk8l1P.js"></script>
9
9
  <link rel="stylesheet" crossorigin href="/apps/chat-vscode/assets/index-B5QK07zO.css">
10
10
  </head>
11
11
  <body>
package/dist/cli.js CHANGED
@@ -365,6 +365,7 @@ export async function runPiboCli(argv = process.argv) {
365
365
  .option("--web-port <port>", "Bind the HTTP web host port", parsePort)
366
366
  .option("--gateway-port <port>", "Bind the agent-runtime gateway port", parsePort)
367
367
  .action(async (options) => {
368
+ warnIfUnsupportedGatewayNodeVersion();
368
369
  const { runWebGatewayServer } = await import("./gateway/web.js");
369
370
  const authMode = options.auth;
370
371
  if (authMode !== undefined && authMode !== "better-auth" && authMode !== "local") {
@@ -397,6 +398,15 @@ export async function runPiboCli(argv = process.argv) {
397
398
  }
398
399
  await program.parseAsync(argv);
399
400
  }
401
+ function warnIfUnsupportedGatewayNodeVersion() {
402
+ const major = Number(process.versions.node.split(".")[0]);
403
+ if (Number.isFinite(major) && major >= 24)
404
+ return;
405
+ const message = `Pibo gateway:web requires Node >=24; current runtime is ${process.version}. Upgrade Node before production gateway use.`;
406
+ if (process.env.PIBO_STRICT_NODE_ENGINE === "1")
407
+ throw new Error(message);
408
+ console.warn(`[pibo] warning: ${message}`);
409
+ }
400
410
  function printRootDiscoveryText() {
401
411
  return `pibo - agent-oriented CLI
402
412
 
@@ -3,6 +3,7 @@ import { gunzipSync, gzipSync } from "node:zlib";
3
3
  import { existsSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from "node:fs";
4
4
  import { dirname, extname, join, resolve } from "node:path";
5
5
  import { piboHomePath } from "../core/pibo-home.js";
6
+ const MAX_SYNC_PAYLOAD_GZIP_BYTES = 512 * 1024;
6
7
  export class PayloadStore {
7
8
  db;
8
9
  rootDir;
@@ -22,10 +23,13 @@ export class PayloadStore {
22
23
  this.db.prepare("UPDATE payloads SET ref_count = ref_count + 1 WHERE id = ?").run(existing.id);
23
24
  return this.getPayload(existing.id) ?? existing;
24
25
  }
25
- const compressed = gzipSync(bytes);
26
- const relativePath = buildRelativePayloadPath(sha256, contentType);
26
+ const shouldCompress = bytes.byteLength <= MAX_SYNC_PAYLOAD_GZIP_BYTES;
27
+ const encoding = shouldCompress ? "gzip" : "identity";
28
+ const bytesToStore = shouldCompress ? gzipSync(bytes) : bytes;
29
+ const compressedByteSize = shouldCompress ? bytesToStore.byteLength : null;
30
+ const relativePath = buildRelativePayloadPath(sha256, contentType, encoding);
27
31
  const absolutePath = this.rootDir === ":memory:" ? relativePath : join(this.rootDir, relativePath);
28
- writeCompressedPayloadFile(absolutePath, compressed);
32
+ writePayloadFile(absolutePath, bytesToStore);
29
33
  const id = input.id ?? `payload_${randomUUID()}`;
30
34
  this.db.prepare(`
31
35
  INSERT INTO payloads (
@@ -44,7 +48,7 @@ export class PayloadStore {
44
48
  created_at,
45
49
  last_verified_at
46
50
  ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
47
- `).run(id, sha256, "file", relativePath, contentType, "gzip", bytes.byteLength, compressed.byteLength, previewTextFromValue(input.value) ?? null, input.retentionClass, 1, "committed", createdAt, createdAt);
51
+ `).run(id, sha256, "file", relativePath, contentType, encoding, bytes.byteLength, compressedByteSize, previewTextFromValue(input.value) ?? null, input.retentionClass, 1, "committed", createdAt, createdAt);
48
52
  const stored = this.getPayload(id);
49
53
  if (!stored)
50
54
  throw new Error(`Failed to persist payload \"${id}\"`);
@@ -62,7 +66,11 @@ export class PayloadStore {
62
66
  throw new Error(`Payload \"${id}\" has no storage path`);
63
67
  const absolutePath = this.rootDir === ":memory:" ? payload.storagePath : join(this.rootDir, payload.storagePath);
64
68
  const bytes = readFileSync(absolutePath);
65
- return gunzipSync(bytes);
69
+ if (payload.encoding === "gzip")
70
+ return gunzipSync(bytes);
71
+ if (payload.encoding === "identity")
72
+ return bytes;
73
+ throw new Error(`Unsupported payload encoding \"${payload.encoding}\"`);
66
74
  }
67
75
  readPayloadText(id) {
68
76
  return Buffer.from(this.readPayloadBytes(id)).toString("utf8");
@@ -98,9 +106,10 @@ function previewTextFromValue(value) {
98
106
  const normalized = text.replace(/\s+/g, " ").trim();
99
107
  return normalized ? normalized.slice(0, 1024) : undefined;
100
108
  }
101
- function buildRelativePayloadPath(sha256, contentType) {
109
+ function buildRelativePayloadPath(sha256, contentType, encoding) {
102
110
  const extension = extensionForContentType(contentType);
103
- return join("sha256", sha256.slice(0, 2), sha256.slice(2, 4), `${sha256}.${extension}.gz`);
111
+ const suffix = encoding === "gzip" ? `${extension}.gz` : extension;
112
+ return join("sha256", sha256.slice(0, 2), sha256.slice(2, 4), `${sha256}.${suffix}`);
104
113
  }
105
114
  function extensionForContentType(contentType) {
106
115
  if (contentType.includes("json"))
@@ -109,13 +118,13 @@ function extensionForContentType(contentType) {
109
118
  return "txt";
110
119
  return "bin";
111
120
  }
112
- function writeCompressedPayloadFile(path, compressed) {
121
+ function writePayloadFile(path, bytes) {
113
122
  if (existsSync(path))
114
123
  return;
115
124
  mkdirSync(dirname(path), { recursive: true });
116
125
  const tempPath = `${path}.tmp-${randomUUID()}${extname(path)}`;
117
126
  try {
118
- writeFileSync(tempPath, compressed);
127
+ writeFileSync(tempPath, bytes);
119
128
  if (!existsSync(path))
120
129
  renameSync(tempPath, path);
121
130
  }
@@ -78,6 +78,7 @@ function debugFields(node) {
78
78
  orderSource: node.source,
79
79
  orderStreamId: node.orderKey?.streamId,
80
80
  orderStreamFrameIndex: node.orderKey?.streamFrameIndex,
81
+ payloadRefs: node.payloadRefs,
81
82
  };
82
83
  }
83
84
  function createUserMessageRow(node) {
@@ -90,6 +91,7 @@ function createUserMessageRow(node) {
90
91
  sourceNodeIds: [node.id],
91
92
  forkEntryId: node.entryId,
92
93
  output: text,
94
+ payloadRefs: node.payloadRefs,
93
95
  };
94
96
  }
95
97
  function createAssistantMessageRow(node) {
@@ -101,6 +103,7 @@ function createAssistantMessageRow(node) {
101
103
  sourceNodeIds: [node.id],
102
104
  output: stringValue(node.output) || stringValue(node.summary) || "",
103
105
  error: node.error,
106
+ payloadRefs: node.payloadRefs,
104
107
  };
105
108
  }
106
109
  function createReasoningRow(node) {
@@ -117,6 +120,7 @@ function createReasoningRow(node) {
117
120
  ],
118
121
  sourceNodeIds: [node.id],
119
122
  markdown: text,
123
+ payloadRefs: node.payloadRefs,
120
124
  };
121
125
  }
122
126
  function createToolRowCandidate(node, turnId) {
@@ -686,6 +690,7 @@ function detailItemsForGroup(candidates, kind) {
686
690
  input: candidate.row.input,
687
691
  output: candidate.row.output,
688
692
  error: candidate.row.error,
693
+ payloadRefs: candidate.row.payloadRefs,
689
694
  linkedPiboSessionId: candidate.row.linkedPiboSessionId,
690
695
  previewOmission: candidate.row.previewOmission,
691
696
  };
package/dist/web/http.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { gzipSync } from "node:zlib";
2
2
  export const MAX_WEB_REQUEST_BODY_BYTES = 4 * 1024 * 1024;
3
3
  const MIN_COMPRESS_RESPONSE_BYTES = 1024;
4
+ const MAX_SYNC_GZIP_RESPONSE_BYTES = 512 * 1024;
4
5
  const INTERNAL_SOCKET_PEER_HEADER = "x-pibo-socket-peer";
5
6
  export class PiboWebHttpError extends Error {
6
7
  statusCode;
@@ -11,12 +12,16 @@ export class PiboWebHttpError extends Error {
11
12
  }
12
13
  }
13
14
  export function responseJson(payload, init = {}) {
14
- return new Response(JSON.stringify(payload), {
15
+ const startedAt = performance.now();
16
+ const body = JSON.stringify(payload);
17
+ const serializeMs = performance.now() - startedAt;
18
+ const headers = new Headers(init.headers);
19
+ headers.set("content-type", "application/json; charset=utf-8");
20
+ headers.set("x-pibo-response-bytes", String(Buffer.byteLength(body, "utf8")));
21
+ headers.set("server-timing", appendServerTiming(headers.get("server-timing"), `json_serialize;dur=${serializeMs.toFixed(1)}`));
22
+ return new Response(body, {
15
23
  ...init,
16
- headers: {
17
- "content-type": "application/json; charset=utf-8",
18
- ...init.headers,
19
- },
24
+ headers,
20
25
  });
21
26
  }
22
27
  export function responseHtml(html, init = {}) {
@@ -76,7 +81,7 @@ export async function sendWebResponse(response, webResponse) {
76
81
  const compressEncoding = preferredResponseEncoding(response.req?.headers["accept-encoding"], webResponse);
77
82
  if (compressEncoding && webResponse.body) {
78
83
  const body = await readResponseBody(webResponse);
79
- if (body.length >= MIN_COMPRESS_RESPONSE_BYTES) {
84
+ if (body.length >= MIN_COMPRESS_RESPONSE_BYTES && body.length <= MAX_SYNC_GZIP_RESPONSE_BYTES) {
80
85
  const compressed = gzipSync(body, { level: 1 });
81
86
  headers["content-encoding"] = compressEncoding;
82
87
  headers["content-length"] = String(compressed.length);
@@ -85,6 +90,9 @@ export async function sendWebResponse(response, webResponse) {
85
90
  response.end(compressed);
86
91
  return;
87
92
  }
93
+ if (body.length > MAX_SYNC_GZIP_RESPONSE_BYTES) {
94
+ headers["x-pibo-compression-skipped"] = "sync-gzip-size-limit";
95
+ }
88
96
  response.writeHead(webResponse.status, headers);
89
97
  response.end(body);
90
98
  return;
@@ -176,3 +184,6 @@ function appendVary(existing, value) {
176
184
  normalized.push(value);
177
185
  return normalized.join(", ");
178
186
  }
187
+ function appendServerTiming(existing, value) {
188
+ return existing ? `${existing}, ${value}` : value;
189
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pasko70/pibo",
3
- "version": "1.6.0",
3
+ "version": "1.7.0",
4
4
  "type": "module",
5
5
  "imports": {
6
6
  "vscode": "./src/apps/chat-vscode/extension/src/vscode-shim.js"