@aria-cli/tools 1.0.8 → 1.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +9 -6
- package/dist-cjs/.tsbuildinfo +0 -1
- package/dist-cjs/ask-user-interaction.d.ts +0 -10
- package/dist-cjs/ask-user-interaction.js +0 -28
- package/dist-cjs/ask-user-interaction.js.map +0 -1
- package/dist-cjs/cache/web-cache.d.ts +0 -52
- package/dist-cjs/cache/web-cache.js +0 -71
- package/dist-cjs/cache/web-cache.js.map +0 -1
- package/dist-cjs/definitions/arion.d.ts +0 -8
- package/dist-cjs/definitions/arion.js +0 -108
- package/dist-cjs/definitions/arion.js.map +0 -1
- package/dist-cjs/definitions/browser/browser.d.ts +0 -2
- package/dist-cjs/definitions/browser/browser.js +0 -422
- package/dist-cjs/definitions/browser/browser.js.map +0 -1
- package/dist-cjs/definitions/browser/index.d.ts +0 -1
- package/dist-cjs/definitions/browser/index.js +0 -9
- package/dist-cjs/definitions/browser/index.js.map +0 -1
- package/dist-cjs/definitions/browser/pw-downloads.d.ts +0 -13
- package/dist-cjs/definitions/browser/pw-downloads.js +0 -118
- package/dist-cjs/definitions/browser/pw-downloads.js.map +0 -1
- package/dist-cjs/definitions/browser/pw-interactions.d.ts +0 -78
- package/dist-cjs/definitions/browser/pw-interactions.js +0 -214
- package/dist-cjs/definitions/browser/pw-interactions.js.map +0 -1
- package/dist-cjs/definitions/browser/pw-responses.d.ts +0 -28
- package/dist-cjs/definitions/browser/pw-responses.js +0 -85
- package/dist-cjs/definitions/browser/pw-responses.js.map +0 -1
- package/dist-cjs/definitions/browser/pw-session.d.ts +0 -65
- package/dist-cjs/definitions/browser/pw-session.js +0 -327
- package/dist-cjs/definitions/browser/pw-session.js.map +0 -1
- package/dist-cjs/definitions/browser/pw-shared.d.ts +0 -22
- package/dist-cjs/definitions/browser/pw-shared.js +0 -73
- package/dist-cjs/definitions/browser/pw-shared.js.map +0 -1
- package/dist-cjs/definitions/browser/pw-snapshot.d.ts +0 -34
- package/dist-cjs/definitions/browser/pw-snapshot.js +0 -308
- package/dist-cjs/definitions/browser/pw-snapshot.js.map +0 -1
- package/dist-cjs/definitions/browser/pw-state.d.ts +0 -22
- package/dist-cjs/definitions/browser/pw-state.js +0 -71
- package/dist-cjs/definitions/browser/pw-state.js.map +0 -1
- package/dist-cjs/definitions/browser/types.d.ts +0 -277
- package/dist-cjs/definitions/browser/types.js +0 -6
- package/dist-cjs/definitions/browser/types.js.map +0 -1
- package/dist-cjs/definitions/code-intelligence.d.ts +0 -8
- package/dist-cjs/definitions/code-intelligence.js +0 -474
- package/dist-cjs/definitions/code-intelligence.js.map +0 -1
- package/dist-cjs/definitions/core.d.ts +0 -47
- package/dist-cjs/definitions/core.js +0 -134
- package/dist-cjs/definitions/core.js.map +0 -1
- package/dist-cjs/definitions/delegation.d.ts +0 -11
- package/dist-cjs/definitions/delegation.js +0 -516
- package/dist-cjs/definitions/delegation.js.map +0 -1
- package/dist-cjs/definitions/deploy.d.ts +0 -15
- package/dist-cjs/definitions/deploy.js +0 -69
- package/dist-cjs/definitions/deploy.js.map +0 -1
- package/dist-cjs/definitions/filesystem.d.ts +0 -9
- package/dist-cjs/definitions/filesystem.js +0 -200
- package/dist-cjs/definitions/filesystem.js.map +0 -1
- package/dist-cjs/definitions/frg.d.ts +0 -3
- package/dist-cjs/definitions/frg.js +0 -67
- package/dist-cjs/definitions/frg.js.map +0 -1
- package/dist-cjs/definitions/index.d.ts +0 -19
- package/dist-cjs/definitions/index.js +0 -44
- package/dist-cjs/definitions/index.js.map +0 -1
- package/dist-cjs/definitions/memory.d.ts +0 -8
- package/dist-cjs/definitions/memory.js +0 -127
- package/dist-cjs/definitions/memory.js.map +0 -1
- package/dist-cjs/definitions/messaging.d.ts +0 -11
- package/dist-cjs/definitions/messaging.js +0 -632
- package/dist-cjs/definitions/messaging.js.map +0 -1
- package/dist-cjs/definitions/meta.d.ts +0 -11
- package/dist-cjs/definitions/meta.js +0 -353
- package/dist-cjs/definitions/meta.js.map +0 -1
- package/dist-cjs/definitions/network.d.ts +0 -11
- package/dist-cjs/definitions/network.js +0 -163
- package/dist-cjs/definitions/network.js.map +0 -1
- package/dist-cjs/definitions/outlook.d.ts +0 -2
- package/dist-cjs/definitions/outlook.js +0 -281
- package/dist-cjs/definitions/outlook.js.map +0 -1
- package/dist-cjs/definitions/patch/apply-patch.d.ts +0 -11
- package/dist-cjs/definitions/patch/apply-patch.js +0 -192
- package/dist-cjs/definitions/patch/apply-patch.js.map +0 -1
- package/dist-cjs/definitions/patch/fuzzy-match.d.ts +0 -10
- package/dist-cjs/definitions/patch/fuzzy-match.js +0 -173
- package/dist-cjs/definitions/patch/fuzzy-match.js.map +0 -1
- package/dist-cjs/definitions/patch/index.d.ts +0 -1
- package/dist-cjs/definitions/patch/index.js +0 -6
- package/dist-cjs/definitions/patch/index.js.map +0 -1
- package/dist-cjs/definitions/patch/patch-parser.d.ts +0 -50
- package/dist-cjs/definitions/patch/patch-parser.js +0 -216
- package/dist-cjs/definitions/patch/patch-parser.js.map +0 -1
- package/dist-cjs/definitions/patch/sandbox-paths.d.ts +0 -18
- package/dist-cjs/definitions/patch/sandbox-paths.js +0 -114
- package/dist-cjs/definitions/patch/sandbox-paths.js.map +0 -1
- package/dist-cjs/definitions/process/index.d.ts +0 -1
- package/dist-cjs/definitions/process/index.js +0 -9
- package/dist-cjs/definitions/process/index.js.map +0 -1
- package/dist-cjs/definitions/process/process-registry.d.ts +0 -67
- package/dist-cjs/definitions/process/process-registry.js +0 -232
- package/dist-cjs/definitions/process/process-registry.js.map +0 -1
- package/dist-cjs/definitions/process/process.d.ts +0 -9
- package/dist-cjs/definitions/process/process.js +0 -390
- package/dist-cjs/definitions/process/process.js.map +0 -1
- package/dist-cjs/definitions/process/pty-keys.d.ts +0 -13
- package/dist-cjs/definitions/process/pty-keys.js +0 -260
- package/dist-cjs/definitions/process/pty-keys.js.map +0 -1
- package/dist-cjs/definitions/process/session-slug.d.ts +0 -1
- package/dist-cjs/definitions/process/session-slug.js +0 -146
- package/dist-cjs/definitions/process/session-slug.js.map +0 -1
- package/dist-cjs/definitions/quip.d.ts +0 -2
- package/dist-cjs/definitions/quip.js +0 -199
- package/dist-cjs/definitions/quip.js.map +0 -1
- package/dist-cjs/definitions/search.d.ts +0 -9
- package/dist-cjs/definitions/search.js +0 -64
- package/dist-cjs/definitions/search.js.map +0 -1
- package/dist-cjs/definitions/session-history.d.ts +0 -11
- package/dist-cjs/definitions/session-history.js +0 -73
- package/dist-cjs/definitions/session-history.js.map +0 -1
- package/dist-cjs/definitions/shell.d.ts +0 -8
- package/dist-cjs/definitions/shell.js +0 -185
- package/dist-cjs/definitions/shell.js.map +0 -1
- package/dist-cjs/definitions/slack.d.ts +0 -2
- package/dist-cjs/definitions/slack.js +0 -184
- package/dist-cjs/definitions/slack.js.map +0 -1
- package/dist-cjs/definitions/web.d.ts +0 -8
- package/dist-cjs/definitions/web.js +0 -113
- package/dist-cjs/definitions/web.js.map +0 -1
- package/dist-cjs/executors/apply-patch.d.ts +0 -51
- package/dist-cjs/executors/apply-patch.js +0 -939
- package/dist-cjs/executors/apply-patch.js.map +0 -1
- package/dist-cjs/executors/arion.d.ts +0 -50
- package/dist-cjs/executors/arion.js +0 -126
- package/dist-cjs/executors/arion.js.map +0 -1
- package/dist-cjs/executors/code-intelligence.d.ts +0 -138
- package/dist-cjs/executors/code-intelligence.js +0 -926
- package/dist-cjs/executors/code-intelligence.js.map +0 -1
- package/dist-cjs/executors/deploy.d.ts +0 -169
- package/dist-cjs/executors/deploy.js +0 -870
- package/dist-cjs/executors/deploy.js.map +0 -1
- package/dist-cjs/executors/filesystem.d.ts +0 -150
- package/dist-cjs/executors/filesystem.js +0 -1168
- package/dist-cjs/executors/filesystem.js.map +0 -1
- package/dist-cjs/executors/frg-freshness.d.ts +0 -93
- package/dist-cjs/executors/frg-freshness.js +0 -628
- package/dist-cjs/executors/frg-freshness.js.map +0 -1
- package/dist-cjs/executors/frg.d.ts +0 -27
- package/dist-cjs/executors/frg.js +0 -335
- package/dist-cjs/executors/frg.js.map +0 -1
- package/dist-cjs/executors/index.d.ts +0 -44
- package/dist-cjs/executors/index.js +0 -144
- package/dist-cjs/executors/index.js.map +0 -1
- package/dist-cjs/executors/learning-meta.d.ts +0 -87
- package/dist-cjs/executors/learning-meta.js +0 -1166
- package/dist-cjs/executors/learning-meta.js.map +0 -1
- package/dist-cjs/executors/lsp-client.d.ts +0 -38
- package/dist-cjs/executors/lsp-client.js +0 -311
- package/dist-cjs/executors/lsp-client.js.map +0 -1
- package/dist-cjs/executors/memory.d.ts +0 -203
- package/dist-cjs/executors/memory.js +0 -797
- package/dist-cjs/executors/memory.js.map +0 -1
- package/dist-cjs/executors/meta.d.ts +0 -73
- package/dist-cjs/executors/meta.js +0 -227
- package/dist-cjs/executors/meta.js.map +0 -1
- package/dist-cjs/executors/process-registry.d.ts +0 -98
- package/dist-cjs/executors/process-registry.js +0 -470
- package/dist-cjs/executors/process-registry.js.map +0 -1
- package/dist-cjs/executors/pty-session-store.d.ts +0 -14
- package/dist-cjs/executors/pty-session-store.js +0 -35
- package/dist-cjs/executors/pty-session-store.js.map +0 -1
- package/dist-cjs/executors/pty.d.ts +0 -133
- package/dist-cjs/executors/pty.js +0 -313
- package/dist-cjs/executors/pty.js.map +0 -1
- package/dist-cjs/executors/restart.d.ts +0 -13
- package/dist-cjs/executors/restart.js +0 -156
- package/dist-cjs/executors/restart.js.map +0 -1
- package/dist-cjs/executors/search-freshness.d.ts +0 -50
- package/dist-cjs/executors/search-freshness.js +0 -235
- package/dist-cjs/executors/search-freshness.js.map +0 -1
- package/dist-cjs/executors/search-types.d.ts +0 -52
- package/dist-cjs/executors/search-types.js +0 -57
- package/dist-cjs/executors/search-types.js.map +0 -1
- package/dist-cjs/executors/search.d.ts +0 -11
- package/dist-cjs/executors/search.js +0 -103
- package/dist-cjs/executors/search.js.map +0 -1
- package/dist-cjs/executors/self-diagnose.d.ts +0 -89
- package/dist-cjs/executors/self-diagnose.js +0 -435
- package/dist-cjs/executors/self-diagnose.js.map +0 -1
- package/dist-cjs/executors/session-history.d.ts +0 -75
- package/dist-cjs/executors/session-history.js +0 -321
- package/dist-cjs/executors/session-history.js.map +0 -1
- package/dist-cjs/executors/shell-safety.d.ts +0 -27
- package/dist-cjs/executors/shell-safety.js +0 -479
- package/dist-cjs/executors/shell-safety.js.map +0 -1
- package/dist-cjs/executors/shell.d.ts +0 -168
- package/dist-cjs/executors/shell.js +0 -1002
- package/dist-cjs/executors/shell.js.map +0 -1
- package/dist-cjs/executors/utils.d.ts +0 -20
- package/dist-cjs/executors/utils.js +0 -74
- package/dist-cjs/executors/utils.js.map +0 -1
- package/dist-cjs/executors/web.d.ts +0 -89
- package/dist-cjs/executors/web.js +0 -548
- package/dist-cjs/executors/web.js.map +0 -1
- package/dist-cjs/extraction/content-extraction.d.ts +0 -48
- package/dist-cjs/extraction/content-extraction.js +0 -244
- package/dist-cjs/extraction/content-extraction.js.map +0 -1
- package/dist-cjs/extraction/index.d.ts +0 -4
- package/dist-cjs/extraction/index.js +0 -9
- package/dist-cjs/extraction/index.js.map +0 -1
- package/dist-cjs/headless-control-contract.d.ts +0 -3182
- package/dist-cjs/headless-control-contract.js +0 -973
- package/dist-cjs/headless-control-contract.js.map +0 -1
- package/dist-cjs/index.d.ts +0 -62
- package/dist-cjs/index.js +0 -438
- package/dist-cjs/index.js.map +0 -1
- package/dist-cjs/local-control-http-auth.d.ts +0 -2
- package/dist-cjs/local-control-http-auth.js +0 -6
- package/dist-cjs/local-control-http-auth.js.map +0 -1
- package/dist-cjs/mcp/client.d.ts +0 -68
- package/dist-cjs/mcp/client.js +0 -186
- package/dist-cjs/mcp/client.js.map +0 -1
- package/dist-cjs/mcp/connection.d.ts +0 -54
- package/dist-cjs/mcp/connection.js +0 -485
- package/dist-cjs/mcp/connection.js.map +0 -1
- package/dist-cjs/mcp/index.d.ts +0 -10
- package/dist-cjs/mcp/index.js +0 -31
- package/dist-cjs/mcp/index.js.map +0 -1
- package/dist-cjs/mcp/jsonrpc.d.ts +0 -36
- package/dist-cjs/mcp/jsonrpc.js +0 -149
- package/dist-cjs/mcp/jsonrpc.js.map +0 -1
- package/dist-cjs/mcp/types.d.ts +0 -178
- package/dist-cjs/mcp/types.js +0 -9
- package/dist-cjs/mcp/types.js.map +0 -1
- package/dist-cjs/network-control-adapter.d.ts +0 -4
- package/dist-cjs/network-control-adapter.js +0 -78
- package/dist-cjs/network-control-adapter.js.map +0 -1
- package/dist-cjs/network-runtime/address-types.d.ts +0 -201
- package/dist-cjs/network-runtime/address-types.js +0 -169
- package/dist-cjs/network-runtime/address-types.js.map +0 -1
- package/dist-cjs/network-runtime/db-owner-fencing.d.ts +0 -43
- package/dist-cjs/network-runtime/db-owner-fencing.js +0 -77
- package/dist-cjs/network-runtime/db-owner-fencing.js.map +0 -1
- package/dist-cjs/network-runtime/delivery-receipts.d.ts +0 -117
- package/dist-cjs/network-runtime/delivery-receipts.js +0 -277
- package/dist-cjs/network-runtime/delivery-receipts.js.map +0 -1
- package/dist-cjs/network-runtime/direct-endpoint-authority.d.ts +0 -8
- package/dist-cjs/network-runtime/direct-endpoint-authority.js +0 -30
- package/dist-cjs/network-runtime/direct-endpoint-authority.js.map +0 -1
- package/dist-cjs/network-runtime/index.d.ts +0 -24
- package/dist-cjs/network-runtime/index.js +0 -173
- package/dist-cjs/network-runtime/index.js.map +0 -1
- package/dist-cjs/network-runtime/local-control-contract.d.ts +0 -758
- package/dist-cjs/network-runtime/local-control-contract.js +0 -634
- package/dist-cjs/network-runtime/local-control-contract.js.map +0 -1
- package/dist-cjs/network-runtime/node-store-contract.d.ts +0 -49
- package/dist-cjs/network-runtime/node-store-contract.js +0 -39
- package/dist-cjs/network-runtime/node-store-contract.js.map +0 -1
- package/dist-cjs/network-runtime/pair-route-contract.d.ts +0 -100
- package/dist-cjs/network-runtime/pair-route-contract.js +0 -81
- package/dist-cjs/network-runtime/pair-route-contract.js.map +0 -1
- package/dist-cjs/network-runtime/peer-capabilities.d.ts +0 -10
- package/dist-cjs/network-runtime/peer-capabilities.js +0 -38
- package/dist-cjs/network-runtime/peer-capabilities.js.map +0 -1
- package/dist-cjs/network-runtime/peer-principal-ref.d.ts +0 -9
- package/dist-cjs/network-runtime/peer-principal-ref.js +0 -16
- package/dist-cjs/network-runtime/peer-principal-ref.js.map +0 -1
- package/dist-cjs/network-runtime/peer-state-machine.d.ts +0 -70
- package/dist-cjs/network-runtime/peer-state-machine.js +0 -130
- package/dist-cjs/network-runtime/peer-state-machine.js.map +0 -1
- package/dist-cjs/network-runtime/protocol-schemas.d.ts +0 -328
- package/dist-cjs/network-runtime/protocol-schemas.js +0 -213
- package/dist-cjs/network-runtime/protocol-schemas.js.map +0 -1
- package/dist-cjs/network-runtime/runtime-bootstrap-contract.d.ts +0 -81
- package/dist-cjs/network-runtime/runtime-bootstrap-contract.js +0 -64
- package/dist-cjs/network-runtime/runtime-bootstrap-contract.js.map +0 -1
- package/dist-cjs/outlook/desktop-session.d.ts +0 -68
- package/dist-cjs/outlook/desktop-session.js +0 -319
- package/dist-cjs/outlook/desktop-session.js.map +0 -1
- package/dist-cjs/package.json +0 -3
- package/dist-cjs/policy.d.ts +0 -43
- package/dist-cjs/policy.js +0 -156
- package/dist-cjs/policy.js.map +0 -1
- package/dist-cjs/providers/brave.d.ts +0 -10
- package/dist-cjs/providers/brave.js +0 -67
- package/dist-cjs/providers/brave.js.map +0 -1
- package/dist-cjs/providers/duckduckgo.d.ts +0 -18
- package/dist-cjs/providers/duckduckgo.js +0 -181
- package/dist-cjs/providers/duckduckgo.js.map +0 -1
- package/dist-cjs/providers/exa.d.ts +0 -10
- package/dist-cjs/providers/exa.js +0 -68
- package/dist-cjs/providers/exa.js.map +0 -1
- package/dist-cjs/providers/firecrawl.d.ts +0 -10
- package/dist-cjs/providers/firecrawl.js +0 -60
- package/dist-cjs/providers/firecrawl.js.map +0 -1
- package/dist-cjs/providers/index.d.ts +0 -8
- package/dist-cjs/providers/index.js +0 -18
- package/dist-cjs/providers/index.js.map +0 -1
- package/dist-cjs/providers/jina.d.ts +0 -10
- package/dist-cjs/providers/jina.js +0 -54
- package/dist-cjs/providers/jina.js.map +0 -1
- package/dist-cjs/providers/router.d.ts +0 -21
- package/dist-cjs/providers/router.js +0 -101
- package/dist-cjs/providers/router.js.map +0 -1
- package/dist-cjs/providers/search-provider.d.ts +0 -35
- package/dist-cjs/providers/search-provider.js +0 -37
- package/dist-cjs/providers/search-provider.js.map +0 -1
- package/dist-cjs/providers/tavily.d.ts +0 -10
- package/dist-cjs/providers/tavily.js +0 -59
- package/dist-cjs/providers/tavily.js.map +0 -1
- package/dist-cjs/quip/desktop-session.d.ts +0 -69
- package/dist-cjs/quip/desktop-session.js +0 -354
- package/dist-cjs/quip/desktop-session.js.map +0 -1
- package/dist-cjs/registry/index.d.ts +0 -1
- package/dist-cjs/registry/index.js +0 -7
- package/dist-cjs/registry/index.js.map +0 -1
- package/dist-cjs/registry/registry.d.ts +0 -156
- package/dist-cjs/registry/registry.js +0 -762
- package/dist-cjs/registry/registry.js.map +0 -1
- package/dist-cjs/runtime-socket-local-control-client.d.ts +0 -10
- package/dist-cjs/runtime-socket-local-control-client.js +0 -368
- package/dist-cjs/runtime-socket-local-control-client.js.map +0 -1
- package/dist-cjs/security/dns-normalization.d.ts +0 -6
- package/dist-cjs/security/dns-normalization.js +0 -23
- package/dist-cjs/security/dns-normalization.js.map +0 -1
- package/dist-cjs/security/dns-pinning.d.ts +0 -27
- package/dist-cjs/security/dns-pinning.js +0 -161
- package/dist-cjs/security/dns-pinning.js.map +0 -1
- package/dist-cjs/security/external-content.d.ts +0 -40
- package/dist-cjs/security/external-content.js +0 -96
- package/dist-cjs/security/external-content.js.map +0 -1
- package/dist-cjs/security/ssrf.d.ts +0 -40
- package/dist-cjs/security/ssrf.js +0 -222
- package/dist-cjs/security/ssrf.js.map +0 -1
- package/dist-cjs/slack/desktop-session.d.ts +0 -69
- package/dist-cjs/slack/desktop-session.js +0 -367
- package/dist-cjs/slack/desktop-session.js.map +0 -1
- package/dist-cjs/tool-factory.d.ts +0 -46
- package/dist-cjs/tool-factory.js +0 -51
- package/dist-cjs/tool-factory.js.map +0 -1
- package/dist-cjs/types.d.ts +0 -1192
- package/dist-cjs/types.js +0 -9
- package/dist-cjs/types.js.map +0 -1
- package/dist-cjs/utils/retry.d.ts +0 -11
- package/dist-cjs/utils/retry.js +0 -170
- package/dist-cjs/utils/retry.js.map +0 -1
- package/dist-cjs/utils/safe-parse-json.d.ts +0 -26
- package/dist-cjs/utils/safe-parse-json.js +0 -165
- package/dist-cjs/utils/safe-parse-json.js.map +0 -1
- package/dist-cjs/utils/url.d.ts +0 -10
- package/dist-cjs/utils/url.js +0 -24
- package/dist-cjs/utils/url.js.map +0 -1
- package/src/__tests__/web-fetch-download.test.ts +0 -433
- package/src/__tests__/web-tools.test.ts +0 -619
- package/src/ask-user-interaction.ts +0 -33
- package/src/cache/web-cache.ts +0 -110
- package/src/definitions/arion.ts +0 -118
- package/src/definitions/browser/browser.ts +0 -502
- package/src/definitions/browser/index.ts +0 -5
- package/src/definitions/browser/pw-downloads.ts +0 -142
- package/src/definitions/browser/pw-interactions.ts +0 -282
- package/src/definitions/browser/pw-responses.ts +0 -98
- package/src/definitions/browser/pw-session.ts +0 -405
- package/src/definitions/browser/pw-shared.ts +0 -85
- package/src/definitions/browser/pw-snapshot.ts +0 -383
- package/src/definitions/browser/pw-state.ts +0 -101
- package/src/definitions/browser/types.ts +0 -203
- package/src/definitions/code-intelligence.ts +0 -526
- package/src/definitions/core.ts +0 -118
- package/src/definitions/delegation.ts +0 -567
- package/src/definitions/deploy.ts +0 -73
- package/src/definitions/filesystem.ts +0 -217
- package/src/definitions/frg.ts +0 -67
- package/src/definitions/index.ts +0 -28
- package/src/definitions/memory.ts +0 -150
- package/src/definitions/messaging.ts +0 -734
- package/src/definitions/meta.ts +0 -392
- package/src/definitions/network.ts +0 -179
- package/src/definitions/outlook.ts +0 -318
- package/src/definitions/patch/apply-patch.ts +0 -235
- package/src/definitions/patch/fuzzy-match.ts +0 -217
- package/src/definitions/patch/index.ts +0 -1
- package/src/definitions/patch/patch-parser.ts +0 -297
- package/src/definitions/patch/sandbox-paths.ts +0 -129
- package/src/definitions/process/index.ts +0 -5
- package/src/definitions/process/process-registry.ts +0 -303
- package/src/definitions/process/process.ts +0 -456
- package/src/definitions/process/pty-keys.ts +0 -298
- package/src/definitions/process/session-slug.ts +0 -147
- package/src/definitions/quip.ts +0 -225
- package/src/definitions/search.ts +0 -67
- package/src/definitions/session-history.ts +0 -79
- package/src/definitions/shell.ts +0 -202
- package/src/definitions/slack.ts +0 -211
- package/src/definitions/web.ts +0 -119
- package/src/executors/apply-patch.ts +0 -1035
- package/src/executors/arion.ts +0 -199
- package/src/executors/code-intelligence.ts +0 -1179
- package/src/executors/deploy.ts +0 -1066
- package/src/executors/filesystem.ts +0 -1428
- package/src/executors/frg-freshness.ts +0 -743
- package/src/executors/frg.ts +0 -394
- package/src/executors/index.ts +0 -280
- package/src/executors/learning-meta.ts +0 -1367
- package/src/executors/lsp-client.ts +0 -355
- package/src/executors/memory.ts +0 -978
- package/src/executors/meta.ts +0 -293
- package/src/executors/process-registry.ts +0 -570
- package/src/executors/pty-session-store.ts +0 -43
- package/src/executors/pty.ts +0 -342
- package/src/executors/restart.ts +0 -133
- package/src/executors/search-freshness.ts +0 -249
- package/src/executors/search-types.ts +0 -98
- package/src/executors/search.ts +0 -89
- package/src/executors/self-diagnose.ts +0 -552
- package/src/executors/session-history.ts +0 -435
- package/src/executors/shell-safety.ts +0 -519
- package/src/executors/shell.ts +0 -1243
- package/src/executors/utils.ts +0 -40
- package/src/executors/web.ts +0 -786
- package/src/extraction/content-extraction.ts +0 -281
- package/src/extraction/index.ts +0 -5
- package/src/headless-control-contract.ts +0 -1149
- package/src/index.ts +0 -788
- package/src/local-control-http-auth.ts +0 -2
- package/src/mcp/client.ts +0 -218
- package/src/mcp/connection.ts +0 -568
- package/src/mcp/index.ts +0 -11
- package/src/mcp/jsonrpc.ts +0 -195
- package/src/mcp/types.ts +0 -199
- package/src/network-control-adapter.ts +0 -88
- package/src/network-runtime/address-types.ts +0 -218
- package/src/network-runtime/db-owner-fencing.ts +0 -91
- package/src/network-runtime/delivery-receipts.ts +0 -372
- package/src/network-runtime/direct-endpoint-authority.ts +0 -35
- package/src/network-runtime/index.ts +0 -316
- package/src/network-runtime/local-control-contract.ts +0 -784
- package/src/network-runtime/node-store-contract.ts +0 -46
- package/src/network-runtime/pair-route-contract.ts +0 -97
- package/src/network-runtime/peer-capabilities.ts +0 -48
- package/src/network-runtime/peer-principal-ref.ts +0 -20
- package/src/network-runtime/peer-state-machine.ts +0 -160
- package/src/network-runtime/protocol-schemas.ts +0 -265
- package/src/network-runtime/runtime-bootstrap-contract.ts +0 -83
- package/src/outlook/desktop-session.ts +0 -409
- package/src/policy.ts +0 -171
- package/src/providers/brave.ts +0 -80
- package/src/providers/duckduckgo.ts +0 -199
- package/src/providers/exa.ts +0 -85
- package/src/providers/firecrawl.ts +0 -77
- package/src/providers/index.ts +0 -8
- package/src/providers/jina.ts +0 -70
- package/src/providers/router.ts +0 -121
- package/src/providers/search-provider.ts +0 -74
- package/src/providers/tavily.ts +0 -74
- package/src/quip/desktop-session.ts +0 -435
- package/src/registry/index.ts +0 -1
- package/src/registry/registry.ts +0 -905
- package/src/runtime-socket-local-control-client.ts +0 -632
- package/src/security/dns-normalization.ts +0 -34
- package/src/security/dns-pinning.ts +0 -138
- package/src/security/external-content.ts +0 -129
- package/src/security/ssrf.ts +0 -207
- package/src/slack/desktop-session.ts +0 -493
- package/src/tool-factory.ts +0 -91
- package/src/types.ts +0 -1341
- package/src/utils/retry.ts +0 -163
- package/src/utils/safe-parse-json.ts +0 -176
- package/src/utils/url.ts +0 -20
- package/tests/benchmarks/registry.bench.ts +0 -57
- package/tests/cache/web-cache.test.ts +0 -147
- package/tests/critical-integration.test.ts +0 -1465
- package/tests/definitions/apply-patch.test.ts +0 -586
- package/tests/definitions/browser.test.ts +0 -495
- package/tests/definitions/delegation-pause-resume.test.ts +0 -758
- package/tests/definitions/execution.test.ts +0 -671
- package/tests/definitions/messaging-inbox-scope.test.ts +0 -229
- package/tests/definitions/messaging.test.ts +0 -1468
- package/tests/definitions/outlook.test.ts +0 -30
- package/tests/definitions/process.test.ts +0 -469
- package/tests/definitions/slack.test.ts +0 -28
- package/tests/definitions/tool-inventory.test.ts +0 -218
- package/tests/e2e/delegation-quest-orchestration.e2e.test.ts +0 -433
- package/tests/e2e/memory-tool-discovery-contract.e2e.test.ts +0 -81
- package/tests/executors/apply-patch.test.ts +0 -538
- package/tests/executors/arion.test.ts +0 -309
- package/tests/executors/conversation-primitives.test.ts +0 -250
- package/tests/executors/deploy.test.ts +0 -746
- package/tests/executors/filesystem-tools.test.ts +0 -357
- package/tests/executors/filesystem.test.ts +0 -959
- package/tests/executors/frg-freshness.test.ts +0 -136
- package/tests/executors/frg-merge.test.ts +0 -70
- package/tests/executors/frg-session-content.test.ts +0 -40
- package/tests/executors/frg.test.ts +0 -56
- package/tests/executors/memory-bugfixes.test.ts +0 -257
- package/tests/executors/memory-real-memoria.integration.test.ts +0 -316
- package/tests/executors/memory.test.ts +0 -853
- package/tests/executors/meta-tools.test.ts +0 -411
- package/tests/executors/meta.test.ts +0 -683
- package/tests/executors/path-containment.test.ts +0 -51
- package/tests/executors/process-registry.test.ts +0 -505
- package/tests/executors/pty.test.ts +0 -664
- package/tests/executors/quest-security.test.ts +0 -249
- package/tests/executors/read-file-media.test.ts +0 -230
- package/tests/executors/recall-knowledge-schema.test.ts +0 -209
- package/tests/executors/recall-tags.test.ts +0 -278
- package/tests/executors/remember-null-safety.contract.test.ts +0 -41
- package/tests/executors/restart.test.ts +0 -67
- package/tests/executors/search-unified.test.ts +0 -381
- package/tests/executors/session-history.test.ts +0 -340
- package/tests/executors/session-transcript.test.ts +0 -561
- package/tests/executors/shell-abort.test.ts +0 -416
- package/tests/executors/shell-env-blocklist.test.ts +0 -648
- package/tests/executors/shell-env-process.test.ts +0 -245
- package/tests/executors/shell-process-registry.test.ts +0 -334
- package/tests/executors/shell-tools.test.ts +0 -393
- package/tests/executors/shell.test.ts +0 -690
- package/tests/executors/web-abort-vs-timeout.test.ts +0 -213
- package/tests/executors/web-integration.test.ts +0 -633
- package/tests/executors/web-symlink.test.ts +0 -18
- package/tests/executors/web.test.ts +0 -1400
- package/tests/executors/write-stdin.test.ts +0 -145
- package/tests/extraction/content-extraction.test.ts +0 -153
- package/tests/guards/tools-default-test-lane.integration.test.ts +0 -21
- package/tests/guards/tools-package-test-commands.e2e.test.ts +0 -43
- package/tests/guards/tools-test-lane-manifest.contract.test.ts +0 -76
- package/tests/guards/tools-vitest-workspace-alias.contract.test.ts +0 -63
- package/tests/helpers/async-waits.ts +0 -53
- package/tests/integration/headless-control-contract.integration.test.ts +0 -153
- package/tests/integration/memory-tool-schema-parity.integration.test.ts +0 -67
- package/tests/integration/meta-tools-round-trip.integration.test.ts +0 -506
- package/tests/integration/quest-round-trip.test.ts +0 -303
- package/tests/integration/registry-executor-flow.test.ts +0 -85
- package/tests/integration.test.ts +0 -177
- package/tests/loading-tier.test.ts +0 -126
- package/tests/mcp/client-reconnect.test.ts +0 -267
- package/tests/mcp/connection.test.ts +0 -846
- package/tests/mcp/injectable-logger.test.ts +0 -83
- package/tests/mcp/jsonrpc.test.ts +0 -109
- package/tests/mcp/lifecycle.test.ts +0 -879
- package/tests/network-runtime/address-types.contract.test.ts +0 -143
- package/tests/network-runtime/continuity-bind-schema.contract.test.ts +0 -203
- package/tests/network-runtime/local-control-contract.test.ts +0 -869
- package/tests/network-runtime/local-control-invite-token.contract.test.ts +0 -146
- package/tests/network-runtime/node-store-contract.test.ts +0 -11
- package/tests/network-runtime/pair-protocol-nodeid.contract.test.ts +0 -15
- package/tests/network-runtime/peer-state-machine.contract.test.ts +0 -148
- package/tests/network-runtime/protocol-schemas.contract.test.ts +0 -512
- package/tests/network-runtime/relay-pending-nodeid.contract.test.ts +0 -62
- package/tests/network-runtime/runtime-bootstrap-contract.test.ts +0 -227
- package/tests/network-runtime/runtime-socket-local-control-client.test.ts +0 -621
- package/tests/network-runtime/wait-for-message-script.test.ts +0 -288
- package/tests/parallel.test.ts +0 -71
- package/tests/policy.test.ts +0 -184
- package/tests/print-default-test-lane.ts +0 -14
- package/tests/print-test-lane-manifest.ts +0 -22
- package/tests/providers/brave.test.ts +0 -159
- package/tests/providers/duckduckgo.test.ts +0 -207
- package/tests/providers/exa.test.ts +0 -175
- package/tests/providers/firecrawl.test.ts +0 -168
- package/tests/providers/jina.test.ts +0 -144
- package/tests/providers/router.test.ts +0 -328
- package/tests/providers/tavily.test.ts +0 -165
- package/tests/registry/discovery.test.ts +0 -154
- package/tests/registry/injectable-logger.test.ts +0 -230
- package/tests/registry/input-validation.test.ts +0 -361
- package/tests/registry/interface-completeness.test.ts +0 -85
- package/tests/registry/mcp-integration.test.ts +0 -103
- package/tests/registry/mcp-read-only-hint.test.ts +0 -60
- package/tests/registry/memoria-discovery.test.ts +0 -390
- package/tests/registry/nested-validation.test.ts +0 -283
- package/tests/registry/pseudo-tool-filtering.test.ts +0 -258
- package/tests/registry/registration-lifecycle.test.ts +0 -133
- package/tests/registry-validation.test.ts +0 -424
- package/tests/registry.test.ts +0 -460
- package/tests/security/dns-pinning.test.ts +0 -162
- package/tests/security/external-content.test.ts +0 -144
- package/tests/security/ssrf.test.ts +0 -118
- package/tests/shell-safety-integration.test.ts +0 -32
- package/tests/shell-safety.test.ts +0 -365
- package/tests/slack/desktop-session.test.ts +0 -50
- package/tests/test-lane-manifest.ts +0 -440
- package/tests/test-utils.ts +0 -27
- package/tests/tool-factory.test.ts +0 -188
- package/tests/utils/retry.test.ts +0 -231
- package/tests/utils/url.test.ts +0 -63
- package/tsconfig.cjs.json +0 -24
- package/tsconfig.json +0 -12
- package/vitest.config.ts +0 -55
- package/vitest.e2e.config.ts +0 -24
- package/vitest.integration.config.ts +0 -24
- package/vitest.native.config.ts +0 -24
|
@@ -1,1465 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @aria/tools - Critical Integration Tests
|
|
3
|
-
*
|
|
4
|
-
* Tests the integration paths between:
|
|
5
|
-
* - Tool registry and executor wiring (every tool has an executor)
|
|
6
|
-
* - ToolContext injection (memoria, arion, manager, router)
|
|
7
|
-
* - Memory executor full flow with Memoria API
|
|
8
|
-
* - Arion executor full flow with ArionManager API
|
|
9
|
-
* - Risk level classifications and sandbox expectations
|
|
10
|
-
* - Error propagation from executor to runner
|
|
11
|
-
*
|
|
12
|
-
* METHODOLOGY: All tests are written to FAIL first (test-first).
|
|
13
|
-
* They describe what CORRECT behavior SHOULD be.
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
|
-
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
17
|
-
import {
|
|
18
|
-
createToolRegistry,
|
|
19
|
-
CORE_TOOL_DEFINITIONS,
|
|
20
|
-
getCoreTool,
|
|
21
|
-
getCoreToolsByCategory,
|
|
22
|
-
getCoreToolsByRiskLevel,
|
|
23
|
-
} from "../src/index.js";
|
|
24
|
-
import { ToolRegistry } from "../src/registry/registry.js";
|
|
25
|
-
import type {
|
|
26
|
-
ToolContext,
|
|
27
|
-
ToolResult,
|
|
28
|
-
Tool,
|
|
29
|
-
RiskLevel,
|
|
30
|
-
ToolCategory,
|
|
31
|
-
ArionRef,
|
|
32
|
-
ArionManagerRef,
|
|
33
|
-
} from "../src/types.js";
|
|
34
|
-
import {
|
|
35
|
-
executeRemember,
|
|
36
|
-
executeRecall,
|
|
37
|
-
executeForget,
|
|
38
|
-
executeDiscover,
|
|
39
|
-
executeReflect,
|
|
40
|
-
} from "../src/executors/memory.js";
|
|
41
|
-
import { executeHatchArion } from "../src/executors/arion.js";
|
|
42
|
-
|
|
43
|
-
// ===========================================================================
|
|
44
|
-
// Shared Helpers
|
|
45
|
-
// ===========================================================================
|
|
46
|
-
|
|
47
|
-
/** Create a mock Memoria with all methods */
|
|
48
|
-
function createMockMemoria() {
|
|
49
|
-
return {
|
|
50
|
-
remember: vi.fn().mockResolvedValue({ id: "mem-test-001" }),
|
|
51
|
-
recall: vi.fn().mockResolvedValue({ memories: [] }),
|
|
52
|
-
recallTools: vi.fn().mockResolvedValue([]),
|
|
53
|
-
rememberTool: vi.fn().mockResolvedValue("knowledge-001"),
|
|
54
|
-
rememberSkill: vi.fn().mockResolvedValue("skill-id"),
|
|
55
|
-
recallSkills: vi.fn().mockResolvedValue([]),
|
|
56
|
-
getSkill: vi.fn().mockResolvedValue(null),
|
|
57
|
-
recordSkillExecution: vi
|
|
58
|
-
.fn()
|
|
59
|
-
.mockResolvedValue({ id: "exec-1", skillId: "s1", success: true, timestamp: new Date() }),
|
|
60
|
-
deleteMemory: vi.fn().mockResolvedValue(true),
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/** Create a mock ArionManager */
|
|
65
|
-
function createMockManager(): ArionManagerRef {
|
|
66
|
-
return {
|
|
67
|
-
hatch: vi.fn().mockResolvedValue({
|
|
68
|
-
id: "arion-new-001",
|
|
69
|
-
name: "TestArion",
|
|
70
|
-
emoji: "🦅",
|
|
71
|
-
}),
|
|
72
|
-
getMemoria: vi.fn().mockResolvedValue(createMockMemoria()),
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/** Create a base ToolContext with optional overrides */
|
|
77
|
-
function createContext(overrides: Partial<ToolContext> = {}): ToolContext {
|
|
78
|
-
return {
|
|
79
|
-
workingDir: "/tmp/test-tools",
|
|
80
|
-
env: {},
|
|
81
|
-
confirm: vi.fn().mockResolvedValue(true),
|
|
82
|
-
...overrides,
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
// ===========================================================================
|
|
87
|
-
// Section 1: Registry-Executor Completeness
|
|
88
|
-
// ===========================================================================
|
|
89
|
-
|
|
90
|
-
describe("Registry-Executor Completeness", () => {
|
|
91
|
-
it("every CORE_TOOL_DEFINITION should have a callable execute function", () => {
|
|
92
|
-
// Verifies no tool was left with a stub/undefined executor
|
|
93
|
-
expect(CORE_TOOL_DEFINITIONS.length).toBeGreaterThan(0);
|
|
94
|
-
for (const tool of CORE_TOOL_DEFINITIONS) {
|
|
95
|
-
expect(typeof tool.execute).toBe("function");
|
|
96
|
-
}
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
it("createToolRegistry() should register all core tools by default", () => {
|
|
100
|
-
const registry = createToolRegistry();
|
|
101
|
-
const all = registry.getAll();
|
|
102
|
-
expect(all.length).toBe(CORE_TOOL_DEFINITIONS.length);
|
|
103
|
-
|
|
104
|
-
// Verify every core tool name is registered
|
|
105
|
-
const registeredNames = new Set(all.map((t) => t.name));
|
|
106
|
-
for (const tool of CORE_TOOL_DEFINITIONS) {
|
|
107
|
-
expect(registeredNames.has(tool.name)).toBe(true);
|
|
108
|
-
}
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
it("createToolRegistry({ includeBuiltins: false }) should be empty", () => {
|
|
112
|
-
const registry = createToolRegistry({ includeBuiltins: false });
|
|
113
|
-
expect(registry.getAll().length).toBe(0);
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
it("every tool retrieved from registry should be the same instance as in CORE_TOOL_DEFINITIONS", () => {
|
|
117
|
-
const registry = createToolRegistry();
|
|
118
|
-
for (const coreTool of CORE_TOOL_DEFINITIONS) {
|
|
119
|
-
const registeredTool = registry.get(coreTool.name);
|
|
120
|
-
expect(registeredTool).toBeDefined();
|
|
121
|
-
// Same execute function reference = same tool, not a copy
|
|
122
|
-
expect(registeredTool!.execute).toBe(coreTool.execute);
|
|
123
|
-
}
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
it("registry.list() by category should return correct tools for each category", () => {
|
|
127
|
-
const registry = createToolRegistry();
|
|
128
|
-
const categories: ToolCategory[] = [
|
|
129
|
-
"memory",
|
|
130
|
-
"web",
|
|
131
|
-
"filesystem",
|
|
132
|
-
"shell",
|
|
133
|
-
"messaging",
|
|
134
|
-
"meta",
|
|
135
|
-
"arion",
|
|
136
|
-
];
|
|
137
|
-
|
|
138
|
-
for (const category of categories) {
|
|
139
|
-
const tools = registry.list(category);
|
|
140
|
-
expect(tools.length).toBe(getCoreToolsByCategory(category).length);
|
|
141
|
-
}
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
it("registry.has() should return true for all core tool names", () => {
|
|
145
|
-
const registry = createToolRegistry();
|
|
146
|
-
const expectedNames = [
|
|
147
|
-
"remember",
|
|
148
|
-
"recall",
|
|
149
|
-
"forget",
|
|
150
|
-
"recall_knowledge",
|
|
151
|
-
"reflect",
|
|
152
|
-
"web_search",
|
|
153
|
-
"web_fetch",
|
|
154
|
-
"browse",
|
|
155
|
-
"read_file",
|
|
156
|
-
"write_file",
|
|
157
|
-
"edit_file",
|
|
158
|
-
"glob",
|
|
159
|
-
"grep",
|
|
160
|
-
"ls",
|
|
161
|
-
"apply_patch",
|
|
162
|
-
"bash",
|
|
163
|
-
"exec",
|
|
164
|
-
"spawn",
|
|
165
|
-
"kill",
|
|
166
|
-
"write_stdin",
|
|
167
|
-
"hatch_arion",
|
|
168
|
-
"rest_arion",
|
|
169
|
-
"wake_arion",
|
|
170
|
-
"retire_arion",
|
|
171
|
-
"delegate_arion",
|
|
172
|
-
"spawn_worker",
|
|
173
|
-
"check_delegation",
|
|
174
|
-
"delegate_remote",
|
|
175
|
-
"ask_user",
|
|
176
|
-
"quest_update",
|
|
177
|
-
"quest_list",
|
|
178
|
-
];
|
|
179
|
-
|
|
180
|
-
for (const name of expectedNames) {
|
|
181
|
-
expect(registry.has(name)).toBe(true);
|
|
182
|
-
}
|
|
183
|
-
});
|
|
184
|
-
});
|
|
185
|
-
|
|
186
|
-
// ===========================================================================
|
|
187
|
-
// Section 2: ToolContext.memoria wiring for memory tools
|
|
188
|
-
// ===========================================================================
|
|
189
|
-
|
|
190
|
-
describe("ToolContext.memoria wiring for memory tools", () => {
|
|
191
|
-
const memoryToolNames = ["remember", "recall", "forget", "recall_knowledge", "reflect"];
|
|
192
|
-
|
|
193
|
-
it("all memory tools should fail gracefully when ctx.memoria is undefined", async () => {
|
|
194
|
-
const ctx = createContext(); // no memoria
|
|
195
|
-
|
|
196
|
-
for (const toolName of memoryToolNames) {
|
|
197
|
-
const tool = getCoreTool(toolName)!;
|
|
198
|
-
// Provide minimal valid input for each tool
|
|
199
|
-
const inputs: Record<string, unknown> = {
|
|
200
|
-
remember: { content: "test content" },
|
|
201
|
-
recall: { query: "test query" },
|
|
202
|
-
forget: { id: "mem-123" },
|
|
203
|
-
recall_knowledge: { topic: "test topic" },
|
|
204
|
-
reflect: { summary: "test summary" },
|
|
205
|
-
};
|
|
206
|
-
|
|
207
|
-
const result = await tool.execute(inputs[toolName], ctx);
|
|
208
|
-
expect(result.success).toBe(false);
|
|
209
|
-
expect(result.message).toMatch(/memoria|Memoria/i);
|
|
210
|
-
}
|
|
211
|
-
});
|
|
212
|
-
|
|
213
|
-
it("all memory tools should fail gracefully when ctx.memoria is null", async () => {
|
|
214
|
-
const ctx = createContext({ memoria: null as any });
|
|
215
|
-
|
|
216
|
-
for (const toolName of memoryToolNames) {
|
|
217
|
-
const tool = getCoreTool(toolName)!;
|
|
218
|
-
const inputs: Record<string, unknown> = {
|
|
219
|
-
remember: { content: "test content" },
|
|
220
|
-
recall: { query: "test query" },
|
|
221
|
-
forget: { id: "mem-123" },
|
|
222
|
-
recall_knowledge: { topic: "test topic" },
|
|
223
|
-
reflect: { summary: "test summary" },
|
|
224
|
-
};
|
|
225
|
-
|
|
226
|
-
const result = await tool.execute(inputs[toolName], ctx);
|
|
227
|
-
expect(result.success).toBe(false);
|
|
228
|
-
expect(result.message).toMatch(/memoria|Memoria/i);
|
|
229
|
-
}
|
|
230
|
-
});
|
|
231
|
-
|
|
232
|
-
it("all memory tools should fail gracefully when ctx.memoria is a partial object missing methods", async () => {
|
|
233
|
-
// Simulates a broken/incomplete Memoria injection
|
|
234
|
-
const partialMemoria = { remember: vi.fn() }; // missing recall, recallTools, deleteMemory
|
|
235
|
-
const ctx = createContext({ memoria: partialMemoria as any });
|
|
236
|
-
|
|
237
|
-
// remember might work since it has remember(), but recall/forget/recallTools should fail
|
|
238
|
-
const recallResult = await executeRecall({ query: "test" }, ctx);
|
|
239
|
-
expect(recallResult.success).toBe(false);
|
|
240
|
-
|
|
241
|
-
const forgetResult = await executeForget({ id: "mem-1" }, ctx);
|
|
242
|
-
expect(forgetResult.success).toBe(false);
|
|
243
|
-
|
|
244
|
-
const recallToolsResult = await executeDiscover({ topic: "test" }, ctx);
|
|
245
|
-
expect(recallToolsResult.success).toBe(false);
|
|
246
|
-
});
|
|
247
|
-
|
|
248
|
-
describe("executeRemember integration", () => {
|
|
249
|
-
it("should call memoria.remember with content and return the stored id", async () => {
|
|
250
|
-
const mockMemoria = createMockMemoria();
|
|
251
|
-
mockMemoria.remember.mockResolvedValue({ id: "mem-integrated-001" });
|
|
252
|
-
const ctx = createContext({ memoria: mockMemoria as any });
|
|
253
|
-
|
|
254
|
-
const result = await executeRemember(
|
|
255
|
-
{
|
|
256
|
-
content: "integration test content",
|
|
257
|
-
importance: 0.8,
|
|
258
|
-
},
|
|
259
|
-
ctx,
|
|
260
|
-
);
|
|
261
|
-
|
|
262
|
-
expect(result.success).toBe(true);
|
|
263
|
-
expect((result.data as any).id).toBe("mem-integrated-001");
|
|
264
|
-
expect(mockMemoria.remember).toHaveBeenCalledTimes(1);
|
|
265
|
-
// First arg should be the content string
|
|
266
|
-
expect(mockMemoria.remember.mock.calls[0][0]).toBe("integration test content");
|
|
267
|
-
// Second arg should contain importance (tags have been removed)
|
|
268
|
-
const options = mockMemoria.remember.mock.calls[0][1];
|
|
269
|
-
expect(options.importance).toBe(0.8);
|
|
270
|
-
});
|
|
271
|
-
|
|
272
|
-
it("should propagate memoria errors as failed ToolResult, not throw", async () => {
|
|
273
|
-
const mockMemoria = createMockMemoria();
|
|
274
|
-
mockMemoria.remember.mockRejectedValue(new Error("SQLite constraint violation"));
|
|
275
|
-
const ctx = createContext({ memoria: mockMemoria as any });
|
|
276
|
-
|
|
277
|
-
const result = await executeRemember({ content: "will fail" }, ctx);
|
|
278
|
-
|
|
279
|
-
expect(result.success).toBe(false);
|
|
280
|
-
expect(result.message).toContain("SQLite constraint violation");
|
|
281
|
-
// Should NOT throw - error is caught and returned as ToolResult
|
|
282
|
-
});
|
|
283
|
-
});
|
|
284
|
-
|
|
285
|
-
describe("executeRecall integration", () => {
|
|
286
|
-
it("should call memoria.recall with query and limit, return memories", async () => {
|
|
287
|
-
const mockMemoria = createMockMemoria();
|
|
288
|
-
const fakeMemories = [
|
|
289
|
-
{ id: "m1", content: "fact 1" },
|
|
290
|
-
{ id: "m2", content: "fact 2" },
|
|
291
|
-
];
|
|
292
|
-
mockMemoria.recall.mockResolvedValue({ memories: fakeMemories });
|
|
293
|
-
const ctx = createContext({ memoria: mockMemoria as any });
|
|
294
|
-
|
|
295
|
-
const result = await executeRecall({ query: "facts", limit: 5 }, ctx);
|
|
296
|
-
|
|
297
|
-
expect(result.success).toBe(true);
|
|
298
|
-
expect((result.data as any).memories).toEqual(fakeMemories);
|
|
299
|
-
expect((result.data as any).count).toBe(2);
|
|
300
|
-
expect(mockMemoria.recall).toHaveBeenCalledWith(
|
|
301
|
-
"facts",
|
|
302
|
-
expect.objectContaining({ limit: 5 }),
|
|
303
|
-
);
|
|
304
|
-
});
|
|
305
|
-
|
|
306
|
-
it("should default limit to 10 when not provided", async () => {
|
|
307
|
-
const mockMemoria = createMockMemoria();
|
|
308
|
-
const ctx = createContext({ memoria: mockMemoria as any });
|
|
309
|
-
|
|
310
|
-
await executeRecall({ query: "test" }, ctx);
|
|
311
|
-
|
|
312
|
-
expect(mockMemoria.recall).toHaveBeenCalledWith(
|
|
313
|
-
"test",
|
|
314
|
-
expect.objectContaining({ limit: 10 }),
|
|
315
|
-
);
|
|
316
|
-
});
|
|
317
|
-
});
|
|
318
|
-
|
|
319
|
-
describe("executeForget integration", () => {
|
|
320
|
-
it("should call memoria.deleteMemory and return deleted status", async () => {
|
|
321
|
-
const mockMemoria = createMockMemoria();
|
|
322
|
-
mockMemoria.deleteMemory.mockResolvedValue(true);
|
|
323
|
-
const ctx = createContext({ memoria: mockMemoria as any });
|
|
324
|
-
|
|
325
|
-
const result = await executeForget({ id: "mem-to-delete" }, ctx);
|
|
326
|
-
|
|
327
|
-
expect(result.success).toBe(true);
|
|
328
|
-
expect((result.data as any).deleted).toBe(true);
|
|
329
|
-
expect((result.data as any).id).toBe("mem-to-delete");
|
|
330
|
-
expect(mockMemoria.deleteMemory).toHaveBeenCalledWith("mem-to-delete");
|
|
331
|
-
});
|
|
332
|
-
|
|
333
|
-
it("should return failure when memory does not exist", async () => {
|
|
334
|
-
const mockMemoria = createMockMemoria();
|
|
335
|
-
mockMemoria.deleteMemory.mockResolvedValue(false);
|
|
336
|
-
const ctx = createContext({ memoria: mockMemoria as any });
|
|
337
|
-
|
|
338
|
-
const result = await executeForget({ id: "nonexistent" }, ctx);
|
|
339
|
-
|
|
340
|
-
expect(result.success).toBe(false);
|
|
341
|
-
expect(result.message).toContain("not found");
|
|
342
|
-
});
|
|
343
|
-
});
|
|
344
|
-
|
|
345
|
-
describe("executeDiscover integration", () => {
|
|
346
|
-
it("should call memoria.recallTools and generate insights", async () => {
|
|
347
|
-
const mockMemoria = createMockMemoria();
|
|
348
|
-
const fakeKnowledge = [
|
|
349
|
-
{
|
|
350
|
-
id: "k1",
|
|
351
|
-
name: "file_reader",
|
|
352
|
-
description: "Reads files",
|
|
353
|
-
},
|
|
354
|
-
{
|
|
355
|
-
id: "k2",
|
|
356
|
-
name: "debugging",
|
|
357
|
-
description: "Debug skills",
|
|
358
|
-
},
|
|
359
|
-
];
|
|
360
|
-
mockMemoria.recallTools.mockResolvedValue(fakeKnowledge);
|
|
361
|
-
mockMemoria.recallSkills.mockResolvedValue([]);
|
|
362
|
-
const ctx = createContext({ memoria: mockMemoria as any });
|
|
363
|
-
|
|
364
|
-
const result = await executeDiscover({ topic: "file operations" }, ctx);
|
|
365
|
-
|
|
366
|
-
expect(result.success).toBe(true);
|
|
367
|
-
const data = result.data as any;
|
|
368
|
-
expect(data.toolCount).toBe(2);
|
|
369
|
-
expect(data.tools).toEqual(fakeKnowledge);
|
|
370
|
-
expect(data.insights).toBeDefined();
|
|
371
|
-
expect(Array.isArray(data.insights)).toBe(true);
|
|
372
|
-
expect(data.insights.length).toBeGreaterThan(0);
|
|
373
|
-
|
|
374
|
-
// Should call recallTools (both tools and skills fetched without kind)
|
|
375
|
-
expect(mockMemoria.recallTools).toHaveBeenCalledWith({
|
|
376
|
-
query: "file operations",
|
|
377
|
-
limit: 10,
|
|
378
|
-
});
|
|
379
|
-
});
|
|
380
|
-
});
|
|
381
|
-
|
|
382
|
-
describe("executeReflect integration", () => {
|
|
383
|
-
it("should call router.chat and store observation when learned", async () => {
|
|
384
|
-
const mockMemoria = createMockMemoria();
|
|
385
|
-
const mockRouter = {
|
|
386
|
-
chat: vi.fn().mockResolvedValue({
|
|
387
|
-
content:
|
|
388
|
-
'{"learnedAboutSelf": true, "observation": "I struggle with edge cases in regex", "skillCandidate": null}',
|
|
389
|
-
}),
|
|
390
|
-
};
|
|
391
|
-
const ctx = createContext({ memoria: mockMemoria as any, router: mockRouter as any });
|
|
392
|
-
|
|
393
|
-
const result = await executeReflect({ summary: "Fixed a regex bug" }, ctx);
|
|
394
|
-
|
|
395
|
-
expect(result.success).toBe(true);
|
|
396
|
-
const data = result.data as any;
|
|
397
|
-
expect(data.learned).toBe(true);
|
|
398
|
-
expect(data.observation).toContain("regex");
|
|
399
|
-
expect(mockMemoria.remember).toHaveBeenCalledWith(
|
|
400
|
-
expect.stringContaining("regex"),
|
|
401
|
-
expect.objectContaining({ network: "beliefs" }),
|
|
402
|
-
);
|
|
403
|
-
});
|
|
404
|
-
|
|
405
|
-
it("should fail gracefully when router is undefined", async () => {
|
|
406
|
-
const mockMemoria = createMockMemoria();
|
|
407
|
-
const ctx = createContext({ memoria: mockMemoria as any });
|
|
408
|
-
// no router
|
|
409
|
-
|
|
410
|
-
const result = await executeReflect({ summary: "test" }, ctx);
|
|
411
|
-
expect(result.success).toBe(false);
|
|
412
|
-
expect(result.message).toContain("Router");
|
|
413
|
-
});
|
|
414
|
-
});
|
|
415
|
-
});
|
|
416
|
-
|
|
417
|
-
// ===========================================================================
|
|
418
|
-
// Section 3: ToolContext.arion and ToolContext.manager wiring for arion tools
|
|
419
|
-
// ===========================================================================
|
|
420
|
-
|
|
421
|
-
describe("ToolContext.arion and ToolContext.manager wiring", () => {
|
|
422
|
-
const validInput = {
|
|
423
|
-
name: "TestArion",
|
|
424
|
-
traits: ["curious", "brave"],
|
|
425
|
-
style: "casual" as const,
|
|
426
|
-
emoji: "🦅",
|
|
427
|
-
};
|
|
428
|
-
|
|
429
|
-
it("hatch_arion should fail when ctx.manager is undefined", async () => {
|
|
430
|
-
const ctx = createContext({
|
|
431
|
-
arion: { id: "parent-1", name: "Parent", emoji: "🐣" },
|
|
432
|
-
// manager not set
|
|
433
|
-
});
|
|
434
|
-
|
|
435
|
-
const result = await executeHatchArion(validInput, ctx);
|
|
436
|
-
expect(result.success).toBe(false);
|
|
437
|
-
expect(result.message).toContain("ArionManager");
|
|
438
|
-
});
|
|
439
|
-
|
|
440
|
-
it("hatch_arion should fail when ctx.arion is undefined", async () => {
|
|
441
|
-
const ctx = createContext({
|
|
442
|
-
manager: createMockManager(),
|
|
443
|
-
// arion not set
|
|
444
|
-
});
|
|
445
|
-
|
|
446
|
-
const result = await executeHatchArion(validInput, ctx);
|
|
447
|
-
expect(result.success).toBe(false);
|
|
448
|
-
expect(result.message).toContain("arion context");
|
|
449
|
-
});
|
|
450
|
-
|
|
451
|
-
it("hatch_arion should call ctx.confirm before creating", async () => {
|
|
452
|
-
const confirmFn = vi.fn().mockResolvedValue(true);
|
|
453
|
-
const mockManager = createMockManager();
|
|
454
|
-
const ctx = createContext({
|
|
455
|
-
arion: { id: "parent-1", name: "Parent", emoji: "🐣" },
|
|
456
|
-
manager: mockManager,
|
|
457
|
-
confirm: confirmFn,
|
|
458
|
-
});
|
|
459
|
-
|
|
460
|
-
await executeHatchArion(validInput, ctx);
|
|
461
|
-
|
|
462
|
-
expect(confirmFn).toHaveBeenCalledTimes(1);
|
|
463
|
-
// Confirm message should include the arion name and traits
|
|
464
|
-
const confirmMsg = confirmFn.mock.calls[0][0] as string;
|
|
465
|
-
expect(confirmMsg).toContain("TestArion");
|
|
466
|
-
expect(confirmMsg).toContain("curious");
|
|
467
|
-
});
|
|
468
|
-
|
|
469
|
-
it("hatch_arion should return failure when user cancels confirmation", async () => {
|
|
470
|
-
const ctx = createContext({
|
|
471
|
-
arion: { id: "parent-1", name: "Parent", emoji: "🐣" },
|
|
472
|
-
manager: createMockManager(),
|
|
473
|
-
confirm: vi.fn().mockResolvedValue(false), // User cancels
|
|
474
|
-
});
|
|
475
|
-
|
|
476
|
-
const result = await executeHatchArion(validInput, ctx);
|
|
477
|
-
|
|
478
|
-
expect(result.success).toBe(false);
|
|
479
|
-
expect(result.message).toContain("cancelled");
|
|
480
|
-
});
|
|
481
|
-
|
|
482
|
-
it("hatch_arion should call manager.hatch with correct config", async () => {
|
|
483
|
-
const mockManager = createMockManager();
|
|
484
|
-
const ctx = createContext({
|
|
485
|
-
arion: { id: "parent-1", name: "Parent", emoji: "🐣" },
|
|
486
|
-
manager: mockManager,
|
|
487
|
-
});
|
|
488
|
-
|
|
489
|
-
const result = await executeHatchArion(validInput, ctx);
|
|
490
|
-
|
|
491
|
-
expect(result.success).toBe(true);
|
|
492
|
-
expect(mockManager.hatch).toHaveBeenCalledTimes(1);
|
|
493
|
-
const hatchConfig = (mockManager.hatch as ReturnType<typeof vi.fn>).mock.calls[0][0];
|
|
494
|
-
expect(hatchConfig.name).toBe("TestArion");
|
|
495
|
-
expect(hatchConfig.personality.traits).toEqual(["curious", "brave"]);
|
|
496
|
-
expect(hatchConfig.personality.style).toBe("casual");
|
|
497
|
-
expect(hatchConfig.createdBy).toBe("Parent");
|
|
498
|
-
});
|
|
499
|
-
|
|
500
|
-
it("hatch_arion should seed beliefs into new arion memory when provided", async () => {
|
|
501
|
-
const newArionMemoria = createMockMemoria();
|
|
502
|
-
const mockManager: any = {
|
|
503
|
-
hatch: vi.fn().mockResolvedValue({
|
|
504
|
-
id: "arion-new",
|
|
505
|
-
name: "NewArion",
|
|
506
|
-
emoji: "🦅",
|
|
507
|
-
}),
|
|
508
|
-
getMemoria: vi.fn().mockResolvedValue(newArionMemoria),
|
|
509
|
-
};
|
|
510
|
-
const ctx = createContext({
|
|
511
|
-
arion: { id: "parent-1", name: "Parent", emoji: "🐣" },
|
|
512
|
-
manager: mockManager,
|
|
513
|
-
});
|
|
514
|
-
|
|
515
|
-
const inputWithBeliefs = {
|
|
516
|
-
...validInput,
|
|
517
|
-
beliefs: ["I am curious", "I value truth"],
|
|
518
|
-
};
|
|
519
|
-
|
|
520
|
-
const result = await executeHatchArion(inputWithBeliefs, ctx);
|
|
521
|
-
|
|
522
|
-
expect(result.success).toBe(true);
|
|
523
|
-
// getMemoria should be called for the new arion
|
|
524
|
-
expect(mockManager.getMemoria).toHaveBeenCalledWith(
|
|
525
|
-
expect.objectContaining({ id: "arion-new" }),
|
|
526
|
-
);
|
|
527
|
-
// Each belief should be stored via remember
|
|
528
|
-
expect(newArionMemoria.remember).toHaveBeenCalledTimes(2);
|
|
529
|
-
expect(newArionMemoria.remember).toHaveBeenCalledWith("I am curious", {
|
|
530
|
-
network: "beliefs",
|
|
531
|
-
});
|
|
532
|
-
expect(newArionMemoria.remember).toHaveBeenCalledWith("I value truth", {
|
|
533
|
-
network: "beliefs",
|
|
534
|
-
});
|
|
535
|
-
});
|
|
536
|
-
|
|
537
|
-
it("hatch_arion should propagate manager.hatch errors as ToolResult", async () => {
|
|
538
|
-
const mockManager: any = {
|
|
539
|
-
hatch: vi.fn().mockRejectedValue(new Error("Arion limit reached")),
|
|
540
|
-
getMemoria: vi.fn(),
|
|
541
|
-
};
|
|
542
|
-
const ctx = createContext({
|
|
543
|
-
arion: { id: "parent-1", name: "Parent", emoji: "🐣" },
|
|
544
|
-
manager: mockManager,
|
|
545
|
-
});
|
|
546
|
-
|
|
547
|
-
const result = await executeHatchArion(validInput, ctx);
|
|
548
|
-
|
|
549
|
-
expect(result.success).toBe(false);
|
|
550
|
-
expect(result.message).toContain("Arion limit reached");
|
|
551
|
-
});
|
|
552
|
-
|
|
553
|
-
it("hatch_arion should return the new arion id, name, and emoji", async () => {
|
|
554
|
-
const mockManager = createMockManager();
|
|
555
|
-
const ctx = createContext({
|
|
556
|
-
arion: { id: "parent-1", name: "Parent", emoji: "🐣" },
|
|
557
|
-
manager: mockManager,
|
|
558
|
-
});
|
|
559
|
-
|
|
560
|
-
const result = await executeHatchArion(validInput, ctx);
|
|
561
|
-
|
|
562
|
-
expect(result.success).toBe(true);
|
|
563
|
-
expect(result.data).toEqual({
|
|
564
|
-
arionId: "arion-new-001",
|
|
565
|
-
name: "TestArion",
|
|
566
|
-
emoji: "🦅",
|
|
567
|
-
});
|
|
568
|
-
});
|
|
569
|
-
});
|
|
570
|
-
|
|
571
|
-
// ===========================================================================
|
|
572
|
-
// Section 4: ToolContext.manager wiring gap (CRITICAL BUG)
|
|
573
|
-
// ===========================================================================
|
|
574
|
-
|
|
575
|
-
describe("ToolContext.manager wiring from AgentRunner", () => {
|
|
576
|
-
/**
|
|
577
|
-
* CRITICAL: AgentRunner at runner.ts:1547-1556 builds ToolContext but
|
|
578
|
-
* does NOT include `manager` in the context object. This means
|
|
579
|
-
* hatch_arion will ALWAYS fail at runtime because ctx.manager is undefined.
|
|
580
|
-
*
|
|
581
|
-
* The runner builds:
|
|
582
|
-
* const ctx: ToolContext = {
|
|
583
|
-
* workingDir, env, memoria, arion, router, confirm, abortSignal, context
|
|
584
|
-
* }
|
|
585
|
-
*
|
|
586
|
-
* Missing: manager
|
|
587
|
-
*
|
|
588
|
-
* This test documents the expected behavior that should be implemented.
|
|
589
|
-
*/
|
|
590
|
-
it("AgentRunner should inject manager into ToolContext when options.manager is provided", () => {
|
|
591
|
-
// This is a documentation test - the actual fix needs to happen in runner.ts
|
|
592
|
-
// When the runner builds ToolContext, it should include:
|
|
593
|
-
// manager: options?.manager as any,
|
|
594
|
-
//
|
|
595
|
-
// This test asserts the expected shape of ToolContext
|
|
596
|
-
const ctx = createContext({
|
|
597
|
-
manager: createMockManager(),
|
|
598
|
-
});
|
|
599
|
-
|
|
600
|
-
expect(ctx.manager).toBeDefined();
|
|
601
|
-
expect(typeof ctx.manager!.hatch).toBe("function");
|
|
602
|
-
expect(typeof ctx.manager!.getMemoria).toBe("function");
|
|
603
|
-
});
|
|
604
|
-
|
|
605
|
-
it("hatch_arion tool from registry should work end-to-end when manager is in context", async () => {
|
|
606
|
-
const registry = createToolRegistry();
|
|
607
|
-
const tool = registry.get("hatch_arion");
|
|
608
|
-
expect(tool).toBeDefined();
|
|
609
|
-
expect(tool!.category).toBe("arion");
|
|
610
|
-
|
|
611
|
-
const mockManager = createMockManager();
|
|
612
|
-
const ctx = createContext({
|
|
613
|
-
arion: { id: "parent", name: "Parent", emoji: "🐣" },
|
|
614
|
-
manager: mockManager,
|
|
615
|
-
});
|
|
616
|
-
|
|
617
|
-
const result = await tool!.execute(
|
|
618
|
-
{
|
|
619
|
-
name: "RegistryTestArion",
|
|
620
|
-
traits: ["smart"],
|
|
621
|
-
style: "technical",
|
|
622
|
-
},
|
|
623
|
-
ctx,
|
|
624
|
-
);
|
|
625
|
-
|
|
626
|
-
expect(result.success).toBe(true);
|
|
627
|
-
expect(mockManager.hatch).toHaveBeenCalled();
|
|
628
|
-
});
|
|
629
|
-
});
|
|
630
|
-
|
|
631
|
-
// ===========================================================================
|
|
632
|
-
// Section 5: Tool safety / riskLevel classification correctness
|
|
633
|
-
// ===========================================================================
|
|
634
|
-
|
|
635
|
-
describe("Tool riskLevel classifications", () => {
|
|
636
|
-
it("selected read-only tools should be classified as 'safe'", () => {
|
|
637
|
-
const expectedSafe = [
|
|
638
|
-
"recall",
|
|
639
|
-
"recall_knowledge",
|
|
640
|
-
"web_fetch",
|
|
641
|
-
"browse",
|
|
642
|
-
"read_file",
|
|
643
|
-
"glob",
|
|
644
|
-
"grep",
|
|
645
|
-
"ls",
|
|
646
|
-
// "search" moved to @aria/aria
|
|
647
|
-
];
|
|
648
|
-
for (const name of expectedSafe) {
|
|
649
|
-
const tool = getCoreTool(name);
|
|
650
|
-
expect(tool).toBeDefined();
|
|
651
|
-
expect(tool!.riskLevel).toBe("safe");
|
|
652
|
-
expect(tool!.isReadOnly).toBe(true);
|
|
653
|
-
}
|
|
654
|
-
});
|
|
655
|
-
|
|
656
|
-
it("destructive tools should be classified as 'dangerous'", () => {
|
|
657
|
-
const expectedDangerous = [
|
|
658
|
-
"forget",
|
|
659
|
-
"write_file",
|
|
660
|
-
"edit_file",
|
|
661
|
-
"apply_patch",
|
|
662
|
-
"bash",
|
|
663
|
-
"exec",
|
|
664
|
-
"spawn",
|
|
665
|
-
"kill",
|
|
666
|
-
"hatch_arion",
|
|
667
|
-
"retire_arion",
|
|
668
|
-
];
|
|
669
|
-
for (const name of expectedDangerous) {
|
|
670
|
-
const tool = getCoreTool(name);
|
|
671
|
-
expect(tool).toBeDefined();
|
|
672
|
-
expect(tool!.riskLevel).toBe("dangerous");
|
|
673
|
-
}
|
|
674
|
-
});
|
|
675
|
-
|
|
676
|
-
it("moderate-risk tools should be classified as 'moderate'", () => {
|
|
677
|
-
const expectedModerate = [
|
|
678
|
-
"remember",
|
|
679
|
-
"reflect",
|
|
680
|
-
"web_search",
|
|
681
|
-
"delegate_arion",
|
|
682
|
-
"delegate_remote",
|
|
683
|
-
"rest_arion",
|
|
684
|
-
"wake_arion",
|
|
685
|
-
"ask_user",
|
|
686
|
-
"quest_update",
|
|
687
|
-
"spawn_worker",
|
|
688
|
-
"write_stdin",
|
|
689
|
-
];
|
|
690
|
-
for (const name of expectedModerate) {
|
|
691
|
-
const tool = getCoreTool(name);
|
|
692
|
-
expect(tool).toBeDefined();
|
|
693
|
-
expect(tool!.riskLevel).toBe("moderate");
|
|
694
|
-
}
|
|
695
|
-
});
|
|
696
|
-
|
|
697
|
-
it("tools with requiresConfirmation should have dangerous riskLevel", () => {
|
|
698
|
-
// Tools that explicitly set requiresConfirmation: true should be dangerous
|
|
699
|
-
const toolsRequiringConfirmation = CORE_TOOL_DEFINITIONS.filter(
|
|
700
|
-
(t) => t.requiresConfirmation === true,
|
|
701
|
-
);
|
|
702
|
-
expect(toolsRequiringConfirmation.length).toBeGreaterThan(0);
|
|
703
|
-
for (const tool of toolsRequiringConfirmation) {
|
|
704
|
-
expect(tool.riskLevel).toBe("dangerous");
|
|
705
|
-
}
|
|
706
|
-
});
|
|
707
|
-
|
|
708
|
-
it("dangerous tools without explicit requiresConfirmation should default to requiring it", () => {
|
|
709
|
-
// The ToolInfo conversion in registry should treat dangerous as requiresConfirmation=true
|
|
710
|
-
const registry = createToolRegistry();
|
|
711
|
-
const infos = registry.getToolInfos();
|
|
712
|
-
|
|
713
|
-
for (const info of infos) {
|
|
714
|
-
const tool = getCoreTool(info.name);
|
|
715
|
-
if (tool && tool.riskLevel === "dangerous") {
|
|
716
|
-
expect(info.requiresConfirmation).toBe(true);
|
|
717
|
-
}
|
|
718
|
-
}
|
|
719
|
-
});
|
|
720
|
-
|
|
721
|
-
it("all tools should have valid category values", () => {
|
|
722
|
-
const validCategories: ToolCategory[] = [
|
|
723
|
-
"filesystem",
|
|
724
|
-
"code",
|
|
725
|
-
"shell",
|
|
726
|
-
"web",
|
|
727
|
-
"data",
|
|
728
|
-
"memory",
|
|
729
|
-
"arion",
|
|
730
|
-
"messaging",
|
|
731
|
-
"meta",
|
|
732
|
-
];
|
|
733
|
-
for (const tool of CORE_TOOL_DEFINITIONS) {
|
|
734
|
-
expect(validCategories).toContain(tool.category);
|
|
735
|
-
}
|
|
736
|
-
});
|
|
737
|
-
|
|
738
|
-
it("all tools should have valid riskLevel values", () => {
|
|
739
|
-
const validRiskLevels: RiskLevel[] = ["safe", "moderate", "dangerous"];
|
|
740
|
-
for (const tool of CORE_TOOL_DEFINITIONS) {
|
|
741
|
-
expect(validRiskLevels).toContain(tool.riskLevel);
|
|
742
|
-
}
|
|
743
|
-
});
|
|
744
|
-
|
|
745
|
-
it("getCoreToolsByRiskLevel should return correct counts", () => {
|
|
746
|
-
const safeTools = getCoreToolsByRiskLevel("safe");
|
|
747
|
-
const moderateTools = getCoreToolsByRiskLevel("moderate");
|
|
748
|
-
const dangerousTools = getCoreToolsByRiskLevel("dangerous");
|
|
749
|
-
|
|
750
|
-
expect(safeTools.length + moderateTools.length + dangerousTools.length).toBe(
|
|
751
|
-
CORE_TOOL_DEFINITIONS.length,
|
|
752
|
-
);
|
|
753
|
-
|
|
754
|
-
// Verify known counts based on the tool definitions
|
|
755
|
-
expect(safeTools.length).toBeGreaterThanOrEqual(9); // read_file, recall, recall_knowledge, web_fetch, browse, glob, grep, ls, check_delegation, quest_list
|
|
756
|
-
expect(dangerousTools.length).toBeGreaterThanOrEqual(10); // forget, write_file, edit_file, apply_patch, bash, exec, spawn, kill, hatch_arion, retire_arion
|
|
757
|
-
expect(moderateTools.length).toBeGreaterThanOrEqual(9); // remember, reflect, web_search, delegate_arion, rest_arion, wake_arion, ask_user, quest_update, spawn_worker, write_stdin
|
|
758
|
-
});
|
|
759
|
-
});
|
|
760
|
-
|
|
761
|
-
// Section 6: Meta tools (search/learn) — moved to @aria/aria.
|
|
762
|
-
// Tests for these tools live in @aria/aria tests now.
|
|
763
|
-
|
|
764
|
-
// ===========================================================================
|
|
765
|
-
// Section 7: Error handling - executor throws should yield tool_result error
|
|
766
|
-
// ===========================================================================
|
|
767
|
-
|
|
768
|
-
describe("Error handling: executor throws yield proper ToolResult errors", () => {
|
|
769
|
-
it("remember executor should catch and return ToolResult on unexpected error", async () => {
|
|
770
|
-
const brokenMemoria = {
|
|
771
|
-
remember: vi.fn().mockImplementation(() => {
|
|
772
|
-
throw new TypeError("Cannot read properties of undefined");
|
|
773
|
-
}),
|
|
774
|
-
recall: vi.fn(),
|
|
775
|
-
recallTools: vi.fn(),
|
|
776
|
-
rememberSkill: vi.fn().mockResolvedValue("skill-id"),
|
|
777
|
-
recallSkills: vi.fn().mockResolvedValue([]),
|
|
778
|
-
getSkill: vi.fn().mockResolvedValue(null),
|
|
779
|
-
recordSkillExecution: vi
|
|
780
|
-
.fn()
|
|
781
|
-
.mockResolvedValue({ id: "exec-1", skillId: "s1", success: true, timestamp: new Date() }),
|
|
782
|
-
deleteMemory: vi.fn(),
|
|
783
|
-
};
|
|
784
|
-
const ctx = createContext({ memoria: brokenMemoria as any });
|
|
785
|
-
|
|
786
|
-
// Should NOT throw - should return a failed ToolResult
|
|
787
|
-
const result = await executeRemember({ content: "test" }, ctx);
|
|
788
|
-
expect(result.success).toBe(false);
|
|
789
|
-
expect(result.message).toBeDefined();
|
|
790
|
-
});
|
|
791
|
-
|
|
792
|
-
it("recall executor should catch and return ToolResult on unexpected error", async () => {
|
|
793
|
-
const brokenMemoria = {
|
|
794
|
-
remember: vi.fn(),
|
|
795
|
-
recall: vi.fn().mockImplementation(() => {
|
|
796
|
-
throw new Error("Connection refused");
|
|
797
|
-
}),
|
|
798
|
-
recallTools: vi.fn(),
|
|
799
|
-
rememberSkill: vi.fn().mockResolvedValue("skill-id"),
|
|
800
|
-
recallSkills: vi.fn().mockResolvedValue([]),
|
|
801
|
-
getSkill: vi.fn().mockResolvedValue(null),
|
|
802
|
-
recordSkillExecution: vi
|
|
803
|
-
.fn()
|
|
804
|
-
.mockResolvedValue({ id: "exec-1", skillId: "s1", success: true, timestamp: new Date() }),
|
|
805
|
-
deleteMemory: vi.fn(),
|
|
806
|
-
};
|
|
807
|
-
const ctx = createContext({ memoria: brokenMemoria as any });
|
|
808
|
-
|
|
809
|
-
const result = await executeRecall({ query: "test" }, ctx);
|
|
810
|
-
expect(result.success).toBe(false);
|
|
811
|
-
expect(result.message).toContain("Connection refused");
|
|
812
|
-
});
|
|
813
|
-
|
|
814
|
-
it("forget executor should catch and return ToolResult on unexpected error", async () => {
|
|
815
|
-
const brokenMemoria = {
|
|
816
|
-
remember: vi.fn(),
|
|
817
|
-
recall: vi.fn(),
|
|
818
|
-
recallTools: vi.fn(),
|
|
819
|
-
rememberSkill: vi.fn().mockResolvedValue("skill-id"),
|
|
820
|
-
recallSkills: vi.fn().mockResolvedValue([]),
|
|
821
|
-
getSkill: vi.fn().mockResolvedValue(null),
|
|
822
|
-
recordSkillExecution: vi
|
|
823
|
-
.fn()
|
|
824
|
-
.mockResolvedValue({ id: "exec-1", skillId: "s1", success: true, timestamp: new Date() }),
|
|
825
|
-
deleteMemory: vi.fn().mockRejectedValue(new Error("Disk full")),
|
|
826
|
-
};
|
|
827
|
-
const ctx = createContext({ memoria: brokenMemoria as any });
|
|
828
|
-
|
|
829
|
-
const result = await executeForget({ id: "mem-123" }, ctx);
|
|
830
|
-
expect(result.success).toBe(false);
|
|
831
|
-
expect(result.message).toContain("Disk full");
|
|
832
|
-
});
|
|
833
|
-
|
|
834
|
-
it("recallTools executor should degrade gracefully when one store errors", async () => {
|
|
835
|
-
const brokenMemoria = {
|
|
836
|
-
remember: vi.fn(),
|
|
837
|
-
recall: vi.fn(),
|
|
838
|
-
recallTools: vi.fn().mockRejectedValue(new Error("Embedding service down")),
|
|
839
|
-
rememberSkill: vi.fn().mockResolvedValue("skill-id"),
|
|
840
|
-
recallSkills: vi.fn().mockResolvedValue([]),
|
|
841
|
-
getSkill: vi.fn().mockResolvedValue(null),
|
|
842
|
-
recordSkillExecution: vi
|
|
843
|
-
.fn()
|
|
844
|
-
.mockResolvedValue({ id: "exec-1", skillId: "s1", success: true, timestamp: new Date() }),
|
|
845
|
-
deleteMemory: vi.fn(),
|
|
846
|
-
};
|
|
847
|
-
const ctx = createContext({ memoria: brokenMemoria as any });
|
|
848
|
-
|
|
849
|
-
const result = await executeDiscover({ topic: "test" }, ctx);
|
|
850
|
-
expect(result.success).toBe(true);
|
|
851
|
-
const data = result.data as { tools: unknown[]; skills: unknown[]; toolCount: number };
|
|
852
|
-
expect(data.tools).toEqual([]);
|
|
853
|
-
expect(data.toolCount).toBe(0);
|
|
854
|
-
expect(Array.isArray(data.skills)).toBe(true);
|
|
855
|
-
});
|
|
856
|
-
|
|
857
|
-
it("hatch_arion should not throw when manager.hatch throws", async () => {
|
|
858
|
-
const mockManager: any = {
|
|
859
|
-
hatch: vi.fn().mockRejectedValue(new Error("Internal error")),
|
|
860
|
-
getMemoria: vi.fn(),
|
|
861
|
-
};
|
|
862
|
-
const ctx = createContext({
|
|
863
|
-
arion: { id: "parent", name: "Parent", emoji: "🐣" },
|
|
864
|
-
manager: mockManager,
|
|
865
|
-
});
|
|
866
|
-
|
|
867
|
-
// Should NOT throw
|
|
868
|
-
const result = await executeHatchArion({ name: "Test", traits: ["a"], style: "casual" }, ctx);
|
|
869
|
-
expect(result.success).toBe(false);
|
|
870
|
-
expect(result.message).toContain("Internal error");
|
|
871
|
-
});
|
|
872
|
-
});
|
|
873
|
-
|
|
874
|
-
// ===========================================================================
|
|
875
|
-
// Section 8: Registry getToolInfos - ToolInfo correctness
|
|
876
|
-
// ===========================================================================
|
|
877
|
-
|
|
878
|
-
describe("Registry getToolInfos correctness", () => {
|
|
879
|
-
it("getToolInfos should return info for all core tools", () => {
|
|
880
|
-
const registry = createToolRegistry();
|
|
881
|
-
const infos = registry.getToolInfos();
|
|
882
|
-
expect(infos.length).toBe(CORE_TOOL_DEFINITIONS.length);
|
|
883
|
-
});
|
|
884
|
-
|
|
885
|
-
it("each ToolInfo should have name, description, and parameters", () => {
|
|
886
|
-
const registry = createToolRegistry();
|
|
887
|
-
const infos = registry.getToolInfos();
|
|
888
|
-
|
|
889
|
-
for (const info of infos) {
|
|
890
|
-
expect(info.name).toBeDefined();
|
|
891
|
-
expect(typeof info.name).toBe("string");
|
|
892
|
-
expect(info.name.length).toBeGreaterThan(0);
|
|
893
|
-
|
|
894
|
-
expect(info.description).toBeDefined();
|
|
895
|
-
expect(typeof info.description).toBe("string");
|
|
896
|
-
expect(info.description.length).toBeGreaterThan(0);
|
|
897
|
-
|
|
898
|
-
expect(info.parameters).toBeDefined();
|
|
899
|
-
expect(Array.isArray(info.parameters)).toBe(true);
|
|
900
|
-
}
|
|
901
|
-
});
|
|
902
|
-
|
|
903
|
-
it("ToolInfo.parameters should list required parameters as required=true", () => {
|
|
904
|
-
const registry = createToolRegistry();
|
|
905
|
-
const infos = registry.getToolInfos();
|
|
906
|
-
|
|
907
|
-
// remember has required: ["content"]
|
|
908
|
-
const rememberInfo = infos.find((i) => i.name === "remember")!;
|
|
909
|
-
const contentParam = rememberInfo.parameters.find((p) => p.name === "content");
|
|
910
|
-
expect(contentParam).toBeDefined();
|
|
911
|
-
expect(contentParam!.required).toBe(true);
|
|
912
|
-
|
|
913
|
-
// Tags have been removed from remember schema
|
|
914
|
-
const tagsParam = rememberInfo.parameters.find((p) => p.name === "tags");
|
|
915
|
-
expect(tagsParam).toBeUndefined();
|
|
916
|
-
});
|
|
917
|
-
});
|
|
918
|
-
|
|
919
|
-
// ===========================================================================
|
|
920
|
-
// Section 9: Memoria-discovered tools (dynamic tool loading)
|
|
921
|
-
// ===========================================================================
|
|
922
|
-
|
|
923
|
-
describe("Memoria-discovered tool execution", () => {
|
|
924
|
-
it("discovered tool with responseTemplate should interpolate input values", async () => {
|
|
925
|
-
const registry = new ToolRegistry();
|
|
926
|
-
const mockMemoria = {
|
|
927
|
-
recallTools: vi.fn().mockResolvedValue([
|
|
928
|
-
{
|
|
929
|
-
id: "k1",
|
|
930
|
-
name: "greet_user",
|
|
931
|
-
description: "Greet a user by name",
|
|
932
|
-
category: "meta",
|
|
933
|
-
parameters: {
|
|
934
|
-
type: "object",
|
|
935
|
-
properties: { name: { type: "string" } },
|
|
936
|
-
required: ["name"],
|
|
937
|
-
},
|
|
938
|
-
riskLevel: "safe",
|
|
939
|
-
responseTemplate: "Hello, {{name}}! Welcome to ARIA.",
|
|
940
|
-
},
|
|
941
|
-
]),
|
|
942
|
-
rememberTool: vi.fn(),
|
|
943
|
-
rememberSkill: vi.fn().mockResolvedValue("skill-id"),
|
|
944
|
-
recallSkills: vi.fn().mockResolvedValue([]),
|
|
945
|
-
getSkill: vi.fn().mockResolvedValue(null),
|
|
946
|
-
recordSkillExecution: vi
|
|
947
|
-
.fn()
|
|
948
|
-
.mockResolvedValue({ id: "exec-1", skillId: "s1", success: true, timestamp: new Date() }),
|
|
949
|
-
};
|
|
950
|
-
|
|
951
|
-
const count = await registry.discoverFromMemoria(mockMemoria as any);
|
|
952
|
-
expect(count).toBe(1);
|
|
953
|
-
|
|
954
|
-
const tool = registry.get("greet_user")!;
|
|
955
|
-
const ctx = createContext();
|
|
956
|
-
const result = await tool.execute({ name: "Alice" }, ctx);
|
|
957
|
-
|
|
958
|
-
expect(result.success).toBe(true);
|
|
959
|
-
expect(result.data).toBe("Hello, Alice! Welcome to ARIA.");
|
|
960
|
-
});
|
|
961
|
-
|
|
962
|
-
it("knowledge-only discovered tool should be skipped", async () => {
|
|
963
|
-
const registry = new ToolRegistry();
|
|
964
|
-
const mockMemoria = {
|
|
965
|
-
recallTools: vi.fn().mockResolvedValue([
|
|
966
|
-
{
|
|
967
|
-
id: "k2",
|
|
968
|
-
name: "explain_concept",
|
|
969
|
-
description: "Explains a concept",
|
|
970
|
-
category: "meta",
|
|
971
|
-
parameters: { type: "object", properties: {} },
|
|
972
|
-
riskLevel: "safe",
|
|
973
|
-
knowledge:
|
|
974
|
-
"Neural networks are computing systems inspired by biological neural networks.",
|
|
975
|
-
},
|
|
976
|
-
]),
|
|
977
|
-
rememberTool: vi.fn(),
|
|
978
|
-
rememberSkill: vi.fn().mockResolvedValue("skill-id"),
|
|
979
|
-
recallSkills: vi.fn().mockResolvedValue([]),
|
|
980
|
-
getSkill: vi.fn().mockResolvedValue(null),
|
|
981
|
-
recordSkillExecution: vi
|
|
982
|
-
.fn()
|
|
983
|
-
.mockResolvedValue({ id: "exec-1", skillId: "s1", success: true, timestamp: new Date() }),
|
|
984
|
-
};
|
|
985
|
-
|
|
986
|
-
const count = await registry.discoverFromMemoria(mockMemoria as any);
|
|
987
|
-
expect(count).toBe(0);
|
|
988
|
-
expect(registry.get("explain_concept")).toBeUndefined();
|
|
989
|
-
});
|
|
990
|
-
|
|
991
|
-
it("discovered tool should validate required parameters", async () => {
|
|
992
|
-
const registry = new ToolRegistry();
|
|
993
|
-
const mockMemoria = {
|
|
994
|
-
recallTools: vi.fn().mockResolvedValue([
|
|
995
|
-
{
|
|
996
|
-
id: "k3",
|
|
997
|
-
name: "requires_input",
|
|
998
|
-
description: "Tool needing input",
|
|
999
|
-
category: "meta",
|
|
1000
|
-
parameters: {
|
|
1001
|
-
type: "object",
|
|
1002
|
-
properties: { input: { type: "string" } },
|
|
1003
|
-
required: ["input"],
|
|
1004
|
-
},
|
|
1005
|
-
riskLevel: "safe",
|
|
1006
|
-
responseTemplate: "Got: {{input}}",
|
|
1007
|
-
},
|
|
1008
|
-
]),
|
|
1009
|
-
rememberTool: vi.fn(),
|
|
1010
|
-
rememberSkill: vi.fn().mockResolvedValue("skill-id"),
|
|
1011
|
-
recallSkills: vi.fn().mockResolvedValue([]),
|
|
1012
|
-
getSkill: vi.fn().mockResolvedValue(null),
|
|
1013
|
-
recordSkillExecution: vi
|
|
1014
|
-
.fn()
|
|
1015
|
-
.mockResolvedValue({ id: "exec-1", skillId: "s1", success: true, timestamp: new Date() }),
|
|
1016
|
-
};
|
|
1017
|
-
|
|
1018
|
-
await registry.discoverFromMemoria(mockMemoria as any);
|
|
1019
|
-
|
|
1020
|
-
const tool = registry.get("requires_input")!;
|
|
1021
|
-
const ctx = createContext();
|
|
1022
|
-
// Missing required "input" parameter
|
|
1023
|
-
const result = await tool.execute({}, ctx);
|
|
1024
|
-
|
|
1025
|
-
expect(result.success).toBe(false);
|
|
1026
|
-
expect(result.message).toContain("input");
|
|
1027
|
-
});
|
|
1028
|
-
|
|
1029
|
-
it("discovered tools should NOT override existing core tools", async () => {
|
|
1030
|
-
const registry = new ToolRegistry();
|
|
1031
|
-
// Register a core tool first
|
|
1032
|
-
const coreTool = getCoreTool("remember")!;
|
|
1033
|
-
registry.register(coreTool);
|
|
1034
|
-
|
|
1035
|
-
const mockMemoria = {
|
|
1036
|
-
recallTools: vi.fn().mockResolvedValue([
|
|
1037
|
-
{
|
|
1038
|
-
id: "k4",
|
|
1039
|
-
name: "remember", // Same name as core tool
|
|
1040
|
-
description: "Fake remember",
|
|
1041
|
-
category: "memory",
|
|
1042
|
-
riskLevel: "safe",
|
|
1043
|
-
},
|
|
1044
|
-
]),
|
|
1045
|
-
rememberTool: vi.fn(),
|
|
1046
|
-
rememberSkill: vi.fn().mockResolvedValue("skill-id"),
|
|
1047
|
-
recallSkills: vi.fn().mockResolvedValue([]),
|
|
1048
|
-
getSkill: vi.fn().mockResolvedValue(null),
|
|
1049
|
-
recordSkillExecution: vi
|
|
1050
|
-
.fn()
|
|
1051
|
-
.mockResolvedValue({ id: "exec-1", skillId: "s1", success: true, timestamp: new Date() }),
|
|
1052
|
-
};
|
|
1053
|
-
|
|
1054
|
-
const count = await registry.discoverFromMemoria(mockMemoria as any);
|
|
1055
|
-
expect(count).toBe(0); // Should NOT add it since "remember" already exists
|
|
1056
|
-
|
|
1057
|
-
// Original tool should still be there
|
|
1058
|
-
const tool = registry.get("remember")!;
|
|
1059
|
-
expect(tool.execute).toBe(coreTool.execute);
|
|
1060
|
-
});
|
|
1061
|
-
});
|
|
1062
|
-
|
|
1063
|
-
// ===========================================================================
|
|
1064
|
-
// Section 10: Registry registration edge cases
|
|
1065
|
-
// ===========================================================================
|
|
1066
|
-
|
|
1067
|
-
describe("Registry registration edge cases", () => {
|
|
1068
|
-
it("register should throw when tool already exists without override flag", () => {
|
|
1069
|
-
const registry = new ToolRegistry();
|
|
1070
|
-
const tool: Tool = {
|
|
1071
|
-
name: "test_tool",
|
|
1072
|
-
description: "Test",
|
|
1073
|
-
category: "meta",
|
|
1074
|
-
parameters: { type: "object", properties: {} },
|
|
1075
|
-
riskLevel: "safe",
|
|
1076
|
-
execute: async () => ({ success: true, message: "ok" }),
|
|
1077
|
-
};
|
|
1078
|
-
|
|
1079
|
-
registry.register(tool);
|
|
1080
|
-
|
|
1081
|
-
expect(() => registry.register(tool)).toThrow("already registered");
|
|
1082
|
-
});
|
|
1083
|
-
|
|
1084
|
-
it("register should succeed with override flag", () => {
|
|
1085
|
-
const registry = new ToolRegistry();
|
|
1086
|
-
const tool: Tool = {
|
|
1087
|
-
name: "test_tool",
|
|
1088
|
-
description: "Original",
|
|
1089
|
-
category: "meta",
|
|
1090
|
-
parameters: { type: "object", properties: {} },
|
|
1091
|
-
riskLevel: "safe",
|
|
1092
|
-
execute: async () => ({ success: true, message: "original" }),
|
|
1093
|
-
};
|
|
1094
|
-
const replacement: Tool = {
|
|
1095
|
-
...tool,
|
|
1096
|
-
description: "Replaced",
|
|
1097
|
-
execute: async () => ({ success: true, message: "replaced" }),
|
|
1098
|
-
};
|
|
1099
|
-
|
|
1100
|
-
registry.register(tool);
|
|
1101
|
-
registry.register(replacement, { override: true });
|
|
1102
|
-
|
|
1103
|
-
const result = registry.get("test_tool");
|
|
1104
|
-
expect(result!.description).toBe("Replaced");
|
|
1105
|
-
});
|
|
1106
|
-
|
|
1107
|
-
it("unregister should remove tool and return true", () => {
|
|
1108
|
-
const registry = new ToolRegistry();
|
|
1109
|
-
const tool: Tool = {
|
|
1110
|
-
name: "removable",
|
|
1111
|
-
description: "Can be removed",
|
|
1112
|
-
category: "meta",
|
|
1113
|
-
parameters: { type: "object", properties: {} },
|
|
1114
|
-
riskLevel: "safe",
|
|
1115
|
-
execute: async () => ({ success: true, message: "ok" }),
|
|
1116
|
-
};
|
|
1117
|
-
|
|
1118
|
-
registry.register(tool);
|
|
1119
|
-
expect(registry.has("removable")).toBe(true);
|
|
1120
|
-
|
|
1121
|
-
const removed = registry.unregister("removable");
|
|
1122
|
-
expect(removed).toBe(true);
|
|
1123
|
-
expect(registry.has("removable")).toBe(false);
|
|
1124
|
-
});
|
|
1125
|
-
|
|
1126
|
-
it("unregister should return false for non-existent tool", () => {
|
|
1127
|
-
const registry = new ToolRegistry();
|
|
1128
|
-
const removed = registry.unregister("nonexistent");
|
|
1129
|
-
expect(removed).toBe(false);
|
|
1130
|
-
});
|
|
1131
|
-
|
|
1132
|
-
it("clear should remove all tools", () => {
|
|
1133
|
-
const registry = createToolRegistry();
|
|
1134
|
-
expect(registry.getAll().length).toBe(CORE_TOOL_DEFINITIONS.length);
|
|
1135
|
-
|
|
1136
|
-
registry.clear();
|
|
1137
|
-
expect(registry.getAll().length).toBe(0);
|
|
1138
|
-
});
|
|
1139
|
-
|
|
1140
|
-
it("search should find tools by name or description substring", () => {
|
|
1141
|
-
const registry = createToolRegistry();
|
|
1142
|
-
|
|
1143
|
-
const fileTools = registry.search("file");
|
|
1144
|
-
expect(fileTools.length).toBeGreaterThanOrEqual(3); // read_file, write_file, edit_file
|
|
1145
|
-
|
|
1146
|
-
const memoryTools = registry.search("memory");
|
|
1147
|
-
expect(memoryTools.length).toBeGreaterThanOrEqual(1);
|
|
1148
|
-
});
|
|
1149
|
-
});
|
|
1150
|
-
|
|
1151
|
-
// ===========================================================================
|
|
1152
|
-
// Section 11: ToolContext.abortSignal propagation
|
|
1153
|
-
// ===========================================================================
|
|
1154
|
-
|
|
1155
|
-
describe("ToolContext.abortSignal propagation", () => {
|
|
1156
|
-
it("MCP tools should check abortSignal before executing", async () => {
|
|
1157
|
-
// This tests the MCP tool wrapper pattern in registry.ts
|
|
1158
|
-
// MCP tools created by connectMCP check ctx.abortSignal?.aborted
|
|
1159
|
-
const controller = new AbortController();
|
|
1160
|
-
controller.abort();
|
|
1161
|
-
|
|
1162
|
-
const ctx = createContext({ abortSignal: controller.signal });
|
|
1163
|
-
expect(ctx.abortSignal?.aborted).toBe(true);
|
|
1164
|
-
|
|
1165
|
-
// Core tools don't currently check abortSignal, but the infrastructure
|
|
1166
|
-
// should support it. This test validates the context shape is correct.
|
|
1167
|
-
});
|
|
1168
|
-
});
|
|
1169
|
-
|
|
1170
|
-
// ===========================================================================
|
|
1171
|
-
// Section 12: Tool isReadOnly classification correctness
|
|
1172
|
-
// ===========================================================================
|
|
1173
|
-
|
|
1174
|
-
describe("Tool isReadOnly classification", () => {
|
|
1175
|
-
it("read-only tools should have isReadOnly: true", () => {
|
|
1176
|
-
const expectedReadOnly = [
|
|
1177
|
-
"recall",
|
|
1178
|
-
"recall_knowledge",
|
|
1179
|
-
"web_search",
|
|
1180
|
-
"web_fetch",
|
|
1181
|
-
"browse",
|
|
1182
|
-
"read_file",
|
|
1183
|
-
"glob",
|
|
1184
|
-
"grep",
|
|
1185
|
-
"ls",
|
|
1186
|
-
// "search" moved to @aria/aria
|
|
1187
|
-
];
|
|
1188
|
-
|
|
1189
|
-
for (const name of expectedReadOnly) {
|
|
1190
|
-
const tool = getCoreTool(name);
|
|
1191
|
-
expect(tool).toBeDefined();
|
|
1192
|
-
expect(tool!.isReadOnly).toBe(true);
|
|
1193
|
-
}
|
|
1194
|
-
});
|
|
1195
|
-
|
|
1196
|
-
it("mutating tools should have isReadOnly: false or undefined", () => {
|
|
1197
|
-
const expectedMutating = [
|
|
1198
|
-
"remember",
|
|
1199
|
-
"reflect",
|
|
1200
|
-
"forget",
|
|
1201
|
-
"write_file",
|
|
1202
|
-
"edit_file",
|
|
1203
|
-
"apply_patch",
|
|
1204
|
-
"bash",
|
|
1205
|
-
"exec",
|
|
1206
|
-
"spawn",
|
|
1207
|
-
"kill",
|
|
1208
|
-
"write_stdin",
|
|
1209
|
-
"hatch_arion",
|
|
1210
|
-
"rest_arion",
|
|
1211
|
-
"wake_arion",
|
|
1212
|
-
"retire_arion",
|
|
1213
|
-
"delegate_arion",
|
|
1214
|
-
"delegate_remote",
|
|
1215
|
-
"spawn_worker",
|
|
1216
|
-
"quest_update",
|
|
1217
|
-
];
|
|
1218
|
-
|
|
1219
|
-
for (const name of expectedMutating) {
|
|
1220
|
-
const tool = getCoreTool(name);
|
|
1221
|
-
expect(tool).toBeDefined();
|
|
1222
|
-
expect(tool!.isReadOnly).not.toBe(true);
|
|
1223
|
-
}
|
|
1224
|
-
});
|
|
1225
|
-
});
|
|
1226
|
-
|
|
1227
|
-
// ===========================================================================
|
|
1228
|
-
// Section 13: FAILING - Missing arion lifecycle tools (rest/wake/retire)
|
|
1229
|
-
// ===========================================================================
|
|
1230
|
-
|
|
1231
|
-
describe("FAILING: Arion lifecycle tools completeness", () => {
|
|
1232
|
-
/**
|
|
1233
|
-
* The arion lifecycle requires 4 operations:
|
|
1234
|
-
* - hatch: Create a new arion (EXISTS)
|
|
1235
|
-
* - rest: Put an arion to sleep (MISSING)
|
|
1236
|
-
* - wake: Wake a sleeping arion (MISSING)
|
|
1237
|
-
* - retire: Permanently retire an arion (MISSING)
|
|
1238
|
-
*
|
|
1239
|
-
* These tools are documented in the ArionManagerRef interface but
|
|
1240
|
-
* no corresponding tool definitions or executors exist.
|
|
1241
|
-
*/
|
|
1242
|
-
|
|
1243
|
-
it("should have a rest_arion tool in CORE_TOOL_DEFINITIONS", () => {
|
|
1244
|
-
const tool = getCoreTool("rest_arion");
|
|
1245
|
-
expect(tool).toBeDefined();
|
|
1246
|
-
expect(tool!.category).toBe("arion");
|
|
1247
|
-
expect(tool!.riskLevel).toBe("moderate");
|
|
1248
|
-
});
|
|
1249
|
-
|
|
1250
|
-
it("should have a wake_arion tool in CORE_TOOL_DEFINITIONS", () => {
|
|
1251
|
-
const tool = getCoreTool("wake_arion");
|
|
1252
|
-
expect(tool).toBeDefined();
|
|
1253
|
-
expect(tool!.category).toBe("arion");
|
|
1254
|
-
expect(tool!.riskLevel).toBe("moderate");
|
|
1255
|
-
});
|
|
1256
|
-
|
|
1257
|
-
it("should have a retire_arion tool in CORE_TOOL_DEFINITIONS", () => {
|
|
1258
|
-
const tool = getCoreTool("retire_arion");
|
|
1259
|
-
expect(tool).toBeDefined();
|
|
1260
|
-
expect(tool!.category).toBe("arion");
|
|
1261
|
-
expect(tool!.riskLevel).toBe("dangerous");
|
|
1262
|
-
});
|
|
1263
|
-
|
|
1264
|
-
it("registry should stay aligned with the authoritative arion tool set", () => {
|
|
1265
|
-
const registry = createToolRegistry();
|
|
1266
|
-
const arionTools = registry.list("arion" as ToolCategory);
|
|
1267
|
-
expect(arionTools.length).toBe(getCoreToolsByCategory("arion").length);
|
|
1268
|
-
const names = arionTools.map((t) => t.name).sort();
|
|
1269
|
-
expect(names).toEqual(
|
|
1270
|
-
getCoreToolsByCategory("arion")
|
|
1271
|
-
.map((tool) => tool.name)
|
|
1272
|
-
.sort(),
|
|
1273
|
-
);
|
|
1274
|
-
expect(names).toEqual(
|
|
1275
|
-
expect.arrayContaining([
|
|
1276
|
-
"delegate_arion",
|
|
1277
|
-
"deploy",
|
|
1278
|
-
"hatch_arion",
|
|
1279
|
-
"list_clients",
|
|
1280
|
-
"manage_network",
|
|
1281
|
-
"rest_arion",
|
|
1282
|
-
"retire_arion",
|
|
1283
|
-
"wake_arion",
|
|
1284
|
-
]),
|
|
1285
|
-
);
|
|
1286
|
-
});
|
|
1287
|
-
});
|
|
1288
|
-
|
|
1289
|
-
// ===========================================================================
|
|
1290
|
-
// Section 14: FAILING - Core executors should respect abortSignal
|
|
1291
|
-
// ===========================================================================
|
|
1292
|
-
|
|
1293
|
-
describe("FAILING: Core executors should respect abortSignal", () => {
|
|
1294
|
-
/**
|
|
1295
|
-
* Currently only MCP tool wrappers (created in registry.ts connectMCP)
|
|
1296
|
-
* check ctx.abortSignal before executing. Core executors like
|
|
1297
|
-
* remember, recall, bash, etc. do NOT check abortSignal at all.
|
|
1298
|
-
*
|
|
1299
|
-
* If a run is cancelled, long-running tools (bash, spawn, web_fetch)
|
|
1300
|
-
* should respect the signal and abort early.
|
|
1301
|
-
*/
|
|
1302
|
-
|
|
1303
|
-
it("executeRemember should check abortSignal before calling memoria", async () => {
|
|
1304
|
-
const controller = new AbortController();
|
|
1305
|
-
controller.abort(); // Pre-abort
|
|
1306
|
-
|
|
1307
|
-
const mockMemoria = createMockMemoria();
|
|
1308
|
-
const ctx = createContext({
|
|
1309
|
-
memoria: mockMemoria as any,
|
|
1310
|
-
abortSignal: controller.signal,
|
|
1311
|
-
});
|
|
1312
|
-
|
|
1313
|
-
const result = await executeRemember({ content: "should not store" }, ctx);
|
|
1314
|
-
|
|
1315
|
-
// Should fail because signal is already aborted
|
|
1316
|
-
expect(result.success).toBe(false);
|
|
1317
|
-
expect(result.message).toMatch(/abort|cancel/i);
|
|
1318
|
-
// Should NOT have called memoria.remember
|
|
1319
|
-
expect(mockMemoria.remember).not.toHaveBeenCalled();
|
|
1320
|
-
});
|
|
1321
|
-
|
|
1322
|
-
it("executeRecall should check abortSignal before calling memoria", async () => {
|
|
1323
|
-
const controller = new AbortController();
|
|
1324
|
-
controller.abort();
|
|
1325
|
-
|
|
1326
|
-
const mockMemoria = createMockMemoria();
|
|
1327
|
-
const ctx = createContext({
|
|
1328
|
-
memoria: mockMemoria as any,
|
|
1329
|
-
abortSignal: controller.signal,
|
|
1330
|
-
});
|
|
1331
|
-
|
|
1332
|
-
const result = await executeRecall({ query: "test" }, ctx);
|
|
1333
|
-
|
|
1334
|
-
expect(result.success).toBe(false);
|
|
1335
|
-
expect(result.message).toMatch(/abort|cancel/i);
|
|
1336
|
-
expect(mockMemoria.recall).not.toHaveBeenCalled();
|
|
1337
|
-
});
|
|
1338
|
-
});
|
|
1339
|
-
|
|
1340
|
-
// ===========================================================================
|
|
1341
|
-
// Section 15: FAILING - ToolContext.manager should be in RunOptions interface
|
|
1342
|
-
// ===========================================================================
|
|
1343
|
-
|
|
1344
|
-
describe("FAILING: RunOptions should expose manager for ToolContext injection", () => {
|
|
1345
|
-
/**
|
|
1346
|
-
* AgentRunner at runner.ts:1547-1556 builds ToolContext but does NOT
|
|
1347
|
-
* inject `manager` from options. The RunOptions type needs a `manager`
|
|
1348
|
-
* field, and the ToolContext construction needs to wire it:
|
|
1349
|
-
*
|
|
1350
|
-
* const ctx: ToolContext = {
|
|
1351
|
-
* ...
|
|
1352
|
-
* manager: options?.manager as any, // <-- MISSING
|
|
1353
|
-
* };
|
|
1354
|
-
*
|
|
1355
|
-
* Without this, hatch_arion always fails at runtime.
|
|
1356
|
-
*/
|
|
1357
|
-
|
|
1358
|
-
it("ToolContext type should include optional manager field", () => {
|
|
1359
|
-
// This passes (manager is on ToolContext interface)
|
|
1360
|
-
const ctx = createContext({
|
|
1361
|
-
manager: createMockManager(),
|
|
1362
|
-
});
|
|
1363
|
-
expect(ctx.manager).toBeDefined();
|
|
1364
|
-
});
|
|
1365
|
-
|
|
1366
|
-
it("hatch_arion through full registry path should work with proper context", async () => {
|
|
1367
|
-
const registry = createToolRegistry();
|
|
1368
|
-
const tool = registry.get("hatch_arion");
|
|
1369
|
-
expect(tool).toBeDefined();
|
|
1370
|
-
|
|
1371
|
-
// Simulate what the runner SHOULD build
|
|
1372
|
-
const mockManager = createMockManager();
|
|
1373
|
-
const ctx = createContext({
|
|
1374
|
-
arion: { id: "p1", name: "Parent", emoji: "🐣" },
|
|
1375
|
-
manager: mockManager,
|
|
1376
|
-
});
|
|
1377
|
-
|
|
1378
|
-
const result = await tool!.execute(
|
|
1379
|
-
{ name: "NewArion", traits: ["smart"], style: "technical" },
|
|
1380
|
-
ctx,
|
|
1381
|
-
);
|
|
1382
|
-
|
|
1383
|
-
expect(result.success).toBe(true);
|
|
1384
|
-
// This works when manager is manually wired, but AgentRunner doesn't wire it
|
|
1385
|
-
});
|
|
1386
|
-
});
|
|
1387
|
-
|
|
1388
|
-
// ===========================================================================
|
|
1389
|
-
// Section 16: Registry population should stay aligned with authoritative definitions
|
|
1390
|
-
// ===========================================================================
|
|
1391
|
-
|
|
1392
|
-
describe("FAILING: Total tool count should reflect complete arion lifecycle", () => {
|
|
1393
|
-
it("CORE_TOOL_DEFINITIONS should remain the authoritative source for registry population", () => {
|
|
1394
|
-
expect(CORE_TOOL_DEFINITIONS.length).toBeGreaterThan(0);
|
|
1395
|
-
});
|
|
1396
|
-
|
|
1397
|
-
it("createToolRegistry should register every authoritative core tool", () => {
|
|
1398
|
-
const registry = createToolRegistry();
|
|
1399
|
-
expect(registry.getAll().length).toBe(CORE_TOOL_DEFINITIONS.length);
|
|
1400
|
-
});
|
|
1401
|
-
});
|
|
1402
|
-
|
|
1403
|
-
// ===========================================================================
|
|
1404
|
-
// Section 17: FAILING - Meta tools with Memoria should work through registry
|
|
1405
|
-
// ===========================================================================
|
|
1406
|
-
|
|
1407
|
-
// Section 17: Meta tools (search/learn) moved to @aria/aria.
|
|
1408
|
-
|
|
1409
|
-
// ===========================================================================
|
|
1410
|
-
// Section 18: FAILING - Concurrent tool execution safety
|
|
1411
|
-
// ===========================================================================
|
|
1412
|
-
|
|
1413
|
-
describe("FAILING: Concurrent execution safety for read-only tools", () => {
|
|
1414
|
-
/**
|
|
1415
|
-
* Read-only tools (isReadOnly: true) should be safe for parallel
|
|
1416
|
-
* execution by the runner. This means they should not share mutable
|
|
1417
|
-
* state and should not interfere with each other.
|
|
1418
|
-
*
|
|
1419
|
-
* The runner dispatches read-only tools in parallel, so they MUST
|
|
1420
|
-
* handle concurrent calls correctly.
|
|
1421
|
-
*/
|
|
1422
|
-
|
|
1423
|
-
it("multiple concurrent recall calls should not interfere", async () => {
|
|
1424
|
-
const mockMemoria = createMockMemoria();
|
|
1425
|
-
let callCount = 0;
|
|
1426
|
-
mockMemoria.recall.mockImplementation(async (query: string) => {
|
|
1427
|
-
callCount++;
|
|
1428
|
-
const myCount = callCount;
|
|
1429
|
-
// Simulate async delay
|
|
1430
|
-
await new Promise((r) => setTimeout(r, 10));
|
|
1431
|
-
return { memories: [{ id: `mem-${myCount}`, content: `Result for: ${query}` }] };
|
|
1432
|
-
});
|
|
1433
|
-
const ctx = createContext({ memoria: mockMemoria as any });
|
|
1434
|
-
|
|
1435
|
-
// Launch 3 concurrent recalls
|
|
1436
|
-
const [r1, r2, r3] = await Promise.all([
|
|
1437
|
-
executeRecall({ query: "alpha" }, ctx),
|
|
1438
|
-
executeRecall({ query: "beta" }, ctx),
|
|
1439
|
-
executeRecall({ query: "gamma" }, ctx),
|
|
1440
|
-
]);
|
|
1441
|
-
|
|
1442
|
-
expect(r1.success).toBe(true);
|
|
1443
|
-
expect(r2.success).toBe(true);
|
|
1444
|
-
expect(r3.success).toBe(true);
|
|
1445
|
-
|
|
1446
|
-
// Each should have gotten distinct results
|
|
1447
|
-
expect(mockMemoria.recall).toHaveBeenCalledTimes(3);
|
|
1448
|
-
});
|
|
1449
|
-
|
|
1450
|
-
it("concurrent remember and recall should not deadlock or corrupt", async () => {
|
|
1451
|
-
const mockMemoria = createMockMemoria();
|
|
1452
|
-
mockMemoria.remember.mockResolvedValue({ id: "mem-concurrent" });
|
|
1453
|
-
mockMemoria.recall.mockResolvedValue({ memories: [{ id: "m1", content: "data" }] });
|
|
1454
|
-
const ctx = createContext({ memoria: mockMemoria as any });
|
|
1455
|
-
|
|
1456
|
-
// Parallel write + read
|
|
1457
|
-
const [writeResult, readResult] = await Promise.all([
|
|
1458
|
-
executeRemember({ content: "concurrent write" }, ctx),
|
|
1459
|
-
executeRecall({ query: "concurrent read" }, ctx),
|
|
1460
|
-
]);
|
|
1461
|
-
|
|
1462
|
-
expect(writeResult.success).toBe(true);
|
|
1463
|
-
expect(readResult.success).toBe(true);
|
|
1464
|
-
});
|
|
1465
|
-
});
|