@agentforge/testing 0.16.21 โ 0.16.23
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/README.md +17 -17
- package/dist/index.cjs +40 -18
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +32 -14
- package/dist/index.d.ts +32 -14
- package/dist/index.js +40 -18
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -6,11 +6,11 @@
|
|
|
6
6
|
[](https://www.typescriptlang.org/)
|
|
7
7
|
[](../../LICENSE)
|
|
8
8
|
|
|
9
|
-
##
|
|
9
|
+
## Status: Production Ready & Published
|
|
10
10
|
|
|
11
11
|
**Complete testing toolkit** | **Full TypeScript support** | **Comprehensive documentation**
|
|
12
12
|
|
|
13
|
-
##
|
|
13
|
+
## Installation
|
|
14
14
|
|
|
15
15
|
```bash
|
|
16
16
|
npm install --save-dev @agentforge/testing
|
|
@@ -20,15 +20,15 @@ pnpm add -D @agentforge/testing
|
|
|
20
20
|
yarn add -D @agentforge/testing
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
-
##
|
|
23
|
+
## Features
|
|
24
24
|
|
|
25
|
-
-
|
|
26
|
-
-
|
|
27
|
-
-
|
|
28
|
-
-
|
|
29
|
-
-
|
|
30
|
-
-
|
|
31
|
-
-
|
|
25
|
+
- **Mock Factories** - Create mock LLMs, tools, and states for testing
|
|
26
|
+
- **Test Helpers** - Assertion helpers and state builders
|
|
27
|
+
- **Fixtures** - Pre-built sample agents, tools, and conversations
|
|
28
|
+
- **Test Runners** - Agent test runner and conversation simulator
|
|
29
|
+
- **Snapshot Testing** - State and message snapshot utilities
|
|
30
|
+
- **Full TypeScript** - Complete type safety and inference
|
|
31
|
+
- **Vitest Integration** - Works seamlessly with Vitest
|
|
32
32
|
|
|
33
33
|
## Quick Start
|
|
34
34
|
|
|
@@ -368,21 +368,21 @@ describe('ReAct Agent Integration Tests', () => {
|
|
|
368
368
|
- `calculatorTool` - Calculator tool
|
|
369
369
|
- `searchTool` - Search tool
|
|
370
370
|
|
|
371
|
-
##
|
|
371
|
+
## Documentation
|
|
372
372
|
|
|
373
|
-
-
|
|
374
|
-
-
|
|
375
|
-
-
|
|
376
|
-
-
|
|
373
|
+
- **[Full Documentation](https://tvscoundrel.github.io/agentforge/)**
|
|
374
|
+
- **[Quick Start](https://tvscoundrel.github.io/agentforge/guide/quick-start)**
|
|
375
|
+
- **[Testing API Reference](https://tvscoundrel.github.io/agentforge/api/testing)**
|
|
376
|
+
- **[Testing Tutorial](https://tvscoundrel.github.io/agentforge/tutorials/testing)**
|
|
377
377
|
|
|
378
|
-
##
|
|
378
|
+
## Links
|
|
379
379
|
|
|
380
380
|
- [GitHub Repository](https://github.com/TVScoundrel/agentforge)
|
|
381
381
|
- [npm Package](https://www.npmjs.com/package/@agentforge/testing)
|
|
382
382
|
- [Changelog](https://tvscoundrel.github.io/agentforge/changelog.html) - See what's new before upgrading
|
|
383
383
|
- [Report Issues](https://github.com/TVScoundrel/agentforge/issues)
|
|
384
384
|
|
|
385
|
-
##
|
|
385
|
+
## Related Packages
|
|
386
386
|
|
|
387
387
|
- [@agentforge/core](https://www.npmjs.com/package/@agentforge/core) - Core abstractions
|
|
388
388
|
- [@agentforge/patterns](https://www.npmjs.com/package/@agentforge/patterns) - Agent patterns
|
package/dist/index.cjs
CHANGED
|
@@ -12808,14 +12808,14 @@ function withTimeout(fn2, timeout, isHook = false) {
|
|
|
12808
12808
|
if (timeout <= 0 || timeout === Number.POSITIVE_INFINITY) {
|
|
12809
12809
|
return fn2;
|
|
12810
12810
|
}
|
|
12811
|
-
const { setTimeout: setTimeout2, clearTimeout } = getSafeTimers();
|
|
12811
|
+
const { setTimeout: setTimeout2, clearTimeout: clearTimeout2 } = getSafeTimers();
|
|
12812
12812
|
return function runWithTimeout(...args) {
|
|
12813
12813
|
return Promise.race([
|
|
12814
12814
|
fn2(...args),
|
|
12815
12815
|
new Promise((resolve4, reject) => {
|
|
12816
12816
|
var _a;
|
|
12817
12817
|
const timer = setTimeout2(() => {
|
|
12818
|
-
|
|
12818
|
+
clearTimeout2(timer);
|
|
12819
12819
|
reject(new Error(makeTimeoutMsg(isHook, timeout)));
|
|
12820
12820
|
}, timeout);
|
|
12821
12821
|
(_a = timer.unref) == null ? void 0 : _a.call(timer);
|
|
@@ -15673,9 +15673,9 @@ function createExpectPoll(expect2) {
|
|
|
15673
15673
|
const promise = () => new Promise((resolve4, reject) => {
|
|
15674
15674
|
let intervalId;
|
|
15675
15675
|
let lastError;
|
|
15676
|
-
const { setTimeout: setTimeout2, clearTimeout } = getSafeTimers();
|
|
15676
|
+
const { setTimeout: setTimeout2, clearTimeout: clearTimeout2 } = getSafeTimers();
|
|
15677
15677
|
const timeoutId = setTimeout2(() => {
|
|
15678
|
-
|
|
15678
|
+
clearTimeout2(intervalId);
|
|
15679
15679
|
reject(
|
|
15680
15680
|
copyStackTrace$1(
|
|
15681
15681
|
new Error(`Matcher did not succeed in ${timeout}ms`, {
|
|
@@ -15691,8 +15691,8 @@ function createExpectPoll(expect2) {
|
|
|
15691
15691
|
const obj = await fn2();
|
|
15692
15692
|
utils_exports.flag(assertion, "object", obj);
|
|
15693
15693
|
resolve4(await assertionFunction.call(assertion, ...args));
|
|
15694
|
-
|
|
15695
|
-
|
|
15694
|
+
clearTimeout2(intervalId);
|
|
15695
|
+
clearTimeout2(timeoutId);
|
|
15696
15696
|
} catch (err) {
|
|
15697
15697
|
lastError = err;
|
|
15698
15698
|
intervalId = setTimeout2(check, interval);
|
|
@@ -17283,7 +17283,7 @@ To automatically clean-up native timers, use \`shouldClearNativeTimers\`.`
|
|
|
17283
17283
|
});
|
|
17284
17284
|
};
|
|
17285
17285
|
}
|
|
17286
|
-
clock.clearTimeout = function
|
|
17286
|
+
clock.clearTimeout = function clearTimeout2(timerId) {
|
|
17287
17287
|
return clearTimer(clock, timerId, "Timeout");
|
|
17288
17288
|
};
|
|
17289
17289
|
clock.nextTick = function nextTick(func) {
|
|
@@ -17926,7 +17926,7 @@ function copyStackTrace(target, source) {
|
|
|
17926
17926
|
return target;
|
|
17927
17927
|
}
|
|
17928
17928
|
function waitFor(callback, options = {}) {
|
|
17929
|
-
const { setTimeout: setTimeout2, setInterval, clearTimeout, clearInterval } = getSafeTimers();
|
|
17929
|
+
const { setTimeout: setTimeout2, setInterval, clearTimeout: clearTimeout2, clearInterval } = getSafeTimers();
|
|
17930
17930
|
const { interval = 50, timeout = 1e3 } = typeof options === "number" ? { timeout: options } : options;
|
|
17931
17931
|
const STACK_TRACE_ERROR = new Error("STACK_TRACE_ERROR");
|
|
17932
17932
|
return new Promise((resolve4, reject) => {
|
|
@@ -17936,7 +17936,7 @@ function waitFor(callback, options = {}) {
|
|
|
17936
17936
|
let intervalId;
|
|
17937
17937
|
const onResolve = (result) => {
|
|
17938
17938
|
if (timeoutId) {
|
|
17939
|
-
|
|
17939
|
+
clearTimeout2(timeoutId);
|
|
17940
17940
|
}
|
|
17941
17941
|
if (intervalId) {
|
|
17942
17942
|
clearInterval(intervalId);
|
|
@@ -17994,7 +17994,7 @@ function waitFor(callback, options = {}) {
|
|
|
17994
17994
|
});
|
|
17995
17995
|
}
|
|
17996
17996
|
function waitUntil(callback, options = {}) {
|
|
17997
|
-
const { setTimeout: setTimeout2, setInterval, clearTimeout, clearInterval } = getSafeTimers();
|
|
17997
|
+
const { setTimeout: setTimeout2, setInterval, clearTimeout: clearTimeout2, clearInterval } = getSafeTimers();
|
|
17998
17998
|
const { interval = 50, timeout = 1e3 } = typeof options === "number" ? { timeout: options } : options;
|
|
17999
17999
|
const STACK_TRACE_ERROR = new Error("STACK_TRACE_ERROR");
|
|
18000
18000
|
return new Promise((resolve4, reject) => {
|
|
@@ -18018,7 +18018,7 @@ function waitUntil(callback, options = {}) {
|
|
|
18018
18018
|
return;
|
|
18019
18019
|
}
|
|
18020
18020
|
if (timeoutId) {
|
|
18021
|
-
|
|
18021
|
+
clearTimeout2(timeoutId);
|
|
18022
18022
|
}
|
|
18023
18023
|
if (intervalId) {
|
|
18024
18024
|
clearInterval(intervalId);
|
|
@@ -18604,20 +18604,21 @@ var AgentTestRunner = class {
|
|
|
18604
18604
|
let messages = [];
|
|
18605
18605
|
let passed = true;
|
|
18606
18606
|
let error;
|
|
18607
|
+
let timeoutId;
|
|
18607
18608
|
try {
|
|
18608
|
-
const timeout = this.config.timeout
|
|
18609
|
+
const timeout = this.config.timeout ?? 3e4;
|
|
18609
18610
|
const timeoutPromise = new Promise((_, reject) => {
|
|
18610
|
-
setTimeout(() => reject(new Error("Agent test timeout")), timeout);
|
|
18611
|
+
timeoutId = setTimeout(() => reject(new Error("Agent test timeout")), timeout);
|
|
18611
18612
|
});
|
|
18612
18613
|
const runPromise = (async () => {
|
|
18613
18614
|
if (this.config.captureSteps) {
|
|
18614
18615
|
const result = await this.agent.invoke(input);
|
|
18615
18616
|
finalState = result;
|
|
18616
|
-
messages = result
|
|
18617
|
+
messages = extractMessages(result);
|
|
18617
18618
|
} else {
|
|
18618
18619
|
const result = await this.agent.invoke(input);
|
|
18619
18620
|
finalState = result;
|
|
18620
|
-
messages = result
|
|
18621
|
+
messages = extractMessages(result);
|
|
18621
18622
|
}
|
|
18622
18623
|
if (this.config.validateState && this.config.stateValidator) {
|
|
18623
18624
|
const isValid = await this.config.stateValidator(finalState);
|
|
@@ -18626,7 +18627,13 @@ var AgentTestRunner = class {
|
|
|
18626
18627
|
}
|
|
18627
18628
|
}
|
|
18628
18629
|
})();
|
|
18629
|
-
|
|
18630
|
+
try {
|
|
18631
|
+
await Promise.race([runPromise, timeoutPromise]);
|
|
18632
|
+
} finally {
|
|
18633
|
+
if (timeoutId !== void 0) {
|
|
18634
|
+
clearTimeout(timeoutId);
|
|
18635
|
+
}
|
|
18636
|
+
}
|
|
18630
18637
|
} catch (err) {
|
|
18631
18638
|
passed = false;
|
|
18632
18639
|
error = err;
|
|
@@ -18651,6 +18658,13 @@ var AgentTestRunner = class {
|
|
|
18651
18658
|
function createAgentTestRunner(agent, config2) {
|
|
18652
18659
|
return new AgentTestRunner(agent, config2);
|
|
18653
18660
|
}
|
|
18661
|
+
function extractMessages(state) {
|
|
18662
|
+
if (typeof state !== "object" || state === null) {
|
|
18663
|
+
return [];
|
|
18664
|
+
}
|
|
18665
|
+
const { messages } = state;
|
|
18666
|
+
return Array.isArray(messages) ? messages : [];
|
|
18667
|
+
}
|
|
18654
18668
|
var ConversationSimulator = class {
|
|
18655
18669
|
constructor(agent, config2 = {}) {
|
|
18656
18670
|
this.agent = agent;
|
|
@@ -18679,7 +18693,7 @@ var ConversationSimulator = class {
|
|
|
18679
18693
|
console.log(`User: ${input}`);
|
|
18680
18694
|
}
|
|
18681
18695
|
const result = await this.agent.invoke({ messages: messages$1 });
|
|
18682
|
-
const aiMessage = result
|
|
18696
|
+
const aiMessage = extractLatestMessage(result);
|
|
18683
18697
|
messages$1.push(aiMessage);
|
|
18684
18698
|
if (this.config.verbose) {
|
|
18685
18699
|
console.log(`AI: ${aiMessage.content}`);
|
|
@@ -18728,7 +18742,7 @@ var ConversationSimulator = class {
|
|
|
18728
18742
|
const userMessage = new messages.HumanMessage(input);
|
|
18729
18743
|
messages$1.push(userMessage);
|
|
18730
18744
|
const result = await this.agent.invoke({ messages: messages$1 });
|
|
18731
|
-
const aiMessage = result
|
|
18745
|
+
const aiMessage = extractLatestMessage(result);
|
|
18732
18746
|
messages$1.push(aiMessage);
|
|
18733
18747
|
turns++;
|
|
18734
18748
|
}
|
|
@@ -18751,6 +18765,14 @@ var ConversationSimulator = class {
|
|
|
18751
18765
|
function createConversationSimulator(agent, config2) {
|
|
18752
18766
|
return new ConversationSimulator(agent, config2);
|
|
18753
18767
|
}
|
|
18768
|
+
function extractLatestMessage(state) {
|
|
18769
|
+
const messages = extractMessages(state);
|
|
18770
|
+
const latestMessage = messages[messages.length - 1];
|
|
18771
|
+
if (!latestMessage) {
|
|
18772
|
+
throw new Error("Agent response did not include any messages");
|
|
18773
|
+
}
|
|
18774
|
+
return latestMessage;
|
|
18775
|
+
}
|
|
18754
18776
|
var ROOT_SNAPSHOT_DIFF_KEY = "$root";
|
|
18755
18777
|
function createSnapshotObject() {
|
|
18756
18778
|
return /* @__PURE__ */ Object.create(null);
|