@pasko70/pibo 1.4.1 → 1.4.2

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 (129) 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.1.vsix → pibo-vscode-ext-1.4.2.vsix} +0 -0
  35. package/dist/bin/pibo.js +0 -0
  36. package/dist/bin/rg.js +0 -0
  37. package/dist/cli.js +35 -35
  38. package/dist/compute/cli.js +54 -54
  39. package/dist/core/runtime.js +2 -0
  40. package/dist/core/session-router.js +1 -0
  41. package/dist/cron/cli.js +15 -15
  42. package/dist/cron/store.js +49 -49
  43. package/dist/data/cli.js +23 -23
  44. package/dist/data/event-log.js +23 -23
  45. package/dist/data/message-store.js +20 -20
  46. package/dist/data/navigation-store.js +9 -9
  47. package/dist/data/observation-store.js +4 -4
  48. package/dist/data/payload-store.js +17 -17
  49. package/dist/data/schema.js +429 -429
  50. package/dist/data/session-store.js +4 -4
  51. package/dist/data/telemetry-queries.js +54 -54
  52. package/dist/data/telemetry.js +156 -156
  53. package/dist/debug/events.js +12 -12
  54. package/dist/debug/failures.js +6 -6
  55. package/dist/debug/index.js +207 -207
  56. package/dist/debug/messages.js +6 -6
  57. package/dist/debug/pty.js +124 -124
  58. package/dist/debug/session.js +29 -29
  59. package/dist/debug/tools.js +5 -5
  60. package/dist/debug/web-snapshot-browser-scripts.js +294 -294
  61. package/dist/debug/web-streaming-browser-library.js +925 -925
  62. package/dist/debug/web-streaming-browser-scripts.js +232 -232
  63. package/dist/debug/web-streaming-provider-telemetry.js +4 -4
  64. package/dist/debug/web.js +93 -93
  65. package/dist/gateway/cli.js +19 -19
  66. package/dist/mcp/config-command.js +53 -53
  67. package/dist/mcp/index.js +21 -21
  68. package/dist/mcp/registry.js +11 -11
  69. package/dist/pi-packages/cli.js +11 -11
  70. package/dist/plugins/context-files-store.js +110 -110
  71. package/dist/plugins/context-files.js +4 -4
  72. package/dist/providers/glm.js +59 -0
  73. package/dist/ralph/cli.js +18 -18
  74. package/dist/ralph/templates.js +140 -140
  75. package/dist/reliability/store.js +226 -226
  76. package/dist/sessions/pibo-data-store.js +16 -16
  77. package/dist/sessions/sqlite-store.js +53 -53
  78. package/dist/setup/cli.js +58 -58
  79. package/dist/tools/agent-browser-wrapper.js +80 -80
  80. package/dist/tools/browser-use-cdp.js +12 -12
  81. package/dist/tools/browser-use-wrapper.js +762 -762
  82. package/dist/tools/guides.js +455 -455
  83. package/dist/tools/index.js +99 -99
  84. package/dist/tools/runtime/node-worker-source.js +205 -205
  85. package/dist/tools/runtime/python-worker-source.js +177 -177
  86. package/dist/vscode/cli.js +9 -9
  87. package/dist/web-annotations/cdp.js +900 -900
  88. package/dist/web-annotations/store.js +96 -96
  89. package/docs/README.md +23 -23
  90. package/docs/ops/install-developer-host.md +112 -112
  91. package/docs/ops/install-user-host.md +96 -96
  92. package/docs/ops/upgrade-user-to-developer-host.md +69 -69
  93. package/docs/ops/vscode-extension-release.md +160 -160
  94. package/package.json +1 -1
  95. package/skills/builtin/pi-agent-harness/SKILL.md +319 -319
  96. package/skills/builtin/pi-agent-harness/agents/openai.yaml +4 -4
  97. package/skills/builtin/pibo-docker-system/SKILL.md +170 -170
  98. package/skills/builtin/pibo-spec-writing/SKILL.md +330 -330
  99. package/skills/builtin/prd/SKILL.md +143 -143
  100. package/skills/builtin/ralph-loop/SKILL.md +359 -359
  101. package/skills/builtin/ralph-prd-json/SKILL.md +123 -123
  102. package/skills/builtin/skill-creator/LICENSE.txt +201 -201
  103. package/skills/builtin/skill-creator/SKILL.md +513 -513
  104. package/skills/builtin/skill-creator/agents/analyzer.md +274 -274
  105. package/skills/builtin/skill-creator/agents/comparator.md +202 -202
  106. package/skills/builtin/skill-creator/agents/grader.md +223 -223
  107. package/skills/builtin/skill-creator/assets/eval_review.html +146 -146
  108. package/skills/builtin/skill-creator/eval-viewer/generate_review.py +471 -471
  109. package/skills/builtin/skill-creator/eval-viewer/viewer.html +1325 -1325
  110. package/skills/builtin/skill-creator/references/schemas.md +430 -430
  111. package/skills/builtin/skill-creator/scripts/aggregate_benchmark.py +401 -401
  112. package/skills/builtin/skill-creator/scripts/generate_report.py +326 -326
  113. package/skills/builtin/skill-creator/scripts/improve_description.py +247 -247
  114. package/skills/builtin/skill-creator/scripts/package_skill.py +136 -136
  115. package/skills/builtin/skill-creator/scripts/quick_validate.py +102 -102
  116. package/skills/builtin/skill-creator/scripts/run_eval.py +310 -310
  117. package/skills/builtin/skill-creator/scripts/run_loop.py +328 -328
  118. package/skills/builtin/skill-creator/scripts/utils.py +47 -47
  119. package/skills/builtin/web-annotations/SKILL.md +93 -93
  120. package/src/mcp/LICENSE.mcp-cli +21 -21
  121. package/dist/apps/vscode-artifacts/pibo-vscode-1.3.0.vsix +0 -0
  122. package/dist/apps/vscode-artifacts/pibo-vscode-ext-1.3.3.vsix +0 -0
  123. package/dist/apps/vscode-artifacts/pibo-vscode-ext-1.3.4.vsix +0 -0
  124. package/dist/apps/vscode-artifacts/pibo-vscode-ext-1.3.5.vsix +0 -0
  125. package/dist/core/shared-app.js +0 -17
  126. package/dist/data/final-app-space-cutover-migration.js +0 -728
  127. package/dist/data/shared-app-migration.js +0 -757
  128. package/dist/session-ui/ownerViewModel.js +0 -27
  129. 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)