@earendil-works/pi-agent-core 0.87.1 → 0.99.1
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 +4 -0
- package/dist/agent-loop.d.ts +27 -2
- package/dist/agent-loop.d.ts.map +1 -1
- package/dist/agent-loop.js +44 -15
- package/dist/agent-loop.js.map +1 -1
- package/dist/agent.d.ts +9 -0
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +3 -0
- package/dist/agent.js.map +1 -1
- package/dist/harness/agent-harness.d.ts.map +1 -1
- package/dist/harness/compaction/branch-summarization.d.ts.map +1 -1
- package/dist/harness/compaction/branch-summarization.js.map +1 -1
- package/dist/harness/compaction/compaction.d.ts.map +1 -1
- package/dist/harness/compaction/compaction.js.map +1 -1
- package/dist/harness/compaction/utils.d.ts.map +1 -1
- package/dist/harness/compaction/utils.js.map +1 -1
- package/dist/harness/config.d.ts.map +1 -1
- package/dist/harness/config.js.map +1 -1
- package/dist/harness/context.d.ts.map +1 -1
- package/dist/harness/context.js.map +1 -1
- package/dist/harness/env/nodejs.d.ts.map +1 -1
- package/dist/harness/env/nodejs.js.map +1 -1
- package/dist/harness/events.d.ts.map +1 -1
- package/dist/harness/events.js.map +1 -1
- package/dist/harness/execution/assistant.d.ts.map +1 -1
- package/dist/harness/execution/assistant.js.map +1 -1
- package/dist/harness/execution/effect-gate.d.ts.map +1 -1
- package/dist/harness/execution/effect-gate.js.map +1 -1
- package/dist/harness/execution/tools.d.ts.map +1 -1
- package/dist/harness/execution/tools.js.map +1 -1
- package/dist/harness/hooks.d.ts.map +1 -1
- package/dist/harness/hooks.js.map +1 -1
- package/dist/harness/messages.d.ts.map +1 -1
- package/dist/harness/messages.js.map +1 -1
- package/dist/harness/pico3/bash.d.ts.map +1 -1
- package/dist/harness/pico3/bash.js.map +1 -1
- package/dist/harness/pico3/bounded.d.ts.map +1 -1
- package/dist/harness/pico3/bounded.js.map +1 -1
- package/dist/harness/pico3/chord.d.ts.map +1 -1
- package/dist/harness/pico3/chord.js.map +1 -1
- package/dist/harness/pico3/context.d.ts.map +1 -1
- package/dist/harness/pico3/context.js.map +1 -1
- package/dist/harness/pico3/harness.d.ts +4 -3
- package/dist/harness/pico3/harness.d.ts.map +1 -1
- package/dist/harness/pico3/harness.js.map +1 -1
- package/dist/harness/pico3/hooks.d.ts +2 -2
- package/dist/harness/pico3/hooks.d.ts.map +1 -1
- package/dist/harness/pico3/hooks.js.map +1 -1
- package/dist/harness/pico3/index.d.ts.map +1 -1
- package/dist/harness/pico3/jsonl.d.ts.map +1 -1
- package/dist/harness/pico3/jsonl.js.map +1 -1
- package/dist/harness/pico3/kinds/collapse.d.ts.map +1 -1
- package/dist/harness/pico3/kinds/collapse.js.map +1 -1
- package/dist/harness/pico3/kinds/entries.d.ts.map +1 -1
- package/dist/harness/pico3/kinds/frames.d.ts.map +1 -1
- package/dist/harness/pico3/kinds/frames.js.map +1 -1
- package/dist/harness/pico3/kinds/generation.d.ts.map +1 -1
- package/dist/harness/pico3/kinds/generation.js.map +1 -1
- package/dist/harness/pico3/kinds/job.d.ts.map +1 -1
- package/dist/harness/pico3/kinds/job.js.map +1 -1
- package/dist/harness/pico3/kinds/plugin.d.ts.map +1 -1
- package/dist/harness/pico3/kinds/plugin.js.map +1 -1
- package/dist/harness/pico3/kinds/post-tools.d.ts.map +1 -1
- package/dist/harness/pico3/kinds/post-tools.js.map +1 -1
- package/dist/harness/pico3/kinds/task-api.d.ts.map +1 -1
- package/dist/harness/pico3/kinds/task-api.js.map +1 -1
- package/dist/harness/pico3/kinds/tool.d.ts.map +1 -1
- package/dist/harness/pico3/kinds/tool.js.map +1 -1
- package/dist/harness/pico3/legacy-tracker.d.ts +11 -0
- package/dist/harness/pico3/legacy-tracker.d.ts.map +1 -0
- package/dist/harness/pico3/legacy-tracker.js +41 -0
- package/dist/harness/pico3/legacy-tracker.js.map +1 -0
- package/dist/harness/pico3/membrane.d.ts.map +1 -1
- package/dist/harness/pico3/membrane.js.map +1 -1
- package/dist/harness/pico3/memory.d.ts +1 -1
- package/dist/harness/pico3/memory.d.ts.map +1 -1
- package/dist/harness/pico3/memory.js.map +1 -1
- package/dist/harness/pico3/scheduler.d.ts +3 -0
- package/dist/harness/pico3/scheduler.d.ts.map +1 -1
- package/dist/harness/pico3/scheduler.js.map +1 -1
- package/dist/harness/pico3/session.d.ts +3 -2
- package/dist/harness/pico3/session.d.ts.map +1 -1
- package/dist/harness/pico3/session.js +5 -4
- package/dist/harness/pico3/session.js.map +1 -1
- package/dist/harness/pico3/system.d.ts +1 -1
- package/dist/harness/pico3/system.d.ts.map +1 -1
- package/dist/harness/pico3/system.js.map +1 -1
- package/dist/harness/pico3/types.d.ts +1 -1
- package/dist/harness/pico3/types.d.ts.map +1 -1
- package/dist/harness/pico3/types.js.map +1 -1
- package/dist/harness/pico3/view.d.ts.map +1 -1
- package/dist/harness/pico3/view.js +6 -12
- package/dist/harness/pico3/view.js.map +1 -1
- package/dist/harness/prompt-templates.d.ts.map +1 -1
- package/dist/harness/prompt-templates.js.map +1 -1
- package/dist/harness/result.d.ts.map +1 -1
- package/dist/harness/result.js.map +1 -1
- package/dist/harness/runtime/drive/boundary.d.ts.map +1 -1
- package/dist/harness/runtime/drive/boundary.js.map +1 -1
- package/dist/harness/runtime/drive/checkpoint.d.ts.map +1 -1
- package/dist/harness/runtime/drive/checkpoint.js.map +1 -1
- package/dist/harness/runtime/drive/deferred.d.ts.map +1 -1
- package/dist/harness/runtime/drive/deferred.js.map +1 -1
- package/dist/harness/runtime/drive/generation.d.ts.map +1 -1
- package/dist/harness/runtime/drive/generation.js.map +1 -1
- package/dist/harness/runtime/drive/reconcile.d.ts.map +1 -1
- package/dist/harness/runtime/drive/reconcile.js.map +1 -1
- package/dist/harness/runtime/drive/recovery.d.ts.map +1 -1
- package/dist/harness/runtime/drive/recovery.js.map +1 -1
- package/dist/harness/runtime/drive/response.d.ts.map +1 -1
- package/dist/harness/runtime/drive/response.js.map +1 -1
- package/dist/harness/runtime/drive/retry.d.ts.map +1 -1
- package/dist/harness/runtime/drive/retry.js.map +1 -1
- package/dist/harness/runtime/drive/structural.d.ts.map +1 -1
- package/dist/harness/runtime/drive/structural.js.map +1 -1
- package/dist/harness/runtime/drive/terminal.d.ts.map +1 -1
- package/dist/harness/runtime/drive/terminal.js.map +1 -1
- package/dist/harness/runtime/drive/tool-placement.d.ts.map +1 -1
- package/dist/harness/runtime/drive/tool-placement.js.map +1 -1
- package/dist/harness/runtime/drive/tools.d.ts.map +1 -1
- package/dist/harness/runtime/drive/tools.js.map +1 -1
- package/dist/harness/runtime/drive.d.ts.map +1 -1
- package/dist/harness/runtime/drive.js.map +1 -1
- package/dist/harness/runtime/harness.d.ts.map +1 -1
- package/dist/harness/runtime/harness.js.map +1 -1
- package/dist/harness/runtime/index.d.ts.map +1 -1
- package/dist/harness/runtime/lane.d.ts +17 -0
- package/dist/harness/runtime/lane.d.ts.map +1 -1
- package/dist/harness/runtime/lane.js.map +1 -1
- package/dist/harness/runtime/progress.d.ts.map +1 -1
- package/dist/harness/runtime/progress.js.map +1 -1
- package/dist/harness/runtime/reducer.d.ts.map +1 -1
- package/dist/harness/runtime/reducer.js.map +1 -1
- package/dist/harness/runtime/restore.d.ts.map +1 -1
- package/dist/harness/runtime/restore.js.map +1 -1
- package/dist/harness/runtime/transcript.d.ts.map +1 -1
- package/dist/harness/runtime/transcript.js.map +1 -1
- package/dist/harness/runtime/types.d.ts.map +1 -1
- package/dist/harness/runtime/types.js.map +1 -1
- package/dist/harness/session/commit.d.ts.map +1 -1
- package/dist/harness/session/commit.js.map +1 -1
- package/dist/harness/session/context.d.ts.map +1 -1
- package/dist/harness/session/context.js.map +1 -1
- package/dist/harness/session/fork-policy.d.ts.map +1 -1
- package/dist/harness/session/fork-policy.js.map +1 -1
- package/dist/harness/session/fork.d.ts.map +1 -1
- package/dist/harness/session/fork.js.map +1 -1
- package/dist/harness/session/in-memory-storage-state.d.ts.map +1 -1
- package/dist/harness/session/in-memory-storage-state.js.map +1 -1
- package/dist/harness/session/index.d.ts.map +1 -1
- package/dist/harness/session/jsonl/codec.d.ts.map +1 -1
- package/dist/harness/session/jsonl/codec.js.map +1 -1
- package/dist/harness/session/jsonl/fork.d.ts.map +1 -1
- package/dist/harness/session/jsonl/fork.js.map +1 -1
- package/dist/harness/session/jsonl/index.d.ts.map +1 -1
- package/dist/harness/session/jsonl/io.d.ts.map +1 -1
- package/dist/harness/session/jsonl/io.js.map +1 -1
- package/dist/harness/session/jsonl/legacy-v3.d.ts +1 -0
- package/dist/harness/session/jsonl/legacy-v3.d.ts.map +1 -1
- package/dist/harness/session/jsonl/legacy-v3.js.map +1 -1
- package/dist/harness/session/jsonl/repo.d.ts.map +1 -1
- package/dist/harness/session/jsonl/repo.js.map +1 -1
- package/dist/harness/session/jsonl/storage.d.ts +1 -0
- package/dist/harness/session/jsonl/storage.d.ts.map +1 -1
- package/dist/harness/session/jsonl/storage.js.map +1 -1
- package/dist/harness/session/jsonl/types.d.ts.map +1 -1
- package/dist/harness/session/memory.d.ts.map +1 -1
- package/dist/harness/session/memory.js.map +1 -1
- package/dist/harness/session/mutation-line.d.ts.map +1 -1
- package/dist/harness/session/mutation-line.js.map +1 -1
- package/dist/harness/session/session.d.ts.map +1 -1
- package/dist/harness/session/session.js.map +1 -1
- package/dist/harness/session/testing/benchmark/datasets.d.ts.map +1 -1
- package/dist/harness/session/testing/benchmark/datasets.js.map +1 -1
- package/dist/harness/session/testing/benchmark/session-repo.d.ts.map +1 -1
- package/dist/harness/session/testing/benchmark/session-repo.js.map +1 -1
- package/dist/harness/session/testing/benchmark/storage.d.ts.map +1 -1
- package/dist/harness/session/testing/benchmark/storage.js.map +1 -1
- package/dist/harness/session/testing/conformance/session-repo.d.ts.map +1 -1
- package/dist/harness/session/testing/conformance/session-repo.js.map +1 -1
- package/dist/harness/session/testing/conformance/storage.d.ts.map +1 -1
- package/dist/harness/session/testing/conformance/storage.js.map +1 -1
- package/dist/harness/session/testing/gating-storage.d.ts.map +1 -1
- package/dist/harness/session/testing/gating-storage.js.map +1 -1
- package/dist/harness/session/testing/index.d.ts.map +1 -1
- package/dist/harness/session/testing/instrumented-storage.d.ts.map +1 -1
- package/dist/harness/session/testing/instrumented-storage.js.map +1 -1
- package/dist/harness/session/testing/storage-decorator.d.ts.map +1 -1
- package/dist/harness/session/testing/storage-decorator.js.map +1 -1
- package/dist/harness/session/testing/types.d.ts.map +1 -1
- package/dist/harness/session/types.d.ts.map +1 -1
- package/dist/harness/session/types.js.map +1 -1
- package/dist/harness/session/values.d.ts +2 -2
- package/dist/harness/session/values.d.ts.map +1 -1
- package/dist/harness/session/values.js.map +1 -1
- package/dist/harness/skills.d.ts.map +1 -1
- package/dist/harness/skills.js.map +1 -1
- package/dist/harness/system-prompt.d.ts.map +1 -1
- package/dist/harness/system-prompt.js.map +1 -1
- package/dist/harness/telemetry.d.ts.map +1 -1
- package/dist/harness/telemetry.js.map +1 -1
- package/dist/harness/tools/bash.d.ts.map +1 -1
- package/dist/harness/tools/bash.js.map +1 -1
- package/dist/harness/tools/edit-diff.d.ts.map +1 -1
- package/dist/harness/tools/edit-diff.js.map +1 -1
- package/dist/harness/tools/edit.d.ts.map +1 -1
- package/dist/harness/tools/edit.js.map +1 -1
- package/dist/harness/tools/file-mutation-queue.d.ts.map +1 -1
- package/dist/harness/tools/file-mutation-queue.js.map +1 -1
- package/dist/harness/tools/image.d.ts.map +1 -1
- package/dist/harness/tools/image.js.map +1 -1
- package/dist/harness/tools/index.d.ts.map +1 -1
- package/dist/harness/tools/path-utils.d.ts.map +1 -1
- package/dist/harness/tools/path-utils.js.map +1 -1
- package/dist/harness/tools/read.d.ts.map +1 -1
- package/dist/harness/tools/read.js.map +1 -1
- package/dist/harness/tools/tool-context.d.ts.map +1 -1
- package/dist/harness/tools/write.d.ts.map +1 -1
- package/dist/harness/tools/write.js.map +1 -1
- package/dist/harness/types.d.ts.map +1 -1
- package/dist/harness/types.js.map +1 -1
- package/dist/harness/utils/adaptive-publisher.d.ts.map +1 -1
- package/dist/harness/utils/adaptive-publisher.js.map +1 -1
- package/dist/harness/utils/output-capture.d.ts.map +1 -1
- package/dist/harness/utils/output-capture.js.map +1 -1
- package/dist/harness/utils/shell-output.d.ts.map +1 -1
- package/dist/harness/utils/shell-output.js.map +1 -1
- package/dist/harness/utils/truncate.d.ts.map +1 -1
- package/dist/harness/utils/truncate.js.map +1 -1
- package/dist/harness/utils/usage.d.ts.map +1 -1
- package/dist/harness/utils/usage.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/node.d.ts.map +1 -1
- package/dist/proxy.d.ts.map +1 -1
- package/dist/proxy.js.map +1 -1
- package/dist/search/index.d.ts.map +1 -1
- package/dist/stream-fn.d.ts.map +1 -1
- package/dist/stream-fn.js.map +1 -1
- package/dist/types.d.ts +30 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +9 -10
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool.js","sourceRoot":"","sources":["../../../../src/harness/pico3/kinds/tool.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAoBN,QAAQ,GACR,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAgCxC,MAAM,SAAS,GAAG,CAAC,IAAY,EAAE,IAAY,EAAc,EAAE,CAAC,CAAC;IAC9D,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IACjC,OAAO,EAAE,IAAI;IACb,WAAW,EAAE,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;CACzD,CAAC,CAAC;AACH,oEAAoE;AACpE,MAAM,UAAU,OAAO,CAAC,WAA+B,EAAE,IAAoB,EAAsB;IAClG,MAAM,MAAM,GAAG,CAAC,GAAG,MAAM,CAAC,WAAW,CAAC,UAAqB,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;IAC9E,OAAO,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,YAAY,IAAI,GAAG,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAAA,CAChH;AACD,MAAM,YAAY,GAAG,CAAC,CAAiB,EAAE,CAAiB,EAAE,EAAE,CAC7D,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,SAAS,CAAC;AAEnE,MAAM,CAAC,MAAM,IAAI,GAAyF;IACzG,IAAI,EAAE,SAAS;IACf,IAAI,EAAE,IAAI;IACV,QAAQ,EAAE,CAAC,SAAS,CAAC;IAErB,wFAAwF;IACxF,sFAAsF;IACtF,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,EAAE,GAAG,EAAE;QAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;QAC7B,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC;YAC1C,OAAO;gBACN,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,SAAS,CAAC,QAAQ,IAAI,CAAC,IAAI,kBAAkB,EAAE,aAAa,CAAC,EAAE,SAAS,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC;aACrG,CAAC;QACH,MAAM,WAAW,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5C,IAAI,WAAW,KAAK,SAAS;YAC5B,OAAO;gBACN,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,SAAS,CAAC,QAAQ,IAAI,CAAC,IAAI,oBAAoB,EAAE,cAAc,CAAC,EAAE,SAAS,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC;aACxG,CAAC;QACH,MAAM,GAAG,GAAG,OAAO,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;QACvC,IAAI,GAAG,KAAK,SAAS;YACpB,OAAO;gBACN,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,SAAS,CAAC,sBAAsB,GAAG,EAAE,EAAE,mBAAmB,CAAC,EAAE,WAAW,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC;aACrG,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;QACrD,IAAI,OAAO,IAAI,MAAM;YACpB,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,SAAS,CAAC,YAAY,MAAM,CAAC,KAAK,EAAE,EAAE,SAAS,CAAC,EAAE,WAAW,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC;QACvG,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC;YACnC,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,SAAS,CAAC,gCAAgC,EAAE,SAAS,CAAC,EAAE,WAAW,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC;QAC7G,MAAM,QAAQ,GAAG,OAAO,CAAC,WAAW,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;QACnD,IAAI,QAAQ,KAAK,SAAS;YACzB,OAAO;gBACN,IAAI,EAAE,KAAK,CACV,IAAI,EACJ,SAAS,CAAC,iCAAiC,QAAQ,EAAE,EAAE,mBAAmB,CAAC,EAC3E,WAAW,EACX,EAAE,CAAC,GAAG,EAAE,CACR;aACD,CAAC;QACH,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACpC,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC;YACvB,EAAE,CAAC,UAAU,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,CAAC,MAAM,IAAI,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;YACzF,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YAC/B,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC;YACxB,OAAO,IAAI,CAAC,SAAS,CAAC;YACtB,EAAE,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;QAAA,CACvF,EAAE,GAAG,CAAC,CAAC,CAAC,4BAA4B;QACrC,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,CAAC;IAAA,CACjE;IAED,MAAM,EAAE;QACP,8GAA8G;QAC9G,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,EAAE,GAAG,EAAE;YAC5B,MAAM,EAAE,GAAG,IAAI,CAAC,UAAU,CAAC;YAC3B,MAAM,WAAW,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC/C,IAAI,WAAW,KAAK,SAAS;gBAC5B,OAAO;oBACN,IAAI,EAAE,KAAK,CACV,IAAI,EACJ,SAAS,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,IAAI,4BAA4B,EAAE,aAAa,CAAC,EAC1E,SAAS,EACT,EAAE,CAAC,GAAG,EAAE,EACR,EAAE,CAAC,IAAI,CACP;iBACD,CAAC;YACH,IAAI,EAAE,CAAC,MAAM,KAAK,MAAM,IAAI,CAAC,WAAW,CAAC,MAAM,IAAI,QAAQ,CAAC,KAAK,MAAM;gBACtE,OAAO;oBACN,IAAI,EAAE,KAAK,CACV,IAAI,EACJ,SAAS,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,IAAI,kBAAkB,EAAE,aAAa,CAAC,EAChE,WAAW,EACX,EAAE,CAAC,GAAG,EAAE,EACR,EAAE,CAAC,IAAI,CACP;iBACD,CAAC;YACH,IAAI,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,SAAS;gBAC9C,OAAO;oBACN,IAAI,EAAE,KAAK,CACV,IAAI,EACJ,SAAS,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,IAAI,gDAAgD,EAAE,aAAa,CAAC,EAC9F,WAAW,EACX,EAAE,CAAC,GAAG,EAAE,EACR,EAAE,CAAC,IAAI,CACP;iBACD,CAAC;YACH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,CAAC;QAAA,CACnE;KACD;IAED,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,EAAE,GAAG,EAAE;QAC1B,KAAK,MAAM,cAAc,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACxC,MAAM,QAAQ,GAAG,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,cAAc,EAAE,MAAM,EAAE,CAAC,SAAS,EAAE,SAAS,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC;YAC5G,KAAK,MAAM,KAAK,IAAI,QAAQ;gBAAE,IAAI,CAAC,KAAK,CAAC,UAAU;oBAAE,MAAM,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;QACxF,CAAC;QACD,OAAO,CAAC,EAAE,EAAE,OAAO,EAAE,EAAE,CAAC;YACvB,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;YACtD,MAAM,KAAK,GAAG,EAAE,CAAC,WAAW,CAAC,OAAO,CAAC,cAAc,EAAE;gBACpD,IAAI,EAAE,gBAAgB;gBACtB,KAAK,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,SAAS,CAAC,cAAc,EAAE,SAAS,CAAC,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC;gBACxE,IAAI,EAAE,EAAE,WAAW,EAAE,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,EAAE;aACnF,CAAC,CAAC;YACH,MAAM,IAAI,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAC5E,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;gBACxB,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC;gBACxB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;gBACnB,OAAO,IAAI,CAAC,SAAS,CAAC;YACvB,CAAC;YACD,EAAE,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;YAC9E,OAAO,EAAE,KAAK,EAAE,CAAC;QAAA,CACjB,CAAC;IAAA,CACF;CACD,CAAC;AAEF,+EAA+E;AAC/E,KAAK,UAAU,UAAU,CACxB,IAAO,EACP,EAAM,EACN,IAAoB,EACpB,GAAY,EAC4C;IACxD,IAAI,OAAO,GAAG,IAAI,CAAC;IACnB,KAAK,MAAM,OAAO,IAAI,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE,CAAC;QAG3C,SAAS,IAAI,CACZ,IAAY,EACZ,kBAA+B,EAC/B,OAAiB,EACQ;YACzB,MAAM,aAAa,GAAG,OAAO,IAAK,kBAA8B,CAAC;YACjE,OAAO,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC;gBACxB,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;gBAC9B,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;gBAC/B,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC;oBAAE,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;gBACnD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAM,CAAC;gBAC1B,MAAM,GAAG,GAAG,QAAQ,OAAO,CAAC,SAAS,CAAC,EAAE,IAAI,IAAI,EAAE,CAAC;gBACnD,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC;oBAAE,OAAO,eAAe,CAAC,KAAK,CAAC,GAAG,CAAC,CAAM,CAAC;gBACvE,IAAI,OAAO,KAAK,SAAS;oBAAE,OAAO,SAAS,CAAC;gBAC5C,MAAM,SAAS,GAAG,eAAe,CAAC,kBAAuB,CAAC,CAAC;gBAC3D,KAAK,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC;gBACvB,OAAO,SAAS,CAAC;YAAA,CACjB,EAAE,aAAa,CAAC,CAAC;QAAA,CAClB;QACD,MAAM,GAAG,GAAkB;YAC1B,GAAG,OAAO,CAAC,GAAG;YACd,MAAM,EAAE,IAAI,CAAC,EAAE;YACf,OAAO,EAAE,CAAC,OAAO,EAAE,EAAE,CACpB,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,WAAW,EAAE,EAAE,CAAC;gBAC9B,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;gBAC9B,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,WAAgB,CAAC,CAAC;gBAC3C,IAAI,IAAI,CAAC,SAAS,KAAK,OAAO,CAAC,SAAS,CAAC,EAAE;oBAAE,OAAO;gBACpD,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;gBACtC,EAAE,CAAC,IAAI,CAAC;oBACP,IAAI,EAAE,cAAc;oBACpB,MAAM,EAAE,WAAW,CAAC,EAAE;oBACtB,MAAM,EAAE,IAAI,CAAC,EAAE;oBACf,EAAE,EAAE,OAAO,CAAC,SAAS,CAAC,EAAE;iBACxB,CAAC,CAAC;YAAA,CACH,EAAE,OAAO,CAAC;YACZ,IAAI;YACJ,IAAI,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,OAAO,CAAC;SACjG,CAAC;QACF,IAAI,CAAC;YACJ,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;YACrE,IAAI,CAAC,KAAK;gBAAE,SAAS;YACrB,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS;gBAAE,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC;YAC7D,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS;gBAAE,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC;QACpD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,IAAI,GAAG,CAAC,WAAW,EAAE,OAAO;gBAAE,MAAM,KAAK,CAAC;YAC1C,OAAO,EAAE,KAAK,EAAE,eAAe,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC;QAClD,CAAC;IACF,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;AAAA,CACzB;AAED,MAAM,CAAC,MAAM,cAAc,GAAG,EAAE,QAAQ,EAAE,EAAE,GAAG,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,EAAE,MAAe,EAAE,CAAC;AAE9F,KAAK,UAAU,MAAM,CACpB,IAAO,EACP,IAAoB,EACpB,WAA+B,EAC/B,EAAM,EACN,GAAY,EACG;IACf,kHAAkH;IAClH,MAAM,CAAC,GAAG,EAAE,GAAG,cAAc,EAAE,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC;IACvD,MAAM,MAAM,GAAG,IAAI,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;IAC7D,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,IAAI,QAAQ,GAAkB,OAAO,CAAC,OAAO,EAAE,CAAC;IAChD,IAAI,UAAmB,CAAC;IACxB,MAAM,KAAK,GAAG,GAAG,EAAE,CAAC;QACnB,SAAS,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC;QACrB,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;QAC3B,QAAQ,GAAG,QAAQ;aACjB,IAAI,CAAC,GAAG,EAAE,CACV,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC;YACjB,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,IAAI,CAAC;QAAA,CAChC,EAAE,GAAG,CAAC,CACP;aACA,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;YACb,UAAU,KAAK,CAAC,CAAC;QAAA,CACjB,CAAC,CAAC;IAAA,CACJ,CAAC;IACF,MAAM,GAAG,GAAG;QACX,GAAG,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;QACpB,yEAAyE;QACzE,QAAQ,EAAE,CAAC,MAA8E,EAAE,CAAU,EAAE,EAAE,CACxG,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YAC/B,MAAM,IAAI,GAA2D;gBACpE,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,WAAW,EAAE,IAAI,CAAC,WAAW;aAC7B,CAAC;YACF,MAAM,CAAC,IAAI,CAAC,CAAC;YACb,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS;gBAAE,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;;gBAC1D,OAAO,IAAI,CAAC,QAAQ,CAAC;YAC1B,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS;gBAAE,IAAI,CAAC,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;;gBACjE,OAAO,IAAI,CAAC,OAAO,CAAC;YACzB,IAAI,IAAI,CAAC,WAAW,KAAK,SAAS;gBAAE,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC;;gBACnE,OAAO,IAAI,CAAC,WAAW,CAAC;QAAA,CAC7B,EAAE,CAAC,CAAC;QACN,MAAM,CAAC,KAA0B,EAAE;YAClC,QAAQ,GAAG,IAAI,CAAC;YAChB,MAAM,CAAC,IAAI,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;YACjF,IAAI,EAAE,CAAC,GAAG,EAAE,GAAG,SAAS,IAAI,GAAG;gBAAE,KAAK,EAAE,CAAC;QAAA,CACzC;KACD,CAAC;IAGF,SAAS,IAAI,CACZ,IAAY,EACZ,kBAA+B,EAC/B,OAAiB,EACQ;QACzB,MAAM,aAAa,GAAG,OAAO,IAAK,kBAA8B,CAAC;QACjE,OAAO,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC;YACxB,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YAC/B,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC;gBAAE,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;YACnD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAM,CAAC;YAC1B,MAAM,GAAG,GAAG,QAAQ,IAAI,EAAE,CAAC;YAC3B,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC;gBAAE,OAAO,eAAe,CAAC,KAAK,CAAC,GAAG,CAAC,CAAM,CAAC;YACvE,IAAI,OAAO,KAAK,SAAS;gBAAE,OAAO,SAAS,CAAC;YAC5C,MAAM,SAAS,GAAG,eAAe,CAAC,kBAAuB,CAAC,CAAC;YAC3D,KAAK,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC;YACvB,OAAO,SAAS,CAAC;QAAA,CACjB,EAAE,aAAa,CAAC,CAAC;IAAA,CAClB;IACD,MAAM,OAAO,GAAkD,EAAE,GAAG,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC;IACjG,IAAI,MAAkB,CAAC;IACvB,IAAI,CAAC;QACJ,MAAM,GAAG,MAAM,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,SAAkB,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC;IAC3E,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,IAAI,GAAG,CAAC,WAAW,EAAE,OAAO;YAAE,MAAM,KAAK,CAAC;QAC1C,MAAM,GAAG,SAAS,CAAC,eAAe,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;IAC7D,CAAC;IACD,IAAI,QAAQ,EAAE,CAAC;QACd,KAAK,EAAE,CAAC;QACR,MAAM,QAAQ,CAAC;QACf,IAAI,UAAU,KAAK,SAAS;YAAE,MAAM,UAAU,CAAC,CAAC,wCAAwC;QACxF,IAAI,MAAM,CAAC,OAAO,KAAK,SAAS;YAC/B,MAAM,GAAG;gBACR,GAAG,MAAM;gBACT,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;gBAChD,GAAG,CAAC,MAAM,CAAC,OAAO;oBACjB,CAAC,CAAC;wBACA,WAAW,EAAE;4BACZ,GAAG,CAAC,MAAM,CAAC,WAAW,IAAI,EAAE,CAAC;4BAC7B;gCACC,QAAQ,EAAE,MAAe;gCACzB,IAAI,EAAE,WAAW;gCACjB,OAAO,EAAE,GAAG,MAAM,CAAC,YAAY,YAAY,MAAM,CAAC,YAAY,mBAAmB,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,QAAQ,YAAY;6BACnH;yBACD;qBACD;oBACF,CAAC,CAAC,EAAE,CAAC;aACN,CAAC;IACJ,CAAC;IACD,IAAI,KAAK,GAAG,MAAM,CAAC;IACnB,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAClB,GAAG,EACH,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,GAAG,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,EAAE,GAAG,CAAC,EACxE,CAAC,KAAK,EAAE,EAAE,CAAC;QACV,IAAI,KAAK,KAAK,SAAS;YAAE,KAAK,GAAG,KAAK,CAAC;IAAA,CACvC,CACD,CAAC;IACF,OAAO,KAAK,CACX,IAAI,EACJ,KAAK,EACL,WAAW,EACX,EAAE,CAAC,GAAG,EAAE,EACR,IAAI,EACJ,QAAQ,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,YAAY,EAAE,KAAK,EAAE,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,SAAS,CACjF,CAAC;AAAA,CACF;AAED,sHAAsH;AACtH,SAAS,KAAK,CACb,IAAO,EACP,GAAe,EACf,WAA2C,EAC3C,GAAW,EACX,IAAI,GAAmB,IAAI,CAAC,KAAK,CAAC,IAAI,EACtC,eAAkD,EAC5C;IACN,OAAO,CAAC,EAAE,EAAE,OAAO,EAAE,EAAE,CAAC;QACvB,MAAM,OAAO,GAAG,KAAK,CAAC,EAAE,GAAG,GAAG,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,IAAI,EAAE,EAAE,EAAE,WAAW,EAAE,MAAM,CAAC,CAAC;QACnF,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;QAC9B,MAAM,KAAK,GAAG,CAAC,OAAO,CAAC,SAAS,EAAE,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC,eAAe,EAAE,KAAK,IAAI,CAAC,CAAC,CAAC;QAC9E,MAAM,KAAK,GAAG,CAAC,OAAO,CAAC,SAAS,EAAE,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC,eAAe,EAAE,KAAK,IAAI,CAAC,CAAC,CAAC;QAC9E,MAAM,SAAS,GAAG,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;QACxE,MAAM,IAAI,GAAe,EAAE,CAAC;QAC5B,IAAI,MAAM,CAAC,OAAO,KAAK,SAAS;YAAE,IAAI,CAAC,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC1E,IAAI,MAAM,CAAC,WAAW,KAAK,SAAS;YAAE,IAAI,CAAC,WAAW,GAAG,QAAQ,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QACtF,IAAI,MAAM,CAAC,OAAO,KAAK,SAAS;YAAE,IAAI,CAAC,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC1E,IAAI,SAAS,KAAK,SAAS;YAAE,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QACxD,MAAM,KAAK,GAAG,EAAE,CAAC,WAAW,CAAC,OAAO,CAAC,cAAc,EAAE;YACpD,IAAI,EAAE,gBAAgB;YACtB,KAAK,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC;YACrC,IAAI;SACJ,CAAC,CAAC;QACH,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC/B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;QACzD,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,OAAO,IAAI,CAAC,SAAS,CAAC;QACtB,EAAE,CAAC,IAAI,CAAC;YACP,IAAI,EAAE,eAAe;YACrB,MAAM,EAAE,OAAO,CAAC,EAAE;YAClB,MAAM,EAAE,IAAI,CAAC,EAAE;YACf,KAAK;YACL,OAAO,EAAE,MAAM,CAAC,OAAO,KAAK,IAAI;YAChC,GAAG,CAAC,MAAM,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;SACpE,CAAC,CAAC;QACH,IAAI,SAAS,KAAK,SAAS;YAC1B,EAAE,CAAC,IAAI,CAAC;gBACP,IAAI,EAAE,SAAS;gBACf,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,0BAA0B,SAAS,CAAC,KAAK,YAAY,SAAS,CAAC,KAAK,gBAAgB;aAC7F,CAAC,CAAC;QACJ,MAAM,UAAU,GAAsC;YACrD,MAAM,EAAE,WAAW;YACnB,MAAM,EAAE,EAAE,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE;SACjG,CAAC;QACF,OAAO,UAAU,CAAC;IAAA,CAClB,CAAC;AAAA,CACF;AAED,SAAS,SAAS,CAAC,IAAoB,EAAE,MAAkB,EAAE,GAAW,EAAE;IACzE,OAAO,QAAQ,CAAC;QACf,IAAI,EAAE,YAAqB;QAC3B,UAAU,EAAE,IAAI,CAAC,EAAE;QACnB,QAAQ,EAAE,IAAI,CAAC,IAAI;QACnB,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,EAAE;QAC7B,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,KAAK;QAChC,SAAS,EAAE,GAAG;KACd,CAAC,CAAC;AAAA,CACH;AAED,SAAS,KAAK,CACb,MAAkB,EAClB,QAAsC,EACiC;IACvE,MAAM,MAAM,GAAG,EAAE,GAAG,cAAc,EAAE,GAAG,QAAQ,EAAE,CAAC;IAClD,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC;IACpC,IAAI,IAAI,GAAG,MAAM;SACf,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,MAAM,CAAC;SACxC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC;SAC1B,IAAI,CAAC,EAAE,CAAC,CAAC;IACX,IAAI,YAAY,GAAG,CAAC,CAAC;IACrB,IAAI,YAAY,GAAG,CAAC,CAAC;IACrB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC/B,IAAI,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;QACpC,YAAY,GAAG,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC;QAC9C,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAChH,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC7C,IAAI,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;QACpC,YAAY,GAAG,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC;QAC9C,IAAI,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAC9B,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAChG,CAAC;IACH,CAAC;IACD,IAAI,YAAY,KAAK,CAAC,IAAI,YAAY,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IAChE,IAAI,SAAS,GAAG,CAAC,CAAC,CAAC;IACnB,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;QACpD,IAAI,MAAM,CAAC,KAAK,CAAE,CAAC,IAAI,KAAK,MAAM;YAAE,SAAS;QAC7C,IAAI,MAAM,CAAC,MAAM,KAAK,MAAM,IAAI,SAAS,IAAI,CAAC;YAAE,SAAS;QACzD,SAAS,GAAG,KAAK,CAAC;IACnB,CAAC;IACD,MAAM,OAAO,GAAuC,EAAE,CAAC;IACvD,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;QACpD,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAE,CAAC;QAC7B,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM;YAAE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;aAC1C,IAAI,KAAK,KAAK,SAAS;YAAE,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAChE,CAAC;IACD,MAAM,IAAI,GAAG;QACZ,QAAQ,EAAE,MAAe;QACzB,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE,qBAAqB,YAAY,WAAW,YAAY,gBAAgB;KACjF,CAAC;IACF,OAAO;QACN,MAAM,EAAE,EAAE,GAAG,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE;QAClF,SAAS,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,YAAY,EAAE;KACvD,CAAC;AAAA,CACF","sourcesContent":["import type { Context } from \"@earendil-works/chord\";\nimport type { ToolCall } from \"@earendil-works/pi-ai\";\nimport type { TSchema } from \"typebox\";\nimport { Errors } from \"typebox/value\";\nimport { Bounded } from \"../bounded.ts\";\nimport {\n\ttype AnyToolDeclaration,\n\ttype BeforeToolApi,\n\ttype Closure,\n\ttype Completion,\n\ttype CoreKind,\n\ttype CoreTx,\n\ttype HookInfo,\n\ttype HookResult,\n\ttype Id,\n\ttype JsonObject,\n\ttype JsonValue,\n\ttype Runtime,\n\ttype Step,\n\ttype Stored,\n\ttype Task,\n\ttype ToolApi,\n\ttype ToolControl,\n\ttype ToolResult,\n\ttype ToolSlot,\n\ttoStored,\n} from \"../types.ts\";\nimport { taskApi } from \"./task-api.ts\";\n\nexport type StoredToolCall = Stored<ToolCall>;\nexport type ToolInput = {\n\tassistant: Id;\n\tcall: StoredToolCall;\n\toffered: string[];\n\tindex: number; // position of the call in the assistant message; also this tool's slot in sticky.turn.tools\n};\nexport type ToolCheckpoint = { phase: \"started\"; replay: \"safe\" | \"unsafe\"; call: StoredToolCall };\nexport type ToolTaskResult = { entry: Id; control?: ToolControl };\n/** Hook points this kind calls. Register with `h.hooks(namespace, kinds.tool, { … })`. */\nexport interface ToolHooks {\n\t/** Before invocation, before `started`. Chain on `call`; `{ block }` stops it. A throw blocks. */\n\tbeforeTool(\n\t\tcall: StoredToolCall,\n\t\tapi: BeforeToolApi,\n\t\tctx: Context,\n\t): HookResult<{ call?: StoredToolCall; block?: string }>;\n\t/** After the tool returns; may replace the result. Chain. */\n\tafterTool(\n\t\tcall: StoredToolCall,\n\t\tresult: ToolResult,\n\t\tapi: HookInfo & { readonly callId: string },\n\t\tctx: Context,\n\t): HookResult<ToolResult>;\n}\n\ntype T = Task<ToolInput, ToolCheckpoint>;\ntype Rt = Runtime<ToolHooks, CoreTx>;\ntype Out = Closure<ToolTaskResult, never, CoreTx>;\n\nconst synthetic = (text: string, code: string): ToolResult => ({\n\tcontent: [{ type: \"text\", text }],\n\tisError: true,\n\tdiagnostics: [{ severity: \"error\", message: text, code }],\n});\n/** Validate arguments with the tool's real schema (TypeBox 1.x). */\nexport function invalid(declaration: AnyToolDeclaration, call: StoredToolCall): string | undefined {\n\tconst errors = [...Errors(declaration.parameters as TSchema, call.arguments)];\n\treturn errors.length === 0 ? undefined : errors.map((e) => `${e.instancePath || \"/\"}: ${e.message}`).join(\"; \");\n}\nconst sameIdentity = (a: StoredToolCall, b: StoredToolCall) =>\n\ta.id === b.id && a.name === b.name && a.namespace === b.namespace;\n\nexport const tool: CoreKind<ToolInput, ToolCheckpoint, ToolTaskResult, never, { entry: Id }, ToolHooks> = {\n\tname: \"pi.tool\",\n\tturn: true,\n\tinflight: [\"started\"],\n\n\t// Offered-set check, lookup, validate, beforeTool, validate again; then write `started`\n\t// (the in-flight checkpoint) and invoke. A crash before `started` reruns all of this.\n\tasync initial(task, rt, ctx) {\n\t\tconst call = task.input.call;\n\t\tif (!task.input.offered.includes(call.name))\n\t\t\treturn {\n\t\t\t\tdone: close(task, synthetic(`tool ${call.name} was not offered`, \"not_offered\"), undefined, rt.now()),\n\t\t\t};\n\t\tconst declaration = rt.tools.get(call.name);\n\t\tif (declaration === undefined)\n\t\t\treturn {\n\t\t\t\tdone: close(task, synthetic(`tool ${call.name} is not registered`, \"missing_tool\"), undefined, rt.now()),\n\t\t\t};\n\t\tconst bad = invalid(declaration, call);\n\t\tif (bad !== undefined)\n\t\t\treturn {\n\t\t\t\tdone: close(task, synthetic(`invalid arguments: ${bad}`, \"invalid_arguments\"), declaration, rt.now()),\n\t\t\t};\n\t\tconst hooked = await beforeTool(task, rt, call, ctx);\n\t\tif (\"block\" in hooked)\n\t\t\treturn { done: close(task, synthetic(`blocked: ${hooked.block}`, \"blocked\"), declaration, rt.now()) };\n\t\tif (!sameIdentity(call, hooked.call))\n\t\t\treturn { done: close(task, synthetic(\"blocked: call identity changed\", \"blocked\"), declaration, rt.now()) };\n\t\tconst badFinal = invalid(declaration, hooked.call);\n\t\tif (badFinal !== undefined)\n\t\t\treturn {\n\t\t\t\tdone: close(\n\t\t\t\t\ttask,\n\t\t\t\t\tsynthetic(`invalid arguments after hook: ${badFinal}`, \"invalid_arguments\"),\n\t\t\t\t\tdeclaration,\n\t\t\t\t\trt.now(),\n\t\t\t\t),\n\t\t\t};\n\t\tconst final = toStored(hooked.call);\n\t\tawait rt.commit((tx) => {\n\t\t\ttx.checkpoint({ phase: \"started\", replay: declaration.replay ?? \"unsafe\", call: final });\n\t\t\tconst slot = tx.toolSlot(task);\n\t\t\tslot.status = \"running\";\n\t\t\tdelete slot.waitingOn;\n\t\t\ttx.emit({ type: \"tool.started\", taskId: task.id, callId: final.id, name: final.name });\n\t\t}, ctx); // durable before the effect\n\t\treturn { done: await invoke(task, final, declaration, rt, ctx) };\n\t},\n\n\tphases: {\n\t\t// Only entered by the scheduler after reopen. The stored final call is the evidence; beforeTool never reruns.\n\t\tasync started(task, rt, ctx) {\n\t\t\tconst cp = task.checkpoint;\n\t\t\tconst declaration = rt.tools.get(cp.call.name);\n\t\t\tif (declaration === undefined)\n\t\t\t\treturn {\n\t\t\t\t\tdone: close(\n\t\t\t\t\t\ttask,\n\t\t\t\t\t\tsynthetic(`tool ${cp.call.name} unavailable after restart`, \"unavailable\"),\n\t\t\t\t\t\tundefined,\n\t\t\t\t\t\trt.now(),\n\t\t\t\t\t\tcp.call,\n\t\t\t\t\t),\n\t\t\t\t};\n\t\t\tif (cp.replay !== \"safe\" || (declaration.replay ?? \"unsafe\") !== \"safe\")\n\t\t\t\treturn {\n\t\t\t\t\tdone: close(\n\t\t\t\t\t\ttask,\n\t\t\t\t\t\tsynthetic(`tool ${cp.call.name} was interrupted`, \"interrupted\"),\n\t\t\t\t\t\tdeclaration,\n\t\t\t\t\t\trt.now(),\n\t\t\t\t\t\tcp.call,\n\t\t\t\t\t),\n\t\t\t\t};\n\t\t\tif (invalid(declaration, cp.call) !== undefined)\n\t\t\t\treturn {\n\t\t\t\t\tdone: close(\n\t\t\t\t\t\ttask,\n\t\t\t\t\t\tsynthetic(`tool ${cp.call.name} was interrupted; arguments no longer validate`, \"interrupted\"),\n\t\t\t\t\t\tdeclaration,\n\t\t\t\t\t\trt.now(),\n\t\t\t\t\t\tcp.call,\n\t\t\t\t\t),\n\t\t\t\t};\n\t\t\treturn { done: await invoke(task, cp.call, declaration, rt, ctx) };\n\t\t},\n\t},\n\n\tasync abort(task, rt, ctx) {\n\t\tfor (const conversationId of task.owns) {\n\t\t\tconst children = await rt.commit((tx) => tx.tasks({ conversationId, status: [\"pending\", \"running\"] }), ctx);\n\t\t\tfor (const child of children) if (!child.background) await rt.abortTask(child.id, ctx);\n\t\t}\n\t\treturn (tx, current) => {\n\t\t\tconst call = task.checkpoint?.call ?? task.input.call;\n\t\t\tconst entry = tx.appendEntry(current.conversationId, {\n\t\t\t\tkind: \"pi.tool_result\",\n\t\t\t\tmodel: [toMessage(call, synthetic(\"tool aborted\", \"aborted\"), rt.now())],\n\t\t\t\tdata: { diagnostics: [{ severity: \"error\", message: \"aborted\", code: \"aborted\" }] },\n\t\t\t});\n\t\t\tconst slot = tx.sticky(current.conversationId).turn.tools[task.input.index];\n\t\t\tif (slot !== undefined) {\n\t\t\t\tslot.status = \"aborted\";\n\t\t\t\tslot.entry = entry;\n\t\t\t\tdelete slot.waitingOn;\n\t\t\t}\n\t\t\ttx.emit({ type: \"tool.aborted\", taskId: current.id, callId: call.id, entry });\n\t\t\treturn { entry };\n\t\t};\n\t},\n};\n\n/** The one point where a throwing handler blocks rather than being skipped. */\nasync function beforeTool(\n\ttask: T,\n\trt: Rt,\n\tcall: StoredToolCall,\n\tctx: Context,\n): Promise<{ call: StoredToolCall } | { block: string }> {\n\tlet current = call;\n\tfor (const binding of rt.hooks.handlers()) {\n\t\tfunction memo<T extends JsonValue>(name: string, candidate: T, context: Context): Promise<T>;\n\t\tfunction memo<T extends JsonValue>(name: string, context: Context): Promise<T | undefined>;\n\t\tfunction memo<T extends JsonValue>(\n\t\t\tname: string,\n\t\t\tcandidateOrContext: T | Context,\n\t\t\tcontext?: Context,\n\t\t): Promise<T | undefined> {\n\t\t\tconst targetContext = context ?? (candidateOrContext as Context);\n\t\t\treturn rt.commit((tx) => {\n\t\t\t\ttx.plugins(binding.namespace);\n\t\t\t\tconst slot = tx.toolSlot(task);\n\t\t\t\tif (!Object.hasOwn(slot, \"memos\")) slot.memos = {};\n\t\t\t\tconst memos = slot.memos!;\n\t\t\t\tconst key = `hook:${binding.namespace.id}:${name}`;\n\t\t\t\tif (Object.hasOwn(memos, key)) return structuredClone(memos[key]) as T;\n\t\t\t\tif (context === undefined) return undefined;\n\t\t\t\tconst candidate = structuredClone(candidateOrContext as T);\n\t\t\t\tmemos[key] = candidate;\n\t\t\t\treturn candidate;\n\t\t\t}, targetContext);\n\t\t}\n\t\tconst api: BeforeToolApi = {\n\t\t\t...binding.api,\n\t\t\tcallId: call.id,\n\t\t\twaiting: (context) =>\n\t\t\t\trt.commit((tx, currentTask) => {\n\t\t\t\t\ttx.plugins(binding.namespace);\n\t\t\t\t\tconst slot = tx.toolSlot(currentTask as T);\n\t\t\t\t\tif (slot.waitingOn === binding.namespace.id) return;\n\t\t\t\t\tslot.waitingOn = binding.namespace.id;\n\t\t\t\t\ttx.emit({\n\t\t\t\t\t\ttype: \"tool.waiting\",\n\t\t\t\t\t\ttaskId: currentTask.id,\n\t\t\t\t\t\tcallId: call.id,\n\t\t\t\t\t\ton: binding.namespace.id,\n\t\t\t\t\t});\n\t\t\t\t}, context),\n\t\t\tmemo,\n\t\t\temit: (name, data, context) => rt.commit((tx) => tx.emit(binding.namespace, name, data), context),\n\t\t};\n\t\ttry {\n\t\t\tconst value = await binding.handlers.beforeTool?.(current, api, ctx);\n\t\t\tif (!value) continue;\n\t\t\tif (value.block !== undefined) return { block: value.block };\n\t\t\tif (value.call !== undefined) current = value.call;\n\t\t} catch (error) {\n\t\t\tif (ctx.abortSignal?.aborted) throw error;\n\t\t\treturn { block: `hook threw: ${String(error)}` };\n\t\t}\n\t}\n\treturn { call: current };\n}\n\nexport const DEFAULT_BOUNDS = { maxBytes: 64 * 1024, maxLines: 200, retain: \"head\" as const };\n\nasync function invoke(\n\ttask: T,\n\tcall: StoredToolCall,\n\tdeclaration: AnyToolDeclaration,\n\trt: Rt,\n\tctx: Context,\n): Promise<Out> {\n\t// The kernel owns the stream: one bounded buffer, one throttle, one flush path. Flush failures are not swallowed.\n\tconst b = { ...DEFAULT_BOUNDS, ...declaration.output };\n\tconst buffer = new Bounded(b.maxBytes, b.maxLines, b.retain);\n\tlet streamed = false;\n\tlet lastFlush = 0;\n\tlet flushing: Promise<void> = Promise.resolve();\n\tlet flushError: unknown;\n\tconst flush = () => {\n\t\tlastFlush = rt.now();\n\t\tconst text = buffer.text();\n\t\tflushing = flushing\n\t\t\t.then(() =>\n\t\t\t\trt.commit((tx) => {\n\t\t\t\t\ttx.toolSlot(task).output = text;\n\t\t\t\t}, ctx),\n\t\t\t)\n\t\t\t.catch((e) => {\n\t\t\t\tflushError ??= e;\n\t\t\t});\n\t};\n\tconst api = {\n\t\t...taskApi(task, rt),\n\t\t// Only the free fields; identity (callId/name/args/output) is protected.\n\t\tprogress: (update: (slot: Pick<ToolSlot, \"progress\" | \"details\" | \"continuedBy\">) => void, c: Context) =>\n\t\t\trt.commit((tx) => {\n\t\t\t\tconst slot = tx.toolSlot(task);\n\t\t\t\tconst free: Pick<ToolSlot, \"progress\" | \"details\" | \"continuedBy\"> = {\n\t\t\t\t\tprogress: slot.progress,\n\t\t\t\t\tdetails: slot.details,\n\t\t\t\t\tcontinuedBy: slot.continuedBy,\n\t\t\t\t};\n\t\t\t\tupdate(free);\n\t\t\t\tif (free.progress !== undefined) slot.progress = free.progress;\n\t\t\t\telse delete slot.progress;\n\t\t\t\tif (free.details !== undefined) slot.details = toStored(free.details);\n\t\t\t\telse delete slot.details;\n\t\t\t\tif (free.continuedBy !== undefined) slot.continuedBy = free.continuedBy;\n\t\t\t\telse delete slot.continuedBy;\n\t\t\t}, c),\n\t\tstream(chunk: string | Uint8Array) {\n\t\t\tstreamed = true;\n\t\t\tbuffer.push(typeof chunk === \"string\" ? new TextEncoder().encode(chunk) : chunk);\n\t\t\tif (rt.now() - lastFlush >= 100) flush();\n\t\t},\n\t};\n\tfunction memo<T extends JsonValue>(name: string, candidate: T, context: Context): Promise<T>;\n\tfunction memo<T extends JsonValue>(name: string, context: Context): Promise<T | undefined>;\n\tfunction memo<T extends JsonValue>(\n\t\tname: string,\n\t\tcandidateOrContext: T | Context,\n\t\tcontext?: Context,\n\t): Promise<T | undefined> {\n\t\tconst targetContext = context ?? (candidateOrContext as Context);\n\t\treturn rt.commit((tx) => {\n\t\t\tconst slot = tx.toolSlot(task);\n\t\t\tif (!Object.hasOwn(slot, \"memos\")) slot.memos = {};\n\t\t\tconst memos = slot.memos!;\n\t\t\tconst key = `tool:${name}`;\n\t\t\tif (Object.hasOwn(memos, key)) return structuredClone(memos[key]) as T;\n\t\t\tif (context === undefined) return undefined;\n\t\t\tconst candidate = structuredClone(candidateOrContext as T);\n\t\t\tmemos[key] = candidate;\n\t\t\treturn candidate;\n\t\t}, targetContext);\n\t}\n\tconst toolApi: typeof api & Pick<ToolApi, \"callId\" | \"memo\"> = { ...api, callId: call.id, memo };\n\tlet result: ToolResult;\n\ttry {\n\t\tresult = await declaration.execute(call.arguments as never, toolApi, ctx);\n\t} catch (error) {\n\t\tif (ctx.abortSignal?.aborted) throw error;\n\t\tresult = synthetic(`tool threw: ${String(error)}`, \"threw\");\n\t}\n\tif (streamed) {\n\t\tflush();\n\t\tawait flushing;\n\t\tif (flushError !== undefined) throw flushError; // a persistence failure is never hidden\n\t\tif (result.content === undefined)\n\t\t\tresult = {\n\t\t\t\t...result,\n\t\t\t\tcontent: [{ type: \"text\", text: buffer.text() }],\n\t\t\t\t...(buffer.dropped\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tdiagnostics: [\n\t\t\t\t\t\t\t\t...(result.diagnostics ?? []),\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tseverity: \"warn\" as const,\n\t\t\t\t\t\t\t\t\tcode: \"truncated\",\n\t\t\t\t\t\t\t\t\tmessage: `${buffer.droppedBytes} bytes / ${buffer.droppedLines} lines dropped (${b.retain} ${b.maxBytes} retained)`,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t}\n\t\t\t\t\t: {}),\n\t\t\t};\n\t}\n\tlet final = result;\n\tawait rt.hooks.each(\n\t\tctx,\n\t\t(h, api) => h.afterTool?.(call, final, { ...api, callId: call.id }, ctx),\n\t\t(value) => {\n\t\t\tif (value !== undefined) final = value;\n\t\t},\n\t);\n\treturn close(\n\t\ttask,\n\t\tfinal,\n\t\tdeclaration,\n\t\trt.now(),\n\t\tcall,\n\t\tstreamed ? { bytes: buffer.droppedBytes, lines: buffer.droppedLines } : undefined,\n\t);\n}\n\n/** Closure: bound the output, store the exact model message under the stored final call, rest as strict-JSON data. */\nfunction close(\n\ttask: T,\n\traw: ToolResult,\n\tdeclaration: AnyToolDeclaration | undefined,\n\tnow: number,\n\tcall: StoredToolCall = task.input.call,\n\tstreamTruncated?: { bytes: number; lines: number },\n): Out {\n\treturn (tx, current) => {\n\t\tconst bounded = bound({ ...raw, content: raw.content ?? [] }, declaration?.output);\n\t\tconst result = bounded.result;\n\t\tconst bytes = (bounded.truncated?.bytes ?? 0) + (streamTruncated?.bytes ?? 0);\n\t\tconst lines = (bounded.truncated?.lines ?? 0) + (streamTruncated?.lines ?? 0);\n\t\tconst truncated = bytes > 0 || lines > 0 ? { bytes, lines } : undefined;\n\t\tconst data: JsonObject = {};\n\t\tif (result.details !== undefined) data.details = toStored(result.details);\n\t\tif (result.diagnostics !== undefined) data.diagnostics = toStored(result.diagnostics);\n\t\tif (result.control !== undefined) data.control = toStored(result.control);\n\t\tif (truncated !== undefined) data.truncated = truncated;\n\t\tconst entry = tx.appendEntry(current.conversationId, {\n\t\t\tkind: \"pi.tool_result\",\n\t\t\tmodel: [toMessage(call, result, now)],\n\t\t\tdata,\n\t\t});\n\t\tconst slot = tx.toolSlot(task);\n\t\tslot.status = result.isError === true ? \"error\" : \"done\";\n\t\tslot.entry = entry;\n\t\tdelete slot.waitingOn;\n\t\ttx.emit({\n\t\t\ttype: \"tool.finished\",\n\t\t\ttaskId: current.id,\n\t\t\tcallId: call.id,\n\t\t\tentry,\n\t\t\tisError: result.isError === true,\n\t\t\t...(result.control === undefined ? {} : { control: result.control }),\n\t\t});\n\t\tif (truncated !== undefined)\n\t\t\ttx.emit({\n\t\t\t\ttype: \"warning\",\n\t\t\t\tsource: \"tool\",\n\t\t\t\tmessage: `tool output truncated: ${truncated.bytes} bytes / ${truncated.lines} lines dropped`,\n\t\t\t});\n\t\tconst completion: Completion<ToolTaskResult, never> = {\n\t\t\tstatus: \"completed\",\n\t\t\tresult: { entry, ...(result.control === undefined ? {} : { control: toStored(result.control) }) },\n\t\t};\n\t\treturn completion;\n\t};\n}\n\nfunction toMessage(call: StoredToolCall, result: ToolResult, now: number) {\n\treturn toStored({\n\t\trole: \"toolResult\" as const,\n\t\ttoolCallId: call.id,\n\t\ttoolName: call.name,\n\t\tcontent: result.content ?? [],\n\t\tisError: result.isError ?? false,\n\t\ttimestamp: now,\n\t});\n}\n\nfunction bound(\n\tresult: ToolResult,\n\tdeclared: AnyToolDeclaration[\"output\"],\n): { result: ToolResult; truncated?: { bytes: number; lines: number } } {\n\tconst bounds = { ...DEFAULT_BOUNDS, ...declared };\n\tconst blocks = result.content ?? [];\n\tlet text = blocks\n\t\t.filter((block) => block.type === \"text\")\n\t\t.map((block) => block.text)\n\t\t.join(\"\");\n\tlet droppedLines = 0;\n\tlet droppedBytes = 0;\n\tconst lines = text.split(\"\\n\");\n\tif (lines.length > bounds.maxLines) {\n\t\tdroppedLines = lines.length - bounds.maxLines;\n\t\ttext = (bounds.retain === \"head\" ? lines.slice(0, bounds.maxLines) : lines.slice(-bounds.maxLines)).join(\"\\n\");\n\t}\n\tconst bytes = new TextEncoder().encode(text);\n\tif (bytes.length > bounds.maxBytes) {\n\t\tdroppedBytes = bytes.length - bounds.maxBytes;\n\t\ttext = new TextDecoder().decode(\n\t\t\tbounds.retain === \"head\" ? bytes.subarray(0, bounds.maxBytes) : bytes.subarray(-bounds.maxBytes),\n\t\t);\n\t}\n\tif (droppedBytes === 0 && droppedLines === 0) return { result };\n\tlet textIndex = -1;\n\tfor (let index = 0; index < blocks.length; index++) {\n\t\tif (blocks[index]!.type !== \"text\") continue;\n\t\tif (bounds.retain === \"head\" && textIndex >= 0) continue;\n\t\ttextIndex = index;\n\t}\n\tconst content: NonNullable<ToolResult[\"content\"]> = [];\n\tfor (let index = 0; index < blocks.length; index++) {\n\t\tconst block = blocks[index]!;\n\t\tif (block.type !== \"text\") content.push(block);\n\t\telse if (index === textIndex) content.push({ ...block, text });\n\t}\n\tconst note = {\n\t\tseverity: \"warn\" as const,\n\t\tcode: \"truncated\",\n\t\tmessage: `output truncated: ${droppedLines} lines, ${droppedBytes} bytes dropped`,\n\t};\n\treturn {\n\t\tresult: { ...result, content, diagnostics: [...(result.diagnostics ?? []), note] },\n\t\ttruncated: { bytes: droppedBytes, lines: droppedLines },\n\t};\n}\n\nexport type { Step };\n"]}
|
|
1
|
+
{"version":3,"file":"tool.js","sourceRoot":"","sources":["../../../../src/harness/pico3/kinds/tool.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Context } from \"@earendil-works/chord\";\nimport type { ToolCall } from \"@earendil-works/pi-ai\";\nimport type { TSchema } from \"typebox\";\nimport { Errors } from \"typebox/value\";\nimport { Bounded } from \"../bounded.ts\";\nimport {\n\ttype AnyToolDeclaration,\n\ttype BeforeToolApi,\n\ttype Closure,\n\ttype Completion,\n\ttype CoreKind,\n\ttype CoreTx,\n\ttype HookInfo,\n\ttype HookResult,\n\ttype Id,\n\ttype JsonObject,\n\ttype JsonValue,\n\ttype Runtime,\n\ttype Step,\n\ttype Stored,\n\ttype Task,\n\ttype ToolApi,\n\ttype ToolControl,\n\ttype ToolResult,\n\ttype ToolSlot,\n\ttoStored,\n} from \"../types.ts\";\nimport { taskApi } from \"./task-api.ts\";\n\nexport type StoredToolCall = Stored<ToolCall>;\nexport type ToolInput = {\n\tassistant: Id;\n\tcall: StoredToolCall;\n\toffered: string[];\n\tindex: number; // position of the call in the assistant message; also this tool's slot in sticky.turn.tools\n};\nexport type ToolCheckpoint = { phase: \"started\"; replay: \"safe\" | \"unsafe\"; call: StoredToolCall };\nexport type ToolTaskResult = { entry: Id; control?: ToolControl };\n/** Hook points this kind calls. Register with `h.hooks(namespace, kinds.tool, { … })`. */\nexport interface ToolHooks {\n\t/** Before invocation, before `started`. Chain on `call`; `{ block }` stops it. A throw blocks. */\n\tbeforeTool(\n\t\tcall: StoredToolCall,\n\t\tapi: BeforeToolApi,\n\t\tctx: Context,\n\t): HookResult<{ call?: StoredToolCall; block?: string }>;\n\t/** After the tool returns; may replace the result. Chain. */\n\tafterTool(\n\t\tcall: StoredToolCall,\n\t\tresult: ToolResult,\n\t\tapi: HookInfo & { readonly callId: string },\n\t\tctx: Context,\n\t): HookResult<ToolResult>;\n}\n\ntype T = Task<ToolInput, ToolCheckpoint>;\ntype Rt = Runtime<ToolHooks, CoreTx>;\ntype Out = Closure<ToolTaskResult, never, CoreTx>;\n\nconst synthetic = (text: string, code: string): ToolResult => ({\n\tcontent: [{ type: \"text\", text }],\n\tisError: true,\n\tdiagnostics: [{ severity: \"error\", message: text, code }],\n});\n/** Validate arguments with the tool's real schema (TypeBox 1.x). */\nexport function invalid(declaration: AnyToolDeclaration, call: StoredToolCall): string | undefined {\n\tconst errors = [...Errors(declaration.parameters as TSchema, call.arguments)];\n\treturn errors.length === 0 ? undefined : errors.map((e) => `${e.instancePath || \"/\"}: ${e.message}`).join(\"; \");\n}\nconst sameIdentity = (a: StoredToolCall, b: StoredToolCall) =>\n\ta.id === b.id && a.name === b.name && a.namespace === b.namespace;\n\nexport const tool: CoreKind<ToolInput, ToolCheckpoint, ToolTaskResult, never, { entry: Id }, ToolHooks> = {\n\tname: \"pi.tool\",\n\tturn: true,\n\tinflight: [\"started\"],\n\n\t// Offered-set check, lookup, validate, beforeTool, validate again; then write `started`\n\t// (the in-flight checkpoint) and invoke. A crash before `started` reruns all of this.\n\tasync initial(task, rt, ctx) {\n\t\tconst call = task.input.call;\n\t\tif (!task.input.offered.includes(call.name))\n\t\t\treturn {\n\t\t\t\tdone: close(task, synthetic(`tool ${call.name} was not offered`, \"not_offered\"), undefined, rt.now()),\n\t\t\t};\n\t\tconst declaration = rt.tools.get(call.name);\n\t\tif (declaration === undefined)\n\t\t\treturn {\n\t\t\t\tdone: close(task, synthetic(`tool ${call.name} is not registered`, \"missing_tool\"), undefined, rt.now()),\n\t\t\t};\n\t\tconst bad = invalid(declaration, call);\n\t\tif (bad !== undefined)\n\t\t\treturn {\n\t\t\t\tdone: close(task, synthetic(`invalid arguments: ${bad}`, \"invalid_arguments\"), declaration, rt.now()),\n\t\t\t};\n\t\tconst hooked = await beforeTool(task, rt, call, ctx);\n\t\tif (\"block\" in hooked)\n\t\t\treturn { done: close(task, synthetic(`blocked: ${hooked.block}`, \"blocked\"), declaration, rt.now()) };\n\t\tif (!sameIdentity(call, hooked.call))\n\t\t\treturn { done: close(task, synthetic(\"blocked: call identity changed\", \"blocked\"), declaration, rt.now()) };\n\t\tconst badFinal = invalid(declaration, hooked.call);\n\t\tif (badFinal !== undefined)\n\t\t\treturn {\n\t\t\t\tdone: close(\n\t\t\t\t\ttask,\n\t\t\t\t\tsynthetic(`invalid arguments after hook: ${badFinal}`, \"invalid_arguments\"),\n\t\t\t\t\tdeclaration,\n\t\t\t\t\trt.now(),\n\t\t\t\t),\n\t\t\t};\n\t\tconst final = toStored(hooked.call);\n\t\tawait rt.commit((tx) => {\n\t\t\ttx.checkpoint({ phase: \"started\", replay: declaration.replay ?? \"unsafe\", call: final });\n\t\t\tconst slot = tx.toolSlot(task);\n\t\t\tslot.status = \"running\";\n\t\t\tdelete slot.waitingOn;\n\t\t\ttx.emit({ type: \"tool.started\", taskId: task.id, callId: final.id, name: final.name });\n\t\t}, ctx); // durable before the effect\n\t\treturn { done: await invoke(task, final, declaration, rt, ctx) };\n\t},\n\n\tphases: {\n\t\t// Only entered by the scheduler after reopen. The stored final call is the evidence; beforeTool never reruns.\n\t\tasync started(task, rt, ctx) {\n\t\t\tconst cp = task.checkpoint;\n\t\t\tconst declaration = rt.tools.get(cp.call.name);\n\t\t\tif (declaration === undefined)\n\t\t\t\treturn {\n\t\t\t\t\tdone: close(\n\t\t\t\t\t\ttask,\n\t\t\t\t\t\tsynthetic(`tool ${cp.call.name} unavailable after restart`, \"unavailable\"),\n\t\t\t\t\t\tundefined,\n\t\t\t\t\t\trt.now(),\n\t\t\t\t\t\tcp.call,\n\t\t\t\t\t),\n\t\t\t\t};\n\t\t\tif (cp.replay !== \"safe\" || (declaration.replay ?? \"unsafe\") !== \"safe\")\n\t\t\t\treturn {\n\t\t\t\t\tdone: close(\n\t\t\t\t\t\ttask,\n\t\t\t\t\t\tsynthetic(`tool ${cp.call.name} was interrupted`, \"interrupted\"),\n\t\t\t\t\t\tdeclaration,\n\t\t\t\t\t\trt.now(),\n\t\t\t\t\t\tcp.call,\n\t\t\t\t\t),\n\t\t\t\t};\n\t\t\tif (invalid(declaration, cp.call) !== undefined)\n\t\t\t\treturn {\n\t\t\t\t\tdone: close(\n\t\t\t\t\t\ttask,\n\t\t\t\t\t\tsynthetic(`tool ${cp.call.name} was interrupted; arguments no longer validate`, \"interrupted\"),\n\t\t\t\t\t\tdeclaration,\n\t\t\t\t\t\trt.now(),\n\t\t\t\t\t\tcp.call,\n\t\t\t\t\t),\n\t\t\t\t};\n\t\t\treturn { done: await invoke(task, cp.call, declaration, rt, ctx) };\n\t\t},\n\t},\n\n\tasync abort(task, rt, ctx) {\n\t\tfor (const conversationId of task.owns) {\n\t\t\tconst children = await rt.commit((tx) => tx.tasks({ conversationId, status: [\"pending\", \"running\"] }), ctx);\n\t\t\tfor (const child of children) if (!child.background) await rt.abortTask(child.id, ctx);\n\t\t}\n\t\treturn (tx, current) => {\n\t\t\tconst call = task.checkpoint?.call ?? task.input.call;\n\t\t\tconst entry = tx.appendEntry(current.conversationId, {\n\t\t\t\tkind: \"pi.tool_result\",\n\t\t\t\tmodel: [toMessage(call, synthetic(\"tool aborted\", \"aborted\"), rt.now())],\n\t\t\t\tdata: { diagnostics: [{ severity: \"error\", message: \"aborted\", code: \"aborted\" }] },\n\t\t\t});\n\t\t\tconst slot = tx.sticky(current.conversationId).turn.tools[task.input.index];\n\t\t\tif (slot !== undefined) {\n\t\t\t\tslot.status = \"aborted\";\n\t\t\t\tslot.entry = entry;\n\t\t\t\tdelete slot.waitingOn;\n\t\t\t}\n\t\t\ttx.emit({ type: \"tool.aborted\", taskId: current.id, callId: call.id, entry });\n\t\t\treturn { entry };\n\t\t};\n\t},\n};\n\n/** The one point where a throwing handler blocks rather than being skipped. */\nasync function beforeTool(\n\ttask: T,\n\trt: Rt,\n\tcall: StoredToolCall,\n\tctx: Context,\n): Promise<{ call: StoredToolCall } | { block: string }> {\n\tlet current = call;\n\tfor (const binding of rt.hooks.handlers()) {\n\t\tfunction memo<T extends JsonValue>(name: string, candidate: T, context: Context): Promise<T>;\n\t\tfunction memo<T extends JsonValue>(name: string, context: Context): Promise<T | undefined>;\n\t\tfunction memo<T extends JsonValue>(\n\t\t\tname: string,\n\t\t\tcandidateOrContext: T | Context,\n\t\t\tcontext?: Context,\n\t\t): Promise<T | undefined> {\n\t\t\tconst targetContext = context ?? (candidateOrContext as Context);\n\t\t\treturn rt.commit((tx) => {\n\t\t\t\ttx.plugins(binding.namespace);\n\t\t\t\tconst slot = tx.toolSlot(task);\n\t\t\t\tif (!Object.hasOwn(slot, \"memos\")) slot.memos = {};\n\t\t\t\tconst memos = slot.memos!;\n\t\t\t\tconst key = `hook:${binding.namespace.id}:${name}`;\n\t\t\t\tif (Object.hasOwn(memos, key)) return structuredClone(memos[key]) as T;\n\t\t\t\tif (context === undefined) return undefined;\n\t\t\t\tconst candidate = structuredClone(candidateOrContext as T);\n\t\t\t\tmemos[key] = candidate;\n\t\t\t\treturn candidate;\n\t\t\t}, targetContext);\n\t\t}\n\t\tconst api: BeforeToolApi = {\n\t\t\t...binding.api,\n\t\t\tcallId: call.id,\n\t\t\twaiting: (context) =>\n\t\t\t\trt.commit((tx, currentTask) => {\n\t\t\t\t\ttx.plugins(binding.namespace);\n\t\t\t\t\tconst slot = tx.toolSlot(currentTask as T);\n\t\t\t\t\tif (slot.waitingOn === binding.namespace.id) return;\n\t\t\t\t\tslot.waitingOn = binding.namespace.id;\n\t\t\t\t\ttx.emit({\n\t\t\t\t\t\ttype: \"tool.waiting\",\n\t\t\t\t\t\ttaskId: currentTask.id,\n\t\t\t\t\t\tcallId: call.id,\n\t\t\t\t\t\ton: binding.namespace.id,\n\t\t\t\t\t});\n\t\t\t\t}, context),\n\t\t\tmemo,\n\t\t\temit: (name, data, context) => rt.commit((tx) => tx.emit(binding.namespace, name, data), context),\n\t\t};\n\t\ttry {\n\t\t\tconst value = await binding.handlers.beforeTool?.(current, api, ctx);\n\t\t\tif (!value) continue;\n\t\t\tif (value.block !== undefined) return { block: value.block };\n\t\t\tif (value.call !== undefined) current = value.call;\n\t\t} catch (error) {\n\t\t\tif (ctx.abortSignal?.aborted) throw error;\n\t\t\treturn { block: `hook threw: ${String(error)}` };\n\t\t}\n\t}\n\treturn { call: current };\n}\n\nexport const DEFAULT_BOUNDS = { maxBytes: 64 * 1024, maxLines: 200, retain: \"head\" as const };\n\nasync function invoke(\n\ttask: T,\n\tcall: StoredToolCall,\n\tdeclaration: AnyToolDeclaration,\n\trt: Rt,\n\tctx: Context,\n): Promise<Out> {\n\t// The kernel owns the stream: one bounded buffer, one throttle, one flush path. Flush failures are not swallowed.\n\tconst b = { ...DEFAULT_BOUNDS, ...declaration.output };\n\tconst buffer = new Bounded(b.maxBytes, b.maxLines, b.retain);\n\tlet streamed = false;\n\tlet lastFlush = 0;\n\tlet flushing: Promise<void> = Promise.resolve();\n\tlet flushError: unknown;\n\tconst flush = () => {\n\t\tlastFlush = rt.now();\n\t\tconst text = buffer.text();\n\t\tflushing = flushing\n\t\t\t.then(() =>\n\t\t\t\trt.commit((tx) => {\n\t\t\t\t\ttx.toolSlot(task).output = text;\n\t\t\t\t}, ctx),\n\t\t\t)\n\t\t\t.catch((e) => {\n\t\t\t\tflushError ??= e;\n\t\t\t});\n\t};\n\tconst api = {\n\t\t...taskApi(task, rt),\n\t\t// Only the free fields; identity (callId/name/args/output) is protected.\n\t\tprogress: (update: (slot: Pick<ToolSlot, \"progress\" | \"details\" | \"continuedBy\">) => void, c: Context) =>\n\t\t\trt.commit((tx) => {\n\t\t\t\tconst slot = tx.toolSlot(task);\n\t\t\t\tconst free: Pick<ToolSlot, \"progress\" | \"details\" | \"continuedBy\"> = {\n\t\t\t\t\tprogress: slot.progress,\n\t\t\t\t\tdetails: slot.details,\n\t\t\t\t\tcontinuedBy: slot.continuedBy,\n\t\t\t\t};\n\t\t\t\tupdate(free);\n\t\t\t\tif (free.progress !== undefined) slot.progress = free.progress;\n\t\t\t\telse delete slot.progress;\n\t\t\t\tif (free.details !== undefined) slot.details = toStored(free.details);\n\t\t\t\telse delete slot.details;\n\t\t\t\tif (free.continuedBy !== undefined) slot.continuedBy = free.continuedBy;\n\t\t\t\telse delete slot.continuedBy;\n\t\t\t}, c),\n\t\tstream(chunk: string | Uint8Array) {\n\t\t\tstreamed = true;\n\t\t\tbuffer.push(typeof chunk === \"string\" ? new TextEncoder().encode(chunk) : chunk);\n\t\t\tif (rt.now() - lastFlush >= 100) flush();\n\t\t},\n\t};\n\tfunction memo<T extends JsonValue>(name: string, candidate: T, context: Context): Promise<T>;\n\tfunction memo<T extends JsonValue>(name: string, context: Context): Promise<T | undefined>;\n\tfunction memo<T extends JsonValue>(\n\t\tname: string,\n\t\tcandidateOrContext: T | Context,\n\t\tcontext?: Context,\n\t): Promise<T | undefined> {\n\t\tconst targetContext = context ?? (candidateOrContext as Context);\n\t\treturn rt.commit((tx) => {\n\t\t\tconst slot = tx.toolSlot(task);\n\t\t\tif (!Object.hasOwn(slot, \"memos\")) slot.memos = {};\n\t\t\tconst memos = slot.memos!;\n\t\t\tconst key = `tool:${name}`;\n\t\t\tif (Object.hasOwn(memos, key)) return structuredClone(memos[key]) as T;\n\t\t\tif (context === undefined) return undefined;\n\t\t\tconst candidate = structuredClone(candidateOrContext as T);\n\t\t\tmemos[key] = candidate;\n\t\t\treturn candidate;\n\t\t}, targetContext);\n\t}\n\tconst toolApi: typeof api & Pick<ToolApi, \"callId\" | \"memo\"> = { ...api, callId: call.id, memo };\n\tlet result: ToolResult;\n\ttry {\n\t\tresult = await declaration.execute(call.arguments as never, toolApi, ctx);\n\t} catch (error) {\n\t\tif (ctx.abortSignal?.aborted) throw error;\n\t\tresult = synthetic(`tool threw: ${String(error)}`, \"threw\");\n\t}\n\tif (streamed) {\n\t\tflush();\n\t\tawait flushing;\n\t\tif (flushError !== undefined) throw flushError; // a persistence failure is never hidden\n\t\tif (result.content === undefined)\n\t\t\tresult = {\n\t\t\t\t...result,\n\t\t\t\tcontent: [{ type: \"text\", text: buffer.text() }],\n\t\t\t\t...(buffer.dropped\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tdiagnostics: [\n\t\t\t\t\t\t\t\t...(result.diagnostics ?? []),\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tseverity: \"warn\" as const,\n\t\t\t\t\t\t\t\t\tcode: \"truncated\",\n\t\t\t\t\t\t\t\t\tmessage: `${buffer.droppedBytes} bytes / ${buffer.droppedLines} lines dropped (${b.retain} ${b.maxBytes} retained)`,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t}\n\t\t\t\t\t: {}),\n\t\t\t};\n\t}\n\tlet final = result;\n\tawait rt.hooks.each(\n\t\tctx,\n\t\t(h, api) => h.afterTool?.(call, final, { ...api, callId: call.id }, ctx),\n\t\t(value) => {\n\t\t\tif (value !== undefined) final = value;\n\t\t},\n\t);\n\treturn close(\n\t\ttask,\n\t\tfinal,\n\t\tdeclaration,\n\t\trt.now(),\n\t\tcall,\n\t\tstreamed ? { bytes: buffer.droppedBytes, lines: buffer.droppedLines } : undefined,\n\t);\n}\n\n/** Closure: bound the output, store the exact model message under the stored final call, rest as strict-JSON data. */\nfunction close(\n\ttask: T,\n\traw: ToolResult,\n\tdeclaration: AnyToolDeclaration | undefined,\n\tnow: number,\n\tcall: StoredToolCall = task.input.call,\n\tstreamTruncated?: { bytes: number; lines: number },\n): Out {\n\treturn (tx, current) => {\n\t\tconst bounded = bound({ ...raw, content: raw.content ?? [] }, declaration?.output);\n\t\tconst result = bounded.result;\n\t\tconst bytes = (bounded.truncated?.bytes ?? 0) + (streamTruncated?.bytes ?? 0);\n\t\tconst lines = (bounded.truncated?.lines ?? 0) + (streamTruncated?.lines ?? 0);\n\t\tconst truncated = bytes > 0 || lines > 0 ? { bytes, lines } : undefined;\n\t\tconst data: JsonObject = {};\n\t\tif (result.details !== undefined) data.details = toStored(result.details);\n\t\tif (result.diagnostics !== undefined) data.diagnostics = toStored(result.diagnostics);\n\t\tif (result.control !== undefined) data.control = toStored(result.control);\n\t\tif (truncated !== undefined) data.truncated = truncated;\n\t\tconst entry = tx.appendEntry(current.conversationId, {\n\t\t\tkind: \"pi.tool_result\",\n\t\t\tmodel: [toMessage(call, result, now)],\n\t\t\tdata,\n\t\t});\n\t\tconst slot = tx.toolSlot(task);\n\t\tslot.status = result.isError === true ? \"error\" : \"done\";\n\t\tslot.entry = entry;\n\t\tdelete slot.waitingOn;\n\t\ttx.emit({\n\t\t\ttype: \"tool.finished\",\n\t\t\ttaskId: current.id,\n\t\t\tcallId: call.id,\n\t\t\tentry,\n\t\t\tisError: result.isError === true,\n\t\t\t...(result.control === undefined ? {} : { control: result.control }),\n\t\t});\n\t\tif (truncated !== undefined)\n\t\t\ttx.emit({\n\t\t\t\ttype: \"warning\",\n\t\t\t\tsource: \"tool\",\n\t\t\t\tmessage: `tool output truncated: ${truncated.bytes} bytes / ${truncated.lines} lines dropped`,\n\t\t\t});\n\t\tconst completion: Completion<ToolTaskResult, never> = {\n\t\t\tstatus: \"completed\",\n\t\t\tresult: { entry, ...(result.control === undefined ? {} : { control: toStored(result.control) }) },\n\t\t};\n\t\treturn completion;\n\t};\n}\n\nfunction toMessage(call: StoredToolCall, result: ToolResult, now: number) {\n\treturn toStored({\n\t\trole: \"toolResult\" as const,\n\t\ttoolCallId: call.id,\n\t\ttoolName: call.name,\n\t\tcontent: result.content ?? [],\n\t\tisError: result.isError ?? false,\n\t\ttimestamp: now,\n\t});\n}\n\nfunction bound(\n\tresult: ToolResult,\n\tdeclared: AnyToolDeclaration[\"output\"],\n): { result: ToolResult; truncated?: { bytes: number; lines: number } } {\n\tconst bounds = { ...DEFAULT_BOUNDS, ...declared };\n\tconst blocks = result.content ?? [];\n\tlet text = blocks\n\t\t.filter((block) => block.type === \"text\")\n\t\t.map((block) => block.text)\n\t\t.join(\"\");\n\tlet droppedLines = 0;\n\tlet droppedBytes = 0;\n\tconst lines = text.split(\"\\n\");\n\tif (lines.length > bounds.maxLines) {\n\t\tdroppedLines = lines.length - bounds.maxLines;\n\t\ttext = (bounds.retain === \"head\" ? lines.slice(0, bounds.maxLines) : lines.slice(-bounds.maxLines)).join(\"\\n\");\n\t}\n\tconst bytes = new TextEncoder().encode(text);\n\tif (bytes.length > bounds.maxBytes) {\n\t\tdroppedBytes = bytes.length - bounds.maxBytes;\n\t\ttext = new TextDecoder().decode(\n\t\t\tbounds.retain === \"head\" ? bytes.subarray(0, bounds.maxBytes) : bytes.subarray(-bounds.maxBytes),\n\t\t);\n\t}\n\tif (droppedBytes === 0 && droppedLines === 0) return { result };\n\tlet textIndex = -1;\n\tfor (let index = 0; index < blocks.length; index++) {\n\t\tif (blocks[index]!.type !== \"text\") continue;\n\t\tif (bounds.retain === \"head\" && textIndex >= 0) continue;\n\t\ttextIndex = index;\n\t}\n\tconst content: NonNullable<ToolResult[\"content\"]> = [];\n\tfor (let index = 0; index < blocks.length; index++) {\n\t\tconst block = blocks[index]!;\n\t\tif (block.type !== \"text\") content.push(block);\n\t\telse if (index === textIndex) content.push({ ...block, text });\n\t}\n\tconst note = {\n\t\tseverity: \"warn\" as const,\n\t\tcode: \"truncated\",\n\t\tmessage: `output truncated: ${droppedLines} lines, ${droppedBytes} bytes dropped`,\n\t};\n\treturn {\n\t\tresult: { ...result, content, diagnostics: [...(result.diagnostics ?? []), note] },\n\t\ttruncated: { bytes: droppedBytes, lines: droppedLines },\n\t};\n}\n\nexport type { Step };\n"]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type Op } from "@earendil-works/chord/delta";
|
|
2
|
+
/** Temporary compatibility surface for Pico3's flush-based document handling. */
|
|
3
|
+
export interface Tracker<T extends object> {
|
|
4
|
+
readonly state: T;
|
|
5
|
+
readonly target: T;
|
|
6
|
+
readonly dirty: boolean;
|
|
7
|
+
flush(): Op[];
|
|
8
|
+
rebase(): void;
|
|
9
|
+
}
|
|
10
|
+
export declare function track<T extends object>(initial: T): Tracker<T>;
|
|
11
|
+
//# sourceMappingURL=legacy-tracker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"legacy-tracker.d.ts","sourceRoot":"","sources":["../../../src/harness/pico3/legacy-tracker.ts"],"names":[],"mappings":"AAAA,OAAO,EAIN,KAAK,EAAE,EAGP,MAAM,6BAA6B,CAAC;AAErC,iFAAiF;AACjF,MAAM,WAAW,OAAO,CAAC,CAAC,SAAS,MAAM;IACxC,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;IAClB,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;IACnB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,KAAK,IAAI,EAAE,EAAE,CAAC;IACd,MAAM,IAAI,IAAI,CAAC;CACf;AA6CD,wBAAgB,KAAK,CAAC,CAAC,SAAS,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAE9D"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { track as trackChord, } from "@earendil-works/chord/delta";
|
|
2
|
+
class LegacyTracker {
|
|
3
|
+
tracker;
|
|
4
|
+
change;
|
|
5
|
+
forceBase = true;
|
|
6
|
+
constructor(initial) {
|
|
7
|
+
this.tracker = trackChord(initial);
|
|
8
|
+
}
|
|
9
|
+
get state() {
|
|
10
|
+
this.change ??= this.tracker.beginChange();
|
|
11
|
+
return this.change.state;
|
|
12
|
+
}
|
|
13
|
+
get target() {
|
|
14
|
+
return this.tracker.value;
|
|
15
|
+
}
|
|
16
|
+
get dirty() {
|
|
17
|
+
return this.forceBase || this.change !== undefined;
|
|
18
|
+
}
|
|
19
|
+
flush() {
|
|
20
|
+
let prepared;
|
|
21
|
+
if (this.change !== undefined) {
|
|
22
|
+
const change = this.change;
|
|
23
|
+
this.change = undefined;
|
|
24
|
+
prepared = change.prepare();
|
|
25
|
+
// Pico3 adopts before storage. A storage failure faults the owning Session.
|
|
26
|
+
this.tracker.adopt(prepared);
|
|
27
|
+
}
|
|
28
|
+
if (this.forceBase) {
|
|
29
|
+
this.forceBase = false;
|
|
30
|
+
return [["r", this.tracker.value]];
|
|
31
|
+
}
|
|
32
|
+
return (prepared?.ops ?? []);
|
|
33
|
+
}
|
|
34
|
+
rebase() {
|
|
35
|
+
this.forceBase = true;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
export function track(initial) {
|
|
39
|
+
return new LegacyTracker(initial);
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=legacy-tracker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"legacy-tracker.js","sourceRoot":"","sources":["../../../src/harness/pico3/legacy-tracker.ts"],"names":[],"mappings":"AAAA,OAAO,EAMN,KAAK,IAAI,UAAU,GACnB,MAAM,6BAA6B,CAAC;AAWrC,MAAM,aAAa;IACD,OAAO,CAAkB;IAClC,MAAM,CAAwB;IAC9B,SAAS,GAAG,IAAI,CAAC;IAEzB,YAAY,OAAU;QACrB,IAAI,CAAC,OAAO,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;IACpC,CAAC;IAED,IAAI,KAAK;QACR,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;QAC3C,OAAO,IAAI,CAAC,MAAM,CAAC,KAAU,CAAC;IAC/B,CAAC;IAED,IAAI,MAAM;QACT,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;IAC3B,CAAC;IAED,IAAI,KAAK;QACR,OAAO,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,CAAC;IACpD,CAAC;IAED,KAAK;QACJ,IAAI,QAAiC,CAAC;QACtC,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YAC/B,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;YAC3B,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC;YACxB,QAAQ,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC;YAC5B,4EAA4E;YAC5E,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAC9B,CAAC;QACD,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACpB,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;YACvB,OAAO,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,KAA6B,CAAC,CAAC,CAAC;QAC5D,CAAC;QACD,OAAO,CAAC,QAAQ,EAAE,GAAG,IAAI,EAAE,CAAS,CAAC;IACtC,CAAC;IAED,MAAM;QACL,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;IACvB,CAAC;CACD;AAED,MAAM,UAAU,KAAK,CAAmB,OAAU;IACjD,OAAO,IAAI,aAAa,CAAC,OAAO,CAAC,CAAC;AACnC,CAAC","sourcesContent":["import {\n\ttype Change,\n\ttype Tracker as ChordTracker,\n\ttype JsonValue,\n\ttype Op,\n\ttype Prepared,\n\ttrack as trackChord,\n} from \"@earendil-works/chord/delta\";\n\n/** Temporary compatibility surface for Pico3's flush-based document handling. */\nexport interface Tracker<T extends object> {\n\treadonly state: T;\n\treadonly target: T;\n\treadonly dirty: boolean;\n\tflush(): Op[];\n\trebase(): void;\n}\n\nclass LegacyTracker<T extends object> implements Tracker<T> {\n\tprivate readonly tracker: ChordTracker<T>;\n\tprivate change: Change<T> | undefined;\n\tprivate forceBase = true;\n\n\tconstructor(initial: T) {\n\t\tthis.tracker = trackChord(initial);\n\t}\n\n\tget state(): T {\n\t\tthis.change ??= this.tracker.beginChange();\n\t\treturn this.change.state as T;\n\t}\n\n\tget target(): T {\n\t\treturn this.tracker.value;\n\t}\n\n\tget dirty(): boolean {\n\t\treturn this.forceBase || this.change !== undefined;\n\t}\n\n\tflush(): Op[] {\n\t\tlet prepared: Prepared<T> | undefined;\n\t\tif (this.change !== undefined) {\n\t\t\tconst change = this.change;\n\t\t\tthis.change = undefined;\n\t\t\tprepared = change.prepare();\n\t\t\t// Pico3 adopts before storage. A storage failure faults the owning Session.\n\t\t\tthis.tracker.adopt(prepared);\n\t\t}\n\t\tif (this.forceBase) {\n\t\t\tthis.forceBase = false;\n\t\t\treturn [[\"r\", this.tracker.value as unknown as JsonValue]];\n\t\t}\n\t\treturn (prepared?.ops ?? []) as Op[];\n\t}\n\n\trebase(): void {\n\t\tthis.forceBase = true;\n\t}\n}\n\nexport function track<T extends object>(initial: T): Tracker<T> {\n\treturn new LegacyTracker(initial);\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"membrane.d.ts","sourceRoot":"","sources":["../../../src/harness/pico3/membrane.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,qBAAa,QAAQ;IACpB,OAAO,CAAC,KAAK,CAAQ;IACrB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAiC;IAC1D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAyB;IACnD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAE9B,YAAY,IAAI,EAAE,MAAM,EAEvB;IAED,MAAM,SAEL;IAED,IAAI,CAAC,CAAC,SAAS,MAAM,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,CAoFnC;IAED,OAAO,CAAC,gBAAgB;CAUxB"
|
|
1
|
+
{"version":3,"file":"membrane.d.ts","sourceRoot":"","sources":["../../../src/harness/pico3/membrane.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,qBAAa,QAAQ;IACpB,OAAO,CAAC,KAAK,CAAQ;IACrB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAiC;IAC1D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAyB;IACnD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAE9B,YAAY,IAAI,EAAE,MAAM,EAEvB;IAED,MAAM,SAEL;IAED,IAAI,CAAC,CAAC,SAAS,MAAM,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,CAoFnC;IAED,OAAO,CAAC,gBAAgB;CAUxB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"membrane.js","sourceRoot":"","sources":["../../../src/harness/pico3/membrane.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * A transaction-scoped revocable membrane over a Chord-tracked document.\n *\n * Every object reached through a document proxy is wrapped lazily; all wrappers of one\n * transaction share one liveness flag; identity is preserved by a WeakMap. Mutations forward\n * to the underlying Chord proxy so its tracker records ops. At transaction finish — success,\n * callback failure, validation failure, storage failure — `revoke()` flips the flag and every\n * retained wrapper, root or nested, throws on any operation.\n *\n * Assigning one wrapper into another (`a.list = b.list`) is rejected: Chord stores the value it\n * is given, and a stored proxy is the classic footgun. Assign plain values; splice in place.\n */\nexport class Membrane {\n\tprivate alive = true;\n\tprivate readonly wrappers = new WeakMap<object, object>();\n\tprivate readonly isWrapper = new WeakSet<object>();\n\tprivate readonly what: string;\n\n\tconstructor(what: string) {\n\t\tthis.what = what;\n\t}\n\n\trevoke() {\n\t\tthis.alive = false;\n\t}\n\n\twrap<T extends object>(target: T): T {\n\t\tconst hit = this.wrappers.get(target);\n\t\tif (hit !== undefined) return hit as T;\n\t\tconst m = this;\n\t\tconst dead = () => new TypeError(`document proxy (${m.what}) used outside its transaction`);\n\t\tconst out = (v: unknown): unknown => (typeof v === \"object\" && v !== null ? m.wrap(v) : v);\n\t\tconst inp = (value: unknown): unknown => {\n\t\t\tif (typeof value !== \"object\" || value === null) return value;\n\t\t\tm.assertPlainInput(value, new WeakSet());\n\t\t\treturn JSON.parse(JSON.stringify(value)) as unknown;\n\t\t};\n\t\tconst proxy = new Proxy(target, {\n\t\t\tget(t, key, receiver) {\n\t\t\t\tif (!m.alive) throw dead();\n\t\t\t\tconst v = Reflect.get(t, key, receiver === proxy ? t : receiver);\n\t\t\t\tif (typeof v === \"function\") {\n\t\t\t\t\t// Methods run against the tracked target. Callback arguments (array elements and\n\t\t\t\t\t// the array itself) must cross back through the membrane before user code sees them.\n\t\t\t\t\treturn (...args: unknown[]) => {\n\t\t\t\t\t\tif (!m.alive) throw dead();\n\t\t\t\t\t\tconst safeArgs = args.map((arg) => {\n\t\t\t\t\t\t\tif (typeof arg !== \"function\") return inp(arg);\n\t\t\t\t\t\t\treturn function (this: unknown, ...callbackArgs: unknown[]) {\n\t\t\t\t\t\t\t\tif (!m.alive) throw dead();\n\t\t\t\t\t\t\t\treturn Reflect.apply(arg, this, callbackArgs.map(out));\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t});\n\t\t\t\t\t\treturn out(Reflect.apply(v, t, safeArgs));\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\treturn out(v);\n\t\t\t},\n\t\t\tset(t, key, value) {\n\t\t\t\tif (!m.alive) throw dead();\n\t\t\t\tif (key === \"__proto__\") throw new TypeError(`document proxy (${m.what}) cannot change prototypes`);\n\t\t\t\treturn Reflect.set(t, key, inp(value) as never);\n\t\t\t},\n\t\t\tdeleteProperty(t, key) {\n\t\t\t\tif (!m.alive) throw dead();\n\t\t\t\treturn Reflect.deleteProperty(t, key);\n\t\t\t},\n\t\t\thas(t, key) {\n\t\t\t\tif (!m.alive) throw dead();\n\t\t\t\treturn Reflect.has(t, key);\n\t\t\t},\n\t\t\townKeys(t) {\n\t\t\t\tif (!m.alive) throw dead();\n\t\t\t\treturn Reflect.ownKeys(t);\n\t\t\t},\n\t\t\tgetOwnPropertyDescriptor(t, key) {\n\t\t\t\tif (!m.alive) throw dead();\n\t\t\t\tconst d = Reflect.getOwnPropertyDescriptor(t, key);\n\t\t\t\tif (d === undefined) return undefined;\n\t\t\t\t// Descriptors must not leak a raw nested object.\n\t\t\t\tif (\"value\" in d) (d as { value: unknown }).value = out(d.value);\n\t\t\t\treturn d;\n\t\t\t},\n\t\t\tdefineProperty(t, key, descriptor) {\n\t\t\t\tif (!m.alive) throw dead();\n\t\t\t\tif (\"get\" in descriptor || \"set\" in descriptor)\n\t\t\t\t\tthrow new TypeError(`document proxy (${m.what}) cannot define accessors`);\n\t\t\t\tconst safe = \"value\" in descriptor ? { ...descriptor, value: inp(descriptor.value) } : descriptor;\n\t\t\t\treturn Reflect.defineProperty(t, key, safe);\n\t\t\t},\n\t\t\tgetPrototypeOf(t) {\n\t\t\t\tif (!m.alive) throw dead();\n\t\t\t\treturn Reflect.getPrototypeOf(t);\n\t\t\t},\n\t\t\tsetPrototypeOf() {\n\t\t\t\tif (!m.alive) throw dead();\n\t\t\t\tthrow new TypeError(`document proxy (${m.what}) cannot change prototypes`);\n\t\t\t},\n\t\t\tisExtensible(t) {\n\t\t\t\tif (!m.alive) throw dead();\n\t\t\t\treturn Reflect.isExtensible(t);\n\t\t\t},\n\t\t\tpreventExtensions() {\n\t\t\t\tif (!m.alive) throw dead();\n\t\t\t\tthrow new TypeError(`document proxy (${m.what}) cannot change extensibility`);\n\t\t\t},\n\t\t});\n\t\tthis.wrappers.set(target, proxy);\n\t\tthis.isWrapper.add(proxy);\n\t\treturn proxy as T;\n\t}\n\n\tprivate assertPlainInput(value: object, seen: WeakSet<object>): void {\n\t\tif (this.isWrapper.has(value))\n\t\t\tthrow new TypeError(`assigning a document proxy into a document (${this.what}); assign a plain value`);\n\t\tif (seen.has(value)) throw new TypeError(`assigning a cyclic value into a document (${this.what})`);\n\t\tseen.add(value);\n\t\tfor (const nested of Object.values(value)) {\n\t\t\tif (typeof nested === \"object\" && nested !== null) this.assertPlainInput(nested, seen);\n\t\t}\n\t\tseen.delete(value);\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"membrane.js","sourceRoot":"","sources":["../../../src/harness/pico3/membrane.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * A transaction-scoped revocable membrane over a Chord-tracked document.\n *\n * Every object reached through a document proxy is wrapped lazily; all wrappers of one\n * transaction share one liveness flag; identity is preserved by a WeakMap. Mutations forward\n * to the underlying Chord proxy so its tracker records ops. At transaction finish — success,\n * callback failure, validation failure, storage failure — `revoke()` flips the flag and every\n * retained wrapper, root or nested, throws on any operation.\n *\n * Assigning one wrapper into another (`a.list = b.list`) is rejected: Chord stores the value it\n * is given, and a stored proxy is the classic footgun. Assign plain values; splice in place.\n */\nexport class Membrane {\n\tprivate alive = true;\n\tprivate readonly wrappers = new WeakMap<object, object>();\n\tprivate readonly isWrapper = new WeakSet<object>();\n\tprivate readonly what: string;\n\n\tconstructor(what: string) {\n\t\tthis.what = what;\n\t}\n\n\trevoke() {\n\t\tthis.alive = false;\n\t}\n\n\twrap<T extends object>(target: T): T {\n\t\tconst hit = this.wrappers.get(target);\n\t\tif (hit !== undefined) return hit as T;\n\t\tconst m = this;\n\t\tconst dead = () => new TypeError(`document proxy (${m.what}) used outside its transaction`);\n\t\tconst out = (v: unknown): unknown => (typeof v === \"object\" && v !== null ? m.wrap(v) : v);\n\t\tconst inp = (value: unknown): unknown => {\n\t\t\tif (typeof value !== \"object\" || value === null) return value;\n\t\t\tm.assertPlainInput(value, new WeakSet());\n\t\t\treturn JSON.parse(JSON.stringify(value)) as unknown;\n\t\t};\n\t\tconst proxy = new Proxy(target, {\n\t\t\tget(t, key, receiver) {\n\t\t\t\tif (!m.alive) throw dead();\n\t\t\t\tconst v = Reflect.get(t, key, receiver === proxy ? t : receiver);\n\t\t\t\tif (typeof v === \"function\") {\n\t\t\t\t\t// Methods run against the tracked target. Callback arguments (array elements and\n\t\t\t\t\t// the array itself) must cross back through the membrane before user code sees them.\n\t\t\t\t\treturn (...args: unknown[]) => {\n\t\t\t\t\t\tif (!m.alive) throw dead();\n\t\t\t\t\t\tconst safeArgs = args.map((arg) => {\n\t\t\t\t\t\t\tif (typeof arg !== \"function\") return inp(arg);\n\t\t\t\t\t\t\treturn function (this: unknown, ...callbackArgs: unknown[]) {\n\t\t\t\t\t\t\t\tif (!m.alive) throw dead();\n\t\t\t\t\t\t\t\treturn Reflect.apply(arg, this, callbackArgs.map(out));\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t});\n\t\t\t\t\t\treturn out(Reflect.apply(v, t, safeArgs));\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\treturn out(v);\n\t\t\t},\n\t\t\tset(t, key, value) {\n\t\t\t\tif (!m.alive) throw dead();\n\t\t\t\tif (key === \"__proto__\") throw new TypeError(`document proxy (${m.what}) cannot change prototypes`);\n\t\t\t\treturn Reflect.set(t, key, inp(value) as never);\n\t\t\t},\n\t\t\tdeleteProperty(t, key) {\n\t\t\t\tif (!m.alive) throw dead();\n\t\t\t\treturn Reflect.deleteProperty(t, key);\n\t\t\t},\n\t\t\thas(t, key) {\n\t\t\t\tif (!m.alive) throw dead();\n\t\t\t\treturn Reflect.has(t, key);\n\t\t\t},\n\t\t\townKeys(t) {\n\t\t\t\tif (!m.alive) throw dead();\n\t\t\t\treturn Reflect.ownKeys(t);\n\t\t\t},\n\t\t\tgetOwnPropertyDescriptor(t, key) {\n\t\t\t\tif (!m.alive) throw dead();\n\t\t\t\tconst d = Reflect.getOwnPropertyDescriptor(t, key);\n\t\t\t\tif (d === undefined) return undefined;\n\t\t\t\t// Descriptors must not leak a raw nested object.\n\t\t\t\tif (\"value\" in d) (d as { value: unknown }).value = out(d.value);\n\t\t\t\treturn d;\n\t\t\t},\n\t\t\tdefineProperty(t, key, descriptor) {\n\t\t\t\tif (!m.alive) throw dead();\n\t\t\t\tif (\"get\" in descriptor || \"set\" in descriptor)\n\t\t\t\t\tthrow new TypeError(`document proxy (${m.what}) cannot define accessors`);\n\t\t\t\tconst safe = \"value\" in descriptor ? { ...descriptor, value: inp(descriptor.value) } : descriptor;\n\t\t\t\treturn Reflect.defineProperty(t, key, safe);\n\t\t\t},\n\t\t\tgetPrototypeOf(t) {\n\t\t\t\tif (!m.alive) throw dead();\n\t\t\t\treturn Reflect.getPrototypeOf(t);\n\t\t\t},\n\t\t\tsetPrototypeOf() {\n\t\t\t\tif (!m.alive) throw dead();\n\t\t\t\tthrow new TypeError(`document proxy (${m.what}) cannot change prototypes`);\n\t\t\t},\n\t\t\tisExtensible(t) {\n\t\t\t\tif (!m.alive) throw dead();\n\t\t\t\treturn Reflect.isExtensible(t);\n\t\t\t},\n\t\t\tpreventExtensions() {\n\t\t\t\tif (!m.alive) throw dead();\n\t\t\t\tthrow new TypeError(`document proxy (${m.what}) cannot change extensibility`);\n\t\t\t},\n\t\t});\n\t\tthis.wrappers.set(target, proxy);\n\t\tthis.isWrapper.add(proxy);\n\t\treturn proxy as T;\n\t}\n\n\tprivate assertPlainInput(value: object, seen: WeakSet<object>): void {\n\t\tif (this.isWrapper.has(value))\n\t\t\tthrow new TypeError(`assigning a document proxy into a document (${this.what}); assign a plain value`);\n\t\tif (seen.has(value)) throw new TypeError(`assigning a cyclic value into a document (${this.what})`);\n\t\tseen.add(value);\n\t\tfor (const nested of Object.values(value)) {\n\t\t\tif (typeof nested === \"object\" && nested !== null) this.assertPlainInput(nested, seen);\n\t\t}\n\t\tseen.delete(value);\n\t}\n}\n"]}
|
|
@@ -17,7 +17,7 @@ export declare class MemoryStorage implements Storage {
|
|
|
17
17
|
protected readonly inputsByRequest: Map<string, Input>;
|
|
18
18
|
/** Rewindable docs keep their full op history with the seq of each batch, for `docAsOf`. */
|
|
19
19
|
protected readonly rewindableLog: Map<number, {
|
|
20
|
-
seq:
|
|
20
|
+
seq: Seq;
|
|
21
21
|
ops: Op[];
|
|
22
22
|
}[]>;
|
|
23
23
|
protected readonly stickyLog: Map<number, Op[][]>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../../src/harness/pico3/memory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAA0B,KAAK,EAAE,EAAE,MAAM,6BAA6B,CAAC;AAC9E,OAAO,KAAK,EACX,YAAY,EACZ,MAAM,EACN,KAAK,EACL,SAAS,EACT,EAAE,EACF,KAAK,EACL,UAAU,EACV,GAAG,EACH,OAAO,EACP,IAAI,EACJ,QAAQ,EACR,KAAK,EACL,MAAM,YAAY,CAAC;AAEpB;;;;;;GAMG;AACH,qBAAa,aAAc,YAAW,OAAO;IAC5C,SAAS,CAAC,QAAQ,CAAC,iBAAiB,4BAA+B;IACnE,SAAS,CAAC,QAAQ,CAAC,WAAW,qBAAwB;IACtD,SAAS,CAAC,QAAQ,CAAC,qBAAqB,uBAA0B;IAClE,SAAS,CAAC,QAAQ,CAAC,SAAS,gGAAuB;IACnD,SAAS,CAAC,QAAQ,CAAC,UAAU,qBAAwB;IACrD,SAAS,CAAC,QAAQ,CAAC,eAAe,qBAA4B;IAC9D,4FAA4F;IAC5F,SAAS,CAAC,QAAQ,CAAC,aAAa;;;SAA4C;IAC5E,SAAS,CAAC,QAAQ,CAAC,SAAS,sBAAyB;IACrD,SAAS,CAAC,UAAU,EAAE,UAAU,GAAG,SAAS,CAAC;IAC7C,SAAS,CAAC,QAAQ,CAAC,QAAQ,sBAAsB;IACjD,SAAS,CAAC,WAAW,SAAK;IAC1B,SAAS,CAAC,GAAG,EAAE,GAAG,CAAK;IACvB,OAAO,CAAC,MAAM,CAAS;IAEvB,MAAM,IAAI,EAAE,CAEX;IACD,SAAS,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,QAExB;IAEK,MAAM,CAAC,MAAM,EAAE,SAAS,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,CAOlE;IAED,8FAA8F;IAC9F,SAAS,CAAC,KAAK,CAAC,MAAM,EAAE,SAAS,KAAK,EAAE,EAAE,GAAG,EAAE,GAAG,GAAG,MAAM,IAAI,CAsG9D;IAEK,YAAY,CAAC,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,OAAO,qCAExC;IACK,aAAa,CAAC,IAAI,CAAC,EAAE,OAAO,2BAEjC;IACK,OAAO,CAAC,GAAG,EAAE,SAAS,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,OAAO,+BAO/C;IACD,qHAAqH;IAC/G,WAAW,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,EAAE,OAAO,oBAkBhD;IACK,IAAI,CAAC,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,OAAO,yGAEhC;IACK,SAAS,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,OAAO,+FAS7C;IACK,KAAK,CAAC,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,OAAO,8BAEjC;IACK,cAAc,CAAC,cAAc,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,8BAEzE;IAEK,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAStE;IACD;;;OAGG;IACG,OAAO,CAAC,cAAc,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAazF;IACD,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE,GAAG,UAAU,CAUtC;IACK,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,iBAWzC;IACK,KAAK,CAAC,IAAI,CAAC,EAAE,OAAO,iBAEzB;CACD","sourcesContent":["import type { Context } from \"@earendil-works/chord\";\nimport { applyImmutable, isBase, type Op } from \"@earendil-works/chord/delta\";\nimport type {\n\tConversation,\n\tDocRef,\n\tEntry,\n\tEntryScan,\n\tId,\n\tInput,\n\tJsonObject,\n\tSeq,\n\tStorage,\n\tTask,\n\tTaskScan,\n\tWrite,\n} from \"./types.ts\";\n\n/**\n * In-memory Storage. The reference backend, and the read path of JsonlStorage.\n *\n * A batch is validated and staged in full before any table changes: one failed\n * batch changes no table, no document, no ID high-water, no sequence. Committed\n * IDs are never reused; IDs minted but never committed may be reused after reopen.\n */\nexport class MemoryStorage implements Storage {\n\tprotected readonly conversationsById = new Map<Id, Conversation>();\n\tprotected readonly entriesById = new Map<Id, Entry>();\n\tprotected readonly entriesByConversation = new Map<Id, Entry[]>(); // ascending\n\tprotected readonly tasksById = new Map<Id, Task>();\n\tprotected readonly inputsById = new Map<Id, Input>();\n\tprotected readonly inputsByRequest = new Map<string, Input>();\n\t/** Rewindable docs keep their full op history with the seq of each batch, for `docAsOf`. */\n\tprotected readonly rewindableLog = new Map<Id, { seq: Seq; ops: Op[] }[]>();\n\tprotected readonly stickyLog = new Map<Id, Op[][]>();\n\tprotected sessionDoc: JsonObject | undefined;\n\tprotected readonly entrySeq = new Map<Id, Seq>(); // entry id → seq of its batch\n\tprotected nextIdValue = 1;\n\tprotected seq: Seq = 0;\n\tprivate closed = false;\n\n\tmintId(): Id {\n\t\treturn this.nextIdValue++;\n\t}\n\tprotected setNextId(n: Id) {\n\t\tthis.nextIdValue = Math.max(this.nextIdValue, n);\n\t}\n\n\tasync commit(writes: readonly Write[], _ctx: Context): Promise<Seq> {\n\t\tif (this.closed) throw new Error(\"storage closed\");\n\t\tconst seq = this.seq + 1;\n\t\tconst staged = this.stage(writes, seq); // throws before any mutation\n\t\tstaged();\n\t\tthis.seq = seq;\n\t\treturn seq;\n\t}\n\n\t/** Validate the whole batch against the current tables; return a function that applies it. */\n\tprotected stage(writes: readonly Write[], seq: Seq): () => void {\n\t\tconst ops: (() => void)[] = [];\n\t\tconst created = new Set<Id>();\n\t\tlet maxId = 0;\n\t\tconst claim = (id: Id, what: string) => {\n\t\t\tif (!Number.isSafeInteger(id) || id <= 0) throw new Error(`${what}: invalid id ${id}`);\n\t\t\tif (created.has(id)) throw new Error(`${what}: id ${id} created twice in one batch`);\n\t\t\tcreated.add(id);\n\t\t\tmaxId = Math.max(maxId, id);\n\t\t};\n\t\tfor (const w of writes) {\n\t\t\tswitch (w.type) {\n\t\t\t\tcase \"conversation\": {\n\t\t\t\t\tif (this.conversationsById.has(w.conversation.id))\n\t\t\t\t\t\tthrow new Error(`conversation ${w.conversation.id} exists`);\n\t\t\t\t\tclaim(w.conversation.id, \"conversation\");\n\t\t\t\t\tconst c = clone(w.conversation);\n\t\t\t\t\tops.push(() => {\n\t\t\t\t\t\tthis.conversationsById.set(c.id, c);\n\t\t\t\t\t\tthis.entriesByConversation.set(c.id, []);\n\t\t\t\t\t});\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase \"entry\": {\n\t\t\t\t\tif (this.entriesById.has(w.entry.id)) throw new Error(`entry ${w.entry.id} exists`);\n\t\t\t\t\tclaim(w.entry.id, \"entry\");\n\t\t\t\t\tconst e = clone(w.entry);\n\t\t\t\t\tops.push(() => {\n\t\t\t\t\t\tthis.entriesById.set(e.id, e);\n\t\t\t\t\t\t(\n\t\t\t\t\t\t\tthis.entriesByConversation.get(e.conversationId) ??\n\t\t\t\t\t\t\tthis.entriesByConversation.set(e.conversationId, []).get(e.conversationId)!\n\t\t\t\t\t\t).push(e);\n\t\t\t\t\t\tthis.entrySeq.set(e.id, seq);\n\t\t\t\t\t});\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase \"task\": {\n\t\t\t\t\tif (this.tasksById.has(w.task.id)) throw new Error(`task ${w.task.id} exists`);\n\t\t\t\t\tclaim(w.task.id, \"task\");\n\t\t\t\t\tconst t = clone(w.task);\n\t\t\t\t\tops.push(() => this.tasksById.set(t.id, t));\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase \"task.patch\": {\n\t\t\t\t\tconst prev =\n\t\t\t\t\t\tthis.tasksById.get(w.patch.id) ??\n\t\t\t\t\t\t[...writes]\n\t\t\t\t\t\t\t.filter((x): x is Extract<Write, { type: \"task\" }> => x.type === \"task\")\n\t\t\t\t\t\t\t.find((x) => x.task.id === w.patch.id)?.task;\n\t\t\t\t\tif (prev === undefined) throw new Error(`patch for unknown task ${w.patch.id}`);\n\t\t\t\t\tconst p = clone(w.patch);\n\t\t\t\t\tops.push(() => {\n\t\t\t\t\t\tconst cur = this.tasksById.get(p.id)!;\n\t\t\t\t\t\tconst { id: _i, ...fields } = p;\n\t\t\t\t\t\tconst next = { ...cur, ...fields } as Task;\n\t\t\t\t\t\tif (p.checkpoint === null) delete (next as { checkpoint?: unknown }).checkpoint;\n\t\t\t\t\t\tthis.tasksById.set(p.id, next);\n\t\t\t\t\t});\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase \"input\": {\n\t\t\t\t\tconst i = clone(w.input);\n\t\t\t\t\tif (!this.inputsById.has(i.id)) claim(i.id, \"input\");\n\t\t\t\t\tops.push(() => {\n\t\t\t\t\t\tthis.inputsById.set(i.id, i);\n\t\t\t\t\t\tif (i.requestId !== undefined) this.inputsByRequest.set(`${i.conversationId}:${i.requestId}`, i);\n\t\t\t\t\t});\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase \"doc\": {\n\t\t\t\t\tconst ref = clone(w.ref);\n\t\t\t\t\tconst o = clone(w.ops);\n\t\t\t\t\tif (ref.doc === \"session\")\n\t\t\t\t\t\tops.push(() => {\n\t\t\t\t\t\t\tthis.sessionDoc = applyImmutable(\n\t\t\t\t\t\t\t\t(this.sessionDoc ?? { plugins: {} }) as JsonObject,\n\t\t\t\t\t\t\t\to,\n\t\t\t\t\t\t\t) as JsonObject;\n\t\t\t\t\t\t});\n\t\t\t\t\telse if (ref.doc === \"rewindable\")\n\t\t\t\t\t\tops.push(() =>\n\t\t\t\t\t\t\t(\n\t\t\t\t\t\t\t\tthis.rewindableLog.get(ref.conversationId) ??\n\t\t\t\t\t\t\t\tthis.rewindableLog.set(ref.conversationId, []).get(ref.conversationId)!\n\t\t\t\t\t\t\t).push({ seq, ops: o }),\n\t\t\t\t\t\t);\n\t\t\t\t\telse\n\t\t\t\t\t\tops.push(() =>\n\t\t\t\t\t\t\t(\n\t\t\t\t\t\t\t\tthis.stickyLog.get(ref.conversationId) ??\n\t\t\t\t\t\t\t\tthis.stickyLog.set(ref.conversationId, []).get(ref.conversationId)!\n\t\t\t\t\t\t\t).push(o),\n\t\t\t\t\t\t);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn () => {\n\t\t\tfor (const op of ops) op();\n\t\t\tthis.setNextId(maxId + 1);\n\t\t};\n\t}\n\n\tasync conversation(id: Id, _ctx?: Context) {\n\t\treturn optionalClone(this.conversationsById.get(id));\n\t}\n\tasync conversations(_ctx?: Context) {\n\t\treturn [...this.conversationsById.values()].map(clone);\n\t}\n\tasync entries(ids: readonly Id[], _ctx?: Context) {\n\t\tconst out = new Map<Id, Entry>();\n\t\tfor (const id of ids) {\n\t\t\tconst e = this.entriesById.get(id);\n\t\t\tif (e) out.set(id, clone(e));\n\t\t}\n\t\treturn out;\n\t}\n\t/** Newest-first, fork-aware: after this conversation's own entries, the parent's up to the fork point, and so on. */\n\tasync scanEntries(scan: EntryScan, _ctx?: Context) {\n\t\tconst out: Entry[] = [];\n\t\tlet conversationId: Id | undefined = scan.conversationId;\n\t\tlet cap: Id | undefined = scan.before;\n\t\twhile (conversationId !== undefined && out.length < scan.limit) {\n\t\t\tconst own = this.entriesByConversation.get(conversationId) ?? [];\n\t\t\tfor (let i = own.length - 1; i >= 0 && out.length < scan.limit; i--) {\n\t\t\t\tconst e = own[i]!;\n\t\t\t\tif (cap !== undefined && e.id >= cap) continue;\n\t\t\t\tif (scan.kind !== undefined && e.kind !== scan.kind) continue;\n\t\t\t\tif (scan.withHead && e.head === undefined) continue;\n\t\t\t\tout.push(clone(e));\n\t\t\t}\n\t\t\tconst c = this.conversationsById.get(conversationId);\n\t\t\tconversationId = c?.parent?.conversationId;\n\t\t\tcap = c?.parent === undefined ? undefined : Math.min(cap ?? Infinity, c.parent.at + 1);\n\t\t}\n\t\treturn out;\n\t}\n\tasync task(id: Id, _ctx?: Context) {\n\t\treturn optionalClone(this.tasksById.get(id));\n\t}\n\tasync scanTasks(scan: TaskScan, _ctx?: Context) {\n\t\tconst out: Task[] = [];\n\t\tfor (const t of this.tasksById.values()) {\n\t\t\tif (scan.conversationId !== undefined && t.conversationId !== scan.conversationId) continue;\n\t\t\tif (scan.status !== undefined && !scan.status.includes(t.status)) continue;\n\t\t\tif (scan.kind !== undefined && t.kind !== scan.kind) continue;\n\t\t\tout.push(clone(t));\n\t\t}\n\t\treturn out;\n\t}\n\tasync input(id: Id, _ctx?: Context) {\n\t\treturn optionalClone(this.inputsById.get(id));\n\t}\n\tasync inputByRequest(conversationId: Id, requestId: string, _ctx?: Context) {\n\t\treturn optionalClone(this.inputsByRequest.get(`${conversationId}:${requestId}`));\n\t}\n\n\tasync doc(ref: DocRef, _ctx?: Context): Promise<JsonObject | undefined> {\n\t\tif (ref.doc === \"session\")\n\t\t\treturn this.sessionDoc === undefined ? { plugins: {} } : structuredClone(this.sessionDoc);\n\t\tconst log =\n\t\t\tref.doc === \"rewindable\"\n\t\t\t\t? this.rewindableLog.get(ref.conversationId)?.map((r) => r.ops)\n\t\t\t\t: this.stickyLog.get(ref.conversationId);\n\t\tif (log === undefined) return undefined;\n\t\treturn clone(this.fold(log));\n\t}\n\t/**\n\t * Commit-granular history: the rewindable state after the atomic commit that contains\n\t * entry `at`, walking the fork chain for entries owned by ancestors.\n\t */\n\tasync docAsOf(conversationId: Id, at: Id, _ctx?: Context): Promise<JsonObject | undefined> {\n\t\tconst owner = this.entriesById.get(at)?.conversationId;\n\t\tif (owner === undefined) return undefined;\n\t\tconst chain: Id[] = [];\n\t\tlet c: Conversation | undefined = this.conversationsById.get(conversationId);\n\t\twhile (c !== undefined && c.id !== owner) {\n\t\t\tchain.push(c.id);\n\t\t\tc = c.parent ? this.conversationsById.get(c.parent.conversationId) : undefined;\n\t\t}\n\t\tif (c === undefined) return undefined;\n\t\tconst seqAt = this.entrySeq.get(at) ?? 0;\n\t\tconst log = (this.rewindableLog.get(owner) ?? []).filter((r) => r.seq <= seqAt).map((r) => r.ops);\n\t\treturn log.length === 0 ? undefined : clone(this.fold(log));\n\t}\n\tprotected fold(log: Op[][]): JsonObject {\n\t\tlet start = 0;\n\t\tfor (let i = log.length - 1; i >= 0; i--)\n\t\t\tif (isBase(log[i]!)) {\n\t\t\t\tstart = i;\n\t\t\t\tbreak;\n\t\t\t}\n\t\tlet state: JsonObject = {};\n\t\tfor (let i = start; i < log.length; i++) state = applyImmutable(state, log[i]!) as JsonObject;\n\t\treturn state;\n\t}\n\tasync truncate(ref: DocRef, _ctx?: Context) {\n\t\tif (ref.doc !== \"sticky\") return;\n\t\tconst log = this.stickyLog.get(ref.conversationId);\n\t\tif (log === undefined) return;\n\t\tlet start = 0;\n\t\tfor (let i = log.length - 1; i >= 0; i--)\n\t\t\tif (isBase(log[i]!)) {\n\t\t\t\tstart = i;\n\t\t\t\tbreak;\n\t\t\t}\n\t\tlog.splice(0, start);\n\t}\n\tasync close(_ctx?: Context) {\n\t\tthis.closed = true;\n\t}\n}\n\nfunction clone<T>(value: T): T {\n\treturn JSON.parse(JSON.stringify(value)) as T;\n}\n\nfunction optionalClone<T>(value: T | undefined): T | undefined {\n\treturn value === undefined ? undefined : clone(value);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../../src/harness/pico3/memory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAA0B,KAAK,EAAE,EAAE,MAAM,6BAA6B,CAAC;AAC9E,OAAO,KAAK,EACX,YAAY,EACZ,MAAM,EACN,KAAK,EACL,SAAS,EACT,EAAE,EACF,KAAK,EACL,UAAU,EACV,GAAG,EACH,OAAO,EACP,IAAI,EACJ,QAAQ,EACR,KAAK,EACL,MAAM,YAAY,CAAC;AAEpB;;;;;;GAMG;AACH,qBAAa,aAAc,YAAW,OAAO;IAC5C,SAAS,CAAC,QAAQ,CAAC,iBAAiB,4BAA+B;IACnE,SAAS,CAAC,QAAQ,CAAC,WAAW,qBAAwB;IACtD,SAAS,CAAC,QAAQ,CAAC,qBAAqB,uBAA0B;IAClE,SAAS,CAAC,QAAQ,CAAC,SAAS,gGAAuB;IACnD,SAAS,CAAC,QAAQ,CAAC,UAAU,qBAAwB;IACrD,SAAS,CAAC,QAAQ,CAAC,eAAe,qBAA4B;IAC9D,4FAA4F;IAC5F,SAAS,CAAC,QAAQ,CAAC,aAAa;aAAsB,GAAG;aAAO,EAAE,EAAE;SAAQ;IAC5E,SAAS,CAAC,QAAQ,CAAC,SAAS,sBAAyB;IACrD,SAAS,CAAC,UAAU,EAAE,UAAU,GAAG,SAAS,CAAC;IAC7C,SAAS,CAAC,QAAQ,CAAC,QAAQ,sBAAsB;IACjD,SAAS,CAAC,WAAW,SAAK;IAC1B,SAAS,CAAC,GAAG,EAAE,GAAG,CAAK;IACvB,OAAO,CAAC,MAAM,CAAS;IAEvB,MAAM,IAAI,EAAE,CAEX;IACD,SAAS,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,QAExB;IAEK,MAAM,CAAC,MAAM,EAAE,SAAS,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,CAOlE;IAED,8FAA8F;IAC9F,SAAS,CAAC,KAAK,CAAC,MAAM,EAAE,SAAS,KAAK,EAAE,EAAE,GAAG,EAAE,GAAG,GAAG,MAAM,IAAI,CAsG9D;IAEK,YAAY,CAAC,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,OAAO,qCAExC;IACK,aAAa,CAAC,IAAI,CAAC,EAAE,OAAO,2BAEjC;IACK,OAAO,CAAC,GAAG,EAAE,SAAS,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,OAAO,+BAO/C;IACD,qHAAqH;IAC/G,WAAW,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,EAAE,OAAO,oBAkBhD;IACK,IAAI,CAAC,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,OAAO,yGAEhC;IACK,SAAS,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,OAAO,+FAS7C;IACK,KAAK,CAAC,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,OAAO,8BAEjC;IACK,cAAc,CAAC,cAAc,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,8BAEzE;IAEK,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAStE;IACD;;;OAGG;IACG,OAAO,CAAC,cAAc,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAazF;IACD,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE,GAAG,UAAU,CAUtC;IACK,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,iBAWzC;IACK,KAAK,CAAC,IAAI,CAAC,EAAE,OAAO,iBAEzB;CACD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory.js","sourceRoot":"","sources":["../../../src/harness/pico3/memory.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Context } from \"@earendil-works/chord\";\nimport { applyImmutable, isBase, type Op } from \"@earendil-works/chord/delta\";\nimport type {\n\tConversation,\n\tDocRef,\n\tEntry,\n\tEntryScan,\n\tId,\n\tInput,\n\tJsonObject,\n\tSeq,\n\tStorage,\n\tTask,\n\tTaskScan,\n\tWrite,\n} from \"./types.ts\";\n\n/**\n * In-memory Storage. The reference backend, and the read path of JsonlStorage.\n *\n * A batch is validated and staged in full before any table changes: one failed\n * batch changes no table, no document, no ID high-water, no sequence. Committed\n * IDs are never reused; IDs minted but never committed may be reused after reopen.\n */\nexport class MemoryStorage implements Storage {\n\tprotected readonly conversationsById = new Map<Id, Conversation>();\n\tprotected readonly entriesById = new Map<Id, Entry>();\n\tprotected readonly entriesByConversation = new Map<Id, Entry[]>(); // ascending\n\tprotected readonly tasksById = new Map<Id, Task>();\n\tprotected readonly inputsById = new Map<Id, Input>();\n\tprotected readonly inputsByRequest = new Map<string, Input>();\n\t/** Rewindable docs keep their full op history with the seq of each batch, for `docAsOf`. */\n\tprotected readonly rewindableLog = new Map<Id, { seq: Seq; ops: Op[] }[]>();\n\tprotected readonly stickyLog = new Map<Id, Op[][]>();\n\tprotected sessionDoc: JsonObject | undefined;\n\tprotected readonly entrySeq = new Map<Id, Seq>(); // entry id → seq of its batch\n\tprotected nextIdValue = 1;\n\tprotected seq: Seq = 0;\n\tprivate closed = false;\n\n\tmintId(): Id {\n\t\treturn this.nextIdValue++;\n\t}\n\tprotected setNextId(n: Id) {\n\t\tthis.nextIdValue = Math.max(this.nextIdValue, n);\n\t}\n\n\tasync commit(writes: readonly Write[], _ctx: Context): Promise<Seq> {\n\t\tif (this.closed) throw new Error(\"storage closed\");\n\t\tconst seq = this.seq + 1;\n\t\tconst staged = this.stage(writes, seq); // throws before any mutation\n\t\tstaged();\n\t\tthis.seq = seq;\n\t\treturn seq;\n\t}\n\n\t/** Validate the whole batch against the current tables; return a function that applies it. */\n\tprotected stage(writes: readonly Write[], seq: Seq): () => void {\n\t\tconst ops: (() => void)[] = [];\n\t\tconst created = new Set<Id>();\n\t\tlet maxId = 0;\n\t\tconst claim = (id: Id, what: string) => {\n\t\t\tif (!Number.isSafeInteger(id) || id <= 0) throw new Error(`${what}: invalid id ${id}`);\n\t\t\tif (created.has(id)) throw new Error(`${what}: id ${id} created twice in one batch`);\n\t\t\tcreated.add(id);\n\t\t\tmaxId = Math.max(maxId, id);\n\t\t};\n\t\tfor (const w of writes) {\n\t\t\tswitch (w.type) {\n\t\t\t\tcase \"conversation\": {\n\t\t\t\t\tif (this.conversationsById.has(w.conversation.id))\n\t\t\t\t\t\tthrow new Error(`conversation ${w.conversation.id} exists`);\n\t\t\t\t\tclaim(w.conversation.id, \"conversation\");\n\t\t\t\t\tconst c = clone(w.conversation);\n\t\t\t\t\tops.push(() => {\n\t\t\t\t\t\tthis.conversationsById.set(c.id, c);\n\t\t\t\t\t\tthis.entriesByConversation.set(c.id, []);\n\t\t\t\t\t});\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase \"entry\": {\n\t\t\t\t\tif (this.entriesById.has(w.entry.id)) throw new Error(`entry ${w.entry.id} exists`);\n\t\t\t\t\tclaim(w.entry.id, \"entry\");\n\t\t\t\t\tconst e = clone(w.entry);\n\t\t\t\t\tops.push(() => {\n\t\t\t\t\t\tthis.entriesById.set(e.id, e);\n\t\t\t\t\t\t(\n\t\t\t\t\t\t\tthis.entriesByConversation.get(e.conversationId) ??\n\t\t\t\t\t\t\tthis.entriesByConversation.set(e.conversationId, []).get(e.conversationId)!\n\t\t\t\t\t\t).push(e);\n\t\t\t\t\t\tthis.entrySeq.set(e.id, seq);\n\t\t\t\t\t});\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase \"task\": {\n\t\t\t\t\tif (this.tasksById.has(w.task.id)) throw new Error(`task ${w.task.id} exists`);\n\t\t\t\t\tclaim(w.task.id, \"task\");\n\t\t\t\t\tconst t = clone(w.task);\n\t\t\t\t\tops.push(() => this.tasksById.set(t.id, t));\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase \"task.patch\": {\n\t\t\t\t\tconst prev =\n\t\t\t\t\t\tthis.tasksById.get(w.patch.id) ??\n\t\t\t\t\t\t[...writes]\n\t\t\t\t\t\t\t.filter((x): x is Extract<Write, { type: \"task\" }> => x.type === \"task\")\n\t\t\t\t\t\t\t.find((x) => x.task.id === w.patch.id)?.task;\n\t\t\t\t\tif (prev === undefined) throw new Error(`patch for unknown task ${w.patch.id}`);\n\t\t\t\t\tconst p = clone(w.patch);\n\t\t\t\t\tops.push(() => {\n\t\t\t\t\t\tconst cur = this.tasksById.get(p.id)!;\n\t\t\t\t\t\tconst { id: _i, ...fields } = p;\n\t\t\t\t\t\tconst next = { ...cur, ...fields } as Task;\n\t\t\t\t\t\tif (p.checkpoint === null) delete (next as { checkpoint?: unknown }).checkpoint;\n\t\t\t\t\t\tthis.tasksById.set(p.id, next);\n\t\t\t\t\t});\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase \"input\": {\n\t\t\t\t\tconst i = clone(w.input);\n\t\t\t\t\tif (!this.inputsById.has(i.id)) claim(i.id, \"input\");\n\t\t\t\t\tops.push(() => {\n\t\t\t\t\t\tthis.inputsById.set(i.id, i);\n\t\t\t\t\t\tif (i.requestId !== undefined) this.inputsByRequest.set(`${i.conversationId}:${i.requestId}`, i);\n\t\t\t\t\t});\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase \"doc\": {\n\t\t\t\t\tconst ref = clone(w.ref);\n\t\t\t\t\tconst o = clone(w.ops);\n\t\t\t\t\tif (ref.doc === \"session\")\n\t\t\t\t\t\tops.push(() => {\n\t\t\t\t\t\t\tthis.sessionDoc = applyImmutable(\n\t\t\t\t\t\t\t\t(this.sessionDoc ?? { plugins: {} }) as JsonObject,\n\t\t\t\t\t\t\t\to,\n\t\t\t\t\t\t\t) as JsonObject;\n\t\t\t\t\t\t});\n\t\t\t\t\telse if (ref.doc === \"rewindable\")\n\t\t\t\t\t\tops.push(() =>\n\t\t\t\t\t\t\t(\n\t\t\t\t\t\t\t\tthis.rewindableLog.get(ref.conversationId) ??\n\t\t\t\t\t\t\t\tthis.rewindableLog.set(ref.conversationId, []).get(ref.conversationId)!\n\t\t\t\t\t\t\t).push({ seq, ops: o }),\n\t\t\t\t\t\t);\n\t\t\t\t\telse\n\t\t\t\t\t\tops.push(() =>\n\t\t\t\t\t\t\t(\n\t\t\t\t\t\t\t\tthis.stickyLog.get(ref.conversationId) ??\n\t\t\t\t\t\t\t\tthis.stickyLog.set(ref.conversationId, []).get(ref.conversationId)!\n\t\t\t\t\t\t\t).push(o),\n\t\t\t\t\t\t);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn () => {\n\t\t\tfor (const op of ops) op();\n\t\t\tthis.setNextId(maxId + 1);\n\t\t};\n\t}\n\n\tasync conversation(id: Id, _ctx?: Context) {\n\t\treturn optionalClone(this.conversationsById.get(id));\n\t}\n\tasync conversations(_ctx?: Context) {\n\t\treturn [...this.conversationsById.values()].map(clone);\n\t}\n\tasync entries(ids: readonly Id[], _ctx?: Context) {\n\t\tconst out = new Map<Id, Entry>();\n\t\tfor (const id of ids) {\n\t\t\tconst e = this.entriesById.get(id);\n\t\t\tif (e) out.set(id, clone(e));\n\t\t}\n\t\treturn out;\n\t}\n\t/** Newest-first, fork-aware: after this conversation's own entries, the parent's up to the fork point, and so on. */\n\tasync scanEntries(scan: EntryScan, _ctx?: Context) {\n\t\tconst out: Entry[] = [];\n\t\tlet conversationId: Id | undefined = scan.conversationId;\n\t\tlet cap: Id | undefined = scan.before;\n\t\twhile (conversationId !== undefined && out.length < scan.limit) {\n\t\t\tconst own = this.entriesByConversation.get(conversationId) ?? [];\n\t\t\tfor (let i = own.length - 1; i >= 0 && out.length < scan.limit; i--) {\n\t\t\t\tconst e = own[i]!;\n\t\t\t\tif (cap !== undefined && e.id >= cap) continue;\n\t\t\t\tif (scan.kind !== undefined && e.kind !== scan.kind) continue;\n\t\t\t\tif (scan.withHead && e.head === undefined) continue;\n\t\t\t\tout.push(clone(e));\n\t\t\t}\n\t\t\tconst c = this.conversationsById.get(conversationId);\n\t\t\tconversationId = c?.parent?.conversationId;\n\t\t\tcap = c?.parent === undefined ? undefined : Math.min(cap ?? Infinity, c.parent.at + 1);\n\t\t}\n\t\treturn out;\n\t}\n\tasync task(id: Id, _ctx?: Context) {\n\t\treturn optionalClone(this.tasksById.get(id));\n\t}\n\tasync scanTasks(scan: TaskScan, _ctx?: Context) {\n\t\tconst out: Task[] = [];\n\t\tfor (const t of this.tasksById.values()) {\n\t\t\tif (scan.conversationId !== undefined && t.conversationId !== scan.conversationId) continue;\n\t\t\tif (scan.status !== undefined && !scan.status.includes(t.status)) continue;\n\t\t\tif (scan.kind !== undefined && t.kind !== scan.kind) continue;\n\t\t\tout.push(clone(t));\n\t\t}\n\t\treturn out;\n\t}\n\tasync input(id: Id, _ctx?: Context) {\n\t\treturn optionalClone(this.inputsById.get(id));\n\t}\n\tasync inputByRequest(conversationId: Id, requestId: string, _ctx?: Context) {\n\t\treturn optionalClone(this.inputsByRequest.get(`${conversationId}:${requestId}`));\n\t}\n\n\tasync doc(ref: DocRef, _ctx?: Context): Promise<JsonObject | undefined> {\n\t\tif (ref.doc === \"session\")\n\t\t\treturn this.sessionDoc === undefined ? { plugins: {} } : structuredClone(this.sessionDoc);\n\t\tconst log =\n\t\t\tref.doc === \"rewindable\"\n\t\t\t\t? this.rewindableLog.get(ref.conversationId)?.map((r) => r.ops)\n\t\t\t\t: this.stickyLog.get(ref.conversationId);\n\t\tif (log === undefined) return undefined;\n\t\treturn clone(this.fold(log));\n\t}\n\t/**\n\t * Commit-granular history: the rewindable state after the atomic commit that contains\n\t * entry `at`, walking the fork chain for entries owned by ancestors.\n\t */\n\tasync docAsOf(conversationId: Id, at: Id, _ctx?: Context): Promise<JsonObject | undefined> {\n\t\tconst owner = this.entriesById.get(at)?.conversationId;\n\t\tif (owner === undefined) return undefined;\n\t\tconst chain: Id[] = [];\n\t\tlet c: Conversation | undefined = this.conversationsById.get(conversationId);\n\t\twhile (c !== undefined && c.id !== owner) {\n\t\t\tchain.push(c.id);\n\t\t\tc = c.parent ? this.conversationsById.get(c.parent.conversationId) : undefined;\n\t\t}\n\t\tif (c === undefined) return undefined;\n\t\tconst seqAt = this.entrySeq.get(at) ?? 0;\n\t\tconst log = (this.rewindableLog.get(owner) ?? []).filter((r) => r.seq <= seqAt).map((r) => r.ops);\n\t\treturn log.length === 0 ? undefined : clone(this.fold(log));\n\t}\n\tprotected fold(log: Op[][]): JsonObject {\n\t\tlet start = 0;\n\t\tfor (let i = log.length - 1; i >= 0; i--)\n\t\t\tif (isBase(log[i]!)) {\n\t\t\t\tstart = i;\n\t\t\t\tbreak;\n\t\t\t}\n\t\tlet state: JsonObject = {};\n\t\tfor (let i = start; i < log.length; i++) state = applyImmutable(state, log[i]!) as JsonObject;\n\t\treturn state;\n\t}\n\tasync truncate(ref: DocRef, _ctx?: Context) {\n\t\tif (ref.doc !== \"sticky\") return;\n\t\tconst log = this.stickyLog.get(ref.conversationId);\n\t\tif (log === undefined) return;\n\t\tlet start = 0;\n\t\tfor (let i = log.length - 1; i >= 0; i--)\n\t\t\tif (isBase(log[i]!)) {\n\t\t\t\tstart = i;\n\t\t\t\tbreak;\n\t\t\t}\n\t\tlog.splice(0, start);\n\t}\n\tasync close(_ctx?: Context) {\n\t\tthis.closed = true;\n\t}\n}\n\nfunction clone<T>(value: T): T {\n\treturn JSON.parse(JSON.stringify(value)) as T;\n}\n\nfunction optionalClone<T>(value: T | undefined): T | undefined {\n\treturn value === undefined ? undefined : clone(value);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"memory.js","sourceRoot":"","sources":["../../../src/harness/pico3/memory.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Context } from \"@earendil-works/chord\";\nimport { applyImmutable, isBase, type Op } from \"@earendil-works/chord/delta\";\nimport type {\n\tConversation,\n\tDocRef,\n\tEntry,\n\tEntryScan,\n\tId,\n\tInput,\n\tJsonObject,\n\tSeq,\n\tStorage,\n\tTask,\n\tTaskScan,\n\tWrite,\n} from \"./types.ts\";\n\n/**\n * In-memory Storage. The reference backend, and the read path of JsonlStorage.\n *\n * A batch is validated and staged in full before any table changes: one failed\n * batch changes no table, no document, no ID high-water, no sequence. Committed\n * IDs are never reused; IDs minted but never committed may be reused after reopen.\n */\nexport class MemoryStorage implements Storage {\n\tprotected readonly conversationsById = new Map<Id, Conversation>();\n\tprotected readonly entriesById = new Map<Id, Entry>();\n\tprotected readonly entriesByConversation = new Map<Id, Entry[]>(); // ascending\n\tprotected readonly tasksById = new Map<Id, Task>();\n\tprotected readonly inputsById = new Map<Id, Input>();\n\tprotected readonly inputsByRequest = new Map<string, Input>();\n\t/** Rewindable docs keep their full op history with the seq of each batch, for `docAsOf`. */\n\tprotected readonly rewindableLog = new Map<Id, { seq: Seq; ops: Op[] }[]>();\n\tprotected readonly stickyLog = new Map<Id, Op[][]>();\n\tprotected sessionDoc: JsonObject | undefined;\n\tprotected readonly entrySeq = new Map<Id, Seq>(); // entry id → seq of its batch\n\tprotected nextIdValue = 1;\n\tprotected seq: Seq = 0;\n\tprivate closed = false;\n\n\tmintId(): Id {\n\t\treturn this.nextIdValue++;\n\t}\n\tprotected setNextId(n: Id) {\n\t\tthis.nextIdValue = Math.max(this.nextIdValue, n);\n\t}\n\n\tasync commit(writes: readonly Write[], _ctx: Context): Promise<Seq> {\n\t\tif (this.closed) throw new Error(\"storage closed\");\n\t\tconst seq = this.seq + 1;\n\t\tconst staged = this.stage(writes, seq); // throws before any mutation\n\t\tstaged();\n\t\tthis.seq = seq;\n\t\treturn seq;\n\t}\n\n\t/** Validate the whole batch against the current tables; return a function that applies it. */\n\tprotected stage(writes: readonly Write[], seq: Seq): () => void {\n\t\tconst ops: (() => void)[] = [];\n\t\tconst created = new Set<Id>();\n\t\tlet maxId = 0;\n\t\tconst claim = (id: Id, what: string) => {\n\t\t\tif (!Number.isSafeInteger(id) || id <= 0) throw new Error(`${what}: invalid id ${id}`);\n\t\t\tif (created.has(id)) throw new Error(`${what}: id ${id} created twice in one batch`);\n\t\t\tcreated.add(id);\n\t\t\tmaxId = Math.max(maxId, id);\n\t\t};\n\t\tfor (const w of writes) {\n\t\t\tswitch (w.type) {\n\t\t\t\tcase \"conversation\": {\n\t\t\t\t\tif (this.conversationsById.has(w.conversation.id))\n\t\t\t\t\t\tthrow new Error(`conversation ${w.conversation.id} exists`);\n\t\t\t\t\tclaim(w.conversation.id, \"conversation\");\n\t\t\t\t\tconst c = clone(w.conversation);\n\t\t\t\t\tops.push(() => {\n\t\t\t\t\t\tthis.conversationsById.set(c.id, c);\n\t\t\t\t\t\tthis.entriesByConversation.set(c.id, []);\n\t\t\t\t\t});\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase \"entry\": {\n\t\t\t\t\tif (this.entriesById.has(w.entry.id)) throw new Error(`entry ${w.entry.id} exists`);\n\t\t\t\t\tclaim(w.entry.id, \"entry\");\n\t\t\t\t\tconst e = clone(w.entry);\n\t\t\t\t\tops.push(() => {\n\t\t\t\t\t\tthis.entriesById.set(e.id, e);\n\t\t\t\t\t\t(\n\t\t\t\t\t\t\tthis.entriesByConversation.get(e.conversationId) ??\n\t\t\t\t\t\t\tthis.entriesByConversation.set(e.conversationId, []).get(e.conversationId)!\n\t\t\t\t\t\t).push(e);\n\t\t\t\t\t\tthis.entrySeq.set(e.id, seq);\n\t\t\t\t\t});\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase \"task\": {\n\t\t\t\t\tif (this.tasksById.has(w.task.id)) throw new Error(`task ${w.task.id} exists`);\n\t\t\t\t\tclaim(w.task.id, \"task\");\n\t\t\t\t\tconst t = clone(w.task);\n\t\t\t\t\tops.push(() => this.tasksById.set(t.id, t));\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase \"task.patch\": {\n\t\t\t\t\tconst prev =\n\t\t\t\t\t\tthis.tasksById.get(w.patch.id) ??\n\t\t\t\t\t\t[...writes]\n\t\t\t\t\t\t\t.filter((x): x is Extract<Write, { type: \"task\" }> => x.type === \"task\")\n\t\t\t\t\t\t\t.find((x) => x.task.id === w.patch.id)?.task;\n\t\t\t\t\tif (prev === undefined) throw new Error(`patch for unknown task ${w.patch.id}`);\n\t\t\t\t\tconst p = clone(w.patch);\n\t\t\t\t\tops.push(() => {\n\t\t\t\t\t\tconst cur = this.tasksById.get(p.id)!;\n\t\t\t\t\t\tconst { id: _i, ...fields } = p;\n\t\t\t\t\t\tconst next = { ...cur, ...fields } as Task;\n\t\t\t\t\t\tif (p.checkpoint === null) delete (next as { checkpoint?: unknown }).checkpoint;\n\t\t\t\t\t\tthis.tasksById.set(p.id, next);\n\t\t\t\t\t});\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase \"input\": {\n\t\t\t\t\tconst i = clone(w.input);\n\t\t\t\t\tif (!this.inputsById.has(i.id)) claim(i.id, \"input\");\n\t\t\t\t\tops.push(() => {\n\t\t\t\t\t\tthis.inputsById.set(i.id, i);\n\t\t\t\t\t\tif (i.requestId !== undefined) this.inputsByRequest.set(`${i.conversationId}:${i.requestId}`, i);\n\t\t\t\t\t});\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase \"doc\": {\n\t\t\t\t\tconst ref = clone(w.ref);\n\t\t\t\t\tconst o = clone(w.ops);\n\t\t\t\t\tif (ref.doc === \"session\")\n\t\t\t\t\t\tops.push(() => {\n\t\t\t\t\t\t\tthis.sessionDoc = applyImmutable(\n\t\t\t\t\t\t\t\t(this.sessionDoc ?? { plugins: {} }) as JsonObject,\n\t\t\t\t\t\t\t\to,\n\t\t\t\t\t\t\t) as JsonObject;\n\t\t\t\t\t\t});\n\t\t\t\t\telse if (ref.doc === \"rewindable\")\n\t\t\t\t\t\tops.push(() =>\n\t\t\t\t\t\t\t(\n\t\t\t\t\t\t\t\tthis.rewindableLog.get(ref.conversationId) ??\n\t\t\t\t\t\t\t\tthis.rewindableLog.set(ref.conversationId, []).get(ref.conversationId)!\n\t\t\t\t\t\t\t).push({ seq, ops: o }),\n\t\t\t\t\t\t);\n\t\t\t\t\telse\n\t\t\t\t\t\tops.push(() =>\n\t\t\t\t\t\t\t(\n\t\t\t\t\t\t\t\tthis.stickyLog.get(ref.conversationId) ??\n\t\t\t\t\t\t\t\tthis.stickyLog.set(ref.conversationId, []).get(ref.conversationId)!\n\t\t\t\t\t\t\t).push(o),\n\t\t\t\t\t\t);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn () => {\n\t\t\tfor (const op of ops) op();\n\t\t\tthis.setNextId(maxId + 1);\n\t\t};\n\t}\n\n\tasync conversation(id: Id, _ctx?: Context) {\n\t\treturn optionalClone(this.conversationsById.get(id));\n\t}\n\tasync conversations(_ctx?: Context) {\n\t\treturn [...this.conversationsById.values()].map(clone);\n\t}\n\tasync entries(ids: readonly Id[], _ctx?: Context) {\n\t\tconst out = new Map<Id, Entry>();\n\t\tfor (const id of ids) {\n\t\t\tconst e = this.entriesById.get(id);\n\t\t\tif (e) out.set(id, clone(e));\n\t\t}\n\t\treturn out;\n\t}\n\t/** Newest-first, fork-aware: after this conversation's own entries, the parent's up to the fork point, and so on. */\n\tasync scanEntries(scan: EntryScan, _ctx?: Context) {\n\t\tconst out: Entry[] = [];\n\t\tlet conversationId: Id | undefined = scan.conversationId;\n\t\tlet cap: Id | undefined = scan.before;\n\t\twhile (conversationId !== undefined && out.length < scan.limit) {\n\t\t\tconst own = this.entriesByConversation.get(conversationId) ?? [];\n\t\t\tfor (let i = own.length - 1; i >= 0 && out.length < scan.limit; i--) {\n\t\t\t\tconst e = own[i]!;\n\t\t\t\tif (cap !== undefined && e.id >= cap) continue;\n\t\t\t\tif (scan.kind !== undefined && e.kind !== scan.kind) continue;\n\t\t\t\tif (scan.withHead && e.head === undefined) continue;\n\t\t\t\tout.push(clone(e));\n\t\t\t}\n\t\t\tconst c = this.conversationsById.get(conversationId);\n\t\t\tconversationId = c?.parent?.conversationId;\n\t\t\tcap = c?.parent === undefined ? undefined : Math.min(cap ?? Infinity, c.parent.at + 1);\n\t\t}\n\t\treturn out;\n\t}\n\tasync task(id: Id, _ctx?: Context) {\n\t\treturn optionalClone(this.tasksById.get(id));\n\t}\n\tasync scanTasks(scan: TaskScan, _ctx?: Context) {\n\t\tconst out: Task[] = [];\n\t\tfor (const t of this.tasksById.values()) {\n\t\t\tif (scan.conversationId !== undefined && t.conversationId !== scan.conversationId) continue;\n\t\t\tif (scan.status !== undefined && !scan.status.includes(t.status)) continue;\n\t\t\tif (scan.kind !== undefined && t.kind !== scan.kind) continue;\n\t\t\tout.push(clone(t));\n\t\t}\n\t\treturn out;\n\t}\n\tasync input(id: Id, _ctx?: Context) {\n\t\treturn optionalClone(this.inputsById.get(id));\n\t}\n\tasync inputByRequest(conversationId: Id, requestId: string, _ctx?: Context) {\n\t\treturn optionalClone(this.inputsByRequest.get(`${conversationId}:${requestId}`));\n\t}\n\n\tasync doc(ref: DocRef, _ctx?: Context): Promise<JsonObject | undefined> {\n\t\tif (ref.doc === \"session\")\n\t\t\treturn this.sessionDoc === undefined ? { plugins: {} } : structuredClone(this.sessionDoc);\n\t\tconst log =\n\t\t\tref.doc === \"rewindable\"\n\t\t\t\t? this.rewindableLog.get(ref.conversationId)?.map((r) => r.ops)\n\t\t\t\t: this.stickyLog.get(ref.conversationId);\n\t\tif (log === undefined) return undefined;\n\t\treturn clone(this.fold(log));\n\t}\n\t/**\n\t * Commit-granular history: the rewindable state after the atomic commit that contains\n\t * entry `at`, walking the fork chain for entries owned by ancestors.\n\t */\n\tasync docAsOf(conversationId: Id, at: Id, _ctx?: Context): Promise<JsonObject | undefined> {\n\t\tconst owner = this.entriesById.get(at)?.conversationId;\n\t\tif (owner === undefined) return undefined;\n\t\tconst chain: Id[] = [];\n\t\tlet c: Conversation | undefined = this.conversationsById.get(conversationId);\n\t\twhile (c !== undefined && c.id !== owner) {\n\t\t\tchain.push(c.id);\n\t\t\tc = c.parent ? this.conversationsById.get(c.parent.conversationId) : undefined;\n\t\t}\n\t\tif (c === undefined) return undefined;\n\t\tconst seqAt = this.entrySeq.get(at) ?? 0;\n\t\tconst log = (this.rewindableLog.get(owner) ?? []).filter((r) => r.seq <= seqAt).map((r) => r.ops);\n\t\treturn log.length === 0 ? undefined : clone(this.fold(log));\n\t}\n\tprotected fold(log: Op[][]): JsonObject {\n\t\tlet start = 0;\n\t\tfor (let i = log.length - 1; i >= 0; i--)\n\t\t\tif (isBase(log[i]!)) {\n\t\t\t\tstart = i;\n\t\t\t\tbreak;\n\t\t\t}\n\t\tlet state: JsonObject = {};\n\t\tfor (let i = start; i < log.length; i++) state = applyImmutable(state, log[i]!) as JsonObject;\n\t\treturn state;\n\t}\n\tasync truncate(ref: DocRef, _ctx?: Context) {\n\t\tif (ref.doc !== \"sticky\") return;\n\t\tconst log = this.stickyLog.get(ref.conversationId);\n\t\tif (log === undefined) return;\n\t\tlet start = 0;\n\t\tfor (let i = log.length - 1; i >= 0; i--)\n\t\t\tif (isBase(log[i]!)) {\n\t\t\t\tstart = i;\n\t\t\t\tbreak;\n\t\t\t}\n\t\tlog.splice(0, start);\n\t}\n\tasync close(_ctx?: Context) {\n\t\tthis.closed = true;\n\t}\n}\n\nfunction clone<T>(value: T): T {\n\treturn JSON.parse(JSON.stringify(value)) as T;\n}\n\nfunction optionalClone<T>(value: T | undefined): T | undefined {\n\treturn value === undefined ? undefined : clone(value);\n}\n"]}
|
|
@@ -26,14 +26,17 @@ export declare class Scheduler {
|
|
|
26
26
|
hold(): () => void;
|
|
27
27
|
kick(): void;
|
|
28
28
|
private drain;
|
|
29
|
+
/** On the line: reserve every eligible task. */
|
|
29
30
|
private reserveEligible;
|
|
30
31
|
private dispatch;
|
|
31
32
|
private lease;
|
|
33
|
+
/** The phase loop. Each handler gets a capability lease revoked when that handler's promise returns. */
|
|
32
34
|
private runPhases;
|
|
33
35
|
/** Mark, revoke, signal, join. The scheduler then reserves the fresh abort on its next drain. */
|
|
34
36
|
abortTask(id: Id, ctx: Context): Promise<"marked" | "terminal">;
|
|
35
37
|
waitForTask(id: Id, ctx: Context): Promise<Task>;
|
|
36
38
|
waitForInput(id: Id, ctx: Context): Promise<Input>;
|
|
39
|
+
/** Read state and install the waiter in one line operation; the wait itself happens off-line. */
|
|
37
40
|
private waiter;
|
|
38
41
|
waitForIdle(conversationId: Id | undefined, ctx: Context): Promise<void>;
|
|
39
42
|
private isIdle;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../../../src/harness/pico3/scheduler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAErD,OAAO,KAAK,EAAE,OAAO,EAAU,MAAM,cAAc,CAAC;AACpD,OAAO,EACN,KAAK,OAAO,EAGZ,KAAK,EAAE,EACP,KAAK,KAAK,EAEV,KAAK,OAAO,EAGZ,KAAK,OAAO,EAEZ,KAAK,IAAI,EAET,MAAM,YAAY,CAAC;AASpB,MAAM,WAAW,aAAa;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC;IACxF,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;IAC/B,GAAG,EAAE,OAAO,CAAC;CACb;AAmDD,qBAAa,SAAS;IACrB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAgB;IACrC,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,KAAK,CAAK;IAClB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA6B;IACzD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAyC;IACrE,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA0C;IACvE,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAsE;IAElG,YAAY,IAAI,EAAE,aAAa,EAoB9B;IAED,MAAM,SAGL;IACD,IAAI,SAEH;IACD,IAAI,IAAI,MAAM,IAAI,CASjB;IACD,IAAI,SAIH;YAEa,KAAK;YAmBL,eAAe;IAyC7B,OAAO,CAAC,QAAQ;IA2GhB,OAAO,CAAC,KAAK;YAiBC,SAAS;IAgDvB,iGAAiG;IAC3F,SAAS,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,GAAG,UAAU,CAAC,CAqBpE;IAID,WAAW,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAK/C;IACD,YAAY,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAKjD;YAEa,MAAM;IA6Bd,WAAW,CAAC,cAAc,EAAE,EAAE,GAAG,SAAS,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAwB7E;IACD,OAAO,CAAC,MAAM;IAKd,OAAO,CAAC,SAAS;IAIjB,qEAAqE;IAC/D,OAAO,kBAIZ;IACD,SAAS,IAAI,OAAO,CAEnB;IACD,IAAI,eAAe,WAElB;CACD","sourcesContent":["import type { Context } from \"@earendil-works/chord\";\nimport { withAbortSignal } from \"@earendil-works/chord/context\";\nimport type { Session, TxImpl } from \"./session.ts\";\nimport {\n\ttype AnyKind,\n\ttype Checkpoint,\n\ttype Completion,\n\ttype Id,\n\ttype Input,\n\tInvocationToken,\n\ttype Invoker,\n\ttype JsonValue,\n\ttype Outcome,\n\ttype Runtime,\n\ttype Step,\n\ttype Task,\n\tTaskContractFault,\n} from \"./types.ts\";\n\ninterface Invocation {\n\ttask: Task;\n\tmode: \"run\" | \"abort\";\n\tcontroller: AbortController;\n\tdone: Promise<void>;\n}\n\nexport interface SchedulerDeps {\n\tsession: Session;\n\tkinds: ReadonlyMap<string, AnyKind>;\n\truntime(task: Task, invoker: Extract<Invoker, { type: \"task\" }>, ctx: Context): Runtime;\n\tonReport(error: unknown): void;\n\tctx: Context;\n}\n\n/**\n * The erased-kind adapter: the one place a concrete `Kind<…>` is called through `AnyKind`\n * and its outputs are validated. A handler that throws or returns an invalid shape is a\n * contract fault, recorded as `{ status: \"faulted\" }` — never a manufactured declared failure.\n */\ntype Handler = (task: Task, rt: Runtime, ctx: Context) => Promise<Step<Checkpoint, JsonValue, JsonValue>>;\nfunction handlerFor(kind: AnyKind, phase: string | undefined): Handler {\n\tconst h = phase === undefined ? kind.initial : kind.phases[phase];\n\tif (typeof h !== \"function\") throw new TaskContractFault(kind.name, `no handler for phase ${phase ?? \"initial\"}`);\n\treturn h as Handler;\n}\nfunction validateStep(kind: AnyKind, step: unknown): Step<Checkpoint, JsonValue, JsonValue> {\n\tif (typeof step !== \"object\" || step === null)\n\t\tthrow new TaskContractFault(kind.name, \"handler returned a non-object step\");\n\tif (\"done\" in step && typeof (step as { done: unknown }).done === \"function\")\n\t\treturn step as Step<Checkpoint, JsonValue, JsonValue>;\n\tif (\"next\" in step) {\n\t\tconst n = (step as { next: unknown }).next;\n\t\tif (typeof n === \"function\") return step as Step<Checkpoint, JsonValue, JsonValue>;\n\t\tif (typeof n === \"object\" && n !== null && typeof (n as { phase?: unknown }).phase === \"string\") {\n\t\t\tif (!((n as { phase: string }).phase in kind.phases))\n\t\t\t\tthrow new TaskContractFault(kind.name, `transition to unknown phase ${(n as { phase: string }).phase}`);\n\t\t\treturn step as Step<Checkpoint, JsonValue, JsonValue>;\n\t\t}\n\t}\n\tthrow new TaskContractFault(kind.name, \"handler returned an invalid step\");\n}\nfunction validateCompletion(kind: AnyKind, c: unknown): Completion<JsonValue, JsonValue> {\n\tif (typeof c === \"object\" && c !== null) {\n\t\tconst s = (c as { status?: unknown }).status;\n\t\tif (s === \"completed\" && \"result\" in c) return c as Completion<JsonValue, JsonValue>;\n\t\tif (s === \"failed\" && \"failure\" in c) return c as Completion<JsonValue, JsonValue>;\n\t}\n\tthrow new TaskContractFault(kind.name, \"closure returned an invalid completion\");\n}\nfunction validateCheckpoint(kind: AnyKind, cp: unknown): Checkpoint {\n\tif (typeof cp !== \"object\" || cp === null || typeof (cp as { phase?: unknown }).phase !== \"string\")\n\t\tthrow new TaskContractFault(kind.name, \"invalid checkpoint\");\n\tconst phase = (cp as { phase: string }).phase;\n\tif (!(phase in kind.phases)) throw new TaskContractFault(kind.name, `checkpoint names unknown phase ${phase}`);\n\tif (kind.inflight?.includes(phase))\n\t\tthrow new TaskContractFault(\n\t\t\tkind.name,\n\t\t\t`transition into in-flight phase ${phase}; write it with rt.commit before the effect instead`,\n\t\t);\n\tJSON.stringify(cp);\n\treturn cp as Checkpoint;\n}\n\nexport class Scheduler {\n\tprivate readonly deps: SchedulerDeps;\n\tprivate enabled = false;\n\tprivate holds = 0;\n\tprivate dirty = false;\n\tprivate draining = false;\n\tprivate readonly invocations = new Map<Id, Invocation>();\n\tprivate readonly taskWaiters = new Map<Id, Set<(t: Task) => void>>();\n\tprivate readonly inputWaiters = new Map<Id, Set<(i: Input) => void>>();\n\tprivate readonly idleWaiters = new Set<{ conversationId: Id | undefined; resolve: () => void }>();\n\n\tconstructor(deps: SchedulerDeps) {\n\t\tthis.deps = deps;\n\t\tdeps.session.listeners.add((r) => {\n\t\t\tfor (const t of r.changes.tasks) {\n\t\t\t\tconst inv = this.invocations.get(t.id);\n\t\t\t\tif (t.abort === true && inv?.mode === \"run\") inv.controller.abort();\n\t\t\t}\n\t\t\tfor (const task of r.changes.tasks)\n\t\t\t\tif (task.status === \"terminal\")\n\t\t\t\t\tthis.taskWaiters.get(task.id)?.forEach((waiter) => {\n\t\t\t\t\t\twaiter(task);\n\t\t\t\t\t});\n\t\t\tfor (const input of r.changes.inputs)\n\t\t\t\tif (input.status === \"done\" || input.status === \"unanswered\")\n\t\t\t\t\tthis.inputWaiters.get(input.id)?.forEach((waiter) => {\n\t\t\t\t\t\twaiter(input);\n\t\t\t\t\t});\n\t\t\tif (r.changes.tasks.length > 0) this.kick();\n\t\t\tthis.checkIdle();\n\t\t});\n\t}\n\n\tresume() {\n\t\tthis.enabled = true;\n\t\tthis.kick();\n\t}\n\tstop() {\n\t\tthis.enabled = false;\n\t}\n\thold(): () => void {\n\t\tthis.holds++;\n\t\tlet released = false;\n\t\treturn () => {\n\t\t\tif (released) return;\n\t\t\treleased = true;\n\t\t\tthis.holds--;\n\t\t\tif (this.holds === 0) this.kick();\n\t\t};\n\t}\n\tkick() {\n\t\tif (!this.enabled) return;\n\t\tthis.dirty = true;\n\t\tif (this.holds === 0 && !this.draining) this.drain().catch((e) => this.deps.onReport(e));\n\t}\n\n\tprivate async drain() {\n\t\tthis.draining = true;\n\t\ttry {\n\t\t\twhile (this.dirty && this.enabled && this.holds === 0) {\n\t\t\t\tthis.dirty = false;\n\t\t\t\tconst reserved = await this.reserveEligible();\n\t\t\t\tif (!this.enabled || this.holds > 0) {\n\t\t\t\t\tthis.dirty = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tfor (const { task, mode } of reserved) this.dispatch(task, mode);\n\t\t\t}\n\t\t} finally {\n\t\t\tthis.draining = false;\n\t\t\tthis.checkIdle();\n\t\t}\n\t}\n\n\t/** On the line: reserve every eligible task. */\n\tprivate async reserveEligible(): Promise<{ task: Task; mode: \"run\" | \"abort\" }[]> {\n\t\tconst { session } = this.deps;\n\t\tconst out: { task: Task; mode: \"run\" | \"abort\" }[] = [];\n\t\tawait session.commit(\n\t\t\t{ type: \"kernel\" },\n\t\t\tasync (tx) => {\n\t\t\t\tfor (const task of [...session.liveTasks.values()]) {\n\t\t\t\t\tif (!this.deps.kinds.has(task.kind)) continue;\n\t\t\t\t\tconst inv = this.invocations.get(task.id);\n\t\t\t\t\tif (task.abort === true) {\n\t\t\t\t\t\tif (inv?.mode === \"abort\") continue;\n\t\t\t\t\t\tif (inv?.mode === \"run\") continue; // winding down; dispatched after it returns\n\t\t\t\t\t\tconst running: Task = task.status === \"pending\" ? { ...task, status: \"running\" } : task;\n\t\t\t\t\t\tif (running !== task) tx.setTask(running);\n\t\t\t\t\t\tout.push({ task: running, mode: \"abort\" });\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (inv !== undefined) continue;\n\t\t\t\t\tif (task.status === \"pending\") {\n\t\t\t\t\t\tlet ready = true;\n\t\t\t\t\t\tfor (const dep of task.after) {\n\t\t\t\t\t\t\tconst d = await tx.task(dep);\n\t\t\t\t\t\t\tif (d === undefined || d.status !== \"terminal\") {\n\t\t\t\t\t\t\t\tready = false;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (!ready) continue;\n\t\t\t\t\t\tconst running: Task = { ...task, status: \"running\" };\n\t\t\t\t\t\ttx.setTask(running);\n\t\t\t\t\t\tout.push({ task: running, mode: \"run\" });\n\t\t\t\t\t} else if (task.status === \"running\") {\n\t\t\t\t\t\tout.push({ task, mode: \"run\" }); // found at open: dispatch into its current phase\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\tthis.deps.ctx,\n\t\t);\n\t\treturn out;\n\t}\n\n\tprivate dispatch(task: Task, mode: \"run\" | \"abort\") {\n\t\tconst { session } = this.deps;\n\t\tconst kind = this.deps.kinds.get(task.kind);\n\t\tif (kind === undefined) {\n\t\t\tthis.deps.onReport(new Error(`unknown kind ${task.kind} for task ${task.id}`));\n\t\t\treturn;\n\t\t}\n\t\tconst controller = new AbortController();\n\t\tconst ctx = withAbortSignal(controller.signal, this.deps.ctx);\n\t\tconst done = (async () => {\n\t\t\ttry {\n\t\t\t\tif (mode === \"run\") {\n\t\t\t\t\tconst closure = await this.runPhases(task, kind, ctx);\n\t\t\t\t\tif (closure === undefined || controller.signal.aborted) return;\n\t\t\t\t\tconst lease = this.lease(task, kind, mode, ctx);\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait session.commit(\n\t\t\t\t\t\t\tlease.invoker,\n\t\t\t\t\t\t\tasync (tx, lineCtx, control) => {\n\t\t\t\t\t\t\t\tconst current = session.liveTasks.get(task.id);\n\t\t\t\t\t\t\t\tif (current === undefined || current.abort === true) return;\n\t\t\t\t\t\t\t\tconst completion = validateCompletion(\n\t\t\t\t\t\t\t\t\tkind,\n\t\t\t\t\t\t\t\t\tawait (closure as (tx: TxImpl, task: Task, ctx: Context) => unknown)(tx, current, lineCtx),\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tconst patched = (await tx.task(task.id)) ?? current;\n\t\t\t\t\t\t\t\tcontrol.setTask({ ...patched, status: \"terminal\", outcome: completion });\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tctx,\n\t\t\t\t\t\t\t{ closing: true },\n\t\t\t\t\t\t);\n\t\t\t\t\t} finally {\n\t\t\t\t\t\tlease.token.revoke();\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tconst handlerLease = this.lease(task, kind, mode, ctx);\n\t\t\t\t\tlet closure: (tx: TxImpl, task: Task, ctx: Context) => unknown;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tclosure = await (\n\t\t\t\t\t\t\tkind.abort as (\n\t\t\t\t\t\t\t\ttask: Task,\n\t\t\t\t\t\t\t\truntime: Runtime,\n\t\t\t\t\t\t\t\tctx: Context,\n\t\t\t\t\t\t\t) => Promise<(tx: TxImpl, task: Task, ctx: Context) => unknown>\n\t\t\t\t\t\t)(task, handlerLease.runtime, ctx);\n\t\t\t\t\t} finally {\n\t\t\t\t\t\thandlerLease.token.revoke();\n\t\t\t\t\t}\n\t\t\t\t\tconst closureLease = this.lease(task, kind, mode, ctx);\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait session.commit(\n\t\t\t\t\t\t\tclosureLease.invoker,\n\t\t\t\t\t\t\tasync (tx, lineCtx, control) => {\n\t\t\t\t\t\t\t\tconst current = session.liveTasks.get(task.id);\n\t\t\t\t\t\t\t\tif (current === undefined) return;\n\t\t\t\t\t\t\t\tconst result = (await closure(tx, current, lineCtx)) as JsonValue;\n\t\t\t\t\t\t\t\tJSON.stringify(result);\n\t\t\t\t\t\t\t\tconst patched = (await tx.task(task.id)) ?? current;\n\t\t\t\t\t\t\t\tcontrol.setTask({ ...patched, status: \"terminal\", outcome: { status: \"aborted\", result } });\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tctx,\n\t\t\t\t\t\t\t{ closing: true },\n\t\t\t\t\t\t);\n\t\t\t\t\t} finally {\n\t\t\t\t\t\tclosureLease.token.revoke();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tif (controller.signal.aborted) return;\n\t\t\t\t// Contract fault or unexpected throw: the task ends `faulted`, never as a declared failure.\n\t\t\t\tthis.deps.onReport(error);\n\t\t\t\tawait session\n\t\t\t\t\t.commit(\n\t\t\t\t\t\t{ type: \"kernel\" },\n\t\t\t\t\t\tasync (tx) => {\n\t\t\t\t\t\t\tconst current = session.liveTasks.get(task.id);\n\t\t\t\t\t\t\tif (current === undefined) return;\n\t\t\t\t\t\t\tconst outcome: Outcome = {\n\t\t\t\t\t\t\t\tstatus: \"faulted\",\n\t\t\t\t\t\t\t\terror: error instanceof TaskContractFault ? error.message : `${kind.name}: ${String(error)}`,\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\ttx.setTask({ ...current, status: \"terminal\", outcome });\n\t\t\t\t\t\t\t// A faulted turn task: its inputs would otherwise stay placed forever; the turn state is stale.\n\t\t\t\t\t\t\tif (kind.turn) {\n\t\t\t\t\t\t\t\tconst inputs = (current.input as { inputs?: unknown }).inputs;\n\t\t\t\t\t\t\t\tif (Array.isArray(inputs))\n\t\t\t\t\t\t\t\t\tawait tx.resolveInputs(\n\t\t\t\t\t\t\t\t\t\tinputs.filter((i): i is Id => typeof i === \"number\"),\n\t\t\t\t\t\t\t\t\t\t{ status: \"unanswered\", reason: \"failed\", detail: outcome.error },\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\ttx.sticky(current.conversationId).turn = { tools: [] };\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\tthis.deps.ctx,\n\t\t\t\t\t\t{ docs: [{ doc: \"sticky\", conversationId: task.conversationId }] },\n\t\t\t\t\t)\n\t\t\t\t\t.catch((e) => this.deps.onReport(e));\n\t\t\t} finally {\n\t\t\t\tthis.invocations.delete(task.id);\n\t\t\t\tconst now = session.liveTasks.get(task.id);\n\t\t\t\tif (now === undefined) await session.retire(task, this.deps.ctx).catch((e) => this.deps.onReport(e));\n\t\t\t\tthis.kick();\n\t\t\t}\n\t\t})();\n\t\tthis.invocations.set(task.id, { task, mode, controller, done });\n\t}\n\n\tprivate lease(task: Task, kind: AnyKind, mode: \"run\" | \"abort\", ctx: Context) {\n\t\tconst token = new InvocationToken(task.id, mode);\n\t\tconst invoker: Extract<Invoker, { type: \"task\" }> = {\n\t\t\ttype: \"task\",\n\t\t\ttoken,\n\t\t\tid: task.id,\n\t\t\tconversationId: task.conversationId,\n\t\t\tkind,\n\t\t\tcore:\n\t\t\t\ttask.kind.startsWith(\"pi.\") &&\n\t\t\t\t[\"pi.generation\", \"pi.tool\", \"pi.post_tools\", \"pi.collapse\"].includes(task.kind),\n\t\t\tmode,\n\t\t};\n\t\treturn { token, invoker, runtime: this.deps.runtime(task, invoker, ctx) };\n\t}\n\n\t/** The phase loop. Each handler gets a capability lease revoked when that handler's promise returns. */\n\tprivate async runPhases(task: Task, kind: AnyKind, ctx: Context): Promise<unknown> {\n\t\tconst { session } = this.deps;\n\t\tlet current = task;\n\t\tfor (;;) {\n\t\t\tconst cp = current.checkpoint;\n\t\t\tconst handler = handlerFor(kind, cp?.phase);\n\t\t\tconst handlerLease = this.lease(task, kind, \"run\", ctx);\n\t\t\tlet step: Step<Checkpoint, JsonValue, JsonValue>;\n\t\t\ttry {\n\t\t\t\tstep = validateStep(kind, await handler(current, handlerLease.runtime, ctx));\n\t\t\t} finally {\n\t\t\t\thandlerLease.token.revoke();\n\t\t\t}\n\t\t\tif (\"done\" in step) return step.done;\n\t\t\tif (ctx.abortSignal?.aborted) return undefined;\n\t\t\tconst transitionLease = this.lease(task, kind, \"run\", ctx);\n\t\t\tlet outcome: { value: \"discard\" | \"retry\" | \"terminal\" | \"advanced\" };\n\t\t\ttry {\n\t\t\t\toutcome = await session.commit(\n\t\t\t\t\ttransitionLease.invoker,\n\t\t\t\t\tasync (tx, lineCtx, control) => {\n\t\t\t\t\t\tconst live = session.liveTasks.get(task.id);\n\t\t\t\t\t\tif (live === undefined || live.abort === true) return \"discard\" as const;\n\t\t\t\t\t\tconst next = typeof step.next === \"function\" ? await step.next(tx, live, lineCtx) : step.next;\n\t\t\t\t\t\tif (next === \"retry\") return \"retry\" as const;\n\t\t\t\t\t\tif (typeof next === \"object\" && next !== null && \"status\" in next) {\n\t\t\t\t\t\t\tconst patched = (await tx.task(task.id)) ?? live;\n\t\t\t\t\t\t\tcontrol.setTask({ ...patched, status: \"terminal\", outcome: validateCompletion(kind, next) });\n\t\t\t\t\t\t\treturn \"terminal\" as const;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst checkpoint = validateCheckpoint(kind, next);\n\t\t\t\t\t\ttx.checkpoint(checkpoint);\n\t\t\t\t\t\tcurrent = { ...live, checkpoint };\n\t\t\t\t\t\treturn \"advanced\" as const;\n\t\t\t\t\t},\n\t\t\t\t\tctx,\n\t\t\t\t);\n\t\t\t} finally {\n\t\t\t\ttransitionLease.token.revoke();\n\t\t\t}\n\t\t\tif (outcome.value === \"retry\") {\n\t\t\t\tcurrent = session.liveTasks.get(task.id) ?? current;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (outcome.value !== \"advanced\") return undefined;\n\t\t}\n\t}\n\n\t/** Mark, revoke, signal, join. The scheduler then reserves the fresh abort on its next drain. */\n\tasync abortTask(id: Id, ctx: Context): Promise<\"marked\" | \"terminal\"> {\n\t\tconst { session } = this.deps;\n\t\tconst r = await session.commit(\n\t\t\t{ type: \"kernel\" },\n\t\t\tasync (tx) => {\n\t\t\t\tconst task = await tx.task(id);\n\t\t\t\tif (task === undefined) throw new Error(`task ${id} not found`);\n\t\t\t\tif (task.status === \"terminal\") return \"terminal\" as const;\n\t\t\t\tif (task.abort !== true) tx.setTask({ ...task, abort: true });\n\t\t\t\treturn \"marked\" as const;\n\t\t\t},\n\t\t\tctx,\n\t\t);\n\t\tif (r.value === \"terminal\") return \"terminal\";\n\t\tconst inv = this.invocations.get(id);\n\t\tif (inv?.mode === \"run\") {\n\t\t\tinv.controller.abort();\n\t\t\tawait inv.done;\n\t\t}\n\t\tthis.kick();\n\t\treturn \"marked\";\n\t}\n\n\t// --- waiters: registered on the line, atomically with the state read -------------------\n\n\twaitForTask(id: Id, ctx: Context): Promise<Task> {\n\t\treturn this.waiter(ctx, this.taskWaiters, id, (lineCtx) => {\n\t\t\tconst live = this.deps.session.liveTasks.get(id);\n\t\t\treturn live === undefined ? this.deps.session.storage.task(id, lineCtx) : Promise.resolve(undefined);\n\t\t});\n\t}\n\twaitForInput(id: Id, ctx: Context): Promise<Input> {\n\t\treturn this.waiter(ctx, this.inputWaiters, id, async (lineCtx) => {\n\t\t\tconst i = await this.deps.session.storage.input(id, lineCtx);\n\t\t\treturn i !== undefined && (i.status === \"done\" || i.status === \"unanswered\") ? i : undefined;\n\t\t});\n\t}\n\t/** Read state and install the waiter in one line operation; the wait itself happens off-line. */\n\tprivate async waiter<T>(\n\t\tctx: Context,\n\t\ttable: Map<Id, Set<(v: T) => void>>,\n\t\tid: Id,\n\t\tterminal: (ctx: Context) => Promise<T | undefined>,\n\t): Promise<T> {\n\t\tctx.abortSignal?.throwIfAborted();\n\t\tconst r = await this.deps.session.onLine(async (lineCtx): Promise<{ now: T } | { pending: Promise<T> }> => {\n\t\t\tconst now = await terminal(lineCtx);\n\t\t\tif (now !== undefined) return { now };\n\t\t\treturn {\n\t\t\t\tpending: new Promise<T>((resolve, reject) => {\n\t\t\t\t\tconst set = table.get(id) ?? table.set(id, new Set()).get(id)!;\n\t\t\t\t\tconst w = (v: T) => {\n\t\t\t\t\t\tset.delete(w);\n\t\t\t\t\t\tctx.abortSignal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\tresolve(v);\n\t\t\t\t\t};\n\t\t\t\t\tconst onAbort = () => {\n\t\t\t\t\t\tset.delete(w);\n\t\t\t\t\t\treject(ctx.abortSignal?.reason ?? new Error(\"aborted\"));\n\t\t\t\t\t};\n\t\t\t\t\tset.add(w);\n\t\t\t\t\tctx.abortSignal?.addEventListener(\"abort\", onAbort, { once: true });\n\t\t\t\t}),\n\t\t\t};\n\t\t}, ctx);\n\t\treturn \"now\" in r ? r.now : r.pending;\n\t}\n\tasync waitForIdle(conversationId: Id | undefined, ctx: Context): Promise<void> {\n\t\tctx.abortSignal?.throwIfAborted();\n\t\tconst r = await this.deps.session.onLine((): { pending?: Promise<void> } => {\n\t\t\tif (this.isIdle(conversationId)) return {};\n\t\t\treturn {\n\t\t\t\tpending: new Promise<void>((resolve, reject) => {\n\t\t\t\t\tconst w = {\n\t\t\t\t\t\tconversationId,\n\t\t\t\t\t\tresolve: () => {\n\t\t\t\t\t\t\tthis.idleWaiters.delete(w);\n\t\t\t\t\t\t\tctx.abortSignal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\t\tresolve();\n\t\t\t\t\t\t},\n\t\t\t\t\t};\n\t\t\t\t\tconst onAbort = () => {\n\t\t\t\t\t\tthis.idleWaiters.delete(w);\n\t\t\t\t\t\treject(ctx.abortSignal?.reason ?? new Error(\"aborted\"));\n\t\t\t\t\t};\n\t\t\t\t\tthis.idleWaiters.add(w);\n\t\t\t\t\tctx.abortSignal?.addEventListener(\"abort\", onAbort, { once: true });\n\t\t\t\t}),\n\t\t\t};\n\t\t}, ctx);\n\t\treturn r.pending;\n\t}\n\tprivate isIdle(conversationId: Id | undefined): boolean {\n\t\tfor (const t of this.deps.session.liveTasks.values())\n\t\t\tif ((conversationId === undefined || t.conversationId === conversationId) && !t.background) return false;\n\t\treturn true;\n\t}\n\tprivate checkIdle() {\n\t\tfor (const w of [...this.idleWaiters]) if (this.isIdle(w.conversationId) && !this.draining) w.resolve();\n\t}\n\n\t/** Signal every invocation and wait for them; nothing is written. */\n\tasync joinAll() {\n\t\tthis.enabled = false;\n\t\tfor (const inv of this.invocations.values()) inv.controller.abort();\n\t\tawait Promise.allSettled([...this.invocations.values()].map((invocation) => invocation.done));\n\t}\n\tquiescent(): boolean {\n\t\treturn this.invocations.size === 0;\n\t}\n\tget liveInvocations() {\n\t\treturn this.invocations.size;\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../../../src/harness/pico3/scheduler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAErD,OAAO,KAAK,EAAE,OAAO,EAAU,MAAM,cAAc,CAAC;AACpD,OAAO,EACN,KAAK,OAAO,EAGZ,KAAK,EAAE,EACP,KAAK,KAAK,EAEV,KAAK,OAAO,EAGZ,KAAK,OAAO,EAEZ,KAAK,IAAI,EAET,MAAM,YAAY,CAAC;AASpB,MAAM,WAAW,aAAa;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC;IACxF,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;IAC/B,GAAG,EAAE,OAAO,CAAC;CACb;AAmDD,qBAAa,SAAS;IACrB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAgB;IACrC,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,KAAK,CAAK;IAClB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA6B;IACzD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAyC;IACrE,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA0C;IACvE,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAsE;IAElG,YAAY,IAAI,EAAE,aAAa,EAoB9B;IAED,MAAM,SAGL;IACD,IAAI,SAEH;IACD,IAAI,IAAI,MAAM,IAAI,CASjB;IACD,IAAI,SAIH;YAEa,KAAK;IAkBnB,gDAAgD;YAClC,eAAe;IAyC7B,OAAO,CAAC,QAAQ;IA2GhB,OAAO,CAAC,KAAK;IAgBb,wGAAwG;YAC1F,SAAS;IAgDvB,iGAAiG;IAC3F,SAAS,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,GAAG,UAAU,CAAC,CAqBpE;IAID,WAAW,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAK/C;IACD,YAAY,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAKjD;IACD,iGAAiG;YACnF,MAAM;IA6Bd,WAAW,CAAC,cAAc,EAAE,EAAE,GAAG,SAAS,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAwB7E;IACD,OAAO,CAAC,MAAM;IAKd,OAAO,CAAC,SAAS;IAIjB,qEAAqE;IAC/D,OAAO,kBAIZ;IACD,SAAS,IAAI,OAAO,CAEnB;IACD,IAAI,eAAe,WAElB;CACD"}
|