@sema-agent/core 7.54.1 → 7.55.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 +437 -0
- package/dist/agents/agent-transcript-tool.js +2 -1
- package/dist/agents/builtin-agents.d.ts +12 -14
- package/dist/agents/cc-peer-directory.d.ts +36 -0
- package/dist/agents/cc-peer-directory.js +138 -0
- package/dist/agents/cc-peer-wire.d.ts +105 -0
- package/dist/agents/cc-peer-wire.js +98 -0
- package/dist/agents/cc-uds-peer-channel.d.ts +40 -0
- package/dist/agents/cc-uds-peer-channel.js +457 -0
- package/dist/agents/cross-session-envelope.d.ts +4 -1
- package/dist/agents/cross-session-envelope.js +8 -1
- package/dist/agents/cross-session-judge.d.ts +2 -2
- package/dist/agents/list-agents-tool.js +2 -1
- package/dist/agents/observer.d.ts +4 -5
- package/dist/agents/observer.js +2 -1
- package/dist/agents/peer-admission.d.ts +6 -0
- package/dist/agents/peer-admission.js +4 -1
- package/dist/agents/peer-directory.d.ts +43 -9
- package/dist/agents/peer-directory.js +66 -23
- package/dist/agents/peer-notices.d.ts +1 -1
- package/dist/agents/peer-session-drain.d.ts +3 -1
- package/dist/agents/peer-session-drain.js +1 -0
- package/dist/agents/read-inbox-tool.js +2 -1
- package/dist/agents/retain-ledger.d.ts +1 -1
- package/dist/agents/roster-store.d.ts +1 -1
- package/dist/agents/send-message-tool.d.ts +10 -0
- package/dist/agents/send-message-tool.js +34 -5
- package/dist/agents/subagent.d.ts +34 -79
- package/dist/agents/subagent.js +45 -46
- package/dist/agents/tool-filter.d.ts +29 -46
- package/dist/agents/tool-filter.js +8 -31
- package/dist/agents/verify.d.ts +3 -3
- package/dist/brain/anthropic.js +14 -9
- package/dist/brain/errors.d.ts +15 -0
- package/dist/brain/errors.js +10 -0
- package/dist/brain/model-presets.d.ts +4 -4
- package/dist/brain/open-responses.js +15 -10
- package/dist/brain/openai.js +17 -12
- package/dist/brain/provider-dialect.d.ts +39 -3
- package/dist/brain/provider-dialect.js +28 -0
- package/dist/brain/reasoning.d.ts +1 -1
- package/dist/brain/request-params.d.ts +55 -5
- package/dist/brain/request-params.js +35 -3
- package/dist/brain/retry.d.ts +1 -1
- package/dist/brain/route-adjudicator.d.ts +15 -0
- package/dist/brain/route-adjudicator.js +15 -0
- package/dist/brain/stream-engine.js +6 -5
- package/dist/brain/stream-shared.d.ts +1 -1
- package/dist/core/advisor-verdict.d.ts +120 -0
- package/dist/core/advisor-verdict.js +92 -0
- package/dist/core/agent-definition.d.ts +7 -8
- package/dist/core/allow-entry.d.ts +49 -23
- package/dist/core/allow-entry.js +57 -32
- package/dist/core/allow-rule-shadow.d.ts +7 -0
- package/dist/core/approval-object.d.ts +2 -1
- package/dist/core/approval-object.js +6 -6
- package/dist/core/ask-origin.d.ts +63 -11
- package/dist/core/ask-origin.js +27 -5
- package/dist/core/ask-question.js +10 -4
- package/dist/core/auto-compaction.d.ts +11 -8
- package/dist/core/auto-compaction.js +4 -2
- package/dist/core/auto-mode-arming.d.ts +2 -2
- package/dist/core/auto-mode-defaults.d.ts +8 -8
- package/dist/core/auto-mode-prompt-assets.d.ts +3 -3
- package/dist/core/auto-mode-prompt.d.ts +1 -1
- package/dist/core/auto-mode.d.ts +17 -9
- package/dist/core/auto-mode.js +9 -6
- package/dist/core/background-agent-store.d.ts +3 -3
- package/dist/core/canonical-json.d.ts +1 -1
- package/dist/core/canonical-json.js +2 -2
- package/dist/core/checkpoint-requirements.d.ts +6 -3
- package/dist/core/checkpoint-requirements.js +4 -14
- package/dist/core/checkpoint-store.d.ts +80 -51
- package/dist/core/checkpoint-store.js +56 -74
- package/dist/core/child-clamp-seats.d.ts +6 -0
- package/dist/core/child-clamp-seats.js +3 -16
- package/dist/core/compliance.d.ts +2 -2
- package/dist/core/context-edit.d.ts +6 -7
- package/dist/core/cross-boundary-taint.d.ts +9 -3
- package/dist/core/cross-boundary-taint.js +5 -3
- package/dist/core/decision-receipt.js +2 -2
- package/dist/core/effective-path-target.d.ts +1 -1
- package/dist/core/engine-notice.d.ts +19 -5
- package/dist/core/exec-output-tail.d.ts +1 -1
- package/dist/core/file-history-retention.d.ts +1 -1
- package/dist/core/file-history-store.d.ts +59 -9
- package/dist/core/file-history-store.js +35 -17
- package/dist/core/gate-fold.js +3 -2
- package/dist/core/gate-lanes.js +12 -8
- package/dist/core/gate-outcome.d.ts +17 -4
- package/dist/core/gate-outcome.js +30 -0
- package/dist/core/governance-codes.d.ts +13 -3
- package/dist/core/governance-codes.js +10 -0
- package/dist/core/hands-band.d.ts +1 -1
- package/dist/core/hooks.d.ts +4 -4
- package/dist/core/host-target.d.ts +49 -0
- package/dist/core/host-target.js +59 -0
- package/dist/core/image-downsample.d.ts +1 -1
- package/dist/core/lsp-diagnostics.d.ts +4 -4
- package/dist/core/lsp.d.ts +3 -3
- package/dist/core/mailbox-store.d.ts +4 -0
- package/dist/core/mcp-connection-pool.d.ts +18 -2
- package/dist/core/mcp-connection-pool.js +53 -6
- package/dist/core/mcp-failure.d.ts +23 -4
- package/dist/core/mcp-failure.js +26 -11
- package/dist/core/mcp-listing-drift.d.ts +10 -0
- package/dist/core/mcp-listing-drift.js +6 -0
- package/dist/core/mcp-server-link.d.ts +173 -0
- package/dist/core/mcp-server-link.js +127 -0
- package/dist/core/mcp-server-spec.d.ts +4 -2
- package/dist/core/mcp-session-end.d.ts +26 -0
- package/dist/core/mcp-session-end.js +29 -0
- package/dist/core/mcp-startup-request.d.ts +17 -0
- package/dist/core/mcp-startup-request.js +17 -0
- package/dist/core/mcp.d.ts +13 -13
- package/dist/core/mcp.js +187 -162
- package/dist/core/media-byte-cap.d.ts +1 -1
- package/dist/core/memory-engine/engine.d.ts +9 -9
- package/dist/core/memory-engine/provenance-wording.d.ts +1 -1
- package/dist/core/memory-engine/tools.js +4 -1
- package/dist/core/mode-policy.d.ts +1 -1
- package/dist/core/namespaced-rule-name.d.ts +33 -7
- package/dist/core/namespaced-rule-name.js +39 -25
- package/dist/core/output-style.d.ts +1 -1
- package/dist/core/param-rule-reach.d.ts +15 -0
- package/dist/core/param-rule-reach.js +30 -0
- package/dist/core/parent-spec-seat.d.ts +8 -1
- package/dist/core/parent-spec-seat.js +4 -0
- package/dist/core/pause-registry.d.ts +16 -5
- package/dist/core/pause-registry.js +6 -2
- package/dist/core/peer-channel.d.ts +70 -0
- package/dist/core/peer-channel.js +1 -0
- package/dist/core/permission-rule-consent.d.ts +11 -5
- package/dist/core/permission-rule-consent.js +37 -30
- package/dist/core/permission-rule-model.d.ts +233 -64
- package/dist/core/permission-rule-model.js +384 -85
- package/dist/core/permission-rule-provider.d.ts +2 -1
- package/dist/core/permission-rule-store.d.ts +20 -25
- package/dist/core/permission-rule-store.js +1 -4
- package/dist/core/permission-rule-sync.d.ts +11 -2
- package/dist/core/permission-rule-sync.js +8 -1
- package/dist/core/permission-rules.d.ts +49 -11
- package/dist/core/permission-rules.js +123 -89
- package/dist/core/persisted-rule-arms.d.ts +4 -2
- package/dist/core/present-plan-tool.js +3 -1
- package/dist/core/protocol-naming.d.ts +2 -2
- package/dist/core/read-only-shell-table.d.ts +1 -1
- package/dist/core/read-only-shell.d.ts +1 -1
- package/dist/core/roles.d.ts +6 -2
- package/dist/core/roles.js +45 -44
- package/dist/core/rule-offer-read.d.ts +53 -0
- package/dist/core/rule-offer-read.js +146 -0
- package/dist/core/rule-owner.d.ts +46 -0
- package/dist/core/rule-owner.js +28 -0
- package/dist/core/runner/advisor-instructions.d.ts +70 -0
- package/dist/core/runner/advisor-instructions.js +61 -0
- package/dist/core/runner/advisor-tool.d.ts +33 -0
- package/dist/core/runner/advisor-tool.js +112 -0
- package/dist/core/runner/announce-once-ledger.d.ts +4 -26
- package/dist/core/runner/announce-once-ledger.js +14 -46
- package/dist/core/runner/approval-feedback.js +6 -3
- package/dist/core/runner/assemble-result.d.ts +1 -1
- package/dist/core/runner/caller-roster.d.ts +7 -0
- package/dist/core/runner/caller-roster.js +11 -0
- package/dist/core/runner/classifier-ladder.d.ts +27 -5
- package/dist/core/runner/classifier-ladder.js +12 -11
- package/dist/core/runner/compaction-restate.d.ts +10 -6
- package/dist/core/runner/compaction-restate.js +9 -3
- package/dist/core/runner/contracts.d.ts +13 -9
- package/dist/core/runner/conversation-segment.d.ts +28 -0
- package/dist/core/runner/conversation-segment.js +42 -0
- package/dist/core/runner/cross-boundary-lane.d.ts +6 -5
- package/dist/core/runner/cross-boundary-lane.js +26 -15
- package/dist/core/runner/decide-continuation.d.ts +7 -4
- package/dist/core/runner/decide-continuation.js +2 -2
- package/dist/core/runner/denial-limit-arms.d.ts +2 -2
- package/dist/core/runner/derived-route-fallback.d.ts +24 -24
- package/dist/core/runner/derived-route-fallback.js +9 -7
- package/dist/core/runner/gate-exit.d.ts +6 -0
- package/dist/core/runner/gate-exit.js +7 -2
- package/dist/core/runner/initial-run-state.js +1 -1
- package/dist/core/runner/permission-rule-lanes.d.ts +2 -2
- package/dist/core/runner/permission-rule-lanes.js +14 -7
- package/dist/core/runner/person-path-rows.js +1 -1
- package/dist/core/runner/prepare-advisor.d.ts +63 -0
- package/dist/core/runner/prepare-advisor.js +77 -0
- package/dist/core/runner/prepare-caps-and-workflow.js +1 -1
- package/dist/core/runner/prepare-config-doors.d.ts +6 -4
- package/dist/core/runner/prepare-config-doors.js +18 -12
- package/dist/core/runner/prepare-delegation-surface.d.ts +2 -2
- package/dist/core/runner/prepare-delegation-surface.js +1 -1
- package/dist/core/runner/prepare-file-history.js +39 -39
- package/dist/core/runner/prepare-gate-stations.d.ts +1 -4
- package/dist/core/runner/prepare-gate-stations.js +2 -7
- package/dist/core/runner/prepare-inherited-gate.d.ts +5 -4
- package/dist/core/runner/prepare-inherited-gate.js +3 -3
- package/dist/core/runner/prepare-park-ask.js +7 -7
- package/dist/core/runner/prepare-policy-chain.d.ts +1 -1
- package/dist/core/runner/prepare-policy-chain.js +4 -10
- package/dist/core/runner/prepare-project-context.d.ts +5 -2
- package/dist/core/runner/prepare-project-context.js +6 -3
- package/dist/core/runner/prepare-prompt-inputs.js +1 -1
- package/dist/core/runner/prepare-protocol-tools.d.ts +2 -2
- package/dist/core/runner/prepare-protocol-tools.js +3 -2
- package/dist/core/runner/prepare-safety-scan.d.ts +9 -12
- package/dist/core/runner/prepare-safety-scan.js +8 -6
- package/dist/core/runner/prepare-task.js +15 -18
- package/dist/core/runner/prepare-tool-disclosure-mount.js +6 -4
- package/dist/core/runner/prepare-wiring-manifest.d.ts +6 -3
- package/dist/core/runner/prepare-wiring-manifest.js +2 -2
- package/dist/core/runner/resume-policy-outcome.js +1 -1
- package/dist/core/runner/retired-runner-deps.js +1 -1
- package/dist/core/runner/run-attachment-seats.js +0 -1
- package/dist/core/runner/run-compaction-machinery.d.ts +1 -1
- package/dist/core/runner/run-compaction-machinery.js +2 -12
- package/dist/core/runner/run-git-lane.d.ts +1 -0
- package/dist/core/runner/run-harness-handlers.js +2 -3
- package/dist/core/runner/run-leg.js +13 -0
- package/dist/core/runner/run-settle-and-teardown.js +1 -1
- package/dist/core/runner/run-telemetry-and-budget-seats.js +1 -1
- package/dist/core/runner/run-turn-boundary.d.ts +1 -0
- package/dist/core/runner/run-turn-boundary.js +14 -12
- package/dist/core/runner/session-rule-policy.d.ts +22 -21
- package/dist/core/runner/session-rule-policy.js +13 -28
- package/dist/core/runner/side-call-account.d.ts +32 -8
- package/dist/core/runner/side-call-account.js +23 -1
- package/dist/core/runner/strict-output-schema.d.ts +1 -1
- package/dist/core/runner/sub-agent-deny-lists.js +4 -3
- package/dist/core/runner/synthetic-tools.d.ts +10 -13
- package/dist/core/runner/synthetic-tools.js +4 -2
- package/dist/core/runner/tool-disclosure.js +2 -1
- package/dist/core/runner/tool-face-overlay.d.ts +2 -1
- package/dist/core/runner/tool-face-overlay.js +17 -1
- package/dist/core/runner/tool-progress-lane.d.ts +2 -2
- package/dist/core/runner/tool-turn-repair-seat.d.ts +3 -2
- package/dist/core/runner/turn-attachments.d.ts +60 -67
- package/dist/core/runner-deps.d.ts +37 -37
- package/dist/core/runtime-caps.d.ts +4 -4
- package/dist/core/safety-merge-corpus.js +17 -1
- package/dist/core/same-plain-value.d.ts +40 -0
- package/dist/core/same-plain-value.js +49 -0
- package/dist/core/scheduler.d.ts +1 -1
- package/dist/core/sensitive-path-policy.d.ts +1 -1
- package/dist/core/sensitive-path-policy.js +1 -1
- package/dist/core/session-policy-store.d.ts +77 -22
- package/dist/core/session-policy-store.js +56 -14
- package/dist/core/session-reconcile.d.ts +2 -2
- package/dist/core/session-store.d.ts +80 -30
- package/dist/core/session-store.js +118 -76
- package/dist/core/session.d.ts +24 -46
- package/dist/core/shared-memory/tools.js +3 -1
- package/dist/core/shared-memory/types.d.ts +1 -1
- package/dist/core/side-query.d.ts +10 -0
- package/dist/core/side-query.js +5 -0
- package/dist/core/store-contracts/checkpoint-store-contract.js +29 -2
- package/dist/core/store-contracts/file-history-store-contract.js +43 -3
- package/dist/core/store-contracts/session-policy-store-contract.d.ts +7 -0
- package/dist/core/store-contracts/session-policy-store-contract.js +130 -0
- package/dist/core/store-contracts/session-repo-contract.js +125 -0
- package/dist/core/store-contracts/session-store-contract.d.ts +4 -7
- package/dist/core/store-contracts/session-store-contract.js +215 -41
- package/dist/core/store-contracts/workflow-journal-store-contract.js +26 -1
- package/dist/core/surrogate-safe-slice.d.ts +3 -3
- package/dist/core/task-event.d.ts +10 -4
- package/dist/core/task-notification.d.ts +3 -3
- package/dist/core/task-registry-agent.d.ts +4 -4
- package/dist/core/task-registry-shared.d.ts +4 -4
- package/dist/core/task-registry-shared.js +1 -0
- package/dist/core/task-registry.d.ts +4 -4
- package/dist/core/task-registry.js +3 -1
- package/dist/core/task-result.d.ts +3 -3
- package/dist/core/task-spec.d.ts +52 -52
- package/dist/core/task-stream.d.ts +6 -6
- package/dist/core/task-tool-shape.d.ts +4 -4
- package/dist/core/tighten-task-spec.d.ts +1 -1
- package/dist/core/tool-catalog-entries.d.ts +19 -2
- package/dist/core/tool-catalog-entries.js +57 -42
- package/dist/core/tool-conformance.js +1 -0
- package/dist/core/tool-errors.d.ts +2 -2
- package/dist/core/tool-face-reader.js +5 -3
- package/dist/core/tool-face.d.ts +21 -2
- package/dist/core/tool-face.js +1 -1
- package/dist/core/tool-model-gate.d.ts +3 -3
- package/dist/core/tool-name-aliases.d.ts +29 -8
- package/dist/core/tool-name-aliases.js +27 -3
- package/dist/core/tool-name-readings.d.ts +5 -8
- package/dist/core/tool-name-readings.js +1 -2
- package/dist/core/tool-policy.d.ts +24 -5
- package/dist/core/tool-policy.js +34 -10
- package/dist/core/tool-registry.d.ts +14 -7
- package/dist/core/tool-registry.js +17 -7
- package/dist/core/tool-result-store.js +2 -1
- package/dist/core/tool-roster.d.ts +47 -18
- package/dist/core/tool-roster.js +53 -32
- package/dist/core/tool-spec-members.js +1 -1
- package/dist/core/tool-spec.d.ts +35 -21
- package/dist/core/tools.js +3 -2
- package/dist/core/trace.d.ts +4 -0
- package/dist/core/untrusted-egress.d.ts +1 -1
- package/dist/core/untrusted-text.d.ts +1 -1
- package/dist/core/warm-resume.d.ts +1 -1
- package/dist/core/wiring-manifest.d.ts +49 -0
- package/dist/core/wiring-manifest.js +13 -5
- package/dist/core/workflow-journal-store.d.ts +62 -0
- package/dist/core/workflow-journal-store.js +77 -1
- package/dist/core/workflow-run-store.d.ts +6 -0
- package/dist/core/workflow-run-store.js +2 -0
- package/dist/engine/compaction/compaction.d.ts +9 -9
- package/dist/engine/execution-env/node-execution-env.d.ts +19 -5
- package/dist/engine/execution-env/node-execution-env.js +43 -22
- package/dist/engine/harness/agent-harness.d.ts +14 -8
- package/dist/engine/harness/agent-harness.js +33 -26
- package/dist/engine/harness/types.d.ts +29 -7
- package/dist/engine/harness/types.js +12 -1
- package/dist/engine/llm/types.d.ts +9 -9
- package/dist/engine/llm/validation.d.ts +4 -1
- package/dist/engine/llm/validation.js +13 -1
- package/dist/engine/loop/agent-loop.d.ts +1 -1
- package/dist/engine/loop/agent-loop.js +10 -8
- package/dist/engine/loop/types.d.ts +15 -13
- package/dist/engine/lsp/node-lsp-manager.d.ts +2 -2
- package/dist/engine/session/memory-repo.d.ts +10 -11
- package/dist/engine/session/memory-repo.js +13 -8
- package/dist/engine/session/parent-chain-guard.d.ts +3 -2
- package/dist/engine/session/parent-chain-guard.js +1 -1
- package/dist/engine/session/repo-utils.d.ts +31 -3
- package/dist/engine/session/repo-utils.js +42 -5
- package/dist/index.d.ts +27 -15
- package/dist/index.js +21 -11
- package/dist/internal/harness-types.d.ts +1 -1
- package/dist/internal/harness.d.ts +3 -3
- package/dist/internal/harness.js +2 -2
- package/dist/internal/llm.d.ts +1 -1
- package/dist/internal/llm.js +1 -1
- package/dist/orchestration/goal.js +2 -2
- package/dist/orchestration/run-workflow-tool.d.ts +2 -2
- package/dist/orchestration/run-workflow-tool.js +5 -3
- package/dist/orchestration/workflow-size-guideline.d.ts +4 -4
- package/dist/orchestration/workflow-types.d.ts +18 -0
- package/dist/orchestration/workflow-types.js +6 -0
- package/dist/orchestration/workflow.d.ts +2 -13
- package/dist/orchestration/workflow.js +21 -31
- package/dist/prompt-assembly/event-registry.js +1 -0
- package/dist/prompt-assembly/tool-catalog.d.ts +3 -0
- package/dist/prompt-assembly/tool-catalog.js +3 -0
- package/dist/prompts/default.d.ts +14 -14
- package/dist/scenarios/full-body.d.ts +4 -4
- package/dist/stores/file/adoption/adopt.d.ts +4 -3
- package/dist/stores/file/adoption/adopt.js +24 -31
- package/dist/stores/file/adoption/marker.d.ts +6 -13
- package/dist/stores/file/adoption/marker.js +6 -15
- package/dist/stores/file/checkpoint-store.d.ts +3 -0
- package/dist/stores/file/checkpoint-store.js +9 -3
- package/dist/stores/file/file-history-store.d.ts +20 -19
- package/dist/stores/file/file-history-store.js +152 -135
- package/dist/stores/file/fs-atomic.d.ts +15 -0
- package/dist/stores/file/fs-atomic.js +89 -14
- package/dist/stores/file/index.d.ts +1 -1
- package/dist/stores/file/mailbox-store.d.ts +3 -0
- package/dist/stores/file/mailbox-store.js +3 -1
- package/dist/stores/file/permission-rule-adopt.d.ts +1 -1
- package/dist/stores/file/permission-rule-adopt.js +15 -16
- package/dist/stores/file/permission-rule-store.d.ts +18 -2
- package/dist/stores/file/permission-rule-store.js +21 -14
- package/dist/stores/file/session-policy-store.d.ts +3 -3
- package/dist/stores/file/session-store.d.ts +26 -11
- package/dist/stores/file/session-store.js +77 -40
- package/dist/stores/file/workflow-journal-store.d.ts +10 -4
- package/dist/stores/file/workflow-journal-store.js +28 -13
- package/dist/tools/artifact/artifact-text.d.ts +1 -1
- package/dist/tools/artifact/artifact-tool.js +2 -1
- package/dist/tools/fs/bash-readonly-classifier.d.ts +3 -3
- package/dist/tools/fs/fs-bash.d.ts +2 -2
- package/dist/tools/fs/fs-bash.js +3 -1
- package/dist/tools/fs/fs-shared.d.ts +8 -8
- package/dist/tools/fs/gh-rate-limit.d.ts +1 -1
- package/dist/tools/fs/notebook.d.ts +2 -2
- package/dist/tools/fs/read-deny.d.ts +29 -7
- package/dist/tools/fs/read-deny.js +63 -22
- package/dist/tools/fs/removal-targets.d.ts +1 -1
- package/dist/tools/fs/safety.d.ts +9 -9
- package/dist/tools/fs/search.d.ts +6 -6
- package/dist/tools/fs/shell-read-check.js +6 -1
- package/dist/tools/fs/shell-read-judge.d.ts +4 -0
- package/dist/tools/fs/shell-read-judge.js +5 -2
- package/dist/tools/loop-tick.d.ts +2 -2
- package/dist/tools/scheduler-tools.js +5 -1
- package/dist/tools/task-list.d.ts +7 -7
- package/dist/tools/task-list.js +5 -1
- package/dist/tools/todo.js +2 -1
- package/dist/tools/web.d.ts +1 -1
- package/dist/tools/web.js +40 -37
- package/dist/tools/worktree.d.ts +3 -3
- package/dist/tools/worktree.js +3 -1
- package/package.json +1 -1
- package/test/export-surface.snapshot.json +5756 -5638
- package/wire-changes/core@7.55.0.json +3318 -0
- package/dist/core/store-contracts/session-store-incarnation-contract.d.ts +0 -39
- package/dist/core/store-contracts/session-store-incarnation-contract.js +0 -95
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { InMemorySessionRepo, SessionError, uuidv7, } from "../internal/harness.js";
|
|
1
|
+
import { InMemorySessionRepo, ParentChainGuard, SessionError, findUnansweredToolBatch, compareOccupants, uuidv7, } from "../internal/harness.js";
|
|
2
2
|
import { isSessionConflict } from "./session.js";
|
|
3
3
|
import { readMember } from "./thrown-value.js";
|
|
4
4
|
const DAY_MS = 24 * 60 * 60 * 1000;
|
|
@@ -23,12 +23,13 @@ export class TtlSessionStore {
|
|
|
23
23
|
durability;
|
|
24
24
|
placements;
|
|
25
25
|
listPlaced;
|
|
26
|
+
headOf;
|
|
27
|
+
repoHead;
|
|
26
28
|
repo;
|
|
27
29
|
entries = new Map();
|
|
28
|
-
owners = new Map();
|
|
29
30
|
pending = new Map();
|
|
30
31
|
pendingPlacedDeletes = new Set();
|
|
31
|
-
|
|
32
|
+
releasing = new Map();
|
|
32
33
|
pinned = new Set();
|
|
33
34
|
defaultTtlMs;
|
|
34
35
|
evictPolicy;
|
|
@@ -46,6 +47,11 @@ export class TtlSessionStore {
|
|
|
46
47
|
if (typeof repoListPlaced === "function") {
|
|
47
48
|
this.listPlaced = (kind, o) => repoListPlaced.call(this.repo, kind, o);
|
|
48
49
|
}
|
|
50
|
+
const repoHeadOf = this.repo.headOf;
|
|
51
|
+
if (typeof repoHeadOf === "function") {
|
|
52
|
+
this.repoHead = (sessionId) => repoHeadOf.call(this.repo, sessionId);
|
|
53
|
+
this.headOf = this.repoHead;
|
|
54
|
+
}
|
|
49
55
|
if (opts.sweepIntervalMs !== undefined && opts.sweepIntervalMs > 0) {
|
|
50
56
|
this.sweepTimer = setInterval(() => this.sweep(), opts.sweepIntervalMs);
|
|
51
57
|
this.sweepTimer.unref?.();
|
|
@@ -54,14 +60,18 @@ export class TtlSessionStore {
|
|
|
54
60
|
async acquire(sessionId, opts) {
|
|
55
61
|
this.sweep();
|
|
56
62
|
if (sessionId) {
|
|
57
|
-
const
|
|
58
|
-
if (
|
|
59
|
-
await
|
|
63
|
+
const inflightRelease = this.releasing.get(sessionId);
|
|
64
|
+
if (inflightRelease !== undefined)
|
|
65
|
+
await inflightRelease;
|
|
60
66
|
const existing = this.entries.get(sessionId);
|
|
61
67
|
if (existing) {
|
|
62
|
-
this.
|
|
63
|
-
|
|
64
|
-
|
|
68
|
+
if (await this.cachedViewStands(sessionId, existing)) {
|
|
69
|
+
this.assertPlacementAdmission(sessionId, existing.placement, opts);
|
|
70
|
+
existing.lastActiveAt = Date.now();
|
|
71
|
+
return { session: existing.session, sessionId };
|
|
72
|
+
}
|
|
73
|
+
if (this.entries.get(sessionId) === existing)
|
|
74
|
+
this.entries.delete(sessionId);
|
|
65
75
|
}
|
|
66
76
|
if (opts?.requireExisting) {
|
|
67
77
|
return { session: await this.openOrCreate(sessionId, true), sessionId };
|
|
@@ -87,6 +97,12 @@ export class TtlSessionStore {
|
|
|
87
97
|
const meta = await session.getMetadata();
|
|
88
98
|
return { session, sessionId: meta.id };
|
|
89
99
|
}
|
|
100
|
+
async cachedViewStands(sessionId, cached) {
|
|
101
|
+
if (this.repoHead === undefined)
|
|
102
|
+
return true;
|
|
103
|
+
const [shown, row] = await Promise.all([cached.session.getMetadata(), this.repoHead(sessionId)]);
|
|
104
|
+
return compareOccupants(shown, row) === "same";
|
|
105
|
+
}
|
|
90
106
|
assertPlacementAdmission(sessionId, placement, opts) {
|
|
91
107
|
const store = this;
|
|
92
108
|
admitSessionPlacement(sessionId, placement, opts ?? {}, {
|
|
@@ -99,8 +115,6 @@ export class TtlSessionStore {
|
|
|
99
115
|
try {
|
|
100
116
|
const session = await this.repo.open({ id, createdAt: "" });
|
|
101
117
|
const meta = await session.getMetadata();
|
|
102
|
-
if (meta.placement === undefined)
|
|
103
|
-
this.pendingPlacedDeletes.delete(id);
|
|
104
118
|
this.entries.set(id, { session, lastActiveAt: Date.now(), createdAt: meta.createdAt, ...(meta.forkedFrom !== undefined ? { forkedFrom: meta.forkedFrom } : {}), ...(meta.placement !== undefined ? { placement: meta.placement } : {}) });
|
|
105
119
|
return session;
|
|
106
120
|
}
|
|
@@ -115,10 +129,16 @@ export class TtlSessionStore {
|
|
|
115
129
|
}
|
|
116
130
|
}
|
|
117
131
|
async createAndStore(id, placement) {
|
|
118
|
-
|
|
132
|
+
let session;
|
|
133
|
+
try {
|
|
134
|
+
session = await this.repo.create({ ...(id !== undefined ? { id } : {}), ...(placement !== undefined ? { placement } : {}) });
|
|
135
|
+
}
|
|
136
|
+
catch (err) {
|
|
137
|
+
if (id === undefined || !isSessionConflict(err))
|
|
138
|
+
throw err;
|
|
139
|
+
session = await this.repo.open({ id, createdAt: "" });
|
|
140
|
+
}
|
|
119
141
|
const meta = await session.getMetadata();
|
|
120
|
-
if (meta.placement === undefined)
|
|
121
|
-
this.pendingPlacedDeletes.delete(meta.id);
|
|
122
142
|
this.entries.set(meta.id, { session, lastActiveAt: Date.now(), createdAt: meta.createdAt, ...(meta.forkedFrom !== undefined ? { forkedFrom: meta.forkedFrom } : {}), ...(meta.placement !== undefined ? { placement: meta.placement } : {}) });
|
|
123
143
|
return session;
|
|
124
144
|
}
|
|
@@ -164,17 +184,8 @@ export class TtlSessionStore {
|
|
|
164
184
|
throw err;
|
|
165
185
|
}
|
|
166
186
|
const forkOptions = await settledForkOptions(source);
|
|
167
|
-
const
|
|
168
|
-
if (owner != null) {
|
|
169
|
-
forkParams.owner = owner;
|
|
170
|
-
}
|
|
171
|
-
const forked = await this.repo.fork(await source.getMetadata(), forkParams);
|
|
187
|
+
const forked = await this.repo.fork(await source.getMetadata(), { ...forkOptions, id: uuidv7(), ...(owner !== undefined ? { owner } : {}) });
|
|
172
188
|
const meta = await forked.getMetadata();
|
|
173
|
-
const inherited = this.owners.has(sourceId) ? this.owners.get(sourceId) : undefined;
|
|
174
|
-
const forkOwner = owner ?? inherited;
|
|
175
|
-
if (forkOwner !== undefined && !this.owners.has(meta.id)) {
|
|
176
|
-
this.owners.set(meta.id, forkOwner);
|
|
177
|
-
}
|
|
178
189
|
this.entries.set(meta.id, {
|
|
179
190
|
session: forked,
|
|
180
191
|
lastActiveAt: Date.now(),
|
|
@@ -187,46 +198,66 @@ export class TtlSessionStore {
|
|
|
187
198
|
if (this.pinned.has(sessionId)) {
|
|
188
199
|
return;
|
|
189
200
|
}
|
|
190
|
-
const
|
|
191
|
-
if (
|
|
192
|
-
this.
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
if (typeof probe === "function") {
|
|
197
|
-
try {
|
|
198
|
-
placed = (await probe.call(this.repo, sessionId)) !== undefined;
|
|
199
|
-
}
|
|
200
|
-
catch {
|
|
201
|
-
placed = false;
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
if (!e && !placed) {
|
|
201
|
+
const cached = this.entries.get(sessionId);
|
|
202
|
+
if (cached !== undefined)
|
|
203
|
+
this.entries.delete(sessionId);
|
|
204
|
+
if (cached !== undefined && cached.placement === undefined && this.evictPolicy !== "delete")
|
|
205
|
+
return;
|
|
206
|
+
if (cached === undefined && !this.releasing.has(sessionId) && !this.rowReadMatters(sessionId))
|
|
206
207
|
return;
|
|
208
|
+
return this.holdingId(sessionId, () => this.releaseRow(sessionId, cached));
|
|
209
|
+
}
|
|
210
|
+
async holdingId(sessionId, work) {
|
|
211
|
+
const prior = this.releasing.get(sessionId);
|
|
212
|
+
let settle;
|
|
213
|
+
const gate = new Promise((r) => (settle = r));
|
|
214
|
+
this.releasing.set(sessionId, gate);
|
|
215
|
+
try {
|
|
216
|
+
if (prior !== undefined)
|
|
217
|
+
await prior;
|
|
218
|
+
await work();
|
|
219
|
+
}
|
|
220
|
+
finally {
|
|
221
|
+
if (this.releasing.get(sessionId) === gate)
|
|
222
|
+
this.releasing.delete(sessionId);
|
|
223
|
+
settle();
|
|
207
224
|
}
|
|
208
|
-
|
|
225
|
+
}
|
|
226
|
+
async releaseRow(sessionId, cached) {
|
|
227
|
+
if (cached?.placement !== undefined)
|
|
209
228
|
this.pendingPlacedDeletes.add(sessionId);
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
try {
|
|
214
|
-
const meta = e !== undefined ? await e.session.getMetadata() : { id: sessionId, createdAt: "" };
|
|
215
|
-
await this.repo.delete(meta);
|
|
216
|
-
}
|
|
217
|
-
finally {
|
|
218
|
-
this.deletingPlaced.delete(sessionId);
|
|
219
|
-
settleGate();
|
|
220
|
-
}
|
|
221
|
-
this.pendingPlacedDeletes.delete(sessionId);
|
|
222
|
-
this.owners.delete(sessionId);
|
|
229
|
+
const view = cached !== undefined && (await this.cachedViewStands(sessionId, cached)) ? cached : undefined;
|
|
230
|
+
const placed = view !== undefined ? view.placement !== undefined : await this.rowIsPlaced(sessionId);
|
|
231
|
+
if (view === undefined && !placed)
|
|
223
232
|
return;
|
|
233
|
+
const meta = view !== undefined ? await view.session.getMetadata() : { id: sessionId, createdAt: "" };
|
|
234
|
+
if (!placed)
|
|
235
|
+
return this.repo.delete(meta);
|
|
236
|
+
this.pendingPlacedDeletes.add(sessionId);
|
|
237
|
+
await this.repo.delete(meta);
|
|
238
|
+
this.pendingPlacedDeletes.delete(sessionId);
|
|
239
|
+
}
|
|
240
|
+
placementProbe() {
|
|
241
|
+
const probe = this.repo.placementOf;
|
|
242
|
+
return typeof probe === "function" ? probe.bind(this.repo) : undefined;
|
|
243
|
+
}
|
|
244
|
+
rowReadMatters(sessionId) {
|
|
245
|
+
return this.pendingPlacedDeletes.has(sessionId) || (this.placements !== undefined && this.placementProbe() !== undefined);
|
|
246
|
+
}
|
|
247
|
+
async rowIsPlaced(sessionId) {
|
|
248
|
+
if (!this.rowReadMatters(sessionId))
|
|
249
|
+
return false;
|
|
250
|
+
const probe = this.placementProbe();
|
|
251
|
+
let placement;
|
|
252
|
+
try {
|
|
253
|
+
placement = probe !== undefined ? await probe(sessionId) : (await (await this.repo.open({ id: sessionId, createdAt: "" })).getMetadata()).placement;
|
|
224
254
|
}
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
this.owners.delete(sessionId);
|
|
255
|
+
catch (err) {
|
|
256
|
+
if (!isNotFound(err))
|
|
257
|
+
throw err;
|
|
229
258
|
}
|
|
259
|
+
this.pendingPlacedDeletes.delete(sessionId);
|
|
260
|
+
return placement !== undefined;
|
|
230
261
|
}
|
|
231
262
|
forget(sessionId) {
|
|
232
263
|
this.entries.delete(sessionId);
|
|
@@ -237,29 +268,36 @@ export class TtlSessionStore {
|
|
|
237
268
|
unpin(sessionId) {
|
|
238
269
|
this.pinned.delete(sessionId);
|
|
239
270
|
}
|
|
240
|
-
async ownerOf(sessionId) {
|
|
241
|
-
return this.owners.has(sessionId) ? this.owners.get(sessionId) : undefined;
|
|
242
|
-
}
|
|
243
271
|
async register(sessionId, owner) {
|
|
244
|
-
|
|
272
|
+
const inflightRelease = this.releasing.get(sessionId);
|
|
273
|
+
if (inflightRelease !== undefined)
|
|
274
|
+
await inflightRelease;
|
|
275
|
+
if (await this.hasRow(sessionId))
|
|
245
276
|
return;
|
|
246
|
-
}
|
|
247
277
|
if (owner !== null && typeof owner !== "string") {
|
|
248
278
|
throw new TypeError(`SessionStore.register: owner must be a string (owned) or null (anonymous), got ${owner === undefined ? "undefined" : typeof owner}`);
|
|
249
279
|
}
|
|
250
|
-
|
|
280
|
+
try {
|
|
281
|
+
await this.repo.create({ id: sessionId, owner });
|
|
282
|
+
}
|
|
283
|
+
catch (err) {
|
|
284
|
+
if (isSessionConflict(err))
|
|
285
|
+
return;
|
|
286
|
+
throw err;
|
|
287
|
+
}
|
|
251
288
|
}
|
|
252
|
-
async
|
|
253
|
-
|
|
289
|
+
async hasRow(sessionId) {
|
|
290
|
+
if (this.repoHead !== undefined)
|
|
291
|
+
return (await this.repoHead(sessionId)) !== undefined;
|
|
254
292
|
try {
|
|
255
|
-
|
|
293
|
+
await this.repo.open({ id: sessionId, createdAt: "" });
|
|
294
|
+
return true;
|
|
256
295
|
}
|
|
257
296
|
catch (err) {
|
|
258
297
|
if (isNotFound(err))
|
|
259
|
-
return
|
|
298
|
+
return false;
|
|
260
299
|
throw err;
|
|
261
300
|
}
|
|
262
|
-
return (await session.getMetadata()).incarnation;
|
|
263
301
|
}
|
|
264
302
|
sweep(now = Date.now()) {
|
|
265
303
|
for (const [id, e] of this.entries) {
|
|
@@ -269,9 +307,10 @@ export class TtlSessionStore {
|
|
|
269
307
|
if (now - e.lastActiveAt > this.defaultTtlMs) {
|
|
270
308
|
this.entries.delete(id);
|
|
271
309
|
if (this.evictPolicy === "delete" && e.placement === undefined) {
|
|
272
|
-
void this.
|
|
273
|
-
this.
|
|
274
|
-
|
|
310
|
+
void this.holdingId(id, async () => {
|
|
311
|
+
if (await this.cachedViewStands(id, e))
|
|
312
|
+
await this.repo.delete({ id, createdAt: "" });
|
|
313
|
+
}).catch(() => { });
|
|
275
314
|
}
|
|
276
315
|
}
|
|
277
316
|
}
|
|
@@ -285,22 +324,25 @@ export class TtlSessionStore {
|
|
|
285
324
|
}
|
|
286
325
|
}
|
|
287
326
|
}
|
|
288
|
-
async function settledForkOptions(source) {
|
|
327
|
+
export async function settledForkOptions(source) {
|
|
289
328
|
const storage = source.getStorage();
|
|
290
329
|
let id = await storage.getLeafId();
|
|
330
|
+
const chain = new ParentChainGuard();
|
|
331
|
+
const answers = [];
|
|
291
332
|
while (id) {
|
|
333
|
+
chain.stepOnto(id);
|
|
292
334
|
const entry = await storage.getEntry(id);
|
|
293
335
|
if (!entry || entry.type !== "message") {
|
|
294
336
|
return {};
|
|
295
337
|
}
|
|
296
338
|
if (entry.message.role === "assistant") {
|
|
297
|
-
const
|
|
298
|
-
|
|
299
|
-
return hasToolCall && entry.parentId ? { entryId: entry.parentId, position: "at" } : {};
|
|
339
|
+
const open = findUnansweredToolBatch([entry.message, ...answers]) !== undefined;
|
|
340
|
+
return open && entry.parentId ? { entryId: entry.parentId, position: "at" } : {};
|
|
300
341
|
}
|
|
301
342
|
if (entry.message.role !== "toolResult") {
|
|
302
343
|
return {};
|
|
303
344
|
}
|
|
345
|
+
answers.push(entry.message);
|
|
304
346
|
id = entry.parentId;
|
|
305
347
|
}
|
|
306
348
|
return {};
|
package/dist/core/session.d.ts
CHANGED
|
@@ -6,8 +6,9 @@ export type { SessionStorage, SessionRepo, SessionMetadata, SessionTreeEntry, }
|
|
|
6
6
|
export { SessionError } from "../internal/harness.js";
|
|
7
7
|
export type { SessionWriteOptions } from "../internal/harness.js";
|
|
8
8
|
import type { Session } from "../internal/harness.js";
|
|
9
|
-
import type { SessionTreeEntry } from "../internal/harness.js";
|
|
9
|
+
import type { SessionHead, SessionTreeEntry } from "../internal/harness.js";
|
|
10
10
|
export type { SessionPlacementRecord } from "../internal/harness.js";
|
|
11
|
+
export type { SessionHead } from "../internal/harness.js";
|
|
11
12
|
/** True when `err` is a session optimistic-lock conflict (a concurrent writer won the branch leaf). Both
|
|
12
13
|
* halves read what a HOST `SessionStorage` threw, so both are guarded — unreadable is not a conflict,
|
|
13
14
|
* never a raise inside the classify-and-rethrow guard. The class test is KEPT: widening the verdict to
|
|
@@ -243,59 +244,36 @@ export interface SessionStore {
|
|
|
243
244
|
* an in-memory repo forks IN-PROCESS yet loses the copy on restart, while a durable repo (file/pg) makes the
|
|
244
245
|
* fork survive restart/replica. **Capability presence ≠ durability** — a cross-replica consumer (design/114
|
|
245
246
|
* warm-resume) MUST wire a durable repo; core cannot verify durability, only fail-loud on a missing source at
|
|
246
|
-
* fork time (returns `null`).
|
|
247
|
-
*
|
|
248
|
-
*
|
|
249
|
-
*
|
|
250
|
-
*
|
|
251
|
-
*
|
|
252
|
-
* effect when the source itself is unowned/anonymous. MUST copy the COMMITTED leaf (an in-flight
|
|
253
|
-
* uncommitted turn of an active source is not included — a fork is a snapshot at the fork point).
|
|
247
|
+
* fork time (returns `null`). The fork is a new row whose owner cell is recorded in the write that creates it — a fork
|
|
248
|
+
* COPIES the source's history, so the copy is never weaker than the original: with no `owner` argument, or an
|
|
249
|
+
* EXPLICIT `null`, the fork records the SOURCE row's owner ("anonymous" on a copy of an OWNED source would admit
|
|
250
|
+
* every principal to that history — a downgrade this face exists to prevent); an owner string records that owner.
|
|
251
|
+
* MUST copy the COMMITTED leaf (an in-flight uncommitted turn of an active source is not included — a fork is a
|
|
252
|
+
* snapshot at the fork point).
|
|
254
253
|
*/
|
|
255
254
|
fork?(sourceId: string, owner?: string | null): Promise<string | null>;
|
|
256
255
|
/**
|
|
257
|
-
*
|
|
258
|
-
*
|
|
259
|
-
*
|
|
256
|
+
* The row's {@link SessionHead} for `sessionId` — owner, occupant and active leaf — in ONE read of the row, never assembled from
|
|
257
|
+
* separate reads (a delete and re-create of the id between two reads would pair one generation's owner with the next one's
|
|
258
|
+
* occupant). `undefined` = no row for this id. A rejection is a read fault, not an answer.
|
|
260
259
|
*
|
|
261
|
-
*
|
|
262
|
-
*
|
|
263
|
-
*
|
|
264
|
-
*
|
|
265
|
-
*
|
|
266
|
-
* Collapsing `undefined` into `null` breaks the gate in both directions at once (an unknown id
|
|
267
|
-
* reads as an admissible anonymous session; an anonymous session reads as claimable).
|
|
260
|
+
* The BY-ID read, for a reader that did not acquire the session (hosts, a deployment's authorizer). A store that has it hands out,
|
|
261
|
+
* from `acquire`, only a session of the occupant it names — a cached view of an occupant the row no longer holds (the row deleted,
|
|
262
|
+
* or deleted and created again, through another writer — on the File lane a writer in another process too) is not served — so its `incarnation` and the acquired session's metadata agree (the kit pins both); a run's own memory seat reads the session it ACQUIRED instead, never this lookup. The owner is a cell of the row: `null` = anonymous (admitted to every principal) — a row created
|
|
263
|
+
* with no owner, a placed row, or a row written before the cell existed; a string = owned. **Optional**: absent ⇒ no by-id read,
|
|
264
|
+
* and a deployment's authorizer, which needs this and {@link register} together, takes its fail-closed arm.
|
|
268
265
|
*/
|
|
269
|
-
|
|
266
|
+
headOf?(sessionId: string): Promise<SessionHead | undefined>;
|
|
270
267
|
/**
|
|
271
|
-
*
|
|
272
|
-
*
|
|
273
|
-
*
|
|
274
|
-
*
|
|
275
|
-
*
|
|
276
|
-
*
|
|
277
|
-
*
|
|
278
|
-
* would be re-claimable by anyone); same-lifetime or longer both satisfy the contract — so a store that
|
|
279
|
-
* deletes the row when it deletes the history must gate that on the history delete having SUCCEEDED.
|
|
280
|
-
* An implementation must never store a value that {@link ownerOf} reads back as `undefined` (a row that
|
|
281
|
-
* EXISTS yet reads as "no row" is permanently claimable and never ownable): a FIRST write whose `owner` is
|
|
282
|
-
* neither a string nor `null` is refused loudly instead — the no-overwrite-no-throw rule above governs
|
|
283
|
-
* LATER calls, which stay silent no-ops whatever they carry.
|
|
268
|
+
* The owner write of the ownership pair ({@link headOf} + this). On an id with NO row it creates the row — an ordinary row, no
|
|
269
|
+
* placement — recording `owner` in the creating write, first-write-wins and atomic: of two concurrent first registers, both
|
|
270
|
+
* callers' re-reads see the same winner (durable implementations need a real uniqueness guarantee, not read-then-write). On an id
|
|
271
|
+
* whose row EXISTS it does nothing, whatever it carries — an owned row, an anonymous row, or a row `acquire` created (which
|
|
272
|
+
* records `null`) stays as it is; there is no claiming of an existing row. A FIRST write whose `owner` is neither a string nor
|
|
273
|
+
* `null` is refused loudly and leaves no row; a later call stays a silent no-op whatever it carries. Deliberately makes NO
|
|
274
|
+
* authorization decision — the caller re-reads {@link headOf} and judges there. The owner lives and dies with its row.
|
|
284
275
|
*/
|
|
285
276
|
register?(sessionId: string, owner: string | null): Promise<void>;
|
|
286
|
-
/**
|
|
287
|
-
* WHICH occupant holds `sessionId` now: the session row's {@link SessionMetadata.incarnation} cell,
|
|
288
|
-
* minted by the repo when the row came into existence and stable for the row's whole life (restarts,
|
|
289
|
-
* cache eviction, replicas). `undefined` = UNKNOWN — no row for this id, or a row written before the
|
|
290
|
-
* cell existed; a reader treats unknown as "cannot tell occupants apart", never as a different one.
|
|
291
|
-
* A rejection is a read fault, not an answer.
|
|
292
|
-
*
|
|
293
|
-
* The BY-ID read, for a reader that did not acquire the session (hosts; this read and the metadata of
|
|
294
|
-
* a session `acquire` hands back must agree — the incarnation kit pins both). A run's own memory seat
|
|
295
|
-
* reads the session it ACQUIRED instead, never a second lookup: the cached view `acquire` returns and
|
|
296
|
-
* a by-id read can answer two different rows. **Optional**: absent ⇒ no by-id read.
|
|
297
|
-
*/
|
|
298
|
-
incarnationOf?(sessionId: string): Promise<string | undefined>;
|
|
299
277
|
/** Number of live/cached sessions (best-effort). */
|
|
300
278
|
readonly size: number;
|
|
301
279
|
/** Release resources (timers, connections). Best-effort; must not throw. */
|
|
@@ -2,7 +2,7 @@ import { Type } from "typebox";
|
|
|
2
2
|
import { errorResult } from "../tools.js";
|
|
3
3
|
import { CONNECTING_MESSAGE, GENERIC_FAILURE_MESSAGE, NO_STORES_MESSAGE, SHARED_STORE_FRAME, UNAVAILABLE_MESSAGE, datePrefixOf, echoUntrusted, foldReaderError, listPrefixArgument, normalizeEntries, normalizeMemoryPath, normalizeReadValue, normalizeSnapshot, pageDocuments, relativePathRefusal, sanitizeSharedContent, validateDocumentPath, validatePathPrefix, } from "./normalize.js";
|
|
4
4
|
import { SHARED_MEMORY_LIST_PAGE_SIZE, SHARED_MEMORY_LIST_TOOL_NAME, SHARED_MEMORY_READ_CAP_BYTES, SHARED_MEMORY_READ_TOOL_NAME, } from "./types.js";
|
|
5
|
-
import { toolFace } from "../tool-catalog-entries.js";
|
|
5
|
+
import { mountRuleFace, toolFace } from "../tool-catalog-entries.js";
|
|
6
6
|
const LIST_HINT = "List shared memory stores and their documents — check here before telling the user you do not have something.";
|
|
7
7
|
const LIST_DESCRIPTION = [
|
|
8
8
|
LIST_HINT,
|
|
@@ -127,6 +127,7 @@ export function createSharedMemoryTools(opts) {
|
|
|
127
127
|
const listTool = {
|
|
128
128
|
name: SHARED_MEMORY_LIST_TOOL_NAME,
|
|
129
129
|
...toolFace("memory-list"),
|
|
130
|
+
ruleFace: mountRuleFace("memory-list"),
|
|
130
131
|
description: LIST_DESCRIPTION,
|
|
131
132
|
defer: true,
|
|
132
133
|
parameters: Type.Object({
|
|
@@ -258,6 +259,7 @@ export function createSharedMemoryTools(opts) {
|
|
|
258
259
|
const readTool = {
|
|
259
260
|
name: SHARED_MEMORY_READ_TOOL_NAME,
|
|
260
261
|
...toolFace("memory-read"),
|
|
262
|
+
ruleFace: mountRuleFace("memory-read"),
|
|
261
263
|
description: READ_DESCRIPTION,
|
|
262
264
|
defer: true,
|
|
263
265
|
parameters: Type.Object({
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* design/177 — the SHARED memory-store seam (connected team/deployment memory libraries the model may
|
|
3
3
|
* BROWSE and READ through two tools) and its model-facing constants.
|
|
4
4
|
*
|
|
5
|
-
* Upstream anchor:
|
|
5
|
+
* Upstream anchor: the reference's `memory_list` / `memory_read` pair, whose defining property was READ/WRITE
|
|
6
6
|
* ASYMMETRY (no model-side write channel); CC no longer has that shape — 2.1.296 also mounts `yd` (cli296.js:242348) "memory_write" — and sema keeps the 223 one (KL-878): write governance is an
|
|
7
7
|
* environment concern, and the tool face's entire participation in it is truthfully reporting each
|
|
8
8
|
* store's `writable` bit. sema keeps that structure and pushes the whole credential/consent half onto
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { AssistantMessage, StopReason, Tool, ToolResultMessage, Usage, UserMessage } from "../internal/llm.js";
|
|
2
2
|
import type { Brain, Model, ModelRef, ModelRole, ModelRoles, TaskSpec, ThinkingLevel } from "./types.js";
|
|
3
3
|
import { type DegradationInfo } from "../brain/degrading.js";
|
|
4
|
+
import { type BrainErrorCode } from "../brain/errors.js";
|
|
4
5
|
/** A tool DEFINITION exposed to the model in a side query (never executed by the engine). */
|
|
5
6
|
export interface SideQueryToolDef {
|
|
6
7
|
name: string;
|
|
@@ -117,6 +118,15 @@ export interface SideQueryResult {
|
|
|
117
118
|
* RETURNS the honest failure instead of throwing: utility callers uniformly need "no answer +
|
|
118
119
|
* why", and a throw would lose usage/model attribution for the failed attempt. */
|
|
119
120
|
errorMessage?: string;
|
|
121
|
+
/** The brain code of a failed query (`stopReason:"error"`), lifted from {@link errorMessage}'s `[code]` prefix by the one
|
|
122
|
+
* shared parser; absent when the message names none (an engine-minted shell, a custom brain). */
|
|
123
|
+
errorCode?: BrainErrorCode;
|
|
124
|
+
/** The STRUCTURAL failure kind the reply carried (`AssistantMessage.errorKind`), forwarded as is: `input_too_long` (the
|
|
125
|
+
* provider refused the request as over its window), `length_empty`, `degenerate`. Absent when the reply carried none. */
|
|
126
|
+
errorKind?: AssistantMessage["errorKind"];
|
|
127
|
+
/** `true` when the failure was a provider refusal its minter RULED OUT as input-too-long (`AssistantMessage.inputTooLongRuledOut`),
|
|
128
|
+
* forwarded as is. Absent otherwise. */
|
|
129
|
+
inputTooLongRuledOut?: true;
|
|
120
130
|
}
|
|
121
131
|
/** Dependencies the Runner passes through (a strict subset of RunnerDeps — no session/tool machinery). */
|
|
122
132
|
export interface SideQueryDeps {
|
package/dist/core/side-query.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ensureToolTurnInvariants } from "../internal/llm.js";
|
|
2
2
|
import { resolveTaskModel } from "./roles.js";
|
|
3
3
|
import { readDegradation } from "../brain/degrading.js";
|
|
4
|
+
import { extractErrorCode } from "../brain/errors.js";
|
|
4
5
|
import { cacheFamilyOf, uncachedInputTokensOf } from "./runner/usage-accounting.js";
|
|
5
6
|
import { providerReportedModel } from "./message-utils.js";
|
|
6
7
|
import { providerToolCallId } from "../brain/tool-call-id.js";
|
|
@@ -71,6 +72,7 @@ export async function runSideQuery(spec, deps) {
|
|
|
71
72
|
const degraded = readDegradation(msg);
|
|
72
73
|
const servedModel = typeof msg.model === "string" && msg.model.length > 0 ? msg.model : resolved.model.id;
|
|
73
74
|
const reportedModel = providerReportedModel(msg);
|
|
75
|
+
const errorCode = extractErrorCode(msg.errorMessage);
|
|
74
76
|
return {
|
|
75
77
|
text,
|
|
76
78
|
toolCalls,
|
|
@@ -82,5 +84,8 @@ export async function runSideQuery(spec, deps) {
|
|
|
82
84
|
...(msg.usageMissing === true ? { usageMissing: true } : {}),
|
|
83
85
|
stopReason: msg.stopReason,
|
|
84
86
|
...(msg.errorMessage !== undefined ? { errorMessage: msg.errorMessage } : {}),
|
|
87
|
+
...(msg.stopReason === "error" && errorCode !== undefined ? { errorCode } : {}),
|
|
88
|
+
...(msg.errorKind !== undefined ? { errorKind: msg.errorKind } : {}),
|
|
89
|
+
...(msg.inputTooLongRuledOut === true ? { inputTooLongRuledOut: true } : {}),
|
|
85
90
|
};
|
|
86
91
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { strict as assert } from "node:assert";
|
|
2
2
|
import { executionVerdict } from "../checkpoint-execution-record.js";
|
|
3
|
-
import { MAX_PENDING_STEER_ENTRIES, mintCheckpointToken, readPendingSteerQueue, } from "../checkpoint-store.js";
|
|
3
|
+
import { MAX_PENDING_STEER_ENTRIES, checkpointIndexFacts, mintCheckpointToken, readPendingSteerQueue, } from "../checkpoint-store.js";
|
|
4
4
|
import { checkpointFrom } from "../pause-registry.js";
|
|
5
5
|
import { beginContract } from "./contract-harness.js";
|
|
6
6
|
export function createCheckpointFixture(over = {}) {
|
|
@@ -308,7 +308,7 @@ export async function checkpointStoreContract(make, runAssertion) {
|
|
|
308
308
|
const stored = (await store.get(bitless.token)).pendingAction;
|
|
309
309
|
assert.equal("hasBidiControls" in stored, false, "projection backfill must not write back to the row");
|
|
310
310
|
});
|
|
311
|
-
run("the approval object's members: a row's identity + face group and its targets (capabilityId/contractId/shapeDigest/implementationRevision + family/pathTarget/names + targets) survive the round-trip verbatim; an absent group stays absent", async () => {
|
|
311
|
+
run("the approval object's members: a row's identity + face group and its targets (capabilityId/contractId/shapeDigest/implementationRevision + family/pathTarget/hostTarget/names + targets) survive the round-trip verbatim; an absent group stays absent", async () => {
|
|
312
312
|
const store = make();
|
|
313
313
|
const carried = createCheckpointFixture({ token: mintCheckpointToken(), sessionId: "id-carried" });
|
|
314
314
|
const group = {
|
|
@@ -331,6 +331,14 @@ export async function checkpointStoreContract(make, runAssertion) {
|
|
|
331
331
|
const bareBack = (await store.get(bare.token)).pendingAction;
|
|
332
332
|
for (const k of Object.keys(group))
|
|
333
333
|
assert.equal(k in bareBack, false, `an absent ${k} must stay OMITTED (a pre-388 row reads name-only, never a partial face)`);
|
|
334
|
+
const fetchRow = createCheckpointFixture({ token: mintCheckpointToken(), sessionId: "id-host" });
|
|
335
|
+
Object.assign(fetchRow.pendingAction, { ...group, family: "web", pathTarget: undefined, targets: undefined, hostTarget: { param: "url" } });
|
|
336
|
+
delete fetchRow.pendingAction.pathTarget;
|
|
337
|
+
delete fetchRow.pendingAction.targets;
|
|
338
|
+
await store.put(fetchRow.token, fetchRow);
|
|
339
|
+
const fetchBack = (await store.get(fetchRow.token)).pendingAction;
|
|
340
|
+
assert.deepEqual(fetchBack.hostTarget, { param: "url" }, "the row's hostTarget must survive the round-trip verbatim (dropped, a resume of the parked fetch reads a face that moved and is vetoed, and its pre-claim recheck judges the catalog's slot for the NAME)");
|
|
341
|
+
assert.equal("hostTarget" in bareBack, false, "an absent hostTarget must stay OMITTED");
|
|
334
342
|
});
|
|
335
343
|
run("#457 previewWithheld three-form matrix: a row's spelling survives + projects; absent stays absent; an out-of-contract spelling reads as absent", async () => {
|
|
336
344
|
const store = make();
|
|
@@ -436,6 +444,25 @@ export async function checkpointStoreContract(make, runAssertion) {
|
|
|
436
444
|
await assert.rejects(store.recordExecutionOutcome(cp.token, cp.scope, EXECUTED_ALLOW), (e) => e.code === "checkpoint.execution_outcome_conflict", "a person's record for a row the policy decided is a different record");
|
|
437
445
|
assert.deepEqual((await store.get(cp.token)).executionOutcome, POLICY_ALLOWED);
|
|
438
446
|
});
|
|
447
|
+
run("index facts: every row's checkpointIndexFacts survive the round trip — an approval gate with a card, a word outside the card set, no card, a descriptor, a deadline, the directional-control bit; a tool-less park", async () => {
|
|
448
|
+
const store = make();
|
|
449
|
+
const descriptor = { severity: 4, axes: { egress: true }, toolName: "Write" };
|
|
450
|
+
const laterWord = createCheckpointFixture({ gate: { kind: "human", reason: "approve", toolName: "Write" } });
|
|
451
|
+
Object.assign(laterWord.gate, { approvalCard: "card-of-a-later-engine" });
|
|
452
|
+
const rows = [
|
|
453
|
+
createCheckpointFixture({ gate: { kind: "human", reason: "approve", toolName: "Write", approvalCard: "file-write", riskDescriptor: descriptor }, deadline: 1_900_000_000_000 }),
|
|
454
|
+
createCheckpointFixture({ gate: { kind: "irreversible_ask", reason: "send", toolName: "Write", approvalCard: "question" } }),
|
|
455
|
+
laterWord,
|
|
456
|
+
createCheckpointFixture({ pendingAction: { kind: "tool_approval", origin: "policy", toolCallId: "call-b", toolName: "Write", args: {}, boundInputHash: "hb", hasBidiControls: true, batchToolCallIds: ["call-b"], completedCallIds: [] } }),
|
|
457
|
+
createCheckpointFixture({ gate: { kind: "resource_limit", reason: "turns" }, pendingAction: { kind: "resource_limit", reason: "turns" }, deadline: 1_900_000_000_001 }),
|
|
458
|
+
];
|
|
459
|
+
for (const cp of rows) {
|
|
460
|
+
await store.put(cp.token, cp);
|
|
461
|
+
const back = await store.get(cp.token);
|
|
462
|
+
assert.ok(back !== null, "a row put is a row read");
|
|
463
|
+
assert.deepEqual(checkpointIndexFacts(back), checkpointIndexFacts(cp), `the index facts of the row ${cp.gate.kind} came back different`);
|
|
464
|
+
}
|
|
465
|
+
});
|
|
439
466
|
await settle();
|
|
440
467
|
}
|
|
441
468
|
const sortByToken = (a, b) => a.token.localeCompare(b.token);
|