@pasko70/pibo 1.11.2 → 1.11.4
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.
- package/dist/apps/chat/data/chat-data-mappers.js +18 -6
- package/dist/apps/chat/loop-api.js +22 -6
- package/dist/apps/chat-ui/assets/dist-B5PTVnox.js +1 -0
- package/dist/apps/chat-ui/assets/dist-B5ZAfwf5.js +1 -0
- package/dist/apps/{context-files-ui/assets/dist-ZsBbt0uY.js → chat-ui/assets/dist-BXjLdcn6.js} +1 -1
- package/dist/apps/{context-files-ui/assets/dist-DqYw0LH7.js → chat-ui/assets/dist-BeKdUsyg.js} +1 -1
- package/dist/apps/chat-ui/assets/dist-BkUONE3N.js +1 -0
- package/dist/apps/{context-files-ui/assets/dist-vnd7PMu3.js → chat-ui/assets/dist-BtQ20SMU.js} +1 -1
- package/dist/apps/{context-files-ui/assets/dist-DPG9jOQ-.js → chat-ui/assets/dist-CNv02m3N.js} +1 -1
- package/dist/apps/{context-files-ui/assets/dist-Dp5AH00p.js → chat-ui/assets/dist-CSBDio7C.js} +1 -1
- package/dist/apps/{context-files-ui/assets/dist-kmsvtHkH.js → chat-ui/assets/dist-CjXSEbsr.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-SVPsM5Oi.js → dist-D1KyNDg5.js} +2 -2
- package/dist/apps/{context-files-ui/assets/dist-DK01b7x4.js → chat-ui/assets/dist-D9B41N2f.js} +1 -1
- package/dist/apps/chat-ui/assets/dist-DKoyMSNr.js +1 -0
- package/dist/apps/chat-ui/assets/dist-DLMjd26T.js +1 -0
- package/dist/apps/chat-ui/assets/dist-DotDq_kD.js +1 -0
- package/dist/apps/chat-ui/assets/dist-QQuDy4KA.js +1 -0
- package/dist/apps/{context-files-ui/assets/dist-BOiGdrG-.js → chat-ui/assets/dist-TAhl1jC0.js} +1 -1
- package/dist/apps/{context-files-ui/assets/dist-TbjAhles.js → chat-ui/assets/dist-TS4EA6YQ.js} +1 -1
- package/dist/apps/{context-files-ui/assets/dist-TF5iO5ML.js → chat-ui/assets/dist-yjwDcRbw.js} +1 -1
- package/dist/apps/chat-ui/assets/{dockerfile-CUaqzcqp.js → dockerfile-CJb2sekW.js} +1 -1
- package/dist/apps/chat-ui/assets/{factor-C2tAxNob.js → factor-B2EMQZkP.js} +1 -1
- package/dist/apps/chat-ui/assets/index-BoRl0OB_.js +473 -0
- package/dist/apps/chat-ui/assets/index-aTOOomMF.css +1 -0
- package/dist/apps/chat-ui/assets/{nsis-SMDwKltR.js → nsis-DOo3SJmd.js} +1 -1
- package/dist/apps/chat-ui/assets/{pug-Bo3wfL-f.js → pug-QU72BPAa.js} +1 -1
- package/dist/apps/chat-ui/index.html +3 -4
- package/dist/apps/chat-vscode-web/assets/index-DGcSd2ZH.js +275 -0
- package/dist/apps/chat-vscode-web/assets/{index-Bf2JvJ9z.css → index-Dupu1DzQ.css} +1 -1
- package/dist/apps/chat-vscode-web/index.html +2 -2
- package/dist/apps/context-files-ui/assets/dist-B07Whoa6.js +1 -0
- package/dist/apps/context-files-ui/assets/dist-BACxmdQ2.js +9 -0
- package/dist/apps/context-files-ui/assets/dist-BFlEjppv.js +1 -0
- package/dist/apps/{chat-ui/assets/dist-CuGiEm5l.js → context-files-ui/assets/dist-BQK_wUMR.js} +2 -2
- package/dist/apps/context-files-ui/assets/dist-CigbyRK5.js +1 -0
- package/dist/apps/context-files-ui/assets/dist-D68eIqmX.js +1 -0
- package/dist/apps/context-files-ui/assets/dist-DT9QkgTN.js +1 -0
- package/dist/apps/context-files-ui/assets/dist-De6eI3Cr.js +1 -0
- package/dist/apps/context-files-ui/assets/dist-Dtv5S2qd.js +11 -0
- package/dist/apps/context-files-ui/assets/dist-TG9QLHKj.js +1 -0
- package/dist/apps/context-files-ui/assets/index-B5j33Q2B.js +438 -0
- package/dist/apps/context-files-ui/assets/{index-B92tL3Pp.css → index-CukPnd6A.css} +1 -1
- package/dist/apps/context-files-ui/index.html +2 -2
- package/dist/apps/vscode-artifacts/latest.vsix +0 -0
- package/dist/apps/vscode-artifacts/pibo-vscode-ext-1.11.4.vsix +0 -0
- package/dist/core/routed-session.js +143 -24
- package/dist/core/runtime-telemetry.js +90 -0
- package/dist/core/runtime.js +1 -0
- package/dist/core/session-router.js +262 -50
- package/dist/debug/web-render-order-analysis.js +307 -0
- package/dist/debug/web-snapshot-browser-scripts.js +10 -1
- package/dist/debug/web-streaming-benchmark-analysis.js +12 -1
- package/dist/debug/web-streaming-browser-library.js +268 -58
- package/dist/debug/web-streaming-report.js +24 -0
- package/dist/debug/web.js +14 -3
- package/dist/gateway/server.js +2 -0
- package/dist/gateway/web.js +1 -0
- package/dist/loops/accounting.js +8 -1
- package/dist/loops/cli.js +1 -1
- package/dist/loops/service.js +167 -27
- package/dist/loops/store.js +229 -17
- package/dist/loops/tools.js +30 -9
- package/dist/plugins/context-files.js +3 -1
- package/dist/runs/registry.js +19 -0
- package/package.json +1 -1
- package/dist/apps/chat-ui/assets/dist--55mTWk3.js +0 -1
- package/dist/apps/chat-ui/assets/dist-BBVpFHAq.js +0 -11
- package/dist/apps/chat-ui/assets/dist-BXyVMdHv.js +0 -1
- package/dist/apps/chat-ui/assets/dist-BZ39rB1W.js +0 -1
- package/dist/apps/chat-ui/assets/dist-BiGfVaXN.js +0 -1
- package/dist/apps/chat-ui/assets/dist-BsedZGJo.js +0 -1
- package/dist/apps/chat-ui/assets/dist-C5YJOwhH.js +0 -1
- package/dist/apps/chat-ui/assets/dist-C5oXtFSP.js +0 -1
- package/dist/apps/chat-ui/assets/dist-CCGKu-Wj.js +0 -9
- package/dist/apps/chat-ui/assets/dist-CE0MvPLM.js +0 -1
- package/dist/apps/chat-ui/assets/dist-CKM5j-iy.js +0 -1
- package/dist/apps/chat-ui/assets/dist-CUp9us2q.js +0 -1
- package/dist/apps/chat-ui/assets/dist-CZ9T4Cly.js +0 -1
- package/dist/apps/chat-ui/assets/dist-DBnh8gXR.js +0 -1
- package/dist/apps/chat-ui/assets/dist-DSKQpPaz.js +0 -1
- package/dist/apps/chat-ui/assets/dist-DeOnZ-pw.js +0 -23
- package/dist/apps/chat-ui/assets/dist-DnQYnLQS.js +0 -1
- package/dist/apps/chat-ui/assets/dist-VT4x40uL.js +0 -6
- package/dist/apps/chat-ui/assets/dist-Zqt9kNG9.js +0 -1
- package/dist/apps/chat-ui/assets/dist-tGfufz3b.js +0 -1
- package/dist/apps/chat-ui/assets/dist-xtnVygdr.js +0 -1
- package/dist/apps/chat-ui/assets/index-DNeE4HrG.css +0 -1
- package/dist/apps/chat-ui/assets/index-vcg8JNj9.js +0 -173
- package/dist/apps/chat-ui/assets/rolldown-runtime-S-ySWqyJ.js +0 -1
- package/dist/apps/chat-vscode-web/assets/index-DVlCO7v_.js +0 -41
- package/dist/apps/context-files-ui/assets/index-BhAWD3dv.js +0 -202
- package/dist/apps/vscode-artifacts/pibo-vscode-ext-1.11.2.vsix +0 -0
- /package/dist/apps/chat-ui/assets/{apl-BxEMbctQ.js → apl-14BqhLYK.js} +0 -0
- /package/dist/apps/chat-ui/assets/{asciiarmor-eFjeGRuZ.js → asciiarmor-WLvjqI7d.js} +0 -0
- /package/dist/apps/chat-ui/assets/{asn1-Cfx-0pt9.js → asn1-Bg4FbdCg.js} +0 -0
- /package/dist/apps/chat-ui/assets/{asterisk-B5BHTsBr.js → asterisk-B2MO-X4d.js} +0 -0
- /package/dist/apps/chat-ui/assets/{brainfuck-CAA2xofr.js → brainfuck-CV9kufud.js} +0 -0
- /package/dist/apps/chat-ui/assets/{clike-BoDCOLzN.js → clike-CjmcUpt6.js} +0 -0
- /package/dist/apps/chat-ui/assets/{clojure-kVFSWX0o.js → clojure-De3QGfx6.js} +0 -0
- /package/dist/apps/chat-ui/assets/{cmake-BUPAhezI.js → cmake-i2VDNaRq.js} +0 -0
- /package/dist/apps/chat-ui/assets/{cobol-BfgHZgup.js → cobol-BwO6DF08.js} +0 -0
- /package/dist/apps/chat-ui/assets/{coffeescript-G1Pe_1AZ.js → coffeescript-BtivDvRz.js} +0 -0
- /package/dist/apps/chat-ui/assets/{commonlisp-B3N0CjHn.js → commonlisp-DFkEQdLP.js} +0 -0
- /package/dist/apps/chat-ui/assets/{crystal-C15ndaGM.js → crystal-CU0NkcVL.js} +0 -0
- /package/dist/apps/chat-ui/assets/{css-BqOeyZOV.js → css-CbMZAQ1W.js} +0 -0
- /package/dist/apps/chat-ui/assets/{cypher-KjIKv-wW.js → cypher-Dke5QOzv.js} +0 -0
- /package/dist/apps/chat-ui/assets/{d-BlT5AEC-.js → d-TPqSVaHM.js} +0 -0
- /package/dist/apps/chat-ui/assets/{diff-oF98tbqj.js → diff-B365LSoZ.js} +0 -0
- /package/dist/apps/chat-ui/assets/{dtd-VCA9yr61.js → dtd-CBMymJ7O.js} +0 -0
- /package/dist/apps/chat-ui/assets/{dylan-O-V5Dw5W.js → dylan-08Azy1NK.js} +0 -0
- /package/dist/apps/chat-ui/assets/{ebnf-SPmdBkvT.js → ebnf-Dkum_1J8.js} +0 -0
- /package/dist/apps/chat-ui/assets/{ecl-ChfCttfI.js → ecl-dhxjHL8y.js} +0 -0
- /package/dist/apps/chat-ui/assets/{eiffel-cB9EbjeN.js → eiffel-C446m6dI.js} +0 -0
- /package/dist/apps/chat-ui/assets/{elm-BTiVflBU.js → elm-po1E9de0.js} +0 -0
- /package/dist/apps/chat-ui/assets/{erlang-egf0TXFm.js → erlang-BD5LkVkR.js} +0 -0
- /package/dist/apps/chat-ui/assets/{fcl-BiCjh1tj.js → fcl-DkEOamHd.js} +0 -0
- /package/dist/apps/chat-ui/assets/{forth-C4kDGW6u.js → forth-dCg2_HVB.js} +0 -0
- /package/dist/apps/chat-ui/assets/{fortran-DzkLaPnd.js → fortran-3ZpXLFh1.js} +0 -0
- /package/dist/apps/chat-ui/assets/{gas-DMOxskQF.js → gas-DMmxLZRI.js} +0 -0
- /package/dist/apps/chat-ui/assets/{gherkin-BPxBpp-k.js → gherkin-DUSFg2R6.js} +0 -0
- /package/dist/apps/chat-ui/assets/{groovy-CkEnc0ZY.js → groovy-Cmduloe1.js} +0 -0
- /package/dist/apps/chat-ui/assets/{haskell-Dadpo9-w.js → haskell-Cyr255R9.js} +0 -0
- /package/dist/apps/chat-ui/assets/{haxe-CDNZL9MW.js → haxe-BJVKtprM.js} +0 -0
- /package/dist/apps/chat-ui/assets/{http-jy9Zxxt3.js → http-DszHFpc-.js} +0 -0
- /package/dist/apps/chat-ui/assets/{idl-CGSB6iiy.js → idl-Cati9Nrv.js} +0 -0
- /package/dist/apps/chat-ui/assets/{javascript-DSlzRUd8.js → javascript-C5pDVaoP.js} +0 -0
- /package/dist/apps/chat-ui/assets/{julia-DTiF9v6R.js → julia-DlqY1cTU.js} +0 -0
- /package/dist/apps/chat-ui/assets/{livescript-Ci8Xxna6.js → livescript-C6p8-2W1.js} +0 -0
- /package/dist/apps/chat-ui/assets/{lua-eVxIrt9t.js → lua-BxuTHaF7.js} +0 -0
- /package/dist/apps/chat-ui/assets/{mathematica-Da3grj36.js → mathematica-nDHZUMJT.js} +0 -0
- /package/dist/apps/chat-ui/assets/{mbox-BWBMSafM.js → mbox-DAaR0Hcz.js} +0 -0
- /package/dist/apps/chat-ui/assets/{mirc-CtHu9S1B.js → mirc-CCA0FRfl.js} +0 -0
- /package/dist/apps/chat-ui/assets/{mllike-wTFlPWXS.js → mllike-Cw3Iccsb.js} +0 -0
- /package/dist/apps/chat-ui/assets/{modelica-cKbQ0UXu.js → modelica-Czx80fNR.js} +0 -0
- /package/dist/apps/chat-ui/assets/{mscgen-C5pXQCMK.js → mscgen-BmfuTbzG.js} +0 -0
- /package/dist/apps/chat-ui/assets/{mumps-CKBHkOQq.js → mumps-Ds_ZaumL.js} +0 -0
- /package/dist/apps/chat-ui/assets/{nginx-B00AiQel.js → nginx-D9M2PQ4U.js} +0 -0
- /package/dist/apps/chat-ui/assets/{ntriples-B_36EBV0.js → ntriples-DLHGTvHs.js} +0 -0
- /package/dist/apps/chat-ui/assets/{octave-BXPjzAif.js → octave-8jj96JiC.js} +0 -0
- /package/dist/apps/chat-ui/assets/{oz-Dedpat1M.js → oz-BmMq7iC4.js} +0 -0
- /package/dist/apps/chat-ui/assets/{pascal-CMcUg72K.js → pascal-BgMr6XpT.js} +0 -0
- /package/dist/apps/chat-ui/assets/{perl-DoVTbnzt.js → perl-D6YJObi_.js} +0 -0
- /package/dist/apps/chat-ui/assets/{pig-CULXT1YV.js → pig-nx7uchs8.js} +0 -0
- /package/dist/apps/chat-ui/assets/{powershell-Cv5Uhf6b.js → powershell-B4IPkVxR.js} +0 -0
- /package/dist/apps/chat-ui/assets/{properties-CQ1C2P-M.js → properties-CoavQdLC.js} +0 -0
- /package/dist/apps/chat-ui/assets/{protobuf-SRlvzrl6.js → protobuf-D5EWhcmc.js} +0 -0
- /package/dist/apps/chat-ui/assets/{puppet-ClSqCGj6.js → puppet-B_0GFuyD.js} +0 -0
- /package/dist/apps/chat-ui/assets/{python-C2_X1GpX.js → python-Cs7sNzy_.js} +0 -0
- /package/dist/apps/chat-ui/assets/{q-B_6Gdyzl.js → q-BIB9pPtI.js} +0 -0
- /package/dist/apps/chat-ui/assets/{r-BD07NGED.js → r-CN5s4f3o.js} +0 -0
- /package/dist/apps/chat-ui/assets/{rpm-CRu5Z2Jl.js → rpm-Ct_Ck8mQ.js} +0 -0
- /package/dist/apps/chat-ui/assets/{ruby-dZPnOz8h.js → ruby-BVPradRk.js} +0 -0
- /package/dist/apps/chat-ui/assets/{sas-S2t8_sDI.js → sas-DN4j74IF.js} +0 -0
- /package/dist/apps/chat-ui/assets/{scheme-WcyFWLW2.js → scheme-CvNgHAnh.js} +0 -0
- /package/dist/apps/chat-ui/assets/{shell-DUelnYSh.js → shell-BjiMLAaM.js} +0 -0
- /package/dist/apps/chat-ui/assets/{sieve-jDjlVhNh.js → sieve-C2U1O5Z4.js} +0 -0
- /package/dist/apps/chat-ui/assets/{simple-mode-CL04yRVp.js → simple-mode-DnMbQuKW.js} +0 -0
- /package/dist/apps/chat-ui/assets/{smalltalk-ddWDYy10.js → smalltalk-DkYwYufV.js} +0 -0
- /package/dist/apps/chat-ui/assets/{solr-C7rQhLuW.js → solr-BopnSD-v.js} +0 -0
- /package/dist/apps/chat-ui/assets/{sparql--fPCCgVd.js → sparql-Cpg3YQfd.js} +0 -0
- /package/dist/apps/chat-ui/assets/{spreadsheet-DjthqD5G.js → spreadsheet-kRxtVt9J.js} +0 -0
- /package/dist/apps/chat-ui/assets/{sql-D_dieYbr.js → sql-DYI2GwJR.js} +0 -0
- /package/dist/apps/chat-ui/assets/{stex-rHcFYcA0.js → stex-BCRT8IJ3.js} +0 -0
- /package/dist/apps/chat-ui/assets/{stylus-DxF70RNr.js → stylus-CARoeVE9.js} +0 -0
- /package/dist/apps/chat-ui/assets/{swift-T0hDoOb-.js → swift-DKNaLAK6.js} +0 -0
- /package/dist/apps/chat-ui/assets/{tcl-Dlzy1mPk.js → tcl-CQyXkgMH.js} +0 -0
- /package/dist/apps/chat-ui/assets/{textile-Dy5rFZe5.js → textile-Yg_UWn-t.js} +0 -0
- /package/dist/apps/chat-ui/assets/{tiddlywiki-DQP1OymS.js → tiddlywiki-dqVbkfX4.js} +0 -0
- /package/dist/apps/chat-ui/assets/{tiki-0vOj3DB2.js → tiki-CC_ic8g0.js} +0 -0
- /package/dist/apps/chat-ui/assets/{toml-DEltN0lI.js → toml-B7gGzVkJ.js} +0 -0
- /package/dist/apps/chat-ui/assets/{troff-CRbBpEqY.js → troff-Bq3z6oAu.js} +0 -0
- /package/dist/apps/chat-ui/assets/{ttcn-M5q1nLKg.js → ttcn-GvRgs2AT.js} +0 -0
- /package/dist/apps/chat-ui/assets/{ttcn-cfg-Rmw9NWq9.js → ttcn-cfg-CGCXz7Vo.js} +0 -0
- /package/dist/apps/chat-ui/assets/{turtle-BCDWhJK0.js → turtle-CwIpz2yy.js} +0 -0
- /package/dist/apps/chat-ui/assets/{vb-QQ7LGlOz.js → vb-BmcHUM2C.js} +0 -0
- /package/dist/apps/chat-ui/assets/{vbscript-BiSEdUzz.js → vbscript-Cs9dylre.js} +0 -0
- /package/dist/apps/chat-ui/assets/{velocity-CzMg5_6w.js → velocity-CBWU0VCy.js} +0 -0
- /package/dist/apps/chat-ui/assets/{verilog-BJOO83gk.js → verilog-DVCHmufx.js} +0 -0
- /package/dist/apps/chat-ui/assets/{vhdl-ed4zAZAA.js → vhdl-BGDk4f1d.js} +0 -0
- /package/dist/apps/chat-ui/assets/{webidl-Ddy6hbV6.js → webidl-egXQEWlC.js} +0 -0
- /package/dist/apps/chat-ui/assets/{xquery-Bw1zwhh6.js → xquery-5f0hn7cg.js} +0 -0
- /package/dist/apps/chat-ui/assets/{yacas-DZdTXy3s.js → yacas-DNs9XkmQ.js} +0 -0
- /package/dist/apps/chat-ui/assets/{z80-DMG02_YV.js → z80-B7Dfb4UO.js} +0 -0
|
@@ -33,8 +33,17 @@ function stats(values) {
|
|
|
33
33
|
function fetchWithTimeout(url, init, timeoutMs) {
|
|
34
34
|
if (typeof AbortController === 'undefined') return fetch(url, init);
|
|
35
35
|
const controller = new AbortController();
|
|
36
|
+
const externalSignal = init && init.signal;
|
|
37
|
+
const abortFromExternal = () => controller.abort();
|
|
38
|
+
if (externalSignal) {
|
|
39
|
+
if (externalSignal.aborted) controller.abort();
|
|
40
|
+
else externalSignal.addEventListener('abort', abortFromExternal, { once: true });
|
|
41
|
+
}
|
|
36
42
|
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
37
|
-
return fetch(url, { ...init, signal: controller.signal }).finally(() =>
|
|
43
|
+
return fetch(url, { ...init, signal: controller.signal }).finally(() => {
|
|
44
|
+
clearTimeout(timer);
|
|
45
|
+
if (externalSignal) externalSignal.removeEventListener('abort', abortFromExternal);
|
|
46
|
+
});
|
|
38
47
|
}
|
|
39
48
|
function installOverlayDropSimulation(enabled) {
|
|
40
49
|
if (!enabled) {
|
|
@@ -107,6 +116,8 @@ function createSseProbe(piboSessionId, startedAt) {
|
|
|
107
116
|
let buffer = '';
|
|
108
117
|
let stopped = false;
|
|
109
118
|
let finished = false;
|
|
119
|
+
let reader;
|
|
120
|
+
let stoppedResult;
|
|
110
121
|
const controller = typeof AbortController === 'undefined' ? undefined : new AbortController();
|
|
111
122
|
const decoder = typeof TextDecoder === 'undefined' ? undefined : new TextDecoder();
|
|
112
123
|
const encoder = typeof TextEncoder === 'undefined' ? undefined : new TextEncoder();
|
|
@@ -169,7 +180,7 @@ function createSseProbe(piboSessionId, startedAt) {
|
|
|
169
180
|
response.headers.forEach((value, key) => { result.headers[key] = value; });
|
|
170
181
|
if (!response.body || typeof response.body.getReader !== 'function') throw new Error('ReadableStream unavailable');
|
|
171
182
|
result.installed = true;
|
|
172
|
-
|
|
183
|
+
reader = response.body.getReader();
|
|
173
184
|
while (true) {
|
|
174
185
|
const next = await reader.read();
|
|
175
186
|
if (next.done) break;
|
|
@@ -197,21 +208,33 @@ function createSseProbe(piboSessionId, startedAt) {
|
|
|
197
208
|
if (stopped || (error && error.name === 'AbortError')) result.aborted = true;
|
|
198
209
|
else result.errors.push(String(error && error.message ? error.message : error));
|
|
199
210
|
} finally {
|
|
211
|
+
reader = undefined;
|
|
200
212
|
finished = true;
|
|
201
213
|
finalize();
|
|
202
214
|
}
|
|
203
215
|
})();
|
|
204
216
|
return {
|
|
205
|
-
result,
|
|
217
|
+
get result() { return stoppedResult || result; },
|
|
206
218
|
stop: async () => {
|
|
219
|
+
if (stoppedResult) return stoppedResult;
|
|
207
220
|
stopped = true;
|
|
208
221
|
if (controller) controller.abort();
|
|
209
|
-
|
|
222
|
+
try { if (reader && typeof reader.cancel === 'function') void Promise.resolve(reader.cancel()).catch(() => {}); } catch {}
|
|
223
|
+
let stopTimeout;
|
|
224
|
+
try {
|
|
225
|
+
await Promise.race([
|
|
226
|
+
done.catch(() => {}),
|
|
227
|
+
new Promise((resolve) => { stopTimeout = setTimeout(resolve, 2500); }),
|
|
228
|
+
]);
|
|
229
|
+
} finally {
|
|
230
|
+
if (stopTimeout !== undefined) clearTimeout(stopTimeout);
|
|
231
|
+
}
|
|
210
232
|
if (!finished) {
|
|
211
233
|
result.aborted = true;
|
|
212
234
|
result.errors.push('stop timeout after abort');
|
|
213
235
|
}
|
|
214
|
-
|
|
236
|
+
stoppedResult = cloneDebugSnapshot(finalize()) || { ...finalize() };
|
|
237
|
+
return stoppedResult;
|
|
215
238
|
},
|
|
216
239
|
};
|
|
217
240
|
}
|
|
@@ -235,50 +258,69 @@ function createTraceProbe(piboSessionId, startedAt, intervalMs) {
|
|
|
235
258
|
maxAssistantOutputLength: 0,
|
|
236
259
|
samples: [],
|
|
237
260
|
};
|
|
238
|
-
let
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
result.
|
|
268
|
-
result.
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
261
|
+
let stopped = false;
|
|
262
|
+
let activeController;
|
|
263
|
+
let activeSample;
|
|
264
|
+
const sample = () => {
|
|
265
|
+
if (stopped) return Promise.resolve();
|
|
266
|
+
if (activeSample) return activeSample;
|
|
267
|
+
const controller = typeof AbortController === 'undefined' ? undefined : new AbortController();
|
|
268
|
+
activeController = controller;
|
|
269
|
+
const currentSample = (async () => {
|
|
270
|
+
try {
|
|
271
|
+
const t = Math.round(performance.now() - startedAt);
|
|
272
|
+
const response = await fetchWithTimeout('/api/chat/trace?piboSessionId=' + encodeURIComponent(piboSessionId) + '&includeRawEvents=true&rawEventsLimit=80', { signal: controller && controller.signal }, 2500);
|
|
273
|
+
if (!response.ok) throw new Error(response.status + ' ' + response.statusText);
|
|
274
|
+
const trace = await response.json();
|
|
275
|
+
result.fetchCount += 1;
|
|
276
|
+
const version = typeof trace.version === 'string' ? trace.version : undefined;
|
|
277
|
+
const rawEvents = Array.isArray(trace.rawEvents) ? trace.rawEvents : [];
|
|
278
|
+
const assistantOutputLength = maxTraceAssistantOutputLength(trace);
|
|
279
|
+
const liveVersion = Boolean(version && version.includes(':live:'));
|
|
280
|
+
const sampleResult = {
|
|
281
|
+
t,
|
|
282
|
+
version,
|
|
283
|
+
eventCount: typeof trace.eventCount === 'number' ? trace.eventCount : undefined,
|
|
284
|
+
rawEventCount: rawEvents.length,
|
|
285
|
+
assistantOutputLength,
|
|
286
|
+
liveVersion,
|
|
287
|
+
rawEventTypes: countRawTraceEventTypes(rawEvents),
|
|
288
|
+
};
|
|
289
|
+
result.samples.push(sampleResult);
|
|
290
|
+
if (result.samples.length > 80) result.samples.shift();
|
|
291
|
+
result.sampleCount = result.samples.length;
|
|
292
|
+
result.maxAssistantOutputLength = Math.max(result.maxAssistantOutputLength, assistantOutputLength);
|
|
293
|
+
result.finalAssistantOutputLength = assistantOutputLength;
|
|
294
|
+
if (typeof sampleResult.eventCount === 'number') {
|
|
295
|
+
result.durableEventCountStart ??= sampleResult.eventCount;
|
|
296
|
+
result.durableEventCountEnd = sampleResult.eventCount;
|
|
297
|
+
}
|
|
298
|
+
if (liveVersion) {
|
|
299
|
+
result.liveVersionCount += 1;
|
|
300
|
+
result.firstLiveVersionMs ??= t;
|
|
301
|
+
}
|
|
302
|
+
} catch (error) {
|
|
303
|
+
if (!(stopped && error && error.name === 'AbortError')) result.failedFetchCount += 1;
|
|
273
304
|
}
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
}
|
|
305
|
+
})();
|
|
306
|
+
const trackedSample = currentSample.finally(() => {
|
|
307
|
+
if (activeSample === trackedSample) activeSample = undefined;
|
|
308
|
+
if (activeController === controller) activeController = undefined;
|
|
309
|
+
});
|
|
310
|
+
activeSample = trackedSample;
|
|
311
|
+
return trackedSample;
|
|
279
312
|
};
|
|
280
313
|
const timer = setInterval(() => { sample().catch(() => {}); }, intervalMs);
|
|
281
|
-
return {
|
|
314
|
+
return {
|
|
315
|
+
result,
|
|
316
|
+
sample,
|
|
317
|
+
stop: async () => {
|
|
318
|
+
stopped = true;
|
|
319
|
+
clearInterval(timer);
|
|
320
|
+
if (activeController) activeController.abort();
|
|
321
|
+
if (activeSample) await activeSample.catch(() => {});
|
|
322
|
+
},
|
|
323
|
+
};
|
|
282
324
|
}
|
|
283
325
|
function countRawTraceEventTypes(rawEvents) {
|
|
284
326
|
const counts = {};
|
|
@@ -649,6 +691,124 @@ async function waitForAssistantDomSettle(timeoutMs) {
|
|
|
649
691
|
}
|
|
650
692
|
}
|
|
651
693
|
}
|
|
694
|
+
function startRenderOrderCapture(startedAt) {
|
|
695
|
+
const piboSessionId = document.querySelector('[data-pibo-debug="chat-shell"]')?.getAttribute('data-pibo-session-id')
|
|
696
|
+
|| document.querySelector('[data-pibo-selected-session-id]')?.getAttribute('data-pibo-selected-session-id')
|
|
697
|
+
|| undefined;
|
|
698
|
+
const capturedSessionIds = new Set(piboSessionId ? [piboSessionId] : []);
|
|
699
|
+
const traceSnapshotsApi = window.__piboTraceSnapshots;
|
|
700
|
+
if (piboSessionId && traceSnapshotsApi && typeof traceSnapshotsApi.clearSnapshots === 'function') {
|
|
701
|
+
try { traceSnapshotsApi.clearSnapshots(piboSessionId); } catch {}
|
|
702
|
+
}
|
|
703
|
+
const domStates = [];
|
|
704
|
+
let omittedDomStates = 0;
|
|
705
|
+
let previousSignature;
|
|
706
|
+
const root = document.querySelector('[data-pibo-debug="chat-shell"]') || document.body;
|
|
707
|
+
const atBottomFor = (element) => {
|
|
708
|
+
let current = element && element.parentElement;
|
|
709
|
+
while (current && current !== document.body) {
|
|
710
|
+
if (current.scrollHeight > current.clientHeight + 2) return current.scrollHeight - current.scrollTop - current.clientHeight <= 180;
|
|
711
|
+
current = current.parentElement;
|
|
712
|
+
}
|
|
713
|
+
return undefined;
|
|
714
|
+
};
|
|
715
|
+
const rowFromElement = (element) => {
|
|
716
|
+
const rect = element.getBoundingClientRect();
|
|
717
|
+
const sourceNodeIds = String(element.getAttribute('data-trace-node-id') || '').split(/\s+/).filter(Boolean);
|
|
718
|
+
const numberAttr = (name) => {
|
|
719
|
+
const raw = element.getAttribute(name);
|
|
720
|
+
if (raw === null || raw === '') return undefined;
|
|
721
|
+
const value = Number(raw);
|
|
722
|
+
return Number.isFinite(value) ? value : undefined;
|
|
723
|
+
};
|
|
724
|
+
return {
|
|
725
|
+
id: element.getAttribute('data-row-id') || element.getAttribute('data-trace-node-id') || '',
|
|
726
|
+
kind: element.getAttribute('data-row-kind') || element.getAttribute('data-span-type') || undefined,
|
|
727
|
+
status: element.getAttribute('data-row-status') || element.getAttribute('data-span-status') || undefined,
|
|
728
|
+
sourceNodeIds,
|
|
729
|
+
eventId: element.getAttribute('data-event-id') || undefined,
|
|
730
|
+
runId: element.getAttribute('data-run-id') || undefined,
|
|
731
|
+
stableKey: element.getAttribute('data-stable-key') || undefined,
|
|
732
|
+
orderSource: element.getAttribute('data-order-source') || undefined,
|
|
733
|
+
orderStreamId: numberAttr('data-order-stream-id'),
|
|
734
|
+
orderStreamFrameIndex: numberAttr('data-order-frame-index'),
|
|
735
|
+
top: Math.round(rect.top * 1000) / 1000,
|
|
736
|
+
left: Math.round(rect.left * 1000) / 1000,
|
|
737
|
+
};
|
|
738
|
+
};
|
|
739
|
+
const capture = (reason) => {
|
|
740
|
+
const shell = document.querySelector('[data-pibo-debug="chat-shell"]');
|
|
741
|
+
const activePiboSessionId = shell?.getAttribute('data-pibo-session-id')
|
|
742
|
+
|| document.querySelector('[data-pibo-selected-session-id]')?.getAttribute('data-pibo-selected-session-id')
|
|
743
|
+
|| piboSessionId;
|
|
744
|
+
if (activePiboSessionId) capturedSessionIds.add(activePiboSessionId);
|
|
745
|
+
const terminalRows = shell ? Array.from(shell.querySelectorAll('[data-pibo-terminal-row="true"][data-row-id]')) : [];
|
|
746
|
+
const traceRows = shell ? Array.from(shell.querySelectorAll('[data-pibo-debug="trace-span"][data-trace-node-id]')) : [];
|
|
747
|
+
const elements = terminalRows.length ? terminalRows : traceRows;
|
|
748
|
+
const rows = elements.map(rowFromElement).filter((row) => row.id);
|
|
749
|
+
const view = terminalRows.length ? 'compact-terminal' : traceRows.length ? 'trace-timeline' : 'unknown';
|
|
750
|
+
const visualRows = rows.slice().sort((left, right) => (left.top || 0) - (right.top || 0) || (left.left || 0) - (right.left || 0));
|
|
751
|
+
let traceSequence;
|
|
752
|
+
if (activePiboSessionId && traceSnapshotsApi && typeof traceSnapshotsApi.getLatestSequence === 'function') {
|
|
753
|
+
try { traceSequence = traceSnapshotsApi.getLatestSequence(activePiboSessionId); } catch {}
|
|
754
|
+
}
|
|
755
|
+
const state = {
|
|
756
|
+
t: Math.round((performance.now() - startedAt) * 1000) / 1000,
|
|
757
|
+
timestamp: Date.now(),
|
|
758
|
+
traceSequence,
|
|
759
|
+
reason,
|
|
760
|
+
piboSessionId: activePiboSessionId,
|
|
761
|
+
view,
|
|
762
|
+
shellState: shell?.getAttribute('data-pibo-state') || undefined,
|
|
763
|
+
atBottom: rows.length ? atBottomFor(elements[0]) : undefined,
|
|
764
|
+
rows,
|
|
765
|
+
rowIds: rows.map((row) => row.id),
|
|
766
|
+
visualRowIds: visualRows.map((row) => row.id),
|
|
767
|
+
};
|
|
768
|
+
const signature = JSON.stringify({ traceSequence: state.traceSequence, view: state.view, shellState: state.shellState, atBottom: state.atBottom, rows: rows.map((row) => [row.id, row.kind, row.status, row.sourceNodeIds, row.eventId, row.runId, row.stableKey, row.orderSource, row.orderStreamId, row.orderStreamFrameIndex]), visual: state.visualRowIds });
|
|
769
|
+
if (signature === previousSignature) return;
|
|
770
|
+
previousSignature = signature;
|
|
771
|
+
if (domStates.length >= 1000) omittedDomStates += 1;
|
|
772
|
+
else domStates.push(state);
|
|
773
|
+
};
|
|
774
|
+
capture('start');
|
|
775
|
+
const observer = new MutationObserver(() => capture('mutation'));
|
|
776
|
+
if (root) observer.observe(root, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class', 'data-row-id', 'data-row-kind', 'data-row-status', 'data-trace-node-id', 'data-event-id', 'data-run-id', 'data-stable-key', 'data-order-source', 'data-order-stream-id', 'data-order-frame-index', 'data-span-type', 'data-span-status'] });
|
|
777
|
+
const interval = setInterval(() => capture('interval'), 50);
|
|
778
|
+
return {
|
|
779
|
+
stop: () => {
|
|
780
|
+
let traceSnapshots = [];
|
|
781
|
+
try {
|
|
782
|
+
try { capture('stop'); } catch {}
|
|
783
|
+
if (traceSnapshotsApi && typeof traceSnapshotsApi.getSnapshots === 'function') {
|
|
784
|
+
for (const sessionId of capturedSessionIds) {
|
|
785
|
+
try {
|
|
786
|
+
const sessionSnapshots = cloneDebugSnapshot(traceSnapshotsApi.getSnapshots(sessionId)) || [];
|
|
787
|
+
traceSnapshots.push(...sessionSnapshots);
|
|
788
|
+
} catch {}
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
return {
|
|
792
|
+
requested: true,
|
|
793
|
+
available: Boolean(root),
|
|
794
|
+
piboSessionId,
|
|
795
|
+
domStates,
|
|
796
|
+
traceSnapshots,
|
|
797
|
+
omittedDomStates,
|
|
798
|
+
warning: traceSnapshotsApi ? undefined : 'window.__piboTraceSnapshots unavailable',
|
|
799
|
+
};
|
|
800
|
+
} finally {
|
|
801
|
+
observer.disconnect();
|
|
802
|
+
clearInterval(interval);
|
|
803
|
+
if (traceSnapshotsApi && typeof traceSnapshotsApi.clearSnapshots === 'function') {
|
|
804
|
+
for (const sessionId of capturedSessionIds) {
|
|
805
|
+
try { traceSnapshotsApi.clearSnapshots(sessionId); } catch {}
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
},
|
|
810
|
+
};
|
|
811
|
+
}
|
|
652
812
|
async function runStreamingBenchmark(options) {
|
|
653
813
|
const warnings = [];
|
|
654
814
|
const selectedSessionId = () => document.querySelector('[data-pibo-debug="chat-shell"]')?.getAttribute('data-pibo-session-id')
|
|
@@ -657,7 +817,38 @@ async function runStreamingBenchmark(options) {
|
|
|
657
817
|
let reset = false;
|
|
658
818
|
let backendPreludeError;
|
|
659
819
|
let backendPreludeConfig;
|
|
660
|
-
|
|
820
|
+
let debugStreamingBefore;
|
|
821
|
+
const traceCollectionBefore = window.__piboTraceSnapshotCollectionEnabled;
|
|
822
|
+
try {
|
|
823
|
+
debugStreamingBefore = localStorage.getItem('pibo.chat.debugStreaming');
|
|
824
|
+
localStorage.setItem('pibo.chat.debugStreaming', '1');
|
|
825
|
+
} catch (error) {
|
|
826
|
+
warnings.push('failed to set debugStreaming localStorage: ' + String(error));
|
|
827
|
+
}
|
|
828
|
+
window.__piboTraceSnapshotCollectionEnabled = true;
|
|
829
|
+
const restoreDebugCollection = () => {
|
|
830
|
+
try {
|
|
831
|
+
if (debugStreamingBefore === null || debugStreamingBefore === undefined) localStorage.removeItem('pibo.chat.debugStreaming');
|
|
832
|
+
else localStorage.setItem('pibo.chat.debugStreaming', debugStreamingBefore);
|
|
833
|
+
} catch {}
|
|
834
|
+
if (traceCollectionBefore === undefined) delete window.__piboTraceSnapshotCollectionEnabled;
|
|
835
|
+
else window.__piboTraceSnapshotCollectionEnabled = traceCollectionBefore;
|
|
836
|
+
const piboSessionId = selectedSessionId();
|
|
837
|
+
const snapshots = window.__piboTraceSnapshots;
|
|
838
|
+
if (piboSessionId && snapshots && typeof snapshots.clearSnapshots === 'function') {
|
|
839
|
+
try { snapshots.clearSnapshots(piboSessionId); } catch {}
|
|
840
|
+
}
|
|
841
|
+
};
|
|
842
|
+
let benchmarkObserver;
|
|
843
|
+
let renderOrderCapture;
|
|
844
|
+
let rafHandle;
|
|
845
|
+
let perfObserver;
|
|
846
|
+
let traceProbe;
|
|
847
|
+
let traceSummary;
|
|
848
|
+
let sseProbe;
|
|
849
|
+
let reconnectTimer;
|
|
850
|
+
let fixtureStarted = false;
|
|
851
|
+
try {
|
|
661
852
|
if (options.startBackendFixture && options.fixturePreludeMessages > 0) {
|
|
662
853
|
const piboSessionId = selectedSessionId();
|
|
663
854
|
if (!piboSessionId) {
|
|
@@ -689,6 +880,7 @@ async function runStreamingBenchmark(options) {
|
|
|
689
880
|
try { window.__piboStreamingDebugReset(); reset = true; } catch (error) { warnings.push('failed to reset __piboStreamingDebug: ' + String(error)); }
|
|
690
881
|
}
|
|
691
882
|
const overlayDrop = installOverlayDropSimulation(Boolean(options.simulateOverlayDrop));
|
|
883
|
+
renderOrderCapture = startRenderOrderCapture(startedAt);
|
|
692
884
|
|
|
693
885
|
const debugBefore = cloneDebugSnapshot(window.__piboStreamingDebug);
|
|
694
886
|
const initialText = selectedAssistantText(fixtureDomInitialTargets, ignorePreludeDomTargets);
|
|
@@ -714,13 +906,12 @@ async function runStreamingBenchmark(options) {
|
|
|
714
906
|
}
|
|
715
907
|
currentLength = length;
|
|
716
908
|
};
|
|
717
|
-
|
|
718
|
-
|
|
909
|
+
benchmarkObserver = new MutationObserver(sample);
|
|
910
|
+
benchmarkObserver.observe(document.body, { childList: true, subtree: true, characterData: true });
|
|
719
911
|
|
|
720
912
|
const rafGaps = [];
|
|
721
913
|
let rafCount = 0;
|
|
722
914
|
let lastRaf;
|
|
723
|
-
let rafHandle;
|
|
724
915
|
const onRaf = (t) => {
|
|
725
916
|
rafCount += 1;
|
|
726
917
|
if (lastRaf !== undefined) rafGaps.push(t - lastRaf);
|
|
@@ -730,7 +921,6 @@ async function runStreamingBenchmark(options) {
|
|
|
730
921
|
rafHandle = requestAnimationFrame(onRaf);
|
|
731
922
|
|
|
732
923
|
const longTasks = [];
|
|
733
|
-
let perfObserver;
|
|
734
924
|
if (typeof PerformanceObserver !== 'undefined') {
|
|
735
925
|
try {
|
|
736
926
|
perfObserver = new PerformanceObserver((list) => {
|
|
@@ -744,11 +934,8 @@ async function runStreamingBenchmark(options) {
|
|
|
744
934
|
warnings.push('PerformanceObserver unavailable');
|
|
745
935
|
}
|
|
746
936
|
|
|
747
|
-
let fixtureStarted = false;
|
|
748
937
|
let fixtureConfig;
|
|
749
938
|
let backendFixtureError;
|
|
750
|
-
let traceProbe;
|
|
751
|
-
let sseProbe;
|
|
752
939
|
if (options.startFixture) {
|
|
753
940
|
if (typeof window.__piboStreamingFixtureStart === 'function') {
|
|
754
941
|
try { fixtureConfig = window.__piboStreamingFixtureStart(); fixtureStarted = true; } catch (error) { warnings.push('failed to start streaming fixture: ' + String(error)); }
|
|
@@ -757,7 +944,8 @@ async function runStreamingBenchmark(options) {
|
|
|
757
944
|
}
|
|
758
945
|
} else if (options.startBackendFixture) {
|
|
759
946
|
if (options.simulateReconnect && typeof window.__piboStreamingBenchmarkForceReconnect === 'function') {
|
|
760
|
-
setTimeout(() => {
|
|
947
|
+
reconnectTimer = setTimeout(() => {
|
|
948
|
+
reconnectTimer = undefined;
|
|
761
949
|
try { window.__piboStreamingBenchmarkForceReconnect(); } catch (error) { warnings.push('failed to force EventSource reconnect: ' + String(error)); }
|
|
762
950
|
}, options.reconnectAtMs || 325);
|
|
763
951
|
} else if (options.simulateReconnect) {
|
|
@@ -800,12 +988,20 @@ async function runStreamingBenchmark(options) {
|
|
|
800
988
|
sample();
|
|
801
989
|
if (traceProbe) {
|
|
802
990
|
await traceProbe.sample();
|
|
803
|
-
traceProbe.
|
|
991
|
+
traceSummary = traceProbe.result;
|
|
992
|
+
await traceProbe.stop();
|
|
993
|
+
traceProbe = undefined;
|
|
804
994
|
}
|
|
805
995
|
const sseSummary = sseProbe ? await sseProbe.stop() : undefined;
|
|
806
|
-
|
|
996
|
+
sseProbe = undefined;
|
|
997
|
+
benchmarkObserver.disconnect();
|
|
998
|
+
benchmarkObserver = undefined;
|
|
999
|
+
const renderOrder = renderOrderCapture.stop();
|
|
1000
|
+
renderOrderCapture = undefined;
|
|
807
1001
|
if (rafHandle !== undefined) cancelAnimationFrame(rafHandle);
|
|
1002
|
+
rafHandle = undefined;
|
|
808
1003
|
try { perfObserver && perfObserver.disconnect(); } catch {}
|
|
1004
|
+
perfObserver = undefined;
|
|
809
1005
|
|
|
810
1006
|
const debugAfter = cloneDebugSnapshot(window.__piboStreamingDebug);
|
|
811
1007
|
const overlayDropSummary = overlayDrop ? cloneDebugSnapshot(window.__piboStreamingBenchmarkOverlayDrop) : undefined;
|
|
@@ -869,7 +1065,6 @@ async function runStreamingBenchmark(options) {
|
|
|
869
1065
|
error: backendPreludeError || backendFixtureError,
|
|
870
1066
|
} : undefined;
|
|
871
1067
|
const eventSourceSummary = summarizeEventSourceProbe(startedAt, Boolean(options.startBackendFixture), options.reconnectAtMs, Boolean(options.simulateTraceCatchup), options.traceCatchupDropMs);
|
|
872
|
-
const traceSummary = traceProbe && traceProbe.result;
|
|
873
1068
|
const regressions = streamingBenchmarkRegressions({
|
|
874
1069
|
debugAfter,
|
|
875
1070
|
debugDelta,
|
|
@@ -920,9 +1115,24 @@ async function runStreamingBenchmark(options) {
|
|
|
920
1115
|
sse: sseSummary,
|
|
921
1116
|
trace: traceSummary,
|
|
922
1117
|
overlayDrop: overlayDropSummary,
|
|
1118
|
+
renderOrder,
|
|
923
1119
|
regressions,
|
|
924
1120
|
warnings,
|
|
925
1121
|
};
|
|
1122
|
+
} finally {
|
|
1123
|
+
try { benchmarkObserver && benchmarkObserver.disconnect(); } catch {}
|
|
1124
|
+
try { renderOrderCapture && renderOrderCapture.stop(); } catch {}
|
|
1125
|
+
if (rafHandle !== undefined) cancelAnimationFrame(rafHandle);
|
|
1126
|
+
if (reconnectTimer !== undefined) clearTimeout(reconnectTimer);
|
|
1127
|
+
try { perfObserver && perfObserver.disconnect(); } catch {}
|
|
1128
|
+
try { if (traceProbe) await traceProbe.stop(); } catch {}
|
|
1129
|
+
try { if (sseProbe) await sseProbe.stop(); } catch {}
|
|
1130
|
+
try { installOverlayDropSimulation(false); } catch {}
|
|
1131
|
+
if (fixtureStarted && options.startFixture && typeof window.__piboStreamingDebugReset === 'function') {
|
|
1132
|
+
try { window.__piboStreamingDebugReset(); } catch {}
|
|
1133
|
+
}
|
|
1134
|
+
restoreDebugCollection();
|
|
1135
|
+
}
|
|
926
1136
|
}
|
|
927
1137
|
`;
|
|
928
1138
|
}
|
|
@@ -117,6 +117,7 @@ function streamingBenchmarkCompactRunRows(benchmark) {
|
|
|
117
117
|
{ section: "compact", metric: "Live trace compute", preservation: liveTraceComputeCount !== undefined ? `count ${jsonShort(liveTraceComputeCount)}, total ${jsonShort(liveTraceComputeTotalMs)}ms` : "n/a", cadenceLatency: liveTraceComputeMaxMs !== undefined ? `max ${jsonShort(liveTraceComputeMaxMs)}ms` : "n/a" },
|
|
118
118
|
{ section: "compact", metric: "Markdown render", preservation: markdownRenderCount !== undefined ? `count ${jsonShort(markdownRenderCount)}, plain ${jsonShort(markdownRenderPlainCount)}, commonmark ${jsonShort(markdownRenderCommonMarkCount)}, gfm ${jsonShort(markdownRenderGfmCount)}, gfmFast ${jsonShort(markdownRenderGfmFastCount)}, full ${jsonShort(markdownRenderFullCount)}` : "n/a", cadenceLatency: markdownRenderMaxMs !== undefined ? `total ${jsonShort(markdownRenderTotalMs)}ms, max ${jsonShort(markdownRenderMaxMs)}ms` : "n/a" },
|
|
119
119
|
{ section: "compact", metric: "DOM", preservation: `positive ${benchmark.dom.positiveUpdateCount}, max jump ${jsonShort(benchmark.dom.positiveCharJumps.max)} chars`, cadenceLatency: `p90 gap ${statP90(benchmark.dom.gapsMs, "ms")}, first visible ${jsonShort(benchmark.dom.firstPositiveUpdateMs)}ms` },
|
|
120
|
+
{ section: "compact", metric: "Render order", preservation: renderOrderPreservation(benchmark), cadenceLatency: renderOrderEvidence(benchmark) },
|
|
120
121
|
{ section: "compact", metric: "Score", preservation: `smoothness ${benchmark.score.smoothness}`, cadenceLatency: `regressions ${benchmark.regressions.length}, warnings ${benchmark.warnings.length}` },
|
|
121
122
|
];
|
|
122
123
|
}
|
|
@@ -131,6 +132,7 @@ function streamingBenchmarkCompactGroupRows(group) {
|
|
|
131
132
|
{ section: "compact", metric: "Live trace compute", preservation: `count ${statP50(group.summary.debugLiveTraceComputeCount)}, total ${statP50(group.summary.debugLiveTraceComputeDurationTotalMs, "ms")}`, cadenceLatency: `max ${statP50(group.summary.debugLiveTraceComputeDurationMaxMs, "ms")}` },
|
|
132
133
|
{ section: "compact", metric: "Markdown render", preservation: `count ${statP50(group.summary.debugMarkdownRenderCount)}, plain ${statP50(group.summary.debugMarkdownRenderPlainCount)}, commonmark ${statP50(group.summary.debugMarkdownRenderCommonMarkCount)}, gfm ${statP50(group.summary.debugMarkdownRenderGfmCount)}, gfmFast ${statP50(group.summary.debugMarkdownRenderGfmFastCount)}, full ${statP50(group.summary.debugMarkdownRenderFullCount)}`, cadenceLatency: `total ${statP50(group.summary.debugMarkdownRenderDurationTotalMs, "ms")}, max ${statP50(group.summary.debugMarkdownRenderDurationMaxMs, "ms")}` },
|
|
133
134
|
{ section: "compact", metric: "DOM", preservation: `positive ${statP50(group.summary.domPositiveUpdateCount)}, max jump ${statP50(group.summary.domJumpMaxChars, " chars")}`, cadenceLatency: `p90 gap ${statP50(group.summary.domGapP90Ms, "ms")}, first visible ${statP50(group.summary.firstVisibleMs, "ms")}` },
|
|
135
|
+
{ section: "compact", metric: "Render order", preservation: `reorder ${statP50(group.summary.renderOrderReorderCount)}, reappear ${statP50(group.summary.renderOrderDisappearReappearCount)}, identity ${statP50(group.summary.renderOrderIdentityReplacementCount)}, mismatch ${statP50(group.summary.renderOrderStateDomMismatchCount)}`, cadenceLatency: `DOM states ${statP50(group.summary.renderOrderDomStateCount)}, trace snapshots ${statP50(group.summary.renderOrderTraceSnapshotCount)}` },
|
|
134
136
|
{ section: "compact", metric: "Score", preservation: `smoothness ${statP50(group.summary.smoothness)}`, cadenceLatency: `regressions ${statP50(group.summary.regressionCount)}, warnings ${group.warnings.length}` },
|
|
135
137
|
];
|
|
136
138
|
}
|
|
@@ -182,6 +184,7 @@ function formatStreamingBenchmarkCompactRun(benchmark, target) {
|
|
|
182
184
|
["Live trace compute", liveTraceComputeCount !== undefined ? `count ${jsonShort(liveTraceComputeCount)}, total ${jsonShort(liveTraceComputeTotalMs)}ms` : "n/a", liveTraceComputeMaxMs !== undefined ? `max ${jsonShort(liveTraceComputeMaxMs)}ms` : "n/a"],
|
|
183
185
|
["Markdown render", markdownRenderCount !== undefined ? `count ${jsonShort(markdownRenderCount)}, plain ${jsonShort(markdownRenderPlainCount)}, commonmark ${jsonShort(markdownRenderCommonMarkCount)}, gfm ${jsonShort(markdownRenderGfmCount)}, gfmFast ${jsonShort(markdownRenderGfmFastCount)}, full ${jsonShort(markdownRenderFullCount)}` : "n/a", markdownRenderMaxMs !== undefined ? `total ${jsonShort(markdownRenderTotalMs)}ms, max ${jsonShort(markdownRenderMaxMs)}ms` : "n/a"],
|
|
184
186
|
["DOM", `positive ${benchmark.dom.positiveUpdateCount}, max jump ${jsonShort(benchmark.dom.positiveCharJumps.max)} chars`, `p90 gap ${statP90(benchmark.dom.gapsMs, "ms")}, first visible ${jsonShort(benchmark.dom.firstPositiveUpdateMs)}ms`],
|
|
187
|
+
["Render order", renderOrderPreservation(benchmark), renderOrderEvidence(benchmark)],
|
|
185
188
|
["Score", `smoothness ${benchmark.score.smoothness}`, `regressions ${benchmark.regressions.length}, warnings ${benchmark.warnings.length}`],
|
|
186
189
|
]),
|
|
187
190
|
];
|
|
@@ -203,6 +206,7 @@ function formatStreamingBenchmarkCompactGroup(group, target) {
|
|
|
203
206
|
["Live trace compute", `count ${statP50(group.summary.debugLiveTraceComputeCount)}, total ${statP50(group.summary.debugLiveTraceComputeDurationTotalMs, "ms")}`, `max ${statP50(group.summary.debugLiveTraceComputeDurationMaxMs, "ms")}`],
|
|
204
207
|
["Markdown render", `count ${statP50(group.summary.debugMarkdownRenderCount)}, plain ${statP50(group.summary.debugMarkdownRenderPlainCount)}, commonmark ${statP50(group.summary.debugMarkdownRenderCommonMarkCount)}, gfm ${statP50(group.summary.debugMarkdownRenderGfmCount)}, gfmFast ${statP50(group.summary.debugMarkdownRenderGfmFastCount)}, full ${statP50(group.summary.debugMarkdownRenderFullCount)}`, `total ${statP50(group.summary.debugMarkdownRenderDurationTotalMs, "ms")}, max ${statP50(group.summary.debugMarkdownRenderDurationMaxMs, "ms")}`],
|
|
205
208
|
["DOM", `positive ${statP50(group.summary.domPositiveUpdateCount)}, max jump ${statP50(group.summary.domJumpMaxChars, " chars")}`, `p90 gap ${statP50(group.summary.domGapP90Ms, "ms")}, first visible ${statP50(group.summary.firstVisibleMs, "ms")}`],
|
|
209
|
+
["Render order", `reorder ${statP50(group.summary.renderOrderReorderCount)}, reappear ${statP50(group.summary.renderOrderDisappearReappearCount)}, identity ${statP50(group.summary.renderOrderIdentityReplacementCount)}, mismatch ${statP50(group.summary.renderOrderStateDomMismatchCount)}`, `DOM states ${statP50(group.summary.renderOrderDomStateCount)}, trace snapshots ${statP50(group.summary.renderOrderTraceSnapshotCount)}`],
|
|
206
210
|
["Score", `smoothness ${statP50(group.summary.smoothness)}`, `regressions ${statP50(group.summary.regressionCount)}, warnings ${group.warnings.length}`],
|
|
207
211
|
]),
|
|
208
212
|
];
|
|
@@ -241,6 +245,18 @@ function formatStreamingBenchmarkCompactUrlComparison(comparison, target) {
|
|
|
241
245
|
appendCompactBenchmarkNotes(lines, comparison.negativeProfile, comparison.regressions, comparison.warnings);
|
|
242
246
|
return lines.join("\n");
|
|
243
247
|
}
|
|
248
|
+
function renderOrderPreservation(benchmark) {
|
|
249
|
+
const analysis = benchmark.renderOrder?.analysis;
|
|
250
|
+
if (!analysis)
|
|
251
|
+
return benchmark.renderOrder?.warning ?? "n/a";
|
|
252
|
+
return `reorder ${analysis.reorderCount}, reappear ${analysis.disappearReappearCount}, identity ${analysis.identityReplacementCount}, mismatch ${analysis.stateDomMismatchCount}`;
|
|
253
|
+
}
|
|
254
|
+
function renderOrderEvidence(benchmark) {
|
|
255
|
+
const analysis = benchmark.renderOrder?.analysis;
|
|
256
|
+
if (!analysis)
|
|
257
|
+
return "n/a";
|
|
258
|
+
return `DOM states ${analysis.domStateCount}, trace snapshots ${analysis.traceSnapshotCount}`;
|
|
259
|
+
}
|
|
244
260
|
function appendCompactBenchmarkNotes(lines, negativeProfile, regressions, warnings) {
|
|
245
261
|
if (negativeProfile)
|
|
246
262
|
lines.push("", `Negative profile: ${negativeProfile}`);
|
|
@@ -308,6 +324,7 @@ function formatStreamingBenchmark(benchmark, target) {
|
|
|
308
324
|
`dom jumps: ${formatStats(benchmark.dom.positiveCharJumps)} chars`,
|
|
309
325
|
`raf: count=${benchmark.raf.count}, gaps=${formatStats(benchmark.raf.gapsMs)}`,
|
|
310
326
|
`longTasks: count=${benchmark.longTasks.count}, max=${benchmark.longTasks.maxMs}ms, total=${benchmark.longTasks.totalMs}ms`,
|
|
327
|
+
`render order: ${renderOrderPreservation(benchmark)}, ${renderOrderEvidence(benchmark)}`,
|
|
311
328
|
];
|
|
312
329
|
if (benchmark.negativeProfile)
|
|
313
330
|
lines.push(`negative profile: ${benchmark.negativeProfile}`);
|
|
@@ -331,6 +348,12 @@ function formatStreamingBenchmark(benchmark, target) {
|
|
|
331
348
|
lines.push(`sse: requested=${benchmark.sse.requested} installed=${benchmark.sse.installed} status=${jsonShort(benchmark.sse.status)} firstChunk=${jsonShort(benchmark.sse.firstChunkMs)}ms firstText=${jsonShort(benchmark.sse.firstTextEventMs)}ms chunks=${benchmark.sse.chunkCount} chunkBytes=${formatStats(benchmark.sse.chunkBytes)} chunkGaps=${formatStats(benchmark.sse.chunkGapsMs)} textPerChunk=${formatStats(benchmark.sse.textEventsPerChunk)} text=${benchmark.sse.textEventCount} reasoning=${benchmark.sse.reasoningEventCount} textGaps=${formatStats(benchmark.sse.textEventGapsMs)} transient=${benchmark.sse.transientIdCount} durable=${benchmark.sse.durableIdCount} errors=${benchmark.sse.errors.length}`);
|
|
332
349
|
if (benchmark.trace)
|
|
333
350
|
lines.push(`trace: requested=${benchmark.trace.requested} samples=${benchmark.trace.sampleCount} fetches=${benchmark.trace.fetchCount} failed=${benchmark.trace.failedFetchCount} liveVersions=${benchmark.trace.liveVersionCount} firstLive=${jsonShort(benchmark.trace.firstLiveVersionMs)}ms assistantMax=${benchmark.trace.maxAssistantOutputLength} assistantFinal=${jsonShort(benchmark.trace.finalAssistantOutputLength)} durableEvents=${jsonShort(benchmark.trace.durableEventCountStart)}->${jsonShort(benchmark.trace.durableEventCountEnd)} session=${jsonShort(benchmark.trace.piboSessionId)}`);
|
|
351
|
+
if (benchmark.renderOrder?.analysis?.findings.length) {
|
|
352
|
+
lines.push("", "Render order findings:");
|
|
353
|
+
for (const finding of benchmark.renderOrder.analysis.findings.slice(0, 20)) {
|
|
354
|
+
lines.push(`- ${finding.source}/${finding.kind} @ ${new Date(finding.timestamp).toISOString()}: ${finding.detail}`);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
334
357
|
if (benchmark.regressions.length) {
|
|
335
358
|
lines.push("", "Regressions:");
|
|
336
359
|
for (const regression of benchmark.regressions)
|
|
@@ -357,6 +380,7 @@ function formatStreamingBenchmarkGroup(group, target) {
|
|
|
357
380
|
`dom gaps p50=${formatStats(group.summary.domGapP50Ms)}, p90=${formatStats(group.summary.domGapP90Ms)}, max=${formatStats(group.summary.domGapMaxMs)}`,
|
|
358
381
|
`dom jumps p90=${formatStats(group.summary.domJumpP90Chars)}, max=${formatStats(group.summary.domJumpMaxChars)} chars`,
|
|
359
382
|
`firstVisible=${formatStats(group.summary.firstVisibleMs)}, longTaskMax=${formatStats(group.summary.longTaskMaxMs)}`,
|
|
383
|
+
`render order: reorder=${formatStats(group.summary.renderOrderReorderCount)}, reappear=${formatStats(group.summary.renderOrderDisappearReappearCount)}, identity=${formatStats(group.summary.renderOrderIdentityReplacementCount)}, mismatch=${formatStats(group.summary.renderOrderStateDomMismatchCount)}, DOM states=${formatStats(group.summary.renderOrderDomStateCount)}, trace snapshots=${formatStats(group.summary.renderOrderTraceSnapshotCount)}`,
|
|
360
384
|
];
|
|
361
385
|
if (group.negativeProfile)
|
|
362
386
|
lines.push(`negative profile: ${group.negativeProfile}`);
|
package/dist/debug/web.js
CHANGED
|
@@ -7,6 +7,7 @@ import { applyExpectedStreamingRegressions, attachStreamingProviderTelemetryToBe
|
|
|
7
7
|
import { collectStreamingProviderTelemetry, collectStreamingProviderTelemetryFromSelectedBrowserSession, collectStreamingProviderTelemetryFromSession, collectStreamingProviderTelemetryFromTurn, } from "./web-streaming-provider-telemetry.js";
|
|
8
8
|
import { buildStreamingBenchmarkExpression, streamingBenchmarkEventSourceProbeScript, streamingBenchmarkFixtureHtml } from "./web-streaming-browser-scripts.js";
|
|
9
9
|
import { buildSnapshotExpression, buildWatchExpression } from "./web-snapshot-browser-scripts.js";
|
|
10
|
+
import { analyzeStreamingRenderOrderCapture } from "./web-render-order-analysis.js";
|
|
10
11
|
import { compactTarget, limitStdout, readBaselineSnapshot, writeArtifact, writeLastSnapshot, writeReportOutput, writeTextArtifact } from "./web-artifacts.js";
|
|
11
12
|
import { applyNegativeStreamingProfile, DEFAULT_DEPTH_LIMIT, DEFAULT_EVENT_LIMIT, DEFAULT_NODE_LIMIT, DEFAULT_TEXT_LIMIT, parseDuration, parseFixtureMix, parseFixturePreludeMessages, parseFixtureProfile, parseNegativeProfile, parseOptions, parseRuns, presetScope, resolveScope, resolveStreamingBenchmarkCompareUrl, resolveStreamingBenchmarkHostedCompareUrl } from "./web-options.js";
|
|
12
13
|
export { formatStreamingBenchmarkAssertionSummary, formatStreamingBenchmarkUrlComparison, summarizeStreamingSelectedLiveEventSource } from "./web-streaming-report.js";
|
|
@@ -14,6 +15,7 @@ export { resolveStreamingBenchmarkHostedCompareUrlFromValues } from "./web-optio
|
|
|
14
15
|
export { attachStreamingProviderTelemetryToBenchmark, evaluateStreamingBenchmarkAssertion, evaluateStreamingBenchmarkUrlComparisonRegressions, evaluateStreamingLivePipelineRegressions, evaluateStreamingProviderRegressions, summarizeStreamingBenchmarkUrlComparison, summarizeStreamingBenchmarks, summarizeStreamingLivePipeline, summarizeStreamingProviderPreservation } from "./web-streaming-benchmark-analysis.js";
|
|
15
16
|
export { collectStreamingProviderTelemetryFromSelectedBrowserSession, collectStreamingProviderTelemetryFromSession, collectStreamingProviderTelemetryFromTurn, summarizeStreamingProviderTelemetry } from "./web-streaming-provider-telemetry.js";
|
|
16
17
|
export { formatWatch, inferWatchFlickers } from "./web-render-analysis.js";
|
|
18
|
+
export { analyzeStreamingRenderOrderCapture } from "./web-render-order-analysis.js";
|
|
17
19
|
export async function runDebugWeb(args) {
|
|
18
20
|
if (args.length === 0 || args[0] === "--help" || args[0] === "-h") {
|
|
19
21
|
printWebDiscovery();
|
|
@@ -110,7 +112,7 @@ Usage:
|
|
|
110
112
|
Defaults:
|
|
111
113
|
new-session --manual waits while you click New Session yourself.
|
|
112
114
|
new-session --act clicks the discovered New Session button after the watcher starts.
|
|
113
|
-
streaming-benchmark enables debugStreaming
|
|
115
|
+
streaming-benchmark enables debugStreaming and traceDebug, observes assistant DOM increments, and records correlated base/overlay/current trace state plus terminal/span DOM and visual order transitions.
|
|
114
116
|
streaming-benchmark --fixture navigates the target to a deterministic in-browser stream fixture before measuring.
|
|
115
117
|
streaming-benchmark --backend-fixture posts to /api/chat/debug/streaming-fixture and records EventSource metrics while the real app consumes deterministic /api/chat/events frames.
|
|
116
118
|
streaming-benchmark --fixture-profile selects steady cadence, deterministic jitter, bursty timing, or intentional batch stress.
|
|
@@ -485,11 +487,20 @@ async function runStreamingBenchmark(client, durationMs, options = {}) {
|
|
|
485
487
|
await client.send("Page.bringToFront").catch(() => undefined);
|
|
486
488
|
const benchmarkTimeoutMs = durationMs + (options.startBackendFixture ? 20_000 : 10_000);
|
|
487
489
|
const benchmark = await client.evaluate(buildStreamingBenchmarkExpression(durationMs, options), benchmarkTimeoutMs);
|
|
488
|
-
const
|
|
490
|
+
const withRenderOrder = { ...benchmark, renderOrder: analyzeStreamingRenderOrderCapture(benchmark.renderOrder) };
|
|
491
|
+
const withProvider = { ...withRenderOrder, provider: options.providerTelemetry };
|
|
489
492
|
const scored = { ...withProvider, score: scoreStreamingBenchmark(withProvider), providerPreservation: summarizeStreamingProviderPreservation(withProvider) };
|
|
490
493
|
const withLivePipeline = { ...scored, livePipeline: summarizeStreamingLivePipeline(scored) };
|
|
491
494
|
const withCadence = { ...withLivePipeline, cadence: summarizeStreamingCadence(withLivePipeline), negativeProfile: options.negativeProfile };
|
|
492
|
-
return {
|
|
495
|
+
return {
|
|
496
|
+
...withCadence,
|
|
497
|
+
regressions: [
|
|
498
|
+
...withCadence.regressions,
|
|
499
|
+
...(withCadence.renderOrder?.analysis?.regressions ?? []),
|
|
500
|
+
...evaluateStreamingLivePipelineRegressions(withCadence),
|
|
501
|
+
...evaluateStreamingProviderRegressions(withCadence),
|
|
502
|
+
],
|
|
503
|
+
};
|
|
493
504
|
}
|
|
494
505
|
async function currentBrowserUrl(client) {
|
|
495
506
|
const state = await client.evaluate(`(() => ({ href: location.href }))()`, 5_000);
|
package/dist/gateway/server.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createServer } from "node:net";
|
|
2
2
|
import { createDefaultPiboPluginRegistry, createPiboProfileFromRegistryOrDefault, resolvePiboProfileNameFromRegistryOrDefault } from "../plugins/builtin.js";
|
|
3
3
|
import { PiboSessionRouter } from "../core/session-router.js";
|
|
4
|
+
import { createLoopMessagePreflight } from "../loops/store.js";
|
|
4
5
|
import { loadPiboModelDefaults, selectRequestedModelProfile } from "../core/model-defaults.js";
|
|
5
6
|
import { ResourceReaperService } from "../resources/reaper.js";
|
|
6
7
|
import { DEFAULT_GATEWAY_HOST, DEFAULT_GATEWAY_PORT, encodeFrame, errorResponse, isGatewayRequestFrame, isGatewaySubscribeFrame, } from "./protocol.js";
|
|
@@ -147,6 +148,7 @@ export class PiboGatewayServer {
|
|
|
147
148
|
persistSession: this.options.persistSession,
|
|
148
149
|
pluginRegistry: this.pluginRegistry,
|
|
149
150
|
sessionStore: this.sessionStore,
|
|
151
|
+
messagePreflight: createLoopMessagePreflight({ path: this.options.loopStorePath }),
|
|
150
152
|
});
|
|
151
153
|
this.unsubscribe = this.router.subscribe((event) => this.broadcastRouterEvent(event));
|
|
152
154
|
this.server = createServer((socket) => this.handleSocket(socket));
|
package/dist/gateway/web.js
CHANGED
|
@@ -197,6 +197,7 @@ export async function runWebGatewayServer(options = {}) {
|
|
|
197
197
|
...resolvedOptions,
|
|
198
198
|
pluginRegistry,
|
|
199
199
|
resourceReaper: resolveGatewayResourceReaperOptions(resolvedOptions),
|
|
200
|
+
loopStorePath: resolvedOptions.chat?.ralphStorePath,
|
|
200
201
|
});
|
|
201
202
|
await server.start();
|
|
202
203
|
}
|
package/dist/loops/accounting.js
CHANGED
|
@@ -13,7 +13,14 @@ export function goalElapsedWallClockSeconds(job, now = new Date()) {
|
|
|
13
13
|
export function goalRemainingTokens(job) {
|
|
14
14
|
return job.tokenBudget === undefined ? undefined : Math.max(0, job.tokenBudget - (job.state.tokensUsed ?? 0));
|
|
15
15
|
}
|
|
16
|
-
export function goalCanStartNextTurn(job) {
|
|
16
|
+
export function goalCanStartNextTurn(job, now = new Date()) {
|
|
17
|
+
if (job.mode !== 'goal' || !job.enabled)
|
|
18
|
+
return false;
|
|
19
|
+
const status = job.state.goalStatus ?? 'paused';
|
|
20
|
+
if (status !== 'active')
|
|
21
|
+
return false;
|
|
22
|
+
if (job.state.nextAttemptAt && Date.parse(job.state.nextAttemptAt) > now.getTime())
|
|
23
|
+
return false;
|
|
17
24
|
const remaining = goalRemainingTokens(job);
|
|
18
25
|
return remaining === undefined || remaining > (job.tokenReserve ?? 0);
|
|
19
26
|
}
|
package/dist/loops/cli.js
CHANGED
|
@@ -207,7 +207,7 @@ export async function runLoopCli(argv = process.argv, defaults = {}) {
|
|
|
207
207
|
printJson(job);
|
|
208
208
|
else
|
|
209
209
|
console.log(`${job.id}\tcancel-requested\t${job.name}`); store.close(); });
|
|
210
|
-
program.command('remove').argument('<id>').description('Delete a Loop job').option('--json', 'Print JSON').action((id, options) => { const store = createDefaultPiboLoopStore({ path: program.opts().store }); const removed = store.removeJob(id); if (options.json)
|
|
210
|
+
program.command('remove').argument('<id>').description('Delete a Loop job and all of its runs and facts; active runs must be cancelled first').option('--json', 'Print JSON').action((id, options) => { const store = createDefaultPiboLoopStore({ path: program.opts().store }); const removed = store.removeJob(id); if (options.json)
|
|
211
211
|
printJson({ removed });
|
|
212
212
|
else
|
|
213
213
|
console.log(removed ? 'removed' : 'not found'); store.close(); });
|