@sema-ai/core 1.275.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +5433 -0
- package/LICENSE +27 -0
- package/NOTICE.md +30 -0
- package/README.md +1040 -0
- package/dist/agents/agent-definition.d.ts +10 -0
- package/dist/agents/agent-definition.d.ts.map +1 -0
- package/dist/agents/agent-definition.js +18 -0
- package/dist/agents/agent-definition.js.map +1 -0
- package/dist/agents/builtin-agents.d.ts +69 -0
- package/dist/agents/builtin-agents.d.ts.map +1 -0
- package/dist/agents/builtin-agents.js +177 -0
- package/dist/agents/builtin-agents.js.map +1 -0
- package/dist/agents/cascade.d.ts +101 -0
- package/dist/agents/cascade.d.ts.map +1 -0
- package/dist/agents/cascade.js +189 -0
- package/dist/agents/cascade.js.map +1 -0
- package/dist/agents/observer.d.ts +209 -0
- package/dist/agents/observer.d.ts.map +1 -0
- package/dist/agents/observer.js +495 -0
- package/dist/agents/observer.js.map +1 -0
- package/dist/agents/repair-loop.d.ts +236 -0
- package/dist/agents/repair-loop.d.ts.map +1 -0
- package/dist/agents/repair-loop.js +293 -0
- package/dist/agents/repair-loop.js.map +1 -0
- package/dist/agents/session-util.d.ts +8 -0
- package/dist/agents/session-util.d.ts.map +1 -0
- package/dist/agents/session-util.js +9 -0
- package/dist/agents/session-util.js.map +1 -0
- package/dist/agents/subagent-steps.d.ts +93 -0
- package/dist/agents/subagent-steps.d.ts.map +1 -0
- package/dist/agents/subagent-steps.js +206 -0
- package/dist/agents/subagent-steps.js.map +1 -0
- package/dist/agents/subagent.d.ts +441 -0
- package/dist/agents/subagent.d.ts.map +1 -0
- package/dist/agents/subagent.js +2492 -0
- package/dist/agents/subagent.js.map +1 -0
- package/dist/agents/suspend-guard.d.ts +35 -0
- package/dist/agents/suspend-guard.d.ts.map +1 -0
- package/dist/agents/suspend-guard.js +48 -0
- package/dist/agents/suspend-guard.js.map +1 -0
- package/dist/agents/teacher.d.ts +137 -0
- package/dist/agents/teacher.d.ts.map +1 -0
- package/dist/agents/teacher.js +575 -0
- package/dist/agents/teacher.js.map +1 -0
- package/dist/agents/team.d.ts +211 -0
- package/dist/agents/team.d.ts.map +1 -0
- package/dist/agents/team.js +293 -0
- package/dist/agents/team.js.map +1 -0
- package/dist/agents/tool-filter.d.ts +29 -0
- package/dist/agents/tool-filter.d.ts.map +1 -0
- package/dist/agents/tool-filter.js +50 -0
- package/dist/agents/tool-filter.js.map +1 -0
- package/dist/agents/verify.d.ts +177 -0
- package/dist/agents/verify.d.ts.map +1 -0
- package/dist/agents/verify.js +305 -0
- package/dist/agents/verify.js.map +1 -0
- package/dist/bench/metrics.d.ts +714 -0
- package/dist/bench/metrics.d.ts.map +1 -0
- package/dist/bench/metrics.js +618 -0
- package/dist/bench/metrics.js.map +1 -0
- package/dist/bin/sema-tb.d.ts +3 -0
- package/dist/bin/sema-tb.d.ts.map +1 -0
- package/dist/bin/sema-tb.js +516 -0
- package/dist/bin/sema-tb.js.map +1 -0
- package/dist/bin/tb-env.d.ts +13 -0
- package/dist/bin/tb-env.d.ts.map +1 -0
- package/dist/bin/tb-env.js +26 -0
- package/dist/bin/tb-env.js.map +1 -0
- package/dist/brain/anthropic.d.ts +46 -0
- package/dist/brain/anthropic.d.ts.map +1 -0
- package/dist/brain/anthropic.js +830 -0
- package/dist/brain/anthropic.js.map +1 -0
- package/dist/brain/circuit-breaker.d.ts +46 -0
- package/dist/brain/circuit-breaker.d.ts.map +1 -0
- package/dist/brain/circuit-breaker.js +173 -0
- package/dist/brain/circuit-breaker.js.map +1 -0
- package/dist/brain/degrading.d.ts +98 -0
- package/dist/brain/degrading.d.ts.map +1 -0
- package/dist/brain/degrading.js +249 -0
- package/dist/brain/degrading.js.map +1 -0
- package/dist/brain/errors.d.ts +31 -0
- package/dist/brain/errors.d.ts.map +1 -0
- package/dist/brain/errors.js +58 -0
- package/dist/brain/errors.js.map +1 -0
- package/dist/brain/failover.d.ts +18 -0
- package/dist/brain/failover.d.ts.map +1 -0
- package/dist/brain/failover.js +118 -0
- package/dist/brain/failover.js.map +1 -0
- package/dist/brain/model-presets.d.ts +36 -0
- package/dist/brain/model-presets.d.ts.map +1 -0
- package/dist/brain/model-presets.js +54 -0
- package/dist/brain/model-presets.js.map +1 -0
- package/dist/brain/openai.d.ts +43 -0
- package/dist/brain/openai.d.ts.map +1 -0
- package/dist/brain/openai.js +784 -0
- package/dist/brain/openai.js.map +1 -0
- package/dist/brain/reasoning.d.ts +138 -0
- package/dist/brain/reasoning.d.ts.map +1 -0
- package/dist/brain/reasoning.js +146 -0
- package/dist/brain/reasoning.js.map +1 -0
- package/dist/brain/repetition.d.ts +60 -0
- package/dist/brain/repetition.d.ts.map +1 -0
- package/dist/brain/repetition.js +121 -0
- package/dist/brain/repetition.js.map +1 -0
- package/dist/brain/request-params.d.ts +29 -0
- package/dist/brain/request-params.d.ts.map +1 -0
- package/dist/brain/request-params.js +78 -0
- package/dist/brain/request-params.js.map +1 -0
- package/dist/brain/retry.d.ts +18 -0
- package/dist/brain/retry.d.ts.map +1 -0
- package/dist/brain/retry.js +42 -0
- package/dist/brain/retry.js.map +1 -0
- package/dist/brain/routing.d.ts +19 -0
- package/dist/brain/routing.d.ts.map +1 -0
- package/dist/brain/routing.js +44 -0
- package/dist/brain/routing.js.map +1 -0
- package/dist/brain/status-sink.d.ts +46 -0
- package/dist/brain/status-sink.d.ts.map +1 -0
- package/dist/brain/status-sink.js +36 -0
- package/dist/brain/status-sink.js.map +1 -0
- package/dist/brain/stream-engine.d.ts +85 -0
- package/dist/brain/stream-engine.d.ts.map +1 -0
- package/dist/brain/stream-engine.js +391 -0
- package/dist/brain/stream-engine.js.map +1 -0
- package/dist/brain/timeout.d.ts +44 -0
- package/dist/brain/timeout.d.ts.map +1 -0
- package/dist/brain/timeout.js +41 -0
- package/dist/brain/timeout.js.map +1 -0
- package/dist/brain/tool-call-repair.d.ts +15 -0
- package/dist/brain/tool-call-repair.d.ts.map +1 -0
- package/dist/brain/tool-call-repair.js +67 -0
- package/dist/brain/tool-call-repair.js.map +1 -0
- package/dist/brain/walltime.d.ts +14 -0
- package/dist/brain/walltime.d.ts.map +1 -0
- package/dist/brain/walltime.js +14 -0
- package/dist/brain/walltime.js.map +1 -0
- package/dist/core/arg-summary.d.ts +19 -0
- package/dist/core/arg-summary.d.ts.map +1 -0
- package/dist/core/arg-summary.js +96 -0
- package/dist/core/arg-summary.js.map +1 -0
- package/dist/core/ask-question.d.ts +113 -0
- package/dist/core/ask-question.d.ts.map +1 -0
- package/dist/core/ask-question.js +246 -0
- package/dist/core/ask-question.js.map +1 -0
- package/dist/core/auto-compaction.d.ts +341 -0
- package/dist/core/auto-compaction.d.ts.map +1 -0
- package/dist/core/auto-compaction.js +495 -0
- package/dist/core/auto-compaction.js.map +1 -0
- package/dist/core/auto-promote.d.ts +126 -0
- package/dist/core/auto-promote.d.ts.map +1 -0
- package/dist/core/auto-promote.js +171 -0
- package/dist/core/auto-promote.js.map +1 -0
- package/dist/core/background-shell.d.ts +128 -0
- package/dist/core/background-shell.d.ts.map +1 -0
- package/dist/core/background-shell.js +42 -0
- package/dist/core/background-shell.js.map +1 -0
- package/dist/core/cache-break-detector.d.ts +63 -0
- package/dist/core/cache-break-detector.d.ts.map +1 -0
- package/dist/core/cache-break-detector.js +0 -0
- package/dist/core/cache-break-detector.js.map +1 -0
- package/dist/core/canonical-json.d.ts +45 -0
- package/dist/core/canonical-json.d.ts.map +1 -0
- package/dist/core/canonical-json.js +132 -0
- package/dist/core/canonical-json.js.map +1 -0
- package/dist/core/checkpoint-store.d.ts +1101 -0
- package/dist/core/checkpoint-store.d.ts.map +1 -0
- package/dist/core/checkpoint-store.js +514 -0
- package/dist/core/checkpoint-store.js.map +1 -0
- package/dist/core/consolidate-scope.d.ts +94 -0
- package/dist/core/consolidate-scope.d.ts.map +1 -0
- package/dist/core/consolidate-scope.js +158 -0
- package/dist/core/consolidate-scope.js.map +1 -0
- package/dist/core/context-edit.d.ts +82 -0
- package/dist/core/context-edit.d.ts.map +1 -0
- package/dist/core/context-edit.js +149 -0
- package/dist/core/context-edit.js.map +1 -0
- package/dist/core/context-guard.d.ts +43 -0
- package/dist/core/context-guard.d.ts.map +1 -0
- package/dist/core/context-guard.js +171 -0
- package/dist/core/context-guard.js.map +1 -0
- package/dist/core/dynamic-recall.d.ts +100 -0
- package/dist/core/dynamic-recall.d.ts.map +1 -0
- package/dist/core/dynamic-recall.js +108 -0
- package/dist/core/dynamic-recall.js.map +1 -0
- package/dist/core/exec-gate.d.ts +74 -0
- package/dist/core/exec-gate.d.ts.map +1 -0
- package/dist/core/exec-gate.js +143 -0
- package/dist/core/exec-gate.js.map +1 -0
- package/dist/core/exec-output-tail.d.ts +37 -0
- package/dist/core/exec-output-tail.d.ts.map +1 -0
- package/dist/core/exec-output-tail.js +63 -0
- package/dist/core/exec-output-tail.js.map +1 -0
- package/dist/core/file-snapshot-store.d.ts +137 -0
- package/dist/core/file-snapshot-store.d.ts.map +1 -0
- package/dist/core/file-snapshot-store.js +319 -0
- package/dist/core/file-snapshot-store.js.map +1 -0
- package/dist/core/git-worktree-env.d.ts +41 -0
- package/dist/core/git-worktree-env.d.ts.map +1 -0
- package/dist/core/git-worktree-env.js +64 -0
- package/dist/core/git-worktree-env.js.map +1 -0
- package/dist/core/hooks.d.ts +372 -0
- package/dist/core/hooks.d.ts.map +1 -0
- package/dist/core/hooks.js +269 -0
- package/dist/core/hooks.js.map +1 -0
- package/dist/core/lsp-diagnostics.d.ts +74 -0
- package/dist/core/lsp-diagnostics.d.ts.map +1 -0
- package/dist/core/lsp-diagnostics.js +125 -0
- package/dist/core/lsp-diagnostics.js.map +1 -0
- package/dist/core/lsp-protocol.d.ts +28 -0
- package/dist/core/lsp-protocol.d.ts.map +1 -0
- package/dist/core/lsp-protocol.js +179 -0
- package/dist/core/lsp-protocol.js.map +1 -0
- package/dist/core/lsp-session.d.ts +56 -0
- package/dist/core/lsp-session.d.ts.map +1 -0
- package/dist/core/lsp-session.js +185 -0
- package/dist/core/lsp-session.js.map +1 -0
- package/dist/core/lsp.d.ts +132 -0
- package/dist/core/lsp.d.ts.map +1 -0
- package/dist/core/lsp.js +147 -0
- package/dist/core/lsp.js.map +1 -0
- package/dist/core/mcp.d.ts +294 -0
- package/dist/core/mcp.d.ts.map +1 -0
- package/dist/core/mcp.js +992 -0
- package/dist/core/mcp.js.map +1 -0
- package/dist/core/media-byte-cap.d.ts +34 -0
- package/dist/core/media-byte-cap.d.ts.map +1 -0
- package/dist/core/media-byte-cap.js +76 -0
- package/dist/core/media-byte-cap.js.map +1 -0
- package/dist/core/memory-engine/data-plane.d.ts +103 -0
- package/dist/core/memory-engine/data-plane.d.ts.map +1 -0
- package/dist/core/memory-engine/data-plane.js +272 -0
- package/dist/core/memory-engine/data-plane.js.map +1 -0
- package/dist/core/memory-engine/dual-root.d.ts +40 -0
- package/dist/core/memory-engine/dual-root.d.ts.map +1 -0
- package/dist/core/memory-engine/dual-root.js +95 -0
- package/dist/core/memory-engine/dual-root.js.map +1 -0
- package/dist/core/memory-engine/engine.d.ts +161 -0
- package/dist/core/memory-engine/engine.d.ts.map +1 -0
- package/dist/core/memory-engine/engine.js +1110 -0
- package/dist/core/memory-engine/engine.js.map +1 -0
- package/dist/core/memory-engine/file-backend.d.ts +162 -0
- package/dist/core/memory-engine/file-backend.d.ts.map +1 -0
- package/dist/core/memory-engine/file-backend.js +948 -0
- package/dist/core/memory-engine/file-backend.js.map +1 -0
- package/dist/core/memory-engine/frontmatter.d.ts +24 -0
- package/dist/core/memory-engine/frontmatter.d.ts.map +1 -0
- package/dist/core/memory-engine/frontmatter.js +135 -0
- package/dist/core/memory-engine/frontmatter.js.map +1 -0
- package/dist/core/memory-engine/index.d.ts +13 -0
- package/dist/core/memory-engine/index.d.ts.map +1 -0
- package/dist/core/memory-engine/index.js +28 -0
- package/dist/core/memory-engine/index.js.map +1 -0
- package/dist/core/memory-engine/layout.d.ts +123 -0
- package/dist/core/memory-engine/layout.d.ts.map +1 -0
- package/dist/core/memory-engine/layout.js +643 -0
- package/dist/core/memory-engine/layout.js.map +1 -0
- package/dist/core/memory-engine/memory-backend-contract.d.ts +22 -0
- package/dist/core/memory-engine/memory-backend-contract.d.ts.map +1 -0
- package/dist/core/memory-engine/memory-backend-contract.js +271 -0
- package/dist/core/memory-engine/memory-backend-contract.js.map +1 -0
- package/dist/core/memory-engine/migrate.d.ts +17 -0
- package/dist/core/memory-engine/migrate.d.ts.map +1 -0
- package/dist/core/memory-engine/migrate.js +35 -0
- package/dist/core/memory-engine/migrate.js.map +1 -0
- package/dist/core/memory-engine/scan.d.ts +20 -0
- package/dist/core/memory-engine/scan.d.ts.map +1 -0
- package/dist/core/memory-engine/scan.js +84 -0
- package/dist/core/memory-engine/scan.js.map +1 -0
- package/dist/core/memory-engine/scope-contract.d.ts +104 -0
- package/dist/core/memory-engine/scope-contract.d.ts.map +1 -0
- package/dist/core/memory-engine/scope-contract.js +288 -0
- package/dist/core/memory-engine/scope-contract.js.map +1 -0
- package/dist/core/memory-engine/sync-client.d.ts +100 -0
- package/dist/core/memory-engine/sync-client.d.ts.map +1 -0
- package/dist/core/memory-engine/sync-client.js +328 -0
- package/dist/core/memory-engine/sync-client.js.map +1 -0
- package/dist/core/memory-engine/sync.d.ts +97 -0
- package/dist/core/memory-engine/sync.d.ts.map +1 -0
- package/dist/core/memory-engine/sync.js +91 -0
- package/dist/core/memory-engine/sync.js.map +1 -0
- package/dist/core/memory-engine/types.d.ts +279 -0
- package/dist/core/memory-engine/types.d.ts.map +1 -0
- package/dist/core/memory-engine/types.js +9 -0
- package/dist/core/memory-engine/types.js.map +1 -0
- package/dist/core/memory-recall.d.ts +261 -0
- package/dist/core/memory-recall.d.ts.map +1 -0
- package/dist/core/memory-recall.js +600 -0
- package/dist/core/memory-recall.js.map +1 -0
- package/dist/core/memory-vector.d.ts +24 -0
- package/dist/core/memory-vector.d.ts.map +1 -0
- package/dist/core/memory-vector.js +51 -0
- package/dist/core/memory-vector.js.map +1 -0
- package/dist/core/memory.d.ts +502 -0
- package/dist/core/memory.d.ts.map +1 -0
- package/dist/core/memory.js +881 -0
- package/dist/core/memory.js.map +1 -0
- package/dist/core/message-utils.d.ts +7 -0
- package/dist/core/message-utils.d.ts.map +1 -0
- package/dist/core/message-utils.js +10 -0
- package/dist/core/message-utils.js.map +1 -0
- package/dist/core/oracle-isolation.d.ts +85 -0
- package/dist/core/oracle-isolation.d.ts.map +1 -0
- package/dist/core/oracle-isolation.js +121 -0
- package/dist/core/oracle-isolation.js.map +1 -0
- package/dist/core/permission-rules.d.ts +102 -0
- package/dist/core/permission-rules.d.ts.map +1 -0
- package/dist/core/permission-rules.js +357 -0
- package/dist/core/permission-rules.js.map +1 -0
- package/dist/core/present-plan-tool.d.ts +28 -0
- package/dist/core/present-plan-tool.d.ts.map +1 -0
- package/dist/core/present-plan-tool.js +119 -0
- package/dist/core/present-plan-tool.js.map +1 -0
- package/dist/core/pricing.d.ts +48 -0
- package/dist/core/pricing.d.ts.map +1 -0
- package/dist/core/pricing.js +46 -0
- package/dist/core/pricing.js.map +1 -0
- package/dist/core/property-harness.d.ts +126 -0
- package/dist/core/property-harness.d.ts.map +1 -0
- package/dist/core/property-harness.js +192 -0
- package/dist/core/property-harness.js.map +1 -0
- package/dist/core/push-queue.d.ts +10 -0
- package/dist/core/push-queue.d.ts.map +1 -0
- package/dist/core/push-queue.js +42 -0
- package/dist/core/push-queue.js.map +1 -0
- package/dist/core/remote-env.d.ts +432 -0
- package/dist/core/remote-env.d.ts.map +1 -0
- package/dist/core/remote-env.js +77 -0
- package/dist/core/remote-env.js.map +1 -0
- package/dist/core/roles.d.ts +74 -0
- package/dist/core/roles.d.ts.map +1 -0
- package/dist/core/roles.js +272 -0
- package/dist/core/roles.js.map +1 -0
- package/dist/core/runner/active-skill-scope.d.ts +64 -0
- package/dist/core/runner/active-skill-scope.d.ts.map +1 -0
- package/dist/core/runner/active-skill-scope.js +197 -0
- package/dist/core/runner/active-skill-scope.js.map +1 -0
- package/dist/core/runner/assemble-result.d.ts +191 -0
- package/dist/core/runner/assemble-result.d.ts.map +1 -0
- package/dist/core/runner/assemble-result.js +250 -0
- package/dist/core/runner/assemble-result.js.map +1 -0
- package/dist/core/runner/call-cap.d.ts +130 -0
- package/dist/core/runner/call-cap.d.ts.map +1 -0
- package/dist/core/runner/call-cap.js +151 -0
- package/dist/core/runner/call-cap.js.map +1 -0
- package/dist/core/runner/grounding-signal.d.ts +12 -0
- package/dist/core/runner/grounding-signal.d.ts.map +1 -0
- package/dist/core/runner/grounding-signal.js +94 -0
- package/dist/core/runner/grounding-signal.js.map +1 -0
- package/dist/core/runner/image.d.ts +23 -0
- package/dist/core/runner/image.d.ts.map +1 -0
- package/dist/core/runner/image.js +151 -0
- package/dist/core/runner/image.js.map +1 -0
- package/dist/core/runner/memory-consolidation.d.ts +112 -0
- package/dist/core/runner/memory-consolidation.d.ts.map +1 -0
- package/dist/core/runner/memory-consolidation.js +372 -0
- package/dist/core/runner/memory-consolidation.js.map +1 -0
- package/dist/core/runner/prepare-task.d.ts +583 -0
- package/dist/core/runner/prepare-task.d.ts.map +1 -0
- package/dist/core/runner/prepare-task.js +3612 -0
- package/dist/core/runner/prepare-task.js.map +1 -0
- package/dist/core/runner/prompt-suggestions.d.ts +33 -0
- package/dist/core/runner/prompt-suggestions.d.ts.map +1 -0
- package/dist/core/runner/prompt-suggestions.js +116 -0
- package/dist/core/runner/prompt-suggestions.js.map +1 -0
- package/dist/core/runner/runtask.d.ts +274 -0
- package/dist/core/runner/runtask.d.ts.map +1 -0
- package/dist/core/runner/runtask.js +4606 -0
- package/dist/core/runner/runtask.js.map +1 -0
- package/dist/core/runner/session-rule-policy.d.ts +28 -0
- package/dist/core/runner/session-rule-policy.d.ts.map +1 -0
- package/dist/core/runner/session-rule-policy.js +110 -0
- package/dist/core/runner/session-rule-policy.js.map +1 -0
- package/dist/core/runner/strict-output-schema.d.ts +36 -0
- package/dist/core/runner/strict-output-schema.d.ts.map +1 -0
- package/dist/core/runner/strict-output-schema.js +365 -0
- package/dist/core/runner/strict-output-schema.js.map +1 -0
- package/dist/core/runner/synthetic-tools.d.ts +72 -0
- package/dist/core/runner/synthetic-tools.d.ts.map +1 -0
- package/dist/core/runner/synthetic-tools.js +203 -0
- package/dist/core/runner/synthetic-tools.js.map +1 -0
- package/dist/core/runner/tool-disclosure.d.ts +117 -0
- package/dist/core/runner/tool-disclosure.d.ts.map +1 -0
- package/dist/core/runner/tool-disclosure.js +0 -0
- package/dist/core/runner/tool-disclosure.js.map +1 -0
- package/dist/core/runner/turn-attachments.d.ts +381 -0
- package/dist/core/runner/turn-attachments.d.ts.map +1 -0
- package/dist/core/runner/turn-attachments.js +596 -0
- package/dist/core/runner/turn-attachments.js.map +1 -0
- package/dist/core/runner/usage-accounting.d.ts +35 -0
- package/dist/core/runner/usage-accounting.d.ts.map +1 -0
- package/dist/core/runner/usage-accounting.js +45 -0
- package/dist/core/runner/usage-accounting.js.map +1 -0
- package/dist/core/runtime.d.ts +9 -0
- package/dist/core/runtime.d.ts.map +1 -0
- package/dist/core/runtime.js +17 -0
- package/dist/core/runtime.js.map +1 -0
- package/dist/core/safety-axis-vocab.d.ts +33 -0
- package/dist/core/safety-axis-vocab.d.ts.map +1 -0
- package/dist/core/safety-axis-vocab.js +35 -0
- package/dist/core/safety-axis-vocab.js.map +1 -0
- package/dist/core/safety-merge-corpus.d.ts +48 -0
- package/dist/core/safety-merge-corpus.d.ts.map +1 -0
- package/dist/core/safety-merge-corpus.js +203 -0
- package/dist/core/safety-merge-corpus.js.map +1 -0
- package/dist/core/scheduler.d.ts +126 -0
- package/dist/core/scheduler.d.ts.map +1 -0
- package/dist/core/scheduler.js +54 -0
- package/dist/core/scheduler.js.map +1 -0
- package/dist/core/secret-env.d.ts +23 -0
- package/dist/core/secret-env.d.ts.map +1 -0
- package/dist/core/secret-env.js +35 -0
- package/dist/core/secret-env.js.map +1 -0
- package/dist/core/select-model.d.ts +26 -0
- package/dist/core/select-model.d.ts.map +1 -0
- package/dist/core/select-model.js +58 -0
- package/dist/core/select-model.js.map +1 -0
- package/dist/core/sensitive-path-policy.d.ts +24 -0
- package/dist/core/sensitive-path-policy.d.ts.map +1 -0
- package/dist/core/sensitive-path-policy.js +96 -0
- package/dist/core/sensitive-path-policy.js.map +1 -0
- package/dist/core/session-policy-store.d.ts +102 -0
- package/dist/core/session-policy-store.d.ts.map +1 -0
- package/dist/core/session-policy-store.js +177 -0
- package/dist/core/session-policy-store.js.map +1 -0
- package/dist/core/session-reconcile.d.ts +63 -0
- package/dist/core/session-reconcile.d.ts.map +1 -0
- package/dist/core/session-reconcile.js +71 -0
- package/dist/core/session-reconcile.js.map +1 -0
- package/dist/core/session-store.d.ts +99 -0
- package/dist/core/session-store.d.ts.map +1 -0
- package/dist/core/session-store.js +298 -0
- package/dist/core/session-store.js.map +1 -0
- package/dist/core/session.d.ts +144 -0
- package/dist/core/session.d.ts.map +1 -0
- package/dist/core/session.js +56 -0
- package/dist/core/session.js.map +1 -0
- package/dist/core/spec-contract.d.ts +147 -0
- package/dist/core/spec-contract.d.ts.map +1 -0
- package/dist/core/spec-contract.js +340 -0
- package/dist/core/spec-contract.js.map +1 -0
- package/dist/core/strategy-store.d.ts +50 -0
- package/dist/core/strategy-store.d.ts.map +1 -0
- package/dist/core/strategy-store.js +100 -0
- package/dist/core/strategy-store.js.map +1 -0
- package/dist/core/stub-env.d.ts +35 -0
- package/dist/core/stub-env.d.ts.map +1 -0
- package/dist/core/stub-env.js +69 -0
- package/dist/core/stub-env.js.map +1 -0
- package/dist/core/task-notification.d.ts +115 -0
- package/dist/core/task-notification.d.ts.map +1 -0
- package/dist/core/task-notification.js +247 -0
- package/dist/core/task-notification.js.map +1 -0
- package/dist/core/task-outcome.d.ts +80 -0
- package/dist/core/task-outcome.d.ts.map +1 -0
- package/dist/core/task-outcome.js +40 -0
- package/dist/core/task-outcome.js.map +1 -0
- package/dist/core/task-registry.d.ts +349 -0
- package/dist/core/task-registry.d.ts.map +1 -0
- package/dist/core/task-registry.js +1751 -0
- package/dist/core/task-registry.js.map +1 -0
- package/dist/core/tighten-task-spec.d.ts +27 -0
- package/dist/core/tighten-task-spec.d.ts.map +1 -0
- package/dist/core/tighten-task-spec.js +95 -0
- package/dist/core/tighten-task-spec.js.map +1 -0
- package/dist/core/tool-detach.d.ts +31 -0
- package/dist/core/tool-detach.d.ts.map +1 -0
- package/dist/core/tool-detach.js +62 -0
- package/dist/core/tool-detach.js.map +1 -0
- package/dist/core/tool-errors.d.ts +72 -0
- package/dist/core/tool-errors.d.ts.map +1 -0
- package/dist/core/tool-errors.js +194 -0
- package/dist/core/tool-errors.js.map +1 -0
- package/dist/core/tool-name-aliases.d.ts +5 -0
- package/dist/core/tool-name-aliases.d.ts.map +1 -0
- package/dist/core/tool-name-aliases.js +130 -0
- package/dist/core/tool-name-aliases.js.map +1 -0
- package/dist/core/tool-policy.d.ts +295 -0
- package/dist/core/tool-policy.d.ts.map +1 -0
- package/dist/core/tool-policy.js +567 -0
- package/dist/core/tool-policy.js.map +1 -0
- package/dist/core/tool-result-budget.d.ts +44 -0
- package/dist/core/tool-result-budget.d.ts.map +1 -0
- package/dist/core/tool-result-budget.js +140 -0
- package/dist/core/tool-result-budget.js.map +1 -0
- package/dist/core/tool-result-store.d.ts +136 -0
- package/dist/core/tool-result-store.d.ts.map +1 -0
- package/dist/core/tool-result-store.js +219 -0
- package/dist/core/tool-result-store.js.map +1 -0
- package/dist/core/tools.d.ts +14 -0
- package/dist/core/tools.d.ts.map +1 -0
- package/dist/core/tools.js +98 -0
- package/dist/core/tools.js.map +1 -0
- package/dist/core/trace.d.ts +340 -0
- package/dist/core/trace.d.ts.map +1 -0
- package/dist/core/trace.js +12 -0
- package/dist/core/trace.js.map +1 -0
- package/dist/core/types.d.ts +2828 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +2 -0
- package/dist/core/types.js.map +1 -0
- package/dist/core/untrusted-egress.d.ts +32 -0
- package/dist/core/untrusted-egress.d.ts.map +1 -0
- package/dist/core/untrusted-egress.js +49 -0
- package/dist/core/untrusted-egress.js.map +1 -0
- package/dist/core/untrusted-text.d.ts +64 -0
- package/dist/core/untrusted-text.d.ts.map +1 -0
- package/dist/core/untrusted-text.js +119 -0
- package/dist/core/untrusted-text.js.map +1 -0
- package/dist/core/warm-resume.d.ts +23 -0
- package/dist/core/warm-resume.d.ts.map +1 -0
- package/dist/core/warm-resume.js +28 -0
- package/dist/core/warm-resume.js.map +1 -0
- package/dist/core/with-retry.d.ts +43 -0
- package/dist/core/with-retry.d.ts.map +1 -0
- package/dist/core/with-retry.js +59 -0
- package/dist/core/with-retry.js.map +1 -0
- package/dist/core/workflow-journal-store.d.ts +44 -0
- package/dist/core/workflow-journal-store.d.ts.map +1 -0
- package/dist/core/workflow-journal-store.js +47 -0
- package/dist/core/workflow-journal-store.js.map +1 -0
- package/dist/core/workflow-run-store-contract.d.ts +31 -0
- package/dist/core/workflow-run-store-contract.d.ts.map +1 -0
- package/dist/core/workflow-run-store-contract.js +191 -0
- package/dist/core/workflow-run-store-contract.js.map +1 -0
- package/dist/core/workflow-run-store.d.ts +149 -0
- package/dist/core/workflow-run-store.d.ts.map +1 -0
- package/dist/core/workflow-run-store.js +110 -0
- package/dist/core/workflow-run-store.js.map +1 -0
- package/dist/engine/compaction/compaction.d.ts +139 -0
- package/dist/engine/compaction/compaction.d.ts.map +1 -0
- package/dist/engine/compaction/compaction.js +1030 -0
- package/dist/engine/compaction/compaction.js.map +1 -0
- package/dist/engine/compaction/utils.d.ts +45 -0
- package/dist/engine/compaction/utils.d.ts.map +1 -0
- package/dist/engine/compaction/utils.js +203 -0
- package/dist/engine/compaction/utils.js.map +1 -0
- package/dist/engine/execution-env/kill-tree.d.ts +20 -0
- package/dist/engine/execution-env/kill-tree.d.ts.map +1 -0
- package/dist/engine/execution-env/kill-tree.js +183 -0
- package/dist/engine/execution-env/kill-tree.js.map +1 -0
- package/dist/engine/execution-env/node-execution-env.d.ts +133 -0
- package/dist/engine/execution-env/node-execution-env.d.ts.map +1 -0
- package/dist/engine/execution-env/node-execution-env.js +1031 -0
- package/dist/engine/execution-env/node-execution-env.js.map +1 -0
- package/dist/engine/harness/agent-harness.d.ts +174 -0
- package/dist/engine/harness/agent-harness.d.ts.map +1 -0
- package/dist/engine/harness/agent-harness.js +1053 -0
- package/dist/engine/harness/agent-harness.js.map +1 -0
- package/dist/engine/harness/messages.d.ts +17 -0
- package/dist/engine/harness/messages.d.ts.map +1 -0
- package/dist/engine/harness/messages.js +122 -0
- package/dist/engine/harness/messages.js.map +1 -0
- package/dist/engine/harness/types.d.ts +713 -0
- package/dist/engine/harness/types.d.ts.map +1 -0
- package/dist/engine/harness/types.js +100 -0
- package/dist/engine/harness/types.js.map +1 -0
- package/dist/engine/llm/diagnostics.d.ts +23 -0
- package/dist/engine/llm/diagnostics.d.ts.map +1 -0
- package/dist/engine/llm/diagnostics.js +32 -0
- package/dist/engine/llm/diagnostics.js.map +1 -0
- package/dist/engine/llm/event-stream.d.ts +25 -0
- package/dist/engine/llm/event-stream.d.ts.map +1 -0
- package/dist/engine/llm/event-stream.js +103 -0
- package/dist/engine/llm/event-stream.js.map +1 -0
- package/dist/engine/llm/index.d.ts +12 -0
- package/dist/engine/llm/index.d.ts.map +1 -0
- package/dist/engine/llm/index.js +12 -0
- package/dist/engine/llm/index.js.map +1 -0
- package/dist/engine/llm/types.d.ts +753 -0
- package/dist/engine/llm/types.d.ts.map +1 -0
- package/dist/engine/llm/types.js +2 -0
- package/dist/engine/llm/types.js.map +1 -0
- package/dist/engine/llm/validation.d.ts +8 -0
- package/dist/engine/llm/validation.d.ts.map +1 -0
- package/dist/engine/llm/validation.js +318 -0
- package/dist/engine/llm/validation.js.map +1 -0
- package/dist/engine/loop/agent-loop.d.ts +74 -0
- package/dist/engine/loop/agent-loop.d.ts.map +1 -0
- package/dist/engine/loop/agent-loop.js +1490 -0
- package/dist/engine/loop/agent-loop.js.map +1 -0
- package/dist/engine/loop/runtime-deps.d.ts +17 -0
- package/dist/engine/loop/runtime-deps.d.ts.map +1 -0
- package/dist/engine/loop/runtime-deps.js +21 -0
- package/dist/engine/loop/runtime-deps.js.map +1 -0
- package/dist/engine/loop/types.d.ts +609 -0
- package/dist/engine/loop/types.d.ts.map +1 -0
- package/dist/engine/loop/types.js +2 -0
- package/dist/engine/loop/types.js.map +1 -0
- package/dist/engine/lsp/frame-decoder.d.ts +16 -0
- package/dist/engine/lsp/frame-decoder.d.ts.map +1 -0
- package/dist/engine/lsp/frame-decoder.js +53 -0
- package/dist/engine/lsp/frame-decoder.js.map +1 -0
- package/dist/engine/lsp/node-lsp-manager.d.ts +105 -0
- package/dist/engine/lsp/node-lsp-manager.d.ts.map +1 -0
- package/dist/engine/lsp/node-lsp-manager.js +343 -0
- package/dist/engine/lsp/node-lsp-manager.js.map +1 -0
- package/dist/engine/lsp/stdio-lsp-transport.d.ts +37 -0
- package/dist/engine/lsp/stdio-lsp-transport.d.ts.map +1 -0
- package/dist/engine/lsp/stdio-lsp-transport.js +185 -0
- package/dist/engine/lsp/stdio-lsp-transport.js.map +1 -0
- package/dist/engine/session/import-validate.d.ts +44 -0
- package/dist/engine/session/import-validate.d.ts.map +1 -0
- package/dist/engine/session/import-validate.js +92 -0
- package/dist/engine/session/import-validate.js.map +1 -0
- package/dist/engine/session/memory-repo.d.ts +25 -0
- package/dist/engine/session/memory-repo.d.ts.map +1 -0
- package/dist/engine/session/memory-repo.js +59 -0
- package/dist/engine/session/memory-repo.js.map +1 -0
- package/dist/engine/session/memory-storage.d.ts +14 -0
- package/dist/engine/session/memory-storage.d.ts.map +1 -0
- package/dist/engine/session/memory-storage.js +17 -0
- package/dist/engine/session/memory-storage.js.map +1 -0
- package/dist/engine/session/repo-utils.d.ts +11 -0
- package/dist/engine/session/repo-utils.d.ts.map +1 -0
- package/dist/engine/session/repo-utils.js +40 -0
- package/dist/engine/session/repo-utils.js.map +1 -0
- package/dist/engine/session/session.d.ts +34 -0
- package/dist/engine/session/session.d.ts.map +1 -0
- package/dist/engine/session/session.js +227 -0
- package/dist/engine/session/session.js.map +1 -0
- package/dist/engine/session/storage-base.d.ts +38 -0
- package/dist/engine/session/storage-base.d.ts.map +1 -0
- package/dist/engine/session/storage-base.js +157 -0
- package/dist/engine/session/storage-base.js.map +1 -0
- package/dist/engine/session/timestamps.d.ts +3 -0
- package/dist/engine/session/timestamps.d.ts.map +1 -0
- package/dist/engine/session/timestamps.js +15 -0
- package/dist/engine/session/timestamps.js.map +1 -0
- package/dist/engine/session/uuid.d.ts +2 -0
- package/dist/engine/session/uuid.d.ts.map +1 -0
- package/dist/engine/session/uuid.js +50 -0
- package/dist/engine/session/uuid.js.map +1 -0
- package/dist/index.d.ts +160 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +374 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/harness.d.ts +26 -0
- package/dist/internal/harness.d.ts.map +1 -0
- package/dist/internal/harness.js +24 -0
- package/dist/internal/harness.js.map +1 -0
- package/dist/internal/llm.d.ts +9 -0
- package/dist/internal/llm.d.ts.map +1 -0
- package/dist/internal/llm.js +8 -0
- package/dist/internal/llm.js.map +1 -0
- package/dist/orchestration/builtin-workflows.d.ts +44 -0
- package/dist/orchestration/builtin-workflows.d.ts.map +1 -0
- package/dist/orchestration/builtin-workflows.js +165 -0
- package/dist/orchestration/builtin-workflows.js.map +1 -0
- package/dist/orchestration/dev-vm-script-runner.d.ts +24 -0
- package/dist/orchestration/dev-vm-script-runner.d.ts.map +1 -0
- package/dist/orchestration/dev-vm-script-runner.js +106 -0
- package/dist/orchestration/dev-vm-script-runner.js.map +1 -0
- package/dist/orchestration/goal.d.ts +97 -0
- package/dist/orchestration/goal.d.ts.map +1 -0
- package/dist/orchestration/goal.js +248 -0
- package/dist/orchestration/goal.js.map +1 -0
- package/dist/orchestration/run-spec.d.ts +63 -0
- package/dist/orchestration/run-spec.d.ts.map +1 -0
- package/dist/orchestration/run-spec.js +274 -0
- package/dist/orchestration/run-spec.js.map +1 -0
- package/dist/orchestration/run-workflow-tool.d.ts +187 -0
- package/dist/orchestration/run-workflow-tool.d.ts.map +1 -0
- package/dist/orchestration/run-workflow-tool.js +612 -0
- package/dist/orchestration/run-workflow-tool.js.map +1 -0
- package/dist/orchestration/workflow-governance.d.ts +70 -0
- package/dist/orchestration/workflow-governance.d.ts.map +1 -0
- package/dist/orchestration/workflow-governance.js +176 -0
- package/dist/orchestration/workflow-governance.js.map +1 -0
- package/dist/orchestration/workflow-meta.d.ts +41 -0
- package/dist/orchestration/workflow-meta.d.ts.map +1 -0
- package/dist/orchestration/workflow-meta.js +426 -0
- package/dist/orchestration/workflow-meta.js.map +1 -0
- package/dist/orchestration/workflow-observe.d.ts +77 -0
- package/dist/orchestration/workflow-observe.d.ts.map +1 -0
- package/dist/orchestration/workflow-observe.js +177 -0
- package/dist/orchestration/workflow-observe.js.map +1 -0
- package/dist/orchestration/workflow-primitives.d.ts +31 -0
- package/dist/orchestration/workflow-primitives.d.ts.map +1 -0
- package/dist/orchestration/workflow-primitives.js +104 -0
- package/dist/orchestration/workflow-primitives.js.map +1 -0
- package/dist/orchestration/workflow-sandbox-conformance.d.ts +34 -0
- package/dist/orchestration/workflow-sandbox-conformance.d.ts.map +1 -0
- package/dist/orchestration/workflow-sandbox-conformance.js +301 -0
- package/dist/orchestration/workflow-sandbox-conformance.js.map +1 -0
- package/dist/orchestration/workflow-script-runner.d.ts +127 -0
- package/dist/orchestration/workflow-script-runner.d.ts.map +1 -0
- package/dist/orchestration/workflow-script-runner.js +48 -0
- package/dist/orchestration/workflow-script-runner.js.map +1 -0
- package/dist/orchestration/workflow-script-store.d.ts +99 -0
- package/dist/orchestration/workflow-script-store.d.ts.map +1 -0
- package/dist/orchestration/workflow-script-store.js +133 -0
- package/dist/orchestration/workflow-script-store.js.map +1 -0
- package/dist/orchestration/workflow-size-guideline.d.ts +50 -0
- package/dist/orchestration/workflow-size-guideline.d.ts.map +1 -0
- package/dist/orchestration/workflow-size-guideline.js +78 -0
- package/dist/orchestration/workflow-size-guideline.js.map +1 -0
- package/dist/orchestration/workflow.d.ts +624 -0
- package/dist/orchestration/workflow.d.ts.map +1 -0
- package/dist/orchestration/workflow.js +1596 -0
- package/dist/orchestration/workflow.js.map +1 -0
- package/dist/prompts/default.d.ts +474 -0
- package/dist/prompts/default.d.ts.map +1 -0
- package/dist/prompts/default.js +676 -0
- package/dist/prompts/default.js.map +1 -0
- package/dist/prompts/supervisor.d.ts +60 -0
- package/dist/prompts/supervisor.d.ts.map +1 -0
- package/dist/prompts/supervisor.js +162 -0
- package/dist/prompts/supervisor.js.map +1 -0
- package/dist/scenarios/env.d.ts +41 -0
- package/dist/scenarios/env.d.ts.map +1 -0
- package/dist/scenarios/env.js +65 -0
- package/dist/scenarios/env.js.map +1 -0
- package/dist/scenarios/full-body.d.ts +47 -0
- package/dist/scenarios/full-body.d.ts.map +1 -0
- package/dist/scenarios/full-body.js +36 -0
- package/dist/scenarios/full-body.js.map +1 -0
- package/dist/scenarios/scenario-registry.d.ts +107 -0
- package/dist/scenarios/scenario-registry.d.ts.map +1 -0
- package/dist/scenarios/scenario-registry.js +192 -0
- package/dist/scenarios/scenario-registry.js.map +1 -0
- package/dist/scenarios/teacher-quickstart.d.ts +41 -0
- package/dist/scenarios/teacher-quickstart.d.ts.map +1 -0
- package/dist/scenarios/teacher-quickstart.js +32 -0
- package/dist/scenarios/teacher-quickstart.js.map +1 -0
- package/dist/server/http.d.ts +36 -0
- package/dist/server/http.d.ts.map +1 -0
- package/dist/server/http.js +144 -0
- package/dist/server/http.js.map +1 -0
- package/dist/stores/file/checkpoint-store.d.ts +62 -0
- package/dist/stores/file/checkpoint-store.d.ts.map +1 -0
- package/dist/stores/file/checkpoint-store.js +250 -0
- package/dist/stores/file/checkpoint-store.js.map +1 -0
- package/dist/stores/file/file-snapshot-store.d.ts +43 -0
- package/dist/stores/file/file-snapshot-store.d.ts.map +1 -0
- package/dist/stores/file/file-snapshot-store.js +374 -0
- package/dist/stores/file/file-snapshot-store.js.map +1 -0
- package/dist/stores/file/fs-atomic.d.ts +95 -0
- package/dist/stores/file/fs-atomic.d.ts.map +1 -0
- package/dist/stores/file/fs-atomic.js +415 -0
- package/dist/stores/file/fs-atomic.js.map +1 -0
- package/dist/stores/file/index.d.ts +98 -0
- package/dist/stores/file/index.d.ts.map +1 -0
- package/dist/stores/file/index.js +109 -0
- package/dist/stores/file/index.js.map +1 -0
- package/dist/stores/file/memory-store.d.ts +95 -0
- package/dist/stores/file/memory-store.d.ts.map +1 -0
- package/dist/stores/file/memory-store.js +393 -0
- package/dist/stores/file/memory-store.js.map +1 -0
- package/dist/stores/file/session-policy-store.d.ts +24 -0
- package/dist/stores/file/session-policy-store.d.ts.map +1 -0
- package/dist/stores/file/session-policy-store.js +123 -0
- package/dist/stores/file/session-policy-store.js.map +1 -0
- package/dist/stores/file/session-store.d.ts +34 -0
- package/dist/stores/file/session-store.d.ts.map +1 -0
- package/dist/stores/file/session-store.js +175 -0
- package/dist/stores/file/session-store.js.map +1 -0
- package/dist/stores/file/tool-result-store.d.ts +23 -0
- package/dist/stores/file/tool-result-store.d.ts.map +1 -0
- package/dist/stores/file/tool-result-store.js +61 -0
- package/dist/stores/file/tool-result-store.js.map +1 -0
- package/dist/stores/file/workflow-journal-store.d.ts +36 -0
- package/dist/stores/file/workflow-journal-store.d.ts.map +1 -0
- package/dist/stores/file/workflow-journal-store.js +157 -0
- package/dist/stores/file/workflow-journal-store.js.map +1 -0
- package/dist/stores/file/workflow-run-store.d.ts +58 -0
- package/dist/stores/file/workflow-run-store.d.ts.map +1 -0
- package/dist/stores/file/workflow-run-store.js +178 -0
- package/dist/stores/file/workflow-run-store.js.map +1 -0
- package/dist/stores/pg.d.ts +210 -0
- package/dist/stores/pg.d.ts.map +1 -0
- package/dist/stores/pg.js +652 -0
- package/dist/stores/pg.js.map +1 -0
- package/dist/tools/fs/encoding.d.ts +51 -0
- package/dist/tools/fs/encoding.d.ts.map +1 -0
- package/dist/tools/fs/encoding.js +74 -0
- package/dist/tools/fs/encoding.js.map +1 -0
- package/dist/tools/fs/gh-rate-limit.d.ts +19 -0
- package/dist/tools/fs/gh-rate-limit.d.ts.map +1 -0
- package/dist/tools/fs/gh-rate-limit.js +35 -0
- package/dist/tools/fs/gh-rate-limit.js.map +1 -0
- package/dist/tools/fs/index.d.ts +246 -0
- package/dist/tools/fs/index.d.ts.map +1 -0
- package/dist/tools/fs/index.js +2130 -0
- package/dist/tools/fs/index.js.map +1 -0
- package/dist/tools/fs/pdf.d.ts +106 -0
- package/dist/tools/fs/pdf.d.ts.map +1 -0
- package/dist/tools/fs/pdf.js +178 -0
- package/dist/tools/fs/pdf.js.map +1 -0
- package/dist/tools/fs/repo-map.d.ts +15 -0
- package/dist/tools/fs/repo-map.d.ts.map +1 -0
- package/dist/tools/fs/repo-map.js +251 -0
- package/dist/tools/fs/repo-map.js.map +1 -0
- package/dist/tools/fs/safety.d.ts +168 -0
- package/dist/tools/fs/safety.d.ts.map +1 -0
- package/dist/tools/fs/safety.js +479 -0
- package/dist/tools/fs/safety.js.map +1 -0
- package/dist/tools/fs/search.d.ts +118 -0
- package/dist/tools/fs/search.d.ts.map +1 -0
- package/dist/tools/fs/search.js +650 -0
- package/dist/tools/fs/search.js.map +1 -0
- package/dist/tools/gitea-issue.d.ts +39 -0
- package/dist/tools/gitea-issue.d.ts.map +1 -0
- package/dist/tools/gitea-issue.js +91 -0
- package/dist/tools/gitea-issue.js.map +1 -0
- package/dist/tools/monitor.d.ts +64 -0
- package/dist/tools/monitor.d.ts.map +1 -0
- package/dist/tools/monitor.js +135 -0
- package/dist/tools/monitor.js.map +1 -0
- package/dist/tools/scheduler-tools.d.ts +48 -0
- package/dist/tools/scheduler-tools.d.ts.map +1 -0
- package/dist/tools/scheduler-tools.js +449 -0
- package/dist/tools/scheduler-tools.js.map +1 -0
- package/dist/tools/sql-adapters.d.ts +32 -0
- package/dist/tools/sql-adapters.d.ts.map +1 -0
- package/dist/tools/sql-adapters.js +31 -0
- package/dist/tools/sql-adapters.js.map +1 -0
- package/dist/tools/sql.d.ts +36 -0
- package/dist/tools/sql.d.ts.map +1 -0
- package/dist/tools/sql.js +131 -0
- package/dist/tools/sql.js.map +1 -0
- package/dist/tools/task-list.d.ts +26 -0
- package/dist/tools/task-list.d.ts.map +1 -0
- package/dist/tools/task-list.js +352 -0
- package/dist/tools/task-list.js.map +1 -0
- package/dist/tools/todo.d.ts +11 -0
- package/dist/tools/todo.d.ts.map +1 -0
- package/dist/tools/todo.js +126 -0
- package/dist/tools/todo.js.map +1 -0
- package/dist/tools/web.d.ts +59 -0
- package/dist/tools/web.d.ts.map +1 -0
- package/dist/tools/web.js +607 -0
- package/dist/tools/web.js.map +1 -0
- package/dist/tools/worktree.d.ts +88 -0
- package/dist/tools/worktree.d.ts.map +1 -0
- package/dist/tools/worktree.js +434 -0
- package/dist/tools/worktree.js.map +1 -0
- package/docs/A1-ATTRIBUTION-ROUND1-2026-07-09.md +181 -0
- package/docs/AB-ORACLE-GATE-VERDICT-2026-07-10.md +100 -0
- package/docs/ANCHOR-GAP-INVENTORY-2026-07-09.md +143 -0
- package/docs/ARCHITECTURE.md +125 -0
- package/docs/BUGHUNT-2026-07-05-NIGHT.md +98 -0
- package/docs/BUILD.md +63 -0
- package/docs/CANCEL-ASYNC-ATTRIBUTION-2026-07-09.md +98 -0
- package/docs/CC-198-VS-201-DRIFT-2026-07-09.md +70 -0
- package/docs/CC-BASELINE-FAKE-ZERO-AUDIT-2026-07-09.md +51 -0
- package/docs/CC-DRIFT-198-206-AGENT-TYPES-2026-07-10.md +82 -0
- package/docs/CC-DRIFT-198-206-CHANGELOG-2026-07-10.md +82 -0
- package/docs/CC-DRIFT-198-206-REMINDERS-2026-07-10.md +96 -0
- package/docs/CC-DRIFT-198-206-ROADMAP-2026-07-10.md +110 -0
- package/docs/CC-DRIFT-198-206-TOOL-INVENTORY-2026-07-10.md +53 -0
- package/docs/CC-DRIFT-198-206-USAGE-CONSTANTS-2026-07-10.md +64 -0
- package/docs/CC-DRIFT-198-206-WORKFLOW-2026-07-10.md +83 -0
- package/docs/CC-PARITY-CHECKLIST.md +220 -0
- package/docs/CC-PARITY-DEEP-SWEEP-2026-07-07.md +149 -0
- package/docs/CC-SUBAGENT-PROMPT-STUDY-2026-07-09.md +219 -0
- package/docs/CC-TASK-REMINDER-CADENCE-STUDY-2026-07-09.md +396 -0
- package/docs/CC-TOOL-PARITY-SWEEP-2026-07.md +56 -0
- package/docs/CC-TOOL-PROMPT-DEEP-DIFF-2026-07-08.md +274 -0
- package/docs/CC-TOOLSURFACE-DEEP-DIVE-2026-07-07.md +197 -0
- package/docs/CC206-OBSERVER-ANCHORS-2026-07-11.md +463 -0
- package/docs/CC207-CORE-SWEEP-BACKLOG-2026-07-12.md +155 -0
- package/docs/CENTER-CONTROL-PLANE-SEAM.md +86 -0
- package/docs/CLEANUP-CONTRACT-ANCHOR-2026-07-09.md +83 -0
- package/docs/COLD-START-RSI-2026-07-09.md +72 -0
- package/docs/COMPACTION-LIVE-AUDIT-2026-07-09.md +114 -0
- package/docs/CONTEXT-lifecycle-extension-points-and-stop-attribution.md +71 -0
- package/docs/COREWARS-POLYGLOT-TRIAGE-2026-07-09.md +85 -0
- package/docs/DEADTARGET-OVERFULL-HBOX-2026-07-10.md +92 -0
- package/docs/DEADTARGET-PATH-TRACING-REVERSE-2026-07-10.md +87 -0
- package/docs/DEADTARGET-WINNING-AVG-COREWARS-2026-07-10.md +96 -0
- package/docs/DEEPSEEK-API-LIMITS-PROBE-2026-07-09.md +118 -0
- package/docs/DESIGN-140-MOCK-VERIFY-2026-07-11.md +79 -0
- package/docs/DESIGN-140-VERIFICATION-2026-07-11.md +43 -0
- package/docs/DESIGN-DRAFT-workflow-collab-2026-07-11.md +56 -0
- package/docs/DESIGN-ORACLE-GROUNDING-GATE-2026-07-10.md +167 -0
- package/docs/DESIGN-TFRAG-RECONCILE-SCAFFOLD-2026-07-09.md +102 -0
- package/docs/EXP-PA2-PE-DESIGN-2026-07-11.md +220 -0
- package/docs/EXT-DOGFOOD-2026-07-12.md +50 -0
- package/docs/FINAL-VERIFY-SURFACE-AUDIT-2026-07-09.md +44 -0
- package/docs/FRAG-RECON-INVESTIGATION-2026-07-09.md +183 -0
- package/docs/HANDOFF.md +121 -0
- package/docs/KNOWN-ISSUES.md +96 -0
- package/docs/LEGW-WINDOW-TAX-2026-07-10.md +82 -0
- package/docs/LIVE-PROBE-BATCH-2026-07-11.md +207 -0
- package/docs/M2-CERT-ATTRIBUTION-2026-07-10.md +61 -0
- package/docs/M25-LEG-VARIANCE-ATTRIBUTION-2026-07-10.md +81 -0
- package/docs/MAILMAN-TIMEOUT-ATTRIBUTION-2026-07-10.md +88 -0
- package/docs/MEMORY-BACKEND-DIALECT-NOTES.md +69 -0
- package/docs/MTEB-ESCAPE-HATCH-ATTRIBUTION-2026-07-09.md +57 -0
- package/docs/MTEB-LEADERBOARD-ATTRIBUTION-2026-07-10.md +134 -0
- package/docs/ORACLE-GATE-NEGATIVE-SAMPLE-2026-07-11.md +28 -0
- package/docs/PARITY-CONTEXT-TRANSACTIONS-2026-07-10.md +67 -0
- package/docs/PARITY-PROGRESS-MATRIX-2026-07-10.md +37 -0
- package/docs/PARITY-SPOT-AGENT-TYPES-2026-07-10.md +70 -0
- package/docs/PARITY-SPOT-REMINDERS-2026-07-10.md +144 -0
- package/docs/PARITY-SPOT-TOOL-INVENTORY-2026-07-10.md +61 -0
- package/docs/PARITY-SPOT-USAGE-CONSTANTS-2026-07-10.md +95 -0
- package/docs/PARITY-SPOT-WORKFLOW-2026-07-10.md +93 -0
- package/docs/PASSWORD-RECOVERY-PANEL-VERDICT-2026-07-10.md +62 -0
- package/docs/R8-R9-FINALIZE-COORDINATION-2026-07-09.md +124 -0
- package/docs/REPL-CODE-MODE-EVALUATION-2026-07-10.md +187 -0
- package/docs/REPORT-1249-TARGETED.md +48 -0
- package/docs/RESEARCH-3P-MEMORY-SWAP-2026-07-12.md +273 -0
- package/docs/ROADMAP.md +111 -0
- package/docs/RSI-CLOUD-DEPLOY-2026-07-06.md +289 -0
- package/docs/RSI-PROCESS-AI-COLDSTART-2026-07-11.md +68 -0
- package/docs/S18-THOROUGHNESS-AUDIT-2026-07-09.md +113 -0
- package/docs/SERVICE-INTEGRATION-GUIDE.md +298 -0
- package/docs/SUBAGENT-STREAM-RESILIENCE-PARITY-2026-07-10.md +118 -0
- package/docs/SWEBENCH-PRO-RECON-2026-07-11.md +31 -0
- package/docs/TB-EFFICIENCY-TELEMETRY-2026-07-08.md +114 -0
- package/docs/TB-FAILURE-AUTOPSY-2026-07-05-RERUN.md +67 -0
- package/docs/TB-FAIRNESS-AUDIT-2026-07-08.md +141 -0
- package/docs/TB-FULL-1257-2026-07-08.md +77 -0
- package/docs/TB-LEG-GAP-ATTRIBUTION-1261-1263-2026-07-11.md +154 -0
- package/docs/TB-REGRESSION-DAEMON-KILL-2026-07-08.md +58 -0
- package/docs/TB-RSI-CROSSCHECK-2026-07-06.md +68 -0
- package/docs/TB-RSI-LEDGER.md +30 -0
- package/docs/TB-STABLE-SET-2026-07-08.md +127 -0
- package/docs/TB21-RECON-2026-07-11.md +28 -0
- package/docs/TEST-DESIGN-BATCH-1-2-3.md +97 -0
- package/docs/THIRD-PARTY-INTEGRATION.md +45 -0
- package/docs/TOKEN-ESTIMATE-CALIBRATION-LIVE-2026-07-09.md +102 -0
- package/docs/audit-2026-06-10-/347/254/254/344/272/214/350/275/256-/347/251/272/347/231/275/345/214/272/344/270/216/345/277/230/346/216/245/347/272/277.md +147 -0
- package/docs/audit-2026-06-10-/350/256/241/347/256/227bug/346/211/253/346/217/217.md +163 -0
- package/docs/audit-2026-06-11-/344/277/256/345/244/215/345/244/215/345/256/241/344/270/216/345/233/236/345/275/222/344/270/223/346/211/253.md +95 -0
- package/docs/audit-2026-06-12-design71-P1/346/275/234/344/274/217/351/235/242/350/243/201/345/206/263/344/270/216/345/220/236/351/224/231/345/256/241/350/256/241.md +45 -0
- package/docs/audit-2026-06-12-/345/205/254/345/274/200/346/227/213/351/222/256/346/264/273/346/200/247/344/270/216vendored/346/255/273/350/267/257.md +63 -0
- package/docs/audit-2026-06-15/ADDENDUM-second-pass.md +88 -0
- package/docs/audit-2026-06-15/ARCHITECTURE-AND-ROADMAP.md +187 -0
- package/docs/audit-2026-06-15/DOC-CORRECTIONS.md +105 -0
- package/docs/audit-2026-06-15/INDEX.md +49 -0
- package/docs/audit-2026-06-15/ORCHESTRATION-STATUS.md +98 -0
- package/docs/audit-2026-06-15/PRODUCTION-ISSUES.md +189 -0
- package/docs/audit-2026-06-15/REFERENCES-literature.md +139 -0
- package/docs/audit-2026-06-15/VENDOR-REFACTOR-PLAN.md +96 -0
- package/docs/cc-probe-198/README.md +72 -0
- package/docs/cc-probe-198/STABILITY-AUDIT.md +118 -0
- package/docs/cc-probe-198/live-schema-monitor-worktree-2026-07-09.json +56 -0
- package/docs/cc-probe-198/mount-variants.json +536 -0
- package/docs/cc-probe-198/plan-mode-run.json +1 -0
- package/docs/cc-probe-198/probe-bash-bg.json +224 -0
- package/docs/cc-probe-198/probe-edit-mismatch.json +120 -0
- package/docs/cc-probe-198/probe-read-missing.json +62 -0
- package/docs/cc-probe-198/probe-search-empty.json +127 -0
- package/docs/cc-probe-198/probe-task-family.json +227 -0
- package/docs/cc-probe-198/probes.status +6 -0
- package/docs/cc-probe-198/raw-capture-interactive.json +948 -0
- package/docs/cc-probe-198/raw-capture-print.json +787 -0
- package/docs/cc-probe-198/raw-capture2-interactive.json +948 -0
- package/docs/cc-probe-198/raw-capture2-print.json +787 -0
- package/docs/cc-probe-198/system-prompt.txt +135 -0
- package/docs/cc-probe-198/tools-array.json +962 -0
- package/docs/durability-boundary.md +63 -0
- package/docs/fix-2026-06-10-/350/256/241/347/256/227bug/344/277/256/345/244/215-search/346/211/271.md +75 -0
- package/docs/fix-2026-06-11-/347/254/254/344/272/214/350/275/256-/344/277/256/345/244/215-search/346/211/271.md +62 -0
- package/docs/parity-sweep/REPORT-DYNAMIC.md +97 -0
- package/docs/parity-sweep/REPORT-STATIC-GGB.md +127 -0
- package/docs/parity-sweep/REPORT-STATIC-RWE.md +133 -0
- package/docs/vendor-history.md +385 -0
- package/docs/vendored-upstream-diff-2026-07.md +83 -0
- package/package.json +70 -0
|
@@ -0,0 +1,881 @@
|
|
|
1
|
+
import { Type } from "typebox";
|
|
2
|
+
import { uuidv7 } from "../internal/harness.js";
|
|
3
|
+
import { defineTool } from "./tools.js";
|
|
4
|
+
import { parseScopeKey } from "./memory-engine/scope-contract.js";
|
|
5
|
+
import { sanitizeUntrustedText } from "./untrusted-text.js";
|
|
6
|
+
/**
|
|
7
|
+
* True when a store implements the full id-addressable trio required for memory consolidation
|
|
8
|
+
* (design/41): {@link MemoryStore.searchScored}/{@link MemoryStore.update}/{@link MemoryStore.delete}.
|
|
9
|
+
* When false, the Runner skips consolidation entirely (graceful no-op).
|
|
10
|
+
*/
|
|
11
|
+
export function supportsConsolidation(store) {
|
|
12
|
+
return (typeof store.searchScored === "function" &&
|
|
13
|
+
typeof store.update === "function" &&
|
|
14
|
+
typeof store.delete === "function");
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* True when a store implements the design/84 Seam B cursor PAIR
|
|
18
|
+
* ({@link MemoryStore.getConsolidationCursor}/{@link MemoryStore.setConsolidationCursor}). Periodic/incremental
|
|
19
|
+
* consolidation ({@link import("./consolidate-scope.js").consolidateScope}) GATES on this: a store missing
|
|
20
|
+
* either method makes a periodic pass a safe **NO-OP** (never a silent full re-consolidation of the whole
|
|
21
|
+
* scope, which would re-merge already-consolidated notes forever). Both-or-neither — a store implementing
|
|
22
|
+
* only one is treated as unsupported. Independent of {@link supportsConsolidation} (the id-addressable trio),
|
|
23
|
+
* which a periodic pass ALSO needs to actually mutate.
|
|
24
|
+
*/
|
|
25
|
+
export function supportsPeriodicConsolidation(store) {
|
|
26
|
+
return (typeof store.getConsolidationCursor === "function" &&
|
|
27
|
+
typeof store.setConsolidationCursor === "function");
|
|
28
|
+
}
|
|
29
|
+
// ============================================================================
|
|
30
|
+
// design/77 §2 — Gate 2: promotable-write utilityVerdict chokepoint
|
|
31
|
+
// ============================================================================
|
|
32
|
+
//
|
|
33
|
+
// A STORE-BOUNDARY, fail-closed gate. A "promotable" memory write (a self-evolution artifact — a
|
|
34
|
+
// skill/playbook/outcome-stats blob, classified by NOTE STRUCTURE, *not* a caller flag) REQUIRES a
|
|
35
|
+
// present-and-positive `utilityVerdict`, else fail-closed — regardless of which tool emitted it. This
|
|
36
|
+
// prevents ungated self-evolution writes: a deployment that forgets the profile promotion gate still
|
|
37
|
+
// cannot silently durably-write a promotable artifact (the chokepoint sits at the store, downstream of
|
|
38
|
+
// every inlet — the `remember` tool AND consolidation ADD).
|
|
39
|
+
//
|
|
40
|
+
// CONSTITUTIONAL SPLIT (design/76 §0 ①②): core enforces the gate's *presence* (a promotable write with
|
|
41
|
+
// no verdict throws); the *threshold/taxonomy* stays in the PROFILE — `utilityVerdict`/`outcomeStats`
|
|
42
|
+
// are opaque `unknown` here, and the definition of "positive" is a profile-injected `utilityGate`. With
|
|
43
|
+
// the gate UNWIRED, a promotable note still fails closed (absent gate NEVER auto-passes).
|
|
44
|
+
/** The closed set of caller-authored note types (design/65 {@link MemoryNoteType}, memory.ts). A note
|
|
45
|
+
* whose `type` is in this set is caller-authored; a `type` *outside* it (e.g. `"skill"`) is promotable.
|
|
46
|
+
* Exported so a caller-authored inlet (e.g. consolidation ADD) can NORMALIZE a model-suggested type to
|
|
47
|
+
* the closed set before the store boundary — a legitimate caller_authored write must never trip the
|
|
48
|
+
* promotable gate just because the model invented a non-standard `type` slug (MINOR-3). */
|
|
49
|
+
export const CALLER_AUTHORED_TYPES = new Set(["user", "feedback", "project", "reference"]);
|
|
50
|
+
/** The default caller-authored note type (matches {@link StructuredNoteInput.type}'s documented default). */
|
|
51
|
+
export const DEFAULT_CALLER_AUTHORED_TYPE = "project";
|
|
52
|
+
/** Typed, fail-closed error thrown when a promotable artifact write reaches the store boundary without a
|
|
53
|
+
* present-and-positive `utilityVerdict` (design/77 §2). The `code` is stable for callers to switch on;
|
|
54
|
+
* the write NEVER reaches the backend. */
|
|
55
|
+
export class MemoryGateError extends Error {
|
|
56
|
+
code;
|
|
57
|
+
constructor(code, detail) {
|
|
58
|
+
// Prefix the stable code into the message so it survives `String(err.message)` sinks (e.g. the
|
|
59
|
+
// consolidation `onWarn` channel, which logs the message, not the typed `.code`).
|
|
60
|
+
super(detail ? `${code}: ${detail}` : code);
|
|
61
|
+
this.name = "MemoryGateError";
|
|
62
|
+
this.code = code;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/** True when `note` carries a structural self-evolution marker (skill/playbook/outcome-stats) — design/77
|
|
66
|
+
* §2. This is what lets the marker WIN over a caller-authored `type` (e.g. `type:"reference"` WITH an
|
|
67
|
+
* `outcomeStats` blob is promotable). Kept taxonomy-free: core only checks PRESENCE, never shape. */
|
|
68
|
+
function hasPromotableMarker(note) {
|
|
69
|
+
return note.outcomeStats !== undefined;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Conservative high-confidence credential patterns (CC-parity P0-2). Each is provider-prefixed or a
|
|
73
|
+
* structurally unmistakable PEM header, so a match is almost certainly a real secret — chosen to MINIMIZE
|
|
74
|
+
* false-positives (a wrongly-rejected normal note is the head risk). No generic `key=value` /
|
|
75
|
+
* `password: …` rule (those flood on ordinary prose). Word-boundary-anchored where a prefix could appear
|
|
76
|
+
* mid-word. NOT exported as values (a consumer could regex-DoS or fingerprint the list); the public
|
|
77
|
+
* surface is {@link detectSecret} only.
|
|
78
|
+
*/
|
|
79
|
+
const SECRET_PATTERNS = [
|
|
80
|
+
// AWS access key id — literal "AKIA" + 16 uppercase-alnum. (Also covers ABIA/ACCA/ASIA variants is NOT
|
|
81
|
+
// done on purpose: AKIA is the long-lived-key prefix and the highest-confidence, lowest-FP shape.)
|
|
82
|
+
{ label: "aws_access_key_id", re: /\bAKIA[0-9A-Z]{16}\b/ },
|
|
83
|
+
// GitHub personal-access / fine-grained / OAuth / app / refresh tokens — all share the `gh*_`/`github_pat_`
|
|
84
|
+
// prefix followed by a long base62 body. The prefixes are GitHub-reserved, so FP risk is ~nil.
|
|
85
|
+
{ label: "github_token", re: /\b(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9]{36,}\b/ },
|
|
86
|
+
{ label: "github_fine_grained_pat", re: /\bgithub_pat_[A-Za-z0-9_]{60,}\b/ },
|
|
87
|
+
// OpenAI / Anthropic-style `sk-…` keys. The key body is a LONG CONTINUOUS base62 run (no hyphen) — the
|
|
88
|
+
// `sk-`/`sk-proj-`/`sk-ant-`/`sk-ant-api03-` prefixes are matched explicitly, then ≥20 alnum/underscore
|
|
89
|
+
// chars. Hyphen is DELIBERATELY excluded from the body: it let a dash-joined word slug
|
|
90
|
+
// (`task-sk-orchestrator-helper-utility`, `prod-sk-compute-cluster-east-1a`) match mid-string and flood
|
|
91
|
+
// fail-closed rejections on ordinary prose — the head FP risk. Real keys have no hyphen in the body.
|
|
92
|
+
{ label: "openai_api_key", re: /\bsk-(?:ant-(?:api03-)?|proj-)?[A-Za-z0-9_]{20,}\b/ },
|
|
93
|
+
// Stripe secret / restricted keys — `sk_live_`/`sk_test_`/`rk_live_`/`rk_test_` then a LONG base62 body.
|
|
94
|
+
// These use an UNDERSCORE (not the OpenAI hyphen), and the `live`/`test` ENV QUALIFIER is what makes the
|
|
95
|
+
// prefix Stripe-distinctive + low-FP: requiring the literal `live_`/`test_` qualifier means an ordinary
|
|
96
|
+
// identifier like `sk_compute`/`sk_handler` (no env qualifier, short body) does NOT match — so the head
|
|
97
|
+
// FP risk (a word slug mid-string) is avoided while real Stripe keys (≥24-char body) are caught.
|
|
98
|
+
{ label: "stripe_secret_key", re: /\b[sr]k_(?:live|test)_[A-Za-z0-9]{24,}\b/ },
|
|
99
|
+
// Slack tokens — `xox[baprs]-` prefix then 1-3 short dash-separated id fields and a LONG (≥16-char)
|
|
100
|
+
// alnum secret body as the final field. Requiring the long terminal run rejects dash-joined word slugs
|
|
101
|
+
// (`xoxb-archive-channel-for-old-stuff`, `xoxr-style-guide-v2`) that the old free `[A-Za-z0-9-]{10,}`
|
|
102
|
+
// body flagged as the head FP risk, while still matching real bot/user/app tokens.
|
|
103
|
+
{ label: "slack_token", re: /\bxox[baprs]-(?:[A-Za-z0-9]+-){1,3}[A-Za-z0-9]{16,}\b/ },
|
|
104
|
+
// Google API key — `AIza` + 35 url-safe chars (Google-reserved prefix).
|
|
105
|
+
{ label: "google_api_key", re: /\bAIza[0-9A-Za-z_-]{35}\b/ },
|
|
106
|
+
// PEM private-key header — RSA/EC/DSA/OPENSSH/PGP/plain. The "-----BEGIN … PRIVATE KEY[ BLOCK]-----" banner
|
|
107
|
+
// is unmistakable and never legitimately appears in a durable declarative fact. The optional " BLOCK" suffix
|
|
108
|
+
// covers PGP's "-----BEGIN PGP PRIVATE KEY BLOCK-----" form (effect-test 1a caught this as a real MISS —
|
|
109
|
+
// private key could otherwise bypass the write-gate into durable memory).
|
|
110
|
+
{ label: "private_key", re: /-----BEGIN (?:[A-Z0-9]+ )*PRIVATE KEY(?: BLOCK)?-----/ },
|
|
111
|
+
];
|
|
112
|
+
/**
|
|
113
|
+
* Scan `text` for a high-confidence credential (CC-parity P0-2). Returns the matched pattern's stable
|
|
114
|
+
* `label` (NEVER the matched secret value — labels are safe to log/surface), or `null` when clean.
|
|
115
|
+
* Deliberately CONSERVATIVE: only provider-prefixed keys + PEM private-key headers match, so ordinary
|
|
116
|
+
* prose that merely mentions tokens/keys/passwords passes through untouched (false-positives are the head
|
|
117
|
+
* risk — a wrongly-rejected normal note silently breaks legitimate memory).
|
|
118
|
+
*/
|
|
119
|
+
export function detectSecret(text) {
|
|
120
|
+
if (!text)
|
|
121
|
+
return null;
|
|
122
|
+
for (const p of SECRET_PATTERNS) {
|
|
123
|
+
if (p.re.test(text))
|
|
124
|
+
return p.label;
|
|
125
|
+
}
|
|
126
|
+
return null;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Store-boundary secret-scan invariant (CC-parity P0-2). Fail-closed: if `body` carries a high-confidence
|
|
130
|
+
* credential, throw {@link MemoryGateError}`("memory.secret_detected")` — the write NEVER reaches the
|
|
131
|
+
* backend. The error detail names the pattern LABEL (e.g. `aws_access_key_id`), never the matched value,
|
|
132
|
+
* so the secret is not re-leaked into a log/error sink. A clean body is a no-op. Applied by
|
|
133
|
+
* {@link guardedMemoryStore} on EVERY durable write inlet (`append`, `appendStructured`, the
|
|
134
|
+
* `appendPromotable` door) so both the `remember` tool and consolidation ADD are covered at one chokepoint.
|
|
135
|
+
*/
|
|
136
|
+
export function enforceSecretWriteGate(body) {
|
|
137
|
+
const label = detectSecret(body);
|
|
138
|
+
if (label !== null) {
|
|
139
|
+
throw new MemoryGateError("memory.secret_detected", `memory write blocked: detected ${label}`);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Structured-note secret-scan invariant (CC-parity P0-2). Scans EVERY text field of a {@link StructuredNoteInput}
|
|
144
|
+
* that becomes DURABLE and/or enters the manifest — not just `body`. The body alone is insufficient: `name`
|
|
145
|
+
* (rendered as `[[name]]` cross-references) and `description` (rendered into the recall manifest + injected
|
|
146
|
+
* into the side-query sub-prompt) are ALSO persisted and surfaced, so a secret hidden there
|
|
147
|
+
* (`appendStructured({ body: "safe", description: "sk_live_…" })`) would otherwise be durably stored and
|
|
148
|
+
* leaked into every later same-scope manifest — a real bypass of the body-only scan. `links` slugs are NOT
|
|
149
|
+
* scanned: they are short `[[name]]`-style reference tokens (no credential body shape clears the
|
|
150
|
+
* conservative detector), and scanning them adds FP surface for no realistic gain. Fail-closed: the first
|
|
151
|
+
* field that carries a high-confidence credential throws {@link MemoryGateError}`("memory.secret_detected")`.
|
|
152
|
+
*/
|
|
153
|
+
export function enforceStructuredNoteSecretGate(note) {
|
|
154
|
+
// Scan EVERY field that lands in the durable store AND/OR the rendered manifest: body, name,
|
|
155
|
+
// description, AND type (a free-form string when unknown — re-review residual-bypass fix). `links` are
|
|
156
|
+
// deliberately NOT scanned: short `[[name]]` ref tokens with no credential-body shape; the conservative
|
|
157
|
+
// detector never fires on them and scanning only adds false-positive surface for no gain.
|
|
158
|
+
enforceSecretWriteGate(note.body);
|
|
159
|
+
if (note.name !== undefined)
|
|
160
|
+
enforceSecretWriteGate(note.name);
|
|
161
|
+
if (note.description !== undefined)
|
|
162
|
+
enforceSecretWriteGate(note.description);
|
|
163
|
+
if (note.type !== undefined)
|
|
164
|
+
enforceSecretWriteGate(note.type);
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Classify a structured-note write as `caller_authored` (normal memory — ungated) or `promotable` (a
|
|
168
|
+
* self-evolution artifact — gated) — design/77 §2. PURE, taxonomy-free CORE logic.
|
|
169
|
+
*
|
|
170
|
+
* `promotable` iff the note's `type` is defined AND outside the caller-authored closed set, OR the note
|
|
171
|
+
* carries a structural promotable marker. **The structural marker WINS over the closed-set type** — a
|
|
172
|
+
* `type:"reference"` note WITH an `outcomeStats` marker classifies `promotable`.
|
|
173
|
+
*/
|
|
174
|
+
export function classifyPromotable(note) {
|
|
175
|
+
if (hasPromotableMarker(note))
|
|
176
|
+
return "promotable"; // structural marker wins over closed-set type
|
|
177
|
+
if (note.type !== undefined && !CALLER_AUTHORED_TYPES.has(note.type))
|
|
178
|
+
return "promotable";
|
|
179
|
+
return "caller_authored";
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* The store-boundary Gate-2 check (design/77 §2). For a `promotable` note, require a present-and-positive
|
|
183
|
+
* `utilityVerdict`; otherwise throw {@link MemoryGateError}`("memory.promotable_ungated")` fail-closed —
|
|
184
|
+
* the write NEVER reaches the backend. A `caller_authored` note is unchanged (no verdict needed).
|
|
185
|
+
*
|
|
186
|
+
* **Gate-presence invariant (CRITICAL):** "positive" is decided by the profile `utilityGate`. When the
|
|
187
|
+
* gate is UNWIRED, a promotable note STILL fails closed (an absent gate never auto-passes). When wired,
|
|
188
|
+
* the verdict must be present (`!== undefined`) and the gate must accept its `outcomeStats`.
|
|
189
|
+
*/
|
|
190
|
+
export function enforcePromotableWriteGate(note, utilityVerdict, utilityGate) {
|
|
191
|
+
if (classifyPromotable(note) === "caller_authored")
|
|
192
|
+
return; // normal memory: unchanged, ungated
|
|
193
|
+
// Promotable artifact: a verdict MUST be present AND judged positive by the (profile) gate.
|
|
194
|
+
if (utilityVerdict === undefined) {
|
|
195
|
+
throw new MemoryGateError("memory.promotable_ungated", "promotable memory write requires a utilityVerdict");
|
|
196
|
+
}
|
|
197
|
+
if (utilityGate === undefined) {
|
|
198
|
+
// Gate-presence invariant: with the profile gate unwired, a present verdict cannot be judged →
|
|
199
|
+
// fail-closed (the gate is ABSENT, never an implicit pass).
|
|
200
|
+
throw new MemoryGateError("memory.promotable_ungated", "promotable memory write but profile utilityGate is unwired");
|
|
201
|
+
}
|
|
202
|
+
if (!utilityGate(note.outcomeStats)) {
|
|
203
|
+
throw new MemoryGateError("memory.promotable_ungated", "promotable memory write failed the profile utilityGate");
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
/** Return a copy of `note` with any caller-supplied `consolidationGenerated` removed (design/84 Seam B
|
|
207
|
+
* boundary defense, council DESIGN-4). The public `appendStructured` inlet uses this so an EXTERNAL caller
|
|
208
|
+
* can never mark a note "consolidation-generated" (which would silently exile it from periodic
|
|
209
|
+
* consolidation forever). When the field is absent the original object is returned unchanged (no churn). */
|
|
210
|
+
function stripConsolidationGenerated(note) {
|
|
211
|
+
if (note.consolidationGenerated === undefined)
|
|
212
|
+
return note;
|
|
213
|
+
const { consolidationGenerated: _drop, ...rest } = note;
|
|
214
|
+
return rest;
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Wrap a {@link MemoryStore} so EVERY durable write path runs the Gate-2 chokepoint (design/77 §2). One
|
|
218
|
+
* wrapper at the store boundary covers BOTH inlets (the `remember` tool and consolidation ADD) — no
|
|
219
|
+
* per-inlet edits. It intercepts BOTH write methods (§2 polish):
|
|
220
|
+
* - `appendStructured` — classify the structured note; a `promotable` one needs a present+positive verdict.
|
|
221
|
+
* Since `appendStructured` carries NO verdict, a promotable structured write is ALWAYS rejected here;
|
|
222
|
+
* the legitimate way to land one is {@link MemoryStore.appendPromotable} (which carries the verdict).
|
|
223
|
+
* - `append` — the legacy/typeless fallback CANNOT carry structure, so any append-path write is
|
|
224
|
+
* classified `caller_authored` and passes through unchanged (documents the chokepoint's exhaustiveness
|
|
225
|
+
* across store methods — a promotable artifact structurally cannot flow out of this path).
|
|
226
|
+
*
|
|
227
|
+
* `appendPromotable` is the gated legitimate door: it runs the gate WITH the supplied verdict, then (on
|
|
228
|
+
* pass) writes via the inner store's `appendStructured` (or `append` fallback). The id-addressed `update`
|
|
229
|
+
* (consolidation's UPDATE op) replaces a note's text with new model-generated content, so it is ALSO
|
|
230
|
+
* secret-scanned (a promotable artifact structurally cannot flow out of it — only existing-note text is
|
|
231
|
+
* rewritten). `delete` and the read/search/manifest surface are straight pass-throughs (they carry no new
|
|
232
|
+
* content and never WRITE a promotable artifact).
|
|
233
|
+
*/
|
|
234
|
+
export function guardedMemoryStore(inner, utilityGate) {
|
|
235
|
+
const guarded = {
|
|
236
|
+
// ---- reads & lifecycle: straight pass-through ----
|
|
237
|
+
get vectorMode() {
|
|
238
|
+
return inner.vectorMode; // forward the Slice-5 rung observable (design/81)
|
|
239
|
+
},
|
|
240
|
+
read: (scope) => inner.read(scope),
|
|
241
|
+
clear: (scope) => inner.clear(scope),
|
|
242
|
+
// ---- legacy/typeless append: structurally caller-authored, but still secret-scanned (P0-2) ----
|
|
243
|
+
append: (scope, note) => {
|
|
244
|
+
enforceSecretWriteGate(note); // CC-parity P0-2: fail-closed on a high-confidence credential
|
|
245
|
+
return inner.append(scope, note);
|
|
246
|
+
},
|
|
247
|
+
// ---- the chokepoint: a structured write with NO verdict ----
|
|
248
|
+
appendStructured: inner.appendStructured
|
|
249
|
+
? (scope, note) => {
|
|
250
|
+
// CC-parity P0-2: scan ALL durable+manifest fields (body, name, description), not just the body —
|
|
251
|
+
// a secret in `description`/`name` would otherwise persist + leak into every later manifest.
|
|
252
|
+
enforceStructuredNoteSecretGate(note);
|
|
253
|
+
// No verdict travels with appendStructured → a caller_authored note passes, a promotable one
|
|
254
|
+
// (free-form type or outcomeStats marker) fails closed before reaching the backend.
|
|
255
|
+
enforcePromotableWriteGate(note, undefined, utilityGate);
|
|
256
|
+
// design/84 Seam B boundary defense (council DESIGN-4): the public appendStructured is the EXTERNAL
|
|
257
|
+
// inlet (the `remember` tool, a caller). It must NEVER honor a caller-supplied
|
|
258
|
+
// `consolidationGenerated` — that flag silently EXILES a note from periodic consolidation forever, so
|
|
259
|
+
// a misconfigured/hostile caller setting it would permanently break consolidation for that note.
|
|
260
|
+
// STRIP it here; the ONLY legitimate inlet is `appendConsolidationGenerated` below (consolidation-only).
|
|
261
|
+
return inner.appendStructured(scope, stripConsolidationGenerated(note));
|
|
262
|
+
}
|
|
263
|
+
: undefined,
|
|
264
|
+
// ---- INTERNAL consolidation-only door: the ONE inlet allowed to SET the Seam B marker ----
|
|
265
|
+
appendConsolidationGenerated: inner.appendStructured
|
|
266
|
+
? (scope, note) => {
|
|
267
|
+
// Same write-boundary hygiene as appendStructured (secret-scan + promotable gate) — consolidation
|
|
268
|
+
// ADDs are caller_authored by construction (memory-consolidation.ts normalizes a non-closed-set
|
|
269
|
+
// type), so the promotable gate passes; the secret scan still applies.
|
|
270
|
+
enforceStructuredNoteSecretGate(note);
|
|
271
|
+
enforcePromotableWriteGate(note, undefined, utilityGate);
|
|
272
|
+
// FORCE the marker on (this is the legitimate consolidation-generated inlet, the counterpart to the
|
|
273
|
+
// strip above). Ignore whatever the note carried and set it true.
|
|
274
|
+
const withMarker = { ...note, consolidationGenerated: true };
|
|
275
|
+
// DOUBLE-WRAP marker transit (codex BLOCKER): when `inner` is ITSELF a guarded store (e.g.
|
|
276
|
+
// FileStorageBackend already wraps its FileMemoryStore in guardedMemoryStore, then the Runner wraps
|
|
277
|
+
// THAT again), routing the marker through the inner's PUBLIC `appendStructured` would hit its
|
|
278
|
+
// boundary-defense `stripConsolidationGenerated` and DROP the marker before it reaches the backing
|
|
279
|
+
// store → the note is never excluded from future passes → infinite re-merge. So PREFER the inner's
|
|
280
|
+
// INTERNAL consolidation door (`appendConsolidationGenerated`) when present: that is the counterpart
|
|
281
|
+
// that FORCES the marker on, so the marker survives every guard layer down to the backing store.
|
|
282
|
+
// Fall back to the inner's `appendStructured` (with the marker set) ONLY for a RAW (un-guarded)
|
|
283
|
+
// inner store, which honors the marker directly (no strip). DESIGN-4 is preserved: this internal
|
|
284
|
+
// door is never reachable by an external caller — the `remember` tool / a caller go through the
|
|
285
|
+
// PUBLIC `appendStructured`, whose strip is untouched; only `runMemoryConsolidation` calls this.
|
|
286
|
+
if (inner.appendConsolidationGenerated)
|
|
287
|
+
return inner.appendConsolidationGenerated(scope, withMarker);
|
|
288
|
+
return inner.appendStructured(scope, withMarker);
|
|
289
|
+
}
|
|
290
|
+
: undefined,
|
|
291
|
+
// ---- the legitimate door: promotable write WITH a verdict ----
|
|
292
|
+
appendPromotable: (scope, note, utilityVerdict) => {
|
|
293
|
+
// CC-parity P0-2: even a verdict-bearing artifact may not carry a secret — and the scan covers
|
|
294
|
+
// name/description too (they enter the durable store + manifest), not just the body.
|
|
295
|
+
enforceStructuredNoteSecretGate(note);
|
|
296
|
+
enforcePromotableWriteGate(note, utilityVerdict, utilityGate); // gate WITH the supplied verdict
|
|
297
|
+
// On pass, persist as a structured note (verdict/outcomeStats are profile-side; core stores the body).
|
|
298
|
+
if (inner.appendPromotable)
|
|
299
|
+
return inner.appendPromotable(scope, note, utilityVerdict);
|
|
300
|
+
if (inner.appendStructured)
|
|
301
|
+
return inner.appendStructured(scope, note);
|
|
302
|
+
return inner.append(scope, note.body);
|
|
303
|
+
},
|
|
304
|
+
};
|
|
305
|
+
// Forward the optional consolidation/recall surface so a wrapped store stays a drop-in (these are reads
|
|
306
|
+
// or id-addressed mutations of EXISTING notes — none can introduce a new promotable artifact).
|
|
307
|
+
if (inner.search)
|
|
308
|
+
guarded.search = (scope, query, limit) => inner.search(scope, query, limit);
|
|
309
|
+
if (inner.searchScored)
|
|
310
|
+
guarded.searchScored = (scope, query, limit) => inner.searchScored(scope, query, limit);
|
|
311
|
+
if (inner.update)
|
|
312
|
+
guarded.update = (scope, id, text) => {
|
|
313
|
+
// CC-parity P0-2: UPDATE replaces a note's stored text with NEW content (consolidation's UPDATE op
|
|
314
|
+
// writes MODEL-GENERATED text), so it is a durable write path and MUST be scanned — otherwise a
|
|
315
|
+
// secret could be laundered past the gate by phrasing it as an edit of an existing note.
|
|
316
|
+
enforceSecretWriteGate(text);
|
|
317
|
+
return inner.update(scope, id, text);
|
|
318
|
+
};
|
|
319
|
+
// `delete` carries no new content (id-addressed removal) → no scan needed.
|
|
320
|
+
if (inner.delete)
|
|
321
|
+
guarded.delete = (scope, id) => inner.delete(scope, id);
|
|
322
|
+
if (inner.listStructuredNotes)
|
|
323
|
+
guarded.listStructuredNotes = (scope) => inner.listStructuredNotes(scope);
|
|
324
|
+
if (inner.getByIds)
|
|
325
|
+
guarded.getByIds = (scope, ids) => inner.getByIds(scope, ids);
|
|
326
|
+
// design/84 Seam B cursor pair: opaque ordering markers carry no new content (no promotable artifact, no
|
|
327
|
+
// secret to scan) → straight pass-throughs. Forwarding them keeps `supportsPeriodicConsolidation` true on
|
|
328
|
+
// a wrapped store (else wrapping would silently disable periodic consolidation).
|
|
329
|
+
if (inner.getConsolidationCursor)
|
|
330
|
+
guarded.getConsolidationCursor = (scope) => inner.getConsolidationCursor(scope);
|
|
331
|
+
if (inner.setConsolidationCursor)
|
|
332
|
+
guarded.setConsolidationCursor = (scope, cursor) => inner.setConsolidationCursor(scope, cursor);
|
|
333
|
+
return guarded;
|
|
334
|
+
}
|
|
335
|
+
/** Render a stored entry as the timestamped bullet used in `read`/`search` output. */
|
|
336
|
+
function renderBullet(e) {
|
|
337
|
+
return `- (${e.ts} UTC) ${e.text}`;
|
|
338
|
+
}
|
|
339
|
+
/** Lower-cased alphanumeric term set of a string (for the lexical distance stand-in). */
|
|
340
|
+
function termSet(s) {
|
|
341
|
+
return new Set(s
|
|
342
|
+
.toLowerCase()
|
|
343
|
+
.split(/[^a-z0-9]+/)
|
|
344
|
+
.filter(Boolean));
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Default in-memory MemoryStore (lost on restart). Use a durable backend in production.
|
|
348
|
+
*
|
|
349
|
+
* Id-addressable (design/41): each note gets a UUID stable across `update` and never reused after
|
|
350
|
+
* `delete`, so {@link searchScored}/{@link update}/{@link delete} work and memory consolidation can run.
|
|
351
|
+
* It has no embeddings, so `searchScored` returns a **lexical** (Jaccard) distance as a stand-in for a
|
|
352
|
+
* real cosine distance — fine for dev/tests, but a production store should back this with vectors.
|
|
353
|
+
*/
|
|
354
|
+
export class InMemoryMemoryStore {
|
|
355
|
+
byScope = new Map();
|
|
356
|
+
/** design/84 Seam B: per-scope periodic-consolidation cursor (lost on restart, like the rest of this store). */
|
|
357
|
+
cursorByScope = new Map();
|
|
358
|
+
/** design/81 Slice 5: the in-memory store has no embedder — always the lexical floor. */
|
|
359
|
+
vectorMode = "lexical";
|
|
360
|
+
read(scope) {
|
|
361
|
+
const entries = this.byScope.get(scope);
|
|
362
|
+
if (!entries || entries.length === 0) {
|
|
363
|
+
return null;
|
|
364
|
+
}
|
|
365
|
+
return entries.map(renderBullet).join("\n");
|
|
366
|
+
}
|
|
367
|
+
append(scope, note) {
|
|
368
|
+
const text = note.trim().replace(/^#+\s*/, ""); // strip a leading "# " quick-add marker
|
|
369
|
+
if (!text) {
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
const ts = new Date().toISOString().replace("T", " ").slice(0, 16);
|
|
373
|
+
const entry = { id: uuidv7(), text, ts };
|
|
374
|
+
const arr = this.byScope.get(scope) ?? [];
|
|
375
|
+
arr.push(entry);
|
|
376
|
+
this.byScope.set(scope, arr);
|
|
377
|
+
return entry.id;
|
|
378
|
+
}
|
|
379
|
+
appendStructured(scope, note) {
|
|
380
|
+
const body = note.body.trim().replace(/^#+\s*/, "");
|
|
381
|
+
if (!body)
|
|
382
|
+
return ""; // nothing to store; caller treats "" like a no-op (mirrors append's empty guard)
|
|
383
|
+
const ts = new Date().toISOString().replace("T", " ").slice(0, 16);
|
|
384
|
+
const entry = {
|
|
385
|
+
id: uuidv7(),
|
|
386
|
+
text: body,
|
|
387
|
+
ts,
|
|
388
|
+
name: note.name,
|
|
389
|
+
type: note.type ?? "project", // default type (design/65 §2.1)
|
|
390
|
+
description: note.description?.trim() || firstSentence(body), // derived at write time (§8#6)
|
|
391
|
+
links: note.links,
|
|
392
|
+
...(note.consolidationGenerated ? { consolidationGenerated: true } : {}), // design/84 Seam B marker
|
|
393
|
+
};
|
|
394
|
+
const arr = this.byScope.get(scope) ?? [];
|
|
395
|
+
arr.push(entry);
|
|
396
|
+
this.byScope.set(scope, arr);
|
|
397
|
+
return entry.id;
|
|
398
|
+
}
|
|
399
|
+
clear(scope) {
|
|
400
|
+
this.byScope.delete(scope);
|
|
401
|
+
this.cursorByScope.delete(scope); // design/84 Seam B: a cleared scope is logically fresh — reset its cursor
|
|
402
|
+
}
|
|
403
|
+
/**
|
|
404
|
+
* Keyword search backing the `recall` tool. design/81 Slice 2b — uses the SHARED synonym/stem-aware
|
|
405
|
+
* {@link lexicalSearchMatch} (the SAME matcher as {@link import("../stores/file/memory-store.js").FileMemoryStore.search}),
|
|
406
|
+
* so the `recall` tool returns IDENTICAL results across the InMemory and File backends. With no synonym/stem
|
|
407
|
+
* hit it degrades to the plain substring filter (byte-identical to the pre-Slice-2b behavior).
|
|
408
|
+
*/
|
|
409
|
+
search(scope, query, limit = 10) {
|
|
410
|
+
const entries = this.byScope.get(scope);
|
|
411
|
+
if (!entries || entries.length === 0) {
|
|
412
|
+
return [];
|
|
413
|
+
}
|
|
414
|
+
return entries
|
|
415
|
+
.map(renderBullet)
|
|
416
|
+
.filter((b) => lexicalSearchMatch(query, b))
|
|
417
|
+
.slice(-limit);
|
|
418
|
+
}
|
|
419
|
+
/**
|
|
420
|
+
* Lexical-distance retrieval (consolidation candidate source). Distance = `1 - Jaccard(terms)` so it
|
|
421
|
+
* lives in [0, 1] ⊂ the [0, 2] cosine-distance contract (0 = identical term set). Returns the top
|
|
422
|
+
* `limit` nearest entries (excludes zero-overlap ones). Deterministic — handy for tests.
|
|
423
|
+
*/
|
|
424
|
+
searchScored(scope, query, limit = 20) {
|
|
425
|
+
const entries = this.byScope.get(scope);
|
|
426
|
+
if (!entries || entries.length === 0) {
|
|
427
|
+
return [];
|
|
428
|
+
}
|
|
429
|
+
const q = termSet(query);
|
|
430
|
+
if (q.size === 0) {
|
|
431
|
+
return [];
|
|
432
|
+
}
|
|
433
|
+
const scored = [];
|
|
434
|
+
for (const e of entries) {
|
|
435
|
+
const t = termSet(e.text);
|
|
436
|
+
let inter = 0;
|
|
437
|
+
for (const term of q) {
|
|
438
|
+
if (t.has(term))
|
|
439
|
+
inter++;
|
|
440
|
+
}
|
|
441
|
+
const union = q.size + t.size - inter;
|
|
442
|
+
const jaccard = union === 0 ? 0 : inter / union;
|
|
443
|
+
if (jaccard === 0)
|
|
444
|
+
continue; // no lexical overlap → not a candidate
|
|
445
|
+
scored.push({ id: e.id, text: e.text, score: 1 - jaccard, ...(e.consolidationGenerated ? { consolidationGenerated: true } : {}) });
|
|
446
|
+
}
|
|
447
|
+
scored.sort((a, b) => a.score - b.score);
|
|
448
|
+
return scored.slice(0, limit);
|
|
449
|
+
}
|
|
450
|
+
update(scope, id, text) {
|
|
451
|
+
const clean = text.trim();
|
|
452
|
+
if (!clean) {
|
|
453
|
+
return;
|
|
454
|
+
}
|
|
455
|
+
const entry = this.byScope.get(scope)?.find((e) => e.id === id);
|
|
456
|
+
if (!entry) {
|
|
457
|
+
return; // unknown id → no-op (the caller already guards ids; this is defensive)
|
|
458
|
+
}
|
|
459
|
+
const newBody = clean.replace(/^#+\s*/, "");
|
|
460
|
+
// design/65 [79]: if the description was AUTO-DERIVED at write time (== first sentence of the OLD body),
|
|
461
|
+
// re-derive it from the new body so the manifest description doesn't drift away from the content after
|
|
462
|
+
// consolidation rewrites it (the side-query selects on the description). An EXPLICIT caller-supplied
|
|
463
|
+
// description (!= the old first sentence) is preserved.
|
|
464
|
+
if (entry.description !== undefined && entry.description === firstSentence(entry.text)) {
|
|
465
|
+
entry.description = firstSentence(newBody);
|
|
466
|
+
}
|
|
467
|
+
entry.text = newBody;
|
|
468
|
+
entry.ts = new Date().toISOString().replace("T", " ").slice(0, 16); // a fresh write refreshes recency
|
|
469
|
+
}
|
|
470
|
+
delete(scope, id) {
|
|
471
|
+
const arr = this.byScope.get(scope);
|
|
472
|
+
if (!arr) {
|
|
473
|
+
return;
|
|
474
|
+
}
|
|
475
|
+
const i = arr.findIndex((e) => e.id === id);
|
|
476
|
+
if (i !== -1) {
|
|
477
|
+
arr.splice(i, 1);
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
/** Manifest (design/65 §2.2): a header per note, body excluded. description = the note's first sentence
|
|
481
|
+
* (legacy flat notes have no frontmatter; this is the council #10 P1 fallback). */
|
|
482
|
+
listStructuredNotes(scope) {
|
|
483
|
+
const entries = this.byScope.get(scope) ?? [];
|
|
484
|
+
// Structured notes surface their name/type/description; legacy flat notes fall back to the first
|
|
485
|
+
// sentence (no name/type) so a mixed store still produces one manifest (design/65 §8#14 / TC-65P2.5).
|
|
486
|
+
return entries.map((e) => ({
|
|
487
|
+
id: e.id,
|
|
488
|
+
description: e.description ?? firstSentence(e.text),
|
|
489
|
+
mtimeMs: mtimeMsOf(e.ts),
|
|
490
|
+
...(e.name ? { name: e.name } : {}),
|
|
491
|
+
...(e.type ? { type: e.type } : {}),
|
|
492
|
+
...(e.consolidationGenerated ? { consolidationGenerated: true } : {}),
|
|
493
|
+
}));
|
|
494
|
+
}
|
|
495
|
+
/** design/84 Seam B: read the periodic-consolidation cursor (opaque note-id high-water mark). */
|
|
496
|
+
getConsolidationCursor(scope) {
|
|
497
|
+
return this.cursorByScope.get(scope);
|
|
498
|
+
}
|
|
499
|
+
/** design/84 Seam B: persist the periodic-consolidation cursor. */
|
|
500
|
+
setConsolidationCursor(scope, cursor) {
|
|
501
|
+
this.cursorByScope.set(scope, cursor);
|
|
502
|
+
}
|
|
503
|
+
getByIds(scope, ids) {
|
|
504
|
+
const entries = this.byScope.get(scope);
|
|
505
|
+
if (!entries)
|
|
506
|
+
return [];
|
|
507
|
+
const want = new Set(ids);
|
|
508
|
+
return entries
|
|
509
|
+
.filter((e) => want.has(e.id))
|
|
510
|
+
.map((e) => ({
|
|
511
|
+
id: e.id,
|
|
512
|
+
text: e.text,
|
|
513
|
+
description: e.description ?? firstSentence(e.text),
|
|
514
|
+
mtimeMs: mtimeMsOf(e.ts),
|
|
515
|
+
...(e.name ? { name: e.name } : {}),
|
|
516
|
+
...(e.type ? { type: e.type } : {}),
|
|
517
|
+
...(e.consolidationGenerated ? { consolidationGenerated: true } : {}),
|
|
518
|
+
}));
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
/**
|
|
522
|
+
* design/81 Slice 2b — a ZERO-MODEL lexical term expander closing the only real lexical recall weakness the
|
|
523
|
+
* red-team raised (the `recall`-tool `search` misses paraphrases like "auth token" vs "credentials/bearer").
|
|
524
|
+
* Pure TS, NO embedder/native/model dep — same posture as the Jaccard stand-in. For a lower-cased query
|
|
525
|
+
* term it returns that term PLUS:
|
|
526
|
+
* - its members of a small bidirectional **synonym set** (auth↔credentials↔bearer, token↔key↔secret, …),
|
|
527
|
+
* looked up for BOTH the original term AND its plural stem (so an inflected query like "tokens" — whose
|
|
528
|
+
* singular "token" is the synonym-group member — still expands to {bearer, apikey, secret, key}), and
|
|
529
|
+
* - a light **plural** stem (`-ies→-y`, `-es`, `-s`, with a ≥3-char guard) so "tokens" reaches "token".
|
|
530
|
+
* (The `-ing`/`-ed` rules were removed — they over-truncated and produced wrong stems.)
|
|
531
|
+
* Always includes the original term, so a non-expandable term degrades to the existing substring match
|
|
532
|
+
* (byte-identical to the prior behavior when no synonym/stem applies). The caller (`lexicalSearchMatch`)
|
|
533
|
+
* treats the returned variants as an OR within one query term (still AND across terms).
|
|
534
|
+
*/
|
|
535
|
+
export function expandLexicalTerms(term) {
|
|
536
|
+
const t = term.toLowerCase();
|
|
537
|
+
const out = new Set([t]);
|
|
538
|
+
// Light, conservative PLURAL stemming (additive — keep the original too). Only strip to a ≥3-char stem.
|
|
539
|
+
const stem = lightStem(t);
|
|
540
|
+
const stemOk = stem !== t && stem.length >= 3;
|
|
541
|
+
if (stemOk)
|
|
542
|
+
out.add(stem);
|
|
543
|
+
// Bidirectional synonym groups — any member expands to all members of its group(s). Look up BOTH the
|
|
544
|
+
// original term AND its plural stem, because the groups are mostly singular: a plural/inflected query
|
|
545
|
+
// (e.g. "tokens") would otherwise never reach its group (the singular "token" IS the member).
|
|
546
|
+
for (const group of LEXICAL_SYNONYM_GROUPS) {
|
|
547
|
+
if (group.has(t) || (stemOk && group.has(stem)))
|
|
548
|
+
for (const w of group)
|
|
549
|
+
out.add(w);
|
|
550
|
+
}
|
|
551
|
+
return [...out];
|
|
552
|
+
}
|
|
553
|
+
/**
|
|
554
|
+
* Shared SYNONYM/STEM-aware lexical match (design/81 Slice 2b) — the ONE matcher used by BOTH
|
|
555
|
+
* {@link InMemoryMemoryStore.search} and {@link import("../stores/file/memory-store.js").FileMemoryStore.search},
|
|
556
|
+
* so the `recall` tool returns IDENTICAL results across backends (the "byte-identical to InMemory" contract).
|
|
557
|
+
* It is a recall-QUALITY behavior, correct to apply everywhere. (Pg's `search` is a separate SQL path —
|
|
558
|
+
* a known follow-on, unchanged in this pass.)
|
|
559
|
+
*
|
|
560
|
+
* Matching rule: tokenize `text` on word boundaries, then for each whitespace-separated `query` term the
|
|
561
|
+
* text must match AT LEAST ONE of that term's {@link expandLexicalTerms} variants (OR within a term), and
|
|
562
|
+
* EVERY query term must match (AND across terms). The ORIGINAL query term keeps its pre-Slice-2b SUBSTRING
|
|
563
|
+
* semantics (back-compat); the EXPANDED synonym/stem variants are matched on WORD BOUNDARIES (set membership
|
|
564
|
+
* over the text's token set) so a short injected synonym like "key"/"db" cannot substring-match an unrelated
|
|
565
|
+
* word ("keyboard"/"double"). An empty/whitespace-only query never matches.
|
|
566
|
+
*/
|
|
567
|
+
export function lexicalSearchMatch(query, text) {
|
|
568
|
+
const terms = query.toLowerCase().split(/\s+/).filter(Boolean);
|
|
569
|
+
if (terms.length === 0)
|
|
570
|
+
return false;
|
|
571
|
+
const lower = text.toLowerCase();
|
|
572
|
+
const tokens = termSet(text); // word-boundary token set of the note text (alphanumeric runs)
|
|
573
|
+
return terms.every((t) => {
|
|
574
|
+
const variants = expandLexicalTerms(t);
|
|
575
|
+
return variants.some((v) =>
|
|
576
|
+
// The original term keeps SUBSTRING semantics (back-compat); expanded variants must hit a whole token.
|
|
577
|
+
v === t ? lower.includes(v) : tokens.has(v));
|
|
578
|
+
});
|
|
579
|
+
}
|
|
580
|
+
/** Small bidirectional synonym groups for {@link expandLexicalTerms} (lexical only, no model). Each set is a
|
|
581
|
+
* mutual-synonym cluster: matching ANY member expands the query term to ALL members. */
|
|
582
|
+
const LEXICAL_SYNONYM_GROUPS = [
|
|
583
|
+
new Set(["auth", "authentication", "authorization", "credentials", "credential", "login", "signin"]),
|
|
584
|
+
new Set(["token", "bearer", "apikey", "secret", "key"]),
|
|
585
|
+
new Set(["password", "passwd", "passphrase", "pwd"]),
|
|
586
|
+
new Set(["delete", "remove", "drop", "erase"]),
|
|
587
|
+
new Set(["config", "configuration", "settings", "setting"]),
|
|
588
|
+
new Set(["error", "failure", "exception", "fault"]),
|
|
589
|
+
new Set(["db", "database"]),
|
|
590
|
+
];
|
|
591
|
+
/**
|
|
592
|
+
* Conservative trailing-PLURAL stem (plural inflections ONLY), returns the input if nothing applies.
|
|
593
|
+
* The `-ing`/`-ed` rules were REMOVED: they over-truncated and produced wrong stems ("string"→"str",
|
|
594
|
+
* "logging"→"logg" — NOT "log"), surfacing unrelated words. Plural stemming is the only safe rule, and a
|
|
595
|
+
* ≥3-char guard keeps the stem a real word fragment (so "is"→"is", not "i").
|
|
596
|
+
*/
|
|
597
|
+
function lightStem(t) {
|
|
598
|
+
if (t.length > 4 && t.endsWith("ies"))
|
|
599
|
+
return `${t.slice(0, -3)}y`; // policies → policy
|
|
600
|
+
if (t.length > 3 && t.endsWith("es"))
|
|
601
|
+
return t.slice(0, -2); // boxes → box
|
|
602
|
+
if (t.length > 3 && t.endsWith("s") && !t.endsWith("ss"))
|
|
603
|
+
return t.slice(0, -1); // tokens → token
|
|
604
|
+
return t;
|
|
605
|
+
}
|
|
606
|
+
/** First sentence (or ~120-char head) of a note — the manifest description fallback for untyped notes. */
|
|
607
|
+
export function firstSentence(text) {
|
|
608
|
+
const t = text.trim().replace(/\s+/g, " ");
|
|
609
|
+
const dot = t.search(/[.!?](\s|$)/);
|
|
610
|
+
const cut = dot >= 0 && dot < 160 ? dot + 1 : Math.min(t.length, 120);
|
|
611
|
+
return t.slice(0, cut).trim();
|
|
612
|
+
}
|
|
613
|
+
/** Parse a "YYYY-MM-DD HH:MM" (UTC) timestamp to ms; 0 if unparseable (treated as oldest/least-fresh). */
|
|
614
|
+
function mtimeMsOf(ts) {
|
|
615
|
+
const ms = Date.parse(`${ts.replace(" ", "T")}:00Z`);
|
|
616
|
+
return Number.isFinite(ms) ? ms : 0;
|
|
617
|
+
}
|
|
618
|
+
/**
|
|
619
|
+
* Normalize the backward-compatible {@link import("./types.js").TaskSpec.memory} union into ONE canonical
|
|
620
|
+
* {@link NormalizedMemorySpec} (design/84 Seam A decision 1). The consumer side reads ONLY this result — no
|
|
621
|
+
* narrowing of the union anywhere downstream:
|
|
622
|
+
* - `scopes` wins over `scope` when both are present; otherwise `scope` → `[scope]`.
|
|
623
|
+
* - blank/whitespace scopes are dropped and duplicates collapsed (FIRST occurrence wins — keeps the
|
|
624
|
+
* caller's stable→volatile order); list order is the inject order (stable prefix first, volatile tail last).
|
|
625
|
+
* - `writeScope` defaults to the LAST scope (the highest-priority layer); an EXPLICIT `null` means read-only
|
|
626
|
+
* (no `remember` tool, no consolidation); an explicit non-null string is taken as-is (it need NOT be one
|
|
627
|
+
* of `scopes` — a deployment may write a layer it does not inject, though normally it is the last scope).
|
|
628
|
+
* ⚠️ Layered READ seeding (service [646]①, 142-S4): when `scopes` comes from a registry's defaultScopes
|
|
629
|
+
* (shared read layers), ALWAYS pin `writeScope` explicitly — the last-scope default would land every
|
|
630
|
+
* harvest in whichever shared layer happens to be listed last (a cross-tenant write surface).
|
|
631
|
+
* - returns `undefined` when there are no usable scopes (the caller treats it like "no memory configured").
|
|
632
|
+
*
|
|
633
|
+
* Backward compatibility: `{ scope: "user:42" }` → `{ scopes: ["user:42"], writeScope: "user:42", enabled: true }`,
|
|
634
|
+
* so every single-scope path is byte-identical to the pre-design/84 behavior.
|
|
635
|
+
*/
|
|
636
|
+
export function normalizeMemorySpec(input) {
|
|
637
|
+
if (!input)
|
|
638
|
+
return undefined;
|
|
639
|
+
const raw = input.scopes && input.scopes.length > 0 ? input.scopes : input.scope !== undefined ? [input.scope] : [];
|
|
640
|
+
const scopes = [];
|
|
641
|
+
const seen = new Set();
|
|
642
|
+
for (const s of raw) {
|
|
643
|
+
const t = typeof s === "string" ? s.trim() : "";
|
|
644
|
+
if (!t || seen.has(t))
|
|
645
|
+
continue;
|
|
646
|
+
seen.add(t);
|
|
647
|
+
scopes.push(t);
|
|
648
|
+
}
|
|
649
|
+
if (scopes.length === 0)
|
|
650
|
+
return undefined;
|
|
651
|
+
// writeScope: explicit `null` = read-only; explicit string = as-is; omitted = the last (highest-priority) scope.
|
|
652
|
+
let writeScope;
|
|
653
|
+
if (input.writeScope === null) {
|
|
654
|
+
writeScope = null;
|
|
655
|
+
}
|
|
656
|
+
else if (typeof input.writeScope === "string" && input.writeScope.trim()) {
|
|
657
|
+
writeScope = input.writeScope.trim();
|
|
658
|
+
}
|
|
659
|
+
else {
|
|
660
|
+
writeScope = scopes[scopes.length - 1];
|
|
661
|
+
}
|
|
662
|
+
// design/142 §1.2 — v2 opt-in: validate every key (writeScope included) against the contract syntax.
|
|
663
|
+
// parseScopeKey is fail-loud ONLY for keys carrying a reserved prefix; unprefixed keys parse as
|
|
664
|
+
// legacy and keep today's opaque behavior. Without the opt-in this block never runs (no sniffing).
|
|
665
|
+
if (input.scopeContract === "v2") {
|
|
666
|
+
for (const key of writeScope !== null ? [...scopes, writeScope] : scopes)
|
|
667
|
+
parseScopeKey(key);
|
|
668
|
+
return { scopes, writeScope, enabled: input.enabled !== false, scopeContract: "v2" };
|
|
669
|
+
}
|
|
670
|
+
return { scopes, writeScope, enabled: input.enabled !== false };
|
|
671
|
+
}
|
|
672
|
+
/** Max bytes of memory injected into the prompt; larger is truncated with a marker. (CodeWhale: 100 KiB)
|
|
673
|
+
* Exported so the inject-all de-dup seeding (prepare-task.ts) can detect truncation and NOT seed dropped
|
|
674
|
+
* (truncated-out) note ids as "already surfaced" — see the MINOR-1 audit fix there. */
|
|
675
|
+
export const MAX_MEMORY_BYTES = 100 * 1024;
|
|
676
|
+
/** The wrapper-tag family the memory injection fences neutralize (`<system-reminder>` is ALWAYS
|
|
677
|
+
* included by {@link sanitizeUntrustedText} itself). Single source (design/138 S2-C, C-F10/O-F11):
|
|
678
|
+
* the memory write-time scan (`memory-engine/scan.ts`) detects break-out markup by diffing
|
|
679
|
+
* `sanitizeUntrustedText(text, MEMORY_WRAPPER_TAGS)` against the raw text, so the scan rules and
|
|
680
|
+
* the ACTUAL injection boundary (this file's compose* fences) can never drift apart. */
|
|
681
|
+
export const MEMORY_WRAPPER_TAGS = ["user_memory"];
|
|
682
|
+
/**
|
|
683
|
+
* Wrap memory content in a `<user_memory>` block. This is the **variable tail** of the system prompt
|
|
684
|
+
* (per-user, scoped, timestamped) — the default prompt provider places it LAST so the stable base
|
|
685
|
+
* prompt before it stays a cacheable prefix (see `defaultPromptProvider`).
|
|
686
|
+
* Truncates over-cap content with a `<truncated bytes=N>` marker (mirrors CodeWhale `as_system_block`).
|
|
687
|
+
* Returns undefined for empty content.
|
|
688
|
+
*/
|
|
689
|
+
export function composeMemoryBlock(content, scope) {
|
|
690
|
+
const trimmed = (content ?? "").trim();
|
|
691
|
+
if (!trimmed) {
|
|
692
|
+
return undefined;
|
|
693
|
+
}
|
|
694
|
+
let payload = trimmed;
|
|
695
|
+
const bytes = Buffer.byteLength(trimmed, "utf8");
|
|
696
|
+
if (bytes > MAX_MEMORY_BYTES) {
|
|
697
|
+
// keep a head slice that fits, then mark the omission
|
|
698
|
+
const buf = Buffer.from(trimmed, "utf8");
|
|
699
|
+
let cut = MAX_MEMORY_BYTES;
|
|
700
|
+
// back up to a valid UTF-8 boundary
|
|
701
|
+
while (cut > 0 && (buf[cut] & 0xc0) === 0x80) {
|
|
702
|
+
cut--;
|
|
703
|
+
}
|
|
704
|
+
const head = buf.subarray(0, cut).toString("utf8");
|
|
705
|
+
payload = `${head}\n<truncated bytes=${bytes - cut}>`;
|
|
706
|
+
}
|
|
707
|
+
// A-7 (round-2 audit): memory content is persisted across sessions and injected into the SYSTEM prompt,
|
|
708
|
+
// so a note containing `</user_memory>` or `<system-reminder>` (remembered by a steered model, or added
|
|
709
|
+
// by a consolidation LLM swayed by candidate text) would escape its fence and forge system authority in
|
|
710
|
+
// every later same-scope session. Neutralize the wrapper + system-reminder tags before injecting.
|
|
711
|
+
return `<user_memory scope="${scope}">\n${sanitizeUntrustedText(payload, [...MEMORY_WRAPPER_TAGS])}\n</user_memory>`;
|
|
712
|
+
}
|
|
713
|
+
/**
|
|
714
|
+
* Compose the LAYERED inject-all memory block for multiple scopes (design/84 Seam A decision 2). One
|
|
715
|
+
* `<user_memory>` block with a `<scope name="…">` subsection per scope, **in the given list order** — the
|
|
716
|
+
* caller passes stable layers FIRST (cacheable prefix) and volatile layers LAST (re-computed tail), and the
|
|
717
|
+
* highest-priority layer is therefore at the END of the block (closest to the model's attention, matching the
|
|
718
|
+
* single-scope tail placement). Empty layers are omitted. Each layer's content is byte-capped + fence-sanitized
|
|
719
|
+
* exactly like {@link composeMemoryBlock} (the same A-7 escape class). Returns `undefined` when every layer is
|
|
720
|
+
* empty (no block to inject).
|
|
721
|
+
*
|
|
722
|
+
* **Cache-stability guarantee (§5):** the subsection order is EXACTLY the caller's list order — never sorted
|
|
723
|
+
* or reordered here — and the per-scope wrapper/format is fixed, so a stable layer at the front renders
|
|
724
|
+
* byte-identically across turns (the 90/98% prefix-cache hit measured in §5.1/§5.2 depends on this). The
|
|
725
|
+
* VOLATILE layers the caller places last are the only part that changes, so only the tail re-computes.
|
|
726
|
+
*/
|
|
727
|
+
export function composeLayeredMemoryBlock(layers) {
|
|
728
|
+
const sections = [];
|
|
729
|
+
for (const layer of layers) {
|
|
730
|
+
const trimmed = (layer.content ?? "").trim();
|
|
731
|
+
if (!trimmed)
|
|
732
|
+
continue; // omit an empty layer entirely (keeps the block tight + the prefix stable)
|
|
733
|
+
let payload = trimmed;
|
|
734
|
+
const bytes = Buffer.byteLength(trimmed, "utf8");
|
|
735
|
+
if (bytes > MAX_MEMORY_BYTES) {
|
|
736
|
+
const buf = Buffer.from(trimmed, "utf8");
|
|
737
|
+
let cut = MAX_MEMORY_BYTES;
|
|
738
|
+
while (cut > 0 && (buf[cut] & 0xc0) === 0x80)
|
|
739
|
+
cut--;
|
|
740
|
+
payload = `${buf.subarray(0, cut).toString("utf8")}\n<truncated bytes=${bytes - cut}>`;
|
|
741
|
+
}
|
|
742
|
+
// A-7: per-scope content is persisted, model-influenced — neutralize wrapper/system-reminder tags so a
|
|
743
|
+
// note in one layer can't escape its fence and forge system authority. The scope ATTRIBUTE is sanitized
|
|
744
|
+
// too (scopes are caller/profile-derived today, but defensive: a scope string never carries markup).
|
|
745
|
+
sections.push(`<scope name="${sanitizeUntrustedText(layer.scope, [...MEMORY_WRAPPER_TAGS])}">\n` +
|
|
746
|
+
`${sanitizeUntrustedText(payload, [...MEMORY_WRAPPER_TAGS])}\n` +
|
|
747
|
+
`</scope>`);
|
|
748
|
+
}
|
|
749
|
+
if (sections.length === 0)
|
|
750
|
+
return undefined;
|
|
751
|
+
return `<user_memory>\n${sections.join("\n")}\n</user_memory>`;
|
|
752
|
+
}
|
|
753
|
+
const REMEMBER_DESCRIPTION = "Append a durable note to long-term memory so it survives across sessions. Use this when you " +
|
|
754
|
+
"notice a stable preference, convention, or fact worth keeping (e.g. 'User prefers concise " +
|
|
755
|
+
"answers', 'The orders table is read-only'). Phrase it as a declarative fact, NOT an instruction " +
|
|
756
|
+
"to your future self, and NOT transient task state. Single, durable sentences only. Optionally tag " +
|
|
757
|
+
"it with a `type` (user | feedback | project | reference) so it can be recalled more precisely. " +
|
|
758
|
+
"For feedback/project notes, include WHY (the reason is what makes the note applicable later).";
|
|
759
|
+
/** Build a `recall` tool that searches long-term memory on demand (just-in-time L3 retrieval).
|
|
760
|
+
* @deprecated design/138 S4 — the Runner no longer mounts this (legacy memoryStore path retired;
|
|
761
|
+
* new model-facing `Recall` calls get the TOMBSTONED_TOOLS migration text). Kept exported one major
|
|
762
|
+
* for deployments that mount it as an explicit custom tool; removal is the next major. */
|
|
763
|
+
export function createRecallTool(store, scope) {
|
|
764
|
+
return defineTool({
|
|
765
|
+
name: "Recall", // design/119: PascalCase like the rest of the roster (sema-own tool; old name in OLD_TO_NEW)
|
|
766
|
+
aliases: ["recall"], // model-call compatibility (old transcripts/habits), same posture as the CC-deprecated names
|
|
767
|
+
description: "Search your long-term memory for durable facts/preferences relevant to a query. Use this " +
|
|
768
|
+
"to retrieve a specific remembered detail on demand (in addition to what is already in your " +
|
|
769
|
+
"system prompt). Returns matching notes, or nothing if none match. Pass \"*\" (or an empty " +
|
|
770
|
+
"query) to LIST the most recent memories instead of keyword-matching.",
|
|
771
|
+
effect: "read", // design/108: recall only searches memory (no mutation) — declare it so plan mode doesn't over-block it
|
|
772
|
+
parameters: Type.Object({
|
|
773
|
+
query: Type.String({ description: "Keywords to search remembered notes for, or \"*\" to list recent memories." }),
|
|
774
|
+
}),
|
|
775
|
+
execute: async (args) => {
|
|
776
|
+
const query = String(args.query ?? "").trim();
|
|
777
|
+
// A wildcard/empty query means "show me what you remember" — keyword-matching a literal "*"
|
|
778
|
+
// can never hit (the lexical matcher does substring/token matching), which made the tool
|
|
779
|
+
// falsely report an EMPTY memory to a model probing its own recall (design/119 review). List
|
|
780
|
+
// the most recent notes instead, bounded.
|
|
781
|
+
if (query === "" || query === "*" || query.toLowerCase() === "all") {
|
|
782
|
+
const full = await store.read(scope);
|
|
783
|
+
// Split on BULLET boundaries, not raw newlines — a multi-line note (remember doesn't collapse
|
|
784
|
+
// the body) must stay one entry, or the count inflates and the tail-slice can split a note
|
|
785
|
+
// (workflow review). Non-bulleted stores degrade to line-splitting.
|
|
786
|
+
const text = (full ?? "").trim();
|
|
787
|
+
const entries = text
|
|
788
|
+
? (/^- /m.test(text) ? text.split(/\n(?=- )/) : text.split("\n")).map((l) => l.trim()).filter(Boolean)
|
|
789
|
+
: [];
|
|
790
|
+
if (entries.length === 0) {
|
|
791
|
+
return { content: "No memories stored yet.", details: { type: "memory-recall", count: 0 } };
|
|
792
|
+
}
|
|
793
|
+
const recent = entries.slice(-20);
|
|
794
|
+
const header = entries.length > recent.length ? `[showing the ${recent.length} most recent of ${entries.length} memories]\n` : "";
|
|
795
|
+
return { content: header + sanitizeUntrustedText(recent.join("\n")), details: { type: "memory-recall", count: recent.length } };
|
|
796
|
+
}
|
|
797
|
+
if (!store.search) {
|
|
798
|
+
return { content: "No memory matches.", details: { type: "memory-recall", count: 0 } };
|
|
799
|
+
}
|
|
800
|
+
const matches = await store.search(scope, query);
|
|
801
|
+
// Same A-7 class as the system-prompt injection (composeMemoryBlock): recalled notes are
|
|
802
|
+
// persisted, model-influenced content — a note carrying `<system-reminder>` must not surface
|
|
803
|
+
// it raw in a tool result either (self-review 2026-06-11: the recall TOOL path was the one
|
|
804
|
+
// memory injection point without the fence).
|
|
805
|
+
return {
|
|
806
|
+
content: matches.length ? sanitizeUntrustedText(matches.join("\n")) : "No memory matches.",
|
|
807
|
+
// 18-tool toolUseResult 尾批: `type` = wire discriminant (sema 形状 — CC 2.1.201 has no Recall
|
|
808
|
+
// Output type; the shell renders a "Recalled N memory" dim line — COUNT ONLY on the wire
|
|
809
|
+
// (codex MED-1: raw persisted memory content must not ride structured un-fenced; the fenced
|
|
810
|
+
// text stays in model-facing content, the consumer redact contract untouched).
|
|
811
|
+
details: { type: "memory-recall", count: matches.length },
|
|
812
|
+
};
|
|
813
|
+
},
|
|
814
|
+
});
|
|
815
|
+
}
|
|
816
|
+
/**
|
|
817
|
+
* Build the `remember` tool bound to a store + scope. Auto-applies (writes are scoped to memory).
|
|
818
|
+
*
|
|
819
|
+
* `onRemembered` (optional) is called after each successful append with the new note's `text` and its
|
|
820
|
+
* store id (when the store returned one) — the Runner used it to collect this task's notes for
|
|
821
|
+
* end-of-task consolidation (design/41) without re-reading the store.
|
|
822
|
+
*
|
|
823
|
+
* @deprecated design/138 S4 — the Runner no longer mounts this (legacy memoryStore path retired; new
|
|
824
|
+
* model-facing `Remember` calls get the TOMBSTONED_TOOLS migration text). Kept exported one major for
|
|
825
|
+
* deployments that mount it as an explicit custom tool; removal is the next major.
|
|
826
|
+
*/
|
|
827
|
+
export function createRememberTool(store, scope, onRemembered) {
|
|
828
|
+
return defineTool({
|
|
829
|
+
name: "Remember", // design/119: PascalCase like the rest of the roster (sema-own tool; old name in OLD_TO_NEW)
|
|
830
|
+
aliases: ["remember"], // model-call compatibility, same posture as the CC-deprecated names
|
|
831
|
+
// design/108: write — remember persists to durable memory (a real side effect); make it explicit so plan mode
|
|
832
|
+
// correctly rejects it (was accidentally correct via the unknown→"write" default, now intentional).
|
|
833
|
+
effect: "write",
|
|
834
|
+
description: REMEMBER_DESCRIPTION,
|
|
835
|
+
parameters: Type.Object({
|
|
836
|
+
note: Type.String({ description: "A single durable, declarative fact or preference to remember." }),
|
|
837
|
+
type: Type.Optional(Type.String({ description: "Optional category: user | feedback | project | reference (default project)." })),
|
|
838
|
+
description: Type.Optional(Type.String({ description: "Optional one-line summary for the memory index (default: the note's first sentence)." })),
|
|
839
|
+
}),
|
|
840
|
+
execute: async (args) => {
|
|
841
|
+
const a = args;
|
|
842
|
+
const note = String(a.note ?? "").trim();
|
|
843
|
+
if (!note) {
|
|
844
|
+
return { content: "Nothing remembered (empty note).", details: { ok: false } };
|
|
845
|
+
}
|
|
846
|
+
// The model authors these directly → inlet hygiene, mirroring the consolidation ADD path: collapse
|
|
847
|
+
// whitespace (a newline would forge manifest lines) + cap (type 32 = the standard values' scale;
|
|
848
|
+
// description 300 = "one-line summary"). The manifest renderer enforces the same single-line
|
|
849
|
+
// guarantee as a backstop for stores written by other inlets.
|
|
850
|
+
const oneLine = (v, cap) => {
|
|
851
|
+
if (typeof v !== "string")
|
|
852
|
+
return undefined;
|
|
853
|
+
const t = v.replace(/\s+/g, " ").trim();
|
|
854
|
+
return t ? t.slice(0, cap) : undefined;
|
|
855
|
+
};
|
|
856
|
+
const type = oneLine(a.type, 32);
|
|
857
|
+
const description = oneLine(a.description, 300);
|
|
858
|
+
// design/65 §2.1: a structured-capable store always stores a typed note (defaulting type="project" +
|
|
859
|
+
// first-sentence description), so even an old caller passing only `note` gets a [type] tag for recall.
|
|
860
|
+
// A legacy store (no appendStructured) keeps the plain append path — full back-compat either way.
|
|
861
|
+
let id;
|
|
862
|
+
if (store.appendStructured) {
|
|
863
|
+
id = await store.appendStructured(scope, { body: note, type, description });
|
|
864
|
+
}
|
|
865
|
+
else {
|
|
866
|
+
id = await store.append(scope, note);
|
|
867
|
+
}
|
|
868
|
+
onRemembered?.({ id: typeof id === "string" ? id : undefined, text: note });
|
|
869
|
+
// design/119 + [378]: carry the note + tags under the discriminant `type:"memory-saved"` so the
|
|
870
|
+
// tool_end.structured allowlist passes it (CC automemory shows a "Saved memory" card). The memory
|
|
871
|
+
// CATEGORY (user/feedback/project/reference) rides as `memoryType` — `type` is the card discriminant.
|
|
872
|
+
// `id` = the store's entry id when the backend reports one (MemoryStore has no file-path concept;
|
|
873
|
+
// a basename-style writtenPaths needs a store-interface extension — deferred, non-blocking per [378]).
|
|
874
|
+
return {
|
|
875
|
+
content: `Remembered: ${note}`,
|
|
876
|
+
details: { type: "memory-saved", ok: true, note, memoryType: type, description, ...(typeof id === "string" ? { id } : {}) },
|
|
877
|
+
};
|
|
878
|
+
},
|
|
879
|
+
});
|
|
880
|
+
}
|
|
881
|
+
//# sourceMappingURL=memory.js.map
|