@pasko70/pibo 1.4.1 → 1.4.3

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 (132) hide show
  1. package/README.md +183 -183
  2. package/context/codex-base-prompt.md +148 -148
  3. package/context/compute-worker.md +23 -23
  4. package/context/pibo-compaction-prompt.md +100 -100
  5. package/context/pibo-native-tooling.md +18 -18
  6. package/context/pibo-system-prompt.md +77 -77
  7. package/dist/apps/chat/agent-store.js +82 -82
  8. package/dist/apps/chat/data/project-service.js +166 -166
  9. package/dist/apps/chat/data/read-state-service.js +18 -18
  10. package/dist/apps/chat/data/timeline-query-service.js +8 -8
  11. package/dist/apps/chat/model-catalog.js +5 -1
  12. package/dist/apps/chat/static-assets.js +853 -853
  13. package/dist/apps/chat/workflow-persistence.js +255 -255
  14. package/dist/apps/chat-ui/assets/{dist-7YaJd19a.js → dist-B2BEpL7n.js} +1 -1
  15. package/dist/apps/chat-ui/assets/{dist-CiYeO8nN.js → dist-BAGS_xkV.js} +1 -1
  16. package/dist/apps/chat-ui/assets/{dist-BIvPnn_C.js → dist-BAXNalar.js} +1 -1
  17. package/dist/apps/chat-ui/assets/{dist-CjSI6y5z.js → dist-BwUvs6Ph.js} +1 -1
  18. package/dist/apps/chat-ui/assets/{dist-Ubstha8t.js → dist-C0zsJ8II.js} +1 -1
  19. package/dist/apps/chat-ui/assets/{dist-KXCMNKIL.js → dist-C3PnEkhb.js} +1 -1
  20. package/dist/apps/chat-ui/assets/{dist-CVQU42Fn.js → dist-CYPL-B2Z.js} +1 -1
  21. package/dist/apps/chat-ui/assets/{dist-BbNE72h8.js → dist-CiDSXgtg.js} +1 -1
  22. package/dist/apps/chat-ui/assets/{dist-D7TCkoFT.js → dist-DnACFKyO.js} +1 -1
  23. package/dist/apps/chat-ui/assets/{dist-ChSZNqKE.js → dist-ZB1-ui2y.js} +1 -1
  24. package/dist/apps/chat-ui/assets/{dist-8Noo5eCN.js → dist-vKlxFkTa.js} +1 -1
  25. package/dist/apps/chat-ui/assets/{index-CmxtUVG1.js → index-0x7tuTNX.js} +3 -3
  26. package/dist/apps/chat-ui/assets/{index-C25VYnyb.css → index-B-qaya1G.css} +1 -1
  27. package/dist/apps/chat-ui/index.html +18 -18
  28. package/dist/apps/chat-ui/manifest.webmanifest +25 -25
  29. package/dist/apps/chat-ui/sw.js +41 -41
  30. package/dist/apps/chat-vscode-web/index.html +12 -12
  31. package/dist/apps/cli-ui/cliSessionsCommand.js +23 -23
  32. package/dist/apps/context-files-ui/index.html +11 -11
  33. package/dist/apps/vscode-artifacts/latest.vsix +0 -0
  34. package/dist/apps/vscode-artifacts/pibo-vscode-ext-1.4.2.vsix +0 -0
  35. package/dist/apps/vscode-artifacts/{pibo-vscode-ext-1.4.1.vsix → pibo-vscode-ext-1.4.3.vsix} +0 -0
  36. package/dist/bin/pibo.js +0 -0
  37. package/dist/bin/rg.js +0 -0
  38. package/dist/cli.js +35 -35
  39. package/dist/compute/cli.js +54 -54
  40. package/dist/core/runtime.js +2 -0
  41. package/dist/core/session-router.js +1 -0
  42. package/dist/cron/cli.js +15 -15
  43. package/dist/cron/store.js +49 -49
  44. package/dist/data/cli.js +23 -23
  45. package/dist/data/event-log.js +23 -23
  46. package/dist/data/message-store.js +20 -20
  47. package/dist/data/navigation-store.js +9 -9
  48. package/dist/data/observation-store.js +4 -4
  49. package/dist/data/payload-store.js +17 -17
  50. package/dist/data/schema.js +429 -429
  51. package/dist/data/session-store.js +4 -4
  52. package/dist/data/telemetry-queries.js +54 -54
  53. package/dist/data/telemetry.js +156 -156
  54. package/dist/debug/events.js +12 -12
  55. package/dist/debug/failures.js +6 -6
  56. package/dist/debug/index.js +207 -207
  57. package/dist/debug/messages.js +6 -6
  58. package/dist/debug/pty.js +124 -124
  59. package/dist/debug/session.js +29 -29
  60. package/dist/debug/tools.js +5 -5
  61. package/dist/debug/web-snapshot-browser-scripts.js +294 -294
  62. package/dist/debug/web-streaming-browser-library.js +925 -925
  63. package/dist/debug/web-streaming-browser-scripts.js +232 -232
  64. package/dist/debug/web-streaming-provider-telemetry.js +4 -4
  65. package/dist/debug/web.js +93 -93
  66. package/dist/gateway/cli.js +19 -19
  67. package/dist/mcp/config-command.js +53 -53
  68. package/dist/mcp/errors.js +1 -1
  69. package/dist/mcp/index.js +21 -21
  70. package/dist/mcp/output.js +47 -7
  71. package/dist/mcp/registry.js +11 -11
  72. package/dist/pi-packages/cli.js +11 -11
  73. package/dist/plugins/context-files-store.js +110 -110
  74. package/dist/plugins/context-files.js +4 -4
  75. package/dist/providers/glm.js +59 -0
  76. package/dist/ralph/cli.js +18 -18
  77. package/dist/ralph/templates.js +140 -140
  78. package/dist/reliability/store.js +226 -226
  79. package/dist/sessions/pibo-data-store.js +16 -16
  80. package/dist/sessions/sqlite-store.js +53 -53
  81. package/dist/setup/cli.js +58 -58
  82. package/dist/tools/agent-browser-wrapper.js +80 -80
  83. package/dist/tools/browser-use-cdp.js +12 -12
  84. package/dist/tools/browser-use-wrapper.js +762 -762
  85. package/dist/tools/guides.js +455 -455
  86. package/dist/tools/index.js +99 -99
  87. package/dist/tools/runtime/node-worker-source.js +205 -205
  88. package/dist/tools/runtime/python-worker-source.js +177 -177
  89. package/dist/vscode/cli.js +9 -9
  90. package/dist/web-annotations/cdp.js +900 -900
  91. package/dist/web-annotations/store.js +96 -96
  92. package/docs/README.md +23 -23
  93. package/docs/ops/install-developer-host.md +112 -112
  94. package/docs/ops/install-user-host.md +96 -96
  95. package/docs/ops/upgrade-user-to-developer-host.md +69 -69
  96. package/docs/ops/vscode-extension-release.md +160 -160
  97. package/package.json +93 -93
  98. package/skills/builtin/pi-agent-harness/SKILL.md +319 -319
  99. package/skills/builtin/pi-agent-harness/agents/openai.yaml +4 -4
  100. package/skills/builtin/pibo-docker-system/SKILL.md +170 -170
  101. package/skills/builtin/pibo-spec-writing/SKILL.md +330 -330
  102. package/skills/builtin/prd/SKILL.md +143 -143
  103. package/skills/builtin/ralph-loop/SKILL.md +359 -359
  104. package/skills/builtin/ralph-prd-json/SKILL.md +123 -123
  105. package/skills/builtin/skill-creator/LICENSE.txt +201 -201
  106. package/skills/builtin/skill-creator/SKILL.md +513 -513
  107. package/skills/builtin/skill-creator/agents/analyzer.md +274 -274
  108. package/skills/builtin/skill-creator/agents/comparator.md +202 -202
  109. package/skills/builtin/skill-creator/agents/grader.md +223 -223
  110. package/skills/builtin/skill-creator/assets/eval_review.html +146 -146
  111. package/skills/builtin/skill-creator/eval-viewer/generate_review.py +471 -471
  112. package/skills/builtin/skill-creator/eval-viewer/viewer.html +1325 -1325
  113. package/skills/builtin/skill-creator/references/schemas.md +430 -430
  114. package/skills/builtin/skill-creator/scripts/aggregate_benchmark.py +401 -401
  115. package/skills/builtin/skill-creator/scripts/generate_report.py +326 -326
  116. package/skills/builtin/skill-creator/scripts/improve_description.py +247 -247
  117. package/skills/builtin/skill-creator/scripts/package_skill.py +136 -136
  118. package/skills/builtin/skill-creator/scripts/quick_validate.py +102 -102
  119. package/skills/builtin/skill-creator/scripts/run_eval.py +310 -310
  120. package/skills/builtin/skill-creator/scripts/run_loop.py +328 -328
  121. package/skills/builtin/skill-creator/scripts/utils.py +47 -47
  122. package/skills/builtin/web-annotations/SKILL.md +93 -93
  123. package/src/mcp/LICENSE.mcp-cli +21 -21
  124. package/dist/apps/vscode-artifacts/pibo-vscode-1.3.0.vsix +0 -0
  125. package/dist/apps/vscode-artifacts/pibo-vscode-ext-1.3.3.vsix +0 -0
  126. package/dist/apps/vscode-artifacts/pibo-vscode-ext-1.3.4.vsix +0 -0
  127. package/dist/apps/vscode-artifacts/pibo-vscode-ext-1.3.5.vsix +0 -0
  128. package/dist/core/shared-app.js +0 -17
  129. package/dist/data/final-app-space-cutover-migration.js +0 -728
  130. package/dist/data/shared-app-migration.js +0 -757
  131. package/dist/session-ui/ownerViewModel.js +0 -27
  132. package/dist/shared-app.js +0 -4
@@ -1,242 +1,242 @@
1
1
  import { browserStreamingBenchmarkLibrary } from "./web-streaming-browser-library.js";
2
2
  export function streamingBenchmarkEventSourceProbeScript() {
3
- return String.raw `
4
- (() => {
5
- if (window.__piboStreamingBenchmarkEventSourceProbeInstalled || typeof window.EventSource !== 'function') return;
6
- const OriginalEventSource = window.EventSource;
7
- const probe = {
8
- createdAt: new Date().toISOString(),
9
- openCount: 0,
10
- errorCount: 0,
11
- closeCount: 0,
12
- forcedCloseCount: 0,
13
- textDropRequested: false,
14
- textDropDurationMs: undefined,
15
- textDropUntil: 0,
16
- textDropCount: 0,
17
- textDropTextEventCount: 0,
18
- events: [],
19
- connections: [],
20
- };
21
- Object.defineProperty(probe, '_instances', { value: [], enumerable: false, configurable: false });
22
- function at() { return typeof performance === 'undefined' ? Date.now() : performance.now(); }
23
- function isChatEventsUrl(url) { return String(url || '').includes('/api/chat/events'); }
24
- function pushConnection(kind, info, extra) {
25
- probe.connections.push({ t: at(), kind, url: info.url, ...(extra || {}) });
26
- if (probe.connections.length > 200) probe.connections.splice(0, probe.connections.length - 200);
27
- }
28
- function WrappedEventSource(url, init) {
29
- const events = new OriginalEventSource(url, init);
30
- const info = { url: String(url), createdAt: at(), closed: false, forcedClosing: false };
31
- probe._instances.push({ events, info });
32
- events.addEventListener('open', () => {
33
- probe.openCount += 1;
34
- pushConnection('open', info, { readyState: events.readyState });
35
- });
36
- events.addEventListener('error', () => {
37
- probe.errorCount += 1;
38
- pushConnection('error', info, { readyState: events.readyState });
39
- });
40
- events.addEventListener('pibo', (message) => {
41
- let payload;
42
- try { payload = JSON.parse(message.data); } catch {}
43
- const type = payload && typeof payload.type === 'string' ? payload.type : undefined;
44
- const record = {
45
- t: at(),
46
- url: info.url,
47
- lastEventId: message.lastEventId || '',
48
- type: typeof type === 'string' ? type : undefined,
49
- liveReplayId: payload && typeof payload.liveReplayId === 'number' && Number.isFinite(payload.liveReplayId) ? payload.liveReplayId : undefined,
50
- liveReplayReplayed: payload && payload.liveReplay && typeof payload.liveReplay.replayed === 'number' && Number.isFinite(payload.liveReplay.replayed) ? payload.liveReplay.replayed : undefined,
51
- liveReplayMissed: Boolean(payload && payload.liveReplay && payload.liveReplay.missed === true),
52
- liveReplayEvictedBefore: payload && payload.liveReplay && typeof payload.liveReplay.evictedBefore === 'number' && Number.isFinite(payload.liveReplay.evictedBefore) ? payload.liveReplay.evictedBefore : undefined,
53
- liveReplayRequestedAfter: payload && payload.liveReplay && typeof payload.liveReplay.requestedAfter === 'number' && Number.isFinite(payload.liveReplay.requestedAfter) ? payload.liveReplay.requestedAfter : undefined,
54
- liveReplayNewestAvailable: payload && payload.liveReplay && typeof payload.liveReplay.newestAvailable === 'number' && Number.isFinite(payload.liveReplay.newestAvailable) ? payload.liveReplay.newestAvailable : undefined,
55
- };
56
- probe.events.push(record);
57
- if (probe.events.length > 1000) probe.events.splice(0, probe.events.length - 1000);
58
- });
59
- const originalClose = events.close.bind(events);
60
- events.close = () => {
61
- if (!info.closed) {
62
- info.closed = true;
63
- probe.closeCount += 1;
64
- pushConnection('close', info, { forced: Boolean(info.forcedClosing), readyState: events.readyState });
65
- }
66
- return originalClose();
67
- };
68
- return events;
69
- }
70
- WrappedEventSource.prototype = OriginalEventSource.prototype;
71
- Object.setPrototypeOf(WrappedEventSource, OriginalEventSource);
72
- window.EventSource = WrappedEventSource;
73
- window.__piboStreamingBenchmarkMarkTextDropRequested = (durationMs) => {
74
- const duration = Math.max(0, Number(durationMs || 0));
75
- probe.textDropRequested = true;
76
- probe.textDropDurationMs = duration;
77
- probe.textDropUntil = at() + duration;
78
- probe.textDropCount = 0;
79
- probe.textDropTextEventCount = 0;
80
- return { durationMs: duration };
81
- };
82
- window.__piboStreamingBenchmarkForceReconnect = () => {
83
- let closed = 0;
84
- for (const entry of probe._instances) {
85
- if (!entry || !entry.events || !isChatEventsUrl(entry.info && entry.info.url)) continue;
86
- if (entry.events.readyState === 2) continue;
87
- entry.info.forcedClosing = true;
88
- probe.forcedCloseCount += 1;
89
- entry.events.close();
90
- closed += 1;
91
- }
92
- window.dispatchEvent(new Event('online'));
93
- window.dispatchEvent(new Event('focus'));
94
- return closed;
95
- };
96
- window.__piboStreamingBenchmarkEventSourceProbe = probe;
97
- window.__piboStreamingBenchmarkEventSourceProbeInstalled = true;
98
- })();
3
+ return String.raw `
4
+ (() => {
5
+ if (window.__piboStreamingBenchmarkEventSourceProbeInstalled || typeof window.EventSource !== 'function') return;
6
+ const OriginalEventSource = window.EventSource;
7
+ const probe = {
8
+ createdAt: new Date().toISOString(),
9
+ openCount: 0,
10
+ errorCount: 0,
11
+ closeCount: 0,
12
+ forcedCloseCount: 0,
13
+ textDropRequested: false,
14
+ textDropDurationMs: undefined,
15
+ textDropUntil: 0,
16
+ textDropCount: 0,
17
+ textDropTextEventCount: 0,
18
+ events: [],
19
+ connections: [],
20
+ };
21
+ Object.defineProperty(probe, '_instances', { value: [], enumerable: false, configurable: false });
22
+ function at() { return typeof performance === 'undefined' ? Date.now() : performance.now(); }
23
+ function isChatEventsUrl(url) { return String(url || '').includes('/api/chat/events'); }
24
+ function pushConnection(kind, info, extra) {
25
+ probe.connections.push({ t: at(), kind, url: info.url, ...(extra || {}) });
26
+ if (probe.connections.length > 200) probe.connections.splice(0, probe.connections.length - 200);
27
+ }
28
+ function WrappedEventSource(url, init) {
29
+ const events = new OriginalEventSource(url, init);
30
+ const info = { url: String(url), createdAt: at(), closed: false, forcedClosing: false };
31
+ probe._instances.push({ events, info });
32
+ events.addEventListener('open', () => {
33
+ probe.openCount += 1;
34
+ pushConnection('open', info, { readyState: events.readyState });
35
+ });
36
+ events.addEventListener('error', () => {
37
+ probe.errorCount += 1;
38
+ pushConnection('error', info, { readyState: events.readyState });
39
+ });
40
+ events.addEventListener('pibo', (message) => {
41
+ let payload;
42
+ try { payload = JSON.parse(message.data); } catch {}
43
+ const type = payload && typeof payload.type === 'string' ? payload.type : undefined;
44
+ const record = {
45
+ t: at(),
46
+ url: info.url,
47
+ lastEventId: message.lastEventId || '',
48
+ type: typeof type === 'string' ? type : undefined,
49
+ liveReplayId: payload && typeof payload.liveReplayId === 'number' && Number.isFinite(payload.liveReplayId) ? payload.liveReplayId : undefined,
50
+ liveReplayReplayed: payload && payload.liveReplay && typeof payload.liveReplay.replayed === 'number' && Number.isFinite(payload.liveReplay.replayed) ? payload.liveReplay.replayed : undefined,
51
+ liveReplayMissed: Boolean(payload && payload.liveReplay && payload.liveReplay.missed === true),
52
+ liveReplayEvictedBefore: payload && payload.liveReplay && typeof payload.liveReplay.evictedBefore === 'number' && Number.isFinite(payload.liveReplay.evictedBefore) ? payload.liveReplay.evictedBefore : undefined,
53
+ liveReplayRequestedAfter: payload && payload.liveReplay && typeof payload.liveReplay.requestedAfter === 'number' && Number.isFinite(payload.liveReplay.requestedAfter) ? payload.liveReplay.requestedAfter : undefined,
54
+ liveReplayNewestAvailable: payload && payload.liveReplay && typeof payload.liveReplay.newestAvailable === 'number' && Number.isFinite(payload.liveReplay.newestAvailable) ? payload.liveReplay.newestAvailable : undefined,
55
+ };
56
+ probe.events.push(record);
57
+ if (probe.events.length > 1000) probe.events.splice(0, probe.events.length - 1000);
58
+ });
59
+ const originalClose = events.close.bind(events);
60
+ events.close = () => {
61
+ if (!info.closed) {
62
+ info.closed = true;
63
+ probe.closeCount += 1;
64
+ pushConnection('close', info, { forced: Boolean(info.forcedClosing), readyState: events.readyState });
65
+ }
66
+ return originalClose();
67
+ };
68
+ return events;
69
+ }
70
+ WrappedEventSource.prototype = OriginalEventSource.prototype;
71
+ Object.setPrototypeOf(WrappedEventSource, OriginalEventSource);
72
+ window.EventSource = WrappedEventSource;
73
+ window.__piboStreamingBenchmarkMarkTextDropRequested = (durationMs) => {
74
+ const duration = Math.max(0, Number(durationMs || 0));
75
+ probe.textDropRequested = true;
76
+ probe.textDropDurationMs = duration;
77
+ probe.textDropUntil = at() + duration;
78
+ probe.textDropCount = 0;
79
+ probe.textDropTextEventCount = 0;
80
+ return { durationMs: duration };
81
+ };
82
+ window.__piboStreamingBenchmarkForceReconnect = () => {
83
+ let closed = 0;
84
+ for (const entry of probe._instances) {
85
+ if (!entry || !entry.events || !isChatEventsUrl(entry.info && entry.info.url)) continue;
86
+ if (entry.events.readyState === 2) continue;
87
+ entry.info.forcedClosing = true;
88
+ probe.forcedCloseCount += 1;
89
+ entry.events.close();
90
+ closed += 1;
91
+ }
92
+ window.dispatchEvent(new Event('online'));
93
+ window.dispatchEvent(new Event('focus'));
94
+ return closed;
95
+ };
96
+ window.__piboStreamingBenchmarkEventSourceProbe = probe;
97
+ window.__piboStreamingBenchmarkEventSourceProbeInstalled = true;
98
+ })();
99
99
  `;
100
100
  }
101
101
  export function streamingBenchmarkFixtureHtml(fixtureProfile, fixtureMix) {
102
- return `<!doctype html>
103
- <html>
104
- <head>
105
- <meta charset="utf-8">
106
- <title>Streaming Benchmark Fixture</title>
107
- <style>body{font-family:system-ui,sans-serif;margin:24px;line-height:1.4} [data-pibo-component]{white-space:pre-wrap}</style>
108
- </head>
109
- <body data-pibo-debug="chat-app">
110
- <h1>Streaming Benchmark Fixture</h1>
111
- <div data-pibo-component="MarkdownRendererHost" data-pibo-markdown-kind="assistant-message">hello</div>
112
- <script>
113
- (() => {
114
- function nowIso() { return new Date().toISOString(); }
115
- const target = document.querySelector('[data-pibo-component="MarkdownRendererHost"]');
116
- const textDeltas = [' a', ' b', ' c', ' d', ' e', ' f', ' g', ' h', ' i', ' j', ' k', ' l'];
117
- const markdownDeltas = [' **a**', ' **b**', ' **c**', ' **d**', ' **e**', ' **f**', ' **g**', ' **h**', ' **i**', ' **j**', ' **k**', ' **l**'];
118
- const gfmMarkdownDeltas = [' ~~a~~', ' ~~b~~', ' ~~c~~', ' ~~d~~', ' ~~e~~', ' ~~f~~', ' ~~g~~', ' ~~h~~', ' ~~i~~', ' ~~j~~', ' ~~k~~', ' ~~l~~'];
119
- const gfmTaskMarkdownDeltas = ['- [ ] [_**a**_](https://e.co/a)', ' [_**b**_](https://e.co/b)', ' [_**c**_](https://e.co/c)', ' [_**d**_](https://e.co/d)', ' [_**e**_](https://e.co/e)', ' [_**f**_](https://e.co/f)', ' [_**g**_](https://e.co/g)', ' [_**h**_](https://e.co/h)', ' [_**i**_](https://e.co/i)', ' [_**j**_](https://e.co/j)', ' [_**k**_](https://e.co/k)', ' [_**l**_](https://e.co/l)'];
120
- const gfmFullMarkdownDeltas = ['- [ ] [_~~a~~_](https://e.co/a)', ' [_~~b~~_](https://e.co/b)', ' [_~~c~~_](https://e.co/c)', ' [_~~d~~_](https://e.co/d)', ' [_~~e~~_](https://e.co/e)', ' [_~~f~~_](https://e.co/f)', ' [_~~g~~_](https://e.co/g)', ' [_~~h~~_](https://e.co/h)', ' [_~~i~~_](https://e.co/i)', ' [_~~j~~_](https://e.co/j)', ' [_~~k~~_](https://e.co/k)', ' [_~~l~~_](https://e.co/l)'];
121
- const cadenceMs = 100;
122
- const profile = ${JSON.stringify(fixtureProfile)};
123
- const mix = ${JSON.stringify(fixtureMix)};
124
- const deltas = mix === 'markdown' ? markdownDeltas : (mix === 'gfm-markdown' ? gfmMarkdownDeltas : (mix === 'gfm-task-markdown' ? gfmTaskMarkdownDeltas : (mix === 'gfm-full-markdown' ? gfmFullMarkdownDeltas : textDeltas)));
125
- const reasoningDeltas = mix === 'reasoning-text' ? [' think', ' plan', ' check', ' answer'] : [];
126
- const scheduleMs = buildSchedule(deltas.length, cadenceMs, profile);
127
- const reasoningScheduleMs = reasoningDeltas.map((_, index) => Math.max(10, Math.round((index + 1) * cadenceMs / 2)));
128
- let timers = [];
129
- function buildSchedule(count, cadence, timingProfile) {
130
- const delays = [];
131
- let elapsed = 0;
132
- for (let index = 0; index < count; index += 1) {
133
- let gap = cadence;
134
- if (timingProfile === 'jitter') {
135
- const jitter = [-30, 50, -20, 30, -40, 60, -10, 40, -50, 70, -20, 30][index % 12];
136
- gap = Math.max(10, cadence + jitter);
137
- } else if (timingProfile === 'burst') {
138
- gap = index > 0 && index % 3 !== 0 ? Math.max(10, Math.round(cadence / 5)) : Math.max(cadence, Math.round(cadence * 2.5));
139
- } else if (timingProfile === 'batch') {
140
- gap = index % 4 === 0 ? Math.max(cadence, Math.round(cadence * 3)) : 0;
141
- }
142
- elapsed += gap;
143
- delays.push(elapsed);
144
- }
145
- return delays;
146
- }
147
- function snapshot() {
148
- const now = nowIso();
149
- return {
150
- startedAt: now,
151
- updatedAt: now,
152
- eventCount: 0,
153
- textDeltaCount: 0,
154
- textDeltaBytes: 0,
155
- reasoningDeltaCount: 0,
156
- reasoningDeltaBytes: 0,
157
- enqueueCount: 0,
158
- flushCount: 0,
159
- flushedEventCount: 0,
160
- overlayUpdateCount: 0,
161
- overlayEventCount: 0,
162
- traceRefreshStartedCount: 0,
163
- traceRefreshCompletedCount: 0,
164
- traceRefreshFailedCount: 0,
165
- traceBaseUpdateCount: 0,
166
- traceBaseOutputLength: 0,
167
- currentOutputLength: target.textContent.length,
168
- lastDurableCursor: undefined,
169
- lastTransientLiveId: 'live:-1',
170
- };
171
- }
172
- window.__piboStreamingDebugReset = () => {
173
- for (const timer of timers) clearTimeout(timer);
174
- timers = [];
175
- target.textContent = 'hello';
176
- window.__piboStreamingDebug = snapshot();
177
- return window.__piboStreamingDebug;
178
- };
179
- window.__piboStreamingFixtureConfig = { deltaCount: deltas.length, reasoningDeltaCount: reasoningDeltas.length, cadenceMs, profile, mix, scheduleMs, reasoningScheduleMs, textBytes: deltas.join('').length, reasoningBytes: reasoningDeltas.join('').length };
180
- window.__piboStreamingFixtureStart = () => {
181
- window.__piboStreamingDebugReset();
182
- reasoningDeltas.forEach((delta, index) => {
183
- timers.push(setTimeout(() => {
184
- const debug = window.__piboStreamingDebug;
185
- const at = nowIso();
186
- debug.eventCount += 1;
187
- debug.firstEventAt ??= at;
188
- debug.firstReasoningDeltaAt ??= at;
189
- debug.reasoningDeltaCount += 1;
190
- debug.reasoningDeltaBytes += delta.length;
191
- debug.firstEnqueueAt ??= at;
192
- debug.enqueueCount += 1;
193
- debug.firstFlushAt ??= at;
194
- debug.flushCount += 1;
195
- debug.flushedEventCount += 1;
196
- debug.firstOverlayUpdateAt ??= at;
197
- debug.overlayUpdateCount += 1;
198
- debug.overlayEventCount += 1;
199
- debug.lastEventAt = at;
200
- debug.updatedAt = at;
201
- debug.lastTransientLiveId = 'live:reasoning-' + index;
202
- }, reasoningScheduleMs[index]));
203
- });
204
- deltas.forEach((delta, index) => {
205
- timers.push(setTimeout(() => {
206
- target.textContent += delta;
207
- const debug = window.__piboStreamingDebug;
208
- const at = nowIso();
209
- debug.eventCount += 1;
210
- debug.firstEventAt ??= at;
211
- debug.firstTextDeltaAt ??= at;
212
- debug.textDeltaCount += 1;
213
- debug.textDeltaBytes += delta.length;
214
- debug.firstEnqueueAt ??= at;
215
- debug.enqueueCount += 1;
216
- debug.firstFlushAt ??= at;
217
- debug.flushCount += 1;
218
- debug.flushedEventCount += 1;
219
- debug.firstOverlayUpdateAt ??= at;
220
- debug.overlayUpdateCount += 1;
221
- debug.overlayEventCount += 1;
222
- debug.currentOutputLength = target.textContent.length;
223
- debug.lastEventAt = at;
224
- debug.updatedAt = at;
225
- debug.lastTransientLiveId = 'live:' + index;
226
- }, scheduleMs[index]));
227
- });
228
- return window.__piboStreamingFixtureConfig;
229
- };
230
- window.__piboStreamingDebugReset();
231
- })();
232
- </script>
233
- </body>
102
+ return `<!doctype html>
103
+ <html>
104
+ <head>
105
+ <meta charset="utf-8">
106
+ <title>Streaming Benchmark Fixture</title>
107
+ <style>body{font-family:system-ui,sans-serif;margin:24px;line-height:1.4} [data-pibo-component]{white-space:pre-wrap}</style>
108
+ </head>
109
+ <body data-pibo-debug="chat-app">
110
+ <h1>Streaming Benchmark Fixture</h1>
111
+ <div data-pibo-component="MarkdownRendererHost" data-pibo-markdown-kind="assistant-message">hello</div>
112
+ <script>
113
+ (() => {
114
+ function nowIso() { return new Date().toISOString(); }
115
+ const target = document.querySelector('[data-pibo-component="MarkdownRendererHost"]');
116
+ const textDeltas = [' a', ' b', ' c', ' d', ' e', ' f', ' g', ' h', ' i', ' j', ' k', ' l'];
117
+ const markdownDeltas = [' **a**', ' **b**', ' **c**', ' **d**', ' **e**', ' **f**', ' **g**', ' **h**', ' **i**', ' **j**', ' **k**', ' **l**'];
118
+ const gfmMarkdownDeltas = [' ~~a~~', ' ~~b~~', ' ~~c~~', ' ~~d~~', ' ~~e~~', ' ~~f~~', ' ~~g~~', ' ~~h~~', ' ~~i~~', ' ~~j~~', ' ~~k~~', ' ~~l~~'];
119
+ const gfmTaskMarkdownDeltas = ['- [ ] [_**a**_](https://e.co/a)', ' [_**b**_](https://e.co/b)', ' [_**c**_](https://e.co/c)', ' [_**d**_](https://e.co/d)', ' [_**e**_](https://e.co/e)', ' [_**f**_](https://e.co/f)', ' [_**g**_](https://e.co/g)', ' [_**h**_](https://e.co/h)', ' [_**i**_](https://e.co/i)', ' [_**j**_](https://e.co/j)', ' [_**k**_](https://e.co/k)', ' [_**l**_](https://e.co/l)'];
120
+ const gfmFullMarkdownDeltas = ['- [ ] [_~~a~~_](https://e.co/a)', ' [_~~b~~_](https://e.co/b)', ' [_~~c~~_](https://e.co/c)', ' [_~~d~~_](https://e.co/d)', ' [_~~e~~_](https://e.co/e)', ' [_~~f~~_](https://e.co/f)', ' [_~~g~~_](https://e.co/g)', ' [_~~h~~_](https://e.co/h)', ' [_~~i~~_](https://e.co/i)', ' [_~~j~~_](https://e.co/j)', ' [_~~k~~_](https://e.co/k)', ' [_~~l~~_](https://e.co/l)'];
121
+ const cadenceMs = 100;
122
+ const profile = ${JSON.stringify(fixtureProfile)};
123
+ const mix = ${JSON.stringify(fixtureMix)};
124
+ const deltas = mix === 'markdown' ? markdownDeltas : (mix === 'gfm-markdown' ? gfmMarkdownDeltas : (mix === 'gfm-task-markdown' ? gfmTaskMarkdownDeltas : (mix === 'gfm-full-markdown' ? gfmFullMarkdownDeltas : textDeltas)));
125
+ const reasoningDeltas = mix === 'reasoning-text' ? [' think', ' plan', ' check', ' answer'] : [];
126
+ const scheduleMs = buildSchedule(deltas.length, cadenceMs, profile);
127
+ const reasoningScheduleMs = reasoningDeltas.map((_, index) => Math.max(10, Math.round((index + 1) * cadenceMs / 2)));
128
+ let timers = [];
129
+ function buildSchedule(count, cadence, timingProfile) {
130
+ const delays = [];
131
+ let elapsed = 0;
132
+ for (let index = 0; index < count; index += 1) {
133
+ let gap = cadence;
134
+ if (timingProfile === 'jitter') {
135
+ const jitter = [-30, 50, -20, 30, -40, 60, -10, 40, -50, 70, -20, 30][index % 12];
136
+ gap = Math.max(10, cadence + jitter);
137
+ } else if (timingProfile === 'burst') {
138
+ gap = index > 0 && index % 3 !== 0 ? Math.max(10, Math.round(cadence / 5)) : Math.max(cadence, Math.round(cadence * 2.5));
139
+ } else if (timingProfile === 'batch') {
140
+ gap = index % 4 === 0 ? Math.max(cadence, Math.round(cadence * 3)) : 0;
141
+ }
142
+ elapsed += gap;
143
+ delays.push(elapsed);
144
+ }
145
+ return delays;
146
+ }
147
+ function snapshot() {
148
+ const now = nowIso();
149
+ return {
150
+ startedAt: now,
151
+ updatedAt: now,
152
+ eventCount: 0,
153
+ textDeltaCount: 0,
154
+ textDeltaBytes: 0,
155
+ reasoningDeltaCount: 0,
156
+ reasoningDeltaBytes: 0,
157
+ enqueueCount: 0,
158
+ flushCount: 0,
159
+ flushedEventCount: 0,
160
+ overlayUpdateCount: 0,
161
+ overlayEventCount: 0,
162
+ traceRefreshStartedCount: 0,
163
+ traceRefreshCompletedCount: 0,
164
+ traceRefreshFailedCount: 0,
165
+ traceBaseUpdateCount: 0,
166
+ traceBaseOutputLength: 0,
167
+ currentOutputLength: target.textContent.length,
168
+ lastDurableCursor: undefined,
169
+ lastTransientLiveId: 'live:-1',
170
+ };
171
+ }
172
+ window.__piboStreamingDebugReset = () => {
173
+ for (const timer of timers) clearTimeout(timer);
174
+ timers = [];
175
+ target.textContent = 'hello';
176
+ window.__piboStreamingDebug = snapshot();
177
+ return window.__piboStreamingDebug;
178
+ };
179
+ window.__piboStreamingFixtureConfig = { deltaCount: deltas.length, reasoningDeltaCount: reasoningDeltas.length, cadenceMs, profile, mix, scheduleMs, reasoningScheduleMs, textBytes: deltas.join('').length, reasoningBytes: reasoningDeltas.join('').length };
180
+ window.__piboStreamingFixtureStart = () => {
181
+ window.__piboStreamingDebugReset();
182
+ reasoningDeltas.forEach((delta, index) => {
183
+ timers.push(setTimeout(() => {
184
+ const debug = window.__piboStreamingDebug;
185
+ const at = nowIso();
186
+ debug.eventCount += 1;
187
+ debug.firstEventAt ??= at;
188
+ debug.firstReasoningDeltaAt ??= at;
189
+ debug.reasoningDeltaCount += 1;
190
+ debug.reasoningDeltaBytes += delta.length;
191
+ debug.firstEnqueueAt ??= at;
192
+ debug.enqueueCount += 1;
193
+ debug.firstFlushAt ??= at;
194
+ debug.flushCount += 1;
195
+ debug.flushedEventCount += 1;
196
+ debug.firstOverlayUpdateAt ??= at;
197
+ debug.overlayUpdateCount += 1;
198
+ debug.overlayEventCount += 1;
199
+ debug.lastEventAt = at;
200
+ debug.updatedAt = at;
201
+ debug.lastTransientLiveId = 'live:reasoning-' + index;
202
+ }, reasoningScheduleMs[index]));
203
+ });
204
+ deltas.forEach((delta, index) => {
205
+ timers.push(setTimeout(() => {
206
+ target.textContent += delta;
207
+ const debug = window.__piboStreamingDebug;
208
+ const at = nowIso();
209
+ debug.eventCount += 1;
210
+ debug.firstEventAt ??= at;
211
+ debug.firstTextDeltaAt ??= at;
212
+ debug.textDeltaCount += 1;
213
+ debug.textDeltaBytes += delta.length;
214
+ debug.firstEnqueueAt ??= at;
215
+ debug.enqueueCount += 1;
216
+ debug.firstFlushAt ??= at;
217
+ debug.flushCount += 1;
218
+ debug.flushedEventCount += 1;
219
+ debug.firstOverlayUpdateAt ??= at;
220
+ debug.overlayUpdateCount += 1;
221
+ debug.overlayEventCount += 1;
222
+ debug.currentOutputLength = target.textContent.length;
223
+ debug.lastEventAt = at;
224
+ debug.updatedAt = at;
225
+ debug.lastTransientLiveId = 'live:' + index;
226
+ }, scheduleMs[index]));
227
+ });
228
+ return window.__piboStreamingFixtureConfig;
229
+ };
230
+ window.__piboStreamingDebugReset();
231
+ })();
232
+ </script>
233
+ </body>
234
234
  </html>`;
235
235
  }
236
236
  export function buildStreamingBenchmarkExpression(durationMs, input = {}) {
237
- return `(async () => {
238
- const options = ${JSON.stringify({ durationMs, startFixture: Boolean(input.startFixture), startBackendFixture: Boolean(input.startBackendFixture), fixtureProfile: input.fixtureProfile ?? "steady", fixtureMix: input.fixtureMix ?? "text", fixturePreludeMessages: input.fixturePreludeMessages ?? 0, simulateReconnect: Boolean(input.simulateReconnect), simulateTraceCatchup: Boolean(input.simulateTraceCatchup), simulateOverlayDrop: Boolean(input.simulateOverlayDrop), reconnectAtMs: input.simulateReconnect ? 325 : undefined, traceCatchupDropMs: input.simulateTraceCatchup ? 1300 : undefined })};
239
- ${browserStreamingBenchmarkLibrary()}
240
- return await runStreamingBenchmark(options);
237
+ return `(async () => {
238
+ const options = ${JSON.stringify({ durationMs, startFixture: Boolean(input.startFixture), startBackendFixture: Boolean(input.startBackendFixture), fixtureProfile: input.fixtureProfile ?? "steady", fixtureMix: input.fixtureMix ?? "text", fixturePreludeMessages: input.fixturePreludeMessages ?? 0, simulateReconnect: Boolean(input.simulateReconnect), simulateTraceCatchup: Boolean(input.simulateTraceCatchup), simulateOverlayDrop: Boolean(input.simulateOverlayDrop), reconnectAtMs: input.simulateReconnect ? 325 : undefined, traceCatchupDropMs: input.simulateTraceCatchup ? 1300 : undefined })};
239
+ ${browserStreamingBenchmarkLibrary()}
240
+ return await runStreamingBenchmark(options);
241
241
  })()`;
242
242
  }
@@ -41,10 +41,10 @@ export function summarizeStreamingProviderTelemetry(input) {
41
41
  };
42
42
  }
43
43
  export async function collectStreamingProviderTelemetryFromSelectedBrowserSession(client) {
44
- const selected = await client.evaluate(`(() => ({
45
- piboSessionId: document.querySelector('[data-pibo-debug="chat-shell"]')?.getAttribute('data-pibo-session-id')
46
- || document.querySelector('[data-pibo-selected-session-id]')?.getAttribute('data-pibo-selected-session-id')
47
- || undefined,
44
+ const selected = await client.evaluate(`(() => ({
45
+ piboSessionId: document.querySelector('[data-pibo-debug="chat-shell"]')?.getAttribute('data-pibo-session-id')
46
+ || document.querySelector('[data-pibo-selected-session-id]')?.getAttribute('data-pibo-selected-session-id')
47
+ || undefined,
48
48
  }))()`, 5_000).catch(() => ({}));
49
49
  const piboSessionId = isRecord(selected) && typeof selected.piboSessionId === "string" ? selected.piboSessionId : undefined;
50
50
  if (!piboSessionId)