@vybestack/llxprt-code-core 0.5.0 → 0.6.0-nightly.251128.1049d5f2b
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/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/src/agents/codebase-investigator.d.ts +46 -0
- package/dist/src/agents/codebase-investigator.js +136 -0
- package/dist/src/agents/codebase-investigator.js.map +1 -0
- package/dist/src/agents/executor.d.ts +92 -0
- package/dist/src/agents/executor.js +624 -0
- package/dist/src/agents/executor.js.map +1 -0
- package/dist/src/agents/invocation.d.ts +45 -0
- package/dist/src/agents/invocation.js +114 -0
- package/dist/src/agents/invocation.js.map +1 -0
- package/dist/src/agents/registry.d.ts +38 -0
- package/dist/src/agents/registry.js +64 -0
- package/dist/src/agents/registry.js.map +1 -0
- package/dist/src/agents/types.d.ts +145 -0
- package/dist/src/agents/types.js +17 -0
- package/dist/src/agents/types.js.map +1 -0
- package/dist/src/agents/utils.d.ts +15 -0
- package/dist/src/agents/utils.js +27 -0
- package/dist/src/agents/utils.js.map +1 -0
- package/dist/src/auth/types.d.ts +4 -4
- package/dist/src/code_assist/oauth-credential-storage.d.ts +27 -0
- package/dist/src/code_assist/oauth-credential-storage.js +115 -0
- package/dist/src/code_assist/oauth-credential-storage.js.map +1 -0
- package/dist/src/code_assist/oauth2.js +36 -9
- package/dist/src/code_assist/oauth2.js.map +1 -1
- package/dist/src/config/config.d.ts +72 -8
- package/dist/src/config/config.js +130 -23
- package/dist/src/config/config.js.map +1 -1
- package/dist/src/config/constants.d.ts +11 -0
- package/dist/src/config/constants.js +16 -0
- package/dist/src/config/constants.js.map +1 -0
- package/dist/src/config/storage.d.ts +1 -0
- package/dist/src/config/storage.js +2 -1
- package/dist/src/config/storage.js.map +1 -1
- package/dist/src/confirmation-bus/index.d.ts +2 -0
- package/dist/src/confirmation-bus/index.js +3 -0
- package/dist/src/confirmation-bus/index.js.map +1 -0
- package/dist/src/confirmation-bus/message-bus.d.ts +60 -0
- package/dist/src/confirmation-bus/message-bus.js +141 -0
- package/dist/src/confirmation-bus/message-bus.js.map +1 -0
- package/dist/src/confirmation-bus/types.d.ts +59 -0
- package/dist/src/confirmation-bus/types.js +10 -0
- package/dist/src/confirmation-bus/types.js.map +1 -0
- package/dist/src/core/baseLlmClient.d.ts +77 -0
- package/dist/src/core/baseLlmClient.js +175 -0
- package/dist/src/core/baseLlmClient.js.map +1 -0
- package/dist/src/core/client.d.ts +13 -1
- package/dist/src/core/client.js +98 -119
- package/dist/src/core/client.js.map +1 -1
- package/dist/src/core/coreToolScheduler.d.ts +20 -1
- package/dist/src/core/coreToolScheduler.js +160 -16
- package/dist/src/core/coreToolScheduler.js.map +1 -1
- package/dist/src/core/geminiChat.d.ts +8 -1
- package/dist/src/core/geminiChat.js +30 -21
- package/dist/src/core/geminiChat.js.map +1 -1
- package/dist/src/core/subagent.d.ts +16 -1
- package/dist/src/core/subagent.js +59 -3
- package/dist/src/core/subagent.js.map +1 -1
- package/dist/src/core/subagentOrchestrator.d.ts +2 -1
- package/dist/src/core/subagentOrchestrator.js +36 -6
- package/dist/src/core/subagentOrchestrator.js.map +1 -1
- package/dist/src/core/turn.d.ts +1 -4
- package/dist/src/core/turn.js +2 -12
- package/dist/src/core/turn.js.map +1 -1
- package/dist/src/ide/detect-ide.d.ts +44 -14
- package/dist/src/ide/detect-ide.js +35 -75
- package/dist/src/ide/detect-ide.js.map +1 -1
- package/dist/src/ide/ide-client.d.ts +5 -4
- package/dist/src/ide/ide-client.js +34 -25
- package/dist/src/ide/ide-client.js.map +1 -1
- package/dist/src/ide/ide-installer.d.ts +2 -2
- package/dist/src/ide/ide-installer.js +7 -9
- package/dist/src/ide/ide-installer.js.map +1 -1
- package/dist/src/index.d.ts +10 -2
- package/dist/src/index.js +12 -3
- package/dist/src/index.js.map +1 -1
- package/dist/src/mcp/oauth-provider.d.ts +5 -1
- package/dist/src/mcp/oauth-provider.js +56 -44
- package/dist/src/mcp/oauth-provider.js.map +1 -1
- package/dist/src/mcp/oauth-token-storage.d.ts +43 -40
- package/dist/src/mcp/oauth-token-storage.js +114 -44
- package/dist/src/mcp/oauth-token-storage.js.map +1 -1
- package/dist/src/mcp/oauth-utils.js +1 -0
- package/dist/src/mcp/oauth-utils.js.map +1 -1
- package/dist/src/mcp/sa-impersonation-provider.d.ts +33 -0
- package/dist/src/mcp/sa-impersonation-provider.js +130 -0
- package/dist/src/mcp/sa-impersonation-provider.js.map +1 -0
- package/dist/src/mcp/token-storage/hybrid-token-storage.js +1 -1
- package/dist/src/policy/config.d.ts +51 -0
- package/dist/src/policy/config.js +102 -0
- package/dist/src/policy/config.js.map +1 -0
- package/dist/src/policy/index.d.ts +5 -0
- package/dist/src/policy/index.js +6 -0
- package/dist/src/policy/index.js.map +1 -0
- package/dist/src/policy/policies/discovered.toml +9 -0
- package/dist/src/policy/policies/read-only.toml +68 -0
- package/dist/src/policy/policies/write.toml +69 -0
- package/dist/src/policy/policies/yolo.toml +8 -0
- package/dist/src/policy/policy-engine.d.ts +55 -0
- package/dist/src/policy/policy-engine.js +126 -0
- package/dist/src/policy/policy-engine.js.map +1 -0
- package/dist/src/policy/stable-stringify.d.ts +29 -0
- package/dist/src/policy/stable-stringify.js +111 -0
- package/dist/src/policy/stable-stringify.js.map +1 -0
- package/dist/src/policy/toml-loader.d.ts +37 -0
- package/dist/src/policy/toml-loader.js +183 -0
- package/dist/src/policy/toml-loader.js.map +1 -0
- package/dist/src/policy/types.d.ts +16 -0
- package/dist/src/policy/types.js +7 -0
- package/dist/src/policy/types.js.map +1 -0
- package/dist/src/providers/LoggingProviderWrapper.d.ts +2 -0
- package/dist/src/providers/LoggingProviderWrapper.js +27 -6
- package/dist/src/providers/LoggingProviderWrapper.js.map +1 -1
- package/dist/src/providers/ProviderManager.d.ts +18 -0
- package/dist/src/providers/ProviderManager.js +54 -3
- package/dist/src/providers/ProviderManager.js.map +1 -1
- package/dist/src/providers/anthropic/AnthropicProvider.d.ts +49 -0
- package/dist/src/providers/anthropic/AnthropicProvider.js +468 -30
- package/dist/src/providers/anthropic/AnthropicProvider.js.map +1 -1
- package/dist/src/providers/openai/OpenAIProvider.d.ts +3 -0
- package/dist/src/providers/openai/OpenAIProvider.js +12 -6
- package/dist/src/providers/openai/OpenAIProvider.js.map +1 -1
- package/dist/src/providers/utils/localEndpoint.d.ts +39 -0
- package/dist/src/providers/utils/localEndpoint.js +117 -0
- package/dist/src/providers/utils/localEndpoint.js.map +1 -0
- package/dist/src/runtime/AgentRuntimeLoader.d.ts +1 -0
- package/dist/src/runtime/AgentRuntimeLoader.js +6 -1
- package/dist/src/runtime/AgentRuntimeLoader.js.map +1 -1
- package/dist/src/runtime/createAgentRuntimeContext.js +8 -7
- package/dist/src/runtime/createAgentRuntimeContext.js.map +1 -1
- package/dist/src/services/fileSystemService.d.ts +9 -0
- package/dist/src/services/fileSystemService.js +12 -1
- package/dist/src/services/fileSystemService.js.map +1 -1
- package/dist/src/services/history/HistoryService.d.ts +4 -0
- package/dist/src/services/history/HistoryService.js +18 -0
- package/dist/src/services/history/HistoryService.js.map +1 -1
- package/dist/src/services/history/IContent.d.ts +6 -0
- package/dist/src/services/history/IContent.js.map +1 -1
- package/dist/src/services/shellExecutionService.js +0 -6
- package/dist/src/services/shellExecutionService.js.map +1 -1
- package/dist/src/settings/types.d.ts +7 -0
- package/dist/src/storage/sessionTypes.d.ts +27 -0
- package/dist/src/storage/sessionTypes.js +10 -0
- package/dist/src/storage/sessionTypes.js.map +1 -0
- package/dist/src/telemetry/constants.d.ts +8 -0
- package/dist/src/telemetry/constants.js +8 -0
- package/dist/src/telemetry/constants.js.map +1 -1
- package/dist/src/telemetry/loggers.d.ts +9 -1
- package/dist/src/telemetry/loggers.js +154 -2
- package/dist/src/telemetry/loggers.js.map +1 -1
- package/dist/src/telemetry/metrics.d.ts +5 -0
- package/dist/src/telemetry/metrics.js +4 -0
- package/dist/src/telemetry/metrics.js.map +1 -1
- package/dist/src/telemetry/types.d.ts +62 -1
- package/dist/src/telemetry/types.js +92 -0
- package/dist/src/telemetry/types.js.map +1 -1
- package/dist/src/telemetry/uiTelemetry.d.ts +1 -1
- package/dist/src/telemetry/uiTelemetry.js +2 -3
- package/dist/src/telemetry/uiTelemetry.js.map +1 -1
- package/dist/src/test-utils/config.js +14 -0
- package/dist/src/test-utils/config.js.map +1 -1
- package/dist/src/test-utils/mock-tool.d.ts +8 -4
- package/dist/src/test-utils/mock-tool.js +35 -18
- package/dist/src/test-utils/mock-tool.js.map +1 -1
- package/dist/src/test-utils/tools.d.ts +1 -1
- package/dist/src/test-utils/tools.js +4 -4
- package/dist/src/test-utils/tools.js.map +1 -1
- package/dist/src/tools/edit.d.ts +3 -2
- package/dist/src/tools/edit.js +29 -10
- package/dist/src/tools/edit.js.map +1 -1
- package/dist/src/tools/glob.d.ts +6 -4
- package/dist/src/tools/glob.js +3 -3
- package/dist/src/tools/glob.js.map +1 -1
- package/dist/src/tools/grep.d.ts +3 -2
- package/dist/src/tools/grep.js +2 -2
- package/dist/src/tools/grep.js.map +1 -1
- package/dist/src/tools/ls.d.ts +4 -3
- package/dist/src/tools/ls.js +3 -3
- package/dist/src/tools/ls.js.map +1 -1
- package/dist/src/tools/mcp-client.d.ts +9 -18
- package/dist/src/tools/mcp-client.js +60 -102
- package/dist/src/tools/mcp-client.js.map +1 -1
- package/dist/src/tools/mcp-tool.js +7 -1
- package/dist/src/tools/mcp-tool.js.map +1 -1
- package/dist/src/tools/memoryTool.d.ts +6 -2
- package/dist/src/tools/memoryTool.js +14 -4
- package/dist/src/tools/memoryTool.js.map +1 -1
- package/dist/src/tools/modifiable-tool.d.ts +1 -1
- package/dist/src/tools/modifiable-tool.js +9 -1
- package/dist/src/tools/modifiable-tool.js.map +1 -1
- package/dist/src/tools/read-file.d.ts +3 -2
- package/dist/src/tools/read-file.js +2 -2
- package/dist/src/tools/read-file.js.map +1 -1
- package/dist/src/tools/read-many-files.d.ts +3 -2
- package/dist/src/tools/read-many-files.js +2 -2
- package/dist/src/tools/read-many-files.js.map +1 -1
- package/dist/src/tools/ripGrep.d.ts +3 -2
- package/dist/src/tools/ripGrep.js +2 -2
- package/dist/src/tools/ripGrep.js.map +1 -1
- package/dist/src/tools/shell.d.ts +3 -2
- package/dist/src/tools/shell.js +69 -9
- package/dist/src/tools/shell.js.map +1 -1
- package/dist/src/tools/smart-edit.d.ts +22 -2
- package/dist/src/tools/smart-edit.js +124 -12
- package/dist/src/tools/smart-edit.js.map +1 -1
- package/dist/src/tools/task.d.ts +1 -0
- package/dist/src/tools/task.js +33 -16
- package/dist/src/tools/task.js.map +1 -1
- package/dist/src/tools/tool-confirmation-types.d.ts +20 -0
- package/dist/src/tools/tool-confirmation-types.js +15 -0
- package/dist/src/tools/tool-confirmation-types.js.map +1 -0
- package/dist/src/tools/tool-error.d.ts +2 -0
- package/dist/src/tools/tool-error.js +2 -0
- package/dist/src/tools/tool-error.js.map +1 -1
- package/dist/src/tools/tool-registry.d.ts +8 -1
- package/dist/src/tools/tool-registry.js +18 -4
- package/dist/src/tools/tool-registry.js.map +1 -1
- package/dist/src/tools/tools.d.ts +52 -14
- package/dist/src/tools/tools.js +71 -15
- package/dist/src/tools/tools.js.map +1 -1
- package/dist/src/tools/web-fetch.d.ts +3 -2
- package/dist/src/tools/web-fetch.js +11 -6
- package/dist/src/tools/web-fetch.js.map +1 -1
- package/dist/src/tools/web-search-invocation.d.ts +3 -1
- package/dist/src/tools/web-search-invocation.js +5 -2
- package/dist/src/tools/web-search-invocation.js.map +1 -1
- package/dist/src/tools/web-search.d.ts +3 -2
- package/dist/src/tools/web-search.js +6 -4
- package/dist/src/tools/web-search.js.map +1 -1
- package/dist/src/tools/write-file.d.ts +3 -2
- package/dist/src/tools/write-file.js +11 -6
- package/dist/src/tools/write-file.js.map +1 -1
- package/dist/src/utils/bfsFileSearch.d.ts +2 -2
- package/dist/src/utils/editor.js +5 -3
- package/dist/src/utils/editor.js.map +1 -1
- package/dist/src/utils/getFolderStructure.d.ts +2 -2
- package/dist/src/utils/getFolderStructure.js +1 -1
- package/dist/src/utils/getFolderStructure.js.map +1 -1
- package/dist/src/utils/llm-edit-fixer.js +10 -1
- package/dist/src/utils/llm-edit-fixer.js.map +1 -1
- package/dist/src/utils/memoryDiscovery.d.ts +2 -1
- package/dist/src/utils/memoryDiscovery.js +3 -2
- package/dist/src/utils/memoryDiscovery.js.map +1 -1
- package/dist/src/utils/memoryImportProcessor.js +13 -20
- package/dist/src/utils/memoryImportProcessor.js.map +1 -1
- package/dist/src/utils/retry.d.ts +5 -1
- package/dist/src/utils/retry.js +31 -16
- package/dist/src/utils/retry.js.map +1 -1
- package/dist/src/utils/schemaValidator.js +11 -1
- package/dist/src/utils/schemaValidator.js.map +1 -1
- package/dist/src/utils/shell-utils.d.ts +1 -0
- package/dist/src/utils/shell-utils.js +6 -2
- package/dist/src/utils/shell-utils.js.map +1 -1
- package/dist/src/utils/thoughtUtils.d.ts +21 -0
- package/dist/src/utils/thoughtUtils.js +39 -0
- package/dist/src/utils/thoughtUtils.js.map +1 -0
- package/dist/src/utils/tool-utils.js +2 -2
- package/dist/src/utils/tool-utils.js.map +1 -1
- package/package.json +6 -4
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { PolicyDecision, } from './types.js';
|
|
2
|
+
import { stableStringify } from './stable-stringify.js';
|
|
3
|
+
/**
|
|
4
|
+
* PolicyEngine evaluates tool execution requests against configured rules.
|
|
5
|
+
* Rules are matched in priority order, with the highest priority rule winning.
|
|
6
|
+
*/
|
|
7
|
+
export class PolicyEngine {
|
|
8
|
+
rules;
|
|
9
|
+
defaultDecision;
|
|
10
|
+
nonInteractive;
|
|
11
|
+
constructor(config) {
|
|
12
|
+
this.rules = config?.rules ?? [];
|
|
13
|
+
this.defaultDecision = config?.defaultDecision ?? PolicyDecision.ASK_USER;
|
|
14
|
+
this.nonInteractive = config?.nonInteractive ?? false;
|
|
15
|
+
// Sort rules by priority (highest first)
|
|
16
|
+
this.rules.sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Evaluates a tool execution request and returns a policy decision.
|
|
20
|
+
*
|
|
21
|
+
* @param toolName - The name of the tool being executed
|
|
22
|
+
* @param args - The arguments passed to the tool
|
|
23
|
+
* @param serverName - Optional MCP server name (for spoofing prevention)
|
|
24
|
+
* @returns PolicyDecision (ALLOW, DENY, or ASK_USER)
|
|
25
|
+
*/
|
|
26
|
+
evaluate(toolName, args, serverName) {
|
|
27
|
+
// Validate serverName to prevent spoofing
|
|
28
|
+
if (serverName) {
|
|
29
|
+
const validatedToolName = this.validateServerName(toolName, serverName);
|
|
30
|
+
if (validatedToolName === null) {
|
|
31
|
+
// Server name spoofing detected - deny
|
|
32
|
+
return PolicyDecision.DENY;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
// Find the highest priority matching rule
|
|
36
|
+
const matchingRule = this.findMatchingRule(toolName, args);
|
|
37
|
+
if (matchingRule) {
|
|
38
|
+
const decision = matchingRule.decision;
|
|
39
|
+
// In non-interactive mode, ASK_USER becomes DENY
|
|
40
|
+
if (this.nonInteractive && decision === PolicyDecision.ASK_USER) {
|
|
41
|
+
return PolicyDecision.DENY;
|
|
42
|
+
}
|
|
43
|
+
return decision;
|
|
44
|
+
}
|
|
45
|
+
// No matching rule - use default decision
|
|
46
|
+
if (this.nonInteractive &&
|
|
47
|
+
this.defaultDecision === PolicyDecision.ASK_USER) {
|
|
48
|
+
return PolicyDecision.DENY;
|
|
49
|
+
}
|
|
50
|
+
return this.defaultDecision;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Finds the highest priority rule matching the tool and args.
|
|
54
|
+
*
|
|
55
|
+
* @param toolName - The name of the tool
|
|
56
|
+
* @param args - The tool arguments
|
|
57
|
+
* @returns The matching rule, or undefined if none match
|
|
58
|
+
*/
|
|
59
|
+
findMatchingRule(toolName, args) {
|
|
60
|
+
const argsString = stableStringify(args);
|
|
61
|
+
for (const rule of this.rules) {
|
|
62
|
+
// Check tool name match
|
|
63
|
+
const toolMatches = !rule.toolName || rule.toolName === toolName;
|
|
64
|
+
if (!toolMatches) {
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
// Check args pattern match
|
|
68
|
+
const argsMatch = !rule.argsPattern || rule.argsPattern.test(argsString);
|
|
69
|
+
if (!argsMatch) {
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
// Both match - return this rule
|
|
73
|
+
return rule;
|
|
74
|
+
}
|
|
75
|
+
return undefined;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Validates that a tool name matches its claimed server name.
|
|
79
|
+
* Returns null if spoofing is detected, otherwise returns the tool name.
|
|
80
|
+
*
|
|
81
|
+
* @param toolName - The tool name (may include server prefix)
|
|
82
|
+
* @param serverName - The claimed server name
|
|
83
|
+
* @returns The validated tool name, or null if spoofing detected
|
|
84
|
+
*/
|
|
85
|
+
validateServerName(toolName, serverName) {
|
|
86
|
+
// For MCP tools, expect format: "serverName__toolName"
|
|
87
|
+
const expectedPrefix = `${serverName}__`;
|
|
88
|
+
if (toolName.startsWith(expectedPrefix)) {
|
|
89
|
+
return toolName;
|
|
90
|
+
}
|
|
91
|
+
// If tool name doesn't have the expected prefix, check if it's a non-MCP tool
|
|
92
|
+
// Non-MCP tools don't have a server prefix, so if a serverName is provided
|
|
93
|
+
// but the tool doesn't have the prefix, it's likely spoofing
|
|
94
|
+
if (!toolName.includes('__')) {
|
|
95
|
+
// This is a built-in tool, serverName should not be set
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
// Tool has a different server prefix - spoofing attempt
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Returns all configured rules (for debugging/inspection).
|
|
103
|
+
*
|
|
104
|
+
* @returns Array of policy rules
|
|
105
|
+
*/
|
|
106
|
+
getRules() {
|
|
107
|
+
return [...this.rules];
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Returns the default decision used when no rules match.
|
|
111
|
+
*
|
|
112
|
+
* @returns PolicyDecision
|
|
113
|
+
*/
|
|
114
|
+
getDefaultDecision() {
|
|
115
|
+
return this.defaultDecision;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Returns whether the engine is in non-interactive mode.
|
|
119
|
+
*
|
|
120
|
+
* @returns boolean
|
|
121
|
+
*/
|
|
122
|
+
isNonInteractive() {
|
|
123
|
+
return this.nonInteractive;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=policy-engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy-engine.js","sourceRoot":"","sources":["../../../src/policy/policy-engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provides deterministic JSON stringification for pattern matching in policy rules.
|
|
3
|
+
* Ensures consistent ordering of object keys and handling of special values.
|
|
4
|
+
*/
|
|
5
|
+
type JSONValue = string | number | boolean | null | JSONValue[] | {
|
|
6
|
+
[key: string]: JSONValue;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Deterministically stringifies a value for use in pattern matching.
|
|
10
|
+
* - Object keys are sorted alphabetically
|
|
11
|
+
* - Arrays maintain their order
|
|
12
|
+
* - undefined values are omitted
|
|
13
|
+
* - Functions and symbols are converted to null
|
|
14
|
+
* - Circular references throw an error
|
|
15
|
+
*
|
|
16
|
+
* @param value - The value to stringify
|
|
17
|
+
* @param space - Optional spacing for readability (default: none)
|
|
18
|
+
* @returns Deterministic JSON string
|
|
19
|
+
*/
|
|
20
|
+
export declare function stableStringify(value: unknown, space?: string | number): string;
|
|
21
|
+
/**
|
|
22
|
+
* Parses a stable-stringified JSON string back into a value.
|
|
23
|
+
* This is just a wrapper around JSON.parse for consistency.
|
|
24
|
+
*
|
|
25
|
+
* @param text - The JSON string to parse
|
|
26
|
+
* @returns Parsed value
|
|
27
|
+
*/
|
|
28
|
+
export declare function stableParse(text: string): JSONValue;
|
|
29
|
+
export {};
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provides deterministic JSON stringification for pattern matching in policy rules.
|
|
3
|
+
* Ensures consistent ordering of object keys and handling of special values.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Deterministically stringifies a value for use in pattern matching.
|
|
7
|
+
* - Object keys are sorted alphabetically
|
|
8
|
+
* - Arrays maintain their order
|
|
9
|
+
* - undefined values are omitted
|
|
10
|
+
* - Functions and symbols are converted to null
|
|
11
|
+
* - Circular references throw an error
|
|
12
|
+
*
|
|
13
|
+
* @param value - The value to stringify
|
|
14
|
+
* @param space - Optional spacing for readability (default: none)
|
|
15
|
+
* @returns Deterministic JSON string
|
|
16
|
+
*/
|
|
17
|
+
export function stableStringify(value, space) {
|
|
18
|
+
const seen = new WeakSet();
|
|
19
|
+
function stringify(val, indent, currentDepth) {
|
|
20
|
+
// Handle primitives
|
|
21
|
+
if (val === null)
|
|
22
|
+
return 'null';
|
|
23
|
+
if (val === undefined)
|
|
24
|
+
return 'null';
|
|
25
|
+
if (typeof val === 'boolean')
|
|
26
|
+
return String(val);
|
|
27
|
+
if (typeof val === 'number') {
|
|
28
|
+
if (!Number.isFinite(val))
|
|
29
|
+
return 'null';
|
|
30
|
+
return String(val);
|
|
31
|
+
}
|
|
32
|
+
if (typeof val === 'string') {
|
|
33
|
+
return JSON.stringify(val);
|
|
34
|
+
}
|
|
35
|
+
// Handle functions and symbols
|
|
36
|
+
if (typeof val === 'function' || typeof val === 'symbol') {
|
|
37
|
+
return 'null';
|
|
38
|
+
}
|
|
39
|
+
// Handle objects and arrays
|
|
40
|
+
if (typeof val === 'object') {
|
|
41
|
+
// Circular reference check
|
|
42
|
+
if (seen.has(val)) {
|
|
43
|
+
throw new TypeError('Converting circular structure to JSON');
|
|
44
|
+
}
|
|
45
|
+
seen.add(val);
|
|
46
|
+
try {
|
|
47
|
+
// Handle arrays
|
|
48
|
+
if (Array.isArray(val)) {
|
|
49
|
+
const items = [];
|
|
50
|
+
const nextIndent = space ? indent + getIndentString(space) : '';
|
|
51
|
+
const separator = space ? '\n' : '';
|
|
52
|
+
for (let i = 0; i < val.length; i++) {
|
|
53
|
+
const item = stringify(val[i], nextIndent, currentDepth + 1);
|
|
54
|
+
items.push(space ? `${nextIndent}${item}` : item);
|
|
55
|
+
}
|
|
56
|
+
if (items.length === 0) {
|
|
57
|
+
return '[]';
|
|
58
|
+
}
|
|
59
|
+
return space
|
|
60
|
+
? `[${separator}${items.join(`,${separator}`)}${separator}${indent}]`
|
|
61
|
+
: `[${items.join(',')}]`;
|
|
62
|
+
}
|
|
63
|
+
// Handle objects
|
|
64
|
+
const keys = Object.keys(val).sort();
|
|
65
|
+
const pairs = [];
|
|
66
|
+
const nextIndent = space ? indent + getIndentString(space) : '';
|
|
67
|
+
const separator = space ? '\n' : '';
|
|
68
|
+
for (const key of keys) {
|
|
69
|
+
const value = val[key];
|
|
70
|
+
if (value !== undefined) {
|
|
71
|
+
const stringifiedKey = JSON.stringify(key);
|
|
72
|
+
const stringifiedValue = stringify(value, nextIndent, currentDepth + 1);
|
|
73
|
+
const pair = space
|
|
74
|
+
? `${nextIndent}${stringifiedKey}: ${stringifiedValue}`
|
|
75
|
+
: `${stringifiedKey}:${stringifiedValue}`;
|
|
76
|
+
pairs.push(pair);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
if (pairs.length === 0) {
|
|
80
|
+
return '{}';
|
|
81
|
+
}
|
|
82
|
+
return space
|
|
83
|
+
? `{${separator}${pairs.join(`,${separator}`)}${separator}${indent}}`
|
|
84
|
+
: `{${pairs.join(',')}}`;
|
|
85
|
+
}
|
|
86
|
+
finally {
|
|
87
|
+
seen.delete(val);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
// Fallback for unknown types
|
|
91
|
+
return 'null';
|
|
92
|
+
}
|
|
93
|
+
function getIndentString(space) {
|
|
94
|
+
if (typeof space === 'number') {
|
|
95
|
+
return ' '.repeat(Math.min(10, Math.max(0, Math.floor(space))));
|
|
96
|
+
}
|
|
97
|
+
return String(space).slice(0, 10);
|
|
98
|
+
}
|
|
99
|
+
return stringify(value, '', 0);
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Parses a stable-stringified JSON string back into a value.
|
|
103
|
+
* This is just a wrapper around JSON.parse for consistency.
|
|
104
|
+
*
|
|
105
|
+
* @param text - The JSON string to parse
|
|
106
|
+
* @returns Parsed value
|
|
107
|
+
*/
|
|
108
|
+
export function stableParse(text) {
|
|
109
|
+
return JSON.parse(text);
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=stable-stringify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stable-stringify.js","sourceRoot":"","sources":["../../../src/policy/stable-stringify.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TOML Policy Loader
|
|
3
|
+
*
|
|
4
|
+
* Loads and parses TOML policy files into PolicyRule objects.
|
|
5
|
+
* Handles:
|
|
6
|
+
* - TOML parsing with @iarna/toml
|
|
7
|
+
* - Schema validation with zod
|
|
8
|
+
* - argsPattern string → RegExp conversion
|
|
9
|
+
* - Priority band enforcement
|
|
10
|
+
* - Comprehensive error handling
|
|
11
|
+
*/
|
|
12
|
+
import { type PolicyRule } from './types.js';
|
|
13
|
+
/**
|
|
14
|
+
* Error thrown when policy loading or validation fails
|
|
15
|
+
*/
|
|
16
|
+
export declare class PolicyLoadError extends Error {
|
|
17
|
+
readonly path?: string;
|
|
18
|
+
readonly cause?: unknown;
|
|
19
|
+
constructor(message: string, path?: string, options?: {
|
|
20
|
+
cause?: unknown;
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Loads and parses a TOML policy file
|
|
25
|
+
*
|
|
26
|
+
* @param path - Absolute path to the TOML policy file
|
|
27
|
+
* @returns Array of PolicyRule objects
|
|
28
|
+
* @throws PolicyLoadError if file cannot be read, parsed, or validated
|
|
29
|
+
*/
|
|
30
|
+
export declare function loadPolicyFromToml(path: string): Promise<PolicyRule[]>;
|
|
31
|
+
/**
|
|
32
|
+
* Loads all default policy files from the policies directory
|
|
33
|
+
*
|
|
34
|
+
* @returns Array of PolicyRule objects from all default policies
|
|
35
|
+
* @throws PolicyLoadError if any default policy file fails to load
|
|
36
|
+
*/
|
|
37
|
+
export declare function loadDefaultPolicies(): Promise<PolicyRule[]>;
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TOML Policy Loader
|
|
3
|
+
*
|
|
4
|
+
* Loads and parses TOML policy files into PolicyRule objects.
|
|
5
|
+
* Handles:
|
|
6
|
+
* - TOML parsing with @iarna/toml
|
|
7
|
+
* - Schema validation with zod
|
|
8
|
+
* - argsPattern string → RegExp conversion
|
|
9
|
+
* - Priority band enforcement
|
|
10
|
+
* - Comprehensive error handling
|
|
11
|
+
*/
|
|
12
|
+
import * as toml from '@iarna/toml';
|
|
13
|
+
import { z } from 'zod';
|
|
14
|
+
import { readFile } from 'node:fs/promises';
|
|
15
|
+
import { join } from 'node:path';
|
|
16
|
+
import { PolicyDecision } from './types.js';
|
|
17
|
+
/**
|
|
18
|
+
* Zod schema for a single policy rule in TOML
|
|
19
|
+
*/
|
|
20
|
+
const TomlRuleSchema = z.object({
|
|
21
|
+
toolName: z.string().optional(),
|
|
22
|
+
argsPattern: z.string().optional(),
|
|
23
|
+
decision: z.nativeEnum(PolicyDecision),
|
|
24
|
+
priority: z.number().optional(),
|
|
25
|
+
});
|
|
26
|
+
/**
|
|
27
|
+
* Zod schema for the entire policy TOML file
|
|
28
|
+
*/
|
|
29
|
+
const PolicyFileSchema = z.object({
|
|
30
|
+
rule: z.array(TomlRuleSchema),
|
|
31
|
+
});
|
|
32
|
+
/**
|
|
33
|
+
* Error thrown when policy loading or validation fails
|
|
34
|
+
*/
|
|
35
|
+
export class PolicyLoadError extends Error {
|
|
36
|
+
path;
|
|
37
|
+
cause;
|
|
38
|
+
constructor(message, path, options) {
|
|
39
|
+
super(message);
|
|
40
|
+
this.name = 'PolicyLoadError';
|
|
41
|
+
this.path = path;
|
|
42
|
+
this.cause = options?.cause;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Validates priority band according to specification:
|
|
47
|
+
* - Tier 3 (Admin): 3.xxx
|
|
48
|
+
* - Tier 2 (User): 2.xxx
|
|
49
|
+
* - Tier 1 (Default): 1.xxx
|
|
50
|
+
*
|
|
51
|
+
* Throws if priority is outside valid range.
|
|
52
|
+
*/
|
|
53
|
+
function validatePriorityBand(priority, path) {
|
|
54
|
+
if (priority === undefined) {
|
|
55
|
+
return; // Priority 0 is default and valid
|
|
56
|
+
}
|
|
57
|
+
// Valid range: 1.0 to 3.999
|
|
58
|
+
if (priority < 1.0 || priority >= 4.0) {
|
|
59
|
+
throw new PolicyLoadError(`Invalid priority ${priority} in ${path}. Priority must be in range [1.0, 4.0).`, path);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Converts argsPattern string to RegExp with proper error handling
|
|
64
|
+
*/
|
|
65
|
+
function parseArgsPattern(pattern, path) {
|
|
66
|
+
try {
|
|
67
|
+
return new RegExp(pattern);
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
throw new PolicyLoadError(`Invalid regular expression in argsPattern: ${pattern}`, path, { cause: error });
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Transforms a parsed TOML rule into a PolicyRule object
|
|
75
|
+
*/
|
|
76
|
+
function transformRule(rule, path) {
|
|
77
|
+
validatePriorityBand(rule.priority, path);
|
|
78
|
+
const policyRule = {
|
|
79
|
+
decision: rule.decision,
|
|
80
|
+
priority: rule.priority ?? 0,
|
|
81
|
+
};
|
|
82
|
+
// toolName is optional - undefined means wildcard (matches all tools)
|
|
83
|
+
if (rule.toolName !== undefined) {
|
|
84
|
+
policyRule.toolName = rule.toolName;
|
|
85
|
+
}
|
|
86
|
+
// argsPattern is optional - converts string to RegExp
|
|
87
|
+
if (rule.argsPattern !== undefined) {
|
|
88
|
+
policyRule.argsPattern = parseArgsPattern(rule.argsPattern, path);
|
|
89
|
+
}
|
|
90
|
+
return policyRule;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Loads and parses a TOML policy file
|
|
94
|
+
*
|
|
95
|
+
* @param path - Absolute path to the TOML policy file
|
|
96
|
+
* @returns Array of PolicyRule objects
|
|
97
|
+
* @throws PolicyLoadError if file cannot be read, parsed, or validated
|
|
98
|
+
*/
|
|
99
|
+
export async function loadPolicyFromToml(path) {
|
|
100
|
+
let content;
|
|
101
|
+
try {
|
|
102
|
+
content = await readFile(path, 'utf-8');
|
|
103
|
+
}
|
|
104
|
+
catch (error) {
|
|
105
|
+
throw new PolicyLoadError(`Failed to read policy file: ${path}`, path, {
|
|
106
|
+
cause: error,
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
let parsed;
|
|
110
|
+
try {
|
|
111
|
+
parsed = toml.parse(content);
|
|
112
|
+
}
|
|
113
|
+
catch (error) {
|
|
114
|
+
const tomlError = error;
|
|
115
|
+
throw new PolicyLoadError(`Invalid TOML syntax in ${path}: ${tomlError.message}`, path, { cause: error });
|
|
116
|
+
}
|
|
117
|
+
let validated;
|
|
118
|
+
try {
|
|
119
|
+
validated = PolicyFileSchema.parse(parsed);
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
if (error instanceof z.ZodError) {
|
|
123
|
+
const errorMessages = error.errors.map((e) => e.message).join(', ');
|
|
124
|
+
throw new PolicyLoadError(`Invalid policy schema in ${path}: ${errorMessages}`, path, { cause: error });
|
|
125
|
+
}
|
|
126
|
+
throw error;
|
|
127
|
+
}
|
|
128
|
+
// Transform each rule
|
|
129
|
+
const rules = [];
|
|
130
|
+
for (const tomlRule of validated.rule) {
|
|
131
|
+
try {
|
|
132
|
+
const rule = transformRule(tomlRule, path);
|
|
133
|
+
rules.push(rule);
|
|
134
|
+
}
|
|
135
|
+
catch (error) {
|
|
136
|
+
if (error instanceof PolicyLoadError) {
|
|
137
|
+
throw error;
|
|
138
|
+
}
|
|
139
|
+
throw new PolicyLoadError(`Failed to transform rule in ${path}`, path, {
|
|
140
|
+
cause: error,
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return rules;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Loads all default policy files from the policies directory
|
|
148
|
+
*
|
|
149
|
+
* @returns Array of PolicyRule objects from all default policies
|
|
150
|
+
* @throws PolicyLoadError if any default policy file fails to load
|
|
151
|
+
*/
|
|
152
|
+
export async function loadDefaultPolicies() {
|
|
153
|
+
const policyFiles = [
|
|
154
|
+
'read-only.toml',
|
|
155
|
+
'write.toml',
|
|
156
|
+
// Note: yolo.toml and discovered.toml are loaded conditionally
|
|
157
|
+
];
|
|
158
|
+
const policiesDirUrl = new URL('./policies/', import.meta.url);
|
|
159
|
+
let policiesDir = decodeURIComponent(policiesDirUrl.pathname);
|
|
160
|
+
if (policiesDir.startsWith('/@fs/')) {
|
|
161
|
+
policiesDir = `/${policiesDir.slice('/@fs/'.length)}`;
|
|
162
|
+
}
|
|
163
|
+
if (process.platform === 'win32' && policiesDir.match(/^\/[A-Za-z]:\//)) {
|
|
164
|
+
policiesDir = policiesDir.slice(1);
|
|
165
|
+
}
|
|
166
|
+
const rules = [];
|
|
167
|
+
for (const file of policyFiles) {
|
|
168
|
+
const path = join(policiesDir, file);
|
|
169
|
+
try {
|
|
170
|
+
const fileRules = await loadPolicyFromToml(path);
|
|
171
|
+
rules.push(...fileRules);
|
|
172
|
+
}
|
|
173
|
+
catch (error) {
|
|
174
|
+
// Re-throw with context about which default file failed
|
|
175
|
+
if (error instanceof PolicyLoadError) {
|
|
176
|
+
throw new PolicyLoadError(`Failed to load default policy ${file}: ${error.message}`, path, { cause: error });
|
|
177
|
+
}
|
|
178
|
+
throw error;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
return rules;
|
|
182
|
+
}
|
|
183
|
+
//# sourceMappingURL=toml-loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toml-loader.js","sourceRoot":"","sources":["../../../src/policy/toml-loader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export declare enum PolicyDecision {
|
|
2
|
+
ALLOW = "allow",
|
|
3
|
+
DENY = "deny",
|
|
4
|
+
ASK_USER = "ask_user"
|
|
5
|
+
}
|
|
6
|
+
export interface PolicyRule {
|
|
7
|
+
toolName?: string;
|
|
8
|
+
argsPattern?: RegExp;
|
|
9
|
+
decision: PolicyDecision;
|
|
10
|
+
priority?: number;
|
|
11
|
+
}
|
|
12
|
+
export interface PolicyEngineConfig {
|
|
13
|
+
rules?: PolicyRule[];
|
|
14
|
+
defaultDecision?: PolicyDecision;
|
|
15
|
+
nonInteractive?: boolean;
|
|
16
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/policy/types.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,cAIX;AAJD,WAAY,cAAc;IACxB,iCAAe,CAAA;IACf,+BAAa,CAAA;IACb,uCAAqB,CAAA;AACvB,CAAC,EAJW,cAAc,KAAd,cAAc,QAIzB"}
|
|
@@ -113,6 +113,8 @@ export declare class LoggingProviderWrapper implements IProvider {
|
|
|
113
113
|
cached_content_token_count: number;
|
|
114
114
|
thoughts_token_count: number;
|
|
115
115
|
tool_token_count: number;
|
|
116
|
+
cache_read_input_tokens: number;
|
|
117
|
+
cache_creation_input_tokens: number;
|
|
116
118
|
};
|
|
117
119
|
/**
|
|
118
120
|
* Accumulate token usage for session tracking
|
|
@@ -408,7 +408,7 @@ export class LoggingProviderWrapper {
|
|
|
408
408
|
}
|
|
409
409
|
catch (error) {
|
|
410
410
|
// Log error but don't fail the request
|
|
411
|
-
|
|
411
|
+
this.debug.warn(() => `Failed to log conversation request: ${error}`);
|
|
412
412
|
}
|
|
413
413
|
}
|
|
414
414
|
/**
|
|
@@ -534,7 +534,7 @@ export class LoggingProviderWrapper {
|
|
|
534
534
|
});
|
|
535
535
|
}
|
|
536
536
|
catch (logError) {
|
|
537
|
-
|
|
537
|
+
this.debug.warn(() => `Failed to log conversation response: ${logError}`);
|
|
538
538
|
}
|
|
539
539
|
}
|
|
540
540
|
generateConversationId() {
|
|
@@ -547,12 +547,17 @@ export class LoggingProviderWrapper {
|
|
|
547
547
|
* Extract token counts from tokenUsage metadata
|
|
548
548
|
*/
|
|
549
549
|
extractTokenCountsFromTokenUsage(tokenUsage) {
|
|
550
|
+
const cacheReads = Math.max(0, Number(tokenUsage.cache_read_input_tokens) || 0);
|
|
551
|
+
const cacheWrites = Math.max(0, Number(tokenUsage.cache_creation_input_tokens) || 0);
|
|
552
|
+
this.debug.debug(() => `[extractTokenCountsFromTokenUsage] Extracting from UsageStats: cacheReads=${cacheReads}, cacheWrites=${cacheWrites}, raw values: cache_read=${tokenUsage.cache_read_input_tokens}, cache_creation=${tokenUsage.cache_creation_input_tokens}`);
|
|
550
553
|
return {
|
|
551
554
|
input_token_count: Number(tokenUsage.promptTokens) || 0,
|
|
552
555
|
output_token_count: Number(tokenUsage.completionTokens) || 0,
|
|
553
556
|
cached_content_token_count: 0, // Not available in basic UsageStats
|
|
554
557
|
thoughts_token_count: 0, // Not available in basic UsageStats
|
|
555
558
|
tool_token_count: 0, // Not available in basic UsageStats
|
|
559
|
+
cache_read_input_tokens: cacheReads,
|
|
560
|
+
cache_creation_input_tokens: cacheWrites,
|
|
556
561
|
};
|
|
557
562
|
}
|
|
558
563
|
/**
|
|
@@ -565,6 +570,8 @@ export class LoggingProviderWrapper {
|
|
|
565
570
|
let cached_content_token_count = 0;
|
|
566
571
|
let thoughts_token_count = 0;
|
|
567
572
|
let tool_token_count = 0;
|
|
573
|
+
let cache_read_input_tokens = 0;
|
|
574
|
+
let cache_creation_input_tokens = 0;
|
|
568
575
|
try {
|
|
569
576
|
// Check if response is a string and try to parse it as JSON
|
|
570
577
|
if (typeof response === 'string') {
|
|
@@ -577,6 +584,10 @@ export class LoggingProviderWrapper {
|
|
|
577
584
|
Number(parsed.usage.cached_content_tokens) || 0;
|
|
578
585
|
thoughts_token_count = Number(parsed.usage.thoughts_tokens) || 0;
|
|
579
586
|
tool_token_count = Number(parsed.usage.tool_tokens) || 0;
|
|
587
|
+
cache_read_input_tokens =
|
|
588
|
+
Number(parsed.usage.cache_read_input_tokens) || 0;
|
|
589
|
+
cache_creation_input_tokens =
|
|
590
|
+
Number(parsed.usage.cache_creation_input_tokens) || 0;
|
|
580
591
|
}
|
|
581
592
|
}
|
|
582
593
|
else if (response && typeof response === 'object') {
|
|
@@ -589,6 +600,9 @@ export class LoggingProviderWrapper {
|
|
|
589
600
|
cached_content_token_count = Number(usage.cached_content_tokens) || 0;
|
|
590
601
|
thoughts_token_count = Number(usage.thoughts_tokens) || 0;
|
|
591
602
|
tool_token_count = Number(usage.tool_tokens) || 0;
|
|
603
|
+
cache_read_input_tokens = Number(usage.cache_read_input_tokens) || 0;
|
|
604
|
+
cache_creation_input_tokens =
|
|
605
|
+
Number(usage.cache_creation_input_tokens) || 0;
|
|
592
606
|
}
|
|
593
607
|
// Check for anthropic-style headers
|
|
594
608
|
if (obj.headers && typeof obj.headers === 'object') {
|
|
@@ -616,6 +630,8 @@ export class LoggingProviderWrapper {
|
|
|
616
630
|
cached_content_token_count: Math.max(0, cached_content_token_count),
|
|
617
631
|
thoughts_token_count: Math.max(0, thoughts_token_count),
|
|
618
632
|
tool_token_count: Math.max(0, tool_token_count),
|
|
633
|
+
cache_read_input_tokens: Math.max(0, cache_read_input_tokens),
|
|
634
|
+
cache_creation_input_tokens: Math.max(0, cache_creation_input_tokens),
|
|
619
635
|
};
|
|
620
636
|
}
|
|
621
637
|
catch (_error) {
|
|
@@ -626,6 +642,8 @@ export class LoggingProviderWrapper {
|
|
|
626
642
|
cached_content_token_count: 0,
|
|
627
643
|
thoughts_token_count: 0,
|
|
628
644
|
tool_token_count: 0,
|
|
645
|
+
cache_read_input_tokens: 0,
|
|
646
|
+
cache_creation_input_tokens: 0,
|
|
629
647
|
};
|
|
630
648
|
}
|
|
631
649
|
}
|
|
@@ -640,20 +658,23 @@ export class LoggingProviderWrapper {
|
|
|
640
658
|
cache: tokenCounts.cached_content_token_count || 0,
|
|
641
659
|
thought: tokenCounts.thoughts_token_count || 0,
|
|
642
660
|
tool: tokenCounts.tool_token_count || 0,
|
|
661
|
+
cacheReads: tokenCounts.cache_read_input_tokens || 0,
|
|
662
|
+
cacheWrites: tokenCounts.cache_creation_input_tokens || 0,
|
|
643
663
|
};
|
|
664
|
+
this.debug.debug(() => `[accumulateTokenUsage] Mapped tokenCounts to usage: cacheReads=${usage.cacheReads}, cacheWrites=${usage.cacheWrites}`);
|
|
644
665
|
// Call accumulateSessionTokens if providerManager is available
|
|
645
666
|
const providerManager = config?.getProviderManager();
|
|
646
667
|
if (providerManager) {
|
|
647
668
|
try {
|
|
648
|
-
|
|
669
|
+
this.debug.debug(() => `[TokenTracking] Accumulating ${usage.input + usage.output + usage.cache + usage.tool + usage.thought} tokens for provider ${this.wrapped.name}, cacheReads=${usage.cacheReads}, cacheWrites=${usage.cacheWrites}`);
|
|
649
670
|
providerManager.accumulateSessionTokens(this.wrapped.name, usage);
|
|
650
671
|
}
|
|
651
672
|
catch (error) {
|
|
652
|
-
|
|
673
|
+
this.debug.warn(() => `Failed to accumulate session tokens: ${error}`);
|
|
653
674
|
}
|
|
654
675
|
}
|
|
655
676
|
else {
|
|
656
|
-
|
|
677
|
+
this.debug.warn(() => `[TokenTracking] No provider manager found in config - tokens not accumulated for ${this.wrapped.name}`);
|
|
657
678
|
}
|
|
658
679
|
}
|
|
659
680
|
resolveLoggingConfig(candidate) {
|
|
@@ -703,7 +724,7 @@ export class LoggingProviderWrapper {
|
|
|
703
724
|
});
|
|
704
725
|
}
|
|
705
726
|
catch (logError) {
|
|
706
|
-
|
|
727
|
+
this.debug.warn(() => `Failed to log tool call: ${logError}`);
|
|
707
728
|
}
|
|
708
729
|
}
|
|
709
730
|
// All other methods are simple passthroughs to wrapped provider
|