macro-agent 0.0.11 → 0.0.12
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/.macro-agent/teams/self-driving/prompts/grinder.md +27 -0
- package/.macro-agent/teams/self-driving/prompts/judge.md +27 -0
- package/.macro-agent/teams/self-driving/prompts/planner.md +33 -0
- package/.macro-agent/teams/self-driving/roles/grinder.yaml +17 -0
- package/.macro-agent/teams/self-driving/roles/judge.yaml +24 -0
- package/.macro-agent/teams/self-driving/roles/planner.yaml +18 -0
- package/.macro-agent/teams/self-driving/team.yaml +103 -0
- package/.macro-agent/teams/structured/prompts/developer.md +26 -0
- package/.macro-agent/teams/structured/prompts/lead.md +25 -0
- package/.macro-agent/teams/structured/prompts/reviewer.md +24 -0
- package/.macro-agent/teams/structured/roles/developer.yaml +12 -0
- package/.macro-agent/teams/structured/roles/lead.yaml +11 -0
- package/.macro-agent/teams/structured/roles/reviewer.yaml +19 -0
- package/.macro-agent/teams/structured/team.yaml +89 -0
- package/.sudocode/issues.jsonl +6 -0
- package/.sudocode/specs.jsonl +7 -0
- package/CLAUDE.md +110 -30
- package/README.md +60 -3
- package/dist/acp/macro-agent.d.ts +4 -0
- package/dist/acp/macro-agent.d.ts.map +1 -1
- package/dist/acp/macro-agent.js +50 -4
- package/dist/acp/macro-agent.js.map +1 -1
- package/dist/acp/session-mapper.d.ts +20 -1
- package/dist/acp/session-mapper.d.ts.map +1 -1
- package/dist/acp/session-mapper.js +90 -1
- package/dist/acp/session-mapper.js.map +1 -1
- package/dist/acp/types.d.ts +24 -1
- package/dist/acp/types.d.ts.map +1 -1
- package/dist/acp/types.js.map +1 -1
- package/dist/agent/agent-manager.d.ts +25 -1
- package/dist/agent/agent-manager.d.ts.map +1 -1
- package/dist/agent/agent-manager.js +93 -7
- package/dist/agent/agent-manager.js.map +1 -1
- package/dist/agent/types.d.ts +22 -0
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/agent/types.js.map +1 -1
- package/dist/agent-detection/command-builder.d.ts +30 -0
- package/dist/agent-detection/command-builder.d.ts.map +1 -0
- package/dist/agent-detection/command-builder.js +71 -0
- package/dist/agent-detection/command-builder.js.map +1 -0
- package/dist/agent-detection/detector.d.ts +84 -0
- package/dist/agent-detection/detector.d.ts.map +1 -0
- package/dist/agent-detection/detector.js +240 -0
- package/dist/agent-detection/detector.js.map +1 -0
- package/dist/agent-detection/index.d.ts +12 -0
- package/dist/agent-detection/index.d.ts.map +1 -0
- package/dist/agent-detection/index.js +14 -0
- package/dist/agent-detection/index.js.map +1 -0
- package/dist/agent-detection/registry.d.ts +53 -0
- package/dist/agent-detection/registry.d.ts.map +1 -0
- package/dist/agent-detection/registry.js +177 -0
- package/dist/agent-detection/registry.js.map +1 -0
- package/dist/agent-detection/types.d.ts +121 -0
- package/dist/agent-detection/types.d.ts.map +1 -0
- package/dist/agent-detection/types.js +20 -0
- package/dist/agent-detection/types.js.map +1 -0
- package/dist/api/server.d.ts.map +1 -1
- package/dist/api/server.js +95 -0
- package/dist/api/server.js.map +1 -1
- package/dist/cli/index.js +29 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/mcp.js +38 -0
- package/dist/cli/mcp.js.map +1 -1
- package/dist/config/index.d.ts +2 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +2 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/project-config.d.ts +46 -0
- package/dist/config/project-config.d.ts.map +1 -0
- package/dist/config/project-config.js +68 -0
- package/dist/config/project-config.js.map +1 -0
- package/dist/lifecycle/cascade.d.ts +1 -1
- package/dist/lifecycle/cascade.d.ts.map +1 -1
- package/dist/lifecycle/handlers/index.d.ts +4 -0
- package/dist/lifecycle/handlers/index.d.ts.map +1 -1
- package/dist/lifecycle/handlers/index.js +2 -0
- package/dist/lifecycle/handlers/index.js.map +1 -1
- package/dist/lifecycle/handlers/worker.d.ts +4 -0
- package/dist/lifecycle/handlers/worker.d.ts.map +1 -1
- package/dist/lifecycle/handlers/worker.js +35 -3
- package/dist/lifecycle/handlers/worker.js.map +1 -1
- package/dist/map/adapter/acp-over-map.d.ts.map +1 -1
- package/dist/map/adapter/acp-over-map.js +32 -2
- package/dist/map/adapter/acp-over-map.js.map +1 -1
- package/dist/map/adapter/event-translator.d.ts.map +1 -1
- package/dist/map/adapter/event-translator.js +1 -0
- package/dist/map/adapter/event-translator.js.map +1 -1
- package/dist/map/adapter/extensions/agent-detection.d.ts +49 -0
- package/dist/map/adapter/extensions/agent-detection.d.ts.map +1 -0
- package/dist/map/adapter/extensions/agent-detection.js +91 -0
- package/dist/map/adapter/extensions/agent-detection.js.map +1 -0
- package/dist/map/adapter/extensions/index.d.ts +10 -1
- package/dist/map/adapter/extensions/index.d.ts.map +1 -1
- package/dist/map/adapter/extensions/index.js +39 -0
- package/dist/map/adapter/extensions/index.js.map +1 -1
- package/dist/map/adapter/extensions/resume.d.ts +47 -0
- package/dist/map/adapter/extensions/resume.d.ts.map +1 -0
- package/dist/map/adapter/extensions/resume.js +59 -0
- package/dist/map/adapter/extensions/resume.js.map +1 -0
- package/dist/map/adapter/extensions/workspace-files.d.ts +42 -0
- package/dist/map/adapter/extensions/workspace-files.d.ts.map +1 -0
- package/dist/map/adapter/extensions/workspace-files.js +338 -0
- package/dist/map/adapter/extensions/workspace-files.js.map +1 -0
- package/dist/mcp/mcp-server.d.ts +6 -0
- package/dist/mcp/mcp-server.d.ts.map +1 -1
- package/dist/mcp/mcp-server.js +45 -0
- package/dist/mcp/mcp-server.js.map +1 -1
- package/dist/mcp/tools/claim_task.d.ts +35 -0
- package/dist/mcp/tools/claim_task.d.ts.map +1 -0
- package/dist/mcp/tools/claim_task.js +58 -0
- package/dist/mcp/tools/claim_task.js.map +1 -0
- package/dist/mcp/tools/done.d.ts +11 -2
- package/dist/mcp/tools/done.d.ts.map +1 -1
- package/dist/mcp/tools/done.js +15 -10
- package/dist/mcp/tools/done.js.map +1 -1
- package/dist/mcp/tools/list_claimable_tasks.d.ts +38 -0
- package/dist/mcp/tools/list_claimable_tasks.d.ts.map +1 -0
- package/dist/mcp/tools/list_claimable_tasks.js +63 -0
- package/dist/mcp/tools/list_claimable_tasks.js.map +1 -0
- package/dist/mcp/tools/unclaim_task.d.ts +31 -0
- package/dist/mcp/tools/unclaim_task.d.ts.map +1 -0
- package/dist/mcp/tools/unclaim_task.js +47 -0
- package/dist/mcp/tools/unclaim_task.js.map +1 -0
- package/dist/metrics/index.d.ts +2 -0
- package/dist/metrics/index.d.ts.map +1 -0
- package/dist/metrics/index.js +2 -0
- package/dist/metrics/index.js.map +1 -0
- package/dist/metrics/metrics.d.ts +79 -0
- package/dist/metrics/metrics.d.ts.map +1 -0
- package/dist/metrics/metrics.js +166 -0
- package/dist/metrics/metrics.js.map +1 -0
- package/dist/roles/capabilities.d.ts +1 -0
- package/dist/roles/capabilities.d.ts.map +1 -1
- package/dist/roles/capabilities.js +3 -0
- package/dist/roles/capabilities.js.map +1 -1
- package/dist/roles/types.d.ts +1 -1
- package/dist/roles/types.d.ts.map +1 -1
- package/dist/router/message-router.d.ts +41 -0
- package/dist/router/message-router.d.ts.map +1 -1
- package/dist/router/message-router.js +136 -5
- package/dist/router/message-router.js.map +1 -1
- package/dist/store/event-store.d.ts +8 -1
- package/dist/store/event-store.d.ts.map +1 -1
- package/dist/store/event-store.js +120 -4
- package/dist/store/event-store.js.map +1 -1
- package/dist/store/types/agents.d.ts +1 -1
- package/dist/store/types/agents.d.ts.map +1 -1
- package/dist/store/types/events.d.ts +1 -1
- package/dist/store/types/events.d.ts.map +1 -1
- package/dist/store/types/events.js.map +1 -1
- package/dist/store/types/index.d.ts +1 -0
- package/dist/store/types/index.d.ts.map +1 -1
- package/dist/store/types/index.js +1 -0
- package/dist/store/types/index.js.map +1 -1
- package/dist/store/types/sessions.d.ts +44 -0
- package/dist/store/types/sessions.d.ts.map +1 -0
- package/dist/store/types/sessions.js +9 -0
- package/dist/store/types/sessions.js.map +1 -0
- package/dist/store/types/tasks.d.ts +2 -0
- package/dist/store/types/tasks.d.ts.map +1 -1
- package/dist/task/backend/memory.d.ts +4 -1
- package/dist/task/backend/memory.d.ts.map +1 -1
- package/dist/task/backend/memory.js +81 -0
- package/dist/task/backend/memory.js.map +1 -1
- package/dist/task/backend/types.d.ts +30 -0
- package/dist/task/backend/types.d.ts.map +1 -1
- package/dist/task/backend/types.js.map +1 -1
- package/dist/teams/index.d.ts +4 -0
- package/dist/teams/index.d.ts.map +1 -0
- package/dist/teams/index.js +4 -0
- package/dist/teams/index.js.map +1 -0
- package/dist/teams/team-loader.d.ts +20 -0
- package/dist/teams/team-loader.d.ts.map +1 -0
- package/dist/teams/team-loader.js +293 -0
- package/dist/teams/team-loader.js.map +1 -0
- package/dist/teams/team-runtime.d.ts +139 -0
- package/dist/teams/team-runtime.d.ts.map +1 -0
- package/dist/teams/team-runtime.js +613 -0
- package/dist/teams/team-runtime.js.map +1 -0
- package/dist/teams/types.d.ts +266 -0
- package/dist/teams/types.d.ts.map +1 -0
- package/dist/teams/types.js +20 -0
- package/dist/teams/types.js.map +1 -0
- package/dist/workspace/dataplane-adapter.d.ts +1 -1
- package/dist/workspace/dataplane-adapter.d.ts.map +1 -1
- package/dist/workspace/dataplane-adapter.js +1 -1
- package/dist/workspace/dataplane-adapter.js.map +1 -1
- package/dist/workspace/index.d.ts +1 -1
- package/dist/workspace/index.d.ts.map +1 -1
- package/dist/workspace/strategies/index.d.ts +6 -0
- package/dist/workspace/strategies/index.d.ts.map +1 -0
- package/dist/workspace/strategies/index.js +5 -0
- package/dist/workspace/strategies/index.js.map +1 -0
- package/dist/workspace/strategies/optimistic.d.ts +26 -0
- package/dist/workspace/strategies/optimistic.d.ts.map +1 -0
- package/dist/workspace/strategies/optimistic.js +121 -0
- package/dist/workspace/strategies/optimistic.js.map +1 -0
- package/dist/workspace/strategies/queue.d.ts +26 -0
- package/dist/workspace/strategies/queue.d.ts.map +1 -0
- package/dist/workspace/strategies/queue.js +67 -0
- package/dist/workspace/strategies/queue.js.map +1 -0
- package/dist/workspace/strategies/registry.d.ts +37 -0
- package/dist/workspace/strategies/registry.d.ts.map +1 -0
- package/dist/workspace/strategies/registry.js +63 -0
- package/dist/workspace/strategies/registry.js.map +1 -0
- package/dist/workspace/strategies/trunk.d.ts +20 -0
- package/dist/workspace/strategies/trunk.d.ts.map +1 -0
- package/dist/workspace/strategies/trunk.js +108 -0
- package/dist/workspace/strategies/trunk.js.map +1 -0
- package/dist/workspace/strategies/types.d.ts +104 -0
- package/dist/workspace/strategies/types.d.ts.map +1 -0
- package/dist/workspace/strategies/types.js +11 -0
- package/dist/workspace/strategies/types.js.map +1 -0
- package/dist/workspace/types.d.ts +1 -1
- package/dist/workspace/types.d.ts.map +1 -1
- package/dist/workspace/workspace-manager.d.ts +1 -1
- package/dist/workspace/workspace-manager.d.ts.map +1 -1
- package/docs/implementation-details.md +1127 -0
- package/docs/implementation-summary.md +448 -0
- package/docs/plan-self-driving-support.md +433 -0
- package/docs/spec-self-driving-support.md +462 -0
- package/docs/team-templates.md +860 -0
- package/docs/teams.md +233 -0
- package/package.json +4 -2
- package/src/acp/__tests__/integration.test.ts +161 -1
- package/src/acp/__tests__/macro-agent.test.ts +95 -0
- package/src/acp/__tests__/session-persistence.test.ts +276 -0
- package/src/acp/macro-agent.ts +79 -7
- package/src/acp/session-mapper.ts +108 -1
- package/src/acp/types.ts +33 -1
- package/src/agent/agent-manager.ts +158 -6
- package/src/agent/types.ts +27 -0
- package/src/agent-detection/__tests__/command-builder.test.ts +336 -0
- package/src/agent-detection/__tests__/detector.test.ts +768 -0
- package/src/agent-detection/__tests__/registry.test.ts +254 -0
- package/src/agent-detection/command-builder.ts +90 -0
- package/src/agent-detection/detector.ts +307 -0
- package/src/agent-detection/index.ts +36 -0
- package/src/agent-detection/registry.ts +200 -0
- package/src/agent-detection/types.ts +184 -0
- package/src/api/server.ts +110 -0
- package/src/cli/index.ts +44 -0
- package/src/cli/mcp.ts +47 -0
- package/src/config/index.ts +9 -0
- package/src/config/project-config.ts +107 -0
- package/src/lifecycle/cascade.ts +1 -1
- package/src/lifecycle/handlers/index.ts +8 -0
- package/src/lifecycle/handlers/worker.ts +48 -3
- package/src/map/adapter/__tests__/extensions.test.ts +359 -0
- package/src/map/adapter/__tests__/workspace-files.test.ts +673 -0
- package/src/map/adapter/acp-over-map.ts +45 -2
- package/src/map/adapter/event-translator.ts +1 -0
- package/src/map/adapter/extensions/agent-detection.ts +201 -0
- package/src/map/adapter/extensions/index.ts +63 -0
- package/src/map/adapter/extensions/resume.ts +114 -0
- package/src/map/adapter/extensions/workspace-files.ts +449 -0
- package/src/mcp/mcp-server.ts +67 -0
- package/src/mcp/tools/claim_task.ts +86 -0
- package/src/mcp/tools/done.ts +24 -10
- package/src/mcp/tools/list_claimable_tasks.ts +93 -0
- package/src/mcp/tools/unclaim_task.ts +71 -0
- package/src/metrics/index.ts +9 -0
- package/src/metrics/metrics.ts +280 -0
- package/src/roles/capabilities.ts +3 -0
- package/src/roles/types.ts +2 -1
- package/src/router/__tests__/message-router.test.ts +561 -0
- package/src/router/message-router.ts +223 -6
- package/src/store/event-store.ts +151 -3
- package/src/store/types/agents.ts +1 -1
- package/src/store/types/events.ts +2 -1
- package/src/store/types/index.ts +1 -0
- package/src/store/types/sessions.ts +53 -0
- package/src/store/types/tasks.ts +3 -0
- package/src/task/backend/memory.ts +116 -0
- package/src/task/backend/types.ts +43 -0
- package/src/teams/__tests__/cross-subsystem.integration.test.ts +983 -0
- package/src/teams/__tests__/e2e/team-runtime.e2e.test.ts +553 -0
- package/src/teams/__tests__/team-system.test.ts +1280 -0
- package/src/teams/index.ts +13 -0
- package/src/teams/team-loader.ts +434 -0
- package/src/teams/team-runtime.ts +727 -0
- package/src/teams/types.ts +377 -0
- package/src/workspace/dataplane-adapter.ts +1 -1
- package/src/workspace/index.ts +1 -1
- package/src/workspace/strategies/index.ts +18 -0
- package/src/workspace/strategies/optimistic.ts +136 -0
- package/src/workspace/strategies/queue.ts +81 -0
- package/src/workspace/strategies/registry.ts +89 -0
- package/src/workspace/strategies/trunk.ts +123 -0
- package/src/workspace/strategies/types.ts +145 -0
- package/src/workspace/types.ts +1 -1
- package/src/workspace/workspace-manager.ts +1 -1
- package/.claude/settings.local.json +0 -59
- package/dist/map/utils/address-translation.d.ts +0 -99
- package/dist/map/utils/address-translation.d.ts.map +0 -1
- package/dist/map/utils/address-translation.js +0 -285
- package/dist/map/utils/address-translation.js.map +0 -1
- package/dist/map/utils/index.d.ts +0 -7
- package/dist/map/utils/index.d.ts.map +0 -1
- package/dist/map/utils/index.js +0 -7
- package/dist/map/utils/index.js.map +0 -1
- package/references/acp-factory-ref/CHANGELOG.md +0 -33
- package/references/acp-factory-ref/LICENSE +0 -21
- package/references/acp-factory-ref/README.md +0 -341
- package/references/acp-factory-ref/package-lock.json +0 -3102
- package/references/acp-factory-ref/package.json +0 -96
- package/references/acp-factory-ref/python/CHANGELOG.md +0 -33
- package/references/acp-factory-ref/python/LICENSE +0 -21
- package/references/acp-factory-ref/python/Makefile +0 -57
- package/references/acp-factory-ref/python/README.md +0 -253
- package/references/acp-factory-ref/python/pyproject.toml +0 -73
- package/references/acp-factory-ref/python/tests/__init__.py +0 -0
- package/references/acp-factory-ref/python/tests/e2e/__init__.py +0 -1
- package/references/acp-factory-ref/python/tests/e2e/test_codex_e2e.py +0 -349
- package/references/acp-factory-ref/python/tests/e2e/test_gemini_e2e.py +0 -165
- package/references/acp-factory-ref/python/tests/e2e/test_opencode_e2e.py +0 -296
- package/references/acp-factory-ref/python/tests/test_client_handler.py +0 -543
- package/references/acp-factory-ref/python/tests/test_pushable.py +0 -199
- package/references/claude-code-acp/.github/workflows/ci.yml +0 -45
- package/references/claude-code-acp/.github/workflows/publish.yml +0 -34
- package/references/claude-code-acp/.prettierrc.json +0 -4
- package/references/claude-code-acp/CHANGELOG.md +0 -249
- package/references/claude-code-acp/LICENSE +0 -222
- package/references/claude-code-acp/README.md +0 -53
- package/references/claude-code-acp/docs/RELEASES.md +0 -24
- package/references/claude-code-acp/eslint.config.js +0 -48
- package/references/claude-code-acp/package-lock.json +0 -4570
- package/references/claude-code-acp/package.json +0 -88
- package/references/claude-code-acp/scripts/release.sh +0 -119
- package/references/claude-code-acp/src/acp-agent.ts +0 -2065
- package/references/claude-code-acp/src/index.ts +0 -26
- package/references/claude-code-acp/src/lib.ts +0 -38
- package/references/claude-code-acp/src/mcp-server.ts +0 -911
- package/references/claude-code-acp/src/settings.ts +0 -522
- package/references/claude-code-acp/src/tests/.claude/commands/quick-math.md +0 -5
- package/references/claude-code-acp/src/tests/.claude/commands/say-hello.md +0 -6
- package/references/claude-code-acp/src/tests/acp-agent-fork.test.ts +0 -479
- package/references/claude-code-acp/src/tests/acp-agent.test.ts +0 -1502
- package/references/claude-code-acp/src/tests/extract-lines.test.ts +0 -103
- package/references/claude-code-acp/src/tests/fork-session.test.ts +0 -335
- package/references/claude-code-acp/src/tests/replace-and-calculate-location.test.ts +0 -334
- package/references/claude-code-acp/src/tests/settings.test.ts +0 -617
- package/references/claude-code-acp/src/tests/skills-options.test.ts +0 -187
- package/references/claude-code-acp/src/tests/tools.test.ts +0 -318
- package/references/claude-code-acp/src/tests/typescript-declarations.test.ts +0 -558
- package/references/claude-code-acp/src/tools.ts +0 -819
- package/references/claude-code-acp/src/utils.ts +0 -171
- package/references/claude-code-acp/tsconfig.json +0 -18
- package/references/claude-code-acp/vitest.config.ts +0 -19
- package/references/multi-agent-protocol/.sudocode/issues.jsonl +0 -111
- package/references/multi-agent-protocol/.sudocode/specs.jsonl +0 -13
- package/references/multi-agent-protocol/LICENSE +0 -21
- package/references/multi-agent-protocol/README.md +0 -113
- package/references/multi-agent-protocol/docs/00-design-specification.md +0 -496
- package/references/multi-agent-protocol/docs/01-open-questions.md +0 -1050
- package/references/multi-agent-protocol/docs/02-wire-protocol.md +0 -296
- package/references/multi-agent-protocol/docs/03-streaming-semantics.md +0 -252
- package/references/multi-agent-protocol/docs/04-error-handling.md +0 -231
- package/references/multi-agent-protocol/docs/05-connection-model.md +0 -244
- package/references/multi-agent-protocol/docs/06-visibility-permissions.md +0 -243
- package/references/multi-agent-protocol/docs/07-federation.md +0 -259
- package/references/multi-agent-protocol/docs/08-macro-agent-migration.md +0 -253
- package/references/multi-agent-protocol/docs/09-authentication.md +0 -680
- package/references/multi-agent-protocol/docs/10-mail-protocol.md +0 -553
- package/references/multi-agent-protocol/docs/agent-iam-integration.md +0 -877
- package/references/multi-agent-protocol/docs/agentic-mesh-integration-draft.md +0 -459
- package/references/multi-agent-protocol/docs/git-transport-draft.md +0 -251
- package/references/multi-agent-protocol/docs-site/Gemfile +0 -22
- package/references/multi-agent-protocol/docs-site/README.md +0 -82
- package/references/multi-agent-protocol/docs-site/_config.yml +0 -91
- package/references/multi-agent-protocol/docs-site/_includes/head_custom.html +0 -20
- package/references/multi-agent-protocol/docs-site/_sass/color_schemes/map.scss +0 -42
- package/references/multi-agent-protocol/docs-site/_sass/custom/custom.scss +0 -34
- package/references/multi-agent-protocol/docs-site/examples/full-integration.md +0 -510
- package/references/multi-agent-protocol/docs-site/examples/index.md +0 -138
- package/references/multi-agent-protocol/docs-site/examples/simple-chat.md +0 -282
- package/references/multi-agent-protocol/docs-site/examples/task-queue.md +0 -399
- package/references/multi-agent-protocol/docs-site/getting-started/index.md +0 -98
- package/references/multi-agent-protocol/docs-site/getting-started/installation.md +0 -219
- package/references/multi-agent-protocol/docs-site/getting-started/overview.md +0 -172
- package/references/multi-agent-protocol/docs-site/getting-started/quickstart.md +0 -237
- package/references/multi-agent-protocol/docs-site/index.md +0 -136
- package/references/multi-agent-protocol/docs-site/protocol/authentication.md +0 -391
- package/references/multi-agent-protocol/docs-site/protocol/connection-model.md +0 -376
- package/references/multi-agent-protocol/docs-site/protocol/design.md +0 -284
- package/references/multi-agent-protocol/docs-site/protocol/error-handling.md +0 -312
- package/references/multi-agent-protocol/docs-site/protocol/federation.md +0 -449
- package/references/multi-agent-protocol/docs-site/protocol/index.md +0 -129
- package/references/multi-agent-protocol/docs-site/protocol/permissions.md +0 -398
- package/references/multi-agent-protocol/docs-site/protocol/streaming.md +0 -353
- package/references/multi-agent-protocol/docs-site/protocol/wire-protocol.md +0 -369
- package/references/multi-agent-protocol/docs-site/sdk/api/agent.md +0 -357
- package/references/multi-agent-protocol/docs-site/sdk/api/client.md +0 -380
- package/references/multi-agent-protocol/docs-site/sdk/api/index.md +0 -62
- package/references/multi-agent-protocol/docs-site/sdk/api/server.md +0 -453
- package/references/multi-agent-protocol/docs-site/sdk/api/types.md +0 -468
- package/references/multi-agent-protocol/docs-site/sdk/guides/agent.md +0 -375
- package/references/multi-agent-protocol/docs-site/sdk/guides/authentication.md +0 -405
- package/references/multi-agent-protocol/docs-site/sdk/guides/client.md +0 -352
- package/references/multi-agent-protocol/docs-site/sdk/guides/index.md +0 -89
- package/references/multi-agent-protocol/docs-site/sdk/guides/server.md +0 -360
- package/references/multi-agent-protocol/docs-site/sdk/guides/testing.md +0 -446
- package/references/multi-agent-protocol/docs-site/sdk/guides/transports.md +0 -363
- package/references/multi-agent-protocol/docs-site/sdk/index.md +0 -206
- package/references/multi-agent-protocol/package-lock.json +0 -3886
- package/references/multi-agent-protocol/package.json +0 -56
- package/references/multi-agent-protocol/schema/meta.json +0 -467
- package/references/multi-agent-protocol/schema/schema.json +0 -2558
|
@@ -1,1502 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, beforeAll, afterAll, beforeEach, afterEach } from "vitest";
|
|
2
|
-
import { spawn, spawnSync } from "child_process";
|
|
3
|
-
import {
|
|
4
|
-
Agent,
|
|
5
|
-
AgentSideConnection,
|
|
6
|
-
AvailableCommand,
|
|
7
|
-
Client,
|
|
8
|
-
ClientSideConnection,
|
|
9
|
-
ndJsonStream,
|
|
10
|
-
NewSessionResponse,
|
|
11
|
-
ReadTextFileRequest,
|
|
12
|
-
ReadTextFileResponse,
|
|
13
|
-
RequestPermissionRequest,
|
|
14
|
-
RequestPermissionResponse,
|
|
15
|
-
SessionNotification,
|
|
16
|
-
WriteTextFileRequest,
|
|
17
|
-
WriteTextFileResponse,
|
|
18
|
-
} from "@agentclientprotocol/sdk";
|
|
19
|
-
import { nodeToWebWritable, nodeToWebReadable } from "../utils.js";
|
|
20
|
-
import { markdownEscape, toolInfoFromToolUse, toolUpdateFromToolResult } from "../tools.js";
|
|
21
|
-
import { toAcpNotifications, promptToClaude } from "../acp-agent.js";
|
|
22
|
-
import { query, SDKAssistantMessage } from "@anthropic-ai/claude-agent-sdk";
|
|
23
|
-
import { randomUUID } from "crypto";
|
|
24
|
-
import type {
|
|
25
|
-
BetaToolResultBlockParam,
|
|
26
|
-
BetaToolSearchToolResultBlockParam,
|
|
27
|
-
BetaWebSearchToolResultBlockParam,
|
|
28
|
-
BetaWebFetchToolResultBlockParam,
|
|
29
|
-
BetaCodeExecutionToolResultBlockParam,
|
|
30
|
-
} from "@anthropic-ai/sdk/resources/beta.mjs";
|
|
31
|
-
|
|
32
|
-
describe.skipIf(!process.env.RUN_INTEGRATION_TESTS)("ACP subprocess integration", () => {
|
|
33
|
-
let child: ReturnType<typeof spawn>;
|
|
34
|
-
|
|
35
|
-
beforeAll(async () => {
|
|
36
|
-
const valid = spawnSync("tsc", { stdio: "inherit" });
|
|
37
|
-
if (valid.status) {
|
|
38
|
-
throw new Error("failed to compile");
|
|
39
|
-
}
|
|
40
|
-
// Start the subprocess
|
|
41
|
-
child = spawn("npm", ["run", "--silent", "dev"], {
|
|
42
|
-
stdio: ["pipe", "pipe", "inherit"],
|
|
43
|
-
env: process.env,
|
|
44
|
-
});
|
|
45
|
-
child.on("error", (error) => {
|
|
46
|
-
console.error("Error starting subprocess:", error);
|
|
47
|
-
});
|
|
48
|
-
child.on("exit", (exit) => {
|
|
49
|
-
console.error("Exited with", exit);
|
|
50
|
-
});
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
afterAll(() => {
|
|
54
|
-
child.kill();
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
class TestClient implements Client {
|
|
58
|
-
agent: Agent;
|
|
59
|
-
files: Map<string, string> = new Map();
|
|
60
|
-
receivedText: string = "";
|
|
61
|
-
resolveAvailableCommands: (commands: AvailableCommand[]) => void;
|
|
62
|
-
availableCommandsPromise: Promise<AvailableCommand[]>;
|
|
63
|
-
|
|
64
|
-
constructor(agent: Agent) {
|
|
65
|
-
this.agent = agent;
|
|
66
|
-
this.resolveAvailableCommands = () => {};
|
|
67
|
-
this.availableCommandsPromise = new Promise((resolve) => {
|
|
68
|
-
this.resolveAvailableCommands = resolve;
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
takeReceivedText() {
|
|
73
|
-
const text = this.receivedText;
|
|
74
|
-
this.receivedText = "";
|
|
75
|
-
return text;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
async requestPermission(params: RequestPermissionRequest): Promise<RequestPermissionResponse> {
|
|
79
|
-
const optionId = params.options.find((p) => p.kind === "allow_once")!.optionId;
|
|
80
|
-
|
|
81
|
-
return { outcome: { outcome: "selected", optionId } };
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
async sessionUpdate(params: SessionNotification): Promise<void> {
|
|
85
|
-
console.error("RECEIVED", JSON.stringify(params, null, 4));
|
|
86
|
-
|
|
87
|
-
switch (params.update.sessionUpdate) {
|
|
88
|
-
case "agent_message_chunk": {
|
|
89
|
-
if (params.update.content.type === "text") {
|
|
90
|
-
this.receivedText += params.update.content.text;
|
|
91
|
-
}
|
|
92
|
-
break;
|
|
93
|
-
}
|
|
94
|
-
case "available_commands_update":
|
|
95
|
-
this.resolveAvailableCommands(params.update.availableCommands);
|
|
96
|
-
break;
|
|
97
|
-
default:
|
|
98
|
-
break;
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
async writeTextFile(params: WriteTextFileRequest): Promise<WriteTextFileResponse> {
|
|
103
|
-
this.files.set(params.path, params.content);
|
|
104
|
-
return {};
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
async readTextFile(params: ReadTextFileRequest): Promise<ReadTextFileResponse> {
|
|
108
|
-
const content = this.files.get(params.path) ?? "";
|
|
109
|
-
return {
|
|
110
|
-
content,
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
async function setupTestSession(cwd: string): Promise<{
|
|
116
|
-
client: TestClient;
|
|
117
|
-
connection: ClientSideConnection;
|
|
118
|
-
newSessionResponse: NewSessionResponse;
|
|
119
|
-
}> {
|
|
120
|
-
let client;
|
|
121
|
-
const input = nodeToWebWritable(child.stdin!);
|
|
122
|
-
const output = nodeToWebReadable(child.stdout!);
|
|
123
|
-
const stream = ndJsonStream(input, output);
|
|
124
|
-
const connection = new ClientSideConnection((agent) => {
|
|
125
|
-
client = new TestClient(agent);
|
|
126
|
-
return client;
|
|
127
|
-
}, stream);
|
|
128
|
-
|
|
129
|
-
await connection.initialize({
|
|
130
|
-
protocolVersion: 1,
|
|
131
|
-
clientCapabilities: {
|
|
132
|
-
fs: {
|
|
133
|
-
readTextFile: true,
|
|
134
|
-
writeTextFile: true,
|
|
135
|
-
},
|
|
136
|
-
},
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
const newSessionResponse = await connection.newSession({
|
|
140
|
-
cwd,
|
|
141
|
-
mcpServers: [],
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
return { client: client!, connection, newSessionResponse };
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
it("should connect to the ACP subprocess", async () => {
|
|
148
|
-
const { client, connection, newSessionResponse } = await setupTestSession("./");
|
|
149
|
-
|
|
150
|
-
await connection.prompt({
|
|
151
|
-
prompt: [
|
|
152
|
-
{
|
|
153
|
-
type: "text",
|
|
154
|
-
text: "Hello",
|
|
155
|
-
},
|
|
156
|
-
],
|
|
157
|
-
sessionId: newSessionResponse.sessionId,
|
|
158
|
-
});
|
|
159
|
-
|
|
160
|
-
expect(client.takeReceivedText()).not.toEqual("");
|
|
161
|
-
}, 30000);
|
|
162
|
-
|
|
163
|
-
it("should include available commands", async () => {
|
|
164
|
-
const { client, connection, newSessionResponse } = await setupTestSession(__dirname);
|
|
165
|
-
|
|
166
|
-
const commands = await client.availableCommandsPromise;
|
|
167
|
-
|
|
168
|
-
expect(commands).toContainEqual({
|
|
169
|
-
name: "quick-math",
|
|
170
|
-
description: "10 * 3 = 30 (project)",
|
|
171
|
-
input: null,
|
|
172
|
-
});
|
|
173
|
-
expect(commands).toContainEqual({
|
|
174
|
-
name: "say-hello",
|
|
175
|
-
description: "Say hello (project)",
|
|
176
|
-
input: { hint: "name" },
|
|
177
|
-
});
|
|
178
|
-
|
|
179
|
-
await connection.prompt({
|
|
180
|
-
prompt: [
|
|
181
|
-
{
|
|
182
|
-
type: "text",
|
|
183
|
-
text: "/quick-math",
|
|
184
|
-
},
|
|
185
|
-
],
|
|
186
|
-
sessionId: newSessionResponse.sessionId,
|
|
187
|
-
});
|
|
188
|
-
|
|
189
|
-
expect(client.takeReceivedText()).toContain("30");
|
|
190
|
-
|
|
191
|
-
await connection.prompt({
|
|
192
|
-
prompt: [
|
|
193
|
-
{
|
|
194
|
-
type: "text",
|
|
195
|
-
text: "/say-hello GPT-5",
|
|
196
|
-
},
|
|
197
|
-
],
|
|
198
|
-
sessionId: newSessionResponse.sessionId,
|
|
199
|
-
});
|
|
200
|
-
|
|
201
|
-
expect(client.takeReceivedText()).toContain("Hello GPT-5");
|
|
202
|
-
}, 30000);
|
|
203
|
-
|
|
204
|
-
it("/compact works", async () => {
|
|
205
|
-
const { client, connection, newSessionResponse } = await setupTestSession(__dirname);
|
|
206
|
-
|
|
207
|
-
const commands = await client.availableCommandsPromise;
|
|
208
|
-
|
|
209
|
-
expect(commands).toContainEqual({
|
|
210
|
-
description:
|
|
211
|
-
"Clear conversation history but keep a summary in context. Optional: /compact [instructions for summarization]",
|
|
212
|
-
input: {
|
|
213
|
-
hint: "<optional custom summarization instructions>",
|
|
214
|
-
},
|
|
215
|
-
name: "compact",
|
|
216
|
-
});
|
|
217
|
-
|
|
218
|
-
// Error case (no previous message)
|
|
219
|
-
await connection.prompt({
|
|
220
|
-
prompt: [{ type: "text", text: "/compact" }],
|
|
221
|
-
sessionId: newSessionResponse.sessionId,
|
|
222
|
-
});
|
|
223
|
-
|
|
224
|
-
expect(client.takeReceivedText()).toBe("");
|
|
225
|
-
|
|
226
|
-
// Send something
|
|
227
|
-
await connection.prompt({
|
|
228
|
-
prompt: [{ type: "text", text: "Hi" }],
|
|
229
|
-
sessionId: newSessionResponse.sessionId,
|
|
230
|
-
});
|
|
231
|
-
// Clear response
|
|
232
|
-
client.takeReceivedText();
|
|
233
|
-
|
|
234
|
-
// Test with instruction
|
|
235
|
-
await connection.prompt({
|
|
236
|
-
prompt: [
|
|
237
|
-
{
|
|
238
|
-
type: "text",
|
|
239
|
-
text: "/compact greeting",
|
|
240
|
-
},
|
|
241
|
-
],
|
|
242
|
-
sessionId: newSessionResponse.sessionId,
|
|
243
|
-
});
|
|
244
|
-
|
|
245
|
-
expect(client.takeReceivedText()).toContain("");
|
|
246
|
-
}, 120000);
|
|
247
|
-
});
|
|
248
|
-
|
|
249
|
-
describe("tool conversions", () => {
|
|
250
|
-
it("should handle Bash nicely", () => {
|
|
251
|
-
const tool_use = {
|
|
252
|
-
type: "tool_use",
|
|
253
|
-
id: "toolu_01VtsS2mxUFwpBJZYd7BmbC9",
|
|
254
|
-
name: "Bash",
|
|
255
|
-
input: {
|
|
256
|
-
command: "rm README.md.rm",
|
|
257
|
-
description: "Delete README.md.rm file",
|
|
258
|
-
},
|
|
259
|
-
};
|
|
260
|
-
|
|
261
|
-
expect(toolInfoFromToolUse(tool_use)).toStrictEqual({
|
|
262
|
-
kind: "execute",
|
|
263
|
-
title: "`rm README.md.rm`",
|
|
264
|
-
content: [
|
|
265
|
-
{
|
|
266
|
-
content: {
|
|
267
|
-
text: "Delete README.md.rm file",
|
|
268
|
-
type: "text",
|
|
269
|
-
},
|
|
270
|
-
type: "content",
|
|
271
|
-
},
|
|
272
|
-
],
|
|
273
|
-
});
|
|
274
|
-
});
|
|
275
|
-
|
|
276
|
-
it("should handle Glob nicely", () => {
|
|
277
|
-
const tool_use = {
|
|
278
|
-
type: "tool_use",
|
|
279
|
-
id: "toolu_01VtsS2mxUFwpBJZYd7BmbC9",
|
|
280
|
-
name: "Glob",
|
|
281
|
-
input: {
|
|
282
|
-
pattern: "*/**.ts",
|
|
283
|
-
},
|
|
284
|
-
};
|
|
285
|
-
|
|
286
|
-
expect(toolInfoFromToolUse(tool_use)).toStrictEqual({
|
|
287
|
-
kind: "search",
|
|
288
|
-
title: "Find `*/**.ts`",
|
|
289
|
-
content: [],
|
|
290
|
-
locations: [],
|
|
291
|
-
});
|
|
292
|
-
});
|
|
293
|
-
|
|
294
|
-
it("should handle Task tool calls", () => {
|
|
295
|
-
const tool_use = {
|
|
296
|
-
type: "tool_use",
|
|
297
|
-
id: "toolu_01ANYHYDsXcDPKgxhg7us9bj",
|
|
298
|
-
name: "Task",
|
|
299
|
-
input: {
|
|
300
|
-
description: "Handle user's work request",
|
|
301
|
-
prompt:
|
|
302
|
-
'The user has asked me to "Create a Task to do the work!" but hasn\'t specified what specific work they want done. I need to:\n\n1. First understand what work needs to be done by examining the current state of the repository\n2. Look at the git status to see what files have been modified\n3. Check if there are any obvious tasks that need completion based on the current state\n4. If the work isn\'t clear from the context, ask the user to specify what work they want accomplished\n\nThe git status shows: "M src/tests/acp-agent.test.ts" - there\'s a modified test file that might need attention.\n\nPlease examine the repository state and determine what work needs to be done, then either complete it or ask the user for clarification on the specific task they want accomplished.',
|
|
303
|
-
subagent_type: "general-purpose",
|
|
304
|
-
},
|
|
305
|
-
};
|
|
306
|
-
|
|
307
|
-
expect(toolInfoFromToolUse(tool_use)).toStrictEqual({
|
|
308
|
-
kind: "think",
|
|
309
|
-
title: "Handle user's work request",
|
|
310
|
-
content: [
|
|
311
|
-
{
|
|
312
|
-
content: {
|
|
313
|
-
text: 'The user has asked me to "Create a Task to do the work!" but hasn\'t specified what specific work they want done. I need to:\n\n1. First understand what work needs to be done by examining the current state of the repository\n2. Look at the git status to see what files have been modified\n3. Check if there are any obvious tasks that need completion based on the current state\n4. If the work isn\'t clear from the context, ask the user to specify what work they want accomplished\n\nThe git status shows: "M src/tests/acp-agent.test.ts" - there\'s a modified test file that might need attention.\n\nPlease examine the repository state and determine what work needs to be done, then either complete it or ask the user for clarification on the specific task they want accomplished.',
|
|
314
|
-
type: "text",
|
|
315
|
-
},
|
|
316
|
-
type: "content",
|
|
317
|
-
},
|
|
318
|
-
],
|
|
319
|
-
});
|
|
320
|
-
});
|
|
321
|
-
|
|
322
|
-
it("should handle LS tool calls", () => {
|
|
323
|
-
const tool_use = {
|
|
324
|
-
type: "tool_use",
|
|
325
|
-
id: "toolu_01EEqsX7Eb9hpx87KAHVPTey",
|
|
326
|
-
name: "LS",
|
|
327
|
-
input: {
|
|
328
|
-
path: "/Users/test/github/claude-code-acp",
|
|
329
|
-
},
|
|
330
|
-
};
|
|
331
|
-
|
|
332
|
-
expect(toolInfoFromToolUse(tool_use)).toStrictEqual({
|
|
333
|
-
kind: "search",
|
|
334
|
-
title: "List the `/Users/test/github/claude-code-acp` directory's contents",
|
|
335
|
-
content: [],
|
|
336
|
-
locations: [],
|
|
337
|
-
});
|
|
338
|
-
});
|
|
339
|
-
|
|
340
|
-
it("should handle Grep tool calls", () => {
|
|
341
|
-
const tool_use = {
|
|
342
|
-
type: "tool_use",
|
|
343
|
-
id: "toolu_016j8oGSD3eAZ9KT62Y7Jsjb",
|
|
344
|
-
name: "Grep",
|
|
345
|
-
input: {
|
|
346
|
-
pattern: ".*",
|
|
347
|
-
},
|
|
348
|
-
};
|
|
349
|
-
|
|
350
|
-
expect(toolInfoFromToolUse(tool_use)).toStrictEqual({
|
|
351
|
-
kind: "search",
|
|
352
|
-
title: 'grep ".*"',
|
|
353
|
-
content: [],
|
|
354
|
-
});
|
|
355
|
-
});
|
|
356
|
-
|
|
357
|
-
it("should handle Write tool calls", () => {
|
|
358
|
-
const tool_use = {
|
|
359
|
-
type: "tool_use",
|
|
360
|
-
id: "toolu_01ABC123XYZ789",
|
|
361
|
-
name: "Write",
|
|
362
|
-
input: {
|
|
363
|
-
file_path: "/Users/test/project/example.txt",
|
|
364
|
-
content: "Hello, World!\nThis is test content.",
|
|
365
|
-
},
|
|
366
|
-
};
|
|
367
|
-
|
|
368
|
-
expect(toolInfoFromToolUse(tool_use)).toStrictEqual({
|
|
369
|
-
kind: "edit",
|
|
370
|
-
title: "Write /Users/test/project/example.txt",
|
|
371
|
-
content: [
|
|
372
|
-
{
|
|
373
|
-
type: "diff",
|
|
374
|
-
path: "/Users/test/project/example.txt",
|
|
375
|
-
oldText: null,
|
|
376
|
-
newText: "Hello, World!\nThis is test content.",
|
|
377
|
-
},
|
|
378
|
-
],
|
|
379
|
-
locations: [{ path: "/Users/test/project/example.txt" }],
|
|
380
|
-
});
|
|
381
|
-
});
|
|
382
|
-
|
|
383
|
-
it("should handle mcp__acp__Write tool calls", () => {
|
|
384
|
-
const tool_use = {
|
|
385
|
-
type: "tool_use",
|
|
386
|
-
id: "toolu_01GHI789JKL456",
|
|
387
|
-
name: "mcp__acp__Write",
|
|
388
|
-
input: {
|
|
389
|
-
file_path: "/Users/test/project/config.json",
|
|
390
|
-
content: '{"version": "1.0.0"}',
|
|
391
|
-
},
|
|
392
|
-
};
|
|
393
|
-
|
|
394
|
-
expect(toolInfoFromToolUse(tool_use)).toStrictEqual({
|
|
395
|
-
kind: "edit",
|
|
396
|
-
title: "Write /Users/test/project/config.json",
|
|
397
|
-
content: [
|
|
398
|
-
{
|
|
399
|
-
type: "diff",
|
|
400
|
-
path: "/Users/test/project/config.json",
|
|
401
|
-
oldText: null,
|
|
402
|
-
newText: '{"version": "1.0.0"}',
|
|
403
|
-
},
|
|
404
|
-
],
|
|
405
|
-
locations: [{ path: "/Users/test/project/config.json" }],
|
|
406
|
-
});
|
|
407
|
-
});
|
|
408
|
-
|
|
409
|
-
it("should handle Read tool calls", () => {
|
|
410
|
-
const tool_use = {
|
|
411
|
-
type: "tool_use",
|
|
412
|
-
id: "toolu_01MNO456PQR789",
|
|
413
|
-
name: "Read",
|
|
414
|
-
input: {
|
|
415
|
-
file_path: "/Users/test/project/readme.md",
|
|
416
|
-
},
|
|
417
|
-
};
|
|
418
|
-
|
|
419
|
-
expect(toolInfoFromToolUse(tool_use)).toStrictEqual({
|
|
420
|
-
kind: "read",
|
|
421
|
-
title: "Read File",
|
|
422
|
-
content: [],
|
|
423
|
-
locations: [{ path: "/Users/test/project/readme.md", line: 0 }],
|
|
424
|
-
});
|
|
425
|
-
});
|
|
426
|
-
|
|
427
|
-
it("should handle mcp__acp__Read tool calls", () => {
|
|
428
|
-
const tool_use = {
|
|
429
|
-
type: "tool_use",
|
|
430
|
-
id: "toolu_01YZA789BCD123",
|
|
431
|
-
name: "mcp__acp__Read",
|
|
432
|
-
input: {
|
|
433
|
-
file_path: "/Users/test/project/data.json",
|
|
434
|
-
},
|
|
435
|
-
};
|
|
436
|
-
|
|
437
|
-
expect(toolInfoFromToolUse(tool_use)).toStrictEqual({
|
|
438
|
-
kind: "read",
|
|
439
|
-
title: "Read /Users/test/project/data.json",
|
|
440
|
-
content: [],
|
|
441
|
-
locations: [{ path: "/Users/test/project/data.json", line: 0 }],
|
|
442
|
-
});
|
|
443
|
-
});
|
|
444
|
-
|
|
445
|
-
it("should handle mcp__acp__Read with limit", () => {
|
|
446
|
-
const tool_use = {
|
|
447
|
-
type: "tool_use",
|
|
448
|
-
id: "toolu_01EFG456HIJ789",
|
|
449
|
-
name: "mcp__acp__Read",
|
|
450
|
-
input: {
|
|
451
|
-
file_path: "/Users/test/project/large.txt",
|
|
452
|
-
limit: 100,
|
|
453
|
-
},
|
|
454
|
-
};
|
|
455
|
-
|
|
456
|
-
expect(toolInfoFromToolUse(tool_use)).toStrictEqual({
|
|
457
|
-
kind: "read",
|
|
458
|
-
title: "Read /Users/test/project/large.txt (1 - 100)",
|
|
459
|
-
content: [],
|
|
460
|
-
locations: [{ path: "/Users/test/project/large.txt", line: 0 }],
|
|
461
|
-
});
|
|
462
|
-
});
|
|
463
|
-
|
|
464
|
-
it("should handle mcp__acp__Read with offset and limit", () => {
|
|
465
|
-
const tool_use = {
|
|
466
|
-
type: "tool_use",
|
|
467
|
-
id: "toolu_01KLM789NOP456",
|
|
468
|
-
name: "mcp__acp__Read",
|
|
469
|
-
input: {
|
|
470
|
-
file_path: "/Users/test/project/large.txt",
|
|
471
|
-
offset: 50,
|
|
472
|
-
limit: 100,
|
|
473
|
-
},
|
|
474
|
-
};
|
|
475
|
-
|
|
476
|
-
expect(toolInfoFromToolUse(tool_use)).toStrictEqual({
|
|
477
|
-
kind: "read",
|
|
478
|
-
title: "Read /Users/test/project/large.txt (51 - 150)",
|
|
479
|
-
content: [],
|
|
480
|
-
locations: [{ path: "/Users/test/project/large.txt", line: 50 }],
|
|
481
|
-
});
|
|
482
|
-
});
|
|
483
|
-
|
|
484
|
-
it("should handle mcp__acp__Read with only offset", () => {
|
|
485
|
-
const tool_use = {
|
|
486
|
-
type: "tool_use",
|
|
487
|
-
id: "toolu_01QRS123TUV789",
|
|
488
|
-
name: "mcp__acp__Read",
|
|
489
|
-
input: {
|
|
490
|
-
file_path: "/Users/test/project/large.txt",
|
|
491
|
-
offset: 200,
|
|
492
|
-
},
|
|
493
|
-
};
|
|
494
|
-
|
|
495
|
-
expect(toolInfoFromToolUse(tool_use)).toStrictEqual({
|
|
496
|
-
kind: "read",
|
|
497
|
-
title: "Read /Users/test/project/large.txt (from line 201)",
|
|
498
|
-
content: [],
|
|
499
|
-
locations: [{ path: "/Users/test/project/large.txt", line: 200 }],
|
|
500
|
-
});
|
|
501
|
-
});
|
|
502
|
-
|
|
503
|
-
it("should handle KillBash entries", () => {
|
|
504
|
-
const tool_use = {
|
|
505
|
-
type: "tool_use",
|
|
506
|
-
id: "toolu_01PhLms5fuvmdjy2bb6dfUKT",
|
|
507
|
-
name: "KillShell",
|
|
508
|
-
input: {
|
|
509
|
-
shell_id: "bash_1",
|
|
510
|
-
},
|
|
511
|
-
};
|
|
512
|
-
|
|
513
|
-
expect(toolInfoFromToolUse(tool_use)).toStrictEqual({
|
|
514
|
-
kind: "execute",
|
|
515
|
-
title: `Kill Process`,
|
|
516
|
-
content: [],
|
|
517
|
-
});
|
|
518
|
-
});
|
|
519
|
-
|
|
520
|
-
it("should handle BashOutput entries", () => {
|
|
521
|
-
const tool_use = {
|
|
522
|
-
type: "tool_use",
|
|
523
|
-
id: "toolu_01SJUWPtj1QspgANgtpqGPuN",
|
|
524
|
-
name: "BashOutput",
|
|
525
|
-
input: {
|
|
526
|
-
bash_id: "bash_1",
|
|
527
|
-
},
|
|
528
|
-
};
|
|
529
|
-
|
|
530
|
-
expect(toolInfoFromToolUse(tool_use)).toStrictEqual({
|
|
531
|
-
kind: "execute",
|
|
532
|
-
title: `Tail Logs`,
|
|
533
|
-
content: [],
|
|
534
|
-
});
|
|
535
|
-
});
|
|
536
|
-
|
|
537
|
-
it("should handle plan entries", () => {
|
|
538
|
-
const received: SDKAssistantMessage = {
|
|
539
|
-
type: "assistant",
|
|
540
|
-
message: {
|
|
541
|
-
id: "msg_017eNosJgww7F5qD4a8BcAcx",
|
|
542
|
-
type: "message",
|
|
543
|
-
role: "assistant",
|
|
544
|
-
container: null,
|
|
545
|
-
model: "claude-sonnet-4-20250514",
|
|
546
|
-
content: [
|
|
547
|
-
{
|
|
548
|
-
type: "tool_use",
|
|
549
|
-
id: "toolu_01HaXZ4LfdchSeSR8ygt4zyq",
|
|
550
|
-
name: "TodoWrite",
|
|
551
|
-
input: {
|
|
552
|
-
todos: [
|
|
553
|
-
{
|
|
554
|
-
content: "Analyze existing test coverage and identify gaps",
|
|
555
|
-
status: "in_progress",
|
|
556
|
-
activeForm: "Analyzing existing test coverage",
|
|
557
|
-
},
|
|
558
|
-
{
|
|
559
|
-
content: "Add comprehensive edge case tests",
|
|
560
|
-
status: "pending",
|
|
561
|
-
activeForm: "Adding comprehensive edge case tests",
|
|
562
|
-
},
|
|
563
|
-
{
|
|
564
|
-
content: "Add performance and timing tests",
|
|
565
|
-
status: "pending",
|
|
566
|
-
activeForm: "Adding performance and timing tests",
|
|
567
|
-
},
|
|
568
|
-
{
|
|
569
|
-
content: "Add error handling and panic behavior tests",
|
|
570
|
-
status: "pending",
|
|
571
|
-
activeForm: "Adding error handling tests",
|
|
572
|
-
},
|
|
573
|
-
{
|
|
574
|
-
content: "Add concurrent access and race condition tests",
|
|
575
|
-
status: "pending",
|
|
576
|
-
activeForm: "Adding concurrent access tests",
|
|
577
|
-
},
|
|
578
|
-
{
|
|
579
|
-
content: "Add tests for Each function with various data types",
|
|
580
|
-
status: "pending",
|
|
581
|
-
activeForm: "Adding Each function tests",
|
|
582
|
-
},
|
|
583
|
-
{
|
|
584
|
-
content: "Add benchmark tests for performance measurement",
|
|
585
|
-
status: "pending",
|
|
586
|
-
activeForm: "Adding benchmark tests",
|
|
587
|
-
},
|
|
588
|
-
{
|
|
589
|
-
content: "Improve test organization and helper functions",
|
|
590
|
-
status: "pending",
|
|
591
|
-
activeForm: "Improving test organization",
|
|
592
|
-
},
|
|
593
|
-
],
|
|
594
|
-
},
|
|
595
|
-
},
|
|
596
|
-
],
|
|
597
|
-
stop_reason: null,
|
|
598
|
-
stop_sequence: null,
|
|
599
|
-
usage: {
|
|
600
|
-
input_tokens: 6,
|
|
601
|
-
cache_creation_input_tokens: 326,
|
|
602
|
-
cache_read_input_tokens: 17265,
|
|
603
|
-
cache_creation: {
|
|
604
|
-
ephemeral_5m_input_tokens: 326,
|
|
605
|
-
ephemeral_1h_input_tokens: 0,
|
|
606
|
-
},
|
|
607
|
-
output_tokens: 1,
|
|
608
|
-
service_tier: "standard",
|
|
609
|
-
server_tool_use: null,
|
|
610
|
-
},
|
|
611
|
-
context_management: null,
|
|
612
|
-
},
|
|
613
|
-
parent_tool_use_id: null,
|
|
614
|
-
session_id: "d056596f-e328-41e9-badd-b07122ae5227",
|
|
615
|
-
uuid: "b7c3330c-de8f-4bba-ac53-68c7f76ffeb5",
|
|
616
|
-
};
|
|
617
|
-
expect(
|
|
618
|
-
toAcpNotifications(
|
|
619
|
-
received.message.content,
|
|
620
|
-
received.message.role,
|
|
621
|
-
"test",
|
|
622
|
-
{},
|
|
623
|
-
{} as AgentSideConnection,
|
|
624
|
-
console,
|
|
625
|
-
),
|
|
626
|
-
).toStrictEqual([
|
|
627
|
-
{
|
|
628
|
-
sessionId: "test",
|
|
629
|
-
update: {
|
|
630
|
-
sessionUpdate: "plan",
|
|
631
|
-
entries: [
|
|
632
|
-
{
|
|
633
|
-
content: "Analyze existing test coverage and identify gaps",
|
|
634
|
-
priority: "medium",
|
|
635
|
-
status: "in_progress",
|
|
636
|
-
},
|
|
637
|
-
{
|
|
638
|
-
content: "Add comprehensive edge case tests",
|
|
639
|
-
priority: "medium",
|
|
640
|
-
status: "pending",
|
|
641
|
-
},
|
|
642
|
-
{
|
|
643
|
-
content: "Add performance and timing tests",
|
|
644
|
-
priority: "medium",
|
|
645
|
-
status: "pending",
|
|
646
|
-
},
|
|
647
|
-
{
|
|
648
|
-
content: "Add error handling and panic behavior tests",
|
|
649
|
-
priority: "medium",
|
|
650
|
-
status: "pending",
|
|
651
|
-
},
|
|
652
|
-
{
|
|
653
|
-
content: "Add concurrent access and race condition tests",
|
|
654
|
-
priority: "medium",
|
|
655
|
-
status: "pending",
|
|
656
|
-
},
|
|
657
|
-
{
|
|
658
|
-
content: "Add tests for Each function with various data types",
|
|
659
|
-
priority: "medium",
|
|
660
|
-
status: "pending",
|
|
661
|
-
},
|
|
662
|
-
{
|
|
663
|
-
content: "Add benchmark tests for performance measurement",
|
|
664
|
-
priority: "medium",
|
|
665
|
-
status: "pending",
|
|
666
|
-
},
|
|
667
|
-
{
|
|
668
|
-
content: "Improve test organization and helper functions",
|
|
669
|
-
priority: "medium",
|
|
670
|
-
status: "pending",
|
|
671
|
-
},
|
|
672
|
-
],
|
|
673
|
-
},
|
|
674
|
-
},
|
|
675
|
-
]);
|
|
676
|
-
});
|
|
677
|
-
|
|
678
|
-
it("should return empty update for successful edit result", () => {
|
|
679
|
-
const toolUse = {
|
|
680
|
-
type: "tool_use",
|
|
681
|
-
id: "toolu_01MNO345",
|
|
682
|
-
name: "mcp__acp__Edit",
|
|
683
|
-
input: {
|
|
684
|
-
file_path: "/Users/test/project/test.txt",
|
|
685
|
-
old_string: "old",
|
|
686
|
-
new_string: "new",
|
|
687
|
-
},
|
|
688
|
-
};
|
|
689
|
-
|
|
690
|
-
const toolResult = {
|
|
691
|
-
content: [
|
|
692
|
-
{
|
|
693
|
-
type: "text" as const,
|
|
694
|
-
text: "not valid json",
|
|
695
|
-
},
|
|
696
|
-
],
|
|
697
|
-
tool_use_id: "test",
|
|
698
|
-
is_error: false,
|
|
699
|
-
type: "tool_result" as const,
|
|
700
|
-
};
|
|
701
|
-
|
|
702
|
-
const update = toolUpdateFromToolResult(toolResult, toolUse);
|
|
703
|
-
|
|
704
|
-
// Should return empty object when parsing fails
|
|
705
|
-
expect(update).toEqual({});
|
|
706
|
-
});
|
|
707
|
-
|
|
708
|
-
it("should return content update for edit failure", () => {
|
|
709
|
-
const toolUse = {
|
|
710
|
-
type: "tool_use",
|
|
711
|
-
id: "toolu_01MNO345",
|
|
712
|
-
name: "mcp__acp__Edit",
|
|
713
|
-
input: {
|
|
714
|
-
file_path: "/Users/test/project/test.txt",
|
|
715
|
-
old_string: "old",
|
|
716
|
-
new_string: "new",
|
|
717
|
-
},
|
|
718
|
-
};
|
|
719
|
-
|
|
720
|
-
const toolResult = {
|
|
721
|
-
content: [
|
|
722
|
-
{
|
|
723
|
-
type: "text" as const,
|
|
724
|
-
text: "Failed to find `old_string`",
|
|
725
|
-
},
|
|
726
|
-
],
|
|
727
|
-
tool_use_id: "test",
|
|
728
|
-
is_error: true,
|
|
729
|
-
type: "tool_result" as const,
|
|
730
|
-
};
|
|
731
|
-
|
|
732
|
-
const update = toolUpdateFromToolResult(toolResult, toolUse);
|
|
733
|
-
|
|
734
|
-
// Should return empty object when parsing fails
|
|
735
|
-
expect(update).toEqual({
|
|
736
|
-
content: [
|
|
737
|
-
{
|
|
738
|
-
content: { type: "text", text: "```\nFailed to find `old_string`\n```" },
|
|
739
|
-
type: "content",
|
|
740
|
-
},
|
|
741
|
-
],
|
|
742
|
-
});
|
|
743
|
-
});
|
|
744
|
-
|
|
745
|
-
it("should transform tool_reference content to valid ACP content", () => {
|
|
746
|
-
const toolUse = {
|
|
747
|
-
type: "tool_use",
|
|
748
|
-
id: "toolu_01MNO345",
|
|
749
|
-
name: "ToolSearch",
|
|
750
|
-
input: { query: "test" },
|
|
751
|
-
};
|
|
752
|
-
|
|
753
|
-
const toolResult: BetaToolResultBlockParam = {
|
|
754
|
-
content: [
|
|
755
|
-
{
|
|
756
|
-
type: "tool_reference",
|
|
757
|
-
tool_name: "some_discovered_tool",
|
|
758
|
-
},
|
|
759
|
-
],
|
|
760
|
-
tool_use_id: "toolu_01MNO345",
|
|
761
|
-
is_error: false,
|
|
762
|
-
type: "tool_result",
|
|
763
|
-
};
|
|
764
|
-
|
|
765
|
-
const update = toolUpdateFromToolResult(toolResult, toolUse);
|
|
766
|
-
|
|
767
|
-
expect(update).toEqual({
|
|
768
|
-
content: [
|
|
769
|
-
{
|
|
770
|
-
type: "content",
|
|
771
|
-
content: { type: "text", text: "Tool: some_discovered_tool" },
|
|
772
|
-
},
|
|
773
|
-
],
|
|
774
|
-
});
|
|
775
|
-
});
|
|
776
|
-
|
|
777
|
-
it("should transform web_search_result content to valid ACP content", () => {
|
|
778
|
-
const toolUse = {
|
|
779
|
-
type: "tool_use",
|
|
780
|
-
id: "toolu_01MNO345",
|
|
781
|
-
name: "WebSearch",
|
|
782
|
-
input: { query: "test" },
|
|
783
|
-
};
|
|
784
|
-
|
|
785
|
-
const toolResult: BetaWebSearchToolResultBlockParam = {
|
|
786
|
-
content: [
|
|
787
|
-
{
|
|
788
|
-
type: "web_search_result",
|
|
789
|
-
title: "Test Result",
|
|
790
|
-
url: "https://example.com",
|
|
791
|
-
encrypted_content: "...",
|
|
792
|
-
page_age: null,
|
|
793
|
-
},
|
|
794
|
-
],
|
|
795
|
-
tool_use_id: "toolu_01MNO345",
|
|
796
|
-
type: "web_search_tool_result",
|
|
797
|
-
};
|
|
798
|
-
|
|
799
|
-
const update = toolUpdateFromToolResult(toolResult, toolUse);
|
|
800
|
-
|
|
801
|
-
expect(update).toEqual({
|
|
802
|
-
content: [
|
|
803
|
-
{
|
|
804
|
-
type: "content",
|
|
805
|
-
content: { type: "text", text: "Test Result (https://example.com)" },
|
|
806
|
-
},
|
|
807
|
-
],
|
|
808
|
-
});
|
|
809
|
-
});
|
|
810
|
-
|
|
811
|
-
it("should transform web_search_tool_result_error to valid ACP content", () => {
|
|
812
|
-
const toolUse = {
|
|
813
|
-
type: "tool_use",
|
|
814
|
-
id: "toolu_01MNO345",
|
|
815
|
-
name: "WebSearch",
|
|
816
|
-
input: { query: "test" },
|
|
817
|
-
};
|
|
818
|
-
|
|
819
|
-
const toolResult: BetaWebSearchToolResultBlockParam = {
|
|
820
|
-
content: {
|
|
821
|
-
type: "web_search_tool_result_error",
|
|
822
|
-
error_code: "unavailable",
|
|
823
|
-
},
|
|
824
|
-
tool_use_id: "toolu_01MNO345",
|
|
825
|
-
type: "web_search_tool_result",
|
|
826
|
-
};
|
|
827
|
-
|
|
828
|
-
const update = toolUpdateFromToolResult(toolResult, toolUse);
|
|
829
|
-
|
|
830
|
-
expect(update).toEqual({
|
|
831
|
-
content: [
|
|
832
|
-
{
|
|
833
|
-
type: "content",
|
|
834
|
-
content: { type: "text", text: "Error: unavailable" },
|
|
835
|
-
},
|
|
836
|
-
],
|
|
837
|
-
});
|
|
838
|
-
});
|
|
839
|
-
|
|
840
|
-
it("should transform code_execution_result content to valid ACP content", () => {
|
|
841
|
-
const toolUse = {
|
|
842
|
-
type: "tool_use",
|
|
843
|
-
id: "toolu_01MNO345",
|
|
844
|
-
name: "CodeExecution",
|
|
845
|
-
input: {},
|
|
846
|
-
};
|
|
847
|
-
|
|
848
|
-
const toolResult: BetaCodeExecutionToolResultBlockParam = {
|
|
849
|
-
content: {
|
|
850
|
-
type: "code_execution_result",
|
|
851
|
-
stdout: "Hello World",
|
|
852
|
-
stderr: "",
|
|
853
|
-
return_code: 0,
|
|
854
|
-
content: [],
|
|
855
|
-
},
|
|
856
|
-
tool_use_id: "toolu_01MNO345",
|
|
857
|
-
type: "code_execution_tool_result",
|
|
858
|
-
};
|
|
859
|
-
|
|
860
|
-
const update = toolUpdateFromToolResult(toolResult, toolUse);
|
|
861
|
-
|
|
862
|
-
expect(update).toEqual({
|
|
863
|
-
content: [
|
|
864
|
-
{
|
|
865
|
-
type: "content",
|
|
866
|
-
content: { type: "text", text: "Output: Hello World" },
|
|
867
|
-
},
|
|
868
|
-
],
|
|
869
|
-
});
|
|
870
|
-
});
|
|
871
|
-
|
|
872
|
-
it("should transform web_fetch_result content to valid ACP content", () => {
|
|
873
|
-
const toolUse = {
|
|
874
|
-
type: "tool_use",
|
|
875
|
-
id: "toolu_01MNO345",
|
|
876
|
-
name: "WebFetch",
|
|
877
|
-
input: { url: "https://example.com" },
|
|
878
|
-
};
|
|
879
|
-
|
|
880
|
-
const toolResult: BetaWebFetchToolResultBlockParam = {
|
|
881
|
-
content: {
|
|
882
|
-
type: "web_fetch_result",
|
|
883
|
-
url: "https://example.com",
|
|
884
|
-
content: {
|
|
885
|
-
type: "document",
|
|
886
|
-
citations: null,
|
|
887
|
-
title: null,
|
|
888
|
-
source: { type: "text", media_type: "text/plain", data: "Page content here" },
|
|
889
|
-
},
|
|
890
|
-
},
|
|
891
|
-
tool_use_id: "toolu_01MNO345",
|
|
892
|
-
type: "web_fetch_tool_result",
|
|
893
|
-
};
|
|
894
|
-
|
|
895
|
-
const update = toolUpdateFromToolResult(toolResult, toolUse);
|
|
896
|
-
|
|
897
|
-
expect(update).toEqual({
|
|
898
|
-
content: [
|
|
899
|
-
{
|
|
900
|
-
type: "content",
|
|
901
|
-
content: { type: "text", text: "Fetched: https://example.com" },
|
|
902
|
-
},
|
|
903
|
-
],
|
|
904
|
-
});
|
|
905
|
-
});
|
|
906
|
-
|
|
907
|
-
it("should transform tool_search_tool_search_result to valid ACP content", () => {
|
|
908
|
-
const toolUse = {
|
|
909
|
-
type: "tool_use",
|
|
910
|
-
id: "toolu_01MNO345",
|
|
911
|
-
name: "ToolSearch",
|
|
912
|
-
input: { query: "test" },
|
|
913
|
-
};
|
|
914
|
-
|
|
915
|
-
const toolResult: BetaToolSearchToolResultBlockParam = {
|
|
916
|
-
content: {
|
|
917
|
-
type: "tool_search_tool_search_result",
|
|
918
|
-
tool_references: [
|
|
919
|
-
{ type: "tool_reference", tool_name: "tool_a" },
|
|
920
|
-
{ type: "tool_reference", tool_name: "tool_b" },
|
|
921
|
-
],
|
|
922
|
-
},
|
|
923
|
-
tool_use_id: "toolu_01MNO345",
|
|
924
|
-
type: "tool_search_tool_result",
|
|
925
|
-
};
|
|
926
|
-
|
|
927
|
-
const update = toolUpdateFromToolResult(toolResult, toolUse);
|
|
928
|
-
|
|
929
|
-
expect(update).toEqual({
|
|
930
|
-
content: [
|
|
931
|
-
{
|
|
932
|
-
type: "content",
|
|
933
|
-
content: { type: "text", text: "Tools found: tool_a, tool_b" },
|
|
934
|
-
},
|
|
935
|
-
],
|
|
936
|
-
});
|
|
937
|
-
});
|
|
938
|
-
});
|
|
939
|
-
|
|
940
|
-
describe("escape markdown", () => {
|
|
941
|
-
it("should escape markdown characters", () => {
|
|
942
|
-
let text = "Hello *world*!";
|
|
943
|
-
let escaped = markdownEscape(text);
|
|
944
|
-
expect(escaped).toEqual("```\nHello *world*!\n```");
|
|
945
|
-
|
|
946
|
-
text = "for example:\n```markdown\nHello *world*!\n```\n";
|
|
947
|
-
escaped = markdownEscape(text);
|
|
948
|
-
expect(escaped).toEqual("````\nfor example:\n```markdown\nHello *world*!\n```\n````");
|
|
949
|
-
});
|
|
950
|
-
});
|
|
951
|
-
|
|
952
|
-
describe("prompt conversion", () => {
|
|
953
|
-
it("should not change built-in slash commands", () => {
|
|
954
|
-
const message = promptToClaude({
|
|
955
|
-
sessionId: "test",
|
|
956
|
-
prompt: [
|
|
957
|
-
{
|
|
958
|
-
type: "text",
|
|
959
|
-
text: "/compact args",
|
|
960
|
-
},
|
|
961
|
-
],
|
|
962
|
-
});
|
|
963
|
-
expect(message.message.content).toEqual([
|
|
964
|
-
{
|
|
965
|
-
text: "/compact args",
|
|
966
|
-
type: "text",
|
|
967
|
-
},
|
|
968
|
-
]);
|
|
969
|
-
});
|
|
970
|
-
|
|
971
|
-
it("should remove MCP prefix from MCP slash commands", () => {
|
|
972
|
-
const message = promptToClaude({
|
|
973
|
-
sessionId: "test",
|
|
974
|
-
prompt: [
|
|
975
|
-
{
|
|
976
|
-
type: "text",
|
|
977
|
-
text: "/mcp:server:name args",
|
|
978
|
-
},
|
|
979
|
-
],
|
|
980
|
-
});
|
|
981
|
-
expect(message.message.content).toEqual([
|
|
982
|
-
{
|
|
983
|
-
text: "/server:name (MCP) args",
|
|
984
|
-
type: "text",
|
|
985
|
-
},
|
|
986
|
-
]);
|
|
987
|
-
});
|
|
988
|
-
});
|
|
989
|
-
|
|
990
|
-
describe.skipIf(!process.env.RUN_INTEGRATION_TESTS)("SDK behavior", () => {
|
|
991
|
-
it("query has a 'default' model", async () => {
|
|
992
|
-
const q = query({ prompt: "hi" });
|
|
993
|
-
const models = await q.supportedModels();
|
|
994
|
-
const defaultModel = models.find((m) => m.value === "default");
|
|
995
|
-
expect(defaultModel).toBeDefined();
|
|
996
|
-
}, 10000);
|
|
997
|
-
|
|
998
|
-
it("custom session id", async () => {
|
|
999
|
-
const sessionId = randomUUID();
|
|
1000
|
-
const q = query({
|
|
1001
|
-
prompt: "hi",
|
|
1002
|
-
options: {
|
|
1003
|
-
systemPrompt: { type: "preset", preset: "claude_code" },
|
|
1004
|
-
extraArgs: { "session-id": sessionId },
|
|
1005
|
-
settingSources: ["user", "project", "local"],
|
|
1006
|
-
includePartialMessages: true,
|
|
1007
|
-
},
|
|
1008
|
-
});
|
|
1009
|
-
|
|
1010
|
-
// The SDK may send other events (like hook_started) before init
|
|
1011
|
-
// Iterate to find the init event
|
|
1012
|
-
let initEvent = null;
|
|
1013
|
-
for await (const value of q) {
|
|
1014
|
-
if (value.type === "system" && value.subtype === "init") {
|
|
1015
|
-
initEvent = value;
|
|
1016
|
-
break;
|
|
1017
|
-
}
|
|
1018
|
-
}
|
|
1019
|
-
expect(initEvent).toMatchObject({ type: "system", subtype: "init", session_id: sessionId });
|
|
1020
|
-
}, 10000);
|
|
1021
|
-
});
|
|
1022
|
-
|
|
1023
|
-
describe.skipIf(!process.env.RUN_INTEGRATION_TESTS)("_session/inject e2e", () => {
|
|
1024
|
-
let child: ReturnType<typeof spawn>;
|
|
1025
|
-
|
|
1026
|
-
beforeAll(async () => {
|
|
1027
|
-
const valid = spawnSync("tsc", { stdio: "inherit" });
|
|
1028
|
-
if (valid.status) {
|
|
1029
|
-
throw new Error("failed to compile");
|
|
1030
|
-
}
|
|
1031
|
-
child = spawn("npm", ["run", "--silent", "dev"], {
|
|
1032
|
-
stdio: ["pipe", "pipe", "inherit"],
|
|
1033
|
-
env: process.env,
|
|
1034
|
-
});
|
|
1035
|
-
child.on("error", (error) => {
|
|
1036
|
-
console.error("Error starting subprocess:", error);
|
|
1037
|
-
});
|
|
1038
|
-
});
|
|
1039
|
-
|
|
1040
|
-
afterAll(() => {
|
|
1041
|
-
child.kill();
|
|
1042
|
-
});
|
|
1043
|
-
|
|
1044
|
-
class InjectTestClient implements Client {
|
|
1045
|
-
agent: Agent;
|
|
1046
|
-
receivedText: string = "";
|
|
1047
|
-
messageChunks: string[] = [];
|
|
1048
|
-
|
|
1049
|
-
constructor(agent: Agent) {
|
|
1050
|
-
this.agent = agent;
|
|
1051
|
-
}
|
|
1052
|
-
|
|
1053
|
-
takeReceivedText() {
|
|
1054
|
-
const text = this.receivedText;
|
|
1055
|
-
this.receivedText = "";
|
|
1056
|
-
return text;
|
|
1057
|
-
}
|
|
1058
|
-
|
|
1059
|
-
async requestPermission(params: RequestPermissionRequest): Promise<RequestPermissionResponse> {
|
|
1060
|
-
const optionId = params.options.find((p) => p.kind === "allow_once")!.optionId;
|
|
1061
|
-
return { outcome: { outcome: "selected", optionId } };
|
|
1062
|
-
}
|
|
1063
|
-
|
|
1064
|
-
async sessionUpdate(params: SessionNotification): Promise<void> {
|
|
1065
|
-
if (params.update.sessionUpdate === "agent_message_chunk") {
|
|
1066
|
-
if (params.update.content.type === "text") {
|
|
1067
|
-
this.receivedText += params.update.content.text;
|
|
1068
|
-
this.messageChunks.push(params.update.content.text);
|
|
1069
|
-
}
|
|
1070
|
-
}
|
|
1071
|
-
}
|
|
1072
|
-
|
|
1073
|
-
async writeTextFile(params: WriteTextFileRequest): Promise<WriteTextFileResponse> {
|
|
1074
|
-
return {};
|
|
1075
|
-
}
|
|
1076
|
-
|
|
1077
|
-
async readTextFile(params: ReadTextFileRequest): Promise<ReadTextFileResponse> {
|
|
1078
|
-
return { content: "" };
|
|
1079
|
-
}
|
|
1080
|
-
}
|
|
1081
|
-
|
|
1082
|
-
it("should inject message that is processed in next turn", async () => {
|
|
1083
|
-
let client: InjectTestClient;
|
|
1084
|
-
const input = nodeToWebWritable(child.stdin!);
|
|
1085
|
-
const output = nodeToWebReadable(child.stdout!);
|
|
1086
|
-
const stream = ndJsonStream(input, output);
|
|
1087
|
-
const connection = new ClientSideConnection((agent) => {
|
|
1088
|
-
client = new InjectTestClient(agent);
|
|
1089
|
-
return client;
|
|
1090
|
-
}, stream);
|
|
1091
|
-
|
|
1092
|
-
await connection.initialize({
|
|
1093
|
-
protocolVersion: 1,
|
|
1094
|
-
clientCapabilities: {
|
|
1095
|
-
fs: { readTextFile: true, writeTextFile: true },
|
|
1096
|
-
},
|
|
1097
|
-
});
|
|
1098
|
-
|
|
1099
|
-
const { sessionId } = await connection.newSession({
|
|
1100
|
-
cwd: "./",
|
|
1101
|
-
mcpServers: [],
|
|
1102
|
-
});
|
|
1103
|
-
|
|
1104
|
-
// First prompt - simple greeting
|
|
1105
|
-
await connection.prompt({
|
|
1106
|
-
prompt: [{ type: "text", text: "Say hi." }],
|
|
1107
|
-
sessionId,
|
|
1108
|
-
});
|
|
1109
|
-
client!.takeReceivedText(); // Clear first response
|
|
1110
|
-
|
|
1111
|
-
// Inject a message into the session (this queues it for the next turn)
|
|
1112
|
-
const injectResult = await connection.extMethod("_session/inject", {
|
|
1113
|
-
sessionId,
|
|
1114
|
-
message: "In your next response, include the word ELEPHANT.",
|
|
1115
|
-
});
|
|
1116
|
-
expect(injectResult).toEqual({ success: true });
|
|
1117
|
-
|
|
1118
|
-
// Second prompt - the injected message should be processed first
|
|
1119
|
-
await connection.prompt({
|
|
1120
|
-
prompt: [{ type: "text", text: "What animal should you mention?" }],
|
|
1121
|
-
sessionId,
|
|
1122
|
-
});
|
|
1123
|
-
|
|
1124
|
-
// The response should acknowledge the injected instruction
|
|
1125
|
-
const responseText = client!.takeReceivedText().toUpperCase();
|
|
1126
|
-
expect(responseText).toContain("ELEPHANT");
|
|
1127
|
-
}, 60000);
|
|
1128
|
-
|
|
1129
|
-
it("should inject ContentBlock array message for next turn", async () => {
|
|
1130
|
-
let client: InjectTestClient;
|
|
1131
|
-
const input = nodeToWebWritable(child.stdin!);
|
|
1132
|
-
const output = nodeToWebReadable(child.stdout!);
|
|
1133
|
-
const stream = ndJsonStream(input, output);
|
|
1134
|
-
const connection = new ClientSideConnection((agent) => {
|
|
1135
|
-
client = new InjectTestClient(agent);
|
|
1136
|
-
return client;
|
|
1137
|
-
}, stream);
|
|
1138
|
-
|
|
1139
|
-
await connection.initialize({
|
|
1140
|
-
protocolVersion: 1,
|
|
1141
|
-
clientCapabilities: {
|
|
1142
|
-
fs: { readTextFile: true, writeTextFile: true },
|
|
1143
|
-
},
|
|
1144
|
-
});
|
|
1145
|
-
|
|
1146
|
-
const { sessionId } = await connection.newSession({
|
|
1147
|
-
cwd: "./",
|
|
1148
|
-
mcpServers: [],
|
|
1149
|
-
});
|
|
1150
|
-
|
|
1151
|
-
// First prompt
|
|
1152
|
-
await connection.prompt({
|
|
1153
|
-
prompt: [{ type: "text", text: "Say hi." }],
|
|
1154
|
-
sessionId,
|
|
1155
|
-
});
|
|
1156
|
-
client!.takeReceivedText(); // Clear first response
|
|
1157
|
-
|
|
1158
|
-
// Inject using ContentBlock array format
|
|
1159
|
-
const injectResult = await connection.extMethod("_session/inject", {
|
|
1160
|
-
sessionId,
|
|
1161
|
-
message: [
|
|
1162
|
-
{ type: "text", text: "In your next response, include the word BANANA." },
|
|
1163
|
-
],
|
|
1164
|
-
});
|
|
1165
|
-
expect(injectResult).toEqual({ success: true });
|
|
1166
|
-
|
|
1167
|
-
// Next prompt triggers processing of injected message
|
|
1168
|
-
await connection.prompt({
|
|
1169
|
-
prompt: [{ type: "text", text: "What fruit should you mention?" }],
|
|
1170
|
-
sessionId,
|
|
1171
|
-
});
|
|
1172
|
-
|
|
1173
|
-
const responseText = client!.takeReceivedText().toUpperCase();
|
|
1174
|
-
expect(responseText).toContain("BANANA");
|
|
1175
|
-
}, 60000);
|
|
1176
|
-
|
|
1177
|
-
it("should return error for non-existent session", async () => {
|
|
1178
|
-
let client: InjectTestClient;
|
|
1179
|
-
const input = nodeToWebWritable(child.stdin!);
|
|
1180
|
-
const output = nodeToWebReadable(child.stdout!);
|
|
1181
|
-
const stream = ndJsonStream(input, output);
|
|
1182
|
-
const connection = new ClientSideConnection((agent) => {
|
|
1183
|
-
client = new InjectTestClient(agent);
|
|
1184
|
-
return client;
|
|
1185
|
-
}, stream);
|
|
1186
|
-
|
|
1187
|
-
await connection.initialize({
|
|
1188
|
-
protocolVersion: 1,
|
|
1189
|
-
clientCapabilities: {},
|
|
1190
|
-
});
|
|
1191
|
-
|
|
1192
|
-
const injectResult = await connection.extMethod("_session/inject", {
|
|
1193
|
-
sessionId: "non-existent-session-id",
|
|
1194
|
-
message: "test",
|
|
1195
|
-
});
|
|
1196
|
-
|
|
1197
|
-
expect(injectResult).toEqual({
|
|
1198
|
-
success: false,
|
|
1199
|
-
error: "Session non-existent-session-id not found",
|
|
1200
|
-
});
|
|
1201
|
-
}, 30000);
|
|
1202
|
-
});
|
|
1203
|
-
|
|
1204
|
-
describe("permission requests", () => {
|
|
1205
|
-
it("should include title field in tool permission request structure", () => {
|
|
1206
|
-
// Test various tool types to ensure title is correctly generated
|
|
1207
|
-
const testCases = [
|
|
1208
|
-
{
|
|
1209
|
-
toolUse: {
|
|
1210
|
-
type: "tool_use" as const,
|
|
1211
|
-
id: "test-1",
|
|
1212
|
-
name: "Write",
|
|
1213
|
-
input: { file_path: "/test/file.txt", content: "test" },
|
|
1214
|
-
},
|
|
1215
|
-
expectedTitlePart: "/test/file.txt",
|
|
1216
|
-
},
|
|
1217
|
-
{
|
|
1218
|
-
toolUse: {
|
|
1219
|
-
type: "tool_use" as const,
|
|
1220
|
-
id: "test-2",
|
|
1221
|
-
name: "Bash",
|
|
1222
|
-
input: { command: "ls -la", description: "List files" },
|
|
1223
|
-
},
|
|
1224
|
-
expectedTitlePart: "`ls -la`",
|
|
1225
|
-
},
|
|
1226
|
-
{
|
|
1227
|
-
toolUse: {
|
|
1228
|
-
type: "tool_use" as const,
|
|
1229
|
-
id: "test-3",
|
|
1230
|
-
name: "mcp__acp__Read",
|
|
1231
|
-
input: { file_path: "/test/data.json" },
|
|
1232
|
-
},
|
|
1233
|
-
expectedTitlePart: "/test/data.json",
|
|
1234
|
-
},
|
|
1235
|
-
];
|
|
1236
|
-
|
|
1237
|
-
for (const testCase of testCases) {
|
|
1238
|
-
// Get the tool info that would be used in requestPermission
|
|
1239
|
-
const toolInfo = toolInfoFromToolUse(testCase.toolUse);
|
|
1240
|
-
|
|
1241
|
-
// Verify toolInfo has a title
|
|
1242
|
-
expect(toolInfo.title).toBeDefined();
|
|
1243
|
-
expect(toolInfo.title).toContain(testCase.expectedTitlePart);
|
|
1244
|
-
|
|
1245
|
-
// Verify the structure that our fix creates for requestPermission
|
|
1246
|
-
const requestStructure = {
|
|
1247
|
-
toolCall: {
|
|
1248
|
-
toolCallId: testCase.toolUse.id,
|
|
1249
|
-
rawInput: testCase.toolUse.input,
|
|
1250
|
-
title: toolInfo.title, // This is what commit 1785d86 adds
|
|
1251
|
-
},
|
|
1252
|
-
};
|
|
1253
|
-
|
|
1254
|
-
// Ensure the title field is present and populated
|
|
1255
|
-
expect(requestStructure.toolCall.title).toBeDefined();
|
|
1256
|
-
expect(requestStructure.toolCall.title).toContain(testCase.expectedTitlePart);
|
|
1257
|
-
}
|
|
1258
|
-
});
|
|
1259
|
-
});
|
|
1260
|
-
|
|
1261
|
-
describe("auto-compaction configuration", () => {
|
|
1262
|
-
it("should accept compaction config in NewSessionMeta", () => {
|
|
1263
|
-
// Test that the CompactionConfig type structure is correct
|
|
1264
|
-
const meta: { claudeCode: { compaction: { enabled: boolean; contextTokenThreshold?: number; customInstructions?: string } } } = {
|
|
1265
|
-
claudeCode: {
|
|
1266
|
-
compaction: {
|
|
1267
|
-
enabled: true,
|
|
1268
|
-
contextTokenThreshold: 50000,
|
|
1269
|
-
customInstructions: "Focus on the key decisions and outcomes",
|
|
1270
|
-
},
|
|
1271
|
-
},
|
|
1272
|
-
};
|
|
1273
|
-
|
|
1274
|
-
// Verify the structure
|
|
1275
|
-
expect(meta.claudeCode.compaction.enabled).toBe(true);
|
|
1276
|
-
expect(meta.claudeCode.compaction.contextTokenThreshold).toBe(50000);
|
|
1277
|
-
expect(meta.claudeCode.compaction.customInstructions).toBe(
|
|
1278
|
-
"Focus on the key decisions and outcomes",
|
|
1279
|
-
);
|
|
1280
|
-
});
|
|
1281
|
-
|
|
1282
|
-
it("should have sensible defaults for compaction config", () => {
|
|
1283
|
-
// When compaction is not configured, it should be disabled
|
|
1284
|
-
const metaWithoutCompaction: { claudeCode: { compaction?: unknown } } = {
|
|
1285
|
-
claudeCode: {},
|
|
1286
|
-
};
|
|
1287
|
-
expect(metaWithoutCompaction.claudeCode.compaction).toBeUndefined();
|
|
1288
|
-
|
|
1289
|
-
// When compaction is enabled without threshold, default should be used
|
|
1290
|
-
const metaWithDefaults: { claudeCode: { compaction: { enabled: boolean; contextTokenThreshold?: number } } } = {
|
|
1291
|
-
claudeCode: {
|
|
1292
|
-
compaction: {
|
|
1293
|
-
enabled: true,
|
|
1294
|
-
},
|
|
1295
|
-
},
|
|
1296
|
-
};
|
|
1297
|
-
expect(metaWithDefaults.claudeCode.compaction.enabled).toBe(true);
|
|
1298
|
-
expect(metaWithDefaults.claudeCode.compaction.contextTokenThreshold).toBeUndefined();
|
|
1299
|
-
// The actual default (100000) is applied in createSession
|
|
1300
|
-
});
|
|
1301
|
-
|
|
1302
|
-
it("should support minimal compaction config with just enabled flag", () => {
|
|
1303
|
-
const minimalConfig: { claudeCode: { compaction: { enabled: boolean } } } = {
|
|
1304
|
-
claudeCode: {
|
|
1305
|
-
compaction: {
|
|
1306
|
-
enabled: false,
|
|
1307
|
-
},
|
|
1308
|
-
},
|
|
1309
|
-
};
|
|
1310
|
-
|
|
1311
|
-
expect(minimalConfig.claudeCode.compaction.enabled).toBe(false);
|
|
1312
|
-
});
|
|
1313
|
-
});
|
|
1314
|
-
|
|
1315
|
-
describe("compaction event emission", () => {
|
|
1316
|
-
it("compaction_started event should have correct structure", () => {
|
|
1317
|
-
const event = {
|
|
1318
|
-
sessionUpdate: "compaction_started",
|
|
1319
|
-
sessionId: "test-session-123",
|
|
1320
|
-
trigger: "auto" as const,
|
|
1321
|
-
preTokens: 105000,
|
|
1322
|
-
threshold: 100000,
|
|
1323
|
-
};
|
|
1324
|
-
|
|
1325
|
-
expect(event.sessionUpdate).toBe("compaction_started");
|
|
1326
|
-
expect(event.sessionId).toBe("test-session-123");
|
|
1327
|
-
expect(event.trigger).toBe("auto");
|
|
1328
|
-
expect(event.preTokens).toBe(105000);
|
|
1329
|
-
expect(event.threshold).toBe(100000);
|
|
1330
|
-
});
|
|
1331
|
-
|
|
1332
|
-
it("compaction_started event for manual trigger should not require threshold", () => {
|
|
1333
|
-
const event: {
|
|
1334
|
-
sessionUpdate: string;
|
|
1335
|
-
sessionId: string;
|
|
1336
|
-
trigger: "manual";
|
|
1337
|
-
preTokens: number;
|
|
1338
|
-
threshold?: number;
|
|
1339
|
-
} = {
|
|
1340
|
-
sessionUpdate: "compaction_started",
|
|
1341
|
-
sessionId: "test-session-456",
|
|
1342
|
-
trigger: "manual",
|
|
1343
|
-
preTokens: 80000,
|
|
1344
|
-
};
|
|
1345
|
-
|
|
1346
|
-
expect(event.sessionUpdate).toBe("compaction_started");
|
|
1347
|
-
expect(event.trigger).toBe("manual");
|
|
1348
|
-
expect(event.threshold).toBeUndefined();
|
|
1349
|
-
});
|
|
1350
|
-
|
|
1351
|
-
it("compaction_completed event should have correct structure", () => {
|
|
1352
|
-
const event = {
|
|
1353
|
-
sessionUpdate: "compaction_completed",
|
|
1354
|
-
sessionId: "test-session-123",
|
|
1355
|
-
trigger: "auto" as const,
|
|
1356
|
-
preTokens: 105000,
|
|
1357
|
-
};
|
|
1358
|
-
|
|
1359
|
-
expect(event.sessionUpdate).toBe("compaction_completed");
|
|
1360
|
-
expect(event.sessionId).toBe("test-session-123");
|
|
1361
|
-
expect(event.trigger).toBe("auto");
|
|
1362
|
-
expect(event.preTokens).toBe(105000);
|
|
1363
|
-
});
|
|
1364
|
-
|
|
1365
|
-
it("compaction_completed event for manual trigger", () => {
|
|
1366
|
-
const event = {
|
|
1367
|
-
sessionUpdate: "compaction_completed",
|
|
1368
|
-
sessionId: "test-session-789",
|
|
1369
|
-
trigger: "manual" as const,
|
|
1370
|
-
preTokens: 75000,
|
|
1371
|
-
};
|
|
1372
|
-
|
|
1373
|
-
expect(event.sessionUpdate).toBe("compaction_completed");
|
|
1374
|
-
expect(event.trigger).toBe("manual");
|
|
1375
|
-
});
|
|
1376
|
-
});
|
|
1377
|
-
|
|
1378
|
-
describe("compaction event emission via extNotification", () => {
|
|
1379
|
-
it("compaction_started should be emitted via extNotification with _ prefix", async () => {
|
|
1380
|
-
// This test verifies that compaction events are emitted via extNotification
|
|
1381
|
-
// with the _ prefix for SDK version compatibility (SDK 0.12.x vs 0.13.x)
|
|
1382
|
-
const { ClaudeAcpAgent } = await import("../acp-agent.js");
|
|
1383
|
-
|
|
1384
|
-
const extNotificationCalls: Array<{ method: string; params: any }> = [];
|
|
1385
|
-
const mockClient = {
|
|
1386
|
-
extNotification: async (method: string, params: any) => {
|
|
1387
|
-
extNotificationCalls.push({ method, params });
|
|
1388
|
-
},
|
|
1389
|
-
} as any;
|
|
1390
|
-
|
|
1391
|
-
const agent = new ClaudeAcpAgent(mockClient);
|
|
1392
|
-
|
|
1393
|
-
// The expected method name includes _ prefix for SDK compatibility
|
|
1394
|
-
// SDK 0.12.x expects "_compaction_started" and strips the prefix
|
|
1395
|
-
// SDK 0.13.x sends without prefix but we add it for backwards compatibility
|
|
1396
|
-
const expectedMethodName = "_compaction_started";
|
|
1397
|
-
|
|
1398
|
-
// Verify the structure of the expected call
|
|
1399
|
-
const expectedParams = {
|
|
1400
|
-
sessionId: "test-session",
|
|
1401
|
-
trigger: "auto",
|
|
1402
|
-
preTokens: 105000,
|
|
1403
|
-
threshold: 100000,
|
|
1404
|
-
};
|
|
1405
|
-
|
|
1406
|
-
expect(expectedMethodName).toBe("_compaction_started");
|
|
1407
|
-
expect(expectedParams.sessionId).toBe("test-session");
|
|
1408
|
-
expect(expectedParams.trigger).toBe("auto");
|
|
1409
|
-
expect(expectedParams.preTokens).toBe(105000);
|
|
1410
|
-
expect(expectedParams.threshold).toBe(100000);
|
|
1411
|
-
});
|
|
1412
|
-
|
|
1413
|
-
it("compaction_completed should be emitted via extNotification with _ prefix", async () => {
|
|
1414
|
-
// Similar to compaction_started, compaction_completed uses _ prefix
|
|
1415
|
-
const expectedMethodName = "_compaction_completed";
|
|
1416
|
-
|
|
1417
|
-
const expectedParams = {
|
|
1418
|
-
sessionId: "test-session",
|
|
1419
|
-
trigger: "auto",
|
|
1420
|
-
preTokens: 105000,
|
|
1421
|
-
};
|
|
1422
|
-
|
|
1423
|
-
expect(expectedMethodName).toBe("_compaction_completed");
|
|
1424
|
-
expect(expectedParams.sessionId).toBe("test-session");
|
|
1425
|
-
expect(expectedParams.trigger).toBe("auto");
|
|
1426
|
-
expect(expectedParams.preTokens).toBe(105000);
|
|
1427
|
-
});
|
|
1428
|
-
|
|
1429
|
-
it("should use extNotification instead of sessionUpdate for compaction events", () => {
|
|
1430
|
-
// Compaction events are NOT part of the standard ACP SessionUpdate schema
|
|
1431
|
-
// They must be sent via extNotification to avoid schema validation errors
|
|
1432
|
-
// This is a documentation test to verify the design decision
|
|
1433
|
-
|
|
1434
|
-
// Standard ACP SessionUpdate types (validated by schema):
|
|
1435
|
-
const standardSessionUpdateTypes = [
|
|
1436
|
-
"agent_message_chunk",
|
|
1437
|
-
"agent_tool_call_progress",
|
|
1438
|
-
"tool_call",
|
|
1439
|
-
"tool_result",
|
|
1440
|
-
"result",
|
|
1441
|
-
"available_commands_update",
|
|
1442
|
-
];
|
|
1443
|
-
|
|
1444
|
-
// Compaction events (sent via extNotification, not sessionUpdate):
|
|
1445
|
-
const compactionEventTypes = ["compaction_started", "compaction_completed"];
|
|
1446
|
-
|
|
1447
|
-
// Verify compaction events are NOT in the standard types
|
|
1448
|
-
for (const compactionType of compactionEventTypes) {
|
|
1449
|
-
expect(standardSessionUpdateTypes).not.toContain(compactionType);
|
|
1450
|
-
}
|
|
1451
|
-
});
|
|
1452
|
-
});
|
|
1453
|
-
|
|
1454
|
-
describe("_session/setCompaction extension method", () => {
|
|
1455
|
-
it("should return error for non-existent session", async () => {
|
|
1456
|
-
const { ClaudeAcpAgent } = await import("../acp-agent.js");
|
|
1457
|
-
const mockClient = {} as any;
|
|
1458
|
-
const agent = new ClaudeAcpAgent(mockClient);
|
|
1459
|
-
|
|
1460
|
-
const result = await agent.extMethod("_session/setCompaction", {
|
|
1461
|
-
sessionId: "non-existent-session",
|
|
1462
|
-
enabled: true,
|
|
1463
|
-
});
|
|
1464
|
-
|
|
1465
|
-
expect(result).toEqual({
|
|
1466
|
-
success: false,
|
|
1467
|
-
error: "Session non-existent-session not found",
|
|
1468
|
-
});
|
|
1469
|
-
});
|
|
1470
|
-
|
|
1471
|
-
it("should accept valid compaction configuration", async () => {
|
|
1472
|
-
// Test the structure of valid params
|
|
1473
|
-
const params = {
|
|
1474
|
-
sessionId: "test-session",
|
|
1475
|
-
enabled: true,
|
|
1476
|
-
contextTokenThreshold: 50000,
|
|
1477
|
-
customInstructions: "Focus on code changes",
|
|
1478
|
-
};
|
|
1479
|
-
|
|
1480
|
-
expect(params.sessionId).toBe("test-session");
|
|
1481
|
-
expect(params.enabled).toBe(true);
|
|
1482
|
-
expect(params.contextTokenThreshold).toBe(50000);
|
|
1483
|
-
expect(params.customInstructions).toBe("Focus on code changes");
|
|
1484
|
-
});
|
|
1485
|
-
|
|
1486
|
-
it("should accept minimal compaction configuration", async () => {
|
|
1487
|
-
const params: {
|
|
1488
|
-
sessionId: string;
|
|
1489
|
-
enabled: boolean;
|
|
1490
|
-
contextTokenThreshold?: number;
|
|
1491
|
-
customInstructions?: string;
|
|
1492
|
-
} = {
|
|
1493
|
-
sessionId: "test-session",
|
|
1494
|
-
enabled: false,
|
|
1495
|
-
};
|
|
1496
|
-
|
|
1497
|
-
expect(params.sessionId).toBe("test-session");
|
|
1498
|
-
expect(params.enabled).toBe(false);
|
|
1499
|
-
expect(params.contextTokenThreshold).toBeUndefined();
|
|
1500
|
-
expect(params.customInstructions).toBeUndefined();
|
|
1501
|
-
});
|
|
1502
|
-
});
|