@google/gemini-cli-core 0.24.0-preview.3 → 0.25.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 +1 -1
- package/dist/docs/assets/monitoring-dashboard-logs.png +0 -0
- package/dist/docs/assets/monitoring-dashboard-metrics.png +0 -0
- package/dist/docs/assets/monitoring-dashboard-overview.png +0 -0
- package/dist/docs/changelogs/index.md +22 -0
- package/dist/docs/changelogs/latest.md +137 -209
- package/dist/docs/changelogs/preview.md +116 -114
- package/dist/docs/changelogs/releases.md +273 -7
- package/dist/docs/cli/commands.md +3 -0
- package/dist/docs/cli/keyboard-shortcuts.md +34 -41
- package/dist/docs/cli/model-routing.md +1 -1
- package/dist/docs/cli/model.md +1 -1
- package/dist/docs/cli/settings.md +69 -53
- package/dist/docs/cli/skills.md +35 -3
- package/dist/docs/cli/telemetry.md +20 -0
- package/dist/docs/core/memport.md +2 -0
- package/dist/docs/core/policy-engine.md +3 -2
- package/dist/docs/extensions/index.md +57 -7
- package/dist/docs/get-started/configuration.md +39 -9
- package/dist/docs/get-started/gemini-3.md +2 -17
- package/dist/docs/hooks/best-practices.md +1 -1
- package/dist/docs/hooks/index.md +47 -11
- package/dist/docs/hooks/reference.md +19 -9
- package/dist/docs/hooks/writing-hooks.md +19 -1
- package/dist/docs/releases.md +1 -1
- package/dist/docs/tools/shell.md +1 -1
- package/dist/docs/troubleshooting.md +9 -3
- package/dist/src/agents/a2a-client-manager.d.ts +4 -0
- package/dist/src/agents/a2a-client-manager.js +22 -22
- package/dist/src/agents/a2a-client-manager.js.map +1 -1
- package/dist/src/agents/a2a-client-manager.test.js +44 -0
- package/dist/src/agents/a2a-client-manager.test.js.map +1 -1
- package/dist/src/agents/a2aUtils.d.ts +3 -2
- package/dist/src/agents/a2aUtils.js +28 -26
- package/dist/src/agents/a2aUtils.js.map +1 -1
- package/dist/src/agents/a2aUtils.test.js +9 -9
- package/dist/src/agents/a2aUtils.test.js.map +1 -1
- package/dist/src/agents/agentLoader.d.ts +68 -0
- package/dist/src/agents/{toml-loader.js → agentLoader.js} +86 -79
- package/dist/src/agents/agentLoader.js.map +1 -0
- package/dist/src/agents/agentLoader.test.js +307 -0
- package/dist/src/agents/agentLoader.test.js.map +1 -0
- package/dist/src/agents/{introspection-agent.d.ts → cli-help-agent.d.ts} +3 -2
- package/dist/src/agents/cli-help-agent.js +85 -0
- package/dist/src/agents/cli-help-agent.js.map +1 -0
- package/dist/src/agents/{introspection-agent.test.js → cli-help-agent.test.js} +25 -7
- package/dist/src/agents/cli-help-agent.test.js.map +1 -0
- package/dist/src/agents/codebase-investigator.js +10 -5
- package/dist/src/agents/codebase-investigator.js.map +1 -1
- package/dist/src/agents/delegate-to-agent-tool.js +17 -10
- package/dist/src/agents/delegate-to-agent-tool.js.map +1 -1
- package/dist/src/agents/delegate-to-agent-tool.test.js +60 -12
- package/dist/src/agents/delegate-to-agent-tool.test.js.map +1 -1
- package/dist/src/agents/local-executor.js +42 -8
- package/dist/src/agents/local-executor.js.map +1 -1
- package/dist/src/agents/local-executor.test.js +70 -11
- package/dist/src/agents/local-executor.test.js.map +1 -1
- package/dist/src/agents/local-invocation.test.js +8 -2
- package/dist/src/agents/local-invocation.test.js.map +1 -1
- package/dist/src/agents/registry.d.ts +12 -0
- package/dist/src/agents/registry.js +111 -42
- package/dist/src/agents/registry.js.map +1 -1
- package/dist/src/agents/registry.test.js +228 -15
- package/dist/src/agents/registry.test.js.map +1 -1
- package/dist/src/agents/remote-invocation.js +10 -13
- package/dist/src/agents/remote-invocation.js.map +1 -1
- package/dist/src/agents/remote-invocation.test.js +1 -1
- package/dist/src/agents/remote-invocation.test.js.map +1 -1
- package/dist/src/agents/subagent-tool-wrapper.test.js +8 -2
- package/dist/src/agents/subagent-tool-wrapper.test.js.map +1 -1
- package/dist/src/agents/types.d.ts +3 -11
- package/dist/src/agents/types.js.map +1 -1
- package/dist/src/availability/fallbackIntegration.test.js +58 -0
- package/dist/src/availability/fallbackIntegration.test.js.map +1 -0
- package/dist/src/code_assist/experiments/experiments.d.ts +1 -1
- package/dist/src/code_assist/experiments/experiments.js +21 -0
- package/dist/src/code_assist/experiments/experiments.js.map +1 -1
- package/dist/src/code_assist/experiments/experiments_local.test.d.ts +6 -0
- package/dist/src/code_assist/experiments/experiments_local.test.js +110 -0
- package/dist/src/code_assist/experiments/experiments_local.test.js.map +1 -0
- package/dist/src/code_assist/oauth-credential-storage.js +3 -4
- package/dist/src/code_assist/oauth-credential-storage.js.map +1 -1
- package/dist/src/code_assist/oauth2.js.map +1 -1
- package/dist/src/code_assist/oauth2.test.js +44 -19
- package/dist/src/code_assist/oauth2.test.js.map +1 -1
- package/dist/src/code_assist/telemetry.js +2 -1
- package/dist/src/code_assist/telemetry.js.map +1 -1
- package/dist/src/code_assist/telemetry.test.js +2 -1
- package/dist/src/code_assist/telemetry.test.js.map +1 -1
- package/dist/src/code_assist/types.d.ts +7 -0
- package/dist/src/code_assist/types.js +7 -0
- package/dist/src/code_assist/types.js.map +1 -1
- package/dist/src/commands/memory.d.ts +11 -0
- package/dist/src/commands/memory.js +80 -0
- package/dist/src/commands/memory.js.map +1 -0
- package/dist/src/commands/memory.test.d.ts +6 -0
- package/dist/src/commands/memory.test.js +155 -0
- package/dist/src/commands/memory.test.js.map +1 -0
- package/dist/src/config/config.d.ts +50 -7
- package/dist/src/config/config.js +113 -48
- package/dist/src/config/config.js.map +1 -1
- package/dist/src/config/config.test.js +34 -4
- package/dist/src/config/config.test.js.map +1 -1
- package/dist/src/config/models.d.ts +7 -0
- package/dist/src/config/models.js +11 -0
- package/dist/src/config/models.js.map +1 -1
- package/dist/src/config/models.test.js +17 -1
- package/dist/src/config/models.test.js.map +1 -1
- package/dist/src/config/storage.d.ts +1 -0
- package/dist/src/config/storage.js +5 -2
- package/dist/src/config/storage.js.map +1 -1
- package/dist/src/core/client.js +25 -8
- package/dist/src/core/client.js.map +1 -1
- package/dist/src/core/client.test.js +45 -31
- package/dist/src/core/client.test.js.map +1 -1
- package/dist/src/core/coreToolHookTriggers.d.ts +8 -4
- package/dist/src/core/coreToolHookTriggers.js +43 -5
- package/dist/src/core/coreToolHookTriggers.js.map +1 -1
- package/dist/src/core/coreToolScheduler.d.ts +1 -8
- package/dist/src/core/coreToolScheduler.js +58 -60
- package/dist/src/core/coreToolScheduler.js.map +1 -1
- package/dist/src/core/coreToolScheduler.test.js +215 -8
- package/dist/src/core/coreToolScheduler.test.js.map +1 -1
- package/dist/src/core/geminiChat.d.ts +26 -1
- package/dist/src/core/geminiChat.js +91 -8
- package/dist/src/core/geminiChat.js.map +1 -1
- package/dist/src/core/geminiChat.test.js +109 -0
- package/dist/src/core/geminiChat.test.js.map +1 -1
- package/dist/src/core/geminiChatHookTriggers.d.ts +8 -4
- package/dist/src/core/geminiChatHookTriggers.js +31 -9
- package/dist/src/core/geminiChatHookTriggers.js.map +1 -1
- package/dist/src/core/geminiChatHookTriggers.test.d.ts +6 -0
- package/dist/src/core/geminiChatHookTriggers.test.js +153 -0
- package/dist/src/core/geminiChatHookTriggers.test.js.map +1 -0
- package/dist/src/core/loggingContentGenerator.js +5 -0
- package/dist/src/core/loggingContentGenerator.js.map +1 -1
- package/dist/src/core/loggingContentGenerator.test.js +30 -0
- package/dist/src/core/loggingContentGenerator.test.js.map +1 -1
- package/dist/src/core/nonInteractiveToolExecutor.test.js +4 -2
- package/dist/src/core/nonInteractiveToolExecutor.test.js.map +1 -1
- package/dist/src/core/prompts.js +8 -8
- package/dist/src/core/prompts.js.map +1 -1
- package/dist/src/core/prompts.test.js +4 -2
- package/dist/src/core/prompts.test.js.map +1 -1
- package/dist/src/core/tokenLimits.js +6 -12
- package/dist/src/core/tokenLimits.js.map +1 -1
- package/dist/src/core/tokenLimits.test.js +8 -4
- package/dist/src/core/tokenLimits.test.js.map +1 -1
- package/dist/src/core/turn.d.ts +2 -0
- package/dist/src/core/turn.js +14 -0
- package/dist/src/core/turn.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.d.ts +3 -3
- package/dist/src/hooks/hookEventHandler.js +27 -8
- package/dist/src/hooks/hookEventHandler.js.map +1 -1
- package/dist/src/hooks/hookEventHandler.test.js +145 -0
- package/dist/src/hooks/hookEventHandler.test.js.map +1 -1
- package/dist/src/hooks/hookSystem.d.ts +12 -0
- package/dist/src/hooks/hookSystem.js +38 -0
- package/dist/src/hooks/hookSystem.js.map +1 -1
- package/dist/src/hooks/hookTranslator.js +2 -1
- package/dist/src/hooks/hookTranslator.js.map +1 -1
- package/dist/src/hooks/index.d.ts +0 -1
- package/dist/src/hooks/index.js +0 -2
- package/dist/src/hooks/index.js.map +1 -1
- package/dist/src/hooks/types.d.ts +21 -0
- package/dist/src/hooks/types.js +0 -15
- package/dist/src/hooks/types.js.map +1 -1
- package/dist/src/hooks/types.test.js +4 -28
- package/dist/src/hooks/types.test.js.map +1 -1
- package/dist/src/ide/detect-ide.d.ts +4 -0
- package/dist/src/ide/detect-ide.js +7 -2
- package/dist/src/ide/detect-ide.js.map +1 -1
- package/dist/src/ide/detect-ide.test.js +10 -0
- package/dist/src/ide/detect-ide.test.js.map +1 -1
- package/dist/src/ide/ide-installer.js +2 -2
- package/dist/src/ide/ide-installer.js.map +1 -1
- package/dist/src/ide/ide-installer.test.js +11 -2
- package/dist/src/ide/ide-installer.test.js.map +1 -1
- package/dist/src/index.d.ts +10 -1
- package/dist/src/index.js +12 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/mcp/token-storage/file-token-storage.js +2 -2
- package/dist/src/mcp/token-storage/file-token-storage.js.map +1 -1
- package/dist/src/policy/config.test.js +3 -2
- package/dist/src/policy/config.test.js.map +1 -1
- package/dist/src/policy/persistence.test.js +1 -1
- package/dist/src/policy/persistence.test.js.map +1 -1
- package/dist/src/policy/policies/agent.toml +1 -1
- package/dist/src/policy/policy-engine.js +80 -20
- package/dist/src/policy/policy-engine.js.map +1 -1
- package/dist/src/policy/policy-engine.test.js +17 -0
- package/dist/src/policy/policy-engine.test.js.map +1 -1
- package/dist/src/policy/policy-updater.test.js +3 -3
- package/dist/src/policy/policy-updater.test.js.map +1 -1
- package/dist/src/policy/shell-safety.test.js +371 -8
- package/dist/src/policy/shell-safety.test.js.map +1 -1
- package/dist/src/policy/types.d.ts +4 -0
- package/dist/src/policy/utils.js +4 -1
- package/dist/src/policy/utils.js.map +1 -1
- package/dist/src/policy/utils.test.js +34 -6
- package/dist/src/policy/utils.test.js.map +1 -1
- package/dist/src/routing/routingStrategy.d.ts +2 -0
- package/dist/src/routing/strategies/classifierStrategy.js +1 -1
- package/dist/src/routing/strategies/classifierStrategy.js.map +1 -1
- package/dist/src/routing/strategies/classifierStrategy.test.js +16 -0
- package/dist/src/routing/strategies/classifierStrategy.test.js.map +1 -1
- package/dist/src/routing/strategies/fallbackStrategy.d.ts +1 -1
- package/dist/src/routing/strategies/fallbackStrategy.js +2 -2
- package/dist/src/routing/strategies/fallbackStrategy.js.map +1 -1
- package/dist/src/routing/strategies/fallbackStrategy.test.js +13 -0
- package/dist/src/routing/strategies/fallbackStrategy.test.js.map +1 -1
- package/dist/src/routing/strategies/overrideStrategy.d.ts +1 -1
- package/dist/src/routing/strategies/overrideStrategy.js +5 -5
- package/dist/src/routing/strategies/overrideStrategy.js.map +1 -1
- package/dist/src/routing/strategies/overrideStrategy.test.js +14 -0
- package/dist/src/routing/strategies/overrideStrategy.test.js.map +1 -1
- package/dist/src/scheduler/tool-executor.js +2 -2
- package/dist/src/scheduler/tool-executor.js.map +1 -1
- package/dist/src/scheduler/tool-modifier.d.ts +23 -0
- package/dist/src/scheduler/tool-modifier.js +50 -0
- package/dist/src/scheduler/tool-modifier.js.map +1 -0
- package/dist/src/scheduler/tool-modifier.test.d.ts +6 -0
- package/dist/src/scheduler/tool-modifier.test.js +159 -0
- package/dist/src/scheduler/tool-modifier.test.js.map +1 -0
- package/dist/src/services/chatCompressionService.js +3 -10
- package/dist/src/services/chatCompressionService.js.map +1 -1
- package/dist/src/services/chatCompressionService.test.js +1 -0
- package/dist/src/services/chatCompressionService.test.js.map +1 -1
- package/dist/src/services/chatRecordingService.d.ts +7 -1
- package/dist/src/services/chatRecordingService.js +20 -2
- package/dist/src/services/chatRecordingService.js.map +1 -1
- package/dist/src/services/chatRecordingService.test.js +43 -0
- package/dist/src/services/chatRecordingService.test.js.map +1 -1
- package/dist/src/services/environmentSanitization.js +4 -3
- package/dist/src/services/environmentSanitization.js.map +1 -1
- package/dist/src/services/gitService.test.js +10 -2
- package/dist/src/services/gitService.test.js.map +1 -1
- package/dist/src/services/modelConfig.integration.test.js +2 -2
- package/dist/src/services/modelConfig.integration.test.js.map +1 -1
- package/dist/src/services/modelConfigService.d.ts +38 -4
- package/dist/src/services/modelConfigService.js +135 -76
- package/dist/src/services/modelConfigService.js.map +1 -1
- package/dist/src/services/modelConfigService.test.js +116 -0
- package/dist/src/services/modelConfigService.test.js.map +1 -1
- package/dist/src/services/shellExecutionService.js +1 -1
- package/dist/src/services/shellExecutionService.js.map +1 -1
- package/dist/src/services/shellExecutionService.test.js +43 -2
- package/dist/src/services/shellExecutionService.test.js.map +1 -1
- package/dist/src/skills/skillLoader.d.ts +3 -0
- package/dist/src/skills/skillLoader.js +3 -3
- package/dist/src/skills/skillLoader.js.map +1 -1
- package/dist/src/skills/skillLoader.test.js +4 -2
- package/dist/src/skills/skillLoader.test.js.map +1 -1
- package/dist/src/skills/skillManager.d.ts +18 -0
- package/dist/src/skills/skillManager.js +43 -5
- package/dist/src/skills/skillManager.js.map +1 -1
- package/dist/src/skills/skillManager.test.js +83 -1
- package/dist/src/skills/skillManager.test.js.map +1 -1
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.d.ts +9 -2
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.js +60 -9
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.js.map +1 -1
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js +105 -6
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js.map +1 -1
- package/dist/src/telemetry/clearcut-logger/event-metadata-key.d.ts +5 -1
- package/dist/src/telemetry/clearcut-logger/event-metadata-key.js +8 -0
- package/dist/src/telemetry/clearcut-logger/event-metadata-key.js.map +1 -1
- package/dist/src/telemetry/loggers.js +1 -1
- package/dist/src/telemetry/loggers.js.map +1 -1
- package/dist/src/telemetry/loggers.test.js +8 -0
- package/dist/src/telemetry/loggers.test.js.map +1 -1
- package/dist/src/telemetry/types.js +4 -2
- package/dist/src/telemetry/types.js.map +1 -1
- package/dist/src/tools/activate-skill.js +23 -10
- package/dist/src/tools/activate-skill.js.map +1 -1
- package/dist/src/tools/activate-skill.test.js +24 -6
- package/dist/src/tools/activate-skill.test.js.map +1 -1
- package/dist/src/tools/confirmation-policy.test.js +1 -0
- package/dist/src/tools/confirmation-policy.test.js.map +1 -1
- package/dist/src/tools/edit.js +12 -0
- package/dist/src/tools/edit.js.map +1 -1
- package/dist/src/tools/edit.test.js +34 -0
- package/dist/src/tools/edit.test.js.map +1 -1
- package/dist/src/tools/get-internal-docs.js +11 -18
- package/dist/src/tools/get-internal-docs.js.map +1 -1
- package/dist/src/tools/mcp-tool.d.ts +18 -3
- package/dist/src/tools/mcp-tool.js +1 -1
- package/dist/src/tools/mcp-tool.js.map +1 -1
- package/dist/src/tools/tool-error.d.ts +4 -0
- package/dist/src/tools/tool-error.js +4 -0
- package/dist/src/tools/tool-error.js.map +1 -1
- package/dist/src/tools/tools.d.ts +2 -0
- package/dist/src/tools/tools.js.map +1 -1
- package/dist/src/tools/write-file.js +4 -2
- package/dist/src/tools/write-file.js.map +1 -1
- package/dist/src/tools/write-file.test.js +45 -6
- package/dist/src/tools/write-file.test.js.map +1 -1
- package/dist/src/utils/apiConversionUtils.d.ts +12 -0
- package/dist/src/utils/apiConversionUtils.js +46 -0
- package/dist/src/utils/apiConversionUtils.js.map +1 -0
- package/dist/src/utils/apiConversionUtils.test.d.ts +6 -0
- package/dist/src/utils/apiConversionUtils.test.js +150 -0
- package/dist/src/utils/apiConversionUtils.test.js.map +1 -0
- package/dist/src/utils/editCorrector.d.ts +3 -3
- package/dist/src/utils/editCorrector.js +21 -5
- package/dist/src/utils/editCorrector.js.map +1 -1
- package/dist/src/utils/editCorrector.test.js +20 -20
- package/dist/src/utils/editCorrector.test.js.map +1 -1
- package/dist/src/utils/editor.d.ts +3 -2
- package/dist/src/utils/editor.js +26 -6
- package/dist/src/utils/editor.js.map +1 -1
- package/dist/src/utils/editor.test.js +27 -4
- package/dist/src/utils/editor.test.js.map +1 -1
- package/dist/src/utils/events.d.ts +23 -1
- package/dist/src/utils/events.js +14 -0
- package/dist/src/utils/events.js.map +1 -1
- package/dist/src/utils/fileDiffUtils.d.ts +18 -0
- package/dist/src/utils/fileDiffUtils.js +37 -0
- package/dist/src/utils/fileDiffUtils.js.map +1 -0
- package/dist/src/utils/fileDiffUtils.test.d.ts +6 -0
- package/dist/src/utils/fileDiffUtils.test.js +84 -0
- package/dist/src/utils/fileDiffUtils.test.js.map +1 -0
- package/dist/src/utils/gitIgnoreParser.js +9 -10
- package/dist/src/utils/gitIgnoreParser.js.map +1 -1
- package/dist/src/utils/installationManager.test.js +11 -3
- package/dist/src/utils/installationManager.test.js.map +1 -1
- package/dist/src/utils/memoryDiscovery.js +1 -2
- package/dist/src/utils/memoryDiscovery.js.map +1 -1
- package/dist/src/utils/memoryDiscovery.test.js +9 -0
- package/dist/src/utils/memoryDiscovery.test.js.map +1 -1
- package/dist/src/utils/paths.d.ts +10 -0
- package/dist/src/utils/paths.js +20 -1
- package/dist/src/utils/paths.js.map +1 -1
- package/dist/src/utils/retry.d.ts +1 -0
- package/dist/src/utils/retry.js +14 -2
- package/dist/src/utils/retry.js.map +1 -1
- package/dist/src/utils/retry.test.js +11 -11
- package/dist/src/utils/retry.test.js.map +1 -1
- package/dist/src/utils/userAccountManager.test.js +5 -5
- package/dist/src/utils/userAccountManager.test.js.map +1 -1
- package/dist/src/utils/workspaceContext.test.js +1 -1
- package/dist/src/utils/workspaceContext.test.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -2
- package/dist/docs/cli/configuration.md +0 -780
- package/dist/docs/get-started/deployment.md +0 -143
- package/dist/google-gemini-cli-core-0.24.0-preview.2.tgz +0 -0
- package/dist/src/agents/introspection-agent.js +0 -72
- package/dist/src/agents/introspection-agent.js.map +0 -1
- package/dist/src/agents/introspection-agent.test.js.map +0 -1
- package/dist/src/agents/toml-loader.d.ts +0 -74
- package/dist/src/agents/toml-loader.js.map +0 -1
- package/dist/src/agents/toml-loader.test.js +0 -309
- package/dist/src/agents/toml-loader.test.js.map +0 -1
- package/dist/src/core/sessionHookTriggers.d.ts +0 -29
- package/dist/src/core/sessionHookTriggers.js +0 -75
- package/dist/src/core/sessionHookTriggers.js.map +0 -1
- package/dist/src/utils/shell-permissions.d.ts +0 -52
- package/dist/src/utils/shell-permissions.js +0 -188
- package/dist/src/utils/shell-permissions.js.map +0 -1
- package/dist/src/utils/shell-permissions.test.js +0 -369
- package/dist/src/utils/shell-permissions.test.js.map +0 -1
- /package/dist/src/agents/{introspection-agent.test.d.ts → agentLoader.test.d.ts} +0 -0
- /package/dist/src/agents/{toml-loader.test.d.ts → cli-help-agent.test.d.ts} +0 -0
- /package/dist/src/{utils/shell-permissions.test.d.ts → availability/fallbackIntegration.test.d.ts} +0 -0
|
@@ -3,26 +3,98 @@
|
|
|
3
3
|
* Copyright 2025 Google LLC
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
|
-
import { describe, it, expect, beforeEach } from 'vitest';
|
|
6
|
+
import { describe, it, expect, beforeEach, vi } from 'vitest';
|
|
7
|
+
// Mock shell-utils to avoid relying on tree-sitter WASM which is flaky in CI on Windows
|
|
8
|
+
vi.mock('../utils/shell-utils.js', async (importOriginal) => {
|
|
9
|
+
const actual = await importOriginal();
|
|
10
|
+
// Static map of test commands to their expected subcommands
|
|
11
|
+
// This mirrors what the real parser would output for these specific strings
|
|
12
|
+
const commandMap = {
|
|
13
|
+
'git log': ['git log'],
|
|
14
|
+
'git log --oneline': ['git log --oneline'],
|
|
15
|
+
'git logout': ['git logout'],
|
|
16
|
+
'git log && rm -rf /': ['git log', 'rm -rf /'],
|
|
17
|
+
'git log; rm -rf /': ['git log', 'rm -rf /'],
|
|
18
|
+
'git log || rm -rf /': ['git log', 'rm -rf /'],
|
|
19
|
+
'git log &&& rm -rf /': [], // Simulates parse failure
|
|
20
|
+
'echo $(rm -rf /)': ['echo $(rm -rf /)', 'rm -rf /'],
|
|
21
|
+
'echo $(git log)': ['echo $(git log)', 'git log'],
|
|
22
|
+
'echo `rm -rf /`': ['echo `rm -rf /`', 'rm -rf /'],
|
|
23
|
+
'diff <(git log) <(rm -rf /)': [
|
|
24
|
+
'diff <(git log) <(rm -rf /)',
|
|
25
|
+
'git log',
|
|
26
|
+
'rm -rf /',
|
|
27
|
+
],
|
|
28
|
+
'tee >(rm -rf /)': ['tee >(rm -rf /)', 'rm -rf /'],
|
|
29
|
+
'git log | rm -rf /': ['git log', 'rm -rf /'],
|
|
30
|
+
'git log --format=$(rm -rf /)': [
|
|
31
|
+
'git log --format=$(rm -rf /)',
|
|
32
|
+
'rm -rf /',
|
|
33
|
+
],
|
|
34
|
+
'git log && echo $(git log | rm -rf /)': [
|
|
35
|
+
'git log',
|
|
36
|
+
'echo $(git log | rm -rf /)',
|
|
37
|
+
'git log',
|
|
38
|
+
'rm -rf /',
|
|
39
|
+
],
|
|
40
|
+
'git log && echo $(git log)': ['git log', 'echo $(git log)', 'git log'],
|
|
41
|
+
'git log > /tmp/test': ['git log > /tmp/test'],
|
|
42
|
+
'git log @(Get-Process)': [], // Simulates parse failure (Bash parser vs PowerShell syntax)
|
|
43
|
+
'git commit -m "msg" && git push': ['git commit -m "msg"', 'git push'],
|
|
44
|
+
'git status && unknown_command': ['git status', 'unknown_command'],
|
|
45
|
+
'unknown_command_1 && another_unknown_command': [
|
|
46
|
+
'unknown_command_1',
|
|
47
|
+
'another_unknown_command',
|
|
48
|
+
],
|
|
49
|
+
'known_ask_command_1 && known_ask_command_2': [
|
|
50
|
+
'known_ask_command_1',
|
|
51
|
+
'known_ask_command_2',
|
|
52
|
+
],
|
|
53
|
+
};
|
|
54
|
+
return {
|
|
55
|
+
...actual,
|
|
56
|
+
initializeShellParsers: vi.fn(),
|
|
57
|
+
splitCommands: (command) => {
|
|
58
|
+
if (Object.prototype.hasOwnProperty.call(commandMap, command)) {
|
|
59
|
+
return commandMap[command];
|
|
60
|
+
}
|
|
61
|
+
const known = commandMap[command];
|
|
62
|
+
if (known)
|
|
63
|
+
return known;
|
|
64
|
+
// Default fallback for unmatched simple cases in development, but explicit map is better
|
|
65
|
+
return [command];
|
|
66
|
+
},
|
|
67
|
+
hasRedirection: (command) =>
|
|
68
|
+
// Simple regex check sufficient for testing the policy engine's handling of the *result* of hasRedirection
|
|
69
|
+
/[><]/.test(command),
|
|
70
|
+
};
|
|
71
|
+
});
|
|
7
72
|
import { PolicyEngine } from './policy-engine.js';
|
|
8
73
|
import { PolicyDecision, ApprovalMode } from './types.js';
|
|
74
|
+
import { buildArgsPatterns } from './utils.js';
|
|
9
75
|
describe('Shell Safety Policy', () => {
|
|
10
76
|
let policyEngine;
|
|
11
|
-
|
|
12
|
-
|
|
77
|
+
// Helper to create a policy engine with a simple command prefix rule
|
|
78
|
+
function createPolicyEngineWithPrefix(prefix) {
|
|
79
|
+
const argsPatterns = buildArgsPatterns(undefined, prefix, undefined);
|
|
80
|
+
// Since buildArgsPatterns returns array of patterns (strings), we pick the first one
|
|
81
|
+
// and compile it.
|
|
82
|
+
const argsPattern = new RegExp(argsPatterns[0]);
|
|
83
|
+
return new PolicyEngine({
|
|
13
84
|
rules: [
|
|
14
85
|
{
|
|
15
86
|
toolName: 'run_shell_command',
|
|
16
|
-
|
|
17
|
-
// Regex: "command":"git log(?:[\s"]|$)
|
|
18
|
-
argsPattern: /"command":"git log(?:[\s"]|$)/,
|
|
87
|
+
argsPattern,
|
|
19
88
|
decision: PolicyDecision.ALLOW,
|
|
20
|
-
priority: 1.01,
|
|
89
|
+
priority: 1.01,
|
|
21
90
|
},
|
|
22
91
|
],
|
|
23
92
|
defaultDecision: PolicyDecision.ASK_USER,
|
|
24
93
|
approvalMode: ApprovalMode.DEFAULT,
|
|
25
94
|
});
|
|
95
|
+
}
|
|
96
|
+
beforeEach(() => {
|
|
97
|
+
policyEngine = createPolicyEngineWithPrefix('git log');
|
|
26
98
|
});
|
|
27
99
|
it('SHOULD match "git log" exactly', async () => {
|
|
28
100
|
const toolCall = {
|
|
@@ -61,15 +133,306 @@ describe('Shell Safety Policy', () => {
|
|
|
61
133
|
const result = await policyEngine.check(toolCall, undefined);
|
|
62
134
|
expect(result.decision).toBe(PolicyDecision.ASK_USER);
|
|
63
135
|
});
|
|
136
|
+
it('SHOULD NOT allow "git log; rm -rf /" (semicolon separator)', async () => {
|
|
137
|
+
const toolCall = {
|
|
138
|
+
name: 'run_shell_command',
|
|
139
|
+
args: { command: 'git log; rm -rf /' },
|
|
140
|
+
};
|
|
141
|
+
const result = await policyEngine.check(toolCall, undefined);
|
|
142
|
+
expect(result.decision).toBe(PolicyDecision.ASK_USER);
|
|
143
|
+
});
|
|
144
|
+
it('SHOULD NOT allow "git log || rm -rf /" (OR separator)', async () => {
|
|
145
|
+
const toolCall = {
|
|
146
|
+
name: 'run_shell_command',
|
|
147
|
+
args: { command: 'git log || rm -rf /' },
|
|
148
|
+
};
|
|
149
|
+
const result = await policyEngine.check(toolCall, undefined);
|
|
150
|
+
expect(result.decision).toBe(PolicyDecision.ASK_USER);
|
|
151
|
+
});
|
|
64
152
|
it('SHOULD NOT allow "git log &&& rm -rf /" when prefix is "git log" (parse failure)', async () => {
|
|
65
153
|
const toolCall = {
|
|
66
154
|
name: 'run_shell_command',
|
|
67
155
|
args: { command: 'git log &&& rm -rf /' },
|
|
68
156
|
};
|
|
69
157
|
// Desired behavior: Should fail safe (ASK_USER or DENY) because parsing failed.
|
|
70
|
-
// If we let it pass as "single command" that matches prefix, it's dangerous.
|
|
71
158
|
const result = await policyEngine.check(toolCall, undefined);
|
|
72
159
|
expect(result.decision).toBe(PolicyDecision.ASK_USER);
|
|
73
160
|
});
|
|
161
|
+
it('SHOULD NOT allow command substitution $(rm -rf /)', async () => {
|
|
162
|
+
const toolCall = {
|
|
163
|
+
name: 'run_shell_command',
|
|
164
|
+
args: { command: 'echo $(rm -rf /)' },
|
|
165
|
+
};
|
|
166
|
+
// `splitCommands` recursively finds nested commands (e.g., `rm` inside `echo $()`).
|
|
167
|
+
// The policy engine requires ALL extracted commands to be allowed.
|
|
168
|
+
// Since `rm` does not match the allowed prefix, this should result in ASK_USER.
|
|
169
|
+
const echoPolicy = createPolicyEngineWithPrefix('echo');
|
|
170
|
+
const result = await echoPolicy.check(toolCall, undefined);
|
|
171
|
+
expect(result.decision).toBe(PolicyDecision.ASK_USER);
|
|
172
|
+
});
|
|
173
|
+
it('SHOULD allow command substitution if inner command is ALSO allowed', async () => {
|
|
174
|
+
// Both `echo` and `git` allowed.
|
|
175
|
+
const argsPatternsEcho = buildArgsPatterns(undefined, 'echo', undefined);
|
|
176
|
+
const argsPatternsGit = buildArgsPatterns(undefined, 'git', undefined); // Allow all git
|
|
177
|
+
const policyEngineWithBoth = new PolicyEngine({
|
|
178
|
+
rules: [
|
|
179
|
+
{
|
|
180
|
+
toolName: 'run_shell_command',
|
|
181
|
+
argsPattern: new RegExp(argsPatternsEcho[0]),
|
|
182
|
+
decision: PolicyDecision.ALLOW,
|
|
183
|
+
priority: 2,
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
toolName: 'run_shell_command',
|
|
187
|
+
argsPattern: new RegExp(argsPatternsGit[0]),
|
|
188
|
+
decision: PolicyDecision.ALLOW,
|
|
189
|
+
priority: 2,
|
|
190
|
+
},
|
|
191
|
+
],
|
|
192
|
+
defaultDecision: PolicyDecision.ASK_USER,
|
|
193
|
+
});
|
|
194
|
+
const toolCall = {
|
|
195
|
+
name: 'run_shell_command',
|
|
196
|
+
args: { command: 'echo $(git log)' },
|
|
197
|
+
};
|
|
198
|
+
const result = await policyEngineWithBoth.check(toolCall, undefined);
|
|
199
|
+
expect(result.decision).toBe(PolicyDecision.ALLOW);
|
|
200
|
+
});
|
|
201
|
+
it('SHOULD NOT allow command substitution with backticks `rm -rf /`', async () => {
|
|
202
|
+
const toolCall = {
|
|
203
|
+
name: 'run_shell_command',
|
|
204
|
+
args: { command: 'echo `rm -rf /`' },
|
|
205
|
+
};
|
|
206
|
+
const result = await policyEngine.check(toolCall, undefined);
|
|
207
|
+
expect(result.decision).toBe(PolicyDecision.ASK_USER);
|
|
208
|
+
});
|
|
209
|
+
it('SHOULD NOT allow process substitution <(rm -rf /)', async () => {
|
|
210
|
+
const toolCall = {
|
|
211
|
+
name: 'run_shell_command',
|
|
212
|
+
args: { command: 'diff <(git log) <(rm -rf /)' },
|
|
213
|
+
};
|
|
214
|
+
const result = await policyEngine.check(toolCall, undefined);
|
|
215
|
+
expect(result.decision).toBe(PolicyDecision.ASK_USER);
|
|
216
|
+
});
|
|
217
|
+
it('SHOULD NOT allow process substitution >(rm -rf /)', async () => {
|
|
218
|
+
// Note: >(...) is output substitution, but syntax is similar.
|
|
219
|
+
const toolCall = {
|
|
220
|
+
name: 'run_shell_command',
|
|
221
|
+
args: { command: 'tee >(rm -rf /)' },
|
|
222
|
+
};
|
|
223
|
+
const result = await policyEngine.check(toolCall, undefined);
|
|
224
|
+
expect(result.decision).toBe(PolicyDecision.ASK_USER);
|
|
225
|
+
});
|
|
226
|
+
it('SHOULD NOT allow piped commands "git log | rm -rf /"', async () => {
|
|
227
|
+
const toolCall = {
|
|
228
|
+
name: 'run_shell_command',
|
|
229
|
+
args: { command: 'git log | rm -rf /' },
|
|
230
|
+
};
|
|
231
|
+
const result = await policyEngine.check(toolCall, undefined);
|
|
232
|
+
expect(result.decision).toBe(PolicyDecision.ASK_USER);
|
|
233
|
+
});
|
|
234
|
+
it('SHOULD NOT allow argument injection via --arg=$(rm -rf /)', async () => {
|
|
235
|
+
const toolCall = {
|
|
236
|
+
name: 'run_shell_command',
|
|
237
|
+
args: { command: 'git log --format=$(rm -rf /)' },
|
|
238
|
+
};
|
|
239
|
+
const result = await policyEngine.check(toolCall, undefined);
|
|
240
|
+
expect(result.decision).toBe(PolicyDecision.ASK_USER);
|
|
241
|
+
});
|
|
242
|
+
it('SHOULD NOT allow complex nested commands "git log && echo $(git log | rm -rf /)"', async () => {
|
|
243
|
+
const toolCall = {
|
|
244
|
+
name: 'run_shell_command',
|
|
245
|
+
args: { command: 'git log && echo $(git log | rm -rf /)' },
|
|
246
|
+
};
|
|
247
|
+
const result = await policyEngine.check(toolCall, undefined);
|
|
248
|
+
expect(result.decision).toBe(PolicyDecision.ASK_USER);
|
|
249
|
+
});
|
|
250
|
+
it('SHOULD allow complex allowed commands "git log && echo $(git log)"', async () => {
|
|
251
|
+
// Both `echo` and `git` allowed.
|
|
252
|
+
const argsPatternsEcho = buildArgsPatterns(undefined, 'echo', undefined);
|
|
253
|
+
const argsPatternsGit = buildArgsPatterns(undefined, 'git', undefined);
|
|
254
|
+
const policyEngineWithBoth = new PolicyEngine({
|
|
255
|
+
rules: [
|
|
256
|
+
{
|
|
257
|
+
toolName: 'run_shell_command',
|
|
258
|
+
argsPattern: new RegExp(argsPatternsEcho[0]),
|
|
259
|
+
decision: PolicyDecision.ALLOW,
|
|
260
|
+
priority: 2,
|
|
261
|
+
},
|
|
262
|
+
{
|
|
263
|
+
toolName: 'run_shell_command',
|
|
264
|
+
// Matches "git" at start of *subcommand*
|
|
265
|
+
argsPattern: new RegExp(argsPatternsGit[0]),
|
|
266
|
+
decision: PolicyDecision.ALLOW,
|
|
267
|
+
priority: 2,
|
|
268
|
+
},
|
|
269
|
+
],
|
|
270
|
+
defaultDecision: PolicyDecision.ASK_USER,
|
|
271
|
+
});
|
|
272
|
+
const toolCall = {
|
|
273
|
+
name: 'run_shell_command',
|
|
274
|
+
args: { command: 'git log && echo $(git log)' },
|
|
275
|
+
};
|
|
276
|
+
const result = await policyEngineWithBoth.check(toolCall, undefined);
|
|
277
|
+
expect(result.decision).toBe(PolicyDecision.ALLOW);
|
|
278
|
+
});
|
|
279
|
+
it('SHOULD NOT allow generic redirection > /tmp/test', async () => {
|
|
280
|
+
// Current logic downgrades ALLOW to ASK_USER for redirections if redirection is not explicitly allowed.
|
|
281
|
+
const toolCall = {
|
|
282
|
+
name: 'run_shell_command',
|
|
283
|
+
args: { command: 'git log > /tmp/test' },
|
|
284
|
+
};
|
|
285
|
+
const result = await policyEngine.check(toolCall, undefined);
|
|
286
|
+
expect(result.decision).toBe(PolicyDecision.ASK_USER);
|
|
287
|
+
});
|
|
288
|
+
it('SHOULD allow generic redirection > /tmp/test if allowRedirection is true', async () => {
|
|
289
|
+
// If PolicyRule has allowRedirection: true, it should stay ALLOW
|
|
290
|
+
const argsPatternsGitLog = buildArgsPatterns(undefined, 'git log', undefined);
|
|
291
|
+
const policyWithRedirection = new PolicyEngine({
|
|
292
|
+
rules: [
|
|
293
|
+
{
|
|
294
|
+
toolName: 'run_shell_command',
|
|
295
|
+
argsPattern: new RegExp(argsPatternsGitLog[0]),
|
|
296
|
+
decision: PolicyDecision.ALLOW,
|
|
297
|
+
priority: 2,
|
|
298
|
+
allowRedirection: true,
|
|
299
|
+
},
|
|
300
|
+
],
|
|
301
|
+
defaultDecision: PolicyDecision.ASK_USER,
|
|
302
|
+
});
|
|
303
|
+
const toolCall = {
|
|
304
|
+
name: 'run_shell_command',
|
|
305
|
+
args: { command: 'git log > /tmp/test' },
|
|
306
|
+
};
|
|
307
|
+
const result = await policyWithRedirection.check(toolCall, undefined);
|
|
308
|
+
expect(result.decision).toBe(PolicyDecision.ALLOW);
|
|
309
|
+
});
|
|
310
|
+
it('SHOULD NOT allow PowerShell @(...) usage if it implies code execution', async () => {
|
|
311
|
+
// Bash parser fails on PowerShell syntax @(...) (returns empty subcommands).
|
|
312
|
+
// The policy engine correctly identifies this as unparseable and falls back to ASK_USER.
|
|
313
|
+
const toolCall = {
|
|
314
|
+
name: 'run_shell_command',
|
|
315
|
+
args: { command: 'git log @(Get-Process)' },
|
|
316
|
+
};
|
|
317
|
+
const result = await policyEngine.check(toolCall, undefined);
|
|
318
|
+
expect(result.decision).toBe(PolicyDecision.ASK_USER);
|
|
319
|
+
});
|
|
320
|
+
it('SHOULD match DENY rule even if nested/chained with unknown command', async () => {
|
|
321
|
+
// Scenario:
|
|
322
|
+
// git commit -m "..." (Unknown/No Rule -> ASK_USER)
|
|
323
|
+
// git push (DENY -> DENY)
|
|
324
|
+
// Overall should be DENY.
|
|
325
|
+
const argsPatternsPush = buildArgsPatterns(undefined, 'git push', undefined);
|
|
326
|
+
const denyPushPolicy = new PolicyEngine({
|
|
327
|
+
rules: [
|
|
328
|
+
{
|
|
329
|
+
toolName: 'run_shell_command',
|
|
330
|
+
argsPattern: new RegExp(argsPatternsPush[0]),
|
|
331
|
+
decision: PolicyDecision.DENY,
|
|
332
|
+
priority: 2,
|
|
333
|
+
},
|
|
334
|
+
],
|
|
335
|
+
defaultDecision: PolicyDecision.ASK_USER,
|
|
336
|
+
});
|
|
337
|
+
const toolCall = {
|
|
338
|
+
name: 'run_shell_command',
|
|
339
|
+
args: { command: 'git commit -m "msg" && git push' },
|
|
340
|
+
};
|
|
341
|
+
const result = await denyPushPolicy.check(toolCall, undefined);
|
|
342
|
+
expect(result.decision).toBe(PolicyDecision.DENY);
|
|
343
|
+
});
|
|
344
|
+
it('SHOULD aggregate ALLOW + ASK_USER to ASK_USER and blame the ASK_USER part', async () => {
|
|
345
|
+
// Scenario:
|
|
346
|
+
// `git status` (ALLOW) && `unknown_command` (ASK_USER by default)
|
|
347
|
+
// Expected: ASK_USER, and the matched rule should be related to the unknown_command
|
|
348
|
+
const argsPatternsGitStatus = buildArgsPatterns(undefined, 'git status', undefined);
|
|
349
|
+
const policyEngine = new PolicyEngine({
|
|
350
|
+
rules: [
|
|
351
|
+
{
|
|
352
|
+
toolName: 'run_shell_command',
|
|
353
|
+
argsPattern: new RegExp(argsPatternsGitStatus[0]),
|
|
354
|
+
decision: PolicyDecision.ALLOW,
|
|
355
|
+
priority: 2,
|
|
356
|
+
name: 'allow_git_status_rule', // Give a name to easily identify
|
|
357
|
+
},
|
|
358
|
+
],
|
|
359
|
+
defaultDecision: PolicyDecision.ASK_USER,
|
|
360
|
+
});
|
|
361
|
+
const toolCall = {
|
|
362
|
+
name: 'run_shell_command',
|
|
363
|
+
args: { command: 'git status && unknown_command' },
|
|
364
|
+
};
|
|
365
|
+
const result = await policyEngine.check(toolCall, undefined);
|
|
366
|
+
expect(result.decision).toBe(PolicyDecision.ASK_USER);
|
|
367
|
+
// Expect the matched rule to be null/undefined since it's the default decision for 'unknown_command'
|
|
368
|
+
// or the rule that led to the ASK_USER decision. In this case, it should be the rule for 'unknown_command', which is the default decision.
|
|
369
|
+
// The policy engine's `matchedRule` will be the rule that caused the final decision.
|
|
370
|
+
// If it's a default ASK_USER, then `result.rule` should be undefined.
|
|
371
|
+
expect(result.rule).toBeUndefined();
|
|
372
|
+
});
|
|
373
|
+
it('SHOULD aggregate ASK_USER (default) + ASK_USER (rule) to ASK_USER and blame the specific ASK_USER rule', async () => {
|
|
374
|
+
// Scenario:
|
|
375
|
+
// `unknown_command_1` (ASK_USER by default) && `another_unknown_command` (ASK_USER by explicit rule)
|
|
376
|
+
// Expected: ASK_USER, and the matched rule should be the explicit ASK_USER rule
|
|
377
|
+
const argsPatternsAnotherUnknown = buildArgsPatterns(undefined, 'another_unknown_command', undefined);
|
|
378
|
+
const policyEngine = new PolicyEngine({
|
|
379
|
+
rules: [
|
|
380
|
+
{
|
|
381
|
+
toolName: 'run_shell_command',
|
|
382
|
+
argsPattern: new RegExp(argsPatternsAnotherUnknown[0]),
|
|
383
|
+
decision: PolicyDecision.ASK_USER,
|
|
384
|
+
priority: 2,
|
|
385
|
+
name: 'ask_another_unknown_command_rule',
|
|
386
|
+
},
|
|
387
|
+
],
|
|
388
|
+
defaultDecision: PolicyDecision.ASK_USER,
|
|
389
|
+
});
|
|
390
|
+
const toolCall = {
|
|
391
|
+
name: 'run_shell_command',
|
|
392
|
+
args: { command: 'unknown_command_1 && another_unknown_command' },
|
|
393
|
+
};
|
|
394
|
+
const result = await policyEngine.check(toolCall, undefined);
|
|
395
|
+
expect(result.decision).toBe(PolicyDecision.ASK_USER);
|
|
396
|
+
// The first command triggers default ASK_USER (undefined rule).
|
|
397
|
+
// The second triggers explicit ASK_USER rule.
|
|
398
|
+
// We attribute to the first cause => undefined.
|
|
399
|
+
expect(result.rule).toBeUndefined();
|
|
400
|
+
});
|
|
401
|
+
it('SHOULD aggregate ASK_USER (rule) + ASK_USER (rule) to ASK_USER and blame the first specific ASK_USER rule in subcommands', async () => {
|
|
402
|
+
// Scenario:
|
|
403
|
+
// `known_ask_command_1` (ASK_USER by explicit rule 1) && `known_ask_command_2` (ASK_USER by explicit rule 2)
|
|
404
|
+
// Expected: ASK_USER, and the matched rule should be explicit ASK_USER rule 1.
|
|
405
|
+
// The current implementation prioritizes the rule that changes the decision to ASK_USER, if any.
|
|
406
|
+
// If multiple rules lead to ASK_USER, it takes the first one.
|
|
407
|
+
const argsPatternsAsk1 = buildArgsPatterns(undefined, 'known_ask_command_1', undefined);
|
|
408
|
+
const argsPatternsAsk2 = buildArgsPatterns(undefined, 'known_ask_command_2', undefined);
|
|
409
|
+
const policyEngine = new PolicyEngine({
|
|
410
|
+
rules: [
|
|
411
|
+
{
|
|
412
|
+
toolName: 'run_shell_command',
|
|
413
|
+
argsPattern: new RegExp(argsPatternsAsk1[0]),
|
|
414
|
+
decision: PolicyDecision.ASK_USER,
|
|
415
|
+
priority: 2,
|
|
416
|
+
name: 'ask_rule_1',
|
|
417
|
+
},
|
|
418
|
+
{
|
|
419
|
+
toolName: 'run_shell_command',
|
|
420
|
+
argsPattern: new RegExp(argsPatternsAsk2[0]),
|
|
421
|
+
decision: PolicyDecision.ASK_USER,
|
|
422
|
+
priority: 2,
|
|
423
|
+
name: 'ask_rule_2',
|
|
424
|
+
},
|
|
425
|
+
],
|
|
426
|
+
defaultDecision: PolicyDecision.ALLOW, // Set default to ALLOW to ensure rules are hit
|
|
427
|
+
});
|
|
428
|
+
const toolCall = {
|
|
429
|
+
name: 'run_shell_command',
|
|
430
|
+
args: { command: 'known_ask_command_1 && known_ask_command_2' },
|
|
431
|
+
};
|
|
432
|
+
const result = await policyEngine.check(toolCall, undefined);
|
|
433
|
+
expect(result.decision).toBe(PolicyDecision.ASK_USER);
|
|
434
|
+
// Expect the rule that first caused ASK_USER to be blamed
|
|
435
|
+
expect(result.rule?.name).toBe('ask_rule_1');
|
|
436
|
+
});
|
|
74
437
|
});
|
|
75
438
|
//# sourceMappingURL=shell-safety.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shell-safety.test.js","sourceRoot":"","sources":["../../../src/policy/shell-safety.test.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"shell-safety.test.js","sourceRoot":"","sources":["../../../src/policy/shell-safety.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAE9D,wFAAwF;AACxF,EAAE,CAAC,IAAI,CAAC,yBAAyB,EAAE,KAAK,EAAE,cAAc,EAAE,EAAE;IAC1D,MAAM,MAAM,GACV,MAAM,cAAc,EAA4C,CAAC;IAEnE,4DAA4D;IAC5D,4EAA4E;IAC5E,MAAM,UAAU,GAA6B;QAC3C,SAAS,EAAE,CAAC,SAAS,CAAC;QACtB,mBAAmB,EAAE,CAAC,mBAAmB,CAAC;QAC1C,YAAY,EAAE,CAAC,YAAY,CAAC;QAC5B,qBAAqB,EAAE,CAAC,SAAS,EAAE,UAAU,CAAC;QAC9C,mBAAmB,EAAE,CAAC,SAAS,EAAE,UAAU,CAAC;QAC5C,qBAAqB,EAAE,CAAC,SAAS,EAAE,UAAU,CAAC;QAC9C,sBAAsB,EAAE,EAAE,EAAE,0BAA0B;QACtD,kBAAkB,EAAE,CAAC,kBAAkB,EAAE,UAAU,CAAC;QACpD,iBAAiB,EAAE,CAAC,iBAAiB,EAAE,SAAS,CAAC;QACjD,iBAAiB,EAAE,CAAC,iBAAiB,EAAE,UAAU,CAAC;QAClD,6BAA6B,EAAE;YAC7B,6BAA6B;YAC7B,SAAS;YACT,UAAU;SACX;QACD,iBAAiB,EAAE,CAAC,iBAAiB,EAAE,UAAU,CAAC;QAClD,oBAAoB,EAAE,CAAC,SAAS,EAAE,UAAU,CAAC;QAC7C,8BAA8B,EAAE;YAC9B,8BAA8B;YAC9B,UAAU;SACX;QACD,uCAAuC,EAAE;YACvC,SAAS;YACT,4BAA4B;YAC5B,SAAS;YACT,UAAU;SACX;QACD,4BAA4B,EAAE,CAAC,SAAS,EAAE,iBAAiB,EAAE,SAAS,CAAC;QACvE,qBAAqB,EAAE,CAAC,qBAAqB,CAAC;QAC9C,wBAAwB,EAAE,EAAE,EAAE,6DAA6D;QAC3F,iCAAiC,EAAE,CAAC,qBAAqB,EAAE,UAAU,CAAC;QACtE,+BAA+B,EAAE,CAAC,YAAY,EAAE,iBAAiB,CAAC;QAClE,8CAA8C,EAAE;YAC9C,mBAAmB;YACnB,yBAAyB;SAC1B;QACD,4CAA4C,EAAE;YAC5C,qBAAqB;YACrB,qBAAqB;SACtB;KACF,CAAC;IAEF,OAAO;QACL,GAAG,MAAM;QACT,sBAAsB,EAAE,EAAE,CAAC,EAAE,EAAE;QAC/B,aAAa,EAAE,CAAC,OAAe,EAAE,EAAE;YACjC,IAAI,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,EAAE,CAAC;gBAC9D,OAAO,UAAU,CAAC,OAAO,CAAC,CAAC;YAC7B,CAAC;YACD,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;YAClC,IAAI,KAAK;gBAAE,OAAO,KAAK,CAAC;YACxB,yFAAyF;YACzF,OAAO,CAAC,OAAO,CAAC,CAAC;QACnB,CAAC;QACD,cAAc,EAAE,CAAC,OAAe,EAAE,EAAE;QAClC,2GAA2G;QAC3G,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC;KACvB,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAE/C,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACnC,IAAI,YAA0B,CAAC;IAE/B,qEAAqE;IACrE,SAAS,4BAA4B,CAAC,MAAc;QAClD,MAAM,YAAY,GAAG,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;QACrE,qFAAqF;QACrF,kBAAkB;QAClB,MAAM,WAAW,GAAG,IAAI,MAAM,CAAC,YAAY,CAAC,CAAC,CAAE,CAAC,CAAC;QAEjD,OAAO,IAAI,YAAY,CAAC;YACtB,KAAK,EAAE;gBACL;oBACE,QAAQ,EAAE,mBAAmB;oBAC7B,WAAW;oBACX,QAAQ,EAAE,cAAc,CAAC,KAAK;oBAC9B,QAAQ,EAAE,IAAI;iBACf;aACF;YACD,eAAe,EAAE,cAAc,CAAC,QAAQ;YACxC,YAAY,EAAE,YAAY,CAAC,OAAO;SACnC,CAAC,CAAC;IACL,CAAC;IAED,UAAU,CAAC,GAAG,EAAE;QACd,YAAY,GAAG,4BAA4B,CAAC,SAAS,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gCAAgC,EAAE,KAAK,IAAI,EAAE;QAC9C,MAAM,QAAQ,GAAiB;YAC7B,IAAI,EAAE,mBAAmB;YACzB,IAAI,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE;SAC7B,CAAC;QACF,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,KAAK,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;QAC7D,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uCAAuC,EAAE,KAAK,IAAI,EAAE;QACrD,MAAM,QAAQ,GAAiB;YAC7B,IAAI,EAAE,mBAAmB;YACzB,IAAI,EAAE,EAAE,OAAO,EAAE,mBAAmB,EAAE;SACvC,CAAC;QACF,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,KAAK,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;QAC7D,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+EAA+E,EAAE,KAAK,IAAI,EAAE;QAC7F,MAAM,QAAQ,GAAiB;YAC7B,IAAI,EAAE,mBAAmB;YACzB,IAAI,EAAE,EAAE,OAAO,EAAE,YAAY,EAAE;SAChC,CAAC;QAEF,uDAAuD;QACvD,2EAA2E;QAC3E,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,KAAK,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;QAC7D,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sGAAsG,EAAE,KAAK,IAAI,EAAE;QACpH,MAAM,QAAQ,GAAiB;YAC7B,IAAI,EAAE,mBAAmB;YACzB,IAAI,EAAE,EAAE,OAAO,EAAE,qBAAqB,EAAE;SACzC,CAAC;QAEF,yEAAyE;QACzE,qEAAqE;QACrE,gCAAgC;QAChC,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,KAAK,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;QAC7D,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4DAA4D,EAAE,KAAK,IAAI,EAAE;QAC1E,MAAM,QAAQ,GAAiB;YAC7B,IAAI,EAAE,mBAAmB;YACzB,IAAI,EAAE,EAAE,OAAO,EAAE,mBAAmB,EAAE;SACvC,CAAC;QACF,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,KAAK,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;QAC7D,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uDAAuD,EAAE,KAAK,IAAI,EAAE;QACrE,MAAM,QAAQ,GAAiB;YAC7B,IAAI,EAAE,mBAAmB;YACzB,IAAI,EAAE,EAAE,OAAO,EAAE,qBAAqB,EAAE;SACzC,CAAC;QACF,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,KAAK,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;QAC7D,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kFAAkF,EAAE,KAAK,IAAI,EAAE;QAChG,MAAM,QAAQ,GAAiB;YAC7B,IAAI,EAAE,mBAAmB;YACzB,IAAI,EAAE,EAAE,OAAO,EAAE,sBAAsB,EAAE;SAC1C,CAAC;QAEF,gFAAgF;QAChF,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,KAAK,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;QAC7D,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mDAAmD,EAAE,KAAK,IAAI,EAAE;QACjE,MAAM,QAAQ,GAAiB;YAC7B,IAAI,EAAE,mBAAmB;YACzB,IAAI,EAAE,EAAE,OAAO,EAAE,kBAAkB,EAAE;SACtC,CAAC;QACF,oFAAoF;QACpF,mEAAmE;QACnE,gFAAgF;QAChF,MAAM,UAAU,GAAG,4BAA4B,CAAC,MAAM,CAAC,CAAC;QACxD,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,KAAK,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;QAC3D,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oEAAoE,EAAE,KAAK,IAAI,EAAE;QAClF,iCAAiC;QACjC,MAAM,gBAAgB,GAAG,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;QACzE,MAAM,eAAe,GAAG,iBAAiB,CAAC,SAAS,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,gBAAgB;QAExF,MAAM,oBAAoB,GAAG,IAAI,YAAY,CAAC;YAC5C,KAAK,EAAE;gBACL;oBACE,QAAQ,EAAE,mBAAmB;oBAC7B,WAAW,EAAE,IAAI,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAE,CAAC;oBAC7C,QAAQ,EAAE,cAAc,CAAC,KAAK;oBAC9B,QAAQ,EAAE,CAAC;iBACZ;gBACD;oBACE,QAAQ,EAAE,mBAAmB;oBAC7B,WAAW,EAAE,IAAI,MAAM,CAAC,eAAe,CAAC,CAAC,CAAE,CAAC;oBAC5C,QAAQ,EAAE,cAAc,CAAC,KAAK;oBAC9B,QAAQ,EAAE,CAAC;iBACZ;aACF;YACD,eAAe,EAAE,cAAc,CAAC,QAAQ;SACzC,CAAC,CAAC;QAEH,MAAM,QAAQ,GAAiB;YAC7B,IAAI,EAAE,mBAAmB;YACzB,IAAI,EAAE,EAAE,OAAO,EAAE,iBAAiB,EAAE;SACrC,CAAC;QAEF,MAAM,MAAM,GAAG,MAAM,oBAAoB,CAAC,KAAK,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;QACrE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IACH,EAAE,CAAC,iEAAiE,EAAE,KAAK,IAAI,EAAE;QAC/E,MAAM,QAAQ,GAAiB;YAC7B,IAAI,EAAE,mBAAmB;YACzB,IAAI,EAAE,EAAE,OAAO,EAAE,iBAAiB,EAAE;SACrC,CAAC;QACF,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,KAAK,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;QAC7D,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mDAAmD,EAAE,KAAK,IAAI,EAAE;QACjE,MAAM,QAAQ,GAAiB;YAC7B,IAAI,EAAE,mBAAmB;YACzB,IAAI,EAAE,EAAE,OAAO,EAAE,6BAA6B,EAAE;SACjD,CAAC;QACF,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,KAAK,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;QAC7D,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mDAAmD,EAAE,KAAK,IAAI,EAAE;QACjE,8DAA8D;QAC9D,MAAM,QAAQ,GAAiB;YAC7B,IAAI,EAAE,mBAAmB;YACzB,IAAI,EAAE,EAAE,OAAO,EAAE,iBAAiB,EAAE;SACrC,CAAC;QACF,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,KAAK,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;QAC7D,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sDAAsD,EAAE,KAAK,IAAI,EAAE;QACpE,MAAM,QAAQ,GAAiB;YAC7B,IAAI,EAAE,mBAAmB;YACzB,IAAI,EAAE,EAAE,OAAO,EAAE,oBAAoB,EAAE;SACxC,CAAC;QACF,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,KAAK,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;QAC7D,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2DAA2D,EAAE,KAAK,IAAI,EAAE;QACzE,MAAM,QAAQ,GAAiB;YAC7B,IAAI,EAAE,mBAAmB;YACzB,IAAI,EAAE,EAAE,OAAO,EAAE,8BAA8B,EAAE;SAClD,CAAC;QACF,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,KAAK,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;QAC7D,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kFAAkF,EAAE,KAAK,IAAI,EAAE;QAChG,MAAM,QAAQ,GAAiB;YAC7B,IAAI,EAAE,mBAAmB;YACzB,IAAI,EAAE,EAAE,OAAO,EAAE,uCAAuC,EAAE;SAC3D,CAAC;QACF,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,KAAK,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;QAC7D,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oEAAoE,EAAE,KAAK,IAAI,EAAE;QAClF,iCAAiC;QACjC,MAAM,gBAAgB,GAAG,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;QACzE,MAAM,eAAe,GAAG,iBAAiB,CAAC,SAAS,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;QAEvE,MAAM,oBAAoB,GAAG,IAAI,YAAY,CAAC;YAC5C,KAAK,EAAE;gBACL;oBACE,QAAQ,EAAE,mBAAmB;oBAC7B,WAAW,EAAE,IAAI,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAE,CAAC;oBAC7C,QAAQ,EAAE,cAAc,CAAC,KAAK;oBAC9B,QAAQ,EAAE,CAAC;iBACZ;gBACD;oBACE,QAAQ,EAAE,mBAAmB;oBAC7B,yCAAyC;oBACzC,WAAW,EAAE,IAAI,MAAM,CAAC,eAAe,CAAC,CAAC,CAAE,CAAC;oBAC5C,QAAQ,EAAE,cAAc,CAAC,KAAK;oBAC9B,QAAQ,EAAE,CAAC;iBACZ;aACF;YACD,eAAe,EAAE,cAAc,CAAC,QAAQ;SACzC,CAAC,CAAC;QAEH,MAAM,QAAQ,GAAiB;YAC7B,IAAI,EAAE,mBAAmB;YACzB,IAAI,EAAE,EAAE,OAAO,EAAE,4BAA4B,EAAE;SAChD,CAAC;QAEF,MAAM,MAAM,GAAG,MAAM,oBAAoB,CAAC,KAAK,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;QACrE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kDAAkD,EAAE,KAAK,IAAI,EAAE;QAChE,wGAAwG;QACxG,MAAM,QAAQ,GAAiB;YAC7B,IAAI,EAAE,mBAAmB;YACzB,IAAI,EAAE,EAAE,OAAO,EAAE,qBAAqB,EAAE;SACzC,CAAC;QACF,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,KAAK,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;QAC7D,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0EAA0E,EAAE,KAAK,IAAI,EAAE;QACxF,iEAAiE;QACjE,MAAM,kBAAkB,GAAG,iBAAiB,CAC1C,SAAS,EACT,SAAS,EACT,SAAS,CACV,CAAC;QACF,MAAM,qBAAqB,GAAG,IAAI,YAAY,CAAC;YAC7C,KAAK,EAAE;gBACL;oBACE,QAAQ,EAAE,mBAAmB;oBAC7B,WAAW,EAAE,IAAI,MAAM,CAAC,kBAAkB,CAAC,CAAC,CAAE,CAAC;oBAC/C,QAAQ,EAAE,cAAc,CAAC,KAAK;oBAC9B,QAAQ,EAAE,CAAC;oBACX,gBAAgB,EAAE,IAAI;iBACvB;aACF;YACD,eAAe,EAAE,cAAc,CAAC,QAAQ;SACzC,CAAC,CAAC;QAEH,MAAM,QAAQ,GAAiB;YAC7B,IAAI,EAAE,mBAAmB;YACzB,IAAI,EAAE,EAAE,OAAO,EAAE,qBAAqB,EAAE;SACzC,CAAC;QACF,MAAM,MAAM,GAAG,MAAM,qBAAqB,CAAC,KAAK,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;QACtE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uEAAuE,EAAE,KAAK,IAAI,EAAE;QACrF,6EAA6E;QAC7E,yFAAyF;QACzF,MAAM,QAAQ,GAAiB;YAC7B,IAAI,EAAE,mBAAmB;YACzB,IAAI,EAAE,EAAE,OAAO,EAAE,wBAAwB,EAAE;SAC5C,CAAC;QACF,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,KAAK,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;QAC7D,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oEAAoE,EAAE,KAAK,IAAI,EAAE;QAClF,YAAY;QACZ,oDAAoD;QACpD,0BAA0B;QAC1B,0BAA0B;QAC1B,MAAM,gBAAgB,GAAG,iBAAiB,CACxC,SAAS,EACT,UAAU,EACV,SAAS,CACV,CAAC;QAEF,MAAM,cAAc,GAAG,IAAI,YAAY,CAAC;YACtC,KAAK,EAAE;gBACL;oBACE,QAAQ,EAAE,mBAAmB;oBAC7B,WAAW,EAAE,IAAI,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAE,CAAC;oBAC7C,QAAQ,EAAE,cAAc,CAAC,IAAI;oBAC7B,QAAQ,EAAE,CAAC;iBACZ;aACF;YACD,eAAe,EAAE,cAAc,CAAC,QAAQ;SACzC,CAAC,CAAC;QAEH,MAAM,QAAQ,GAAiB;YAC7B,IAAI,EAAE,mBAAmB;YACzB,IAAI,EAAE,EAAE,OAAO,EAAE,iCAAiC,EAAE;SACrD,CAAC;QAEF,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,KAAK,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;QAC/D,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2EAA2E,EAAE,KAAK,IAAI,EAAE;QACzF,YAAY;QACZ,kEAAkE;QAClE,oFAAoF;QACpF,MAAM,qBAAqB,GAAG,iBAAiB,CAC7C,SAAS,EACT,YAAY,EACZ,SAAS,CACV,CAAC;QAEF,MAAM,YAAY,GAAG,IAAI,YAAY,CAAC;YACpC,KAAK,EAAE;gBACL;oBACE,QAAQ,EAAE,mBAAmB;oBAC7B,WAAW,EAAE,IAAI,MAAM,CAAC,qBAAqB,CAAC,CAAC,CAAE,CAAC;oBAClD,QAAQ,EAAE,cAAc,CAAC,KAAK;oBAC9B,QAAQ,EAAE,CAAC;oBACX,IAAI,EAAE,uBAAuB,EAAE,iCAAiC;iBACjE;aACF;YACD,eAAe,EAAE,cAAc,CAAC,QAAQ;SACzC,CAAC,CAAC;QAEH,MAAM,QAAQ,GAAiB;YAC7B,IAAI,EAAE,mBAAmB;YACzB,IAAI,EAAE,EAAE,OAAO,EAAE,+BAA+B,EAAE;SACnD,CAAC;QAEF,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,KAAK,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;QAC7D,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;QACtD,qGAAqG;QACrG,2IAA2I;QAC3I,qFAAqF;QACrF,sEAAsE;QACtE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,aAAa,EAAE,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wGAAwG,EAAE,KAAK,IAAI,EAAE;QACtH,YAAY;QACZ,qGAAqG;QACrG,gFAAgF;QAChF,MAAM,0BAA0B,GAAG,iBAAiB,CAClD,SAAS,EACT,yBAAyB,EACzB,SAAS,CACV,CAAC;QAEF,MAAM,YAAY,GAAG,IAAI,YAAY,CAAC;YACpC,KAAK,EAAE;gBACL;oBACE,QAAQ,EAAE,mBAAmB;oBAC7B,WAAW,EAAE,IAAI,MAAM,CAAC,0BAA0B,CAAC,CAAC,CAAE,CAAC;oBACvD,QAAQ,EAAE,cAAc,CAAC,QAAQ;oBACjC,QAAQ,EAAE,CAAC;oBACX,IAAI,EAAE,kCAAkC;iBACzC;aACF;YACD,eAAe,EAAE,cAAc,CAAC,QAAQ;SACzC,CAAC,CAAC;QAEH,MAAM,QAAQ,GAAiB;YAC7B,IAAI,EAAE,mBAAmB;YACzB,IAAI,EAAE,EAAE,OAAO,EAAE,8CAA8C,EAAE;SAClE,CAAC;QAEF,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,KAAK,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;QAC7D,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;QACtD,gEAAgE;QAChE,8CAA8C;QAC9C,gDAAgD;QAChD,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,aAAa,EAAE,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0HAA0H,EAAE,KAAK,IAAI,EAAE;QACxI,YAAY;QACZ,6GAA6G;QAC7G,+EAA+E;QAC/E,iGAAiG;QACjG,8DAA8D;QAC9D,MAAM,gBAAgB,GAAG,iBAAiB,CACxC,SAAS,EACT,qBAAqB,EACrB,SAAS,CACV,CAAC;QACF,MAAM,gBAAgB,GAAG,iBAAiB,CACxC,SAAS,EACT,qBAAqB,EACrB,SAAS,CACV,CAAC;QAEF,MAAM,YAAY,GAAG,IAAI,YAAY,CAAC;YACpC,KAAK,EAAE;gBACL;oBACE,QAAQ,EAAE,mBAAmB;oBAC7B,WAAW,EAAE,IAAI,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAE,CAAC;oBAC7C,QAAQ,EAAE,cAAc,CAAC,QAAQ;oBACjC,QAAQ,EAAE,CAAC;oBACX,IAAI,EAAE,YAAY;iBACnB;gBACD;oBACE,QAAQ,EAAE,mBAAmB;oBAC7B,WAAW,EAAE,IAAI,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAE,CAAC;oBAC7C,QAAQ,EAAE,cAAc,CAAC,QAAQ;oBACjC,QAAQ,EAAE,CAAC;oBACX,IAAI,EAAE,YAAY;iBACnB;aACF;YACD,eAAe,EAAE,cAAc,CAAC,KAAK,EAAE,+CAA+C;SACvF,CAAC,CAAC;QAEH,MAAM,QAAQ,GAAiB;YAC7B,IAAI,EAAE,mBAAmB;YACzB,IAAI,EAAE,EAAE,OAAO,EAAE,4CAA4C,EAAE;SAChE,CAAC;QAEF,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,KAAK,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;QAC7D,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;QACtD,0DAA0D;QAC1D,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -62,6 +62,10 @@ export interface InProcessCheckerConfig {
|
|
|
62
62
|
*/
|
|
63
63
|
export type SafetyCheckerConfig = ExternalCheckerConfig | InProcessCheckerConfig;
|
|
64
64
|
export interface PolicyRule {
|
|
65
|
+
/**
|
|
66
|
+
* A unique name for the policy rule, useful for identification and debugging.
|
|
67
|
+
*/
|
|
68
|
+
name?: string;
|
|
65
69
|
/**
|
|
66
70
|
* The name of the tool this rule applies to.
|
|
67
71
|
* If undefined, the rule applies to all tools.
|
package/dist/src/policy/utils.js
CHANGED
|
@@ -31,7 +31,10 @@ export function buildArgsPatterns(argsPattern, commandPrefix, commandRegex) {
|
|
|
31
31
|
// always followed by a space or a closing quote.
|
|
32
32
|
return prefixes.map((prefix) => {
|
|
33
33
|
const jsonPrefix = JSON.stringify(prefix).slice(1, -1);
|
|
34
|
-
|
|
34
|
+
// We allow [\s], ["], or the specific sequence [\"] (for escaped quotes
|
|
35
|
+
// in JSON). We do NOT allow generic [\\], which would match "git\status"
|
|
36
|
+
// -> "gitstatus".
|
|
37
|
+
return `"command":"${escapeRegex(jsonPrefix)}(?:[\\s"]|\\\\")`;
|
|
35
38
|
});
|
|
36
39
|
}
|
|
37
40
|
if (commandRegex) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/policy/utils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,OAAO,IAAI,CAAC,OAAO,CAAC,2BAA2B,EAAE,MAAM,CAAC,CAAC;AAC3D,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,iBAAiB,CAC/B,WAAoB,EACpB,aAAiC,EACjC,YAAqB;IAErB,IAAI,aAAa,EAAE,CAAC;QAClB,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC;YAC3C,CAAC,CAAC,aAAa;YACf,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC;QAEpB,gDAAgD;QAChD,4EAA4E;QAC5E,wEAAwE;QACxE,iDAAiD;QACjD,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;YAC7B,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACvD,OAAO,cAAc,WAAW,CAAC,UAAU,CAAC,
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/policy/utils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,OAAO,IAAI,CAAC,OAAO,CAAC,2BAA2B,EAAE,MAAM,CAAC,CAAC;AAC3D,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,iBAAiB,CAC/B,WAAoB,EACpB,aAAiC,EACjC,YAAqB;IAErB,IAAI,aAAa,EAAE,CAAC;QAClB,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC;YAC3C,CAAC,CAAC,aAAa;YACf,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC;QAEpB,gDAAgD;QAChD,4EAA4E;QAC5E,wEAAwE;QACxE,iDAAiD;QACjD,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;YAC7B,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACvD,wEAAwE;YACxE,yEAAyE;YACzE,kBAAkB;YAClB,OAAO,cAAc,WAAW,CAAC,UAAU,CAAC,kBAAkB,CAAC;QACjE,CAAC,CAAC,CAAC;IACL,CAAC;IAED,IAAI,YAAY,EAAE,CAAC;QACjB,OAAO,CAAC,cAAc,YAAY,EAAE,CAAC,CAAC;IACxC,CAAC;IAED,OAAO,CAAC,WAAW,CAAC,CAAC;AACvB,CAAC"}
|
|
@@ -24,13 +24,13 @@ describe('policy/utils', () => {
|
|
|
24
24
|
});
|
|
25
25
|
it('should build pattern from a single commandPrefix', () => {
|
|
26
26
|
const result = buildArgsPatterns(undefined, 'ls', undefined);
|
|
27
|
-
expect(result).toEqual(['"command":"ls(?:[\\s"]
|
|
27
|
+
expect(result).toEqual(['"command":"ls(?:[\\s"]|\\\\")']);
|
|
28
28
|
});
|
|
29
29
|
it('should build patterns from an array of commandPrefixes', () => {
|
|
30
30
|
const result = buildArgsPatterns(undefined, ['ls', 'cd'], undefined);
|
|
31
31
|
expect(result).toEqual([
|
|
32
|
-
'"command":"ls(?:[\\s"]
|
|
33
|
-
'"command":"cd(?:[\\s"]
|
|
32
|
+
'"command":"ls(?:[\\s"]|\\\\")',
|
|
33
|
+
'"command":"cd(?:[\\s"]|\\\\")',
|
|
34
34
|
]);
|
|
35
35
|
});
|
|
36
36
|
it('should build pattern from commandRegex', () => {
|
|
@@ -39,7 +39,7 @@ describe('policy/utils', () => {
|
|
|
39
39
|
});
|
|
40
40
|
it('should prioritize commandPrefix over commandRegex and argsPattern', () => {
|
|
41
41
|
const result = buildArgsPatterns('raw', 'prefix', 'regex');
|
|
42
|
-
expect(result).toEqual(['"command":"prefix(?:[\\s"]
|
|
42
|
+
expect(result).toEqual(['"command":"prefix(?:[\\s"]|\\\\")']);
|
|
43
43
|
});
|
|
44
44
|
it('should prioritize commandRegex over argsPattern if no commandPrefix', () => {
|
|
45
45
|
const result = buildArgsPatterns('raw', undefined, 'regex');
|
|
@@ -47,18 +47,46 @@ describe('policy/utils', () => {
|
|
|
47
47
|
});
|
|
48
48
|
it('should escape characters in commandPrefix', () => {
|
|
49
49
|
const result = buildArgsPatterns(undefined, 'git checkout -b', undefined);
|
|
50
|
-
expect(result).toEqual([
|
|
50
|
+
expect(result).toEqual([
|
|
51
|
+
'"command":"git\\ checkout\\ \\-b(?:[\\s"]|\\\\")',
|
|
52
|
+
]);
|
|
51
53
|
});
|
|
52
54
|
it('should correctly escape quotes in commandPrefix', () => {
|
|
53
55
|
const result = buildArgsPatterns(undefined, 'git "fix"', undefined);
|
|
54
56
|
expect(result).toEqual([
|
|
55
|
-
'"command":"git\\ \\\\\\"fix\\\\\\"(?:[\\s"]
|
|
57
|
+
'"command":"git\\ \\\\\\"fix\\\\\\"(?:[\\s"]|\\\\")',
|
|
56
58
|
]);
|
|
57
59
|
});
|
|
58
60
|
it('should handle undefined correctly when no inputs are provided', () => {
|
|
59
61
|
const result = buildArgsPatterns(undefined, undefined, undefined);
|
|
60
62
|
expect(result).toEqual([undefined]);
|
|
61
63
|
});
|
|
64
|
+
it('should match prefixes followed by JSON escaped quotes', () => {
|
|
65
|
+
// Testing the security fix logic: allowing "echo \"foo\""
|
|
66
|
+
const prefix = 'echo ';
|
|
67
|
+
const patterns = buildArgsPatterns(undefined, prefix, undefined);
|
|
68
|
+
const regex = new RegExp(patterns[0]);
|
|
69
|
+
// Mimic JSON stringified args
|
|
70
|
+
// echo "foo" -> {"command":"echo \"foo\""}
|
|
71
|
+
const validJsonArgs = '{"command":"echo \\"foo\\""}';
|
|
72
|
+
expect(regex.test(validJsonArgs)).toBe(true);
|
|
73
|
+
});
|
|
74
|
+
it('should NOT match prefixes followed by raw backslashes (security check)', () => {
|
|
75
|
+
// Testing that we blocked the hole: "echo\foo"
|
|
76
|
+
const prefix = 'echo ';
|
|
77
|
+
const patterns = buildArgsPatterns(undefined, prefix, undefined);
|
|
78
|
+
const regex = new RegExp(patterns[0]);
|
|
79
|
+
// echo\foo -> {"command":"echo\\foo"}
|
|
80
|
+
// In regex matching: "echo " is followed by "\" which is NOT in [\s"] and is not \"
|
|
81
|
+
const attackJsonArgs = '{"command":"echo\\\\foo"}';
|
|
82
|
+
expect(regex.test(attackJsonArgs)).toBe(false);
|
|
83
|
+
// Also validation for "git " matching "git\status"
|
|
84
|
+
const gitPatterns = buildArgsPatterns(undefined, 'git ', undefined);
|
|
85
|
+
const gitRegex = new RegExp(gitPatterns[0]);
|
|
86
|
+
// git\status -> {"command":"git\\status"}
|
|
87
|
+
const gitAttack = '{"command":"git\\\\status"}';
|
|
88
|
+
expect(gitRegex.test(gitAttack)).toBe(false);
|
|
89
|
+
});
|
|
62
90
|
});
|
|
63
91
|
});
|
|
64
92
|
//# sourceMappingURL=utils.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.test.js","sourceRoot":"","sources":["../../../src/policy/utils.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAE5D,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;IAC5B,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;QAC3B,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;YAChD,MAAM,KAAK,GAAG,oBAAoB,CAAC;YACnC,MAAM,OAAO,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;YACnC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAClB,sDAAsD,CACvD,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,oEAAoE,EAAE,GAAG,EAAE;YAC5E,MAAM,KAAK,GAAG,WAAW,CAAC;YAC1B,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACzC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;QACjC,EAAE,CAAC,kEAAkE,EAAE,GAAG,EAAE;YAC1E,MAAM,MAAM,GAAG,iBAAiB,CAAC,YAAY,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;YACrE,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC;QACzC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE;YAC1D,MAAM,MAAM,GAAG,iBAAiB,CAAC,SAAS,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC;YAC7D,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"utils.test.js","sourceRoot":"","sources":["../../../src/policy/utils.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -32,6 +32,8 @@ export interface RoutingContext {
|
|
|
32
32
|
request: PartListUnion;
|
|
33
33
|
/** An abort signal to cancel an LLM call during routing. */
|
|
34
34
|
signal: AbortSignal;
|
|
35
|
+
/** The model string requested for this turn, if any. */
|
|
36
|
+
requestedModel?: string;
|
|
35
37
|
}
|
|
36
38
|
/**
|
|
37
39
|
* The core interface that all routing strategies must implement.
|
|
@@ -134,7 +134,7 @@ export class ClassifierStrategy {
|
|
|
134
134
|
const routerResponse = ClassifierResponseSchema.parse(jsonResponse);
|
|
135
135
|
const reasoning = routerResponse.reasoning;
|
|
136
136
|
const latencyMs = Date.now() - startTime;
|
|
137
|
-
const selectedModel = resolveClassifierModel(config.getModel(), routerResponse.model_choice, config.getPreviewFeatures());
|
|
137
|
+
const selectedModel = resolveClassifierModel(context.requestedModel ?? config.getModel(), routerResponse.model_choice, config.getPreviewFeatures());
|
|
138
138
|
return {
|
|
139
139
|
model: selectedModel,
|
|
140
140
|
metadata: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"classifierStrategy.js","sourceRoot":"","sources":["../../../../src/routing/strategies/classifierStrategy.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"classifierStrategy.js","sourceRoot":"","sources":["../../../../src/routing/strategies/classifierStrategy.ts"],"names":[],"mappings":"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"}
|
|
@@ -193,5 +193,21 @@ describe('ClassifierStrategy', () => {
|
|
|
193
193
|
expect(consoleWarnSpy).toHaveBeenCalledWith(expect.stringContaining('Could not find promptId in context. This is unexpected. Using a fallback ID:'));
|
|
194
194
|
consoleWarnSpy.mockRestore();
|
|
195
195
|
});
|
|
196
|
+
it('should respect requestedModel from context in resolveClassifierModel', async () => {
|
|
197
|
+
const requestedModel = DEFAULT_GEMINI_MODEL; // Pro model
|
|
198
|
+
const mockApiResponse = {
|
|
199
|
+
reasoning: 'Choice is flash',
|
|
200
|
+
model_choice: 'flash',
|
|
201
|
+
};
|
|
202
|
+
vi.mocked(mockBaseLlmClient.generateJson).mockResolvedValue(mockApiResponse);
|
|
203
|
+
const contextWithRequestedModel = {
|
|
204
|
+
...mockContext,
|
|
205
|
+
requestedModel,
|
|
206
|
+
};
|
|
207
|
+
const decision = await strategy.route(contextWithRequestedModel, mockConfig, mockBaseLlmClient);
|
|
208
|
+
expect(decision).not.toBeNull();
|
|
209
|
+
// Since requestedModel is Pro, and choice is flash, it should resolve to Flash
|
|
210
|
+
expect(decision?.model).toBe(DEFAULT_GEMINI_FLASH_MODEL);
|
|
211
|
+
});
|
|
196
212
|
});
|
|
197
213
|
//# sourceMappingURL=classifierStrategy.test.js.map
|