@office-ai/aioncli-core 0.30.0 → 0.30.1
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/dist/docs/assets/theme-ansi-dark.png +0 -0
- package/dist/docs/assets/theme-atom-one-dark.png +0 -0
- package/dist/docs/assets/theme-ayu-dark.png +0 -0
- package/dist/docs/assets/theme-default-dark.png +0 -0
- package/dist/docs/assets/theme-dracula-dark.png +0 -0
- package/dist/docs/assets/theme-github-dark.png +0 -0
- package/dist/docs/assets/theme-holiday-dark.png +0 -0
- package/dist/docs/assets/theme-shades-of-purple-dark.png +0 -0
- package/dist/docs/assets/theme-solarized-dark.png +0 -0
- package/dist/docs/assets/theme-solarized-light.png +0 -0
- package/dist/docs/cli/notifications.md +58 -0
- package/dist/docs/redirects.json +20 -0
- package/dist/docs/reference/commands.md +563 -0
- package/dist/docs/reference/configuration.md +1804 -0
- package/dist/docs/reference/keyboard-shortcuts.md +168 -0
- package/dist/docs/reference/memport.md +246 -0
- package/dist/docs/reference/policy-engine.md +386 -0
- package/dist/docs/reference/tools.md +106 -0
- package/dist/docs/resources/faq.md +175 -0
- package/dist/docs/resources/quota-and-pricing.md +199 -0
- package/dist/docs/resources/tos-privacy.md +102 -0
- package/dist/docs/resources/troubleshooting.md +176 -0
- package/dist/docs/resources/uninstall.md +56 -0
- package/dist/src/agents/a2a-errors.d.ts +65 -0
- package/dist/src/agents/a2a-errors.js +164 -0
- package/dist/src/agents/a2a-errors.js.map +1 -0
- package/dist/src/agents/a2a-errors.test.d.ts +6 -0
- package/dist/src/agents/a2a-errors.test.js +183 -0
- package/dist/src/agents/a2a-errors.test.js.map +1 -0
- package/dist/src/agents/auth-provider/api-key-provider.d.ts +30 -0
- package/dist/src/agents/auth-provider/api-key-provider.js +66 -0
- package/dist/src/agents/auth-provider/api-key-provider.js.map +1 -0
- package/dist/src/agents/auth-provider/api-key-provider.test.d.ts +6 -0
- package/dist/src/agents/auth-provider/api-key-provider.test.js +130 -0
- package/dist/src/agents/auth-provider/api-key-provider.test.js.map +1 -0
- package/dist/src/agents/auth-provider/http-provider.d.ts +28 -0
- package/dist/src/agents/auth-provider/http-provider.js +73 -0
- package/dist/src/agents/auth-provider/http-provider.js.map +1 -0
- package/dist/src/agents/auth-provider/http-provider.test.d.ts +6 -0
- package/dist/src/agents/auth-provider/http-provider.test.js +112 -0
- package/dist/src/agents/auth-provider/http-provider.test.js.map +1 -0
- package/dist/src/agents/auth-provider/oauth2-provider.d.ts +65 -0
- package/dist/src/agents/auth-provider/oauth2-provider.js +233 -0
- package/dist/src/agents/auth-provider/oauth2-provider.js.map +1 -0
- package/dist/src/agents/auth-provider/oauth2-provider.test.d.ts +6 -0
- package/dist/src/agents/auth-provider/oauth2-provider.test.js +490 -0
- package/dist/src/agents/auth-provider/oauth2-provider.test.js.map +1 -0
- package/dist/src/agents/browser/analyzeScreenshot.d.ts +35 -0
- package/dist/src/agents/browser/analyzeScreenshot.js +183 -0
- package/dist/src/agents/browser/analyzeScreenshot.js.map +1 -0
- package/dist/src/agents/browser/analyzeScreenshot.test.d.ts +6 -0
- package/dist/src/agents/browser/analyzeScreenshot.test.js +161 -0
- package/dist/src/agents/browser/analyzeScreenshot.test.js.map +1 -0
- package/dist/src/agents/browser/automationOverlay.d.ts +26 -0
- package/dist/src/agents/browser/automationOverlay.js +100 -0
- package/dist/src/agents/browser/automationOverlay.js.map +1 -0
- package/dist/src/agents/browser/browserAgentDefinition.d.ts +50 -0
- package/dist/src/agents/browser/browserAgentDefinition.js +141 -0
- package/dist/src/agents/browser/browserAgentDefinition.js.map +1 -0
- package/dist/src/agents/browser/browserAgentFactory.d.ts +42 -0
- package/dist/src/agents/browser/browserAgentFactory.js +116 -0
- package/dist/src/agents/browser/browserAgentFactory.js.map +1 -0
- package/dist/src/agents/browser/browserAgentFactory.test.d.ts +6 -0
- package/dist/src/agents/browser/browserAgentFactory.test.js +240 -0
- package/dist/src/agents/browser/browserAgentFactory.test.js.map +1 -0
- package/dist/src/agents/browser/browserAgentInvocation.d.ts +34 -0
- package/dist/src/agents/browser/browserAgentInvocation.js +386 -0
- package/dist/src/agents/browser/browserAgentInvocation.js.map +1 -0
- package/dist/src/agents/browser/browserAgentInvocation.test.d.ts +6 -0
- package/dist/src/agents/browser/browserAgentInvocation.test.js +382 -0
- package/dist/src/agents/browser/browserAgentInvocation.test.js.map +1 -0
- package/dist/src/agents/browser/browserManager.d.ts +115 -0
- package/dist/src/agents/browser/browserManager.js +370 -0
- package/dist/src/agents/browser/browserManager.js.map +1 -0
- package/dist/src/agents/browser/browserManager.test.d.ts +6 -0
- package/dist/src/agents/browser/browserManager.test.js +382 -0
- package/dist/src/agents/browser/browserManager.test.js.map +1 -0
- package/dist/src/agents/browser/mcpToolWrapper.d.ts +45 -0
- package/dist/src/agents/browser/mcpToolWrapper.js +358 -0
- package/dist/src/agents/browser/mcpToolWrapper.js.map +1 -0
- package/dist/src/agents/browser/mcpToolWrapper.test.d.ts +6 -0
- package/dist/src/agents/browser/mcpToolWrapper.test.js +126 -0
- package/dist/src/agents/browser/mcpToolWrapper.test.js.map +1 -0
- package/dist/src/agents/browser/mcpToolWrapperConfirmation.test.d.ts +6 -0
- package/dist/src/agents/browser/mcpToolWrapperConfirmation.test.js +59 -0
- package/dist/src/agents/browser/mcpToolWrapperConfirmation.test.js.map +1 -0
- package/dist/src/agents/browser/modelAvailability.d.ts +23 -0
- package/dist/src/agents/browser/modelAvailability.js +23 -0
- package/dist/src/agents/browser/modelAvailability.js.map +1 -0
- package/dist/src/agents/cli-help-agent.d.ts +2 -2
- package/dist/src/billing/billing.d.ts +80 -0
- package/dist/src/billing/billing.js +128 -0
- package/dist/src/billing/billing.js.map +1 -0
- package/dist/src/billing/billing.test.d.ts +6 -0
- package/dist/src/billing/billing.test.js +182 -0
- package/dist/src/billing/billing.test.js.map +1 -0
- package/dist/src/billing/index.d.ts +6 -0
- package/dist/src/billing/index.js +7 -0
- package/dist/src/billing/index.js.map +1 -0
- package/dist/src/code_assist/oauth2.d.ts +1 -1
- package/dist/src/code_assist/types.d.ts +26 -26
- package/dist/src/config/agent-loop-context.d.ts +22 -0
- package/dist/src/config/agent-loop-context.js +7 -0
- package/dist/src/config/agent-loop-context.js.map +1 -0
- package/dist/src/config/trackerFeatureFlag.test.d.ts +6 -0
- package/dist/src/config/trackerFeatureFlag.test.js +43 -0
- package/dist/src/config/trackerFeatureFlag.test.js.map +1 -0
- package/dist/src/config/userHintService.d.ts +46 -0
- package/dist/src/config/userHintService.js +81 -0
- package/dist/src/config/userHintService.js.map +1 -0
- package/dist/src/config/userHintService.test.d.ts +6 -0
- package/dist/src/config/userHintService.test.js +62 -0
- package/dist/src/config/userHintService.test.js.map +1 -0
- package/dist/src/core/localLiteRtLmClient.d.ts +24 -0
- package/dist/src/core/localLiteRtLmClient.js +77 -0
- package/dist/src/core/localLiteRtLmClient.js.map +1 -0
- package/dist/src/core/localLiteRtLmClient.test.d.ts +6 -0
- package/dist/src/core/localLiteRtLmClient.test.js +87 -0
- package/dist/src/core/localLiteRtLmClient.test.js.map +1 -0
- package/dist/src/core/openaiContentGenerator.d.ts +1 -0
- package/dist/src/core/openaiContentGenerator.js +13 -13
- package/dist/src/core/openaiContentGenerator.js.map +1 -1
- package/dist/src/hooks/runtimeHooks.test.d.ts +6 -0
- package/dist/src/hooks/runtimeHooks.test.js +100 -0
- package/dist/src/hooks/runtimeHooks.test.js.map +1 -0
- package/dist/src/ide/types.d.ts +6 -6
- package/dist/src/mcp/mcp-oauth-provider.d.ts +43 -0
- package/dist/src/mcp/mcp-oauth-provider.js +67 -0
- package/dist/src/mcp/mcp-oauth-provider.js.map +1 -0
- package/dist/src/mcp/mcp-oauth-provider.test.d.ts +6 -0
- package/dist/src/mcp/mcp-oauth-provider.test.js +63 -0
- package/dist/src/mcp/mcp-oauth-provider.test.js.map +1 -0
- package/dist/src/policy/integrity.d.ts +45 -0
- package/dist/src/policy/integrity.js +121 -0
- package/dist/src/policy/integrity.js.map +1 -0
- package/dist/src/policy/integrity.test.d.ts +6 -0
- package/dist/src/policy/integrity.test.js +132 -0
- package/dist/src/policy/integrity.test.js.map +1 -0
- package/dist/src/policy/policies/conseca.toml +6 -0
- package/dist/src/policy/workspace-policy.test.js +231 -0
- package/dist/src/policy/workspace-policy.test.js.map +1 -0
- package/dist/src/routing/strategies/approvalModeStrategy.d.ts +18 -0
- package/dist/src/routing/strategies/approvalModeStrategy.js +59 -0
- package/dist/src/routing/strategies/approvalModeStrategy.js.map +1 -0
- package/dist/src/routing/strategies/approvalModeStrategy.test.d.ts +6 -0
- package/dist/src/routing/strategies/approvalModeStrategy.test.js +140 -0
- package/dist/src/routing/strategies/approvalModeStrategy.test.js.map +1 -0
- package/dist/src/routing/strategies/gemmaClassifierStrategy.d.ts +14 -0
- package/dist/src/routing/strategies/gemmaClassifierStrategy.js +182 -0
- package/dist/src/routing/strategies/gemmaClassifierStrategy.js.map +1 -0
- package/dist/src/routing/strategies/gemmaClassifierStrategy.test.d.ts +6 -0
- package/dist/src/routing/strategies/gemmaClassifierStrategy.test.js +218 -0
- package/dist/src/routing/strategies/gemmaClassifierStrategy.test.js.map +1 -0
- package/dist/src/safety/conseca/conseca.d.ts +31 -0
- package/dist/src/safety/conseca/conseca.js +105 -0
- package/dist/src/safety/conseca/conseca.js.map +1 -0
- package/dist/src/safety/conseca/conseca.test.js +226 -0
- package/dist/src/safety/conseca/conseca.test.js.map +1 -0
- package/dist/src/safety/conseca/integration.test.js +19 -0
- package/dist/src/safety/conseca/integration.test.js.map +1 -0
- package/dist/src/safety/conseca/policy-enforcer.d.ts +13 -0
- package/dist/src/safety/conseca/policy-enforcer.js +135 -0
- package/dist/src/safety/conseca/policy-enforcer.js.map +1 -0
- package/dist/src/safety/conseca/policy-enforcer.test.js +141 -0
- package/dist/src/safety/conseca/policy-enforcer.test.js.map +1 -0
- package/dist/src/safety/conseca/policy-generator.d.ts +15 -0
- package/dist/src/safety/conseca/policy-generator.js +144 -0
- package/dist/src/safety/conseca/policy-generator.js.map +1 -0
- package/dist/src/safety/conseca/policy-generator.test.d.ts +6 -0
- package/dist/src/safety/conseca/policy-generator.test.js +84 -0
- package/dist/src/safety/conseca/policy-generator.test.js.map +1 -0
- package/dist/src/safety/conseca/types.d.ts +15 -0
- package/dist/src/safety/conseca/types.js +7 -0
- package/dist/src/safety/conseca/types.js.map +1 -0
- package/dist/src/scheduler/scheduler_parallel.test.d.ts +6 -0
- package/dist/src/scheduler/scheduler_parallel.test.js +401 -0
- package/dist/src/scheduler/scheduler_parallel.test.js.map +1 -0
- package/dist/src/services/FolderTrustDiscoveryService.d.ts +32 -0
- package/dist/src/services/FolderTrustDiscoveryService.js +169 -0
- package/dist/src/services/FolderTrustDiscoveryService.js.map +1 -0
- package/dist/src/services/FolderTrustDiscoveryService.test.d.ts +6 -0
- package/dist/src/services/FolderTrustDiscoveryService.test.js +118 -0
- package/dist/src/services/FolderTrustDiscoveryService.test.js.map +1 -0
- package/dist/src/services/fileKeychain.d.ts +24 -0
- package/dist/src/services/fileKeychain.js +123 -0
- package/dist/src/services/fileKeychain.js.map +1 -0
- package/dist/src/services/keychainService.d.ts +51 -0
- package/dist/src/services/keychainService.js +133 -0
- package/dist/src/services/keychainService.js.map +1 -0
- package/dist/src/services/keychainService.test.d.ts +6 -0
- package/dist/src/services/keychainService.test.js +150 -0
- package/dist/src/services/keychainService.test.js.map +1 -0
- package/dist/src/services/keychainTypes.d.ts +41 -0
- package/dist/src/services/keychainTypes.js +18 -0
- package/dist/src/services/keychainTypes.js.map +1 -0
- package/dist/src/services/trackerService.d.ts +49 -0
- package/dist/src/services/trackerService.js +193 -0
- package/dist/src/services/trackerService.js.map +1 -0
- package/dist/src/services/trackerService.test.d.ts +6 -0
- package/dist/src/services/trackerService.test.js +117 -0
- package/dist/src/services/trackerService.test.js.map +1 -0
- package/dist/src/services/trackerTypes.d.ts +51 -0
- package/dist/src/services/trackerTypes.js +33 -0
- package/dist/src/services/trackerTypes.js.map +1 -0
- package/dist/src/telemetry/billingEvents.d.ts +75 -0
- package/dist/src/telemetry/billingEvents.js +181 -0
- package/dist/src/telemetry/billingEvents.js.map +1 -0
- package/dist/src/telemetry/billingEvents.test.d.ts +6 -0
- package/dist/src/telemetry/billingEvents.test.js +139 -0
- package/dist/src/telemetry/billingEvents.test.js.map +1 -0
- package/dist/src/telemetry/conseca-logger.d.ts +9 -0
- package/dist/src/telemetry/conseca-logger.js +91 -0
- package/dist/src/telemetry/conseca-logger.js.map +1 -0
- package/dist/src/telemetry/conseca-logger.test.d.ts +6 -0
- package/dist/src/telemetry/conseca-logger.test.js +90 -0
- package/dist/src/telemetry/conseca-logger.test.js.map +1 -0
- package/dist/src/telemetry/trace.test.d.ts +6 -0
- package/dist/src/telemetry/trace.test.js +116 -0
- package/dist/src/telemetry/trace.test.js.map +1 -0
- package/dist/src/tools/definitions/trackerTools.d.ts +12 -0
- package/dist/src/tools/definitions/trackerTools.js +146 -0
- package/dist/src/tools/definitions/trackerTools.js.map +1 -0
- package/dist/src/tools/diff-utils.d.ts +9 -0
- package/dist/src/tools/diff-utils.js +66 -0
- package/dist/src/tools/diff-utils.js.map +1 -0
- package/dist/src/tools/diff-utils.test.d.ts +6 -0
- package/dist/src/tools/diff-utils.test.js +53 -0
- package/dist/src/tools/diff-utils.test.js.map +1 -0
- package/dist/src/tools/grep-utils.d.ts +49 -0
- package/dist/src/tools/grep-utils.js +147 -0
- package/dist/src/tools/grep-utils.js.map +1 -0
- package/dist/src/tools/omissionPlaceholderDetector.d.ts +15 -0
- package/dist/src/tools/omissionPlaceholderDetector.js +90 -0
- package/dist/src/tools/omissionPlaceholderDetector.js.map +1 -0
- package/dist/src/tools/omissionPlaceholderDetector.test.d.ts +6 -0
- package/dist/src/tools/omissionPlaceholderDetector.test.js +49 -0
- package/dist/src/tools/omissionPlaceholderDetector.test.js.map +1 -0
- package/dist/src/tools/trackerTools.d.ts +122 -0
- package/dist/src/tools/trackerTools.js +365 -0
- package/dist/src/tools/trackerTools.js.map +1 -0
- package/dist/src/tools/trackerTools.test.d.ts +6 -0
- package/dist/src/tools/trackerTools.test.js +97 -0
- package/dist/src/tools/trackerTools.test.js.map +1 -0
- package/dist/src/utils/approvalModeUtils.d.ts +14 -0
- package/dist/src/utils/approvalModeUtils.js +35 -0
- package/dist/src/utils/approvalModeUtils.js.map +1 -0
- package/dist/src/utils/approvalModeUtils.test.d.ts +6 -0
- package/dist/src/utils/approvalModeUtils.test.js +36 -0
- package/dist/src/utils/approvalModeUtils.test.js.map +1 -0
- package/dist/src/utils/cache.d.ts +63 -0
- package/dist/src/utils/cache.js +103 -0
- package/dist/src/utils/cache.js.map +1 -0
- package/dist/src/utils/cache.test.d.ts +6 -0
- package/dist/src/utils/cache.test.js +158 -0
- package/dist/src/utils/cache.test.js.map +1 -0
- package/dist/src/utils/checkpointUtils.d.ts +2 -2
- package/dist/src/utils/compatibility.d.ts +41 -0
- package/dist/src/utils/compatibility.js +112 -0
- package/dist/src/utils/compatibility.js.map +1 -0
- package/dist/src/utils/compatibility.test.d.ts +6 -0
- package/dist/src/utils/compatibility.test.js +233 -0
- package/dist/src/utils/compatibility.test.js.map +1 -0
- package/dist/src/utils/envExpansion.d.ts +18 -0
- package/dist/src/utils/envExpansion.js +46 -0
- package/dist/src/utils/envExpansion.js.map +1 -0
- package/dist/src/utils/envExpansion.test.d.ts +6 -0
- package/dist/src/utils/envExpansion.test.js +110 -0
- package/dist/src/utils/envExpansion.test.js.map +1 -0
- package/dist/src/utils/errors_timeout.test.d.ts +6 -0
- package/dist/src/utils/errors_timeout.test.js +40 -0
- package/dist/src/utils/errors_timeout.test.js.map +1 -0
- package/dist/src/utils/fetch.test.d.ts +6 -0
- package/dist/src/utils/fetch.test.js +206 -0
- package/dist/src/utils/fetch.test.js.map +1 -0
- package/dist/src/utils/markdownUtils.d.ts +22 -0
- package/dist/src/utils/markdownUtils.js +126 -0
- package/dist/src/utils/markdownUtils.js.map +1 -0
- package/dist/src/utils/markdownUtils.test.d.ts +6 -0
- package/dist/src/utils/markdownUtils.test.js +107 -0
- package/dist/src/utils/markdownUtils.test.js.map +1 -0
- package/dist/src/utils/oauth-flow.d.ts +105 -0
- package/dist/src/utils/oauth-flow.js +370 -0
- package/dist/src/utils/oauth-flow.js.map +1 -0
- package/dist/src/utils/oauth-flow.test.d.ts +6 -0
- package/dist/src/utils/oauth-flow.test.js +360 -0
- package/dist/src/utils/oauth-flow.test.js.map +1 -0
- package/dist/src/utils/sessionUtils.d.ts +14 -0
- package/dist/src/utils/sessionUtils.js +122 -0
- package/dist/src/utils/sessionUtils.js.map +1 -0
- package/dist/src/utils/sessionUtils.test.d.ts +1 -0
- package/dist/src/utils/sessionUtils.test.js +171 -0
- package/dist/src/utils/sessionUtils.test.js.map +1 -0
- package/dist/src/voice/responseFormatter.d.ts +38 -0
- package/dist/src/voice/responseFormatter.js +130 -0
- package/dist/src/voice/responseFormatter.js.map +1 -0
- package/dist/src/voice/responseFormatter.test.d.ts +6 -0
- package/dist/src/voice/responseFormatter.test.js +214 -0
- package/dist/src/voice/responseFormatter.test.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/dist/docs/CONTRIBUTING.md +0 -555
- package/dist/src/agents/executor.d.ts +0 -114
- package/dist/src/agents/executor.js +0 -779
- package/dist/src/agents/executor.js.map +0 -1
- package/dist/src/agents/executor.test.js +0 -1362
- package/dist/src/agents/executor.test.js.map +0 -1
- package/dist/src/agents/invocation.d.ts +0 -46
- package/dist/src/agents/invocation.js +0 -102
- package/dist/src/agents/invocation.js.map +0 -1
- package/dist/src/agents/invocation.test.js +0 -215
- package/dist/src/agents/invocation.test.js.map +0 -1
- package/dist/src/core/subagent.d.ts +0 -236
- package/dist/src/core/subagent.js +0 -482
- package/dist/src/core/subagent.js.map +0 -1
- package/dist/src/core/subagent.test.js +0 -530
- package/dist/src/core/subagent.test.js.map +0 -1
- package/dist/src/tools/smart-edit.d.ts +0 -78
- package/dist/src/tools/smart-edit.js +0 -717
- package/dist/src/tools/smart-edit.js.map +0 -1
- package/dist/src/tools/smart-edit.test.js +0 -592
- package/dist/src/tools/smart-edit.test.js.map +0 -1
- /package/dist/src/{agents/executor.test.d.ts → policy/workspace-policy.test.d.ts} +0 -0
- /package/dist/src/{agents/invocation.test.d.ts → safety/conseca/conseca.test.d.ts} +0 -0
- /package/dist/src/{core/subagent.test.d.ts → safety/conseca/integration.test.d.ts} +0 -0
- /package/dist/src/{tools/smart-edit.test.d.ts → safety/conseca/policy-enforcer.test.d.ts} +0 -0
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
7
|
+
import { enforcePolicy } from './policy-enforcer.js';
|
|
8
|
+
import { SafetyCheckDecision } from '../protocol.js';
|
|
9
|
+
import { LlmRole } from '../../telemetry/index.js';
|
|
10
|
+
describe('policy_enforcer', () => {
|
|
11
|
+
let mockConfig;
|
|
12
|
+
let mockContentGenerator;
|
|
13
|
+
beforeEach(() => {
|
|
14
|
+
vi.clearAllMocks();
|
|
15
|
+
mockContentGenerator = {
|
|
16
|
+
generateContent: vi.fn(),
|
|
17
|
+
};
|
|
18
|
+
mockConfig = {
|
|
19
|
+
getContentGenerator: vi.fn().mockReturnValue(mockContentGenerator),
|
|
20
|
+
};
|
|
21
|
+
});
|
|
22
|
+
it('should return ALLOW when content generator returns ALLOW', async () => {
|
|
23
|
+
mockContentGenerator.generateContent = vi.fn().mockResolvedValue({
|
|
24
|
+
candidates: [
|
|
25
|
+
{
|
|
26
|
+
content: {
|
|
27
|
+
parts: [
|
|
28
|
+
{ text: JSON.stringify({ decision: 'allow', reason: 'Safe' }) },
|
|
29
|
+
],
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
],
|
|
33
|
+
});
|
|
34
|
+
const toolCall = { name: 'testTool', args: {} };
|
|
35
|
+
const policy = {
|
|
36
|
+
testTool: {
|
|
37
|
+
permissions: SafetyCheckDecision.ALLOW,
|
|
38
|
+
constraints: 'None',
|
|
39
|
+
rationale: 'Test',
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
const result = await enforcePolicy(policy, toolCall, mockConfig);
|
|
43
|
+
expect(mockConfig.getContentGenerator).toHaveBeenCalled();
|
|
44
|
+
expect(mockContentGenerator.generateContent).toHaveBeenCalledWith(expect.objectContaining({
|
|
45
|
+
model: expect.any(String),
|
|
46
|
+
config: expect.objectContaining({
|
|
47
|
+
responseMimeType: 'application/json',
|
|
48
|
+
responseSchema: expect.any(Object),
|
|
49
|
+
}),
|
|
50
|
+
contents: expect.arrayContaining([
|
|
51
|
+
expect.objectContaining({
|
|
52
|
+
role: 'user',
|
|
53
|
+
parts: expect.arrayContaining([
|
|
54
|
+
expect.objectContaining({
|
|
55
|
+
text: expect.stringContaining('Security Policy:'),
|
|
56
|
+
}),
|
|
57
|
+
]),
|
|
58
|
+
}),
|
|
59
|
+
]),
|
|
60
|
+
}), 'conseca-policy-enforcement', LlmRole.SUBAGENT);
|
|
61
|
+
expect(result.decision).toBe(SafetyCheckDecision.ALLOW);
|
|
62
|
+
});
|
|
63
|
+
it('should handle missing content generator gracefully (error case)', async () => {
|
|
64
|
+
vi.mocked(mockConfig.getContentGenerator).mockReturnValue(undefined);
|
|
65
|
+
const toolCall = { name: 'testTool', args: {} };
|
|
66
|
+
const policy = {
|
|
67
|
+
testTool: {
|
|
68
|
+
permissions: SafetyCheckDecision.ALLOW,
|
|
69
|
+
constraints: 'None',
|
|
70
|
+
rationale: 'Test',
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
const result = await enforcePolicy(policy, toolCall, mockConfig);
|
|
74
|
+
expect(result.decision).toBe(SafetyCheckDecision.ALLOW);
|
|
75
|
+
});
|
|
76
|
+
it('should ALLOW if tool name is missing with the reason and error as tool name is missing', async () => {
|
|
77
|
+
const toolCall = { args: {} };
|
|
78
|
+
const policy = {};
|
|
79
|
+
const result = await enforcePolicy(policy, toolCall, mockConfig);
|
|
80
|
+
expect(result.decision).toBe(SafetyCheckDecision.ALLOW);
|
|
81
|
+
expect(result.reason).toBe('Tool name is missing');
|
|
82
|
+
if (result.decision === SafetyCheckDecision.ALLOW) {
|
|
83
|
+
expect(result.error).toBe('Tool name is missing');
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
it('should handle empty policy by checking with LLM (fail-open/check behavior)', async () => {
|
|
87
|
+
// Even if policy is empty for the tool, we currently send it to LLM.
|
|
88
|
+
// The LLM might ALLOW or DENY based on its own judgment of "no policy".
|
|
89
|
+
// We simulate the LLM allowing the action to match the current fail-open strategy.
|
|
90
|
+
mockContentGenerator.generateContent = vi.fn().mockResolvedValue({
|
|
91
|
+
candidates: [
|
|
92
|
+
{
|
|
93
|
+
content: {
|
|
94
|
+
parts: [
|
|
95
|
+
{
|
|
96
|
+
text: JSON.stringify({
|
|
97
|
+
decision: 'allow',
|
|
98
|
+
reason: 'No restrictions',
|
|
99
|
+
}),
|
|
100
|
+
},
|
|
101
|
+
],
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
],
|
|
105
|
+
});
|
|
106
|
+
const toolCall = { name: 'unknownTool', args: {} };
|
|
107
|
+
const policy = {}; // Empty policy
|
|
108
|
+
const result = await enforcePolicy(policy, toolCall, mockConfig);
|
|
109
|
+
expect(result.decision).toBe(SafetyCheckDecision.ALLOW);
|
|
110
|
+
expect(mockContentGenerator.generateContent).toHaveBeenCalled();
|
|
111
|
+
if (result.decision === SafetyCheckDecision.ALLOW) {
|
|
112
|
+
expect(result.error).toBeUndefined();
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
it('should handle malformed JSON response from LLM by failing open (ALLOW)', async () => {
|
|
116
|
+
mockContentGenerator.generateContent = vi.fn().mockResolvedValue({
|
|
117
|
+
candidates: [
|
|
118
|
+
{
|
|
119
|
+
content: {
|
|
120
|
+
parts: [{ text: 'This is not JSON' }],
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
],
|
|
124
|
+
});
|
|
125
|
+
const toolCall = { name: 'testTool', args: {} };
|
|
126
|
+
const policy = {
|
|
127
|
+
testTool: {
|
|
128
|
+
permissions: SafetyCheckDecision.ALLOW,
|
|
129
|
+
constraints: 'None',
|
|
130
|
+
rationale: 'Test',
|
|
131
|
+
},
|
|
132
|
+
};
|
|
133
|
+
const result = await enforcePolicy(policy, toolCall, mockConfig);
|
|
134
|
+
expect(result.decision).toBe(SafetyCheckDecision.ALLOW);
|
|
135
|
+
expect(result.reason).toContain('JSON Parse Error');
|
|
136
|
+
if (result.decision === SafetyCheckDecision.ALLOW) {
|
|
137
|
+
expect(result.error).toContain('JSON Parse Error');
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
//# sourceMappingURL=policy-enforcer.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy-enforcer.test.js","sourceRoot":"","sources":["../../../../src/safety/conseca/policy-enforcer.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import type { Config } from '../../config/config.js';
|
|
7
|
+
import type { SecurityPolicy } from './types.js';
|
|
8
|
+
export interface PolicyGenerationResult {
|
|
9
|
+
policy: SecurityPolicy;
|
|
10
|
+
error?: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Generates a security policy for the given user prompt and trusted content.
|
|
14
|
+
*/
|
|
15
|
+
export declare function generatePolicy(userPrompt: string, trustedContent: string, config: Config): Promise<PolicyGenerationResult>;
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { getResponseText } from '../../utils/partUtils.js';
|
|
7
|
+
import { safeTemplateReplace } from '../../utils/textUtils.js';
|
|
8
|
+
import { DEFAULT_GEMINI_FLASH_MODEL } from '../../config/models.js';
|
|
9
|
+
import { debugLogger } from '../../utils/debugLogger.js';
|
|
10
|
+
import { SafetyCheckDecision } from '../protocol.js';
|
|
11
|
+
import { LlmRole } from '../../telemetry/index.js';
|
|
12
|
+
const CONSECA_POLICY_GENERATION_PROMPT = `
|
|
13
|
+
You are a security expert responsible for generating fine-grained security policies for a large language model integrated into a command-line tool. Your role is to act as a "policy generator" that creates temporary, context-specific rules based on a user's prompt and the tools available to the main LLM.
|
|
14
|
+
|
|
15
|
+
Your primary goal is to enforce the principle of least privilege. The policies you create should be as restrictive as possible while still allowing the main LLM to complete the user's requested task.
|
|
16
|
+
|
|
17
|
+
For each tool that is relevant to the user's prompt, you must generate a policy object.
|
|
18
|
+
|
|
19
|
+
### Output Format
|
|
20
|
+
You must return a JSON object with a "policies" key, which is an array of objects. Each object must have:
|
|
21
|
+
- "tool_name": The name of the tool.
|
|
22
|
+
- "policy": An object with:
|
|
23
|
+
- "permissions": "allow" | "deny" | "ask_user"
|
|
24
|
+
- "constraints": A detailed description of conditions (e.g. allowed files, arguments).
|
|
25
|
+
- "rationale": Explanation for the policy.
|
|
26
|
+
|
|
27
|
+
Example JSON:
|
|
28
|
+
\`\`\`json
|
|
29
|
+
{
|
|
30
|
+
"policies": [
|
|
31
|
+
{
|
|
32
|
+
"tool_name": "read_file",
|
|
33
|
+
"policy": {
|
|
34
|
+
"permissions": "allow",
|
|
35
|
+
"constraints": "Only allow reading 'main.py'.",
|
|
36
|
+
"rationale": "User asked to read main.py"
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"tool_name": "run_shell_command",
|
|
41
|
+
"policy": {
|
|
42
|
+
"permissions": "deny",
|
|
43
|
+
"constraints": "None",
|
|
44
|
+
"rationale": "Shell commands are not needed for this task"
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
]
|
|
48
|
+
}
|
|
49
|
+
\`\`\`
|
|
50
|
+
|
|
51
|
+
### Guiding Principles:
|
|
52
|
+
1. **Permissions:**
|
|
53
|
+
* **allow:** Required tools for the task.
|
|
54
|
+
* **deny:** Tools clearly outside the scope.
|
|
55
|
+
* **ask_user:** Destructive actions or ambiguity.
|
|
56
|
+
|
|
57
|
+
2. **Constraints:**
|
|
58
|
+
* Be specific! Restrict file paths, command arguments, etc.
|
|
59
|
+
|
|
60
|
+
3. **Rationale:**
|
|
61
|
+
* Reference the user's prompt.
|
|
62
|
+
|
|
63
|
+
User Prompt: "{{user_prompt}}"
|
|
64
|
+
|
|
65
|
+
Trusted Tools (Context):
|
|
66
|
+
{{trusted_content}}
|
|
67
|
+
`;
|
|
68
|
+
import { z } from 'zod';
|
|
69
|
+
import { zodToJsonSchema } from 'zod-to-json-schema';
|
|
70
|
+
const ToolPolicySchema = z.object({
|
|
71
|
+
permissions: z.nativeEnum(SafetyCheckDecision),
|
|
72
|
+
constraints: z.string(),
|
|
73
|
+
rationale: z.string(),
|
|
74
|
+
});
|
|
75
|
+
const SecurityPolicyResponseSchema = z.object({
|
|
76
|
+
policies: z.array(z.object({
|
|
77
|
+
tool_name: z.string(),
|
|
78
|
+
policy: ToolPolicySchema,
|
|
79
|
+
})),
|
|
80
|
+
});
|
|
81
|
+
/**
|
|
82
|
+
* Generates a security policy for the given user prompt and trusted content.
|
|
83
|
+
*/
|
|
84
|
+
export async function generatePolicy(userPrompt, trustedContent, config) {
|
|
85
|
+
const model = DEFAULT_GEMINI_FLASH_MODEL;
|
|
86
|
+
const contentGenerator = config.getContentGenerator();
|
|
87
|
+
if (!contentGenerator) {
|
|
88
|
+
return { policy: {}, error: 'Content generator not initialized' };
|
|
89
|
+
}
|
|
90
|
+
try {
|
|
91
|
+
const result = await contentGenerator.generateContent({
|
|
92
|
+
model,
|
|
93
|
+
config: {
|
|
94
|
+
responseMimeType: 'application/json',
|
|
95
|
+
responseSchema: zodToJsonSchema(SecurityPolicyResponseSchema, {
|
|
96
|
+
target: 'openApi3',
|
|
97
|
+
}),
|
|
98
|
+
},
|
|
99
|
+
contents: [
|
|
100
|
+
{
|
|
101
|
+
role: 'user',
|
|
102
|
+
parts: [
|
|
103
|
+
{
|
|
104
|
+
text: safeTemplateReplace(CONSECA_POLICY_GENERATION_PROMPT, {
|
|
105
|
+
user_prompt: userPrompt,
|
|
106
|
+
trusted_content: trustedContent,
|
|
107
|
+
}),
|
|
108
|
+
},
|
|
109
|
+
],
|
|
110
|
+
},
|
|
111
|
+
],
|
|
112
|
+
}, 'conseca-policy-generation', LlmRole.SUBAGENT);
|
|
113
|
+
const responseText = getResponseText(result);
|
|
114
|
+
debugLogger.debug(`[Conseca] Policy Generation Raw Response: ${responseText}`);
|
|
115
|
+
if (!responseText) {
|
|
116
|
+
return { policy: {}, error: 'Empty response from policy generator' };
|
|
117
|
+
}
|
|
118
|
+
try {
|
|
119
|
+
const parsed = SecurityPolicyResponseSchema.parse(JSON.parse(responseText));
|
|
120
|
+
const policiesList = parsed.policies;
|
|
121
|
+
const policy = {};
|
|
122
|
+
for (const item of policiesList) {
|
|
123
|
+
policy[item.tool_name] = item.policy;
|
|
124
|
+
}
|
|
125
|
+
debugLogger.debug(`[Conseca] Policy Generation Parsed:`, policy);
|
|
126
|
+
return { policy };
|
|
127
|
+
}
|
|
128
|
+
catch (parseError) {
|
|
129
|
+
debugLogger.debug(`[Conseca] Policy Generation JSON Parse Error:`, parseError);
|
|
130
|
+
return {
|
|
131
|
+
policy: {},
|
|
132
|
+
error: `JSON Parse Error: ${parseError instanceof Error ? parseError.message : String(parseError)}. Raw: ${responseText}`,
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
catch (error) {
|
|
137
|
+
debugLogger.error('Policy generation failed:', error);
|
|
138
|
+
return {
|
|
139
|
+
policy: {},
|
|
140
|
+
error: `Policy generation failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=policy-generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy-generator.js","sourceRoot":"","sources":["../../../../src/safety/conseca/policy-generator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
7
|
+
import { generatePolicy } from './policy-generator.js';
|
|
8
|
+
import { SafetyCheckDecision } from '../protocol.js';
|
|
9
|
+
import { LlmRole } from '../../telemetry/index.js';
|
|
10
|
+
describe('policy_generator', () => {
|
|
11
|
+
let mockConfig;
|
|
12
|
+
let mockContentGenerator;
|
|
13
|
+
beforeEach(() => {
|
|
14
|
+
mockContentGenerator = {
|
|
15
|
+
generateContent: vi.fn(),
|
|
16
|
+
};
|
|
17
|
+
mockConfig = {
|
|
18
|
+
getContentGenerator: vi.fn().mockReturnValue(mockContentGenerator),
|
|
19
|
+
};
|
|
20
|
+
});
|
|
21
|
+
it('should return a policy object when content generator is available', async () => {
|
|
22
|
+
const mockPolicy = {
|
|
23
|
+
read_file: {
|
|
24
|
+
permissions: SafetyCheckDecision.ALLOW,
|
|
25
|
+
constraints: 'None',
|
|
26
|
+
rationale: 'Test',
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
mockContentGenerator.generateContent = vi.fn().mockResolvedValue({
|
|
30
|
+
candidates: [
|
|
31
|
+
{
|
|
32
|
+
content: {
|
|
33
|
+
parts: [
|
|
34
|
+
{
|
|
35
|
+
text: JSON.stringify({
|
|
36
|
+
policies: [
|
|
37
|
+
{
|
|
38
|
+
tool_name: 'read_file',
|
|
39
|
+
policy: mockPolicy.read_file,
|
|
40
|
+
},
|
|
41
|
+
],
|
|
42
|
+
}),
|
|
43
|
+
},
|
|
44
|
+
],
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
],
|
|
48
|
+
});
|
|
49
|
+
const result = await generatePolicy('test prompt', 'trusted content', mockConfig);
|
|
50
|
+
expect(mockConfig.getContentGenerator).toHaveBeenCalled();
|
|
51
|
+
expect(mockContentGenerator.generateContent).toHaveBeenCalledWith(expect.objectContaining({
|
|
52
|
+
model: expect.any(String),
|
|
53
|
+
config: expect.objectContaining({
|
|
54
|
+
responseMimeType: 'application/json',
|
|
55
|
+
responseSchema: expect.any(Object),
|
|
56
|
+
}),
|
|
57
|
+
contents: expect.any(Array),
|
|
58
|
+
}), 'conseca-policy-generation', LlmRole.SUBAGENT);
|
|
59
|
+
expect(result.policy).toEqual(mockPolicy);
|
|
60
|
+
expect(result.error).toBeUndefined();
|
|
61
|
+
});
|
|
62
|
+
it('should handle missing content generator gracefully', async () => {
|
|
63
|
+
vi.mocked(mockConfig.getContentGenerator).mockReturnValue(undefined);
|
|
64
|
+
const result = await generatePolicy('test prompt', 'trusted content', mockConfig);
|
|
65
|
+
expect(result.policy).toEqual({});
|
|
66
|
+
expect(result.error).toBe('Content generator not initialized');
|
|
67
|
+
});
|
|
68
|
+
it('should prevent template injection (double interpolation)', async () => {
|
|
69
|
+
mockContentGenerator.generateContent = vi.fn().mockResolvedValue({});
|
|
70
|
+
const userPrompt = '{{trusted_content}}';
|
|
71
|
+
const trustedContent = 'SECRET_DATA';
|
|
72
|
+
await generatePolicy(userPrompt, trustedContent, mockConfig);
|
|
73
|
+
const generateContentCall = vi.mocked(mockContentGenerator.generateContent)
|
|
74
|
+
.mock.calls[0];
|
|
75
|
+
const request = generateContentCall[0];
|
|
76
|
+
const promptText = request.contents[0].parts[0].text;
|
|
77
|
+
// The user prompt should contain the literal placeholder, NOT the secret data
|
|
78
|
+
expect(promptText).toContain('User Prompt: "{{trusted_content}}"');
|
|
79
|
+
expect(promptText).not.toContain('User Prompt: "SECRET_DATA"');
|
|
80
|
+
// The trusted tools section SHOULD contain the secret data
|
|
81
|
+
expect(promptText).toContain('Trusted Tools (Context):\nSECRET_DATA');
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
//# sourceMappingURL=policy-generator.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy-generator.test.js","sourceRoot":"","sources":["../../../../src/safety/conseca/policy-generator.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import type { SafetyCheckDecision } from '../protocol.js';
|
|
7
|
+
export interface ToolPolicy {
|
|
8
|
+
permissions: SafetyCheckDecision;
|
|
9
|
+
constraints: string;
|
|
10
|
+
rationale: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* A map of tool names to their specific security policies.
|
|
14
|
+
*/
|
|
15
|
+
export type SecurityPolicy = Record<string, ToolPolicy>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/safety/conseca/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
|