@namzu/sdk 30.1.0 → 31.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +576 -0
- package/README.md +43 -2
- package/dist/advisory/executor.d.ts +2 -1
- package/dist/advisory/executor.d.ts.map +1 -1
- package/dist/advisory/executor.js +4 -1
- package/dist/advisory/executor.js.map +1 -1
- package/dist/agents/ReactiveAgent.d.ts.map +1 -1
- package/dist/agents/ReactiveAgent.js +12 -0
- package/dist/agents/ReactiveAgent.js.map +1 -1
- package/dist/agents/RouterAgent.d.ts.map +1 -1
- package/dist/agents/RouterAgent.js +21 -3
- package/dist/agents/RouterAgent.js.map +1 -1
- package/dist/agents/SupervisorAgent.d.ts.map +1 -1
- package/dist/agents/SupervisorAgent.js +34 -11
- package/dist/agents/SupervisorAgent.js.map +1 -1
- package/dist/agents/runAgent.d.ts +12 -0
- package/dist/agents/runAgent.d.ts.map +1 -1
- package/dist/agents/runAgent.js +26 -2
- package/dist/agents/runAgent.js.map +1 -1
- package/dist/authorization/command-line.d.ts +81 -0
- package/dist/authorization/command-line.d.ts.map +1 -0
- package/dist/authorization/command-line.js +347 -0
- package/dist/authorization/command-line.js.map +1 -0
- package/dist/authorization/rules.d.ts.map +1 -1
- package/dist/authorization/rules.js +22 -1
- package/dist/authorization/rules.js.map +1 -1
- package/dist/bridge/a2a/client.d.ts +23 -5
- package/dist/bridge/a2a/client.d.ts.map +1 -1
- package/dist/bridge/a2a/client.js +320 -73
- package/dist/bridge/a2a/client.js.map +1 -1
- package/dist/bridge/a2a/mapper.d.ts.map +1 -1
- package/dist/bridge/a2a/mapper.js +4 -0
- package/dist/bridge/a2a/mapper.js.map +1 -1
- package/dist/bridge/acp/server.d.ts +13 -1
- package/dist/bridge/acp/server.d.ts.map +1 -1
- package/dist/bridge/acp/server.js +150 -44
- package/dist/bridge/acp/server.js.map +1 -1
- package/dist/bridge/mcp/connector/adapter.d.ts +3 -2
- package/dist/bridge/mcp/connector/adapter.d.ts.map +1 -1
- package/dist/bridge/mcp/connector/adapter.js +17 -21
- package/dist/bridge/mcp/connector/adapter.js.map +1 -1
- package/dist/bridge/sse/mapper.d.ts.map +1 -1
- package/dist/bridge/sse/mapper.js +3 -0
- package/dist/bridge/sse/mapper.js.map +1 -1
- package/dist/compaction/dangling.d.ts +29 -2
- package/dist/compaction/dangling.d.ts.map +1 -1
- package/dist/compaction/dangling.js +172 -35
- package/dist/compaction/dangling.js.map +1 -1
- package/dist/compaction/index.d.ts +3 -2
- package/dist/compaction/index.d.ts.map +1 -1
- package/dist/compaction/index.js +1 -1
- package/dist/compaction/index.js.map +1 -1
- package/dist/compaction/manual.d.ts +11 -1
- package/dist/compaction/manual.d.ts.map +1 -1
- package/dist/compaction/manual.js +89 -14
- package/dist/compaction/manual.js.map +1 -1
- package/dist/compaction/plan.d.ts +19 -6
- package/dist/compaction/plan.d.ts.map +1 -1
- package/dist/compaction/plan.js +18 -4
- package/dist/compaction/plan.js.map +1 -1
- package/dist/compaction/retention.d.ts +10 -7
- package/dist/compaction/retention.d.ts.map +1 -1
- package/dist/compaction/retention.js +26 -8
- package/dist/compaction/retention.js.map +1 -1
- package/dist/compaction/summary.d.ts +4 -4
- package/dist/compaction/summary.js +4 -4
- package/dist/compaction/verifier.d.ts +19 -1
- package/dist/compaction/verifier.d.ts.map +1 -1
- package/dist/compaction/verifier.js +20 -1
- package/dist/compaction/verifier.js.map +1 -1
- package/dist/config/runtime.d.ts +6 -6
- package/dist/connector/BaseConnector.d.ts +6 -4
- package/dist/connector/BaseConnector.d.ts.map +1 -1
- package/dist/connector/BaseConnector.js +8 -2
- package/dist/connector/BaseConnector.js.map +1 -1
- package/dist/connector/builtins/http.d.ts +16 -4
- package/dist/connector/builtins/http.d.ts.map +1 -1
- package/dist/connector/builtins/http.js +177 -44
- package/dist/connector/builtins/http.js.map +1 -1
- package/dist/connector/builtins/webhook.d.ts +15 -4
- package/dist/connector/builtins/webhook.d.ts.map +1 -1
- package/dist/connector/builtins/webhook.js +165 -45
- package/dist/connector/builtins/webhook.js.map +1 -1
- package/dist/connector/execution-contract.d.ts +11 -0
- package/dist/connector/execution-contract.d.ts.map +1 -0
- package/dist/connector/execution-contract.js +14 -0
- package/dist/connector/execution-contract.js.map +1 -0
- package/dist/connector/http-operation.d.ts +48 -0
- package/dist/connector/http-operation.d.ts.map +1 -0
- package/dist/connector/http-operation.js +205 -0
- package/dist/connector/http-operation.js.map +1 -0
- package/dist/connector/mcp/adapter.d.ts.map +1 -1
- package/dist/connector/mcp/adapter.js +8 -3
- package/dist/connector/mcp/adapter.js.map +1 -1
- package/dist/connector/mcp/client.d.ts +14 -8
- package/dist/connector/mcp/client.d.ts.map +1 -1
- package/dist/connector/mcp/client.js +160 -44
- package/dist/connector/mcp/client.js.map +1 -1
- package/dist/connector/mcp/http-sse.d.ts +8 -2
- package/dist/connector/mcp/http-sse.d.ts.map +1 -1
- package/dist/connector/mcp/http-sse.js +70 -17
- package/dist/connector/mcp/http-sse.js.map +1 -1
- package/dist/connector/mcp/prompt-adapter.d.ts.map +1 -1
- package/dist/connector/mcp/prompt-adapter.js +9 -2
- package/dist/connector/mcp/prompt-adapter.js.map +1 -1
- package/dist/connector/mcp/stdio.d.ts +2 -2
- package/dist/connector/mcp/stdio.d.ts.map +1 -1
- package/dist/connector/mcp/stdio.js +14 -50
- package/dist/connector/mcp/stdio.js.map +1 -1
- package/dist/connector/mcp/streamable-http.d.ts +7 -2
- package/dist/connector/mcp/streamable-http.d.ts.map +1 -1
- package/dist/connector/mcp/streamable-http.js +66 -18
- package/dist/connector/mcp/streamable-http.js.map +1 -1
- package/dist/connector/tools/adapter.d.ts +2 -2
- package/dist/connector/tools/adapter.d.ts.map +1 -1
- package/dist/connector/tools/adapter.js +23 -14
- package/dist/connector/tools/adapter.js.map +1 -1
- package/dist/connector/tools/definitions.d.ts.map +1 -1
- package/dist/connector/tools/definitions.js +5 -2
- package/dist/connector/tools/definitions.js.map +1 -1
- package/dist/connector/tools/result.d.ts +4 -0
- package/dist/connector/tools/result.d.ts.map +1 -0
- package/dist/connector/tools/result.js +20 -0
- package/dist/connector/tools/result.js.map +1 -0
- package/dist/connector/web/guarded-fetch.d.ts +4 -2
- package/dist/connector/web/guarded-fetch.d.ts.map +1 -1
- package/dist/connector/web/guarded-fetch.js +157 -43
- package/dist/connector/web/guarded-fetch.js.map +1 -1
- package/dist/constants/sandbox/index.d.ts +3 -2
- package/dist/constants/sandbox/index.d.ts.map +1 -1
- package/dist/constants/sandbox/index.js +3 -2
- package/dist/constants/sandbox/index.js.map +1 -1
- package/dist/contracts/api.d.ts +2 -0
- package/dist/contracts/api.d.ts.map +1 -1
- package/dist/contracts/schemas.d.ts +38 -12
- package/dist/contracts/schemas.d.ts.map +1 -1
- package/dist/contracts/schemas.js +7 -0
- package/dist/contracts/schemas.js.map +1 -1
- package/dist/directory/derive-supervisor.d.ts.map +1 -1
- package/dist/directory/derive-supervisor.js +8 -0
- package/dist/directory/derive-supervisor.js.map +1 -1
- package/dist/directory/derive.d.ts.map +1 -1
- package/dist/directory/derive.js +8 -0
- package/dist/directory/derive.js.map +1 -1
- package/dist/directory/load.d.ts.map +1 -1
- package/dist/directory/load.js +2 -0
- package/dist/directory/load.js.map +1 -1
- package/dist/directory/types.d.ts +4 -0
- package/dist/directory/types.d.ts.map +1 -1
- package/dist/eval/experiment.d.ts +10 -10
- package/dist/eval/experiment.d.ts.map +1 -1
- package/dist/eval/experiment.js +121 -91
- package/dist/eval/experiment.js.map +1 -1
- package/dist/eval/judge.d.ts +6 -0
- package/dist/eval/judge.d.ts.map +1 -1
- package/dist/eval/judge.js +7 -2
- package/dist/eval/judge.js.map +1 -1
- package/dist/eval/types.d.ts +7 -1
- package/dist/eval/types.d.ts.map +1 -1
- package/dist/manager/agent/lifecycle.d.ts +12 -10
- package/dist/manager/agent/lifecycle.d.ts.map +1 -1
- package/dist/manager/agent/lifecycle.js +16 -3
- package/dist/manager/agent/lifecycle.js.map +1 -1
- package/dist/manager/connector/environment.d.ts +2 -2
- package/dist/manager/connector/environment.d.ts.map +1 -1
- package/dist/manager/connector/environment.js +2 -2
- package/dist/manager/connector/environment.js.map +1 -1
- package/dist/manager/connector/lifecycle.d.ts +10 -2
- package/dist/manager/connector/lifecycle.d.ts.map +1 -1
- package/dist/manager/connector/lifecycle.js +273 -24
- package/dist/manager/connector/lifecycle.js.map +1 -1
- package/dist/manager/connector/tenant.d.ts +5 -4
- package/dist/manager/connector/tenant.d.ts.map +1 -1
- package/dist/manager/connector/tenant.js +47 -22
- package/dist/manager/connector/tenant.js.map +1 -1
- package/dist/manager/goal/activation.d.ts +23 -0
- package/dist/manager/goal/activation.d.ts.map +1 -0
- package/dist/manager/goal/activation.js +41 -0
- package/dist/manager/goal/activation.js.map +1 -0
- package/dist/manager/index.d.ts +3 -2
- package/dist/manager/index.d.ts.map +1 -1
- package/dist/manager/index.js.map +1 -1
- package/dist/manager/run/persistence.d.ts +2 -0
- package/dist/manager/run/persistence.d.ts.map +1 -1
- package/dist/manager/run/persistence.js +5 -1
- package/dist/manager/run/persistence.js.map +1 -1
- package/dist/manager/topic/dependency.d.ts +24 -0
- package/dist/manager/topic/dependency.d.ts.map +1 -0
- package/dist/manager/topic/dependency.js +13 -0
- package/dist/manager/topic/dependency.js.map +1 -0
- package/dist/manager/topic/lifecycle.d.ts +9 -21
- package/dist/manager/topic/lifecycle.d.ts.map +1 -1
- package/dist/manager/topic/lifecycle.js +17 -29
- package/dist/manager/topic/lifecycle.js.map +1 -1
- package/dist/plugin/index.d.ts +1 -0
- package/dist/plugin/index.d.ts.map +1 -1
- package/dist/plugin/index.js.map +1 -1
- package/dist/plugin/lifecycle.d.ts +15 -0
- package/dist/plugin/lifecycle.d.ts.map +1 -1
- package/dist/plugin/lifecycle.js +144 -38
- package/dist/plugin/lifecycle.js.map +1 -1
- package/dist/plugin/loader.d.ts +3 -3
- package/dist/plugin/loader.d.ts.map +1 -1
- package/dist/plugin/loader.js +58 -12
- package/dist/plugin/loader.js.map +1 -1
- package/dist/provider/collect-chat-completion.d.ts +7 -0
- package/dist/provider/collect-chat-completion.d.ts.map +1 -1
- package/dist/provider/collect-chat-completion.js +35 -0
- package/dist/provider/collect-chat-completion.js.map +1 -1
- package/dist/provider/fallback.d.ts +3 -1
- package/dist/provider/fallback.d.ts.map +1 -1
- package/dist/provider/fallback.js +62 -10
- package/dist/provider/fallback.js.map +1 -1
- package/dist/provider/idle-timeout.d.ts +4 -0
- package/dist/provider/idle-timeout.d.ts.map +1 -1
- package/dist/provider/idle-timeout.js +131 -15
- package/dist/provider/idle-timeout.js.map +1 -1
- package/dist/provider/index.d.ts +2 -0
- package/dist/provider/index.d.ts.map +1 -1
- package/dist/provider/index.js +1 -0
- package/dist/provider/index.js.map +1 -1
- package/dist/provider/instrumentation.d.ts.map +1 -1
- package/dist/provider/instrumentation.js +1 -0
- package/dist/provider/instrumentation.js.map +1 -1
- package/dist/provider/retry.d.ts.map +1 -1
- package/dist/provider/retry.js +13 -1
- package/dist/provider/retry.js.map +1 -1
- package/dist/public-runtime.d.ts +57 -24
- package/dist/public-runtime.d.ts.map +1 -1
- package/dist/public-runtime.js +42 -35
- package/dist/public-runtime.js.map +1 -1
- package/dist/public-tools.d.ts +1 -0
- package/dist/public-tools.d.ts.map +1 -1
- package/dist/public-tools.js +5 -0
- package/dist/public-tools.js.map +1 -1
- package/dist/public-types.d.ts +33 -12
- package/dist/public-types.d.ts.map +1 -1
- package/dist/rag/embedding.d.ts +8 -3
- package/dist/rag/embedding.d.ts.map +1 -1
- package/dist/rag/embedding.js +120 -9
- package/dist/rag/embedding.js.map +1 -1
- package/dist/rag/index.d.ts +1 -1
- package/dist/rag/index.d.ts.map +1 -1
- package/dist/rag/index.js +1 -1
- package/dist/rag/index.js.map +1 -1
- package/dist/rag/ingestion.d.ts +2 -2
- package/dist/rag/ingestion.d.ts.map +1 -1
- package/dist/rag/ingestion.js +15 -3
- package/dist/rag/ingestion.js.map +1 -1
- package/dist/rag/knowledge-base.d.ts +3 -3
- package/dist/rag/knowledge-base.d.ts.map +1 -1
- package/dist/rag/knowledge-base.js +8 -4
- package/dist/rag/knowledge-base.js.map +1 -1
- package/dist/rag/operation.d.ts +10 -0
- package/dist/rag/operation.d.ts.map +1 -0
- package/dist/rag/operation.js +26 -0
- package/dist/rag/operation.js.map +1 -0
- package/dist/rag/rag-tool.d.ts.map +1 -1
- package/dist/rag/rag-tool.js +6 -3
- package/dist/rag/rag-tool.js.map +1 -1
- package/dist/rag/retriever.d.ts +2 -2
- package/dist/rag/retriever.d.ts.map +1 -1
- package/dist/rag/retriever.js +31 -15
- package/dist/rag/retriever.js.map +1 -1
- package/dist/rag/vector-store.d.ts +3 -3
- package/dist/rag/vector-store.d.ts.map +1 -1
- package/dist/rag/vector-store.js +4 -2
- package/dist/rag/vector-store.js.map +1 -1
- package/dist/registry/command/kernel-commands.d.ts +16 -4
- package/dist/registry/command/kernel-commands.d.ts.map +1 -1
- package/dist/registry/command/kernel-commands.js +171 -0
- package/dist/registry/command/kernel-commands.js.map +1 -1
- package/dist/run/reporter.d.ts.map +1 -1
- package/dist/run/reporter.js +9 -0
- package/dist/run/reporter.js.map +1 -1
- package/dist/run-query/index.d.ts +15 -1
- package/dist/run-query/index.d.ts.map +1 -1
- package/dist/run-query/index.js +69 -15
- package/dist/run-query/index.js.map +1 -1
- package/dist/runtime/query/context.d.ts.map +1 -1
- package/dist/runtime/query/context.js +10 -3
- package/dist/runtime/query/context.js.map +1 -1
- package/dist/runtime/query/executor.d.ts +3 -0
- package/dist/runtime/query/executor.d.ts.map +1 -1
- package/dist/runtime/query/executor.js +80 -18
- package/dist/runtime/query/executor.js.map +1 -1
- package/dist/runtime/query/guard.d.ts +9 -0
- package/dist/runtime/query/guard.d.ts.map +1 -1
- package/dist/runtime/query/guard.js +11 -0
- package/dist/runtime/query/guard.js.map +1 -1
- package/dist/runtime/query/index.d.ts +30 -1
- package/dist/runtime/query/index.d.ts.map +1 -1
- package/dist/runtime/query/index.js +548 -95
- package/dist/runtime/query/index.js.map +1 -1
- package/dist/runtime/query/iteration/index.d.ts.map +1 -1
- package/dist/runtime/query/iteration/index.js +74 -14
- package/dist/runtime/query/iteration/index.js.map +1 -1
- package/dist/runtime/query/iteration/phases/compaction.d.ts.map +1 -1
- package/dist/runtime/query/iteration/phases/compaction.js +94 -53
- package/dist/runtime/query/iteration/phases/compaction.js.map +1 -1
- package/dist/runtime/query/iteration/phases/context.d.ts +3 -0
- package/dist/runtime/query/iteration/phases/context.d.ts.map +1 -1
- package/dist/runtime/query/iteration/phases/context.js.map +1 -1
- package/dist/runtime/query/iteration/phases/tool-review.d.ts.map +1 -1
- package/dist/runtime/query/iteration/phases/tool-review.js +21 -0
- package/dist/runtime/query/iteration/phases/tool-review.js.map +1 -1
- package/dist/runtime/query/iteration/stream-turn.d.ts.map +1 -1
- package/dist/runtime/query/iteration/stream-turn.js +4 -0
- package/dist/runtime/query/iteration/stream-turn.js.map +1 -1
- package/dist/runtime/query/project-instructions.d.ts +69 -0
- package/dist/runtime/query/project-instructions.d.ts.map +1 -0
- package/dist/runtime/query/project-instructions.js +137 -0
- package/dist/runtime/query/project-instructions.js.map +1 -0
- package/dist/runtime/query/request-rich-content.d.ts +22 -0
- package/dist/runtime/query/request-rich-content.d.ts.map +1 -0
- package/dist/runtime/query/request-rich-content.js +122 -0
- package/dist/runtime/query/request-rich-content.js.map +1 -0
- package/dist/runtime/query/result.d.ts.map +1 -1
- package/dist/runtime/query/result.js +12 -1
- package/dist/runtime/query/result.js.map +1 -1
- package/dist/runtime/query/resume-pending.d.ts.map +1 -1
- package/dist/runtime/query/resume-pending.js +19 -20
- package/dist/runtime/query/resume-pending.js.map +1 -1
- package/dist/runtime/query/resume-run.d.ts.map +1 -1
- package/dist/runtime/query/resume-run.js +54 -8
- package/dist/runtime/query/resume-run.js.map +1 -1
- package/dist/runtime/query/run-state.d.ts +5 -0
- package/dist/runtime/query/run-state.d.ts.map +1 -1
- package/dist/runtime/query/run-state.js +6 -1
- package/dist/runtime/query/run-state.js.map +1 -1
- package/dist/runtime/query/sandbox-lifecycle.d.ts +54 -0
- package/dist/runtime/query/sandbox-lifecycle.d.ts.map +1 -0
- package/dist/runtime/query/sandbox-lifecycle.js +167 -0
- package/dist/runtime/query/sandbox-lifecycle.js.map +1 -0
- package/dist/sandbox/isolation.d.ts.map +1 -1
- package/dist/sandbox/isolation.js +9 -0
- package/dist/sandbox/isolation.js.map +1 -1
- package/dist/sandbox/provider/local.d.ts +56 -6
- package/dist/sandbox/provider/local.d.ts.map +1 -1
- package/dist/sandbox/provider/local.js +181 -76
- package/dist/sandbox/provider/local.js.map +1 -1
- package/dist/sandbox/terminal.d.ts +13 -5
- package/dist/sandbox/terminal.d.ts.map +1 -1
- package/dist/sandbox/terminal.js +11 -3
- package/dist/sandbox/terminal.js.map +1 -1
- package/dist/session/errors.d.ts +28 -29
- package/dist/session/errors.d.ts.map +1 -1
- package/dist/session/errors.js +28 -29
- package/dist/session/errors.js.map +1 -1
- package/dist/session/handoff/broadcast.d.ts +5 -8
- package/dist/session/handoff/broadcast.d.ts.map +1 -1
- package/dist/session/handoff/broadcast.js +16 -6
- package/dist/session/handoff/broadcast.js.map +1 -1
- package/dist/session/handoff/single.d.ts +5 -8
- package/dist/session/handoff/single.d.ts.map +1 -1
- package/dist/session/handoff/single.js +7 -4
- package/dist/session/handoff/single.js.map +1 -1
- package/dist/store/attachment/index.d.ts +11 -3
- package/dist/store/attachment/index.d.ts.map +1 -1
- package/dist/store/attachment/index.js +49 -4
- package/dist/store/attachment/index.js.map +1 -1
- package/dist/store/feedback/conformance.d.ts.map +1 -1
- package/dist/store/feedback/conformance.js +32 -0
- package/dist/store/feedback/conformance.js.map +1 -1
- package/dist/store/feedback/disk.d.ts +8 -6
- package/dist/store/feedback/disk.d.ts.map +1 -1
- package/dist/store/feedback/disk.js +111 -76
- package/dist/store/feedback/disk.js.map +1 -1
- package/dist/store/goal/index.d.ts +111 -0
- package/dist/store/goal/index.d.ts.map +1 -0
- package/dist/store/goal/index.js +436 -0
- package/dist/store/goal/index.js.map +1 -0
- package/dist/store/index.d.ts +1 -1
- package/dist/store/index.d.ts.map +1 -1
- package/dist/store/index.js +1 -1
- package/dist/store/index.js.map +1 -1
- package/dist/store/kv/revision-record-store.d.ts +70 -0
- package/dist/store/kv/revision-record-store.d.ts.map +1 -0
- package/dist/store/kv/revision-record-store.js +290 -0
- package/dist/store/kv/revision-record-store.js.map +1 -0
- package/dist/store/memory/disk.d.ts +9 -7
- package/dist/store/memory/disk.d.ts.map +1 -1
- package/dist/store/memory/disk.js +256 -98
- package/dist/store/memory/disk.js.map +1 -1
- package/dist/store/run/disk.d.ts +10 -2
- package/dist/store/run/disk.d.ts.map +1 -1
- package/dist/store/run/disk.js +70 -4
- package/dist/store/run/disk.js.map +1 -1
- package/dist/store/run/memory.d.ts +4 -2
- package/dist/store/run/memory.d.ts.map +1 -1
- package/dist/store/run/memory.js +15 -1
- package/dist/store/run/memory.js.map +1 -1
- package/dist/store/session/disk.d.ts +9 -0
- package/dist/store/session/disk.d.ts.map +1 -1
- package/dist/store/session/disk.js +57 -5
- package/dist/store/session/disk.js.map +1 -1
- package/dist/store/session/memory.d.ts +1 -0
- package/dist/store/session/memory.d.ts.map +1 -1
- package/dist/store/session/memory.js +14 -0
- package/dist/store/session/memory.js.map +1 -1
- package/dist/store/topic/memory.d.ts +1 -2
- package/dist/store/topic/memory.d.ts.map +1 -1
- package/dist/store/topic/memory.js +4 -5
- package/dist/store/topic/memory.js.map +1 -1
- package/dist/store/topic/objective.d.ts +8 -4
- package/dist/store/topic/objective.d.ts.map +1 -1
- package/dist/store/topic/objective.js +185 -100
- package/dist/store/topic/objective.js.map +1 -1
- package/dist/store/topic/state.d.ts +1 -2
- package/dist/store/topic/state.d.ts.map +1 -1
- package/dist/store/topic/state.js +50 -62
- package/dist/store/topic/state.js.map +1 -1
- package/dist/tools/builtins/bash.d.ts.map +1 -1
- package/dist/tools/builtins/bash.js +20 -0
- package/dist/tools/builtins/bash.js.map +1 -1
- package/dist/tools/builtins/computer-use.d.ts +9 -1
- package/dist/tools/builtins/computer-use.d.ts.map +1 -1
- package/dist/tools/builtins/computer-use.js.map +1 -1
- package/dist/tools/builtins/content-fingerprint.d.ts +8 -7
- package/dist/tools/builtins/content-fingerprint.d.ts.map +1 -1
- package/dist/tools/builtins/content-fingerprint.js +9 -10
- package/dist/tools/builtins/content-fingerprint.js.map +1 -1
- package/dist/tools/builtins/edit.d.ts +6 -1
- package/dist/tools/builtins/edit.d.ts.map +1 -1
- package/dist/tools/builtins/edit.js +166 -27
- package/dist/tools/builtins/edit.js.map +1 -1
- package/dist/tools/builtins/write-file.d.ts.map +1 -1
- package/dist/tools/builtins/write-file.js +45 -19
- package/dist/tools/builtins/write-file.js.map +1 -1
- package/dist/tools/command-arguments.d.ts +43 -0
- package/dist/tools/command-arguments.d.ts.map +1 -0
- package/dist/tools/command-arguments.js +52 -0
- package/dist/tools/command-arguments.js.map +1 -0
- package/dist/tools/coordinator/index.d.ts +2 -0
- package/dist/tools/coordinator/index.d.ts.map +1 -1
- package/dist/tools/coordinator/index.js +3 -1
- package/dist/tools/coordinator/index.js.map +1 -1
- package/dist/tools/defineTool.d.ts +10 -0
- package/dist/tools/defineTool.d.ts.map +1 -1
- package/dist/tools/defineTool.js +1 -0
- package/dist/tools/defineTool.js.map +1 -1
- package/dist/tools/env-scrub.d.ts +7 -5
- package/dist/tools/env-scrub.d.ts.map +1 -1
- package/dist/tools/env-scrub.js +7 -5
- package/dist/tools/env-scrub.js.map +1 -1
- package/dist/tools/goal/index.d.ts +20 -0
- package/dist/tools/goal/index.d.ts.map +1 -0
- package/dist/tools/goal/index.js +104 -0
- package/dist/tools/goal/index.js.map +1 -0
- package/dist/tools/memory/index.d.ts +16 -0
- package/dist/tools/memory/index.d.ts.map +1 -1
- package/dist/tools/memory/index.js +6 -2
- package/dist/tools/memory/index.js.map +1 -1
- package/dist/tools/memory/search.d.ts +4 -1
- package/dist/tools/memory/search.d.ts.map +1 -1
- package/dist/tools/memory/search.js +10 -2
- package/dist/tools/memory/search.js.map +1 -1
- package/dist/types/agent/base.d.ts +11 -3
- package/dist/types/agent/base.d.ts.map +1 -1
- package/dist/types/agent/factory.d.ts +2 -0
- package/dist/types/agent/factory.d.ts.map +1 -1
- package/dist/types/agent/reactive.d.ts +2 -0
- package/dist/types/agent/reactive.d.ts.map +1 -1
- package/dist/types/agent/supervisor.d.ts +6 -0
- package/dist/types/agent/supervisor.d.ts.map +1 -1
- package/dist/types/agent/task.d.ts +6 -2
- package/dist/types/agent/task.d.ts.map +1 -1
- package/dist/types/connector/core.d.ts +13 -8
- package/dist/types/connector/core.d.ts.map +1 -1
- package/dist/types/connector/definition.d.ts +37 -18
- package/dist/types/connector/definition.d.ts.map +1 -1
- package/dist/types/connector/http.d.ts +6 -0
- package/dist/types/connector/http.d.ts.map +1 -1
- package/dist/types/connector/mcp.d.ts +24 -6
- package/dist/types/connector/mcp.d.ts.map +1 -1
- package/dist/types/connector/tenant.d.ts +17 -7
- package/dist/types/connector/tenant.d.ts.map +1 -1
- package/dist/types/connector/webhook.d.ts +6 -0
- package/dist/types/connector/webhook.d.ts.map +1 -1
- package/dist/types/goal/index.d.ts +46 -0
- package/dist/types/goal/index.d.ts.map +1 -0
- package/dist/types/goal/index.js +2 -0
- package/dist/types/goal/index.js.map +1 -0
- package/dist/types/ids/index.d.ts +2 -0
- package/dist/types/ids/index.d.ts.map +1 -1
- package/dist/types/ids/index.js.map +1 -1
- package/dist/types/message/index.d.ts +75 -10
- package/dist/types/message/index.d.ts.map +1 -1
- package/dist/types/message/index.js +49 -3
- package/dist/types/message/index.js.map +1 -1
- package/dist/types/plugin/index.d.ts +7 -5
- package/dist/types/plugin/index.d.ts.map +1 -1
- package/dist/types/plugin/index.js.map +1 -1
- package/dist/types/provider/chat.d.ts +27 -4
- package/dist/types/provider/chat.d.ts.map +1 -1
- package/dist/types/provider/interface.d.ts +18 -7
- package/dist/types/provider/interface.d.ts.map +1 -1
- package/dist/types/provider/stream.d.ts +6 -0
- package/dist/types/provider/stream.d.ts.map +1 -1
- package/dist/types/rag/embedding.d.ts +15 -2
- package/dist/types/rag/embedding.d.ts.map +1 -1
- package/dist/types/rag/ingestion.d.ts +2 -2
- package/dist/types/rag/ingestion.d.ts.map +1 -1
- package/dist/types/rag/knowledge-base.d.ts +3 -3
- package/dist/types/rag/knowledge-base.d.ts.map +1 -1
- package/dist/types/rag/retrieval.d.ts +2 -2
- package/dist/types/rag/retrieval.d.ts.map +1 -1
- package/dist/types/rag/scope.d.ts +4 -0
- package/dist/types/rag/scope.d.ts.map +1 -1
- package/dist/types/rag/vector.d.ts +5 -2
- package/dist/types/rag/vector.d.ts.map +1 -1
- package/dist/types/run/config.d.ts +20 -0
- package/dist/types/run/config.d.ts.map +1 -1
- package/dist/types/run/events.d.ts +25 -1
- package/dist/types/run/events.d.ts.map +1 -1
- package/dist/types/run/events.js.map +1 -1
- package/dist/types/run/metadata.d.ts +2 -0
- package/dist/types/run/metadata.d.ts.map +1 -1
- package/dist/types/run/step.d.ts +2 -6
- package/dist/types/run/step.d.ts.map +1 -1
- package/dist/types/run/step.js.map +1 -1
- package/dist/types/run/store.d.ts +55 -2
- package/dist/types/run/store.d.ts.map +1 -1
- package/dist/types/sandbox/index.d.ts +47 -6
- package/dist/types/sandbox/index.d.ts.map +1 -1
- package/dist/types/sandbox/index.js +23 -10
- package/dist/types/sandbox/index.js.map +1 -1
- package/dist/types/session/store.d.ts +13 -0
- package/dist/types/session/store.d.ts.map +1 -1
- package/dist/types/tool/index.d.ts +33 -11
- package/dist/types/tool/index.d.ts.map +1 -1
- package/dist/types/tool/index.js.map +1 -1
- package/dist/types/topic/entity.d.ts +3 -4
- package/dist/types/topic/entity.d.ts.map +1 -1
- package/dist/types/topic/store.d.ts +3 -3
- package/dist/utils/id.d.ts +3 -1
- package/dist/utils/id.d.ts.map +1 -1
- package/dist/utils/id.js +4 -0
- package/dist/utils/id.js.map +1 -1
- package/dist/utils/process-environment.d.ts +26 -0
- package/dist/utils/process-environment.d.ts.map +1 -0
- package/dist/utils/process-environment.js +78 -0
- package/dist/utils/process-environment.js.map +1 -0
- package/dist/vault/InMemoryCredentialVault.d.ts +2 -0
- package/dist/vault/InMemoryCredentialVault.d.ts.map +1 -1
- package/dist/vault/InMemoryCredentialVault.js +24 -4
- package/dist/vault/InMemoryCredentialVault.js.map +1 -1
- package/dist/vault/instrumentation.d.ts.map +1 -1
- package/dist/vault/instrumentation.js +15 -0
- package/dist/vault/instrumentation.js.map +1 -1
- package/package.json +1 -1
- package/src/advisory/executor.ts +4 -1
- package/src/agents/ReactiveAgent.ts +12 -0
- package/src/agents/RouterAgent.ts +25 -3
- package/src/agents/SupervisorAgent.ts +33 -11
- package/src/agents/runAgent.ts +38 -2
- package/src/authorization/command-line.ts +390 -0
- package/src/authorization/rules.ts +22 -1
- package/src/bridge/a2a/client.ts +384 -97
- package/src/bridge/a2a/mapper.ts +5 -0
- package/src/bridge/acp/server.ts +184 -42
- package/src/bridge/mcp/connector/adapter.ts +28 -20
- package/src/bridge/sse/mapper.ts +3 -0
- package/src/compaction/dangling.ts +203 -38
- package/src/compaction/index.ts +9 -2
- package/src/compaction/manual.ts +125 -18
- package/src/compaction/plan.ts +42 -11
- package/src/compaction/retention.ts +23 -8
- package/src/compaction/summary.ts +4 -4
- package/src/compaction/verifier.ts +66 -0
- package/src/connector/BaseConnector.ts +19 -4
- package/src/connector/builtins/http.ts +236 -46
- package/src/connector/builtins/webhook.ts +207 -47
- package/src/connector/execution-contract.ts +27 -0
- package/src/connector/http-operation.ts +238 -0
- package/src/connector/mcp/adapter.ts +8 -3
- package/src/connector/mcp/client.ts +207 -58
- package/src/connector/mcp/http-sse.ts +91 -23
- package/src/connector/mcp/prompt-adapter.ts +8 -2
- package/src/connector/mcp/stdio.ts +21 -46
- package/src/connector/mcp/streamable-http.ts +86 -22
- package/src/connector/tools/adapter.ts +23 -14
- package/src/connector/tools/definitions.ts +5 -2
- package/src/connector/tools/result.ts +21 -0
- package/src/connector/web/guarded-fetch.ts +188 -48
- package/src/constants/sandbox/index.ts +3 -2
- package/src/contracts/api.ts +2 -0
- package/src/contracts/schemas.ts +7 -0
- package/src/directory/derive-supervisor.ts +8 -0
- package/src/directory/derive.ts +8 -0
- package/src/directory/load.ts +2 -0
- package/src/directory/types.ts +4 -0
- package/src/eval/experiment.ts +160 -111
- package/src/eval/judge.ts +13 -2
- package/src/eval/types.ts +7 -1
- package/src/manager/agent/lifecycle.ts +28 -12
- package/src/manager/connector/environment.ts +3 -1
- package/src/manager/connector/lifecycle.ts +364 -24
- package/src/manager/connector/tenant.ts +56 -23
- package/src/manager/goal/activation.ts +52 -0
- package/src/manager/index.ts +10 -2
- package/src/manager/run/persistence.ts +6 -1
- package/src/manager/topic/dependency.ts +39 -0
- package/src/manager/topic/lifecycle.ts +19 -31
- package/src/plugin/index.ts +1 -0
- package/src/plugin/lifecycle.ts +180 -39
- package/src/plugin/loader.ts +70 -13
- package/src/pricing/rates.source.json +315 -204
- package/src/provider/collect-chat-completion.ts +36 -0
- package/src/provider/fallback.ts +79 -11
- package/src/provider/idle-timeout.ts +143 -17
- package/src/provider/index.ts +2 -0
- package/src/provider/instrumentation.ts +1 -0
- package/src/provider/retry.ts +16 -1
- package/src/public-runtime.ts +190 -32
- package/src/public-tools.ts +5 -0
- package/src/public-types.ts +85 -11
- package/src/rag/embedding.ts +147 -19
- package/src/rag/index.ts +1 -1
- package/src/rag/ingestion.ts +16 -2
- package/src/rag/knowledge-base.ts +13 -4
- package/src/rag/operation.ts +28 -0
- package/src/rag/rag-tool.ts +6 -3
- package/src/rag/retriever.ts +62 -11
- package/src/rag/vector-store.ts +8 -2
- package/src/registry/command/kernel-commands.ts +223 -4
- package/src/run/reporter.ts +10 -0
- package/src/run-query/index.ts +84 -15
- package/src/runtime/query/context.ts +13 -3
- package/src/runtime/query/executor.ts +90 -17
- package/src/runtime/query/guard.ts +12 -0
- package/src/runtime/query/index.ts +652 -103
- package/src/runtime/query/iteration/index.ts +89 -13
- package/src/runtime/query/iteration/phases/compaction.ts +120 -55
- package/src/runtime/query/iteration/phases/context.ts +4 -0
- package/src/runtime/query/iteration/phases/tool-review.ts +28 -0
- package/src/runtime/query/iteration/stream-turn.ts +3 -0
- package/src/runtime/query/project-instructions.ts +212 -0
- package/src/runtime/query/request-rich-content.ts +153 -0
- package/src/runtime/query/result.ts +12 -1
- package/src/runtime/query/resume-pending.ts +20 -18
- package/src/runtime/query/resume-run.ts +52 -8
- package/src/runtime/query/run-state.ts +11 -1
- package/src/runtime/query/sandbox-lifecycle.ts +210 -0
- package/src/sandbox/isolation.ts +9 -0
- package/src/sandbox/provider/local.ts +255 -90
- package/src/sandbox/terminal.ts +13 -5
- package/src/session/errors.ts +68 -42
- package/src/session/handoff/broadcast.ts +20 -14
- package/src/session/handoff/single.ts +14 -13
- package/src/store/attachment/index.ts +65 -3
- package/src/store/feedback/conformance.ts +39 -0
- package/src/store/feedback/disk.ts +128 -82
- package/src/store/goal/index.ts +594 -0
- package/src/store/index.ts +1 -1
- package/src/store/kv/revision-record-store.ts +346 -0
- package/src/store/memory/disk.ts +288 -113
- package/src/store/run/disk.ts +96 -5
- package/src/store/run/memory.ts +22 -2
- package/src/store/session/disk.ts +93 -6
- package/src/store/session/memory.ts +22 -0
- package/src/store/topic/memory.ts +4 -5
- package/src/store/topic/objective.ts +215 -100
- package/src/store/topic/state.ts +100 -63
- package/src/tools/builtins/bash.ts +21 -0
- package/src/tools/builtins/computer-use.ts +9 -1
- package/src/tools/builtins/content-fingerprint.ts +9 -12
- package/src/tools/builtins/edit.ts +190 -27
- package/src/tools/builtins/write-file.ts +55 -19
- package/src/tools/command-arguments.ts +54 -0
- package/src/tools/coordinator/index.ts +4 -1
- package/src/tools/defineTool.ts +11 -0
- package/src/tools/env-scrub.ts +7 -5
- package/src/tools/goal/index.ts +129 -0
- package/src/tools/memory/index.ts +26 -3
- package/src/tools/memory/search.ts +20 -3
- package/src/types/agent/base.ts +12 -3
- package/src/types/agent/factory.ts +2 -0
- package/src/types/agent/reactive.ts +2 -0
- package/src/types/agent/supervisor.ts +6 -0
- package/src/types/agent/task.ts +6 -2
- package/src/types/connector/core.ts +13 -8
- package/src/types/connector/definition.ts +54 -20
- package/src/types/connector/http.ts +7 -0
- package/src/types/connector/mcp.ts +27 -6
- package/src/types/connector/tenant.ts +21 -7
- package/src/types/connector/webhook.ts +7 -0
- package/src/types/goal/index.ts +50 -0
- package/src/types/ids/index.ts +2 -0
- package/src/types/message/index.ts +143 -9
- package/src/types/plugin/index.ts +7 -5
- package/src/types/provider/chat.ts +35 -4
- package/src/types/provider/interface.ts +22 -7
- package/src/types/provider/stream.ts +6 -0
- package/src/types/rag/embedding.ts +16 -2
- package/src/types/rag/ingestion.ts +2 -1
- package/src/types/rag/knowledge-base.ts +7 -3
- package/src/types/rag/retrieval.ts +2 -1
- package/src/types/rag/scope.ts +5 -0
- package/src/types/rag/vector.ts +5 -2
- package/src/types/run/config.ts +20 -0
- package/src/types/run/events.ts +28 -3
- package/src/types/run/metadata.ts +2 -0
- package/src/types/run/step.ts +2 -7
- package/src/types/run/store.ts +60 -2
- package/src/types/sandbox/index.ts +57 -14
- package/src/types/session/store.ts +18 -0
- package/src/types/tool/index.ts +33 -11
- package/src/types/topic/entity.ts +3 -4
- package/src/types/topic/store.ts +3 -3
- package/src/utils/id.ts +6 -0
- package/src/utils/process-environment.ts +101 -0
- package/src/vault/InMemoryCredentialVault.ts +29 -4
- package/src/vault/instrumentation.ts +24 -0
package/src/store/topic/state.ts
CHANGED
|
@@ -1,11 +1,17 @@
|
|
|
1
|
-
import { mkdir } from 'node:fs/promises'
|
|
2
1
|
import { join } from 'node:path'
|
|
3
2
|
|
|
3
|
+
import { TenantIsolationError } from '../../session/errors.js'
|
|
4
4
|
import type { TenantId, TopicId } from '../../types/ids/index.js'
|
|
5
5
|
import type { Message } from '../../types/message/index.js'
|
|
6
6
|
import type { PermissionMode } from '../../types/permission/index.js'
|
|
7
7
|
import { StaleTopicStateError, type TopicState } from '../../types/topic/state.js'
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
DiskRevisionRecordStore,
|
|
10
|
+
type RevisionMutation,
|
|
11
|
+
type RevisionedRecordLocation,
|
|
12
|
+
legacyRevisionFileSegment,
|
|
13
|
+
revisionFileSegment,
|
|
14
|
+
} from '../kv/revision-record-store.js'
|
|
9
15
|
import { defineSchema } from '../schema.js'
|
|
10
16
|
|
|
11
17
|
/**
|
|
@@ -25,8 +31,16 @@ import { defineSchema } from '../schema.js'
|
|
|
25
31
|
* record is designed to be folded into one if that arrives.
|
|
26
32
|
*/
|
|
27
33
|
|
|
28
|
-
const SCHEMA = defineSchema({
|
|
29
|
-
|
|
34
|
+
const SCHEMA = defineSchema({
|
|
35
|
+
kind: 'topic-state',
|
|
36
|
+
current: 1,
|
|
37
|
+
migrations: {},
|
|
38
|
+
})
|
|
39
|
+
const revisionRecords = new DiskRevisionRecordStore<TopicState>(
|
|
40
|
+
SCHEMA,
|
|
41
|
+
'topic state store',
|
|
42
|
+
(record) => record.revision,
|
|
43
|
+
)
|
|
30
44
|
|
|
31
45
|
export interface TopicStateStore {
|
|
32
46
|
/** `null` when this topic has never had state written. */
|
|
@@ -66,7 +80,10 @@ function next(
|
|
|
66
80
|
topicId: TopicId,
|
|
67
81
|
tenantId: TenantId,
|
|
68
82
|
previous: TopicState | null,
|
|
69
|
-
patch: {
|
|
83
|
+
patch: {
|
|
84
|
+
permissionMode?: PermissionMode
|
|
85
|
+
queuedMessages?: readonly Message[]
|
|
86
|
+
},
|
|
70
87
|
now: number,
|
|
71
88
|
): TopicState {
|
|
72
89
|
return {
|
|
@@ -83,6 +100,42 @@ function next(
|
|
|
83
100
|
}
|
|
84
101
|
}
|
|
85
102
|
|
|
103
|
+
function assertTenant(record: TopicState, tenantId: TenantId): void {
|
|
104
|
+
if (record.tenantId !== tenantId) {
|
|
105
|
+
throw new TenantIsolationError({
|
|
106
|
+
requested: tenantId,
|
|
107
|
+
resource: `topic-state(${record.topicId})`,
|
|
108
|
+
})
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function assertFresh(topicId: TopicId, actual: number, expected: number): void {
|
|
113
|
+
if (expected !== actual) {
|
|
114
|
+
throw new StaleTopicStateError({
|
|
115
|
+
topicId,
|
|
116
|
+
expectedRevision: expected,
|
|
117
|
+
actualRevision: actual,
|
|
118
|
+
})
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function proposeState(
|
|
123
|
+
topicId: TopicId,
|
|
124
|
+
tenantId: TenantId,
|
|
125
|
+
patch: {
|
|
126
|
+
permissionMode?: PermissionMode
|
|
127
|
+
queuedMessages?: readonly Message[]
|
|
128
|
+
},
|
|
129
|
+
revision: number,
|
|
130
|
+
now: () => number,
|
|
131
|
+
existing: TopicState | null,
|
|
132
|
+
): RevisionMutation<TopicState, TopicState> {
|
|
133
|
+
if (existing) assertTenant(existing, tenantId)
|
|
134
|
+
assertFresh(topicId, existing?.revision ?? 0, revision)
|
|
135
|
+
const record = next(topicId, tenantId, existing, patch, now())
|
|
136
|
+
return { record, result: record }
|
|
137
|
+
}
|
|
138
|
+
|
|
86
139
|
export class InMemoryTopicStateStore implements TopicStateStore {
|
|
87
140
|
private readonly states = new Map<TopicId, TopicState>()
|
|
88
141
|
|
|
@@ -90,9 +143,6 @@ export class InMemoryTopicStateStore implements TopicStateStore {
|
|
|
90
143
|
|
|
91
144
|
async getState(topicId: TopicId, tenantId: TenantId): Promise<TopicState | null> {
|
|
92
145
|
const found = this.states.get(topicId)
|
|
93
|
-
// A record from another tenant reads as absent rather than as an
|
|
94
|
-
// error, for the reason the project listing gives: refusing would
|
|
95
|
-
// confirm that somebody else's topic is there.
|
|
96
146
|
return found && found.tenantId === tenantId ? found : null
|
|
97
147
|
}
|
|
98
148
|
|
|
@@ -102,18 +152,18 @@ export class InMemoryTopicStateStore implements TopicStateStore {
|
|
|
102
152
|
mode: PermissionMode,
|
|
103
153
|
opts: { revision: number },
|
|
104
154
|
): Promise<TopicState> {
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
this.states.set(topicId, record)
|
|
116
|
-
return
|
|
155
|
+
// Deliberately no await: read, domain checks and publish are one JS turn.
|
|
156
|
+
// Awaiting an async get here lets two callers capture the same revision.
|
|
157
|
+
const proposal = proposeState(
|
|
158
|
+
topicId,
|
|
159
|
+
tenantId,
|
|
160
|
+
{ permissionMode: mode },
|
|
161
|
+
opts.revision,
|
|
162
|
+
this.now,
|
|
163
|
+
this.states.get(topicId) ?? null,
|
|
164
|
+
)
|
|
165
|
+
this.states.set(topicId, proposal.record)
|
|
166
|
+
return proposal.result
|
|
117
167
|
}
|
|
118
168
|
|
|
119
169
|
async setQueuedMessages(
|
|
@@ -122,18 +172,16 @@ export class InMemoryTopicStateStore implements TopicStateStore {
|
|
|
122
172
|
messages: readonly Message[],
|
|
123
173
|
opts: { revision: number },
|
|
124
174
|
): Promise<TopicState> {
|
|
125
|
-
const
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
this.states.set(topicId, record)
|
|
136
|
-
return record
|
|
175
|
+
const proposal = proposeState(
|
|
176
|
+
topicId,
|
|
177
|
+
tenantId,
|
|
178
|
+
{ queuedMessages: messages },
|
|
179
|
+
opts.revision,
|
|
180
|
+
this.now,
|
|
181
|
+
this.states.get(topicId) ?? null,
|
|
182
|
+
)
|
|
183
|
+
this.states.set(topicId, proposal.record)
|
|
184
|
+
return proposal.result
|
|
137
185
|
}
|
|
138
186
|
}
|
|
139
187
|
|
|
@@ -148,12 +196,17 @@ export class DiskTopicStateStore implements TopicStateStore {
|
|
|
148
196
|
private readonly now: () => number = Date.now,
|
|
149
197
|
) {}
|
|
150
198
|
|
|
151
|
-
private
|
|
152
|
-
|
|
199
|
+
private location(topicId: TopicId): RevisionedRecordLocation {
|
|
200
|
+
const root = join(this.config.rootDir, 'topic-state')
|
|
201
|
+
const segment = revisionFileSegment(topicId)
|
|
202
|
+
return {
|
|
203
|
+
legacyPath: join(root, `${legacyRevisionFileSegment(topicId)}.json`),
|
|
204
|
+
revisionsDir: join(root, '.revisions', segment),
|
|
205
|
+
}
|
|
153
206
|
}
|
|
154
207
|
|
|
155
208
|
async getState(topicId: TopicId, tenantId: TenantId): Promise<TopicState | null> {
|
|
156
|
-
const found = await
|
|
209
|
+
const found = await revisionRecords.read(this.location(topicId))
|
|
157
210
|
return found && found.tenantId === tenantId ? found : null
|
|
158
211
|
}
|
|
159
212
|
|
|
@@ -163,18 +216,9 @@ export class DiskTopicStateStore implements TopicStateStore {
|
|
|
163
216
|
mode: PermissionMode,
|
|
164
217
|
opts: { revision: number },
|
|
165
218
|
): Promise<TopicState> {
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
throw new StaleTopicStateError({
|
|
170
|
-
topicId,
|
|
171
|
-
expectedRevision: opts.revision,
|
|
172
|
-
actualRevision: actual,
|
|
173
|
-
})
|
|
174
|
-
}
|
|
175
|
-
const record = next(topicId, tenantId, existing, { permissionMode: mode }, this.now())
|
|
176
|
-
await this.persist(record)
|
|
177
|
-
return record
|
|
219
|
+
return await revisionRecords.transact(this.location(topicId), (existing) =>
|
|
220
|
+
proposeState(topicId, tenantId, { permissionMode: mode }, opts.revision, this.now, existing),
|
|
221
|
+
)
|
|
178
222
|
}
|
|
179
223
|
|
|
180
224
|
async setQueuedMessages(
|
|
@@ -183,22 +227,15 @@ export class DiskTopicStateStore implements TopicStateStore {
|
|
|
183
227
|
messages: readonly Message[],
|
|
184
228
|
opts: { revision: number },
|
|
185
229
|
): Promise<TopicState> {
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
if (opts.revision !== actual) {
|
|
189
|
-
throw new StaleTopicStateError({
|
|
230
|
+
return await revisionRecords.transact(this.location(topicId), (existing) =>
|
|
231
|
+
proposeState(
|
|
190
232
|
topicId,
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
private async persist(record: TopicState): Promise<void> {
|
|
201
|
-
await mkdir(join(this.config.rootDir, 'topic-state'), { recursive: true })
|
|
202
|
-
await records.write(this.path(record.topicId), record)
|
|
233
|
+
tenantId,
|
|
234
|
+
{ queuedMessages: messages },
|
|
235
|
+
opts.revision,
|
|
236
|
+
this.now,
|
|
237
|
+
existing,
|
|
238
|
+
),
|
|
239
|
+
)
|
|
203
240
|
}
|
|
204
241
|
}
|
|
@@ -98,6 +98,10 @@ export const BashTool = defineTool({
|
|
|
98
98
|
'Executes a bash command and returns stdout/stderr output. Command timeout is configurable. The `command` parameter is required — never call this tool with empty arguments. For very long content (e.g. building a large file), prefer `write` for the opening and `edit` with insertLine: "end" for follow-up chunks over a heredoc to avoid hitting the output token limit mid-stream.',
|
|
99
99
|
inputSchema,
|
|
100
100
|
category: 'shell',
|
|
101
|
+
// This tool's own description tells the model to chain with `&&` and `;`,
|
|
102
|
+
// so a permission rule about it is a rule about several commands more often
|
|
103
|
+
// than not. Naming the argument is what lets the gate read it that way.
|
|
104
|
+
commandArgument: 'command',
|
|
101
105
|
permissions: ['shell_execute'],
|
|
102
106
|
readOnly: false,
|
|
103
107
|
destructive: (input: BashInput) => isDangerousCommand(input.command),
|
|
@@ -119,6 +123,23 @@ export const BashTool = defineTool({
|
|
|
119
123
|
}
|
|
120
124
|
|
|
121
125
|
if (input.run_in_background) {
|
|
126
|
+
// The current registry owns a host process. Foreground execution,
|
|
127
|
+
// however, goes through `context.sandbox.exec()` below. Treating the
|
|
128
|
+
// same command as host work just because `run_in_background` changed
|
|
129
|
+
// would make that boolean an escape hatch from the configured boundary.
|
|
130
|
+
//
|
|
131
|
+
// Query-built contexts structurally withhold the registry in this
|
|
132
|
+
// composition. This explicit check also protects direct tool callers
|
|
133
|
+
// and says why the capability is absent instead of misdiagnosing the
|
|
134
|
+
// host as having configured no registry.
|
|
135
|
+
if (context.sandbox) {
|
|
136
|
+
return {
|
|
137
|
+
success: false,
|
|
138
|
+
output: '',
|
|
139
|
+
error:
|
|
140
|
+
'run_in_background is unavailable while a sandbox is active because the host background-job registry cannot preserve that sandbox boundary. Run the command in the foreground, or use a sandbox-aware persistent-process capability.',
|
|
141
|
+
}
|
|
142
|
+
}
|
|
122
143
|
// Refused, not degraded to `cmd &`. The fallback is not a lesser
|
|
123
144
|
// version of this: under the local sandbox's `linux-namespace` tier
|
|
124
145
|
// the wrapping `sh` is PID 1 of a fresh PID namespace, so the
|
|
@@ -42,7 +42,15 @@ const actionSchema = z.discriminatedUnion('type', [
|
|
|
42
42
|
z.object({ type: z.literal('key'), keys: z.string() }),
|
|
43
43
|
])
|
|
44
44
|
|
|
45
|
-
|
|
45
|
+
/**
|
|
46
|
+
* The tool's input, inferred from its schema.
|
|
47
|
+
*
|
|
48
|
+
* Exported because `createComputerUseTool` returns a `ToolDefinition<ActionInput>`
|
|
49
|
+
* and a consumer typing that variable, or writing a wrapper around it, had no
|
|
50
|
+
* name for the parameter — the type was module-private while the function
|
|
51
|
+
* carrying it was public.
|
|
52
|
+
*/
|
|
53
|
+
export type ActionInput = z.infer<typeof actionSchema>
|
|
46
54
|
|
|
47
55
|
const DESTRUCTIVE_ACTION_TYPES = new Set<ComputerUseAction['type']>([
|
|
48
56
|
'mouse_click',
|
|
@@ -3,11 +3,12 @@ import { createHash } from 'node:crypto'
|
|
|
3
3
|
/**
|
|
4
4
|
* A short, stable fingerprint of a file body.
|
|
5
5
|
*
|
|
6
|
-
* Used to answer one question at mutation
|
|
7
|
-
* agent read? An `edit` is
|
|
8
|
-
*
|
|
9
|
-
* editor, another process, a second agent run. The in-process mutation
|
|
10
|
-
* serializes this runtime's own writers and is blind to every one of
|
|
6
|
+
* Used to answer one question at mutation admission: is the file still what
|
|
7
|
+
* the agent read? An `edit` or full replacement is based on a remembered
|
|
8
|
+
* body, and before the write begins that body can move — a person editing in
|
|
9
|
+
* an editor, another process, a second agent run. The in-process mutation
|
|
10
|
+
* lock serializes this runtime's own writers and is blind to every one of
|
|
11
|
+
* those.
|
|
11
12
|
*
|
|
12
13
|
* Without this the drift is not merely undetected, it is actively
|
|
13
14
|
* misreported: an `old_string` that no longer matches comes back as "not
|
|
@@ -23,11 +24,7 @@ export function fingerprintContent(content: string): string {
|
|
|
23
24
|
return createHash('sha256').update(content, 'utf-8').digest('hex').slice(0, 16)
|
|
24
25
|
}
|
|
25
26
|
|
|
26
|
-
/** What a mutation tool tells the agent when
|
|
27
|
-
export function staleFileError(path: string): string {
|
|
28
|
-
return
|
|
29
|
-
`${path} changed on disk after you read it, so this edit was computed against a stale copy ` +
|
|
30
|
-
'and was not applied. Read the file again and redo the edit against its current contents. ' +
|
|
31
|
-
'Nothing was written.'
|
|
32
|
-
)
|
|
27
|
+
/** What a mutation tool tells the agent when admission sees a moved file. */
|
|
28
|
+
export function staleFileError(path: string, operation: 'edit' | 'write' = 'edit'): string {
|
|
29
|
+
return `${path} changed on disk after you read it, so this ${operation} was based on a stale copy and was not applied. Read the file again and redo the ${operation} against its current contents. Nothing was written.`
|
|
33
30
|
}
|
|
@@ -57,22 +57,79 @@ const inputSchema = z
|
|
|
57
57
|
.describe(
|
|
58
58
|
'Optional line insertion target. Inserts the replacement after this 1-indexed line; 0 inserts before the first line; "end" appends to the file.',
|
|
59
59
|
),
|
|
60
|
+
// Optional rather than defaulted, for the reason given on the entry
|
|
61
|
+
// field below: `execute` takes the schema's OUTPUT type, so a default
|
|
62
|
+
// here makes `replace_all` mandatory for every hand-built call —
|
|
63
|
+
// including a batch call, where the top-level flag means nothing at
|
|
64
|
+
// all. The default is applied in `normalizeEditInput`.
|
|
60
65
|
replace_all: z
|
|
61
66
|
.boolean()
|
|
62
|
-
.
|
|
67
|
+
.optional()
|
|
63
68
|
.describe('Replace all occurrences instead of just the first unique match'),
|
|
69
|
+
edits: z
|
|
70
|
+
.array(
|
|
71
|
+
z
|
|
72
|
+
.object({
|
|
73
|
+
old_string: z
|
|
74
|
+
.string()
|
|
75
|
+
.min(1)
|
|
76
|
+
.describe('The exact string to find. Must be unique in the file at this point.'),
|
|
77
|
+
new_string: z.string().describe('The replacement string.'),
|
|
78
|
+
// `.optional()` where the top-level field uses `.default(false)`,
|
|
79
|
+
// and the difference is about the CALLER rather than the
|
|
80
|
+
// value. `execute` takes the schema's OUTPUT type, so a
|
|
81
|
+
// defaulted field is required of everyone who builds a call
|
|
82
|
+
// by hand — and a batch entry is built by hand far more
|
|
83
|
+
// often than the top-level object is. The default lives in
|
|
84
|
+
// `normalizeEditInput` instead, where it is applied once for
|
|
85
|
+
// every entry.
|
|
86
|
+
replace_all: z
|
|
87
|
+
.boolean()
|
|
88
|
+
.optional()
|
|
89
|
+
.describe('Replace every occurrence of this old_string instead of requiring one.'),
|
|
90
|
+
})
|
|
91
|
+
.strict(),
|
|
92
|
+
)
|
|
93
|
+
.min(1)
|
|
94
|
+
.optional()
|
|
95
|
+
.describe(
|
|
96
|
+
'Several replacements in one file, applied in order and committed together. Nothing is written unless every one applies.',
|
|
97
|
+
),
|
|
64
98
|
})
|
|
65
99
|
.strict()
|
|
66
|
-
.refine((value) => typeof value.new_string === 'string' || typeof value.newStr === 'string', {
|
|
67
|
-
message: 'Either new_string or newStr is required.',
|
|
68
|
-
})
|
|
69
100
|
.refine(
|
|
70
101
|
(value) =>
|
|
102
|
+
value.edits !== undefined ||
|
|
103
|
+
typeof value.new_string === 'string' ||
|
|
104
|
+
typeof value.newStr === 'string',
|
|
105
|
+
{ message: 'Either new_string or newStr is required.' },
|
|
106
|
+
)
|
|
107
|
+
.refine(
|
|
108
|
+
(value) =>
|
|
109
|
+
value.edits !== undefined ||
|
|
71
110
|
value.insertLine !== undefined ||
|
|
72
111
|
typeof value.old_string === 'string' ||
|
|
73
112
|
typeof value.oldStr === 'string',
|
|
74
113
|
{ message: 'Either old_string/oldStr or insertLine is required.' },
|
|
75
114
|
)
|
|
115
|
+
// Refused rather than resolved. A call carrying both an `edits` list and a
|
|
116
|
+
// top-level replacement is two different intentions in one object, and any
|
|
117
|
+
// precedence this code picked would be a guess about which the model meant
|
|
118
|
+
// — silently dropping the other. There is no reading of that which is safe:
|
|
119
|
+
// the dropped half is an edit somebody believes was made.
|
|
120
|
+
.refine(
|
|
121
|
+
(value) =>
|
|
122
|
+
value.edits === undefined ||
|
|
123
|
+
(value.old_string === undefined &&
|
|
124
|
+
value.oldStr === undefined &&
|
|
125
|
+
value.new_string === undefined &&
|
|
126
|
+
value.newStr === undefined &&
|
|
127
|
+
value.insertLine === undefined),
|
|
128
|
+
{
|
|
129
|
+
message:
|
|
130
|
+
'Use either `edits` or a single top-level edit, not both. Move the top-level old_string/new_string into the edits list.',
|
|
131
|
+
},
|
|
132
|
+
)
|
|
76
133
|
|
|
77
134
|
type EditInput = z.infer<typeof inputSchema>
|
|
78
135
|
|
|
@@ -134,6 +191,31 @@ const modelInputSchema: Record<string, unknown> = {
|
|
|
134
191
|
type: 'boolean',
|
|
135
192
|
description: 'Replace every occurrence instead of requiring one unique match.',
|
|
136
193
|
},
|
|
194
|
+
edits: {
|
|
195
|
+
// The batch shape. Stated as an array of the same two fields
|
|
196
|
+
// rather than as a second tool, because a model offered two tools
|
|
197
|
+
// that both edit a file spends a decision on every turn choosing
|
|
198
|
+
// between them — and the choice carries no information.
|
|
199
|
+
type: 'array',
|
|
200
|
+
items: {
|
|
201
|
+
type: 'object',
|
|
202
|
+
properties: {
|
|
203
|
+
old_string: {
|
|
204
|
+
type: 'string',
|
|
205
|
+
description: 'Exact text from the file at this point in the sequence.',
|
|
206
|
+
},
|
|
207
|
+
new_string: { type: 'string', description: 'Exact replacement text.' },
|
|
208
|
+
replace_all: {
|
|
209
|
+
type: 'boolean',
|
|
210
|
+
description: 'Replace every occurrence of this old_string.',
|
|
211
|
+
},
|
|
212
|
+
},
|
|
213
|
+
required: ['old_string', 'new_string'],
|
|
214
|
+
additionalProperties: false,
|
|
215
|
+
},
|
|
216
|
+
description:
|
|
217
|
+
'Several replacements in one file, applied in order and committed together. Nothing is written unless every one applies. Use this instead of several edit calls when the changes only make sense together.',
|
|
218
|
+
},
|
|
137
219
|
},
|
|
138
220
|
// `old_string` is deliberately NOT required, and this is the fix.
|
|
139
221
|
//
|
|
@@ -152,7 +234,13 @@ const modelInputSchema: Record<string, unknown> = {
|
|
|
152
234
|
// incomplete call is now expressible and caught at execution rather than
|
|
153
235
|
// at generation — paid knowingly, because the alternative is that a
|
|
154
236
|
// working capability stays unreachable.
|
|
155
|
-
|
|
237
|
+
//
|
|
238
|
+
// `new_string` left the required list for exactly that reason, one shape
|
|
239
|
+
// later: a batch call carries its replacements inside `edits` and has no
|
|
240
|
+
// top-level `new_string` to give. This is the same trade, made the same
|
|
241
|
+
// way — a third refinement names what is missing at execution, and it also
|
|
242
|
+
// refuses a call that carries both shapes rather than picking one.
|
|
243
|
+
required: ['path'],
|
|
156
244
|
additionalProperties: false,
|
|
157
245
|
}
|
|
158
246
|
|
|
@@ -173,12 +261,12 @@ type NormalizedEditInput =
|
|
|
173
261
|
export const EditTool = defineTool({
|
|
174
262
|
name: 'edit',
|
|
175
263
|
description:
|
|
176
|
-
'Makes targeted edits to a file using exact string find-and-replace or line insertion. THIS IS THE PREFERRED WAY TO MODIFY AN EXISTING FILE — never reach for `write` to change a file that already exists, because `write` overwrites the whole body and discards earlier work on partial failure. `edit` keeps the rest of the file byte-for-byte intact and is recoverable: if a single edit fails (old_string/oldStr ambiguous, broader restructuring needed), follow up with another `edit` instead of re-emitting the entire file via `write`. The old_string/oldStr must be unique in the file unless replace_all is true. For insertions, pass insertLine plus new_string/newStr; use insertLine: "end" to extend a file at the end. Self-budget new_string/newStr under 12000 characters before emitting the tool call; use repeated bounded edits for long sections. Preserves file formatting and indentation.',
|
|
264
|
+
'Makes targeted edits to a file using exact string find-and-replace or line insertion. THIS IS THE PREFERRED WAY TO MODIFY AN EXISTING FILE — never reach for `write` to change a file that already exists, because `write` overwrites the whole body and discards earlier work on partial failure. `edit` keeps the rest of the file byte-for-byte intact and is recoverable: if a single edit fails (old_string/oldStr ambiguous, broader restructuring needed), follow up with another `edit` instead of re-emitting the entire file via `write`. The old_string/oldStr must be unique in the file unless replace_all is true. For insertions, pass insertLine plus new_string/newStr; use insertLine: "end" to extend a file at the end. Self-budget new_string/newStr under 12000 characters before emitting the tool call; use repeated bounded edits for long sections. Preserves file formatting and indentation. To make several changes to ONE file that only make sense together, send them as `edits`: a list of {old_string, new_string} applied in order and committed as one write — if any of them does not apply, nothing is written and the reply names which one, so the file is never left half-changed.',
|
|
177
265
|
inputSchema,
|
|
178
266
|
modelInputSchema,
|
|
179
267
|
enforceModelInput: true,
|
|
180
268
|
validationErrorHint:
|
|
181
|
-
'
|
|
269
|
+
'Three shapes. Replace: {"path":"file.md","old_string":"exact unique text","new_string":"replacement text"} (optional "replace_all": true). Insert: {"path":"file.md","insertLine":"end","new_string":"text to add"} where insertLine is a non-negative line number or "end". Batch: {"path":"file.md","edits":[{"old_string":"a","new_string":"b"},{"old_string":"c","new_string":"d"}]} applied in order, all or nothing. Exactly one of old_string, insertLine or edits — a call carrying more than one of them is refused rather than resolved.',
|
|
182
270
|
category: 'filesystem',
|
|
183
271
|
permissions: ['file_write'],
|
|
184
272
|
readOnly: false,
|
|
@@ -237,14 +325,22 @@ export const EditTool = defineTool({
|
|
|
237
325
|
if (!normalized.success) {
|
|
238
326
|
return { success: false, output: '', error: normalized.error }
|
|
239
327
|
}
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
328
|
+
// Checked per operation, not for the call. A batch whose third entry is
|
|
329
|
+
// a no-op is still a mistake worth naming: the model believed it was
|
|
330
|
+
// changing something there, and a silent pass would leave it believing
|
|
331
|
+
// that after the edit reported success.
|
|
332
|
+
const noOp = normalized.operations.findIndex(
|
|
333
|
+
(operation) =>
|
|
334
|
+
operation.operation === 'replace' && operation.oldString === operation.newString,
|
|
335
|
+
)
|
|
336
|
+
if (noOp >= 0) {
|
|
244
337
|
return {
|
|
245
338
|
success: false,
|
|
246
339
|
output: '',
|
|
247
|
-
error:
|
|
340
|
+
error:
|
|
341
|
+
normalized.operations.length === 1
|
|
342
|
+
? 'old_string/oldStr and new_string/newStr are identical — no change needed'
|
|
343
|
+
: `edits[${noOp}]: old_string and new_string are identical — no change needed. Nothing was written.`,
|
|
248
344
|
}
|
|
249
345
|
}
|
|
250
346
|
|
|
@@ -266,7 +362,7 @@ export const EditTool = defineTool({
|
|
|
266
362
|
return withFileMutationLock(lockKey, async () => {
|
|
267
363
|
if (context.sandbox) {
|
|
268
364
|
const buffer = await context.sandbox.readFile(parsed.data.path)
|
|
269
|
-
const result = applyEdit(buffer.toString('utf-8'), normalized.
|
|
365
|
+
const result = applyEdit(buffer.toString('utf-8'), normalized.operations)
|
|
270
366
|
if (!result.success) {
|
|
271
367
|
return { success: false as const, output: '', error: result.error }
|
|
272
368
|
}
|
|
@@ -282,7 +378,7 @@ export const EditTool = defineTool({
|
|
|
282
378
|
const hostPath = filePath as string
|
|
283
379
|
const content = await readFile(hostPath, 'utf-8')
|
|
284
380
|
|
|
285
|
-
const result = applyEdit(content, normalized.
|
|
381
|
+
const result = applyEdit(content, normalized.operations)
|
|
286
382
|
if (!result.success) {
|
|
287
383
|
// The anchor did not match what is on disk. Two very different
|
|
288
384
|
// situations produce that, and the difference is the whole
|
|
@@ -327,9 +423,31 @@ export const EditTool = defineTool({
|
|
|
327
423
|
},
|
|
328
424
|
})
|
|
329
425
|
|
|
426
|
+
/**
|
|
427
|
+
* Turn one call into the ordered list of operations it stands for.
|
|
428
|
+
*
|
|
429
|
+
* A list rather than a single operation because the batch shape is not a
|
|
430
|
+
* different kind of edit, only a longer one. Keeping ONE representation is
|
|
431
|
+
* what stops the two shapes diverging: everything below this function — the
|
|
432
|
+
* uniqueness check, the CRLF reconciliation, the identical-text refusal, the
|
|
433
|
+
* atomic write — sees a list of length one for a single edit and never learns
|
|
434
|
+
* which shape the caller used.
|
|
435
|
+
*/
|
|
330
436
|
function normalizeEditInput(
|
|
331
437
|
input: EditInput,
|
|
332
|
-
): { success: true;
|
|
438
|
+
): { success: true; operations: NormalizedEditInput[] } | { success: false; error: string } {
|
|
439
|
+
if (input.edits !== undefined) {
|
|
440
|
+
return {
|
|
441
|
+
success: true,
|
|
442
|
+
operations: input.edits.map((edit) => ({
|
|
443
|
+
operation: 'replace' as const,
|
|
444
|
+
oldString: edit.old_string,
|
|
445
|
+
newString: edit.new_string,
|
|
446
|
+
replace_all: edit.replace_all ?? false,
|
|
447
|
+
})),
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
|
|
333
451
|
const newString = input.new_string ?? input.newStr
|
|
334
452
|
if (typeof newString !== 'string') {
|
|
335
453
|
return { success: false, error: 'Either new_string or newStr is required.' }
|
|
@@ -340,12 +458,14 @@ function normalizeEditInput(
|
|
|
340
458
|
if (!insertLine.success) return insertLine
|
|
341
459
|
return {
|
|
342
460
|
success: true,
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
461
|
+
operations: [
|
|
462
|
+
{
|
|
463
|
+
operation: 'insert',
|
|
464
|
+
insertLine: insertLine.value,
|
|
465
|
+
newString,
|
|
466
|
+
replace_all: input.replace_all ?? false,
|
|
467
|
+
},
|
|
468
|
+
],
|
|
349
469
|
}
|
|
350
470
|
}
|
|
351
471
|
|
|
@@ -355,12 +475,14 @@ function normalizeEditInput(
|
|
|
355
475
|
}
|
|
356
476
|
return {
|
|
357
477
|
success: true,
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
478
|
+
operations: [
|
|
479
|
+
{
|
|
480
|
+
operation: 'replace',
|
|
481
|
+
oldString,
|
|
482
|
+
newString,
|
|
483
|
+
replace_all: input.replace_all ?? false,
|
|
484
|
+
},
|
|
485
|
+
],
|
|
364
486
|
}
|
|
365
487
|
}
|
|
366
488
|
|
|
@@ -398,7 +520,48 @@ function normalizeInsertLine(
|
|
|
398
520
|
return { success: true, value }
|
|
399
521
|
}
|
|
400
522
|
|
|
523
|
+
/**
|
|
524
|
+
* Apply every operation in order, or none of them.
|
|
525
|
+
*
|
|
526
|
+
* "Or none" is the whole reason this takes a list. Four related changes sent
|
|
527
|
+
* as four calls are four chances to stop halfway, and the file left behind
|
|
528
|
+
* after the third succeeded and the fourth did not is in a state no one wrote
|
|
529
|
+
* and no one is looking at. Here the fold runs entirely in memory and the
|
|
530
|
+
* caller writes once, so a failure anywhere leaves the file exactly as it was.
|
|
531
|
+
*
|
|
532
|
+
* Each operation matches against the content as the ones before it left it,
|
|
533
|
+
* not against the original. That is what lets a later edit target text an
|
|
534
|
+
* earlier one produced — and it is also why a failure names the INDEX: by the
|
|
535
|
+
* time hunk 3 fails, the string it was looking for may have been consumed by
|
|
536
|
+
* hunk 1, and "old_string not found" without a position sends the model to
|
|
537
|
+
* re-check the wrong hunk.
|
|
538
|
+
*/
|
|
401
539
|
function applyEdit(
|
|
540
|
+
content: string,
|
|
541
|
+
operations: readonly NormalizedEditInput[],
|
|
542
|
+
): { success: true; content: string; replacements: number } | { success: false; error: string } {
|
|
543
|
+
let current = content
|
|
544
|
+
let replacements = 0
|
|
545
|
+
|
|
546
|
+
for (const [index, operation] of operations.entries()) {
|
|
547
|
+
const result = applyOne(current, operation)
|
|
548
|
+
if (!result.success) {
|
|
549
|
+
return {
|
|
550
|
+
success: false,
|
|
551
|
+
error:
|
|
552
|
+
operations.length === 1
|
|
553
|
+
? result.error
|
|
554
|
+
: `edits[${index}] of ${operations.length}: ${result.error} Nothing was written — the whole batch is refused, so the file is exactly as it was.`,
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
current = result.content
|
|
558
|
+
replacements += result.replacements
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
return { success: true, content: current, replacements }
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
function applyOne(
|
|
402
565
|
content: string,
|
|
403
566
|
input: NormalizedEditInput,
|
|
404
567
|
): { success: true; content: string; replacements: number } | { success: false; error: string } {
|