@google/gemini-cli-core 0.37.0-preview.2 → 0.38.0-preview.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +58 -50
- package/dist/docs/changelogs/index.md +25 -0
- package/dist/docs/changelogs/latest.md +353 -362
- package/dist/docs/changelogs/preview.md +399 -366
- package/dist/docs/cli/plan-mode.md +1 -0
- package/dist/docs/cli/sandbox.md +52 -0
- package/dist/docs/cli/settings.md +17 -14
- package/dist/docs/core/remote-agents.md +14 -18
- package/dist/docs/core/subagents.md +63 -27
- package/dist/docs/get-started/authentication.md +2 -2
- package/dist/docs/get-started/installation.md +7 -0
- package/dist/docs/hooks/index.md +6 -6
- package/dist/docs/reference/configuration.md +41 -11
- package/dist/docs/reference/keyboard-shortcuts.md +14 -9
- package/dist/docs/reference/tools.md +4 -4
- package/dist/docs/release-confidence.md +0 -6
- package/dist/docs/releases.md +4 -0
- package/dist/docs/tools/mcp-server.md +3 -3
- package/dist/docs/tools/web-fetch.md +3 -0
- package/dist/src/agent/agent-session.test.js +14 -6
- package/dist/src/agent/agent-session.test.js.map +1 -1
- package/dist/src/agent/event-translator.js +2 -1
- package/dist/src/agent/event-translator.js.map +1 -1
- package/dist/src/agent/event-translator.test.js +1 -0
- package/dist/src/agent/event-translator.test.js.map +1 -1
- package/dist/src/agent/legacy-agent-session.d.ts +47 -4
- package/dist/src/agent/legacy-agent-session.js +38 -15
- package/dist/src/agent/legacy-agent-session.js.map +1 -1
- package/dist/src/agent/legacy-agent-session.test.js +60 -73
- package/dist/src/agent/legacy-agent-session.test.js.map +1 -1
- package/dist/src/agent/mock.js +7 -1
- package/dist/src/agent/mock.js.map +1 -1
- package/dist/src/agent/mock.test.js +1 -1
- package/dist/src/agent/mock.test.js.map +1 -1
- package/dist/src/agent/types.d.ts +34 -1
- package/dist/src/agents/agent-scheduler.js +6 -1
- package/dist/src/agents/agent-scheduler.js.map +1 -1
- package/dist/src/agents/agent-scheduler.test.js +38 -0
- package/dist/src/agents/agent-scheduler.test.js.map +1 -1
- package/dist/src/agents/auth-provider/api-key-provider.test.js +18 -2
- package/dist/src/agents/auth-provider/api-key-provider.test.js.map +1 -1
- package/dist/src/agents/auth-provider/value-resolver.test.js +30 -0
- package/dist/src/agents/auth-provider/value-resolver.test.js.map +1 -1
- package/dist/src/agents/browser/analyzeScreenshot.js +36 -6
- package/dist/src/agents/browser/analyzeScreenshot.js.map +1 -1
- package/dist/src/agents/browser/analyzeScreenshot.test.js +35 -3
- package/dist/src/agents/browser/analyzeScreenshot.test.js.map +1 -1
- package/dist/src/agents/browser/browserAgentFactory.d.ts +8 -0
- package/dist/src/agents/browser/browserAgentFactory.js +174 -118
- package/dist/src/agents/browser/browserAgentFactory.js.map +1 -1
- package/dist/src/agents/browser/browserAgentFactory.test.js +70 -1
- package/dist/src/agents/browser/browserAgentFactory.test.js.map +1 -1
- package/dist/src/agents/browser/browserAgentInvocation.js +29 -2
- package/dist/src/agents/browser/browserAgentInvocation.js.map +1 -1
- package/dist/src/agents/browser/browserAgentInvocation.test.js +51 -5
- package/dist/src/agents/browser/browserAgentInvocation.test.js.map +1 -1
- package/dist/src/agents/browser/browserManager.d.ts +38 -0
- package/dist/src/agents/browser/browserManager.js +117 -6
- package/dist/src/agents/browser/browserManager.js.map +1 -1
- package/dist/src/agents/browser/browserManager.test.js +156 -2
- package/dist/src/agents/browser/browserManager.test.js.map +1 -1
- package/dist/src/agents/browser/modelAvailability.d.ts +5 -0
- package/dist/src/agents/browser/modelAvailability.js +12 -0
- package/dist/src/agents/browser/modelAvailability.js.map +1 -1
- package/dist/src/agents/local-executor.d.ts +5 -0
- package/dist/src/agents/local-executor.js +98 -181
- package/dist/src/agents/local-executor.js.map +1 -1
- package/dist/src/agents/local-executor.test.js +386 -101
- package/dist/src/agents/local-executor.test.js.map +1 -1
- package/dist/src/agents/memory-manager-agent.js +1 -0
- package/dist/src/agents/memory-manager-agent.js.map +1 -1
- package/dist/src/agents/memory-manager-agent.test.js +6 -0
- package/dist/src/agents/memory-manager-agent.test.js.map +1 -1
- package/dist/src/agents/registry.js +3 -10
- package/dist/src/agents/registry.js.map +1 -1
- package/dist/src/agents/skill-extraction-agent.d.ts +24 -0
- package/dist/src/agents/skill-extraction-agent.js +269 -0
- package/dist/src/agents/skill-extraction-agent.js.map +1 -0
- package/dist/src/agents/types.d.ts +11 -0
- package/dist/src/code_assist/admin/admin_controls.js +1 -1
- package/dist/src/code_assist/admin/admin_controls.js.map +1 -1
- package/dist/src/code_assist/experiments/flagNames.d.ts +1 -0
- package/dist/src/code_assist/experiments/flagNames.js +1 -0
- package/dist/src/code_assist/experiments/flagNames.js.map +1 -1
- package/dist/src/code_assist/server.js +1 -1
- package/dist/src/code_assist/server.js.map +1 -1
- package/dist/src/commands/memory.js +1 -1
- package/dist/src/commands/memory.js.map +1 -1
- package/dist/src/config/config.d.ts +34 -31
- package/dist/src/config/config.js +101 -38
- package/dist/src/config/config.js.map +1 -1
- package/dist/src/config/config.test.js +102 -15
- package/dist/src/config/config.test.js.map +1 -1
- package/dist/src/config/extensions/integrity.js +1 -1
- package/dist/src/config/extensions/integrity.js.map +1 -1
- package/dist/src/config/projectRegistry.js +5 -3
- package/dist/src/config/projectRegistry.js.map +1 -1
- package/dist/src/config/scoped-config.d.ts +30 -0
- package/dist/src/config/scoped-config.js +69 -0
- package/dist/src/config/scoped-config.js.map +1 -0
- package/dist/src/config/scoped-config.test.d.ts +6 -0
- package/dist/src/config/scoped-config.test.js +161 -0
- package/dist/src/config/scoped-config.test.js.map +1 -0
- package/dist/src/config/storage.d.ts +2 -0
- package/dist/src/config/storage.js +7 -2
- package/dist/src/config/storage.js.map +1 -1
- package/dist/src/config/storage.test.js +7 -7
- package/dist/src/config/storage.test.js.map +1 -1
- package/dist/src/confirmation-bus/types.d.ts +2 -2
- package/dist/src/context/agentHistoryProvider.d.ts +1 -1
- package/dist/src/context/agentHistoryProvider.js +1 -5
- package/dist/src/context/agentHistoryProvider.js.map +1 -1
- package/dist/src/context/agentHistoryProvider.test.js +2 -39
- package/dist/src/context/agentHistoryProvider.test.js.map +1 -1
- package/dist/src/context/contextCompressionService.d.ts +30 -0
- package/dist/src/context/contextCompressionService.js +405 -0
- package/dist/src/context/contextCompressionService.js.map +1 -0
- package/dist/src/context/contextCompressionService.test.d.ts +1 -0
- package/dist/src/context/contextCompressionService.test.js +253 -0
- package/dist/src/context/contextCompressionService.test.js.map +1 -0
- package/dist/src/context/{contextManager.d.ts → memoryContextManager.d.ts} +1 -1
- package/dist/src/context/{contextManager.js → memoryContextManager.js} +2 -2
- package/dist/src/context/memoryContextManager.js.map +1 -0
- package/dist/src/context/{contextManager.test.js → memoryContextManager.test.js} +22 -28
- package/dist/src/context/memoryContextManager.test.js.map +1 -0
- package/dist/src/context/profiles.d.ts +7 -0
- package/dist/src/context/profiles.js +21 -0
- package/dist/src/context/profiles.js.map +1 -0
- package/dist/src/context/toolDistillationService.test.js +3 -0
- package/dist/src/context/toolDistillationService.test.js.map +1 -1
- package/dist/src/context/types.d.ts +36 -0
- package/dist/src/context/types.js.map +1 -0
- package/dist/src/core/baseLlmClient.js +1 -1
- package/dist/src/core/baseLlmClient.js.map +1 -1
- package/dist/src/core/baseLlmClient.test.js +1 -0
- package/dist/src/core/baseLlmClient.test.js.map +1 -1
- package/dist/src/core/client.js +1 -1
- package/dist/src/core/client.js.map +1 -1
- package/dist/src/core/client.test.js +7 -6
- package/dist/src/core/client.test.js.map +1 -1
- package/dist/src/core/geminiChat.js +8 -0
- package/dist/src/core/geminiChat.js.map +1 -1
- package/dist/src/core/geminiChat.test.js +1 -0
- package/dist/src/core/geminiChat.test.js.map +1 -1
- package/dist/src/core/geminiChat_network_retry.test.js +1 -0
- package/dist/src/core/geminiChat_network_retry.test.js.map +1 -1
- package/dist/src/core/logger.js +4 -4
- package/dist/src/core/logger.js.map +1 -1
- package/dist/src/core/logger.test.js +1 -1
- package/dist/src/core/logger.test.js.map +1 -1
- package/dist/src/core/loggingContentGenerator.js +1 -1
- package/dist/src/core/loggingContentGenerator.js.map +1 -1
- package/dist/src/generated/git-commit.d.ts +2 -2
- package/dist/src/generated/git-commit.js +2 -2
- package/dist/src/hooks/hookEventHandler.js +8 -0
- package/dist/src/hooks/hookEventHandler.js.map +1 -1
- package/dist/src/hooks/hookRunner.js +9 -5
- package/dist/src/hooks/hookRunner.js.map +1 -1
- package/dist/src/hooks/hookRunner.test.js +20 -3
- package/dist/src/hooks/hookRunner.test.js.map +1 -1
- package/dist/src/hooks/hookSystem.d.ts +2 -0
- package/dist/src/hooks/hookSystem.js +1 -0
- package/dist/src/hooks/hookSystem.js.map +1 -1
- package/dist/src/hooks/hookTranslator.js +20 -13
- package/dist/src/hooks/hookTranslator.js.map +1 -1
- package/dist/src/hooks/hookTranslator.test.js +36 -0
- package/dist/src/hooks/hookTranslator.test.js.map +1 -1
- package/dist/src/hooks/types.d.ts +2 -0
- package/dist/src/ide/ide-client.js +3 -3
- package/dist/src/ide/ide-client.js.map +1 -1
- package/dist/src/ide/ide-connection-utils.js +1 -1
- package/dist/src/ide/ide-connection-utils.js.map +1 -1
- package/dist/src/ide/ide-installer.js +3 -3
- package/dist/src/ide/ide-installer.js.map +1 -1
- package/dist/src/ide/process-utils.js +3 -3
- package/dist/src/ide/process-utils.js.map +1 -1
- package/dist/src/index.d.ts +4 -1
- package/dist/src/index.js +5 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/output/json-formatter.js +2 -1
- package/dist/src/output/json-formatter.js.map +1 -1
- package/dist/src/policy/config.test.js +21 -20
- package/dist/src/policy/config.test.js.map +1 -1
- package/dist/src/policy/policies/memory-manager.toml +11 -1
- package/dist/src/policy/policies/plan.toml +4 -3
- package/dist/src/policy/policies/read-only.toml +6 -0
- package/dist/src/policy/policies/sandbox-default.toml +2 -3
- package/dist/src/policy/policy-engine.js +23 -0
- package/dist/src/policy/policy-engine.js.map +1 -1
- package/dist/src/policy/policy-engine.test.js +129 -1
- package/dist/src/policy/policy-engine.test.js.map +1 -1
- package/dist/src/policy/sandboxPolicyManager.d.ts +26 -1
- package/dist/src/policy/sandboxPolicyManager.js +41 -12
- package/dist/src/policy/sandboxPolicyManager.js.map +1 -1
- package/dist/src/policy/sandboxPolicyManager.test.d.ts +6 -0
- package/dist/src/policy/sandboxPolicyManager.test.js +61 -0
- package/dist/src/policy/sandboxPolicyManager.test.js.map +1 -0
- package/dist/src/policy/workspace-policy.test.js +18 -15
- package/dist/src/policy/workspace-policy.test.js.map +1 -1
- package/dist/src/prompts/snippets.js +6 -3
- package/dist/src/prompts/snippets.js.map +1 -1
- package/dist/src/prompts/snippets.legacy.js +6 -2
- package/dist/src/prompts/snippets.legacy.js.map +1 -1
- package/dist/src/prompts/utils.test.js +7 -5
- package/dist/src/prompts/utils.test.js.map +1 -1
- package/dist/src/safety/built-in.js +1 -1
- package/dist/src/safety/built-in.js.map +1 -1
- package/dist/src/sandbox/linux/LinuxSandboxManager.d.ts +4 -4
- package/dist/src/sandbox/linux/LinuxSandboxManager.js +47 -191
- package/dist/src/sandbox/linux/LinuxSandboxManager.js.map +1 -1
- package/dist/src/sandbox/linux/LinuxSandboxManager.test.js +33 -395
- package/dist/src/sandbox/linux/LinuxSandboxManager.test.js.map +1 -1
- package/dist/src/sandbox/linux/bwrapArgsBuilder.d.ts +24 -0
- package/dist/src/sandbox/linux/bwrapArgsBuilder.js +200 -0
- package/dist/src/sandbox/linux/bwrapArgsBuilder.js.map +1 -0
- package/dist/src/sandbox/linux/bwrapArgsBuilder.test.d.ts +6 -0
- package/dist/src/sandbox/linux/bwrapArgsBuilder.test.js +247 -0
- package/dist/src/sandbox/linux/bwrapArgsBuilder.test.js.map +1 -0
- package/dist/src/sandbox/macos/MacOsSandboxManager.d.ts +3 -0
- package/dist/src/sandbox/macos/MacOsSandboxManager.js +12 -5
- package/dist/src/sandbox/macos/MacOsSandboxManager.js.map +1 -1
- package/dist/src/sandbox/macos/MacOsSandboxManager.test.js +20 -0
- package/dist/src/sandbox/macos/MacOsSandboxManager.test.js.map +1 -1
- package/dist/src/sandbox/macos/baseProfile.d.ts +1 -1
- package/dist/src/sandbox/macos/baseProfile.js +28 -4
- package/dist/src/sandbox/macos/baseProfile.js.map +1 -1
- package/dist/src/sandbox/macos/seatbeltArgsBuilder.js +1 -1
- package/dist/src/sandbox/macos/seatbeltArgsBuilder.js.map +1 -1
- package/dist/src/sandbox/macos/seatbeltArgsBuilder.test.js +2 -1
- package/dist/src/sandbox/macos/seatbeltArgsBuilder.test.js.map +1 -1
- package/dist/src/sandbox/utils/fsUtils.js +8 -6
- package/dist/src/sandbox/utils/fsUtils.js.map +1 -1
- package/dist/src/sandbox/utils/fsUtils.test.d.ts +6 -0
- package/dist/src/sandbox/utils/fsUtils.test.js +43 -0
- package/dist/src/sandbox/utils/fsUtils.test.js.map +1 -0
- package/dist/src/sandbox/utils/proactivePermissions.d.ts +19 -0
- package/dist/src/sandbox/utils/proactivePermissions.js +163 -0
- package/dist/src/sandbox/utils/proactivePermissions.js.map +1 -0
- package/dist/src/sandbox/utils/proactivePermissions.test.d.ts +6 -0
- package/dist/src/sandbox/utils/proactivePermissions.test.js +145 -0
- package/dist/src/sandbox/utils/proactivePermissions.test.js.map +1 -0
- package/dist/src/sandbox/utils/sandboxDenialUtils.d.ts +16 -1
- package/dist/src/sandbox/utils/sandboxDenialUtils.js +98 -24
- package/dist/src/sandbox/utils/sandboxDenialUtils.js.map +1 -1
- package/dist/src/sandbox/utils/sandboxDenialUtils.test.js +152 -1
- package/dist/src/sandbox/utils/sandboxDenialUtils.test.js.map +1 -1
- package/dist/src/sandbox/utils/sandboxReadWriteUtils.js +4 -0
- package/dist/src/sandbox/utils/sandboxReadWriteUtils.js.map +1 -1
- package/dist/src/sandbox/windows/GeminiSandbox.cs +90 -42
- package/dist/src/sandbox/windows/WindowsSandboxManager.d.ts +4 -0
- package/dist/src/sandbox/windows/WindowsSandboxManager.js +65 -60
- package/dist/src/sandbox/windows/WindowsSandboxManager.js.map +1 -1
- package/dist/src/sandbox/windows/WindowsSandboxManager.test.js +99 -54
- package/dist/src/sandbox/windows/WindowsSandboxManager.test.js.map +1 -1
- package/dist/src/sandbox/windows/windowsSandboxDenialUtils.d.ts +2 -1
- package/dist/src/sandbox/windows/windowsSandboxDenialUtils.js +19 -18
- package/dist/src/sandbox/windows/windowsSandboxDenialUtils.js.map +1 -1
- package/dist/src/scheduler/scheduler.js +1 -1
- package/dist/src/scheduler/scheduler.js.map +1 -1
- package/dist/src/scheduler/scheduler_hooks.test.js +1 -1
- package/dist/src/scheduler/scheduler_hooks.test.js.map +1 -1
- package/dist/src/scheduler/tool-executor.js +1 -1
- package/dist/src/scheduler/tool-executor.js.map +1 -1
- package/dist/src/scheduler/tool-executor.test.js +1 -1
- package/dist/src/scheduler/tool-executor.test.js.map +1 -1
- package/dist/src/services/executionLifecycleService.d.ts +1 -0
- package/dist/src/services/executionLifecycleService.js +3 -0
- package/dist/src/services/executionLifecycleService.js.map +1 -1
- package/dist/src/services/gitService.js +1 -1
- package/dist/src/services/gitService.js.map +1 -1
- package/dist/src/services/memoryService.d.ts +65 -0
- package/dist/src/services/memoryService.js +511 -0
- package/dist/src/services/memoryService.js.map +1 -0
- package/dist/src/services/memoryService.test.d.ts +6 -0
- package/dist/src/services/memoryService.test.js +563 -0
- package/dist/src/services/memoryService.test.js.map +1 -0
- package/dist/src/services/sandboxManager.d.ts +17 -0
- package/dist/src/services/sandboxManager.integration.test.js +18 -11
- package/dist/src/services/sandboxManager.integration.test.js.map +1 -1
- package/dist/src/services/sandboxManager.js +20 -0
- package/dist/src/services/sandboxManager.js.map +1 -1
- package/dist/src/services/sandboxManager.test.js +84 -56
- package/dist/src/services/sandboxManager.test.js.map +1 -1
- package/dist/src/services/sandboxManagerFactory.js +2 -5
- package/dist/src/services/sandboxManagerFactory.js.map +1 -1
- package/dist/src/services/sandboxedFileSystemService.js +14 -3
- package/dist/src/services/sandboxedFileSystemService.js.map +1 -1
- package/dist/src/services/sandboxedFileSystemService.test.js +29 -14
- package/dist/src/services/sandboxedFileSystemService.test.js.map +1 -1
- package/dist/src/services/shellExecutionService.d.ts +16 -1
- package/dist/src/services/shellExecutionService.js +70 -10
- package/dist/src/services/shellExecutionService.js.map +1 -1
- package/dist/src/services/shellExecutionService.test.js +65 -4
- package/dist/src/services/shellExecutionService.test.js.map +1 -1
- package/dist/src/services/worktreeService.test.js +7 -7
- package/dist/src/services/worktreeService.test.js.map +1 -1
- package/dist/src/skills/skillLoader.d.ts +8 -0
- package/dist/src/skills/skillLoader.js +1 -1
- package/dist/src/skills/skillLoader.js.map +1 -1
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.d.ts +29 -1
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.js +101 -0
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.js.map +1 -1
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js +167 -0
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js.map +1 -1
- package/dist/src/telemetry/clearcut-logger/event-metadata-key.d.ts +9 -1
- package/dist/src/telemetry/clearcut-logger/event-metadata-key.js +20 -1
- package/dist/src/telemetry/clearcut-logger/event-metadata-key.js.map +1 -1
- package/dist/src/telemetry/loggers.d.ts +22 -0
- package/dist/src/telemetry/loggers.js +40 -1
- package/dist/src/telemetry/loggers.js.map +1 -1
- package/dist/src/telemetry/metrics.d.ts +108 -0
- package/dist/src/telemetry/metrics.js +177 -0
- package/dist/src/telemetry/metrics.js.map +1 -1
- package/dist/src/telemetry/metrics.test.js +254 -0
- package/dist/src/telemetry/metrics.test.js.map +1 -1
- package/dist/src/tools/complete-task.d.ts +29 -0
- package/dist/src/tools/complete-task.js +123 -0
- package/dist/src/tools/complete-task.js.map +1 -0
- package/dist/src/tools/complete-task.test.d.ts +6 -0
- package/dist/src/tools/complete-task.test.js +114 -0
- package/dist/src/tools/complete-task.test.js.map +1 -0
- package/dist/src/tools/definitions/base-declarations.d.ts +2 -0
- package/dist/src/tools/definitions/base-declarations.js +3 -0
- package/dist/src/tools/definitions/base-declarations.js.map +1 -1
- package/dist/src/tools/definitions/coreTools.d.ts +1 -1
- package/dist/src/tools/definitions/coreTools.js +1 -1
- package/dist/src/tools/definitions/coreTools.js.map +1 -1
- package/dist/src/tools/definitions/dynamic-declaration-helpers.js +4 -0
- package/dist/src/tools/definitions/dynamic-declaration-helpers.js.map +1 -1
- package/dist/src/tools/definitions/model-family-sets/default-legacy.js +3 -3
- package/dist/src/tools/definitions/model-family-sets/default-legacy.js.map +1 -1
- package/dist/src/tools/definitions/model-family-sets/gemini-3.js +3 -3
- package/dist/src/tools/definitions/model-family-sets/gemini-3.js.map +1 -1
- package/dist/src/tools/grep.test.js +2 -2
- package/dist/src/tools/grep.test.js.map +1 -1
- package/dist/src/tools/jit-context.js +3 -3
- package/dist/src/tools/jit-context.js.map +1 -1
- package/dist/src/tools/jit-context.test.js +15 -13
- package/dist/src/tools/jit-context.test.js.map +1 -1
- package/dist/src/tools/mcp-client.js +1 -1
- package/dist/src/tools/mcp-client.js.map +1 -1
- package/dist/src/tools/mcp-tool.test.js +1 -1
- package/dist/src/tools/mcp-tool.test.js.map +1 -1
- package/dist/src/tools/ripGrep.test.js +1 -1
- package/dist/src/tools/ripGrep.test.js.map +1 -1
- package/dist/src/tools/shell.d.ts +7 -4
- package/dist/src/tools/shell.js +255 -37
- package/dist/src/tools/shell.js.map +1 -1
- package/dist/src/tools/shell.test.js +182 -8
- package/dist/src/tools/shell.test.js.map +1 -1
- package/dist/src/tools/shellBackgroundTools.d.ts +38 -0
- package/dist/src/tools/shellBackgroundTools.integration.test.d.ts +6 -0
- package/dist/src/tools/shellBackgroundTools.integration.test.js +86 -0
- package/dist/src/tools/shellBackgroundTools.integration.test.js.map +1 -0
- package/dist/src/tools/shellBackgroundTools.js +186 -0
- package/dist/src/tools/shellBackgroundTools.js.map +1 -0
- package/dist/src/tools/shellBackgroundTools.test.d.ts +6 -0
- package/dist/src/tools/shellBackgroundTools.test.js +230 -0
- package/dist/src/tools/shellBackgroundTools.test.js.map +1 -0
- package/dist/src/tools/shell_proactive.test.d.ts +6 -0
- package/dist/src/tools/shell_proactive.test.js +122 -0
- package/dist/src/tools/shell_proactive.test.js.map +1 -0
- package/dist/src/tools/tool-names.d.ts +3 -3
- package/dist/src/tools/tool-names.js +3 -2
- package/dist/src/tools/tool-names.js.map +1 -1
- package/dist/src/tools/tools.js +1 -1
- package/dist/src/tools/tools.js.map +1 -1
- package/dist/src/tools/web-fetch.js +8 -8
- package/dist/src/tools/web-fetch.js.map +1 -1
- package/dist/src/tools/web-fetch.test.js +5 -5
- package/dist/src/tools/web-fetch.test.js.map +1 -1
- package/dist/src/tools/xcode-mcp-fix-transport.js +1 -1
- package/dist/src/tools/xcode-mcp-fix-transport.js.map +1 -1
- package/dist/src/utils/bfsFileSearch.js +3 -6
- package/dist/src/utils/bfsFileSearch.js.map +1 -1
- package/dist/src/utils/checkpointUtils.js +11 -8
- package/dist/src/utils/checkpointUtils.js.map +1 -1
- package/dist/src/utils/compatibility.js +0 -7
- package/dist/src/utils/compatibility.js.map +1 -1
- package/dist/src/utils/compatibility.test.js +0 -9
- package/dist/src/utils/compatibility.test.js.map +1 -1
- package/dist/src/utils/editor.js +3 -0
- package/dist/src/utils/editor.js.map +1 -1
- package/dist/src/utils/errorParsing.js +2 -2
- package/dist/src/utils/errorParsing.js.map +1 -1
- package/dist/src/utils/events.d.ts +12 -0
- package/dist/src/utils/events.js +7 -0
- package/dist/src/utils/events.js.map +1 -1
- package/dist/src/utils/fetch.d.ts +1 -0
- package/dist/src/utils/fetch.js +22 -6
- package/dist/src/utils/fetch.js.map +1 -1
- package/dist/src/utils/fetch.test.js +26 -1
- package/dist/src/utils/fetch.test.js.map +1 -1
- package/dist/src/utils/fileUtils.js +1 -1
- package/dist/src/utils/fileUtils.js.map +1 -1
- package/dist/src/utils/filesearch/crawler.js +1 -1
- package/dist/src/utils/filesearch/crawler.js.map +1 -1
- package/dist/src/utils/filesearch/fileSearch.test.js +7 -2
- package/dist/src/utils/filesearch/fileSearch.test.js.map +1 -1
- package/dist/src/utils/getPty.js +2 -2
- package/dist/src/utils/getPty.js.map +1 -1
- package/dist/src/utils/gitIgnoreParser.js +2 -2
- package/dist/src/utils/gitIgnoreParser.js.map +1 -1
- package/dist/src/utils/gitUtils.js +2 -2
- package/dist/src/utils/gitUtils.js.map +1 -1
- package/dist/src/utils/googleErrors.js +5 -5
- package/dist/src/utils/googleErrors.js.map +1 -1
- package/dist/src/utils/ignoreFileParser.js +1 -1
- package/dist/src/utils/ignoreFileParser.js.map +1 -1
- package/dist/src/utils/memoryDiscovery.js +3 -7
- package/dist/src/utils/memoryDiscovery.js.map +1 -1
- package/dist/src/utils/paths.d.ts +8 -0
- package/dist/src/utils/paths.js +37 -6
- package/dist/src/utils/paths.js.map +1 -1
- package/dist/src/utils/paths.test.js +61 -3
- package/dist/src/utils/paths.test.js.map +1 -1
- package/dist/src/utils/process-utils.js +2 -2
- package/dist/src/utils/process-utils.js.map +1 -1
- package/dist/src/utils/retry.js +7 -0
- package/dist/src/utils/retry.js.map +1 -1
- package/dist/src/utils/retry.test.js +41 -0
- package/dist/src/utils/retry.test.js.map +1 -1
- package/dist/src/utils/secure-browser-launcher.js +1 -1
- package/dist/src/utils/secure-browser-launcher.js.map +1 -1
- package/dist/src/utils/shell-utils.d.ts +9 -0
- package/dist/src/utils/shell-utils.integration.test.js +1 -1
- package/dist/src/utils/shell-utils.integration.test.js.map +1 -1
- package/dist/src/utils/shell-utils.js +43 -4
- package/dist/src/utils/shell-utils.js.map +1 -1
- package/dist/src/utils/shell-utils.test.js +13 -1
- package/dist/src/utils/shell-utils.test.js.map +1 -1
- package/dist/src/utils/systemEncoding.js +1 -1
- package/dist/src/utils/systemEncoding.js.map +1 -1
- package/dist/src/utils/terminalSerializer.d.ts +1 -0
- package/dist/src/utils/terminalSerializer.js +31 -8
- package/dist/src/utils/terminalSerializer.js.map +1 -1
- package/dist/src/utils/terminalSerializer.test.js +3 -2
- package/dist/src/utils/terminalSerializer.test.js.map +1 -1
- package/dist/src/utils/workspaceContext.js +2 -2
- package/dist/src/utils/workspaceContext.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/dist/google-gemini-cli-core-0.37.0-preview.1.tgz +0 -0
- package/dist/src/context/contextManager.js.map +0 -1
- package/dist/src/context/contextManager.test.js.map +0 -1
- package/dist/src/services/types.d.ts +0 -14
- package/dist/src/services/types.js.map +0 -1
- /package/dist/src/context/{contextManager.test.d.ts → memoryContextManager.test.d.ts} +0 -0
- /package/dist/src/{services → context}/types.js +0 -0
|
@@ -35,7 +35,7 @@ import { PromptRegistry } from '../prompts/prompt-registry.js';
|
|
|
35
35
|
import { ResourceRegistry } from '../resources/resource-registry.js';
|
|
36
36
|
import { DiscoveredMCPTool } from '../tools/mcp-tool.js';
|
|
37
37
|
import { LSTool } from '../tools/ls.js';
|
|
38
|
-
import { LS_TOOL_NAME, READ_FILE_TOOL_NAME } from '../tools/tool-names.js';
|
|
38
|
+
import { COMPLETE_TASK_TOOL_NAME, LS_TOOL_NAME, READ_FILE_TOOL_NAME, } from '../tools/tool-names.js';
|
|
39
39
|
import { GeminiChat, StreamEventType, } from '../core/geminiChat.js';
|
|
40
40
|
import {} from '@google/genai';
|
|
41
41
|
import { MockTool } from '../test-utils/mock-tool.js';
|
|
@@ -113,6 +113,17 @@ vi.mock('../utils/promptIdContext.js', async (importOriginal) => {
|
|
|
113
113
|
},
|
|
114
114
|
};
|
|
115
115
|
});
|
|
116
|
+
vi.mock('../config/scoped-config.js', async (importOriginal) => {
|
|
117
|
+
const actual = await importOriginal();
|
|
118
|
+
return {
|
|
119
|
+
...actual,
|
|
120
|
+
runWithScopedWorkspaceContext: vi.fn(actual.runWithScopedWorkspaceContext),
|
|
121
|
+
createScopedWorkspaceContext: vi.fn(actual.createScopedWorkspaceContext),
|
|
122
|
+
};
|
|
123
|
+
});
|
|
124
|
+
import { runWithScopedWorkspaceContext, createScopedWorkspaceContext, } from '../config/scoped-config.js';
|
|
125
|
+
const mockedRunWithScopedWorkspaceContext = vi.mocked(runWithScopedWorkspaceContext);
|
|
126
|
+
const mockedCreateScopedWorkspaceContext = vi.mocked(createScopedWorkspaceContext);
|
|
116
127
|
const MockedGeminiChat = vi.mocked(GeminiChat);
|
|
117
128
|
const mockedGetDirectoryContextString = vi.mocked(getDirectoryContextString);
|
|
118
129
|
const mockedPromptIdContext = vi.mocked(promptIdContext);
|
|
@@ -120,8 +131,31 @@ const mockedLogAgentStart = vi.mocked(logAgentStart);
|
|
|
120
131
|
const mockedLogAgentFinish = vi.mocked(logAgentFinish);
|
|
121
132
|
const mockedLogRecoveryAttempt = vi.mocked(logRecoveryAttempt);
|
|
122
133
|
// Constants for testing
|
|
123
|
-
const TASK_COMPLETE_TOOL_NAME = 'complete_task';
|
|
124
134
|
const MOCK_TOOL_NOT_ALLOWED = new MockTool({ name: 'write_file_interactive' });
|
|
135
|
+
/**
|
|
136
|
+
* Helper to mock a successful completion result from the scheduler.
|
|
137
|
+
*/
|
|
138
|
+
const mockCompletionResult = (callId, submittedOutput, toolName = COMPLETE_TASK_TOOL_NAME) => {
|
|
139
|
+
mockScheduleAgentTools.mockResolvedValueOnce([
|
|
140
|
+
{
|
|
141
|
+
status: 'success',
|
|
142
|
+
request: {
|
|
143
|
+
callId,
|
|
144
|
+
name: toolName,
|
|
145
|
+
args: {},
|
|
146
|
+
prompt_id: 'test-prompt',
|
|
147
|
+
},
|
|
148
|
+
response: {
|
|
149
|
+
resultDisplay: 'Task completed.',
|
|
150
|
+
responseParts: [],
|
|
151
|
+
data: {
|
|
152
|
+
taskCompleted: true,
|
|
153
|
+
submittedOutput,
|
|
154
|
+
},
|
|
155
|
+
},
|
|
156
|
+
},
|
|
157
|
+
]);
|
|
158
|
+
};
|
|
125
159
|
/**
|
|
126
160
|
* Helper to create a mock API response chunk.
|
|
127
161
|
* Uses conditional spread to handle readonly functionCalls property safely.
|
|
@@ -212,11 +246,50 @@ describe('LocalAgentExecutor', () => {
|
|
|
212
246
|
vi.resetAllMocks();
|
|
213
247
|
mockCompress.mockClear();
|
|
214
248
|
mockSetHistory.mockClear();
|
|
215
|
-
mockSendMessageStream.mockReset()
|
|
249
|
+
mockSendMessageStream.mockReset().mockResolvedValue({
|
|
250
|
+
async *[Symbol.asyncIterator]() {
|
|
251
|
+
yield {
|
|
252
|
+
type: StreamEventType.CHUNK,
|
|
253
|
+
value: { candidates: [] },
|
|
254
|
+
};
|
|
255
|
+
},
|
|
256
|
+
});
|
|
216
257
|
mockSetSystemInstruction.mockReset();
|
|
217
|
-
mockScheduleAgentTools
|
|
258
|
+
mockScheduleAgentTools
|
|
259
|
+
.mockReset()
|
|
260
|
+
.mockImplementation(async (_config, requests) =>
|
|
261
|
+
// Default mock behavior for scheduleAgentTools
|
|
262
|
+
requests.map((req) => {
|
|
263
|
+
if (req.name === COMPLETE_TASK_TOOL_NAME) {
|
|
264
|
+
return {
|
|
265
|
+
status: 'success',
|
|
266
|
+
request: req,
|
|
267
|
+
response: {
|
|
268
|
+
resultDisplay: 'Task completed.',
|
|
269
|
+
responseParts: [],
|
|
270
|
+
data: {
|
|
271
|
+
taskCompleted: true,
|
|
272
|
+
submittedOutput: req.args['finalResult'] ||
|
|
273
|
+
req.args['result'] ||
|
|
274
|
+
JSON.stringify(req.args),
|
|
275
|
+
},
|
|
276
|
+
},
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
return {
|
|
280
|
+
status: 'success',
|
|
281
|
+
request: req,
|
|
282
|
+
response: {
|
|
283
|
+
resultDisplay: 'Mock tool executed',
|
|
284
|
+
responseParts: [],
|
|
285
|
+
data: {},
|
|
286
|
+
},
|
|
287
|
+
};
|
|
288
|
+
}));
|
|
218
289
|
mockedLogAgentStart.mockReset();
|
|
219
290
|
mockedLogAgentFinish.mockReset();
|
|
291
|
+
mockedRunWithScopedWorkspaceContext.mockClear();
|
|
292
|
+
mockedCreateScopedWorkspaceContext.mockClear();
|
|
220
293
|
mockedPromptIdContext.getStore.mockReset();
|
|
221
294
|
mockedPromptIdContext.run.mockImplementation((_id, fn) => fn());
|
|
222
295
|
ChatCompressionService.mockImplementation(() => ({
|
|
@@ -281,7 +354,7 @@ describe('LocalAgentExecutor', () => {
|
|
|
281
354
|
const executor = await LocalAgentExecutor.create(definition, extendedContext, onActivity);
|
|
282
355
|
mockModelResponse([
|
|
283
356
|
{
|
|
284
|
-
name:
|
|
357
|
+
name: COMPLETE_TASK_TOOL_NAME,
|
|
285
358
|
args: { finalResult: 'done' },
|
|
286
359
|
id: 'call1',
|
|
287
360
|
},
|
|
@@ -336,7 +409,7 @@ describe('LocalAgentExecutor', () => {
|
|
|
336
409
|
const executor = await LocalAgentExecutor.create(definition, context);
|
|
337
410
|
mockModelResponse([
|
|
338
411
|
{
|
|
339
|
-
name:
|
|
412
|
+
name: COMPLETE_TASK_TOOL_NAME,
|
|
340
413
|
args: { finalResult: 'done' },
|
|
341
414
|
id: 'call1',
|
|
342
415
|
},
|
|
@@ -374,7 +447,7 @@ describe('LocalAgentExecutor', () => {
|
|
|
374
447
|
const executor = await LocalAgentExecutor.create(definition, context);
|
|
375
448
|
mockModelResponse([
|
|
376
449
|
{
|
|
377
|
-
name:
|
|
450
|
+
name: COMPLETE_TASK_TOOL_NAME,
|
|
378
451
|
args: { finalResult: 'done' },
|
|
379
452
|
id: 'call1',
|
|
380
453
|
},
|
|
@@ -403,8 +476,12 @@ describe('LocalAgentExecutor', () => {
|
|
|
403
476
|
const executor = await LocalAgentExecutor.create(definition, mockConfig, onActivity);
|
|
404
477
|
const agentRegistry = executor['toolRegistry'];
|
|
405
478
|
expect(agentRegistry).not.toBe(parentToolRegistry);
|
|
406
|
-
expect(agentRegistry.getAllToolNames()).toEqual(expect.arrayContaining([
|
|
407
|
-
|
|
479
|
+
expect(agentRegistry.getAllToolNames()).toEqual(expect.arrayContaining([
|
|
480
|
+
LS_TOOL_NAME,
|
|
481
|
+
READ_FILE_TOOL_NAME,
|
|
482
|
+
COMPLETE_TASK_TOOL_NAME,
|
|
483
|
+
]));
|
|
484
|
+
expect(agentRegistry.getAllToolNames()).toHaveLength(3);
|
|
408
485
|
expect(agentRegistry.getTool(MOCK_TOOL_NOT_ALLOWED.name)).toBeUndefined();
|
|
409
486
|
});
|
|
410
487
|
it('should use parentPromptId from context to create agentId', async () => {
|
|
@@ -430,7 +507,7 @@ describe('LocalAgentExecutor', () => {
|
|
|
430
507
|
// Mock a response to prevent the loop from running forever
|
|
431
508
|
mockModelResponse([
|
|
432
509
|
{
|
|
433
|
-
name:
|
|
510
|
+
name: COMPLETE_TASK_TOOL_NAME,
|
|
434
511
|
args: { finalResult: 'done' },
|
|
435
512
|
id: 'call1',
|
|
436
513
|
},
|
|
@@ -536,6 +613,39 @@ describe('LocalAgentExecutor', () => {
|
|
|
536
613
|
expect(toolNames).toContain(LS_TOOL_NAME);
|
|
537
614
|
});
|
|
538
615
|
});
|
|
616
|
+
describe('run (Workspace Scoping)', () => {
|
|
617
|
+
it('should use runWithScopedWorkspaceContext when workspaceDirectories is set', async () => {
|
|
618
|
+
const definition = createTestDefinition();
|
|
619
|
+
definition.workspaceDirectories = ['/tmp/extra-dir'];
|
|
620
|
+
const executor = await LocalAgentExecutor.create(definition, mockConfig, onActivity);
|
|
621
|
+
// Mock a simple complete_task response so run() terminates
|
|
622
|
+
mockModelResponse([
|
|
623
|
+
{
|
|
624
|
+
name: COMPLETE_TASK_TOOL_NAME,
|
|
625
|
+
args: { finalResult: 'done' },
|
|
626
|
+
id: 'c1',
|
|
627
|
+
},
|
|
628
|
+
]);
|
|
629
|
+
await executor.run({ goal: 'test' }, signal);
|
|
630
|
+
expect(mockedCreateScopedWorkspaceContext).toHaveBeenCalledOnce();
|
|
631
|
+
expect(mockedRunWithScopedWorkspaceContext).toHaveBeenCalledOnce();
|
|
632
|
+
});
|
|
633
|
+
it('should not use runWithScopedWorkspaceContext when workspaceDirectories is not set', async () => {
|
|
634
|
+
const definition = createTestDefinition();
|
|
635
|
+
const executor = await LocalAgentExecutor.create(definition, mockConfig, onActivity);
|
|
636
|
+
// Mock a simple complete_task response so run() terminates
|
|
637
|
+
mockModelResponse([
|
|
638
|
+
{
|
|
639
|
+
name: COMPLETE_TASK_TOOL_NAME,
|
|
640
|
+
args: { finalResult: 'done' },
|
|
641
|
+
id: 'c1',
|
|
642
|
+
},
|
|
643
|
+
]);
|
|
644
|
+
await executor.run({ goal: 'test' }, signal);
|
|
645
|
+
expect(mockedCreateScopedWorkspaceContext).not.toHaveBeenCalled();
|
|
646
|
+
expect(mockedRunWithScopedWorkspaceContext).not.toHaveBeenCalled();
|
|
647
|
+
});
|
|
648
|
+
});
|
|
539
649
|
describe('run (Execution Loop and Logic)', () => {
|
|
540
650
|
it('should log AgentFinish with error if run throws', async () => {
|
|
541
651
|
const definition = createTestDefinition();
|
|
@@ -595,15 +705,43 @@ describe('LocalAgentExecutor', () => {
|
|
|
595
705
|
// Turn 2: Model calls complete_task with required output
|
|
596
706
|
mockModelResponse([
|
|
597
707
|
{
|
|
598
|
-
name:
|
|
708
|
+
name: COMPLETE_TASK_TOOL_NAME,
|
|
599
709
|
args: { finalResult: 'Found file1.txt' },
|
|
600
710
|
id: 'call2',
|
|
601
711
|
},
|
|
602
712
|
], 'T2: Done');
|
|
713
|
+
mockScheduleAgentTools.mockResolvedValueOnce([
|
|
714
|
+
{
|
|
715
|
+
status: 'success',
|
|
716
|
+
request: {
|
|
717
|
+
callId: 'call2',
|
|
718
|
+
name: COMPLETE_TASK_TOOL_NAME,
|
|
719
|
+
args: { finalResult: 'Found file1.txt' },
|
|
720
|
+
prompt_id: 'p1',
|
|
721
|
+
},
|
|
722
|
+
response: {
|
|
723
|
+
resultDisplay: 'Output submitted and task completed.',
|
|
724
|
+
responseParts: [
|
|
725
|
+
{
|
|
726
|
+
functionResponse: {
|
|
727
|
+
name: COMPLETE_TASK_TOOL_NAME,
|
|
728
|
+
id: 'call2',
|
|
729
|
+
response: { result: 'Output submitted and task completed.' },
|
|
730
|
+
},
|
|
731
|
+
},
|
|
732
|
+
],
|
|
733
|
+
data: {
|
|
734
|
+
taskCompleted: true,
|
|
735
|
+
submittedOutput: 'Found file1.txt',
|
|
736
|
+
},
|
|
737
|
+
},
|
|
738
|
+
},
|
|
739
|
+
]);
|
|
603
740
|
const output = await executor.run(inputs, signal);
|
|
604
741
|
expect(mockSendMessageStream).toHaveBeenCalledTimes(2);
|
|
742
|
+
expect(mockScheduleAgentTools).toHaveBeenCalledTimes(2);
|
|
605
743
|
const systemInstruction = MockedGeminiChat.mock.calls[0][1];
|
|
606
|
-
expect(systemInstruction).toContain(`MUST call the \`${
|
|
744
|
+
expect(systemInstruction).toContain(`MUST call the \`${COMPLETE_TASK_TOOL_NAME}\` tool`);
|
|
607
745
|
expect(systemInstruction).toContain('Mocked Environment Context');
|
|
608
746
|
expect(systemInstruction).toContain('You are running in a non-interactive mode');
|
|
609
747
|
expect(systemInstruction).toContain('Always use absolute paths');
|
|
@@ -616,10 +754,11 @@ describe('LocalAgentExecutor', () => {
|
|
|
616
754
|
expect(sentTools).toBeDefined();
|
|
617
755
|
expect(sentTools).toEqual(expect.arrayContaining([
|
|
618
756
|
expect.objectContaining({ name: LS_TOOL_NAME }),
|
|
619
|
-
expect.objectContaining({ name:
|
|
757
|
+
expect.objectContaining({ name: COMPLETE_TASK_TOOL_NAME }),
|
|
620
758
|
]));
|
|
621
|
-
const completeToolDef = sentTools.find((t) => t.name ===
|
|
622
|
-
|
|
759
|
+
const completeToolDef = sentTools.find((t) => t.name === COMPLETE_TASK_TOOL_NAME);
|
|
760
|
+
const completeSchema = completeToolDef?.parametersJsonSchema;
|
|
761
|
+
expect(completeSchema?.['required']).toContain('finalResult');
|
|
623
762
|
expect(output.result).toBe('Found file1.txt');
|
|
624
763
|
expect(output.terminate_reason).toBe(AgentTerminateMode.GOAL);
|
|
625
764
|
// Telemetry checks
|
|
@@ -632,8 +771,8 @@ describe('LocalAgentExecutor', () => {
|
|
|
632
771
|
// Context checks
|
|
633
772
|
expect(mockedPromptIdContext.run).toHaveBeenCalledTimes(2); // Two turns
|
|
634
773
|
// Recording checks
|
|
635
|
-
expect(mockRecordCompletedToolCalls).toHaveBeenCalledTimes(
|
|
636
|
-
expect(mockRecordCompletedToolCalls).
|
|
774
|
+
expect(mockRecordCompletedToolCalls).toHaveBeenCalledTimes(2);
|
|
775
|
+
expect(mockRecordCompletedToolCalls).toHaveBeenNthCalledWith(1, expect.any(String), // model
|
|
637
776
|
expect.arrayContaining([
|
|
638
777
|
expect.objectContaining({
|
|
639
778
|
status: 'success',
|
|
@@ -660,14 +799,14 @@ describe('LocalAgentExecutor', () => {
|
|
|
660
799
|
expect.objectContaining({
|
|
661
800
|
type: 'TOOL_CALL_START',
|
|
662
801
|
data: expect.objectContaining({
|
|
663
|
-
name:
|
|
802
|
+
name: COMPLETE_TASK_TOOL_NAME,
|
|
664
803
|
args: { finalResult: 'Found file1.txt' },
|
|
665
804
|
}),
|
|
666
805
|
}),
|
|
667
806
|
expect.objectContaining({
|
|
668
807
|
type: 'TOOL_CALL_END',
|
|
669
808
|
data: expect.objectContaining({
|
|
670
|
-
name:
|
|
809
|
+
name: COMPLETE_TASK_TOOL_NAME,
|
|
671
810
|
output: expect.stringContaining('Output submitted'),
|
|
672
811
|
}),
|
|
673
812
|
}),
|
|
@@ -711,11 +850,12 @@ describe('LocalAgentExecutor', () => {
|
|
|
711
850
|
]);
|
|
712
851
|
mockModelResponse([
|
|
713
852
|
{
|
|
714
|
-
name:
|
|
853
|
+
name: COMPLETE_TASK_TOOL_NAME,
|
|
715
854
|
args: { result: 'All work done' },
|
|
716
855
|
id: 'call2',
|
|
717
856
|
},
|
|
718
857
|
], 'Task finished.');
|
|
858
|
+
mockCompletionResult('call2', 'All work done');
|
|
719
859
|
const output = await executor.run({ goal: 'Do work' }, signal);
|
|
720
860
|
const { modelConfigKey } = getMockMessageParams(0);
|
|
721
861
|
expect(modelConfigKey.model).toBe(getModelConfigAlias(definition));
|
|
@@ -723,11 +863,13 @@ describe('LocalAgentExecutor', () => {
|
|
|
723
863
|
const passedToolsArg = chatConstructorArgs[2];
|
|
724
864
|
const sentTools = passedToolsArg[0].functionDeclarations;
|
|
725
865
|
expect(sentTools).toBeDefined();
|
|
726
|
-
const completeToolDef = sentTools.find((t) => t.name ===
|
|
727
|
-
|
|
866
|
+
const completeToolDef = sentTools.find((t) => t.name === COMPLETE_TASK_TOOL_NAME);
|
|
867
|
+
const schema = completeToolDef?.parametersJsonSchema;
|
|
868
|
+
expect(schema?.['required']).toContain('result');
|
|
728
869
|
expect(completeToolDef?.description).toContain('submit your final findings');
|
|
729
870
|
expect(output.result).toBe('All work done');
|
|
730
871
|
expect(output.terminate_reason).toBe(AgentTerminateMode.GOAL);
|
|
872
|
+
expect(mockScheduleAgentTools).toHaveBeenCalledTimes(2);
|
|
731
873
|
});
|
|
732
874
|
it('should error immediately if the model stops tools without calling complete_task (Protocol Violation)', async () => {
|
|
733
875
|
const definition = createTestDefinition();
|
|
@@ -771,7 +913,7 @@ describe('LocalAgentExecutor', () => {
|
|
|
771
913
|
mockModelResponse([], 'I still give up.');
|
|
772
914
|
const output = await executor.run({ goal: 'Strict test' }, signal);
|
|
773
915
|
expect(mockSendMessageStream).toHaveBeenCalledTimes(3);
|
|
774
|
-
const expectedError = `Agent stopped calling tools but did not call '${
|
|
916
|
+
const expectedError = `Agent stopped calling tools but did not call '${COMPLETE_TASK_TOOL_NAME}'.`;
|
|
775
917
|
expect(output.terminate_reason).toBe(AgentTerminateMode.ERROR_NO_COMPLETE_TASK_CALL);
|
|
776
918
|
expect(output.result).toBe(expectedError);
|
|
777
919
|
// Telemetry check for error
|
|
@@ -793,27 +935,59 @@ describe('LocalAgentExecutor', () => {
|
|
|
793
935
|
// Turn 1: Missing arg
|
|
794
936
|
mockModelResponse([
|
|
795
937
|
{
|
|
796
|
-
name:
|
|
938
|
+
name: COMPLETE_TASK_TOOL_NAME,
|
|
797
939
|
args: { wrongArg: 'oops' },
|
|
798
940
|
id: 'call1',
|
|
799
941
|
},
|
|
800
942
|
]);
|
|
943
|
+
// Mock failure in scheduler for Turn 1
|
|
944
|
+
mockScheduleAgentTools.mockResolvedValueOnce([
|
|
945
|
+
{
|
|
946
|
+
status: 'error',
|
|
947
|
+
request: {
|
|
948
|
+
callId: 'call1',
|
|
949
|
+
name: COMPLETE_TASK_TOOL_NAME,
|
|
950
|
+
args: { wrongArg: 'oops' },
|
|
951
|
+
prompt_id: 'p1',
|
|
952
|
+
},
|
|
953
|
+
response: {
|
|
954
|
+
resultDisplay: 'Error',
|
|
955
|
+
responseParts: [
|
|
956
|
+
{
|
|
957
|
+
functionResponse: {
|
|
958
|
+
name: COMPLETE_TASK_TOOL_NAME,
|
|
959
|
+
id: 'call1',
|
|
960
|
+
response: {
|
|
961
|
+
error: "Missing required argument 'finalResult' for completion.",
|
|
962
|
+
},
|
|
963
|
+
},
|
|
964
|
+
},
|
|
965
|
+
],
|
|
966
|
+
error: {
|
|
967
|
+
message: "Missing required argument 'finalResult' for completion.",
|
|
968
|
+
type: 'INVALID_TOOL_PARAMS',
|
|
969
|
+
},
|
|
970
|
+
},
|
|
971
|
+
},
|
|
972
|
+
]);
|
|
801
973
|
// Turn 2: Corrected
|
|
802
974
|
mockModelResponse([
|
|
803
975
|
{
|
|
804
|
-
name:
|
|
976
|
+
name: COMPLETE_TASK_TOOL_NAME,
|
|
805
977
|
args: { finalResult: 'Corrected result' },
|
|
806
978
|
id: 'call2',
|
|
807
979
|
},
|
|
808
980
|
]);
|
|
981
|
+
mockCompletionResult('call2', 'Corrected result');
|
|
809
982
|
const output = await executor.run({ goal: 'Error test' }, signal);
|
|
810
983
|
expect(mockSendMessageStream).toHaveBeenCalledTimes(2);
|
|
984
|
+
expect(mockScheduleAgentTools).toHaveBeenCalledTimes(2);
|
|
811
985
|
const expectedError = "Missing required argument 'finalResult' for completion.";
|
|
812
986
|
expect(activities).toContainEqual(expect.objectContaining({
|
|
813
987
|
type: 'ERROR',
|
|
814
988
|
data: expect.objectContaining({
|
|
815
989
|
context: 'tool_call',
|
|
816
|
-
name:
|
|
990
|
+
name: COMPLETE_TASK_TOOL_NAME,
|
|
817
991
|
error: expectedError,
|
|
818
992
|
errorType: SubagentActivityErrorType.GENERIC,
|
|
819
993
|
}),
|
|
@@ -824,7 +998,7 @@ describe('LocalAgentExecutor', () => {
|
|
|
824
998
|
expect(turn2Parts).toHaveLength(1);
|
|
825
999
|
expect(turn2Parts[0]).toEqual(expect.objectContaining({
|
|
826
1000
|
functionResponse: expect.objectContaining({
|
|
827
|
-
name:
|
|
1001
|
+
name: COMPLETE_TASK_TOOL_NAME,
|
|
828
1002
|
response: { error: expectedError },
|
|
829
1003
|
id: 'call1',
|
|
830
1004
|
}),
|
|
@@ -832,31 +1006,61 @@ describe('LocalAgentExecutor', () => {
|
|
|
832
1006
|
expect(output.result).toBe('Corrected result');
|
|
833
1007
|
expect(output.terminate_reason).toBe(AgentTerminateMode.GOAL);
|
|
834
1008
|
});
|
|
835
|
-
it('should handle multiple calls to complete_task in the same turn
|
|
1009
|
+
it('should handle multiple calls to complete_task in the same turn', async () => {
|
|
836
1010
|
const definition = createTestDefinition([], {}, 'none');
|
|
837
1011
|
const executor = await LocalAgentExecutor.create(definition, mockConfig, onActivity);
|
|
838
1012
|
// Turn 1: Duplicate calls
|
|
839
1013
|
mockModelResponse([
|
|
840
1014
|
{
|
|
841
|
-
name:
|
|
842
|
-
args: { result: '
|
|
1015
|
+
name: COMPLETE_TASK_TOOL_NAME,
|
|
1016
|
+
args: { result: 'first' },
|
|
843
1017
|
id: 'call1',
|
|
844
1018
|
},
|
|
845
1019
|
{
|
|
846
|
-
name:
|
|
847
|
-
args: { result: '
|
|
1020
|
+
name: COMPLETE_TASK_TOOL_NAME,
|
|
1021
|
+
args: { result: 'second' },
|
|
848
1022
|
id: 'call2',
|
|
849
1023
|
},
|
|
850
1024
|
]);
|
|
1025
|
+
mockScheduleAgentTools.mockResolvedValueOnce([
|
|
1026
|
+
{
|
|
1027
|
+
status: 'success',
|
|
1028
|
+
request: {
|
|
1029
|
+
callId: 'call1',
|
|
1030
|
+
name: COMPLETE_TASK_TOOL_NAME,
|
|
1031
|
+
args: { result: 'first' },
|
|
1032
|
+
prompt_id: 'p1',
|
|
1033
|
+
},
|
|
1034
|
+
response: {
|
|
1035
|
+
resultDisplay: 'ok',
|
|
1036
|
+
responseParts: [],
|
|
1037
|
+
data: { taskCompleted: true, submittedOutput: 'first' },
|
|
1038
|
+
},
|
|
1039
|
+
},
|
|
1040
|
+
{
|
|
1041
|
+
status: 'success',
|
|
1042
|
+
request: {
|
|
1043
|
+
callId: 'call2',
|
|
1044
|
+
name: COMPLETE_TASK_TOOL_NAME,
|
|
1045
|
+
args: { result: 'second' },
|
|
1046
|
+
prompt_id: 'p1',
|
|
1047
|
+
},
|
|
1048
|
+
response: {
|
|
1049
|
+
resultDisplay: 'ok',
|
|
1050
|
+
responseParts: [],
|
|
1051
|
+
data: { taskCompleted: true, submittedOutput: 'second' },
|
|
1052
|
+
},
|
|
1053
|
+
},
|
|
1054
|
+
]);
|
|
851
1055
|
const output = await executor.run({ goal: 'Dup test' }, signal);
|
|
852
1056
|
expect(mockSendMessageStream).toHaveBeenCalledTimes(1);
|
|
1057
|
+
expect(mockScheduleAgentTools).toHaveBeenCalledTimes(1);
|
|
853
1058
|
expect(output.terminate_reason).toBe(AgentTerminateMode.GOAL);
|
|
1059
|
+
// In current impl, the first successful complete_task in the batch is respected.
|
|
1060
|
+
expect(output.result).toBe('first');
|
|
854
1061
|
const completions = activities.filter((a) => a.type === 'TOOL_CALL_END' &&
|
|
855
|
-
a.data['name'] ===
|
|
856
|
-
|
|
857
|
-
expect(completions).toHaveLength(1);
|
|
858
|
-
expect(errors).toHaveLength(1);
|
|
859
|
-
expect(errors[0].data['error']).toContain('Task already marked complete in this turn');
|
|
1062
|
+
a.data['name'] === COMPLETE_TASK_TOOL_NAME);
|
|
1063
|
+
expect(completions).toHaveLength(2);
|
|
860
1064
|
});
|
|
861
1065
|
it('should execute parallel tool calls and then complete', async () => {
|
|
862
1066
|
const definition = createTestDefinition([LS_TOOL_NAME]);
|
|
@@ -881,39 +1085,57 @@ describe('LocalAgentExecutor', () => {
|
|
|
881
1085
|
});
|
|
882
1086
|
mockScheduleAgentTools.mockImplementation(async (_ctx, requests) => {
|
|
883
1087
|
const results = await Promise.all(requests.map(async (reqInfo) => {
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
1088
|
+
if (reqInfo.name === LS_TOOL_NAME) {
|
|
1089
|
+
callsStarted++;
|
|
1090
|
+
if (callsStarted === 2)
|
|
1091
|
+
resolveCalls();
|
|
1092
|
+
await vi.advanceTimersByTimeAsync(100);
|
|
1093
|
+
return {
|
|
1094
|
+
status: CoreToolCallStatus.Success,
|
|
1095
|
+
request: reqInfo,
|
|
1096
|
+
tool: {},
|
|
1097
|
+
invocation: {},
|
|
1098
|
+
response: {
|
|
1099
|
+
callId: reqInfo.callId,
|
|
1100
|
+
resultDisplay: 'ok',
|
|
1101
|
+
responseParts: [
|
|
1102
|
+
{
|
|
1103
|
+
functionResponse: {
|
|
1104
|
+
name: reqInfo.name,
|
|
1105
|
+
response: {},
|
|
1106
|
+
id: reqInfo.callId,
|
|
1107
|
+
},
|
|
902
1108
|
},
|
|
1109
|
+
],
|
|
1110
|
+
error: undefined,
|
|
1111
|
+
errorType: undefined,
|
|
1112
|
+
contentLength: 0,
|
|
1113
|
+
},
|
|
1114
|
+
};
|
|
1115
|
+
}
|
|
1116
|
+
else if (reqInfo.name === COMPLETE_TASK_TOOL_NAME) {
|
|
1117
|
+
return {
|
|
1118
|
+
status: CoreToolCallStatus.Success,
|
|
1119
|
+
request: reqInfo,
|
|
1120
|
+
response: {
|
|
1121
|
+
callId: reqInfo.callId,
|
|
1122
|
+
resultDisplay: 'Task completed.',
|
|
1123
|
+
responseParts: [],
|
|
1124
|
+
data: {
|
|
1125
|
+
taskCompleted: true,
|
|
1126
|
+
submittedOutput: reqInfo.args['finalResult'],
|
|
903
1127
|
},
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
},
|
|
909
|
-
};
|
|
1128
|
+
},
|
|
1129
|
+
};
|
|
1130
|
+
}
|
|
1131
|
+
throw new Error(`Unexpected tool: ${reqInfo.name}`);
|
|
910
1132
|
}));
|
|
911
1133
|
return results;
|
|
912
1134
|
});
|
|
913
1135
|
// Turn 2: Completion
|
|
914
1136
|
mockModelResponse([
|
|
915
1137
|
{
|
|
916
|
-
name:
|
|
1138
|
+
name: COMPLETE_TASK_TOOL_NAME,
|
|
917
1139
|
args: { finalResult: 'done' },
|
|
918
1140
|
id: 'c3',
|
|
919
1141
|
},
|
|
@@ -924,7 +1146,7 @@ describe('LocalAgentExecutor', () => {
|
|
|
924
1146
|
await vi.advanceTimersByTimeAsync(150);
|
|
925
1147
|
await vi.advanceTimersByTimeAsync(1);
|
|
926
1148
|
const output = await runPromise;
|
|
927
|
-
expect(mockScheduleAgentTools).toHaveBeenCalledTimes(
|
|
1149
|
+
expect(mockScheduleAgentTools).toHaveBeenCalledTimes(2);
|
|
928
1150
|
expect(output.terminate_reason).toBe(AgentTerminateMode.GOAL);
|
|
929
1151
|
// Safe access to message parts
|
|
930
1152
|
const turn2Params = getMockMessageParams(1);
|
|
@@ -955,7 +1177,7 @@ describe('LocalAgentExecutor', () => {
|
|
|
955
1177
|
// Turn 2: Model gives up and completes
|
|
956
1178
|
mockModelResponse([
|
|
957
1179
|
{
|
|
958
|
-
name:
|
|
1180
|
+
name: COMPLETE_TASK_TOOL_NAME,
|
|
959
1181
|
args: { finalResult: 'Could not read file.' },
|
|
960
1182
|
id: 'c2',
|
|
961
1183
|
},
|
|
@@ -963,9 +1185,28 @@ describe('LocalAgentExecutor', () => {
|
|
|
963
1185
|
const consoleWarnSpy = vi
|
|
964
1186
|
.spyOn(debugLogger, 'warn')
|
|
965
1187
|
.mockImplementation(() => { });
|
|
1188
|
+
mockScheduleAgentTools.mockResolvedValueOnce([
|
|
1189
|
+
{
|
|
1190
|
+
status: 'success',
|
|
1191
|
+
request: {
|
|
1192
|
+
callId: 'c2',
|
|
1193
|
+
name: COMPLETE_TASK_TOOL_NAME,
|
|
1194
|
+
args: { finalResult: 'Could not read file.' },
|
|
1195
|
+
prompt_id: 'p2',
|
|
1196
|
+
},
|
|
1197
|
+
response: {
|
|
1198
|
+
resultDisplay: 'Output submitted and task completed.',
|
|
1199
|
+
responseParts: [],
|
|
1200
|
+
data: {
|
|
1201
|
+
taskCompleted: true,
|
|
1202
|
+
submittedOutput: 'Could not read file.',
|
|
1203
|
+
},
|
|
1204
|
+
},
|
|
1205
|
+
},
|
|
1206
|
+
]);
|
|
966
1207
|
await executor.run({ goal: 'Sec test' }, signal);
|
|
967
|
-
// Verify external executor was
|
|
968
|
-
expect(mockScheduleAgentTools).
|
|
1208
|
+
// Verify external executor was called exactly once (for complete_task)
|
|
1209
|
+
expect(mockScheduleAgentTools).toHaveBeenCalledTimes(1);
|
|
969
1210
|
// 2. Verify console warning
|
|
970
1211
|
expect(consoleWarnSpy).toHaveBeenCalledWith(expect.stringContaining(`[LocalAgentExecutor] Blocked call:`));
|
|
971
1212
|
consoleWarnSpy.mockRestore();
|
|
@@ -1000,28 +1241,53 @@ describe('LocalAgentExecutor', () => {
|
|
|
1000
1241
|
// Turn 1: Invalid arg (too short)
|
|
1001
1242
|
mockModelResponse([
|
|
1002
1243
|
{
|
|
1003
|
-
name:
|
|
1244
|
+
name: COMPLETE_TASK_TOOL_NAME,
|
|
1004
1245
|
args: { finalResult: 'short' },
|
|
1005
1246
|
id: 'call1',
|
|
1006
1247
|
},
|
|
1007
1248
|
]);
|
|
1249
|
+
const expectedError = 'Output validation failed: {"formErrors":["String must contain at least 10 character(s)"],"fieldErrors":{}}';
|
|
1250
|
+
mockScheduleAgentTools.mockResolvedValueOnce([
|
|
1251
|
+
{
|
|
1252
|
+
status: 'error',
|
|
1253
|
+
request: {
|
|
1254
|
+
callId: 'call1',
|
|
1255
|
+
name: COMPLETE_TASK_TOOL_NAME,
|
|
1256
|
+
args: { finalResult: 'short' },
|
|
1257
|
+
prompt_id: 'p1',
|
|
1258
|
+
},
|
|
1259
|
+
response: {
|
|
1260
|
+
resultDisplay: expectedError,
|
|
1261
|
+
responseParts: [
|
|
1262
|
+
{
|
|
1263
|
+
functionResponse: {
|
|
1264
|
+
name: COMPLETE_TASK_TOOL_NAME,
|
|
1265
|
+
id: 'call1',
|
|
1266
|
+
response: { error: expectedError },
|
|
1267
|
+
},
|
|
1268
|
+
},
|
|
1269
|
+
],
|
|
1270
|
+
data: { taskCompleted: false },
|
|
1271
|
+
error: new Error(expectedError),
|
|
1272
|
+
},
|
|
1273
|
+
},
|
|
1274
|
+
]);
|
|
1008
1275
|
// Turn 2: Corrected
|
|
1009
1276
|
mockModelResponse([
|
|
1010
1277
|
{
|
|
1011
|
-
name:
|
|
1278
|
+
name: COMPLETE_TASK_TOOL_NAME,
|
|
1012
1279
|
args: { finalResult: 'This is a much longer and valid result' },
|
|
1013
1280
|
id: 'call2',
|
|
1014
1281
|
},
|
|
1015
1282
|
]);
|
|
1016
1283
|
const output = await executor.run({ goal: 'Validation test' }, signal);
|
|
1017
1284
|
expect(mockSendMessageStream).toHaveBeenCalledTimes(2);
|
|
1018
|
-
const expectedError = 'Output validation failed: {"formErrors":["String must contain at least 10 character(s)"],"fieldErrors":{}}';
|
|
1019
1285
|
// Check that the error was reported in the activity stream
|
|
1020
1286
|
expect(activities).toContainEqual(expect.objectContaining({
|
|
1021
1287
|
type: 'ERROR',
|
|
1022
1288
|
data: expect.objectContaining({
|
|
1023
1289
|
context: 'tool_call',
|
|
1024
|
-
name:
|
|
1290
|
+
name: COMPLETE_TASK_TOOL_NAME,
|
|
1025
1291
|
error: expect.stringContaining('Output validation failed'),
|
|
1026
1292
|
errorType: SubagentActivityErrorType.GENERIC,
|
|
1027
1293
|
}),
|
|
@@ -1032,7 +1298,7 @@ describe('LocalAgentExecutor', () => {
|
|
|
1032
1298
|
expect(turn2Parts).toEqual([
|
|
1033
1299
|
expect.objectContaining({
|
|
1034
1300
|
functionResponse: expect.objectContaining({
|
|
1035
|
-
name:
|
|
1301
|
+
name: COMPLETE_TASK_TOOL_NAME,
|
|
1036
1302
|
response: { error: expectedError },
|
|
1037
1303
|
id: 'call1',
|
|
1038
1304
|
}),
|
|
@@ -1105,13 +1371,32 @@ describe('LocalAgentExecutor', () => {
|
|
|
1105
1371
|
// Turn 2: Model sees the error and completes
|
|
1106
1372
|
mockModelResponse([
|
|
1107
1373
|
{
|
|
1108
|
-
name:
|
|
1374
|
+
name: COMPLETE_TASK_TOOL_NAME,
|
|
1109
1375
|
args: { finalResult: 'Aborted due to tool failure.' },
|
|
1110
1376
|
id: 'call2',
|
|
1111
1377
|
},
|
|
1112
1378
|
]);
|
|
1379
|
+
mockScheduleAgentTools.mockResolvedValueOnce([
|
|
1380
|
+
{
|
|
1381
|
+
status: 'success',
|
|
1382
|
+
request: {
|
|
1383
|
+
callId: 'call2',
|
|
1384
|
+
name: COMPLETE_TASK_TOOL_NAME,
|
|
1385
|
+
args: { finalResult: 'Aborted due to tool failure.' },
|
|
1386
|
+
prompt_id: 'p2',
|
|
1387
|
+
},
|
|
1388
|
+
response: {
|
|
1389
|
+
resultDisplay: 'Task completed.',
|
|
1390
|
+
responseParts: [],
|
|
1391
|
+
data: {
|
|
1392
|
+
taskCompleted: true,
|
|
1393
|
+
submittedOutput: 'Aborted due to tool failure.',
|
|
1394
|
+
},
|
|
1395
|
+
},
|
|
1396
|
+
},
|
|
1397
|
+
]);
|
|
1113
1398
|
const output = await executor.run({ goal: 'Tool failure test' }, signal);
|
|
1114
|
-
expect(mockScheduleAgentTools).toHaveBeenCalledTimes(
|
|
1399
|
+
expect(mockScheduleAgentTools).toHaveBeenCalledTimes(2);
|
|
1115
1400
|
expect(mockSendMessageStream).toHaveBeenCalledTimes(2);
|
|
1116
1401
|
// Verify the error was reported in the activity stream
|
|
1117
1402
|
expect(activities).toContainEqual(expect.objectContaining({
|
|
@@ -1183,7 +1468,7 @@ describe('LocalAgentExecutor', () => {
|
|
|
1183
1468
|
// Turn 2: Model sees the rejection + consolidated instructions and completes
|
|
1184
1469
|
mockModelResponse([
|
|
1185
1470
|
{
|
|
1186
|
-
name:
|
|
1471
|
+
name: COMPLETE_TASK_TOOL_NAME,
|
|
1187
1472
|
args: { finalResult: 'User rejected access to /secret.' },
|
|
1188
1473
|
id: 'call2',
|
|
1189
1474
|
},
|
|
@@ -1283,7 +1568,7 @@ describe('LocalAgentExecutor', () => {
|
|
|
1283
1568
|
const executor = await LocalAgentExecutor.create(definition, mockConfig, onActivity);
|
|
1284
1569
|
mockModelResponse([
|
|
1285
1570
|
{
|
|
1286
|
-
name:
|
|
1571
|
+
name: COMPLETE_TASK_TOOL_NAME,
|
|
1287
1572
|
args: { finalResult: 'done' },
|
|
1288
1573
|
id: 'call1',
|
|
1289
1574
|
},
|
|
@@ -1307,7 +1592,7 @@ describe('LocalAgentExecutor', () => {
|
|
|
1307
1592
|
const executor = await LocalAgentExecutor.create(definition, mockConfig, onActivity);
|
|
1308
1593
|
mockModelResponse([
|
|
1309
1594
|
{
|
|
1310
|
-
name:
|
|
1595
|
+
name: COMPLETE_TASK_TOOL_NAME,
|
|
1311
1596
|
args: { finalResult: 'done' },
|
|
1312
1597
|
id: 'call1',
|
|
1313
1598
|
},
|
|
@@ -1487,7 +1772,7 @@ describe('LocalAgentExecutor', () => {
|
|
|
1487
1772
|
// Recovery Turn (succeeds)
|
|
1488
1773
|
mockModelResponse([
|
|
1489
1774
|
{
|
|
1490
|
-
name:
|
|
1775
|
+
name: COMPLETE_TASK_TOOL_NAME,
|
|
1491
1776
|
args: { finalResult: 'Recovered!' },
|
|
1492
1777
|
id: 't2',
|
|
1493
1778
|
},
|
|
@@ -1542,7 +1827,7 @@ describe('LocalAgentExecutor', () => {
|
|
|
1542
1827
|
// Turn 3: Recovery turn (succeeds)
|
|
1543
1828
|
mockModelResponse([
|
|
1544
1829
|
{
|
|
1545
|
-
name:
|
|
1830
|
+
name: COMPLETE_TASK_TOOL_NAME,
|
|
1546
1831
|
args: { finalResult: 'Recovered from violation!' },
|
|
1547
1832
|
id: 't3',
|
|
1548
1833
|
},
|
|
@@ -1570,7 +1855,7 @@ describe('LocalAgentExecutor', () => {
|
|
|
1570
1855
|
const output = await executor.run({ goal: 'Violation recovery fail' }, signal);
|
|
1571
1856
|
expect(mockSendMessageStream).toHaveBeenCalledTimes(3);
|
|
1572
1857
|
expect(output.terminate_reason).toBe(AgentTerminateMode.ERROR_NO_COMPLETE_TASK_CALL);
|
|
1573
|
-
expect(output.result).toContain(`Agent stopped calling tools but did not call '${
|
|
1858
|
+
expect(output.result).toContain(`Agent stopped calling tools but did not call '${COMPLETE_TASK_TOOL_NAME}'`);
|
|
1574
1859
|
expect(activities).toContainEqual(expect.objectContaining({
|
|
1575
1860
|
type: 'ERROR',
|
|
1576
1861
|
data: expect.objectContaining({
|
|
@@ -1599,7 +1884,7 @@ describe('LocalAgentExecutor', () => {
|
|
|
1599
1884
|
// Recovery turn (succeeds)
|
|
1600
1885
|
mockModelResponse([
|
|
1601
1886
|
{
|
|
1602
|
-
name:
|
|
1887
|
+
name: COMPLETE_TASK_TOOL_NAME,
|
|
1603
1888
|
args: { finalResult: 'Recovered from timeout!' },
|
|
1604
1889
|
id: 't2',
|
|
1605
1890
|
},
|
|
@@ -1721,7 +2006,7 @@ describe('LocalAgentExecutor', () => {
|
|
|
1721
2006
|
// Recovery Turn (succeeds)
|
|
1722
2007
|
mockModelResponse([
|
|
1723
2008
|
{
|
|
1724
|
-
name:
|
|
2009
|
+
name: COMPLETE_TASK_TOOL_NAME,
|
|
1725
2010
|
args: { finalResult: 'Recovered!' },
|
|
1726
2011
|
id: 't2',
|
|
1727
2012
|
},
|
|
@@ -1759,7 +2044,7 @@ describe('LocalAgentExecutor', () => {
|
|
|
1759
2044
|
// Turn 2: Model calls complete_task
|
|
1760
2045
|
mockModelResponse([
|
|
1761
2046
|
{
|
|
1762
|
-
name:
|
|
2047
|
+
name: COMPLETE_TASK_TOOL_NAME,
|
|
1763
2048
|
args: { finalResult: 'Done' },
|
|
1764
2049
|
id: 'call2',
|
|
1765
2050
|
},
|
|
@@ -1811,7 +2096,7 @@ describe('LocalAgentExecutor', () => {
|
|
|
1811
2096
|
const executor = await LocalAgentExecutor.create(definition, configWithHints);
|
|
1812
2097
|
mockModelResponse([
|
|
1813
2098
|
{
|
|
1814
|
-
name:
|
|
2099
|
+
name: COMPLETE_TASK_TOOL_NAME,
|
|
1815
2100
|
args: { finalResult: 'Done' },
|
|
1816
2101
|
id: 'call1',
|
|
1817
2102
|
},
|
|
@@ -1841,7 +2126,7 @@ describe('LocalAgentExecutor', () => {
|
|
|
1841
2126
|
// Turn 2: Model calls complete_task
|
|
1842
2127
|
mockModelResponse([
|
|
1843
2128
|
{
|
|
1844
|
-
name:
|
|
2129
|
+
name: COMPLETE_TASK_TOOL_NAME,
|
|
1845
2130
|
args: { finalResult: 'Done' },
|
|
1846
2131
|
id: 'call2',
|
|
1847
2132
|
},
|
|
@@ -1909,7 +2194,7 @@ describe('LocalAgentExecutor', () => {
|
|
|
1909
2194
|
mockScheduleAgentTools.mockReturnValueOnce(toolCallPromise);
|
|
1910
2195
|
mockModelResponse([
|
|
1911
2196
|
{
|
|
1912
|
-
name:
|
|
2197
|
+
name: COMPLETE_TASK_TOOL_NAME,
|
|
1913
2198
|
args: { finalResult: 'Done' },
|
|
1914
2199
|
id: 'call2',
|
|
1915
2200
|
},
|
|
@@ -1964,7 +2249,7 @@ describe('LocalAgentExecutor', () => {
|
|
|
1964
2249
|
mockScheduleAgentTools.mockReturnValueOnce(toolCallPromise);
|
|
1965
2250
|
mockModelResponse([
|
|
1966
2251
|
{
|
|
1967
|
-
name:
|
|
2252
|
+
name: COMPLETE_TASK_TOOL_NAME,
|
|
1968
2253
|
args: { finalResult: 'Done' },
|
|
1969
2254
|
id: 'call2',
|
|
1970
2255
|
},
|
|
@@ -2018,7 +2303,7 @@ describe('LocalAgentExecutor', () => {
|
|
|
2018
2303
|
expect(configWithHints.injectionService.getInjections('background_completion')).toEqual(['bg output']);
|
|
2019
2304
|
mockModelResponse([
|
|
2020
2305
|
{
|
|
2021
|
-
name:
|
|
2306
|
+
name: COMPLETE_TASK_TOOL_NAME,
|
|
2022
2307
|
args: { finalResult: 'Done' },
|
|
2023
2308
|
id: 'call1',
|
|
2024
2309
|
},
|
|
@@ -2074,7 +2359,7 @@ describe('LocalAgentExecutor', () => {
|
|
|
2074
2359
|
// Turn 2: Complete
|
|
2075
2360
|
mockModelResponse([
|
|
2076
2361
|
{
|
|
2077
|
-
name:
|
|
2362
|
+
name: COMPLETE_TASK_TOOL_NAME,
|
|
2078
2363
|
args: { finalResult: 'Done' },
|
|
2079
2364
|
id: 'call2',
|
|
2080
2365
|
},
|
|
@@ -2095,7 +2380,7 @@ describe('LocalAgentExecutor', () => {
|
|
|
2095
2380
|
// Turn 1: Complete
|
|
2096
2381
|
mockModelResponse([
|
|
2097
2382
|
{
|
|
2098
|
-
name:
|
|
2383
|
+
name: COMPLETE_TASK_TOOL_NAME,
|
|
2099
2384
|
args: { finalResult: 'Done' },
|
|
2100
2385
|
id: 'call1',
|
|
2101
2386
|
},
|
|
@@ -2125,7 +2410,7 @@ describe('LocalAgentExecutor', () => {
|
|
|
2125
2410
|
// Turn 2: Complete
|
|
2126
2411
|
mockModelResponse([
|
|
2127
2412
|
{
|
|
2128
|
-
name:
|
|
2413
|
+
name: COMPLETE_TASK_TOOL_NAME,
|
|
2129
2414
|
args: { finalResult: 'Done' },
|
|
2130
2415
|
id: 't2',
|
|
2131
2416
|
},
|
|
@@ -2167,7 +2452,7 @@ describe('LocalAgentExecutor', () => {
|
|
|
2167
2452
|
// Turn 3: Complete
|
|
2168
2453
|
mockModelResponse([
|
|
2169
2454
|
{
|
|
2170
|
-
name:
|
|
2455
|
+
name: COMPLETE_TASK_TOOL_NAME,
|
|
2171
2456
|
args: { finalResult: 'Done' },
|
|
2172
2457
|
id: 't3',
|
|
2173
2458
|
},
|
|
@@ -2283,7 +2568,7 @@ describe('LocalAgentExecutor', () => {
|
|
|
2283
2568
|
]);
|
|
2284
2569
|
mockModelResponse([
|
|
2285
2570
|
{
|
|
2286
|
-
name:
|
|
2571
|
+
name: COMPLETE_TASK_TOOL_NAME,
|
|
2287
2572
|
args: { finalResult: 'done' },
|
|
2288
2573
|
id: 'c1',
|
|
2289
2574
|
},
|
|
@@ -2342,7 +2627,7 @@ describe('LocalAgentExecutor', () => {
|
|
|
2342
2627
|
};
|
|
2343
2628
|
mockModelResponse([
|
|
2344
2629
|
{
|
|
2345
|
-
name:
|
|
2630
|
+
name: COMPLETE_TASK_TOOL_NAME,
|
|
2346
2631
|
args: { finalResult: 'ok' },
|
|
2347
2632
|
id: 'c1',
|
|
2348
2633
|
},
|
|
@@ -2353,7 +2638,7 @@ describe('LocalAgentExecutor', () => {
|
|
|
2353
2638
|
const names = declarations.map((d) => d.name);
|
|
2354
2639
|
expect(names.filter((n) => n === LS_TOOL_NAME)).toHaveLength(1);
|
|
2355
2640
|
expect(names.filter((n) => n === 'fill')).toHaveLength(1);
|
|
2356
|
-
expect(names.filter((n) => n ===
|
|
2641
|
+
expect(names.filter((n) => n === COMPLETE_TASK_TOOL_NAME)).toHaveLength(1);
|
|
2357
2642
|
// Total = ls + fill + complete_task
|
|
2358
2643
|
expect(declarations).toHaveLength(3);
|
|
2359
2644
|
});
|
|
@@ -2401,7 +2686,7 @@ describe('LocalAgentExecutor', () => {
|
|
|
2401
2686
|
// Turn 2: Model completes
|
|
2402
2687
|
mockModelResponse([
|
|
2403
2688
|
{
|
|
2404
|
-
name:
|
|
2689
|
+
name: COMPLETE_TASK_TOOL_NAME,
|
|
2405
2690
|
args: { finalResult: 'done' },
|
|
2406
2691
|
id: 'call-done',
|
|
2407
2692
|
},
|
|
@@ -2420,7 +2705,7 @@ describe('LocalAgentExecutor', () => {
|
|
|
2420
2705
|
const definition = createInstanceToolDefinition([new MockTool({ name: 'take_snapshot' })], 'none');
|
|
2421
2706
|
mockModelResponse([
|
|
2422
2707
|
{
|
|
2423
|
-
name:
|
|
2708
|
+
name: COMPLETE_TASK_TOOL_NAME,
|
|
2424
2709
|
args: { result: 'done' },
|
|
2425
2710
|
id: 'c1',
|
|
2426
2711
|
},
|
|
@@ -2429,7 +2714,7 @@ describe('LocalAgentExecutor', () => {
|
|
|
2429
2714
|
await executor.run({ goal: 'Test' }, signal);
|
|
2430
2715
|
const declarations = getSentFunctionDeclarations();
|
|
2431
2716
|
const names = declarations.map((d) => d.name);
|
|
2432
|
-
expect(names).toContain(
|
|
2717
|
+
expect(names).toContain(COMPLETE_TASK_TOOL_NAME);
|
|
2433
2718
|
expect(names).toContain('take_snapshot');
|
|
2434
2719
|
expect(declarations).toHaveLength(2);
|
|
2435
2720
|
});
|
|
@@ -2455,7 +2740,7 @@ describe('LocalAgentExecutor', () => {
|
|
|
2455
2740
|
const definition = createInstanceToolDefinition(instanceTools);
|
|
2456
2741
|
mockModelResponse([
|
|
2457
2742
|
{
|
|
2458
|
-
name:
|
|
2743
|
+
name: COMPLETE_TASK_TOOL_NAME,
|
|
2459
2744
|
args: { finalResult: 'done' },
|
|
2460
2745
|
id: 'c1',
|
|
2461
2746
|
},
|
|
@@ -2483,7 +2768,7 @@ describe('LocalAgentExecutor', () => {
|
|
|
2483
2768
|
vi.spyOn(mockConfig, 'getSystemInstructionMemory').mockReturnValue(mockMemory);
|
|
2484
2769
|
mockModelResponse([
|
|
2485
2770
|
{
|
|
2486
|
-
name:
|
|
2771
|
+
name: COMPLETE_TASK_TOOL_NAME,
|
|
2487
2772
|
args: { finalResult: 'done' },
|
|
2488
2773
|
id: 'call1',
|
|
2489
2774
|
},
|
|
@@ -2502,7 +2787,7 @@ describe('LocalAgentExecutor', () => {
|
|
|
2502
2787
|
vi.spyOn(mockConfig, 'isJitContextEnabled').mockReturnValue(false);
|
|
2503
2788
|
mockModelResponse([
|
|
2504
2789
|
{
|
|
2505
|
-
name:
|
|
2790
|
+
name: COMPLETE_TASK_TOOL_NAME,
|
|
2506
2791
|
args: { finalResult: 'done' },
|
|
2507
2792
|
id: 'call1',
|
|
2508
2793
|
},
|
|
@@ -2523,7 +2808,7 @@ describe('LocalAgentExecutor', () => {
|
|
|
2523
2808
|
vi.spyOn(mockConfig, 'isJitContextEnabled').mockReturnValue(true);
|
|
2524
2809
|
mockModelResponse([
|
|
2525
2810
|
{
|
|
2526
|
-
name:
|
|
2811
|
+
name: COMPLETE_TASK_TOOL_NAME,
|
|
2527
2812
|
args: { finalResult: 'done' },
|
|
2528
2813
|
id: 'call1',
|
|
2529
2814
|
},
|