mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-12 21:53:00 -06:00
refactor: eliminate export name collisions (#122084)
* refactor: eliminate export name collisions * chore(scripts): burn resolved collision baselines * refactor: narrow legacy session load options * chore: refresh SDK and session debt baselines * refactor: adopt upstream secrets collision fix * test(plugin-sdk): mock renamed session store core * fix(scripts): track renamed session accessor core
This commit is contained in:
committed by
GitHub
parent
653ab3b2aa
commit
ebb2770000
@@ -1 +1 @@
|
||||
{"contentHash":"f0501615d366cab1ceffabfcbb580b9a9f1008bbd4e24a46e1fc10d73e9cd2a3","entrypoint":"agent-harness-runtime","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime"}
|
||||
{"contentHash":"14115e942e60b33851a102cf0091ec7c6e29e015ad800471c095346de6708e0b","entrypoint":"agent-harness-runtime","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime"}
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
{"contentHash":"ae5e7178a886a346e7a7d88e80344b84c84679e156d08eb863c8a5e2bbffe03c","entrypoint":"agent-harness","importSpecifier":"openclaw/plugin-sdk/agent-harness"}
|
||||
{"contentHash":"944bceb3db8adc5516b7f80933a3a3dd483cfeb162b102f78e7f31e40286ac54","entrypoint":"agent-harness","importSpecifier":"openclaw/plugin-sdk/agent-harness"}
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
{"contentHash":"2f175fa56f7836b6dc666ef556b964ecfa83f6f81f683340907c7456c8f301ea","entrypoint":"agent-runtime","importSpecifier":"openclaw/plugin-sdk/agent-runtime"}
|
||||
{"contentHash":"e0ee84e5e66b6c524a69e4d5791ee3d962859937e572b452db54b926f57219a3","entrypoint":"agent-runtime","importSpecifier":"openclaw/plugin-sdk/agent-runtime"}
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
{"contentHash":"9360377bb569d5f8f53151152e4b1e27e860ebc38d176ee3d71cbf3461c79ca8","entrypoint":"channel-core","importSpecifier":"openclaw/plugin-sdk/channel-core"}
|
||||
{"contentHash":"0841384461391ee65d656cdcce3e956417be3a861f6a7dcde8b7592e951c8381","entrypoint":"channel-core","importSpecifier":"openclaw/plugin-sdk/channel-core"}
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"contentHash":"5e756ed6e46b362058d9ca438cf858c463bb01fd55269b0b019341fe0075bcda","entrypoint":"channel-entry-contract","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract"}
|
||||
{"contentHash":"87519437ca1f4ed669866f5efa28ab61836ead8c9251f2d401d755b43debdaa4","entrypoint":"channel-entry-contract","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract"}
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"contentHash":"3523cddf2dad5146687de9564879903e20224b140f4a9756ba57e76034c6490a","entrypoint":"channel-inbound","importSpecifier":"openclaw/plugin-sdk/channel-inbound"}
|
||||
{"contentHash":"2598df91c020fd173ef4c0b171718a4fd90e90599536ff71ca3f4d1b3adf97fe","entrypoint":"channel-inbound","importSpecifier":"openclaw/plugin-sdk/channel-inbound"}
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"contentHash":"5091fb6b03b3e1b3cb6b51323cb7bd991f8022d1aac479b4a67982993dec79cf","entrypoint":"channel-message","importSpecifier":"openclaw/plugin-sdk/channel-message"}
|
||||
{"contentHash":"b6454c9a2e9fd243ec392fb51d1542fc176f350bc682213813f0ea7fc0166af6","entrypoint":"channel-message","importSpecifier":"openclaw/plugin-sdk/channel-message"}
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"contentHash":"33c41deadb29159ecaf9e40c0053d43a81531ca48145f11217f811e4232c5cf2","entrypoint":"channel-outbound","importSpecifier":"openclaw/plugin-sdk/channel-outbound"}
|
||||
{"contentHash":"6236a390dab6017b4eef42591729660b3e114b43ae34798d41482670a3ee0613","entrypoint":"channel-outbound","importSpecifier":"openclaw/plugin-sdk/channel-outbound"}
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"contentHash":"c6e8524442d54875e1ce5ec211394472c2e2734fbfbebe320b069346374b922d","entrypoint":"channel-plugin-common","importSpecifier":"openclaw/plugin-sdk/channel-plugin-common"}
|
||||
{"contentHash":"b2bbf7a51a586c54b554475998b6a259be1e7fc7db9604c2e1205f56ff35f704","entrypoint":"channel-plugin-common","importSpecifier":"openclaw/plugin-sdk/channel-plugin-common"}
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
{"contentHash":"1edb0e67f51c958fff1d3ace6e47debb831555720208ebfb732cf65de2bb333a","entrypoint":"core","importSpecifier":"openclaw/plugin-sdk/core"}
|
||||
{"contentHash":"c5239579070b39b2d63a3cf6b9faa66152e5d71f64d73716a84c4cc510054d2d","entrypoint":"core","importSpecifier":"openclaw/plugin-sdk/core"}
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
{"contentHash":"243be23ce58934cc502148cde9b747c4e8d26d176526e99dda383f16f20fc124","entrypoint":"discord","importSpecifier":"openclaw/plugin-sdk/discord"}
|
||||
{"contentHash":"fe90342ef9fd6a4173e1feed09852380f256fafafb7836bc2c1df7400a8bcf3c","entrypoint":"discord","importSpecifier":"openclaw/plugin-sdk/discord"}
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"contentHash":"a27b168ddc12affa72e1d646d36ea8ef65f18f2de7a7397f0f9e816659e54c0e","entrypoint":"inbound-reply-dispatch","importSpecifier":"openclaw/plugin-sdk/inbound-reply-dispatch"}
|
||||
{"contentHash":"23c052386a61874b2f9d19f872a90a9e6863971e812e573d8271b89d92181e30","entrypoint":"inbound-reply-dispatch","importSpecifier":"openclaw/plugin-sdk/inbound-reply-dispatch"}
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"contentHash":"336c432da880945a8dccc3f6e0c96cc062b4afdd96b73b35382ffedc537762be","entrypoint":"meeting-runtime","importSpecifier":"openclaw/plugin-sdk/meeting-runtime"}
|
||||
{"contentHash":"f31959d35168e31228f318289d78117945dcd79e8ff5c57473636025c7f8d881","entrypoint":"meeting-runtime","importSpecifier":"openclaw/plugin-sdk/meeting-runtime"}
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
{"contentHash":"66b344dc4d56bdb7d3c1ddccb64899a013f98e1dda7f734e6b75de49c41ba0fc","entrypoint":"plugin-entry","importSpecifier":"openclaw/plugin-sdk/plugin-entry"}
|
||||
{"contentHash":"76391f09ded09871b1a5ac2fbbf2bd9901f55c529cdd97c00a0111aeb319ba33","entrypoint":"plugin-entry","importSpecifier":"openclaw/plugin-sdk/plugin-entry"}
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
{"contentHash":"e7788890d54d5784f4bce552c7143a0083cd1cdd46f126b98d66ad8357327e51","entrypoint":"plugin-runtime","importSpecifier":"openclaw/plugin-sdk/plugin-runtime"}
|
||||
{"contentHash":"d05730f5b90c0164e719e97694582d27f15ec4442c8d764044b0960a6e575c93","entrypoint":"plugin-runtime","importSpecifier":"openclaw/plugin-sdk/plugin-runtime"}
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"contentHash":"4b0295b65533f821a02e3399298424b35c2c75082e4d53d57ea88ff2f84d74ad","entrypoint":"provider-catalog-runtime","importSpecifier":"openclaw/plugin-sdk/provider-catalog-runtime"}
|
||||
{"contentHash":"ef4d5d011283052e9b24d4bf57fba52e38b48aef38e1be322273eaf290f3eb85","entrypoint":"provider-catalog-runtime","importSpecifier":"openclaw/plugin-sdk/provider-catalog-runtime"}
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
{"contentHash":"c489a3d36e88b55b29c9019df733662acb67ec95e2fd0a99d2b208ac123801f5","entrypoint":"tool-plugin","importSpecifier":"openclaw/plugin-sdk/tool-plugin"}
|
||||
{"contentHash":"a72d078274268d0e5b2c1a18a4787980c55e61479d3efb7a11dfc7303ac28d28","entrypoint":"tool-plugin","importSpecifier":"openclaw/plugin-sdk/tool-plugin"}
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"contentHash":"73b1700f912dfb34554f7a9e72bca0ff9e1ea08360f32c981519488a25023f2c","entrypoint":"webhook-ingress","importSpecifier":"openclaw/plugin-sdk/webhook-ingress"}
|
||||
{"contentHash":"9d8a7eec9dba85091301963980960ddb8993aaae52972fb245f25c5bd608b150","entrypoint":"webhook-ingress","importSpecifier":"openclaw/plugin-sdk/webhook-ingress"}
|
||||
|
||||
@@ -67,7 +67,10 @@ const sessionStoreRuntimeFileBackedCompatNames = new Set([
|
||||
"updateSessionStore",
|
||||
]);
|
||||
const embeddedAgentSessionFileRuntimeNames = new Set(["resolveSessionFilePath"]);
|
||||
const materializingSessionEntryAccessorNames = new Set(["listSessionEntries", "loadSessionEntry"]);
|
||||
const materializingSessionEntryAccessorNames = new Set([
|
||||
"listSessionEntriesCore",
|
||||
"loadSessionEntry",
|
||||
]);
|
||||
|
||||
// Shipped beta.5 official plugins import these deprecated helpers during
|
||||
// doctor migrations. Remove this ratchet with the compatibility bridge once
|
||||
|
||||
@@ -1,400 +1,4 @@
|
||||
[
|
||||
{
|
||||
"name": "cleanupSessionLifecycleArtifacts",
|
||||
"files": [
|
||||
"src/config/sessions/session-accessor.sqlite-lifecycle.ts",
|
||||
"src/plugin-sdk/session-store-runtime.ts"
|
||||
],
|
||||
"sdk": true
|
||||
},
|
||||
{
|
||||
"name": "createPluginLoaderLogger",
|
||||
"files": [
|
||||
"src/plugins/loader-shared.ts",
|
||||
"src/plugins/logger.ts"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "listMemoryEmbeddingProviders",
|
||||
"files": [
|
||||
"src/plugins/memory-embedding-provider-runtime.ts",
|
||||
"src/plugins/memory-embedding-providers.ts"
|
||||
],
|
||||
"sdk": true
|
||||
},
|
||||
{
|
||||
"name": "listSessionEntries",
|
||||
"files": [
|
||||
"src/config/sessions/session-accessor.entry.ts",
|
||||
"src/plugin-sdk/session-store-runtime.ts"
|
||||
],
|
||||
"sdk": true
|
||||
},
|
||||
{
|
||||
"name": "loadBundledPluginPublicSurface",
|
||||
"files": [
|
||||
"src/plugin-sdk/test-helpers/public-surface-loader.ts",
|
||||
"src/test-utils/bundled-plugin-public-surface.ts"
|
||||
],
|
||||
"sdk": true
|
||||
},
|
||||
{
|
||||
"name": "loadBundledPluginPublicSurfaceModuleSync",
|
||||
"files": [
|
||||
"src/plugin-sdk/facade-loader.ts",
|
||||
"src/plugin-sdk/facade-runtime.ts"
|
||||
],
|
||||
"sdk": true
|
||||
},
|
||||
{
|
||||
"name": "loadCodexBundleMcpThreadConfig",
|
||||
"files": [
|
||||
"src/agents/codex-mcp-config.ts",
|
||||
"src/plugin-sdk/agent-harness-runtime.ts"
|
||||
],
|
||||
"sdk": true
|
||||
},
|
||||
{
|
||||
"name": "loadCombinedSessionStoreForGateway",
|
||||
"files": [
|
||||
"src/config/sessions/combined-store-gateway.ts",
|
||||
"src/plugin-sdk/session-transcript-hit.ts"
|
||||
],
|
||||
"sdk": true
|
||||
},
|
||||
{
|
||||
"name": "loadConfig",
|
||||
"files": [
|
||||
"src/cli/plugins-cli-test-helpers.ts",
|
||||
"src/config/io.runtime.ts"
|
||||
],
|
||||
"sdk": true
|
||||
},
|
||||
{
|
||||
"name": "loadJsonFile",
|
||||
"files": [
|
||||
"src/infra/json-file.ts",
|
||||
"src/plugin-sdk/json-store.ts"
|
||||
],
|
||||
"sdk": true
|
||||
},
|
||||
{
|
||||
"name": "loadPluginManifestRegistry",
|
||||
"files": [
|
||||
"src/cli/plugins-cli-test-helpers.ts",
|
||||
"src/plugins/manifest-registry.ts"
|
||||
],
|
||||
"sdk": true
|
||||
},
|
||||
{
|
||||
"name": "loadQaRuntimeModule",
|
||||
"files": [
|
||||
"src/plugin-sdk/qa-runner-runtime.ts",
|
||||
"src/plugin-sdk/qa-runtime.ts"
|
||||
],
|
||||
"sdk": true
|
||||
},
|
||||
{
|
||||
"name": "loadSessionStore",
|
||||
"files": [
|
||||
"src/library.ts",
|
||||
"src/plugin-sdk/session-store-runtime.ts"
|
||||
],
|
||||
"sdk": true
|
||||
},
|
||||
{
|
||||
"name": "loadWebMedia",
|
||||
"files": [
|
||||
"src/media/web-media.ts",
|
||||
"src/plugins/runtime/runtime-web-channel-plugin.ts"
|
||||
],
|
||||
"sdk": true
|
||||
},
|
||||
{
|
||||
"name": "loadWebMediaRaw",
|
||||
"files": [
|
||||
"src/media/web-media.ts",
|
||||
"src/plugins/runtime/runtime-web-channel-plugin.ts"
|
||||
],
|
||||
"sdk": true
|
||||
},
|
||||
{
|
||||
"name": "materializeRequesterScopedMcpToolsForHarnessRun",
|
||||
"files": [
|
||||
"src/agents/agent-bundle-mcp-harness.ts",
|
||||
"src/plugin-sdk/agent-harness-runtime.ts"
|
||||
],
|
||||
"sdk": true
|
||||
},
|
||||
{
|
||||
"name": "materializeStaticMcpToolsForScheduledHarnessRun",
|
||||
"files": [
|
||||
"src/agents/agent-bundle-mcp-harness.ts",
|
||||
"src/plugin-sdk/codex-mcp-projection.ts"
|
||||
],
|
||||
"sdk": true
|
||||
},
|
||||
{
|
||||
"name": "maybeApplyTtsToPayload",
|
||||
"files": [
|
||||
"src/tts/tts-payload.ts",
|
||||
"src/tts/tts.ts"
|
||||
],
|
||||
"sdk": true
|
||||
},
|
||||
{
|
||||
"name": "mergeSessionEntry",
|
||||
"files": [
|
||||
"src/config/sessions/types.ts",
|
||||
"src/infra/state-migrations.session-store.ts"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "normalizeCronRunDiagnostics",
|
||||
"files": [
|
||||
"src/cron/run-diagnostics-normalize.ts",
|
||||
"src/cron/run-diagnostics.ts"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "normalizeStringRecord",
|
||||
"files": [
|
||||
"src/agents/bundle-mcp-adapter.ts",
|
||||
"src/plugins/manifest-capability-normalizers.ts"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "normalizeToolName",
|
||||
"files": [
|
||||
"src/agents/tool-display-common.ts",
|
||||
"src/agents/tool-policy-shared.ts",
|
||||
"src/cron/run-diagnostics-normalize.ts"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "optimizeImageToJpeg",
|
||||
"files": [
|
||||
"src/media/web-media.ts",
|
||||
"src/plugins/runtime/runtime-web-channel-plugin.ts"
|
||||
],
|
||||
"sdk": true
|
||||
},
|
||||
{
|
||||
"name": "pad",
|
||||
"files": [
|
||||
"src/agents/bash-tools.shared.ts",
|
||||
"src/commands/models/list.format.ts"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "parseClawHubPluginSpec",
|
||||
"files": [
|
||||
"src/cli/plugins-cli-test-helpers.ts",
|
||||
"src/infra/clawhub-spec.ts"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "parseCsvFilter",
|
||||
"files": [
|
||||
"src/image-generation/live-test-helpers.ts",
|
||||
"src/video-generation/live-test-helpers.ts"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "parseFrontmatter",
|
||||
"files": [
|
||||
"src/agents/utils/frontmatter.ts",
|
||||
"src/hooks/frontmatter.ts",
|
||||
"src/skills/loading/frontmatter.ts"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "parseInlineDirectives",
|
||||
"files": [
|
||||
"src/auto-reply/reply/directive-handling.parse.ts",
|
||||
"src/utils/directive-tags.ts"
|
||||
],
|
||||
"sdk": true
|
||||
},
|
||||
{
|
||||
"name": "parseModelRef",
|
||||
"files": [
|
||||
"src/agents/model-selection-normalize.ts",
|
||||
"src/commands/doctor/shared/codex-route-model-ref.ts"
|
||||
],
|
||||
"sdk": true
|
||||
},
|
||||
{
|
||||
"name": "parseQaTarget",
|
||||
"files": [
|
||||
"src/plugin-sdk/qa-channel-protocol.ts",
|
||||
"src/plugin-sdk/qa-channel.ts"
|
||||
],
|
||||
"sdk": true
|
||||
},
|
||||
{
|
||||
"name": "parseTimeoutMs",
|
||||
"files": [
|
||||
"src/cli/parse-timeout.ts",
|
||||
"src/commands/gateway-status/helpers.ts"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "patchSessionEntry",
|
||||
"files": [
|
||||
"src/config/sessions/session-accessor.sqlite-entry.ts",
|
||||
"src/plugin-sdk/session-store-runtime.ts"
|
||||
],
|
||||
"sdk": true
|
||||
},
|
||||
{
|
||||
"name": "pathExists",
|
||||
"files": [
|
||||
"src/agents/worktrees/git.ts",
|
||||
"src/utils.ts"
|
||||
],
|
||||
"sdk": true
|
||||
},
|
||||
{
|
||||
"name": "pathsEqual",
|
||||
"files": [
|
||||
"src/commands/doctor/shared/missing-configured-plugin-install.records.ts",
|
||||
"src/plugins/update-config.ts"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "peekSessionMcpRuntime",
|
||||
"files": [
|
||||
"src/agents/agent-bundle-mcp-manager-api.ts",
|
||||
"src/gateway/server-methods/__mocks__/tools-effective.runtime.ts"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "planPluginUninstall",
|
||||
"files": [
|
||||
"src/cli/plugins-cli-test-helpers.ts",
|
||||
"src/plugins/uninstall.ts"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "readAmbientTranscriptWatermark",
|
||||
"files": [
|
||||
"src/config/sessions/ambient-transcript-watermark.ts",
|
||||
"src/plugin-sdk/session-store-runtime.ts"
|
||||
],
|
||||
"sdk": true
|
||||
},
|
||||
{
|
||||
"name": "readAskUserQuestionId",
|
||||
"files": [
|
||||
"src/auto-reply/reply/dispatch-from-config.payloads.ts",
|
||||
"src/infra/question-reaction-runtime.ts"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "readConfigFileSnapshot",
|
||||
"files": [
|
||||
"src/cli/plugins-cli-test-helpers.ts",
|
||||
"src/config/io.runtime.ts"
|
||||
],
|
||||
"sdk": true
|
||||
},
|
||||
{
|
||||
"name": "readConfigFileSnapshotForWrite",
|
||||
"files": [
|
||||
"src/cli/plugins-cli-test-helpers.ts",
|
||||
"src/config/io.runtime.ts"
|
||||
],
|
||||
"sdk": true
|
||||
},
|
||||
{
|
||||
"name": "readPersistedInstalledPluginIndex",
|
||||
"files": [
|
||||
"src/cli/plugins-cli-test-helpers.ts",
|
||||
"src/plugins/installed-plugin-index-store.ts"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "readSessionEntry",
|
||||
"files": [
|
||||
"src/agents/subagents/announce/subagent-announce.runtime.ts",
|
||||
"src/cron/isolated-agent.turn-test-helpers.ts"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "readSessionTranscriptVisibleMessageDelta",
|
||||
"files": [
|
||||
"src/config/sessions/session-accessor.sqlite-active-events.ts",
|
||||
"src/plugin-sdk/session-transcript-runtime.ts"
|
||||
],
|
||||
"sdk": true
|
||||
},
|
||||
{
|
||||
"name": "readSessionUpdatedAt",
|
||||
"files": [
|
||||
"src/config/sessions/session-accessor.sqlite-entry.ts",
|
||||
"src/plugin-sdk/session-store-runtime.ts"
|
||||
],
|
||||
"sdk": true
|
||||
},
|
||||
{
|
||||
"name": "recordHookInstall",
|
||||
"files": [
|
||||
"src/cli/plugins-cli-test-helpers.ts",
|
||||
"src/hooks/installs.ts"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "recordPluginInstall",
|
||||
"files": [
|
||||
"src/cli/plugins-cli-test-helpers.ts",
|
||||
"src/plugins/installs.ts"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "redactSecrets",
|
||||
"files": [
|
||||
"src/commands/status-all/format.ts",
|
||||
"src/logging/redact.ts"
|
||||
],
|
||||
"sdk": true
|
||||
},
|
||||
{
|
||||
"name": "refreshPluginRegistry",
|
||||
"files": [
|
||||
"src/cli/plugins-cli-test-helpers.ts",
|
||||
"src/plugins/plugin-registry-snapshot.ts"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "replaceConfigFile",
|
||||
"files": [
|
||||
"src/cli/plugins-cli-test-helpers.ts",
|
||||
"src/config/mutate.ts"
|
||||
],
|
||||
"sdk": true
|
||||
},
|
||||
{
|
||||
"name": "reportClawHubPluginInstallTelemetry",
|
||||
"files": [
|
||||
"src/cli/plugins-cli-test-helpers.ts",
|
||||
"src/infra/clawhub-packages.ts"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "requestSafeGatewayRestart",
|
||||
"files": [
|
||||
"src/cli/daemon-cli/lifecycle-safe-restart.ts",
|
||||
"src/infra/restart-coordinator.ts"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "requireRecord",
|
||||
"files": [
|
||||
"src/acp/translator.bridge-test-helpers.ts",
|
||||
"src/gateway/test-helpers.assertions.ts"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "resolveAdvertisedLanHost",
|
||||
"files": [
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
"embeddedAgentSessionTarget": {},
|
||||
"memoryHostSessionCorpus": {},
|
||||
"sessionAccessorRead": {
|
||||
"src/agents/subagents/announce/subagent-announce-output.ts": 3,
|
||||
"src/agents/subagents/announce/subagent-announce.test-support.ts": 2,
|
||||
"src/agents/tools/transcripts-tool.ts": 2,
|
||||
"src/auto-reply/reply/commands-session-store.ts": 2,
|
||||
|
||||
@@ -1,39 +1,9 @@
|
||||
[
|
||||
{
|
||||
"name": "loadBundledPluginPublicSurfaceModuleSync",
|
||||
"wrapped": "src/plugin-sdk/facade-loader.ts",
|
||||
"wrapper": "src/plugin-sdk/facade-runtime.ts"
|
||||
},
|
||||
{
|
||||
"name": "loadCombinedSessionStoreForGateway",
|
||||
"wrapped": "src/config/sessions/combined-store-gateway.ts",
|
||||
"wrapper": "src/plugin-sdk/session-transcript-hit.ts"
|
||||
},
|
||||
{
|
||||
"name": "loadPluginManifestRegistry",
|
||||
"wrapped": "src/plugins/manifest-registry.ts",
|
||||
"wrapper": "src/config/doc-baseline.runtime.ts"
|
||||
},
|
||||
{
|
||||
"name": "loadWebMediaRaw",
|
||||
"wrapped": "src/media/web-media.ts",
|
||||
"wrapper": "src/plugins/runtime/runtime-web-channel-plugin.ts"
|
||||
},
|
||||
{
|
||||
"name": "loadWebMedia",
|
||||
"wrapped": "src/media/web-media.ts",
|
||||
"wrapper": "src/plugins/runtime/runtime-web-channel-plugin.ts"
|
||||
},
|
||||
{
|
||||
"name": "maybeApplyTtsToPayload",
|
||||
"wrapped": "src/tts/tts-payload.ts",
|
||||
"wrapper": "src/tts/tts.ts"
|
||||
},
|
||||
{
|
||||
"name": "normalizeCronRunDiagnostics",
|
||||
"wrapped": "src/cron/run-diagnostics-normalize.ts",
|
||||
"wrapper": "src/cron/run-diagnostics.ts"
|
||||
},
|
||||
{
|
||||
"name": "normalizeOutboundReplyPayload",
|
||||
"wrapped": "src/infra/outbound/reply-payload-normalize.ts",
|
||||
@@ -44,32 +14,16 @@
|
||||
"wrapped": "src/plugins/config-normalization-shared.ts",
|
||||
"wrapper": "src/plugins/config-policy.ts"
|
||||
},
|
||||
{
|
||||
"name": "optimizeImageToJpeg",
|
||||
"wrapped": "src/media/web-media.ts",
|
||||
"wrapper": "src/plugins/runtime/runtime-web-channel-plugin.ts"
|
||||
},
|
||||
{
|
||||
"name": "pruneStaleCommandPolls",
|
||||
"wrapped": "src/agents/command-poll-backoff.ts",
|
||||
"wrapper": "src/agents/command-poll-backoff.runtime.ts"
|
||||
},
|
||||
{
|
||||
"name": "readAmbientTranscriptWatermark",
|
||||
"wrapped": "src/config/sessions/ambient-transcript-watermark.ts",
|
||||
"wrapper": "src/plugin-sdk/session-store-runtime.ts"
|
||||
},
|
||||
{
|
||||
"name": "readBooleanParam",
|
||||
"wrapped": "src/plugin-sdk/boolean-param.ts",
|
||||
"wrapper": "src/infra/outbound/message-action-params.ts"
|
||||
},
|
||||
{
|
||||
"name": "readSessionTranscriptVisibleMessageDelta",
|
||||
"wrapped": "src/config/sessions/session-accessor.sqlite-active-events.ts",
|
||||
"wrapper": "src/plugin-sdk/session-transcript-runtime.ts",
|
||||
"via": "src/config/sessions/session-accessor.ts"
|
||||
},
|
||||
{
|
||||
"name": "resolveAllowedModelRef",
|
||||
"wrapped": "src/agents/model-selection-resolve.ts",
|
||||
|
||||
@@ -63,7 +63,7 @@ function readFirstStringValue(
|
||||
return readTrimmedStringAlias(source, keys);
|
||||
}
|
||||
|
||||
function normalizeToolName(value: string): string | undefined {
|
||||
function normalizeToolPolicyName(value: string): string | undefined {
|
||||
const normalized = normalizeLowercaseStringOrEmpty(value);
|
||||
if (!normalized || normalized.length > 128) {
|
||||
return undefined;
|
||||
@@ -76,7 +76,7 @@ function parseToolNameFromTitle(title: string | undefined | null): string | unde
|
||||
return undefined;
|
||||
}
|
||||
const head = normalizeOptionalString(title.split(":", 1)[0]);
|
||||
return head ? normalizeToolName(head) : undefined;
|
||||
return head ? normalizeToolPolicyName(head) : undefined;
|
||||
}
|
||||
|
||||
function resolveToolNameForPermission(params: {
|
||||
@@ -93,8 +93,8 @@ function resolveToolNameForPermission(params: {
|
||||
const fromMeta = readFirstStringValue(toolMeta, ["toolName", "tool_name", "name"]);
|
||||
const fromRawInput = readFirstStringValue(rawInput, ["tool", "toolName", "tool_name", "name"]);
|
||||
const fromTitle = parseToolNameFromTitle(toolCall?.title);
|
||||
const metaName = fromMeta ? normalizeToolName(fromMeta) : undefined;
|
||||
const rawInputName = fromRawInput ? normalizeToolName(fromRawInput) : undefined;
|
||||
const metaName = fromMeta ? normalizeToolPolicyName(fromMeta) : undefined;
|
||||
const rawInputName = fromRawInput ? normalizeToolPolicyName(fromRawInput) : undefined;
|
||||
const titleName = fromTitle;
|
||||
if ((fromMeta && !metaName) || (fromRawInput && !rawInputName)) {
|
||||
return undefined;
|
||||
|
||||
@@ -133,7 +133,7 @@ export async function expectOversizedPromptRejected(params: { sessionId: string;
|
||||
|
||||
export type MockCallSource = { mock: { calls: Array<Array<unknown>> } };
|
||||
|
||||
export function requireRecord(value: unknown, label: string): Record<string, unknown> {
|
||||
export function requireAcpObject(value: unknown, label: string): Record<string, unknown> {
|
||||
if (!value || typeof value !== "object") {
|
||||
throw new Error(`expected ${label}`);
|
||||
}
|
||||
@@ -157,10 +157,10 @@ export function expectConfigOption(options: unknown, id: string, fields: Record<
|
||||
|
||||
export function sessionUpdatePayloads(source: MockCallSource, updateType?: string) {
|
||||
const payloads = source.mock.calls.map((call, index) => {
|
||||
const envelope = requireRecord(call[0], `session update envelope ${index}`);
|
||||
const envelope = requireAcpObject(call[0], `session update envelope ${index}`);
|
||||
return {
|
||||
sessionId: envelope.sessionId,
|
||||
update: requireRecord(envelope.update, `session update ${index}`),
|
||||
update: requireAcpObject(envelope.update, `session update ${index}`),
|
||||
};
|
||||
});
|
||||
if (!updateType) {
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
createSetSessionModeRequest,
|
||||
createSetSessionConfigOptionRequest,
|
||||
type MockCallSource,
|
||||
requireRecord,
|
||||
requireAcpObject,
|
||||
expectConfigOption,
|
||||
expectSessionUpdate,
|
||||
} from "./translator.bridge-test-helpers.js";
|
||||
@@ -352,7 +352,7 @@ describe("acp setSessionConfigOption bridge behavior", () => {
|
||||
(request as unknown as MockCallSource).mock.calls.some(
|
||||
([method, params]) =>
|
||||
method === "sessions.patch" &&
|
||||
requireRecord(params, "sessions.patch params").key === "bool-config-session",
|
||||
requireAcpObject(params, "sessions.patch params").key === "bool-config-session",
|
||||
),
|
||||
).toBe(false);
|
||||
|
||||
@@ -383,7 +383,7 @@ describe("acp setSessionConfigOption bridge behavior", () => {
|
||||
};
|
||||
}
|
||||
if (method === "sessions.patch") {
|
||||
expect(requireRecord(_params, "sessions.patch params")).toMatchObject({
|
||||
expect(requireAcpObject(_params, "sessions.patch params")).toMatchObject({
|
||||
key: "usage-inherit-session",
|
||||
responseUsage: null,
|
||||
});
|
||||
@@ -434,7 +434,7 @@ describe("acp setSessionConfigOption bridge behavior", () => {
|
||||
};
|
||||
}
|
||||
if (method === "sessions.patch") {
|
||||
expect(requireRecord(_params, "sessions.patch params")).toMatchObject({
|
||||
expect(requireAcpObject(_params, "sessions.patch params")).toMatchObject({
|
||||
key: "usage-off-session",
|
||||
responseUsage: "off",
|
||||
});
|
||||
|
||||
@@ -74,8 +74,8 @@ vi.mock("./agent-bundle-mcp-runtime.js", async (importOriginal) => {
|
||||
});
|
||||
|
||||
import {
|
||||
materializeRequesterScopedMcpToolsForHarnessRun,
|
||||
materializeStaticMcpToolsForScheduledHarnessRun,
|
||||
materializeRequesterScopedMcpToolsForHarnessRunCore,
|
||||
materializeStaticMcpToolsForScheduledHarnessRunCore,
|
||||
} from "./agent-bundle-mcp-harness.js";
|
||||
|
||||
function makeRuntime(params: { sessionId: string; requesterSenderId: string }): SessionMcpRuntime {
|
||||
@@ -152,14 +152,14 @@ beforeEach(() => {
|
||||
mocks.getAdvertisedScopedMcpCatalog.mockClear();
|
||||
});
|
||||
|
||||
describe("materializeStaticMcpToolsForScheduledHarnessRun", () => {
|
||||
describe("materializeStaticMcpToolsForScheduledHarnessRunCore", () => {
|
||||
it("materializes static tools without carrying requester identity and applies the stored cap", async () => {
|
||||
const runtime = makeRuntime({ sessionId: "scheduled", requesterSenderId: "unused" });
|
||||
delete runtime.requesterScope;
|
||||
runtime.peekCatalog()!.servers["user-mail"]!.codexApprovalMode = "approve";
|
||||
mocks.getOrCreateSessionMcpRuntime.mockResolvedValue(runtime);
|
||||
|
||||
const result = await materializeStaticMcpToolsForScheduledHarnessRun({
|
||||
const result = await materializeStaticMcpToolsForScheduledHarnessRunCore({
|
||||
sessionId: "scheduled",
|
||||
workspaceDir: "/workspace",
|
||||
toolsAllow: ["user-mail__inbox"],
|
||||
@@ -181,7 +181,7 @@ describe("materializeStaticMcpToolsForScheduledHarnessRun", () => {
|
||||
delete runtime.requesterScope;
|
||||
mocks.getOrCreateSessionMcpRuntime.mockResolvedValue(runtime);
|
||||
|
||||
const result = await materializeStaticMcpToolsForScheduledHarnessRun({
|
||||
const result = await materializeStaticMcpToolsForScheduledHarnessRunCore({
|
||||
sessionId: "scheduled-denied",
|
||||
workspaceDir: "/workspace",
|
||||
toolsAllow: ["read"],
|
||||
@@ -228,7 +228,7 @@ describe("materializeStaticMcpToolsForScheduledHarnessRun", () => {
|
||||
const callTool = vi.spyOn(runtime, "callTool");
|
||||
mocks.getOrCreateSessionMcpRuntime.mockResolvedValue(runtime);
|
||||
|
||||
const result = await materializeStaticMcpToolsForScheduledHarnessRun({
|
||||
const result = await materializeStaticMcpToolsForScheduledHarnessRunCore({
|
||||
sessionId: "scheduled-app",
|
||||
workspaceDir: "/workspace",
|
||||
toolsAllow: ["user-mail__show", "user-mail__app-only"],
|
||||
@@ -299,7 +299,7 @@ describe("materializeStaticMcpToolsForScheduledHarnessRun", () => {
|
||||
const callTool = vi.spyOn(runtime, "callTool");
|
||||
mocks.getOrCreateSessionMcpRuntime.mockResolvedValue(runtime);
|
||||
|
||||
const result = await materializeStaticMcpToolsForScheduledHarnessRun({
|
||||
const result = await materializeStaticMcpToolsForScheduledHarnessRunCore({
|
||||
sessionId: "scheduled-app-approval",
|
||||
workspaceDir: "/workspace",
|
||||
toolsAllow: ["*"],
|
||||
@@ -363,7 +363,7 @@ describe("materializeStaticMcpToolsForScheduledHarnessRun", () => {
|
||||
});
|
||||
mocks.getOrCreateSessionMcpRuntime.mockResolvedValue(runtime);
|
||||
|
||||
const result = await materializeStaticMcpToolsForScheduledHarnessRun({
|
||||
const result = await materializeStaticMcpToolsForScheduledHarnessRunCore({
|
||||
sessionId: "scheduled-app-yolo",
|
||||
workspaceDir: "/workspace",
|
||||
toolsAllow: ["*"],
|
||||
@@ -386,7 +386,7 @@ describe("materializeStaticMcpToolsForScheduledHarnessRun", () => {
|
||||
runtime.getCatalog = async () => emptyCatalog;
|
||||
mocks.getOrCreateSessionMcpRuntime.mockResolvedValue(runtime);
|
||||
|
||||
const result = await materializeStaticMcpToolsForScheduledHarnessRun({
|
||||
const result = await materializeStaticMcpToolsForScheduledHarnessRunCore({
|
||||
sessionId: "scheduled-empty",
|
||||
workspaceDir: "/workspace",
|
||||
toolsAllow: ["*"],
|
||||
@@ -417,7 +417,7 @@ describe("materializeStaticMcpToolsForScheduledHarnessRun", () => {
|
||||
runtime.getCatalog = async () => failedCatalog;
|
||||
mocks.getOrCreateSessionMcpRuntime.mockResolvedValue(runtime);
|
||||
|
||||
const result = await materializeStaticMcpToolsForScheduledHarnessRun({
|
||||
const result = await materializeStaticMcpToolsForScheduledHarnessRunCore({
|
||||
sessionId: "scheduled-diagnostic",
|
||||
workspaceDir: "/workspace",
|
||||
toolsAllow: ["*"],
|
||||
@@ -436,7 +436,7 @@ describe("materializeStaticMcpToolsForScheduledHarnessRun", () => {
|
||||
mocks.getOrCreateSessionMcpRuntime.mockResolvedValue(runtime);
|
||||
const callTool = vi.spyOn(runtime, "callTool");
|
||||
|
||||
const result = await materializeStaticMcpToolsForScheduledHarnessRun({
|
||||
const result = await materializeStaticMcpToolsForScheduledHarnessRunCore({
|
||||
sessionId: "scheduled-prompt",
|
||||
workspaceDir: "/workspace",
|
||||
toolsAllow: ["user-mail__inbox"],
|
||||
@@ -456,7 +456,7 @@ describe("materializeStaticMcpToolsForScheduledHarnessRun", () => {
|
||||
mocks.getOrCreateSessionMcpRuntime.mockResolvedValue(runtime);
|
||||
const callTool = vi.spyOn(runtime, "callTool");
|
||||
|
||||
const result = await materializeStaticMcpToolsForScheduledHarnessRun({
|
||||
const result = await materializeStaticMcpToolsForScheduledHarnessRunCore({
|
||||
sessionId: "scheduled-yolo",
|
||||
workspaceDir: "/workspace",
|
||||
toolsAllow: ["user-mail__inbox"],
|
||||
@@ -482,7 +482,7 @@ describe("materializeStaticMcpToolsForScheduledHarnessRun", () => {
|
||||
mocks.getOrCreateSessionMcpRuntime.mockResolvedValue(runtime);
|
||||
const callTool = vi.spyOn(runtime, "callTool");
|
||||
|
||||
const result = await materializeStaticMcpToolsForScheduledHarnessRun({
|
||||
const result = await materializeStaticMcpToolsForScheduledHarnessRunCore({
|
||||
sessionId: `scheduled-${mode}`,
|
||||
workspaceDir: "/workspace",
|
||||
toolsAllow: ["user-mail__inbox"],
|
||||
@@ -499,7 +499,7 @@ describe("materializeStaticMcpToolsForScheduledHarnessRun", () => {
|
||||
mocks.getOrCreateSessionMcpRuntime.mockResolvedValue(runtime);
|
||||
const callTool = vi.spyOn(runtime, "callTool");
|
||||
|
||||
const result = await materializeStaticMcpToolsForScheduledHarnessRun({
|
||||
const result = await materializeStaticMcpToolsForScheduledHarnessRunCore({
|
||||
sessionId: "scheduled-unknown",
|
||||
workspaceDir: "/workspace",
|
||||
toolsAllow: ["user-mail__inbox"],
|
||||
@@ -518,10 +518,10 @@ afterEach(() => {
|
||||
mcpUiResourceTesting.clearViewStore();
|
||||
});
|
||||
|
||||
describe("materializeRequesterScopedMcpToolsForHarnessRun", () => {
|
||||
describe("materializeRequesterScopedMcpToolsForHarnessRunCore", () => {
|
||||
it("returns undefined before any requester resolves", async () => {
|
||||
mocks.setResolveImpl(async () => undefined);
|
||||
const result = await materializeRequesterScopedMcpToolsForHarnessRun({
|
||||
const result = await materializeRequesterScopedMcpToolsForHarnessRunCore({
|
||||
sessionId: "session-empty",
|
||||
workspaceDir: "/workspace",
|
||||
requesterSenderId: "guest",
|
||||
@@ -538,7 +538,7 @@ describe("materializeRequesterScopedMcpToolsForHarnessRun", () => {
|
||||
});
|
||||
|
||||
await expect(
|
||||
materializeRequesterScopedMcpToolsForHarnessRun({
|
||||
materializeRequesterScopedMcpToolsForHarnessRunCore({
|
||||
sessionId: "session-cleanup",
|
||||
workspaceDir: "/workspace",
|
||||
requesterSenderId: "authed",
|
||||
@@ -559,7 +559,7 @@ describe("materializeRequesterScopedMcpToolsForHarnessRun", () => {
|
||||
});
|
||||
});
|
||||
|
||||
const authed = await materializeRequesterScopedMcpToolsForHarnessRun({
|
||||
const authed = await materializeRequesterScopedMcpToolsForHarnessRunCore({
|
||||
sessionId: "session-stable",
|
||||
workspaceDir: "/workspace",
|
||||
requesterSenderId: "authed",
|
||||
@@ -575,7 +575,7 @@ describe("materializeRequesterScopedMcpToolsForHarnessRun", () => {
|
||||
});
|
||||
await authed!.dispose();
|
||||
|
||||
const guest = await materializeRequesterScopedMcpToolsForHarnessRun({
|
||||
const guest = await materializeRequesterScopedMcpToolsForHarnessRunCore({
|
||||
sessionId: "session-stable",
|
||||
workspaceDir: "/workspace",
|
||||
requesterSenderId: "guest",
|
||||
@@ -602,7 +602,7 @@ describe("materializeRequesterScopedMcpToolsForHarnessRun", () => {
|
||||
}),
|
||||
);
|
||||
|
||||
const result = await materializeRequesterScopedMcpToolsForHarnessRun({
|
||||
const result = await materializeRequesterScopedMcpToolsForHarnessRunCore({
|
||||
sessionId: "session-policy",
|
||||
workspaceDir: "/workspace",
|
||||
requesterSenderId: "authed",
|
||||
@@ -630,12 +630,12 @@ describe("materializeRequesterScopedMcpToolsForHarnessRun", () => {
|
||||
});
|
||||
});
|
||||
|
||||
const alice = await materializeRequesterScopedMcpToolsForHarnessRun({
|
||||
const alice = await materializeRequesterScopedMcpToolsForHarnessRunCore({
|
||||
sessionId: "session-route",
|
||||
workspaceDir: "/workspace",
|
||||
requesterSenderId: "alice",
|
||||
});
|
||||
const bob = await materializeRequesterScopedMcpToolsForHarnessRun({
|
||||
const bob = await materializeRequesterScopedMcpToolsForHarnessRunCore({
|
||||
sessionId: "session-route",
|
||||
workspaceDir: "/workspace",
|
||||
requesterSenderId: "bob",
|
||||
|
||||
@@ -160,7 +160,7 @@ function buildCatalogTools(
|
||||
* Materialize only static configured MCP for an authenticated scheduled turn.
|
||||
* No requester identity is accepted here, so requester resolvers stay unreachable.
|
||||
*/
|
||||
export async function materializeStaticMcpToolsForScheduledHarnessRun(
|
||||
export async function materializeStaticMcpToolsForScheduledHarnessRunCore(
|
||||
params: Omit<
|
||||
MaterializeRequesterScopedMcpToolsForHarnessRunParams,
|
||||
"requesterSenderId" | "agentAccountId" | "messageChannel"
|
||||
@@ -252,7 +252,7 @@ export async function materializeStaticMcpToolsForScheduledHarnessRun(
|
||||
* Updates the session advertised-catalog cache when a requester resolves a catalog.
|
||||
* Before any requester resolves in the session, returns undefined (nothing to advertise).
|
||||
*/
|
||||
export async function materializeRequesterScopedMcpToolsForHarnessRun(
|
||||
export async function materializeRequesterScopedMcpToolsForHarnessRunCore(
|
||||
params: MaterializeRequesterScopedMcpToolsForHarnessRunParams,
|
||||
): Promise<RequesterScopedHarnessMcpTools | undefined> {
|
||||
const scopedRuntime = await getOrCreateRequesterScopedMcpRuntime({
|
||||
|
||||
@@ -6,7 +6,7 @@ import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vite
|
||||
import type { SessionEntry } from "../config/sessions.js";
|
||||
import { formatSqliteSessionFileMarker } from "../config/sessions/legacy-sqlite-marker.js";
|
||||
import {
|
||||
listSessionEntries,
|
||||
listSessionEntriesCore,
|
||||
loadTranscriptEvents,
|
||||
replaceSessionEntry,
|
||||
} from "../config/sessions/session-accessor.js";
|
||||
@@ -304,7 +304,7 @@ function requireStorePath(): string {
|
||||
}
|
||||
|
||||
function findStoredSessionEntry(sessionKey: string): SessionEntry | undefined {
|
||||
return listSessionEntries({ storePath: requireStorePath() }).find(
|
||||
return listSessionEntriesCore({ storePath: requireStorePath() }).find(
|
||||
(candidate) => candidate.sessionKey === sessionKey,
|
||||
)?.entry;
|
||||
}
|
||||
@@ -443,7 +443,7 @@ describe("agentCommand compaction transcript rotation", () => {
|
||||
});
|
||||
|
||||
const storeAfterRotation = Object.fromEntries(
|
||||
listSessionEntries({ storePath }).map(({ entry, sessionKey }) => [sessionKey, entry]),
|
||||
listSessionEntriesCore({ storePath }).map(({ entry, sessionKey }) => [sessionKey, entry]),
|
||||
);
|
||||
const entriesAfterRotation = Object.entries(storeAfterRotation);
|
||||
expect(entriesAfterRotation).toHaveLength(1);
|
||||
@@ -977,7 +977,7 @@ describe("agentCommand compaction transcript rotation", () => {
|
||||
sessionId: "rotated-session",
|
||||
});
|
||||
const persisted = Object.fromEntries(
|
||||
listSessionEntries({ storePath }).map(({ entry, sessionKey: key }) => [key, entry]),
|
||||
listSessionEntriesCore({ storePath }).map(({ entry, sessionKey: key }) => [key, entry]),
|
||||
);
|
||||
expect(persisted[sessionKey]).toMatchObject({
|
||||
sessionId: "rotated-session",
|
||||
|
||||
@@ -38,7 +38,7 @@ import {
|
||||
getInternalToolExecutionPreparer,
|
||||
} from "./runtime/internal-hooks.js";
|
||||
import type { ToolDefinition } from "./sessions/index.js";
|
||||
import { normalizeToolName } from "./tool-policy.js";
|
||||
import { normalizeToolPolicyName } from "./tool-policy.js";
|
||||
import { jsonResult, payloadTextResult, ToolInputError } from "./tools/common.js";
|
||||
|
||||
type AnyAgentTool = AgentTool;
|
||||
@@ -357,7 +357,7 @@ export function findClientToolNameConflicts(params: {
|
||||
for (const name of params.existingToolNames ?? []) {
|
||||
const trimmed = name.trim();
|
||||
if (trimmed) {
|
||||
existingNormalized.add(normalizeToolName(trimmed));
|
||||
existingNormalized.add(normalizeToolPolicyName(trimmed));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -368,7 +368,7 @@ export function findClientToolNameConflicts(params: {
|
||||
if (!rawName) {
|
||||
continue;
|
||||
}
|
||||
const normalizedName = normalizeToolName(rawName);
|
||||
const normalizedName = normalizeToolPolicyName(rawName);
|
||||
if (existingNormalized.has(normalizedName)) {
|
||||
conflicts.add(rawName);
|
||||
}
|
||||
@@ -400,7 +400,7 @@ export function toToolDefinitions(
|
||||
): ToolDefinition[] {
|
||||
return tools.map((tool) => {
|
||||
const name = tool.name || "tool";
|
||||
const normalizedName = normalizeToolName(name);
|
||||
const normalizedName = normalizeToolPolicyName(name);
|
||||
const beforeHookWrapped = isToolWrappedWithBeforeToolCallHook(tool);
|
||||
const sourcePreparer = getInternalToolExecutionPreparer(tool);
|
||||
const definition = {
|
||||
|
||||
@@ -48,7 +48,7 @@ import { normalizeFileToolPathParam } from "./agent-tools.params.js";
|
||||
import { BEFORE_TOOL_CALL_SOURCE_TOOL } from "./before-tool-call-metadata.js";
|
||||
import { getChannelAgentToolMeta } from "./channel-tools.js";
|
||||
import { resolveAgentRunAbortLifecycleFields } from "./run-termination.js";
|
||||
import { normalizeToolName } from "./tool-policy.js";
|
||||
import { normalizeToolPolicyName } from "./tool-policy.js";
|
||||
import {
|
||||
resolveToolExecutionErrorKind,
|
||||
resolveToolResultFailureKind,
|
||||
@@ -391,7 +391,7 @@ export function findSkillUsageMatch(params: {
|
||||
}): SkillUsageMatch | undefined {
|
||||
const command = params.ctx?.skillCommand;
|
||||
if (command) {
|
||||
const commandToolName = normalizeToolName(command.toolName ?? params.toolName);
|
||||
const commandToolName = normalizeToolPolicyName(command.toolName ?? params.toolName);
|
||||
if (!commandToolName || commandToolName === params.toolName) {
|
||||
const skillSource = resolveSkillTelemetrySourceValue(command.skillSource);
|
||||
const snapshotMatch = findResolvedSkillUsageMatch({
|
||||
|
||||
@@ -51,7 +51,7 @@ import {
|
||||
normalizeCodeModeExecBeforeHookParamsForToolKind,
|
||||
} from "./code-mode-control-tools.js";
|
||||
import { admitSingleToolCallLoop } from "./tool-loop-admission.js";
|
||||
import { normalizeToolName } from "./tool-policy.js";
|
||||
import { normalizeToolPolicyName } from "./tool-policy.js";
|
||||
|
||||
const BEFORE_TOOL_CALL_HOOK_FAILURE_REASON =
|
||||
"Tool call blocked because before_tool_call hook failed";
|
||||
@@ -81,7 +81,7 @@ export function consumeFinalClientVoiceToolConfirmation(args: {
|
||||
agentId: voiceRun?.agentId,
|
||||
voiceSessionId: voiceRun?.voiceSessionId,
|
||||
runId: args.ctx?.runId,
|
||||
toolName: normalizeToolName(args.toolName || "tool"),
|
||||
toolName: normalizeToolPolicyName(args.toolName || "tool"),
|
||||
toolParams: args.params,
|
||||
...(voiceRun ? { isConfirmable: () => isClientVoiceSessionConfirmable(voiceRun) } : {}),
|
||||
});
|
||||
@@ -97,7 +97,7 @@ export async function runBeforeToolCallHook(args: {
|
||||
signal?: AbortSignal;
|
||||
approvalMode?: "request" | "report" | "deny" | "defer";
|
||||
}): Promise<HookOutcome> {
|
||||
const toolName = normalizeToolName(args.toolName || "tool");
|
||||
const toolName = normalizeToolPolicyName(args.toolName || "tool");
|
||||
const params = args.params;
|
||||
let releaseArgumentChurnPolicyWait: (() => void) | undefined;
|
||||
|
||||
|
||||
@@ -73,7 +73,7 @@ import {
|
||||
} from "./code-mode-control-tools.js";
|
||||
import { attachInternalToolExecutionPreparer } from "./runtime/internal-hooks.js";
|
||||
import { buildToolMutationState } from "./tool-mutation.js";
|
||||
import { normalizeToolName } from "./tool-policy.js";
|
||||
import { normalizeToolPolicyName } from "./tool-policy.js";
|
||||
import {
|
||||
formatToolExecutionErrorMessage,
|
||||
isTrustedToolExecutionPreflightError,
|
||||
@@ -303,7 +303,7 @@ export function wrapToolWithBeforeToolCallHook(
|
||||
}
|
||||
const toolCallOrdinal = ctx?.allocateToolOutcomeOrdinal?.(toolCallId);
|
||||
const preExecutionStartedAt = Date.now();
|
||||
const normalizedToolName = normalizeToolName(toolName || "tool");
|
||||
const normalizedToolName = normalizeToolPolicyName(toolName || "tool");
|
||||
const trace =
|
||||
hookOptions.emitDiagnostics && ctx?.trace
|
||||
? freezeDiagnosticTraceContext(createChildDiagnosticTraceContext(ctx.trace))
|
||||
|
||||
@@ -55,7 +55,7 @@ import { createAgentToolsSandboxContext } from "./test-helpers/agent-tools-sandb
|
||||
import { stubTool } from "./test-helpers/fast-tool-stubs.js";
|
||||
import { createHostSandboxFsBridge } from "./test-helpers/host-sandbox-fs-bridge.js";
|
||||
import { buildEmptyExplicitToolAllowlistError } from "./tool-allowlist-guard.js";
|
||||
import { DEFAULT_PLUGIN_TOOLS_ALLOWLIST_ENTRY, normalizeToolName } from "./tool-policy.js";
|
||||
import { DEFAULT_PLUGIN_TOOLS_ALLOWLIST_ENTRY, normalizeToolPolicyName } from "./tool-policy.js";
|
||||
import { replaceWithEffectiveCronCreatorToolAllowlist } from "./tools/cron-tool.js";
|
||||
import { getGatewayToolCallerIdentity } from "./tools/gateway-caller-context.js";
|
||||
|
||||
@@ -127,8 +127,8 @@ function expectNoSubagentControlTools(tools: ReturnType<typeof createOpenClawCod
|
||||
}
|
||||
|
||||
function applyRuntimeToolsAllow<T extends { name: string }>(tools: T[], toolsAllow: string[]) {
|
||||
const allowSet = new Set(toolsAllow.map((name) => normalizeToolName(name)));
|
||||
return tools.filter((tool) => allowSet.has(normalizeToolName(tool.name)));
|
||||
const allowSet = new Set(toolsAllow.map((name) => normalizeToolPolicyName(name)));
|
||||
return tools.filter((tool) => allowSet.has(normalizeToolPolicyName(tool.name)));
|
||||
}
|
||||
|
||||
type OpenClawCodingTool = ReturnType<typeof createOpenClawCodingTools>[number];
|
||||
|
||||
@@ -86,7 +86,7 @@ import { applyToolPolicyPipeline } from "./tool-policy-pipeline.js";
|
||||
import {
|
||||
expandToolGroups,
|
||||
hasRestrictiveAllowPolicy,
|
||||
normalizeToolName,
|
||||
normalizeToolPolicyName,
|
||||
replaceWithEffectiveToolAllowlist,
|
||||
} from "./tool-policy.js";
|
||||
import {
|
||||
@@ -466,7 +466,7 @@ function createOpenClawCodingToolsInternal(options?: OpenClawCodingToolsOptions)
|
||||
const runtimeToolAllowlistIncludesMessage = expandToolGroups(
|
||||
options?.runtimeToolAllowlist ?? [],
|
||||
).some((toolName) => {
|
||||
const normalized = normalizeToolName(toolName);
|
||||
const normalized = normalizeToolPolicyName(toolName);
|
||||
return normalized === "*" || normalized === "message";
|
||||
});
|
||||
// The verified requester profile owns completion authority; its delivery grant
|
||||
|
||||
@@ -9,7 +9,7 @@ import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import {
|
||||
deleteSessionEntryLifecycle,
|
||||
loadSessionEntry,
|
||||
patchSessionEntry,
|
||||
patchSessionEntryCore,
|
||||
replaceSessionEntry,
|
||||
} from "../../config/sessions/session-accessor.js";
|
||||
import type { SessionEntry } from "../../config/sessions/types.js";
|
||||
@@ -643,7 +643,7 @@ describe("resolveSessionAuthProfileOverride", () => {
|
||||
expect(sessionEntry).toBeDefined();
|
||||
const sessionStore = { [sessionKey]: sessionEntry! };
|
||||
|
||||
await patchSessionEntry(scope, () => ({ label: "renamed", pinnedAt: undefined }));
|
||||
await patchSessionEntryCore(scope, () => ({ label: "renamed", pinnedAt: undefined }));
|
||||
await clearSessionAuthProfileOverride({
|
||||
sessionEntry: sessionEntry!,
|
||||
sessionStore,
|
||||
@@ -700,7 +700,7 @@ describe("resolveSessionAuthProfileOverride", () => {
|
||||
expect(sessionEntry).toBeDefined();
|
||||
const sessionStore = { [sessionKey]: sessionEntry! };
|
||||
|
||||
await patchSessionEntry(scope, () => ({ label: "renamed", pinnedAt: undefined }));
|
||||
await patchSessionEntryCore(scope, () => ({ label: "renamed", pinnedAt: undefined }));
|
||||
const resolved = await resolveOpenAiSession({
|
||||
agentDir,
|
||||
sessionEntry: sessionEntry!,
|
||||
@@ -740,7 +740,7 @@ describe("resolveSessionAuthProfileOverride", () => {
|
||||
const sessionEntry = loadSessionEntry({ ...scope, readConsistency: "latest" });
|
||||
expect(sessionEntry).toBeDefined();
|
||||
const sessionStore = { [sessionKey]: sessionEntry! };
|
||||
await patchSessionEntry(scope, () => ({ label: "renamed", pinnedAt: undefined }));
|
||||
await patchSessionEntryCore(scope, () => ({ label: "renamed", pinnedAt: undefined }));
|
||||
|
||||
const resolved = await resolveOpenAiSession({
|
||||
agentDir,
|
||||
@@ -803,7 +803,7 @@ describe("resolveSessionAuthProfileOverride", () => {
|
||||
if (persisted) {
|
||||
await replaceSessionEntry(scope, sessionEntry);
|
||||
sessionEntry = loadSessionEntry({ ...scope, readConsistency: "latest" })!;
|
||||
await patchSessionEntry(scope, () => ({
|
||||
await patchSessionEntryCore(scope, () => ({
|
||||
...latestEntry,
|
||||
authProfileOverrideSource: source,
|
||||
pinnedAt: undefined,
|
||||
|
||||
@@ -113,7 +113,7 @@ async function persistSessionAuthProfileOverrideState(params: {
|
||||
}
|
||||
const persisted = await (
|
||||
await loadSessionAccessor()
|
||||
).patchSessionEntry(
|
||||
).patchSessionEntryCore(
|
||||
{ storePath, sessionKey },
|
||||
(current) => {
|
||||
// Compare inside the canonical SQLite writer so a concurrent /model pin
|
||||
|
||||
@@ -33,7 +33,7 @@ import { processSchema } from "./bash-tools.schemas.js";
|
||||
import {
|
||||
clampWithDefault,
|
||||
deriveSessionName,
|
||||
pad,
|
||||
padProcessStatus,
|
||||
readEnvInt,
|
||||
sliceLogLines,
|
||||
truncateMiddle,
|
||||
@@ -356,7 +356,7 @@ export function createProcessTool(
|
||||
.map((s) => {
|
||||
const label = s.name ? truncateMiddle(s.name, 80) : truncateMiddle(s.command, 120);
|
||||
const marker = "waitingForInput" in s && s.waitingForInput ? " [input-wait]" : "";
|
||||
return `${s.sessionId} ${pad(s.status, 9)} ${
|
||||
return `${s.sessionId} ${padProcessStatus(s.status, 9)} ${
|
||||
formatDurationCompact(s.runtimeMs) ?? "n/a"
|
||||
}${marker} :: ${label}`;
|
||||
});
|
||||
|
||||
@@ -231,7 +231,7 @@ function stripQuotes(value: string): string {
|
||||
}
|
||||
|
||||
/** Right-pads a string for aligned plain-text process output. */
|
||||
export function pad(str: string, width: number) {
|
||||
export function padProcessStatus(str: string, width: number) {
|
||||
if (str.length >= width) {
|
||||
return str;
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
} from "../config/sessions.js";
|
||||
import { parseSqliteSessionFileMarker } from "../config/sessions/legacy-sqlite-marker.js";
|
||||
import {
|
||||
listSessionEntries,
|
||||
listSessionEntriesCore,
|
||||
loadSessionEntry,
|
||||
loadTranscriptEvents,
|
||||
} from "../config/sessions/session-accessor.js";
|
||||
@@ -125,7 +125,7 @@ export async function readBtwTranscriptMessages(params: {
|
||||
const storePath = completeTarget ? params.storePath : (params.storePath ?? marker?.storePath);
|
||||
const markerMatches =
|
||||
marker && !completeTarget
|
||||
? listSessionEntries({
|
||||
? listSessionEntriesCore({
|
||||
agentId: marker.agentId,
|
||||
storePath: marker.storePath,
|
||||
}).filter(({ entry }) => entry.sessionId === marker.sessionId)
|
||||
|
||||
@@ -3,7 +3,7 @@ import { isRecord } from "../../packages/normalization-core/src/record-coerce.js
|
||||
import type { BundleMcpServerConfig } from "../plugins/bundle-mcp.js";
|
||||
export { isRecord } from "../../packages/normalization-core/src/record-coerce.js";
|
||||
|
||||
export function normalizeStringRecord(value: unknown): Record<string, string> | undefined {
|
||||
export function normalizeMcpStringRecord(value: unknown): Record<string, string> | undefined {
|
||||
if (!isRecord(value)) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -47,7 +47,7 @@ export function normalizeBundleMcpServerConfig(
|
||||
if (args) {
|
||||
next.args = args;
|
||||
}
|
||||
const env = normalizeStringRecord(server.env);
|
||||
const env = normalizeMcpStringRecord(server.env);
|
||||
if (env) {
|
||||
next.env = env;
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
resolveExpiresAtMsFromDurationMs,
|
||||
} from "@openclaw/normalization-core/number-coercion";
|
||||
import { resolveOsHomeRelativePath } from "../infra/home-dir.js";
|
||||
import { loadJsonFile } from "../infra/json-file.js";
|
||||
import { loadJsonFileThroughSymlink } from "../infra/json-file.js";
|
||||
import { createSubsystemLogger } from "../logging/subsystem.js";
|
||||
import type { OAuthProvider } from "./auth-profiles/types.js";
|
||||
|
||||
@@ -415,7 +415,7 @@ function readPortalCliOauthCredentials<TProvider extends string>(
|
||||
credPath: string,
|
||||
provider: TProvider,
|
||||
): { type: "oauth"; provider: TProvider; access: string; refresh: string; expires: number } | null {
|
||||
const raw = loadJsonFile(credPath);
|
||||
const raw = loadJsonFileThroughSymlink(credPath);
|
||||
if (!raw || typeof raw !== "object") {
|
||||
return null;
|
||||
}
|
||||
@@ -430,7 +430,7 @@ function readMiniMaxCliCredentials(options?: { homeDir?: string }): MiniMaxCliCr
|
||||
|
||||
function readGeminiCliCredentials(options?: { homeDir?: string }): GeminiCliCredential | null {
|
||||
const credPath = resolveGeminiCliCredentialsPath(options?.homeDir);
|
||||
const raw = loadJsonFile(credPath);
|
||||
const raw = loadJsonFileThroughSymlink(credPath);
|
||||
if (!raw || typeof raw !== "object") {
|
||||
return null;
|
||||
}
|
||||
@@ -477,7 +477,7 @@ function readClaudeCliKeychainCredentials(
|
||||
}
|
||||
|
||||
function readClaudeCliUserApiKeyHelperCredential(homeDir?: string): ClaudeCliCredential | null {
|
||||
const raw = loadJsonFile(resolveClaudeCliUserSettingsPath(homeDir));
|
||||
const raw = loadJsonFileThroughSymlink(resolveClaudeCliUserSettingsPath(homeDir));
|
||||
if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
|
||||
return null;
|
||||
}
|
||||
@@ -497,7 +497,7 @@ function readClaudeCliUserApiKeyHelperCredential(homeDir?: string): ClaudeCliCre
|
||||
// later account switch could mislabel another credential's quota.
|
||||
function readClaudeCliAccountEmail(homeDir?: string): string | undefined {
|
||||
const baseDir = resolveOsHomeRelativePath(homeDir ?? "~");
|
||||
const raw = loadJsonFile(path.join(baseDir, ".claude.json"));
|
||||
const raw = loadJsonFileThroughSymlink(path.join(baseDir, ".claude.json"));
|
||||
if (!raw || typeof raw !== "object") {
|
||||
return undefined;
|
||||
}
|
||||
@@ -547,7 +547,7 @@ function readClaudeCliCredentials(options?: {
|
||||
}
|
||||
|
||||
const credPath = resolveClaudeCliCredentialsPath(options?.homeDir);
|
||||
const raw = loadJsonFile(credPath);
|
||||
const raw = loadJsonFileThroughSymlink(credPath);
|
||||
if (!raw || typeof raw !== "object") {
|
||||
return null;
|
||||
}
|
||||
@@ -624,7 +624,7 @@ export function readCodexCliActiveApiKey(options?: {
|
||||
|
||||
const candidates: CodexCliApiKeyCredential[] = [];
|
||||
const authPath = path.join(codexHome, CODEX_CLI_AUTH_FILENAME);
|
||||
const raw = loadJsonFile(authPath);
|
||||
const raw = loadJsonFileThroughSymlink(authPath);
|
||||
if (raw && typeof raw === "object") {
|
||||
const fileCredential = parseCodexApiKeyCredential(raw as Record<string, unknown>);
|
||||
if (fileCredential) {
|
||||
@@ -684,7 +684,7 @@ function readCodexCliCredentials(options?: {
|
||||
}
|
||||
|
||||
const authPath = path.join(resolveCodexHomePath(options?.codexHome), CODEX_CLI_AUTH_FILENAME);
|
||||
const raw = loadJsonFile(authPath);
|
||||
const raw = loadJsonFileThroughSymlink(authPath);
|
||||
if (!raw || typeof raw !== "object") {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import { setReplyPayloadMetadata, type ReplyPayload } from "../auto-reply/reply-payload.js";
|
||||
import { SILENT_REPLY_TOKEN } from "../auto-reply/tokens.js";
|
||||
import { resolveStorePath } from "../config/sessions/paths.js";
|
||||
import { patchSessionEntry } from "../config/sessions/session-accessor.js";
|
||||
import { patchSessionEntryCore } from "../config/sessions/session-accessor.js";
|
||||
import { appendExactAssistantMessageToSessionTranscript } from "../config/sessions/transcript.js";
|
||||
import { buildGenericCliContextEngineHostSupport } from "../context-engine/host-compat.js";
|
||||
import {
|
||||
@@ -1108,7 +1108,7 @@ export async function runPreparedCliAgent(
|
||||
agentId,
|
||||
}),
|
||||
};
|
||||
const persistedEntry = await patchSessionEntry(
|
||||
const persistedEntry = await patchSessionEntryCore(
|
||||
sessionTarget,
|
||||
(entry, patchContext) => {
|
||||
if (patchContext.existingEntry && entry.sessionId !== sessionTarget.sessionId) {
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
decodeHeaderEnvPlaceholder,
|
||||
isRecord,
|
||||
normalizeBundleMcpServerConfig,
|
||||
normalizeStringRecord,
|
||||
normalizeMcpStringRecord,
|
||||
} from "../bundle-mcp-adapter.js";
|
||||
import { withOpenClawMcpCaptureHeader, writeTemporaryBundleMcpJson } from "./bundle-mcp-runtime.js";
|
||||
|
||||
@@ -81,7 +81,7 @@ function normalizeGeminiServerConfig(
|
||||
deniedTools: readonly string[] | undefined,
|
||||
): Record<string, unknown> {
|
||||
const next = normalizeBundleMcpServerConfig(server, GEMINI_MCP_SERVER_FIELDS);
|
||||
const headers = normalizeStringRecord(server.headers);
|
||||
const headers = normalizeMcpStringRecord(server.headers);
|
||||
if (headers) {
|
||||
next.headers = Object.fromEntries(
|
||||
Object.entries(headers).map(([name, value]) => [
|
||||
|
||||
@@ -114,7 +114,7 @@ import { collectRuntimeChannelCapabilities } from "../runtime-capabilities.js";
|
||||
import { ensureSandboxWorkspaceForSession } from "../sandbox.js";
|
||||
import { buildSystemPromptReport } from "../system-prompt-report.js";
|
||||
import { appendModelIdentitySystemPrompt, buildModelIdentityPromptLine } from "../system-prompt.js";
|
||||
import { expandToolGroups, normalizeToolName } from "../tool-policy.js";
|
||||
import { expandToolGroups, normalizeToolPolicyName } from "../tool-policy.js";
|
||||
import { redactRunIdentifier, resolveRunWorkspaceDir } from "../workspace-run.js";
|
||||
import {
|
||||
DEFAULT_BOOTSTRAP_FILENAME,
|
||||
@@ -479,13 +479,13 @@ export async function prepareCliRunContext(
|
||||
`CLI backend ${backendResolved.id} received conflicting runtime tool policies`,
|
||||
);
|
||||
}
|
||||
if (params.toolsAllow.some((toolName) => normalizeToolName(toolName) === "*")) {
|
||||
if (params.toolsAllow.some((toolName) => normalizeToolPolicyName(toolName) === "*")) {
|
||||
params = { ...params, toolsAllow: undefined };
|
||||
} else {
|
||||
runtimeToolsAllowPolicy = [...params.toolsAllow];
|
||||
const fallbackOpenClawTools = uniqueStrings(
|
||||
expandToolGroups(params.toolsAllow)
|
||||
.map((toolName) => normalizeToolName(toolName))
|
||||
.map((toolName) => normalizeToolPolicyName(toolName))
|
||||
.filter(Boolean),
|
||||
);
|
||||
if (
|
||||
@@ -795,7 +795,7 @@ export async function prepareCliRunContext(
|
||||
);
|
||||
const promptBuildRestrictsTools =
|
||||
promptBuildToolsAllow !== undefined &&
|
||||
!promptBuildToolsAllow.some((toolName) => normalizeToolName(toolName) === "*");
|
||||
!promptBuildToolsAllow.some((toolName) => normalizeToolPolicyName(toolName) === "*");
|
||||
const isClaudeCli = isClaudeCliBackendId(params.provider);
|
||||
const requestedContextModelId = isClaudeCli ? resolveClaudeCliContextModelId(modelId) : modelId;
|
||||
const normalizedContextModelId = isClaudeCli
|
||||
@@ -1055,7 +1055,7 @@ export async function prepareCliRunContext(
|
||||
: hookFilteredProjectedTools;
|
||||
const promptTools = bundleMcpEnabled ? projectedTools : [];
|
||||
const messageToolAvailable = promptTools.some(
|
||||
(tool) => normalizeToolName(tool.name) === "message",
|
||||
(tool) => normalizeToolPolicyName(tool.name) === "message",
|
||||
);
|
||||
const resultContentSourceByToolName = new Map(
|
||||
promptTools.flatMap((tool) =>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { CliBackendToolAvailability } from "../../plugins/cli-backend.types.js";
|
||||
import { normalizeToolName } from "../tool-policy.js";
|
||||
import { normalizeToolPolicyName } from "../tool-policy.js";
|
||||
|
||||
/** Transport prefix CLI harnesses use for loopback OpenClaw MCP tool names. */
|
||||
const OPENCLAW_MCP_TOOL_PREFIX = "mcp__openclaw__";
|
||||
@@ -31,7 +31,7 @@ export function resolveCliRuntimeToolsAllow(
|
||||
if (toolsAllow === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
return toolsAllow.some((toolName) => normalizeToolName(toolName) === "*")
|
||||
return toolsAllow.some((toolName) => normalizeToolPolicyName(toolName) === "*")
|
||||
? undefined
|
||||
: toolsAllow;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* exec-compatible before-tool-call surface.
|
||||
*/
|
||||
import { isPlainObject } from "../utils.js";
|
||||
import { normalizeToolName } from "./tool-policy.js";
|
||||
import { normalizeToolPolicyName } from "./tool-policy.js";
|
||||
import type { AnyAgentTool } from "./tools/common.js";
|
||||
|
||||
/** Model-visible Code Mode exec tool name. */
|
||||
@@ -44,7 +44,9 @@ export function isCodeModeControlTool(tool: object): boolean {
|
||||
}
|
||||
|
||||
function isCodeModeExecTool(tool: AnyAgentTool): boolean {
|
||||
return isCodeModeControlTool(tool) && normalizeToolName(tool.name) === CODE_MODE_EXEC_TOOL_NAME;
|
||||
return (
|
||||
isCodeModeControlTool(tool) && normalizeToolPolicyName(tool.name) === CODE_MODE_EXEC_TOOL_NAME
|
||||
);
|
||||
}
|
||||
|
||||
function resolveCodeModeExecToolInputKind(params: unknown): CodeModeExecToolInputKind | undefined {
|
||||
|
||||
@@ -4,7 +4,10 @@ import fs from "node:fs/promises";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { buildCodexMcpServersConfig, loadCodexBundleMcpThreadConfig } from "./codex-mcp-config.js";
|
||||
import {
|
||||
buildCodexMcpServersConfig,
|
||||
loadCodexBundleMcpThreadConfigCore,
|
||||
} from "./codex-mcp-config.js";
|
||||
import { testing as resolverTesting } from "./mcp-connection-resolver.js";
|
||||
|
||||
const mocks = vi.hoisted(() => ({
|
||||
@@ -94,11 +97,11 @@ describe("buildCodexMcpServersConfig", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("loadCodexBundleMcpThreadConfig", () => {
|
||||
describe("loadCodexBundleMcpThreadConfigCore", () => {
|
||||
it("forwards a prepared manifest registry to bundle loading", () => {
|
||||
const manifestRegistry = { plugins: [] };
|
||||
|
||||
loadCodexBundleMcpThreadConfig({ workspaceDir: "/workspace", manifestRegistry });
|
||||
loadCodexBundleMcpThreadConfigCore({ workspaceDir: "/workspace", manifestRegistry });
|
||||
|
||||
expect(mocks.loadCalls).toEqual([
|
||||
expect.objectContaining({ workspaceDir: "/workspace", manifestRegistry }),
|
||||
@@ -128,7 +131,7 @@ describe("loadCodexBundleMcpThreadConfig", () => {
|
||||
},
|
||||
});
|
||||
|
||||
const loaded = loadCodexBundleMcpThreadConfig({ workspaceDir: "/workspace" });
|
||||
const loaded = loadCodexBundleMcpThreadConfigCore({ workspaceDir: "/workspace" });
|
||||
|
||||
expect((await fs.stat(dataDir)).isDirectory()).toBe(true);
|
||||
expect(loaded.configPatch?.mcp_servers.weather).toMatchObject({ command: "node" });
|
||||
@@ -154,7 +157,7 @@ describe("loadCodexBundleMcpThreadConfig", () => {
|
||||
diagnostics: [],
|
||||
};
|
||||
|
||||
const loaded = loadCodexBundleMcpThreadConfig({
|
||||
const loaded = loadCodexBundleMcpThreadConfigCore({
|
||||
workspaceDir: "/workspace",
|
||||
cfg: {
|
||||
plugins: {
|
||||
@@ -192,7 +195,7 @@ describe("loadCodexBundleMcpThreadConfig", () => {
|
||||
diagnostics: [],
|
||||
};
|
||||
|
||||
const loaded = loadCodexBundleMcpThreadConfig({
|
||||
const loaded = loadCodexBundleMcpThreadConfigCore({
|
||||
workspaceDir: "/workspace",
|
||||
cfg: {},
|
||||
toolOverrides: {
|
||||
@@ -232,10 +235,10 @@ describe("loadCodexBundleMcpThreadConfig", () => {
|
||||
};
|
||||
|
||||
expect(
|
||||
loadCodexBundleMcpThreadConfig({ workspaceDir: "/workspace", cfg }).configPatch,
|
||||
loadCodexBundleMcpThreadConfigCore({ workspaceDir: "/workspace", cfg }).configPatch,
|
||||
).toBeUndefined();
|
||||
expect(
|
||||
loadCodexBundleMcpThreadConfig({
|
||||
loadCodexBundleMcpThreadConfigCore({
|
||||
workspaceDir: "/workspace",
|
||||
cfg,
|
||||
toolOverrides: { mcpServers: { docs: true } },
|
||||
@@ -250,7 +253,7 @@ describe("loadCodexBundleMcpThreadConfig", () => {
|
||||
it("leaves user mcp.servers to the Codex user MCP projection path", () => {
|
||||
// User MCP config is projected elsewhere; this loader only injects bundled
|
||||
// MCP servers so the same server does not appear twice in Codex.
|
||||
const loaded = loadCodexBundleMcpThreadConfig({
|
||||
const loaded = loadCodexBundleMcpThreadConfigCore({
|
||||
workspaceDir: "/workspace",
|
||||
cfg: {
|
||||
mcp: {
|
||||
@@ -290,7 +293,7 @@ describe("loadCodexBundleMcpThreadConfig", () => {
|
||||
{ toolsEnabled: true, toolsAllow: [] },
|
||||
{ toolsEnabled: true, toolsAllow: ["memory_search"] },
|
||||
]) {
|
||||
const loaded = loadCodexBundleMcpThreadConfig({
|
||||
const loaded = loadCodexBundleMcpThreadConfigCore({
|
||||
workspaceDir: "/workspace",
|
||||
cfg,
|
||||
...params,
|
||||
@@ -304,7 +307,7 @@ describe("loadCodexBundleMcpThreadConfig", () => {
|
||||
});
|
||||
|
||||
it("omits the config patch when no MCP servers are configured", () => {
|
||||
const loaded = loadCodexBundleMcpThreadConfig({
|
||||
const loaded = loadCodexBundleMcpThreadConfigCore({
|
||||
workspaceDir: "/workspace",
|
||||
cfg: {},
|
||||
toolsEnabled: true,
|
||||
@@ -338,7 +341,7 @@ describe("loadCodexBundleMcpThreadConfig", () => {
|
||||
diagnostics: [],
|
||||
};
|
||||
|
||||
const loaded = loadCodexBundleMcpThreadConfig({
|
||||
const loaded = loadCodexBundleMcpThreadConfigCore({
|
||||
workspaceDir: "/workspace",
|
||||
cfg: {},
|
||||
toolsEnabled: true,
|
||||
@@ -355,7 +358,7 @@ describe("loadCodexBundleMcpThreadConfig", () => {
|
||||
},
|
||||
diagnostics: [],
|
||||
};
|
||||
const withoutScopedConfig = loadCodexBundleMcpThreadConfig({
|
||||
const withoutScopedConfig = loadCodexBundleMcpThreadConfigCore({
|
||||
workspaceDir: "/workspace",
|
||||
cfg: {},
|
||||
toolsEnabled: true,
|
||||
@@ -388,12 +391,12 @@ describe("loadCodexBundleMcpThreadConfig", () => {
|
||||
diagnostics: [],
|
||||
};
|
||||
|
||||
const a = loadCodexBundleMcpThreadConfig({
|
||||
const a = loadCodexBundleMcpThreadConfigCore({
|
||||
workspaceDir: "/workspace",
|
||||
cfg: {},
|
||||
toolsEnabled: true,
|
||||
});
|
||||
const b = loadCodexBundleMcpThreadConfig({
|
||||
const b = loadCodexBundleMcpThreadConfigCore({
|
||||
workspaceDir: "/workspace",
|
||||
cfg: {},
|
||||
toolsEnabled: true,
|
||||
|
||||
@@ -16,7 +16,7 @@ import { isRecord } from "../utils.js";
|
||||
import {
|
||||
decodeHeaderEnvPlaceholder,
|
||||
normalizeBundleMcpServerConfig,
|
||||
normalizeStringRecord,
|
||||
normalizeMcpStringRecord,
|
||||
} from "./bundle-mcp-adapter.js";
|
||||
import { prepareOwnedBundleMcpDataDirs } from "./bundle-mcp-config.js";
|
||||
import type {
|
||||
@@ -106,7 +106,7 @@ export function normalizeCodexMcpServerConfig(
|
||||
if (defaultToolsApprovalMode) {
|
||||
next.default_tools_approval_mode = defaultToolsApprovalMode;
|
||||
}
|
||||
const httpHeaders = normalizeStringRecord(server.headers);
|
||||
const httpHeaders = normalizeMcpStringRecord(server.headers);
|
||||
if (httpHeaders) {
|
||||
const staticHeaders: Record<string, string> = {};
|
||||
const envHeaders: Record<string, string> = {};
|
||||
@@ -170,7 +170,7 @@ function fingerprintCodexMcpServersConfig(config: CodexMcpServersConfig): string
|
||||
}
|
||||
|
||||
/** Load bundle MCP config for one Codex app-server thread. */
|
||||
export function loadCodexBundleMcpThreadConfig(
|
||||
export function loadCodexBundleMcpThreadConfigCore(
|
||||
params: LoadCodexBundleMcpThreadConfigParams,
|
||||
): CodexBundleMcpThreadConfig {
|
||||
const shouldCreateRuntime = shouldCreateBundleMcpRuntimeForAttempt({
|
||||
|
||||
@@ -6,7 +6,7 @@ import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vite
|
||||
import { setReplyPayloadMetadata } from "../../auto-reply/reply-payload.js";
|
||||
import type { SessionEntry } from "../../config/sessions.js";
|
||||
import {
|
||||
listSessionEntries,
|
||||
listSessionEntriesCore,
|
||||
loadTranscriptEvents,
|
||||
} from "../../config/sessions/session-accessor.js";
|
||||
import type { appendExactAssistantMessageToSessionTranscript } from "../../config/sessions/transcript.runtime.js";
|
||||
@@ -384,7 +384,7 @@ function requireStorePath(): string {
|
||||
}
|
||||
|
||||
function findStoredSessionEntry(sessionKey: string): SessionEntry | undefined {
|
||||
return listSessionEntries({ storePath: requireStorePath() }).find(
|
||||
return listSessionEntriesCore({ storePath: requireStorePath() }).find(
|
||||
(candidate) => candidate.sessionKey === sessionKey,
|
||||
)?.entry;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
import {
|
||||
appendTranscriptEvent,
|
||||
appendTranscriptMessage,
|
||||
listSessionEntries,
|
||||
listSessionEntriesCore,
|
||||
loadTranscriptEvents,
|
||||
replaceSessionEntry,
|
||||
} from "../../config/sessions/session-accessor.js";
|
||||
@@ -710,7 +710,7 @@ describe("CLI attempt execution", () => {
|
||||
|
||||
function readSessionStore(): Record<string, SessionEntry> {
|
||||
return Object.fromEntries(
|
||||
listSessionEntries({ storePath }).map(({ entry, sessionKey }) => [sessionKey, entry]),
|
||||
listSessionEntriesCore({ storePath }).map(({ entry, sessionKey }) => [sessionKey, entry]),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Shared session persistence and prompt-body helpers for agent attempt
|
||||
* execution paths.
|
||||
*/
|
||||
import { patchSessionEntry } from "../../config/sessions/session-accessor.js";
|
||||
import { patchSessionEntryCore } from "../../config/sessions/session-accessor.js";
|
||||
import { mergeSessionSnapshotChanges } from "../../config/sessions/session-snapshot-merge.js";
|
||||
import type { SessionEntry } from "../../config/sessions/types.js";
|
||||
import {
|
||||
@@ -30,7 +30,7 @@ export async function persistAgentSession(
|
||||
params: PersistSessionEntryParams,
|
||||
): Promise<SessionEntry | undefined> {
|
||||
let rejectedMissingEntry = false;
|
||||
const persisted = await patchSessionEntry(
|
||||
const persisted = await patchSessionEntryCore(
|
||||
{ sessionKey: params.sessionKey, storePath: params.storePath },
|
||||
(_entry, context) => {
|
||||
const shouldPersistCurrent = params.shouldPersist?.(context.existingEntry);
|
||||
|
||||
@@ -7,7 +7,7 @@ import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import type { OpenClawConfig } from "../../config/config.js";
|
||||
import type { InternalSessionEntry as SessionEntry } from "../../config/sessions.js";
|
||||
import {
|
||||
listSessionEntries,
|
||||
listSessionEntriesCore,
|
||||
loadSessionEntry,
|
||||
replaceSessionEntry,
|
||||
} from "../../config/sessions/session-accessor.js";
|
||||
@@ -111,7 +111,7 @@ async function seedSessionStore(
|
||||
|
||||
function loadPersistedSessionStore(storePath: string): Record<string, SessionEntry> {
|
||||
return Object.fromEntries(
|
||||
listSessionEntries({ storePath }).map(({ sessionKey, entry }) => [sessionKey, entry]),
|
||||
listSessionEntriesCore({ storePath }).map(({ sessionKey, entry }) => [sessionKey, entry]),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
setSessionRuntimeModel,
|
||||
type SessionEntry,
|
||||
} from "../../config/sessions.js";
|
||||
import { patchSessionEntry } from "../../config/sessions/session-accessor.js";
|
||||
import { patchSessionEntryCore } from "../../config/sessions/session-accessor.js";
|
||||
import { projectSessionSnapshotChanges } from "../../config/sessions/session-snapshot-merge.js";
|
||||
import { resolveMaintenanceConfigFromInput } from "../../config/sessions/store-maintenance.js";
|
||||
import type { OpenClawConfig } from "../../config/types.openclaw.js";
|
||||
@@ -286,7 +286,7 @@ export async function updateSessionStoreAfterAgentRun(params: {
|
||||
}
|
||||
: next;
|
||||
const maintenanceConfig = resolveMaintenanceConfigFromInput(cfg.session?.maintenance);
|
||||
const persisted = await patchSessionEntry(
|
||||
const persisted = await patchSessionEntryCore(
|
||||
{
|
||||
storePath,
|
||||
sessionKey,
|
||||
@@ -338,7 +338,7 @@ export async function clearCliSessionInStore(params: {
|
||||
}
|
||||
|
||||
let didClear = false;
|
||||
const persisted = await patchSessionEntry(
|
||||
const persisted = await patchSessionEntryCore(
|
||||
{
|
||||
storePath,
|
||||
sessionKey,
|
||||
@@ -385,7 +385,7 @@ export async function consumeCliSessionForkInStore(params: {
|
||||
if (!entry || binding?.sessionId !== expectedCliSessionId || binding.forkNextResume !== true) {
|
||||
return undefined;
|
||||
}
|
||||
const persisted = await patchSessionEntry(
|
||||
const persisted = await patchSessionEntryCore(
|
||||
{ storePath, sessionKey },
|
||||
(currentEntry) => {
|
||||
const currentBinding = currentEntry.cliSessionBindings?.[provider];
|
||||
@@ -422,7 +422,7 @@ export async function restoreCliSessionForkInStore(params: {
|
||||
if (!entry || binding?.sessionId !== expectedCliSessionId || binding.forkNextResume === true) {
|
||||
return undefined;
|
||||
}
|
||||
const persisted = await patchSessionEntry(
|
||||
const persisted = await patchSessionEntryCore(
|
||||
{ storePath, sessionKey },
|
||||
(currentEntry) => {
|
||||
const currentBinding = currentEntry.cliSessionBindings?.[provider];
|
||||
@@ -465,7 +465,7 @@ export async function persistCliSessionForkSuccessorInStore(params: {
|
||||
if (!entry || successorCliSessionId === expectedCliSessionId) {
|
||||
return undefined;
|
||||
}
|
||||
const persisted = await patchSessionEntry(
|
||||
const persisted = await patchSessionEntryCore(
|
||||
{ storePath, sessionKey },
|
||||
(currentEntry) => {
|
||||
const currentBinding = currentEntry.cliSessionBindings?.[provider];
|
||||
@@ -540,7 +540,7 @@ export async function recordCliCompactionInStore(params: {
|
||||
next.cacheWrite = undefined;
|
||||
}
|
||||
|
||||
const persisted = await patchSessionEntry(
|
||||
const persisted = await patchSessionEntryCore(
|
||||
{
|
||||
storePath,
|
||||
sessionKey,
|
||||
|
||||
@@ -8,7 +8,7 @@ const hoisted = vi.hoisted(() => ({
|
||||
}));
|
||||
|
||||
vi.mock("../../config/sessions/session-accessor.js", () => ({
|
||||
listSessionEntries: () =>
|
||||
listSessionEntriesCore: () =>
|
||||
Object.entries(hoisted.store).map(([sessionKey, entry]) => ({
|
||||
sessionKey,
|
||||
entry,
|
||||
|
||||
@@ -14,7 +14,7 @@ const hoisted = vi.hoisted(() => ({
|
||||
}));
|
||||
|
||||
vi.mock("../../config/sessions/session-accessor.js", () => ({
|
||||
listSessionEntries: (scope?: { storePath?: string; clone?: boolean }) =>
|
||||
listSessionEntriesCore: (scope?: { storePath?: string; clone?: boolean }) =>
|
||||
hoisted.listSessionEntriesMock(scope),
|
||||
}));
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ import {
|
||||
resolveSessionResetPolicy,
|
||||
} from "../../config/sessions/reset-policy.js";
|
||||
import { resolveChannelResetConfig, resolveSessionResetType } from "../../config/sessions/reset.js";
|
||||
import { listSessionEntries } from "../../config/sessions/session-accessor.js";
|
||||
import { listSessionEntriesCore } from "../../config/sessions/session-accessor.js";
|
||||
import { resolveSessionKey } from "../../config/sessions/session-key.js";
|
||||
import type { InternalSessionEntry as SessionEntry } from "../../config/sessions/types.js";
|
||||
import type { OpenClawConfig } from "../../config/types.openclaw.js";
|
||||
@@ -112,7 +112,7 @@ function loadCommandSessionStore(params: {
|
||||
storePath: string;
|
||||
}): Record<string, SessionEntry> {
|
||||
return Object.fromEntries(
|
||||
listSessionEntries({
|
||||
listSessionEntriesCore({
|
||||
storePath: params.storePath,
|
||||
...(params.agentId ? { agentId: params.agentId } : {}),
|
||||
...(params.clone === false ? { clone: false } : {}),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { isCompletionReportInputProvenance } from "../sessions/input-provenance.js";
|
||||
import { isRuntimeToolAllowed } from "./tool-policy-match.js";
|
||||
import { normalizeToolName } from "./tool-policy.js";
|
||||
import { normalizeToolPolicyName } from "./tool-policy.js";
|
||||
import { AUTOMATIONS_TOOL_NAME } from "./tools/automations-tool-name.js";
|
||||
import type { AnyAgentTool } from "./tools/common.js";
|
||||
import { ToolAuthorizationError } from "./tools/common.js";
|
||||
@@ -96,7 +96,7 @@ export function applyDelegationCapability(
|
||||
return tools;
|
||||
}
|
||||
return tools.flatMap((tool) => {
|
||||
const name = normalizeToolName(tool.name);
|
||||
const name = normalizeToolPolicyName(tool.name);
|
||||
if (NEW_DELEGATION_TOOL_NAMES.has(name)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
isMessagingToolDeliveryAction,
|
||||
} from "./embedded-agent-messaging.js";
|
||||
import { isToolResultError } from "./embedded-agent-subscribe.tools.js";
|
||||
import { normalizeToolName } from "./tool-policy.js";
|
||||
import { normalizeToolPolicyName } from "./tool-policy.js";
|
||||
|
||||
const MESSAGE_TOOL_NAME = "message";
|
||||
const SESSIONS_SEND_TOOL_NAME = "sessions_send";
|
||||
@@ -535,7 +535,7 @@ export function isDeliveredMessagingToolResult(params: {
|
||||
if (params.isError || isToolResultError(params.result) || isToolResultError(params.hookResult)) {
|
||||
return false;
|
||||
}
|
||||
const normalizedToolName = normalizeToolName(params.toolName ?? MESSAGE_TOOL_NAME);
|
||||
const normalizedToolName = normalizeToolPolicyName(params.toolName ?? MESSAGE_TOOL_NAME);
|
||||
const mutationHasBareOk =
|
||||
isMessagingToolDeliveryAction(normalizedToolName, args) &&
|
||||
action !== "broadcast" &&
|
||||
@@ -590,7 +590,7 @@ export function isDeliveredMessageToolOnlySourceReplyResult(params: {
|
||||
if (params.sourceReplyDeliveryMode !== "message_tool_only" && !confirmedCurrentSourceRoute) {
|
||||
return false;
|
||||
}
|
||||
if (normalizeToolName(params.toolName) !== MESSAGE_TOOL_NAME) {
|
||||
if (normalizeToolPolicyName(params.toolName) !== MESSAGE_TOOL_NAME) {
|
||||
return false;
|
||||
}
|
||||
const args = asOptionalRecord(params.args) ?? {};
|
||||
|
||||
@@ -16,7 +16,7 @@ import { onAgentEvent } from "../../infra/agent-events.js";
|
||||
import { createSubsystemLogger } from "../../logging/subsystem.js";
|
||||
import { resolvePreparedRunAdmission } from "../admitted-run-context.js";
|
||||
import { stripOpenClawMcpToolPrefix } from "../cli-runner/tool-policy.js";
|
||||
import { normalizeToolName } from "../tool-policy.js";
|
||||
import { normalizeToolPolicyName } from "../tool-policy.js";
|
||||
import { isToolResultError } from "../tool-result-error.js";
|
||||
import { resolveEmbeddedCliBackendDispatchEligibility } from "./cli-backend-dispatch-eligibility.js";
|
||||
import { createCliDispatchTranscriptRecorder } from "./cli-backend-dispatch-transcript.js";
|
||||
@@ -84,7 +84,7 @@ function resolveDispatchableToolsAllow(params: RunEmbeddedAgentParams): string[]
|
||||
if (!params.toolsAllow || params.toolsAllow.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
const names = params.toolsAllow.map((name) => normalizeToolName(name));
|
||||
const names = params.toolsAllow.map((name) => normalizeToolPolicyName(name));
|
||||
if (names.some((name) => !name || name === "*" || name.includes("*"))) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -159,7 +159,7 @@ async function runEmbeddedAgentViaCliBackend(
|
||||
if (!rawName) {
|
||||
return;
|
||||
}
|
||||
const toolName = normalizeToolName(stripOpenClawMcpToolPrefix(rawName));
|
||||
const toolName = normalizeToolPolicyName(stripOpenClawMcpToolPrefix(rawName));
|
||||
const toolCallId = typeof evt.data.toolCallId === "string" ? evt.data.toolCallId : undefined;
|
||||
if (phase === "start") {
|
||||
transcript.noteToolEvent({
|
||||
|
||||
@@ -4,7 +4,7 @@ import {
|
||||
parseSqliteSessionFileMarker,
|
||||
} from "../../config/sessions/legacy-sqlite-marker.js";
|
||||
import {
|
||||
listSessionEntries,
|
||||
listSessionEntriesCore,
|
||||
loadSessionEntry,
|
||||
type SessionTranscriptRuntimeTarget,
|
||||
} from "../../config/sessions/session-accessor.js";
|
||||
@@ -85,7 +85,7 @@ export async function resolveContextEngineCompactionSuccessor(params: {
|
||||
})
|
||||
: undefined;
|
||||
const markerMatches = marker
|
||||
? listSessionEntries({
|
||||
? listSessionEntriesCore({
|
||||
agentId: marker.agentId,
|
||||
storePath: marker.storePath,
|
||||
}).filter(({ entry }) => entry.sessionId === marker.sessionId)
|
||||
|
||||
@@ -4,14 +4,14 @@ import { buildContextEngineCompactionSessionTarget } from "./session-bootstrap.j
|
||||
import { createEmbeddedRunSessionPromptState } from "./session-prompt-state.js";
|
||||
|
||||
const sessionAccessorMocks = vi.hoisted(() => ({
|
||||
listSessionEntries: vi.fn(() => []),
|
||||
listSessionEntriesCore: vi.fn(() => []),
|
||||
loadSessionEntry: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock("../../../config/sessions/session-accessor.js", () => sessionAccessorMocks);
|
||||
|
||||
beforeEach(() => {
|
||||
sessionAccessorMocks.listSessionEntries.mockReset().mockReturnValue([]);
|
||||
sessionAccessorMocks.listSessionEntriesCore.mockReset().mockReturnValue([]);
|
||||
sessionAccessorMocks.loadSessionEntry.mockReset();
|
||||
});
|
||||
|
||||
@@ -178,7 +178,7 @@ describe("applyEmbeddedAttemptSessionIdentity", () => {
|
||||
sessionId: "session-before",
|
||||
updatedAt: 1,
|
||||
});
|
||||
sessionAccessorMocks.listSessionEntries.mockReturnValue([
|
||||
sessionAccessorMocks.listSessionEntriesCore.mockReturnValue([
|
||||
{
|
||||
sessionKey: "agent:main:other",
|
||||
entry: { sessionId: "session-after", updatedAt: 2 },
|
||||
|
||||
@@ -34,7 +34,7 @@ import {
|
||||
appendModelIdentitySystemPrompt,
|
||||
buildModelIdentityPromptLine,
|
||||
} from "../../system-prompt.js";
|
||||
import { normalizeToolName } from "../../tool-policy.js";
|
||||
import { normalizeToolPolicyName } from "../../tool-policy.js";
|
||||
import { log } from "../logger.js";
|
||||
import {
|
||||
beginPromptCacheObservation,
|
||||
@@ -170,7 +170,7 @@ export async function prepareEmbeddedAttemptPromptAssembly(input: {
|
||||
bootstrapContextRunKind: attempt.bootstrapContextRunKind,
|
||||
});
|
||||
const promptCacheToolNames = input.applyPromptBuildToolsAllow(hookResult?.toolsAllow);
|
||||
const promptCacheToolNameSet = new Set(promptCacheToolNames.map(normalizeToolName));
|
||||
const promptCacheToolNameSet = new Set(promptCacheToolNames.map(normalizeToolPolicyName));
|
||||
const promptBeforeResolvedToolFinalization = effectivePrompt;
|
||||
effectivePrompt = applyResolvedToolPromptFinalizer({
|
||||
prompt: effectivePrompt,
|
||||
@@ -182,7 +182,7 @@ export async function prepareEmbeddedAttemptPromptAssembly(input: {
|
||||
? promptBeforeResolvedToolFinalization
|
||||
: attempt.transcriptPrompt;
|
||||
const promptCacheTools = input.cache.tools.filter((tool) =>
|
||||
promptCacheToolNameSet.has(normalizeToolName(tool.name)),
|
||||
promptCacheToolNameSet.has(normalizeToolPolicyName(tool.name)),
|
||||
);
|
||||
const promptBeforePromptBuildHooks = effectivePrompt;
|
||||
const promptBuildPrependContext = hookResult?.prependContext;
|
||||
|
||||
@@ -26,7 +26,7 @@ import {
|
||||
} from "../../code-mode-control-tools.js";
|
||||
import type { AgentMessage } from "../../runtime/index.js";
|
||||
import type { AgentSession } from "../../sessions/index.js";
|
||||
import { normalizeToolName } from "../../tool-policy.js";
|
||||
import { normalizeToolPolicyName } from "../../tool-policy.js";
|
||||
import { TOOL_SEARCH_CONTROL_TOOL_NAMES } from "../../tool-search-types.js";
|
||||
import {
|
||||
restrictToolSearchCatalog,
|
||||
@@ -63,7 +63,7 @@ export function applyResolvedToolPromptFinalizer(params: {
|
||||
return params.finalize({
|
||||
prompt: params.prompt,
|
||||
messageToolAvailable: params.activeToolNames.some(
|
||||
(toolName) => normalizeToolName(toolName) === "message",
|
||||
(toolName) => normalizeToolPolicyName(toolName) === "message",
|
||||
),
|
||||
});
|
||||
}
|
||||
@@ -136,17 +136,17 @@ export function applyPromptBuildToolsAllow<
|
||||
applyToolsAllow(
|
||||
params.baseline.activeToolNames.map((name) => ({ name })),
|
||||
toolsAllow,
|
||||
).map((tool) => normalizeToolName(tool.name)),
|
||||
).map((tool) => normalizeToolPolicyName(tool.name)),
|
||||
);
|
||||
for (const tool of [...allowedEffectiveTools, ...allowedUncompactedTools, ...allowedTools]) {
|
||||
allowedActiveNames.add(normalizeToolName(tool.name));
|
||||
allowedActiveNames.add(normalizeToolPolicyName(tool.name));
|
||||
}
|
||||
|
||||
const catalogControlNames = params.codeModeControlsEnabled
|
||||
? new Set([CODE_MODE_EXEC_TOOL_NAME, CODE_MODE_WAIT_TOOL_NAME])
|
||||
: TOOL_SEARCH_CONTROL_TOOL_NAMES;
|
||||
const keepVisibleTool = (tool: NamedTool) => {
|
||||
const normalized = normalizeToolName(tool.name);
|
||||
const normalized = normalizeToolPolicyName(tool.name);
|
||||
return (
|
||||
allowedActiveNames.has(normalized) ||
|
||||
(catalogToolCount > 0 && catalogControlNames.has(normalized))
|
||||
|
||||
@@ -3,7 +3,10 @@ import {
|
||||
formatSqliteSessionFileMarker,
|
||||
parseSqliteSessionFileMarker,
|
||||
} from "../../../config/sessions/legacy-sqlite-marker.js";
|
||||
import { listSessionEntries, loadSessionEntry } from "../../../config/sessions/session-accessor.js";
|
||||
import {
|
||||
listSessionEntriesCore,
|
||||
loadSessionEntry,
|
||||
} from "../../../config/sessions/session-accessor.js";
|
||||
import { resolveAgentIdFromSessionKey } from "../../../routing/session-key.js";
|
||||
import { resolvePreferredSessionKeyForSessionIdMatches } from "../../../sessions/session-id-resolution.js";
|
||||
import type { createEmbeddedRunSessionPromptState } from "./session-prompt-state.js";
|
||||
@@ -36,7 +39,7 @@ export function applyEmbeddedAttemptSessionIdentity(params: {
|
||||
storePath: marker.storePath,
|
||||
})
|
||||
: undefined;
|
||||
const markerMatches = listSessionEntries({
|
||||
const markerMatches = listSessionEntriesCore({
|
||||
agentId: marker.agentId,
|
||||
storePath: marker.storePath,
|
||||
}).filter(({ entry }) => entry.sessionId === marker.sessionId);
|
||||
|
||||
@@ -14,7 +14,7 @@ import {
|
||||
expandPolicyWithPluginGroups,
|
||||
expandToolGroups,
|
||||
normalizeToolList,
|
||||
normalizeToolName,
|
||||
normalizeToolPolicyName,
|
||||
readToolAllowlistIntersection,
|
||||
} from "../../tool-policy.js";
|
||||
|
||||
@@ -50,7 +50,7 @@ function isPluginGroupAllowlistName(normalized: string): boolean {
|
||||
}
|
||||
|
||||
function hasWildcardToolAllowlist(toolsAllow: string[]): boolean {
|
||||
return toolsAllow.some((entry) => normalizeToolName(entry) === "*");
|
||||
return toolsAllow.some((entry) => normalizeToolPolicyName(entry) === "*");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -104,8 +104,8 @@ export function mergeForcedEmbeddedAttemptToolsAllow(
|
||||
if (required.length === 0) {
|
||||
return toolsAllow;
|
||||
}
|
||||
const normalized = new Set(toolsAllow.map((entry) => normalizeToolName(entry)));
|
||||
const missing = required.filter((name) => !normalized.has(normalizeToolName(name)));
|
||||
const normalized = new Set(toolsAllow.map((entry) => normalizeToolPolicyName(entry)));
|
||||
const missing = required.filter((name) => !normalized.has(normalizeToolPolicyName(name)));
|
||||
if (missing.length === 0) {
|
||||
return toolsAllow;
|
||||
}
|
||||
@@ -232,7 +232,7 @@ function shouldCreateBundleRuntimeForAttempt(
|
||||
if (hasWildcardToolAllowlist(params.toolsAllow)) {
|
||||
return true;
|
||||
}
|
||||
return params.toolsAllow.some((toolName) => matchesAllowlist(normalizeToolName(toolName)));
|
||||
return params.toolsAllow.some((toolName) => matchesAllowlist(normalizeToolPolicyName(toolName)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*/
|
||||
import { getPluginToolMeta } from "../../../plugins/tools.js";
|
||||
import { isToolAllowedByPolicyName } from "../../tool-policy-match.js";
|
||||
import { normalizeToolName } from "../../tool-policy.js";
|
||||
import { normalizeToolPolicyName } from "../../tool-policy.js";
|
||||
import {
|
||||
collectUniqueCatalogToolNames,
|
||||
TOOL_CALL_RAW_TOOL_NAME,
|
||||
@@ -108,14 +108,16 @@ export function buildToolSearchRunPlan(params: {
|
||||
}
|
||||
const explicitControlAllowlistNames = new Set(
|
||||
params.explicitAllowlistSources.flatMap((source) =>
|
||||
source.entries.map((entry) => normalizeToolName(entry)),
|
||||
source.entries.map((entry) => normalizeToolPolicyName(entry)),
|
||||
),
|
||||
);
|
||||
const autoAddedControlNames = new Set(
|
||||
(params.controlsEnabled
|
||||
? (params.controlNames ?? TOOL_SEARCH_CONTROL_ALLOWLIST_NAMES)
|
||||
: []
|
||||
).filter((controlName) => !explicitControlAllowlistNames.has(normalizeToolName(controlName))),
|
||||
).filter(
|
||||
(controlName) => !explicitControlAllowlistNames.has(normalizeToolPolicyName(controlName)),
|
||||
),
|
||||
);
|
||||
const explicitlyAllowedClientToolNames = collectExplicitlyAllowedClientToolNames({
|
||||
clientTools: params.clientTools,
|
||||
|
||||
@@ -33,7 +33,10 @@ import {
|
||||
sanitizeToolCallIdsForCloudCodeAssist,
|
||||
type ToolCallIdMode,
|
||||
} from "../../tool-call-id.js";
|
||||
import { couldNormalizeToolNamePrefixToAllowedTool, normalizeToolName } from "../../tool-policy.js";
|
||||
import {
|
||||
couldNormalizeToolNamePrefixToAllowedTool,
|
||||
normalizeToolPolicyName,
|
||||
} from "../../tool-policy.js";
|
||||
import { shouldAllowProviderOwnedThinkingReplay } from "../../transcript-policy.js";
|
||||
import type { TranscriptPolicy } from "../../transcript-policy.js";
|
||||
import { isRunnerToolCallBlockType } from "./attempt-tool-call-block-type.js";
|
||||
@@ -79,7 +82,7 @@ function resolveExactAllowedToolName(
|
||||
if (allowedToolNames.has(rawName)) {
|
||||
return rawName;
|
||||
}
|
||||
const normalized = normalizeToolName(rawName);
|
||||
const normalized = normalizeToolPolicyName(rawName);
|
||||
if (allowedToolNames.has(normalized)) {
|
||||
return normalized;
|
||||
}
|
||||
@@ -107,7 +110,7 @@ function buildStructuredToolNameCandidates(rawName: string): string[] {
|
||||
};
|
||||
|
||||
addCandidate(trimmed);
|
||||
addCandidate(normalizeToolName(trimmed));
|
||||
addCandidate(normalizeToolPolicyName(trimmed));
|
||||
const structuredSeeds = [trimmed];
|
||||
|
||||
const xmlFragmentOffset = ['"', "'", "<"]
|
||||
@@ -120,21 +123,21 @@ function buildStructuredToolNameCandidates(rawName: string): string[] {
|
||||
if (xmlFragmentOffset !== undefined) {
|
||||
const prefix = trimmed.slice(0, xmlFragmentOffset);
|
||||
addCandidate(prefix);
|
||||
addCandidate(normalizeToolName(prefix));
|
||||
addCandidate(normalizeToolPolicyName(prefix));
|
||||
structuredSeeds.push(prefix);
|
||||
}
|
||||
|
||||
for (const seed of structuredSeeds) {
|
||||
const normalizedDelimiter = seed.replace(/\//g, ".");
|
||||
addCandidate(normalizedDelimiter);
|
||||
addCandidate(normalizeToolName(normalizedDelimiter));
|
||||
addCandidate(normalizeToolPolicyName(normalizedDelimiter));
|
||||
|
||||
const segments = normalizeStringEntries(normalizedDelimiter.split("."));
|
||||
if (segments.length > 1) {
|
||||
for (let index = 1; index < segments.length; index += 1) {
|
||||
const suffix = segments.slice(index).join(".");
|
||||
addCandidate(suffix);
|
||||
addCandidate(normalizeToolName(suffix));
|
||||
addCandidate(normalizeToolPolicyName(suffix));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -769,7 +772,7 @@ function classifyToolCallMessage(
|
||||
sawAllowedToolCall = true;
|
||||
continue;
|
||||
}
|
||||
const normalizedUnknownToolName = normalizeToolName(rawName);
|
||||
const normalizedUnknownToolName = normalizeToolPolicyName(rawName);
|
||||
if (!unknownToolName) {
|
||||
unknownToolName = normalizedUnknownToolName;
|
||||
continue;
|
||||
|
||||
@@ -4,7 +4,7 @@ import { sanitizeForLog } from "../../../../packages/terminal-core/src/ansi.js";
|
||||
import { resolveStorePath, SESSION_TOTAL_TOKENS_VERSION } from "../../../config/sessions.js";
|
||||
import { parseSqliteSessionFileMarker } from "../../../config/sessions/legacy-sqlite-marker.js";
|
||||
import {
|
||||
listSessionEntries,
|
||||
listSessionEntriesCore,
|
||||
loadSessionEntry,
|
||||
updateSessionEntry,
|
||||
} from "../../../config/sessions/session-accessor.js";
|
||||
@@ -63,7 +63,7 @@ export function buildContextEngineCompactionSessionTarget(params: {
|
||||
})
|
||||
: undefined;
|
||||
const markerMatches = marker
|
||||
? listSessionEntries({
|
||||
? listSessionEntriesCore({
|
||||
agentId: marker.agentId,
|
||||
storePath: marker.storePath,
|
||||
}).filter(({ entry }) => entry.sessionId === marker.sessionId)
|
||||
|
||||
@@ -95,7 +95,7 @@ import {
|
||||
summarizeToolValidationError,
|
||||
} from "./tool-error-summary.js";
|
||||
import { resolveFileMutationToolName } from "./tool-mutation-names.js";
|
||||
import { normalizeToolName } from "./tool-policy.js";
|
||||
import { normalizeToolPolicyName } from "./tool-policy.js";
|
||||
import { cancelAskUserPromptDelivery } from "./tools/ask-user-tool.js";
|
||||
import { isAutomationsToolName } from "./tools/automations-tool-name.js";
|
||||
|
||||
@@ -105,7 +105,7 @@ export async function handleToolExecutionEnd(
|
||||
evt: Extract<AgentEvent, { type: "tool_execution_end" }>,
|
||||
) {
|
||||
const rawToolName = evt.toolName;
|
||||
const toolName = normalizeToolName(rawToolName);
|
||||
const toolName = normalizeToolPolicyName(rawToolName);
|
||||
const hideFromChannelProgress = evt.hideFromChannelProgress === true;
|
||||
const toolCallId = evt.toolCallId;
|
||||
ctx.state.liveEditDiffStateById.delete(toolCallId);
|
||||
|
||||
@@ -26,7 +26,7 @@ import {
|
||||
truncateLiveExecOutput,
|
||||
} from "./embedded-agent-subscribe.tools.js";
|
||||
import type { AgentEvent } from "./runtime/index.js";
|
||||
import { normalizeToolName } from "./tool-policy.js";
|
||||
import { normalizeToolPolicyName } from "./tool-policy.js";
|
||||
|
||||
type ChannelToolProgress = {
|
||||
text: string;
|
||||
@@ -69,7 +69,7 @@ export function handleToolExecutionUpdate(
|
||||
hideFromChannelProgress?: boolean;
|
||||
},
|
||||
) {
|
||||
const toolName = normalizeToolName(evt.toolName);
|
||||
const toolName = normalizeToolPolicyName(evt.toolName);
|
||||
const toolCallId = evt.toolCallId;
|
||||
const hideFromChannelProgress = evt.hideFromChannelProgress === true;
|
||||
const partial = evt.partialResult;
|
||||
|
||||
@@ -34,7 +34,7 @@ import type { AgentEvent } from "./runtime/index.js";
|
||||
import { inferToolMetaFromArgsCore, isCommandBearingToolCall } from "./tool-display.js";
|
||||
import { resolveFileMutationToolName } from "./tool-mutation-names.js";
|
||||
import { buildToolMutationState } from "./tool-mutation.js";
|
||||
import { normalizeToolName } from "./tool-policy.js";
|
||||
import { normalizeToolPolicyName } from "./tool-policy.js";
|
||||
import {
|
||||
cancelAskUserPromptDelivery,
|
||||
normalizeAskUserParams,
|
||||
@@ -322,7 +322,7 @@ export function handleToolExecutionStart(
|
||||
hideFromChannelProgress?: boolean;
|
||||
},
|
||||
): void | Promise<void> {
|
||||
const startToolName = normalizeToolName(evt.toolName);
|
||||
const startToolName = normalizeToolPolicyName(evt.toolName);
|
||||
ctx.state.liveEditDiffStateById.delete(evt.toolCallId);
|
||||
const askUserPromptReservation =
|
||||
startToolName === "ask_user" && ctx.params.onToolResult
|
||||
@@ -358,7 +358,7 @@ export function handleToolExecutionStart(
|
||||
|
||||
const continueToolExecutionStart = (): void | Promise<void> => {
|
||||
const rawToolName = evt.toolName;
|
||||
const toolName = normalizeToolName(rawToolName);
|
||||
const toolName = normalizeToolPolicyName(rawToolName);
|
||||
const hideFromChannelProgress = evt.hideFromChannelProgress === true;
|
||||
const toolCallId = evt.toolCallId;
|
||||
const args = evt.args;
|
||||
|
||||
@@ -7,7 +7,7 @@ import { extractTextFromChatContent } from "../shared/chat-content.js";
|
||||
import { detectAssistantTranscriptRoleHeaderText } from "../shared/text/assistant-transcript-role-headers.js";
|
||||
import { detectToolCallShapedText } from "../shared/text/tool-call-shaped-text.js";
|
||||
import type { EmbeddedAgentSubscribeContext } from "./embedded-agent-subscribe.handlers.types.js";
|
||||
import { normalizeToolName } from "./tool-policy.js";
|
||||
import { normalizeToolPolicyName } from "./tool-policy.js";
|
||||
|
||||
// Detect provider/model bugs where a reply serializes a tool call as plain
|
||||
// assistant text instead of emitting a structured invocation block.
|
||||
@@ -51,9 +51,9 @@ function isRegisteredToolName(
|
||||
if (!toolName || !registeredToolNames) {
|
||||
return undefined;
|
||||
}
|
||||
const normalized = normalizeToolName(toolName);
|
||||
const normalized = normalizeToolPolicyName(toolName);
|
||||
for (const registeredToolName of registeredToolNames) {
|
||||
if (normalizeToolName(registeredToolName) === normalized) {
|
||||
if (normalizeToolPolicyName(registeredToolName) === normalized) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ import type {
|
||||
MessagingToolSend,
|
||||
MessagingToolSourceReplyPayload,
|
||||
} from "./embedded-agent-messaging.types.js";
|
||||
import { normalizeToolName } from "./tool-policy.js";
|
||||
import { normalizeToolPolicyName } from "./tool-policy.js";
|
||||
import {
|
||||
isToolResultError,
|
||||
readToolResultDetails,
|
||||
@@ -636,7 +636,7 @@ function isCoreToolResultMediaTrustedName(toolName?: string): boolean {
|
||||
if (!toolName) {
|
||||
return false;
|
||||
}
|
||||
return TRUSTED_TOOL_RESULT_MEDIA.has(normalizeToolName(toolName));
|
||||
return TRUSTED_TOOL_RESULT_MEDIA.has(normalizeToolPolicyName(toolName));
|
||||
}
|
||||
|
||||
function isExternalToolResult(result: unknown): boolean {
|
||||
@@ -676,7 +676,7 @@ function isTrustedOwnedTtsLocalMedia(
|
||||
if (
|
||||
!toolName ||
|
||||
!isToolResultMediaTrusted(toolName, result, trustedLocalMediaToolNames) ||
|
||||
normalizeToolName(toolName) !== "tts"
|
||||
normalizeToolPolicyName(toolName) !== "tts"
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { stableStringify } from "@openclaw/normalization-core";
|
||||
import { normalizeToolName } from "../tool-policy.js";
|
||||
import { normalizeToolPolicyName } from "../tool-policy.js";
|
||||
import { codexNativeHookRelayResponseCodec } from "./native-hook-relay-response-codec.js";
|
||||
import type {
|
||||
JsonValue,
|
||||
@@ -186,6 +186,6 @@ export function readNativeHookRelayApprovalMode(rawPayload: JsonValue): "report"
|
||||
}
|
||||
|
||||
export function normalizeNativeHookToolName(toolName: string | undefined): string {
|
||||
const normalized = normalizeToolName(toolName ?? "tool");
|
||||
const normalized = normalizeToolPolicyName(toolName ?? "tool");
|
||||
return CODEX_NATIVE_HOOK_TOOL_NAME_ALIASES[normalized] ?? normalized;
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ import { resolveSandboxRuntimeStatus } from "../sandbox/runtime-status.js";
|
||||
import {
|
||||
expandToolGroups,
|
||||
mergeAlsoAllowPolicy,
|
||||
normalizeToolName,
|
||||
normalizeToolPolicyName,
|
||||
toolPolicyRestrictsTools,
|
||||
} from "../tool-policy.js";
|
||||
import type { SystemAgentToolOptions } from "../tools/system-agent-tool.js";
|
||||
@@ -681,7 +681,7 @@ async function runAgentHarnessOperation<T>(
|
||||
}
|
||||
|
||||
function isSystemAgentOnlyAllowlist(toolsAllow: readonly string[] | undefined): boolean {
|
||||
return toolsAllow?.length === 1 && normalizeToolName(toolsAllow[0] ?? "") === "openclaw";
|
||||
return toolsAllow?.length === 1 && normalizeToolPolicyName(toolsAllow[0] ?? "") === "openclaw";
|
||||
}
|
||||
|
||||
function withoutHarnessSetupAuthority(
|
||||
@@ -816,7 +816,7 @@ function applyPluginHarnessDenyAllToolPolicy(
|
||||
if (
|
||||
isHostScopedAgentToolActive("openclaw") &&
|
||||
params.toolsAllow?.length === 1 &&
|
||||
normalizeToolName(params.toolsAllow[0] ?? "") === "openclaw"
|
||||
normalizeToolPolicyName(params.toolsAllow[0] ?? "") === "openclaw"
|
||||
) {
|
||||
return params;
|
||||
}
|
||||
@@ -983,7 +983,9 @@ function appendPluginHarnessToolPolicyPrompt(existing: string | undefined, promp
|
||||
}
|
||||
|
||||
function policyDeniesAllTools(policy?: { deny?: string[] }): boolean {
|
||||
return expandToolGroups(policy?.deny ?? []).some((entry) => normalizeToolName(entry) === "*");
|
||||
return expandToolGroups(policy?.deny ?? []).some(
|
||||
(entry) => normalizeToolPolicyName(entry) === "*",
|
||||
);
|
||||
}
|
||||
|
||||
function listHarnessCandidates(harnesses: AgentHarness[]): AgentHarnessSelectionCandidate[] {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*/
|
||||
import { uniqueStrings } from "@openclaw/normalization-core/string-normalization";
|
||||
import { isToolAllowedByPolicyName } from "./tool-policy-match.js";
|
||||
import { normalizeToolName } from "./tool-policy-shared.js";
|
||||
import { normalizeToolPolicyName } from "./tool-policy-shared.js";
|
||||
|
||||
const ACP_UNSUPPORTED_INHERITED_TOOL_DENY = [
|
||||
"apply_patch",
|
||||
@@ -37,7 +37,7 @@ export function normalizeInheritedToolDenylist(value: unknown): string[] {
|
||||
}
|
||||
return uniqueStrings(
|
||||
value.flatMap((entry) => {
|
||||
const normalized = typeof entry === "string" ? normalizeToolName(entry) : "";
|
||||
const normalized = typeof entry === "string" ? normalizeToolPolicyName(entry) : "";
|
||||
return normalized ? [normalized] : [];
|
||||
}),
|
||||
);
|
||||
|
||||
@@ -3,7 +3,7 @@ import path from "node:path";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import {
|
||||
appendTranscriptMessage,
|
||||
listSessionEntries,
|
||||
listSessionEntriesCore,
|
||||
loadExactSessionEntry,
|
||||
loadTranscriptEvents,
|
||||
persistSessionResetLifecycle,
|
||||
@@ -114,7 +114,7 @@ describe("internal session effects", () => {
|
||||
delivery: { kind: "internal" },
|
||||
createdAt: expect.any(Number),
|
||||
});
|
||||
expect(listSessionEntries({ agentId: "main", storePath })).toEqual([]);
|
||||
expect(listSessionEntriesCore({ agentId: "main", storePath })).toEqual([]);
|
||||
await expect(loadTranscriptEvents(target)).resolves.toEqual([
|
||||
expect.objectContaining({ id: target.sessionId, type: "session" }),
|
||||
]);
|
||||
@@ -173,7 +173,7 @@ describe("internal session effects", () => {
|
||||
type: "message",
|
||||
}),
|
||||
);
|
||||
expect(listSessionEntries({ agentId: "main", storePath })).toEqual([
|
||||
expect(listSessionEntriesCore({ agentId: "main", storePath })).toEqual([
|
||||
expect.objectContaining({ sessionKey: source.sessionKey }),
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -35,7 +35,7 @@ vi.mock("../config/sessions/session-accessor.js", () => {
|
||||
return {
|
||||
loadSessionEntry,
|
||||
loadSessionEntryReadOnly: loadSessionEntry,
|
||||
patchSessionEntry: (...args: unknown[]) => state.updateSessionStoreMock(...args),
|
||||
patchSessionEntryCore: (...args: unknown[]) => state.updateSessionStoreMock(...args),
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import { resolveStorePath } from "../config/sessions/paths.js";
|
||||
import {
|
||||
loadSessionEntry,
|
||||
loadSessionEntryReadOnly,
|
||||
patchSessionEntry,
|
||||
patchSessionEntryCore,
|
||||
} from "../config/sessions/session-accessor.js";
|
||||
import type { SessionEntry } from "../config/sessions/types.js";
|
||||
import type { OpenClawConfig } from "../config/types.openclaw.js";
|
||||
@@ -275,7 +275,7 @@ export async function consolidateLiveModelSwitchAfterRun(params: {
|
||||
if (!storePath) {
|
||||
return;
|
||||
}
|
||||
await patchSessionEntry(
|
||||
await patchSessionEntryCore(
|
||||
{ storePath, sessionKey },
|
||||
(entry) => {
|
||||
if (!entry.liveModelSwitchPending) {
|
||||
@@ -325,7 +325,7 @@ export async function clearLiveModelSwitchPending(params: {
|
||||
if (!storePath) {
|
||||
return;
|
||||
}
|
||||
await patchSessionEntry(
|
||||
await patchSessionEntryCore(
|
||||
{ storePath, sessionKey },
|
||||
(entry) => {
|
||||
const next = { ...entry };
|
||||
|
||||
@@ -9,7 +9,7 @@ import { normalizeAgentId, parseAgentSessionKey } from "../routing/session-key.j
|
||||
import { resolveAgentConfig, resolveDefaultAgentId } from "./agent-scope-config.js";
|
||||
import type { AnyAgentTool } from "./agent-tools.types.js";
|
||||
import { compileGlobPatterns, matchesAnyGlobPattern } from "./glob-pattern.js";
|
||||
import { expandToolGroups, normalizeToolName } from "./tool-policy.js";
|
||||
import { expandToolGroups, normalizeToolPolicyName } from "./tool-policy.js";
|
||||
import { AUTOMATIONS_TOOL_NAME } from "./tools/automations-tool-name.js";
|
||||
|
||||
const LOCAL_MODEL_LEAN_DENY_TOOL_NAMES = new Set([
|
||||
@@ -34,8 +34,8 @@ function resolvePreservedLocalModelLeanToolNames(names?: Iterable<string>) {
|
||||
return [];
|
||||
}
|
||||
return compileGlobPatterns({
|
||||
raw: expandToolGroups([...names]).filter((name) => normalizeToolName(name) !== "*"),
|
||||
normalize: normalizeToolName,
|
||||
raw: expandToolGroups([...names]).filter((name) => normalizeToolPolicyName(name) !== "*"),
|
||||
normalize: normalizeToolPolicyName,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ export function filterLocalModelLeanTools(params: {
|
||||
}
|
||||
const preservedToolNames = resolvePreservedLocalModelLeanToolNames(params.preserveToolNames);
|
||||
return params.tools.filter((tool) => {
|
||||
const normalizedName = normalizeToolName(tool.name);
|
||||
const normalizedName = normalizeToolPolicyName(tool.name);
|
||||
return (
|
||||
matchesAnyGlobPattern(normalizedName, preservedToolNames) ||
|
||||
!LOCAL_MODEL_LEAN_DENY_TOOL_NAMES.has(normalizedName)
|
||||
|
||||
@@ -5,7 +5,7 @@ import type { InternalSessionEntry as SessionEntry } from "../../config/sessions
|
||||
import * as sessionAccessor from "../../config/sessions/session-accessor.js";
|
||||
import {
|
||||
applySessionEntryLifecycleMutation,
|
||||
listSessionEntries,
|
||||
listSessionEntriesCore,
|
||||
} from "../../config/sessions/session-accessor.js";
|
||||
import {
|
||||
getAgentEventLifecycleGeneration,
|
||||
@@ -58,7 +58,7 @@ describe("main session recovery store", () => {
|
||||
|
||||
function readStore(): Record<string, SessionEntry> {
|
||||
return Object.fromEntries(
|
||||
listSessionEntries({ storePath }).map(({ sessionKey: key, entry }) => [key, entry]),
|
||||
listSessionEntriesCore({ storePath }).map(({ sessionKey: key, entry }) => [key, entry]),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ import type { InternalSessionEntry as SessionEntry } from "../../config/sessions
|
||||
import * as sessionAccessor from "../../config/sessions/session-accessor.js";
|
||||
import {
|
||||
appendTranscriptMessage,
|
||||
listSessionEntries,
|
||||
listSessionEntriesCore,
|
||||
loadSessionEntry as loadSessionEntryRaw,
|
||||
loadTranscriptEvents,
|
||||
replaceSessionEntry,
|
||||
@@ -363,7 +363,7 @@ async function writeMainSession({
|
||||
|
||||
function readStore(storePath: string): Record<string, SessionEntry> {
|
||||
return Object.fromEntries(
|
||||
listSessionEntries({ storePath }).map(({ sessionKey, entry }) => [sessionKey, entry]),
|
||||
listSessionEntriesCore({ storePath }).map(({ sessionKey, entry }) => [sessionKey, entry]),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ import { setPluginToolMeta } from "../plugins/tools.js";
|
||||
import { sanitizeServerName } from "./agent-bundle-mcp-names.js";
|
||||
import { compileGlobPatterns, matchesAnyGlobPattern } from "./glob-pattern.js";
|
||||
import type { AgentToolResult } from "./runtime/index.js";
|
||||
import { DEFAULT_PLUGIN_TOOLS_ALLOWLIST_ENTRY, normalizeToolName } from "./tool-policy.js";
|
||||
import { DEFAULT_PLUGIN_TOOLS_ALLOWLIST_ENTRY, normalizeToolPolicyName } from "./tool-policy.js";
|
||||
import { jsonResult } from "./tools/common.js";
|
||||
import type { AnyAgentTool } from "./tools/common.js";
|
||||
import { callGatewayTool } from "./tools/gateway.js";
|
||||
@@ -65,7 +65,7 @@ function mapMcpPayloadToAgentToolResult(payload: unknown): AgentToolResult<unkno
|
||||
}
|
||||
|
||||
function normalizePolicyNames(values: readonly string[] | undefined): Set<string> {
|
||||
return new Set((values ?? []).map((value) => normalizeToolName(value)).filter(Boolean));
|
||||
return new Set((values ?? []).map((value) => normalizeToolPolicyName(value)).filter(Boolean));
|
||||
}
|
||||
|
||||
function toolPolicyAllows(params: {
|
||||
@@ -76,9 +76,9 @@ function toolPolicyAllows(params: {
|
||||
denylist: ReturnType<typeof compileGlobPatterns>;
|
||||
registered: boolean;
|
||||
}): boolean {
|
||||
const pluginId = normalizeToolName(params.pluginId);
|
||||
const toolName = normalizeToolName(params.toolName);
|
||||
const exposedToolName = normalizeToolName(params.exposedToolName ?? params.toolName);
|
||||
const pluginId = normalizeToolPolicyName(params.pluginId);
|
||||
const toolName = normalizeToolPolicyName(params.toolName);
|
||||
const exposedToolName = normalizeToolPolicyName(params.exposedToolName ?? params.toolName);
|
||||
if (
|
||||
matchesAnyGlobPattern(pluginId, params.denylist) ||
|
||||
matchesAnyGlobPattern(toolName, params.denylist) ||
|
||||
@@ -152,7 +152,7 @@ function resolveUniqueToolName(params: {
|
||||
for (let index = 0; index < 100; index += 1) {
|
||||
const suffix = index === 0 ? "" : `_${index + 1}`;
|
||||
const candidate = prependToolNameFragment(params.baseName, nodeFragment, suffix);
|
||||
const normalized = normalizeToolName(candidate);
|
||||
const normalized = normalizeToolPolicyName(candidate);
|
||||
if (
|
||||
isProviderSafeToolName(candidate) &&
|
||||
normalized &&
|
||||
@@ -171,19 +171,19 @@ export function createNodePluginTools(params: {
|
||||
agentSessionKey?: string;
|
||||
}): AnyAgentTool[] {
|
||||
const existingNormalized = new Set(
|
||||
[...(params.existingToolNames ?? [])].map((name) => normalizeToolName(name)),
|
||||
[...(params.existingToolNames ?? [])].map((name) => normalizeToolPolicyName(name)),
|
||||
);
|
||||
const allowlist = normalizePolicyNames(params.toolAllowlist);
|
||||
const denylist = compileGlobPatterns({
|
||||
raw: params.toolDenylist,
|
||||
normalize: normalizeToolName,
|
||||
normalize: normalizeToolPolicyName,
|
||||
});
|
||||
const entries: MaterializedNodeToolEntry[] = [];
|
||||
const nameCounts = new Map<string, number>();
|
||||
for (const entry of listConnectedNodePluginTools()) {
|
||||
const descriptor = entry.descriptor;
|
||||
const command = descriptor.command?.trim();
|
||||
const normalizedName = normalizeToolName(descriptor.name);
|
||||
const normalizedName = normalizeToolPolicyName(descriptor.name);
|
||||
if (!command || !normalizedName) {
|
||||
continue;
|
||||
}
|
||||
@@ -216,7 +216,7 @@ export function createNodePluginTools(params: {
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
existingNormalized.add(normalizeToolName(toolName));
|
||||
existingNormalized.add(normalizeToolPolicyName(toolName));
|
||||
const mcpTool = descriptor.command === NODE_MCP_TOOLS_CALL_COMMAND ? descriptor.mcp : undefined;
|
||||
const tool: AnyAgentTool = {
|
||||
name: toolName,
|
||||
|
||||
@@ -4,7 +4,7 @@ import { getRuntimeConfig } from "../config/io.js";
|
||||
import { parseSqliteSessionFileMarker } from "../config/sessions/legacy-sqlite-marker.js";
|
||||
import { resolveStorePath } from "../config/sessions/paths.js";
|
||||
import {
|
||||
listSessionEntries,
|
||||
listSessionEntriesCore,
|
||||
resolveTranscriptSessionKeyBySessionId,
|
||||
resolveSessionTranscriptRuntimeTarget,
|
||||
type SessionTranscriptRuntimeTarget,
|
||||
@@ -104,7 +104,7 @@ export async function resolveAgentRunSessionTarget(params: {
|
||||
(params.missingSessionKey === "create" ? plainCompatibilitySessionKey : undefined);
|
||||
const markerEntries =
|
||||
legacyMarker && !hasCompleteTypedTarget
|
||||
? listSessionEntries({
|
||||
? listSessionEntriesCore({
|
||||
agentId: legacyMarker.agentId,
|
||||
storePath: legacyMarker.storePath,
|
||||
})
|
||||
|
||||
@@ -8,7 +8,7 @@ import { uniqueStrings } from "@openclaw/normalization-core/string-normalization
|
||||
import type { OpenClawConfig } from "../../config/types.openclaw.js";
|
||||
import { resolveAgentConfig } from "../agent-scope.js";
|
||||
import { compileGlobPatterns, matchesAnyGlobPattern } from "../glob-pattern.js";
|
||||
import { expandToolGroups, normalizeToolName } from "../tool-policy.js";
|
||||
import { expandToolGroups, normalizeToolPolicyName } from "../tool-policy.js";
|
||||
import { DEFAULT_TOOL_ALLOW, DEFAULT_TOOL_DENY } from "./constants.js";
|
||||
import type {
|
||||
SandboxToolPolicy,
|
||||
@@ -157,13 +157,13 @@ function filterDefaultDenyForExplicitAllows(params: {
|
||||
}
|
||||
const allowPatterns = compileGlobPatterns({
|
||||
raw: expandToolGroups(params.explicitAllowPatterns),
|
||||
normalize: normalizeToolName,
|
||||
normalize: normalizeToolPolicyName,
|
||||
});
|
||||
if (allowPatterns.length === 0) {
|
||||
return [...params.deny];
|
||||
}
|
||||
return params.deny.filter(
|
||||
(toolName) => !matchesAnyGlobPattern(normalizeToolName(toolName), allowPatterns),
|
||||
(toolName) => !matchesAnyGlobPattern(normalizeToolPolicyName(toolName), allowPatterns),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -197,15 +197,15 @@ export function classifyToolAgainstSandboxToolPolicy(name: string, policy?: Sand
|
||||
};
|
||||
}
|
||||
|
||||
const normalized = normalizeToolName(name);
|
||||
const normalized = normalizeToolPolicyName(name);
|
||||
const deny = compileGlobPatterns({
|
||||
raw: expandToolGroups(policy.deny ?? []),
|
||||
normalize: normalizeToolName,
|
||||
normalize: normalizeToolPolicyName,
|
||||
});
|
||||
const blockedByDeny = matchesAnyGlobPattern(normalized, deny);
|
||||
const allow = compileGlobPatterns({
|
||||
raw: expandToolGroups(policy.allow ?? []),
|
||||
normalize: normalizeToolName,
|
||||
normalize: normalizeToolPolicyName,
|
||||
});
|
||||
const blockedByAllow =
|
||||
!blockedByDeny && allow.length > 0 && !matchesAnyGlobPattern(normalized, allow);
|
||||
|
||||
@@ -15,7 +15,7 @@ import { isToolAllowedByPolicies } from "../tool-policy-match.js";
|
||||
import {
|
||||
expandToolGroups,
|
||||
mergeAlsoAllowPolicy,
|
||||
normalizeToolName,
|
||||
normalizeToolPolicyName,
|
||||
resolveToolProfilePolicy,
|
||||
} from "../tool-policy.js";
|
||||
import { resolveSandboxConfigForAgent } from "./config.js";
|
||||
@@ -54,7 +54,7 @@ function findUnconfinedAllowedTool(
|
||||
}
|
||||
for (const entry of candidatePolicy.allow) {
|
||||
for (const candidate of expandToolGroups([entry])) {
|
||||
const normalized = normalizeToolName(candidate);
|
||||
const normalized = normalizeToolPolicyName(candidate);
|
||||
if (!isToolAllowedByPolicies(normalized, policies)) {
|
||||
continue;
|
||||
}
|
||||
@@ -216,14 +216,14 @@ export function resolveSandboxWorkspaceAuthority(params: {
|
||||
sandboxPolicy: sandbox.tools,
|
||||
});
|
||||
const unavailableTool = (params.requiredToolNames ?? [])
|
||||
.map(normalizeToolName)
|
||||
.map(normalizeToolPolicyName)
|
||||
.find((name) => !isToolAllowedByPolicies(name, policies));
|
||||
if (unavailableTool) {
|
||||
confinementError = `target tool policy blocks required tool ${unavailableTool}.`;
|
||||
} else {
|
||||
const unsafeTool = findUnconfinedAllowedTool(
|
||||
policies,
|
||||
new Set((params.confinedToolNames ?? []).map(normalizeToolName)),
|
||||
new Set((params.confinedToolNames ?? []).map(normalizeToolPolicyName)),
|
||||
);
|
||||
if (unsafeTool) {
|
||||
confinementError = `target sandbox allows unclassified tool surface ${unsafeTool}.`;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import {
|
||||
appendTranscriptMessage,
|
||||
loadSessionEntry,
|
||||
patchSessionEntry,
|
||||
patchSessionEntryCore,
|
||||
} from "../config/sessions/session-accessor.js";
|
||||
import {
|
||||
createAgentPatchedSessionModelFallback,
|
||||
@@ -47,7 +47,7 @@ async function reconcileAgentPatchedSessionModel(params: {
|
||||
let note: string | undefined;
|
||||
let sessionId: string | undefined;
|
||||
let result: "cleared" | "promoted" | "reverted" | "none" = "none";
|
||||
await patchSessionEntry(
|
||||
await patchSessionEntryCore(
|
||||
{
|
||||
agentId: params.agentId,
|
||||
sessionKey: params.sessionKey,
|
||||
|
||||
@@ -6,7 +6,7 @@ import { CommandLane } from "../process/lanes.js";
|
||||
import { MAX_TIMER_TIMEOUT_MS } from "../shared/number-coercion.js";
|
||||
|
||||
const sessionAccessorMocks = vi.hoisted(() => ({
|
||||
patchSessionEntry: vi.fn(),
|
||||
patchSessionEntryCore: vi.fn(),
|
||||
}));
|
||||
|
||||
const commandQueueMocks = vi.hoisted(() => ({
|
||||
@@ -50,7 +50,7 @@ describe("session suspension", () => {
|
||||
const { resetSessionSuspensionStateForTest } =
|
||||
await import("./session-suspension.test-support.js");
|
||||
resetSessionSuspensionStateForTest();
|
||||
sessionAccessorMocks.patchSessionEntry.mockClear();
|
||||
sessionAccessorMocks.patchSessionEntryCore.mockClear();
|
||||
commandQueueMocks.setCommandLaneConcurrency.mockClear();
|
||||
});
|
||||
|
||||
@@ -183,7 +183,7 @@ describe("session suspension", () => {
|
||||
vi.useFakeTimers();
|
||||
const { setGatewayLaneResumeConcurrencies } = await import("./session-suspension.js");
|
||||
let resolvePatch: (() => void) | undefined;
|
||||
sessionAccessorMocks.patchSessionEntry.mockImplementationOnce(async (_scope, update) => {
|
||||
sessionAccessorMocks.patchSessionEntryCore.mockImplementationOnce(async (_scope, update) => {
|
||||
await new Promise<void>((resolve) => {
|
||||
resolvePatch = resolve;
|
||||
});
|
||||
@@ -222,7 +222,7 @@ describe("session suspension", () => {
|
||||
await suspendLane(Number.MAX_SAFE_INTEGER, {} as OpenClawConfig, CommandLane.Main);
|
||||
|
||||
expect(setTimeoutSpy).toHaveBeenCalledWith(expect.any(Function), MAX_TIMER_TIMEOUT_MS);
|
||||
const buildPatch = sessionAccessorMocks.patchSessionEntry.mock.calls[0]?.[1] as (_entry: {
|
||||
const buildPatch = sessionAccessorMocks.patchSessionEntryCore.mock.calls[0]?.[1] as (_entry: {
|
||||
quotaSuspension?: unknown;
|
||||
}) => {
|
||||
quotaSuspension?: { expectedResumeBy?: number };
|
||||
@@ -261,12 +261,12 @@ describe("session suspension", () => {
|
||||
expect(commandQueueMocks.setCommandLaneConcurrency).toHaveBeenCalledWith(CommandLane.Nested, 0);
|
||||
expect(clearSessionSuspensionTimers()).toBe(1);
|
||||
commandQueueMocks.setCommandLaneConcurrency.mockClear();
|
||||
sessionAccessorMocks.patchSessionEntry.mockClear();
|
||||
sessionAccessorMocks.patchSessionEntryCore.mockClear();
|
||||
|
||||
await suspendLane(100, {} as OpenClawConfig, CommandLane.Nested);
|
||||
|
||||
expect(commandQueueMocks.setCommandLaneConcurrency).not.toHaveBeenCalled();
|
||||
expect(sessionAccessorMocks.patchSessionEntry).not.toHaveBeenCalled();
|
||||
expect(sessionAccessorMocks.patchSessionEntryCore).not.toHaveBeenCalled();
|
||||
|
||||
enableSessionSuspensionTimersForGatewayStart();
|
||||
await suspendLane(100, {} as OpenClawConfig, CommandLane.Nested);
|
||||
@@ -378,7 +378,7 @@ describe("session suspension", () => {
|
||||
laneId?: string;
|
||||
}
|
||||
| undefined;
|
||||
sessionAccessorMocks.patchSessionEntry.mockImplementationOnce(async (_scope, update) => {
|
||||
sessionAccessorMocks.patchSessionEntryCore.mockImplementationOnce(async (_scope, update) => {
|
||||
await new Promise<void>((resolve) => {
|
||||
resolvePatch = resolve;
|
||||
});
|
||||
@@ -400,7 +400,7 @@ describe("session suspension", () => {
|
||||
|
||||
expect(commandQueueMocks.setCommandLaneConcurrency).not.toHaveBeenCalled();
|
||||
expect(writtenQuotaSuspension).toBeUndefined();
|
||||
expect(sessionAccessorMocks.patchSessionEntry).toHaveBeenCalledOnce();
|
||||
expect(sessionAccessorMocks.patchSessionEntryCore).toHaveBeenCalledOnce();
|
||||
|
||||
await vi.advanceTimersByTimeAsync(100);
|
||||
|
||||
@@ -410,7 +410,7 @@ describe("session suspension", () => {
|
||||
it("does not let a pending suspension regain ownership after test state resets", async () => {
|
||||
let resolvePatch: (() => void) | undefined;
|
||||
let writtenQuotaSuspension: unknown;
|
||||
sessionAccessorMocks.patchSessionEntry.mockImplementationOnce(async (_scope, update) => {
|
||||
sessionAccessorMocks.patchSessionEntryCore.mockImplementationOnce(async (_scope, update) => {
|
||||
await new Promise<void>((resolve) => {
|
||||
resolvePatch = resolve;
|
||||
});
|
||||
@@ -452,7 +452,7 @@ describe("session suspension", () => {
|
||||
const initialWritesReleased = new Promise<void>((resolve) => {
|
||||
releaseInitialWrites = resolve;
|
||||
});
|
||||
sessionAccessorMocks.patchSessionEntry.mockImplementation(async (_scope, update) => {
|
||||
sessionAccessorMocks.patchSessionEntryCore.mockImplementation(async (_scope, update) => {
|
||||
const patch = update(storeEntry) as typeof storeEntry | null;
|
||||
if (patch && "quotaSuspension" in patch) {
|
||||
storeEntry =
|
||||
@@ -481,7 +481,7 @@ describe("session suspension", () => {
|
||||
|
||||
it("still throttles the lane when persistence fails while gateway is active", async () => {
|
||||
vi.useFakeTimers();
|
||||
sessionAccessorMocks.patchSessionEntry.mockRejectedValueOnce(new Error("disk busy"));
|
||||
sessionAccessorMocks.patchSessionEntryCore.mockRejectedValueOnce(new Error("disk busy"));
|
||||
|
||||
await suspendLane(
|
||||
100,
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import { AsyncLocalStorage } from "node:async_hooks";
|
||||
import { resolveAgentMaxConcurrent, resolveSubagentMaxConcurrent } from "../config/agent-limits.js";
|
||||
import { resolveCronMaxConcurrentRuns } from "../config/cron-limits.js";
|
||||
import { patchSessionEntry } from "../config/sessions/session-accessor.js";
|
||||
import { patchSessionEntryCore } from "../config/sessions/session-accessor.js";
|
||||
import type { QuotaSuspension } from "../config/sessions/types.js";
|
||||
import type { OpenClawConfig } from "../config/types.openclaw.js";
|
||||
import { createSubsystemLogger } from "../logging/subsystem.js";
|
||||
@@ -374,7 +374,7 @@ async function suspendSessionQueued(params: SessionSuspensionParams, queuedGener
|
||||
let persistedSuspension: boolean;
|
||||
|
||||
try {
|
||||
const patchedEntry = await patchSessionEntry(
|
||||
const patchedEntry = await patchSessionEntryCore(
|
||||
{ storePath, sessionKey },
|
||||
(entry) => {
|
||||
if (getSessionSuspensionState().cleanupGeneration !== suspensionGeneration) {
|
||||
@@ -423,7 +423,7 @@ async function suspendSessionQueued(params: SessionSuspensionParams, queuedGener
|
||||
(postPatchState.cleanupActive || suspensionGeneration !== postPatchState.cleanupGeneration)
|
||||
) {
|
||||
try {
|
||||
await patchSessionEntry(
|
||||
await patchSessionEntryCore(
|
||||
{ storePath, sessionKey },
|
||||
(entry) =>
|
||||
entry.quotaSuspension?.suspendedAt === now &&
|
||||
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
*/
|
||||
import { expandTildePath } from "../../shared/tilde-path.js";
|
||||
import { CONFIG_DIR_NAME } from "../config.js";
|
||||
import { parseFrontmatter } from "../utils/frontmatter.js";
|
||||
import { parsePromptFrontmatter } from "../utils/frontmatter.js";
|
||||
import { createSyntheticSourceInfo, type SourceInfo } from "./source-info.js";
|
||||
|
||||
/**
|
||||
@@ -30,7 +30,7 @@ export interface PromptTemplate {
|
||||
function loadTemplateFromFile(filePath: string, sourceInfo: SourceInfo): PromptTemplate | null {
|
||||
try {
|
||||
const rawContent = readFileSync(filePath, "utf-8");
|
||||
const { frontmatter, body } = parseFrontmatter<Record<string, string>>(rawContent);
|
||||
const { frontmatter, body } = parsePromptFrontmatter<Record<string, string>>(rawContent);
|
||||
|
||||
const name = basename(filePath).replace(/\.md$/, "");
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ type OutputDeps = Pick<
|
||||
OutputRuntime,
|
||||
| "callGateway"
|
||||
| "getRuntimeConfig"
|
||||
| "readSessionEntry"
|
||||
| "readSubagentSessionEntry"
|
||||
| "readSessionMessagesAsync"
|
||||
| "resolveAgentIdFromSessionKey"
|
||||
| "resolveStorePath"
|
||||
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
|
||||
type CallGateway = typeof import("../../../gateway/call.js").callGateway;
|
||||
type GetRuntimeConfig = typeof import("./subagent-announce.runtime.js").getRuntimeConfig;
|
||||
type ReadSessionEntry = typeof import("./subagent-announce.runtime.js").readSessionEntry;
|
||||
type ReadSessionEntry = typeof import("./subagent-announce.runtime.js").readSubagentSessionEntry;
|
||||
type ReadSessionMessagesAsync =
|
||||
typeof import("./subagent-announce.runtime.js").readSessionMessagesAsync;
|
||||
type ResolveAgentIdFromSessionKey =
|
||||
@@ -89,7 +89,7 @@ describe("buildCompactAnnounceStatsLine", () => {
|
||||
it("rolls one-decimal thousand token stats over to the million unit", async () => {
|
||||
testing.setDepsForTest({
|
||||
getRuntimeConfig: (() => ({ session: { store: "memory" } })) as GetRuntimeConfig,
|
||||
readSessionEntry: (() => ({
|
||||
readSubagentSessionEntry: (() => ({
|
||||
sessionId: "child-session",
|
||||
updatedAt: 0,
|
||||
inputTokens: 999_999,
|
||||
|
||||
@@ -25,7 +25,7 @@ import {
|
||||
import {
|
||||
callGateway,
|
||||
getRuntimeConfig,
|
||||
readSessionEntry,
|
||||
readSubagentSessionEntry,
|
||||
readSessionMessagesAsync,
|
||||
resolveAgentIdFromSessionKey,
|
||||
resolveStorePath,
|
||||
@@ -47,7 +47,7 @@ const ASSISTANT_TOOL_CALL_BLOCK_TYPES = new Set([
|
||||
type SubagentAnnounceOutputDeps = {
|
||||
callGateway: typeof callGateway;
|
||||
getRuntimeConfig: typeof getRuntimeConfig;
|
||||
readSessionEntry: typeof readSessionEntry;
|
||||
readSubagentSessionEntry: typeof readSubagentSessionEntry;
|
||||
readSessionMessagesAsync: typeof readSessionMessagesAsync;
|
||||
resolveAgentIdFromSessionKey: typeof resolveAgentIdFromSessionKey;
|
||||
resolveStorePath: typeof resolveStorePath;
|
||||
@@ -56,7 +56,7 @@ type SubagentAnnounceOutputDeps = {
|
||||
const defaultSubagentAnnounceOutputDeps: SubagentAnnounceOutputDeps = {
|
||||
callGateway,
|
||||
getRuntimeConfig,
|
||||
readSessionEntry,
|
||||
readSubagentSessionEntry,
|
||||
readSessionMessagesAsync,
|
||||
resolveAgentIdFromSessionKey,
|
||||
resolveStorePath,
|
||||
@@ -650,7 +650,7 @@ export async function buildCompactAnnounceStatsLine(params: {
|
||||
const cfg = subagentAnnounceOutputDeps.getRuntimeConfig();
|
||||
const agentId = subagentAnnounceOutputDeps.resolveAgentIdFromSessionKey(params.sessionKey);
|
||||
const storePath = subagentAnnounceOutputDeps.resolveStorePath(cfg.session?.store, { agentId });
|
||||
let entry = subagentAnnounceOutputDeps.readSessionEntry(storePath, params.sessionKey);
|
||||
let entry = subagentAnnounceOutputDeps.readSubagentSessionEntry(storePath, params.sessionKey);
|
||||
const tokenWaitAttempts = isFastTestMode() ? 1 : 3;
|
||||
for (let attempt = 0; attempt < tokenWaitAttempts; attempt += 1) {
|
||||
const hasTokenData =
|
||||
@@ -665,7 +665,7 @@ export async function buildCompactAnnounceStatsLine(params: {
|
||||
setTimeout(resolve, 150);
|
||||
});
|
||||
}
|
||||
entry = subagentAnnounceOutputDeps.readSessionEntry(storePath, params.sessionKey);
|
||||
entry = subagentAnnounceOutputDeps.readSubagentSessionEntry(storePath, params.sessionKey);
|
||||
}
|
||||
|
||||
const input = typeof entry?.inputTokens === "number" ? entry.inputTokens : 0;
|
||||
|
||||
@@ -430,7 +430,7 @@ describe("subagent announce formatting", () => {
|
||||
req: Parameters<typeof gatewayCall.callGateway>[0],
|
||||
) => (await callGatewaySpy(req)) as T,
|
||||
getRuntimeConfig: () => configOverride,
|
||||
readSessionEntry: (_storePath, sessionKey) => loadSessionStoreFixture()[sessionKey],
|
||||
readSubagentSessionEntry: (_storePath, sessionKey) => loadSessionStoreFixture()[sessionKey],
|
||||
resolveAgentIdFromSessionKey: () => "main",
|
||||
resolveStorePath: () => "/tmp/sessions.json",
|
||||
});
|
||||
|
||||
@@ -44,7 +44,7 @@ vi.mock("./subagent-announce.runtime.js", () => ({
|
||||
getRuntimeConfig: () => ({ session: { mainKey: "main", scope: "per-sender" } }),
|
||||
loadSessionStore: vi.fn(() => ({})),
|
||||
readSessionMessagesAsync: vi.fn(async () => []),
|
||||
readSessionEntry: vi.fn(() => undefined),
|
||||
readSubagentSessionEntry: vi.fn(() => undefined),
|
||||
resolveAgentIdFromSessionKey: vi.fn(() => "main"),
|
||||
resolveMainSessionKey: vi.fn(() => "agent:main:main"),
|
||||
resolveStorePath: vi.fn(() => "/tmp/sessions.json"),
|
||||
|
||||
@@ -8,7 +8,7 @@ export { getRuntimeConfig } from "../../../config/config.js";
|
||||
export { resolveAgentIdFromSessionKey, resolveStorePath } from "../../../config/sessions.js";
|
||||
import { loadSessionEntry } from "../../../config/sessions/session-accessor.js";
|
||||
|
||||
export function readSessionEntry(storePath: string, sessionKey: string) {
|
||||
export function readSubagentSessionEntry(storePath: string, sessionKey: string) {
|
||||
return loadSessionEntry({ storePath, sessionKey });
|
||||
}
|
||||
export { callGateway } from "../../../gateway/call.js";
|
||||
|
||||
@@ -71,7 +71,7 @@ vi.mock("./subagent-announce.runtime.js", () => ({
|
||||
getRuntimeConfig: () => mockConfig,
|
||||
loadSessionStore: (storePath: string) => loadSessionStoreMock(storePath),
|
||||
readSessionMessagesAsync: vi.fn(async () => []),
|
||||
readSessionEntry: (storePath: string, sessionKey: string) =>
|
||||
readSubagentSessionEntry: (storePath: string, sessionKey: string) =>
|
||||
(loadSessionStoreMock(storePath) as Record<string, unknown>)[sessionKey],
|
||||
resolveAgentIdFromSessionKey: (sessionKey: string) =>
|
||||
resolveAgentIdFromSessionKeyMock(sessionKey),
|
||||
|
||||
@@ -188,7 +188,7 @@ vi.mock("./subagent-announce.runtime.js", () => ({
|
||||
getRuntimeConfig: () => configOverride,
|
||||
loadSessionStore: vi.fn(() => sessionStore),
|
||||
readSessionMessagesAsync: vi.fn(async () => []),
|
||||
readSessionEntry: (_storePath: string, sessionKey: string) => sessionStore[sessionKey],
|
||||
readSubagentSessionEntry: (_storePath: string, sessionKey: string) => sessionStore[sessionKey],
|
||||
resolveAgentIdFromSessionKey: () => "main",
|
||||
resolveStorePath: () => "/tmp/sessions-main.json",
|
||||
resolveMainSessionKey: () => "agent:main:main",
|
||||
|
||||
@@ -3,7 +3,7 @@ export * from "./subagent-control.js";
|
||||
type ControlRuntime = typeof import("./subagent-control.runtime.js");
|
||||
type ControlDeps = {
|
||||
callGateway: typeof import("../../../gateway/call.js").callGateway;
|
||||
patchSessionEntry: typeof import("../../../config/sessions/session-accessor.js").patchSessionEntry;
|
||||
patchSessionEntryCore: typeof import("../../../config/sessions/session-accessor.js").patchSessionEntryCore;
|
||||
abortEmbeddedAgentRun: ControlRuntime["abortEmbeddedAgentRun"];
|
||||
isEmbeddedAgentRunActive: ControlRuntime["isEmbeddedAgentRunActive"];
|
||||
clearSessionQueues: ControlRuntime["clearSessionQueues"];
|
||||
|
||||
@@ -167,7 +167,7 @@ function setSubagentControlDepsForTest(
|
||||
abortEmbeddedAgentRun: () => false,
|
||||
isEmbeddedAgentRunActive: () => false,
|
||||
clearSessionQueues: () => ({ followupCleared: 0, laneCleared: 0, keys: [] }),
|
||||
patchSessionEntry: async (
|
||||
patchSessionEntryCore: async (
|
||||
scope: SessionAccessScope,
|
||||
patcher: (
|
||||
entry: SessionEntry,
|
||||
@@ -811,7 +811,7 @@ describe("killSubagentRunAdmin", () => {
|
||||
});
|
||||
return true;
|
||||
},
|
||||
patchSessionEntry: async (_scope, patcher) => {
|
||||
patchSessionEntryCore: async (_scope, patcher) => {
|
||||
const current = { sessionId: "sess-abort-lifecycle-race", updatedAt: Date.now() };
|
||||
const patch = await patcher(current, { existingEntry: { ...current } });
|
||||
abortedLastRunWrites.push(patch?.abortedLastRun === true);
|
||||
@@ -878,7 +878,7 @@ describe("killSubagentRunAdmin", () => {
|
||||
});
|
||||
return true;
|
||||
},
|
||||
patchSessionEntry: async (_scope, patcher) => {
|
||||
patchSessionEntryCore: async (_scope, patcher) => {
|
||||
const current = { sessionId: "sess-completion-race", updatedAt: Date.now() };
|
||||
const patch = await patcher(current, { existingEntry: { ...current } });
|
||||
abortedLastRunWrites.push(patch?.abortedLastRun === true);
|
||||
@@ -953,7 +953,7 @@ describe("killSubagentRunAdmin", () => {
|
||||
setSubagentControlDepsForTest({
|
||||
isEmbeddedAgentRunActive: () => true,
|
||||
abortEmbeddedAgentRun: () => true,
|
||||
patchSessionEntry: async (scope, patcher) => {
|
||||
patchSessionEntryCore: async (scope, patcher) => {
|
||||
if (!scope.storePath) {
|
||||
return null;
|
||||
}
|
||||
@@ -1032,7 +1032,7 @@ describe("killSubagentRunAdmin", () => {
|
||||
run.pauseReason = "sessions_yield";
|
||||
return true;
|
||||
},
|
||||
patchSessionEntry: async () => {
|
||||
patchSessionEntryCore: async () => {
|
||||
return null;
|
||||
},
|
||||
});
|
||||
@@ -1471,7 +1471,7 @@ describe("killControlledSubagentRun", () => {
|
||||
isEmbeddedAgentRunActive: () => false,
|
||||
abortEmbeddedAgentRun: abort,
|
||||
clearSessionQueues: clearQueues,
|
||||
patchSessionEntry: async (_scope, patcher) => {
|
||||
patchSessionEntryCore: async (_scope, patcher) => {
|
||||
markPersistenceStarted();
|
||||
await persistenceRelease;
|
||||
const current = { sessionId: "sess-persist-generation-race", updatedAt: Date.now() };
|
||||
@@ -1624,7 +1624,7 @@ describe("killControlledSubagentRun", () => {
|
||||
addSubagentRunForTests(entry);
|
||||
const patches: Array<Partial<SessionEntry> | null> = [];
|
||||
setSubagentControlDepsForTest({
|
||||
patchSessionEntry: async (_scope, patcher) => {
|
||||
patchSessionEntryCore: async (_scope, patcher) => {
|
||||
const replacement: SessionEntry = {
|
||||
sessionId: "sess-kill-session-patch-reset",
|
||||
lifecycleRevision: "revision-after-reset",
|
||||
@@ -2079,7 +2079,7 @@ describe("killControlledSubagentRun", () => {
|
||||
const abortedLastRunWrites: boolean[] = [];
|
||||
let persistenceWrites = 0;
|
||||
setSubagentControlDepsForTest({
|
||||
patchSessionEntry: async (_scope, patcher) => {
|
||||
patchSessionEntryCore: async (_scope, patcher) => {
|
||||
const current = { sessionId, updatedAt: 1, abortedLastRun: true };
|
||||
const patch = await patcher(current, { existingEntry: { ...current } });
|
||||
if (patch) {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user