@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 CHANGED
@@ -6,11 +6,11 @@
6
6
  [![TypeScript](https://img.shields.io/badge/TypeScript-5.9-blue)](https://www.typescriptlang.org/)
7
7
  [![License](https://img.shields.io/badge/license-MIT-green)](../../LICENSE)
8
8
 
9
- ## ๐ŸŽ‰ Status: Production Ready & Published
9
+ ## Status: Production Ready & Published
10
10
 
11
11
  **Complete testing toolkit** | **Full TypeScript support** | **Comprehensive documentation**
12
12
 
13
- ## ๐Ÿ“ฆ Installation
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
- ## โœจ Features
23
+ ## Features
24
24
 
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
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
- ## ๐Ÿ“– Documentation
371
+ ## Documentation
372
372
 
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)**
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
- ## ๐Ÿ”— Links
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
- ## ๐Ÿ“š Related Packages
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
- clearTimeout(timer);
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
- clearTimeout(intervalId);
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
- clearTimeout(intervalId);
15695
- clearTimeout(timeoutId);
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 clearTimeout(timerId) {
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
- clearTimeout(timeoutId);
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
- clearTimeout(timeoutId);
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 || 3e4;
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.messages || [];
18617
+ messages = extractMessages(result);
18617
18618
  } else {
18618
18619
  const result = await this.agent.invoke(input);
18619
18620
  finalState = result;
18620
- messages = result.messages || [];
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
- await Promise.race([runPromise, timeoutPromise]);
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.messages[result.messages.length - 1];
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.messages[result.messages.length - 1];
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);