import { AgentOutputEvent } from '@theokit/presenter'; export { AgentOutputEvent } from '@theokit/presenter'; import { WireChunk } from '@theokit/presenter/wire'; import { A as AgentDefinition } from './agent-compiler-BMpuJFAI.js'; import '@theokit/sdk'; import '@theokit/sdk/subagents-loader'; import '@theokit/sdk/errors'; import './types-DdltPCj2.js'; import 'zod'; import './setting-sources-gate-BJJiKq33.js'; import './hook-handlers-Cw2FsnE5.js'; /** * createMockAgentStream — test agents without an LLM API key. * * Returns an AsyncIterable that yields typed SSE events in sequence, * simulating an agent conversation. Use in vitest/jest to test agent * wiring, tool call handling, and UI rendering without real LLM costs. * * @example * ```ts * import { createMockAgentStream } from '@theokit/agents/testing' * * const stream = createMockAgentStream({ * responses: [ * { type: 'text', content: 'Here are your tasks:' }, * { type: 'tool_call', name: 'tasks.list', input: {}, output: '[{"id":1}]' }, * { type: 'text', content: 'You have 1 task.' }, * ], * }) * * const events = [] * for await (const event of stream('hello', 'session-1')) { * events.push(event) * } * // events: [run_started, text_delta, tool_call, tool_result, text_delta, done] * ``` */ interface MockResponse { type: 'text' | 'tool_call' | 'error'; content?: string; name?: string; input?: unknown; output?: string; message?: string; } interface MockAgentStreamOptions { agentName?: string; responses: MockResponse[]; /** Simulated cost in USD (default: 0). */ cost?: number; } interface MockStreamEvent { type: string; [key: string]: unknown; } declare function createMockAgentStream(opts: MockAgentStreamOptions): (_message: string, _sessionId: string) => AsyncIterable; /** * Typed builders for the chunks a test needs. * * Not a builder per member of the union — most of the thirteen never appear in a fixture, and * writing them all would be surface nobody asked for (YAGNI). These are the four a consumer's * fixtures actually contained. A test needing another writes the literal and passes it through * {@link createMockWireStream}, which validates all the same. */ declare const wireChunk: { /** A text fragment. `id` groups deltas into one message; a fixture rarely cares which. */ text(delta: string, id?: string): WireChunk; /** The error frame. This is the literal a consumer was writing with `as never` on the end. */ error(errorText: string): WireChunk; /** Stream end. */ finish(): WireChunk; /** Stream start. `messageId` is optional in the schema and omitted here for the same reason. */ start(messageId?: string): WireChunk; }; /** * A stream of wire chunks, for driving anything that consumes the wire. * * Async because every production consumer is: a mock that were synchronous would let a test pass * over code that never awaited, which is the class of bug a stream test exists to catch. */ declare function createMockWireStream(chunks: readonly WireChunk[]): AsyncGenerator; /** * A stream of presenter output events. * * Published alongside the wire one, deliberately: a test of a presenter surface should not have to * round-trip through the wire to produce a single event. Two vocabularies exist in production, and a * seam that admitted only one would push every test of the other back into casts. */ declare function createMockOutputEvents(events: readonly AgentOutputEvent[]): AsyncGenerator; /** * M85 — assert at the COMPILATION boundary, which is the one with the widest blast radius. * * The consumer documented this itself: in an agent product, the question that matters is not "did * the stream emit the right frames" but **"does this agent have the tools I think it has, and are * the dangerous ones gated?"**. A wrong answer there is a shell running unapproved, or a tool the * model cannot see and the operator believes it can. * * ## Why a helper and not `compileAgentDefinition` directly * * `CompiledAgentOptions` is the shape the SDK adapter consumes — thirty-odd fields, most of which a * test does not care about. Asserting against it directly is how 90 occurrences of `vi.mock` over * the framework barrel got written: the assertion was too awkward, so the test faked the module * instead, pinning itself to export NAMES and detecting no drift whatsoever. * * ## Capabilities are NOT here, and that is measured * * `capabilities` is a field of the DEFINITION, not of `CompiledAgentOptions` — the compiler resolves * it into tools rather than carrying it through. The DoD named it, and projecting it would have * meant reading the definition instead of the compilation, which is a different assertion wearing * this function's name: it would report what the author WROTE, not what the agent GOT. * * This projects the three facts a test actually asserts. It is a READ over the real compiler — never * a second one — so a compilation change surfaces here rather than in a fixture that agreed with an * older version of the truth. */ /** The facts a test asserts about a compiled agent. */ interface CompiledInspection { /** Tool names, sorted, as the model will see them. */ readonly toolNames: readonly string[]; /** Names of the tools that require human approval before running. */ readonly gatedToolNames: readonly string[]; /** The model the agent will use, when one is declared. */ readonly model: string | undefined; } /** * Inspect what a definition compiles to. * * ```ts * expect(inspectCompiled(myAgent).gatedToolNames).toContain('run_shell') * ``` * * Sorted output, because a list whose order changes with a decorator's position is a list nobody can * diff — and a test that pinned that order would fail on a reordering that changed nothing. */ declare function inspectCompiled(definition: AgentDefinition): CompiledInspection; export { type CompiledInspection, type MockAgentStreamOptions, type MockResponse, type MockStreamEvent, createMockAgentStream, createMockOutputEvents, createMockWireStream, inspectCompiled, wireChunk };