@demlik/tea 0.12.0 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -9
- package/dist/agent/index.d.ts +638 -45
- package/dist/agent/index.js +9 -19
- package/dist/{chunk-25LBDCBC.js → chunk-6IQPODUF.js} +2 -2
- package/dist/{chunk-25LBDCBC.js.map → chunk-6IQPODUF.js.map} +1 -1
- package/dist/chunk-AQ6ZIMEA.js +421 -0
- package/dist/chunk-AQ6ZIMEA.js.map +1 -0
- package/dist/{chunk-MUUROGIH.js → chunk-BLJ2JQSH.js} +62 -12
- package/dist/chunk-BLJ2JQSH.js.map +1 -0
- package/dist/{chunk-7SVIRMC6.js → chunk-F2US5BW6.js} +25 -5
- package/dist/chunk-F2US5BW6.js.map +1 -0
- package/dist/{batch-window/index.js → chunk-F7FMAWLA.js} +4 -8
- package/dist/chunk-F7FMAWLA.js.map +1 -0
- package/dist/{chunk-7V4EVLZA.js → chunk-HUKZQX6U.js} +20 -16
- package/dist/chunk-HUKZQX6U.js.map +1 -0
- package/dist/{chunk-EWJP3YYP.js → chunk-HWVW4AXC.js} +3 -3
- package/dist/chunk-HWVW4AXC.js.map +1 -0
- package/dist/{chunk-WLGO64WC.js → chunk-HYDWG35Q.js} +23 -6
- package/dist/chunk-HYDWG35Q.js.map +1 -0
- package/dist/{chunk-I5OV65MS.js → chunk-I5MQMJDW.js} +57 -7
- package/dist/chunk-I5MQMJDW.js.map +1 -0
- package/dist/{chunk-J6527VRQ.js → chunk-LFZUK6J2.js} +3 -3
- package/dist/chunk-LFZUK6J2.js.map +1 -0
- package/dist/{chunk-ZVJZ72HY.js → chunk-LYLTKJWM.js} +25 -11
- package/dist/chunk-LYLTKJWM.js.map +1 -0
- package/dist/{chunk-D736QUGF.js → chunk-MYXFNWAJ.js} +4 -5
- package/dist/chunk-MYXFNWAJ.js.map +1 -0
- package/dist/{chunk-K575PT4S.js → chunk-PR6TB3BL.js} +15 -4
- package/dist/chunk-PR6TB3BL.js.map +1 -0
- package/dist/chunk-RQULHGYH.js +1804 -0
- package/dist/chunk-RQULHGYH.js.map +1 -0
- package/dist/{chunk-FV3Z5MBE.js → chunk-TXN2KFHF.js} +14 -4
- package/dist/chunk-TXN2KFHF.js.map +1 -0
- package/dist/{chunk-Q2UM7BXU.js → chunk-VBDU4JL6.js} +2 -2
- package/dist/chunk-VBDU4JL6.js.map +1 -0
- package/dist/chunk-Z2L3LSNV.js +1470 -0
- package/dist/chunk-Z2L3LSNV.js.map +1 -0
- package/dist/core-CTzMJ82M.d.ts +562 -0
- package/dist/devtools/index.d.ts +2 -2
- package/dist/devtools/index.js +207 -2
- package/dist/devtools/index.js.map +1 -1
- package/dist/do/index.d.ts +48 -31
- package/dist/do/index.js +36 -25
- package/dist/do/index.js.map +1 -1
- package/dist/{durable-effects-D8SqU_if.d.ts → durable-effects-B0-qGQDy.d.ts} +2 -2
- package/dist/extension/index.d.ts +301 -3
- package/dist/extension/index.js +596 -5
- package/dist/extension/index.js.map +1 -1
- package/dist/flow/index.d.ts +1295 -0
- package/dist/flow/index.js +732 -0
- package/dist/flow/index.js.map +1 -0
- package/dist/idempotency/index.d.ts +90 -116
- package/dist/idempotency/index.js +4 -1
- package/dist/{batch-window/index.d.ts → index-4vZzljCD.d.ts} +7 -11
- package/dist/{fan-out/index.d.ts → index-6A7dB8f6.d.ts} +7 -8
- package/dist/index-B5BZ-_cT.d.ts +616 -0
- package/dist/index-Bc40JWVl.d.ts +131 -0
- package/dist/{debounce/index.d.ts → index-DHSUmQTR.d.ts} +7 -7
- package/dist/index-DJWIER_3.d.ts +69 -0
- package/dist/{snapshot/index.d.ts → index-DMCeMPMJ.d.ts} +15 -77
- package/dist/{monitored-run/index.d.ts → index-NjrT3fL2.d.ts} +37 -12
- package/dist/{recorder/index.d.ts → index-TvRb1KVf.d.ts} +4 -6
- package/dist/{deadline/index.d.ts → index-q0hXFeZ0.d.ts} +155 -8
- package/dist/index.d.ts +719 -6
- package/dist/index.js +1 -2
- package/dist/jev/index.d.ts +634 -0
- package/dist/jev/index.js +433 -0
- package/dist/jev/index.js.map +1 -0
- package/dist/machine-CdIcN2Xm.d.ts +1773 -0
- package/dist/machine-viz/index.d.ts +2 -1
- package/dist/machine-viz/index.js +12 -5
- package/dist/machine-viz/index.js.map +1 -1
- package/dist/mem/index.d.ts +19 -3
- package/dist/mem/index.js +22 -2
- package/dist/mem/index.js.map +1 -1
- package/dist/node/index.d.ts +130 -4
- package/dist/node/index.js +222 -10
- package/dist/node/index.js.map +1 -1
- package/dist/{paginator → paginate}/index.d.ts +151 -6
- package/dist/paginate/index.js +7 -0
- package/dist/parity/index.d.ts +5 -10
- package/dist/parity/index.js +4 -7
- package/dist/parity/index.js.map +1 -1
- package/dist/pbt/index.d.ts +248 -5
- package/dist/pbt/index.js +124 -5
- package/dist/pbt/index.js.map +1 -1
- package/dist/{trace-replay → persistence}/index.d.ts +7 -4
- package/dist/persistence/index.js +6 -0
- package/dist/react/index.d.ts +4 -3
- package/dist/react/index.js +1 -2
- package/dist/react/index.js.map +1 -1
- package/dist/resilience/index.d.ts +743 -0
- package/dist/resilience/index.js +657 -0
- package/dist/resilience/index.js.map +1 -0
- package/dist/retry-backoff/index.d.ts +3 -2
- package/dist/retry-backoff/index.js +1 -1
- package/dist/runtime-types-LWDoi943.d.ts +998 -0
- package/dist/testing/index.d.ts +3 -2
- package/dist/testing/index.js +1 -2
- package/dist/testing/index.js.map +1 -1
- package/dist/{throttled-input → timing}/index.d.ts +144 -12
- package/dist/{throttled-input → timing}/index.js +57 -12
- package/dist/timing/index.js.map +1 -0
- package/dist/{types-D7u9DkH7.d.ts → types-DP3f5NIl.d.ts} +1 -1
- package/dist/work-queue/index.d.ts +131 -54
- package/dist/work-queue/index.js +3 -2
- package/dist/work-queue/index.js.map +1 -1
- package/package.json +50 -216
- package/dist/authed-call/index.d.ts +0 -119
- package/dist/authed-call/index.js +0 -134
- package/dist/authed-call/index.js.map +0 -1
- package/dist/await-terminal/index.d.ts +0 -100
- package/dist/await-terminal/index.js +0 -76
- package/dist/await-terminal/index.js.map +0 -1
- package/dist/batch-window/index.js.map +0 -1
- package/dist/cache/index.d.ts +0 -151
- package/dist/cache/index.js +0 -8
- package/dist/chart/index.d.ts +0 -217
- package/dist/chart/index.js +0 -16
- package/dist/chart/index.js.map +0 -1
- package/dist/chart/inspect/index.d.ts +0 -85
- package/dist/chart/inspect/index.js +0 -5
- package/dist/chart/inspect/react.d.ts +0 -112
- package/dist/chart/inspect/react.js +0 -11
- package/dist/chart/inspect/react.js.map +0 -1
- package/dist/chart/inspect/styles.css +0 -286
- package/dist/chart/lane/index.d.ts +0 -361
- package/dist/chart/lane/index.js +0 -9
- package/dist/chart/lane/index.js.map +0 -1
- package/dist/chart/lane/react.d.ts +0 -83
- package/dist/chart/lane/react.js +0 -559
- package/dist/chart/lane/react.js.map +0 -1
- package/dist/chart/lane/server.d.ts +0 -148
- package/dist/chart/lane/server.js +0 -209
- package/dist/chart/lane/server.js.map +0 -1
- package/dist/chart/lane/styles.css +0 -498
- package/dist/chart/lane/viewer/assets/abnfDiagram-N423BO3Z-C729LI31.js +0 -1
- package/dist/chart/lane/viewer/assets/architectureDiagram-T3A2C74G-C729LI31.js +0 -1
- package/dist/chart/lane/viewer/assets/blockDiagram-VBNYF7ZC-C729LI31.js +0 -1
- package/dist/chart/lane/viewer/assets/c4Diagram-5PPSVZJV-C729LI31.js +0 -1
- package/dist/chart/lane/viewer/assets/chunk-2GRJ4B5K-HdDf8SI3.js +0 -1
- package/dist/chart/lane/viewer/assets/chunk-5RXB4S5H-CcNtpUd7.js +0 -231
- package/dist/chart/lane/viewer/assets/chunk-5VM5RSS4-BP4fRS_5.js +0 -15
- package/dist/chart/lane/viewer/assets/chunk-KBJHAD2P-DZOw7xU6.js +0 -1
- package/dist/chart/lane/viewer/assets/chunk-NSK5VX7P-CBCyTZMs.js +0 -128
- package/dist/chart/lane/viewer/assets/classDiagram-JCYQIIEL-C729LI31.js +0 -1
- package/dist/chart/lane/viewer/assets/classDiagram-v2-OCEON4UE-D4uAiFr8.js +0 -206
- package/dist/chart/lane/viewer/assets/cose-bilkent-JH36ORCC-DOwCrGXH.js +0 -1
- package/dist/chart/lane/viewer/assets/cynefinDiagram-MW4NZA55-C729LI31.js +0 -1
- package/dist/chart/lane/viewer/assets/dagre-K_PewWfS.js +0 -1
- package/dist/chart/lane/viewer/assets/dagre-VZM6K2ZE-831qZcA8.js +0 -4
- package/dist/chart/lane/viewer/assets/diagram-7IWD3JNH-C729LI31.js +0 -1
- package/dist/chart/lane/viewer/assets/diagram-B4RE2ZJO-C729LI31.js +0 -1
- package/dist/chart/lane/viewer/assets/diagram-LBJQPF4R-C729LI31.js +0 -1
- package/dist/chart/lane/viewer/assets/diagram-Q27KOJAE-C729LI31.js +0 -1
- package/dist/chart/lane/viewer/assets/diagram-UB23O5K3-C729LI31.js +0 -1
- package/dist/chart/lane/viewer/assets/ebnfDiagram-BXEA7PRR-C729LI31.js +0 -1
- package/dist/chart/lane/viewer/assets/erDiagram-JOGREHBK-C729LI31.js +0 -1
- package/dist/chart/lane/viewer/assets/flowDiagram-UKHOOZJN-C729LI31.js +0 -1
- package/dist/chart/lane/viewer/assets/ganttDiagram-PKOTCBZU-C729LI31.js +0 -1
- package/dist/chart/lane/viewer/assets/gitGraphDiagram-DS77QQ5N-C729LI31.js +0 -1
- package/dist/chart/lane/viewer/assets/index-9SkH5NA3.css +0 -1
- package/dist/chart/lane/viewer/assets/index-Bgt4sXpW.js +0 -195
- package/dist/chart/lane/viewer/assets/infoDiagram-6WML65LV-C729LI31.js +0 -1
- package/dist/chart/lane/viewer/assets/ishikawaDiagram-WSZJBQD7-C729LI31.js +0 -1
- package/dist/chart/lane/viewer/assets/journeyDiagram-NVQOT4AX-C729LI31.js +0 -1
- package/dist/chart/lane/viewer/assets/kanban-definition-27J2QSJJ-G7PaPzy-.js +0 -89
- package/dist/chart/lane/viewer/assets/katex-DOwCrGXH.js +0 -1
- package/dist/chart/lane/viewer/assets/mindmap-definition-FAOFIHXS-CGj9nrVk.js +0 -96
- package/dist/chart/lane/viewer/assets/path-fybaL0A-.js +0 -1
- package/dist/chart/lane/viewer/assets/pegDiagram-VL7TDLO6-C729LI31.js +0 -1
- package/dist/chart/lane/viewer/assets/pieDiagram-7S7Q4E2Y-C729LI31.js +0 -1
- package/dist/chart/lane/viewer/assets/quadrantDiagram-CIZ2JOQS-C729LI31.js +0 -1
- package/dist/chart/lane/viewer/assets/railroadDiagram-AXF67PYL-C729LI31.js +0 -1
- package/dist/chart/lane/viewer/assets/requirementDiagram-LRYGKXZP-C729LI31.js +0 -1
- package/dist/chart/lane/viewer/assets/sankeyDiagram-W5VNT64P-C729LI31.js +0 -1
- package/dist/chart/lane/viewer/assets/sequenceDiagram-SI44F4Z6-C729LI31.js +0 -1
- package/dist/chart/lane/viewer/assets/stateDiagram-OKZ733FA-B_88AzBS.js +0 -1
- package/dist/chart/lane/viewer/assets/stateDiagram-v2-UEYNNEHI-CR5gcgq6.js +0 -1
- package/dist/chart/lane/viewer/assets/swimlanes-SLNWSIFB-B4xK-rwg.js +0 -1
- package/dist/chart/lane/viewer/assets/swimlanesDiagram-ULZ7WXOC-C729LI31.js +0 -1
- package/dist/chart/lane/viewer/assets/timeline-definition-Z64GVDOM-CCv52MfY.js +0 -120
- package/dist/chart/lane/viewer/assets/vennDiagram-T6HMQDX7-C729LI31.js +0 -1
- package/dist/chart/lane/viewer/assets/wardleyDiagram-T6FBY63Y-C729LI31.js +0 -1
- package/dist/chart/lane/viewer/assets/xychartDiagram-ELKLHX3M-C729LI31.js +0 -1
- package/dist/chart/lane/viewer/index.html +0 -15
- package/dist/chart/report/index.d.ts +0 -116
- package/dist/chart/report/index.js +0 -32
- package/dist/chart/report/index.js.map +0 -1
- package/dist/chunk-2YFLOCWX.js +0 -15
- package/dist/chunk-2YFLOCWX.js.map +0 -1
- package/dist/chunk-3JU6657S.js +0 -372
- package/dist/chunk-3JU6657S.js.map +0 -1
- package/dist/chunk-4KTWLPL5.js +0 -33
- package/dist/chunk-4KTWLPL5.js.map +0 -1
- package/dist/chunk-5EHLEUTL.js +0 -686
- package/dist/chunk-5EHLEUTL.js.map +0 -1
- package/dist/chunk-5KJKJOFC.js +0 -758
- package/dist/chunk-5KJKJOFC.js.map +0 -1
- package/dist/chunk-7SVIRMC6.js.map +0 -1
- package/dist/chunk-7V4EVLZA.js.map +0 -1
- package/dist/chunk-A56OR5RF.js +0 -184
- package/dist/chunk-A56OR5RF.js.map +0 -1
- package/dist/chunk-AZZLE7XR.js +0 -62
- package/dist/chunk-AZZLE7XR.js.map +0 -1
- package/dist/chunk-B5VXOFMZ.js +0 -266
- package/dist/chunk-B5VXOFMZ.js.map +0 -1
- package/dist/chunk-BYQUGDD3.js +0 -16
- package/dist/chunk-BYQUGDD3.js.map +0 -1
- package/dist/chunk-D736QUGF.js.map +0 -1
- package/dist/chunk-E6GEDSF4.js +0 -307
- package/dist/chunk-E6GEDSF4.js.map +0 -1
- package/dist/chunk-EUF7XOEE.js +0 -223
- package/dist/chunk-EUF7XOEE.js.map +0 -1
- package/dist/chunk-EWJP3YYP.js.map +0 -1
- package/dist/chunk-FV3Z5MBE.js.map +0 -1
- package/dist/chunk-HCEVHFJ7.js +0 -54
- package/dist/chunk-HCEVHFJ7.js.map +0 -1
- package/dist/chunk-I5OV65MS.js.map +0 -1
- package/dist/chunk-J6527VRQ.js.map +0 -1
- package/dist/chunk-JELSZN25.js +0 -47
- package/dist/chunk-JELSZN25.js.map +0 -1
- package/dist/chunk-JER5O7PQ.js +0 -416
- package/dist/chunk-JER5O7PQ.js.map +0 -1
- package/dist/chunk-JGVL3WPL.js +0 -26
- package/dist/chunk-JGVL3WPL.js.map +0 -1
- package/dist/chunk-JP5D6GSL.js +0 -71
- package/dist/chunk-JP5D6GSL.js.map +0 -1
- package/dist/chunk-K575PT4S.js.map +0 -1
- package/dist/chunk-MU6MCIAC.js +0 -15
- package/dist/chunk-MU6MCIAC.js.map +0 -1
- package/dist/chunk-MUUROGIH.js.map +0 -1
- package/dist/chunk-ND3DH6KM.js +0 -88
- package/dist/chunk-ND3DH6KM.js.map +0 -1
- package/dist/chunk-Q2UM7BXU.js.map +0 -1
- package/dist/chunk-S2EGRPCM.js +0 -47
- package/dist/chunk-S2EGRPCM.js.map +0 -1
- package/dist/chunk-SINXE47Y.js +0 -55
- package/dist/chunk-SINXE47Y.js.map +0 -1
- package/dist/chunk-SUST46KO.js +0 -53
- package/dist/chunk-SUST46KO.js.map +0 -1
- package/dist/chunk-TP5UPGLY.js +0 -61
- package/dist/chunk-TP5UPGLY.js.map +0 -1
- package/dist/chunk-UF4MZSLT.js +0 -53
- package/dist/chunk-UF4MZSLT.js.map +0 -1
- package/dist/chunk-UOC2PL46.js +0 -13
- package/dist/chunk-UOC2PL46.js.map +0 -1
- package/dist/chunk-WLGO64WC.js.map +0 -1
- package/dist/chunk-WRAA7GVZ.js +0 -209
- package/dist/chunk-WRAA7GVZ.js.map +0 -1
- package/dist/chunk-ZCL7SCBK.js +0 -685
- package/dist/chunk-ZCL7SCBK.js.map +0 -1
- package/dist/chunk-ZD6PNZBK.js +0 -457
- package/dist/chunk-ZD6PNZBK.js.map +0 -1
- package/dist/chunk-ZF6WDK2D.js +0 -519
- package/dist/chunk-ZF6WDK2D.js.map +0 -1
- package/dist/chunk-ZJ5AOYBH.js +0 -8
- package/dist/chunk-ZJ5AOYBH.js.map +0 -1
- package/dist/chunk-ZVJZ72HY.js.map +0 -1
- package/dist/circuit-breaker/index.d.ts +0 -197
- package/dist/circuit-breaker/index.js +0 -3
- package/dist/circuit-breaker/index.js.map +0 -1
- package/dist/core-Bjc0bS8j.d.ts +0 -326
- package/dist/deadline/index.js +0 -6
- package/dist/deadline/index.js.map +0 -1
- package/dist/debounce/index.js +0 -3
- package/dist/debounce/index.js.map +0 -1
- package/dist/extension/react.d.ts +0 -121
- package/dist/extension/react.js +0 -75
- package/dist/extension/react.js.map +0 -1
- package/dist/extension/subs/index.d.ts +0 -44
- package/dist/extension/subs/index.js +0 -80
- package/dist/extension/subs/index.js.map +0 -1
- package/dist/extension/test-utils.d.ts +0 -128
- package/dist/extension/test-utils.js +0 -277
- package/dist/extension/test-utils.js.map +0 -1
- package/dist/fan-out/index.js +0 -5
- package/dist/fan-out/index.js.map +0 -1
- package/dist/fold-Blbhru48.d.ts +0 -435
- package/dist/graph-CcjWZVrd.d.ts +0 -923
- package/dist/idempotency/adapter.d.ts +0 -62
- package/dist/idempotency/adapter.js +0 -4
- package/dist/idempotency/adapter.js.map +0 -1
- package/dist/idempotent-intake/index.d.ts +0 -187
- package/dist/idempotent-intake/index.js +0 -7
- package/dist/idempotent-intake/index.js.map +0 -1
- package/dist/llm-call/index.d.ts +0 -310
- package/dist/llm-call/index.js +0 -16
- package/dist/llm-call/index.js.map +0 -1
- package/dist/machine-0OmPvsy_.d.ts +0 -804
- package/dist/monitored-run/index.js +0 -10
- package/dist/monitored-run/index.js.map +0 -1
- package/dist/paginated-walk/index.d.ts +0 -234
- package/dist/paginated-walk/index.js +0 -16
- package/dist/paginated-walk/index.js.map +0 -1
- package/dist/paginator/index.js +0 -3
- package/dist/paginator/index.js.map +0 -1
- package/dist/pbt/arbitraries/index.d.ts +0 -135
- package/dist/pbt/arbitraries/index.js +0 -3
- package/dist/pbt/arbitraries/index.js.map +0 -1
- package/dist/pbt/runners/index.d.ts +0 -117
- package/dist/pbt/runners/index.js +0 -5
- package/dist/pbt/runners/index.js.map +0 -1
- package/dist/poller/index.d.ts +0 -351
- package/dist/poller/index.js +0 -115
- package/dist/poller/index.js.map +0 -1
- package/dist/prediction/index.d.ts +0 -130
- package/dist/prediction/index.js +0 -4
- package/dist/prediction/index.js.map +0 -1
- package/dist/protocol-B5YmJr0d.d.ts +0 -45
- package/dist/pure/index.d.ts +0 -2
- package/dist/pure/index.js +0 -4
- package/dist/pure/index.js.map +0 -1
- package/dist/rate-limit/index.d.ts +0 -115
- package/dist/rate-limit/index.js +0 -3
- package/dist/rate-limit/index.js.map +0 -1
- package/dist/reconciler/index.d.ts +0 -192
- package/dist/reconciler/index.js +0 -164
- package/dist/reconciler/index.js.map +0 -1
- package/dist/recorder/index.js +0 -3
- package/dist/recorder/index.js.map +0 -1
- package/dist/reducer-BqyoVyBG.d.ts +0 -447
- package/dist/resilient-call/index.d.ts +0 -319
- package/dist/resilient-call/index.js +0 -14
- package/dist/resilient-call/index.js.map +0 -1
- package/dist/retry-to-success/index.d.ts +0 -109
- package/dist/retry-to-success/index.js +0 -37
- package/dist/retry-to-success/index.js.map +0 -1
- package/dist/run-BVeqJDBF.d.ts +0 -713
- package/dist/runtime-types-Bxc637bp.d.ts +0 -502
- package/dist/saga/index.d.ts +0 -240
- package/dist/saga/index.js +0 -150
- package/dist/saga/index.js.map +0 -1
- package/dist/samples-DCt6nF8H.d.ts +0 -59
- package/dist/snapshot/index.js +0 -5
- package/dist/snapshot/index.js.map +0 -1
- package/dist/subs/index.d.ts +0 -471
- package/dist/subs/index.js +0 -7
- package/dist/subs/index.js.map +0 -1
- package/dist/throttle/index.d.ts +0 -134
- package/dist/throttle/index.js +0 -3
- package/dist/throttle/index.js.map +0 -1
- package/dist/throttled-input/index.js.map +0 -1
- package/dist/token-refresh/index.d.ts +0 -215
- package/dist/token-refresh/index.js +0 -6
- package/dist/token-refresh/index.js.map +0 -1
- package/dist/trace-replay/index.js +0 -6
- package/dist/trace-replay/index.js.map +0 -1
- package/dist/with-deadline/index.d.ts +0 -196
- package/dist/with-deadline/index.js +0 -111
- package/dist/with-deadline/index.js.map +0 -1
- package/dist/with-resilience/index.d.ts +0 -224
- package/dist/with-resilience/index.js +0 -240
- package/dist/with-resilience/index.js.map +0 -1
- package/dist/with-telemetry/index.d.ts +0 -149
- package/dist/with-telemetry/index.js +0 -70
- package/dist/with-telemetry/index.js.map +0 -1
- package/dist/work-queue/adapter.d.ts +0 -83
- package/dist/work-queue/adapter.js +0 -4
- package/dist/work-queue/adapter.js.map +0 -1
- package/dist/work-queue/ops.d.ts +0 -70
- package/dist/work-queue/ops.js +0 -3
- package/dist/work-queue/ops.js.map +0 -1
- package/dist/workflow/index.d.ts +0 -484
- package/dist/workflow/index.js +0 -244
- package/dist/workflow/index.js.map +0 -1
- /package/dist/{cache → paginate}/index.js.map +0 -0
- /package/dist/{chart/inspect → persistence}/index.js.map +0 -0
|
@@ -0,0 +1,1470 @@
|
|
|
1
|
+
import { createMonitoredRun } from './chunk-HYDWG35Q.js';
|
|
2
|
+
import { createFanOut, initFanOut } from './chunk-MYXFNWAJ.js';
|
|
3
|
+
import { MsgType, createResilientCall } from './chunk-AQ6ZIMEA.js';
|
|
4
|
+
import { subscribeDeadline } from './chunk-F2US5BW6.js';
|
|
5
|
+
import { describeError } from './chunk-G5E74IJB.js';
|
|
6
|
+
import { Cmd, cmdEdgeOf, detachWorkOf, absurd, defineMachine, malformedResult, run, driveToDone } from './chunk-RQULHGYH.js';
|
|
7
|
+
import { Result } from 'better-result';
|
|
8
|
+
import { z } from 'zod';
|
|
9
|
+
|
|
10
|
+
// src/internal/llm-call/index.ts
|
|
11
|
+
function plainModel(fn) {
|
|
12
|
+
return () => ({
|
|
13
|
+
withStructuredOutput(schema) {
|
|
14
|
+
return {
|
|
15
|
+
invoke: async (messages) => schema.parse(await fn(messages))
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
function isPlainModel(model) {
|
|
21
|
+
return Object.prototype.toString.call(model) === "[object AsyncFunction]";
|
|
22
|
+
}
|
|
23
|
+
var PLAIN_MODEL_MISROUTE_REASON = "model: a sync function returned a Promise where an Llm was expected \u2014 a promise-returning model that is not declared `async` must be wrapped in plainModel(fn) (see the llm-call module)";
|
|
24
|
+
function isThenable(value) {
|
|
25
|
+
return typeof value === "object" && value !== null && "then" in value && typeof value.then === "function";
|
|
26
|
+
}
|
|
27
|
+
function asModelFactory(model) {
|
|
28
|
+
if (isPlainModel(model)) return plainModel(model);
|
|
29
|
+
return (modelId) => {
|
|
30
|
+
const llm = model(modelId);
|
|
31
|
+
if (isThenable(llm)) {
|
|
32
|
+
llm.then(void 0, () => void 0);
|
|
33
|
+
throw new Error(PLAIN_MODEL_MISROUTE_REASON);
|
|
34
|
+
}
|
|
35
|
+
return llm;
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
function createLlmCall(config, rng = Math.random) {
|
|
39
|
+
const resilientConfig = {
|
|
40
|
+
...config.retry === void 0 ? {} : { retry: config.retry }
|
|
41
|
+
};
|
|
42
|
+
const rc = createResilientCall(resilientConfig, rng);
|
|
43
|
+
const modelOf = asModelFactory(config.model);
|
|
44
|
+
function init() {
|
|
45
|
+
return rc.init();
|
|
46
|
+
}
|
|
47
|
+
function attempt(s, input, at, key = input.purpose) {
|
|
48
|
+
return rc.attempt(s, key, input, at);
|
|
49
|
+
}
|
|
50
|
+
function succeed(s, key, msg) {
|
|
51
|
+
return rc.succeed(s, key, msg);
|
|
52
|
+
}
|
|
53
|
+
function fail(s, key, msg) {
|
|
54
|
+
return rc.fail(s, key, msg);
|
|
55
|
+
}
|
|
56
|
+
function onTimer(s, msg) {
|
|
57
|
+
return rc.onTimer(s, msg);
|
|
58
|
+
}
|
|
59
|
+
function subs(s) {
|
|
60
|
+
return rc.subs(s);
|
|
61
|
+
}
|
|
62
|
+
async function invokeOne(input) {
|
|
63
|
+
const model = modelOf(input.model);
|
|
64
|
+
const messages = config.loadMessages ? await config.loadMessages(input) : [];
|
|
65
|
+
const schema = config.schemas[input.purpose];
|
|
66
|
+
const structured = model.withStructuredOutput(schema);
|
|
67
|
+
const raw = await structured.invoke(messages);
|
|
68
|
+
const output = schema.parse(raw);
|
|
69
|
+
return { key: input.purpose, purpose: input.purpose, output };
|
|
70
|
+
}
|
|
71
|
+
const resilientRunHandler = rc.handlers({
|
|
72
|
+
run: (input) => invokeOne(input)
|
|
73
|
+
}).resilient_run;
|
|
74
|
+
async function settleOf(cmd) {
|
|
75
|
+
const settle = await resilientRunHandler(cmd, {});
|
|
76
|
+
if (settle.type === MsgType.ResilientOk) {
|
|
77
|
+
return { ...settle, result: { ...settle.result, key: cmd.key } };
|
|
78
|
+
}
|
|
79
|
+
const rawError = settle.error;
|
|
80
|
+
const err = {
|
|
81
|
+
key: cmd.key,
|
|
82
|
+
purpose: cmd.input.purpose,
|
|
83
|
+
reason: describeError(rawError),
|
|
84
|
+
error: rawError
|
|
85
|
+
};
|
|
86
|
+
return {
|
|
87
|
+
type: MsgType.ResilientErr,
|
|
88
|
+
key: settle.key,
|
|
89
|
+
error: err,
|
|
90
|
+
at: settle.at
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
function handlers(ports) {
|
|
94
|
+
if (ports === void 0) {
|
|
95
|
+
return { resilient_run: (cmd) => settleOf(cmd) };
|
|
96
|
+
}
|
|
97
|
+
return {
|
|
98
|
+
resilient_run: (cmd, ctx) => {
|
|
99
|
+
const fired = (async () => {
|
|
100
|
+
const settle = await settleOf(cmd);
|
|
101
|
+
if (settle.type === MsgType.ResilientOk) {
|
|
102
|
+
const msg2 = ports.onOk(settle.result);
|
|
103
|
+
if (msg2 !== void 0) await ctx.dispatch(msg2);
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
const msg = ports.onErr(settle.error);
|
|
107
|
+
if (msg !== void 0) await ctx.dispatch(msg);
|
|
108
|
+
})();
|
|
109
|
+
ctx.waitUntil(fired);
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
return { init, attempt, succeed, fail, onTimer, subs, handlers, invokeOne };
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// src/agent/schema.ts
|
|
117
|
+
function schemaFromGuard(guard, name) {
|
|
118
|
+
return {
|
|
119
|
+
parse: (value) => {
|
|
120
|
+
if (!guard(value)) {
|
|
121
|
+
throw new Error(`structured-output parse failed: not ${name}`);
|
|
122
|
+
}
|
|
123
|
+
return value;
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// src/agent/compaction.ts
|
|
129
|
+
var COMPACTION_PURPOSE = "$compact";
|
|
130
|
+
function isCompactionSummary(value) {
|
|
131
|
+
if (value === null || typeof value !== "object") return false;
|
|
132
|
+
return typeof value.summary === "string";
|
|
133
|
+
}
|
|
134
|
+
var compactionSummarySchema = schemaFromGuard(isCompactionSummary, "a CompactionSummary");
|
|
135
|
+
|
|
136
|
+
// src/agent/internal.ts
|
|
137
|
+
function freshConversation() {
|
|
138
|
+
return {
|
|
139
|
+
turns: [],
|
|
140
|
+
toolRecords: [],
|
|
141
|
+
turnCount: 0,
|
|
142
|
+
awaiting: { kind: "llm" }
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
function dedupeByCallId(calls) {
|
|
146
|
+
const seen = /* @__PURE__ */ new Set();
|
|
147
|
+
const out = [];
|
|
148
|
+
for (const call of calls) {
|
|
149
|
+
if (seen.has(call.callId)) continue;
|
|
150
|
+
seen.add(call.callId);
|
|
151
|
+
out.push(call);
|
|
152
|
+
}
|
|
153
|
+
return out;
|
|
154
|
+
}
|
|
155
|
+
function foldSummary(conv, folding, summaryTurn) {
|
|
156
|
+
const shift = folding - 1;
|
|
157
|
+
const survivingTurns = conv.turns.slice(folding);
|
|
158
|
+
const survivingRecords = conv.toolRecords.filter((rec) => rec.turn >= folding).map((rec) => ({ ...rec, turn: rec.turn - shift }));
|
|
159
|
+
return {
|
|
160
|
+
...conv,
|
|
161
|
+
turns: [summaryTurn, ...survivingTurns],
|
|
162
|
+
toolRecords: survivingRecords,
|
|
163
|
+
awaiting: { kind: "llm" }
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
function currentStage(s) {
|
|
167
|
+
return s.run.stepStates.find((i) => i.status === "running")?.input;
|
|
168
|
+
}
|
|
169
|
+
function isSettled(s) {
|
|
170
|
+
return s.run.phase === "done" || s.run.phase === "failed" || s.run.phase === "cancelled" || s.failure !== null;
|
|
171
|
+
}
|
|
172
|
+
function requireAwaiting(s, kind) {
|
|
173
|
+
if (isSettled(s)) return null;
|
|
174
|
+
const conv = s.conversation;
|
|
175
|
+
if (conv === null || conv.awaiting.kind !== kind) return null;
|
|
176
|
+
return conv;
|
|
177
|
+
}
|
|
178
|
+
function toCompactRunCmd(cmd) {
|
|
179
|
+
return {
|
|
180
|
+
type: MsgType.CompactRun,
|
|
181
|
+
key: COMPACTION_PURPOSE,
|
|
182
|
+
input: cmd.input
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// src/agent/machine.ts
|
|
187
|
+
function agentBootMsg(at) {
|
|
188
|
+
return { type: MsgType.AgentBoot, at };
|
|
189
|
+
}
|
|
190
|
+
function agentCancelMsg(at) {
|
|
191
|
+
return { type: MsgType.AgentCancel, at };
|
|
192
|
+
}
|
|
193
|
+
function agentEvents(opts) {
|
|
194
|
+
const tools = opts?.tools;
|
|
195
|
+
return (msg, state) => {
|
|
196
|
+
const events = [];
|
|
197
|
+
if (state.run.phase === "cancelled") return events;
|
|
198
|
+
const refused = new Set(state.refusedCalls ?? []);
|
|
199
|
+
const routed = tools === void 0 ? null : tools.outcomeOf(msg);
|
|
200
|
+
if (routed !== null) {
|
|
201
|
+
if (routed.outcome.kind === "ok" && !refused.has(routed.callId)) {
|
|
202
|
+
events.push({
|
|
203
|
+
type: "ToolSettled",
|
|
204
|
+
callId: routed.callId,
|
|
205
|
+
result: routed.outcome.result
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
} else {
|
|
209
|
+
projectOwn(msg, events, refused);
|
|
210
|
+
}
|
|
211
|
+
if (state.run.phase === "done") {
|
|
212
|
+
events.push({ type: "RunDone", output: state.output });
|
|
213
|
+
}
|
|
214
|
+
return events;
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
function projectOwn(msg, events, refused) {
|
|
218
|
+
switch (msg.type) {
|
|
219
|
+
case MsgType.ResilientOk:
|
|
220
|
+
events.push({ type: "TurnSettled", turn: msg.result.output });
|
|
221
|
+
break;
|
|
222
|
+
case MsgType.AgentToolOk:
|
|
223
|
+
if (!refused.has(msg.callId)) {
|
|
224
|
+
events.push({
|
|
225
|
+
type: "ToolSettled",
|
|
226
|
+
callId: msg.callId,
|
|
227
|
+
result: msg.result
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
break;
|
|
231
|
+
// start / boot / cancel / timer / the *_err arms / the compaction settles
|
|
232
|
+
// carry no public event. (No `default`: the switch is exhaustive over the Msg
|
|
233
|
+
// discriminant, so a new Msg variant forces a decision here at compile
|
|
234
|
+
// time.) Compaction is an internal optimization, not a semantic lifecycle
|
|
235
|
+
// moment a UI folds — its settles are deliberately silent here. Cancel is
|
|
236
|
+
// silent for a stronger reason: the run the caller stopped owes the public
|
|
237
|
+
// channel nothing after the stop, so a `RunCancelled` would be one more
|
|
238
|
+
// late thing to have to ignore.
|
|
239
|
+
case MsgType.AgentStart:
|
|
240
|
+
case MsgType.AgentCancel:
|
|
241
|
+
case MsgType.AgentToolErr:
|
|
242
|
+
case MsgType.ResilientErr:
|
|
243
|
+
case MsgType.CompactOk:
|
|
244
|
+
case MsgType.CompactErr:
|
|
245
|
+
case "deadline_exceeded":
|
|
246
|
+
case MsgType.AgentBoot:
|
|
247
|
+
break;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
function mergeInterpret(a, b) {
|
|
251
|
+
return { ...a ?? {}, ...b };
|
|
252
|
+
}
|
|
253
|
+
function liftAgent(state, [slice, cmds]) {
|
|
254
|
+
return [{ ...state, agent: slice }, cmds];
|
|
255
|
+
}
|
|
256
|
+
var REJECTED_TYPE = "tool_rejected";
|
|
257
|
+
var SNAPSHOT_WRITE_TYPE = "snapshot_write";
|
|
258
|
+
var SETTLE_SUFFIX = /_(?:ok|err|run)$/;
|
|
259
|
+
var reservedToolNames = /* @__PURE__ */ new Set([
|
|
260
|
+
...Object.values(MsgType),
|
|
261
|
+
...Object.values(MsgType).flatMap((t) => {
|
|
262
|
+
const suffix = SETTLE_SUFFIX.exec(t);
|
|
263
|
+
return suffix === null ? [] : [t.slice(0, suffix.index)];
|
|
264
|
+
}),
|
|
265
|
+
REJECTED_TYPE,
|
|
266
|
+
SNAPSHOT_WRITE_TYPE
|
|
267
|
+
]);
|
|
268
|
+
function isReservedToolName(name) {
|
|
269
|
+
return reservedToolNames.has(name);
|
|
270
|
+
}
|
|
271
|
+
function tool(name, spec, handler) {
|
|
272
|
+
if (isReservedToolName(name)) {
|
|
273
|
+
throw new Error(
|
|
274
|
+
`tool: "${name}" is reserved \u2014 it is an agent-owned Msg prefix`
|
|
275
|
+
);
|
|
276
|
+
}
|
|
277
|
+
const def = Cmd.define(name, {
|
|
278
|
+
input: z.object({
|
|
279
|
+
callId: z.string(),
|
|
280
|
+
args: spec.input
|
|
281
|
+
}),
|
|
282
|
+
ok: spec.ok,
|
|
283
|
+
err: [...spec.err, "thrown"],
|
|
284
|
+
requirements: spec.requirements
|
|
285
|
+
});
|
|
286
|
+
const declared = new Set(spec.err);
|
|
287
|
+
const settle = {
|
|
288
|
+
ok: (value) => Result.ok(value),
|
|
289
|
+
fail: (error) => Result.err(error)
|
|
290
|
+
};
|
|
291
|
+
const asDeclared = (thrown) => {
|
|
292
|
+
if (isTagged(thrown) && declared.has(thrown._tag)) return thrown;
|
|
293
|
+
return { _tag: "thrown", message: describeError(thrown) };
|
|
294
|
+
};
|
|
295
|
+
const interpret = async (cmd, ctx) => {
|
|
296
|
+
let result;
|
|
297
|
+
try {
|
|
298
|
+
result = await handler(cmd.args, ctx, settle);
|
|
299
|
+
} catch (thrown) {
|
|
300
|
+
return def.err(cmd, asDeclared(thrown));
|
|
301
|
+
}
|
|
302
|
+
return result.match({
|
|
303
|
+
ok: (value) => {
|
|
304
|
+
const parsed = spec.ok.safeParse(value);
|
|
305
|
+
return parsed.success ? def.ok(cmd, parsed.data) : {
|
|
306
|
+
type: def.errType,
|
|
307
|
+
cmd,
|
|
308
|
+
error: malformedResult(parsed.error.issues)
|
|
309
|
+
};
|
|
310
|
+
},
|
|
311
|
+
err: (error) => def.err(cmd, error)
|
|
312
|
+
});
|
|
313
|
+
};
|
|
314
|
+
return Object.assign(def, {
|
|
315
|
+
description: spec.description,
|
|
316
|
+
args: spec.input,
|
|
317
|
+
resilience: resilienceOf(spec),
|
|
318
|
+
interpret
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
function resilienceOf(spec) {
|
|
322
|
+
if (spec.timeoutMs === void 0 && spec.retry === void 0) return null;
|
|
323
|
+
return {
|
|
324
|
+
...spec.timeoutMs !== void 0 ? { timeoutMs: spec.timeoutMs } : {},
|
|
325
|
+
...spec.retry !== void 0 ? { retry: spec.retry } : {}
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
function isTagged(value) {
|
|
329
|
+
return typeof value === "object" && value !== null && typeof value._tag === "string";
|
|
330
|
+
}
|
|
331
|
+
var rejected = Cmd.define(REJECTED_TYPE, {
|
|
332
|
+
input: z.custom(
|
|
333
|
+
() => true
|
|
334
|
+
),
|
|
335
|
+
ok: z.never(),
|
|
336
|
+
err: ["unknown_tool", "malformed_args"]
|
|
337
|
+
});
|
|
338
|
+
function toolRouter(tools) {
|
|
339
|
+
const byName = /* @__PURE__ */ new Map();
|
|
340
|
+
for (const t of tools) {
|
|
341
|
+
if (byName.has(t.cmdType)) {
|
|
342
|
+
throw new Error(`toolRouter: tool "${t.cmdType}" is declared twice`);
|
|
343
|
+
}
|
|
344
|
+
byName.set(t.cmdType, t);
|
|
345
|
+
}
|
|
346
|
+
const defs = [...tools, rejected];
|
|
347
|
+
const okTypes = new Map(defs.map((d) => [d.okType, d]));
|
|
348
|
+
const errTypes = new Map(defs.map((d) => [d.errType, d]));
|
|
349
|
+
const toolOf = (call) => {
|
|
350
|
+
const t = byName.get(call.name);
|
|
351
|
+
if (t === void 0) {
|
|
352
|
+
return rejected({
|
|
353
|
+
callId: call.callId,
|
|
354
|
+
error: { _tag: "unknown_tool", name: call.name }
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
const parsed = t.args.safeParse(call.args);
|
|
358
|
+
if (!parsed.success) {
|
|
359
|
+
return rejected({
|
|
360
|
+
callId: call.callId,
|
|
361
|
+
error: {
|
|
362
|
+
_tag: "malformed_args",
|
|
363
|
+
name: call.name,
|
|
364
|
+
issues: malformedResult(parsed.error.issues).issues
|
|
365
|
+
}
|
|
366
|
+
});
|
|
367
|
+
}
|
|
368
|
+
const build = t;
|
|
369
|
+
return build({ callId: call.callId, args: parsed.data });
|
|
370
|
+
};
|
|
371
|
+
const handlers = {
|
|
372
|
+
[rejected.cmdType]: async (cmd) => rejected.err(cmd, cmd.error)
|
|
373
|
+
};
|
|
374
|
+
for (const t of tools) handlers[t.cmdType] = t.interpret;
|
|
375
|
+
const interpret = handlers;
|
|
376
|
+
const outcomeOf = (msg) => {
|
|
377
|
+
if (okTypes.has(msg.type)) {
|
|
378
|
+
const ok = msg;
|
|
379
|
+
return {
|
|
380
|
+
callId: ok.cmd.callId,
|
|
381
|
+
outcome: { kind: "ok", result: ok.value }
|
|
382
|
+
};
|
|
383
|
+
}
|
|
384
|
+
if (errTypes.has(msg.type)) {
|
|
385
|
+
const err = msg;
|
|
386
|
+
return {
|
|
387
|
+
callId: err.cmd.callId,
|
|
388
|
+
// The tag and its payload spread FIRST, so `kind` and `reason` are
|
|
389
|
+
// written over anything a payload field of those names carries: the
|
|
390
|
+
// discriminant and the model's channel are the router's to state, and a
|
|
391
|
+
// tool that fails with `{ _tag, kind: "ok" }` must not be able to say
|
|
392
|
+
// otherwise.
|
|
393
|
+
outcome: {
|
|
394
|
+
...err.error,
|
|
395
|
+
reason: toolErrorReason(err.error),
|
|
396
|
+
kind: "error"
|
|
397
|
+
}
|
|
398
|
+
};
|
|
399
|
+
}
|
|
400
|
+
return null;
|
|
401
|
+
};
|
|
402
|
+
const resilienceOf2 = (call) => byName.get(call.name)?.resilience ?? null;
|
|
403
|
+
return { defs, toolOf, interpret, outcomeOf, resilienceOf: resilienceOf2 };
|
|
404
|
+
}
|
|
405
|
+
function fanOutInterpret(interpret) {
|
|
406
|
+
let release = Promise.resolve();
|
|
407
|
+
const fanned = {};
|
|
408
|
+
for (const [type, cell] of Object.entries(
|
|
409
|
+
interpret
|
|
410
|
+
)) {
|
|
411
|
+
fanned[type] = async (cmd, ctx, dispatch) => {
|
|
412
|
+
const edge = cmdEdgeOf(ctx);
|
|
413
|
+
const detach = detachWorkOf(ctx);
|
|
414
|
+
const work = (async () => cell(cmd, ctx, dispatch))();
|
|
415
|
+
const prior = release;
|
|
416
|
+
const settled = work.then(async (follow) => {
|
|
417
|
+
await prior;
|
|
418
|
+
const msg = edge(cmd, follow);
|
|
419
|
+
if (msg === void 0 || msg === null) return;
|
|
420
|
+
dispatch?.(msg);
|
|
421
|
+
});
|
|
422
|
+
release = settled.then(swallow, swallow);
|
|
423
|
+
detach(settled);
|
|
424
|
+
return void 0;
|
|
425
|
+
};
|
|
426
|
+
}
|
|
427
|
+
return fanned;
|
|
428
|
+
}
|
|
429
|
+
function swallow() {
|
|
430
|
+
}
|
|
431
|
+
function toolErrorReason(error) {
|
|
432
|
+
const { _tag, ...detail } = error;
|
|
433
|
+
return Object.keys(detail).length === 0 ? _tag : `${_tag} ${JSON.stringify(detail)}`;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
// src/agent/types.ts
|
|
437
|
+
function isStreamingModel(model) {
|
|
438
|
+
return model.length >= 2;
|
|
439
|
+
}
|
|
440
|
+
function isToolCall(value) {
|
|
441
|
+
if (value === null || typeof value !== "object") return false;
|
|
442
|
+
const t = value;
|
|
443
|
+
return typeof t.callId === "string" && typeof t.name === "string" && t.args !== null && typeof t.args === "object";
|
|
444
|
+
}
|
|
445
|
+
function isAgentTurn(value) {
|
|
446
|
+
if (value === null || typeof value !== "object") return false;
|
|
447
|
+
const t = value;
|
|
448
|
+
return typeof t.content === "string" && Array.isArray(t.toolCalls) && t.toolCalls.every(isToolCall);
|
|
449
|
+
}
|
|
450
|
+
var agentTurnSchema = schemaFromGuard(
|
|
451
|
+
isAgentTurn,
|
|
452
|
+
"an AgentTurn"
|
|
453
|
+
);
|
|
454
|
+
var TOOL_TIMEOUT_TAG = "timeout";
|
|
455
|
+
var TOOL_RETRY_EXHAUSTED_TAG = "retry_exhausted";
|
|
456
|
+
function status(s) {
|
|
457
|
+
if (s.failure !== null) {
|
|
458
|
+
return { kind: "failed", failure: s.failure };
|
|
459
|
+
}
|
|
460
|
+
const run2 = s.run;
|
|
461
|
+
switch (run2.phase) {
|
|
462
|
+
// 2) Never started — monitored-run's `idle` phase is exactly the "has this
|
|
463
|
+
// actually started?" guard, and the status channel keeps that distinction.
|
|
464
|
+
case "idle":
|
|
465
|
+
return { kind: "idle" };
|
|
466
|
+
// 3) The monitored-run terminal failure (deadline / stage). `run.failure`
|
|
467
|
+
// rides ONLY the `failed` arm of the discriminated union, so narrowing on
|
|
468
|
+
// `phase === "failed"` surfaces it with no nullable side field and no
|
|
469
|
+
// fabricated fallback — the old "failed-yet-failure-null" state is
|
|
470
|
+
// unrepresentable.
|
|
471
|
+
case "failed":
|
|
472
|
+
return { kind: "failed", failure: run2.failure };
|
|
473
|
+
// 4) The pipeline finished — the terminal output landed on `state.output`.
|
|
474
|
+
case "done":
|
|
475
|
+
return { kind: "done", output: s.output };
|
|
476
|
+
// 5) Stopped from outside. Terminal, and deliberately NOT folded into
|
|
477
|
+
// `failed`: the unified failure channel answers "what went wrong", and
|
|
478
|
+
// nothing did.
|
|
479
|
+
case "cancelled":
|
|
480
|
+
return { kind: "cancelled", at: run2.at };
|
|
481
|
+
// 6) Live. Awaiting tools is the resumable shape — the outstanding calls are
|
|
482
|
+
// the in-flight fan-out batch (`tools.running`); anything else is plain
|
|
483
|
+
// `running`, which is also where `stale` reads (a soft mark the next
|
|
484
|
+
// progress clears, not an outcome).
|
|
485
|
+
case "running":
|
|
486
|
+
case "stale":
|
|
487
|
+
return s.conversation !== null && s.conversation.awaiting.kind === "tools" ? { kind: "suspended", pending: s.tools.running } : { kind: "running" };
|
|
488
|
+
}
|
|
489
|
+
return absurd(run2);
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
// src/agent/tool-resilience.ts
|
|
493
|
+
var TOOL_KEY_PREFIX = "$tool:";
|
|
494
|
+
var NAME_CALL_SEP = "#";
|
|
495
|
+
function toolCallKey(name, callId) {
|
|
496
|
+
return `${TOOL_KEY_PREFIX}${name}${NAME_CALL_SEP}${callId}`;
|
|
497
|
+
}
|
|
498
|
+
function readToolCallKey(key) {
|
|
499
|
+
if (!key.startsWith(TOOL_KEY_PREFIX)) return null;
|
|
500
|
+
const body = key.slice(TOOL_KEY_PREFIX.length);
|
|
501
|
+
const at = body.indexOf(NAME_CALL_SEP);
|
|
502
|
+
if (at <= 0) return null;
|
|
503
|
+
return { name: body.slice(0, at), callId: body.slice(at + 1) };
|
|
504
|
+
}
|
|
505
|
+
function isToolTimerId(id) {
|
|
506
|
+
return keyOfTimerId(id) !== null;
|
|
507
|
+
}
|
|
508
|
+
function keyOfTimerId(id) {
|
|
509
|
+
for (const prefix of ["resilient:retry:", "resilient:deadline:"]) {
|
|
510
|
+
if (id.startsWith(prefix)) {
|
|
511
|
+
const key = id.slice(prefix.length);
|
|
512
|
+
return key.startsWith(TOOL_KEY_PREFIX) ? key : null;
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
return null;
|
|
516
|
+
}
|
|
517
|
+
function createToolLadder(resilienceOf2, toolOf, rng) {
|
|
518
|
+
const instances = /* @__PURE__ */ new Map();
|
|
519
|
+
function rcFor(call) {
|
|
520
|
+
const policy = resilienceOf2(call);
|
|
521
|
+
if (policy === null) return null;
|
|
522
|
+
if (policy.timeoutMs === void 0 && policy.retry === void 0) {
|
|
523
|
+
return null;
|
|
524
|
+
}
|
|
525
|
+
const cached = instances.get(call.name);
|
|
526
|
+
if (cached !== void 0) return cached;
|
|
527
|
+
const made = createResilientCall(
|
|
528
|
+
{
|
|
529
|
+
...policy.retry !== void 0 ? { retry: policy.retry } : {},
|
|
530
|
+
...policy.timeoutMs !== void 0 ? { deadline: { ms: policy.timeoutMs } } : {}
|
|
531
|
+
},
|
|
532
|
+
rng
|
|
533
|
+
);
|
|
534
|
+
instances.set(call.name, made);
|
|
535
|
+
return made;
|
|
536
|
+
}
|
|
537
|
+
function sliceOf(s, name, rc) {
|
|
538
|
+
return s[name] ?? rc.init();
|
|
539
|
+
}
|
|
540
|
+
function toLaunchCmds(runCmds) {
|
|
541
|
+
return runCmds.map((cmd) => toolOf(cmd.input));
|
|
542
|
+
}
|
|
543
|
+
const launch = (s, calls, at) => {
|
|
544
|
+
let next = s;
|
|
545
|
+
const cmds = [];
|
|
546
|
+
for (const call of calls) {
|
|
547
|
+
const rc = rcFor(call);
|
|
548
|
+
if (rc === null) {
|
|
549
|
+
cmds.push(toolOf(call));
|
|
550
|
+
continue;
|
|
551
|
+
}
|
|
552
|
+
const [slice, runCmds] = rc.attempt(
|
|
553
|
+
sliceOf(next, call.name, rc),
|
|
554
|
+
toolCallKey(call.name, call.callId),
|
|
555
|
+
call,
|
|
556
|
+
at
|
|
557
|
+
);
|
|
558
|
+
next = { ...next, [call.name]: slice };
|
|
559
|
+
cmds.push(...toLaunchCmds(runCmds));
|
|
560
|
+
}
|
|
561
|
+
return [next, cmds];
|
|
562
|
+
};
|
|
563
|
+
const ok = (s, call, at) => {
|
|
564
|
+
const rc = rcFor(call);
|
|
565
|
+
if (rc === null) return s;
|
|
566
|
+
const key = toolCallKey(call.name, call.callId);
|
|
567
|
+
const [slice] = rc.succeed(sliceOf(s, call.name, rc), key, {
|
|
568
|
+
type: MsgType.ResilientOk,
|
|
569
|
+
key,
|
|
570
|
+
result: null,
|
|
571
|
+
at
|
|
572
|
+
});
|
|
573
|
+
return { ...s, [call.name]: forget(slice, key) };
|
|
574
|
+
};
|
|
575
|
+
const err = (s, call, failure, at) => {
|
|
576
|
+
const rc = rcFor(call);
|
|
577
|
+
if (rc === null) return [s, failure];
|
|
578
|
+
const key = toolCallKey(call.name, call.callId);
|
|
579
|
+
const before = sliceOf(s, call.name, rc);
|
|
580
|
+
const [slice] = rc.fail(before, key, {
|
|
581
|
+
type: MsgType.ResilientErr,
|
|
582
|
+
key,
|
|
583
|
+
error: failure,
|
|
584
|
+
at
|
|
585
|
+
});
|
|
586
|
+
if (slice.calls[key]?.phase === "waiting_retry") {
|
|
587
|
+
return [{ ...s, [call.name]: slice }, null];
|
|
588
|
+
}
|
|
589
|
+
const attempts = before.retry[key]?.attempt;
|
|
590
|
+
const settled = resilienceOf2(call)?.retry === void 0 ? failure : exhaustedFailure((attempts ?? 0) + 1, failure);
|
|
591
|
+
return [{ ...s, [call.name]: forget(slice, key) }, settled];
|
|
592
|
+
};
|
|
593
|
+
const onTimer = (s, msg) => {
|
|
594
|
+
const key = keyOfTimerId(msg.id);
|
|
595
|
+
const parsed = key === null ? null : readToolCallKey(key);
|
|
596
|
+
if (key === null || parsed === null) return [s, { cmds: [], settle: [] }];
|
|
597
|
+
const slice = s[parsed.name];
|
|
598
|
+
if (slice === void 0) return [s, { cmds: [], settle: [] }];
|
|
599
|
+
const remembered = inputOf(slice, key);
|
|
600
|
+
const rc = remembered === null ? null : rcFor(remembered);
|
|
601
|
+
if (rc === null) return [s, { cmds: [], settle: [] }];
|
|
602
|
+
const [next, runCmds] = rc.onTimer(slice, msg);
|
|
603
|
+
const phase = next.calls[key];
|
|
604
|
+
if (phase?.phase === "failed" && isDeadline(phase.error)) {
|
|
605
|
+
return [
|
|
606
|
+
{ ...s, [parsed.name]: forget(next, key) },
|
|
607
|
+
{
|
|
608
|
+
cmds: [],
|
|
609
|
+
settle: [{ callId: parsed.callId, failure: timeoutFailure() }]
|
|
610
|
+
}
|
|
611
|
+
];
|
|
612
|
+
}
|
|
613
|
+
return [
|
|
614
|
+
{ ...s, [parsed.name]: next },
|
|
615
|
+
{ cmds: toLaunchCmds(runCmds), settle: [] }
|
|
616
|
+
];
|
|
617
|
+
};
|
|
618
|
+
const boot = (s, calls, at) => {
|
|
619
|
+
let next = s;
|
|
620
|
+
const cmds = [];
|
|
621
|
+
const settle = [];
|
|
622
|
+
for (const call of calls) {
|
|
623
|
+
const rc = rcFor(call);
|
|
624
|
+
if (rc === null) {
|
|
625
|
+
cmds.push(toolOf(call));
|
|
626
|
+
continue;
|
|
627
|
+
}
|
|
628
|
+
const key = toolCallKey(call.name, call.callId);
|
|
629
|
+
next = {
|
|
630
|
+
...next,
|
|
631
|
+
[call.name]: rc.resume(sliceOf(next, call.name, rc), at)
|
|
632
|
+
};
|
|
633
|
+
const phase = sliceOf(next, call.name, rc).calls[key]?.phase;
|
|
634
|
+
if (phase === "waiting_retry") continue;
|
|
635
|
+
const [slice, runCmds] = rc.attempt(
|
|
636
|
+
sliceOf(next, call.name, rc),
|
|
637
|
+
key,
|
|
638
|
+
call,
|
|
639
|
+
at
|
|
640
|
+
);
|
|
641
|
+
const settled = slice.calls[key];
|
|
642
|
+
if (settled?.phase === "failed" && isDeadline(settled.error)) {
|
|
643
|
+
next = { ...next, [call.name]: forget(slice, key) };
|
|
644
|
+
settle.push({ callId: call.callId, failure: timeoutFailure() });
|
|
645
|
+
continue;
|
|
646
|
+
}
|
|
647
|
+
next = { ...next, [call.name]: slice };
|
|
648
|
+
cmds.push(...toLaunchCmds(runCmds));
|
|
649
|
+
}
|
|
650
|
+
return [next, { cmds, settle }];
|
|
651
|
+
};
|
|
652
|
+
const subs = (s) => {
|
|
653
|
+
const out = [];
|
|
654
|
+
for (const slice of Object.values(s)) {
|
|
655
|
+
const sample = firstInput(slice);
|
|
656
|
+
const rc = sample === null ? null : rcFor(sample);
|
|
657
|
+
if (rc !== null) out.push(...rc.subs(slice));
|
|
658
|
+
}
|
|
659
|
+
return out;
|
|
660
|
+
};
|
|
661
|
+
return { init: () => ({}), launch, ok, err, onTimer, boot, subs };
|
|
662
|
+
}
|
|
663
|
+
function forget(s, key) {
|
|
664
|
+
const { [key]: _settled, ...calls } = s.calls;
|
|
665
|
+
const { [key]: _spent, ...retry } = s.retry;
|
|
666
|
+
return { ...s, calls, retry };
|
|
667
|
+
}
|
|
668
|
+
function inputOf(s, key) {
|
|
669
|
+
const call = s.calls[key];
|
|
670
|
+
if (call === void 0) return null;
|
|
671
|
+
return call.phase === "running" || call.phase === "waiting_retry" ? call.input : null;
|
|
672
|
+
}
|
|
673
|
+
function firstInput(s) {
|
|
674
|
+
for (const key of Object.keys(s.calls)) {
|
|
675
|
+
const input = inputOf(s, key);
|
|
676
|
+
if (input !== null) return input;
|
|
677
|
+
}
|
|
678
|
+
return null;
|
|
679
|
+
}
|
|
680
|
+
function isDeadline(error) {
|
|
681
|
+
return typeof error === "object" && error !== null && error._tag === "deadline_exceeded";
|
|
682
|
+
}
|
|
683
|
+
function exhaustedFailure(attempts, last) {
|
|
684
|
+
return taggedFailure({
|
|
685
|
+
_tag: TOOL_RETRY_EXHAUSTED_TAG,
|
|
686
|
+
attempts,
|
|
687
|
+
last: last.reason
|
|
688
|
+
});
|
|
689
|
+
}
|
|
690
|
+
function timeoutFailure() {
|
|
691
|
+
return taggedFailure({ _tag: TOOL_TIMEOUT_TAG });
|
|
692
|
+
}
|
|
693
|
+
function taggedFailure(tagged) {
|
|
694
|
+
return { ...tagged, reason: toolErrorReason(tagged), kind: "error" };
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
// src/agent/define-agent.ts
|
|
698
|
+
function defineAgent(config) {
|
|
699
|
+
const router = toolRouter(config.tools);
|
|
700
|
+
const { onToolError } = config;
|
|
701
|
+
const tools = onToolError === void 0 ? router : withToolErrorHook(router, onToolError);
|
|
702
|
+
return definedAgent(config, { router, tools }, []);
|
|
703
|
+
}
|
|
704
|
+
function definedAgent(config, wiring, overlays) {
|
|
705
|
+
const { router, tools } = wiring;
|
|
706
|
+
const { onToolError } = config;
|
|
707
|
+
const machineWith = (input, onChunk) => {
|
|
708
|
+
const brain = brainOf(config.model, onChunk);
|
|
709
|
+
const core = {
|
|
710
|
+
stages: [input],
|
|
711
|
+
turnOf: () => "act",
|
|
712
|
+
schemas: { act: agentTurnSchema },
|
|
713
|
+
model: brain,
|
|
714
|
+
instructions: config.instructions,
|
|
715
|
+
payloadOf: promptOf,
|
|
716
|
+
loadMessages: messagesOf,
|
|
717
|
+
toolOf: tools.toolOf,
|
|
718
|
+
// The per-tool timeout / retry knob (#117). The lid grows no option for
|
|
719
|
+
// it: the policy is declared on the `tool()` that needs it, and the
|
|
720
|
+
// router is what carries it down to the reducer that runs it.
|
|
721
|
+
toolResilienceOf: tools.resilienceOf,
|
|
722
|
+
// The BRAIN-call ladder (#146), which does grow one, because a bare
|
|
723
|
+
// `model` function has nowhere else to declare it. Forwarded only when
|
|
724
|
+
// set, so an omitted lid option leaves `AgentConfigCore.retry` unset
|
|
725
|
+
// and the brain call unbackedoff, byte for byte as before.
|
|
726
|
+
...config.retry !== void 0 ? { retry: config.retry } : {},
|
|
727
|
+
// Forwarded only when set, for the same reason: an omitted knob leaves
|
|
728
|
+
// `AgentConfigCore.toolConcurrency` unset and the fan-out at its serial
|
|
729
|
+
// default.
|
|
730
|
+
...config.toolConcurrency !== void 0 ? { toolConcurrency: config.toolConcurrency } : {},
|
|
731
|
+
maxTurns: config.maxTurns,
|
|
732
|
+
deadlineMs: config.deadlineMs,
|
|
733
|
+
maxElapsedMs: config.maxElapsedMs,
|
|
734
|
+
stopWhen: config.stopWhen
|
|
735
|
+
};
|
|
736
|
+
const compaction = config.compaction;
|
|
737
|
+
const agent = compaction === void 0 ? (
|
|
738
|
+
// The one assertion in the pair, and it widens the Cmd union rather
|
|
739
|
+
// than the interpret obligation: this machine's `AgentCmd` fixes
|
|
740
|
+
// compaction OFF, `DefinedAgentMachine` names the ON superset, and the
|
|
741
|
+
// gap is the `compact_run` Cmd a policy-less reducer provably never
|
|
742
|
+
// emits. Widening a union nothing can produce is sound; the reverse —
|
|
743
|
+
// claiming a cell that is not wired — is what the discriminant refuses.
|
|
744
|
+
createAgent(core).toMachine({
|
|
745
|
+
tools
|
|
746
|
+
})
|
|
747
|
+
) : compactingMachine(core, compaction, brain, tools);
|
|
748
|
+
return overlaid(agent, overlays);
|
|
749
|
+
};
|
|
750
|
+
const machine = (input) => machineWith(input, void 0);
|
|
751
|
+
const drive = (input, ...[opts = noHost()]) => {
|
|
752
|
+
const { onEvent, onChunk } = opts;
|
|
753
|
+
const handle = run(machineWith(input, onChunk), {
|
|
754
|
+
...opts,
|
|
755
|
+
terminal: isEnded,
|
|
756
|
+
events: onEvent === void 0 ? void 0 : agentEvents({
|
|
757
|
+
tools
|
|
758
|
+
})
|
|
759
|
+
});
|
|
760
|
+
if (onEvent !== void 0) forwardEvents(handle, onEvent);
|
|
761
|
+
if (onToolError !== void 0) {
|
|
762
|
+
forwardLadderErrors(handle, router, onToolError);
|
|
763
|
+
}
|
|
764
|
+
const clock = opts.clock ?? Date.now;
|
|
765
|
+
const begin = (booted) => {
|
|
766
|
+
const at = clock();
|
|
767
|
+
return isMidRun(booted) ? agentBootMsg(at) : startMsg(opts.runId ?? crypto.randomUUID(), at);
|
|
768
|
+
};
|
|
769
|
+
const signal = opts.signal;
|
|
770
|
+
if (signal === void 0) {
|
|
771
|
+
return ended(driveToDone(handle, begin, isEnded, { failed: isFailed }));
|
|
772
|
+
}
|
|
773
|
+
return ended(
|
|
774
|
+
driveToDone(handle, begin, isEnded, {
|
|
775
|
+
failed: isFailed,
|
|
776
|
+
signal,
|
|
777
|
+
cancel: () => agentCancelMsg(clock())
|
|
778
|
+
})
|
|
779
|
+
);
|
|
780
|
+
};
|
|
781
|
+
return {
|
|
782
|
+
machine,
|
|
783
|
+
run: drive,
|
|
784
|
+
with: (overlay) => definedAgent(config, wiring, [...overlays, overlay.interpret])
|
|
785
|
+
};
|
|
786
|
+
}
|
|
787
|
+
function overlaid(machine, overlays) {
|
|
788
|
+
if (overlays.length === 0) return machine;
|
|
789
|
+
const cells = { ...machine.interpret };
|
|
790
|
+
for (const overlay of overlays) {
|
|
791
|
+
const wrappers = overlay;
|
|
792
|
+
for (const [type, wrap] of Object.entries(wrappers)) {
|
|
793
|
+
const cell = cells[type];
|
|
794
|
+
if (cell === void 0) {
|
|
795
|
+
throw new Error(
|
|
796
|
+
`@demlik/tea: defineAgent(...).with named the interpret cell "${type}", which this agent's machine has none of. Its cells are: ${Object.keys(cells).sort().join(", ")}.`
|
|
797
|
+
);
|
|
798
|
+
}
|
|
799
|
+
cells[type] = wrap(cell);
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
return defineMachine({
|
|
803
|
+
...machine,
|
|
804
|
+
interpret: cells
|
|
805
|
+
});
|
|
806
|
+
}
|
|
807
|
+
function brainOf(model, onChunk) {
|
|
808
|
+
if (!isStreamingModel(model)) {
|
|
809
|
+
return model;
|
|
810
|
+
}
|
|
811
|
+
const streaming = model;
|
|
812
|
+
const stream = {
|
|
813
|
+
onChunk: onChunk === void 0 ? dropChunk : contained("onChunk", onChunk)
|
|
814
|
+
};
|
|
815
|
+
return async (messages) => streaming(messages, stream);
|
|
816
|
+
}
|
|
817
|
+
function dropChunk() {
|
|
818
|
+
}
|
|
819
|
+
function contained(what, listener) {
|
|
820
|
+
return (event) => {
|
|
821
|
+
try {
|
|
822
|
+
listener(event);
|
|
823
|
+
} catch (err) {
|
|
824
|
+
console.warn(`@demlik/tea: a run's ${what} listener threw`, err);
|
|
825
|
+
}
|
|
826
|
+
};
|
|
827
|
+
}
|
|
828
|
+
function compactingMachine(core, knob, brain, tools) {
|
|
829
|
+
const agent = createAgent({ ...core, compaction: compactionPolicyOf(knob) });
|
|
830
|
+
const wiring = {
|
|
831
|
+
tools,
|
|
832
|
+
toolInterpret: { compact_run: summarizeWith(brain) }
|
|
833
|
+
};
|
|
834
|
+
return agent.toMachine(wiring);
|
|
835
|
+
}
|
|
836
|
+
var SUMMARIZE_INSTRUCTION = "Summarize the conversation so far. Preserve the facts, decisions and tool results a continuation would need, and drop everything else. Reply with the summary as your message content and request no tools.";
|
|
837
|
+
function compactionPolicyOf(knob) {
|
|
838
|
+
const keep = knob.keepTurns ?? 0;
|
|
839
|
+
return {
|
|
840
|
+
planCompaction: (conversation) => conversation.turns.length >= knob.afterTurns ? Math.max(0, conversation.turns.length - keep) : 0,
|
|
841
|
+
payloadOf: (conversation, folding) => ({
|
|
842
|
+
instructions: SUMMARIZE_INSTRUCTION,
|
|
843
|
+
input: null,
|
|
844
|
+
conversation: {
|
|
845
|
+
...conversation,
|
|
846
|
+
turns: conversation.turns.slice(0, folding),
|
|
847
|
+
toolRecords: conversation.toolRecords.filter((r) => r.turn < folding)
|
|
848
|
+
}
|
|
849
|
+
})
|
|
850
|
+
};
|
|
851
|
+
}
|
|
852
|
+
function summarizeWith(model) {
|
|
853
|
+
return async (cmd) => {
|
|
854
|
+
const payload = cmd.input.payload;
|
|
855
|
+
const turn = await model(renderPrompt(payload));
|
|
856
|
+
return {
|
|
857
|
+
type: MsgType.CompactOk,
|
|
858
|
+
key: COMPACTION_PURPOSE,
|
|
859
|
+
result: {
|
|
860
|
+
key: COMPACTION_PURPOSE,
|
|
861
|
+
purpose: COMPACTION_PURPOSE,
|
|
862
|
+
output: { summary: turn.content }
|
|
863
|
+
},
|
|
864
|
+
at: Date.now()
|
|
865
|
+
};
|
|
866
|
+
};
|
|
867
|
+
}
|
|
868
|
+
function promptOf(stage, conversation, instructions) {
|
|
869
|
+
return { instructions, input: stage ?? null, conversation };
|
|
870
|
+
}
|
|
871
|
+
var messagesOf = async (call) => renderPrompt(call.payload);
|
|
872
|
+
function renderPrompt(prompt) {
|
|
873
|
+
const head = [];
|
|
874
|
+
if (prompt.instructions !== null) {
|
|
875
|
+
head.push({ role: "system", content: prompt.instructions });
|
|
876
|
+
}
|
|
877
|
+
if (prompt.input !== null) {
|
|
878
|
+
head.push({ role: "user", content: prompt.input });
|
|
879
|
+
}
|
|
880
|
+
const { turns, toolRecords } = prompt.conversation;
|
|
881
|
+
const transcript2 = turns.flatMap((turn, i) => [
|
|
882
|
+
assistantOf(turn),
|
|
883
|
+
...toolRecords.filter((r) => r.turn === i).map((r) => ({
|
|
884
|
+
role: "tool",
|
|
885
|
+
callId: r.call.callId,
|
|
886
|
+
name: r.call.name,
|
|
887
|
+
outcome: r.outcome
|
|
888
|
+
}))
|
|
889
|
+
]);
|
|
890
|
+
return [...head, ...transcript2];
|
|
891
|
+
}
|
|
892
|
+
function assistantOf(turn) {
|
|
893
|
+
const { content, toolCalls } = turn;
|
|
894
|
+
return "provider" in turn ? { role: "assistant", content, toolCalls, provider: turn.provider } : { role: "assistant", content, toolCalls };
|
|
895
|
+
}
|
|
896
|
+
function noHost() {
|
|
897
|
+
return {};
|
|
898
|
+
}
|
|
899
|
+
var AGENT_EVENT_TYPES = ["TurnSettled", "ToolSettled", "RunDone"];
|
|
900
|
+
function forwardEvents(handle, onEvent) {
|
|
901
|
+
const deliver = contained("onEvent", onEvent);
|
|
902
|
+
for (const type of AGENT_EVENT_TYPES) {
|
|
903
|
+
handle.on(type, deliver);
|
|
904
|
+
}
|
|
905
|
+
}
|
|
906
|
+
function forwardLadderErrors(handle, router, onToolError) {
|
|
907
|
+
const fired = /* @__PURE__ */ new Set();
|
|
908
|
+
handle.observe((msg, state) => {
|
|
909
|
+
const seeding = msg.type === MsgType.AgentStart || msg.type === MsgType.AgentBoot;
|
|
910
|
+
for (const record of state.conversation?.toolRecords ?? []) {
|
|
911
|
+
const { outcome, call } = record;
|
|
912
|
+
if (outcome.kind !== "error") continue;
|
|
913
|
+
if (fired.has(call.callId)) continue;
|
|
914
|
+
fired.add(call.callId);
|
|
915
|
+
if (seeding) continue;
|
|
916
|
+
if (router.resilienceOf(call) === null) continue;
|
|
917
|
+
void Promise.resolve(
|
|
918
|
+
onToolError(outcome, {
|
|
919
|
+
callId: call.callId,
|
|
920
|
+
name: call.name
|
|
921
|
+
})
|
|
922
|
+
).catch((err) => {
|
|
923
|
+
console.warn("@demlik/tea: a run's onToolError hook threw", err);
|
|
924
|
+
});
|
|
925
|
+
}
|
|
926
|
+
});
|
|
927
|
+
}
|
|
928
|
+
function withToolErrorHook(router, onToolError) {
|
|
929
|
+
const handlers = router.interpret;
|
|
930
|
+
const wrapped = {};
|
|
931
|
+
for (const [type, handler] of Object.entries(handlers)) {
|
|
932
|
+
wrapped[type] = async (cmd, ctx) => {
|
|
933
|
+
const msg = await handler(cmd, ctx);
|
|
934
|
+
if (msg === void 0) return msg;
|
|
935
|
+
const settled = router.outcomeOf(msg);
|
|
936
|
+
if (settled === null || settled.outcome.kind === "ok") return msg;
|
|
937
|
+
if (ownedByLadder(router, cmd, settled.callId)) return msg;
|
|
938
|
+
try {
|
|
939
|
+
await onToolError(settled.outcome, {
|
|
940
|
+
callId: settled.callId,
|
|
941
|
+
name: calledName(cmd)
|
|
942
|
+
});
|
|
943
|
+
} catch (err) {
|
|
944
|
+
console.warn("@demlik/tea: a run's onToolError hook threw", err);
|
|
945
|
+
}
|
|
946
|
+
return msg;
|
|
947
|
+
};
|
|
948
|
+
}
|
|
949
|
+
return {
|
|
950
|
+
...router,
|
|
951
|
+
interpret: wrapped
|
|
952
|
+
};
|
|
953
|
+
}
|
|
954
|
+
function ownedByLadder(router, cmd, callId) {
|
|
955
|
+
return router.resilienceOf({ name: cmd.type, callId, args: {} }) !== null;
|
|
956
|
+
}
|
|
957
|
+
function calledName(cmd) {
|
|
958
|
+
const rejection = cmd.error;
|
|
959
|
+
return typeof rejection?.name === "string" ? rejection.name : cmd.type;
|
|
960
|
+
}
|
|
961
|
+
function startMsg(runId, at) {
|
|
962
|
+
return { type: MsgType.AgentStart, runId, at };
|
|
963
|
+
}
|
|
964
|
+
function isMidRun(s) {
|
|
965
|
+
const { kind } = status(s);
|
|
966
|
+
return kind === "running" || kind === "suspended";
|
|
967
|
+
}
|
|
968
|
+
function isEnded(s) {
|
|
969
|
+
return s.run.phase === "done" || s.run.phase === "cancelled";
|
|
970
|
+
}
|
|
971
|
+
function ended(drive) {
|
|
972
|
+
return drive;
|
|
973
|
+
}
|
|
974
|
+
function isFailed(s) {
|
|
975
|
+
return status(s).kind === "failed";
|
|
976
|
+
}
|
|
977
|
+
|
|
978
|
+
// src/agent/transcript.ts
|
|
979
|
+
function transcript(seed) {
|
|
980
|
+
const turns = [...seed?.conversation?.turns ?? []];
|
|
981
|
+
const tools = (seed?.conversation?.toolRecords ?? []).flatMap(
|
|
982
|
+
(record) => record.outcome.kind === "ok" ? [{ callId: record.call.callId, result: record.outcome.result }] : []
|
|
983
|
+
);
|
|
984
|
+
let outcome = { kind: "running" };
|
|
985
|
+
return {
|
|
986
|
+
onEvent: (event) => {
|
|
987
|
+
switch (event.type) {
|
|
988
|
+
case "TurnSettled":
|
|
989
|
+
turns.push(event.turn);
|
|
990
|
+
return;
|
|
991
|
+
case "ToolSettled":
|
|
992
|
+
tools.push({ callId: event.callId, result: event.result });
|
|
993
|
+
return;
|
|
994
|
+
case "RunDone":
|
|
995
|
+
outcome = { kind: "done", output: event.output };
|
|
996
|
+
return;
|
|
997
|
+
}
|
|
998
|
+
},
|
|
999
|
+
read: () => ({ turns: [...turns], tools: [...tools], outcome })
|
|
1000
|
+
};
|
|
1001
|
+
}
|
|
1002
|
+
|
|
1003
|
+
// src/agent/index.ts
|
|
1004
|
+
function createAgent(config) {
|
|
1005
|
+
const rng = config.rng ?? Math.random;
|
|
1006
|
+
const run2 = createMonitoredRun({
|
|
1007
|
+
...config.stages !== void 0 ? { stages: config.stages } : {},
|
|
1008
|
+
...config.deadlineMs !== void 0 ? { deadlineMs: config.deadlineMs } : {},
|
|
1009
|
+
...config.snapshotEvery !== void 0 ? { snapshotEvery: config.snapshotEvery } : {}
|
|
1010
|
+
});
|
|
1011
|
+
const llm = createLlmCall(
|
|
1012
|
+
{
|
|
1013
|
+
model: config.model,
|
|
1014
|
+
schemas: config.schemas,
|
|
1015
|
+
...config.retry !== void 0 ? { retry: config.retry } : {},
|
|
1016
|
+
...config.loadMessages !== void 0 ? { loadMessages: config.loadMessages } : {}
|
|
1017
|
+
},
|
|
1018
|
+
rng
|
|
1019
|
+
);
|
|
1020
|
+
const compactRc = createResilientCall({ ...config.retry !== void 0 ? { retry: config.retry } : {} }, rng);
|
|
1021
|
+
const fan = createFanOut({
|
|
1022
|
+
concurrency: config.toolConcurrency ?? 1,
|
|
1023
|
+
idOf: (call) => call.callId,
|
|
1024
|
+
of: (call) => config.toolOf(call)
|
|
1025
|
+
});
|
|
1026
|
+
const ladder = createToolLadder(
|
|
1027
|
+
config.toolResilienceOf ?? (() => null),
|
|
1028
|
+
config.toolOf,
|
|
1029
|
+
rng
|
|
1030
|
+
);
|
|
1031
|
+
function init() {
|
|
1032
|
+
return {
|
|
1033
|
+
run: run2.init(),
|
|
1034
|
+
resilience: llm.init(),
|
|
1035
|
+
tools: initFanOut(),
|
|
1036
|
+
conversation: null,
|
|
1037
|
+
compaction: compactRc.init(),
|
|
1038
|
+
toolResilience: ladder.init(),
|
|
1039
|
+
refusedCalls: [],
|
|
1040
|
+
failure: null,
|
|
1041
|
+
output: null,
|
|
1042
|
+
instructions: config.instructions ?? null
|
|
1043
|
+
};
|
|
1044
|
+
}
|
|
1045
|
+
function brainCall(s) {
|
|
1046
|
+
const stage = currentStage(s);
|
|
1047
|
+
const conversation = s.conversation ?? freshConversation();
|
|
1048
|
+
const instructions = s.instructions ?? null;
|
|
1049
|
+
return {
|
|
1050
|
+
purpose: config.turnOf(stage),
|
|
1051
|
+
model: config.modelId ?? null,
|
|
1052
|
+
payload: config.payloadOf ? config.payloadOf(stage, conversation, instructions) : null
|
|
1053
|
+
};
|
|
1054
|
+
}
|
|
1055
|
+
function fireBrainCall(s, at) {
|
|
1056
|
+
const call = brainCall(s);
|
|
1057
|
+
const [resilience, cmds] = llm.attempt(s.resilience, call, at);
|
|
1058
|
+
return [{ ...s, resilience }, cmds];
|
|
1059
|
+
}
|
|
1060
|
+
function compactionCall(conv, folding) {
|
|
1061
|
+
const payloadOf = config.compaction?.payloadOf;
|
|
1062
|
+
return {
|
|
1063
|
+
purpose: COMPACTION_PURPOSE,
|
|
1064
|
+
model: config.modelId ?? null,
|
|
1065
|
+
payload: payloadOf ? payloadOf(conv, folding) : null
|
|
1066
|
+
};
|
|
1067
|
+
}
|
|
1068
|
+
function reKeyCompactCmds(result) {
|
|
1069
|
+
const [slice, cmds] = result;
|
|
1070
|
+
return [slice, cmds.map(toCompactRunCmd)];
|
|
1071
|
+
}
|
|
1072
|
+
const compact = {
|
|
1073
|
+
attempt: (slice, key, input, at) => reKeyCompactCmds(compactRc.attempt(slice, key, input, at)),
|
|
1074
|
+
succeed: (slice, key, msg) => reKeyCompactCmds(compactRc.succeed(slice, key, msg)),
|
|
1075
|
+
fail: (slice, key, msg) => reKeyCompactCmds(compactRc.fail(slice, key, msg)),
|
|
1076
|
+
onTimer: (slice, msg) => reKeyCompactCmds(compactRc.onTimer(slice, msg))
|
|
1077
|
+
};
|
|
1078
|
+
function start(s, runId, at) {
|
|
1079
|
+
const [runSlice] = run2.start(s.run, runId, at);
|
|
1080
|
+
const conversation = freshConversation();
|
|
1081
|
+
const withRun = {
|
|
1082
|
+
...s,
|
|
1083
|
+
run: runSlice,
|
|
1084
|
+
conversation,
|
|
1085
|
+
failure: null,
|
|
1086
|
+
// A restart clears the prior run's terminal output — `result()` reads
|
|
1087
|
+
// `undefined` again until THIS run finishes (#46).
|
|
1088
|
+
output: null,
|
|
1089
|
+
tools: initFanOut(),
|
|
1090
|
+
// A restart also clears any prior compaction slice — a fresh run never
|
|
1091
|
+
// inherits the previous run's summarize retry bookkeeping (#85).
|
|
1092
|
+
compaction: compactRc.init(),
|
|
1093
|
+
// …and the prior run's refusals: those `callId`s belong to a batch this
|
|
1094
|
+
// run will never settle, so carrying them would only grow the Model (#145).
|
|
1095
|
+
refusedCalls: []
|
|
1096
|
+
};
|
|
1097
|
+
return fireBrainCall(withRun, at);
|
|
1098
|
+
}
|
|
1099
|
+
function turn(s, result, at) {
|
|
1100
|
+
const conv = requireAwaiting(s, "llm");
|
|
1101
|
+
if (conv === null) return [s, []];
|
|
1102
|
+
const withTurn = {
|
|
1103
|
+
...conv,
|
|
1104
|
+
turns: [...conv.turns, result]
|
|
1105
|
+
};
|
|
1106
|
+
if (result.toolCalls.length === 0) {
|
|
1107
|
+
return advanceStage({ ...s, conversation: withTurn }, result, at);
|
|
1108
|
+
}
|
|
1109
|
+
const batch = dedupeByCallId(result.toolCalls);
|
|
1110
|
+
const [tools] = fan.scatter(initFanOut(), batch);
|
|
1111
|
+
const nextConv = {
|
|
1112
|
+
...withTurn,
|
|
1113
|
+
awaiting: { kind: "tools", batchTurn: withTurn.turnCount }
|
|
1114
|
+
};
|
|
1115
|
+
const [runSlice] = run2.progress(s.run, void 0, at);
|
|
1116
|
+
const [toolResilience, launchCmds] = armLaunch(s, [], tools.running, at);
|
|
1117
|
+
return [
|
|
1118
|
+
{ ...s, run: runSlice, tools, toolResilience, conversation: nextConv },
|
|
1119
|
+
launchCmds
|
|
1120
|
+
];
|
|
1121
|
+
}
|
|
1122
|
+
function advanceStage(s, terminatingTurn, at) {
|
|
1123
|
+
const [runSlice, runCmds] = run2.advance(
|
|
1124
|
+
s.run,
|
|
1125
|
+
void 0,
|
|
1126
|
+
{ kind: "ok" },
|
|
1127
|
+
at
|
|
1128
|
+
);
|
|
1129
|
+
if (runSlice.phase === "done") {
|
|
1130
|
+
return [
|
|
1131
|
+
{ ...s, run: runSlice, conversation: null, output: terminatingTurn },
|
|
1132
|
+
runCmds
|
|
1133
|
+
];
|
|
1134
|
+
}
|
|
1135
|
+
const conversation = freshConversation();
|
|
1136
|
+
const moved = {
|
|
1137
|
+
...s,
|
|
1138
|
+
run: runSlice,
|
|
1139
|
+
conversation,
|
|
1140
|
+
tools: initFanOut()
|
|
1141
|
+
};
|
|
1142
|
+
const [fired, llmCmds] = fireBrainCall(moved, at);
|
|
1143
|
+
return [fired, [...runCmds, ...llmCmds]];
|
|
1144
|
+
}
|
|
1145
|
+
function toolOk(s, callId, result, at) {
|
|
1146
|
+
const call = inFlight(s, callId);
|
|
1147
|
+
const laddered = call === null ? s : { ...s, toolResilience: ladder.ok(toolSlice(s), call, at) };
|
|
1148
|
+
return settleTool(laddered, callId, { kind: "ok", result }, at);
|
|
1149
|
+
}
|
|
1150
|
+
function toolErr(s, callId, reported, at) {
|
|
1151
|
+
const failure = typeof reported === "string" ? { kind: "error", reason: reported } : reported;
|
|
1152
|
+
const call = inFlight(s, callId);
|
|
1153
|
+
if (call === null) return settleTool(s, callId, failure, at);
|
|
1154
|
+
const [toolResilience, settled] = ladder.err(
|
|
1155
|
+
toolSlice(s),
|
|
1156
|
+
call,
|
|
1157
|
+
failure,
|
|
1158
|
+
at
|
|
1159
|
+
);
|
|
1160
|
+
const next = { ...s, toolResilience };
|
|
1161
|
+
if (settled === null) return [next, []];
|
|
1162
|
+
return settleTool(next, callId, settled, at);
|
|
1163
|
+
}
|
|
1164
|
+
function inFlight(s, callId) {
|
|
1165
|
+
return s.tools.running.find((c) => c.callId === callId) ?? null;
|
|
1166
|
+
}
|
|
1167
|
+
function toolSlice(s) {
|
|
1168
|
+
return s.toolResilience ?? {};
|
|
1169
|
+
}
|
|
1170
|
+
function refusedOf(s) {
|
|
1171
|
+
return s.refusedCalls ?? [];
|
|
1172
|
+
}
|
|
1173
|
+
function armLaunch(s, before, after, at) {
|
|
1174
|
+
const known = new Set(before.map((c) => c.callId));
|
|
1175
|
+
return ladder.launch(
|
|
1176
|
+
toolSlice(s),
|
|
1177
|
+
after.filter((c) => !known.has(c.callId)),
|
|
1178
|
+
at
|
|
1179
|
+
);
|
|
1180
|
+
}
|
|
1181
|
+
function settleTool(prev, callId, outcome, at) {
|
|
1182
|
+
const conv = requireAwaiting(prev, "tools");
|
|
1183
|
+
if (conv === null) return [prev, []];
|
|
1184
|
+
const call = prev.tools.running.find((c) => c.callId === callId);
|
|
1185
|
+
if (call === void 0) return [prev, []];
|
|
1186
|
+
const [tools] = outcome.kind === "ok" ? fan.itemOk(prev.tools, callId, outcome) : fan.itemErr(prev.tools, callId, outcome);
|
|
1187
|
+
const [toolResilience, launchCmds] = armLaunch(
|
|
1188
|
+
prev,
|
|
1189
|
+
prev.tools.running,
|
|
1190
|
+
tools.running,
|
|
1191
|
+
at
|
|
1192
|
+
);
|
|
1193
|
+
const refusedCalls = outcome.kind === "ok" ? refusedOf(prev) : [...refusedOf(prev), callId];
|
|
1194
|
+
const s = { ...prev, toolResilience, refusedCalls };
|
|
1195
|
+
const foldedConv = {
|
|
1196
|
+
...conv,
|
|
1197
|
+
// Stamp the producing-turn index on the record (#85, A1). At settle time
|
|
1198
|
+
// `conv.turnCount` equals the index in `turns` of the turn that scattered
|
|
1199
|
+
// this batch (each prior drained batch bumped `turnCount` exactly once, and
|
|
1200
|
+
// each tool-bearing turn appended exactly one entry to `turns`), so a record
|
|
1201
|
+
// carrying `turn: conv.turnCount` is dropped iff its producing turn is folded
|
|
1202
|
+
// (`turn < N`) — the association the fold-back relies on.
|
|
1203
|
+
toolRecords: [
|
|
1204
|
+
...conv.toolRecords,
|
|
1205
|
+
{ call, outcome, turn: conv.turnCount }
|
|
1206
|
+
]
|
|
1207
|
+
};
|
|
1208
|
+
if (!fan.isComplete(tools)) {
|
|
1209
|
+
const [runSlice2] = run2.progress(s.run, void 0, at);
|
|
1210
|
+
return [
|
|
1211
|
+
{ ...s, run: runSlice2, tools, conversation: foldedConv },
|
|
1212
|
+
launchCmds
|
|
1213
|
+
];
|
|
1214
|
+
}
|
|
1215
|
+
const turnedConv = {
|
|
1216
|
+
...foldedConv,
|
|
1217
|
+
turnCount: foldedConv.turnCount + 1,
|
|
1218
|
+
awaiting: { kind: "llm" }
|
|
1219
|
+
};
|
|
1220
|
+
const turned = { ...s, tools, conversation: turnedConv };
|
|
1221
|
+
const stopped = stopConditions(turned, at);
|
|
1222
|
+
if (stopped !== null) return stopped;
|
|
1223
|
+
const drained = {
|
|
1224
|
+
...turned,
|
|
1225
|
+
tools: initFanOut()
|
|
1226
|
+
};
|
|
1227
|
+
const compacting = maybeCompact(drained, at);
|
|
1228
|
+
if (compacting !== null) return compacting;
|
|
1229
|
+
const [runSlice] = run2.progress(drained.run, void 0, at);
|
|
1230
|
+
const [fired, llmCmds] = fireBrainCall({ ...drained, run: runSlice }, at);
|
|
1231
|
+
return [fired, [...launchCmds, ...llmCmds]];
|
|
1232
|
+
}
|
|
1233
|
+
function maybeCompact(s, at) {
|
|
1234
|
+
const policy = config.compaction;
|
|
1235
|
+
const conv = s.conversation;
|
|
1236
|
+
if (policy === void 0 || conv === null) return null;
|
|
1237
|
+
const requested = policy.planCompaction(conv);
|
|
1238
|
+
const folding = Math.min(requested, conv.turns.length);
|
|
1239
|
+
if (folding < 2) return null;
|
|
1240
|
+
const compactConv = {
|
|
1241
|
+
...conv,
|
|
1242
|
+
awaiting: { kind: "compacting", folding }
|
|
1243
|
+
};
|
|
1244
|
+
const [runSlice] = run2.progress(s.run, void 0, at);
|
|
1245
|
+
const input = compactionCall(conv, folding);
|
|
1246
|
+
const [compaction, cmds] = compact.attempt(
|
|
1247
|
+
s.compaction,
|
|
1248
|
+
COMPACTION_PURPOSE,
|
|
1249
|
+
input,
|
|
1250
|
+
at
|
|
1251
|
+
);
|
|
1252
|
+
return [
|
|
1253
|
+
{ ...s, run: runSlice, conversation: compactConv, compaction },
|
|
1254
|
+
cmds
|
|
1255
|
+
];
|
|
1256
|
+
}
|
|
1257
|
+
function stopConditions(s, at) {
|
|
1258
|
+
const turnCount = s.conversation?.turnCount ?? 0;
|
|
1259
|
+
if (config.maxTurns !== void 0 && turnCount >= config.maxTurns) {
|
|
1260
|
+
return [{ ...s, failure: { reason: "turn_limit", at } }, []];
|
|
1261
|
+
}
|
|
1262
|
+
if (config.maxElapsedMs !== void 0 && at - s.run.startedAt >= config.maxElapsedMs) {
|
|
1263
|
+
return [{ ...s, failure: { reason: "elapsed_limit", at } }, []];
|
|
1264
|
+
}
|
|
1265
|
+
if (config.stopWhen?.(s) === true) return cancel(s, at);
|
|
1266
|
+
return null;
|
|
1267
|
+
}
|
|
1268
|
+
function succeed(s, key, msg, at) {
|
|
1269
|
+
const [resilience, retryCmds] = llm.succeed(s.resilience, key, msg);
|
|
1270
|
+
const settled = { ...s, resilience };
|
|
1271
|
+
const [withTurn, turnCmds] = turn(settled, msg.result.output, at);
|
|
1272
|
+
return [withTurn, [...retryCmds, ...turnCmds]];
|
|
1273
|
+
}
|
|
1274
|
+
function fail(s, key, msg, at) {
|
|
1275
|
+
const [resilience, cmds] = llm.fail(s.resilience, key, msg);
|
|
1276
|
+
const call = resilience.calls[key];
|
|
1277
|
+
const failure = call?.phase === "failed" ? { reason: "llm", error: msg.error, at } : s.failure;
|
|
1278
|
+
return [{ ...s, resilience, failure }, cmds];
|
|
1279
|
+
}
|
|
1280
|
+
function compactOk(s, key, msg, at) {
|
|
1281
|
+
const [compaction, retryCmds] = compact.succeed(s.compaction, key, {
|
|
1282
|
+
type: MsgType.ResilientOk,
|
|
1283
|
+
key: msg.key,
|
|
1284
|
+
result: msg.result,
|
|
1285
|
+
at: msg.at
|
|
1286
|
+
});
|
|
1287
|
+
const settledRetry = { ...s, compaction };
|
|
1288
|
+
const conv = requireAwaiting(settledRetry, "compacting");
|
|
1289
|
+
if (conv === null) return [settledRetry, retryCmds];
|
|
1290
|
+
const folding = conv.awaiting.folding;
|
|
1291
|
+
const summaryTurn = {
|
|
1292
|
+
content: msg.result.output.summary,
|
|
1293
|
+
toolCalls: []
|
|
1294
|
+
};
|
|
1295
|
+
const foldedConv = foldSummary(conv, folding, summaryTurn);
|
|
1296
|
+
const [fired, llmCmds] = fireBrainCall(
|
|
1297
|
+
{ ...settledRetry, conversation: foldedConv },
|
|
1298
|
+
at
|
|
1299
|
+
);
|
|
1300
|
+
return [fired, [...retryCmds, ...llmCmds]];
|
|
1301
|
+
}
|
|
1302
|
+
function compactErr(s, key, msg, at) {
|
|
1303
|
+
const [compaction, cmds] = compact.fail(s.compaction, key, {
|
|
1304
|
+
type: MsgType.ResilientErr,
|
|
1305
|
+
key: msg.key,
|
|
1306
|
+
error: msg.error,
|
|
1307
|
+
at: msg.at
|
|
1308
|
+
});
|
|
1309
|
+
const settledRetry = { ...s, compaction };
|
|
1310
|
+
const call = compaction.calls[key];
|
|
1311
|
+
if (call?.phase === "waiting_retry") {
|
|
1312
|
+
return [settledRetry, cmds];
|
|
1313
|
+
}
|
|
1314
|
+
const conv = requireAwaiting(settledRetry, "compacting");
|
|
1315
|
+
if (conv === null) return [settledRetry, cmds];
|
|
1316
|
+
const resumedConv = { ...conv, awaiting: { kind: "llm" } };
|
|
1317
|
+
const [fired, llmCmds] = fireBrainCall(
|
|
1318
|
+
{ ...settledRetry, conversation: resumedConv },
|
|
1319
|
+
at
|
|
1320
|
+
);
|
|
1321
|
+
return [fired, [...cmds, ...llmCmds]];
|
|
1322
|
+
}
|
|
1323
|
+
function onTimer(s, msg) {
|
|
1324
|
+
if (msg.id.startsWith("monitored:")) {
|
|
1325
|
+
const [runSlice] = run2.onDeadline(s.run, msg);
|
|
1326
|
+
return [{ ...s, run: runSlice }, []];
|
|
1327
|
+
}
|
|
1328
|
+
if (msg.id.endsWith(`:${COMPACTION_PURPOSE}`)) {
|
|
1329
|
+
const [compaction, cmds2] = compact.onTimer(s.compaction, msg);
|
|
1330
|
+
return [{ ...s, compaction }, cmds2];
|
|
1331
|
+
}
|
|
1332
|
+
if (isToolTimerId(msg.id)) return toolTimer(s, msg);
|
|
1333
|
+
const [resilience, cmds] = llm.onTimer(s.resilience, msg);
|
|
1334
|
+
return [{ ...s, resilience }, cmds];
|
|
1335
|
+
}
|
|
1336
|
+
function toolTimer(s, msg) {
|
|
1337
|
+
const [toolResilience, outcome] = ladder.onTimer(toolSlice(s), msg);
|
|
1338
|
+
return applyLadder(s, toolResilience, outcome, msg.atMs);
|
|
1339
|
+
}
|
|
1340
|
+
function applyLadder(s, toolResilience, outcome, at) {
|
|
1341
|
+
let next = { ...s, toolResilience };
|
|
1342
|
+
const cmds = [...outcome.cmds];
|
|
1343
|
+
for (const order of outcome.settle) {
|
|
1344
|
+
const [settled, more] = settleTool(next, order.callId, order.failure, at);
|
|
1345
|
+
next = settled;
|
|
1346
|
+
cmds.push(...more);
|
|
1347
|
+
}
|
|
1348
|
+
return [next, cmds];
|
|
1349
|
+
}
|
|
1350
|
+
function boot(s, at) {
|
|
1351
|
+
const [runSlice] = run2.boot(s.run, at);
|
|
1352
|
+
const rebooted = { ...s, run: runSlice };
|
|
1353
|
+
if (isSettled(rebooted)) return [rebooted, []];
|
|
1354
|
+
const conv = rebooted.conversation;
|
|
1355
|
+
if (conv === null) return [rebooted, []];
|
|
1356
|
+
if (conv.awaiting.kind === "llm") {
|
|
1357
|
+
return fireBrainCall(rebooted, at);
|
|
1358
|
+
}
|
|
1359
|
+
if (conv.awaiting.kind === "compacting") {
|
|
1360
|
+
const input = compactionCall(conv, conv.awaiting.folding);
|
|
1361
|
+
const [compaction, cmds] = compact.attempt(
|
|
1362
|
+
rebooted.compaction,
|
|
1363
|
+
COMPACTION_PURPOSE,
|
|
1364
|
+
input,
|
|
1365
|
+
at
|
|
1366
|
+
);
|
|
1367
|
+
return [{ ...rebooted, compaction }, cmds];
|
|
1368
|
+
}
|
|
1369
|
+
const [toolResilience, outcome] = ladder.boot(
|
|
1370
|
+
toolSlice(rebooted),
|
|
1371
|
+
rebooted.tools.running,
|
|
1372
|
+
at
|
|
1373
|
+
);
|
|
1374
|
+
return applyLadder(rebooted, toolResilience, outcome, at);
|
|
1375
|
+
}
|
|
1376
|
+
function cancel(s, at) {
|
|
1377
|
+
const [runSlice] = run2.cancel(s.run, at);
|
|
1378
|
+
return [{ ...s, run: runSlice }, []];
|
|
1379
|
+
}
|
|
1380
|
+
function subs(s) {
|
|
1381
|
+
return [
|
|
1382
|
+
...llm.subs(s.resilience),
|
|
1383
|
+
...compactRc.subs(s.compaction),
|
|
1384
|
+
...ladder.subs(toolSlice(s)),
|
|
1385
|
+
...run2.subs(s.run)
|
|
1386
|
+
];
|
|
1387
|
+
}
|
|
1388
|
+
function unsafeDetachedHandlers(ports) {
|
|
1389
|
+
return llm.handlers(ports);
|
|
1390
|
+
}
|
|
1391
|
+
function brainHandlers() {
|
|
1392
|
+
return llm.handlers();
|
|
1393
|
+
}
|
|
1394
|
+
function toMachine(opts) {
|
|
1395
|
+
const tools = opts?.tools;
|
|
1396
|
+
const toolCellsInterpret = tools === void 0 ? void 0 : (config.toolConcurrency ?? 1) > 1 ? fanOutInterpret(tools.interpret) : tools.interpret;
|
|
1397
|
+
const consumerInterpret = {
|
|
1398
|
+
...toolCellsInterpret,
|
|
1399
|
+
...opts?.toolInterpret
|
|
1400
|
+
};
|
|
1401
|
+
const interpret = mergeInterpret(consumerInterpret, brainHandlers());
|
|
1402
|
+
const foldTool = (s, m) => {
|
|
1403
|
+
const settled = tools?.outcomeOf(m);
|
|
1404
|
+
if (settled === void 0 || settled === null) return [s, []];
|
|
1405
|
+
return settled.outcome.kind === "ok" ? toolOk(s, settled.callId, settled.outcome.result, m.at) : toolErr(s, settled.callId, settled.outcome, m.at);
|
|
1406
|
+
};
|
|
1407
|
+
const toolCells = {};
|
|
1408
|
+
for (const def of tools?.defs ?? []) {
|
|
1409
|
+
toolCells[def.okType] = foldTool;
|
|
1410
|
+
toolCells[def.errType] = foldTool;
|
|
1411
|
+
}
|
|
1412
|
+
const ownUpdate = {
|
|
1413
|
+
[MsgType.AgentStart]: (s, m) => start(s, m.runId, m.at),
|
|
1414
|
+
[MsgType.AgentToolOk]: (s, m) => toolOk(s, m.callId, m.result, m.at),
|
|
1415
|
+
// `agent_tool_err` is `createAgent`'s own raw settle Msg and its wire
|
|
1416
|
+
// shape is a bare `reason` string — a consumer routing their own interpret
|
|
1417
|
+
// through it never declared a tag, so the failure it mints carries none.
|
|
1418
|
+
[MsgType.AgentToolErr]: (s, m) => toolErr(s, m.callId, m.reason, m.at),
|
|
1419
|
+
// The re-entered brain-call settle Msgs (from `brainHandlers`): success
|
|
1420
|
+
// runs `succeed` (reset retry + fold the turn), failure runs `fail`.
|
|
1421
|
+
[MsgType.ResilientOk]: (s, m) => succeed(s, m.key, m, m.at),
|
|
1422
|
+
[MsgType.ResilientErr]: (s, m) => fail(s, m.key, m, m.at),
|
|
1423
|
+
// The re-entered compaction settle Msgs (from the consumer's `compact_run`
|
|
1424
|
+
// cell, #85): `compact_ok` folds the summary back (drop oldest turns +
|
|
1425
|
+
// their records, fire the next brain call), `compact_err` backs off via the
|
|
1426
|
+
// compaction retry or proceeds without compacting.
|
|
1427
|
+
[MsgType.CompactOk]: (s, m) => compactOk(s, m.key, m, m.at),
|
|
1428
|
+
[MsgType.CompactErr]: (s, m) => compactErr(s, m.key, m, m.at),
|
|
1429
|
+
deadline_exceeded: (s, m) => onTimer(s, m),
|
|
1430
|
+
[MsgType.AgentBoot]: (s, m) => boot(s, m.at),
|
|
1431
|
+
[MsgType.AgentCancel]: (s, m) => cancel(s, m.at)
|
|
1432
|
+
};
|
|
1433
|
+
const update = { ...ownUpdate, ...toolCells };
|
|
1434
|
+
const machine = {
|
|
1435
|
+
init: (loaded) => loaded !== null ? [loaded, []] : [init(), []],
|
|
1436
|
+
update,
|
|
1437
|
+
subscriptions: (s) => subs(s),
|
|
1438
|
+
subscribe: { deadline: subscribeDeadline },
|
|
1439
|
+
interpret,
|
|
1440
|
+
...tools !== void 0 ? { cmds: tools.defs } : {}
|
|
1441
|
+
};
|
|
1442
|
+
return defineMachine(machine);
|
|
1443
|
+
}
|
|
1444
|
+
return {
|
|
1445
|
+
init,
|
|
1446
|
+
start,
|
|
1447
|
+
turn,
|
|
1448
|
+
toolOk,
|
|
1449
|
+
toolErr,
|
|
1450
|
+
succeed,
|
|
1451
|
+
fail,
|
|
1452
|
+
compactOk,
|
|
1453
|
+
compactErr,
|
|
1454
|
+
onTimer,
|
|
1455
|
+
boot,
|
|
1456
|
+
isSettled,
|
|
1457
|
+
currentStage,
|
|
1458
|
+
brainCall,
|
|
1459
|
+
subs,
|
|
1460
|
+
// `toMachine` is THE wired path. `unsafeDetachedHandlers` is the
|
|
1461
|
+
// hand-wiring escape hatch — named to advertise the retry-loop gap so it is
|
|
1462
|
+
// never mistaken for the loop driver (#54).
|
|
1463
|
+
toMachine,
|
|
1464
|
+
unsafeDetachedHandlers
|
|
1465
|
+
};
|
|
1466
|
+
}
|
|
1467
|
+
|
|
1468
|
+
export { COMPACTION_PURPOSE, PLAIN_MODEL_MISROUTE_REASON, TOOL_RETRY_EXHAUSTED_TAG, TOOL_TIMEOUT_TAG, agentBootMsg, agentCancelMsg, agentEvents, agentTurnSchema, compactionSummarySchema, createAgent, defineAgent, fanOutInterpret, isAgentTurn, isCompactionSummary, isReservedToolName, isStreamingModel, liftAgent, mergeInterpret, plainModel, renderPrompt, status, tool, toolErrorReason, toolRouter, transcript };
|
|
1469
|
+
//# sourceMappingURL=chunk-Z2L3LSNV.js.map
|
|
1470
|
+
//# sourceMappingURL=chunk-Z2L3LSNV.js.map
|