@vfarcic/dot-ai 0.108.0 → 0.110.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/dist/core/ai-provider.interface.d.ts +11 -16
- package/dist/core/ai-provider.interface.d.ts.map +1 -1
- package/dist/core/kubectl-tools.d.ts +66 -0
- package/dist/core/kubectl-tools.d.ts.map +1 -0
- package/dist/core/kubectl-tools.js +473 -0
- package/dist/core/kubernetes-utils.d.ts +1 -0
- package/dist/core/kubernetes-utils.d.ts.map +1 -1
- package/dist/core/kubernetes-utils.js +30 -0
- package/dist/core/providers/anthropic-provider.d.ts +5 -4
- package/dist/core/providers/anthropic-provider.d.ts.map +1 -1
- package/dist/core/providers/anthropic-provider.js +152 -109
- package/dist/core/providers/provider-debug-utils.d.ts +47 -4
- package/dist/core/providers/provider-debug-utils.d.ts.map +1 -1
- package/dist/core/providers/provider-debug-utils.js +67 -7
- package/dist/core/providers/vercel-provider.d.ts +11 -21
- package/dist/core/providers/vercel-provider.d.ts.map +1 -1
- package/dist/core/providers/vercel-provider.js +285 -25
- package/dist/tools/remediate.d.ts +0 -40
- package/dist/tools/remediate.d.ts.map +1 -1
- package/dist/tools/remediate.js +133 -493
- package/package.json +1 -1
- package/prompts/remediate-system.md +166 -0
- package/prompts/remediate-final-analysis.md +0 -243
- package/prompts/remediate-investigation.md +0 -194
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Implements AIProvider interface using Anthropic SDK directly.
|
|
5
5
|
* Supports streaming for long operations and debug logging.
|
|
6
6
|
*/
|
|
7
|
-
import { AIProvider, AIResponse, AIProviderConfig,
|
|
7
|
+
import { AIProvider, AIResponse, AIProviderConfig, ToolLoopConfig, AgenticResult } from '../ai-provider.interface';
|
|
8
8
|
export declare class AnthropicProvider implements AIProvider {
|
|
9
9
|
private client;
|
|
10
10
|
private apiKey;
|
|
@@ -15,6 +15,10 @@ export declare class AnthropicProvider implements AIProvider {
|
|
|
15
15
|
getProviderType(): string;
|
|
16
16
|
getDefaultModel(): string;
|
|
17
17
|
isInitialized(): boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Helper method to log debug information if debug mode is enabled
|
|
20
|
+
*/
|
|
21
|
+
private logDebugIfEnabled;
|
|
18
22
|
sendMessage(message: string, operation?: string): Promise<AIResponse>;
|
|
19
23
|
/**
|
|
20
24
|
* Agentic tool loop implementation
|
|
@@ -37,8 +41,5 @@ export declare class AnthropicProvider implements AIProvider {
|
|
|
37
41
|
* See PRD #136 for full architecture analysis and decision rationale.
|
|
38
42
|
*/
|
|
39
43
|
toolLoop(config: ToolLoopConfig): Promise<AgenticResult>;
|
|
40
|
-
sendMessageWithTools(message: string, tools: AITool[], toolExecutor: ToolExecutor, operation?: string): Promise<AIResponse & {
|
|
41
|
-
toolCalls?: any[];
|
|
42
|
-
}>;
|
|
43
44
|
}
|
|
44
45
|
//# sourceMappingURL=anthropic-provider.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"anthropic-provider.d.ts","sourceRoot":"","sources":["../../../src/core/providers/anthropic-provider.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EACL,UAAU,EACV,UAAU,EACV,gBAAgB,EAChB,
|
|
1
|
+
{"version":3,"file":"anthropic-provider.d.ts","sourceRoot":"","sources":["../../../src/core/providers/anthropic-provider.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EACL,UAAU,EACV,UAAU,EACV,gBAAgB,EAChB,cAAc,EACd,aAAa,EACd,MAAM,0BAA0B,CAAC;AAGlC,qBAAa,iBAAkB,YAAW,UAAU;IAClD,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,SAAS,CAAU;gBAEf,MAAM,EAAE,gBAAgB;IAWpC,OAAO,CAAC,cAAc;IAStB,eAAe,IAAI,MAAM;IAIzB,eAAe,IAAI,MAAM;IAIzB,aAAa,IAAI,OAAO;IAIxB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAqBnB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,GAAE,MAAkB,GAAG,OAAO,CAAC,UAAU,CAAC;IAoDtF;;;;;;;;;;;;;;;;;;;OAmBG;IACG,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC;CAmO/D"}
|
|
@@ -43,6 +43,24 @@ class AnthropicProvider {
|
|
|
43
43
|
isInitialized() {
|
|
44
44
|
return this.client !== undefined;
|
|
45
45
|
}
|
|
46
|
+
/**
|
|
47
|
+
* Helper method to log debug information if debug mode is enabled
|
|
48
|
+
*/
|
|
49
|
+
logDebugIfEnabled(operation, prompt, response, durationMs) {
|
|
50
|
+
if (!this.debugMode)
|
|
51
|
+
return;
|
|
52
|
+
const debugId = (0, provider_debug_utils_1.generateDebugId)(operation);
|
|
53
|
+
(0, provider_debug_utils_1.debugLogInteraction)(debugId, prompt, response, operation, this.getProviderType(), this.model, this.debugMode);
|
|
54
|
+
// Use logMetrics for sendMessage calls (simple token structure, no extended metrics)
|
|
55
|
+
(0, provider_debug_utils_1.logMetrics)(operation, this.getProviderType(), {
|
|
56
|
+
totalTokens: {
|
|
57
|
+
input: response.usage.input_tokens,
|
|
58
|
+
output: response.usage.output_tokens,
|
|
59
|
+
cacheCreation: response.usage.cache_creation_input_tokens,
|
|
60
|
+
cacheRead: response.usage.cache_read_input_tokens
|
|
61
|
+
}
|
|
62
|
+
}, durationMs, this.debugMode);
|
|
63
|
+
}
|
|
46
64
|
async sendMessage(message, operation = 'generic') {
|
|
47
65
|
if (!this.client) {
|
|
48
66
|
throw new Error('Anthropic client not initialized');
|
|
@@ -81,11 +99,7 @@ class AnthropicProvider {
|
|
|
81
99
|
};
|
|
82
100
|
const durationMs = Date.now() - startTime;
|
|
83
101
|
// Debug log the interaction if enabled
|
|
84
|
-
|
|
85
|
-
const debugId = (0, provider_debug_utils_1.generateDebugId)(operation);
|
|
86
|
-
(0, provider_debug_utils_1.debugLogInteraction)(debugId, message, response, operation, this.getProviderType(), this.model, this.debugMode);
|
|
87
|
-
(0, provider_debug_utils_1.logMetrics)(operation, this.getProviderType(), response.usage, durationMs, this.debugMode);
|
|
88
|
-
}
|
|
102
|
+
this.logDebugIfEnabled(operation, message, response, durationMs);
|
|
89
103
|
return response;
|
|
90
104
|
}
|
|
91
105
|
catch (error) {
|
|
@@ -117,82 +131,142 @@ class AnthropicProvider {
|
|
|
117
131
|
throw new Error('Anthropic client not initialized');
|
|
118
132
|
}
|
|
119
133
|
const startTime = Date.now();
|
|
120
|
-
// Convert AITool[] to Anthropic Tool format
|
|
121
|
-
const tools = config.tools.map(t =>
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
134
|
+
// Convert AITool[] to Anthropic Tool format with caching on last tool
|
|
135
|
+
const tools = config.tools.map((t, index) => {
|
|
136
|
+
const tool = {
|
|
137
|
+
name: t.name,
|
|
138
|
+
description: t.description,
|
|
139
|
+
input_schema: t.inputSchema
|
|
140
|
+
};
|
|
141
|
+
// Add cache control to the last tool to cache the entire tools array
|
|
142
|
+
if (index === config.tools.length - 1) {
|
|
143
|
+
tool.cache_control = { type: 'ephemeral' };
|
|
144
|
+
}
|
|
145
|
+
return tool;
|
|
146
|
+
});
|
|
147
|
+
// Separate system prompt with caching from user message
|
|
148
|
+
const systemPrompt = [
|
|
149
|
+
{
|
|
150
|
+
type: 'text',
|
|
151
|
+
text: config.systemPrompt,
|
|
152
|
+
cache_control: { type: 'ephemeral' }
|
|
153
|
+
}
|
|
154
|
+
];
|
|
155
|
+
// Initialize conversation history with just the user message
|
|
128
156
|
const conversationHistory = [
|
|
129
157
|
{
|
|
130
158
|
role: 'user',
|
|
131
|
-
content:
|
|
159
|
+
content: config.userMessage
|
|
132
160
|
}
|
|
133
161
|
];
|
|
134
162
|
let iterations = 0;
|
|
135
163
|
const toolCallsExecuted = [];
|
|
136
|
-
const totalTokens = { input: 0, output: 0 };
|
|
164
|
+
const totalTokens = { input: 0, output: 0, cacheCreation: 0, cacheRead: 0 };
|
|
137
165
|
const maxIterations = config.maxIterations || 20;
|
|
166
|
+
const operation = config.operation || 'tool-loop';
|
|
138
167
|
try {
|
|
139
168
|
while (iterations < maxIterations) {
|
|
140
169
|
iterations++;
|
|
141
|
-
|
|
170
|
+
const iterationStartTime = Date.now();
|
|
171
|
+
// Call Anthropic API with tools and cached system prompt
|
|
142
172
|
const response = await this.client.messages.create({
|
|
143
173
|
model: this.model,
|
|
144
174
|
max_tokens: 4096,
|
|
175
|
+
system: systemPrompt,
|
|
145
176
|
messages: conversationHistory,
|
|
146
177
|
tools: tools
|
|
147
178
|
});
|
|
148
|
-
// Track token usage
|
|
179
|
+
// Track token usage including cache metrics
|
|
149
180
|
totalTokens.input += response.usage.input_tokens;
|
|
150
181
|
totalTokens.output += response.usage.output_tokens;
|
|
182
|
+
// Track cache usage (available when prompt caching is used)
|
|
183
|
+
if ('cache_creation_input_tokens' in response.usage) {
|
|
184
|
+
totalTokens.cacheCreation += response.usage.cache_creation_input_tokens || 0;
|
|
185
|
+
}
|
|
186
|
+
if ('cache_read_input_tokens' in response.usage) {
|
|
187
|
+
totalTokens.cacheRead += response.usage.cache_read_input_tokens || 0;
|
|
188
|
+
}
|
|
189
|
+
// Debug log this iteration if enabled
|
|
190
|
+
if (this.debugMode) {
|
|
191
|
+
const currentPrompt = conversationHistory.map(m => typeof m.content === 'string' ? m.content : JSON.stringify(m.content, null, 2)).join('\n\n---\n\n');
|
|
192
|
+
const aiResponse = {
|
|
193
|
+
content: response.content.map(c => c.type === 'text' ? c.text : `[${c.type}]`).join('\n'),
|
|
194
|
+
usage: {
|
|
195
|
+
input_tokens: response.usage.input_tokens,
|
|
196
|
+
output_tokens: response.usage.output_tokens,
|
|
197
|
+
cache_creation_input_tokens: response.usage.cache_creation_input_tokens,
|
|
198
|
+
cache_read_input_tokens: response.usage.cache_read_input_tokens
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
const iterationDurationMs = Date.now() - iterationStartTime;
|
|
202
|
+
this.logDebugIfEnabled(`${operation}-iter${iterations}`, currentPrompt, aiResponse, iterationDurationMs);
|
|
203
|
+
}
|
|
151
204
|
// Check if AI wants to use tools
|
|
152
205
|
const toolUses = response.content.filter((c) => c.type === 'tool_use');
|
|
153
206
|
if (toolUses.length === 0) {
|
|
154
207
|
// AI is done - extract final text message
|
|
155
208
|
const textContent = response.content.find((c) => c.type === 'text');
|
|
156
|
-
|
|
209
|
+
return (0, provider_debug_utils_1.createAndLogAgenticResult)({
|
|
157
210
|
finalMessage: textContent?.text || '',
|
|
158
211
|
iterations,
|
|
159
212
|
toolCallsExecuted,
|
|
160
|
-
totalTokens
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
|
|
213
|
+
totalTokens: {
|
|
214
|
+
input: totalTokens.input,
|
|
215
|
+
output: totalTokens.output,
|
|
216
|
+
cacheCreation: totalTokens.cacheCreation,
|
|
217
|
+
cacheRead: totalTokens.cacheRead
|
|
218
|
+
},
|
|
219
|
+
status: 'success',
|
|
220
|
+
completionReason: 'investigation_complete',
|
|
221
|
+
modelVersion: this.model,
|
|
222
|
+
operation: `${operation}-summary`,
|
|
223
|
+
sdk: this.getProviderType(),
|
|
224
|
+
startTime,
|
|
225
|
+
debugMode: this.debugMode
|
|
226
|
+
});
|
|
172
227
|
}
|
|
173
|
-
// Execute all requested tools
|
|
228
|
+
// Execute all requested tools in parallel
|
|
174
229
|
const toolResults = [];
|
|
175
|
-
|
|
230
|
+
// Create promises for parallel execution
|
|
231
|
+
const toolExecutionPromises = toolUses.map(async (toolUse) => {
|
|
176
232
|
try {
|
|
177
233
|
const result = await config.toolExecutor(toolUse.name, toolUse.input);
|
|
234
|
+
return {
|
|
235
|
+
success: true,
|
|
236
|
+
toolUse,
|
|
237
|
+
result
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
catch (error) {
|
|
241
|
+
return {
|
|
242
|
+
success: false,
|
|
243
|
+
toolUse,
|
|
244
|
+
error: error instanceof Error ? error.message : String(error)
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
});
|
|
248
|
+
// Execute all tools simultaneously
|
|
249
|
+
const executionResults = await Promise.all(toolExecutionPromises);
|
|
250
|
+
// Process results and build tool_result blocks
|
|
251
|
+
for (const executionResult of executionResults) {
|
|
252
|
+
if (executionResult.success) {
|
|
178
253
|
toolCallsExecuted.push({
|
|
179
|
-
tool: toolUse.name,
|
|
180
|
-
input: toolUse.input,
|
|
181
|
-
output: result
|
|
254
|
+
tool: executionResult.toolUse.name,
|
|
255
|
+
input: executionResult.toolUse.input,
|
|
256
|
+
output: executionResult.result
|
|
182
257
|
});
|
|
183
258
|
toolResults.push({
|
|
184
259
|
type: 'tool_result',
|
|
185
|
-
tool_use_id: toolUse.id,
|
|
186
|
-
content: JSON.stringify(result)
|
|
260
|
+
tool_use_id: executionResult.toolUse.id,
|
|
261
|
+
content: JSON.stringify(executionResult.result)
|
|
187
262
|
});
|
|
188
263
|
}
|
|
189
|
-
|
|
264
|
+
else {
|
|
190
265
|
// Feed error back to AI as tool result
|
|
191
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
192
266
|
toolResults.push({
|
|
193
267
|
type: 'tool_result',
|
|
194
|
-
tool_use_id: toolUse.id,
|
|
195
|
-
content: JSON.stringify({ error:
|
|
268
|
+
tool_use_id: executionResult.toolUse.id,
|
|
269
|
+
content: JSON.stringify({ error: executionResult.error }),
|
|
196
270
|
is_error: true
|
|
197
271
|
});
|
|
198
272
|
}
|
|
@@ -204,77 +278,46 @@ class AnthropicProvider {
|
|
|
204
278
|
config.onIteration(iterations, toolCallsExecuted);
|
|
205
279
|
}
|
|
206
280
|
}
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
if (!this.client) {
|
|
218
|
-
throw new Error('Anthropic client not initialized');
|
|
219
|
-
}
|
|
220
|
-
// Convert AITool[] to Anthropic Tool format
|
|
221
|
-
const anthropicTools = tools.map(t => ({
|
|
222
|
-
name: t.name,
|
|
223
|
-
description: t.description,
|
|
224
|
-
input_schema: t.inputSchema
|
|
225
|
-
}));
|
|
226
|
-
try {
|
|
227
|
-
// Single API call with tools
|
|
228
|
-
const response = await this.client.messages.create({
|
|
229
|
-
model: this.model,
|
|
230
|
-
max_tokens: 4096,
|
|
231
|
-
messages: [{ role: 'user', content: message }],
|
|
232
|
-
tools: anthropicTools
|
|
233
|
-
});
|
|
234
|
-
const toolCalls = [];
|
|
235
|
-
let textContent = '';
|
|
236
|
-
// Process response content
|
|
237
|
-
for (const block of response.content) {
|
|
238
|
-
if (block.type === 'text') {
|
|
239
|
-
textContent += block.text;
|
|
240
|
-
}
|
|
241
|
-
else if (block.type === 'tool_use') {
|
|
242
|
-
// Execute the tool
|
|
243
|
-
try {
|
|
244
|
-
const result = await toolExecutor(block.name, block.input);
|
|
245
|
-
toolCalls.push({
|
|
246
|
-
tool: block.name,
|
|
247
|
-
input: block.input,
|
|
248
|
-
output: result
|
|
249
|
-
});
|
|
250
|
-
}
|
|
251
|
-
catch (error) {
|
|
252
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
253
|
-
toolCalls.push({
|
|
254
|
-
tool: block.name,
|
|
255
|
-
input: block.input,
|
|
256
|
-
error: errorMessage
|
|
257
|
-
});
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
const aiResponse = {
|
|
262
|
-
content: textContent,
|
|
263
|
-
usage: {
|
|
264
|
-
input_tokens: response.usage.input_tokens,
|
|
265
|
-
output_tokens: response.usage.output_tokens
|
|
281
|
+
// Reached max iterations without completion
|
|
282
|
+
return (0, provider_debug_utils_1.createAndLogAgenticResult)({
|
|
283
|
+
finalMessage: `Investigation incomplete - reached maximum ${maxIterations} iterations`,
|
|
284
|
+
iterations,
|
|
285
|
+
toolCallsExecuted,
|
|
286
|
+
totalTokens: {
|
|
287
|
+
input: totalTokens.input,
|
|
288
|
+
output: totalTokens.output,
|
|
289
|
+
cacheCreation: totalTokens.cacheCreation,
|
|
290
|
+
cacheRead: totalTokens.cacheRead
|
|
266
291
|
},
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
292
|
+
status: 'failed',
|
|
293
|
+
completionReason: 'max_iterations',
|
|
294
|
+
modelVersion: this.model,
|
|
295
|
+
operation: `${operation}-max-iterations`,
|
|
296
|
+
sdk: this.getProviderType(),
|
|
297
|
+
startTime,
|
|
298
|
+
debugMode: this.debugMode
|
|
299
|
+
});
|
|
275
300
|
}
|
|
276
301
|
catch (error) {
|
|
277
|
-
|
|
302
|
+
// Return error result with extended metrics
|
|
303
|
+
return (0, provider_debug_utils_1.createAndLogAgenticResult)({
|
|
304
|
+
finalMessage: `Error during investigation: ${error instanceof Error ? error.message : String(error)}`,
|
|
305
|
+
iterations,
|
|
306
|
+
toolCallsExecuted,
|
|
307
|
+
totalTokens: {
|
|
308
|
+
input: totalTokens.input,
|
|
309
|
+
output: totalTokens.output,
|
|
310
|
+
cacheCreation: totalTokens.cacheCreation,
|
|
311
|
+
cacheRead: totalTokens.cacheRead
|
|
312
|
+
},
|
|
313
|
+
status: 'failed',
|
|
314
|
+
completionReason: 'error',
|
|
315
|
+
modelVersion: this.model,
|
|
316
|
+
operation: `${operation}-error`,
|
|
317
|
+
sdk: this.getProviderType(),
|
|
318
|
+
startTime,
|
|
319
|
+
debugMode: this.debugMode
|
|
320
|
+
});
|
|
278
321
|
}
|
|
279
322
|
}
|
|
280
323
|
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Common functions for logging metrics and debugging AI interactions
|
|
5
5
|
* when DEBUG_DOT_AI=true
|
|
6
6
|
*/
|
|
7
|
-
import { AIResponse } from '../ai-provider.interface';
|
|
7
|
+
import { AIResponse, AgenticResult } from '../ai-provider.interface';
|
|
8
8
|
/**
|
|
9
9
|
* Create debug directory if it doesn't exist
|
|
10
10
|
*/
|
|
@@ -15,11 +15,54 @@ export declare function ensureDebugDirectory(): string;
|
|
|
15
15
|
export declare function generateDebugId(operation: string): string;
|
|
16
16
|
/**
|
|
17
17
|
* Log metrics for token usage and execution time when DEBUG_DOT_AI=true
|
|
18
|
+
*
|
|
19
|
+
* PRD #143 Decision 5: Extended metrics for model comparison analysis
|
|
18
20
|
*/
|
|
19
|
-
export declare function logMetrics(operation: string,
|
|
20
|
-
|
|
21
|
-
|
|
21
|
+
export declare function logMetrics(operation: string, sdk: string, result: {
|
|
22
|
+
totalTokens: {
|
|
23
|
+
input: number;
|
|
24
|
+
output: number;
|
|
25
|
+
cacheCreation?: number;
|
|
26
|
+
cacheRead?: number;
|
|
27
|
+
};
|
|
28
|
+
iterations?: number;
|
|
29
|
+
toolCallsExecuted?: Array<{
|
|
30
|
+
tool: string;
|
|
31
|
+
input: any;
|
|
32
|
+
output: any;
|
|
33
|
+
}>;
|
|
34
|
+
status?: string;
|
|
35
|
+
completionReason?: string;
|
|
36
|
+
modelVersion?: string;
|
|
22
37
|
}, durationMs: number, debugMode: boolean): void;
|
|
38
|
+
/**
|
|
39
|
+
* Create AgenticResult and log metrics in one step
|
|
40
|
+
* Reduces code duplication across providers
|
|
41
|
+
*
|
|
42
|
+
* PRD #143 Decision 5: Standardized metrics logging
|
|
43
|
+
*/
|
|
44
|
+
export declare function createAndLogAgenticResult(config: {
|
|
45
|
+
finalMessage: string;
|
|
46
|
+
iterations: number;
|
|
47
|
+
toolCallsExecuted: Array<{
|
|
48
|
+
tool: string;
|
|
49
|
+
input: any;
|
|
50
|
+
output: any;
|
|
51
|
+
}>;
|
|
52
|
+
totalTokens: {
|
|
53
|
+
input: number;
|
|
54
|
+
output: number;
|
|
55
|
+
cacheCreation: number;
|
|
56
|
+
cacheRead: number;
|
|
57
|
+
};
|
|
58
|
+
status: 'success' | 'failed' | 'timeout' | 'parse_error';
|
|
59
|
+
completionReason: 'investigation_complete' | 'max_iterations' | 'parse_failure' | 'model_stopped' | 'error';
|
|
60
|
+
modelVersion: string;
|
|
61
|
+
operation: string;
|
|
62
|
+
sdk: string;
|
|
63
|
+
startTime: number;
|
|
64
|
+
debugMode: boolean;
|
|
65
|
+
}): AgenticResult;
|
|
23
66
|
/**
|
|
24
67
|
* Save AI interaction for debugging when DEBUG_DOT_AI=true
|
|
25
68
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provider-debug-utils.d.ts","sourceRoot":"","sources":["../../../src/core/providers/provider-debug-utils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"provider-debug-utils.d.ts","sourceRoot":"","sources":["../../../src/core/providers/provider-debug-utils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAErE;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAM7C;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAKzD;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CACxB,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,EACX,MAAM,EAAE;IACN,WAAW,EAAE;QACX,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iBAAiB,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,GAAG,CAAC;QAAC,MAAM,EAAE,GAAG,CAAA;KAAE,CAAC,CAAC;IACrE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,EACD,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,OAAO,GACjB,IAAI,CA2DN;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE;IAChD,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,GAAG,CAAC;QAAC,MAAM,EAAE,GAAG,CAAA;KAAE,CAAC,CAAC;IACpE,WAAW,EAAE;QACX,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,aAAa,EAAE,MAAM,CAAC;QACtB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,MAAM,EAAE,SAAS,GAAG,QAAQ,GAAG,SAAS,GAAG,aAAa,CAAC;IACzD,gBAAgB,EAAE,wBAAwB,GAAG,gBAAgB,GAAG,eAAe,GAAG,eAAe,GAAG,OAAO,CAAC;IAC5G,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;CACpB,GAAG,aAAa,CAiBhB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,UAAU,EACpB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,OAAO,GACjB,IAAI,CAkCN"}
|
|
@@ -42,6 +42,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
42
42
|
exports.ensureDebugDirectory = ensureDebugDirectory;
|
|
43
43
|
exports.generateDebugId = generateDebugId;
|
|
44
44
|
exports.logMetrics = logMetrics;
|
|
45
|
+
exports.createAndLogAgenticResult = createAndLogAgenticResult;
|
|
45
46
|
exports.debugLogInteraction = debugLogInteraction;
|
|
46
47
|
const fs = __importStar(require("fs"));
|
|
47
48
|
const path = __importStar(require("path"));
|
|
@@ -67,27 +68,86 @@ function generateDebugId(operation) {
|
|
|
67
68
|
}
|
|
68
69
|
/**
|
|
69
70
|
* Log metrics for token usage and execution time when DEBUG_DOT_AI=true
|
|
71
|
+
*
|
|
72
|
+
* PRD #143 Decision 5: Extended metrics for model comparison analysis
|
|
70
73
|
*/
|
|
71
|
-
function logMetrics(operation,
|
|
74
|
+
function logMetrics(operation, sdk, result, durationMs, debugMode) {
|
|
72
75
|
if (!debugMode)
|
|
73
76
|
return;
|
|
74
77
|
try {
|
|
75
78
|
const debugDir = ensureDebugDirectory();
|
|
76
79
|
const metricsFile = path.join(debugDir, 'metrics.jsonl');
|
|
77
|
-
const entry =
|
|
80
|
+
const entry = {
|
|
78
81
|
timestamp: new Date().toISOString(),
|
|
79
|
-
|
|
82
|
+
sdk,
|
|
80
83
|
operation,
|
|
81
|
-
inputTokens:
|
|
82
|
-
outputTokens:
|
|
84
|
+
inputTokens: result.totalTokens.input,
|
|
85
|
+
outputTokens: result.totalTokens.output,
|
|
83
86
|
durationMs
|
|
84
|
-
}
|
|
85
|
-
|
|
87
|
+
};
|
|
88
|
+
// Add cache metrics if present
|
|
89
|
+
if (result.totalTokens.cacheCreation !== undefined) {
|
|
90
|
+
entry.cacheCreationTokens = result.totalTokens.cacheCreation;
|
|
91
|
+
}
|
|
92
|
+
if (result.totalTokens.cacheRead !== undefined) {
|
|
93
|
+
entry.cacheReadTokens = result.totalTokens.cacheRead;
|
|
94
|
+
}
|
|
95
|
+
// Calculate cache hit rate (percentage)
|
|
96
|
+
if (result.totalTokens.cacheRead !== undefined && result.totalTokens.input > 0) {
|
|
97
|
+
entry.cacheHitRate = Math.round((result.totalTokens.cacheRead / result.totalTokens.input) * 100);
|
|
98
|
+
}
|
|
99
|
+
// Add extended metrics (PRD #143 Decision 5)
|
|
100
|
+
if (result.iterations !== undefined) {
|
|
101
|
+
entry.iterationCount = result.iterations;
|
|
102
|
+
}
|
|
103
|
+
if (result.toolCallsExecuted) {
|
|
104
|
+
entry.toolCallCount = result.toolCallsExecuted.length;
|
|
105
|
+
// Extract unique tool names
|
|
106
|
+
const uniqueTools = [...new Set(result.toolCallsExecuted.map(tc => tc.tool))];
|
|
107
|
+
entry.uniqueToolsUsed = uniqueTools;
|
|
108
|
+
}
|
|
109
|
+
if (result.status) {
|
|
110
|
+
entry.status = result.status;
|
|
111
|
+
}
|
|
112
|
+
if (result.completionReason) {
|
|
113
|
+
entry.completionReason = result.completionReason;
|
|
114
|
+
}
|
|
115
|
+
if (result.modelVersion) {
|
|
116
|
+
entry.modelVersion = result.modelVersion;
|
|
117
|
+
}
|
|
118
|
+
// Manual annotation placeholders (populate after test analysis)
|
|
119
|
+
entry.manualNotes = '';
|
|
120
|
+
entry.failureReason = '';
|
|
121
|
+
entry.qualityIssues = [];
|
|
122
|
+
entry.comparisonNotes = '';
|
|
123
|
+
fs.appendFileSync(metricsFile, JSON.stringify(entry) + '\n');
|
|
86
124
|
}
|
|
87
125
|
catch (error) {
|
|
88
126
|
console.warn('Failed to log metrics:', error);
|
|
89
127
|
}
|
|
90
128
|
}
|
|
129
|
+
/**
|
|
130
|
+
* Create AgenticResult and log metrics in one step
|
|
131
|
+
* Reduces code duplication across providers
|
|
132
|
+
*
|
|
133
|
+
* PRD #143 Decision 5: Standardized metrics logging
|
|
134
|
+
*/
|
|
135
|
+
function createAndLogAgenticResult(config) {
|
|
136
|
+
const result = {
|
|
137
|
+
finalMessage: config.finalMessage,
|
|
138
|
+
iterations: config.iterations,
|
|
139
|
+
toolCallsExecuted: config.toolCallsExecuted,
|
|
140
|
+
totalTokens: config.totalTokens,
|
|
141
|
+
status: config.status,
|
|
142
|
+
completionReason: config.completionReason,
|
|
143
|
+
modelVersion: config.modelVersion
|
|
144
|
+
};
|
|
145
|
+
const durationMs = Date.now() - config.startTime;
|
|
146
|
+
if (config.debugMode) {
|
|
147
|
+
logMetrics(config.operation, config.sdk, result, durationMs, config.debugMode);
|
|
148
|
+
}
|
|
149
|
+
return result;
|
|
150
|
+
}
|
|
91
151
|
/**
|
|
92
152
|
* Save AI interaction for debugging when DEBUG_DOT_AI=true
|
|
93
153
|
*/
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Implements AIProvider interface using Vercel AI SDK.
|
|
5
5
|
* Supports OpenAI and Google Gemini providers through unified interface.
|
|
6
6
|
*/
|
|
7
|
-
import { AIProvider, AIResponse, AIProviderConfig,
|
|
7
|
+
import { AIProvider, AIResponse, AIProviderConfig, ToolLoopConfig, AgenticResult } from '../ai-provider.interface';
|
|
8
8
|
export declare class VercelProvider implements AIProvider {
|
|
9
9
|
private providerType;
|
|
10
10
|
private model;
|
|
@@ -17,31 +17,21 @@ export declare class VercelProvider implements AIProvider {
|
|
|
17
17
|
getProviderType(): string;
|
|
18
18
|
getDefaultModel(): string;
|
|
19
19
|
isInitialized(): boolean;
|
|
20
|
+
private logDebugIfEnabled;
|
|
20
21
|
sendMessage(message: string, operation?: string): Promise<AIResponse>;
|
|
21
22
|
/**
|
|
22
|
-
* Agentic tool loop
|
|
23
|
+
* Agentic tool loop using Vercel AI SDK
|
|
23
24
|
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* 2. JSON-based agentic loops already provide equivalent functionality
|
|
27
|
-
* 3. No current workflows require SDK-managed tool loops
|
|
25
|
+
* Implements multi-turn tool calling using generateText with maxSteps.
|
|
26
|
+
* The Vercel AI SDK handles the conversation loop automatically.
|
|
28
27
|
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
28
|
+
* Provider-specific caching:
|
|
29
|
+
* - Anthropic: Manual cache control via providerOptions
|
|
30
|
+
* - OpenAI: Automatic caching (no code changes needed)
|
|
31
|
+
* - Google: Check Gemini caching capabilities
|
|
31
32
|
*
|
|
32
|
-
* See
|
|
33
|
+
* See PRD #143 Milestone 2.5 for Vercel provider implementation details.
|
|
33
34
|
*/
|
|
34
|
-
toolLoop(
|
|
35
|
-
/**
|
|
36
|
-
* Single-shot tool calling - NOT IMPLEMENTED for Vercel provider
|
|
37
|
-
*
|
|
38
|
-
* Same reasoning as toolLoop(): not currently needed in codebase.
|
|
39
|
-
* JSON-based approach achieves same functionality without SDK overhead.
|
|
40
|
-
*
|
|
41
|
-
* See AnthropicProvider.sendMessageWithTools() for reference implementation.
|
|
42
|
-
*/
|
|
43
|
-
sendMessageWithTools(_message: string, _tools: AITool[], _toolExecutor: ToolExecutor, _operation?: string): Promise<AIResponse & {
|
|
44
|
-
toolCalls?: any[];
|
|
45
|
-
}>;
|
|
35
|
+
toolLoop(config: ToolLoopConfig): Promise<AgenticResult>;
|
|
46
36
|
}
|
|
47
37
|
//# sourceMappingURL=vercel-provider.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vercel-provider.d.ts","sourceRoot":"","sources":["../../../src/core/providers/vercel-provider.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,EACL,UAAU,EACV,UAAU,EACV,gBAAgB,EAChB,
|
|
1
|
+
{"version":3,"file":"vercel-provider.d.ts","sourceRoot":"","sources":["../../../src/core/providers/vercel-provider.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,EACL,UAAU,EACV,UAAU,EACV,gBAAgB,EAChB,cAAc,EACd,aAAa,EACd,MAAM,0BAA0B,CAAC;AAclC,qBAAa,cAAe,YAAW,UAAU;IAC/C,OAAO,CAAC,YAAY,CAAoB;IACxC,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,SAAS,CAAU;IAC3B,OAAO,CAAC,aAAa,CAAM;gBAEf,MAAM,EAAE,gBAAgB;IAUpC,OAAO,CAAC,qBAAqB;IAU7B,OAAO,CAAC,eAAe;IAgCvB,eAAe,IAAI,MAAM;IAIzB,eAAe,IAAI,MAAM;IAIzB,aAAa,IAAI,OAAO;IAIxB,OAAO,CAAC,iBAAiB;IAqBnB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,GAAE,MAAkB,GAAG,OAAO,CAAC,UAAU,CAAC;IA8CtF;;;;;;;;;;;;OAYG;IACG,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC;CA0P/D"}
|