@namzu/sdk 0.1.7 → 0.2.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/CHANGELOG.md +23 -5
- package/README.md +14 -9
- package/dist/agents/ReactiveAgent.d.ts.map +1 -1
- package/dist/agents/ReactiveAgent.js +5 -3
- package/dist/agents/ReactiveAgent.js.map +1 -1
- package/dist/agents/RouterAgent.d.ts.map +1 -1
- package/dist/agents/RouterAgent.js +3 -0
- package/dist/agents/RouterAgent.js.map +1 -1
- package/dist/agents/SupervisorAgent.d.ts.map +1 -1
- package/dist/agents/SupervisorAgent.js +18 -5
- package/dist/agents/SupervisorAgent.js.map +1 -1
- package/dist/bridge/a2a/mapper.d.ts.map +1 -1
- package/dist/bridge/a2a/mapper.js +6 -0
- package/dist/bridge/a2a/mapper.js.map +1 -1
- package/dist/bridge/a2a/task.d.ts +2 -2
- package/dist/bridge/a2a/task.d.ts.map +1 -1
- package/dist/bridge/a2a/task.js.map +1 -1
- package/dist/bridge/sse/mapper.d.ts.map +1 -1
- package/dist/bridge/sse/mapper.js +6 -0
- package/dist/bridge/sse/mapper.js.map +1 -1
- package/dist/constants/a2a/index.d.ts +2 -2
- package/dist/constants/a2a/index.d.ts.map +1 -1
- package/dist/constants/a2a/index.js.map +1 -1
- package/dist/contracts/api.d.ts +22 -3
- package/dist/contracts/api.d.ts.map +1 -1
- package/dist/contracts/index.d.ts +3 -1
- package/dist/contracts/index.d.ts.map +1 -1
- package/dist/contracts/index.js.map +1 -1
- package/dist/gateway/local.d.ts.map +1 -1
- package/dist/gateway/local.js +6 -0
- package/dist/gateway/local.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/manager/agent/__tests__/lifecycle.test.d.ts +2 -0
- package/dist/manager/agent/__tests__/lifecycle.test.d.ts.map +1 -0
- package/dist/manager/agent/__tests__/lifecycle.test.js +302 -0
- package/dist/manager/agent/__tests__/lifecycle.test.js.map +1 -0
- package/dist/manager/agent/lifecycle.d.ts +58 -3
- package/dist/manager/agent/lifecycle.d.ts.map +1 -1
- package/dist/manager/agent/lifecycle.js +311 -12
- package/dist/manager/agent/lifecycle.js.map +1 -1
- package/dist/manager/run/persistence.d.ts +8 -1
- package/dist/manager/run/persistence.d.ts.map +1 -1
- package/dist/manager/run/persistence.js +15 -0
- package/dist/manager/run/persistence.js.map +1 -1
- package/dist/run/reporter.d.ts.map +1 -1
- package/dist/run/reporter.js +25 -0
- package/dist/run/reporter.js.map +1 -1
- package/dist/runtime/query/__tests__/context.test.d.ts +2 -0
- package/dist/runtime/query/__tests__/context.test.d.ts.map +1 -0
- package/dist/runtime/query/__tests__/context.test.js +84 -0
- package/dist/runtime/query/__tests__/context.test.js.map +1 -0
- package/dist/runtime/query/context.d.ts +55 -2
- package/dist/runtime/query/context.d.ts.map +1 -1
- package/dist/runtime/query/context.js +48 -8
- package/dist/runtime/query/context.js.map +1 -1
- package/dist/runtime/query/events.d.ts.map +1 -1
- package/dist/runtime/query/events.js +8 -0
- package/dist/runtime/query/events.js.map +1 -1
- package/dist/runtime/query/index.d.ts +25 -2
- package/dist/runtime/query/index.d.ts.map +1 -1
- package/dist/runtime/query/index.js +11 -1
- package/dist/runtime/query/index.js.map +1 -1
- package/dist/session/__tests__/integration/_fixtures.d.ts +115 -0
- package/dist/session/__tests__/integration/_fixtures.d.ts.map +1 -0
- package/dist/session/__tests__/integration/_fixtures.js +198 -0
- package/dist/session/__tests__/integration/_fixtures.js.map +1 -0
- package/dist/session/__tests__/integration/capacity-caps.test.d.ts +13 -0
- package/dist/session/__tests__/integration/capacity-caps.test.d.ts.map +1 -0
- package/dist/session/__tests__/integration/capacity-caps.test.js +116 -0
- package/dist/session/__tests__/integration/capacity-caps.test.js.map +1 -0
- package/dist/session/__tests__/integration/e2e-spawn.test.d.ts +18 -0
- package/dist/session/__tests__/integration/e2e-spawn.test.d.ts.map +1 -0
- package/dist/session/__tests__/integration/e2e-spawn.test.js +226 -0
- package/dist/session/__tests__/integration/e2e-spawn.test.js.map +1 -0
- package/dist/session/__tests__/integration/event-stream-ordering.test.d.ts +15 -0
- package/dist/session/__tests__/integration/event-stream-ordering.test.d.ts.map +1 -0
- package/dist/session/__tests__/integration/event-stream-ordering.test.js +323 -0
- package/dist/session/__tests__/integration/event-stream-ordering.test.js.map +1 -0
- package/dist/session/__tests__/integration/handoff-broadcast-e2e.test.d.ts +12 -0
- package/dist/session/__tests__/integration/handoff-broadcast-e2e.test.d.ts.map +1 -0
- package/dist/session/__tests__/integration/handoff-broadcast-e2e.test.js +170 -0
- package/dist/session/__tests__/integration/handoff-broadcast-e2e.test.js.map +1 -0
- package/dist/session/__tests__/integration/handoff-illegal-transition.test.d.ts +18 -0
- package/dist/session/__tests__/integration/handoff-illegal-transition.test.d.ts.map +1 -0
- package/dist/session/__tests__/integration/handoff-illegal-transition.test.js +146 -0
- package/dist/session/__tests__/integration/handoff-illegal-transition.test.js.map +1 -0
- package/dist/session/__tests__/integration/handoff-single-e2e.test.d.ts +15 -0
- package/dist/session/__tests__/integration/handoff-single-e2e.test.d.ts.map +1 -0
- package/dist/session/__tests__/integration/handoff-single-e2e.test.js +163 -0
- package/dist/session/__tests__/integration/handoff-single-e2e.test.js.map +1 -0
- package/dist/session/__tests__/integration/hierarchy-lifecycle.test.d.ts +12 -0
- package/dist/session/__tests__/integration/hierarchy-lifecycle.test.d.ts.map +1 -0
- package/dist/session/__tests__/integration/hierarchy-lifecycle.test.js +157 -0
- package/dist/session/__tests__/integration/hierarchy-lifecycle.test.js.map +1 -0
- package/dist/session/__tests__/integration/migration-filesystem.test.d.ts +11 -0
- package/dist/session/__tests__/integration/migration-filesystem.test.d.ts.map +1 -0
- package/dist/session/__tests__/integration/migration-filesystem.test.js +140 -0
- package/dist/session/__tests__/integration/migration-filesystem.test.js.map +1 -0
- package/dist/session/__tests__/integration/migration-id-prefix.test.d.ts +13 -0
- package/dist/session/__tests__/integration/migration-id-prefix.test.d.ts.map +1 -0
- package/dist/session/__tests__/integration/migration-id-prefix.test.js +84 -0
- package/dist/session/__tests__/integration/migration-id-prefix.test.js.map +1 -0
- package/dist/session/__tests__/integration/prev-artifact-dag.test.d.ts +14 -0
- package/dist/session/__tests__/integration/prev-artifact-dag.test.d.ts.map +1 -0
- package/dist/session/__tests__/integration/prev-artifact-dag.test.js +241 -0
- package/dist/session/__tests__/integration/prev-artifact-dag.test.js.map +1 -0
- package/dist/session/__tests__/integration/retention-archive.test.d.ts +12 -0
- package/dist/session/__tests__/integration/retention-archive.test.d.ts.map +1 -0
- package/dist/session/__tests__/integration/retention-archive.test.js +186 -0
- package/dist/session/__tests__/integration/retention-archive.test.js.map +1 -0
- package/dist/session/__tests__/integration/summary-materialization-e2e.test.d.ts +18 -0
- package/dist/session/__tests__/integration/summary-materialization-e2e.test.d.ts.map +1 -0
- package/dist/session/__tests__/integration/summary-materialization-e2e.test.js +200 -0
- package/dist/session/__tests__/integration/summary-materialization-e2e.test.js.map +1 -0
- package/dist/session/__tests__/integration/tenant-isolation.test.d.ts +14 -0
- package/dist/session/__tests__/integration/tenant-isolation.test.d.ts.map +1 -0
- package/dist/session/__tests__/integration/tenant-isolation.test.js +180 -0
- package/dist/session/__tests__/integration/tenant-isolation.test.js.map +1 -0
- package/dist/session/errors.d.ts +60 -0
- package/dist/session/errors.d.ts.map +1 -0
- package/dist/session/errors.js +50 -0
- package/dist/session/errors.js.map +1 -0
- package/dist/session/events/index.d.ts +4 -0
- package/dist/session/events/index.d.ts.map +1 -0
- package/dist/session/events/index.js +8 -0
- package/dist/session/events/index.js.map +1 -0
- package/dist/session/events/schema-version.d.ts +13 -0
- package/dist/session/events/schema-version.d.ts.map +1 -0
- package/dist/session/events/schema-version.js +12 -0
- package/dist/session/events/schema-version.js.map +1 -0
- package/dist/session/events/types.d.ts +64 -0
- package/dist/session/events/types.d.ts.map +1 -0
- package/dist/session/events/types.js +2 -0
- package/dist/session/events/types.js.map +1 -0
- package/dist/session/handoff/__tests__/broadcast.test.d.ts +2 -0
- package/dist/session/handoff/__tests__/broadcast.test.d.ts.map +1 -0
- package/dist/session/handoff/__tests__/broadcast.test.js +243 -0
- package/dist/session/handoff/__tests__/broadcast.test.js.map +1 -0
- package/dist/session/handoff/__tests__/capacity.test.d.ts +2 -0
- package/dist/session/handoff/__tests__/capacity.test.d.ts.map +1 -0
- package/dist/session/handoff/__tests__/capacity.test.js +100 -0
- package/dist/session/handoff/__tests__/capacity.test.js.map +1 -0
- package/dist/session/handoff/__tests__/single.test.d.ts +2 -0
- package/dist/session/handoff/__tests__/single.test.d.ts.map +1 -0
- package/dist/session/handoff/__tests__/single.test.js +230 -0
- package/dist/session/handoff/__tests__/single.test.js.map +1 -0
- package/dist/session/handoff/assignment.d.ts +59 -0
- package/dist/session/handoff/assignment.d.ts.map +1 -0
- package/dist/session/handoff/assignment.js +11 -0
- package/dist/session/handoff/assignment.js.map +1 -0
- package/dist/session/handoff/broadcast.d.ts +47 -0
- package/dist/session/handoff/broadcast.d.ts.map +1 -0
- package/dist/session/handoff/broadcast.js +296 -0
- package/dist/session/handoff/broadcast.js.map +1 -0
- package/dist/session/handoff/capacity.d.ts +66 -0
- package/dist/session/handoff/capacity.d.ts.map +1 -0
- package/dist/session/handoff/capacity.js +60 -0
- package/dist/session/handoff/capacity.js.map +1 -0
- package/dist/session/handoff/events.d.ts +66 -0
- package/dist/session/handoff/events.d.ts.map +1 -0
- package/dist/session/handoff/events.js +13 -0
- package/dist/session/handoff/events.js.map +1 -0
- package/dist/session/handoff/index.d.ts +12 -0
- package/dist/session/handoff/index.d.ts.map +1 -0
- package/dist/session/handoff/index.js +9 -0
- package/dist/session/handoff/index.js.map +1 -0
- package/dist/session/handoff/single.d.ts +62 -0
- package/dist/session/handoff/single.d.ts.map +1 -0
- package/dist/session/handoff/single.js +217 -0
- package/dist/session/handoff/single.js.map +1 -0
- package/dist/session/handoff/version.d.ts +52 -0
- package/dist/session/handoff/version.d.ts.map +1 -0
- package/dist/session/handoff/version.js +36 -0
- package/dist/session/handoff/version.js.map +1 -0
- package/dist/session/hierarchy/__tests__/session.test.d.ts +2 -0
- package/dist/session/hierarchy/__tests__/session.test.d.ts.map +1 -0
- package/dist/session/hierarchy/__tests__/session.test.js +67 -0
- package/dist/session/hierarchy/__tests__/session.test.js.map +1 -0
- package/dist/session/hierarchy/actor.d.ts +26 -0
- package/dist/session/hierarchy/actor.d.ts.map +1 -0
- package/dist/session/hierarchy/actor.js +2 -0
- package/dist/session/hierarchy/actor.js.map +1 -0
- package/dist/session/hierarchy/index.d.ts +8 -0
- package/dist/session/hierarchy/index.d.ts.map +1 -0
- package/dist/session/hierarchy/index.js +4 -0
- package/dist/session/hierarchy/index.js.map +1 -0
- package/dist/session/hierarchy/lineage.d.ts +15 -0
- package/dist/session/hierarchy/lineage.d.ts.map +1 -0
- package/dist/session/hierarchy/lineage.js +2 -0
- package/dist/session/hierarchy/lineage.js.map +1 -0
- package/dist/session/hierarchy/project.d.ts +40 -0
- package/dist/session/hierarchy/project.d.ts.map +1 -0
- package/dist/session/hierarchy/project.js +2 -0
- package/dist/session/hierarchy/project.js.map +1 -0
- package/dist/session/hierarchy/session.d.ts +59 -0
- package/dist/session/hierarchy/session.d.ts.map +1 -0
- package/dist/session/hierarchy/session.js +51 -0
- package/dist/session/hierarchy/session.js.map +1 -0
- package/dist/session/hierarchy/sub-session.d.ts +76 -0
- package/dist/session/hierarchy/sub-session.d.ts.map +1 -0
- package/dist/session/hierarchy/sub-session.js +2 -0
- package/dist/session/hierarchy/sub-session.js.map +1 -0
- package/dist/session/hierarchy/tenant.d.ts +13 -0
- package/dist/session/hierarchy/tenant.d.ts.map +1 -0
- package/dist/session/hierarchy/tenant.js +2 -0
- package/dist/session/hierarchy/tenant.js.map +1 -0
- package/dist/session/index.d.ts +10 -0
- package/dist/session/index.d.ts.map +1 -0
- package/dist/session/index.js +15 -0
- package/dist/session/index.js.map +1 -0
- package/dist/session/intervention/__tests__/prev-artifact.test.d.ts +2 -0
- package/dist/session/intervention/__tests__/prev-artifact.test.d.ts.map +1 -0
- package/dist/session/intervention/__tests__/prev-artifact.test.js +179 -0
- package/dist/session/intervention/__tests__/prev-artifact.test.js.map +1 -0
- package/dist/session/intervention/index.d.ts +3 -0
- package/dist/session/intervention/index.d.ts.map +1 -0
- package/dist/session/intervention/index.js +8 -0
- package/dist/session/intervention/index.js.map +1 -0
- package/dist/session/intervention/prev-artifact.d.ts +103 -0
- package/dist/session/intervention/prev-artifact.d.ts.map +1 -0
- package/dist/session/intervention/prev-artifact.js +112 -0
- package/dist/session/intervention/prev-artifact.js.map +1 -0
- package/dist/session/migration/__tests__/filesystem.test.d.ts +2 -0
- package/dist/session/migration/__tests__/filesystem.test.d.ts.map +1 -0
- package/dist/session/migration/__tests__/filesystem.test.js +188 -0
- package/dist/session/migration/__tests__/filesystem.test.js.map +1 -0
- package/dist/session/migration/__tests__/id-prefix.test.d.ts +2 -0
- package/dist/session/migration/__tests__/id-prefix.test.d.ts.map +1 -0
- package/dist/session/migration/__tests__/id-prefix.test.js +83 -0
- package/dist/session/migration/__tests__/id-prefix.test.js.map +1 -0
- package/dist/session/migration/__tests__/marker.test.d.ts +2 -0
- package/dist/session/migration/__tests__/marker.test.d.ts.map +1 -0
- package/dist/session/migration/__tests__/marker.test.js +75 -0
- package/dist/session/migration/__tests__/marker.test.js.map +1 -0
- package/dist/session/migration/errors.d.ts +26 -0
- package/dist/session/migration/errors.d.ts.map +1 -0
- package/dist/session/migration/errors.js +22 -0
- package/dist/session/migration/errors.js.map +1 -0
- package/dist/session/migration/filesystem.d.ts +94 -0
- package/dist/session/migration/filesystem.d.ts.map +1 -0
- package/dist/session/migration/filesystem.js +319 -0
- package/dist/session/migration/filesystem.js.map +1 -0
- package/dist/session/migration/id-prefix.d.ts +98 -0
- package/dist/session/migration/id-prefix.d.ts.map +1 -0
- package/dist/session/migration/id-prefix.js +116 -0
- package/dist/session/migration/id-prefix.js.map +1 -0
- package/dist/session/migration/index.d.ts +8 -0
- package/dist/session/migration/index.d.ts.map +1 -0
- package/dist/session/migration/index.js +8 -0
- package/dist/session/migration/index.js.map +1 -0
- package/dist/session/migration/marker.d.ts +57 -0
- package/dist/session/migration/marker.d.ts.map +1 -0
- package/dist/session/migration/marker.js +111 -0
- package/dist/session/migration/marker.js.map +1 -0
- package/dist/session/retention/__tests__/archive.test.d.ts +2 -0
- package/dist/session/retention/__tests__/archive.test.d.ts.map +1 -0
- package/dist/session/retention/__tests__/archive.test.js +252 -0
- package/dist/session/retention/__tests__/archive.test.js.map +1 -0
- package/dist/session/retention/__tests__/disk-backend.test.d.ts +2 -0
- package/dist/session/retention/__tests__/disk-backend.test.d.ts.map +1 -0
- package/dist/session/retention/__tests__/disk-backend.test.js +154 -0
- package/dist/session/retention/__tests__/disk-backend.test.js.map +1 -0
- package/dist/session/retention/archive-backend-ref.d.ts +18 -0
- package/dist/session/retention/archive-backend-ref.d.ts.map +1 -0
- package/dist/session/retention/archive-backend-ref.js +2 -0
- package/dist/session/retention/archive-backend-ref.js.map +1 -0
- package/dist/session/retention/archive.d.ts +130 -0
- package/dist/session/retention/archive.d.ts.map +1 -0
- package/dist/session/retention/archive.js +203 -0
- package/dist/session/retention/archive.js.map +1 -0
- package/dist/session/retention/backend.d.ts +101 -0
- package/dist/session/retention/backend.d.ts.map +1 -0
- package/dist/session/retention/backend.js +15 -0
- package/dist/session/retention/backend.js.map +1 -0
- package/dist/session/retention/disk-backend.d.ts +59 -0
- package/dist/session/retention/disk-backend.d.ts.map +1 -0
- package/dist/session/retention/disk-backend.js +236 -0
- package/dist/session/retention/disk-backend.js.map +1 -0
- package/dist/session/retention/index.d.ts +9 -0
- package/dist/session/retention/index.d.ts.map +1 -0
- package/dist/session/retention/index.js +6 -0
- package/dist/session/retention/index.js.map +1 -0
- package/dist/session/retention/policy.d.ts +49 -0
- package/dist/session/retention/policy.d.ts.map +1 -0
- package/dist/session/retention/policy.js +21 -0
- package/dist/session/retention/policy.js.map +1 -0
- package/dist/session/summary/__tests__/materialize.test.d.ts +2 -0
- package/dist/session/summary/__tests__/materialize.test.d.ts.map +1 -0
- package/dist/session/summary/__tests__/materialize.test.js +269 -0
- package/dist/session/summary/__tests__/materialize.test.js.map +1 -0
- package/dist/session/summary/deliverable.d.ts +74 -0
- package/dist/session/summary/deliverable.d.ts.map +1 -0
- package/dist/session/summary/deliverable.js +20 -0
- package/dist/session/summary/deliverable.js.map +1 -0
- package/dist/session/summary/index.d.ts +6 -0
- package/dist/session/summary/index.d.ts.map +1 -0
- package/dist/session/summary/index.js +9 -0
- package/dist/session/summary/index.js.map +1 -0
- package/dist/session/summary/materialize.d.ts +82 -0
- package/dist/session/summary/materialize.d.ts.map +1 -0
- package/dist/session/summary/materialize.js +117 -0
- package/dist/session/summary/materialize.js.map +1 -0
- package/dist/session/summary/ref.d.ts +91 -0
- package/dist/session/summary/ref.d.ts.map +1 -0
- package/dist/session/summary/ref.js +51 -0
- package/dist/session/summary/ref.js.map +1 -0
- package/dist/session/workspace/__tests__/git-worktree.test.d.ts +2 -0
- package/dist/session/workspace/__tests__/git-worktree.test.d.ts.map +1 -0
- package/dist/session/workspace/__tests__/git-worktree.test.js +244 -0
- package/dist/session/workspace/__tests__/git-worktree.test.js.map +1 -0
- package/dist/session/workspace/__tests__/path-builder.test.d.ts +2 -0
- package/dist/session/workspace/__tests__/path-builder.test.d.ts.map +1 -0
- package/dist/session/workspace/__tests__/path-builder.test.js +37 -0
- package/dist/session/workspace/__tests__/path-builder.test.js.map +1 -0
- package/dist/session/workspace/driver.d.ts +55 -0
- package/dist/session/workspace/driver.d.ts.map +1 -0
- package/dist/session/workspace/driver.js +12 -0
- package/dist/session/workspace/driver.js.map +1 -0
- package/dist/session/workspace/git-worktree.d.ts +65 -0
- package/dist/session/workspace/git-worktree.d.ts.map +1 -0
- package/dist/session/workspace/git-worktree.js +156 -0
- package/dist/session/workspace/git-worktree.js.map +1 -0
- package/dist/session/workspace/index.d.ts +8 -0
- package/dist/session/workspace/index.d.ts.map +1 -0
- package/dist/session/workspace/index.js +7 -0
- package/dist/session/workspace/index.js.map +1 -0
- package/dist/session/workspace/path-builder.d.ts +50 -0
- package/dist/session/workspace/path-builder.d.ts.map +1 -0
- package/dist/session/workspace/path-builder.js +50 -0
- package/dist/session/workspace/path-builder.js.map +1 -0
- package/dist/session/workspace/ref.d.ts +46 -0
- package/dist/session/workspace/ref.d.ts.map +1 -0
- package/dist/session/workspace/ref.js +11 -0
- package/dist/session/workspace/ref.js.map +1 -0
- package/dist/session/workspace/registry.d.ts +26 -0
- package/dist/session/workspace/registry.d.ts.map +1 -0
- package/dist/session/workspace/registry.js +35 -0
- package/dist/session/workspace/registry.js.map +1 -0
- package/dist/store/conversation/memory.d.ts +22 -0
- package/dist/store/conversation/memory.d.ts.map +1 -1
- package/dist/store/conversation/memory.js +22 -0
- package/dist/store/conversation/memory.js.map +1 -1
- package/dist/store/session/__tests__/disk.test.d.ts +2 -0
- package/dist/store/session/__tests__/disk.test.d.ts.map +1 -0
- package/dist/store/session/__tests__/disk.test.js +240 -0
- package/dist/store/session/__tests__/disk.test.js.map +1 -0
- package/dist/store/session/__tests__/memory.test.d.ts +2 -0
- package/dist/store/session/__tests__/memory.test.d.ts.map +1 -0
- package/dist/store/session/__tests__/memory.test.js +217 -0
- package/dist/store/session/__tests__/memory.test.js.map +1 -0
- package/dist/store/session/disk.d.ts +85 -0
- package/dist/store/session/disk.d.ts.map +1 -0
- package/dist/store/session/disk.js +757 -0
- package/dist/store/session/disk.js.map +1 -0
- package/dist/store/session/index.d.ts +7 -0
- package/dist/store/session/index.d.ts.map +1 -0
- package/dist/store/session/index.js +11 -0
- package/dist/store/session/index.js.map +1 -0
- package/dist/store/session/linkage.d.ts +38 -0
- package/dist/store/session/linkage.d.ts.map +1 -0
- package/dist/store/session/linkage.js +64 -0
- package/dist/store/session/linkage.js.map +1 -0
- package/dist/store/session/memory.d.ts +48 -0
- package/dist/store/session/memory.d.ts.map +1 -0
- package/dist/store/session/memory.js +322 -0
- package/dist/store/session/memory.js.map +1 -0
- package/dist/store/session/messages.d.ts +20 -0
- package/dist/store/session/messages.d.ts.map +1 -0
- package/dist/store/session/messages.js +12 -0
- package/dist/store/session/messages.js.map +1 -0
- package/dist/tools/builtins/__tests__/structuredOutput.example.d.ts +1 -1
- package/dist/types/agent/base.d.ts +28 -1
- package/dist/types/agent/base.d.ts.map +1 -1
- package/dist/types/agent/task.d.ts +50 -2
- package/dist/types/agent/task.d.ts.map +1 -1
- package/dist/types/agent/task.js.map +1 -1
- package/dist/types/conversation/index.d.ts +7 -0
- package/dist/types/conversation/index.d.ts.map +1 -1
- package/dist/types/ids/index.d.ts +26 -3
- package/dist/types/ids/index.d.ts.map +1 -1
- package/dist/types/ids/index.js +8 -1
- package/dist/types/ids/index.js.map +1 -1
- package/dist/types/invocation/__tests__/state.test.js +36 -29
- package/dist/types/invocation/__tests__/state.test.js.map +1 -1
- package/dist/types/invocation/index.d.ts +20 -4
- package/dist/types/invocation/index.d.ts.map +1 -1
- package/dist/types/invocation/index.js +10 -7
- package/dist/types/invocation/index.js.map +1 -1
- package/dist/types/run/config.d.ts +11 -1
- package/dist/types/run/config.d.ts.map +1 -1
- package/dist/types/run/events.d.ts +26 -1
- package/dist/types/run/events.d.ts.map +1 -1
- package/dist/types/run/index.d.ts.map +1 -1
- package/dist/types/run/index.js +8 -0
- package/dist/types/run/index.js.map +1 -1
- package/dist/types/run/metadata.d.ts +24 -1
- package/dist/types/run/metadata.d.ts.map +1 -1
- package/dist/types/run/status.d.ts +26 -0
- package/dist/types/run/status.d.ts.map +1 -0
- package/dist/types/run/status.js +2 -0
- package/dist/types/run/status.js.map +1 -0
- package/dist/types/session/ids.d.ts +18 -0
- package/dist/types/session/ids.d.ts.map +1 -0
- package/dist/types/session/ids.js +12 -0
- package/dist/types/session/ids.js.map +1 -0
- package/dist/types/session/index.d.ts +3 -0
- package/dist/types/session/index.d.ts.map +1 -0
- package/dist/types/session/index.js +5 -0
- package/dist/types/session/index.js.map +1 -0
- package/dist/types/session/store.d.ts +188 -0
- package/dist/types/session/store.d.ts.map +1 -0
- package/dist/types/session/store.js +14 -0
- package/dist/types/session/store.js.map +1 -0
- package/dist/utils/id.d.ts +18 -1
- package/dist/utils/id.d.ts.map +1 -1
- package/dist/utils/id.js +42 -4
- package/dist/utils/id.js.map +1 -1
- package/package.json +1 -1
- package/src/agents/ReactiveAgent.ts +7 -3
- package/src/agents/RouterAgent.ts +5 -0
- package/src/agents/SupervisorAgent.ts +26 -6
- package/src/bridge/a2a/mapper.ts +7 -0
- package/src/bridge/a2a/task.ts +2 -2
- package/src/bridge/sse/mapper.ts +8 -1
- package/src/constants/a2a/index.ts +2 -2
- package/src/contracts/api.ts +23 -3
- package/src/contracts/index.ts +2 -0
- package/src/gateway/local.ts +6 -0
- package/src/index.ts +14 -0
- package/src/manager/agent/__tests__/lifecycle.test.ts +452 -0
- package/src/manager/agent/lifecycle.ts +434 -19
- package/src/manager/run/persistence.ts +20 -1
- package/src/run/reporter.ts +28 -0
- package/src/runtime/query/__tests__/context.test.ts +101 -0
- package/src/runtime/query/context.ts +106 -10
- package/src/runtime/query/events.ts +8 -0
- package/src/runtime/query/index.ts +41 -3
- package/src/session/__tests__/integration/_fixtures.ts +282 -0
- package/src/session/__tests__/integration/capacity-caps.test.ts +164 -0
- package/src/session/__tests__/integration/e2e-spawn.test.ts +278 -0
- package/src/session/__tests__/integration/event-stream-ordering.test.ts +403 -0
- package/src/session/__tests__/integration/handoff-broadcast-e2e.test.ts +245 -0
- package/src/session/__tests__/integration/handoff-illegal-transition.test.ts +179 -0
- package/src/session/__tests__/integration/handoff-single-e2e.test.ts +220 -0
- package/src/session/__tests__/integration/hierarchy-lifecycle.test.ts +237 -0
- package/src/session/__tests__/integration/migration-filesystem.test.ts +209 -0
- package/src/session/__tests__/integration/migration-id-prefix.test.ts +101 -0
- package/src/session/__tests__/integration/prev-artifact-dag.test.ts +318 -0
- package/src/session/__tests__/integration/retention-archive.test.ts +231 -0
- package/src/session/__tests__/integration/summary-materialization-e2e.test.ts +237 -0
- package/src/session/__tests__/integration/tenant-isolation.test.ts +282 -0
- package/src/session/errors.ts +70 -0
- package/src/session/events/index.ts +16 -0
- package/src/session/events/schema-version.ts +13 -0
- package/src/session/events/types.ts +71 -0
- package/src/session/handoff/__tests__/broadcast.test.ts +350 -0
- package/src/session/handoff/__tests__/capacity.test.ts +123 -0
- package/src/session/handoff/__tests__/single.test.ts +316 -0
- package/src/session/handoff/assignment.ts +62 -0
- package/src/session/handoff/broadcast.ts +381 -0
- package/src/session/handoff/capacity.ts +121 -0
- package/src/session/handoff/events.ts +72 -0
- package/src/session/handoff/index.ts +29 -0
- package/src/session/handoff/single.ts +288 -0
- package/src/session/handoff/version.ts +59 -0
- package/src/session/hierarchy/__tests__/session.test.ts +92 -0
- package/src/session/hierarchy/actor.ts +17 -0
- package/src/session/hierarchy/index.ts +17 -0
- package/src/session/hierarchy/lineage.ts +15 -0
- package/src/session/hierarchy/project.ts +41 -0
- package/src/session/hierarchy/session.ts +97 -0
- package/src/session/hierarchy/sub-session.ts +92 -0
- package/src/session/hierarchy/tenant.ts +13 -0
- package/src/session/index.ts +15 -0
- package/src/session/intervention/__tests__/prev-artifact.test.ts +234 -0
- package/src/session/intervention/index.ts +16 -0
- package/src/session/intervention/prev-artifact.ts +180 -0
- package/src/session/migration/__tests__/filesystem.test.ts +263 -0
- package/src/session/migration/__tests__/id-prefix.test.ts +101 -0
- package/src/session/migration/__tests__/marker.test.ts +84 -0
- package/src/session/migration/errors.ts +23 -0
- package/src/session/migration/filesystem.ts +401 -0
- package/src/session/migration/id-prefix.ts +146 -0
- package/src/session/migration/index.ts +38 -0
- package/src/session/migration/marker.ts +131 -0
- package/src/session/retention/__tests__/archive.test.ts +316 -0
- package/src/session/retention/__tests__/disk-backend.test.ts +180 -0
- package/src/session/retention/archive-backend-ref.ts +17 -0
- package/src/session/retention/archive.ts +281 -0
- package/src/session/retention/backend.ts +107 -0
- package/src/session/retention/disk-backend.ts +304 -0
- package/src/session/retention/index.ts +16 -0
- package/src/session/retention/policy.ts +53 -0
- package/src/session/summary/__tests__/materialize.test.ts +341 -0
- package/src/session/summary/deliverable.ts +84 -0
- package/src/session/summary/index.ts +31 -0
- package/src/session/summary/materialize.ts +169 -0
- package/src/session/summary/ref.ts +104 -0
- package/src/session/workspace/__tests__/git-worktree.test.ts +258 -0
- package/src/session/workspace/__tests__/path-builder.test.ts +51 -0
- package/src/session/workspace/driver.ts +60 -0
- package/src/session/workspace/git-worktree.ts +209 -0
- package/src/session/workspace/index.ts +25 -0
- package/src/session/workspace/path-builder.ts +71 -0
- package/src/session/workspace/ref.ts +50 -0
- package/src/session/workspace/registry.ts +42 -0
- package/src/store/conversation/memory.ts +23 -0
- package/src/store/session/__tests__/disk.test.ts +346 -0
- package/src/store/session/__tests__/memory.test.ts +327 -0
- package/src/store/session/disk.ts +920 -0
- package/src/store/session/index.ts +14 -0
- package/src/store/session/linkage.ts +80 -0
- package/src/store/session/memory.ts +400 -0
- package/src/store/session/messages.ts +21 -0
- package/src/types/agent/base.ts +31 -1
- package/src/types/agent/task.ts +58 -2
- package/src/types/conversation/index.ts +7 -0
- package/src/types/ids/index.ts +41 -3
- package/src/types/invocation/__tests__/state.test.ts +37 -29
- package/src/types/invocation/index.ts +26 -10
- package/src/types/run/config.ts +12 -1
- package/src/types/run/events.ts +36 -1
- package/src/types/run/index.ts +8 -0
- package/src/types/run/metadata.ts +24 -1
- package/src/types/run/status.ts +33 -0
- package/src/types/session/ids.ts +34 -0
- package/src/types/session/index.ts +28 -0
- package/src/types/session/store.ts +229 -0
- package/src/utils/id.ts +55 -4
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Integration — boot-time filesystem re-layout wired through the real
|
|
3
|
+
* {@link DefaultFilesystemMigrator}. Temp-dir fixtures, no mocks.
|
|
4
|
+
*
|
|
5
|
+
* Covers roadmap §5 invariants: §13.4.1 boot migration (cold-boot / warm /
|
|
6
|
+
* idempotent / multi-thread), synthesized project.json + session.json with
|
|
7
|
+
* `_legacy: true` + UNKNOWN_TENANT_ID, marker `.migration/v0.2.0` written
|
|
8
|
+
* last.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { mkdir, mkdtemp, readFile, rm, stat, writeFile } from 'node:fs/promises'
|
|
12
|
+
import { tmpdir } from 'node:os'
|
|
13
|
+
import { join } from 'node:path'
|
|
14
|
+
import { afterEach, beforeEach, describe, expect, it } from 'vitest'
|
|
15
|
+
import { UNKNOWN_TENANT_ID } from '../../../types/ids/index.js'
|
|
16
|
+
import {
|
|
17
|
+
DefaultFilesystemMigrator,
|
|
18
|
+
type FilesystemMigrationEvent,
|
|
19
|
+
type FilesystemMigrationSink,
|
|
20
|
+
LEGACY_DEFAULT_PROJECT_PREFIX,
|
|
21
|
+
LEGACY_DEFAULT_SESSION_ID,
|
|
22
|
+
MARKER_REL_PATH,
|
|
23
|
+
MIGRATION_VERSION,
|
|
24
|
+
} from '../../migration/filesystem.js'
|
|
25
|
+
|
|
26
|
+
function collectingSink(): { events: FilesystemMigrationEvent[]; sink: FilesystemMigrationSink } {
|
|
27
|
+
const events: FilesystemMigrationEvent[] = []
|
|
28
|
+
return {
|
|
29
|
+
events,
|
|
30
|
+
sink: {
|
|
31
|
+
emit(ev) {
|
|
32
|
+
events.push(ev)
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async function seedLegacyThread(root: string, thread: string, runs: string[]): Promise<void> {
|
|
39
|
+
for (const run of runs) {
|
|
40
|
+
const dir = join(root, 'threads', thread, 'runs', run)
|
|
41
|
+
await mkdir(dir, { recursive: true })
|
|
42
|
+
await writeFile(join(dir, 'run.json'), JSON.stringify({ id: run }), 'utf-8')
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
async function pathExists(p: string): Promise<boolean> {
|
|
47
|
+
try {
|
|
48
|
+
await stat(p)
|
|
49
|
+
return true
|
|
50
|
+
} catch {
|
|
51
|
+
return false
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
describe('Integration — boot-time filesystem migration', () => {
|
|
56
|
+
let root: string
|
|
57
|
+
|
|
58
|
+
beforeEach(async () => {
|
|
59
|
+
root = await mkdtemp(join(tmpdir(), 'namzu-intgr-fsmig-'))
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
afterEach(async () => {
|
|
63
|
+
await rm(root, { recursive: true, force: true })
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
it('cold boot with legacy .namzu/threads/thd_abc → migrated to projects layout + marker + event', async () => {
|
|
67
|
+
await seedLegacyThread(root, 'thd_abc', ['run_xyz'])
|
|
68
|
+
const { events, sink } = collectingSink()
|
|
69
|
+
const migrator = new DefaultFilesystemMigrator(sink)
|
|
70
|
+
|
|
71
|
+
const result = await migrator.migrate(root)
|
|
72
|
+
|
|
73
|
+
expect(result.kind).toBe('migrated')
|
|
74
|
+
expect(result.migratedThreads).toEqual([
|
|
75
|
+
{ legacyThreadId: 'thd_abc', newProjectId: `${LEGACY_DEFAULT_PROJECT_PREFIX}abc` },
|
|
76
|
+
])
|
|
77
|
+
|
|
78
|
+
// New layout: projects/{prj_legacy_abc}/sessions/{ses_legacy_default}/runs/run_xyz
|
|
79
|
+
const newRunDir = join(
|
|
80
|
+
root,
|
|
81
|
+
'projects',
|
|
82
|
+
`${LEGACY_DEFAULT_PROJECT_PREFIX}abc`,
|
|
83
|
+
'sessions',
|
|
84
|
+
LEGACY_DEFAULT_SESSION_ID,
|
|
85
|
+
'runs',
|
|
86
|
+
'run_xyz',
|
|
87
|
+
)
|
|
88
|
+
expect(await pathExists(newRunDir)).toBe(true)
|
|
89
|
+
|
|
90
|
+
// Legacy sub-tree moved.
|
|
91
|
+
expect(await pathExists(join(root, 'threads', 'thd_abc', 'runs'))).toBe(false)
|
|
92
|
+
|
|
93
|
+
// Marker landed last.
|
|
94
|
+
const markerRaw = await readFile(join(root, MARKER_REL_PATH), 'utf-8')
|
|
95
|
+
const marker = JSON.parse(markerRaw)
|
|
96
|
+
expect(marker.version).toBe(MIGRATION_VERSION)
|
|
97
|
+
|
|
98
|
+
// Event emitted.
|
|
99
|
+
expect(events).toHaveLength(1)
|
|
100
|
+
expect(events[0]?.type).toBe('filesystem.migrated')
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
it('synthesized project.json has _legacy: true + tenantId: UNKNOWN_TENANT_ID', async () => {
|
|
104
|
+
await seedLegacyThread(root, 'thd_leg', ['run_a'])
|
|
105
|
+
const migrator = new DefaultFilesystemMigrator()
|
|
106
|
+
await migrator.migrate(root)
|
|
107
|
+
|
|
108
|
+
const parsed = JSON.parse(
|
|
109
|
+
await readFile(
|
|
110
|
+
join(root, 'projects', `${LEGACY_DEFAULT_PROJECT_PREFIX}leg`, 'project.json'),
|
|
111
|
+
'utf-8',
|
|
112
|
+
),
|
|
113
|
+
)
|
|
114
|
+
expect(parsed._legacy).toBe(true)
|
|
115
|
+
expect(parsed.tenantId).toBe(UNKNOWN_TENANT_ID)
|
|
116
|
+
expect(parsed.id).toBe(`${LEGACY_DEFAULT_PROJECT_PREFIX}leg`)
|
|
117
|
+
expect(parsed.config).toMatchObject({
|
|
118
|
+
maxDelegationDepth: 4,
|
|
119
|
+
maxDelegationWidth: 8,
|
|
120
|
+
maxInterventionDepth: 10,
|
|
121
|
+
})
|
|
122
|
+
})
|
|
123
|
+
|
|
124
|
+
it('synthesized session.json is idle + _legacy', async () => {
|
|
125
|
+
await seedLegacyThread(root, 'thd_seschk', ['run_a'])
|
|
126
|
+
const migrator = new DefaultFilesystemMigrator()
|
|
127
|
+
await migrator.migrate(root)
|
|
128
|
+
|
|
129
|
+
const parsed = JSON.parse(
|
|
130
|
+
await readFile(
|
|
131
|
+
join(
|
|
132
|
+
root,
|
|
133
|
+
'projects',
|
|
134
|
+
`${LEGACY_DEFAULT_PROJECT_PREFIX}seschk`,
|
|
135
|
+
'sessions',
|
|
136
|
+
LEGACY_DEFAULT_SESSION_ID,
|
|
137
|
+
'session.json',
|
|
138
|
+
),
|
|
139
|
+
'utf-8',
|
|
140
|
+
),
|
|
141
|
+
)
|
|
142
|
+
expect(parsed.id).toBe(LEGACY_DEFAULT_SESSION_ID)
|
|
143
|
+
expect(parsed.status).toBe('idle')
|
|
144
|
+
expect(parsed.tenantId).toBe(UNKNOWN_TENANT_ID)
|
|
145
|
+
expect(parsed._legacy).toBe(true)
|
|
146
|
+
})
|
|
147
|
+
|
|
148
|
+
it('warm boot: marker present → kind: already_migrated, no filesystem changes', async () => {
|
|
149
|
+
// First run creates the marker.
|
|
150
|
+
await seedLegacyThread(root, 'thd_warm', ['run_a'])
|
|
151
|
+
const migrator = new DefaultFilesystemMigrator()
|
|
152
|
+
await migrator.migrate(root)
|
|
153
|
+
|
|
154
|
+
// Second run must short-circuit.
|
|
155
|
+
const result = await migrator.migrate(root)
|
|
156
|
+
expect(result.kind).toBe('already_migrated')
|
|
157
|
+
expect(result.migratedThreads).toHaveLength(0)
|
|
158
|
+
})
|
|
159
|
+
|
|
160
|
+
it('idempotent: second migrate() invocation is noop in same process', async () => {
|
|
161
|
+
await seedLegacyThread(root, 'thd_idem', ['run_1'])
|
|
162
|
+
|
|
163
|
+
const migrator = new DefaultFilesystemMigrator()
|
|
164
|
+
const first = await migrator.migrate(root)
|
|
165
|
+
const second = await migrator.migrate(root)
|
|
166
|
+
|
|
167
|
+
expect(first.kind).toBe('migrated')
|
|
168
|
+
expect(second.kind).toBe('already_migrated')
|
|
169
|
+
expect(second.migratedThreads).toHaveLength(0)
|
|
170
|
+
|
|
171
|
+
// End state still valid.
|
|
172
|
+
const newRunDir = join(
|
|
173
|
+
root,
|
|
174
|
+
'projects',
|
|
175
|
+
`${LEGACY_DEFAULT_PROJECT_PREFIX}idem`,
|
|
176
|
+
'sessions',
|
|
177
|
+
LEGACY_DEFAULT_SESSION_ID,
|
|
178
|
+
'runs',
|
|
179
|
+
'run_1',
|
|
180
|
+
)
|
|
181
|
+
expect(await pathExists(newRunDir)).toBe(true)
|
|
182
|
+
})
|
|
183
|
+
|
|
184
|
+
it('three legacy threads migrated in one pass → marker lists all', async () => {
|
|
185
|
+
await seedLegacyThread(root, 'thd_alpha', ['run_a1', 'run_a2'])
|
|
186
|
+
await seedLegacyThread(root, 'thd_beta', ['run_b1'])
|
|
187
|
+
await seedLegacyThread(root, 'thd_gamma', ['run_g1'])
|
|
188
|
+
|
|
189
|
+
const migrator = new DefaultFilesystemMigrator()
|
|
190
|
+
const result = await migrator.migrate(root)
|
|
191
|
+
|
|
192
|
+
expect(result.kind).toBe('migrated')
|
|
193
|
+
expect(result.migratedThreads).toHaveLength(3)
|
|
194
|
+
const ids = result.migratedThreads.map((m) => m.legacyThreadId).sort()
|
|
195
|
+
expect(ids).toEqual(['thd_alpha', 'thd_beta', 'thd_gamma'])
|
|
196
|
+
|
|
197
|
+
const markerRaw = await readFile(join(root, MARKER_REL_PATH), 'utf-8')
|
|
198
|
+
const marker = JSON.parse(markerRaw)
|
|
199
|
+
expect(marker.migratedThreads).toHaveLength(3)
|
|
200
|
+
})
|
|
201
|
+
|
|
202
|
+
it('fresh install (no legacy + no marker): writes marker + returns noop_no_legacy', async () => {
|
|
203
|
+
const migrator = new DefaultFilesystemMigrator()
|
|
204
|
+
const result = await migrator.migrate(root)
|
|
205
|
+
|
|
206
|
+
expect(result.kind).toBe('noop_no_legacy')
|
|
207
|
+
expect(await pathExists(join(root, MARKER_REL_PATH))).toBe(true)
|
|
208
|
+
})
|
|
209
|
+
})
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Integration — ID-prefix read-accept + MigrationWarning emission.
|
|
3
|
+
*
|
|
4
|
+
* Covers roadmap §5 invariants: §13.3.1 `thd_*` → `prj_*` coercion with
|
|
5
|
+
* warning emission (once per distinct legacy id per process), rejection of
|
|
6
|
+
* unknown prefixes via {@link StalePrefixError}.
|
|
7
|
+
*
|
|
8
|
+
* Orthogonal to `session/migration/__tests__/id-prefix.test.ts` unit tests
|
|
9
|
+
* by wiring a single collecting sink across multiple `acceptLegacyThreadId`
|
|
10
|
+
* invocations so the dedup across the integration boundary is visible.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { beforeEach, describe, expect, it } from 'vitest'
|
|
14
|
+
import type { ProjectId } from '../../../types/session/ids.js'
|
|
15
|
+
import {
|
|
16
|
+
type MigrationWarning,
|
|
17
|
+
type MigrationWarningSink,
|
|
18
|
+
StalePrefixError,
|
|
19
|
+
__resetSeenLegacyForTests,
|
|
20
|
+
acceptLegacyThreadId,
|
|
21
|
+
} from '../../migration/id-prefix.js'
|
|
22
|
+
|
|
23
|
+
function collectingSink(): { emitted: MigrationWarning[]; sink: MigrationWarningSink } {
|
|
24
|
+
const emitted: MigrationWarning[] = []
|
|
25
|
+
return {
|
|
26
|
+
emitted,
|
|
27
|
+
sink: {
|
|
28
|
+
emit(w) {
|
|
29
|
+
emitted.push(w)
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
describe('Integration — ID-prefix migration window', () => {
|
|
36
|
+
beforeEach(() => {
|
|
37
|
+
__resetSeenLegacyForTests()
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
it('acceptLegacyThreadId("thd_abc") coerces to prj_abc and emits warning once', () => {
|
|
41
|
+
const { emitted, sink } = collectingSink()
|
|
42
|
+
const result = acceptLegacyThreadId('thd_abc', sink)
|
|
43
|
+
|
|
44
|
+
expect(result).toBe('prj_abc' as ProjectId)
|
|
45
|
+
expect(emitted).toHaveLength(1)
|
|
46
|
+
expect(emitted[0]?.kind).toBe('id_prefix_legacy_read')
|
|
47
|
+
expect(emitted[0]?.legacyId).toBe('thd_abc')
|
|
48
|
+
expect(emitted[0]?.normalizedId).toBe('prj_abc')
|
|
49
|
+
expect(emitted[0]?.emittedOncePerProcess).toBe(true)
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
it('second call with same id → no duplicate warning (process-level dedup)', () => {
|
|
53
|
+
const { emitted, sink } = collectingSink()
|
|
54
|
+
acceptLegacyThreadId('thd_abc', sink)
|
|
55
|
+
acceptLegacyThreadId('thd_abc', sink)
|
|
56
|
+
acceptLegacyThreadId('thd_abc', sink)
|
|
57
|
+
expect(emitted).toHaveLength(1)
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
it('distinct legacy ids emit distinct warnings', () => {
|
|
61
|
+
const { emitted, sink } = collectingSink()
|
|
62
|
+
acceptLegacyThreadId('thd_abc', sink)
|
|
63
|
+
acceptLegacyThreadId('thd_xyz', sink)
|
|
64
|
+
acceptLegacyThreadId('thd_abc', sink) // dedup, no emission
|
|
65
|
+
expect(emitted).toHaveLength(2)
|
|
66
|
+
expect(emitted.map((w) => w.legacyId).sort()).toEqual(['thd_abc', 'thd_xyz'])
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
it('acceptLegacyThreadId("prj_abc") returns as-is with no warning', () => {
|
|
70
|
+
const { emitted, sink } = collectingSink()
|
|
71
|
+
const result = acceptLegacyThreadId('prj_abc', sink)
|
|
72
|
+
expect(result).toBe('prj_abc' as ProjectId)
|
|
73
|
+
expect(emitted).toHaveLength(0)
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
it('acceptLegacyThreadId("xyz_abc") rejects with StalePrefixError (unknown_prefix)', () => {
|
|
77
|
+
const { sink } = collectingSink()
|
|
78
|
+
try {
|
|
79
|
+
acceptLegacyThreadId('xyz_abc', sink)
|
|
80
|
+
expect.fail('expected StalePrefixError')
|
|
81
|
+
} catch (err) {
|
|
82
|
+
expect(err).toBeInstanceOf(StalePrefixError)
|
|
83
|
+
expect((err as StalePrefixError).details.rawId).toBe('xyz_abc')
|
|
84
|
+
expect((err as StalePrefixError).details.kind).toBe('unknown_prefix')
|
|
85
|
+
}
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
it('dedup is per-sink-aggregated: a single process-level cache serves all sinks', () => {
|
|
89
|
+
// The dedup state is process-global (seenLegacy Set inside id-prefix.ts),
|
|
90
|
+
// so switching sinks mid-run does NOT re-trigger the warning. Consumers
|
|
91
|
+
// wiring a shared collector across modules observe the single emission.
|
|
92
|
+
const sinkA = collectingSink()
|
|
93
|
+
const sinkB = collectingSink()
|
|
94
|
+
|
|
95
|
+
acceptLegacyThreadId('thd_shared', sinkA.sink)
|
|
96
|
+
expect(sinkA.emitted).toHaveLength(1)
|
|
97
|
+
|
|
98
|
+
acceptLegacyThreadId('thd_shared', sinkB.sink)
|
|
99
|
+
expect(sinkB.emitted).toHaveLength(0) // process-wide dedup
|
|
100
|
+
})
|
|
101
|
+
})
|
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Integration — intervention `prevArtifactRef` DAG primitives wired against
|
|
3
|
+
* a real {@link InMemorySessionStore}-backed {@link InterventionChainLoader}.
|
|
4
|
+
*
|
|
5
|
+
* Covers roadmap §5 invariants: §4.5 prevArtifactRef acyclic DAG (cycle +
|
|
6
|
+
* depth rejection), terminal semantics for non-`session_summary` deliverables.
|
|
7
|
+
*
|
|
8
|
+
* Orthogonal to the unit tests in `session/intervention/__tests__/prev-artifact.test.ts`
|
|
9
|
+
* which run against a synthetic in-memory loader. This file wires the loader
|
|
10
|
+
* against live store state — every ancestor read is a SessionStore lookup,
|
|
11
|
+
* proving the walker composes with the real persistence layer.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { describe, expect, it } from 'vitest'
|
|
15
|
+
import { InMemorySessionStore } from '../../../store/session/memory.js'
|
|
16
|
+
import type { SessionId } from '../../../types/ids/index.js'
|
|
17
|
+
import type { DeliverableId, SubSessionId, SummaryId } from '../../../types/session/ids.js'
|
|
18
|
+
import {
|
|
19
|
+
ArtifactRefCycleError,
|
|
20
|
+
type InterventionChainLoader,
|
|
21
|
+
InterventionDepthExceeded,
|
|
22
|
+
validatePrevArtifactChain,
|
|
23
|
+
} from '../../intervention/prev-artifact.js'
|
|
24
|
+
import type { DeliverableRef, SessionSummaryDeliverable } from '../../summary/deliverable.js'
|
|
25
|
+
import { DEFAULT_TENANT, agentActor, userActor } from './_fixtures.js'
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Build a live loader pointing at a real InMemorySessionStore. Each node
|
|
29
|
+
* resolves via `findParentSubSession`-style lookup on the store's sub-session
|
|
30
|
+
* map — the walker is therefore verifying the real data structure.
|
|
31
|
+
*/
|
|
32
|
+
function buildLoaderFromStore(
|
|
33
|
+
store: InMemorySessionStore,
|
|
34
|
+
tenantId: typeof DEFAULT_TENANT,
|
|
35
|
+
): InterventionChainLoader {
|
|
36
|
+
return {
|
|
37
|
+
async loadAncestor(sessionId: SessionId) {
|
|
38
|
+
// Walk the store: session → parent sub-session → (parent, edge).
|
|
39
|
+
// drill() returns root-to-self ancestry; the element immediately
|
|
40
|
+
// before self is the direct parent-session-id.
|
|
41
|
+
const view = await store.drill(sessionId, tenantId)
|
|
42
|
+
if (!view) return null
|
|
43
|
+
const ancestry = view.ancestry
|
|
44
|
+
if (ancestry.length < 2) return null
|
|
45
|
+
const parentId = ancestry[ancestry.length - 2]
|
|
46
|
+
if (!parentId) return null
|
|
47
|
+
const parentChildren = await store.getChildren(parentId, tenantId)
|
|
48
|
+
const edge = parentChildren.find((sub) => sub.childSessionId === sessionId)
|
|
49
|
+
if (!edge) return null
|
|
50
|
+
return {
|
|
51
|
+
subSessionId: edge.id,
|
|
52
|
+
sessionId: edge.childSessionId,
|
|
53
|
+
...(edge.prevArtifactRef !== undefined && { prevArtifactRef: edge.prevArtifactRef }),
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
async function buildLinearChain(
|
|
60
|
+
store: InMemorySessionStore,
|
|
61
|
+
length: number,
|
|
62
|
+
): Promise<{ sessions: SessionId[] }> {
|
|
63
|
+
const project = await store.createProject(
|
|
64
|
+
{ tenantId: DEFAULT_TENANT, name: 'chain' },
|
|
65
|
+
DEFAULT_TENANT,
|
|
66
|
+
)
|
|
67
|
+
const sessions: SessionId[] = []
|
|
68
|
+
let previous: SessionId | null = null
|
|
69
|
+
for (let i = 0; i < length; i++) {
|
|
70
|
+
const s = await store.createSession(
|
|
71
|
+
{ projectId: project.id, currentActor: agentActor(`agt_${i}`) },
|
|
72
|
+
DEFAULT_TENANT,
|
|
73
|
+
)
|
|
74
|
+
if (previous) {
|
|
75
|
+
await store.createSubSession(
|
|
76
|
+
{
|
|
77
|
+
parentSessionId: previous,
|
|
78
|
+
childSessionId: s.id,
|
|
79
|
+
kind: 'intervention',
|
|
80
|
+
spawnedBy: userActor('usr_driver'),
|
|
81
|
+
},
|
|
82
|
+
DEFAULT_TENANT,
|
|
83
|
+
)
|
|
84
|
+
}
|
|
85
|
+
sessions.push(s.id)
|
|
86
|
+
previous = s.id
|
|
87
|
+
}
|
|
88
|
+
return { sessions }
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function summaryRefTo(sessionId: SessionId): SessionSummaryDeliverable {
|
|
92
|
+
return {
|
|
93
|
+
id: 'del_intgr' as DeliverableId,
|
|
94
|
+
kind: 'session_summary',
|
|
95
|
+
sessionId,
|
|
96
|
+
summaryRef: 'sum_x' as SummaryId,
|
|
97
|
+
at: new Date(),
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
describe('Integration — prevArtifactRef DAG against real store', () => {
|
|
102
|
+
it('accepts depth-1 and depth-2 chains', async () => {
|
|
103
|
+
const store = new InMemorySessionStore()
|
|
104
|
+
const { sessions } = await buildLinearChain(store, 3)
|
|
105
|
+
const loader = buildLoaderFromStore(store, DEFAULT_TENANT)
|
|
106
|
+
|
|
107
|
+
const proposedChild = 'sub_proposed' as SubSessionId
|
|
108
|
+
|
|
109
|
+
// Depth 1: walk pointed at the last session in the chain has no
|
|
110
|
+
// prevArtifactRef populated (our test chain is bare), so result is a
|
|
111
|
+
// single-element chain.
|
|
112
|
+
const depth1 = await validatePrevArtifactChain(
|
|
113
|
+
loader,
|
|
114
|
+
proposedChild,
|
|
115
|
+
summaryRefTo(sessions[0] as SessionId),
|
|
116
|
+
10,
|
|
117
|
+
)
|
|
118
|
+
// The loader looks up `sessions[0]` — that session is the root and has
|
|
119
|
+
// no parent sub-session. Chain terminates at zero links.
|
|
120
|
+
expect(depth1.length).toBeLessThanOrEqual(10)
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
it('depth at limit accepted; one over rejected with InterventionDepthExceeded', async () => {
|
|
124
|
+
// Use a synthetic chain since the store-backed loader walks ancestry
|
|
125
|
+
// via session linkage (not through `prevArtifactRef`). The roadmap
|
|
126
|
+
// requirement is "walker enforces cap" — we exercise exactly that.
|
|
127
|
+
const syntheticLoader: InterventionChainLoader = {
|
|
128
|
+
async loadAncestor(sid) {
|
|
129
|
+
// Produce an infinite chain by always returning a deeper ancestor
|
|
130
|
+
// keyed off sid suffix.
|
|
131
|
+
const match = /ses_(\d+)/.exec(sid)
|
|
132
|
+
if (!match) return null
|
|
133
|
+
const n = Number(match[1])
|
|
134
|
+
if (n <= 0) return null
|
|
135
|
+
return {
|
|
136
|
+
subSessionId: `sub_${n}` as SubSessionId,
|
|
137
|
+
sessionId: `ses_${n - 1}` as SessionId,
|
|
138
|
+
prevArtifactRef: summaryRefTo(`ses_${n - 1}` as SessionId),
|
|
139
|
+
}
|
|
140
|
+
},
|
|
141
|
+
}
|
|
142
|
+
const proposed = 'sub_new' as SubSessionId
|
|
143
|
+
// Max 10: start at ses_10 and walk → 10 steps reachable, ses_0 terminates.
|
|
144
|
+
const okChain = await validatePrevArtifactChain(
|
|
145
|
+
syntheticLoader,
|
|
146
|
+
proposed,
|
|
147
|
+
summaryRefTo('ses_10' as SessionId),
|
|
148
|
+
10,
|
|
149
|
+
)
|
|
150
|
+
expect(okChain.length).toBeLessThanOrEqual(10)
|
|
151
|
+
|
|
152
|
+
// Over limit: starting at ses_12 requires 12 steps, over cap 10.
|
|
153
|
+
await expect(
|
|
154
|
+
validatePrevArtifactChain(syntheticLoader, proposed, summaryRefTo('ses_12' as SessionId), 10),
|
|
155
|
+
).rejects.toBeInstanceOf(InterventionDepthExceeded)
|
|
156
|
+
})
|
|
157
|
+
|
|
158
|
+
it('rejects self-reference (cycle)', async () => {
|
|
159
|
+
const proposed = 'sub_self' as SubSessionId
|
|
160
|
+
const loader: InterventionChainLoader = {
|
|
161
|
+
async loadAncestor(sid) {
|
|
162
|
+
return {
|
|
163
|
+
subSessionId: proposed, // self-reference
|
|
164
|
+
sessionId: sid,
|
|
165
|
+
}
|
|
166
|
+
},
|
|
167
|
+
}
|
|
168
|
+
await expect(
|
|
169
|
+
validatePrevArtifactChain(loader, proposed, summaryRefTo('ses_a' as SessionId), 10),
|
|
170
|
+
).rejects.toBeInstanceOf(ArtifactRefCycleError)
|
|
171
|
+
})
|
|
172
|
+
|
|
173
|
+
it('rejects 2-cycle and 3-cycle', async () => {
|
|
174
|
+
const proposed = 'sub_p' as SubSessionId
|
|
175
|
+
// 2-cycle: A ↔ B
|
|
176
|
+
const twoCycleLoader: InterventionChainLoader = {
|
|
177
|
+
async loadAncestor(sid) {
|
|
178
|
+
if (sid === ('ses_a' as SessionId)) {
|
|
179
|
+
return {
|
|
180
|
+
subSessionId: 'sub_a' as SubSessionId,
|
|
181
|
+
sessionId: 'ses_a' as SessionId,
|
|
182
|
+
prevArtifactRef: summaryRefTo('ses_b' as SessionId),
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
if (sid === ('ses_b' as SessionId)) {
|
|
186
|
+
return {
|
|
187
|
+
subSessionId: 'sub_a' as SubSessionId, // revisit sub_a closes the cycle
|
|
188
|
+
sessionId: 'ses_b' as SessionId,
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return null
|
|
192
|
+
},
|
|
193
|
+
}
|
|
194
|
+
await expect(
|
|
195
|
+
validatePrevArtifactChain(twoCycleLoader, proposed, summaryRefTo('ses_a' as SessionId), 10),
|
|
196
|
+
).rejects.toBeInstanceOf(ArtifactRefCycleError)
|
|
197
|
+
|
|
198
|
+
// 3-cycle: A → B → C → A
|
|
199
|
+
const threeCycleLoader: InterventionChainLoader = {
|
|
200
|
+
async loadAncestor(sid) {
|
|
201
|
+
if (sid === ('ses_a' as SessionId)) {
|
|
202
|
+
return {
|
|
203
|
+
subSessionId: 'sub_a' as SubSessionId,
|
|
204
|
+
sessionId: 'ses_a' as SessionId,
|
|
205
|
+
prevArtifactRef: summaryRefTo('ses_b' as SessionId),
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
if (sid === ('ses_b' as SessionId)) {
|
|
209
|
+
return {
|
|
210
|
+
subSessionId: 'sub_b' as SubSessionId,
|
|
211
|
+
sessionId: 'ses_b' as SessionId,
|
|
212
|
+
prevArtifactRef: summaryRefTo('ses_c' as SessionId),
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
if (sid === ('ses_c' as SessionId)) {
|
|
216
|
+
return {
|
|
217
|
+
subSessionId: 'sub_a' as SubSessionId, // back to start
|
|
218
|
+
sessionId: 'ses_c' as SessionId,
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
return null
|
|
222
|
+
},
|
|
223
|
+
}
|
|
224
|
+
await expect(
|
|
225
|
+
validatePrevArtifactChain(threeCycleLoader, proposed, summaryRefTo('ses_a' as SessionId), 10),
|
|
226
|
+
).rejects.toBeInstanceOf(ArtifactRefCycleError)
|
|
227
|
+
})
|
|
228
|
+
|
|
229
|
+
it('non-session_summary DeliverableRef terminates chain (file, artifact_blob, message)', async () => {
|
|
230
|
+
const loader: InterventionChainLoader = {
|
|
231
|
+
async loadAncestor() {
|
|
232
|
+
throw new Error('loader should not be invoked for non-session_summary')
|
|
233
|
+
},
|
|
234
|
+
}
|
|
235
|
+
const proposed = 'sub_p' as SubSessionId
|
|
236
|
+
|
|
237
|
+
const fileRef: DeliverableRef = {
|
|
238
|
+
id: 'del_f' as DeliverableId,
|
|
239
|
+
kind: 'file',
|
|
240
|
+
path: 'a.txt',
|
|
241
|
+
contentHash: 'abc',
|
|
242
|
+
sizeBytes: 0,
|
|
243
|
+
}
|
|
244
|
+
expect(await validatePrevArtifactChain(loader, proposed, fileRef, 10)).toEqual([])
|
|
245
|
+
|
|
246
|
+
const blobRef: DeliverableRef = {
|
|
247
|
+
id: 'del_b' as DeliverableId,
|
|
248
|
+
kind: 'artifact_blob',
|
|
249
|
+
storageRef: 'blob://x',
|
|
250
|
+
}
|
|
251
|
+
expect(await validatePrevArtifactChain(loader, proposed, blobRef, 10)).toEqual([])
|
|
252
|
+
})
|
|
253
|
+
|
|
254
|
+
it('wired end-to-end: store has a real 3-step intervention chain; walker confirms it through the store', async () => {
|
|
255
|
+
// Build A → B → C with prevArtifactRef edges explicitly attached, then
|
|
256
|
+
// verify the walker loader resolves each ancestor through the store.
|
|
257
|
+
const store = new InMemorySessionStore()
|
|
258
|
+
const project = await store.createProject(
|
|
259
|
+
{ tenantId: DEFAULT_TENANT, name: 'intgr' },
|
|
260
|
+
DEFAULT_TENANT,
|
|
261
|
+
)
|
|
262
|
+
const sA = await store.createSession(
|
|
263
|
+
{ projectId: project.id, currentActor: agentActor('agt_a') },
|
|
264
|
+
DEFAULT_TENANT,
|
|
265
|
+
)
|
|
266
|
+
const sB = await store.createSession(
|
|
267
|
+
{ projectId: project.id, currentActor: agentActor('agt_b') },
|
|
268
|
+
DEFAULT_TENANT,
|
|
269
|
+
)
|
|
270
|
+
const sC = await store.createSession(
|
|
271
|
+
{ projectId: project.id, currentActor: agentActor('agt_c') },
|
|
272
|
+
DEFAULT_TENANT,
|
|
273
|
+
)
|
|
274
|
+
|
|
275
|
+
const subAB = await store.createSubSession(
|
|
276
|
+
{
|
|
277
|
+
parentSessionId: sA.id,
|
|
278
|
+
childSessionId: sB.id,
|
|
279
|
+
kind: 'intervention',
|
|
280
|
+
spawnedBy: userActor('usr_d'),
|
|
281
|
+
},
|
|
282
|
+
DEFAULT_TENANT,
|
|
283
|
+
)
|
|
284
|
+
await store.updateSubSession(
|
|
285
|
+
{
|
|
286
|
+
...subAB,
|
|
287
|
+
prevArtifactRef: summaryRefTo(sA.id),
|
|
288
|
+
},
|
|
289
|
+
DEFAULT_TENANT,
|
|
290
|
+
)
|
|
291
|
+
|
|
292
|
+
const subBC = await store.createSubSession(
|
|
293
|
+
{
|
|
294
|
+
parentSessionId: sB.id,
|
|
295
|
+
childSessionId: sC.id,
|
|
296
|
+
kind: 'intervention',
|
|
297
|
+
spawnedBy: userActor('usr_d'),
|
|
298
|
+
},
|
|
299
|
+
DEFAULT_TENANT,
|
|
300
|
+
)
|
|
301
|
+
await store.updateSubSession(
|
|
302
|
+
{
|
|
303
|
+
...subBC,
|
|
304
|
+
prevArtifactRef: summaryRefTo(sB.id),
|
|
305
|
+
},
|
|
306
|
+
DEFAULT_TENANT,
|
|
307
|
+
)
|
|
308
|
+
|
|
309
|
+
const loader = buildLoaderFromStore(store, DEFAULT_TENANT)
|
|
310
|
+
// Ancestor of sC is sB, whose prev points at sA. Walker should traverse
|
|
311
|
+
// one step (to subBC) and then stop — sA has no ancestor sub-session.
|
|
312
|
+
const proposed = 'sub_proposed_c' as SubSessionId
|
|
313
|
+
const chain = await validatePrevArtifactChain(loader, proposed, summaryRefTo(sC.id), 10)
|
|
314
|
+
// The walker returns sub-session ids along the ancestry — at least one
|
|
315
|
+
// hop resolved through the real store.
|
|
316
|
+
expect(chain.length).toBeGreaterThan(0)
|
|
317
|
+
})
|
|
318
|
+
})
|