@b4run/testing 0.8.35 → 0.9.0

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/harness.d.ts CHANGED
@@ -1,10 +1,32 @@
1
1
  import { type B4ResumeEntry } from "@b4run/cli/runtime";
2
+ import type { B4ToolContext } from "@b4run/sdk";
2
3
  import type { FixtureSet, ScriptBuilder } from "./fixture-builder.js";
3
4
  import { type AgentRunResult } from "./run-result.js";
5
+ /** The turn a harness is about to drive; passed to a `middlewareContext` factory. */
6
+ export interface AgentHarnessRunInfo {
7
+ readonly threadId: string;
8
+ /** The user message for `run()`; absent for `resume()`. */
9
+ readonly input?: string;
10
+ /** The interrupt resolutions for `resume()`; absent for `run()`. */
11
+ readonly resume?: readonly B4ResumeEntry[];
12
+ }
13
+ /**
14
+ * The context a route's `middleware.ts` would have produced via `allow(context)`,
15
+ * either as a fixed value or as a factory evaluated once per `run()`/`resume()`.
16
+ * Tools read it as `ctx.middleware`.
17
+ */
18
+ export type AgentHarnessMiddlewareContext = NonNullable<B4ToolContext["middleware"]> | ((run: AgentHarnessRunInfo) => NonNullable<B4ToolContext["middleware"]> | undefined | Promise<NonNullable<B4ToolContext["middleware"]> | undefined>);
4
19
  export interface AgentHarnessOptions {
5
20
  readonly appRoot: string;
6
21
  readonly route: string;
7
22
  readonly fixtures?: FixtureSet;
23
+ /**
24
+ * The harness invokes the route's agent directly, so `middleware.ts` never
25
+ * runs. Supply the context it would have returned so tools that read
26
+ * `ctx.middleware` (a session, a database handle, a per-request snapshot)
27
+ * behave as they do behind the server. A function is evaluated per turn.
28
+ */
29
+ readonly middlewareContext?: AgentHarnessMiddlewareContext;
8
30
  /**
9
31
  * When true, proxy all LLM requests through a real upstream (OPENAI_API_KEY
10
32
  * must be set). Requires OPENAI_API_KEY to be present in the environment.
@@ -1 +1 @@
1
- {"version":3,"file":"harness.d.ts","sourceRoot":"","sources":["../src/harness.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,KAAK,aAAa,EASnB,MAAM,oBAAoB,CAAA;AAI3B,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAErE,OAAO,EAAE,KAAK,cAAc,EAAoB,MAAM,iBAAiB,CAAA;AA0BvE,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,QAAQ,CAAC,EAAE,UAAU,CAAA;IAC9B;;;OAGG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAA;IACvB,uFAAuF;IACvF,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAA;IACzB,yFAAyF;IACzF,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAA;CACjC;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,GAAG,CAAC,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,UAAU,GAAG,aAAa,CAAA;KAAE,GAAG,OAAO,CAAC,cAAc,CAAC,CAAA;IAC5F,MAAM,CAAC,IAAI,EAAE;QACX,MAAM,EAAE,SAAS,aAAa,EAAE,CAAA;QAChC,QAAQ,CAAC,EAAE,UAAU,GAAG,aAAa,CAAA;KACtC,GAAG,OAAO,CAAC,cAAc,CAAC,CAAA;IAC3B,KAAK,IAAI,IAAI,CAAA;IACb,KAAK,CAAC,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,iBAAiB,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACxE,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACtC,4FAA4F;IAC5F,mBAAmB,IAAI,UAAU,CAAA;CAClC;AAED,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,YAAY,CAAC,CAoM5F"}
1
+ {"version":3,"file":"harness.d.ts","sourceRoot":"","sources":["../src/harness.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,KAAK,aAAa,EASnB,MAAM,oBAAoB,CAAA;AAG3B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAE/C,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAErE,OAAO,EAAE,KAAK,cAAc,EAAoB,MAAM,iBAAiB,CAAA;AA0BvE,qFAAqF;AACrF,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,2DAA2D;IAC3D,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;IACvB,oEAAoE;IACpE,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,aAAa,EAAE,CAAA;CAC3C;AAED;;;;GAIG;AACH,MAAM,MAAM,6BAA6B,GACrC,WAAW,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC,GACxC,CAAC,CACC,GAAG,EAAE,mBAAmB,KAEtB,WAAW,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC,GACxC,SAAS,GACT,OAAO,CAAC,WAAW,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAA;AAEtE,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,QAAQ,CAAC,EAAE,UAAU,CAAA;IAC9B;;;;;OAKG;IACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,6BAA6B,CAAA;IAC1D;;;OAGG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAA;IACvB,uFAAuF;IACvF,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAA;IACzB,yFAAyF;IACzF,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAA;CACjC;AAYD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,GAAG,CAAC,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,UAAU,GAAG,aAAa,CAAA;KAAE,GAAG,OAAO,CAAC,cAAc,CAAC,CAAA;IAC5F,MAAM,CAAC,IAAI,EAAE;QACX,MAAM,EAAE,SAAS,aAAa,EAAE,CAAA;QAChC,QAAQ,CAAC,EAAE,UAAU,GAAG,aAAa,CAAA;KACtC,GAAG,OAAO,CAAC,cAAc,CAAC,CAAA;IAC3B,KAAK,IAAI,IAAI,CAAA;IACb,KAAK,CAAC,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,iBAAiB,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACxE,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACtC,4FAA4F;IAC5F,mBAAmB,IAAI,UAAU,CAAA;CAClC;AAED,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,YAAY,CAAC,CA0M5F"}
package/dist/harness.js CHANGED
@@ -26,6 +26,14 @@ function systemPromptFromRequests(reqs) {
26
26
  }
27
27
  return "";
28
28
  }
29
+ /** Evaluate a `middlewareContext` option (value or per-turn factory) for one turn. */
30
+ async function resolveMiddlewareContext(option, run) {
31
+ if (option === undefined)
32
+ return undefined;
33
+ if (typeof option === "function")
34
+ return await option(run);
35
+ return option;
36
+ }
29
37
  export async function createAgentHarness(options) {
30
38
  const live = options.live ?? false;
31
39
  const record = options.record ?? false;
@@ -119,6 +127,11 @@ export async function createAgentHarness(options) {
119
127
  }
120
128
  resolvedResume = resolution.resume;
121
129
  }
130
+ const middlewareContext = await resolveMiddlewareContext(options.middlewareContext, {
131
+ threadId,
132
+ ...(driveOpts.input !== undefined ? { input: driveOpts.input } : {}),
133
+ ...(driveOpts.resume !== undefined ? { resume: driveOpts.resume } : {}),
134
+ });
122
135
  const streamArgs = {
123
136
  appRoot: options.appRoot,
124
137
  input: driveOpts.input !== undefined
@@ -130,6 +143,7 @@ export async function createAgentHarness(options) {
130
143
  threadId,
131
144
  ...(sandboxManager ? { sandboxManager } : {}),
132
145
  ...(resolvedResume ? { resume: resolvedResume } : {}),
146
+ ...(middlewareContext !== undefined ? { middlewareContext } : {}),
133
147
  };
134
148
  const stream = streamResolvedRoute(streamArgs);
135
149
  const result = await collectRunResult(stream, threadId);
package/dist/index.d.ts CHANGED
@@ -3,7 +3,7 @@ export { runCheckpointerConformance } from "./checkpointer-conformance.js";
3
3
  export { fakeEmbedder } from "./fake-embedder.js";
4
4
  export { type AimockFixture, type AimockResponse, type AimockToolCall, type FixtureSet, type ScriptBuilder, script, } from "./fixture-builder.js";
5
5
  export { loadFixtures, writeFixtures } from "./fixture-file.js";
6
- export { type AgentHarness, type AgentHarnessOptions, createAgentHarness } from "./harness.js";
6
+ export { type AgentHarness, type AgentHarnessMiddlewareContext, type AgentHarnessOptions, type AgentHarnessRunInfo, createAgentHarness, } from "./harness.js";
7
7
  export { type AgentProtocolInjector, createAgentProtocolInjector, type InjectResult, } from "./http-inject.js";
8
8
  export { expectFinalMessage, expectInterrupt, expectNoInterrupt, expectNoToolErrors, expectOffloaded, expectPlan, expectState, expectStreamedTokens, expectSubagent, expectSystemPrompt, expectToolCalled, expectToolSequence, type InterruptInfo, type SubagentEvent, type SubagentRun, type Todo, } from "./matchers.js";
9
9
  export { seedMemory } from "./memory.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAC9D,OAAO,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAA;AAC1E,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACjD,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,UAAU,EACf,KAAK,aAAa,EAClB,MAAM,GACP,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAC/D,OAAO,EAAE,KAAK,YAAY,EAAE,KAAK,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAA;AAC9F,OAAO,EACL,KAAK,qBAAqB,EAC1B,2BAA2B,EAC3B,KAAK,YAAY,GAClB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,eAAe,EACf,UAAU,EACV,WAAW,EACX,oBAAoB,EACpB,cAAc,EACd,kBAAkB,EAClB,gBAAgB,EAChB,kBAAkB,EAClB,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,IAAI,GACV,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAA;AACnE,OAAO,EACL,uBAAuB,EACvB,KAAK,iBAAiB,GACvB,MAAM,yBAAyB,CAAA;AAChC,OAAO,EACL,KAAK,oBAAoB,EACzB,8BAA8B,GAC/B,MAAM,8BAA8B,CAAA;AACrC,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACxD,OAAO,EACL,KAAK,cAAc,EACnB,gBAAgB,EAChB,iBAAiB,EACjB,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,GACxB,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAAE,mBAAmB,EAAE,KAAK,aAAa,EAAE,MAAM,iBAAiB,CAAA;AACzE,OAAO,EACL,yBAAyB,EACzB,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,GACzB,MAAM,4BAA4B,CAAA;AACnC,OAAO,EAAE,0BAA0B,EAAE,MAAM,0BAA0B,CAAA;AACrE,OAAO,EACL,iBAAiB,EACjB,KAAK,WAAW,EAChB,KAAK,kBAAkB,GACxB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EACL,sBAAsB,EACtB,KAAK,gBAAgB,EACrB,KAAK,uBAAuB,GAC7B,MAAM,wBAAwB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAC9D,OAAO,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAA;AAC1E,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACjD,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,UAAU,EACf,KAAK,aAAa,EAClB,MAAM,GACP,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAC/D,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,6BAA6B,EAClC,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACxB,kBAAkB,GACnB,MAAM,cAAc,CAAA;AACrB,OAAO,EACL,KAAK,qBAAqB,EAC1B,2BAA2B,EAC3B,KAAK,YAAY,GAClB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,eAAe,EACf,UAAU,EACV,WAAW,EACX,oBAAoB,EACpB,cAAc,EACd,kBAAkB,EAClB,gBAAgB,EAChB,kBAAkB,EAClB,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,IAAI,GACV,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAA;AACnE,OAAO,EACL,uBAAuB,EACvB,KAAK,iBAAiB,GACvB,MAAM,yBAAyB,CAAA;AAChC,OAAO,EACL,KAAK,oBAAoB,EACzB,8BAA8B,GAC/B,MAAM,8BAA8B,CAAA;AACrC,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACxD,OAAO,EACL,KAAK,cAAc,EACnB,gBAAgB,EAChB,iBAAiB,EACjB,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,GACxB,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAAE,mBAAmB,EAAE,KAAK,aAAa,EAAE,MAAM,iBAAiB,CAAA;AACzE,OAAO,EACL,yBAAyB,EACzB,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,GACzB,MAAM,4BAA4B,CAAA;AACnC,OAAO,EAAE,0BAA0B,EAAE,MAAM,0BAA0B,CAAA;AACrE,OAAO,EACL,iBAAiB,EACjB,KAAK,WAAW,EAChB,KAAK,kBAAkB,GACxB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EACL,sBAAsB,EACtB,KAAK,gBAAgB,EACrB,KAAK,uBAAuB,GAC7B,MAAM,wBAAwB,CAAA"}
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@ export { runCheckpointerConformance } from "./checkpointer-conformance.js";
3
3
  export { fakeEmbedder } from "./fake-embedder.js";
4
4
  export { script, } from "./fixture-builder.js";
5
5
  export { loadFixtures, writeFixtures } from "./fixture-file.js";
6
- export { createAgentHarness } from "./harness.js";
6
+ export { createAgentHarness, } from "./harness.js";
7
7
  export { createAgentProtocolInjector, } from "./http-inject.js";
8
8
  export { expectFinalMessage, expectInterrupt, expectNoInterrupt, expectNoToolErrors, expectOffloaded, expectPlan, expectState, expectStreamedTokens, expectSubagent, expectSystemPrompt, expectToolCalled, expectToolSequence, } from "./matchers.js";
9
9
  export { seedMemory } from "./memory.js";
@@ -20,6 +20,19 @@ export interface ObservedToolResult {
20
20
  * - Live LangChain instance format: `{ type:"tool", name, status, content, ... }`
21
21
  */
22
22
  export declare function deriveToolResults(messages: ReadonlyArray<Record<string, unknown>>): ObservedToolResult[];
23
+ /**
24
+ * Derive one observed tool result from a live `tool_result` stream chunk.
25
+ *
26
+ * The chunk's `output` is whatever the tool execution produced: a ToolMessage
27
+ * (live instance or serialized) for string-returning tools — including the
28
+ * `status: "error"` ToolMessage the adapter emits when a tool throws — a
29
+ * Command whose `update.messages` carries that ToolMessage, or a plain value
30
+ * for legacy producers. A plain value has no status and is never an error.
31
+ */
32
+ export declare function deriveToolResultFromChunk(chunk: {
33
+ readonly name: string;
34
+ readonly output: unknown;
35
+ }): ObservedToolResult;
23
36
  export interface CommandInterruptDetail {
24
37
  readonly command: string;
25
38
  readonly suggestedPattern: string;
@@ -1 +1 @@
1
- {"version":3,"file":"run-result.d.ts","sourceRoot":"","sources":["../src/run-result.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"run-result.d.ts","sourceRoot":"","sources":["../src/run-result.ts"],"names":[],"mappings":"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"}
@@ -36,6 +36,34 @@ export function deriveToolResults(messages) {
36
36
  }
37
37
  return results;
38
38
  }
39
+ /**
40
+ * Derive one observed tool result from a live `tool_result` stream chunk.
41
+ *
42
+ * The chunk's `output` is whatever the tool execution produced: a ToolMessage
43
+ * (live instance or serialized) for string-returning tools — including the
44
+ * `status: "error"` ToolMessage the adapter emits when a tool throws — a
45
+ * Command whose `update.messages` carries that ToolMessage, or a plain value
46
+ * for legacy producers. A plain value has no status and is never an error.
47
+ */
48
+ export function deriveToolResultFromChunk(chunk) {
49
+ const output = chunk.output;
50
+ if (isRecord(output)) {
51
+ const direct = deriveToolResults([output]);
52
+ if (direct.length === 1 && direct[0])
53
+ return withName(direct[0], chunk.name);
54
+ const update = output.update;
55
+ if (isRecord(update) && Array.isArray(update.messages)) {
56
+ const nested = deriveToolResults(update.messages.filter((m) => isRecord(m)));
57
+ const last = nested[nested.length - 1];
58
+ if (last)
59
+ return withName(last, chunk.name);
60
+ }
61
+ }
62
+ return { name: chunk.name, content: output, isError: false };
63
+ }
64
+ function withName(result, fallback) {
65
+ return result.name === "" ? { ...result, name: fallback } : result;
66
+ }
39
67
  function finalMessageFrom(state) {
40
68
  const messages = Array.isArray(state.messages)
41
69
  ? state.messages
@@ -162,6 +190,7 @@ function parseInterruptInfo(value) {
162
190
  export async function collectRunResult(stream, threadId) {
163
191
  const tokens = [];
164
192
  const toolCalls = [];
193
+ const streamedToolResults = [];
165
194
  let state = {};
166
195
  const interrupts = [];
167
196
  const planUpdates = [];
@@ -197,6 +226,11 @@ export async function collectRunResult(stream, threadId) {
197
226
  toolCalls.push(entry);
198
227
  break;
199
228
  }
229
+ case "tool_result": {
230
+ const c = chunk;
231
+ streamedToolResults.push(deriveToolResultFromChunk(c));
232
+ break;
233
+ }
200
234
  case "done": {
201
235
  const out = chunk.output;
202
236
  if (out && typeof out === "object")
@@ -273,7 +307,11 @@ export async function collectRunResult(stream, threadId) {
273
307
  threadId,
274
308
  tokens,
275
309
  toolCalls,
276
- toolResults: deriveToolResults(finalMessages),
310
+ // Prefer what the run streamed: a thrown tool resolves on the wire as a
311
+ // `status: "error"` ToolMessage, so `isError` never depends on the final
312
+ // message list. Streams that carried no tool_result chunks (fixtures,
313
+ // legacy producers) still derive from the final messages.
314
+ toolResults: streamedToolResults.length > 0 ? streamedToolResults : deriveToolResults(finalMessages),
277
315
  state,
278
316
  messages: finalMessages,
279
317
  finalMessage: finalMessageFrom(state),