@vfarcic/dot-ai 0.111.0 → 0.113.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-factory.d.ts +0 -10
- package/dist/core/ai-provider-factory.d.ts.map +1 -1
- package/dist/core/ai-provider-factory.js +14 -24
- package/dist/core/ai-provider.interface.d.ts +28 -1
- package/dist/core/ai-provider.interface.d.ts.map +1 -1
- package/dist/core/capabilities.d.ts +1 -1
- package/dist/core/capabilities.d.ts.map +1 -1
- package/dist/core/capabilities.js +7 -4
- package/dist/core/capability-scan-workflow.js +2 -2
- package/dist/core/embedding-service.d.ts +35 -2
- package/dist/core/embedding-service.d.ts.map +1 -1
- package/dist/core/embedding-service.js +228 -15
- package/dist/core/model-config.d.ts +23 -0
- package/dist/core/model-config.d.ts.map +1 -0
- package/dist/core/model-config.js +28 -0
- package/dist/core/platform-operations.d.ts.map +1 -1
- package/dist/core/platform-operations.js +3 -5
- package/dist/core/platform-utils.d.ts +13 -2
- package/dist/core/platform-utils.d.ts.map +1 -1
- package/dist/core/platform-utils.js +91 -9
- package/dist/core/providers/anthropic-provider.d.ts +6 -1
- package/dist/core/providers/anthropic-provider.d.ts.map +1 -1
- package/dist/core/providers/anthropic-provider.js +99 -27
- package/dist/core/providers/provider-debug-utils.d.ts +53 -20
- package/dist/core/providers/provider-debug-utils.d.ts.map +1 -1
- package/dist/core/providers/provider-debug-utils.js +106 -51
- package/dist/core/providers/vercel-provider.d.ts +6 -1
- package/dist/core/providers/vercel-provider.d.ts.map +1 -1
- package/dist/core/providers/vercel-provider.js +212 -130
- package/dist/core/schema.d.ts +1 -101
- package/dist/core/schema.d.ts.map +1 -1
- package/dist/core/schema.js +20 -154
- package/dist/core/unified-creation-session.d.ts.map +1 -1
- package/dist/core/unified-creation-session.js +15 -7
- package/dist/evaluation/dataset-analyzer.d.ts +118 -0
- package/dist/evaluation/dataset-analyzer.d.ts.map +1 -0
- package/dist/evaluation/dataset-analyzer.js +234 -0
- package/dist/evaluation/datasets/loader.d.ts +42 -0
- package/dist/evaluation/datasets/loader.d.ts.map +1 -0
- package/dist/evaluation/datasets/loader.js +104 -0
- package/dist/evaluation/eval-runner.d.ts +9 -0
- package/dist/evaluation/eval-runner.d.ts.map +1 -0
- package/dist/evaluation/eval-runner.js +399 -0
- package/dist/evaluation/evaluators/base-comparative.d.ts +94 -0
- package/dist/evaluation/evaluators/base-comparative.d.ts.map +1 -0
- package/dist/evaluation/evaluators/base-comparative.js +187 -0
- package/dist/evaluation/evaluators/base.d.ts +47 -0
- package/dist/evaluation/evaluators/base.d.ts.map +1 -0
- package/dist/evaluation/evaluators/base.js +10 -0
- package/dist/evaluation/evaluators/capability-comparative.d.ts +32 -0
- package/dist/evaluation/evaluators/capability-comparative.d.ts.map +1 -0
- package/dist/evaluation/evaluators/capability-comparative.js +104 -0
- package/dist/evaluation/evaluators/pattern-comparative.d.ts +31 -0
- package/dist/evaluation/evaluators/pattern-comparative.d.ts.map +1 -0
- package/dist/evaluation/evaluators/pattern-comparative.js +97 -0
- package/dist/evaluation/evaluators/policy-comparative.d.ts +31 -0
- package/dist/evaluation/evaluators/policy-comparative.d.ts.map +1 -0
- package/dist/evaluation/evaluators/policy-comparative.js +97 -0
- package/dist/evaluation/evaluators/recommendation-comparative.d.ts +25 -0
- package/dist/evaluation/evaluators/recommendation-comparative.d.ts.map +1 -0
- package/dist/evaluation/evaluators/recommendation-comparative.js +55 -0
- package/dist/evaluation/evaluators/remediation-comparative.d.ts +25 -0
- package/dist/evaluation/evaluators/remediation-comparative.d.ts.map +1 -0
- package/dist/evaluation/evaluators/remediation-comparative.js +54 -0
- package/dist/evaluation/platform-synthesizer.d.ts +54 -0
- package/dist/evaluation/platform-synthesizer.d.ts.map +1 -0
- package/dist/evaluation/platform-synthesizer.js +368 -0
- package/dist/evaluation/run-platform-synthesis.d.ts +9 -0
- package/dist/evaluation/run-platform-synthesis.d.ts.map +1 -0
- package/dist/evaluation/run-platform-synthesis.js +45 -0
- package/dist/interfaces/mcp.d.ts.map +1 -1
- package/dist/interfaces/mcp.js +23 -29
- package/dist/interfaces/rest-api.d.ts.map +1 -1
- package/dist/tools/answer-question.d.ts +2 -0
- package/dist/tools/answer-question.d.ts.map +1 -1
- package/dist/tools/answer-question.js +18 -11
- package/dist/tools/generate-manifests.d.ts +2 -0
- package/dist/tools/generate-manifests.d.ts.map +1 -1
- package/dist/tools/generate-manifests.js +11 -12
- package/dist/tools/organizational-data.d.ts +1 -0
- package/dist/tools/organizational-data.d.ts.map +1 -1
- package/dist/tools/organizational-data.js +2 -1
- package/dist/tools/recommend.d.ts +1 -0
- package/dist/tools/recommend.d.ts.map +1 -1
- package/dist/tools/recommend.js +13 -21
- package/dist/tools/remediate.d.ts +3 -0
- package/dist/tools/remediate.d.ts.map +1 -1
- package/dist/tools/remediate.js +35 -14
- package/dist/tools/test-docs.d.ts +1 -0
- package/dist/tools/test-docs.d.ts.map +1 -1
- package/dist/tools/test-docs.js +4 -2
- package/dist/tools/version.d.ts +5 -1
- package/dist/tools/version.d.ts.map +1 -1
- package/dist/tools/version.js +23 -8
- package/package.json +19 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"platform-operations.d.ts","sourceRoot":"","sources":["../../src/core/platform-operations.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAM1C,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,4CAA4C,CAAC;AAGzF,OAAO,EAAE,SAAS,EAAE,MAAM,4CAA4C,CAAC;AAEvE,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC;IACjD,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,GAAG,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,UAAU,EAAE,iBAAiB,EAAE,CAAC;IAChC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC7B,WAAW,EAAE,mBAAmB,GAAG,SAAS,GAAG,SAAS,GAAG,UAAU,CAAC;IACtE,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,UAAU,EAAE,UAAU,EACtB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,SAAS,EAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"platform-operations.d.ts","sourceRoot":"","sources":["../../src/core/platform-operations.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAM1C,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,4CAA4C,CAAC;AAGzF,OAAO,EAAE,SAAS,EAAE,MAAM,4CAA4C,CAAC;AAEvE,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC;IACjD,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,GAAG,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,UAAU,EAAE,iBAAiB,EAAE,CAAC;IAChC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC7B,WAAW,EAAE,mBAAmB,GAAG,SAAS,GAAG,SAAS,GAAG,UAAU,CAAC;IACtE,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,UAAU,EAAE,UAAU,EACtB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,SAAS,EAAE,CAAC,CAkCtB;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,SAAS,EAAE,EACvB,UAAU,EAAE,UAAU,EACtB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,aAAa,CAAC,CAoCxB;AAED;;GAEG;AACH,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,MAAM,EAAE,EACjB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAuE9B;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,gBAAgB,EAAE,gBAAgB,EAClC,UAAU,EAAE,iBAAiB,EAAE,EAC/B,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,eAAe,CAAC,CA8B1B;AAED;;GAEG;AACH,wBAAgB,WAAW,CACzB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GACb,eAAe,GAAG,IAAI,CAmBxB;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,eAAe,EACxB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC5B,MAAM,EAAE,MAAM,GACb,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAkE/F"}
|
|
@@ -69,8 +69,7 @@ async function discoverOperations(aiProvider, logger) {
|
|
|
69
69
|
// Single AI call with injected data
|
|
70
70
|
const response = await aiProvider.sendMessage(prompt, 'platform-discover-operations');
|
|
71
71
|
// Parse operations from AI response
|
|
72
|
-
const
|
|
73
|
-
const operations = JSON.parse(jsonContent);
|
|
72
|
+
const operations = (0, platform_utils_1.extractJsonFromAIResponse)(response.content);
|
|
74
73
|
logger.info?.('Discovered operations from Nu scripts', {
|
|
75
74
|
count: operations.length
|
|
76
75
|
});
|
|
@@ -95,9 +94,8 @@ async function mapIntentToOperation(intent, operations, aiProvider, logger) {
|
|
|
95
94
|
.replace('{operations}', JSON.stringify(operations, null, 2));
|
|
96
95
|
// Send to AI provider for AI-powered intent matching
|
|
97
96
|
const response = await aiProvider.sendMessage(prompt, 'platform-map-intent');
|
|
98
|
-
//
|
|
99
|
-
const
|
|
100
|
-
const mapping = JSON.parse(jsonContent);
|
|
97
|
+
// Extract JSON from AI response with robust parsing
|
|
98
|
+
const mapping = (0, platform_utils_1.extractJsonFromAIResponse)(response.content);
|
|
101
99
|
// Validate that AI returned required fields
|
|
102
100
|
if (mapping.matched && mapping.operation) {
|
|
103
101
|
if (!mapping.operation.command || !Array.isArray(mapping.operation.command)) {
|
|
@@ -10,7 +10,18 @@ export declare const execAsync: typeof exec.__promisify__;
|
|
|
10
10
|
*/
|
|
11
11
|
export declare function getScriptsDir(): string;
|
|
12
12
|
/**
|
|
13
|
-
*
|
|
13
|
+
* Extract JSON object from AI response with robust parsing
|
|
14
|
+
* Handles markdown code blocks and finds proper JSON boundaries
|
|
14
15
|
*/
|
|
15
|
-
export declare function
|
|
16
|
+
export declare function extractJsonFromAIResponse(aiResponse: string): any;
|
|
17
|
+
/**
|
|
18
|
+
* Extract content from markdown code blocks in AI responses
|
|
19
|
+
* Handles various code block formats: ```yaml, ```yml, ```json, or plain ```
|
|
20
|
+
*/
|
|
21
|
+
export declare function extractContentFromMarkdownCodeBlocks(content: string, language?: string): string;
|
|
22
|
+
/**
|
|
23
|
+
* Extract JSON array from AI response with robust parsing
|
|
24
|
+
* Handles markdown code blocks and finds proper array boundaries
|
|
25
|
+
*/
|
|
26
|
+
export declare function extractJsonArrayFromAIResponse(aiResponse: string): any[];
|
|
16
27
|
//# sourceMappingURL=platform-utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"platform-utils.d.ts","sourceRoot":"","sources":["../../src/core/platform-utils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAIrC,eAAO,MAAM,SAAS,2BAAkB,CAAC;AAEzC;;GAEG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAItC;AAED
|
|
1
|
+
{"version":3,"file":"platform-utils.d.ts","sourceRoot":"","sources":["../../src/core/platform-utils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAIrC,eAAO,MAAM,SAAS,2BAAkB,CAAC;AAEzC;;GAEG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAItC;AAGD;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,UAAU,EAAE,MAAM,GAAG,GAAG,CAkCjE;AAED;;;GAGG;AACH,wBAAgB,oCAAoC,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAY/F;AAED;;;GAGG;AACH,wBAAgB,8BAA8B,CAAC,UAAU,EAAE,MAAM,GAAG,GAAG,EAAE,CAkCxE"}
|
|
@@ -40,7 +40,9 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
40
40
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
41
41
|
exports.execAsync = void 0;
|
|
42
42
|
exports.getScriptsDir = getScriptsDir;
|
|
43
|
-
exports.
|
|
43
|
+
exports.extractJsonFromAIResponse = extractJsonFromAIResponse;
|
|
44
|
+
exports.extractContentFromMarkdownCodeBlocks = extractContentFromMarkdownCodeBlocks;
|
|
45
|
+
exports.extractJsonArrayFromAIResponse = extractJsonArrayFromAIResponse;
|
|
44
46
|
const child_process_1 = require("child_process");
|
|
45
47
|
const util_1 = require("util");
|
|
46
48
|
const path = __importStar(require("path"));
|
|
@@ -54,15 +56,95 @@ function getScriptsDir() {
|
|
|
54
56
|
return path.join(__dirname, '..', '..', 'scripts');
|
|
55
57
|
}
|
|
56
58
|
/**
|
|
57
|
-
*
|
|
59
|
+
* Extract JSON object from AI response with robust parsing
|
|
60
|
+
* Handles markdown code blocks and finds proper JSON boundaries
|
|
58
61
|
*/
|
|
59
|
-
function
|
|
60
|
-
let jsonContent =
|
|
61
|
-
|
|
62
|
-
|
|
62
|
+
function extractJsonFromAIResponse(aiResponse) {
|
|
63
|
+
let jsonContent = aiResponse;
|
|
64
|
+
// First try to find JSON wrapped in code blocks
|
|
65
|
+
const codeBlockMatch = aiResponse.match(/```(?:json)?\s*(\{[\s\S]*?\})\s*```/);
|
|
66
|
+
if (codeBlockMatch) {
|
|
67
|
+
jsonContent = codeBlockMatch[1];
|
|
63
68
|
}
|
|
64
|
-
else
|
|
65
|
-
|
|
69
|
+
else {
|
|
70
|
+
// Try to find JSON that starts with { and find the matching closing }
|
|
71
|
+
const startIndex = aiResponse.indexOf('{');
|
|
72
|
+
if (startIndex !== -1) {
|
|
73
|
+
let braceCount = 0;
|
|
74
|
+
let endIndex = startIndex;
|
|
75
|
+
for (let i = startIndex; i < aiResponse.length; i++) {
|
|
76
|
+
if (aiResponse[i] === '{')
|
|
77
|
+
braceCount++;
|
|
78
|
+
if (aiResponse[i] === '}')
|
|
79
|
+
braceCount--;
|
|
80
|
+
if (braceCount === 0) {
|
|
81
|
+
endIndex = i;
|
|
82
|
+
break;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
if (endIndex > startIndex) {
|
|
86
|
+
jsonContent = aiResponse.substring(startIndex, endIndex + 1);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
try {
|
|
91
|
+
return JSON.parse(jsonContent.trim());
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
throw new Error(`Failed to parse JSON from AI response: ${error}`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Extract content from markdown code blocks in AI responses
|
|
99
|
+
* Handles various code block formats: ```yaml, ```yml, ```json, or plain ```
|
|
100
|
+
*/
|
|
101
|
+
function extractContentFromMarkdownCodeBlocks(content, language) {
|
|
102
|
+
// Create regex pattern for the specified language or any language
|
|
103
|
+
const languagePattern = language ? `(?:${language})` : '(?:yaml|yml|json)?';
|
|
104
|
+
const regex = new RegExp(`\`\`\`${languagePattern}\\s*([\\s\\S]*?)\\s*\`\`\``, 'g');
|
|
105
|
+
const match = regex.exec(content);
|
|
106
|
+
if (match && match[1]) {
|
|
107
|
+
return match[1].trim();
|
|
108
|
+
}
|
|
109
|
+
// Return original content if no code blocks found
|
|
110
|
+
return content.trim();
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Extract JSON array from AI response with robust parsing
|
|
114
|
+
* Handles markdown code blocks and finds proper array boundaries
|
|
115
|
+
*/
|
|
116
|
+
function extractJsonArrayFromAIResponse(aiResponse) {
|
|
117
|
+
let jsonContent = aiResponse;
|
|
118
|
+
// First try to find JSON array wrapped in code blocks
|
|
119
|
+
const codeBlockMatch = aiResponse.match(/```(?:json)?\s*(\[[\s\S]*?\])\s*```/);
|
|
120
|
+
if (codeBlockMatch) {
|
|
121
|
+
jsonContent = codeBlockMatch[1];
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
// Try to find JSON array that starts with [ and find the matching closing ]
|
|
125
|
+
const startIndex = aiResponse.indexOf('[');
|
|
126
|
+
if (startIndex !== -1) {
|
|
127
|
+
let bracketCount = 0;
|
|
128
|
+
let endIndex = startIndex;
|
|
129
|
+
for (let i = startIndex; i < aiResponse.length; i++) {
|
|
130
|
+
if (aiResponse[i] === '[')
|
|
131
|
+
bracketCount++;
|
|
132
|
+
if (aiResponse[i] === ']')
|
|
133
|
+
bracketCount--;
|
|
134
|
+
if (bracketCount === 0) {
|
|
135
|
+
endIndex = i;
|
|
136
|
+
break;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
if (bracketCount === 0) {
|
|
140
|
+
jsonContent = aiResponse.substring(startIndex, endIndex + 1);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
try {
|
|
145
|
+
return JSON.parse(jsonContent.trim());
|
|
146
|
+
}
|
|
147
|
+
catch (error) {
|
|
148
|
+
throw new Error(`Failed to parse JSON array from AI response: ${error}`);
|
|
66
149
|
}
|
|
67
|
-
return jsonContent;
|
|
68
150
|
}
|
|
@@ -14,12 +14,17 @@ export declare class AnthropicProvider implements AIProvider {
|
|
|
14
14
|
private validateApiKey;
|
|
15
15
|
getProviderType(): string;
|
|
16
16
|
getDefaultModel(): string;
|
|
17
|
+
getModelName(): string;
|
|
18
|
+
getSDKProvider(): string;
|
|
17
19
|
isInitialized(): boolean;
|
|
18
20
|
/**
|
|
19
21
|
* Helper method to log debug information if debug mode is enabled
|
|
20
22
|
*/
|
|
21
23
|
private logDebugIfEnabled;
|
|
22
|
-
sendMessage(message: string, operation?: string
|
|
24
|
+
sendMessage(message: string, operation?: string, evaluationContext?: {
|
|
25
|
+
user_intent?: string;
|
|
26
|
+
interaction_id?: string;
|
|
27
|
+
}): Promise<AIResponse>;
|
|
23
28
|
/**
|
|
24
29
|
* Agentic tool loop implementation
|
|
25
30
|
*
|
|
@@ -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,cAAc,EACd,aAAa,EACd,MAAM,0BAA0B,CAAC;
|
|
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;AAIlC,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;IAepC,OAAO,CAAC,cAAc;IAStB,eAAe,IAAI,MAAM;IAIzB,eAAe,IAAI,MAAM;IAIzB,YAAY,IAAI,MAAM;IAItB,cAAc,IAAI,MAAM;IAIxB,aAAa,IAAI,OAAO;IAIxB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAiBnB,WAAW,CACf,OAAO,EAAE,MAAM,EACf,SAAS,GAAE,MAAkB,EAC7B,iBAAiB,CAAC,EAAE;QAClB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB,GACA,OAAO,CAAC,UAAU,CAAC;IA+EtB;;;;;;;;;;;;;;;;;;;OAmBG;IACG,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC;CAsQ/D"}
|
|
@@ -12,6 +12,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
12
12
|
exports.AnthropicProvider = void 0;
|
|
13
13
|
const sdk_1 = __importDefault(require("@anthropic-ai/sdk"));
|
|
14
14
|
const provider_debug_utils_1 = require("./provider-debug-utils");
|
|
15
|
+
const model_config_1 = require("../model-config");
|
|
15
16
|
class AnthropicProvider {
|
|
16
17
|
client;
|
|
17
18
|
apiKey;
|
|
@@ -24,6 +25,10 @@ class AnthropicProvider {
|
|
|
24
25
|
this.validateApiKey();
|
|
25
26
|
this.client = new sdk_1.default({
|
|
26
27
|
apiKey: this.apiKey,
|
|
28
|
+
// Enable 1M token context window for Claude Sonnet 4 (5x increase from 200K)
|
|
29
|
+
defaultHeaders: {
|
|
30
|
+
'anthropic-beta': 'context-1m-2025-08-07'
|
|
31
|
+
}
|
|
27
32
|
});
|
|
28
33
|
}
|
|
29
34
|
validateApiKey() {
|
|
@@ -38,7 +43,13 @@ class AnthropicProvider {
|
|
|
38
43
|
return 'anthropic';
|
|
39
44
|
}
|
|
40
45
|
getDefaultModel() {
|
|
41
|
-
return '
|
|
46
|
+
return (0, model_config_1.getCurrentModel)('anthropic');
|
|
47
|
+
}
|
|
48
|
+
getModelName() {
|
|
49
|
+
return this.model;
|
|
50
|
+
}
|
|
51
|
+
getSDKProvider() {
|
|
52
|
+
return 'anthropic';
|
|
42
53
|
}
|
|
43
54
|
isInitialized() {
|
|
44
55
|
return this.client !== undefined;
|
|
@@ -46,22 +57,18 @@ class AnthropicProvider {
|
|
|
46
57
|
/**
|
|
47
58
|
* Helper method to log debug information if debug mode is enabled
|
|
48
59
|
*/
|
|
49
|
-
logDebugIfEnabled(operation, prompt, response
|
|
60
|
+
logDebugIfEnabled(operation, prompt, response) {
|
|
50
61
|
if (!this.debugMode)
|
|
51
|
-
return;
|
|
62
|
+
return null;
|
|
52
63
|
const debugId = (0, provider_debug_utils_1.generateDebugId)(operation);
|
|
53
64
|
(0, provider_debug_utils_1.debugLogInteraction)(debugId, prompt, response, operation, this.getProviderType(), this.model, this.debugMode);
|
|
54
|
-
//
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
cacheCreation: response.usage.cache_creation_input_tokens,
|
|
60
|
-
cacheRead: response.usage.cache_read_input_tokens
|
|
61
|
-
}
|
|
62
|
-
}, durationMs, this.debugMode);
|
|
65
|
+
// Return the actual debug file names created
|
|
66
|
+
return {
|
|
67
|
+
promptFile: `${debugId}_prompt.md`,
|
|
68
|
+
responseFile: `${debugId}_response.md`
|
|
69
|
+
};
|
|
63
70
|
}
|
|
64
|
-
async sendMessage(message, operation = 'generic') {
|
|
71
|
+
async sendMessage(message, operation = 'generic', evaluationContext) {
|
|
65
72
|
if (!this.client) {
|
|
66
73
|
throw new Error('Anthropic client not initialized');
|
|
67
74
|
}
|
|
@@ -97,9 +104,32 @@ class AnthropicProvider {
|
|
|
97
104
|
output_tokens
|
|
98
105
|
}
|
|
99
106
|
};
|
|
100
|
-
const durationMs = Date.now() - startTime;
|
|
101
107
|
// Debug log the interaction if enabled
|
|
102
|
-
this.logDebugIfEnabled(operation, message, response
|
|
108
|
+
this.logDebugIfEnabled(operation, message, response);
|
|
109
|
+
// PRD #154: Log evaluation dataset if evaluation context is provided
|
|
110
|
+
if (this.debugMode && evaluationContext?.interaction_id) {
|
|
111
|
+
const durationMs = Date.now() - startTime;
|
|
112
|
+
const evaluationMetrics = {
|
|
113
|
+
// Core execution data
|
|
114
|
+
operation,
|
|
115
|
+
sdk: this.getProviderType(),
|
|
116
|
+
inputTokens: input_tokens,
|
|
117
|
+
outputTokens: output_tokens,
|
|
118
|
+
durationMs,
|
|
119
|
+
// Required fields
|
|
120
|
+
iterationCount: 1,
|
|
121
|
+
toolCallCount: 0,
|
|
122
|
+
status: 'completed',
|
|
123
|
+
completionReason: 'stop',
|
|
124
|
+
modelVersion: this.model,
|
|
125
|
+
// Required evaluation context - NO DEFAULTS, must be provided
|
|
126
|
+
test_scenario: operation,
|
|
127
|
+
ai_response_summary: content,
|
|
128
|
+
user_intent: evaluationContext?.user_intent || '',
|
|
129
|
+
interaction_id: evaluationContext?.interaction_id || '',
|
|
130
|
+
};
|
|
131
|
+
(0, provider_debug_utils_1.logEvaluationDataset)(evaluationMetrics, this.debugMode);
|
|
132
|
+
}
|
|
103
133
|
return response;
|
|
104
134
|
}
|
|
105
135
|
catch (error) {
|
|
@@ -167,7 +197,40 @@ class AnthropicProvider {
|
|
|
167
197
|
try {
|
|
168
198
|
while (iterations < maxIterations) {
|
|
169
199
|
iterations++;
|
|
170
|
-
|
|
200
|
+
// Build current prompt for debug logging
|
|
201
|
+
const currentPrompt = `System: ${config.systemPrompt}\n\n${conversationHistory.map(msg => {
|
|
202
|
+
let content = '';
|
|
203
|
+
if (typeof msg.content === 'string') {
|
|
204
|
+
content = msg.content;
|
|
205
|
+
}
|
|
206
|
+
else if (Array.isArray(msg.content)) {
|
|
207
|
+
// Extract text from content blocks
|
|
208
|
+
content = msg.content.map(block => {
|
|
209
|
+
if (block.type === 'text') {
|
|
210
|
+
return block.text;
|
|
211
|
+
}
|
|
212
|
+
else if (block.type === 'tool_use') {
|
|
213
|
+
return `[TOOL_USE: ${block.name}]`;
|
|
214
|
+
}
|
|
215
|
+
else if (block.type === 'tool_result') {
|
|
216
|
+
const content = block.content;
|
|
217
|
+
if (typeof content === 'string') {
|
|
218
|
+
return `[TOOL_RESULT: ${block.tool_use_id}]\n${content}`;
|
|
219
|
+
}
|
|
220
|
+
else if (Array.isArray(content)) {
|
|
221
|
+
const textContent = content.map(c => c.type === 'text' ? c.text : `[${c.type}]`).join(' ');
|
|
222
|
+
return `[TOOL_RESULT: ${block.tool_use_id}]\n${textContent}`;
|
|
223
|
+
}
|
|
224
|
+
return `[TOOL_RESULT: ${block.tool_use_id}]`;
|
|
225
|
+
}
|
|
226
|
+
return `[${block.type}]`;
|
|
227
|
+
}).join(' ');
|
|
228
|
+
}
|
|
229
|
+
else {
|
|
230
|
+
content = '[complex_content]';
|
|
231
|
+
}
|
|
232
|
+
return `${msg.role}: ${content}`;
|
|
233
|
+
}).join('\n\n')}`;
|
|
171
234
|
// Call Anthropic API with tools and cached system prompt
|
|
172
235
|
const response = await this.client.messages.create({
|
|
173
236
|
model: this.model,
|
|
@@ -186,11 +249,16 @@ class AnthropicProvider {
|
|
|
186
249
|
if ('cache_read_input_tokens' in response.usage) {
|
|
187
250
|
totalTokens.cacheRead += response.usage.cache_read_input_tokens || 0;
|
|
188
251
|
}
|
|
189
|
-
//
|
|
190
|
-
|
|
191
|
-
|
|
252
|
+
// Check if AI wants to use tools
|
|
253
|
+
const toolUses = response.content.filter((c) => c.type === 'tool_use');
|
|
254
|
+
// Log debug for final iteration to capture complete prompts/responses for evaluation
|
|
255
|
+
let debugFiles = null;
|
|
256
|
+
if (toolUses.length === 0) {
|
|
192
257
|
const aiResponse = {
|
|
193
|
-
content: response.content
|
|
258
|
+
content: response.content
|
|
259
|
+
.filter((c) => c.type === 'text')
|
|
260
|
+
.map(c => c.text)
|
|
261
|
+
.join('\n\n'),
|
|
194
262
|
usage: {
|
|
195
263
|
input_tokens: response.usage.input_tokens,
|
|
196
264
|
output_tokens: response.usage.output_tokens,
|
|
@@ -198,11 +266,8 @@ class AnthropicProvider {
|
|
|
198
266
|
cache_read_input_tokens: response.usage.cache_read_input_tokens
|
|
199
267
|
}
|
|
200
268
|
};
|
|
201
|
-
|
|
202
|
-
this.logDebugIfEnabled(`${operation}-iter${iterations}`, currentPrompt, aiResponse, iterationDurationMs);
|
|
269
|
+
debugFiles = this.logDebugIfEnabled(`${config.operation}-summary`, currentPrompt, aiResponse);
|
|
203
270
|
}
|
|
204
|
-
// Check if AI wants to use tools
|
|
205
|
-
const toolUses = response.content.filter((c) => c.type === 'tool_use');
|
|
206
271
|
if (toolUses.length === 0) {
|
|
207
272
|
// AI is done - extract final text message
|
|
208
273
|
const textContent = response.content.find((c) => c.type === 'text');
|
|
@@ -222,7 +287,10 @@ class AnthropicProvider {
|
|
|
222
287
|
operation: `${operation}-summary`,
|
|
223
288
|
sdk: this.getProviderType(),
|
|
224
289
|
startTime,
|
|
225
|
-
debugMode: this.debugMode
|
|
290
|
+
debugMode: this.debugMode,
|
|
291
|
+
debugFiles,
|
|
292
|
+
evaluationContext: config.evaluationContext,
|
|
293
|
+
interaction_id: config.interaction_id
|
|
226
294
|
});
|
|
227
295
|
}
|
|
228
296
|
// Execute all requested tools in parallel
|
|
@@ -295,7 +363,9 @@ class AnthropicProvider {
|
|
|
295
363
|
operation: `${operation}-max-iterations`,
|
|
296
364
|
sdk: this.getProviderType(),
|
|
297
365
|
startTime,
|
|
298
|
-
debugMode: this.debugMode
|
|
366
|
+
debugMode: this.debugMode,
|
|
367
|
+
evaluationContext: config.evaluationContext,
|
|
368
|
+
interaction_id: config.interaction_id
|
|
299
369
|
});
|
|
300
370
|
}
|
|
301
371
|
catch (error) {
|
|
@@ -316,7 +386,9 @@ class AnthropicProvider {
|
|
|
316
386
|
operation: `${operation}-error`,
|
|
317
387
|
sdk: this.getProviderType(),
|
|
318
388
|
startTime,
|
|
319
|
-
debugMode: this.debugMode
|
|
389
|
+
debugMode: this.debugMode,
|
|
390
|
+
evaluationContext: config.evaluationContext,
|
|
391
|
+
interaction_id: config.interaction_id
|
|
320
392
|
});
|
|
321
393
|
}
|
|
322
394
|
}
|
|
@@ -14,32 +14,56 @@ export declare function ensureDebugDirectory(): string;
|
|
|
14
14
|
*/
|
|
15
15
|
export declare function generateDebugId(operation: string): string;
|
|
16
16
|
/**
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* PRD #143 Decision 5: Extended metrics for model comparison analysis
|
|
17
|
+
* Unified evaluation metrics entry for AI quality assessment and performance tracking
|
|
18
|
+
* PRD #154: Single interface for all metrics and evaluation data
|
|
20
19
|
*/
|
|
21
|
-
export
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
20
|
+
export interface EvaluationMetrics {
|
|
21
|
+
operation: string;
|
|
22
|
+
sdk: string;
|
|
23
|
+
inputTokens: number;
|
|
24
|
+
outputTokens: number;
|
|
25
|
+
durationMs: number;
|
|
26
|
+
iterationCount: number;
|
|
27
|
+
toolCallCount: number;
|
|
28
|
+
status: string;
|
|
29
|
+
completionReason: string;
|
|
30
|
+
modelVersion: string;
|
|
31
|
+
cacheCreationTokens?: number;
|
|
32
|
+
cacheReadTokens?: number;
|
|
33
|
+
cacheHitRate?: number;
|
|
34
|
+
uniqueToolsUsed?: string[];
|
|
35
|
+
test_scenario: string;
|
|
36
|
+
ai_response_summary: string;
|
|
37
|
+
debug_files?: {
|
|
38
|
+
full_prompt: string;
|
|
39
|
+
full_response: string;
|
|
27
40
|
};
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
41
|
+
user_intent: string;
|
|
42
|
+
interaction_id: string;
|
|
43
|
+
failure_analysis?: string | {
|
|
44
|
+
failure_type: "timeout" | "error" | "infrastructure";
|
|
45
|
+
failure_reason: string;
|
|
46
|
+
time_to_failure: number;
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Determine if dataset generation should be skipped for specific operations
|
|
51
|
+
*/
|
|
52
|
+
export declare function shouldSkipDatasetGeneration(operation: string): boolean;
|
|
53
|
+
/**
|
|
54
|
+
* Log unified evaluation metrics when DEBUG_DOT_AI=true
|
|
55
|
+
* Single function for all metrics and evaluation data capture
|
|
56
|
+
*/
|
|
57
|
+
/**
|
|
58
|
+
* Generate eval dataset entry in standard OpenAI Evals format
|
|
59
|
+
* Logs evaluation metrics to JSONL dataset files for AI quality assessment
|
|
60
|
+
*/
|
|
61
|
+
export declare function logEvaluationDataset(metrics: EvaluationMetrics, debugMode?: boolean): void;
|
|
38
62
|
/**
|
|
39
63
|
* Create AgenticResult and log metrics in one step
|
|
40
64
|
* Reduces code duplication across providers
|
|
41
65
|
*
|
|
42
|
-
* PRD #
|
|
66
|
+
* PRD #154: Updated to use unified evaluation metrics
|
|
43
67
|
*/
|
|
44
68
|
export declare function createAndLogAgenticResult(config: {
|
|
45
69
|
finalMessage: string;
|
|
@@ -62,6 +86,15 @@ export declare function createAndLogAgenticResult(config: {
|
|
|
62
86
|
sdk: string;
|
|
63
87
|
startTime: number;
|
|
64
88
|
debugMode: boolean;
|
|
89
|
+
debugFiles?: {
|
|
90
|
+
promptFile: string;
|
|
91
|
+
responseFile: string;
|
|
92
|
+
} | null;
|
|
93
|
+
evaluationContext?: {
|
|
94
|
+
user_intent?: string;
|
|
95
|
+
failure_analysis?: string;
|
|
96
|
+
};
|
|
97
|
+
interaction_id?: string;
|
|
65
98
|
}): AgenticResult;
|
|
66
99
|
/**
|
|
67
100
|
* Save AI interaction for debugging when DEBUG_DOT_AI=true
|
|
@@ -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,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
|
|
1
|
+
{"version":3,"file":"provider-debug-utils.d.ts","sourceRoot":"","sources":["../../../src/core/providers/provider-debug-utils.ts"],"names":[],"mappings":"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"}
|