@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 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":[]}