elanous 0.2.42 → 0.2.44
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/apps/pwa/out/404/index.html +1 -1
- package/apps/pwa/out/404.html +1 -1
- package/apps/pwa/out/_next/static/{X1ucLw10Cds_h614NoEnh → HMXsxdy5MIIcHPMHv1wD4}/_buildManifest.js +1 -1
- package/apps/pwa/out/_next/static/chunks/08334415.f0e80896acbef722.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1032-78ba4f6391258cab.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1082-53f86a26e03d309d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1109-7d0e264f6f2edbc7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1124-7c26330402481143.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{2160.a097e7b138ae1c55.js → 118.2a89982fe4276880.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/1244.6c435dbf1bf21d8a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1252.9e665904d3aa3b1a.js +32 -0
- package/apps/pwa/out/_next/static/chunks/1266.a46cc33cb6a72d75.js +104 -0
- package/apps/pwa/out/_next/static/chunks/1306.967240ede9a0f757.js +24 -0
- package/apps/pwa/out/_next/static/chunks/1344.3b95f3bd1b77a3fe.js +94 -0
- package/apps/pwa/out/_next/static/chunks/{4043.6b91203436c9c86b.js → 1401.22dfe92640a2b1ac.js} +4 -4
- package/apps/pwa/out/_next/static/chunks/1431-f7c78bd5be21e011.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1451-cdd35a8a0b31834b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6632.0eac1c554f8f2ef3.js → 1694.18debfd77562e56d.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/1708-f03d587b7a7545c8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1775-fa7152bdeff6c95f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/178-4da509cd7266672a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1850-522de4ee34957210.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1876-c6f6e0ddcc76c6a1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1976.097066b072432242.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3507.97e1977bc4d5fb0a.js → 1978.eeb60a606dc5deac.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/2043.e233e3b5a3e790f5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2150.71b94e3348107c83.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2158.ebc6fc5a10280ab7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2216.802962c04f40a26e.js +64 -0
- package/apps/pwa/out/_next/static/chunks/2294.7890edcfa046c97d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/235.c89aaae4bcd6233a.js +74 -0
- package/apps/pwa/out/_next/static/chunks/{5885.0a3e52c8faccec98.js → 239.de075467b5523469.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/249.ba7051590d603c8f.js +226 -0
- package/apps/pwa/out/_next/static/chunks/2571.a6ac4e26c8618403.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2610.e149cd564a08913e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2705.9816f3c244f8b85f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2801.afeb8a4dae22f85f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2954.bbefc95d6b20e0d8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2e0f720a.a0697c08e3806a60.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3042.96ec235fe41c8d4e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3097-8e358f158acef46b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3205-93b1abe28b4fb16a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3273.b4434f0dcae7eb29.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3311.9cbc43ea0c90d60c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{1487.2f67b79444062da6.js → 3349.b5f09ee474d9533e.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/3503.a47a9755fb4d97b0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3506-5f429b3b7e1392b0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3843.bad404d008893291.js +77 -0
- package/apps/pwa/out/_next/static/chunks/3877-4b40e530b47e3bf9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/435-ce2958253cf7de61.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4393.28fa5228d0eec217.js +149 -0
- package/apps/pwa/out/_next/static/chunks/4404.7281c847c6e10dfc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8673-bab689a55f7e13b9.js → 4415-b9d6a90960920a4a.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/447-5b304de1fe098f43.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4484-8ebea83d431e6fae.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8262.ddc03e06b733f184.js → 4502.bdcc877abd437a05.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4599-f95790fc5c65b8df.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{1262.e804feb8fd1acb8c.js → 46.57c783fa4884714f.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/463-b9114e411f33728e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4659.a57d1f0c5d754cd2.js +36 -0
- package/apps/pwa/out/_next/static/chunks/4722-a847e7a28115035f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{1063.2fb8a9dc55c731f2.js → 4757.67c6d7473a038e78.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4874-c86f878ec4502ad3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6377.bc7df239edbff244.js → 4891.3f80ba517a3b2373.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4998.810ca8833084caa9.js +62 -0
- package/apps/pwa/out/_next/static/chunks/4f98febc.ea5841d4d616bfb2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3482.a9ae9d2ad6a5bd97.js → 5052.7dbb12a55d4f18f5.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5166-ca73b3e361085a6d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5180-039f4a18b07ad387.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5232.5a2ce4daf7a9e11d.js +115 -0
- package/apps/pwa/out/_next/static/chunks/5439.3fec6dbce29ecb36.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5612-074d9a5e00dfac6a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5675-01989d524a84c505.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5751.af641a1adf5ec697.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5758-c6cb98714d18ab0c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/578eded8.b582637306e16964.js +122 -0
- package/apps/pwa/out/_next/static/chunks/5790.5eb06a653ebd8571.js +34 -0
- package/apps/pwa/out/_next/static/chunks/5853-4033e5bd5afbe06b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5904.97d70bb7f46b2db7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3347.f846266b5e5f3ede.js → 5989.7ecd362c5c44b747.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/{73d2eb0e.4966ad55293c801a.js → 5a34fb2f.52f1b4e1baebb48a.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/{7a98bc80.fa935989e829f9c2.js → 5a5078f8.2099200e5ea95e16.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/6036-c302c34ff0b3d410.js +1 -0
- package/apps/pwa/out/_next/static/chunks/606.ef81c313381f4264.js +1 -0
- package/apps/pwa/out/_next/static/chunks/616.1af54a928b1ba704.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6201.bc936f71f613a8e9.js +41 -0
- package/apps/pwa/out/_next/static/chunks/6204-fdc86e0e64c4f92d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{7411.9b4b8b747dc7b802.js → 6245.1182e007e9d230d9.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{b450776b.3db34d8d965f82d3.js → 63699a35.17262e162bc514b2.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/6420.494801a80030160c.js +27 -0
- package/apps/pwa/out/_next/static/chunks/{e8543907.5b040a5f22a0b0e5.js → 6549dad0.2740b25e51bf8f05.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{9427.96aa912ddb5801e0.js → 6881.9e7955847640c7fe.js} +17 -17
- package/apps/pwa/out/_next/static/chunks/6931.fcdfb94141e67b3d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6991-8e081c6ce38c0ba1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7010.1bbd17a7f2b3e376.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7029.d1466acf55fae2ed.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7152-a123aa8e129c131f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7455.196168fffac3b9c4.js +24 -0
- package/apps/pwa/out/_next/static/chunks/7638.6ca4770dd1129138.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7649-f37d76260e5e2a5a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7679.32c40cdd14f20b4a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7751.04bfbd16b4c6cd0a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7864.b1ff31d4030b8994.js +148 -0
- package/apps/pwa/out/_next/static/chunks/7869-c47bd2c075c1fefa.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8138.6c10b2a356d52fca.js → 8442.2f09ca969d631615.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8445.2738dbd59a78c78c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8447.5510c439f9938c6d.js +286 -0
- package/apps/pwa/out/_next/static/chunks/{9415.69e4a21c60c7d2db.js → 8551.f762945c2cda2e95.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8635-57a9d8d9db70f4f1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/86961958-4b0689a5048f756b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8709.3c6019bb18f8554f.js +8 -0
- package/apps/pwa/out/_next/static/chunks/8759.c999528a0a907bf6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{9a852a62-6192a6ea9346ced3.js → 87f498e5-0881de09f2e44707.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8843.c3197f904c952b81.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3d0154af.5331fec737ffe8c3.js → 892fd990.456232f326cc39c2.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8965-135a2c9eaa2464cb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8971-8d3b9c96f8a6c958.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9059.c8598d96f8e5e9cd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9115.90447ae198b84eae.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9147.d9b0a02e0babc9b4.js +93 -0
- package/apps/pwa/out/_next/static/chunks/9204-83075f4b70c61cdc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9244-c32ef14b5dc72bdf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/930.2a9a30f964350c66.js +90 -0
- package/apps/pwa/out/_next/static/chunks/9398.1f56e3f17795f43f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9527.3e5ad31c891c5fcb.js +79 -0
- package/apps/pwa/out/_next/static/chunks/9571-4ac933e774d1225c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-9fc644de2d8edae3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-0c9dace2db62bee8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-f5e65c3dc9d89f2a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/board/page-2a9c19b9a140b7b1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-61533ad92141adfb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/bots/page-112004ced6fd0329.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-f733318c237a49d8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/chat/page-51ea677d2d33bbc0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/consult/page-428b41f2f9566e3c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/control/page-1b29396ea90a61e5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-cf83ec613ac904bf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-3f4c0ecbc284bb5f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/editor/page-b63c322f54f70cc6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/exec/page-fe328c4ee9aac6b4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/field/page-bfb855c584f0fb98.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-9fc644de2d8edae3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/inside/page-47b1710c110eabd7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/intake/page-42895214458bc6d2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/layout-d03de0ebd8366e23.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live/page-3ed6c47e4b1c61c2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-ae653e9bf261c738.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/loops/page-23f3f0a0209c0ac4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/market/page-88c691273aae66f9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-e187ac52a95538b3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/morning/page-6e45828daed1295e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/not-found-edb5d7287bb46186.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-4a7eaacd93c3f6a5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-3ca073d43d74cc84.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-1e9fee67b1199436.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-df1283ea963c6816.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-19fcf8d8301ccd18.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/page-5ab699e0303bbb40.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-7cde0d29756984c5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-9d4c598e8ee22f7a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-cc1609a71f44ec62.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-7659a9a1345bfaa9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/page-0afef60ecc0c4af5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-a3553949f8f34f5f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-9fc644de2d8edae3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/page-057a69702f3c67c7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/share/page-c0f0e570f3f74c73.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-1825071ae34e3b89.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-6244e3e135d8ccfc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/term/page-da787e8a10b8a82e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/today/page-1316d32498e2be42.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/trace/page-4df94572e343de2e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/vault/page-708969f7475e88c1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-c58add08c919a1dc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-a24847f45e5d5bf9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-acfec65a3a60e22e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-3dfc598e6fbde245.js +1 -0
- package/apps/pwa/out/_next/static/chunks/framework-c658a626118411b7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-4c73685fd891445b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-app-6310f7e5de7dd01d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_app-51c326bf48610be1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_error-d0beadf754da59b0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/webpack-acd243bfbf3f6732.js +1 -0
- package/apps/pwa/out/_next/static/css/d1f8bb401740a549.css +1 -0
- package/apps/pwa/out/approvals/index.html +1 -1
- package/apps/pwa/out/approvals/index.txt +23 -23
- package/apps/pwa/out/autopilot/index.html +1 -1
- package/apps/pwa/out/autopilot/index.txt +23 -23
- package/apps/pwa/out/board/index.html +1 -1
- package/apps/pwa/out/board/index.txt +23 -23
- package/apps/pwa/out/botlab/index.html +1 -1
- package/apps/pwa/out/botlab/index.txt +22 -22
- package/apps/pwa/out/bots/index.html +1 -1
- package/apps/pwa/out/bots/index.txt +22 -22
- package/apps/pwa/out/ceo/index.html +1 -1
- package/apps/pwa/out/ceo/index.txt +23 -23
- package/apps/pwa/out/chat/index.html +1 -1
- package/apps/pwa/out/chat/index.txt +22 -22
- package/apps/pwa/out/consult/index.html +1 -1
- package/apps/pwa/out/consult/index.txt +23 -23
- package/apps/pwa/out/control/index.html +1 -1
- package/apps/pwa/out/control/index.txt +23 -23
- package/apps/pwa/out/decisions/index.html +1 -1
- package/apps/pwa/out/decisions/index.txt +22 -22
- package/apps/pwa/out/design-check/index.html +1 -1
- package/apps/pwa/out/design-check/index.txt +23 -23
- package/apps/pwa/out/editor/index.html +1 -1
- package/apps/pwa/out/editor/index.txt +23 -23
- package/apps/pwa/out/exec/index.html +1 -1
- package/apps/pwa/out/exec/index.txt +23 -23
- package/apps/pwa/out/field/index.html +1 -1
- package/apps/pwa/out/field/index.txt +23 -23
- package/apps/pwa/out/healthz +1 -1
- package/apps/pwa/out/index.html +1 -1
- package/apps/pwa/out/index.txt +22 -22
- package/apps/pwa/out/inside/index.html +1 -1
- package/apps/pwa/out/inside/index.txt +22 -22
- package/apps/pwa/out/intake/index.html +1 -1
- package/apps/pwa/out/intake/index.txt +23 -23
- package/apps/pwa/out/live/index.html +1 -1
- package/apps/pwa/out/live/index.txt +23 -23
- package/apps/pwa/out/live-run/index.html +1 -1
- package/apps/pwa/out/live-run/index.txt +23 -23
- package/apps/pwa/out/loops/index.html +1 -1
- package/apps/pwa/out/loops/index.txt +22 -22
- package/apps/pwa/out/market/index.html +1 -1
- package/apps/pwa/out/market/index.txt +22 -22
- package/apps/pwa/out/missions/placeholder/index.html +1 -1
- package/apps/pwa/out/missions/placeholder/index.txt +22 -22
- package/apps/pwa/out/morning/index.html +1 -1
- package/apps/pwa/out/morning/index.txt +23 -23
- package/apps/pwa/out/observatory/index.html +1 -1
- package/apps/pwa/out/observatory/index.txt +23 -23
- package/apps/pwa/out/ops/checklist/index.html +1 -1
- package/apps/pwa/out/ops/checklist/index.txt +22 -22
- package/apps/pwa/out/ops/release/index.html +1 -1
- package/apps/pwa/out/ops/release/index.txt +22 -22
- package/apps/pwa/out/ops/seats/index.html +1 -1
- package/apps/pwa/out/ops/seats/index.txt +22 -22
- package/apps/pwa/out/outputs/index.html +1 -1
- package/apps/pwa/out/outputs/index.txt +22 -22
- package/apps/pwa/out/reflection/index.html +1 -1
- package/apps/pwa/out/reflection/index.txt +23 -23
- package/apps/pwa/out/scheduler/index.html +1 -1
- package/apps/pwa/out/scheduler/index.txt +23 -23
- package/apps/pwa/out/sessions/index.html +1 -1
- package/apps/pwa/out/sessions/index.txt +22 -22
- package/apps/pwa/out/settings/devices/index.html +1 -1
- package/apps/pwa/out/settings/devices/index.txt +23 -23
- package/apps/pwa/out/settings/index.html +1 -1
- package/apps/pwa/out/settings/index.txt +23 -23
- package/apps/pwa/out/setup/done/index.html +1 -1
- package/apps/pwa/out/setup/done/index.txt +23 -23
- package/apps/pwa/out/setup/index.html +1 -1
- package/apps/pwa/out/setup/index.txt +23 -23
- package/apps/pwa/out/share/index.html +1 -1
- package/apps/pwa/out/share/index.txt +23 -23
- package/apps/pwa/out/showroom/index.html +1 -1
- package/apps/pwa/out/showroom/index.txt +22 -22
- package/apps/pwa/out/tasks/index.html +1 -1
- package/apps/pwa/out/tasks/index.txt +23 -23
- package/apps/pwa/out/term/index.html +1 -1
- package/apps/pwa/out/term/index.txt +23 -23
- package/apps/pwa/out/today/index.html +1 -1
- package/apps/pwa/out/today/index.txt +23 -23
- package/apps/pwa/out/trace/index.html +1 -1
- package/apps/pwa/out/trace/index.txt +23 -23
- package/apps/pwa/out/vault/index.html +1 -1
- package/apps/pwa/out/vault/index.txt +23 -23
- package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
- package/apps/pwa/out/workflows/chat-ui/index.txt +23 -23
- package/apps/pwa/out/workflows/index.html +1 -1
- package/apps/pwa/out/workflows/index.txt +23 -23
- package/apps/pwa/out/workspace/index.html +1 -1
- package/apps/pwa/out/workspace/index.txt +23 -23
- package/apps/pwa/out/worktrees/index.html +1 -1
- package/apps/pwa/out/worktrees/index.txt +23 -23
- package/catalog/external-commands.yaml +5 -3
- package/catalog/meta/catalogVersion.yaml +2 -1
- package/catalog/signing/catalog-signing-public.pem +3 -0
- package/graphs/intake/intake-daily.yaml +16 -0
- package/graphs/intake/news-sources.yaml +1 -0
- package/graphs/intake/recipes.yaml +7 -0
- package/graphs/overlays/README.md +6 -0
- package/graphs/overlays/examples/research-runtime-empty-terminal.yaml +28 -0
- package/graphs/profiles/local.yaml +5 -0
- package/graphs/profiles/pod.yaml +4 -0
- package/graphs/release/release-loop.yaml +33 -17
- package/graphs/units/verbs/make-doc.yaml +1 -0
- package/package.json +6 -2
- package/plugins/demo-absorption-briefing/plugin.json +18 -0
- package/plugins/demo-absorption-briefing/skills/demo-absorption-briefing/SKILL.md +8 -0
- package/plugins/demo-browser-hand/plugin.json +13 -0
- package/plugins/demo-browser-hand/skills/demo-browser-hand/SKILL.md +8 -0
- package/plugins/demo-linear-secretary/plugin.json +15 -0
- package/plugins/demo-linear-secretary/skills/demo-linear-secretary/SKILL.md +8 -0
- package/plugins/demo-plugin-wizard/plugin.json +11 -0
- package/plugins/demo-plugin-wizard/skills/demo-plugin-wizard/SKILL.md +8 -0
- package/plugins/demo-research/plugin.json +16 -0
- package/plugins/demo-research/skills/demo-research/SKILL.md +8 -0
- package/plugins/demo-video-briefing/plugin.json +15 -0
- package/plugins/demo-video-briefing/skills/demo-video-briefing/SKILL.md +8 -0
- package/scripts/bench-metering-plan.ts +229 -0
- package/scripts/build-signed-catalog.ts +48 -0
- package/scripts/ci-typecheck-main-delta.sh +88 -0
- package/scripts/codex-fallback-live-probe.ts +1 -1
- package/scripts/demo/demo1104-parallel-host.ts +56 -0
- package/scripts/demo/demo1104-parallel-scenes.ts +301 -0
- package/scripts/demo/demo1104-parallel.ts +72 -0
- package/scripts/demo/demo1104-stage.config.ts +21 -0
- package/scripts/demo/demo1104-stage.ts +316 -0
- package/scripts/goal-method-audit.ts +17 -1
- package/scripts/graph-units/land-enqueue.ts +90 -0
- package/scripts/hooks/codex-notify.sh +32 -0
- package/scripts/install.sh +10 -38
- package/scripts/landing-heal/land-plan.ts +57 -0
- package/scripts/public-leak-baseline.txt +0 -1
- package/scripts/release-loop/auto-approve-node.ts +1 -1
- package/scripts/release-loop/docs-node.ts +4 -2
- package/scripts/release-loop/gate-autoheal-sim-evidence.ts +60 -0
- package/scripts/release-loop/gate-image-pin.ts +116 -2
- package/scripts/release-loop/gate-method.ts +139 -0
- package/scripts/release-loop/gate-node.ts +395 -43
- package/scripts/release-loop/gate-progress-sim.ts +73 -0
- package/scripts/release-loop/gate-traffic-mode.ts +151 -3
- package/scripts/release-loop/node-verdict.ts +38 -25
- package/scripts/release-loop/notes-repair.ts +18 -1
- package/scripts/release-loop/preflight.ts +544 -10
- package/scripts/release-loop/render-warm-control-manifest.ts +22 -0
- package/scripts/release-loop/resume-release.ts +9 -7
- package/scripts/release-loop/resume.ts +13 -4
- package/scripts/release-loop/unattended-release.ts +20 -9
- package/scripts/release-loop/warm-control-forward.ts +178 -0
- package/scripts/retro-cycle.ts +30 -8
- package/scripts/rhythm/daily.ts +39 -4
- package/scripts/rhythm/linear-progress-sync.ts +311 -0
- package/scripts/ux-sim.ts +7 -1
- package/scripts/video-pipeline.ts +9 -1
- package/scripts/warm-pool-provider-config.ts +35 -7
- package/src/acp/agent-manager.ts +1 -0
- package/src/acp/codex-app-server-agent.ts +33 -0
- package/src/acp/codex-app-server-client.ts +153 -16
- package/src/acp/core-turn-bridge.ts +17 -12
- package/src/acp/event-router.ts +20 -1
- package/src/acp/server.ts +6 -0
- package/src/agent-mission/browser-roundtrip-coordinator.ts +85 -0
- package/src/agent-mission/claude-headless.ts +4 -1
- package/src/agent-mission/codex-exec.ts +105 -0
- package/src/agent-mission/driver.ts +192 -11
- package/src/agent-mission/grok-auth-status.ts +107 -0
- package/src/agent-mission/hand-hooks.ts +101 -0
- package/src/agent-mission/mission-cli.ts +56 -21
- package/src/agent-mission/mission-hand-reply.ts +118 -0
- package/src/agent-mission/mission-line.ts +180 -0
- package/src/agent-mission/mission-out.ts +256 -18
- package/src/agent-mission/tool-install.ts +122 -11
- package/src/agent-substrate/pr-reviewer.ts +147 -11
- package/src/agent-substrate/self-review-cli.ts +10 -2
- package/src/agents/general-purpose.md +1 -1
- package/src/auto-research/research-fanout.ts +221 -0
- package/src/auto-research/research-turn.ts +362 -31
- package/src/autopilot/mission-codebase-gate.ts +7 -3
- package/src/autopilot/pr-manager.ts +31 -3
- package/src/boot/daemon-tools/self-implement.ts +3 -1
- package/src/boot/daemon-tools/web-search.ts +1 -2
- package/src/briefing/brief-items.ts +55 -11
- package/src/cli/agent-cli.ts +2 -1
- package/src/cli/catalog-cli.ts +31 -0
- package/src/cli/connector-cli.ts +16 -0
- package/src/cli/control-cli.ts +15 -6
- package/src/cli/doctor-fix.ts +2 -2
- package/src/cli/intake-source-cli.ts +44 -8
- package/src/cli/log-event-names.ts +8 -0
- package/src/cli/msg-cli.ts +32 -3
- package/src/cli/pr-cli.ts +21 -1
- package/src/cli/pr-land-heavy-remote.ts +44 -6
- package/src/cli/pr-land-overlap-evidence.ts +13 -1
- package/src/cli/pr-land-pod-shadow-job.ts +143 -5
- package/src/cli/pr-land-pod-shadow.ts +9 -2
- package/src/cli/release-checklist-read-cli.ts +44 -16
- package/src/cli/release-cli.ts +23 -3
- package/src/cli/research-cli.ts +9 -0
- package/src/cli/setup-cli.ts +166 -6
- package/src/cli/setup-keys.ts +199 -0
- package/src/cli/task-plugin-wizard-host.ts +114 -0
- package/src/cli/tasks-cli.ts +54 -9
- package/src/cli/tui-test-cli.ts +190 -0
- package/src/config.ts +4 -2
- package/src/connectors/linear-daily-progress.ts +228 -0
- package/src/connectors/linear-projector.ts +34 -12
- package/src/connectors/linear.ts +151 -7
- package/src/control-plane/ledger.ts +42 -4
- package/src/control-plane/member-tokens.ts +25 -2
- package/src/control-plane/ports.ts +8 -3
- package/src/control-plane/server.ts +26 -5
- package/src/core-turn/deep-turn-bloom.ts +67 -0
- package/src/core-turn/research-policy.ts +43 -0
- package/src/core-turn/run-core-turn.ts +488 -51
- package/src/core-turn/types.ts +4 -0
- package/src/dashboard/chat/acp-chat.ts +10 -0
- package/src/dashboard/classic-sidetab-mission-job.ts +192 -0
- package/src/dashboard/classic-sidetab-mission-pair.ts +82 -0
- package/src/dashboard/classic-sidetab-mission-trio.ts +242 -0
- package/src/dashboard/classic-sidetab-mission.ts +169 -5
- package/src/dashboard/index.ts +387 -14
- package/src/dashboard/input/chat-main-acp-dispatch.ts +23 -0
- package/src/dashboard/input/chat-main-plain-turn-runtime.ts +8 -0
- package/src/dashboard/mission-cli-consumer.ts +20 -8
- package/src/dashboard/plugin-wizard-runtime.ts +50 -0
- package/src/dashboard/plugin-wizard-tool.ts +55 -0
- package/src/dashboard/sidetab-runtime.ts +3 -1
- package/src/dashboard/terminal-popup-runtime.ts +6 -3
- package/src/dashboard/visible-mission-diagnostics.ts +16 -0
- package/src/decisions/linear-progress-summary.ts +78 -0
- package/src/decisions/linear-progress-sync.ts +152 -0
- package/src/domains/outbound-alert.ts +49 -11
- package/src/domains/retro-cycle-observation.ts +43 -0
- package/src/domains/retro-cycle.ts +13 -2
- package/src/domains/retro-proposals.ts +92 -0
- package/src/domains/retro-report.ts +6 -1
- package/src/domains/telegram-kind-route.ts +16 -9
- package/src/graph-runner/arg-allowance.ts +13 -0
- package/src/graph-runner/graph-cli.ts +24 -1
- package/src/graph-runner/graph-grow-llm.ts +3 -1
- package/src/graph-runner/graph-run-api.ts +3 -1
- package/src/graph-runner/runner.ts +310 -46
- package/src/graph-wizard/mission-compose.ts +407 -12
- package/src/harness/dispatch-backpressure.ts +54 -1
- package/src/harness/dispatch-shadow-compare.ts +74 -0
- package/src/harness/harness-cli-command.ts +15 -3
- package/src/harness/harness-pod-dispatch.ts +3 -0
- package/src/harness/skill-exec.ts +21 -9
- package/src/harness/skill-select.ts +1 -1
- package/src/hooks/error-report-cloud.ts +101 -0
- package/src/hooks/receiver.ts +29 -2
- package/src/index.ts +129 -12
- package/src/intake-plane/actions.ts +354 -0
- package/src/intake-plane/adapters/telegram-ambient.ts +34 -18
- package/src/intake-plane/intake-sources.ts +78 -8
- package/src/intake-plane/items.ts +14 -4
- package/src/intake-plane/linear-mission-sync.ts +80 -0
- package/src/intake-plane/linear-secretary-runtime.ts +178 -0
- package/src/intake-plane/linear-wish.ts +227 -1
- package/src/life/life-cli.ts +168 -0
- package/src/life/life-kinds.ts +160 -0
- package/src/live-supply/budget-consumer.ts +78 -0
- package/src/live-supply/read.ts +3 -0
- package/src/live-supply/snapshot.ts +45 -0
- package/src/llm/child-first-llm-observation.ts +112 -0
- package/src/llm/provider-credentials.ts +68 -6
- package/src/llm/provider-failure-evidence.ts +44 -0
- package/src/llm.ts +172 -12
- package/src/maturity/feature-maturity.ts +3 -3
- package/src/mcp/client.ts +7 -0
- package/src/mcp/proxy-runtime.ts +6 -1
- package/src/mcp/server.ts +54 -0
- package/src/msg/msg-sse-server.ts +3 -3
- package/src/msg/msg-store.ts +177 -19
- package/src/native-tool-catalog.ts +36 -2
- package/src/nexus/api/consult-requests.ts +18 -6
- package/src/nexus/api/discord-trigger-bot.ts +6 -6
- package/src/nexus/api/graphs-api.ts +4 -2
- package/src/nexus/api/grokbot-trigger-bot.ts +206 -0
- package/src/nexus/api/http-server.ts +37 -1
- package/src/nexus/api/mcp-public-allowlist.ts +2 -0
- package/src/nexus/api/telegram-trigger-bot.ts +6 -6
- package/src/nexus/boot/register-mcp-clients.ts +114 -8
- package/src/nexus/index.ts +22 -2
- package/src/nexus/outbound/format.ts +9 -0
- package/src/nexus/outbound/grokbot-adapter.ts +71 -0
- package/src/nexus/outbound/router.ts +121 -16
- package/src/nexus/setup-status.ts +9 -0
- package/src/nexus/state/state.ts +3 -0
- package/src/oauth/codex-account-store.ts +20 -7
- package/src/oauth/codex-owner-mirror.ts +81 -0
- package/src/oauth/codex.ts +17 -2
- package/src/oauth/fallback-chain.ts +47 -17
- package/src/onboarding/first-run-doctor.ts +8 -1
- package/src/onboarding/first-run.ts +126 -29
- package/src/onboarding/key-setup.ts +103 -0
- package/src/onboarding/menu-answer.ts +13 -0
- package/src/onboarding/secret-prompt.ts +37 -0
- package/src/plugins/install/plugin-install.ts +59 -0
- package/src/pr-tool/census.ts +130 -0
- package/src/preview/terminal.ts +22 -7
- package/src/prompt-enhance/enhance.ts +10 -0
- package/src/pty-shell/pty-control-ipc.ts +4 -1
- package/src/pty-shell/pty-write-provenance.ts +21 -3
- package/src/pty-shell/registry.ts +9 -2
- package/src/registry/catalog-server.ts +232 -0
- package/src/registry/loader.ts +45 -1
- package/src/registry/types.ts +1 -2
- package/src/release-loop/proposal-auto-place.ts +83 -0
- package/src/research/axis-fanout.ts +79 -29
- package/src/research/lenses/second-order.ts +312 -0
- package/src/self-dev/ask-launch-flow.ts +72 -1
- package/src/self-dev/dev-cli.ts +7 -2
- package/src/self-dev/dev-pipeline.ts +5 -0
- package/src/self-dev/draft-residue.ts +64 -5
- package/src/self-dev/draft-sweep.ts +31 -10
- package/src/self-dev/draft-triage-rules.ts +60 -3
- package/src/self-dev/graph-front-nodes.ts +2 -1
- package/src/self-dev/graph-journey-route.ts +76 -21
- package/src/self-dev/launch-preflight.ts +58 -0
- package/src/self-dev/orchestrate.ts +1 -1
- package/src/self-dev/run-supervisor.ts +152 -2
- package/src/self-dev/shard-aggregate.ts +4 -0
- package/src/self-dev/shard-run.ts +36 -15
- package/src/self-implement/abandoned-classification.ts +12 -3
- package/src/self-implement/budget-gate.ts +7 -0
- package/src/self-implement/child-llm-preference.ts +10 -1
- package/src/self-implement/doctor-visit.ts +30 -8
- package/src/self-implement/elanous-tui-spawn.ts +3 -0
- package/src/self-implement/fixtures/tdd-green-missing-passing-child-transcript.txt +2 -0
- package/src/self-implement/gate-artifacts.ts +2 -1
- package/src/self-implement/goal-author-cli.ts +4 -2
- package/src/self-implement/goal-author.ts +549 -10
- package/src/self-implement/graph-overlay-yaml.ts +181 -4
- package/src/self-implement/graph-overlay.ts +3 -1
- package/src/self-implement/graph-profile-yaml.ts +107 -0
- package/src/self-implement/graph-yaml.ts +94 -5
- package/src/self-implement/off-diff-evidence.ts +249 -5
- package/src/self-implement/orchestrator.ts +298 -26
- package/src/self-implement/run-chart.ts +6 -3
- package/src/self-implement/run-ledger.ts +51 -1
- package/src/self-implement/runtime-overlay-run-steps.ts +95 -0
- package/src/self-implement/tdd-evidence-tags.ts +9 -0
- package/src/self-implement/test-scenario-request.ts +37 -6
- package/src/self-implement/train-gate-receipt.ts +166 -0
- package/src/self-implement/train-gate-remote.ts +62 -18
- package/src/session/chat.ts +6 -4
- package/src/session/session-fanout.ts +2 -0
- package/src/session/streaming/acp-stream-sink.ts +2 -1
- package/src/session/streaming/chunk-producer.ts +6 -0
- package/src/session/streaming/stream-compositor.ts +3 -2
- package/src/session-runtime/index.ts +74 -6
- package/src/session-runtime/retry-policy.ts +1 -1
- package/src/setup/llm-env-detect.ts +3 -0
- package/src/setup/service-key-catalog.ts +46 -0
- package/src/setup/service-keys.ts +241 -0
- package/src/sidetab-core/model.ts +205 -10
- package/src/sidetab-core/visible-agent-mission-pair.ts +51 -0
- package/src/sidetab-core/visible-agent-mission.ts +182 -48
- package/src/skills/tools/agent.ts +23 -4
- package/src/skills/tools/omni-search.ts +127 -27
- package/src/task-agent/parent-host.ts +29 -1
- package/src/task-agent/recall-inject.ts +98 -0
- package/src/task-agent/repair-outcomes.ts +65 -0
- package/src/task-agent/task-hand.ts +46 -14
- package/src/task-orchestrator/dispatcher.ts +14 -1
- package/src/task-orchestrator/linear-capture-events.ts +55 -0
- package/src/task-orchestrator/store.ts +16 -5
- package/src/task-orchestrator/surfaces/pod-artifact-return.ts +23 -1
- package/src/task-orchestrator/surfaces/pod-failure-reason.ts +107 -1
- package/src/task-orchestrator/surfaces/pod-ledger-events.ts +113 -14
- package/src/task-orchestrator/surfaces/pod-si-warm-host.ts +21 -9
- package/src/task-orchestrator/surfaces/pod-source-receive.ts +23 -11
- package/src/task-orchestrator/surfaces/pod-warm-switch.ts +2 -0
- package/src/task-orchestrator/surfaces/pod-warm-worker-pod.ts +1 -1
- package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +467 -77
- package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +45 -3
- package/src/task-orchestrator/surfaces/self-implement-pod.ts +210 -14
- package/src/task-orchestrator/surfaces/self-implement.ts +27 -3
- package/src/task-orchestrator/surfaces/warm-reuse-evidence.ts +169 -0
- package/src/task-orchestrator/types.ts +14 -0
- package/src/telegram.ts +14 -16
- package/src/terminal/coding-agent.ts +14 -5
- package/src/terminal/session-registry.ts +1 -1
- package/src/tool-hints/gate.ts +46 -14
- package/src/tool-hints/signals.ts +1 -1
- package/src/tool-hints/types.ts +2 -0
- package/src/tool-runtime/agent-runtime.ts +1 -0
- package/src/tool-runtime/browser-hand-runtime.ts +391 -0
- package/src/tool-runtime/browser-runtime.ts +33 -19
- package/src/tool-runtime/elanous-linear-issue-runtime.ts +76 -0
- package/src/tool-runtime/elanous-linear-secretary-runtime.ts +173 -0
- package/src/tool-runtime/graph-mcp-runtimes.ts +240 -0
- package/src/tool-runtime/index.ts +6 -0
- package/src/tool-runtime/types.ts +5 -0
- package/src/tui/entry.ts +51 -8
- package/src/tui/sidetab/attach.ts +252 -11
- package/src/tui/sidetab/herdr-portal.ts +225 -0
- package/src/tui/sidetab/list.ts +3 -2
- package/src/tui-client/next-dashboard-runtime.ts +52 -0
- package/src/user-config.ts +34 -9
- package/src/user-intent/types.ts +4 -3
- package/src/ux-sim/browser-hand.ts +165 -0
- package/src/ux-sim/draft-inventory-builder.ts +199 -0
- package/src/ux-sim/fake-browser-page.ts +81 -0
- package/src/ux-sim/fake-linear-device.ts +31 -0
- package/src/ux-sim/graph-engine-sim.ts +47 -0
- package/src/ux-sim/linear-secretary.ts +208 -0
- package/src/ux-sim/mock-scenario-catalog.json +81 -26
- package/src/ux-sim/mock-scenario-catalog.ts +175 -5
- package/src/ux-sim/onboarding-first-run-device.ts +31 -21
- package/src/ux-sim/release-sim-rig.ts +62 -18
- package/src/ux-sim/scenario.ts +70 -26
- package/src/ux-sim/service-key-setup.ts +113 -0
- package/src/ux-sim/term-slash-device.ts +74 -0
- package/src/ux-sim/turn-throw-sim.ts +31 -0
- package/src/version/packed-revision.json +1 -1
- package/src/web-search/exa.ts +77 -0
- package/src/web-search/index.ts +30 -9
- package/src/web-search/provider.ts +4 -1
- package/src/web-search/x-intent.ts +5 -0
- package/apps/pwa/out/_next/static/chunks/0244e5b5.6fc7670f8223d82d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1121.13ba7a8aff19df81.js +0 -36
- package/apps/pwa/out/_next/static/chunks/1147-5196d19c222051b3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1319.b9b815ae0f181e06.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1345-31427b833438f521.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1455-530ca16c7e71baff.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1574.878c18ecc97b1bd4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1586.fafc33a9a5835cb7.js +0 -32
- package/apps/pwa/out/_next/static/chunks/1744.855fd60ae4c4a8c8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/193.21a47a3e07ef6860.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1945.7b54990d578c119b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2004.e839fda7ea5a738a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2044-dd681a5c08779ff8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2101.2248decb38829b03.js +0 -286
- package/apps/pwa/out/_next/static/chunks/2300.41ea70ac1bef1446.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2357-07b5eeb5fb12628d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2364.28652020695a6db3.js +0 -34
- package/apps/pwa/out/_next/static/chunks/2456.b6de0e1c05f28843.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2526.c3e50ac1fec064bd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2549-cda50b716ff4250c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2550-5f1e88f615568045.js +0 -1
- package/apps/pwa/out/_next/static/chunks/261-319078c954e40d66.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2690.0521c738b7749931.js +0 -115
- package/apps/pwa/out/_next/static/chunks/2974.595d1e29d040cb6a.js +0 -64
- package/apps/pwa/out/_next/static/chunks/3207.a756c95e9ec8c3c8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3285.89ee2f298682f5e5.js +0 -93
- package/apps/pwa/out/_next/static/chunks/3447.06edc7b092021417.js +0 -41
- package/apps/pwa/out/_next/static/chunks/3510-9ca392698bfe4391.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3541.772e5ce425aaa611.js +0 -24
- package/apps/pwa/out/_next/static/chunks/3741.9cf76acaa2ee5298.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3837.a210d7d0db8d8abd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3898-955c896f394217a6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3947-ef57acea76eaa8d2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4037-3b82ebc7d78afdc7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/405.9022d4a478202b67.js +0 -77
- package/apps/pwa/out/_next/static/chunks/417-fb2cc9a9910e5968.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4276.336d76d858fcdf1b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4302.6ced9aa4535de947.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4320.583cbab64db6be02.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4768-8eac183fd291ca53.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4770.769c9cd9c7034eba.js +0 -148
- package/apps/pwa/out/_next/static/chunks/4895.65605ec3e6504e89.js +0 -74
- package/apps/pwa/out/_next/static/chunks/50061469.0326382241ef3b2d.js +0 -122
- package/apps/pwa/out/_next/static/chunks/5112.4b9f300124fab7b3.js +0 -149
- package/apps/pwa/out/_next/static/chunks/5335.375ee922bcd5bc83.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5342.023a2e729689b320.js +0 -27
- package/apps/pwa/out/_next/static/chunks/53c73f84.373b6160adfa89a4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5431-72a1dbde59400691.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5440-4236de26c5ea5856.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5486-b318c165f645d8ba.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5506-c7d2ec25c62a7c94.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5570-c66ecbea26b4e3b1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5696.ffca5aa259d8451e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5793-8c584aea2aa87560.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5848-6de6b8c173351a90.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5999.94e3c83040200f31.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5a7901d6-2d8d9b5587cf9042.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6131.348b7d6bdcd267ce.js +0 -226
- package/apps/pwa/out/_next/static/chunks/6164.86133a0172611184.js +0 -90
- package/apps/pwa/out/_next/static/chunks/6515.e07e8b2b8a707a87.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6522-c005514f87d18982.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6642.648adb1767f39ecf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6848.138805a09d001d09.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7049-c09e2b7a253a24f3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7072.1e00447d9fa39972.js +0 -104
- package/apps/pwa/out/_next/static/chunks/7106.64201c539c5e220c.js +0 -94
- package/apps/pwa/out/_next/static/chunks/7151-1f742b455986530e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7199.18d6b25e001154ce.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7279-c199ea83f34338fa.js +0 -1
- package/apps/pwa/out/_next/static/chunks/728b938d.ffaa7ad583d60e58.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7309.171c3de54e0322f1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/733.7a1ab3342e03306f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7504.d5cf1e7cd89b1b08.js +0 -24
- package/apps/pwa/out/_next/static/chunks/7573-0fd4af62d65d4598.js +0 -1
- package/apps/pwa/out/_next/static/chunks/759.6f8267df4689c401.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7825-668b046f72f14483.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7852-1538768b6eb19388.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7868.cff810430bb63c91.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8084-dfcc796874ab4e07.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8266.6bf9b131b2584678.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8403.7b81d5e64074a725.js +0 -8
- package/apps/pwa/out/_next/static/chunks/8470.1998cbd0866a7eac.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8505.fd803c6c33b54cc3.js +0 -79
- package/apps/pwa/out/_next/static/chunks/8546-6f03f8ea34dd61d9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8687-246fda8433d3477c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/898-280022fb082936bc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9098-50eefc1844212e3d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9211-330b6736a63d4cb3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9249.976f1e69a9d80754.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9255-cf88fceda5666645.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9306-e523ba58bb8adc42.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9324.a9866d717ba62cb6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9325.a8510e8aa87c8143.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9353-12bfff0c130104cf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9479-154a697d4b6e4e98.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9540-65aa6ccc31b3fd78.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9633.ce5bddc56784da72.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9656-374232558fd528d0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9832.f4a98c878ecf2c0a.js +0 -62
- package/apps/pwa/out/_next/static/chunks/9865.f094440645f02d98.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-e772b4710df5d936.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-4361368e6a76b967.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-802f349fdd65248d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/board/page-7f35513988a2a495.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-798121656540e33e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-20a089490affe98c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-e5e4ec786d70e604.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/chat/page-d12fe5d0801430e4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/consult/page-d8cf21022fecc026.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/control/page-21ce565c9c57ee97.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-b56563025f619c9b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-52f14dd133da8348.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/editor/page-c0ed7fdcdba76633.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/exec/page-af8c3020cb520f15.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/field/page-72eda67af9f5e35c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-e772b4710df5d936.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/inside/page-67a6620d31f0a46f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/intake/page-f059363aa0880ec2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/layout-f9f917d6a57f69fb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live/page-d3ae55eee2f0826c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-0e3d7b9421b79dac.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/loops/page-ba738f7e233eb211.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/market/page-33438b98c74fd599.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-0b34d5fd990d793a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/morning/page-0f291d3c8fd55a3a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-3fced192be5279c1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-04cb3cf182a7c1ea.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-6ccbd2ab23a21542.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-aa0518c48a5f4e56.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-4b32226d341ad7d7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-3224fd8f6383b61f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/page-efbc97459f2914e2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-2fe487d88cd5d97c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-48861dd1a858bab7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-197d5d4d21d228ea.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-a763ba89fbdd9c27.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/page-7edb253510b1c136.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-0c875702c61965ea.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-e772b4710df5d936.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/page-e425c951151095f7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/share/page-9c90e0aec4e27f77.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-733e09a02e727d42.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-4f899e14c34d77a1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/term/page-bf067887b3307423.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-7af10868ff87d04e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/trace/page-efe5304057aa11c7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/vault/page-76bcd29aaa8a26c3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-4cfd88e2273ce50f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-0a1ddb47efba0a32.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-2a176c707152c892.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-efe03031b8797fbf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/framework-d0d2d673bfd8a8a9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-4c9fceb2baa09cb7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-app-b0ab8d8fc9a97556.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_app-7e2cc62a2e5cec96.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_error-22324935f753ec5e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/webpack-9dc1bfa25334998a.js +0 -1
- package/apps/pwa/out/_next/static/css/be9019f696217521.css +0 -1
- /package/apps/pwa/out/_next/static/{X1ucLw10Cds_h614NoEnh → HMXsxdy5MIIcHPMHv1wD4}/_ssgManifest.js +0 -0
|
@@ -27,6 +27,19 @@ import { debug, redactSecretText, withAmbientSessionScope } from '../debug/log.j
|
|
|
27
27
|
import { applyDeferredTools } from '../session-runtime/tier-flip.js';
|
|
28
28
|
import { isResearchAgentIntent } from '../tool-hints/signals.js';
|
|
29
29
|
import { buildResearchDateSystemMessage, resolveSessionSurfaceProfile } from '../session-runtime/index.js';
|
|
30
|
+
import {
|
|
31
|
+
isResearchToolAllowed,
|
|
32
|
+
RESEARCH_DOCUMENT_WRITE_TOOLS,
|
|
33
|
+
requestsResearchDocumentWrite,
|
|
34
|
+
RESEARCH_TOOL_ALLOWLIST,
|
|
35
|
+
RESEARCH_TURN_DEEP_BUDGET_MS,
|
|
36
|
+
RESEARCH_TURN_DEADLINE_STOP_ERROR,
|
|
37
|
+
RESEARCH_TURN_FIRST_REPLY_BUDGET_MS,
|
|
38
|
+
RESEARCH_TURN_FINAL_ANSWER_DEADLINE_MS,
|
|
39
|
+
RESEARCH_TURN_MAX_TOOL_TURNS,
|
|
40
|
+
RESEARCH_TURN_SHALLOW_FINAL_ANSWER_DEADLINE_MS,
|
|
41
|
+
RESEARCH_TURN_SHALLOW_BUDGET_MS,
|
|
42
|
+
} from './research-policy.js';
|
|
30
43
|
import type {
|
|
31
44
|
CoreTurnContext,
|
|
32
45
|
CoreTurnResult,
|
|
@@ -35,6 +48,14 @@ import type {
|
|
|
35
48
|
|
|
36
49
|
const CORE_TURN_TOOL_RESULT_INLINE_LIMIT_BYTES = 50 * 1024;
|
|
37
50
|
|
|
51
|
+
// A deep, non-research prompt gets the same-call Bloom frame, but should not
|
|
52
|
+
// silently grow into multi-source research just because the model can reach
|
|
53
|
+
// generic skill/search tools. Explicit research turns and explicit named-skill
|
|
54
|
+
// requests keep the normal tool surface.
|
|
55
|
+
const DEEP_NON_RESEARCH_SEARCH_TOOLS = new Set([
|
|
56
|
+
'skill_exec', 'elanous_skills_list', 'websearch', 'web_search', 'omnisearch', 'omni_search', 'webfetch', 'web_fetch',
|
|
57
|
+
]);
|
|
58
|
+
|
|
38
59
|
/** Classify an error thrown out of `streamLLMWithTools` into the
|
|
39
60
|
* Core-turn stop-reason set. Abort wins over everything else;
|
|
40
61
|
* credential rejection (`isAuthRejectionError`) is distinct from a
|
|
@@ -82,8 +103,31 @@ function selectSurfaceUserText(ctx: CoreTurnContext): string | undefined {
|
|
|
82
103
|
* the research turn's text-only provisional answer. That provisional pass
|
|
83
104
|
* has no tools by design and otherwise tells the user the requested skill
|
|
84
105
|
* cannot be invoked, even when the skill router already resolved it. */
|
|
85
|
-
function
|
|
106
|
+
function requestedInstalledSkillName(text: string | undefined, installedSkillNames: readonly string[]): string | undefined {
|
|
107
|
+
if (!text) return undefined;
|
|
108
|
+
return installedSkillNames
|
|
109
|
+
.filter((name) => name.includes('-'))
|
|
110
|
+
.sort((a, b) => b.length - a.length)
|
|
111
|
+
.find((name) => {
|
|
112
|
+
const parts = name.trim().split(/[-\s]+/).filter(Boolean);
|
|
113
|
+
if (parts.length < 2 || !parts.every((part) => /^[a-z0-9]+$/i.test(part))) return false;
|
|
114
|
+
const slug = parts.join('[\\s-]*');
|
|
115
|
+
return new RegExp('(?:^|[^\\p{L}\\p{N}])' + slug + '(?=$|[^a-z0-9])\\s*(?:으로|로)(?=[^\\n!?]{0,120}(?:찾아|조사|정리))', 'iu').test(text);
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export function requestsNamedSkill(text: string | undefined, installedSkillNames: readonly string[] = []): boolean {
|
|
86
120
|
if (!text) return false;
|
|
121
|
+
const requestedInstalledSkill = installedSkillNames
|
|
122
|
+
.filter((name) => name.includes('-'))
|
|
123
|
+
.sort((a, b) => b.length - a.length)
|
|
124
|
+
.some((name) => {
|
|
125
|
+
const parts = name.trim().split(/[-\s]+/).filter(Boolean);
|
|
126
|
+
if (parts.length < 2 || !parts.every((part) => /^[a-z0-9]+$/i.test(part))) return false;
|
|
127
|
+
const slug = parts.join('[\\s-]*');
|
|
128
|
+
return new RegExp('(?:^|[^\\p{L}\\p{N}])' + slug + '(?=$|[^a-z0-9])\\s*(?:으로|로)(?=[^\\n!?]{0,120}(?:찾아|조사|정리))', 'iu').test(text);
|
|
129
|
+
});
|
|
130
|
+
if (requestedInstalledSkill) return true;
|
|
87
131
|
const action = '(?:use|invoke|run|call|execute|launch|trigger|apply|start)';
|
|
88
132
|
return new RegExp(`\\b${action}\\s+(?:(?:the|a|an)\\s+)?skill\\s+(?:named|called)\\s+['"“‘]([a-z0-9][a-z0-9 _-]{1,60}?)['"”’](?=$|[\\s.,;!?])`, 'i').test(text)
|
|
89
133
|
|| new RegExp(`\\b${action}\\s+(?:the\\s+)?['"“‘]([a-z0-9][a-z0-9 _-]{1,60}?)['"”’](?=$|[\\s.,;!?])`, 'i').test(text)
|
|
@@ -119,23 +163,36 @@ function requestsNamedSkill(text: string | undefined): boolean {
|
|
|
119
163
|
*/
|
|
120
164
|
export interface RunCoreTurnOptions {
|
|
121
165
|
now?: () => number;
|
|
122
|
-
|
|
166
|
+
timers?: { setTimeout(callback: () => void, delayMs: number): ReturnType<typeof setTimeout>; clearTimeout(handle: ReturnType<typeof setTimeout>): void };
|
|
167
|
+
firstReplyBudgetMs?: number;
|
|
168
|
+
researchWallClockBudgetMs?: number;
|
|
169
|
+
runResearch?: (
|
|
170
|
+
request: string,
|
|
171
|
+
signal: AbortSignal,
|
|
172
|
+
admitToolCall?: (name: string) => boolean,
|
|
173
|
+
providerRouting?: Pick<CoreTurnContext, 'initialProvider' | 'skipProviders' | 'runId'>,
|
|
174
|
+
) => Promise<{ ok: boolean; output: string; error?: string; axisCount?: number }>;
|
|
123
175
|
}
|
|
124
176
|
|
|
177
|
+
type ResearchTimer = ReturnType<typeof setTimeout>;
|
|
178
|
+
|
|
125
179
|
type AbortRace<T> = { aborted: true } | { aborted: false; value: T };
|
|
126
180
|
|
|
127
181
|
function settleBeforeAbort<T>(work: Promise<T>, signal: AbortSignal): Promise<AbortRace<T>> {
|
|
128
|
-
if (signal.aborted) return Promise.resolve({ aborted: true });
|
|
129
182
|
return new Promise((resolve, reject) => {
|
|
183
|
+
let abortGraceTimer: ReturnType<typeof setTimeout> | undefined;
|
|
130
184
|
const onAbort = () => {
|
|
131
185
|
signal.removeEventListener('abort', onAbort);
|
|
132
|
-
|
|
186
|
+
// Let work handlers that synchronously settle in response to abort
|
|
187
|
+
// expose their final partial result before taking the deadline path.
|
|
188
|
+
abortGraceTimer = setTimeout(() => resolve({ aborted: true }), 50);
|
|
133
189
|
};
|
|
134
|
-
signal.addEventListener('abort', onAbort, { once: true });
|
|
135
190
|
work.then(
|
|
136
|
-
value => { signal.removeEventListener('abort', onAbort); resolve({ aborted: false, value }); },
|
|
137
|
-
error => { signal.removeEventListener('abort', onAbort); reject(error); },
|
|
191
|
+
value => { signal.removeEventListener('abort', onAbort); if (abortGraceTimer) clearTimeout(abortGraceTimer); resolve({ aborted: false, value }); },
|
|
192
|
+
error => { signal.removeEventListener('abort', onAbort); if (abortGraceTimer) clearTimeout(abortGraceTimer); reject(error); },
|
|
138
193
|
);
|
|
194
|
+
if (signal.aborted) onAbort();
|
|
195
|
+
else signal.addEventListener('abort', onAbort, { once: true });
|
|
139
196
|
});
|
|
140
197
|
}
|
|
141
198
|
|
|
@@ -174,6 +231,41 @@ function commitProvisionalTurn(
|
|
|
174
231
|
commitCompletion(messages, handlers, setFinalPhaseAnswer);
|
|
175
232
|
}
|
|
176
233
|
|
|
234
|
+
function completionWithFinalText(messages: TurnCompletion | undefined, text: string): TurnCompletion {
|
|
235
|
+
const completed = [...(messages ?? [])];
|
|
236
|
+
let lastAssistant = -1;
|
|
237
|
+
for (let index = completed.length - 1; index >= 0; index -= 1) {
|
|
238
|
+
if (completed[index]?.role === 'assistant') { lastAssistant = index; break; }
|
|
239
|
+
}
|
|
240
|
+
if (lastAssistant < 0) {
|
|
241
|
+
completed.push({ role: 'assistant', content: text, phase: 'final_answer' });
|
|
242
|
+
} else {
|
|
243
|
+
const previous = completed[lastAssistant]!;
|
|
244
|
+
let content: typeof previous.content;
|
|
245
|
+
if (typeof previous.content === 'string') {
|
|
246
|
+
content = text;
|
|
247
|
+
} else {
|
|
248
|
+
let lastText = -1;
|
|
249
|
+
for (let index = previous.content.length - 1; index >= 0; index -= 1) {
|
|
250
|
+
if (previous.content[index]?.type === 'text') { lastText = index; break; }
|
|
251
|
+
}
|
|
252
|
+
if (lastText < 0) {
|
|
253
|
+
// A tool-only assistant message must stay paired with its tool result;
|
|
254
|
+
// the synthesized prose is a separate final answer message.
|
|
255
|
+
completed.push({ role: 'assistant', content: text, phase: 'final_answer' });
|
|
256
|
+
return completed;
|
|
257
|
+
}
|
|
258
|
+
content = previous.content.map((block, index) => index === lastText && block.type === 'text'
|
|
259
|
+
? { ...block, text }
|
|
260
|
+
: block);
|
|
261
|
+
}
|
|
262
|
+
completed[lastAssistant] = {
|
|
263
|
+
...previous, content, phase: 'final_answer',
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
return completed;
|
|
267
|
+
}
|
|
268
|
+
|
|
177
269
|
function commitStagedTurn(
|
|
178
270
|
messages: TurnCompletion | undefined,
|
|
179
271
|
handlers: StreamWithToolsHandlers,
|
|
@@ -182,8 +274,25 @@ function commitStagedTurn(
|
|
|
182
274
|
setFinalPhaseAnswer: (value: boolean) => void,
|
|
183
275
|
onReplaceText?: (fullText: string) => void,
|
|
184
276
|
): void {
|
|
185
|
-
|
|
277
|
+
// Replacement must reach the stream bridge before completion: ACP tracks the
|
|
278
|
+
// visible tail in `onReplaceText` so its completion callback will not emit the
|
|
279
|
+
// same synthesized answer a second time.
|
|
186
280
|
if (replaceVisibleText && text) onReplaceText?.(text);
|
|
281
|
+
commitCompletion(messages, handlers, setFinalPhaseAnswer);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
function commitSynthesizedTurn(
|
|
285
|
+
staged: ReturnType<typeof createStagedHandlers>,
|
|
286
|
+
fallbackMessages: TurnCompletion | undefined,
|
|
287
|
+
handlers: StreamWithToolsHandlers,
|
|
288
|
+
finalText: string,
|
|
289
|
+
provisionalText: string,
|
|
290
|
+
setFinalPhaseAnswer: (value: boolean) => void,
|
|
291
|
+
onReplaceText?: (fullText: string) => void,
|
|
292
|
+
): void {
|
|
293
|
+
const completion = staged.completion() ?? completionWithFinalText(fallbackMessages, finalText);
|
|
294
|
+
commitStagedTurn(completion, handlers, finalText, finalText !== provisionalText,
|
|
295
|
+
setFinalPhaseAnswer, onReplaceText);
|
|
187
296
|
}
|
|
188
297
|
|
|
189
298
|
export async function runCoreTurn(
|
|
@@ -191,6 +300,10 @@ export async function runCoreTurn(
|
|
|
191
300
|
options: RunCoreTurnOptions = {},
|
|
192
301
|
): Promise<CoreTurnResult> {
|
|
193
302
|
const now = options.now ?? Date.now;
|
|
303
|
+
const timers = options.timers ?? {
|
|
304
|
+
setTimeout: (callback: () => void, delayMs: number) => setTimeout(callback, delayMs),
|
|
305
|
+
clearTimeout: (handle: ReturnType<typeof setTimeout>) => clearTimeout(handle),
|
|
306
|
+
};
|
|
194
307
|
let turnStartedAt: number | undefined;
|
|
195
308
|
let researchStartedAt: number | undefined;
|
|
196
309
|
let researchFirstTokenRecorded = false;
|
|
@@ -214,6 +327,62 @@ export async function runCoreTurn(
|
|
|
214
327
|
let accumulatedText = '';
|
|
215
328
|
let dispatchCount = 0;
|
|
216
329
|
let finalPhaseAnswer = false;
|
|
330
|
+
let enforceResearchToolAllowlist = false;
|
|
331
|
+
let enforceResearchDocumentWrite = false;
|
|
332
|
+
const isAllowedResearchTool = (name: string): boolean => isResearchToolAllowed(name)
|
|
333
|
+
|| (enforceResearchDocumentWrite && (RESEARCH_DOCUMENT_WRITE_TOOLS as readonly string[]).includes(name));
|
|
334
|
+
let enforceResearchToolBudget = false;
|
|
335
|
+
let researchToolCallCount = 0;
|
|
336
|
+
let researchAxisCount = 0;
|
|
337
|
+
let researchStopReason: string | undefined;
|
|
338
|
+
const loggedResearchStops = new Set<string>();
|
|
339
|
+
const logResearchStop = (reason: string, extra: Record<string, unknown> = {}): void => {
|
|
340
|
+
if (loggedResearchStops.has(reason)) return;
|
|
341
|
+
loggedResearchStops.add(reason);
|
|
342
|
+
debug.log('research.stop', 'stopped', { sessionId: ctx.sessionId, reason, ...extra });
|
|
343
|
+
};
|
|
344
|
+
const admitResearchToolCall = (name: string): boolean => {
|
|
345
|
+
if (!enforceResearchToolBudget) return true;
|
|
346
|
+
if (name === 'Agent' && researchAxisCount < 3) {
|
|
347
|
+
debug.log('research.turn', 'subagent-skipped', {
|
|
348
|
+
sessionId: ctx.sessionId, reason: 'insufficient-judgment-axes', axisCount: researchAxisCount, minimum: 3,
|
|
349
|
+
});
|
|
350
|
+
return false;
|
|
351
|
+
}
|
|
352
|
+
if (researchToolCallCount >= RESEARCH_TURN_MAX_TOOL_TURNS) {
|
|
353
|
+
// A prior denied tool is observable, but it must not mask the hard
|
|
354
|
+
// budget stop that requires tool-free synthesis. A wall-clock stop is
|
|
355
|
+
// already terminal and keeps its more specific reason.
|
|
356
|
+
if (researchStopReason !== 'wall-clock-budget') researchStopReason = 'tool-budget';
|
|
357
|
+
logResearchStop('tool-budget', { stage: 'tool-dispatch', tool: name, count: researchToolCallCount, limit: RESEARCH_TURN_MAX_TOOL_TURNS });
|
|
358
|
+
return false;
|
|
359
|
+
}
|
|
360
|
+
researchToolCallCount += 1;
|
|
361
|
+
return true;
|
|
362
|
+
};
|
|
363
|
+
const constrainResearchToolArgs = (name: string, args: Record<string, unknown>): Record<string, unknown> => {
|
|
364
|
+
if (!enforceResearchToolAllowlist || name !== 'Agent' || !args || typeof args !== 'object' || Array.isArray(args)) return args;
|
|
365
|
+
const raw = args;
|
|
366
|
+
const rawFilter = raw.tool_filter && typeof raw.tool_filter === 'object' && !Array.isArray(raw.tool_filter)
|
|
367
|
+
? raw.tool_filter as { deny?: unknown }
|
|
368
|
+
: {};
|
|
369
|
+
const deny = Array.isArray(rawFilter.deny) ? rawFilter.deny.filter((tool): tool is string => typeof tool === 'string') : [];
|
|
370
|
+
return {
|
|
371
|
+
...raw,
|
|
372
|
+
subagent_type: typeof raw.subagent_type === 'string' && raw.subagent_type.trim()
|
|
373
|
+
? raw.subagent_type
|
|
374
|
+
: 'general-purpose',
|
|
375
|
+
run_in_background: false,
|
|
376
|
+
wait_for_slot: false,
|
|
377
|
+
max_turns: typeof raw.max_turns === 'number' && Number.isFinite(raw.max_turns)
|
|
378
|
+
? Math.max(1, Math.min(RESEARCH_TURN_MAX_TOOL_TURNS, Math.floor(raw.max_turns)))
|
|
379
|
+
: RESEARCH_TURN_MAX_TOOL_TURNS,
|
|
380
|
+
tool_filter: {
|
|
381
|
+
allow: ['Read', 'WebFetch'],
|
|
382
|
+
deny: [...new Set([...deny, 'Bash', 'Edit', 'Grep'])],
|
|
383
|
+
},
|
|
384
|
+
};
|
|
385
|
+
};
|
|
217
386
|
|
|
218
387
|
const handlers: StreamWithToolsHandlers = {
|
|
219
388
|
onText: (delta, full) => {
|
|
@@ -254,9 +423,28 @@ export async function runCoreTurn(
|
|
|
254
423
|
|
|
255
424
|
let success = false;
|
|
256
425
|
try {
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
426
|
+
let result: unknown;
|
|
427
|
+
if (enforceResearchToolAllowlist && !isAllowedResearchTool(name)) {
|
|
428
|
+
researchStopReason ??= 'tool-not-allowed';
|
|
429
|
+
logResearchStop('tool-not-allowed', { stage: 'tool-dispatch', tool: name, allowedTools: [...RESEARCH_TOOL_ALLOWLIST, ...(enforceResearchDocumentWrite ? ['Edit', 'Write'] : [])] });
|
|
430
|
+
debug.log('core.turn', 'research-tool-denied', {
|
|
431
|
+
sessionId: ctx.sessionId,
|
|
432
|
+
tool: name,
|
|
433
|
+
dispatchCount: currentDispatchCount,
|
|
434
|
+
}, { level: 'warn' });
|
|
435
|
+
result = { error: enforceResearchDocumentWrite
|
|
436
|
+
? 'This research turn may use research tools and Edit/Write only for the explicitly requested document.'
|
|
437
|
+
: 'This research turn may only use the research tool allowlist.' };
|
|
438
|
+
} else if (enforceResearchToolAllowlist && !admitResearchToolCall(name)) {
|
|
439
|
+
debug.log('core.turn', 'research-tool-budget-reached', {
|
|
440
|
+
sessionId: ctx.sessionId, tool: name, count: researchToolCallCount,
|
|
441
|
+
maxToolTurns: RESEARCH_TURN_MAX_TOOL_TURNS,
|
|
442
|
+
}, { level: 'warn' });
|
|
443
|
+
result = { error: 'Research tool budget reached. Answer with the evidence collected so far.' };
|
|
444
|
+
} else {
|
|
445
|
+
result = await ctx.dispatchTool(
|
|
446
|
+
name,
|
|
447
|
+
constrainResearchToolArgs(name, args),
|
|
260
448
|
// Image-pipeline followup #1 (2026-05-05) — forward sessionId so
|
|
261
449
|
// the dispatcher can auto-inject into session-keyed tool calls
|
|
262
450
|
// (WebTerminal* etc.) when the LLM didn't supply one. `c` may
|
|
@@ -269,10 +457,20 @@ export async function runCoreTurn(
|
|
|
269
457
|
c
|
|
270
458
|
? { ...c, sessionId: ctx.sessionId, signal: ctx.signal, ...(ctx.userText ? { userText: ctx.userText } : {}) }
|
|
271
459
|
: { callId: '', sessionId: ctx.sessionId, signal: ctx.signal, ...(ctx.userText ? { userText: ctx.userText } : {}) },
|
|
272
|
-
|
|
460
|
+
);
|
|
461
|
+
}
|
|
273
462
|
success = true;
|
|
274
463
|
return result;
|
|
275
464
|
} finally {
|
|
465
|
+
if (name === 'Agent' && enforceResearchToolAllowlist) {
|
|
466
|
+
debug.log('research.turn', 'subagent-completed', {
|
|
467
|
+
sessionId: ctx.sessionId,
|
|
468
|
+
dispatchCount: currentDispatchCount,
|
|
469
|
+
durationMs: now() - startedAt,
|
|
470
|
+
completionMode: 'awaited-tool-result',
|
|
471
|
+
success,
|
|
472
|
+
});
|
|
473
|
+
}
|
|
276
474
|
try {
|
|
277
475
|
debug.log('core.turn', 'dispatch-done', {
|
|
278
476
|
sessionId: ctx.sessionId,
|
|
@@ -344,20 +542,140 @@ export async function runCoreTurn(
|
|
|
344
542
|
// Use the shared #31663 research-intent verdict. Surface labels are a
|
|
345
543
|
// presentation/routing result and may remain `chat` for a research turn.
|
|
346
544
|
const researchTurn = isResearchAgentIntent(surfaceUserText);
|
|
347
|
-
const {
|
|
545
|
+
const { selectDeepBloom } = await import('./deep-turn-bloom.js');
|
|
546
|
+
const deepBloomDecision = selectDeepBloom(surfaceUserText, {
|
|
547
|
+
researchIntent: researchTurn,
|
|
548
|
+
reasoningEffort: ctx.reasoningEffort,
|
|
549
|
+
});
|
|
550
|
+
const { messages, tools: tieredTools, stats } = applyDeferredTools(
|
|
348
551
|
ctx.messages,
|
|
349
552
|
ctx.tools,
|
|
350
553
|
{ enabled: deferredEnabled, ...(recentUserText ? { userText: recentUserText } : {}) },
|
|
351
554
|
);
|
|
555
|
+
// Preserve the pre-routing contract: a named skill only skips the research
|
|
556
|
+
// prepass when skill_exec is actually active after the normal tier split.
|
|
557
|
+
// Resolve the installed skill name even if skill_exec is deferred/missing:
|
|
558
|
+
// a named request with no executor falls back to the unfiltered normal pool.
|
|
559
|
+
let installedSkillNames: string[] = [];
|
|
560
|
+
if (researchTurn && surfaceUserText?.trim()) {
|
|
561
|
+
const { getSkillIndex } = await import('../skills/index.js');
|
|
562
|
+
installedSkillNames = getSkillIndex().map(({ name }) => name);
|
|
563
|
+
}
|
|
564
|
+
const namedSkillRequest = requestsNamedSkill(surfaceUserText, installedSkillNames);
|
|
565
|
+
// A named skill only skips the research prepass when its executor is active.
|
|
566
|
+
const explicitSkillToolRequest = namedSkillRequest
|
|
567
|
+
&& tieredTools.some((tool) => tool.name === 'skill_exec');
|
|
568
|
+
const constrainDeepNonResearchTools = deepBloomDecision.apply && !researchTurn;
|
|
569
|
+
// ToolSearch routes against the surface's full live pool, so hiding a tool
|
|
570
|
+
// from the model alone is insufficient. Remove the summoner from the
|
|
571
|
+
// model-visible tiered set while retaining original split stats/messages.
|
|
572
|
+
const bloomFilteredTools = constrainDeepNonResearchTools
|
|
573
|
+
? tieredTools.filter((tool) => {
|
|
574
|
+
const name = tool.name.toLowerCase();
|
|
575
|
+
return name === 'skill_exec' && explicitSkillToolRequest
|
|
576
|
+
? true
|
|
577
|
+
: name !== 'toolsearch' && !DEEP_NON_RESEARCH_SEARCH_TOOLS.has(name);
|
|
578
|
+
})
|
|
579
|
+
: tieredTools;
|
|
580
|
+
if (constrainDeepNonResearchTools) {
|
|
581
|
+
const suppressed = tieredTools.filter((tool) => !bloomFilteredTools.includes(tool)).map((tool) => tool.name);
|
|
582
|
+
debug.log('research.turn', 'deep-bloom-search-tools-suppressed', {
|
|
583
|
+
sessionId: ctx.sessionId, reason: deepBloomDecision.reason, suppressed,
|
|
584
|
+
explicitSkillToolRequest,
|
|
585
|
+
});
|
|
586
|
+
}
|
|
587
|
+
enforceResearchToolBudget = researchTurn;
|
|
588
|
+
enforceResearchToolAllowlist = researchTurn && !namedSkillRequest;
|
|
589
|
+
enforceResearchDocumentWrite = enforceResearchToolAllowlist && requestsResearchDocumentWrite(surfaceUserText);
|
|
590
|
+
// Codex Responses only supports tool_choice="required" (not a named
|
|
591
|
+
// function choice). Make the first request deterministic by exposing only
|
|
592
|
+
// skill_exec there; streamLLMWithTools restores the full pool on later turns.
|
|
593
|
+
const routedSkillTools = explicitSkillToolRequest
|
|
594
|
+
? bloomFilteredTools.filter((tool) => tool.name === 'skill_exec')
|
|
595
|
+
: [];
|
|
596
|
+
const tools = enforceResearchToolAllowlist
|
|
597
|
+
? bloomFilteredTools.filter((tool) => isAllowedResearchTool(tool.name))
|
|
598
|
+
: bloomFilteredTools;
|
|
599
|
+
// Preserve the ordinary pool if a later filter removes the executor.
|
|
600
|
+
const firstTurnTools = routedSkillTools.length > 0 ? routedSkillTools : undefined;
|
|
601
|
+
const maxToolTurns = researchTurn
|
|
602
|
+
? Math.min(ctx.maxToolTurns ?? RESEARCH_TURN_MAX_TOOL_TURNS, RESEARCH_TURN_MAX_TOOL_TURNS)
|
|
603
|
+
: ctx.maxToolTurns;
|
|
352
604
|
if (researchTurn && !messages.some((message) =>
|
|
353
605
|
message.role === 'system' && typeof message.content === 'string'
|
|
354
606
|
&& message.content.startsWith('Current local date:'))
|
|
355
607
|
) {
|
|
356
608
|
messages.unshift(buildResearchDateSystemMessage());
|
|
609
|
+
}
|
|
610
|
+
if (researchTurn) {
|
|
611
|
+
messages.unshift({
|
|
612
|
+
role: 'system',
|
|
613
|
+
content: [
|
|
614
|
+
'<research-answer-guidance>',
|
|
615
|
+
'작은 후속 작업은 추가 질문 없이 현재 턴에서 먼저 처리한다.',
|
|
616
|
+
'답은 결론(무엇을 찾았고 무엇을 해 두었는지)을 먼저 말하고, 근거를 짧게 덧붙인다.',
|
|
617
|
+
'비용·외부 노출·되돌리기 어려움이 큰 다음 단계만 그 하나를 확인한다. 그 밖에는 묻지 않는다.',
|
|
618
|
+
'다음 할 일 목록을 형식으로 요구하지 않는다.',
|
|
619
|
+
'본문은 질문이 요구한 범위만 답하고, 가정 나열과 반복 설명을 줄인다.',
|
|
620
|
+
'근거는 출처 링크로 짧게 붙인다.',
|
|
621
|
+
'질문에 필요한 만큼 읽기 좋게 설명하며, 고정 줄 수나 글자 수로 자르지 않는다.',
|
|
622
|
+
'</research-answer-guidance>',
|
|
623
|
+
].join('\n'),
|
|
624
|
+
});
|
|
625
|
+
}
|
|
626
|
+
if (deepBloomDecision.apply) {
|
|
627
|
+
const { buildDeepBloomInstruction } = await import('./deep-turn-bloom.js');
|
|
628
|
+
const instruction = await buildDeepBloomInstruction(surfaceUserText ?? '', deepBloomDecision.reason);
|
|
629
|
+
messages.unshift({ role: 'system', content: instruction.prompt! });
|
|
630
|
+
debug.log('research.turn', 'deep-bloom-applied', {
|
|
631
|
+
sessionId: ctx.sessionId, levels: instruction.levels, trigger: instruction.reason,
|
|
632
|
+
questionCount: instruction.questionCount, stage: researchTurn ? 'first-answer' : 'answer',
|
|
633
|
+
exemplarDomain: instruction.exemplarDomain,
|
|
634
|
+
exemplarLevels: instruction.exemplarLevels,
|
|
635
|
+
});
|
|
636
|
+
} else if (!deepBloomDecision.apply) {
|
|
637
|
+
debug.log('research.turn', 'deep-bloom-skipped', {
|
|
638
|
+
sessionId: ctx.sessionId, reason: deepBloomDecision.reason,
|
|
639
|
+
});
|
|
357
640
|
}
|
|
358
641
|
let researchResultPromise: Promise<{ ok: boolean; output: string; error?: string } | null> | undefined;
|
|
359
|
-
|
|
360
|
-
|
|
642
|
+
let researchDeadlineSignal: AbortSignal | undefined;
|
|
643
|
+
let requestedSkillName: string | undefined;
|
|
644
|
+
if (researchTurn && surfaceUserText?.trim() && explicitSkillToolRequest) {
|
|
645
|
+
// Resolve a display name only for the research opening plan; ordinary
|
|
646
|
+
// turns and unrequested research keep the core startup lean.
|
|
647
|
+
requestedSkillName = requestedInstalledSkillName(surfaceUserText, installedSkillNames);
|
|
648
|
+
const selectedTool = firstTurnTools?.find((tool) => tool.name === 'skill_exec');
|
|
649
|
+
if (requestedSkillName && selectedTool) {
|
|
650
|
+
debug.log('research.turn', 'named-skill-route-first', {
|
|
651
|
+
sessionId: ctx.sessionId,
|
|
652
|
+
requestedSkillName,
|
|
653
|
+
selectedTool: selectedTool.name,
|
|
654
|
+
availableToolNames: firstTurnTools?.map((tool) => tool.name) ?? [],
|
|
655
|
+
});
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
if (researchTurn && surfaceUserText?.trim()) {
|
|
659
|
+
// `tools` is the active post-tier-flip pool; use the shared research
|
|
660
|
+
// allowlist order so the plan names only currently callable tools.
|
|
661
|
+
const availableResearchTools = RESEARCH_TOOL_ALLOWLIST
|
|
662
|
+
.filter((name) => tools.some((tool) => tool.name === name));
|
|
663
|
+
const planTools = requestedSkillName && firstTurnTools?.some((tool) => tool.name === 'skill_exec')
|
|
664
|
+
? [`${requestedSkillName} (skill_exec)`]
|
|
665
|
+
: availableResearchTools;
|
|
666
|
+
const plan = planTools.length > 0
|
|
667
|
+
? [
|
|
668
|
+
`${planTools.join(' → ')}로 질문에 나온 주제와 요구 조건의 근거를 찾습니다.`,
|
|
669
|
+
'출처의 주장과 제약을 비교해 확인된 사실을 가립니다.',
|
|
670
|
+
'확인한 결론과 짧은 근거로 답합니다.',
|
|
671
|
+
].join('\n')
|
|
672
|
+
: [
|
|
673
|
+
'현재 사용할 수 있는 조사 도구가 없습니다.',
|
|
674
|
+
'근거를 확인할 수 없어 결론을 단정하지 않습니다.',
|
|
675
|
+
'도구가 활성화되면 출처를 확인해 답합니다.',
|
|
676
|
+
].join('\n');
|
|
677
|
+
try { ctx.callbacks?.onStatus?.(plan); } catch { /* UI feedback is fail-soft. */ }
|
|
678
|
+
}
|
|
361
679
|
if (researchTurn && surfaceUserText?.trim() && !explicitSkillToolRequest) {
|
|
362
680
|
turnStartedAt = now();
|
|
363
681
|
researchStartedAt = turnStartedAt;
|
|
@@ -365,17 +683,61 @@ export async function runCoreTurn(
|
|
|
365
683
|
sessionId: ctx.sessionId,
|
|
366
684
|
sinceTurnStartMs: researchStartedAt - turnStartedAt,
|
|
367
685
|
});
|
|
368
|
-
//
|
|
369
|
-
//
|
|
370
|
-
//
|
|
371
|
-
|
|
686
|
+
// The opening plan was already emitted above. Do not add a generic
|
|
687
|
+
// answer-first status that contradicts that plan; stream the provisional
|
|
688
|
+
// answer while evidence collection runs, then reconcile in the second pass.
|
|
689
|
+
const researchController = new AbortController();
|
|
690
|
+
researchDeadlineSignal = researchController.signal;
|
|
691
|
+
const abortResearchFromParent = (): void => {
|
|
692
|
+
if (researchStopReason !== 'wall-clock-budget') researchStopReason = 'parent-abort';
|
|
693
|
+
researchController.abort(ctx.signal.reason);
|
|
694
|
+
};
|
|
695
|
+
if (ctx.signal.aborted) abortResearchFromParent();
|
|
696
|
+
else ctx.signal.addEventListener('abort', abortResearchFromParent, { once: true });
|
|
697
|
+
const defaultResearchWallClockBudgetMs = deepBloomDecision.apply
|
|
698
|
+
? RESEARCH_TURN_DEEP_BUDGET_MS
|
|
699
|
+
: RESEARCH_TURN_SHALLOW_BUDGET_MS;
|
|
700
|
+
const researchWallClockBudgetMs = options.researchWallClockBudgetMs ?? defaultResearchWallClockBudgetMs;
|
|
701
|
+
let researchDeadlineTimer: ResearchTimer | undefined;
|
|
702
|
+
if (!researchController.signal.aborted) {
|
|
703
|
+
researchDeadlineTimer = timers.setTimeout(() => {
|
|
704
|
+
if (researchController.signal.aborted) return;
|
|
705
|
+
researchStopReason = 'wall-clock-budget';
|
|
706
|
+
logResearchStop('wall-clock-budget', {
|
|
707
|
+
stage: 'research-prepass',
|
|
708
|
+
elapsedMs: researchStartedAt === undefined ? undefined : now() - researchStartedAt,
|
|
709
|
+
limitMs: researchWallClockBudgetMs,
|
|
710
|
+
});
|
|
711
|
+
researchController.abort(new Error('Research wall-clock budget reached'));
|
|
712
|
+
}, researchWallClockBudgetMs);
|
|
713
|
+
}
|
|
372
714
|
researchResultPromise = (async () => {
|
|
373
715
|
try {
|
|
374
|
-
const
|
|
716
|
+
const work = (options.runResearch ?? (async (request, signal, admitToolCall, providerRouting) => {
|
|
375
717
|
// Keep the Bloom/skill pipeline out of ordinary and packaged TUI startup graphs.
|
|
376
718
|
const { researchTurnForGrounding, runResearchQuestionLadder } = await import('../auto-research/research-turn.js');
|
|
377
|
-
return researchTurnForGrounding(await runResearchQuestionLadder(request, {
|
|
378
|
-
|
|
719
|
+
return researchTurnForGrounding(await runResearchQuestionLadder(request, {
|
|
720
|
+
...providerRouting,
|
|
721
|
+
signal, admitToolCall, allowPartialOnAbort: true, allowOutputSkill: false,
|
|
722
|
+
deadlineMs: deepBloomDecision.apply
|
|
723
|
+
? RESEARCH_TURN_FINAL_ANSWER_DEADLINE_MS
|
|
724
|
+
: Math.min(RESEARCH_TURN_SHALLOW_FINAL_ANSWER_DEADLINE_MS, Math.max(1, researchWallClockBudgetMs - 1)),
|
|
725
|
+
}));
|
|
726
|
+
}))(surfaceUserText, researchController.signal, admitResearchToolCall, {
|
|
727
|
+
...(ctx.initialProvider ? { initialProvider: ctx.initialProvider } : {}),
|
|
728
|
+
...(ctx.skipProviders ? { skipProviders: ctx.skipProviders } : {}),
|
|
729
|
+
...(ctx.runId ? { runId: ctx.runId } : {}),
|
|
730
|
+
});
|
|
731
|
+
const result = await work;
|
|
732
|
+
researchAxisCount = result?.axisCount ?? 0;
|
|
733
|
+
if (researchController.signal.aborted && !researchStopReason) researchStopReason = ctx.signal.aborted ? 'parent-abort' : 'research-aborted';
|
|
734
|
+
if (researchStopReason) logResearchStop(researchStopReason, {
|
|
735
|
+
stage: 'research-prepass',
|
|
736
|
+
elapsedMs: researchStartedAt === undefined ? undefined : now() - researchStartedAt,
|
|
737
|
+
});
|
|
738
|
+
logResearchStop(result.ok ? 'evidence-complete' : 'evidence-incomplete', {
|
|
739
|
+
stage: 'research-prepass', outputChars: result.output.length,
|
|
740
|
+
});
|
|
379
741
|
debug.log('research.turn', 'tui-research-completed', {
|
|
380
742
|
sessionId: ctx.sessionId,
|
|
381
743
|
ok: result.ok,
|
|
@@ -385,23 +747,30 @@ export async function runCoreTurn(
|
|
|
385
747
|
});
|
|
386
748
|
return result;
|
|
387
749
|
} catch (error) {
|
|
750
|
+
logResearchStop('research-error', { stage: 'research-prepass', error: error instanceof Error ? error.message : String(error) });
|
|
388
751
|
debug.log('research.turn', 'tui-research-fallback', {
|
|
389
752
|
sessionId: ctx.sessionId,
|
|
390
753
|
reason: error instanceof Error ? error.message : String(error),
|
|
391
754
|
elapsedMs: researchStartedAt === undefined ? undefined : now() - researchStartedAt,
|
|
392
755
|
}, { level: 'warn' });
|
|
393
756
|
return null;
|
|
757
|
+
} finally {
|
|
758
|
+
if (researchDeadlineTimer !== undefined) timers.clearTimeout(researchDeadlineTimer);
|
|
759
|
+
ctx.signal.removeEventListener('abort', abortResearchFromParent);
|
|
394
760
|
}
|
|
395
761
|
})();
|
|
396
762
|
}
|
|
397
|
-
const streamOptions = (turnTools: typeof tools) => ({
|
|
763
|
+
const streamOptions = (turnTools: typeof tools, signal: AbortSignal = ctx.signal) => ({
|
|
398
764
|
tools: turnTools,
|
|
765
|
+
...(firstTurnTools ? { firstTurnTools } : {}),
|
|
399
766
|
researchTurn,
|
|
400
|
-
|
|
767
|
+
...(firstTurnTools ? { toolChoice: { name: 'skill_exec' } } : {}),
|
|
768
|
+
signal,
|
|
401
769
|
...(ctx.requestSizeGuard ? { requestSizeGuard: ctx.requestSizeGuard } : {}),
|
|
770
|
+
...(ctx.reasoningEffort !== undefined ? { reasoningEffort: ctx.reasoningEffort } : {}),
|
|
402
771
|
toolResultInlineLimitBytes: CORE_TURN_TOOL_RESULT_INLINE_LIMIT_BYTES,
|
|
403
772
|
...(ctx.sessionId !== undefined ? { sessionId: ctx.sessionId } : {}),
|
|
404
|
-
...(
|
|
773
|
+
...(maxToolTurns !== undefined ? { maxTurns: maxToolTurns } : {}),
|
|
405
774
|
...(ctx.initialProvider !== undefined
|
|
406
775
|
? { initialProvider: ctx.initialProvider, ...(ctx.skipProviders ? { skipProviders: ctx.skipProviders } : {}) }
|
|
407
776
|
: ctx.modelOverride !== undefined ? { model: ctx.modelOverride } : {}),
|
|
@@ -431,12 +800,34 @@ export async function runCoreTurn(
|
|
|
431
800
|
surfaceSelectionReason: surface.selectionReason,
|
|
432
801
|
activeCount: stats.activeCount,
|
|
433
802
|
deferredCount: stats.deferredCount,
|
|
434
|
-
immediateCount:
|
|
803
|
+
immediateCount: tools.length,
|
|
435
804
|
immediate: tools.map((tool) => tool.name),
|
|
436
805
|
warmPreloaded: stats.warmPreloaded,
|
|
437
806
|
deferred: stats.deferredNames,
|
|
438
807
|
unhydratable: stats.unhydratableNames,
|
|
439
808
|
}, { compact: { arrayMax: Number.MAX_SAFE_INTEGER } });
|
|
809
|
+
const activeToolNames = new Set(tools.map((tool) => tool.name));
|
|
810
|
+
const immediateToolNames = new Set(tieredTools.map((tool) => tool.name));
|
|
811
|
+
const bloomToolNames = new Set(bloomFilteredTools.map((tool) => tool.name));
|
|
812
|
+
const excludedTools = ctx.tools
|
|
813
|
+
.filter((tool) => !activeToolNames.has(tool.name))
|
|
814
|
+
.map((tool) => ({
|
|
815
|
+
name: tool.name,
|
|
816
|
+
reason: !immediateToolNames.has(tool.name)
|
|
817
|
+
? stats.deferredNames.includes(tool.name) ? 'deferred-tool-tier' : 'not-in-immediate-tier'
|
|
818
|
+
: !bloomToolNames.has(tool.name) ? 'deep-bloom-non-research-suppression'
|
|
819
|
+
: enforceResearchToolAllowlist && !isAllowedResearchTool(tool.name) ? 'research-tool-allowlist'
|
|
820
|
+
: 'not-active-after-turn-filtering',
|
|
821
|
+
}));
|
|
822
|
+
debug.log('capability.resolve', 'tier-split', {
|
|
823
|
+
sessionId: ctx.sessionId,
|
|
824
|
+
surfaceId: surface.id,
|
|
825
|
+
researchTurn,
|
|
826
|
+
activeTools: [...activeToolNames],
|
|
827
|
+
excludedTools,
|
|
828
|
+
deferredTools: stats.deferredNames,
|
|
829
|
+
unhydratableTools: stats.unhydratableNames,
|
|
830
|
+
}, { compact: { arrayMax: Number.MAX_SAFE_INTEGER } });
|
|
440
831
|
if (stats.unhydratableCount > 0) {
|
|
441
832
|
debug.log('capability.resolve', 'unhydratable-capabilities', {
|
|
442
833
|
sessionId: ctx.sessionId,
|
|
@@ -447,8 +838,13 @@ export async function runCoreTurn(
|
|
|
447
838
|
|
|
448
839
|
try {
|
|
449
840
|
let provisionalTurnMessages: Parameters<NonNullable<StreamWithToolsHandlers['onTurnComplete']>>[0] | undefined;
|
|
450
|
-
|
|
451
|
-
|
|
841
|
+
let firstPassTimedOut = false;
|
|
842
|
+
const firstPassHandlers: StreamWithToolsHandlers = researchResultPromise
|
|
843
|
+
? {
|
|
844
|
+
...handlers,
|
|
845
|
+
onText: (delta, full) => { if (!firstPassTimedOut) handlers.onText?.(delta, full); },
|
|
846
|
+
onTurnComplete: (newMessages) => { if (!firstPassTimedOut) provisionalTurnMessages = newMessages; },
|
|
847
|
+
}
|
|
452
848
|
: handlers;
|
|
453
849
|
const firstPassMessages = researchResultPromise
|
|
454
850
|
? [...messages, {
|
|
@@ -457,7 +853,38 @@ export async function runCoreTurn(
|
|
|
457
853
|
}]
|
|
458
854
|
: messages;
|
|
459
855
|
const firstPassStartedAt = researchResultPromise ? now() : undefined;
|
|
460
|
-
|
|
856
|
+
if (researchResultPromise && firstPassStartedAt !== undefined) {
|
|
857
|
+
const firstPassController = new AbortController();
|
|
858
|
+
const abortFirstPassFromParent = (): void => firstPassController.abort(ctx.signal.reason);
|
|
859
|
+
if (ctx.signal.aborted) abortFirstPassFromParent();
|
|
860
|
+
else ctx.signal.addEventListener('abort', abortFirstPassFromParent, { once: true });
|
|
861
|
+
const firstReplyBudgetMs = options.firstReplyBudgetMs ?? RESEARCH_TURN_FIRST_REPLY_BUDGET_MS;
|
|
862
|
+
let firstReplyTimer: ResearchTimer | undefined;
|
|
863
|
+
const deadline = new Promise<{ timedOut: true }>(resolve => {
|
|
864
|
+
firstReplyTimer = timers.setTimeout(() => resolve({ timedOut: true }), firstReplyBudgetMs);
|
|
865
|
+
});
|
|
866
|
+
try {
|
|
867
|
+
const firstPass = streamLLMWithTools(firstPassMessages, firstPassHandlers, streamOptions(tools, firstPassController.signal))
|
|
868
|
+
.then(text => ({ timedOut: false as const, text }));
|
|
869
|
+
const outcome = await Promise.race([firstPass, deadline]);
|
|
870
|
+
if (outcome.timedOut) {
|
|
871
|
+
firstPassTimedOut = true;
|
|
872
|
+
firstPassController.abort(new Error('First answer budget reached'));
|
|
873
|
+
logResearchStop('first-reply-budget', { stage: 'first-response', limitMs: firstReplyBudgetMs, elapsedMs: now() - firstPassStartedAt });
|
|
874
|
+
const partial = accumulatedText.trim();
|
|
875
|
+
finalText = partial || '질문을 확인하고 있습니다. 근거를 조사한 뒤 제한 시간 안에 답을 정리하겠습니다.';
|
|
876
|
+
if (!partial) handlers.onText?.(finalText, finalText);
|
|
877
|
+
provisionalTurnMessages = [{ role: 'assistant', content: finalText, phase: 'final_answer' }];
|
|
878
|
+
} else {
|
|
879
|
+
finalText = outcome.text;
|
|
880
|
+
}
|
|
881
|
+
} finally {
|
|
882
|
+
if (firstReplyTimer !== undefined) timers.clearTimeout(firstReplyTimer);
|
|
883
|
+
ctx.signal.removeEventListener('abort', abortFirstPassFromParent);
|
|
884
|
+
}
|
|
885
|
+
} else {
|
|
886
|
+
finalText = await streamLLMWithTools(firstPassMessages, firstPassHandlers, streamOptions(tools));
|
|
887
|
+
}
|
|
461
888
|
if (researchResultPromise && firstPassStartedAt !== undefined) {
|
|
462
889
|
debug.log('research.turn', 'first-pass-answer-ready', {
|
|
463
890
|
sessionId: ctx.sessionId,
|
|
@@ -468,17 +895,29 @@ export async function runCoreTurn(
|
|
|
468
895
|
});
|
|
469
896
|
}
|
|
470
897
|
if (researchResultPromise) {
|
|
471
|
-
const racedResearch = await settleBeforeAbort(researchResultPromise, ctx.signal);
|
|
472
|
-
if (racedResearch.aborted) {
|
|
898
|
+
const racedResearch = await settleBeforeAbort(researchResultPromise, researchDeadlineSignal ?? ctx.signal);
|
|
899
|
+
if (racedResearch.aborted && ctx.signal.aborted) {
|
|
473
900
|
commitProvisionalTurn(provisionalTurnMessages, handlers, value => { finalPhaseAnswer = value; });
|
|
474
901
|
return { stopReason: 'aborted', finalText };
|
|
475
902
|
}
|
|
476
|
-
|
|
903
|
+
// A native research tool can ignore cancellation and leave its promise
|
|
904
|
+
// pending. The deadline must still end the prepass and enter the
|
|
905
|
+
// no-tools synthesis path with the provisional answer.
|
|
906
|
+
const result = racedResearch.aborted
|
|
907
|
+
? { ok: false, output: '', error: RESEARCH_TURN_DEADLINE_STOP_ERROR }
|
|
908
|
+
: racedResearch.value;
|
|
477
909
|
if (ctx.signal.aborted) {
|
|
478
910
|
commitProvisionalTurn(provisionalTurnMessages, handlers, value => { finalPhaseAnswer = value; });
|
|
479
911
|
return { stopReason: 'aborted', finalText };
|
|
480
912
|
}
|
|
481
|
-
|
|
913
|
+
const forcedSynthesis = researchStopReason === 'wall-clock-budget' || researchStopReason === 'tool-budget';
|
|
914
|
+
const hasUsableResearch = Boolean(result?.output.trim())
|
|
915
|
+
&& (result?.ok === true || result?.error === RESEARCH_TURN_DEADLINE_STOP_ERROR);
|
|
916
|
+
if (forcedSynthesis) {
|
|
917
|
+
logResearchStop('forced-synthesis', { stage: 'synthesis', trigger: researchStopReason, toolCalls: researchToolCallCount });
|
|
918
|
+
try { ctx.callbacks?.onStatus?.('조사 한도에 도달해 확인된 근거만으로 답을 정리합니다.'); } catch { /* UI feedback is fail-soft. */ }
|
|
919
|
+
}
|
|
920
|
+
if (hasUsableResearch && result && !ctx.signal.aborted) {
|
|
482
921
|
try { ctx.callbacks?.onStatus?.('근거를 반영해 답변을 보강합니다.'); } catch { /* UI feedback is fail-soft. */ }
|
|
483
922
|
const synthesisStartedAt = now();
|
|
484
923
|
debug.log('research.turn', 'synthesis-started', {
|
|
@@ -492,9 +931,11 @@ export async function runCoreTurn(
|
|
|
492
931
|
messages.push(
|
|
493
932
|
{ role: 'assistant', content: provisionalText.trim() },
|
|
494
933
|
{ role: 'system', content: `<bloom-research>\n${result.output.trim()}\n</bloom-research>` },
|
|
495
|
-
{ role: 'system', content:
|
|
934
|
+
{ role: 'system', content: forcedSynthesis
|
|
935
|
+
? 'The research budget has ended. Synthesize now using only the partial evidence above. State uncertainty and gaps clearly. Do not call tools or continue research.'
|
|
936
|
+
: 'Revise the answer above using this research evidence. Correct any unsupported or contradicted claims, preserve uncertainty, and answer in natural prose. Do not output JSON or a tool transcript. If the evidence does not materially change the answer, state the answer directly.' },
|
|
496
937
|
);
|
|
497
|
-
const synthesisTools = tools.filter(tool => !['WebSearch', 'OmniSearch'].includes(tool.name));
|
|
938
|
+
const synthesisTools = forcedSynthesis ? [] : tools.filter(tool => !['WebSearch', 'OmniSearch'].includes(tool.name));
|
|
498
939
|
try {
|
|
499
940
|
const synthesizedText = await streamLLMWithTools(messages, staged.handlers, streamOptions(synthesisTools));
|
|
500
941
|
if (ctx.signal.aborted) {
|
|
@@ -509,12 +950,9 @@ export async function runCoreTurn(
|
|
|
509
950
|
sinceTurnStartMs: turnStartedAt === undefined ? undefined : now() - turnStartedAt,
|
|
510
951
|
outputChars: finalText.length,
|
|
511
952
|
});
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
} else {
|
|
516
|
-
commitProvisionalTurn(provisionalTurnMessages, handlers, value => { finalPhaseAnswer = value; });
|
|
517
|
-
}
|
|
953
|
+
logResearchStop('synthesis-complete', { stage: 'synthesis', outputChars: finalText.length });
|
|
954
|
+
commitSynthesizedTurn(staged, provisionalTurnMessages, handlers, finalText, provisionalText,
|
|
955
|
+
value => { finalPhaseAnswer = value; }, ctx.callbacks?.onReplaceText);
|
|
518
956
|
} catch (error) {
|
|
519
957
|
commitProvisionalTurn(provisionalTurnMessages, handlers, value => { finalPhaseAnswer = value; });
|
|
520
958
|
const stopReason = classifyStopReason(error, ctx.signal);
|
|
@@ -529,15 +967,18 @@ export async function runCoreTurn(
|
|
|
529
967
|
try { ctx.callbacks?.onStatus?.('근거 반영에 실패해 첫 답변을 유지합니다.'); } catch { /* UI feedback is fail-soft. */ }
|
|
530
968
|
return { stopReason: 'end_turn', finalText: provisionalText, ...(handlers.onTurnComplete ? { finalPhaseAnswer } : {}) };
|
|
531
969
|
}
|
|
532
|
-
} else if (tools.some(tool => !['WebSearch', 'OmniSearch'].includes(tool.name))) {
|
|
533
|
-
try { ctx.callbacks?.onStatus?.('근거 검색은 실패해 사용할 수 있는 도구로 답변을 마무리합니다.'); } catch { /* UI feedback is fail-soft. */ }
|
|
970
|
+
} else if (forcedSynthesis || tools.some(tool => !['WebSearch', 'OmniSearch'].includes(tool.name))) {
|
|
971
|
+
try { ctx.callbacks?.onStatus?.(forcedSynthesis ? '조사 한도에 도달해 첫 답변을 근거 없이 확장하지 않고 마무리합니다.' : '근거 검색은 실패해 사용할 수 있는 도구로 답변을 마무리합니다.'); } catch { /* UI feedback is fail-soft. */ }
|
|
534
972
|
const provisionalText = finalText;
|
|
535
973
|
const staged = createStagedHandlers(handlers);
|
|
536
974
|
messages.push(
|
|
537
975
|
{ role: 'assistant', content: provisionalText.trim() },
|
|
538
|
-
{ role: 'system', content:
|
|
976
|
+
...(result?.output.trim() ? [{ role: 'system' as const, content: `<partial-research>\n${result.output.trim()}\n</partial-research>` }] : []),
|
|
977
|
+
{ role: 'system', content: forcedSynthesis
|
|
978
|
+
? 'The research budget has ended. Synthesize now without tools. Use any partial evidence above and clearly state uncertainty; do not continue research.'
|
|
979
|
+
: 'Research evidence was unavailable. Continue answering the user using available non-search tools as needed. Do not invoke web search.' },
|
|
539
980
|
);
|
|
540
|
-
const fallbackTools = tools.filter(tool => !['WebSearch', 'OmniSearch'].includes(tool.name));
|
|
981
|
+
const fallbackTools = forcedSynthesis ? [] : tools.filter(tool => !['WebSearch', 'OmniSearch'].includes(tool.name));
|
|
541
982
|
try {
|
|
542
983
|
const fallbackText = await streamLLMWithTools(messages, staged.handlers, streamOptions(fallbackTools));
|
|
543
984
|
if (ctx.signal.aborted) {
|
|
@@ -546,12 +987,8 @@ export async function runCoreTurn(
|
|
|
546
987
|
}
|
|
547
988
|
finalText = fallbackText || staged.text() || provisionalText;
|
|
548
989
|
accumulatedText = finalText;
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
value => { finalPhaseAnswer = value; }, ctx.callbacks?.onReplaceText);
|
|
552
|
-
} else {
|
|
553
|
-
commitProvisionalTurn(provisionalTurnMessages, handlers, value => { finalPhaseAnswer = value; });
|
|
554
|
-
}
|
|
990
|
+
commitSynthesizedTurn(staged, provisionalTurnMessages, handlers, finalText, provisionalText,
|
|
991
|
+
value => { finalPhaseAnswer = value; }, ctx.callbacks?.onReplaceText);
|
|
555
992
|
} catch (error) {
|
|
556
993
|
commitProvisionalTurn(provisionalTurnMessages, handlers, value => { finalPhaseAnswer = value; });
|
|
557
994
|
const stopReason = classifyStopReason(error, ctx.signal);
|