@m4ike1/ion-agent-core 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +622 -0
- package/dist/agent-loop.d.ts +24 -0
- package/dist/agent-loop.d.ts.map +1 -0
- package/dist/agent-loop.js +560 -0
- package/dist/agent-loop.js.map +1 -0
- package/dist/agent.d.ts +122 -0
- package/dist/agent.d.ts.map +1 -0
- package/dist/agent.js +422 -0
- package/dist/agent.js.map +1 -0
- package/dist/harness/agent-harness.d.ts +716 -0
- package/dist/harness/agent-harness.d.ts.map +1 -0
- package/dist/harness/agent-harness.js +6 -0
- package/dist/harness/agent-harness.js.map +1 -0
- package/dist/harness/compaction/branch-summarization.d.ts +68 -0
- package/dist/harness/compaction/branch-summarization.d.ts.map +1 -0
- package/dist/harness/compaction/branch-summarization.js +176 -0
- package/dist/harness/compaction/branch-summarization.js.map +1 -0
- package/dist/harness/compaction/compaction.d.ts +126 -0
- package/dist/harness/compaction/compaction.d.ts.map +1 -0
- package/dist/harness/compaction/compaction.js +560 -0
- package/dist/harness/compaction/compaction.js.map +1 -0
- package/dist/harness/compaction/utils.d.ts +25 -0
- package/dist/harness/compaction/utils.d.ts.map +1 -0
- package/dist/harness/compaction/utils.js +120 -0
- package/dist/harness/compaction/utils.js.map +1 -0
- package/dist/harness/config.d.ts +9 -0
- package/dist/harness/config.d.ts.map +1 -0
- package/dist/harness/config.js +35 -0
- package/dist/harness/config.js.map +1 -0
- package/dist/harness/context.d.ts +9 -0
- package/dist/harness/context.d.ts.map +1 -0
- package/dist/harness/context.js +13 -0
- package/dist/harness/context.js.map +1 -0
- package/dist/harness/env/nodejs.d.ts +43 -0
- package/dist/harness/env/nodejs.d.ts.map +1 -0
- package/dist/harness/env/nodejs.js +865 -0
- package/dist/harness/env/nodejs.js.map +1 -0
- package/dist/harness/events.d.ts +25 -0
- package/dist/harness/events.d.ts.map +1 -0
- package/dist/harness/events.js +250 -0
- package/dist/harness/events.js.map +1 -0
- package/dist/harness/execution/assistant.d.ts +42 -0
- package/dist/harness/execution/assistant.d.ts.map +1 -0
- package/dist/harness/execution/assistant.js +82 -0
- package/dist/harness/execution/assistant.js.map +1 -0
- package/dist/harness/execution/effect-gate.d.ts +22 -0
- package/dist/harness/execution/effect-gate.d.ts.map +1 -0
- package/dist/harness/execution/effect-gate.js +49 -0
- package/dist/harness/execution/effect-gate.js.map +1 -0
- package/dist/harness/execution/tools.d.ts +67 -0
- package/dist/harness/execution/tools.d.ts.map +1 -0
- package/dist/harness/execution/tools.js +121 -0
- package/dist/harness/execution/tools.js.map +1 -0
- package/dist/harness/hooks.d.ts +38 -0
- package/dist/harness/hooks.d.ts.map +1 -0
- package/dist/harness/hooks.js +406 -0
- package/dist/harness/hooks.js.map +1 -0
- package/dist/harness/messages.d.ts +51 -0
- package/dist/harness/messages.d.ts.map +1 -0
- package/dist/harness/messages.js +102 -0
- package/dist/harness/messages.js.map +1 -0
- package/dist/harness/prompt-templates.d.ts +49 -0
- package/dist/harness/prompt-templates.d.ts.map +1 -0
- package/dist/harness/prompt-templates.js +225 -0
- package/dist/harness/prompt-templates.js.map +1 -0
- package/dist/harness/result.d.ts +133 -0
- package/dist/harness/result.d.ts.map +1 -0
- package/dist/harness/result.js +81 -0
- package/dist/harness/result.js.map +1 -0
- package/dist/harness/runtime/drive/boundary.d.ts +28 -0
- package/dist/harness/runtime/drive/boundary.d.ts.map +1 -0
- package/dist/harness/runtime/drive/boundary.js +173 -0
- package/dist/harness/runtime/drive/boundary.js.map +1 -0
- package/dist/harness/runtime/drive/checkpoint.d.ts +8 -0
- package/dist/harness/runtime/drive/checkpoint.d.ts.map +1 -0
- package/dist/harness/runtime/drive/checkpoint.js +133 -0
- package/dist/harness/runtime/drive/checkpoint.js.map +1 -0
- package/dist/harness/runtime/drive/deferred.d.ts +15 -0
- package/dist/harness/runtime/drive/deferred.d.ts.map +1 -0
- package/dist/harness/runtime/drive/deferred.js +179 -0
- package/dist/harness/runtime/drive/deferred.js.map +1 -0
- package/dist/harness/runtime/drive/generation.d.ts +8 -0
- package/dist/harness/runtime/drive/generation.d.ts.map +1 -0
- package/dist/harness/runtime/drive/generation.js +205 -0
- package/dist/harness/runtime/drive/generation.js.map +1 -0
- package/dist/harness/runtime/drive/reconcile.d.ts +5 -0
- package/dist/harness/runtime/drive/reconcile.d.ts.map +1 -0
- package/dist/harness/runtime/drive/reconcile.js +140 -0
- package/dist/harness/runtime/drive/reconcile.js.map +1 -0
- package/dist/harness/runtime/drive/recovery.d.ts +8 -0
- package/dist/harness/runtime/drive/recovery.d.ts.map +1 -0
- package/dist/harness/runtime/drive/recovery.js +85 -0
- package/dist/harness/runtime/drive/recovery.js.map +1 -0
- package/dist/harness/runtime/drive/response.d.ts +23 -0
- package/dist/harness/runtime/drive/response.d.ts.map +1 -0
- package/dist/harness/runtime/drive/response.js +394 -0
- package/dist/harness/runtime/drive/response.js.map +1 -0
- package/dist/harness/runtime/drive/retry.d.ts +4 -0
- package/dist/harness/runtime/drive/retry.d.ts.map +1 -0
- package/dist/harness/runtime/drive/retry.js +34 -0
- package/dist/harness/runtime/drive/retry.js.map +1 -0
- package/dist/harness/runtime/drive/structural.d.ts +32 -0
- package/dist/harness/runtime/drive/structural.d.ts.map +1 -0
- package/dist/harness/runtime/drive/structural.js +929 -0
- package/dist/harness/runtime/drive/structural.js.map +1 -0
- package/dist/harness/runtime/drive/terminal.d.ts +7 -0
- package/dist/harness/runtime/drive/terminal.d.ts.map +1 -0
- package/dist/harness/runtime/drive/terminal.js +49 -0
- package/dist/harness/runtime/drive/terminal.js.map +1 -0
- package/dist/harness/runtime/drive/tool-placement.d.ts +14 -0
- package/dist/harness/runtime/drive/tool-placement.d.ts.map +1 -0
- package/dist/harness/runtime/drive/tool-placement.js +244 -0
- package/dist/harness/runtime/drive/tool-placement.js.map +1 -0
- package/dist/harness/runtime/drive/tools.d.ts +6 -0
- package/dist/harness/runtime/drive/tools.d.ts.map +1 -0
- package/dist/harness/runtime/drive/tools.js +449 -0
- package/dist/harness/runtime/drive/tools.js.map +1 -0
- package/dist/harness/runtime/drive.d.ts +6 -0
- package/dist/harness/runtime/drive.d.ts.map +1 -0
- package/dist/harness/runtime/drive.js +93 -0
- package/dist/harness/runtime/drive.js.map +1 -0
- package/dist/harness/runtime/harness.d.ts +59 -0
- package/dist/harness/runtime/harness.d.ts.map +1 -0
- package/dist/harness/runtime/harness.js +311 -0
- package/dist/harness/runtime/harness.js.map +1 -0
- package/dist/harness/runtime/index.d.ts +2 -0
- package/dist/harness/runtime/index.d.ts.map +1 -0
- package/dist/harness/runtime/index.js +2 -0
- package/dist/harness/runtime/index.js.map +1 -0
- package/dist/harness/runtime/lane.d.ts +101 -0
- package/dist/harness/runtime/lane.d.ts.map +1 -0
- package/dist/harness/runtime/lane.js +1575 -0
- package/dist/harness/runtime/lane.js.map +1 -0
- package/dist/harness/runtime/progress.d.ts +15 -0
- package/dist/harness/runtime/progress.d.ts.map +1 -0
- package/dist/harness/runtime/progress.js +66 -0
- package/dist/harness/runtime/progress.js.map +1 -0
- package/dist/harness/runtime/reducer.d.ts +5 -0
- package/dist/harness/runtime/reducer.d.ts.map +1 -0
- package/dist/harness/runtime/reducer.js +240 -0
- package/dist/harness/runtime/reducer.js.map +1 -0
- package/dist/harness/runtime/restore.d.ts +24 -0
- package/dist/harness/runtime/restore.d.ts.map +1 -0
- package/dist/harness/runtime/restore.js +117 -0
- package/dist/harness/runtime/restore.js.map +1 -0
- package/dist/harness/runtime/transcript.d.ts +21 -0
- package/dist/harness/runtime/transcript.d.ts.map +1 -0
- package/dist/harness/runtime/transcript.js +72 -0
- package/dist/harness/runtime/transcript.js.map +1 -0
- package/dist/harness/runtime/types.d.ts +105 -0
- package/dist/harness/runtime/types.d.ts.map +1 -0
- package/dist/harness/runtime/types.js +61 -0
- package/dist/harness/runtime/types.js.map +1 -0
- package/dist/harness/session/commit.d.ts +53 -0
- package/dist/harness/session/commit.d.ts.map +1 -0
- package/dist/harness/session/commit.js +57 -0
- package/dist/harness/session/commit.js.map +1 -0
- package/dist/harness/session/context.d.ts +10 -0
- package/dist/harness/session/context.d.ts.map +1 -0
- package/dist/harness/session/context.js +49 -0
- package/dist/harness/session/context.js.map +1 -0
- package/dist/harness/session/fork-policy.d.ts +21 -0
- package/dist/harness/session/fork-policy.d.ts.map +1 -0
- package/dist/harness/session/fork-policy.js +55 -0
- package/dist/harness/session/fork-policy.js.map +1 -0
- package/dist/harness/session/fork.d.ts +16 -0
- package/dist/harness/session/fork.d.ts.map +1 -0
- package/dist/harness/session/fork.js +79 -0
- package/dist/harness/session/fork.js.map +1 -0
- package/dist/harness/session/in-memory-storage-state.d.ts +39 -0
- package/dist/harness/session/in-memory-storage-state.d.ts.map +1 -0
- package/dist/harness/session/in-memory-storage-state.js +276 -0
- package/dist/harness/session/in-memory-storage-state.js.map +1 -0
- package/dist/harness/session/index.d.ts +11 -0
- package/dist/harness/session/index.d.ts.map +1 -0
- package/dist/harness/session/index.js +9 -0
- package/dist/harness/session/index.js.map +1 -0
- package/dist/harness/session/jsonl/codec.d.ts +21 -0
- package/dist/harness/session/jsonl/codec.d.ts.map +1 -0
- package/dist/harness/session/jsonl/codec.js +45 -0
- package/dist/harness/session/jsonl/codec.js.map +1 -0
- package/dist/harness/session/jsonl/fork.d.ts +38 -0
- package/dist/harness/session/jsonl/fork.d.ts.map +1 -0
- package/dist/harness/session/jsonl/fork.js +264 -0
- package/dist/harness/session/jsonl/fork.js.map +1 -0
- package/dist/harness/session/jsonl/index.d.ts +4 -0
- package/dist/harness/session/jsonl/index.d.ts.map +1 -0
- package/dist/harness/session/jsonl/index.js +4 -0
- package/dist/harness/session/jsonl/index.js.map +1 -0
- package/dist/harness/session/jsonl/io.d.ts +14 -0
- package/dist/harness/session/jsonl/io.d.ts.map +1 -0
- package/dist/harness/session/jsonl/io.js +86 -0
- package/dist/harness/session/jsonl/io.js.map +1 -0
- package/dist/harness/session/jsonl/legacy-v3.d.ts +43 -0
- package/dist/harness/session/jsonl/legacy-v3.d.ts.map +1 -0
- package/dist/harness/session/jsonl/legacy-v3.js +462 -0
- package/dist/harness/session/jsonl/legacy-v3.js.map +1 -0
- package/dist/harness/session/jsonl/repo.d.ts +35 -0
- package/dist/harness/session/jsonl/repo.d.ts.map +1 -0
- package/dist/harness/session/jsonl/repo.js +301 -0
- package/dist/harness/session/jsonl/repo.js.map +1 -0
- package/dist/harness/session/jsonl/storage.d.ts +40 -0
- package/dist/harness/session/jsonl/storage.d.ts.map +1 -0
- package/dist/harness/session/jsonl/storage.js +200 -0
- package/dist/harness/session/jsonl/storage.js.map +1 -0
- package/dist/harness/session/jsonl/types.d.ts +39 -0
- package/dist/harness/session/jsonl/types.d.ts.map +1 -0
- package/dist/harness/session/jsonl/types.js +3 -0
- package/dist/harness/session/jsonl/types.js.map +1 -0
- package/dist/harness/session/memory.d.ts +48 -0
- package/dist/harness/session/memory.d.ts.map +1 -0
- package/dist/harness/session/memory.js +369 -0
- package/dist/harness/session/memory.js.map +1 -0
- package/dist/harness/session/mutation-line.d.ts +8 -0
- package/dist/harness/session/mutation-line.d.ts.map +1 -0
- package/dist/harness/session/mutation-line.js +21 -0
- package/dist/harness/session/mutation-line.js.map +1 -0
- package/dist/harness/session/session.d.ts +82 -0
- package/dist/harness/session/session.d.ts.map +1 -0
- package/dist/harness/session/session.js +361 -0
- package/dist/harness/session/session.js.map +1 -0
- package/dist/harness/session/testing/benchmark/datasets.d.ts +12 -0
- package/dist/harness/session/testing/benchmark/datasets.d.ts.map +1 -0
- package/dist/harness/session/testing/benchmark/datasets.js +24 -0
- package/dist/harness/session/testing/benchmark/datasets.js.map +1 -0
- package/dist/harness/session/testing/benchmark/session-repo.d.ts +42 -0
- package/dist/harness/session/testing/benchmark/session-repo.d.ts.map +1 -0
- package/dist/harness/session/testing/benchmark/session-repo.js +127 -0
- package/dist/harness/session/testing/benchmark/session-repo.js.map +1 -0
- package/dist/harness/session/testing/benchmark/storage.d.ts +25 -0
- package/dist/harness/session/testing/benchmark/storage.d.ts.map +1 -0
- package/dist/harness/session/testing/benchmark/storage.js +114 -0
- package/dist/harness/session/testing/benchmark/storage.js.map +1 -0
- package/dist/harness/session/testing/conformance/session-repo.d.ts +23 -0
- package/dist/harness/session/testing/conformance/session-repo.d.ts.map +1 -0
- package/dist/harness/session/testing/conformance/session-repo.js +809 -0
- package/dist/harness/session/testing/conformance/session-repo.js.map +1 -0
- package/dist/harness/session/testing/conformance/storage.d.ts +4 -0
- package/dist/harness/session/testing/conformance/storage.d.ts.map +1 -0
- package/dist/harness/session/testing/conformance/storage.js +600 -0
- package/dist/harness/session/testing/conformance/storage.js.map +1 -0
- package/dist/harness/session/testing/gating-storage.d.ts +26 -0
- package/dist/harness/session/testing/gating-storage.d.ts.map +1 -0
- package/dist/harness/session/testing/gating-storage.js +100 -0
- package/dist/harness/session/testing/gating-storage.js.map +1 -0
- package/dist/harness/session/testing/index.d.ts +10 -0
- package/dist/harness/session/testing/index.d.ts.map +1 -0
- package/dist/harness/session/testing/index.js +9 -0
- package/dist/harness/session/testing/index.js.map +1 -0
- package/dist/harness/session/testing/instrumented-storage.d.ts +11 -0
- package/dist/harness/session/testing/instrumented-storage.d.ts.map +1 -0
- package/dist/harness/session/testing/instrumented-storage.js +16 -0
- package/dist/harness/session/testing/instrumented-storage.js.map +1 -0
- package/dist/harness/session/testing/storage-decorator.d.ts +20 -0
- package/dist/harness/session/testing/storage-decorator.d.ts.map +1 -0
- package/dist/harness/session/testing/storage-decorator.js +41 -0
- package/dist/harness/session/testing/storage-decorator.js.map +1 -0
- package/dist/harness/session/testing/types.d.ts +12 -0
- package/dist/harness/session/testing/types.d.ts.map +1 -0
- package/dist/harness/session/testing/types.js +2 -0
- package/dist/harness/session/testing/types.js.map +1 -0
- package/dist/harness/session/types.d.ts +512 -0
- package/dist/harness/session/types.d.ts.map +1 -0
- package/dist/harness/session/types.js +9 -0
- package/dist/harness/session/types.js.map +1 -0
- package/dist/harness/session/values.d.ts +95 -0
- package/dist/harness/session/values.d.ts.map +1 -0
- package/dist/harness/session/values.js +81 -0
- package/dist/harness/session/values.js.map +1 -0
- package/dist/harness/skills.d.ts +46 -0
- package/dist/harness/skills.d.ts.map +1 -0
- package/dist/harness/skills.js +326 -0
- package/dist/harness/skills.js.map +1 -0
- package/dist/harness/system-prompt.d.ts +3 -0
- package/dist/harness/system-prompt.d.ts.map +1 -0
- package/dist/harness/system-prompt.js +30 -0
- package/dist/harness/system-prompt.js.map +1 -0
- package/dist/harness/telemetry.d.ts +1242 -0
- package/dist/harness/telemetry.d.ts.map +1 -0
- package/dist/harness/telemetry.js +527 -0
- package/dist/harness/telemetry.js.map +1 -0
- package/dist/harness/tools/bash.d.ts +27 -0
- package/dist/harness/tools/bash.d.ts.map +1 -0
- package/dist/harness/tools/bash.js +105 -0
- package/dist/harness/tools/bash.js.map +1 -0
- package/dist/harness/tools/edit-diff.d.ts +89 -0
- package/dist/harness/tools/edit-diff.d.ts.map +1 -0
- package/dist/harness/tools/edit-diff.js +386 -0
- package/dist/harness/tools/edit-diff.js.map +1 -0
- package/dist/harness/tools/edit.d.ts +19 -0
- package/dist/harness/tools/edit.d.ts.map +1 -0
- package/dist/harness/tools/edit.js +108 -0
- package/dist/harness/tools/edit.js.map +1 -0
- package/dist/harness/tools/file-mutation-queue.d.ts +5 -0
- package/dist/harness/tools/file-mutation-queue.d.ts.map +1 -0
- package/dist/harness/tools/file-mutation-queue.js +46 -0
- package/dist/harness/tools/file-mutation-queue.js.map +1 -0
- package/dist/harness/tools/image.d.ts +3 -0
- package/dist/harness/tools/image.d.ts.map +1 -0
- package/dist/harness/tools/image.js +106 -0
- package/dist/harness/tools/image.js.map +1 -0
- package/dist/harness/tools/index.d.ts +6 -0
- package/dist/harness/tools/index.d.ts.map +1 -0
- package/dist/harness/tools/index.js +5 -0
- package/dist/harness/tools/index.js.map +1 -0
- package/dist/harness/tools/path-utils.d.ts +5 -0
- package/dist/harness/tools/path-utils.d.ts.map +1 -0
- package/dist/harness/tools/path-utils.js +26 -0
- package/dist/harness/tools/path-utils.js.map +1 -0
- package/dist/harness/tools/read.d.ts +35 -0
- package/dist/harness/tools/read.d.ts.map +1 -0
- package/dist/harness/tools/read.js +108 -0
- package/dist/harness/tools/read.js.map +1 -0
- package/dist/harness/tools/tool-context.d.ts +6 -0
- package/dist/harness/tools/tool-context.d.ts.map +1 -0
- package/dist/harness/tools/tool-context.js +2 -0
- package/dist/harness/tools/tool-context.js.map +1 -0
- package/dist/harness/tools/write.d.ts +11 -0
- package/dist/harness/tools/write.d.ts.map +1 -0
- package/dist/harness/tools/write.js +31 -0
- package/dist/harness/tools/write.js.map +1 -0
- package/dist/harness/types.d.ts +305 -0
- package/dist/harness/types.d.ts.map +1 -0
- package/dist/harness/types.js +75 -0
- package/dist/harness/types.js.map +1 -0
- package/dist/harness/utils/adaptive-publisher.d.ts +24 -0
- package/dist/harness/utils/adaptive-publisher.d.ts.map +1 -0
- package/dist/harness/utils/adaptive-publisher.js +79 -0
- package/dist/harness/utils/adaptive-publisher.js.map +1 -0
- package/dist/harness/utils/output-capture.d.ts +31 -0
- package/dist/harness/utils/output-capture.d.ts.map +1 -0
- package/dist/harness/utils/output-capture.js +217 -0
- package/dist/harness/utils/output-capture.js.map +1 -0
- package/dist/harness/utils/shell-output.d.ts +29 -0
- package/dist/harness/utils/shell-output.d.ts.map +1 -0
- package/dist/harness/utils/shell-output.js +71 -0
- package/dist/harness/utils/shell-output.js.map +1 -0
- package/dist/harness/utils/truncate.d.ts +71 -0
- package/dist/harness/utils/truncate.d.ts.map +1 -0
- package/dist/harness/utils/truncate.js +296 -0
- package/dist/harness/utils/truncate.js.map +1 -0
- package/dist/harness/utils/usage.d.ts +4 -0
- package/dist/harness/utils/usage.d.ts.map +1 -0
- package/dist/harness/utils/usage.js +33 -0
- package/dist/harness/utils/usage.js.map +1 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +26 -0
- package/dist/index.js.map +1 -0
- package/dist/node.d.ts +3 -0
- package/dist/node.d.ts.map +1 -0
- package/dist/node.js +3 -0
- package/dist/node.js.map +1 -0
- package/dist/proxy.d.ts +72 -0
- package/dist/proxy.d.ts.map +1 -0
- package/dist/proxy.js +310 -0
- package/dist/proxy.js.map +1 -0
- package/dist/search/index.d.ts +29 -0
- package/dist/search/index.d.ts.map +1 -0
- package/dist/search/index.js +2 -0
- package/dist/search/index.js.map +1 -0
- package/dist/stream-fn.d.ts +10 -0
- package/dist/stream-fn.d.ts.map +1 -0
- package/dist/stream-fn.js +17 -0
- package/dist/stream-fn.js.map +1 -0
- package/dist/types.d.ts +416 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +89 -0
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
import { uuidv7 } from "@m4ike1/ion-ai/utils/uuid";
|
|
2
|
+
import { insertEntry } from "./commit.js";
|
|
3
|
+
import { MutationLine } from "./mutation-line.js";
|
|
4
|
+
import { appendList as appendListWrite, branchTip, deleteList as deleteListWrite, deleteValue as deleteValueWrite, entryLabel, sessionName, setValue as setValueWrite, } from "./values.js";
|
|
5
|
+
/** Durable session state is internally inconsistent and cannot be safely advanced. */
|
|
6
|
+
export class SessionInvariantError extends Error {
|
|
7
|
+
constructor(message) {
|
|
8
|
+
super(message);
|
|
9
|
+
this.name = "SessionInvariantError";
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
/** A requested Branch name is invalid. */
|
|
13
|
+
export class SessionInvalidBranchError extends Error {
|
|
14
|
+
branch;
|
|
15
|
+
reason;
|
|
16
|
+
constructor(branch, reason) {
|
|
17
|
+
super(`Invalid branch ${JSON.stringify(branch)}: ${reason}`);
|
|
18
|
+
this.name = "SessionInvalidBranchError";
|
|
19
|
+
this.branch = branch;
|
|
20
|
+
this.reason = reason;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/** A requested branch already exists. */
|
|
24
|
+
export class SessionBranchExistsError extends Error {
|
|
25
|
+
branch;
|
|
26
|
+
constructor(branch) {
|
|
27
|
+
super(`Branch already exists: ${branch}`);
|
|
28
|
+
this.name = "SessionBranchExistsError";
|
|
29
|
+
this.branch = branch;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/** A pending assistant message cannot be persisted as a session entry. */
|
|
33
|
+
export class SessionPendingAssistantMessageError extends Error {
|
|
34
|
+
constructor() {
|
|
35
|
+
super("Cannot persist a pending assistant message");
|
|
36
|
+
this.name = "SessionPendingAssistantMessageError";
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/** A requested session entry target does not exist. */
|
|
40
|
+
export class SessionUnknownTargetError extends Error {
|
|
41
|
+
targetId;
|
|
42
|
+
constructor(targetId) {
|
|
43
|
+
super(`Unknown target: ${targetId}`);
|
|
44
|
+
this.name = "SessionUnknownTargetError";
|
|
45
|
+
this.targetId = targetId;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
class StorageBackedSessionMutation {
|
|
49
|
+
storage;
|
|
50
|
+
release;
|
|
51
|
+
active = true;
|
|
52
|
+
commitResult;
|
|
53
|
+
endPromise;
|
|
54
|
+
constructor(storage, release) {
|
|
55
|
+
this.storage = storage;
|
|
56
|
+
this.release = release;
|
|
57
|
+
}
|
|
58
|
+
commit(writes, context) {
|
|
59
|
+
this.assertActive();
|
|
60
|
+
if (this.commitResult !== undefined)
|
|
61
|
+
return Promise.reject(new Error("SessionMutator commit already attempted"));
|
|
62
|
+
try {
|
|
63
|
+
for (const write of writes) {
|
|
64
|
+
if (write.kind === "entry" &&
|
|
65
|
+
write.entry.type === "message" &&
|
|
66
|
+
write.entry.message.role === "assistant" &&
|
|
67
|
+
write.entry.message.stopReason === "pending") {
|
|
68
|
+
throw new SessionPendingAssistantMessageError();
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
this.commitResult = this.storage.commit(writes, context);
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
this.commitResult = Promise.reject(error);
|
|
75
|
+
}
|
|
76
|
+
return this.commitResult;
|
|
77
|
+
}
|
|
78
|
+
end(_context) {
|
|
79
|
+
if (this.endPromise !== undefined)
|
|
80
|
+
return this.endPromise;
|
|
81
|
+
this.active = false;
|
|
82
|
+
this.endPromise = this.settle().finally(this.release);
|
|
83
|
+
return this.endPromise;
|
|
84
|
+
}
|
|
85
|
+
getEntries(ids, context) {
|
|
86
|
+
this.assertActive();
|
|
87
|
+
return this.storage.getEntries(ids, context);
|
|
88
|
+
}
|
|
89
|
+
getStats(context) {
|
|
90
|
+
this.assertActive();
|
|
91
|
+
return this.storage.getStats(context);
|
|
92
|
+
}
|
|
93
|
+
getValue(address, context) {
|
|
94
|
+
this.assertActive();
|
|
95
|
+
return this.storage.getValue(address, context);
|
|
96
|
+
}
|
|
97
|
+
scanValues(prefix, context) {
|
|
98
|
+
this.assertActive();
|
|
99
|
+
return this.storage.scanValues(prefix, context);
|
|
100
|
+
}
|
|
101
|
+
readList(address, options, context) {
|
|
102
|
+
this.assertActive();
|
|
103
|
+
return this.storage.readList(address, options, context);
|
|
104
|
+
}
|
|
105
|
+
scanBranch(query, context) {
|
|
106
|
+
this.assertActive();
|
|
107
|
+
return this.storage.scanBranch(query, context);
|
|
108
|
+
}
|
|
109
|
+
settle() {
|
|
110
|
+
return (this.commitResult?.then(() => undefined, () => undefined) ?? Promise.resolve());
|
|
111
|
+
}
|
|
112
|
+
assertActive() {
|
|
113
|
+
if (!this.active)
|
|
114
|
+
throw new Error("SessionMutator cannot be used outside its mutation callback");
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
class StorageBackedBranch {
|
|
118
|
+
name;
|
|
119
|
+
session;
|
|
120
|
+
constructor(name, session) {
|
|
121
|
+
this.name = name;
|
|
122
|
+
this.session = session;
|
|
123
|
+
}
|
|
124
|
+
getTipId(context) {
|
|
125
|
+
return this.session.getBranchTip(this.name, context);
|
|
126
|
+
}
|
|
127
|
+
async findEntries(query, context) {
|
|
128
|
+
query ??= {};
|
|
129
|
+
const start = query.start ?? (await this.getTipId(context));
|
|
130
|
+
if (start === null)
|
|
131
|
+
return [];
|
|
132
|
+
return this.session.scanBranch({ ...query, start, order: query.order ?? "newestFirst" }, context);
|
|
133
|
+
}
|
|
134
|
+
async findEntry(query, context) {
|
|
135
|
+
query ??= {};
|
|
136
|
+
return (await this.findEntries({ ...query, limit: query.limit === undefined ? 1 : Math.min(query.limit, 1) }, context))[0];
|
|
137
|
+
}
|
|
138
|
+
appendMessage(message, context) {
|
|
139
|
+
return this.session.appendToBranch(this.name, { type: "message", message }, context);
|
|
140
|
+
}
|
|
141
|
+
appendCustomEntry(customType, data, context) {
|
|
142
|
+
return this.session.appendToBranch(this.name, { type: "custom", customType, ...(data === undefined ? {} : { data }) }, context);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
/** Package-internal typed boundary shared by concrete session repositories. */
|
|
146
|
+
export class StorageBackedSession {
|
|
147
|
+
metadata;
|
|
148
|
+
idGenerator;
|
|
149
|
+
storage;
|
|
150
|
+
mutationLine;
|
|
151
|
+
onClose;
|
|
152
|
+
branches = new Map();
|
|
153
|
+
closedError = new Error("Session is closed");
|
|
154
|
+
state = "open";
|
|
155
|
+
closePromise;
|
|
156
|
+
constructor(metadata, storage, options = {}) {
|
|
157
|
+
this.metadata = metadata;
|
|
158
|
+
this.idGenerator = options.idGenerator ?? { next: uuidv7 };
|
|
159
|
+
this.storage = storage;
|
|
160
|
+
this.mutationLine = options.mutationLine ?? new MutationLine();
|
|
161
|
+
this.onClose = options.onClose;
|
|
162
|
+
}
|
|
163
|
+
async beginMutation(_context) {
|
|
164
|
+
this.assertOpen();
|
|
165
|
+
let grant;
|
|
166
|
+
let rejectGrant;
|
|
167
|
+
const granted = new Promise((resolve, reject) => {
|
|
168
|
+
grant = resolve;
|
|
169
|
+
rejectGrant = reject;
|
|
170
|
+
});
|
|
171
|
+
let release;
|
|
172
|
+
const finished = new Promise((resolve) => {
|
|
173
|
+
release = resolve;
|
|
174
|
+
});
|
|
175
|
+
const line = this.mutationLine.run(async () => {
|
|
176
|
+
grant(new StorageBackedSessionMutation(this.storage, release));
|
|
177
|
+
await finished;
|
|
178
|
+
});
|
|
179
|
+
void line.catch(rejectGrant);
|
|
180
|
+
return granted;
|
|
181
|
+
}
|
|
182
|
+
async mutate(mutation, context) {
|
|
183
|
+
const mutator = await this.beginMutation(context);
|
|
184
|
+
try {
|
|
185
|
+
return await mutation(mutator, context);
|
|
186
|
+
}
|
|
187
|
+
finally {
|
|
188
|
+
await mutator.end(context);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
async getEntries(ids, context) {
|
|
192
|
+
this.assertOpen();
|
|
193
|
+
return this.storage.getEntries(ids, context);
|
|
194
|
+
}
|
|
195
|
+
async getEntry(id, context) {
|
|
196
|
+
return (await this.getEntries([id], context)).get(id);
|
|
197
|
+
}
|
|
198
|
+
async getValue(address, context) {
|
|
199
|
+
this.assertOpen();
|
|
200
|
+
return this.storage.getValue(address, context);
|
|
201
|
+
}
|
|
202
|
+
async scanValues(prefix, context) {
|
|
203
|
+
this.assertOpen();
|
|
204
|
+
return this.storage.scanValues(prefix, context);
|
|
205
|
+
}
|
|
206
|
+
async readList(address, options, context) {
|
|
207
|
+
this.assertOpen();
|
|
208
|
+
return this.storage.readList(address, options, context);
|
|
209
|
+
}
|
|
210
|
+
async scanBranch(query, context) {
|
|
211
|
+
this.assertOpen();
|
|
212
|
+
return this.storage.scanBranch(query, context);
|
|
213
|
+
}
|
|
214
|
+
async getStats(context) {
|
|
215
|
+
this.assertOpen();
|
|
216
|
+
return this.storage.getStats(context);
|
|
217
|
+
}
|
|
218
|
+
async getName(context) {
|
|
219
|
+
return (await this.getValue(sessionName, context))?.value;
|
|
220
|
+
}
|
|
221
|
+
async getLabel(targetId, context) {
|
|
222
|
+
return (await this.getValue(entryLabel(targetId), context))?.value;
|
|
223
|
+
}
|
|
224
|
+
async findEntries(query, context) {
|
|
225
|
+
query ??= {};
|
|
226
|
+
this.assertOpen();
|
|
227
|
+
const order = query.order ?? "desc";
|
|
228
|
+
if (query.cursor !== undefined) {
|
|
229
|
+
if (order === "asc" && query.cursor.seq === Number.MAX_SAFE_INTEGER)
|
|
230
|
+
return [];
|
|
231
|
+
if (order === "desc" && query.cursor.seq <= 1)
|
|
232
|
+
return [];
|
|
233
|
+
}
|
|
234
|
+
return this.storage.scanEntries({
|
|
235
|
+
type: query.type,
|
|
236
|
+
customType: query.customType,
|
|
237
|
+
order,
|
|
238
|
+
limit: query.limit,
|
|
239
|
+
...(query.cursor === undefined
|
|
240
|
+
? {}
|
|
241
|
+
: order === "asc"
|
|
242
|
+
? { fromSeq: query.cursor.seq + 1 }
|
|
243
|
+
: { toSeq: query.cursor.seq - 1 }),
|
|
244
|
+
}, context);
|
|
245
|
+
}
|
|
246
|
+
async findEntry(query, context) {
|
|
247
|
+
query ??= {};
|
|
248
|
+
return (await this.findEntries({ ...query, limit: query.limit === undefined ? 1 : Math.min(query.limit, 1) }, context))[0];
|
|
249
|
+
}
|
|
250
|
+
async branch(name, context) {
|
|
251
|
+
this.assertValidBranchName(name);
|
|
252
|
+
if ((await this.getValue(branchTip(name), context)) === undefined)
|
|
253
|
+
return undefined;
|
|
254
|
+
return this.getOrCreateBranchObject(name);
|
|
255
|
+
}
|
|
256
|
+
async createBranch(name, at, context) {
|
|
257
|
+
this.assertOpen();
|
|
258
|
+
this.assertValidBranchName(name);
|
|
259
|
+
await this.mutate(async (mutator) => {
|
|
260
|
+
if ((await mutator.getValue(branchTip(name), context)) !== undefined) {
|
|
261
|
+
throw new SessionBranchExistsError(name);
|
|
262
|
+
}
|
|
263
|
+
if (at !== null && !(await mutator.getEntries([at], context)).has(at)) {
|
|
264
|
+
throw new SessionUnknownTargetError(at);
|
|
265
|
+
}
|
|
266
|
+
await mutator.commit([setValueWrite(branchTip(name), at)], context);
|
|
267
|
+
}, context);
|
|
268
|
+
return this.getOrCreateBranchObject(name);
|
|
269
|
+
}
|
|
270
|
+
setValue(address, next, context) {
|
|
271
|
+
return this.mutate(async (mutator) => {
|
|
272
|
+
await mutator.commit([setValueWrite(address, next)], context);
|
|
273
|
+
}, context);
|
|
274
|
+
}
|
|
275
|
+
deleteValue(address, context) {
|
|
276
|
+
return this.mutate(async (mutator) => {
|
|
277
|
+
await mutator.commit([deleteValueWrite(address)], context);
|
|
278
|
+
}, context);
|
|
279
|
+
}
|
|
280
|
+
appendList(address, element, context) {
|
|
281
|
+
return this.mutate(async (mutator) => {
|
|
282
|
+
await mutator.commit([appendListWrite(address, element)], context);
|
|
283
|
+
}, context);
|
|
284
|
+
}
|
|
285
|
+
deleteList(address, context) {
|
|
286
|
+
return this.mutate(async (mutator) => {
|
|
287
|
+
await mutator.commit([deleteListWrite(address)], context);
|
|
288
|
+
}, context);
|
|
289
|
+
}
|
|
290
|
+
setName(name, context) {
|
|
291
|
+
return name === undefined ? this.deleteValue(sessionName, context) : this.setValue(sessionName, name, context);
|
|
292
|
+
}
|
|
293
|
+
setLabel(targetId, label, context) {
|
|
294
|
+
const address = entryLabel(targetId);
|
|
295
|
+
return label === undefined ? this.deleteValue(address, context) : this.setValue(address, label, context);
|
|
296
|
+
}
|
|
297
|
+
close(context) {
|
|
298
|
+
if (this.closePromise !== undefined)
|
|
299
|
+
return this.closePromise;
|
|
300
|
+
this.state = "closing";
|
|
301
|
+
this.closePromise = this.mutationLine
|
|
302
|
+
.seal(this.closedError)
|
|
303
|
+
.then(() => this.storage.close(context))
|
|
304
|
+
.finally(() => {
|
|
305
|
+
this.state = "closed";
|
|
306
|
+
this.onClose?.();
|
|
307
|
+
});
|
|
308
|
+
return this.closePromise;
|
|
309
|
+
}
|
|
310
|
+
async getBranchTip(name, context) {
|
|
311
|
+
const stored = await this.getValue(branchTip(name), context);
|
|
312
|
+
if (stored === undefined)
|
|
313
|
+
throw new SessionInvariantError(`Unknown branch: ${name}`);
|
|
314
|
+
return stored.value;
|
|
315
|
+
}
|
|
316
|
+
async appendToBranch(name, entry, context) {
|
|
317
|
+
this.assertOpen();
|
|
318
|
+
if (entry.type === "message" && entry.message.role === "assistant" && entry.message.stopReason === "pending") {
|
|
319
|
+
throw new SessionPendingAssistantMessageError();
|
|
320
|
+
}
|
|
321
|
+
const id = this.idGenerator.next();
|
|
322
|
+
await this.mutate(async (mutator) => {
|
|
323
|
+
const tip = await mutator.getValue(branchTip(name), context);
|
|
324
|
+
if (tip === undefined)
|
|
325
|
+
throw new SessionInvariantError(`Unknown branch: ${name}`);
|
|
326
|
+
await mutator.commit([
|
|
327
|
+
insertEntry(entry.type === "message"
|
|
328
|
+
? { id, parentId: tip.value, type: "message", message: entry.message }
|
|
329
|
+
: {
|
|
330
|
+
id,
|
|
331
|
+
parentId: tip.value,
|
|
332
|
+
type: "custom",
|
|
333
|
+
customType: entry.customType,
|
|
334
|
+
...(entry.data === undefined ? {} : { data: entry.data }),
|
|
335
|
+
}),
|
|
336
|
+
setValueWrite(branchTip(name), id),
|
|
337
|
+
], context);
|
|
338
|
+
}, context);
|
|
339
|
+
return id;
|
|
340
|
+
}
|
|
341
|
+
getOrCreateBranchObject(name) {
|
|
342
|
+
let branch = this.branches.get(name);
|
|
343
|
+
if (branch === undefined) {
|
|
344
|
+
branch = new StorageBackedBranch(name, this);
|
|
345
|
+
this.branches.set(name, branch);
|
|
346
|
+
}
|
|
347
|
+
return branch;
|
|
348
|
+
}
|
|
349
|
+
assertValidBranchName(name) {
|
|
350
|
+
if (name.length === 0)
|
|
351
|
+
throw new SessionInvalidBranchError(name, "branch name must not be empty");
|
|
352
|
+
if (name.includes("\u0000")) {
|
|
353
|
+
throw new SessionInvalidBranchError(name, "branch name must not contain \\u0000");
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
assertOpen() {
|
|
357
|
+
if (this.state !== "open")
|
|
358
|
+
throw this.closedError;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
//# sourceMappingURL=session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../../src/harness/session/session.ts"],"names":[],"mappings":"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","sourcesContent":["import { uuidv7 } from \"@m4ike1/ion-ai/utils/uuid\";\nimport type { AgentMessage } from \"../../types.ts\";\nimport type { Context } from \"../context.ts\";\nimport { insertEntry } from \"./commit.ts\";\nimport { MutationLine } from \"./mutation-line.ts\";\nimport type {\n\tBranch,\n\tBranchScan,\n\tCommitResult,\n\tEntry,\n\tEntryQuery,\n\tIdGenerator,\n\tJsonValue,\n\tSession,\n\tSessionMetadata,\n\tSessionMutation,\n\tSessionMutationCallback,\n\tSessionStats,\n\tStorage,\n\tStorageBranchScan,\n\tWrite,\n} from \"./types.ts\";\nimport {\n\tappendList as appendListWrite,\n\tbranchTip,\n\tdeleteList as deleteListWrite,\n\tdeleteValue as deleteValueWrite,\n\tentryLabel,\n\ttype ListElement,\n\ttype ListReadOptions,\n\ttype StoredValue,\n\tsessionName,\n\tsetValue as setValueWrite,\n\ttype Value,\n\ttype ValueList,\n} from \"./values.ts\";\n\nexport interface StorageBackedSessionOptions {\n\tmutationLine?: MutationLine;\n\tidGenerator?: IdGenerator;\n\tonClose?: () => void;\n}\n\n/** Durable session state is internally inconsistent and cannot be safely advanced. */\nexport class SessionInvariantError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"SessionInvariantError\";\n\t}\n}\n\n/** A requested Branch name is invalid. */\nexport class SessionInvalidBranchError extends Error {\n\treadonly branch: string;\n\treadonly reason: string;\n\n\tconstructor(branch: string, reason: string) {\n\t\tsuper(`Invalid branch ${JSON.stringify(branch)}: ${reason}`);\n\t\tthis.name = \"SessionInvalidBranchError\";\n\t\tthis.branch = branch;\n\t\tthis.reason = reason;\n\t}\n}\n\n/** A requested branch already exists. */\nexport class SessionBranchExistsError extends Error {\n\treadonly branch: string;\n\n\tconstructor(branch: string) {\n\t\tsuper(`Branch already exists: ${branch}`);\n\t\tthis.name = \"SessionBranchExistsError\";\n\t\tthis.branch = branch;\n\t}\n}\n\n/** A pending assistant message cannot be persisted as a session entry. */\nexport class SessionPendingAssistantMessageError extends Error {\n\tconstructor() {\n\t\tsuper(\"Cannot persist a pending assistant message\");\n\t\tthis.name = \"SessionPendingAssistantMessageError\";\n\t}\n}\n\n/** A requested session entry target does not exist. */\nexport class SessionUnknownTargetError extends Error {\n\treadonly targetId: string;\n\n\tconstructor(targetId: string) {\n\t\tsuper(`Unknown target: ${targetId}`);\n\t\tthis.name = \"SessionUnknownTargetError\";\n\t\tthis.targetId = targetId;\n\t}\n}\n\nclass StorageBackedSessionMutation implements SessionMutation {\n\tprivate readonly storage: Storage;\n\tprivate readonly release: () => void;\n\tprivate active = true;\n\tprivate commitResult: Promise<CommitResult> | undefined;\n\tprivate endPromise: Promise<void> | undefined;\n\n\tconstructor(storage: Storage, release: () => void) {\n\t\tthis.storage = storage;\n\t\tthis.release = release;\n\t}\n\n\tcommit(writes: Write[], context: Context): Promise<CommitResult> {\n\t\tthis.assertActive();\n\t\tif (this.commitResult !== undefined) return Promise.reject(new Error(\"SessionMutator commit already attempted\"));\n\t\ttry {\n\t\t\tfor (const write of writes) {\n\t\t\t\tif (\n\t\t\t\t\twrite.kind === \"entry\" &&\n\t\t\t\t\twrite.entry.type === \"message\" &&\n\t\t\t\t\twrite.entry.message.role === \"assistant\" &&\n\t\t\t\t\twrite.entry.message.stopReason === \"pending\"\n\t\t\t\t) {\n\t\t\t\t\tthrow new SessionPendingAssistantMessageError();\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.commitResult = this.storage.commit(writes, context);\n\t\t} catch (error) {\n\t\t\tthis.commitResult = Promise.reject(error);\n\t\t}\n\t\treturn this.commitResult;\n\t}\n\n\tend(_context: Context): Promise<void> {\n\t\tif (this.endPromise !== undefined) return this.endPromise;\n\t\tthis.active = false;\n\t\tthis.endPromise = this.settle().finally(this.release);\n\t\treturn this.endPromise;\n\t}\n\n\tgetEntries(ids: string[], context: Context): Promise<Map<string, Entry>> {\n\t\tthis.assertActive();\n\t\treturn this.storage.getEntries(ids, context);\n\t}\n\n\tgetStats(context: Context): Promise<SessionStats> {\n\t\tthis.assertActive();\n\t\treturn this.storage.getStats(context);\n\t}\n\n\tgetValue<T>(address: Value<T>, context: Context): Promise<StoredValue<T> | undefined> {\n\t\tthis.assertActive();\n\t\treturn this.storage.getValue(address, context);\n\t}\n\n\tscanValues<T>(prefix: Value<T>, context: Context): Promise<StoredValue<T>[]> {\n\t\tthis.assertActive();\n\t\treturn this.storage.scanValues(prefix, context);\n\t}\n\n\treadList<T>(\n\t\taddress: ValueList<T>,\n\t\toptions: ListReadOptions | undefined,\n\t\tcontext: Context,\n\t): Promise<ListElement<T>[]> {\n\t\tthis.assertActive();\n\t\treturn this.storage.readList(address, options, context);\n\t}\n\n\tscanBranch(query: StorageBranchScan, context: Context): Promise<Entry[]> {\n\t\tthis.assertActive();\n\t\treturn this.storage.scanBranch(query, context);\n\t}\n\n\tprivate settle(): Promise<void> {\n\t\treturn (\n\t\t\tthis.commitResult?.then(\n\t\t\t\t() => undefined,\n\t\t\t\t() => undefined,\n\t\t\t) ?? Promise.resolve()\n\t\t);\n\t}\n\n\tprivate assertActive(): void {\n\t\tif (!this.active) throw new Error(\"SessionMutator cannot be used outside its mutation callback\");\n\t}\n}\n\nclass StorageBackedBranch implements Branch {\n\treadonly name: string;\n\tprivate readonly session: StorageBackedSession;\n\n\tconstructor(name: string, session: StorageBackedSession) {\n\t\tthis.name = name;\n\t\tthis.session = session;\n\t}\n\n\tgetTipId(context: Context): Promise<string | null> {\n\t\treturn this.session.getBranchTip(this.name, context);\n\t}\n\n\tasync findEntries(query: BranchScan | undefined, context: Context): Promise<Entry[]> {\n\t\tquery ??= {};\n\t\tconst start = query.start ?? (await this.getTipId(context));\n\t\tif (start === null) return [];\n\t\treturn this.session.scanBranch({ ...query, start, order: query.order ?? \"newestFirst\" }, context);\n\t}\n\n\tasync findEntry(query: BranchScan | undefined, context: Context): Promise<Entry | undefined> {\n\t\tquery ??= {};\n\t\treturn (\n\t\t\tawait this.findEntries({ ...query, limit: query.limit === undefined ? 1 : Math.min(query.limit, 1) }, context)\n\t\t)[0];\n\t}\n\n\tappendMessage(message: AgentMessage, context: Context): Promise<string> {\n\t\treturn this.session.appendToBranch(this.name, { type: \"message\", message }, context);\n\t}\n\n\tappendCustomEntry(customType: string, data: JsonValue | undefined, context: Context): Promise<string> {\n\t\treturn this.session.appendToBranch(\n\t\t\tthis.name,\n\t\t\t{ type: \"custom\", customType, ...(data === undefined ? {} : { data }) },\n\t\t\tcontext,\n\t\t);\n\t}\n}\n\n/** Package-internal typed boundary shared by concrete session repositories. */\nexport class StorageBackedSession<TMetadata extends SessionMetadata = SessionMetadata> implements Session<TMetadata> {\n\treadonly metadata: TMetadata;\n\treadonly idGenerator: IdGenerator;\n\tprivate readonly storage: Storage;\n\tprivate readonly mutationLine: MutationLine;\n\tprivate readonly onClose: (() => void) | undefined;\n\tprivate readonly branches = new Map<string, StorageBackedBranch>();\n\tprivate readonly closedError = new Error(\"Session is closed\");\n\tprivate state: \"open\" | \"closing\" | \"closed\" = \"open\";\n\tprivate closePromise: Promise<void> | undefined;\n\n\tconstructor(metadata: TMetadata, storage: Storage, options: StorageBackedSessionOptions = {}) {\n\t\tthis.metadata = metadata;\n\t\tthis.idGenerator = options.idGenerator ?? { next: uuidv7 };\n\t\tthis.storage = storage;\n\t\tthis.mutationLine = options.mutationLine ?? new MutationLine();\n\t\tthis.onClose = options.onClose;\n\t}\n\n\tasync beginMutation(_context: Context): Promise<SessionMutation> {\n\t\tthis.assertOpen();\n\t\tlet grant!: (mutation: SessionMutation) => void;\n\t\tlet rejectGrant!: (error: unknown) => void;\n\t\tconst granted = new Promise<SessionMutation>((resolve, reject) => {\n\t\t\tgrant = resolve;\n\t\t\trejectGrant = reject;\n\t\t});\n\t\tlet release!: () => void;\n\t\tconst finished = new Promise<void>((resolve) => {\n\t\t\trelease = resolve;\n\t\t});\n\t\tconst line = this.mutationLine.run(async () => {\n\t\t\tgrant(new StorageBackedSessionMutation(this.storage, release));\n\t\t\tawait finished;\n\t\t});\n\t\tvoid line.catch(rejectGrant);\n\t\treturn granted;\n\t}\n\n\tasync mutate<T>(mutation: SessionMutationCallback<T>, context: Context): Promise<T> {\n\t\tconst mutator = await this.beginMutation(context);\n\t\ttry {\n\t\t\treturn await mutation(mutator, context);\n\t\t} finally {\n\t\t\tawait mutator.end(context);\n\t\t}\n\t}\n\n\tasync getEntries(ids: string[], context: Context): Promise<Map<string, Entry>> {\n\t\tthis.assertOpen();\n\t\treturn this.storage.getEntries(ids, context);\n\t}\n\n\tasync getEntry(id: string, context: Context): Promise<Entry | undefined> {\n\t\treturn (await this.getEntries([id], context)).get(id);\n\t}\n\n\tasync getValue<T>(address: Value<T>, context: Context): Promise<StoredValue<T> | undefined> {\n\t\tthis.assertOpen();\n\t\treturn this.storage.getValue(address, context);\n\t}\n\n\tasync scanValues<T>(prefix: Value<T>, context: Context): Promise<StoredValue<T>[]> {\n\t\tthis.assertOpen();\n\t\treturn this.storage.scanValues(prefix, context);\n\t}\n\n\tasync readList<T>(\n\t\taddress: ValueList<T>,\n\t\toptions: ListReadOptions | undefined,\n\t\tcontext: Context,\n\t): Promise<ListElement<T>[]> {\n\t\tthis.assertOpen();\n\t\treturn this.storage.readList(address, options, context);\n\t}\n\n\tasync scanBranch(query: StorageBranchScan, context: Context): Promise<Entry[]> {\n\t\tthis.assertOpen();\n\t\treturn this.storage.scanBranch(query, context);\n\t}\n\n\tasync getStats(context: Context): Promise<SessionStats> {\n\t\tthis.assertOpen();\n\t\treturn this.storage.getStats(context);\n\t}\n\n\tasync getName(context: Context): Promise<string | undefined> {\n\t\treturn (await this.getValue(sessionName, context))?.value;\n\t}\n\n\tasync getLabel(targetId: string, context: Context): Promise<string | undefined> {\n\t\treturn (await this.getValue(entryLabel(targetId), context))?.value;\n\t}\n\n\tasync findEntries(query: EntryQuery | undefined, context: Context): Promise<Entry[]> {\n\t\tquery ??= {};\n\t\tthis.assertOpen();\n\t\tconst order = query.order ?? \"desc\";\n\t\tif (query.cursor !== undefined) {\n\t\t\tif (order === \"asc\" && query.cursor.seq === Number.MAX_SAFE_INTEGER) return [];\n\t\t\tif (order === \"desc\" && query.cursor.seq <= 1) return [];\n\t\t}\n\t\treturn this.storage.scanEntries(\n\t\t\t{\n\t\t\t\ttype: query.type,\n\t\t\t\tcustomType: query.customType,\n\t\t\t\torder,\n\t\t\t\tlimit: query.limit,\n\t\t\t\t...(query.cursor === undefined\n\t\t\t\t\t? {}\n\t\t\t\t\t: order === \"asc\"\n\t\t\t\t\t\t? { fromSeq: query.cursor.seq + 1 }\n\t\t\t\t\t\t: { toSeq: query.cursor.seq - 1 }),\n\t\t\t},\n\t\t\tcontext,\n\t\t);\n\t}\n\n\tasync findEntry(query: EntryQuery | undefined, context: Context): Promise<Entry | undefined> {\n\t\tquery ??= {};\n\t\treturn (\n\t\t\tawait this.findEntries({ ...query, limit: query.limit === undefined ? 1 : Math.min(query.limit, 1) }, context)\n\t\t)[0];\n\t}\n\n\tasync branch(name: string, context: Context): Promise<Branch | undefined> {\n\t\tthis.assertValidBranchName(name);\n\t\tif ((await this.getValue(branchTip(name), context)) === undefined) return undefined;\n\t\treturn this.getOrCreateBranchObject(name);\n\t}\n\n\tasync createBranch(name: string, at: string | null, context: Context): Promise<Branch> {\n\t\tthis.assertOpen();\n\t\tthis.assertValidBranchName(name);\n\t\tawait this.mutate(async (mutator) => {\n\t\t\tif ((await mutator.getValue(branchTip(name), context)) !== undefined) {\n\t\t\t\tthrow new SessionBranchExistsError(name);\n\t\t\t}\n\t\t\tif (at !== null && !(await mutator.getEntries([at], context)).has(at)) {\n\t\t\t\tthrow new SessionUnknownTargetError(at);\n\t\t\t}\n\t\t\tawait mutator.commit([setValueWrite(branchTip(name), at)], context);\n\t\t}, context);\n\t\treturn this.getOrCreateBranchObject(name);\n\t}\n\n\tsetValue<T>(address: Value<T>, next: NoInfer<T>, context: Context): Promise<void> {\n\t\treturn this.mutate(async (mutator) => {\n\t\t\tawait mutator.commit([setValueWrite(address, next)], context);\n\t\t}, context);\n\t}\n\n\tdeleteValue<T>(address: Value<T>, context: Context): Promise<void> {\n\t\treturn this.mutate(async (mutator) => {\n\t\t\tawait mutator.commit([deleteValueWrite(address)], context);\n\t\t}, context);\n\t}\n\n\tappendList<T>(address: ValueList<T>, element: NoInfer<T>, context: Context): Promise<void> {\n\t\treturn this.mutate(async (mutator) => {\n\t\t\tawait mutator.commit([appendListWrite(address, element)], context);\n\t\t}, context);\n\t}\n\n\tdeleteList<T>(address: ValueList<T>, context: Context): Promise<void> {\n\t\treturn this.mutate(async (mutator) => {\n\t\t\tawait mutator.commit([deleteListWrite(address)], context);\n\t\t}, context);\n\t}\n\n\tsetName(name: string | undefined, context: Context): Promise<void> {\n\t\treturn name === undefined ? this.deleteValue(sessionName, context) : this.setValue(sessionName, name, context);\n\t}\n\n\tsetLabel(targetId: string, label: string | undefined, context: Context): Promise<void> {\n\t\tconst address = entryLabel(targetId);\n\t\treturn label === undefined ? this.deleteValue(address, context) : this.setValue(address, label, context);\n\t}\n\n\tclose(context: Context): Promise<void> {\n\t\tif (this.closePromise !== undefined) return this.closePromise;\n\t\tthis.state = \"closing\";\n\t\tthis.closePromise = this.mutationLine\n\t\t\t.seal(this.closedError)\n\t\t\t.then(() => this.storage.close(context))\n\t\t\t.finally(() => {\n\t\t\t\tthis.state = \"closed\";\n\t\t\t\tthis.onClose?.();\n\t\t\t});\n\t\treturn this.closePromise;\n\t}\n\n\tasync getBranchTip(name: string, context: Context): Promise<string | null> {\n\t\tconst stored = await this.getValue(branchTip(name), context);\n\t\tif (stored === undefined) throw new SessionInvariantError(`Unknown branch: ${name}`);\n\t\treturn stored.value;\n\t}\n\n\tasync appendToBranch(\n\t\tname: string,\n\t\tentry: { type: \"message\"; message: AgentMessage } | { type: \"custom\"; customType: string; data?: JsonValue },\n\t\tcontext: Context,\n\t): Promise<string> {\n\t\tthis.assertOpen();\n\t\tif (entry.type === \"message\" && entry.message.role === \"assistant\" && entry.message.stopReason === \"pending\") {\n\t\t\tthrow new SessionPendingAssistantMessageError();\n\t\t}\n\t\tconst id = this.idGenerator.next();\n\t\tawait this.mutate(async (mutator) => {\n\t\t\tconst tip = await mutator.getValue(branchTip(name), context);\n\t\t\tif (tip === undefined) throw new SessionInvariantError(`Unknown branch: ${name}`);\n\t\t\tawait mutator.commit(\n\t\t\t\t[\n\t\t\t\t\tinsertEntry(\n\t\t\t\t\t\tentry.type === \"message\"\n\t\t\t\t\t\t\t? { id, parentId: tip.value, type: \"message\", message: entry.message }\n\t\t\t\t\t\t\t: {\n\t\t\t\t\t\t\t\t\tid,\n\t\t\t\t\t\t\t\t\tparentId: tip.value,\n\t\t\t\t\t\t\t\t\ttype: \"custom\",\n\t\t\t\t\t\t\t\t\tcustomType: entry.customType,\n\t\t\t\t\t\t\t\t\t...(entry.data === undefined ? {} : { data: entry.data }),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t),\n\t\t\t\t\tsetValueWrite(branchTip(name), id),\n\t\t\t\t],\n\t\t\t\tcontext,\n\t\t\t);\n\t\t}, context);\n\t\treturn id;\n\t}\n\n\tprivate getOrCreateBranchObject(name: string): Branch {\n\t\tlet branch = this.branches.get(name);\n\t\tif (branch === undefined) {\n\t\t\tbranch = new StorageBackedBranch(name, this);\n\t\t\tthis.branches.set(name, branch);\n\t\t}\n\t\treturn branch;\n\t}\n\n\tprivate assertValidBranchName(name: string): void {\n\t\tif (name.length === 0) throw new SessionInvalidBranchError(name, \"branch name must not be empty\");\n\t\tif (name.includes(\"\\u0000\")) {\n\t\t\tthrow new SessionInvalidBranchError(name, \"branch name must not contain \\\\u0000\");\n\t\t}\n\t}\n\n\tprivate assertOpen(): void {\n\t\tif (this.state !== \"open\") throw this.closedError;\n\t}\n}\n"]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface StorageBenchmarkDataset {
|
|
2
|
+
readonly name: string;
|
|
3
|
+
readonly entryCount: number;
|
|
4
|
+
readonly payloadBytes: number;
|
|
5
|
+
readonly lookupIds: readonly string[];
|
|
6
|
+
readonly tipId: string;
|
|
7
|
+
}
|
|
8
|
+
/** Package-internal deterministic id shared by dataset and transaction generation. */
|
|
9
|
+
export declare function storageBenchmarkEntryId(index: number): string;
|
|
10
|
+
/** Deterministic synthetic linear branches shared by all storage measurements. */
|
|
11
|
+
export declare const STORAGE_BENCHMARK_DATASETS: readonly StorageBenchmarkDataset[];
|
|
12
|
+
//# sourceMappingURL=datasets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"datasets.d.ts","sourceRoot":"","sources":["../../../../../src/harness/session/testing/benchmark/datasets.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,uBAAuB;IACvC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACvB;AAED,sFAAsF;AACtF,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE7D;AAgBD,kFAAkF;AAClF,eAAO,MAAM,0BAA0B,EAAE,SAAS,uBAAuB,EAIxE,CAAC","sourcesContent":["export interface StorageBenchmarkDataset {\n\treadonly name: string;\n\treadonly entryCount: number;\n\treadonly payloadBytes: number;\n\treadonly lookupIds: readonly string[];\n\treadonly tipId: string;\n}\n\n/** Package-internal deterministic id shared by dataset and transaction generation. */\nexport function storageBenchmarkEntryId(index: number): string {\n\treturn `benchmark-entry-${index.toString().padStart(8, \"0\")}`;\n}\n\nfunction createDataset(scale: string, entryCount: number): StorageBenchmarkDataset {\n\tconst lookupCount = Math.min(100, entryCount);\n\treturn {\n\t\tname: `synthetic linear branch: ${scale}, 256-byte payloads`,\n\t\tentryCount,\n\t\tpayloadBytes: 256,\n\t\tlookupIds: Array.from({ length: lookupCount }, (_, index) => {\n\t\t\tconst entryIndex = Math.floor((index * (entryCount - 1)) / Math.max(1, lookupCount - 1));\n\t\t\treturn storageBenchmarkEntryId(entryIndex);\n\t\t}),\n\t\ttipId: storageBenchmarkEntryId(entryCount - 1),\n\t};\n}\n\n/** Deterministic synthetic linear branches shared by all storage measurements. */\nexport const STORAGE_BENCHMARK_DATASETS: readonly StorageBenchmarkDataset[] = [\n\tcreateDataset(\"1k entries\", 1_000),\n\tcreateDataset(\"10k entries\", 10_000),\n\tcreateDataset(\"100k entries\", 100_000),\n];\n"]}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/** Package-internal deterministic id shared by dataset and transaction generation. */
|
|
2
|
+
export function storageBenchmarkEntryId(index) {
|
|
3
|
+
return `benchmark-entry-${index.toString().padStart(8, "0")}`;
|
|
4
|
+
}
|
|
5
|
+
function createDataset(scale, entryCount) {
|
|
6
|
+
const lookupCount = Math.min(100, entryCount);
|
|
7
|
+
return {
|
|
8
|
+
name: `synthetic linear branch: ${scale}, 256-byte payloads`,
|
|
9
|
+
entryCount,
|
|
10
|
+
payloadBytes: 256,
|
|
11
|
+
lookupIds: Array.from({ length: lookupCount }, (_, index) => {
|
|
12
|
+
const entryIndex = Math.floor((index * (entryCount - 1)) / Math.max(1, lookupCount - 1));
|
|
13
|
+
return storageBenchmarkEntryId(entryIndex);
|
|
14
|
+
}),
|
|
15
|
+
tipId: storageBenchmarkEntryId(entryCount - 1),
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
/** Deterministic synthetic linear branches shared by all storage measurements. */
|
|
19
|
+
export const STORAGE_BENCHMARK_DATASETS = [
|
|
20
|
+
createDataset("1k entries", 1_000),
|
|
21
|
+
createDataset("10k entries", 10_000),
|
|
22
|
+
createDataset("100k entries", 100_000),
|
|
23
|
+
];
|
|
24
|
+
//# sourceMappingURL=datasets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"datasets.js","sourceRoot":"","sources":["../../../../../src/harness/session/testing/benchmark/datasets.ts"],"names":[],"mappings":"AAQA,sFAAsF;AACtF,MAAM,UAAU,uBAAuB,CAAC,KAAa,EAAU;IAC9D,OAAO,mBAAmB,KAAK,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;AAAA,CAC9D;AAED,SAAS,aAAa,CAAC,KAAa,EAAE,UAAkB,EAA2B;IAClF,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;IAC9C,OAAO;QACN,IAAI,EAAE,4BAA4B,KAAK,qBAAqB;QAC5D,UAAU;QACV,YAAY,EAAE,GAAG;QACjB,SAAS,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC;YAC5D,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC;YACzF,OAAO,uBAAuB,CAAC,UAAU,CAAC,CAAC;QAAA,CAC3C,CAAC;QACF,KAAK,EAAE,uBAAuB,CAAC,UAAU,GAAG,CAAC,CAAC;KAC9C,CAAC;AAAA,CACF;AAED,kFAAkF;AAClF,MAAM,CAAC,MAAM,0BAA0B,GAAuC;IAC7E,aAAa,CAAC,YAAY,EAAE,KAAK,CAAC;IAClC,aAAa,CAAC,aAAa,EAAE,MAAM,CAAC;IACpC,aAAa,CAAC,cAAc,EAAE,OAAO,CAAC;CACtC,CAAC","sourcesContent":["export interface StorageBenchmarkDataset {\n\treadonly name: string;\n\treadonly entryCount: number;\n\treadonly payloadBytes: number;\n\treadonly lookupIds: readonly string[];\n\treadonly tipId: string;\n}\n\n/** Package-internal deterministic id shared by dataset and transaction generation. */\nexport function storageBenchmarkEntryId(index: number): string {\n\treturn `benchmark-entry-${index.toString().padStart(8, \"0\")}`;\n}\n\nfunction createDataset(scale: string, entryCount: number): StorageBenchmarkDataset {\n\tconst lookupCount = Math.min(100, entryCount);\n\treturn {\n\t\tname: `synthetic linear branch: ${scale}, 256-byte payloads`,\n\t\tentryCount,\n\t\tpayloadBytes: 256,\n\t\tlookupIds: Array.from({ length: lookupCount }, (_, index) => {\n\t\t\tconst entryIndex = Math.floor((index * (entryCount - 1)) / Math.max(1, lookupCount - 1));\n\t\t\treturn storageBenchmarkEntryId(entryIndex);\n\t\t}),\n\t\ttipId: storageBenchmarkEntryId(entryCount - 1),\n\t};\n}\n\n/** Deterministic synthetic linear branches shared by all storage measurements. */\nexport const STORAGE_BENCHMARK_DATASETS: readonly StorageBenchmarkDataset[] = [\n\tcreateDataset(\"1k entries\", 1_000),\n\tcreateDataset(\"10k entries\", 10_000),\n\tcreateDataset(\"100k entries\", 100_000),\n];\n"]}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { SessionMetadata, SessionRepo } from "../../types.ts";
|
|
2
|
+
import { type StorageBenchmarkDataset } from "./datasets.ts";
|
|
3
|
+
export interface SessionRepoCatalogBenchmarkDataset {
|
|
4
|
+
readonly name: string;
|
|
5
|
+
readonly sessionCount: number;
|
|
6
|
+
}
|
|
7
|
+
interface SessionRepoCatalogReadBenchmarkScenario {
|
|
8
|
+
readonly name: string;
|
|
9
|
+
expectedResult(dataset: SessionRepoCatalogBenchmarkDataset): number;
|
|
10
|
+
run(repo: SessionRepo): Promise<number>;
|
|
11
|
+
}
|
|
12
|
+
interface SessionRepoCatalogWriteBenchmarkOperation {
|
|
13
|
+
run(): Promise<number>;
|
|
14
|
+
}
|
|
15
|
+
interface SessionRepoCatalogWriteBenchmarkScenario {
|
|
16
|
+
readonly name: string;
|
|
17
|
+
readonly expectedResult: number;
|
|
18
|
+
prepare(repo: SessionRepo): Promise<SessionRepoCatalogWriteBenchmarkOperation>;
|
|
19
|
+
}
|
|
20
|
+
interface SessionRepoForkWriteBenchmarkScenario {
|
|
21
|
+
readonly name: string;
|
|
22
|
+
expectedResult(dataset: StorageBenchmarkDataset): number;
|
|
23
|
+
run(repo: SessionRepo, source: SessionMetadata, dataset: StorageBenchmarkDataset): Promise<number>;
|
|
24
|
+
}
|
|
25
|
+
/** Package-internal deterministic session id shared by repository benchmark workloads. */
|
|
26
|
+
export declare function sessionRepoBenchmarkSessionId(index: number): string;
|
|
27
|
+
/** Deterministic closed-session catalogs shared by repository measurements. */
|
|
28
|
+
export declare const SESSION_REPO_CATALOG_BENCHMARK_DATASETS: readonly SessionRepoCatalogBenchmarkDataset[];
|
|
29
|
+
/** Seeds one deterministic catalog and returns its durable metadata in creation order. */
|
|
30
|
+
export declare function seedSessionRepoCatalogBenchmark(repo: SessionRepo, dataset: SessionRepoCatalogBenchmarkDataset): Promise<SessionMetadata[]>;
|
|
31
|
+
/** Shared catalog reads. Returning a number ensures each result is consumed. */
|
|
32
|
+
export declare const SESSION_REPO_CATALOG_READ_BENCHMARK_SCENARIOS: readonly SessionRepoCatalogReadBenchmarkScenario[];
|
|
33
|
+
/** Shared catalog writes. Every invocation receives an equivalent independently prepared repository. */
|
|
34
|
+
export declare const SESSION_REPO_CATALOG_WRITE_BENCHMARK_SCENARIOS: readonly SessionRepoCatalogWriteBenchmarkScenario[];
|
|
35
|
+
/** Initial fork timing uses a bounded source because each iteration owns an equivalent seeded repository. */
|
|
36
|
+
export declare const SESSION_REPO_FORK_BENCHMARK_DATASETS: readonly StorageBenchmarkDataset[];
|
|
37
|
+
/** Seeds one deterministic open source session with a linear main branch. */
|
|
38
|
+
export declare function seedSessionRepoForkBenchmark(repo: SessionRepo, dataset: StorageBenchmarkDataset): Promise<SessionMetadata>;
|
|
39
|
+
/** Shared fork writes. Every invocation receives an equivalent source repository. */
|
|
40
|
+
export declare const SESSION_REPO_FORK_WRITE_BENCHMARK_SCENARIOS: readonly SessionRepoForkWriteBenchmarkScenario[];
|
|
41
|
+
export {};
|
|
42
|
+
//# sourceMappingURL=session-repo.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-repo.d.ts","sourceRoot":"","sources":["../../../../../src/harness/session/testing/benchmark/session-repo.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAEnE,OAAO,EAA8B,KAAK,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAGzF,MAAM,WAAW,kCAAkC;IAClD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC9B;AAED,UAAU,uCAAuC;IAChD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,OAAO,EAAE,kCAAkC,GAAG,MAAM,CAAC;IACpE,GAAG,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACxC;AAED,UAAU,yCAAyC;IAClD,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;CACvB;AAED,UAAU,wCAAwC;IACjD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,OAAO,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,yCAAyC,CAAC,CAAC;CAC/E;AAED,UAAU,qCAAqC;IAC9C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,OAAO,EAAE,uBAAuB,GAAG,MAAM,CAAC;IACzD,GAAG,CAAC,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,eAAe,EAAE,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACnG;AAED,0FAA0F;AAC1F,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEnE;AAYD,+EAA+E;AAC/E,eAAO,MAAM,uCAAuC,EAAE,SAAS,kCAAkC,EAIhG,CAAC;AAEF,0FAA0F;AAC1F,wBAAsB,+BAA+B,CACpD,IAAI,EAAE,WAAW,EACjB,OAAO,EAAE,kCAAkC,GACzC,OAAO,CAAC,eAAe,EAAE,CAAC,CAQ5B;AAED,gFAAgF;AAChF,eAAO,MAAM,6CAA6C,EAAE,SAAS,uCAAuC,EAU3G,CAAC;AAEF,wGAAwG;AACxG,eAAO,MAAM,8CAA8C,EAAE,SAAS,wCAAwC,EA2C7G,CAAC;AAEF,6GAA6G;AAC7G,eAAO,MAAM,oCAAoC,EAAE,SAAS,uBAAuB,EAGlF,CAAC;AAEF,6EAA6E;AAC7E,wBAAsB,4BAA4B,CACjD,IAAI,EAAE,WAAW,EACjB,OAAO,EAAE,uBAAuB,GAC9B,OAAO,CAAC,eAAe,CAAC,CAsB1B;AAED,qFAAqF;AACrF,eAAO,MAAM,2CAA2C,EAAE,SAAS,qCAAqC,EAiBvG,CAAC","sourcesContent":["import { BACKGROUND_CONTEXT } from \"../../../context.ts\";\nimport type { SessionMetadata, SessionRepo } from \"../../types.ts\";\nimport { branchTip, laneConfig, laneState, setValue } from \"../../values.ts\";\nimport { STORAGE_BENCHMARK_DATASETS, type StorageBenchmarkDataset } from \"./datasets.ts\";\nimport { generateStorageBenchmarkSeedTransactions } from \"./storage.ts\";\n\nexport interface SessionRepoCatalogBenchmarkDataset {\n\treadonly name: string;\n\treadonly sessionCount: number;\n}\n\ninterface SessionRepoCatalogReadBenchmarkScenario {\n\treadonly name: string;\n\texpectedResult(dataset: SessionRepoCatalogBenchmarkDataset): number;\n\trun(repo: SessionRepo): Promise<number>;\n}\n\ninterface SessionRepoCatalogWriteBenchmarkOperation {\n\trun(): Promise<number>;\n}\n\ninterface SessionRepoCatalogWriteBenchmarkScenario {\n\treadonly name: string;\n\treadonly expectedResult: number;\n\tprepare(repo: SessionRepo): Promise<SessionRepoCatalogWriteBenchmarkOperation>;\n}\n\ninterface SessionRepoForkWriteBenchmarkScenario {\n\treadonly name: string;\n\texpectedResult(dataset: StorageBenchmarkDataset): number;\n\trun(repo: SessionRepo, source: SessionMetadata, dataset: StorageBenchmarkDataset): Promise<number>;\n}\n\n/** Package-internal deterministic session id shared by repository benchmark workloads. */\nexport function sessionRepoBenchmarkSessionId(index: number): string {\n\treturn `benchmark-session-${index.toString().padStart(8, \"0\")}`;\n}\n\nconst BENCHMARK_SESSION_ID = sessionRepoBenchmarkSessionId(0);\nconst FORK_DESTINATION_SESSION_ID = sessionRepoBenchmarkSessionId(1);\n\nfunction createCatalogDataset(scale: string, sessionCount: number): SessionRepoCatalogBenchmarkDataset {\n\treturn {\n\t\tname: `synthetic catalog: ${scale} closed sessions`,\n\t\tsessionCount,\n\t};\n}\n\n/** Deterministic closed-session catalogs shared by repository measurements. */\nexport const SESSION_REPO_CATALOG_BENCHMARK_DATASETS: readonly SessionRepoCatalogBenchmarkDataset[] = [\n\tcreateCatalogDataset(\"100\", 100),\n\tcreateCatalogDataset(\"1k\", 1_000),\n\tcreateCatalogDataset(\"10k\", 10_000),\n];\n\n/** Seeds one deterministic catalog and returns its durable metadata in creation order. */\nexport async function seedSessionRepoCatalogBenchmark(\n\trepo: SessionRepo,\n\tdataset: SessionRepoCatalogBenchmarkDataset,\n): Promise<SessionMetadata[]> {\n\tconst metadata: SessionMetadata[] = [];\n\tfor (let index = 0; index < dataset.sessionCount; index++) {\n\t\tconst session = await repo.create({ id: sessionRepoBenchmarkSessionId(index) }, BACKGROUND_CONTEXT);\n\t\tmetadata.push(session.metadata);\n\t\tawait session.close(BACKGROUND_CONTEXT);\n\t}\n\treturn metadata;\n}\n\n/** Shared catalog reads. Returning a number ensures each result is consumed. */\nexport const SESSION_REPO_CATALOG_READ_BENCHMARK_SCENARIOS: readonly SessionRepoCatalogReadBenchmarkScenario[] = [\n\t{\n\t\tname: \"list sessions\",\n\t\texpectedResult(dataset) {\n\t\t\treturn dataset.sessionCount;\n\t\t},\n\t\tasync run(repo) {\n\t\t\treturn (await repo.list(undefined, BACKGROUND_CONTEXT)).length;\n\t\t},\n\t},\n];\n\n/** Shared catalog writes. Every invocation receives an equivalent independently prepared repository. */\nexport const SESSION_REPO_CATALOG_WRITE_BENCHMARK_SCENARIOS: readonly SessionRepoCatalogWriteBenchmarkScenario[] = [\n\t{\n\t\tname: \"create empty session\",\n\t\texpectedResult: 1,\n\t\tprepare(repo) {\n\t\t\treturn Promise.resolve({\n\t\t\t\tasync run() {\n\t\t\t\t\tconst session = await repo.create({ id: BENCHMARK_SESSION_ID }, BACKGROUND_CONTEXT);\n\t\t\t\t\treturn session.metadata.id === BENCHMARK_SESSION_ID ? 1 : 0;\n\t\t\t\t},\n\t\t\t});\n\t\t},\n\t},\n\t{\n\t\tname: \"open closed empty session\",\n\t\texpectedResult: 1,\n\t\tasync prepare(repo) {\n\t\t\tconst session = await repo.create({ id: BENCHMARK_SESSION_ID }, BACKGROUND_CONTEXT);\n\t\t\tconst { metadata } = session;\n\t\t\tawait session.close(BACKGROUND_CONTEXT);\n\t\t\treturn {\n\t\t\t\tasync run() {\n\t\t\t\t\tconst reopened = await repo.open(metadata, BACKGROUND_CONTEXT);\n\t\t\t\t\treturn reopened.metadata.id === metadata.id ? 1 : 0;\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t},\n\t{\n\t\tname: \"delete closed empty session\",\n\t\texpectedResult: 1,\n\t\tasync prepare(repo) {\n\t\t\tconst session = await repo.create({ id: BENCHMARK_SESSION_ID }, BACKGROUND_CONTEXT);\n\t\t\tconst { metadata } = session;\n\t\t\tawait session.close(BACKGROUND_CONTEXT);\n\t\t\treturn {\n\t\t\t\tasync run() {\n\t\t\t\t\tawait repo.delete(metadata, BACKGROUND_CONTEXT);\n\t\t\t\t\treturn 1;\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t},\n];\n\n/** Initial fork timing uses a bounded source because each iteration owns an equivalent seeded repository. */\nexport const SESSION_REPO_FORK_BENCHMARK_DATASETS: readonly StorageBenchmarkDataset[] = [\n\tSTORAGE_BENCHMARK_DATASETS[0]!,\n\tSTORAGE_BENCHMARK_DATASETS[1]!,\n];\n\n/** Seeds one deterministic open source session with a linear main branch. */\nexport async function seedSessionRepoForkBenchmark(\n\trepo: SessionRepo,\n\tdataset: StorageBenchmarkDataset,\n): Promise<SessionMetadata> {\n\tconst session = await repo.create({ id: BENCHMARK_SESSION_ID }, BACKGROUND_CONTEXT);\n\tfor (const transaction of generateStorageBenchmarkSeedTransactions(dataset)) {\n\t\tawait session.mutate((mutator) => mutator.commit(transaction, BACKGROUND_CONTEXT), BACKGROUND_CONTEXT);\n\t}\n\tawait session.mutate(\n\t\t(mutator) =>\n\t\t\tmutator.commit(\n\t\t\t\t[\n\t\t\t\t\tsetValue(branchTip(\"main\"), dataset.tipId),\n\t\t\t\t\tsetValue(laneConfig(\"main\"), {\n\t\t\t\t\t\tmodel: { provider: \"benchmark\", modelId: \"benchmark\" },\n\t\t\t\t\t\tthinkingLevel: \"off\",\n\t\t\t\t\t\tactiveToolNames: [],\n\t\t\t\t\t}),\n\t\t\t\t\tsetValue(laneState(\"main\"), { currentOperationId: null, lastOperationId: null, inbox: [] }),\n\t\t\t\t],\n\t\t\t\tBACKGROUND_CONTEXT,\n\t\t\t),\n\t\tBACKGROUND_CONTEXT,\n\t);\n\treturn session.metadata;\n}\n\n/** Shared fork writes. Every invocation receives an equivalent source repository. */\nexport const SESSION_REPO_FORK_WRITE_BENCHMARK_SCENARIOS: readonly SessionRepoForkWriteBenchmarkScenario[] = [\n\t{\n\t\tname: \"fork open current branch\",\n\t\texpectedResult(dataset) {\n\t\t\treturn dataset.entryCount;\n\t\t},\n\t\tasync run(repo, source, dataset) {\n\t\t\tconst fork = await repo.fork(\n\t\t\t\tsource,\n\t\t\t\t{ id: FORK_DESTINATION_SESSION_ID, scope: \"branch\", branch: \"main\" },\n\t\t\t\tBACKGROUND_CONTEXT,\n\t\t\t);\n\t\t\treturn fork.metadata.id === FORK_DESTINATION_SESSION_ID && fork.metadata.parentSessionId === source.id\n\t\t\t\t? dataset.entryCount\n\t\t\t\t: 0;\n\t\t},\n\t},\n];\n"]}
|