@sebastiantuyu/agest 0.3.2 → 0.3.3-next.1
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/adapters/remote.js +2 -1
- package/dist/cli.js +30 -3
- package/dist/discover.d.ts +16 -0
- package/dist/discover.js +62 -0
- package/dist/index.d.ts +1 -1
- package/dist/runner.js +14 -7
- package/dist/types.d.ts +4 -1
- package/package.json +15 -14
package/dist/adapters/remote.js
CHANGED
|
@@ -24,12 +24,13 @@
|
|
|
24
24
|
*/
|
|
25
25
|
export function remote(endpoint, options = {}) {
|
|
26
26
|
const { headers = {}, method = "POST", body: extraBody, buildRequest = defaultBuildRequest, parseResponse, metadata: staticMetadata, } = options;
|
|
27
|
-
return async (input) => {
|
|
27
|
+
return async (input, execOptions) => {
|
|
28
28
|
let res;
|
|
29
29
|
try {
|
|
30
30
|
const fetchOptions = {
|
|
31
31
|
method,
|
|
32
32
|
headers: { "Content-Type": "application/json", ...headers },
|
|
33
|
+
signal: execOptions?.signal,
|
|
33
34
|
};
|
|
34
35
|
if (method !== "GET") {
|
|
35
36
|
const built = buildRequest(input);
|
package/dist/cli.js
CHANGED
|
@@ -2,11 +2,35 @@
|
|
|
2
2
|
import { spawn } from "child_process";
|
|
3
3
|
import { main as stats } from "./stats.js";
|
|
4
4
|
import { main as preview } from "./preview.js";
|
|
5
|
+
import { DEFAULT_PATTERN, discoverTestFiles } from "./discover.js";
|
|
5
6
|
const command = process.argv[2];
|
|
7
|
+
function parseRunArgs(args) {
|
|
8
|
+
const targets = [];
|
|
9
|
+
let pattern;
|
|
10
|
+
for (let i = 0; i < args.length; i++) {
|
|
11
|
+
const a = args[i];
|
|
12
|
+
if (a === "--pattern" || a === "-p") {
|
|
13
|
+
pattern = args[++i];
|
|
14
|
+
if (pattern === undefined) {
|
|
15
|
+
console.error(" Error: --pattern requires a value");
|
|
16
|
+
process.exit(1);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
else if (a.startsWith("--pattern=")) {
|
|
20
|
+
pattern = a.slice("--pattern=".length);
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
targets.push(a);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return { pattern, targets };
|
|
27
|
+
}
|
|
6
28
|
async function run() {
|
|
7
|
-
const
|
|
29
|
+
const { pattern, targets } = parseRunArgs(process.argv.slice(3));
|
|
30
|
+
const files = await discoverTestFiles(targets, { pattern });
|
|
8
31
|
if (files.length === 0) {
|
|
9
|
-
|
|
32
|
+
const effective = pattern ?? DEFAULT_PATTERN;
|
|
33
|
+
console.error(` No test files found (pattern: ${effective})`);
|
|
10
34
|
process.exit(1);
|
|
11
35
|
}
|
|
12
36
|
for (const file of files) {
|
|
@@ -29,7 +53,10 @@ if (!command || !commands[command]) {
|
|
|
29
53
|
Usage: agest <command>
|
|
30
54
|
|
|
31
55
|
Commands:
|
|
32
|
-
run Run test file(s)
|
|
56
|
+
run Run test file(s), directories, or glob patterns
|
|
57
|
+
agest run tests/ # walks for ${DEFAULT_PATTERN}
|
|
58
|
+
agest run src/agest --pattern "**/*.test.ts"
|
|
59
|
+
agest run "tests/**/*.agest.ts" path/to/file.agest.ts
|
|
33
60
|
stats Show aggregated test statistics
|
|
34
61
|
preview Generate an HTML report preview
|
|
35
62
|
`);
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export declare const DEFAULT_PATTERN = "**/*.agest.ts";
|
|
2
|
+
export interface DiscoverOptions {
|
|
3
|
+
pattern?: string;
|
|
4
|
+
cwd?: string;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Resolve a mix of file paths, directories, and glob patterns into a
|
|
8
|
+
* deduplicated, sorted list of absolute file paths.
|
|
9
|
+
*
|
|
10
|
+
* Rules per target:
|
|
11
|
+
* - directory: search recursively for `pattern` (default `**\/*.agest.ts`)
|
|
12
|
+
* - glob (contains *, ?, [], {}): expand it
|
|
13
|
+
* - file: use as-is
|
|
14
|
+
* - anything else: try as glob (zero matches is fine)
|
|
15
|
+
*/
|
|
16
|
+
export declare function discoverTestFiles(targets: string[], options?: DiscoverOptions): Promise<string[]>;
|
package/dist/discover.js
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { promises as fs } from "node:fs";
|
|
2
|
+
import { isAbsolute, resolve } from "node:path";
|
|
3
|
+
export const DEFAULT_PATTERN = "**/*.agest.ts";
|
|
4
|
+
const GLOB_CHARS = /[*?[\]{}]/;
|
|
5
|
+
function hasGlobChars(value) {
|
|
6
|
+
return GLOB_CHARS.test(value);
|
|
7
|
+
}
|
|
8
|
+
async function statSafe(path) {
|
|
9
|
+
try {
|
|
10
|
+
const stat = await fs.stat(path);
|
|
11
|
+
return { isFile: stat.isFile(), isDir: stat.isDirectory() };
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
return { isFile: false, isDir: false };
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
async function expandGlob(pattern, cwd) {
|
|
18
|
+
const out = [];
|
|
19
|
+
// fs.promises.glob is available in Node >= 22 (the package's required engine).
|
|
20
|
+
for await (const match of fs.glob(pattern, { cwd })) {
|
|
21
|
+
out.push(isAbsolute(match) ? match : resolve(cwd, match));
|
|
22
|
+
}
|
|
23
|
+
return out;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Resolve a mix of file paths, directories, and glob patterns into a
|
|
27
|
+
* deduplicated, sorted list of absolute file paths.
|
|
28
|
+
*
|
|
29
|
+
* Rules per target:
|
|
30
|
+
* - directory: search recursively for `pattern` (default `**\/*.agest.ts`)
|
|
31
|
+
* - glob (contains *, ?, [], {}): expand it
|
|
32
|
+
* - file: use as-is
|
|
33
|
+
* - anything else: try as glob (zero matches is fine)
|
|
34
|
+
*/
|
|
35
|
+
export async function discoverTestFiles(targets, options = {}) {
|
|
36
|
+
const cwd = options.cwd ?? process.cwd();
|
|
37
|
+
const pattern = options.pattern ?? DEFAULT_PATTERN;
|
|
38
|
+
const work = targets.length === 0 ? ["."] : targets;
|
|
39
|
+
const found = new Set();
|
|
40
|
+
for (const target of work) {
|
|
41
|
+
if (hasGlobChars(target)) {
|
|
42
|
+
for (const f of await expandGlob(target, cwd))
|
|
43
|
+
found.add(f);
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
const stat = await statSafe(isAbsolute(target) ? target : resolve(cwd, target));
|
|
47
|
+
if (stat.isDir) {
|
|
48
|
+
const trimmed = target.replace(/\/+$/, "");
|
|
49
|
+
const dirPattern = `${trimmed}/${pattern}`;
|
|
50
|
+
for (const f of await expandGlob(dirPattern, cwd))
|
|
51
|
+
found.add(f);
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
if (stat.isFile) {
|
|
55
|
+
found.add(isAbsolute(target) ? target : resolve(cwd, target));
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
for (const f of await expandGlob(target, cwd))
|
|
59
|
+
found.add(f);
|
|
60
|
+
}
|
|
61
|
+
return [...found].sort();
|
|
62
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ export type { AgestConfig, JudgeConfig, JudgeExecutor } from "./config";
|
|
|
7
7
|
export type { LogLevel } from "./logger";
|
|
8
8
|
export type { AgentExpectation, AgentMatchers } from "./assertions";
|
|
9
9
|
export type { JudgeCriteria } from "./judge";
|
|
10
|
-
export type { AgentExecutor, AgentResponse, AgentReport, SceneResult, RunResult, JudgeVerdict, JudgeResult, HookFn, } from "./types";
|
|
10
|
+
export type { AgentExecutor, ExecutorOptions, AgentResponse, AgentReport, SceneResult, RunResult, JudgeVerdict, JudgeResult, HookFn, } from "./types";
|
|
11
11
|
export interface AgentOptions {
|
|
12
12
|
name?: string;
|
|
13
13
|
}
|
package/dist/runner.js
CHANGED
|
@@ -37,13 +37,20 @@ async function executeSingleRun(executor, scene, timeoutMs, turns, judgeConfig)
|
|
|
37
37
|
const start = performance.now();
|
|
38
38
|
const input = scene.prompt;
|
|
39
39
|
for (let t = 0; t < turns; t++) {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
40
|
+
const controller = new AbortController();
|
|
41
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
42
|
+
try {
|
|
43
|
+
response = await executor(input, { signal: controller.signal });
|
|
44
|
+
}
|
|
45
|
+
catch (err) {
|
|
46
|
+
if (err.name === "AbortError" || controller.signal.aborted) {
|
|
47
|
+
throw new Error(`Scene timed out after ${timeoutMs}ms`);
|
|
48
|
+
}
|
|
49
|
+
throw err;
|
|
50
|
+
}
|
|
51
|
+
finally {
|
|
52
|
+
clearTimeout(timer);
|
|
53
|
+
}
|
|
47
54
|
if (response.executionError)
|
|
48
55
|
break;
|
|
49
56
|
}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
export
|
|
1
|
+
export interface ExecutorOptions {
|
|
2
|
+
signal?: AbortSignal;
|
|
3
|
+
}
|
|
4
|
+
export type AgentExecutor = (input: string, options?: ExecutorOptions) => Promise<AgentResponse>;
|
|
2
5
|
export interface AgentResponse {
|
|
3
6
|
text: string;
|
|
4
7
|
refusal?: boolean;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sebastiantuyu/agest",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.3-next.1",
|
|
4
4
|
"description": "A testing library for agents",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -37,25 +37,26 @@
|
|
|
37
37
|
"site:preview": "npx serve site -p 3000",
|
|
38
38
|
"release:patch": "npm version patch && git push && git push --tags",
|
|
39
39
|
"release:minor": "npm version minor && git push && git push --tags",
|
|
40
|
-
"release:major": "npm version major && git push && git push --tags"
|
|
40
|
+
"release:major": "npm version major && git push && git push --tags",
|
|
41
|
+
"release:next": "npm version prerelease --preid=next && git push && git push --tags"
|
|
41
42
|
},
|
|
42
43
|
"engines": {
|
|
43
44
|
"node": ">=22.0.0"
|
|
44
45
|
},
|
|
45
46
|
"devDependencies": {
|
|
46
|
-
"@langchain/core": "
|
|
47
|
-
"@langchain/langgraph": "
|
|
48
|
-
"@langchain/openai": "
|
|
49
|
-
"@types/node": "
|
|
50
|
-
"@vitest/coverage-v8": "
|
|
51
|
-
"dotenv": "
|
|
52
|
-
"langchain": "
|
|
53
|
-
"tsx": "
|
|
54
|
-
"typescript": "
|
|
55
|
-
"vitest": "
|
|
56
|
-
"zod": "
|
|
47
|
+
"@langchain/core": "1.1.39",
|
|
48
|
+
"@langchain/langgraph": "1.2.8",
|
|
49
|
+
"@langchain/openai": "1.4.4",
|
|
50
|
+
"@types/node": "22.19.17",
|
|
51
|
+
"@vitest/coverage-v8": "3.2.4",
|
|
52
|
+
"dotenv": "17.4.1",
|
|
53
|
+
"langchain": "1.3.1",
|
|
54
|
+
"tsx": "4.21.0",
|
|
55
|
+
"typescript": "5.9.3",
|
|
56
|
+
"vitest": "3.2.4",
|
|
57
|
+
"zod": "4.3.6"
|
|
57
58
|
},
|
|
58
59
|
"dependencies": {
|
|
59
|
-
"@supercharge/promise-pool": "
|
|
60
|
+
"@supercharge/promise-pool": "3.3.0"
|
|
60
61
|
}
|
|
61
62
|
}
|