@agentv/core 0.2.3
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/LICENSE +21 -0
- package/README.md +78 -0
- package/dist/chunk-5REK5RSI.js +86 -0
- package/dist/chunk-5REK5RSI.js.map +1 -0
- package/dist/evaluation/validation/index.cjs +617 -0
- package/dist/evaluation/validation/index.cjs.map +1 -0
- package/dist/evaluation/validation/index.d.cts +56 -0
- package/dist/evaluation/validation/index.d.ts +56 -0
- package/dist/evaluation/validation/index.js +499 -0
- package/dist/evaluation/validation/index.js.map +1 -0
- package/dist/index.cjs +2204 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +406 -0
- package/dist/index.d.ts +406 -0
- package/dist/index.js +2079 -0
- package/dist/index.js.map +1 -0
- package/package.json +49 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 EntityProcess
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# @agentv/core
|
|
2
|
+
|
|
3
|
+
Core evaluation engine and runtime primitives for AgentV - a TypeScript-based AI agent evaluation and optimization framework.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
This package provides the foundational components for building and evaluating AI agents:
|
|
8
|
+
|
|
9
|
+
- **Provider Abstraction**: Unified interface for Azure OpenAI, Anthropic, Google Gemini, VS Code Copilot, and mock providers
|
|
10
|
+
- **Evaluation Engine**: YAML-based test specification and execution
|
|
11
|
+
- **Quality Grading**: AI-powered scoring system for comparing expected vs. actual outputs
|
|
12
|
+
- **Target Management**: Flexible configuration for different execution environments
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install @agentv/core
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Usage
|
|
21
|
+
|
|
22
|
+
This is a low-level package primarily used by the [agentv](https://www.npmjs.com/package/agentv) CLI. Most users should install the CLI package instead:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install -g agentv
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
For programmatic usage or custom integrations, you can import core components:
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
import { createProvider, runEvaluation } from '@agentv/core';
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Features
|
|
35
|
+
|
|
36
|
+
### Multi-Provider Support
|
|
37
|
+
|
|
38
|
+
- **Azure OpenAI**: Enterprise-grade deployment support
|
|
39
|
+
- **Anthropic Claude**: Latest Claude models including Sonnet 4.5
|
|
40
|
+
- **Google Gemini**: Gemini 2.0 Flash and other models
|
|
41
|
+
- **VS Code Copilot**: Programmatic integration via subagent
|
|
42
|
+
- **Mock Provider**: Testing without API calls
|
|
43
|
+
|
|
44
|
+
### Evaluation Framework
|
|
45
|
+
|
|
46
|
+
- YAML-based test specifications
|
|
47
|
+
- Code block extraction and structured prompting
|
|
48
|
+
- Automatic retry handling for timeouts
|
|
49
|
+
- Detailed scoring with hit/miss analysis
|
|
50
|
+
- Multiple output formats (JSONL, YAML)
|
|
51
|
+
|
|
52
|
+
### Quality Grading
|
|
53
|
+
|
|
54
|
+
- AI-powered aspect extraction and comparison
|
|
55
|
+
- Normalized scoring (0.0 to 1.0)
|
|
56
|
+
- Detailed reasoning and analysis
|
|
57
|
+
- Configurable grading models
|
|
58
|
+
|
|
59
|
+
## Architecture
|
|
60
|
+
|
|
61
|
+
Built on modern TypeScript tooling:
|
|
62
|
+
|
|
63
|
+
- **@ax-llm/ax**: LLM provider abstraction
|
|
64
|
+
- **Vercel AI SDK**: Streaming and tool use
|
|
65
|
+
- **Zod**: Runtime type validation
|
|
66
|
+
- **YAML**: Configuration and test specifications
|
|
67
|
+
|
|
68
|
+
## Documentation
|
|
69
|
+
|
|
70
|
+
For complete documentation, examples, and CLI usage, see the [agentv](https://www.npmjs.com/package/agentv) package.
|
|
71
|
+
|
|
72
|
+
## Repository
|
|
73
|
+
|
|
74
|
+
[https://github.com/EntityProcess/agentv](https://github.com/EntityProcess/agentv)
|
|
75
|
+
|
|
76
|
+
## License
|
|
77
|
+
|
|
78
|
+
MIT License - see [LICENSE](../../LICENSE) for details.
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
// src/evaluation/file-utils.ts
|
|
2
|
+
import { constants } from "node:fs";
|
|
3
|
+
import { access } from "node:fs/promises";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
async function fileExists(filePath) {
|
|
6
|
+
try {
|
|
7
|
+
await access(filePath, constants.F_OK);
|
|
8
|
+
return true;
|
|
9
|
+
} catch {
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
async function findGitRoot(startPath) {
|
|
14
|
+
let currentDir = path.dirname(path.resolve(startPath));
|
|
15
|
+
const root = path.parse(currentDir).root;
|
|
16
|
+
while (currentDir !== root) {
|
|
17
|
+
const gitPath = path.join(currentDir, ".git");
|
|
18
|
+
if (await fileExists(gitPath)) {
|
|
19
|
+
return currentDir;
|
|
20
|
+
}
|
|
21
|
+
const parentDir = path.dirname(currentDir);
|
|
22
|
+
if (parentDir === currentDir) {
|
|
23
|
+
break;
|
|
24
|
+
}
|
|
25
|
+
currentDir = parentDir;
|
|
26
|
+
}
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
function buildSearchRoots(evalPath, repoRoot) {
|
|
30
|
+
const uniqueRoots = [];
|
|
31
|
+
const addRoot = (root) => {
|
|
32
|
+
const normalized = path.resolve(root);
|
|
33
|
+
if (!uniqueRoots.includes(normalized)) {
|
|
34
|
+
uniqueRoots.push(normalized);
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
let currentDir = path.dirname(evalPath);
|
|
38
|
+
let reachedBoundary = false;
|
|
39
|
+
while (!reachedBoundary) {
|
|
40
|
+
addRoot(currentDir);
|
|
41
|
+
const parentDir = path.dirname(currentDir);
|
|
42
|
+
if (currentDir === repoRoot || parentDir === currentDir) {
|
|
43
|
+
reachedBoundary = true;
|
|
44
|
+
} else {
|
|
45
|
+
currentDir = parentDir;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
addRoot(repoRoot);
|
|
49
|
+
addRoot(process.cwd());
|
|
50
|
+
return uniqueRoots;
|
|
51
|
+
}
|
|
52
|
+
function trimLeadingSeparators(value) {
|
|
53
|
+
const trimmed = value.replace(/^[/\\]+/, "");
|
|
54
|
+
return trimmed.length > 0 ? trimmed : value;
|
|
55
|
+
}
|
|
56
|
+
async function resolveFileReference(rawValue, searchRoots) {
|
|
57
|
+
const displayPath = trimLeadingSeparators(rawValue);
|
|
58
|
+
const potentialPaths = [];
|
|
59
|
+
if (path.isAbsolute(rawValue)) {
|
|
60
|
+
potentialPaths.push(path.normalize(rawValue));
|
|
61
|
+
}
|
|
62
|
+
for (const base of searchRoots) {
|
|
63
|
+
potentialPaths.push(path.resolve(base, displayPath));
|
|
64
|
+
}
|
|
65
|
+
const attempted = [];
|
|
66
|
+
const seen = /* @__PURE__ */ new Set();
|
|
67
|
+
for (const candidate of potentialPaths) {
|
|
68
|
+
const absoluteCandidate = path.resolve(candidate);
|
|
69
|
+
if (seen.has(absoluteCandidate)) {
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
seen.add(absoluteCandidate);
|
|
73
|
+
attempted.push(absoluteCandidate);
|
|
74
|
+
if (await fileExists(absoluteCandidate)) {
|
|
75
|
+
return { displayPath, resolvedPath: absoluteCandidate, attempted };
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return { displayPath, attempted };
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export {
|
|
82
|
+
findGitRoot,
|
|
83
|
+
buildSearchRoots,
|
|
84
|
+
resolveFileReference
|
|
85
|
+
};
|
|
86
|
+
//# sourceMappingURL=chunk-5REK5RSI.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/evaluation/file-utils.ts"],"sourcesContent":["import { constants } from \"node:fs\";\r\nimport { access } from \"node:fs/promises\";\r\nimport path from \"node:path\";\r\n\r\nexport async function fileExists(filePath: string): Promise<boolean> {\r\n try {\r\n await access(filePath, constants.F_OK);\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * Find git repository root by walking up the directory tree.\r\n */\r\nexport async function findGitRoot(startPath: string): Promise<string | null> {\r\n let currentDir = path.dirname(path.resolve(startPath));\r\n const root = path.parse(currentDir).root;\r\n\r\n while (currentDir !== root) {\r\n const gitPath = path.join(currentDir, \".git\");\r\n if (await fileExists(gitPath)) {\r\n return currentDir;\r\n }\r\n\r\n const parentDir = path.dirname(currentDir);\r\n if (parentDir === currentDir) {\r\n break;\r\n }\r\n currentDir = parentDir;\r\n }\r\n\r\n return null;\r\n}\r\n\r\n/**\r\n * Build search roots for file resolution, matching yaml-parser behavior.\r\n * Searches from eval file directory up to repo root.\r\n */\r\nexport function buildSearchRoots(evalPath: string, repoRoot: string): readonly string[] {\r\n const uniqueRoots: string[] = [];\r\n const addRoot = (root: string): void => {\r\n const normalized = path.resolve(root);\r\n if (!uniqueRoots.includes(normalized)) {\r\n uniqueRoots.push(normalized);\r\n }\r\n };\r\n\r\n let currentDir = path.dirname(evalPath);\r\n let reachedBoundary = false;\r\n while (!reachedBoundary) {\r\n addRoot(currentDir);\r\n const parentDir = path.dirname(currentDir);\r\n if (currentDir === repoRoot || parentDir === currentDir) {\r\n reachedBoundary = true;\r\n } else {\r\n currentDir = parentDir;\r\n }\r\n }\r\n\r\n addRoot(repoRoot);\r\n addRoot(process.cwd());\r\n return uniqueRoots;\r\n}\r\n\r\n/**\r\n * Trim leading path separators for display.\r\n */\r\nfunction trimLeadingSeparators(value: string): string {\r\n const trimmed = value.replace(/^[/\\\\]+/, \"\");\r\n return trimmed.length > 0 ? trimmed : value;\r\n}\r\n\r\n/**\r\n * Resolve a file reference using search roots, matching yaml-parser behavior.\r\n */\r\nexport async function resolveFileReference(\r\n rawValue: string,\r\n searchRoots: readonly string[],\r\n): Promise<{\r\n readonly displayPath: string;\r\n readonly resolvedPath?: string;\r\n readonly attempted: readonly string[];\r\n}> {\r\n const displayPath = trimLeadingSeparators(rawValue);\r\n const potentialPaths: string[] = [];\r\n\r\n if (path.isAbsolute(rawValue)) {\r\n potentialPaths.push(path.normalize(rawValue));\r\n }\r\n\r\n for (const base of searchRoots) {\r\n potentialPaths.push(path.resolve(base, displayPath));\r\n }\r\n\r\n const attempted: string[] = [];\r\n const seen = new Set<string>();\r\n for (const candidate of potentialPaths) {\r\n const absoluteCandidate = path.resolve(candidate);\r\n if (seen.has(absoluteCandidate)) {\r\n continue;\r\n }\r\n seen.add(absoluteCandidate);\r\n attempted.push(absoluteCandidate);\r\n if (await fileExists(absoluteCandidate)) {\r\n return { displayPath, resolvedPath: absoluteCandidate, attempted };\r\n }\r\n }\r\n\r\n return { displayPath, attempted };\r\n}\r\n"],"mappings":";AAAA,SAAS,iBAAiB;AAC1B,SAAS,cAAc;AACvB,OAAO,UAAU;AAEjB,eAAsB,WAAW,UAAoC;AACnE,MAAI;AACF,UAAM,OAAO,UAAU,UAAU,IAAI;AACrC,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAKA,eAAsB,YAAY,WAA2C;AAC3E,MAAI,aAAa,KAAK,QAAQ,KAAK,QAAQ,SAAS,CAAC;AACrD,QAAM,OAAO,KAAK,MAAM,UAAU,EAAE;AAEpC,SAAO,eAAe,MAAM;AAC1B,UAAM,UAAU,KAAK,KAAK,YAAY,MAAM;AAC5C,QAAI,MAAM,WAAW,OAAO,GAAG;AAC7B,aAAO;AAAA,IACT;AAEA,UAAM,YAAY,KAAK,QAAQ,UAAU;AACzC,QAAI,cAAc,YAAY;AAC5B;AAAA,IACF;AACA,iBAAa;AAAA,EACf;AAEA,SAAO;AACT;AAMO,SAAS,iBAAiB,UAAkB,UAAqC;AACtF,QAAM,cAAwB,CAAC;AAC/B,QAAM,UAAU,CAAC,SAAuB;AACtC,UAAM,aAAa,KAAK,QAAQ,IAAI;AACpC,QAAI,CAAC,YAAY,SAAS,UAAU,GAAG;AACrC,kBAAY,KAAK,UAAU;AAAA,IAC7B;AAAA,EACF;AAEA,MAAI,aAAa,KAAK,QAAQ,QAAQ;AACtC,MAAI,kBAAkB;AACtB,SAAO,CAAC,iBAAiB;AACvB,YAAQ,UAAU;AAClB,UAAM,YAAY,KAAK,QAAQ,UAAU;AACzC,QAAI,eAAe,YAAY,cAAc,YAAY;AACvD,wBAAkB;AAAA,IACpB,OAAO;AACL,mBAAa;AAAA,IACf;AAAA,EACF;AAEA,UAAQ,QAAQ;AAChB,UAAQ,QAAQ,IAAI,CAAC;AACrB,SAAO;AACT;AAKA,SAAS,sBAAsB,OAAuB;AACpD,QAAM,UAAU,MAAM,QAAQ,WAAW,EAAE;AAC3C,SAAO,QAAQ,SAAS,IAAI,UAAU;AACxC;AAKA,eAAsB,qBACpB,UACA,aAKC;AACD,QAAM,cAAc,sBAAsB,QAAQ;AAClD,QAAM,iBAA2B,CAAC;AAElC,MAAI,KAAK,WAAW,QAAQ,GAAG;AAC7B,mBAAe,KAAK,KAAK,UAAU,QAAQ,CAAC;AAAA,EAC9C;AAEA,aAAW,QAAQ,aAAa;AAC9B,mBAAe,KAAK,KAAK,QAAQ,MAAM,WAAW,CAAC;AAAA,EACrD;AAEA,QAAM,YAAsB,CAAC;AAC7B,QAAM,OAAO,oBAAI,IAAY;AAC7B,aAAW,aAAa,gBAAgB;AACtC,UAAM,oBAAoB,KAAK,QAAQ,SAAS;AAChD,QAAI,KAAK,IAAI,iBAAiB,GAAG;AAC/B;AAAA,IACF;AACA,SAAK,IAAI,iBAAiB;AAC1B,cAAU,KAAK,iBAAiB;AAChC,QAAI,MAAM,WAAW,iBAAiB,GAAG;AACvC,aAAO,EAAE,aAAa,cAAc,mBAAmB,UAAU;AAAA,IACnE;AAAA,EACF;AAEA,SAAO,EAAE,aAAa,UAAU;AAClC;","names":[]}
|