@directive-run/ai 1.12.0 → 1.14.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/anthropic.cjs +1 -1
- package/dist/anthropic.d.cts +1 -1
- package/dist/anthropic.d.ts +1 -1
- package/dist/anthropic.js +1 -1
- package/dist/anthropic.js.map +1 -1
- package/dist/{chunk-XV2QSBBE.cjs → chunk-2TD4ZSGZ.cjs} +7 -7
- package/dist/{chunk-XV2QSBBE.cjs.map → chunk-2TD4ZSGZ.cjs.map} +1 -1
- package/dist/chunk-3WO4MWJM.cjs +3 -0
- package/dist/chunk-3WO4MWJM.cjs.map +1 -0
- package/dist/chunk-5JQ2A3JK.js +2 -0
- package/dist/chunk-5JQ2A3JK.js.map +1 -0
- package/dist/chunk-A22KLB23.cjs +67 -0
- package/dist/chunk-A22KLB23.cjs.map +1 -0
- package/dist/chunk-A5K77UDX.cjs +4 -0
- package/dist/chunk-A5K77UDX.cjs.map +1 -0
- package/dist/chunk-DN5NAJM6.js +6 -0
- package/dist/chunk-DN5NAJM6.js.map +1 -0
- package/dist/chunk-FABDFT74.cjs +6 -0
- package/dist/chunk-FABDFT74.cjs.map +1 -0
- package/dist/chunk-FBT73WFY.js +2 -0
- package/dist/chunk-FBT73WFY.js.map +1 -0
- package/dist/chunk-FFRWQNK7.cjs +7 -0
- package/dist/chunk-FFRWQNK7.cjs.map +1 -0
- package/dist/chunk-IR3IHBVQ.cjs +2 -0
- package/dist/chunk-IR3IHBVQ.cjs.map +1 -0
- package/dist/chunk-IUGSMTBE.js +16 -0
- package/dist/{chunk-Q3PQLWBR.js.map → chunk-IUGSMTBE.js.map} +1 -1
- package/dist/chunk-J2Q5KKPN.js +37 -0
- package/dist/chunk-J2Q5KKPN.js.map +1 -0
- package/dist/chunk-K64WKZ22.cjs +2 -0
- package/dist/chunk-K64WKZ22.cjs.map +1 -0
- package/dist/chunk-LKY4K5TV.cjs +11 -0
- package/dist/chunk-LKY4K5TV.cjs.map +1 -0
- package/dist/chunk-LXUMJKGJ.js +67 -0
- package/dist/chunk-LXUMJKGJ.js.map +1 -0
- package/dist/chunk-NNAQ4ZH2.js +11 -0
- package/dist/chunk-NNAQ4ZH2.js.map +1 -0
- package/dist/chunk-PD772MSE.cjs +30 -0
- package/dist/chunk-PD772MSE.cjs.map +1 -0
- package/dist/chunk-POBEEJR6.js +30 -0
- package/dist/chunk-POBEEJR6.js.map +1 -0
- package/dist/chunk-QRXWLD6H.js +4 -0
- package/dist/chunk-QRXWLD6H.js.map +1 -0
- package/dist/chunk-UR4ZGO7V.js +7 -0
- package/dist/chunk-UR4ZGO7V.js.map +1 -0
- package/dist/chunk-UR5BMWEN.js +2 -0
- package/dist/chunk-UR5BMWEN.js.map +1 -0
- package/dist/chunk-WOFIBIPW.cjs +2 -0
- package/dist/chunk-WOFIBIPW.cjs.map +1 -0
- package/dist/chunk-XN5LUOVS.cjs +37 -0
- package/dist/chunk-XN5LUOVS.cjs.map +1 -0
- package/dist/chunk-ZFLHWJ56.js +3 -0
- package/dist/chunk-ZFLHWJ56.js.map +1 -0
- package/dist/debug-timeline-DpnRMnLU.d.cts +87 -0
- package/dist/debug-timeline-L13P-U2I.d.ts +87 -0
- package/dist/devtools.cjs +2 -0
- package/dist/devtools.cjs.map +1 -0
- package/dist/devtools.d.cts +354 -0
- package/dist/devtools.d.ts +354 -0
- package/dist/devtools.js +2 -0
- package/dist/devtools.js.map +1 -0
- package/dist/evals.cjs +2 -0
- package/dist/evals.cjs.map +1 -0
- package/dist/evals.d.cts +361 -0
- package/dist/evals.d.ts +361 -0
- package/dist/evals.js +2 -0
- package/dist/evals.js.map +1 -0
- package/dist/gemini.cjs +1 -1
- package/dist/gemini.d.cts +1 -1
- package/dist/gemini.d.ts +1 -1
- package/dist/gemini.js +1 -1
- package/dist/gemini.js.map +1 -1
- package/dist/guardrails.cjs +2 -0
- package/dist/guardrails.cjs.map +1 -0
- package/dist/guardrails.d.cts +618 -0
- package/dist/guardrails.d.ts +618 -0
- package/dist/guardrails.js +2 -0
- package/dist/guardrails.js.map +1 -0
- package/dist/health-monitor-C6xoXrQz.d.cts +55 -0
- package/dist/health-monitor-qL9RNMH3.d.ts +55 -0
- package/dist/index.cjs +21 -99
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1202 -4542
- package/dist/index.d.ts +1202 -4542
- package/dist/index.js +21 -99
- package/dist/index.js.map +1 -1
- package/dist/mcp.cjs +2 -0
- package/dist/mcp.cjs.map +1 -0
- package/dist/mcp.d.cts +450 -0
- package/dist/mcp.d.ts +450 -0
- package/dist/mcp.js +2 -0
- package/dist/mcp.js.map +1 -0
- package/dist/multi-agent-orchestrator-QWWQKKGX.js +2 -0
- package/dist/{multi-agent-orchestrator-4PXNYRHB.js.map → multi-agent-orchestrator-QWWQKKGX.js.map} +1 -1
- package/dist/multi-agent-orchestrator-Y5U4JCFO.cjs +2 -0
- package/dist/{multi-agent-orchestrator-KFGTEGE5.cjs.map → multi-agent-orchestrator-Y5U4JCFO.cjs.map} +1 -1
- package/dist/multi-agent.cjs +2 -0
- package/dist/multi-agent.cjs.map +1 -0
- package/dist/multi-agent.d.cts +1429 -0
- package/dist/multi-agent.d.ts +1429 -0
- package/dist/multi-agent.js +2 -0
- package/dist/multi-agent.js.map +1 -0
- package/dist/ollama.cjs +1 -1
- package/dist/ollama.d.cts +1 -1
- package/dist/ollama.d.ts +1 -1
- package/dist/ollama.js +2 -2
- package/dist/ollama.js.map +1 -1
- package/dist/openai.cjs +1 -1
- package/dist/openai.d.cts +2 -2
- package/dist/openai.d.ts +2 -2
- package/dist/openai.js +1 -1
- package/dist/openai.js.map +1 -1
- package/dist/{orchestrator-types-CTfIKk0W.d.ts → orchestrator-types-DGBhL6mc.d.ts} +5 -138
- package/dist/{orchestrator-types-Bh8r3_Sq.d.cts → orchestrator-types-DeIMRLR7.d.cts} +5 -138
- package/dist/predicate.cjs +2 -0
- package/dist/predicate.cjs.map +1 -0
- package/dist/predicate.d.cts +371 -0
- package/dist/predicate.d.ts +371 -0
- package/dist/predicate.js +2 -0
- package/dist/predicate.js.map +1 -0
- package/dist/{semantic-cache-nBpQqILc.d.cts → semantic-cache-DM7ev7NQ.d.cts} +1 -1
- package/dist/{semantic-cache-nBpQqILc.d.ts → semantic-cache-DM7ev7NQ.d.ts} +1 -1
- package/dist/testing.cjs +1 -1
- package/dist/testing.cjs.map +1 -1
- package/dist/testing.d.cts +4 -2
- package/dist/testing.d.ts +4 -2
- package/dist/testing.js +1 -1
- package/dist/testing.js.map +1 -1
- package/dist/{types-CRmwFnVk.d.cts → types-DJ09LjZX.d.cts} +1 -1
- package/dist/{types-CRmwFnVk.d.ts → types-DJ09LjZX.d.ts} +1 -1
- package/package.json +32 -2
- package/dist/chunk-Q3PQLWBR.js +0 -16
- package/dist/chunk-RW4R3O5P.js +0 -72
- package/dist/chunk-RW4R3O5P.js.map +0 -1
- package/dist/chunk-W6MVJKWN.cjs +0 -3
- package/dist/chunk-W6MVJKWN.cjs.map +0 -1
- package/dist/chunk-W6WZBQER.js +0 -3
- package/dist/chunk-W6WZBQER.js.map +0 -1
- package/dist/chunk-X3VQ5F7D.cjs +0 -72
- package/dist/chunk-X3VQ5F7D.cjs.map +0 -1
- package/dist/multi-agent-orchestrator-4PXNYRHB.js +0 -2
- package/dist/multi-agent-orchestrator-KFGTEGE5.cjs +0 -2
package/dist/testing.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/testing.ts"],"names":["createMockAgentRunner","options","defaultResponse","responses","recordCalls","onRun","calls","responseMap","currentDefault","agent","input","runOptions","config","generated","resolve","messages","message","toolCalls","toolCall","name","testGuardrail","guardrail","testInput","context","data","fullContext","start","result","duration","expectedReason","expected","testGuardrailBatch","testCases","results","failures","i","testCase","createApprovalSimulator","autoApprove","autoReject","delay","recordRequests","requests","pendingRequests","requestWaiters","request","waiter","requestId","pending","reason","r","predicate","timeoutMs","existing","reject","entry","req","timeout","idx","createTestOrchestrator","mockResponses","defaultMockResponse","orchestratorOptions","mockRunner","approvalSimulator","orchestrator","createAgentOrchestrator","testOrchestrator","createConstraintRecorder","snapshots","assertOrchestratorState","state","min","max","exact","len","createTimeController","startTime","currentTime","initial","ms","time","createTestMultiAgentOrchestrator","mockTaskConfigs","existingTasks","taskId","createMockTask","responsesByName","agentId","registration","createMultiAgentOrchestrator","assertMultiAgentState","expectedStatus","allStates","total","sum","s","pendingCount","output","_input","signal","timer","createTestDag","nodes","merge","dag","assertDagExecution","nodeId","actual","expectedOutput","createTestTimeline","events","timeline","createDebugTimeline","event","assertTimelineEvents","type","e","expectedCount","createFailingRunner","error","callCount","failAfter","_agent","_runOptions","assertRerouted","assertAgentHealth","monitor","metrics","createTestCheckpointStore","maxCheckpoints","inner","InMemoryCheckpointStore","saved","checkpoint","id","assertCheckpoint","createBreakpointSimulator","hits","orchestratorRef","attached","doResolve","orch","assertBreakpointHit","h","types","agents","createMockSchema","validate","description","collectMultiplexedStream","stream","chunks","chunk","assertMultiplexedStream","seenAgents","c","createTestReflectionEvaluator","passAfter","feedback","score","_output","_context","passed","assertScratchpadState","scratchpad","all","key","expectedValue","assertDerivedValues","derived","sortedStringify","v"],"mappings":"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","file":"testing.cjs","sourcesContent":["/**\n * Directive AI Testing Utilities\n *\n * Provides testing helpers for:\n * - Mock agent runners with configurable responses\n * - Guardrail testing with assertions\n * - Approval workflow simulation\n * - Snapshot testing for constraint evaluation\n *\n * @example\n * ```typescript\n * import { createMockAgentRunner, testGuardrail, createApprovalSimulator } from '@directive-run/ai/testing';\n *\n * describe('MyOrchestrator', () => {\n * it('should block PII in input', async () => {\n * const result = await testGuardrail(createPIIGuardrail(), {\n * input: 'My SSN is 123-45-6789',\n * });\n * expect(result.passed).toBe(false);\n * expect(result.reason).toContain('PII');\n * });\n * });\n * ```\n */\n\nimport {\n type AgentOrchestrator,\n type OrchestratorOptions,\n createAgentOrchestrator,\n} from \"./agent-orchestrator.js\";\nimport type {\n BreakpointModifications,\n BreakpointRequest,\n} from \"./breakpoints.js\";\nimport {\n type Checkpoint,\n type CheckpointStore,\n InMemoryCheckpointStore,\n} from \"./checkpoint.js\";\nimport {\n type MultiAgentOrchestrator,\n type MultiAgentOrchestratorOptions,\n type TaskRegistration,\n createMultiAgentOrchestrator,\n} from \"./multi-agent-orchestrator.js\";\nimport type { MultiplexedStreamChunk } from \"./streaming.js\";\nimport type {\n AgentLike,\n AgentRunner,\n ApprovalRequest,\n GuardrailContext,\n GuardrailFn,\n GuardrailResult,\n InputGuardrailData,\n Message,\n OutputGuardrailData,\n RunOptions,\n RunResult,\n ToolCall,\n ToolCallGuardrailData,\n} from \"./types.js\";\n\n// ============================================================================\n// Mock Agent Runner\n// ============================================================================\n\n/** Configuration for mock agent responses */\nexport interface MockAgentConfig<T = unknown> {\n /** Final output to return */\n output: T;\n /** Messages to emit during run */\n messages?: Message[];\n /** Tool calls to emit during run */\n toolCalls?: ToolCall[];\n /** Total tokens to report */\n totalTokens?: number;\n /** Delay before responding (ms) */\n delay?: number;\n /** Error to throw instead of returning */\n error?: Error;\n /** Function to generate dynamic responses */\n generate?: (input: string, agent: AgentLike) => Partial<MockAgentConfig<T>>;\n}\n\n/** Mock agent runner options */\nexport interface MockAgentRunnerOptions {\n /** Default response for unmatched agents */\n defaultResponse?: MockAgentConfig;\n /** Responses keyed by agent name */\n responses?: Record<string, MockAgentConfig>;\n /** Record all calls for assertions */\n recordCalls?: boolean;\n /** Callback for each run */\n onRun?: (agent: AgentLike, input: string) => void;\n}\n\n/** Recorded call for assertions */\nexport interface RecordedCall {\n agent: AgentLike;\n input: string;\n options?: RunOptions;\n timestamp: number;\n}\n\n/** Mock agent runner instance */\nexport interface MockAgentRunner {\n /** The run function to pass to orchestrator */\n run: AgentRunner;\n /** Get all recorded calls */\n getCalls(): RecordedCall[];\n /** Get calls for a specific agent */\n getCallsFor(agentName: string): RecordedCall[];\n /** Clear recorded calls */\n clearCalls(): void;\n /** Set response for an agent */\n setResponse<T>(agentName: string, config: MockAgentConfig<T>): void;\n /** Set default response */\n setDefaultResponse<T>(config: MockAgentConfig<T>): void;\n}\n\n/**\n * Create a mock agent runner for testing.\n *\n * @example\n * ```typescript\n * const mock = createMockAgentRunner({\n * responses: {\n * 'my-agent': {\n * output: 'Hello, world!',\n * totalTokens: 100,\n * },\n * },\n * });\n *\n * const orchestrator = createAgentOrchestrator({ runner: mock.run });\n * const result = await orchestrator.run(myAgent, 'Hi');\n *\n * expect(result.output).toBe('Hello, world!');\n * expect(mock.getCalls()).toHaveLength(1);\n * ```\n */\nexport function createMockAgentRunner(\n options: MockAgentRunnerOptions = {},\n): MockAgentRunner {\n const {\n defaultResponse = { output: \"mock response\", totalTokens: 10 },\n responses = {},\n recordCalls = true,\n onRun,\n } = options;\n\n const calls: RecordedCall[] = [];\n const responseMap = new Map<string, MockAgentConfig>(\n Object.entries(responses),\n );\n let currentDefault = defaultResponse;\n\n const run: AgentRunner = async <T>(\n agent: AgentLike,\n input: string,\n runOptions?: RunOptions,\n ): Promise<RunResult<T>> => {\n onRun?.(agent, input);\n\n if (recordCalls) {\n calls.push({\n agent,\n input,\n options: runOptions,\n timestamp: Date.now(),\n });\n }\n\n // Get config for this agent\n let config = responseMap.get(agent.name) ?? currentDefault;\n\n // Apply dynamic generation if present\n if (config.generate) {\n const generated = config.generate(input, agent);\n config = { ...config, ...generated };\n }\n\n // Handle error case\n if (config.error) {\n throw config.error;\n }\n\n // Apply delay\n if (config.delay && config.delay > 0) {\n await new Promise((resolve) => setTimeout(resolve, config.delay));\n }\n\n // Emit messages\n const messages = config.messages ?? [];\n for (const message of messages) {\n runOptions?.onMessage?.(message);\n }\n\n // Emit tool calls\n const toolCalls = config.toolCalls ?? [];\n for (const toolCall of toolCalls) {\n runOptions?.onToolCall?.(toolCall);\n }\n\n return {\n output: config.output as T,\n messages,\n toolCalls,\n totalTokens: config.totalTokens ?? 10,\n };\n };\n\n return {\n run,\n getCalls: () => [...calls],\n getCallsFor: (name) => calls.filter((c) => c.agent.name === name),\n clearCalls: () => (calls.length = 0),\n setResponse: (name, config) => responseMap.set(name, config),\n setDefaultResponse: (config) => (currentDefault = config),\n };\n}\n\n// ============================================================================\n// Guardrail Testing\n// ============================================================================\n\n/** Test input for guardrail testing */\nexport type GuardrailTestInput<T> = T extends InputGuardrailData\n ? { input: string; agentName?: string }\n : T extends OutputGuardrailData\n ? {\n output: unknown;\n agentName?: string;\n input?: string;\n messages?: Message[];\n }\n : T extends ToolCallGuardrailData\n ? { toolCall: ToolCall; agentName?: string; input?: string }\n : Partial<T>;\n\n/** Extended guardrail result with test assertions */\nexport interface GuardrailTestResult extends GuardrailResult {\n /** Time taken to evaluate (ms) */\n duration: number;\n /** The data that was tested */\n testedData: unknown;\n /** Assert that the guardrail passed */\n assertPassed(): void;\n /** Assert that the guardrail failed */\n assertFailed(expectedReason?: string | RegExp): void;\n /** Assert that transformation occurred */\n assertTransformed(expected?: unknown): void;\n}\n\n/**\n * Test a guardrail with assertions.\n *\n * @example\n * ```typescript\n * // Test PII detection\n * const result = await testGuardrail(createPIIGuardrail(), {\n * input: 'My SSN is 123-45-6789',\n * });\n * result.assertFailed(/PII/);\n *\n * // Test input transformation\n * const redactResult = await testGuardrail(createPIIGuardrail({ redact: true }), {\n * input: 'My SSN is 123-45-6789',\n * });\n * redactResult.assertPassed();\n * redactResult.assertTransformed();\n * ```\n */\nexport async function testGuardrail<T>(\n guardrail: GuardrailFn<T>,\n testInput: GuardrailTestInput<T>,\n context?: Partial<GuardrailContext>,\n): Promise<GuardrailTestResult> {\n // Build full data object\n const data = {\n agentName: \"test-agent\",\n input: \"\",\n ...testInput,\n } as unknown as T;\n\n // Build context\n const fullContext: GuardrailContext = {\n agentName: (testInput as { agentName?: string }).agentName ?? \"test-agent\",\n input: (testInput as { input?: string }).input ?? \"\",\n facts: context?.facts ?? {},\n ...context,\n };\n\n const start = Date.now();\n const result = await guardrail(data, fullContext);\n const duration = Date.now() - start;\n\n return {\n ...result,\n duration,\n testedData: data,\n assertPassed() {\n if (!result.passed) {\n throw new Error(\n `Expected guardrail to pass, but it failed: ${result.reason}`,\n );\n }\n },\n assertFailed(expectedReason) {\n if (result.passed) {\n throw new Error(\"Expected guardrail to fail, but it passed\");\n }\n if (expectedReason !== undefined) {\n if (\n typeof expectedReason === \"string\" &&\n !result.reason?.includes(expectedReason)\n ) {\n throw new Error(\n `Expected failure reason to include \"${expectedReason}\", got: ${result.reason}`,\n );\n }\n if (\n expectedReason instanceof RegExp &&\n !expectedReason.test(result.reason ?? \"\")\n ) {\n throw new Error(\n `Expected failure reason to match ${expectedReason}, got: ${result.reason}`,\n );\n }\n }\n },\n assertTransformed(expected) {\n if (result.transformed === undefined) {\n throw new Error(\n \"Expected guardrail to transform input, but no transformation occurred\",\n );\n }\n if (expected !== undefined && result.transformed !== expected) {\n throw new Error(\n `Expected transformation to be ${JSON.stringify(expected)}, got: ${JSON.stringify(result.transformed)}`,\n );\n }\n },\n };\n}\n\n/**\n * Test multiple inputs against a guardrail.\n *\n * @example\n * ```typescript\n * const results = await testGuardrailBatch(createPIIGuardrail(), [\n * { input: 'Hello world', expect: 'pass' },\n * { input: 'My SSN is 123-45-6789', expect: 'fail' },\n * { input: 'Email: test@example.com', expect: 'fail' },\n * ]);\n *\n * expect(results.allPassed()).toBe(true);\n * ```\n */\nexport async function testGuardrailBatch<T>(\n guardrail: GuardrailFn<T>,\n testCases: Array<{\n input: GuardrailTestInput<T>;\n expect: \"pass\" | \"fail\" | \"transform\";\n context?: Partial<GuardrailContext>;\n }>,\n): Promise<{\n results: GuardrailTestResult[];\n allPassed(): boolean;\n failures(): Array<{\n index: number;\n expected: string;\n actual: GuardrailTestResult;\n }>;\n}> {\n const results: GuardrailTestResult[] = [];\n const failures: Array<{\n index: number;\n expected: string;\n actual: GuardrailTestResult;\n }> = [];\n\n for (let i = 0; i < testCases.length; i++) {\n const testCase = testCases[i]!;\n const result = await testGuardrail(\n guardrail,\n testCase.input,\n testCase.context,\n );\n results.push(result);\n\n const actualOutcome = !result.passed\n ? \"fail\"\n : result.transformed !== undefined\n ? \"transform\"\n : \"pass\";\n\n if (actualOutcome !== testCase.expect) {\n failures.push({ index: i, expected: testCase.expect, actual: result });\n }\n }\n\n return {\n results,\n allPassed: () => failures.length === 0,\n failures: () => failures,\n };\n}\n\n// ============================================================================\n// Approval Simulation\n// ============================================================================\n\n/** Approval simulator options */\nexport interface ApprovalSimulatorOptions {\n /** Auto-approve requests matching this predicate */\n autoApprove?: (request: ApprovalRequest) => boolean;\n /** Auto-reject requests matching this predicate */\n autoReject?: (request: ApprovalRequest) => boolean | string;\n /** Delay before auto-approval/rejection (ms) */\n delay?: number;\n /** Record all requests for assertions */\n recordRequests?: boolean;\n}\n\n/** Approval simulator instance */\nexport interface ApprovalSimulator {\n /** Handle an approval request */\n handle(request: ApprovalRequest): Promise<\"approved\" | \"rejected\">;\n /** Get all recorded requests */\n getRequests(): ApprovalRequest[];\n /** Clear recorded requests */\n clearRequests(): void;\n /** Manually approve a request */\n approve(requestId: string): void;\n /** Manually reject a request */\n reject(requestId: string, reason?: string): void;\n /** Wait for a specific request */\n waitForRequest(\n predicate: (req: ApprovalRequest) => boolean,\n timeoutMs?: number,\n ): Promise<ApprovalRequest>;\n}\n\n/**\n * Create an approval simulator for testing approval workflows.\n *\n * @example\n * ```typescript\n * const simulator = createApprovalSimulator({\n * autoApprove: (req) => req.type === 'tool_call' && req.data.name === 'search',\n * autoReject: (req) => req.type === 'tool_call' && req.data.name === 'delete',\n * });\n *\n * // Use in tests\n * orchestrator.onApprovalRequest = (req) => simulator.handle(req);\n * ```\n */\nexport function createApprovalSimulator(\n options: ApprovalSimulatorOptions = {},\n): ApprovalSimulator {\n const { autoApprove, autoReject, delay = 0, recordRequests = true } = options;\n\n const requests: ApprovalRequest[] = [];\n const pendingRequests = new Map<\n string,\n {\n request: ApprovalRequest;\n resolve: (decision: \"approved\" | \"rejected\") => void;\n }\n >();\n const requestWaiters: Array<{\n predicate: (req: ApprovalRequest) => boolean;\n resolve: (req: ApprovalRequest) => void;\n }> = [];\n\n return {\n async handle(request: ApprovalRequest): Promise<\"approved\" | \"rejected\"> {\n if (recordRequests) {\n requests.push(request);\n }\n\n // Notify waiters (resolve matching ones, remove them from array)\n for (let i = requestWaiters.length - 1; i >= 0; i--) {\n const waiter = requestWaiters[i]!;\n if (waiter.predicate(request)) {\n requestWaiters.splice(i, 1);\n waiter.resolve(request);\n }\n }\n\n // Apply delay\n if (delay > 0) {\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n\n // Check auto-reject first (security-first)\n if (autoReject) {\n const rejectResult = autoReject(request);\n if (rejectResult) {\n return \"rejected\";\n }\n }\n\n // Check auto-approve\n if (autoApprove?.(request)) {\n return \"approved\";\n }\n\n // Wait for manual decision\n return new Promise((resolve) => {\n pendingRequests.set(request.id, { request, resolve });\n });\n },\n\n getRequests: () => [...requests],\n clearRequests: () => (requests.length = 0),\n\n approve(requestId: string) {\n const pending = pendingRequests.get(requestId);\n if (pending) {\n pending.resolve(\"approved\");\n pendingRequests.delete(requestId);\n }\n },\n\n reject(requestId: string, reason?: string) {\n const pending = pendingRequests.get(requestId);\n if (pending) {\n pending.resolve(\"rejected\");\n pendingRequests.delete(requestId);\n // Store reason on the request for test assertions\n const request = requests.find((r) => r.id === requestId);\n if (request) {\n (\n request as ApprovalRequest & { rejectionReason?: string }\n ).rejectionReason = reason;\n }\n }\n },\n\n waitForRequest(predicate, timeoutMs = 5000): Promise<ApprovalRequest> {\n // Check existing requests first\n const existing = requests.find(predicate);\n if (existing) {\n return Promise.resolve(existing);\n }\n\n // Wait for future request\n return new Promise((resolve, reject) => {\n const entry = {\n predicate,\n resolve: (req: ApprovalRequest) => {\n clearTimeout(timeout);\n resolve(req);\n },\n };\n\n const timeout = setTimeout(() => {\n const idx = requestWaiters.indexOf(entry);\n if (idx >= 0) {\n requestWaiters.splice(idx, 1);\n }\n reject(new Error(\"Timeout waiting for approval request\"));\n }, timeoutMs);\n\n requestWaiters.push(entry);\n });\n },\n };\n}\n\n// ============================================================================\n// Test Orchestrator Factory\n// ============================================================================\n\n/** Options for test orchestrator */\nexport interface TestOrchestratorOptions<F extends Record<string, unknown>>\n extends Omit<OrchestratorOptions<F>, \"runner\"> {\n /** Mock responses for agents */\n mockResponses?: Record<string, MockAgentConfig>;\n /** Default mock response */\n defaultMockResponse?: MockAgentConfig;\n}\n\n/** Test orchestrator with additional testing utilities */\nexport interface TestOrchestrator<F extends Record<string, unknown>>\n extends AgentOrchestrator<F> {\n /** The mock runner */\n mockRunner: MockAgentRunner;\n /** Approval simulator */\n approvalSimulator: ApprovalSimulator;\n /** Get recorded agent calls */\n getCalls(): RecordedCall[];\n /** Get approval requests */\n getApprovalRequests(): ApprovalRequest[];\n /** Reset all state */\n resetAll(): void;\n}\n\n/**\n * Create a test orchestrator with mocking and simulation built in.\n *\n * @example\n * ```typescript\n * const test = createTestOrchestrator({\n * mockResponses: {\n * 'my-agent': { output: 'test response' },\n * },\n * constraints: {\n * needsApproval: {\n * when: () => true,\n * require: { type: 'NEED_APPROVAL' },\n * },\n * },\n * });\n *\n * await test.run(myAgent, 'Hello');\n * expect(test.getCalls()).toHaveLength(1);\n * ```\n */\nexport function createTestOrchestrator<\n F extends Record<string, unknown> = Record<string, never>,\n>(options: TestOrchestratorOptions<F> = {}): TestOrchestrator<F> {\n const { mockResponses, defaultMockResponse, ...orchestratorOptions } =\n options;\n\n const mockRunner = createMockAgentRunner({\n responses: mockResponses,\n defaultResponse: defaultMockResponse,\n });\n\n const approvalSimulator = createApprovalSimulator();\n\n const orchestrator = createAgentOrchestrator<F>({\n ...orchestratorOptions,\n runner: mockRunner.run,\n onApprovalRequest: (req) => {\n approvalSimulator.handle(req);\n orchestratorOptions.onApprovalRequest?.(req);\n },\n });\n\n // Use Object.create to preserve getters instead of { ...orchestrator } which evaluates them once\n const testOrchestrator = Object.create(orchestrator) as TestOrchestrator<F>;\n testOrchestrator.mockRunner = mockRunner;\n testOrchestrator.approvalSimulator = approvalSimulator;\n testOrchestrator.getCalls = () => mockRunner.getCalls();\n testOrchestrator.getApprovalRequests = () => approvalSimulator.getRequests();\n testOrchestrator.resetAll = () => {\n orchestrator.reset();\n mockRunner.clearCalls();\n approvalSimulator.clearRequests();\n };\n\n return testOrchestrator;\n}\n\n// ============================================================================\n// Snapshot Testing\n// ============================================================================\n\n/** Constraint evaluation snapshot */\nexport interface ConstraintSnapshot {\n constraintId: string;\n triggered: boolean;\n requirement?: unknown;\n facts: Record<string, unknown>;\n timestamp: number;\n}\n\n/**\n * Create a constraint evaluation recorder for snapshot testing.\n *\n * @example\n * ```typescript\n * const recorder = createConstraintRecorder();\n * const orchestrator = createAgentOrchestrator({\n * plugins: [recorder.plugin],\n * });\n *\n * await orchestrator.run(agent, 'Hello');\n *\n * expect(recorder.getSnapshots()).toMatchSnapshot();\n * ```\n */\nexport function createConstraintRecorder(): {\n plugin: {\n name: string;\n onRequirementCreated: (data: {\n constraintId: string;\n requirement: unknown;\n facts: unknown;\n }) => void;\n };\n getSnapshots(): ConstraintSnapshot[];\n clearSnapshots(): void;\n} {\n const snapshots: ConstraintSnapshot[] = [];\n\n return {\n plugin: {\n name: \"constraint-recorder\",\n onRequirementCreated(data) {\n snapshots.push({\n constraintId: data.constraintId,\n triggered: true,\n requirement: data.requirement,\n facts: data.facts as Record<string, unknown>,\n timestamp: Date.now(),\n });\n },\n },\n getSnapshots: () => [...snapshots],\n clearSnapshots: () => (snapshots.length = 0),\n };\n}\n\n// ============================================================================\n// Assertion Helpers\n// ============================================================================\n\n/**\n * Assert that an orchestrator has specific state.\n *\n * @example\n * ```typescript\n * assertOrchestratorState(orchestrator, {\n * agentStatus: 'completed',\n * tokenUsage: { min: 0, max: 1000 },\n * pendingApprovals: 0,\n * });\n * ```\n */\nexport function assertOrchestratorState<F extends Record<string, unknown>>(\n orchestrator: AgentOrchestrator<F>,\n expected: {\n agentStatus?: \"idle\" | \"running\" | \"paused\" | \"completed\" | \"error\";\n tokenUsage?: { min?: number; max?: number; exact?: number };\n pendingApprovals?: number;\n conversationLength?: { min?: number; max?: number; exact?: number };\n },\n): void {\n const state = orchestrator.facts;\n\n if (\n expected.agentStatus !== undefined &&\n state.agent.status !== expected.agentStatus\n ) {\n throw new Error(\n `Expected agent status to be \"${expected.agentStatus}\", got \"${state.agent.status}\"`,\n );\n }\n\n if (expected.tokenUsage !== undefined) {\n const { min, max, exact } = expected.tokenUsage;\n if (exact !== undefined && state.agent.tokenUsage !== exact) {\n throw new Error(\n `Expected token usage to be exactly ${exact}, got ${state.agent.tokenUsage}`,\n );\n }\n if (min !== undefined && state.agent.tokenUsage < min) {\n throw new Error(\n `Expected token usage to be at least ${min}, got ${state.agent.tokenUsage}`,\n );\n }\n if (max !== undefined && state.agent.tokenUsage > max) {\n throw new Error(\n `Expected token usage to be at most ${max}, got ${state.agent.tokenUsage}`,\n );\n }\n }\n\n if (\n expected.pendingApprovals !== undefined &&\n state.approval.pending.length !== expected.pendingApprovals\n ) {\n throw new Error(\n `Expected ${expected.pendingApprovals} pending approvals, got ${state.approval.pending.length}`,\n );\n }\n\n if (expected.conversationLength !== undefined) {\n const { min, max, exact } = expected.conversationLength;\n const len = state.conversation.length;\n if (exact !== undefined && len !== exact) {\n throw new Error(\n `Expected conversation length to be exactly ${exact}, got ${len}`,\n );\n }\n if (min !== undefined && len < min) {\n throw new Error(\n `Expected conversation length to be at least ${min}, got ${len}`,\n );\n }\n if (max !== undefined && len > max) {\n throw new Error(\n `Expected conversation length to be at most ${max}, got ${len}`,\n );\n }\n }\n}\n\n// ============================================================================\n// Fake Timers Support\n// ============================================================================\n\n/**\n * Create a time controller for testing time-dependent behavior.\n *\n * @example\n * ```typescript\n * const time = createTimeController();\n *\n * // Override Date.now\n * const originalNow = Date.now;\n * Date.now = () => time.now();\n *\n * time.advance(1000); // Advance 1 second\n *\n * // Restore\n * Date.now = originalNow;\n * ```\n */\nexport function createTimeController(startTime = Date.now()): {\n now(): number;\n advance(ms: number): void;\n set(time: number): void;\n reset(): void;\n} {\n let currentTime = startTime;\n const initial = startTime;\n\n return {\n now: () => currentTime,\n advance: (ms) => {\n currentTime += ms;\n },\n set: (time) => {\n currentTime = time;\n },\n reset: () => {\n currentTime = initial;\n },\n };\n}\n\n// ============================================================================\n// Multi-Agent Test Orchestrator\n// ============================================================================\n\n/** Options for test multi-agent orchestrator */\nexport interface TestMultiAgentOrchestratorOptions\n extends Omit<MultiAgentOrchestratorOptions, \"runner\"> {\n /** Mock responses keyed by agent ID — internally mapped to agent names for the mock runner */\n mockResponses?: Record<string, MockAgentConfig>;\n /** Default mock response for unmatched agents */\n defaultMockResponse?: MockAgentConfig;\n /** Mock tasks keyed by task ID — auto-generates TaskRegistration wrappers */\n mockTasks?: Record<\n string,\n { output: unknown; delay?: number; shouldError?: boolean }\n >;\n}\n\n/** Test multi-agent orchestrator with additional testing utilities */\nexport interface TestMultiAgentOrchestrator extends MultiAgentOrchestrator {\n /** The mock runner */\n mockRunner: MockAgentRunner;\n /** Approval simulator */\n approvalSimulator: ApprovalSimulator;\n /** Get recorded agent calls */\n getCalls(): RecordedCall[];\n /** Get approval requests */\n getApprovalRequests(): ApprovalRequest[];\n /** Reset all state */\n resetAll(): void;\n}\n\n/**\n * Create a test multi-agent orchestrator with mocking and simulation built in.\n *\n * @example\n * ```typescript\n * const test = createTestMultiAgentOrchestrator({\n * agents: {\n * researcher: { agent: { name: 'researcher' } },\n * writer: { agent: { name: 'writer' } },\n * },\n * mockResponses: {\n * researcher: { output: 'Research results', totalTokens: 100 },\n * writer: { output: 'Written article', totalTokens: 200 },\n * },\n * });\n *\n * const result = await test.runAgent('researcher', 'What is AI?');\n * expect(result.output).toBe('Research results');\n * expect(test.getCalls()).toHaveLength(1);\n * ```\n */\nexport function createTestMultiAgentOrchestrator(\n options: TestMultiAgentOrchestratorOptions,\n): TestMultiAgentOrchestrator {\n const {\n mockResponses = {},\n defaultMockResponse,\n mockTasks: mockTaskConfigs,\n ...orchestratorOptions\n } = options;\n\n // Convert mockTasks into real TaskRegistration entries\n if (mockTaskConfigs) {\n const existingTasks = orchestratorOptions.tasks ?? {};\n for (const [taskId, config] of Object.entries(mockTaskConfigs)) {\n if (!existingTasks[taskId]) {\n existingTasks[taskId] = createMockTask(config.output, {\n delay: config.delay,\n shouldError: config.shouldError,\n });\n }\n }\n orchestratorOptions.tasks = existingTasks;\n }\n\n // Map mock responses by agent name (from agent registration)\n const responsesByName: Record<string, MockAgentConfig> = {};\n for (const [agentId, config] of Object.entries(mockResponses)) {\n const registration = orchestratorOptions.agents[agentId];\n if (registration) {\n responsesByName[registration.agent.name] = config;\n }\n }\n\n const mockRunner = createMockAgentRunner({\n responses: responsesByName,\n defaultResponse: defaultMockResponse,\n });\n\n const approvalSimulator = createApprovalSimulator();\n\n const orchestrator = createMultiAgentOrchestrator({\n ...orchestratorOptions,\n runner: mockRunner.run,\n onApprovalRequest: (req) => {\n approvalSimulator.handle(req);\n orchestratorOptions.onApprovalRequest?.(req);\n },\n });\n\n // Use Object.create to preserve getters (derived, scratchpad, timeline, etc.)\n // instead of { ...orchestrator } which evaluates getters at spread time\n const testOrchestrator = Object.create(\n orchestrator,\n ) as TestMultiAgentOrchestrator;\n testOrchestrator.mockRunner = mockRunner;\n testOrchestrator.approvalSimulator = approvalSimulator;\n testOrchestrator.getCalls = () => mockRunner.getCalls();\n testOrchestrator.getApprovalRequests = () => approvalSimulator.getRequests();\n testOrchestrator.resetAll = () => {\n orchestrator.reset();\n mockRunner.clearCalls();\n approvalSimulator.clearRequests();\n };\n\n return testOrchestrator;\n}\n\n// ============================================================================\n// Multi-Agent Assertion Helpers\n// ============================================================================\n\n/**\n * Assert that a multi-agent orchestrator has specific state.\n *\n * @example\n * ```typescript\n * assertMultiAgentState(orchestrator, {\n * agentStatus: { researcher: 'completed', writer: 'idle' },\n * globalTokens: { min: 0, max: 1000 },\n * pendingHandoffs: 0,\n * });\n * ```\n */\nexport function assertMultiAgentState(\n orchestrator: MultiAgentOrchestrator,\n expected: {\n agentStatus?: Record<string, \"idle\" | \"running\" | \"completed\" | \"error\">;\n taskStatus?: Record<string, string>;\n totalTokens?: { agentId?: string; min?: number; max?: number };\n globalTokens?: { min?: number; max?: number };\n pendingHandoffs?: number;\n },\n): void {\n if (expected.taskStatus) {\n for (const [taskId, expectedStatus] of Object.entries(\n expected.taskStatus,\n )) {\n const state = orchestrator.getTaskState(taskId);\n if (!state) {\n throw new Error(\n `Expected task \"${taskId}\" to exist, but it was not found`,\n );\n }\n if (state.status !== expectedStatus) {\n throw new Error(\n `Expected task \"${taskId}\" status to be \"${expectedStatus}\", got \"${state.status}\"`,\n );\n }\n }\n }\n\n if (expected.agentStatus) {\n for (const [agentId, expectedStatus] of Object.entries(\n expected.agentStatus,\n )) {\n const state = orchestrator.getAgentState(agentId);\n if (!state) {\n throw new Error(\n `Expected agent \"${agentId}\" to exist, but it was not found`,\n );\n }\n if (state.status !== expectedStatus) {\n throw new Error(\n `Expected agent \"${agentId}\" status to be \"${expectedStatus}\", got \"${state.status}\"`,\n );\n }\n }\n }\n\n if (expected.totalTokens) {\n const { agentId, min, max } = expected.totalTokens;\n if (agentId) {\n const state = orchestrator.getAgentState(agentId);\n if (!state) {\n throw new Error(\n `Expected agent \"${agentId}\" to exist, but it was not found`,\n );\n }\n if (min !== undefined && state.totalTokens < min) {\n throw new Error(\n `Expected agent \"${agentId}\" tokens to be at least ${min}, got ${state.totalTokens}`,\n );\n }\n if (max !== undefined && state.totalTokens > max) {\n throw new Error(\n `Expected agent \"${agentId}\" tokens to be at most ${max}, got ${state.totalTokens}`,\n );\n }\n } else {\n const allStates = orchestrator.getAllAgentStates();\n const total = Object.values(allStates).reduce(\n (sum, s) => sum + s.totalTokens,\n 0,\n );\n if (min !== undefined && total < min) {\n throw new Error(\n `Expected total tokens to be at least ${min}, got ${total}`,\n );\n }\n if (max !== undefined && total > max) {\n throw new Error(\n `Expected total tokens to be at most ${max}, got ${total}`,\n );\n }\n }\n }\n\n if (expected.globalTokens) {\n const { min, max } = expected.globalTokens;\n const total = orchestrator.totalTokens;\n if (min !== undefined && total < min) {\n throw new Error(\n `Expected global tokens to be at least ${min}, got ${total}`,\n );\n }\n if (max !== undefined && total > max) {\n throw new Error(\n `Expected global tokens to be at most ${max}, got ${total}`,\n );\n }\n }\n\n if (expected.pendingHandoffs !== undefined) {\n const pendingCount = orchestrator.getPendingHandoffs().length;\n if (pendingCount !== expected.pendingHandoffs) {\n throw new Error(\n `Expected ${expected.pendingHandoffs} pending handoffs, got ${pendingCount}`,\n );\n }\n }\n}\n\n// ============================================================================\n// Mock Task Helpers\n// ============================================================================\n\n/**\n * Create a mock TaskRegistration for testing.\n *\n * @example\n * ```typescript\n * const task = createMockTask({ result: \"processed\" }, { delay: 100 });\n * const orchestrator = createTestMultiAgentOrchestrator({\n * agents: { writer: { agent: { name: \"writer\" } } },\n * tasks: { process: task },\n * });\n * ```\n */\nexport function createMockTask(\n output: unknown,\n options?: {\n delay?: number;\n shouldError?: boolean;\n label?: string;\n description?: string;\n },\n): TaskRegistration {\n return {\n run: async (_input: string, signal: AbortSignal) => {\n if (signal.aborted) {\n throw new Error(\"Task aborted\");\n }\n if (options?.delay && options.delay > 0) {\n await new Promise<void>((resolve, reject) => {\n const timer = setTimeout(resolve, options.delay);\n signal.addEventListener(\n \"abort\",\n () => {\n clearTimeout(timer);\n reject(new Error(\"Task aborted\"));\n },\n { once: true },\n );\n });\n }\n\n if (options?.shouldError) {\n throw new Error(\"Mock task error\");\n }\n\n return output;\n },\n label: options?.label ?? \"Mock Task\",\n description: options?.description,\n };\n}\n\n// ============================================================================\n// DAG Testing Helpers\n// ============================================================================\n\nimport { dag } from \"./multi-agent-orchestrator.js\";\nimport type {\n DagExecutionContext,\n DagNode,\n DagNodeStatus,\n DagPattern,\n} from \"./types.js\";\n\n/**\n * Create a test DAG pattern from a simplified node spec.\n *\n * @example\n * ```typescript\n * const pattern = createTestDag({\n * A: { handler: \"researcher\" },\n * B: { handler: \"writer\", deps: [\"A\"] },\n * C: { handler: \"reviewer\", deps: [\"B\"] },\n * });\n * ```\n */\nexport function createTestDag<T = unknown>(\n nodes: Record<\n string,\n Pick<\n DagNode,\n \"handler\" | \"deps\" | \"when\" | \"transform\" | \"timeout\" | \"priority\"\n >\n >,\n merge?: (context: DagExecutionContext) => T | Promise<T>,\n options?: {\n timeout?: number;\n maxConcurrent?: number;\n onNodeError?: \"fail\" | \"skip-downstream\" | \"continue\";\n },\n): DagPattern<T> {\n const defaultMerge = (context: DagExecutionContext) =>\n context.outputs as unknown as T;\n\n return dag<T>(nodes, merge ?? defaultMerge, options);\n}\n\n/**\n * Assert that a DAG execution produced the expected node statuses.\n *\n * @example\n * ```typescript\n * assertDagExecution(context, {\n * nodeStatuses: { A: \"completed\", B: \"completed\", C: \"skipped\" },\n * completedNodes: [\"A\", \"B\"],\n * skippedNodes: [\"C\"],\n * });\n * ```\n */\nexport function assertDagExecution(\n context: DagExecutionContext,\n expected: {\n nodeStatuses?: Record<string, DagNodeStatus>;\n completedNodes?: string[];\n skippedNodes?: string[];\n errorNodes?: string[];\n outputContains?: Record<string, unknown>;\n },\n): void {\n if (expected.nodeStatuses) {\n for (const [nodeId, expectedStatus] of Object.entries(\n expected.nodeStatuses,\n )) {\n const actual = context.statuses[nodeId];\n if (actual !== expectedStatus) {\n throw new Error(\n `Expected node \"${nodeId}\" status to be \"${expectedStatus}\", got \"${actual}\"`,\n );\n }\n }\n }\n\n if (expected.completedNodes) {\n for (const nodeId of expected.completedNodes) {\n if (context.statuses[nodeId] !== \"completed\") {\n throw new Error(\n `Expected node \"${nodeId}\" to be completed, got \"${context.statuses[nodeId]}\"`,\n );\n }\n }\n }\n\n if (expected.skippedNodes) {\n for (const nodeId of expected.skippedNodes) {\n if (context.statuses[nodeId] !== \"skipped\") {\n throw new Error(\n `Expected node \"${nodeId}\" to be skipped, got \"${context.statuses[nodeId]}\"`,\n );\n }\n }\n }\n\n if (expected.errorNodes) {\n for (const nodeId of expected.errorNodes) {\n if (context.statuses[nodeId] !== \"error\") {\n throw new Error(\n `Expected node \"${nodeId}\" to be error, got \"${context.statuses[nodeId]}\"`,\n );\n }\n }\n }\n\n if (expected.outputContains) {\n for (const [nodeId, expectedOutput] of Object.entries(\n expected.outputContains,\n )) {\n const actual = context.outputs[nodeId];\n if (actual !== expectedOutput) {\n throw new Error(\n `Expected node \"${nodeId}\" output to be ${JSON.stringify(expectedOutput)}, got ${JSON.stringify(actual)}`,\n );\n }\n }\n }\n}\n\n// ============================================================================\n// Debug Timeline Testing Helpers\n// ============================================================================\n\nimport { type DebugTimeline, createDebugTimeline } from \"./debug-timeline.js\";\nimport type { DebugEvent, DebugEventType } from \"./types.js\";\n\n/**\n * Create a test debug timeline pre-populated with events.\n *\n * @example\n * ```typescript\n * const timeline = createTestTimeline([\n * { type: \"agent_start\", agentId: \"researcher\", inputLength: 42 },\n * { type: \"agent_complete\", agentId: \"researcher\", outputLength: 100, durationMs: 500, totalTokens: 200 },\n * ]);\n *\n * expect(timeline.getEventsForAgent(\"researcher\")).toHaveLength(2);\n * ```\n */\nexport function createTestTimeline(\n events?: Array<Partial<DebugEvent> & { type: DebugEventType }>,\n options?: { maxEvents?: number },\n): DebugTimeline {\n const timeline = createDebugTimeline({\n maxEvents: options?.maxEvents ?? 500,\n });\n\n if (events) {\n for (const event of events) {\n timeline.record({\n timestamp: Date.now(),\n snapshotId: null,\n agentId: \"\",\n ...event,\n } as Omit<DebugEvent, \"id\">);\n }\n }\n\n return timeline;\n}\n\n/**\n * Assert that a debug timeline contains expected events.\n *\n * @example\n * ```typescript\n * assertTimelineEvents(timeline, {\n * totalEvents: 5,\n * eventTypes: [\"agent_start\", \"guardrail_check\", \"agent_complete\"],\n * agentEvents: { researcher: 3, writer: 2 },\n * hasType: \"guardrail_check\",\n * });\n * ```\n */\nexport function assertTimelineEvents(\n timeline: DebugTimeline,\n expected: {\n totalEvents?: number;\n minEvents?: number;\n maxEvents?: number;\n eventTypes?: DebugEventType[];\n agentEvents?: Record<string, number>;\n hasType?: DebugEventType;\n doesNotHaveType?: DebugEventType;\n },\n): void {\n const events = timeline.getEvents();\n\n if (\n expected.totalEvents !== undefined &&\n events.length !== expected.totalEvents\n ) {\n throw new Error(\n `Expected ${expected.totalEvents} timeline events, got ${events.length}`,\n );\n }\n\n if (expected.minEvents !== undefined && events.length < expected.minEvents) {\n throw new Error(\n `Expected at least ${expected.minEvents} timeline events, got ${events.length}`,\n );\n }\n\n if (expected.maxEvents !== undefined && events.length > expected.maxEvents) {\n throw new Error(\n `Expected at most ${expected.maxEvents} timeline events, got ${events.length}`,\n );\n }\n\n if (expected.eventTypes) {\n for (const type of expected.eventTypes) {\n const found = events.some((e) => e.type === type);\n if (!found) {\n throw new Error(\n `Expected timeline to contain event of type \"${type}\", but none found`,\n );\n }\n }\n }\n\n if (expected.agentEvents) {\n for (const [agentId, expectedCount] of Object.entries(\n expected.agentEvents,\n )) {\n const actual = timeline.getEventsForAgent(agentId).length;\n if (actual !== expectedCount) {\n throw new Error(\n `Expected ${expectedCount} events for agent \"${agentId}\", got ${actual}`,\n );\n }\n }\n }\n\n if (expected.hasType) {\n const found = events.some((e) => e.type === expected.hasType);\n if (!found) {\n throw new Error(\n `Expected timeline to contain event of type \"${expected.hasType}\"`,\n );\n }\n }\n\n if (expected.doesNotHaveType) {\n const found = events.some((e) => e.type === expected.doesNotHaveType);\n if (found) {\n throw new Error(\n `Expected timeline NOT to contain event of type \"${expected.doesNotHaveType}\"`,\n );\n }\n }\n}\n\n// ============================================================================\n// Self-Healing Testing Helpers\n// ============================================================================\n\nimport type { HealthMonitor } from \"./health-monitor.js\";\nimport type { ReflectionEvaluator } from \"./reflection.js\";\nimport type { RerouteEvent, Scratchpad } from \"./types.js\";\n\n/**\n * Create a runner that always fails, useful for testing self-healing.\n *\n * @example\n * ```typescript\n * const failing = createFailingRunner(new Error(\"Provider down\"));\n * const orchestrator = createAgentOrchestrator({\n * runner: failing,\n * selfHealing: { fallbackRunners: [backupRunner] },\n * });\n * ```\n */\nexport function createFailingRunner(\n error?: Error,\n options?: { delay?: number; failAfter?: number },\n): AgentRunner {\n let callCount = 0;\n const failAfter = options?.failAfter ?? 0;\n\n return async <T>(\n _agent: AgentLike,\n _input: string,\n _runOptions?: RunOptions,\n ): Promise<RunResult<T>> => {\n callCount++;\n\n if (failAfter > 0 && callCount <= failAfter) {\n return {\n output: \"success\" as T,\n messages: [],\n toolCalls: [],\n totalTokens: 10,\n };\n }\n\n if (options?.delay && options.delay > 0) {\n await new Promise((resolve) => setTimeout(resolve, options.delay));\n }\n\n throw error ?? new Error(\"Runner failed\");\n };\n}\n\n/**\n * Assert that an agent was rerouted during execution.\n *\n * @example\n * ```typescript\n * const events: RerouteEvent[] = [];\n * const orchestrator = createMultiAgentOrchestrator({\n * selfHealing: {\n * onReroute: (event) => events.push(event),\n * },\n * });\n *\n * // ... trigger reroute ...\n * assertRerouted(events, {\n * fromAgent: \"primary\",\n * toAgent: \"backup\",\n * reason: /circuit breaker/i,\n * });\n * ```\n */\nexport function assertRerouted(\n events: RerouteEvent[],\n expected: {\n fromAgent?: string;\n toAgent?: string;\n reason?: string | RegExp;\n minReroutes?: number;\n },\n): void {\n if (events.length === 0) {\n throw new Error(\"Expected at least one reroute event, but none occurred\");\n }\n\n if (\n expected.minReroutes !== undefined &&\n events.length < expected.minReroutes\n ) {\n throw new Error(\n `Expected at least ${expected.minReroutes} reroute events, got ${events.length}`,\n );\n }\n\n if (expected.fromAgent) {\n const found = events.some((e) => e.originalAgent === expected.fromAgent);\n if (!found) {\n throw new Error(\n `Expected reroute from agent \"${expected.fromAgent}\", but no matching event found`,\n );\n }\n }\n\n if (expected.toAgent) {\n const found = events.some((e) => e.reroutedTo === expected.toAgent);\n if (!found) {\n throw new Error(\n `Expected reroute to agent \"${expected.toAgent}\", but no matching event found`,\n );\n }\n }\n\n if (expected.reason) {\n const found = events.some((e) => {\n if (typeof expected.reason === \"string\") {\n return e.reason.includes(expected.reason);\n }\n\n return expected.reason!.test(e.reason);\n });\n if (!found) {\n throw new Error(\n `Expected reroute reason matching ${expected.reason}, but no matching event found`,\n );\n }\n }\n}\n\n/**\n * Assert the health state of an agent in the health monitor.\n *\n * @example\n * ```typescript\n * assertAgentHealth(monitor, \"researcher\", {\n * minScore: 70,\n * circuitState: \"CLOSED\",\n * });\n * ```\n */\nexport function assertAgentHealth(\n monitor: HealthMonitor,\n agentId: string,\n expected: {\n minScore?: number;\n maxScore?: number;\n circuitState?: \"CLOSED\" | \"OPEN\" | \"HALF_OPEN\";\n minSuccessRate?: number;\n },\n): void {\n const metrics = monitor.getMetrics(agentId);\n\n if (\n expected.minScore !== undefined &&\n metrics.healthScore < expected.minScore\n ) {\n throw new Error(\n `Expected agent \"${agentId}\" health score to be at least ${expected.minScore}, got ${metrics.healthScore}`,\n );\n }\n\n if (\n expected.maxScore !== undefined &&\n metrics.healthScore > expected.maxScore\n ) {\n throw new Error(\n `Expected agent \"${agentId}\" health score to be at most ${expected.maxScore}, got ${metrics.healthScore}`,\n );\n }\n\n if (\n expected.circuitState !== undefined &&\n metrics.circuitState !== expected.circuitState\n ) {\n throw new Error(\n `Expected agent \"${agentId}\" circuit state to be \"${expected.circuitState}\", got \"${metrics.circuitState}\"`,\n );\n }\n\n if (\n expected.minSuccessRate !== undefined &&\n metrics.successRate < expected.minSuccessRate\n ) {\n throw new Error(\n `Expected agent \"${agentId}\" success rate to be at least ${expected.minSuccessRate}, got ${metrics.successRate}`,\n );\n }\n}\n\n// ============================================================================\n// Checkpoint Test Helpers\n// ============================================================================\n\n/**\n * Create a test checkpoint store (wraps InMemoryCheckpointStore with assertion helpers).\n *\n * @example\n * ```typescript\n * const store = createTestCheckpointStore();\n * const orchestrator = createAgentOrchestrator({ runner, checkpointStore: store });\n * const cp = await orchestrator.checkpoint();\n * expect(store.saved).toHaveLength(1);\n * ```\n */\nexport function createTestCheckpointStore(\n maxCheckpoints = 100,\n): CheckpointStore & {\n saved: Checkpoint[];\n inner: InMemoryCheckpointStore;\n /** Get the most recently saved checkpoint */\n getLatest: () => Checkpoint | undefined;\n} {\n const inner = new InMemoryCheckpointStore({ maxCheckpoints });\n const saved: Checkpoint[] = [];\n\n return {\n inner,\n saved,\n getLatest: () => saved[saved.length - 1],\n async save(checkpoint: Checkpoint): Promise<string> {\n saved.push(checkpoint);\n\n return inner.save(checkpoint);\n },\n load: (id: string) => inner.load(id),\n list: () => inner.list(),\n delete: (id: string) => inner.delete(id),\n clear: () => inner.clear(),\n prune: () => inner.prune(),\n };\n}\n\n/**\n * Assert that a checkpoint has expected properties.\n */\nexport function assertCheckpoint(\n checkpoint: Checkpoint,\n expected: {\n orchestratorType?: \"single\" | \"multi\";\n hasTimeline?: boolean;\n hasMemory?: boolean;\n hasSystemExport?: boolean;\n label?: string;\n },\n): void {\n if (\n expected.orchestratorType !== undefined &&\n checkpoint.orchestratorType !== expected.orchestratorType\n ) {\n throw new Error(\n `Expected checkpoint orchestratorType \"${expected.orchestratorType}\", got \"${checkpoint.orchestratorType}\"`,\n );\n }\n\n if (\n expected.hasSystemExport === true &&\n (!checkpoint.systemExport || checkpoint.systemExport === \"\")\n ) {\n throw new Error(\n \"Expected checkpoint to have non-empty systemExport, but it was empty\",\n );\n }\n\n if (expected.hasTimeline === true && checkpoint.timelineExport === null) {\n throw new Error(\n \"Expected checkpoint to have timeline export, but it was null\",\n );\n }\n\n if (expected.hasTimeline === false && checkpoint.timelineExport !== null) {\n throw new Error(\n \"Expected checkpoint to have no timeline export, but it was present\",\n );\n }\n\n if (expected.hasMemory === true && checkpoint.memoryExport === null) {\n throw new Error(\n \"Expected checkpoint to have memory export, but it was null\",\n );\n }\n\n if (expected.hasMemory === false && checkpoint.memoryExport !== null) {\n throw new Error(\n \"Expected checkpoint to have no memory export, but it was present\",\n );\n }\n\n if (expected.label !== undefined && checkpoint.label !== expected.label) {\n throw new Error(\n `Expected checkpoint label \"${expected.label}\", got \"${checkpoint.label}\"`,\n );\n }\n}\n\n// ============================================================================\n// Breakpoint Test Helpers\n// ============================================================================\n\n/** Options for the breakpoint simulator */\nexport interface BreakpointSimulatorOptions {\n /** Auto-resume after this delay (ms). Default: 0 (immediate) */\n autoResumeDelay?: number;\n /** Modifications to apply on resume */\n modifications?: BreakpointModifications;\n /** If true, cancel instead of resume */\n cancel?: boolean;\n /** Cancel reason */\n cancelReason?: string;\n}\n\n/**\n * Create a breakpoint simulator that auto-resolves breakpoints.\n *\n * @example\n * ```typescript\n * const simulator = createBreakpointSimulator({ autoResumeDelay: 10 });\n * const orchestrator = createAgentOrchestrator({\n * runner,\n * breakpoints: [{ type: \"pre_agent_run\" }],\n * onBreakpoint: simulator.handler,\n * });\n * // Run agent — breakpoint fires and auto-resumes\n * await orchestrator.run(\"test input\");\n * expect(simulator.hits).toHaveLength(1);\n * ```\n */\n/** Minimal interface for breakpoint-capable orchestrators */\nexport interface BreakpointCapable {\n resumeBreakpoint(id: string, modifications?: BreakpointModifications): void;\n cancelBreakpoint(id: string, reason?: string): void;\n}\n\n/**\n * Create a breakpoint simulator that auto-resolves breakpoints for testing.\n *\n * @param options - Simulator options including `autoResumeDelay` and `modifications`.\n * @returns An object with `handler`, `hits`, and `attachTo` for test assertions.\n */\nexport function createBreakpointSimulator(\n options: BreakpointSimulatorOptions = {},\n): {\n handler: (request: BreakpointRequest) => void;\n hits: BreakpointRequest[];\n attachTo: (orchestrator: BreakpointCapable) => void;\n} {\n const hits: BreakpointRequest[] = [];\n let orchestratorRef: BreakpointCapable | null = null;\n let attached = false;\n\n const handler = (request: BreakpointRequest) => {\n hits.push(request);\n\n if (!attached) {\n throw new Error(\n \"[Directive] BreakpointSimulator: handler called but attachTo() was never called. \" +\n \"Breakpoints will not be resolved. Call simulator.attachTo(orchestrator) after creation.\",\n );\n }\n\n const delay = options.autoResumeDelay ?? 0;\n\n const doResolve = () => {\n if (!orchestratorRef) {\n return;\n }\n if (options.cancel) {\n orchestratorRef.cancelBreakpoint(request.id, options.cancelReason);\n } else {\n orchestratorRef.resumeBreakpoint(request.id, options.modifications);\n }\n };\n\n if (delay > 0) {\n setTimeout(doResolve, delay);\n } else {\n // Use queueMicrotask so the breakpoint state is written before we resolve\n queueMicrotask(doResolve);\n }\n };\n\n return {\n handler,\n hits,\n attachTo: (orch: BreakpointCapable) => {\n orchestratorRef = orch;\n attached = true;\n },\n };\n}\n\n/**\n * Assert that a breakpoint was hit with expected properties.\n */\nexport function assertBreakpointHit(\n hits: BreakpointRequest[],\n expected: {\n type?: string;\n agentId?: string;\n count?: number;\n },\n): void {\n if (expected.count !== undefined && hits.length !== expected.count) {\n throw new Error(\n `Expected ${expected.count} breakpoint hits, got ${hits.length}`,\n );\n }\n\n if (expected.type) {\n const found = hits.some((h) => h.type === expected.type);\n if (!found) {\n const types = hits.map((h) => h.type).join(\", \");\n\n throw new Error(\n `Expected breakpoint of type \"${expected.type}\", found types: [${types}]`,\n );\n }\n }\n\n if (expected.agentId) {\n const found = hits.some((h) => h.agentId === expected.agentId);\n if (!found) {\n const agents = hits.map((h) => h.agentId).join(\", \");\n\n throw new Error(\n `Expected breakpoint for agent \"${expected.agentId}\", found agents: [${agents}]`,\n );\n }\n }\n}\n\n// ============================================================================\n// Structured Output Test Helpers\n// ============================================================================\n\n/**\n * Create a mock SafeParseable schema for testing.\n *\n * @example\n * ```typescript\n * const schema = createMockSchema((data) => typeof data === \"object\" && data !== null);\n * const orchestrator = createAgentOrchestrator({\n * runner,\n * outputSchema: schema,\n * });\n * ```\n */\nexport function createMockSchema<T>(\n validate: (data: unknown) => boolean,\n description?: string,\n): {\n safeParse: (data: unknown) => {\n success: boolean;\n data?: T;\n error?: { message: string };\n };\n description?: string;\n} {\n return {\n safeParse: (data: unknown) => {\n if (validate(data)) {\n return { success: true, data: data as T };\n }\n\n return { success: false, error: { message: \"Validation failed\" } };\n },\n description,\n };\n}\n\n// ============================================================================\n// Multiplexed Stream Test Helpers\n// ============================================================================\n\n/**\n * Collect all chunks from a multiplexed stream into an array.\n *\n * @example\n * ```typescript\n * const { stream } = orchestrator.runParallelStream([\"a\", \"b\"], \"input\", merge);\n * const chunks = await collectMultiplexedStream(stream);\n * expect(chunks.length).toBeGreaterThan(0);\n * ```\n */\nexport async function collectMultiplexedStream(\n stream: AsyncIterable<MultiplexedStreamChunk>,\n): Promise<MultiplexedStreamChunk[]> {\n const chunks: MultiplexedStreamChunk[] = [];\n for await (const chunk of stream) {\n chunks.push(chunk);\n }\n\n return chunks;\n}\n\n/**\n * Assert properties of collected multiplexed stream chunks.\n */\nexport function assertMultiplexedStream(\n chunks: MultiplexedStreamChunk[],\n expected: {\n agentIds?: string[];\n minChunks?: number;\n hasDone?: boolean;\n hasErrors?: boolean;\n },\n): void {\n if (expected.minChunks !== undefined && chunks.length < expected.minChunks) {\n throw new Error(\n `Expected at least ${expected.minChunks} chunks, got ${chunks.length}`,\n );\n }\n\n if (expected.agentIds) {\n const seenAgents = new Set(chunks.map((c) => c.agentId));\n for (const agentId of expected.agentIds) {\n if (!seenAgents.has(agentId)) {\n throw new Error(\n `Expected chunks from agent \"${agentId}\", found agents: [${[...seenAgents].join(\", \")}]`,\n );\n }\n }\n }\n\n if (expected.hasDone === true) {\n const hasDone = chunks.some((c) => c.chunk.type === \"done\");\n if (!hasDone) {\n throw new Error(\"Expected at least one 'done' chunk, found none\");\n }\n }\n\n if (expected.hasErrors === true) {\n const hasError = chunks.some((c) => c.chunk.type === \"error\");\n if (!hasError) {\n throw new Error(\"Expected at least one 'error' chunk, found none\");\n }\n }\n\n if (expected.hasErrors === false) {\n const hasError = chunks.some((c) => c.chunk.type === \"error\");\n if (hasError) {\n throw new Error(\"Expected no 'error' chunks, but found some\");\n }\n }\n}\n\n// ============================================================================\n// Reflection Test Helpers\n// ============================================================================\n\n/**\n * Create a test reflection evaluator that passes after N iterations.\n *\n * @example\n * ```typescript\n * const evaluator = createTestReflectionEvaluator({ passAfter: 2 });\n * const reflective = withReflection(runner, { evaluate: evaluator });\n * ```\n */\nexport function createTestReflectionEvaluator(options?: {\n /** Pass after this many evaluations (1 = pass on first try). Default: 1 */\n passAfter?: number;\n /** Feedback to provide on failure */\n feedback?: string;\n /** Score to assign (0-1) */\n score?: number;\n}): ReflectionEvaluator {\n const passAfter = options?.passAfter ?? 1;\n const feedback = options?.feedback ?? \"Needs improvement\";\n const score = options?.score;\n let callCount = 0;\n\n return (_output: unknown, _context) => {\n callCount++;\n const passed = callCount >= passAfter;\n\n return {\n passed,\n feedback: passed ? undefined : feedback,\n score: score ?? (passed ? 1 : 0.5),\n };\n };\n}\n\n// ============================================================================\n// Scratchpad Test Helpers\n// ============================================================================\n\n/**\n * Assert that a scratchpad contains expected values.\n *\n * @example\n * ```typescript\n * assertScratchpadState(orchestrator.scratchpad!, {\n * \"plan.status\": \"complete\",\n * \"research.results\": expect.any(Array),\n * });\n * ```\n */\nexport function assertScratchpadState(\n scratchpad: Scratchpad,\n expected: Record<string, unknown>,\n): void {\n const all = scratchpad.getAll();\n for (const [key, expectedValue] of Object.entries(expected)) {\n const actual = all[key];\n if (actual !== expectedValue) {\n throw new Error(\n `Expected scratchpad key \"${key}\" to be ${JSON.stringify(expectedValue)}, got ${JSON.stringify(actual)}`,\n );\n }\n }\n}\n\n// ============================================================================\n// Derivation Test Helpers\n// ============================================================================\n\n/**\n * Assert that derived values match expected values.\n *\n * @example\n * ```typescript\n * assertDerivedValues(orchestrator, {\n * totalRuns: 3,\n * allComplete: true,\n * });\n * ```\n */\nexport function assertDerivedValues(\n orchestrator: MultiAgentOrchestrator,\n expected: Record<string, unknown>,\n): void {\n const derived = orchestrator.derived;\n for (const [key, expectedValue] of Object.entries(expected)) {\n const actual = derived[key];\n if (typeof expectedValue === \"object\" && expectedValue !== null) {\n // Sort keys for order-independent comparison\n const sortedStringify = (v: unknown): string =>\n JSON.stringify(v, Object.keys(v as Record<string, unknown>).sort());\n if (sortedStringify(actual) !== sortedStringify(expectedValue)) {\n throw new Error(\n `Expected derived value \"${key}\" to be ${JSON.stringify(expectedValue)}, got ${JSON.stringify(actual)}`,\n );\n }\n } else if (actual !== expectedValue) {\n throw new Error(\n `Expected derived value \"${key}\" to be ${JSON.stringify(expectedValue)}, got ${JSON.stringify(actual)}`,\n );\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/testing.ts"],"names":["createMockAgentRunner","options","defaultResponse","responses","recordCalls","onRun","calls","responseMap","currentDefault","agent","input","runOptions","config","generated","resolve","messages","message","toolCalls","toolCall","name","testGuardrail","guardrail","testInput","context","data","fullContext","start","result","duration","expectedReason","expected","testGuardrailBatch","testCases","results","failures","i","testCase","createApprovalSimulator","autoApprove","autoReject","delay","recordRequests","requests","pendingRequests","requestWaiters","request","waiter","requestId","pending","reason","r","predicate","timeoutMs","existing","reject","entry","req","timeout","idx","createTestOrchestrator","mockResponses","defaultMockResponse","orchestratorOptions","mockRunner","approvalSimulator","orchestrator","createAgentOrchestrator","testOrchestrator","createConstraintRecorder","snapshots","assertOrchestratorState","state","min","max","exact","len","createTimeController","startTime","currentTime","initial","ms","time","createTestMultiAgentOrchestrator","mockTaskConfigs","existingTasks","taskId","createMockTask","responsesByName","agentId","registration","createMultiAgentOrchestrator","assertMultiAgentState","expectedStatus","allStates","total","sum","s","pendingCount","output","_input","signal","timer","createTestDag","nodes","merge","dag","assertDagExecution","nodeId","actual","expectedOutput","createTestTimeline","events","timeline","createDebugTimeline","event","assertTimelineEvents","type","e","expectedCount","createFailingRunner","error","callCount","failAfter","_agent","_runOptions","assertRerouted","assertAgentHealth","monitor","metrics","createTestCheckpointStore","maxCheckpoints","inner","InMemoryCheckpointStore","saved","checkpoint","id","assertCheckpoint","createBreakpointSimulator","hits","orchestratorRef","attached","doResolve","orch","assertBreakpointHit","h","types","agents","createMockSchema","validate","description","collectMultiplexedStream","stream","chunks","chunk","assertMultiplexedStream","seenAgents","c","createTestReflectionEvaluator","passAfter","feedback","score","_output","_context","passed","assertScratchpadState","scratchpad","all","key","expectedValue","assertDerivedValues","derived","sortedStringify","v"],"mappings":"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","file":"testing.cjs","sourcesContent":["/**\n * Directive AI Testing Utilities\n *\n * Provides testing helpers for:\n * - Mock agent runners with configurable responses\n * - Guardrail testing with assertions\n * - Approval workflow simulation\n * - Snapshot testing for constraint evaluation\n *\n * @example\n * ```typescript\n * import { createMockAgentRunner, testGuardrail, createApprovalSimulator } from '@directive-run/ai/testing';\n *\n * describe('MyOrchestrator', () => {\n * it('should block PII in input', async () => {\n * const result = await testGuardrail(createPIIGuardrail(), {\n * input: 'My SSN is 123-45-6789',\n * });\n * expect(result.passed).toBe(false);\n * expect(result.reason).toContain('PII');\n * });\n * });\n * ```\n */\n\nimport {\n type AgentOrchestrator,\n type OrchestratorOptions,\n createAgentOrchestrator,\n} from \"./agent-orchestrator.js\";\nimport type {\n BreakpointModifications,\n BreakpointRequest,\n} from \"./breakpoints.js\";\nimport {\n type Checkpoint,\n type CheckpointStore,\n InMemoryCheckpointStore,\n} from \"./checkpoint.js\";\nimport {\n type MultiAgentOrchestrator,\n type MultiAgentOrchestratorOptions,\n type TaskRegistration,\n createMultiAgentOrchestrator,\n} from \"./multi-agent-orchestrator.js\";\nimport type { MultiplexedStreamChunk } from \"./streaming.js\";\nimport type {\n AgentLike,\n AgentRunner,\n ApprovalRequest,\n GuardrailContext,\n GuardrailFn,\n GuardrailResult,\n InputGuardrailData,\n Message,\n OutputGuardrailData,\n RunOptions,\n RunResult,\n ToolCall,\n ToolCallGuardrailData,\n} from \"./types.js\";\n\n// ============================================================================\n// Mock Agent Runner\n// ============================================================================\n\n/** Configuration for mock agent responses */\nexport interface MockAgentConfig<T = unknown> {\n /** Final output to return */\n output: T;\n /** Messages to emit during run */\n messages?: Message[];\n /** Tool calls to emit during run */\n toolCalls?: ToolCall[];\n /** Total tokens to report */\n totalTokens?: number;\n /** Delay before responding (ms) */\n delay?: number;\n /** Error to throw instead of returning */\n error?: Error;\n /** Function to generate dynamic responses */\n generate?: (input: string, agent: AgentLike) => Partial<MockAgentConfig<T>>;\n}\n\n/** Mock agent runner options */\nexport interface MockAgentRunnerOptions {\n /** Default response for unmatched agents */\n defaultResponse?: MockAgentConfig;\n /** Responses keyed by agent name */\n responses?: Record<string, MockAgentConfig>;\n /** Record all calls for assertions */\n recordCalls?: boolean;\n /** Callback for each run */\n onRun?: (agent: AgentLike, input: string) => void;\n}\n\n/** Recorded call for assertions */\nexport interface RecordedCall {\n agent: AgentLike;\n input: string;\n options?: RunOptions;\n timestamp: number;\n}\n\n/** Mock agent runner instance */\nexport interface MockAgentRunner {\n /** The run function to pass to orchestrator */\n run: AgentRunner;\n /** Get all recorded calls */\n getCalls(): RecordedCall[];\n /** Get calls for a specific agent */\n getCallsFor(agentName: string): RecordedCall[];\n /** Clear recorded calls */\n clearCalls(): void;\n /** Set response for an agent */\n setResponse<T>(agentName: string, config: MockAgentConfig<T>): void;\n /** Set default response */\n setDefaultResponse<T>(config: MockAgentConfig<T>): void;\n}\n\n/**\n * Create a mock agent runner for testing.\n *\n * @example\n * ```typescript\n * const mock = createMockAgentRunner({\n * responses: {\n * 'my-agent': {\n * output: 'Hello, world!',\n * totalTokens: 100,\n * },\n * },\n * });\n *\n * const orchestrator = createAgentOrchestrator({ runner: mock.run });\n * const result = await orchestrator.run(myAgent, 'Hi');\n *\n * expect(result.output).toBe('Hello, world!');\n * expect(mock.getCalls()).toHaveLength(1);\n * ```\n */\nexport function createMockAgentRunner(\n options: MockAgentRunnerOptions = {},\n): MockAgentRunner {\n const {\n defaultResponse = { output: \"mock response\", totalTokens: 10 },\n responses = {},\n recordCalls = true,\n onRun,\n } = options;\n\n const calls: RecordedCall[] = [];\n const responseMap = new Map<string, MockAgentConfig>(\n Object.entries(responses),\n );\n let currentDefault = defaultResponse;\n\n const run: AgentRunner = async <T>(\n agent: AgentLike,\n input: string,\n runOptions?: RunOptions,\n ): Promise<RunResult<T>> => {\n onRun?.(agent, input);\n\n if (recordCalls) {\n calls.push({\n agent,\n input,\n options: runOptions,\n timestamp: Date.now(),\n });\n }\n\n // Get config for this agent\n let config = responseMap.get(agent.name) ?? currentDefault;\n\n // Apply dynamic generation if present\n if (config.generate) {\n const generated = config.generate(input, agent);\n config = { ...config, ...generated };\n }\n\n // Handle error case\n if (config.error) {\n throw config.error;\n }\n\n // Apply delay\n if (config.delay && config.delay > 0) {\n await new Promise((resolve) => setTimeout(resolve, config.delay));\n }\n\n // Emit messages\n const messages = config.messages ?? [];\n for (const message of messages) {\n runOptions?.onMessage?.(message);\n }\n\n // Emit tool calls\n const toolCalls = config.toolCalls ?? [];\n for (const toolCall of toolCalls) {\n runOptions?.onToolCall?.(toolCall);\n }\n\n return {\n output: config.output as T,\n messages,\n toolCalls,\n totalTokens: config.totalTokens ?? 10,\n };\n };\n\n return {\n run,\n getCalls: () => [...calls],\n getCallsFor: (name) => calls.filter((c) => c.agent.name === name),\n clearCalls: () => (calls.length = 0),\n setResponse: (name, config) => responseMap.set(name, config),\n setDefaultResponse: (config) => (currentDefault = config),\n };\n}\n\n// ============================================================================\n// Guardrail Testing\n// ============================================================================\n\n/** Test input for guardrail testing */\nexport type GuardrailTestInput<T> = T extends InputGuardrailData\n ? { input: string; agentName?: string }\n : T extends OutputGuardrailData\n ? {\n output: unknown;\n agentName?: string;\n input?: string;\n messages?: Message[];\n }\n : T extends ToolCallGuardrailData\n ? { toolCall: ToolCall; agentName?: string; input?: string }\n : Partial<T>;\n\n/** Extended guardrail result with test assertions */\nexport interface GuardrailTestResult extends GuardrailResult {\n /** Time taken to evaluate (ms) */\n duration: number;\n /** The data that was tested */\n testedData: unknown;\n /** Assert that the guardrail passed */\n assertPassed(): void;\n /** Assert that the guardrail failed */\n assertFailed(expectedReason?: string | RegExp): void;\n /** Assert that transformation occurred */\n assertTransformed(expected?: unknown): void;\n}\n\n/**\n * Test a guardrail with assertions.\n *\n * @example\n * ```typescript\n * // Test PII detection\n * const result = await testGuardrail(createPIIGuardrail(), {\n * input: 'My SSN is 123-45-6789',\n * });\n * result.assertFailed(/PII/);\n *\n * // Test input transformation\n * const redactResult = await testGuardrail(createPIIGuardrail({ redact: true }), {\n * input: 'My SSN is 123-45-6789',\n * });\n * redactResult.assertPassed();\n * redactResult.assertTransformed();\n * ```\n */\nexport async function testGuardrail<T>(\n guardrail: GuardrailFn<T>,\n testInput: GuardrailTestInput<T>,\n context?: Partial<GuardrailContext>,\n): Promise<GuardrailTestResult> {\n // Build full data object\n const data = {\n agentName: \"test-agent\",\n input: \"\",\n ...testInput,\n } as unknown as T;\n\n // Build context\n const fullContext: GuardrailContext = {\n agentName: (testInput as { agentName?: string }).agentName ?? \"test-agent\",\n input: (testInput as { input?: string }).input ?? \"\",\n facts: context?.facts ?? {},\n ...context,\n };\n\n const start = Date.now();\n const result = await guardrail(data, fullContext);\n const duration = Date.now() - start;\n\n return {\n ...result,\n duration,\n testedData: data,\n assertPassed() {\n if (!result.passed) {\n throw new Error(\n `Expected guardrail to pass, but it failed: ${result.reason}`,\n );\n }\n },\n assertFailed(expectedReason) {\n if (result.passed) {\n throw new Error(\"Expected guardrail to fail, but it passed\");\n }\n if (expectedReason !== undefined) {\n if (\n typeof expectedReason === \"string\" &&\n !result.reason?.includes(expectedReason)\n ) {\n throw new Error(\n `Expected failure reason to include \"${expectedReason}\", got: ${result.reason}`,\n );\n }\n if (\n expectedReason instanceof RegExp &&\n !expectedReason.test(result.reason ?? \"\")\n ) {\n throw new Error(\n `Expected failure reason to match ${expectedReason}, got: ${result.reason}`,\n );\n }\n }\n },\n assertTransformed(expected) {\n if (result.transformed === undefined) {\n throw new Error(\n \"Expected guardrail to transform input, but no transformation occurred\",\n );\n }\n if (expected !== undefined && result.transformed !== expected) {\n throw new Error(\n `Expected transformation to be ${JSON.stringify(expected)}, got: ${JSON.stringify(result.transformed)}`,\n );\n }\n },\n };\n}\n\n/**\n * Test multiple inputs against a guardrail.\n *\n * @example\n * ```typescript\n * const results = await testGuardrailBatch(createPIIGuardrail(), [\n * { input: 'Hello world', expect: 'pass' },\n * { input: 'My SSN is 123-45-6789', expect: 'fail' },\n * { input: 'Email: test@example.com', expect: 'fail' },\n * ]);\n *\n * expect(results.allPassed()).toBe(true);\n * ```\n */\nexport async function testGuardrailBatch<T>(\n guardrail: GuardrailFn<T>,\n testCases: Array<{\n input: GuardrailTestInput<T>;\n expect: \"pass\" | \"fail\" | \"transform\";\n context?: Partial<GuardrailContext>;\n }>,\n): Promise<{\n results: GuardrailTestResult[];\n allPassed(): boolean;\n failures(): Array<{\n index: number;\n expected: string;\n actual: GuardrailTestResult;\n }>;\n}> {\n const results: GuardrailTestResult[] = [];\n const failures: Array<{\n index: number;\n expected: string;\n actual: GuardrailTestResult;\n }> = [];\n\n for (let i = 0; i < testCases.length; i++) {\n const testCase = testCases[i]!;\n const result = await testGuardrail(\n guardrail,\n testCase.input,\n testCase.context,\n );\n results.push(result);\n\n const actualOutcome = !result.passed\n ? \"fail\"\n : result.transformed !== undefined\n ? \"transform\"\n : \"pass\";\n\n if (actualOutcome !== testCase.expect) {\n failures.push({ index: i, expected: testCase.expect, actual: result });\n }\n }\n\n return {\n results,\n allPassed: () => failures.length === 0,\n failures: () => failures,\n };\n}\n\n// ============================================================================\n// Approval Simulation\n// ============================================================================\n\n/** Approval simulator options */\nexport interface ApprovalSimulatorOptions {\n /** Auto-approve requests matching this predicate */\n autoApprove?: (request: ApprovalRequest) => boolean;\n /** Auto-reject requests matching this predicate */\n autoReject?: (request: ApprovalRequest) => boolean | string;\n /** Delay before auto-approval/rejection (ms) */\n delay?: number;\n /** Record all requests for assertions */\n recordRequests?: boolean;\n}\n\n/** Approval simulator instance */\nexport interface ApprovalSimulator {\n /** Handle an approval request */\n handle(request: ApprovalRequest): Promise<\"approved\" | \"rejected\">;\n /** Get all recorded requests */\n getRequests(): ApprovalRequest[];\n /** Clear recorded requests */\n clearRequests(): void;\n /** Manually approve a request */\n approve(requestId: string): void;\n /** Manually reject a request */\n reject(requestId: string, reason?: string): void;\n /** Wait for a specific request */\n waitForRequest(\n predicate: (req: ApprovalRequest) => boolean,\n timeoutMs?: number,\n ): Promise<ApprovalRequest>;\n}\n\n/**\n * Create an approval simulator for testing approval workflows.\n *\n * @example\n * ```typescript\n * const simulator = createApprovalSimulator({\n * autoApprove: (req) => req.type === 'tool_call' && req.data.name === 'search',\n * autoReject: (req) => req.type === 'tool_call' && req.data.name === 'delete',\n * });\n *\n * // Use in tests\n * orchestrator.onApprovalRequest = (req) => simulator.handle(req);\n * ```\n */\nexport function createApprovalSimulator(\n options: ApprovalSimulatorOptions = {},\n): ApprovalSimulator {\n const { autoApprove, autoReject, delay = 0, recordRequests = true } = options;\n\n const requests: ApprovalRequest[] = [];\n const pendingRequests = new Map<\n string,\n {\n request: ApprovalRequest;\n resolve: (decision: \"approved\" | \"rejected\") => void;\n }\n >();\n const requestWaiters: Array<{\n predicate: (req: ApprovalRequest) => boolean;\n resolve: (req: ApprovalRequest) => void;\n }> = [];\n\n return {\n async handle(request: ApprovalRequest): Promise<\"approved\" | \"rejected\"> {\n if (recordRequests) {\n requests.push(request);\n }\n\n // Notify waiters (resolve matching ones, remove them from array)\n for (let i = requestWaiters.length - 1; i >= 0; i--) {\n const waiter = requestWaiters[i]!;\n if (waiter.predicate(request)) {\n requestWaiters.splice(i, 1);\n waiter.resolve(request);\n }\n }\n\n // Apply delay\n if (delay > 0) {\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n\n // Check auto-reject first (security-first)\n if (autoReject) {\n const rejectResult = autoReject(request);\n if (rejectResult) {\n return \"rejected\";\n }\n }\n\n // Check auto-approve\n if (autoApprove?.(request)) {\n return \"approved\";\n }\n\n // Wait for manual decision\n return new Promise((resolve) => {\n pendingRequests.set(request.id, { request, resolve });\n });\n },\n\n getRequests: () => [...requests],\n clearRequests: () => (requests.length = 0),\n\n approve(requestId: string) {\n const pending = pendingRequests.get(requestId);\n if (pending) {\n pending.resolve(\"approved\");\n pendingRequests.delete(requestId);\n }\n },\n\n reject(requestId: string, reason?: string) {\n const pending = pendingRequests.get(requestId);\n if (pending) {\n pending.resolve(\"rejected\");\n pendingRequests.delete(requestId);\n // Store reason on the request for test assertions\n const request = requests.find((r) => r.id === requestId);\n if (request) {\n (\n request as ApprovalRequest & { rejectionReason?: string }\n ).rejectionReason = reason;\n }\n }\n },\n\n waitForRequest(predicate, timeoutMs = 5000): Promise<ApprovalRequest> {\n // Check existing requests first\n const existing = requests.find(predicate);\n if (existing) {\n return Promise.resolve(existing);\n }\n\n // Wait for future request\n return new Promise((resolve, reject) => {\n const entry = {\n predicate,\n resolve: (req: ApprovalRequest) => {\n clearTimeout(timeout);\n resolve(req);\n },\n };\n\n const timeout = setTimeout(() => {\n const idx = requestWaiters.indexOf(entry);\n if (idx >= 0) {\n requestWaiters.splice(idx, 1);\n }\n reject(new Error(\"Timeout waiting for approval request\"));\n }, timeoutMs);\n\n requestWaiters.push(entry);\n });\n },\n };\n}\n\n// ============================================================================\n// Test Orchestrator Factory\n// ============================================================================\n\n/** Options for test orchestrator */\nexport interface TestOrchestratorOptions<F extends Record<string, unknown>>\n extends Omit<OrchestratorOptions<F>, \"runner\"> {\n /** Mock responses for agents */\n mockResponses?: Record<string, MockAgentConfig>;\n /** Default mock response */\n defaultMockResponse?: MockAgentConfig;\n}\n\n/** Test orchestrator with additional testing utilities */\nexport interface TestOrchestrator<F extends Record<string, unknown>>\n extends AgentOrchestrator<F> {\n /** The mock runner */\n mockRunner: MockAgentRunner;\n /** Approval simulator */\n approvalSimulator: ApprovalSimulator;\n /** Get recorded agent calls */\n getCalls(): RecordedCall[];\n /** Get approval requests */\n getApprovalRequests(): ApprovalRequest[];\n /** Reset all state */\n resetAll(): void;\n}\n\n/**\n * Create a test orchestrator with mocking and simulation built in.\n *\n * @example\n * ```typescript\n * const test = createTestOrchestrator({\n * mockResponses: {\n * 'my-agent': { output: 'test response' },\n * },\n * constraints: {\n * needsApproval: {\n * when: () => true,\n * require: { type: 'NEED_APPROVAL' },\n * },\n * },\n * });\n *\n * await test.run(myAgent, 'Hello');\n * expect(test.getCalls()).toHaveLength(1);\n * ```\n */\nexport function createTestOrchestrator<\n F extends Record<string, unknown> = Record<string, never>,\n>(options: TestOrchestratorOptions<F> = {}): TestOrchestrator<F> {\n const { mockResponses, defaultMockResponse, ...orchestratorOptions } =\n options;\n\n const mockRunner = createMockAgentRunner({\n responses: mockResponses,\n defaultResponse: defaultMockResponse,\n });\n\n const approvalSimulator = createApprovalSimulator();\n\n const orchestrator = createAgentOrchestrator<F>({\n ...orchestratorOptions,\n runner: mockRunner.run,\n onApprovalRequest: (req) => {\n approvalSimulator.handle(req);\n orchestratorOptions.onApprovalRequest?.(req);\n },\n });\n\n // Use Object.create to preserve getters instead of { ...orchestrator } which evaluates them once\n const testOrchestrator = Object.create(orchestrator) as TestOrchestrator<F>;\n testOrchestrator.mockRunner = mockRunner;\n testOrchestrator.approvalSimulator = approvalSimulator;\n testOrchestrator.getCalls = () => mockRunner.getCalls();\n testOrchestrator.getApprovalRequests = () => approvalSimulator.getRequests();\n testOrchestrator.resetAll = () => {\n orchestrator.reset();\n mockRunner.clearCalls();\n approvalSimulator.clearRequests();\n };\n\n return testOrchestrator;\n}\n\n// ============================================================================\n// Snapshot Testing\n// ============================================================================\n\n/** Constraint evaluation snapshot */\nexport interface ConstraintSnapshot {\n constraintId: string;\n triggered: boolean;\n requirement?: unknown;\n facts: Record<string, unknown>;\n timestamp: number;\n}\n\n/**\n * Create a constraint evaluation recorder for snapshot testing.\n *\n * @example\n * ```typescript\n * const recorder = createConstraintRecorder();\n * const orchestrator = createAgentOrchestrator({\n * plugins: [recorder.plugin],\n * });\n *\n * await orchestrator.run(agent, 'Hello');\n *\n * expect(recorder.getSnapshots()).toMatchSnapshot();\n * ```\n */\nexport function createConstraintRecorder(): {\n plugin: {\n name: string;\n onRequirementCreated: (data: {\n constraintId: string;\n requirement: unknown;\n facts: unknown;\n }) => void;\n };\n getSnapshots(): ConstraintSnapshot[];\n clearSnapshots(): void;\n} {\n const snapshots: ConstraintSnapshot[] = [];\n\n return {\n plugin: {\n name: \"constraint-recorder\",\n onRequirementCreated(data) {\n snapshots.push({\n constraintId: data.constraintId,\n triggered: true,\n requirement: data.requirement,\n facts: data.facts as Record<string, unknown>,\n timestamp: Date.now(),\n });\n },\n },\n getSnapshots: () => [...snapshots],\n clearSnapshots: () => (snapshots.length = 0),\n };\n}\n\n// ============================================================================\n// Assertion Helpers\n// ============================================================================\n\n/**\n * Assert that an orchestrator has specific state.\n *\n * @example\n * ```typescript\n * assertOrchestratorState(orchestrator, {\n * agentStatus: 'completed',\n * tokenUsage: { min: 0, max: 1000 },\n * pendingApprovals: 0,\n * });\n * ```\n */\nexport function assertOrchestratorState<F extends Record<string, unknown>>(\n orchestrator: AgentOrchestrator<F>,\n expected: {\n agentStatus?: \"idle\" | \"running\" | \"paused\" | \"completed\" | \"error\";\n tokenUsage?: { min?: number; max?: number; exact?: number };\n pendingApprovals?: number;\n conversationLength?: { min?: number; max?: number; exact?: number };\n },\n): void {\n const state = orchestrator.facts;\n\n if (\n expected.agentStatus !== undefined &&\n state.agent.status !== expected.agentStatus\n ) {\n throw new Error(\n `Expected agent status to be \"${expected.agentStatus}\", got \"${state.agent.status}\"`,\n );\n }\n\n if (expected.tokenUsage !== undefined) {\n const { min, max, exact } = expected.tokenUsage;\n if (exact !== undefined && state.agent.tokenUsage !== exact) {\n throw new Error(\n `Expected token usage to be exactly ${exact}, got ${state.agent.tokenUsage}`,\n );\n }\n if (min !== undefined && state.agent.tokenUsage < min) {\n throw new Error(\n `Expected token usage to be at least ${min}, got ${state.agent.tokenUsage}`,\n );\n }\n if (max !== undefined && state.agent.tokenUsage > max) {\n throw new Error(\n `Expected token usage to be at most ${max}, got ${state.agent.tokenUsage}`,\n );\n }\n }\n\n if (\n expected.pendingApprovals !== undefined &&\n state.approval.pending.length !== expected.pendingApprovals\n ) {\n throw new Error(\n `Expected ${expected.pendingApprovals} pending approvals, got ${state.approval.pending.length}`,\n );\n }\n\n if (expected.conversationLength !== undefined) {\n const { min, max, exact } = expected.conversationLength;\n const len = state.conversation.length;\n if (exact !== undefined && len !== exact) {\n throw new Error(\n `Expected conversation length to be exactly ${exact}, got ${len}`,\n );\n }\n if (min !== undefined && len < min) {\n throw new Error(\n `Expected conversation length to be at least ${min}, got ${len}`,\n );\n }\n if (max !== undefined && len > max) {\n throw new Error(\n `Expected conversation length to be at most ${max}, got ${len}`,\n );\n }\n }\n}\n\n// ============================================================================\n// Fake Timers Support\n// ============================================================================\n\n/**\n * Create a time controller for testing time-dependent behavior.\n *\n * @example\n * ```typescript\n * const time = createTimeController();\n *\n * // Override Date.now\n * const originalNow = Date.now;\n * Date.now = () => time.now();\n *\n * time.advance(1000); // Advance 1 second\n *\n * // Restore\n * Date.now = originalNow;\n * ```\n */\nexport function createTimeController(startTime = Date.now()): {\n now(): number;\n advance(ms: number): void;\n set(time: number): void;\n reset(): void;\n} {\n let currentTime = startTime;\n const initial = startTime;\n\n return {\n now: () => currentTime,\n advance: (ms) => {\n currentTime += ms;\n },\n set: (time) => {\n currentTime = time;\n },\n reset: () => {\n currentTime = initial;\n },\n };\n}\n\n// ============================================================================\n// Multi-Agent Test Orchestrator\n// ============================================================================\n\n/** Options for test multi-agent orchestrator */\nexport interface TestMultiAgentOrchestratorOptions\n extends Omit<MultiAgentOrchestratorOptions, \"runner\"> {\n /** Mock responses keyed by agent ID — internally mapped to agent names for the mock runner */\n mockResponses?: Record<string, MockAgentConfig>;\n /** Default mock response for unmatched agents */\n defaultMockResponse?: MockAgentConfig;\n /** Mock tasks keyed by task ID — auto-generates TaskRegistration wrappers */\n mockTasks?: Record<\n string,\n { output: unknown; delay?: number; shouldError?: boolean }\n >;\n}\n\n/** Test multi-agent orchestrator with additional testing utilities */\nexport interface TestMultiAgentOrchestrator extends MultiAgentOrchestrator {\n /** The mock runner */\n mockRunner: MockAgentRunner;\n /** Approval simulator */\n approvalSimulator: ApprovalSimulator;\n /** Get recorded agent calls */\n getCalls(): RecordedCall[];\n /** Get approval requests */\n getApprovalRequests(): ApprovalRequest[];\n /** Reset all state */\n resetAll(): void;\n}\n\n/**\n * Create a test multi-agent orchestrator with mocking and simulation built in.\n *\n * @example\n * ```typescript\n * const test = createTestMultiAgentOrchestrator({\n * agents: {\n * researcher: { agent: { name: 'researcher' } },\n * writer: { agent: { name: 'writer' } },\n * },\n * mockResponses: {\n * researcher: { output: 'Research results', totalTokens: 100 },\n * writer: { output: 'Written article', totalTokens: 200 },\n * },\n * });\n *\n * const result = await test.runAgent('researcher', 'What is AI?');\n * expect(result.output).toBe('Research results');\n * expect(test.getCalls()).toHaveLength(1);\n * ```\n */\nexport function createTestMultiAgentOrchestrator(\n options: TestMultiAgentOrchestratorOptions,\n): TestMultiAgentOrchestrator {\n const {\n mockResponses = {},\n defaultMockResponse,\n mockTasks: mockTaskConfigs,\n ...orchestratorOptions\n } = options;\n\n // Convert mockTasks into real TaskRegistration entries\n if (mockTaskConfigs) {\n const existingTasks = orchestratorOptions.tasks ?? {};\n for (const [taskId, config] of Object.entries(mockTaskConfigs)) {\n if (!existingTasks[taskId]) {\n existingTasks[taskId] = createMockTask(config.output, {\n delay: config.delay,\n shouldError: config.shouldError,\n });\n }\n }\n orchestratorOptions.tasks = existingTasks;\n }\n\n // Map mock responses by agent name (from agent registration)\n const responsesByName: Record<string, MockAgentConfig> = {};\n for (const [agentId, config] of Object.entries(mockResponses)) {\n const registration = orchestratorOptions.agents[agentId];\n if (registration) {\n responsesByName[registration.agent.name] = config;\n }\n }\n\n const mockRunner = createMockAgentRunner({\n responses: responsesByName,\n defaultResponse: defaultMockResponse,\n });\n\n const approvalSimulator = createApprovalSimulator();\n\n const orchestrator = createMultiAgentOrchestrator({\n ...orchestratorOptions,\n runner: mockRunner.run,\n onApprovalRequest: (req) => {\n approvalSimulator.handle(req);\n orchestratorOptions.onApprovalRequest?.(req);\n },\n });\n\n // Use Object.create to preserve getters (derived, scratchpad, timeline, etc.)\n // instead of { ...orchestrator } which evaluates getters at spread time\n const testOrchestrator = Object.create(\n orchestrator,\n ) as TestMultiAgentOrchestrator;\n testOrchestrator.mockRunner = mockRunner;\n testOrchestrator.approvalSimulator = approvalSimulator;\n testOrchestrator.getCalls = () => mockRunner.getCalls();\n testOrchestrator.getApprovalRequests = () => approvalSimulator.getRequests();\n testOrchestrator.resetAll = () => {\n orchestrator.reset();\n mockRunner.clearCalls();\n approvalSimulator.clearRequests();\n };\n\n return testOrchestrator;\n}\n\n// ============================================================================\n// Multi-Agent Assertion Helpers\n// ============================================================================\n\n/**\n * Assert that a multi-agent orchestrator has specific state.\n *\n * @example\n * ```typescript\n * assertMultiAgentState(orchestrator, {\n * agentStatus: { researcher: 'completed', writer: 'idle' },\n * globalTokens: { min: 0, max: 1000 },\n * pendingHandoffs: 0,\n * });\n * ```\n */\nexport function assertMultiAgentState(\n orchestrator: MultiAgentOrchestrator,\n expected: {\n agentStatus?: Record<string, \"idle\" | \"running\" | \"completed\" | \"error\">;\n taskStatus?: Record<string, string>;\n totalTokens?: { agentId?: string; min?: number; max?: number };\n globalTokens?: { min?: number; max?: number };\n pendingHandoffs?: number;\n },\n): void {\n if (expected.taskStatus) {\n for (const [taskId, expectedStatus] of Object.entries(\n expected.taskStatus,\n )) {\n const state = orchestrator.getTaskState(taskId);\n if (!state) {\n throw new Error(\n `Expected task \"${taskId}\" to exist, but it was not found`,\n );\n }\n if (state.status !== expectedStatus) {\n throw new Error(\n `Expected task \"${taskId}\" status to be \"${expectedStatus}\", got \"${state.status}\"`,\n );\n }\n }\n }\n\n if (expected.agentStatus) {\n for (const [agentId, expectedStatus] of Object.entries(\n expected.agentStatus,\n )) {\n const state = orchestrator.getAgentState(agentId);\n if (!state) {\n throw new Error(\n `Expected agent \"${agentId}\" to exist, but it was not found`,\n );\n }\n if (state.status !== expectedStatus) {\n throw new Error(\n `Expected agent \"${agentId}\" status to be \"${expectedStatus}\", got \"${state.status}\"`,\n );\n }\n }\n }\n\n if (expected.totalTokens) {\n const { agentId, min, max } = expected.totalTokens;\n if (agentId) {\n const state = orchestrator.getAgentState(agentId);\n if (!state) {\n throw new Error(\n `Expected agent \"${agentId}\" to exist, but it was not found`,\n );\n }\n if (min !== undefined && state.totalTokens < min) {\n throw new Error(\n `Expected agent \"${agentId}\" tokens to be at least ${min}, got ${state.totalTokens}`,\n );\n }\n if (max !== undefined && state.totalTokens > max) {\n throw new Error(\n `Expected agent \"${agentId}\" tokens to be at most ${max}, got ${state.totalTokens}`,\n );\n }\n } else {\n const allStates = orchestrator.getAllAgentStates();\n const total = Object.values(allStates).reduce(\n (sum, s) => sum + s.totalTokens,\n 0,\n );\n if (min !== undefined && total < min) {\n throw new Error(\n `Expected total tokens to be at least ${min}, got ${total}`,\n );\n }\n if (max !== undefined && total > max) {\n throw new Error(\n `Expected total tokens to be at most ${max}, got ${total}`,\n );\n }\n }\n }\n\n if (expected.globalTokens) {\n const { min, max } = expected.globalTokens;\n const total = orchestrator.totalTokens;\n if (min !== undefined && total < min) {\n throw new Error(\n `Expected global tokens to be at least ${min}, got ${total}`,\n );\n }\n if (max !== undefined && total > max) {\n throw new Error(\n `Expected global tokens to be at most ${max}, got ${total}`,\n );\n }\n }\n\n if (expected.pendingHandoffs !== undefined) {\n const pendingCount = orchestrator.getPendingHandoffs().length;\n if (pendingCount !== expected.pendingHandoffs) {\n throw new Error(\n `Expected ${expected.pendingHandoffs} pending handoffs, got ${pendingCount}`,\n );\n }\n }\n}\n\n// ============================================================================\n// Mock Task Helpers\n// ============================================================================\n\n/**\n * Create a mock TaskRegistration for testing.\n *\n * @example\n * ```typescript\n * const task = createMockTask({ result: \"processed\" }, { delay: 100 });\n * const orchestrator = createTestMultiAgentOrchestrator({\n * agents: { writer: { agent: { name: \"writer\" } } },\n * tasks: { process: task },\n * });\n * ```\n */\nexport function createMockTask(\n output: unknown,\n options?: {\n delay?: number;\n shouldError?: boolean;\n label?: string;\n description?: string;\n },\n): TaskRegistration {\n return {\n run: async (_input: string, signal: AbortSignal) => {\n if (signal.aborted) {\n throw new Error(\"Task aborted\");\n }\n if (options?.delay && options.delay > 0) {\n await new Promise<void>((resolve, reject) => {\n const timer = setTimeout(resolve, options.delay);\n signal.addEventListener(\n \"abort\",\n () => {\n clearTimeout(timer);\n reject(new Error(\"Task aborted\"));\n },\n { once: true },\n );\n });\n }\n\n if (options?.shouldError) {\n throw new Error(\"Mock task error\");\n }\n\n return output;\n },\n label: options?.label ?? \"Mock Task\",\n description: options?.description,\n };\n}\n\n// ============================================================================\n// DAG Testing Helpers\n// ============================================================================\n\nimport { dag } from \"./multi-agent-orchestrator.js\";\nimport type {\n DagExecutionContext,\n DagNode,\n DagNodeStatus,\n DagPattern,\n} from \"./types.js\";\n\n/**\n * Create a test DAG pattern from a simplified node spec.\n *\n * @example\n * ```typescript\n * const pattern = createTestDag({\n * A: { handler: \"researcher\" },\n * B: { handler: \"writer\", deps: [\"A\"] },\n * C: { handler: \"reviewer\", deps: [\"B\"] },\n * });\n * ```\n */\nexport function createTestDag<T = unknown>(\n nodes: Record<\n string,\n Pick<\n DagNode,\n \"handler\" | \"deps\" | \"when\" | \"transform\" | \"timeout\" | \"priority\"\n >\n >,\n merge?: (context: DagExecutionContext) => T | Promise<T>,\n options?: {\n timeout?: number;\n maxConcurrent?: number;\n onNodeError?: \"fail\" | \"skip-downstream\" | \"continue\";\n },\n): DagPattern<T> {\n const defaultMerge = (context: DagExecutionContext) =>\n context.outputs as unknown as T;\n\n return dag<T>(nodes, merge ?? defaultMerge, options);\n}\n\n/**\n * Assert that a DAG execution produced the expected node statuses.\n *\n * @example\n * ```typescript\n * assertDagExecution(context, {\n * nodeStatuses: { A: \"completed\", B: \"completed\", C: \"skipped\" },\n * completedNodes: [\"A\", \"B\"],\n * skippedNodes: [\"C\"],\n * });\n * ```\n */\nexport function assertDagExecution(\n context: DagExecutionContext,\n expected: {\n nodeStatuses?: Record<string, DagNodeStatus>;\n completedNodes?: string[];\n skippedNodes?: string[];\n errorNodes?: string[];\n outputContains?: Record<string, unknown>;\n },\n): void {\n if (expected.nodeStatuses) {\n for (const [nodeId, expectedStatus] of Object.entries(\n expected.nodeStatuses,\n )) {\n const actual = context.statuses[nodeId];\n if (actual !== expectedStatus) {\n throw new Error(\n `Expected node \"${nodeId}\" status to be \"${expectedStatus}\", got \"${actual}\"`,\n );\n }\n }\n }\n\n if (expected.completedNodes) {\n for (const nodeId of expected.completedNodes) {\n if (context.statuses[nodeId] !== \"completed\") {\n throw new Error(\n `Expected node \"${nodeId}\" to be completed, got \"${context.statuses[nodeId]}\"`,\n );\n }\n }\n }\n\n if (expected.skippedNodes) {\n for (const nodeId of expected.skippedNodes) {\n if (context.statuses[nodeId] !== \"skipped\") {\n throw new Error(\n `Expected node \"${nodeId}\" to be skipped, got \"${context.statuses[nodeId]}\"`,\n );\n }\n }\n }\n\n if (expected.errorNodes) {\n for (const nodeId of expected.errorNodes) {\n if (context.statuses[nodeId] !== \"error\") {\n throw new Error(\n `Expected node \"${nodeId}\" to be error, got \"${context.statuses[nodeId]}\"`,\n );\n }\n }\n }\n\n if (expected.outputContains) {\n for (const [nodeId, expectedOutput] of Object.entries(\n expected.outputContains,\n )) {\n const actual = context.outputs[nodeId];\n if (actual !== expectedOutput) {\n throw new Error(\n `Expected node \"${nodeId}\" output to be ${JSON.stringify(expectedOutput)}, got ${JSON.stringify(actual)}`,\n );\n }\n }\n }\n}\n\n// ============================================================================\n// Debug Timeline Testing Helpers\n// ============================================================================\n\nimport { type DebugTimeline, createDebugTimeline } from \"./debug-timeline.js\";\nimport type { DebugEvent, DebugEventType } from \"./types.js\";\n\n/**\n * Create a test debug timeline pre-populated with events.\n *\n * @example\n * ```typescript\n * const timeline = createTestTimeline([\n * { type: \"agent_start\", agentId: \"researcher\", inputLength: 42 },\n * { type: \"agent_complete\", agentId: \"researcher\", outputLength: 100, durationMs: 500, totalTokens: 200 },\n * ]);\n *\n * expect(timeline.getEventsForAgent(\"researcher\")).toHaveLength(2);\n * ```\n */\nexport function createTestTimeline(\n events?: Array<Partial<DebugEvent> & { type: DebugEventType }>,\n options?: { maxEvents?: number },\n): DebugTimeline {\n const timeline = createDebugTimeline({\n maxEvents: options?.maxEvents ?? 500,\n });\n\n if (events) {\n for (const event of events) {\n timeline.record({\n timestamp: Date.now(),\n snapshotId: null,\n agentId: \"\",\n ...event,\n } as Omit<DebugEvent, \"id\">);\n }\n }\n\n return timeline;\n}\n\n/**\n * Assert that a debug timeline contains expected events.\n *\n * @example\n * ```typescript\n * assertTimelineEvents(timeline, {\n * totalEvents: 5,\n * eventTypes: [\"agent_start\", \"guardrail_check\", \"agent_complete\"],\n * agentEvents: { researcher: 3, writer: 2 },\n * hasType: \"guardrail_check\",\n * });\n * ```\n */\nexport function assertTimelineEvents(\n timeline: DebugTimeline,\n expected: {\n totalEvents?: number;\n minEvents?: number;\n maxEvents?: number;\n eventTypes?: DebugEventType[];\n agentEvents?: Record<string, number>;\n hasType?: DebugEventType;\n doesNotHaveType?: DebugEventType;\n },\n): void {\n const events = timeline.getEvents();\n\n if (\n expected.totalEvents !== undefined &&\n events.length !== expected.totalEvents\n ) {\n throw new Error(\n `Expected ${expected.totalEvents} timeline events, got ${events.length}`,\n );\n }\n\n if (expected.minEvents !== undefined && events.length < expected.minEvents) {\n throw new Error(\n `Expected at least ${expected.minEvents} timeline events, got ${events.length}`,\n );\n }\n\n if (expected.maxEvents !== undefined && events.length > expected.maxEvents) {\n throw new Error(\n `Expected at most ${expected.maxEvents} timeline events, got ${events.length}`,\n );\n }\n\n if (expected.eventTypes) {\n for (const type of expected.eventTypes) {\n const found = events.some((e) => e.type === type);\n if (!found) {\n throw new Error(\n `Expected timeline to contain event of type \"${type}\", but none found`,\n );\n }\n }\n }\n\n if (expected.agentEvents) {\n for (const [agentId, expectedCount] of Object.entries(\n expected.agentEvents,\n )) {\n const actual = timeline.getEventsForAgent(agentId).length;\n if (actual !== expectedCount) {\n throw new Error(\n `Expected ${expectedCount} events for agent \"${agentId}\", got ${actual}`,\n );\n }\n }\n }\n\n if (expected.hasType) {\n const found = events.some((e) => e.type === expected.hasType);\n if (!found) {\n throw new Error(\n `Expected timeline to contain event of type \"${expected.hasType}\"`,\n );\n }\n }\n\n if (expected.doesNotHaveType) {\n const found = events.some((e) => e.type === expected.doesNotHaveType);\n if (found) {\n throw new Error(\n `Expected timeline NOT to contain event of type \"${expected.doesNotHaveType}\"`,\n );\n }\n }\n}\n\n// ============================================================================\n// Self-Healing Testing Helpers\n// ============================================================================\n\nimport type { HealthMonitor } from \"./health-monitor.js\";\nimport type { ReflectionEvaluator } from \"./reflection.js\";\nimport type { RerouteEvent, Scratchpad } from \"./types.js\";\n\n/**\n * Create a runner that always fails, useful for testing self-healing.\n *\n * @example\n * ```typescript\n * const failing = createFailingRunner(new Error(\"Provider down\"));\n * const orchestrator = createAgentOrchestrator({\n * runner: failing,\n * selfHealing: { fallbackRunners: [backupRunner] },\n * });\n * ```\n */\nexport function createFailingRunner(\n error?: Error,\n options?: { delay?: number; failAfter?: number },\n): AgentRunner {\n let callCount = 0;\n const failAfter = options?.failAfter ?? 0;\n\n return async <T>(\n _agent: AgentLike,\n _input: string,\n _runOptions?: RunOptions,\n ): Promise<RunResult<T>> => {\n callCount++;\n\n if (failAfter > 0 && callCount <= failAfter) {\n return {\n output: \"success\" as T,\n messages: [],\n toolCalls: [],\n totalTokens: 10,\n };\n }\n\n if (options?.delay && options.delay > 0) {\n await new Promise((resolve) => setTimeout(resolve, options.delay));\n }\n\n throw error ?? new Error(\"Runner failed\");\n };\n}\n\n/**\n * Assert that an agent was rerouted during execution.\n *\n * @example\n * ```typescript\n * const events: RerouteEvent[] = [];\n * const orchestrator = createMultiAgentOrchestrator({\n * selfHealing: {\n * onReroute: (event) => events.push(event),\n * },\n * });\n *\n * // ... trigger reroute ...\n * assertRerouted(events, {\n * fromAgent: \"primary\",\n * toAgent: \"backup\",\n * reason: /circuit breaker/i,\n * });\n * ```\n */\nexport function assertRerouted(\n events: RerouteEvent[],\n expected: {\n fromAgent?: string;\n toAgent?: string;\n reason?: string | RegExp;\n minReroutes?: number;\n },\n): void {\n if (events.length === 0) {\n throw new Error(\"Expected at least one reroute event, but none occurred\");\n }\n\n if (\n expected.minReroutes !== undefined &&\n events.length < expected.minReroutes\n ) {\n throw new Error(\n `Expected at least ${expected.minReroutes} reroute events, got ${events.length}`,\n );\n }\n\n if (expected.fromAgent) {\n const found = events.some((e) => e.originalAgent === expected.fromAgent);\n if (!found) {\n throw new Error(\n `Expected reroute from agent \"${expected.fromAgent}\", but no matching event found`,\n );\n }\n }\n\n if (expected.toAgent) {\n const found = events.some((e) => e.reroutedTo === expected.toAgent);\n if (!found) {\n throw new Error(\n `Expected reroute to agent \"${expected.toAgent}\", but no matching event found`,\n );\n }\n }\n\n if (expected.reason) {\n const found = events.some((e) => {\n if (typeof expected.reason === \"string\") {\n return e.reason.includes(expected.reason);\n }\n\n return expected.reason!.test(e.reason);\n });\n if (!found) {\n throw new Error(\n `Expected reroute reason matching ${expected.reason}, but no matching event found`,\n );\n }\n }\n}\n\n/**\n * Assert the health state of an agent in the health monitor.\n *\n * @example\n * ```typescript\n * assertAgentHealth(monitor, \"researcher\", {\n * minScore: 70,\n * circuitState: \"CLOSED\",\n * });\n * ```\n */\nexport function assertAgentHealth(\n monitor: HealthMonitor,\n agentId: string,\n expected: {\n minScore?: number;\n maxScore?: number;\n circuitState?: \"CLOSED\" | \"OPEN\" | \"HALF_OPEN\";\n minSuccessRate?: number;\n },\n): void {\n const metrics = monitor.getMetrics(agentId);\n\n if (\n expected.minScore !== undefined &&\n metrics.healthScore < expected.minScore\n ) {\n throw new Error(\n `Expected agent \"${agentId}\" health score to be at least ${expected.minScore}, got ${metrics.healthScore}`,\n );\n }\n\n if (\n expected.maxScore !== undefined &&\n metrics.healthScore > expected.maxScore\n ) {\n throw new Error(\n `Expected agent \"${agentId}\" health score to be at most ${expected.maxScore}, got ${metrics.healthScore}`,\n );\n }\n\n if (\n expected.circuitState !== undefined &&\n metrics.circuitState !== expected.circuitState\n ) {\n throw new Error(\n `Expected agent \"${agentId}\" circuit state to be \"${expected.circuitState}\", got \"${metrics.circuitState}\"`,\n );\n }\n\n if (\n expected.minSuccessRate !== undefined &&\n metrics.successRate < expected.minSuccessRate\n ) {\n throw new Error(\n `Expected agent \"${agentId}\" success rate to be at least ${expected.minSuccessRate}, got ${metrics.successRate}`,\n );\n }\n}\n\n// ============================================================================\n// Checkpoint Test Helpers\n// ============================================================================\n\n/**\n * Create a test checkpoint store (wraps InMemoryCheckpointStore with assertion helpers).\n *\n * @example\n * ```typescript\n * const store = createTestCheckpointStore();\n * const orchestrator = createAgentOrchestrator({ runner, checkpointStore: store });\n * const cp = await orchestrator.checkpoint();\n * expect(store.saved).toHaveLength(1);\n * ```\n */\nexport function createTestCheckpointStore(\n maxCheckpoints = 100,\n): CheckpointStore & {\n saved: Checkpoint[];\n inner: InMemoryCheckpointStore;\n /** Get the most recently saved checkpoint */\n getLatest: () => Checkpoint | undefined;\n} {\n const inner = new InMemoryCheckpointStore({ maxCheckpoints });\n const saved: Checkpoint[] = [];\n\n return {\n inner,\n saved,\n getLatest: () => saved[saved.length - 1],\n async save(checkpoint: Checkpoint): Promise<string> {\n saved.push(checkpoint);\n\n return inner.save(checkpoint);\n },\n load: (id: string) => inner.load(id),\n list: () => inner.list(),\n delete: (id: string) => inner.delete(id),\n clear: () => inner.clear(),\n prune: () => inner.prune(),\n };\n}\n\n/**\n * Assert that a checkpoint has expected properties.\n */\nexport function assertCheckpoint(\n checkpoint: Checkpoint,\n expected: {\n orchestratorType?: \"single\" | \"multi\";\n hasTimeline?: boolean;\n hasMemory?: boolean;\n hasSystemExport?: boolean;\n label?: string;\n },\n): void {\n if (\n expected.orchestratorType !== undefined &&\n checkpoint.orchestratorType !== expected.orchestratorType\n ) {\n throw new Error(\n `Expected checkpoint orchestratorType \"${expected.orchestratorType}\", got \"${checkpoint.orchestratorType}\"`,\n );\n }\n\n if (\n expected.hasSystemExport === true &&\n (!checkpoint.systemExport || checkpoint.systemExport === \"\")\n ) {\n throw new Error(\n \"Expected checkpoint to have non-empty systemExport, but it was empty\",\n );\n }\n\n if (expected.hasTimeline === true && checkpoint.timelineExport === null) {\n throw new Error(\n \"Expected checkpoint to have timeline export, but it was null\",\n );\n }\n\n if (expected.hasTimeline === false && checkpoint.timelineExport !== null) {\n throw new Error(\n \"Expected checkpoint to have no timeline export, but it was present\",\n );\n }\n\n if (expected.hasMemory === true && checkpoint.memoryExport === null) {\n throw new Error(\n \"Expected checkpoint to have memory export, but it was null\",\n );\n }\n\n if (expected.hasMemory === false && checkpoint.memoryExport !== null) {\n throw new Error(\n \"Expected checkpoint to have no memory export, but it was present\",\n );\n }\n\n if (expected.label !== undefined && checkpoint.label !== expected.label) {\n throw new Error(\n `Expected checkpoint label \"${expected.label}\", got \"${checkpoint.label}\"`,\n );\n }\n}\n\n// ============================================================================\n// Breakpoint Test Helpers\n// ============================================================================\n\n/** Options for the breakpoint simulator */\nexport interface BreakpointSimulatorOptions {\n /** Auto-resume after this delay (ms). Default: 0 (immediate) */\n autoResumeDelay?: number;\n /** Modifications to apply on resume */\n modifications?: BreakpointModifications;\n /** If true, cancel instead of resume */\n cancel?: boolean;\n /** Cancel reason */\n cancelReason?: string;\n}\n\n/**\n * Create a breakpoint simulator that auto-resolves breakpoints.\n *\n * @example\n * ```typescript\n * const simulator = createBreakpointSimulator({ autoResumeDelay: 10 });\n * const orchestrator = createAgentOrchestrator({\n * runner,\n * breakpoints: [{ type: \"pre_agent_run\" }],\n * onBreakpoint: simulator.handler,\n * });\n * // Run agent — breakpoint fires and auto-resumes\n * await orchestrator.run(\"test input\");\n * expect(simulator.hits).toHaveLength(1);\n * ```\n */\n/** Minimal interface for breakpoint-capable orchestrators */\nexport interface BreakpointCapable {\n resumeBreakpoint(id: string, modifications?: BreakpointModifications): void;\n cancelBreakpoint(id: string, reason?: string): void;\n}\n\n/**\n * Create a breakpoint simulator that auto-resolves breakpoints for testing.\n *\n * @param options - Simulator options including `autoResumeDelay` and `modifications`.\n * @returns An object with `handler`, `hits`, and `attachTo` for test assertions.\n */\nexport function createBreakpointSimulator(\n options: BreakpointSimulatorOptions = {},\n): {\n handler: (request: BreakpointRequest) => void;\n hits: BreakpointRequest[];\n attachTo: (orchestrator: BreakpointCapable) => void;\n} {\n const hits: BreakpointRequest[] = [];\n let orchestratorRef: BreakpointCapable | null = null;\n let attached = false;\n\n const handler = (request: BreakpointRequest) => {\n hits.push(request);\n\n if (!attached) {\n throw new Error(\n \"[Directive] BreakpointSimulator: handler called but attachTo() was never called. \" +\n \"Breakpoints will not be resolved. Call simulator.attachTo(orchestrator) after creation.\",\n );\n }\n\n const delay = options.autoResumeDelay ?? 0;\n\n const doResolve = () => {\n if (!orchestratorRef) {\n return;\n }\n if (options.cancel) {\n orchestratorRef.cancelBreakpoint(request.id, options.cancelReason);\n } else {\n orchestratorRef.resumeBreakpoint(request.id, options.modifications);\n }\n };\n\n if (delay > 0) {\n setTimeout(doResolve, delay);\n } else {\n // Use queueMicrotask so the breakpoint state is written before we resolve\n queueMicrotask(doResolve);\n }\n };\n\n return {\n handler,\n hits,\n attachTo: (orch: BreakpointCapable) => {\n orchestratorRef = orch;\n attached = true;\n },\n };\n}\n\n/**\n * Assert that a breakpoint was hit with expected properties.\n */\nexport function assertBreakpointHit(\n hits: BreakpointRequest[],\n expected: {\n type?: string;\n agentId?: string;\n count?: number;\n },\n): void {\n if (expected.count !== undefined && hits.length !== expected.count) {\n throw new Error(\n `Expected ${expected.count} breakpoint hits, got ${hits.length}`,\n );\n }\n\n if (expected.type) {\n const found = hits.some((h) => h.type === expected.type);\n if (!found) {\n const types = hits.map((h) => h.type).join(\", \");\n\n throw new Error(\n `Expected breakpoint of type \"${expected.type}\", found types: [${types}]`,\n );\n }\n }\n\n if (expected.agentId) {\n const found = hits.some((h) => h.agentId === expected.agentId);\n if (!found) {\n const agents = hits.map((h) => h.agentId).join(\", \");\n\n throw new Error(\n `Expected breakpoint for agent \"${expected.agentId}\", found agents: [${agents}]`,\n );\n }\n }\n}\n\n// ============================================================================\n// Structured Output Test Helpers\n// ============================================================================\n\n/**\n * Create a mock SafeParseable schema for testing.\n *\n * @example\n * ```typescript\n * const schema = createMockSchema((data) => typeof data === \"object\" && data !== null);\n * const orchestrator = createAgentOrchestrator({\n * runner,\n * outputSchema: schema,\n * });\n * ```\n */\nexport function createMockSchema<T>(\n validate: (data: unknown) => boolean,\n description?: string,\n): {\n safeParse: (data: unknown) => {\n success: boolean;\n data?: T;\n error?: { message: string };\n };\n description?: string;\n} {\n return {\n safeParse: (data: unknown) => {\n if (validate(data)) {\n return { success: true, data: data as T };\n }\n\n return { success: false, error: { message: \"Validation failed\" } };\n },\n description,\n };\n}\n\n// ============================================================================\n// Multiplexed Stream Test Helpers\n// ============================================================================\n\n/**\n * Collect all chunks from a multiplexed stream into an array.\n *\n * @example\n * ```typescript\n * const { stream } = orchestrator.runParallelStream([\"a\", \"b\"], \"input\", merge);\n * const chunks = await collectMultiplexedStream(stream);\n * expect(chunks.length).toBeGreaterThan(0);\n * ```\n */\nexport async function collectMultiplexedStream(\n stream: AsyncIterable<MultiplexedStreamChunk>,\n): Promise<MultiplexedStreamChunk[]> {\n const chunks: MultiplexedStreamChunk[] = [];\n for await (const chunk of stream) {\n chunks.push(chunk);\n }\n\n return chunks;\n}\n\n/**\n * Assert properties of collected multiplexed stream chunks.\n */\nexport function assertMultiplexedStream(\n chunks: MultiplexedStreamChunk[],\n expected: {\n agentIds?: string[];\n minChunks?: number;\n hasDone?: boolean;\n hasErrors?: boolean;\n },\n): void {\n if (expected.minChunks !== undefined && chunks.length < expected.minChunks) {\n throw new Error(\n `Expected at least ${expected.minChunks} chunks, got ${chunks.length}`,\n );\n }\n\n if (expected.agentIds) {\n const seenAgents = new Set(chunks.map((c) => c.agentId));\n for (const agentId of expected.agentIds) {\n if (!seenAgents.has(agentId)) {\n throw new Error(\n `Expected chunks from agent \"${agentId}\", found agents: [${[...seenAgents].join(\", \")}]`,\n );\n }\n }\n }\n\n if (expected.hasDone === true) {\n const hasDone = chunks.some((c) => c.chunk.type === \"done\");\n if (!hasDone) {\n throw new Error(\"Expected at least one 'done' chunk, found none\");\n }\n }\n\n if (expected.hasErrors === true) {\n const hasError = chunks.some((c) => c.chunk.type === \"error\");\n if (!hasError) {\n throw new Error(\"Expected at least one 'error' chunk, found none\");\n }\n }\n\n if (expected.hasErrors === false) {\n const hasError = chunks.some((c) => c.chunk.type === \"error\");\n if (hasError) {\n throw new Error(\"Expected no 'error' chunks, but found some\");\n }\n }\n}\n\n// ============================================================================\n// Reflection Test Helpers\n// ============================================================================\n\n/**\n * Create a test reflection evaluator that passes after N iterations.\n *\n * @example\n * ```typescript\n * const evaluator = createTestReflectionEvaluator({ passAfter: 2 });\n * const reflective = withReflection(runner, { evaluate: evaluator });\n * ```\n */\nexport function createTestReflectionEvaluator(options?: {\n /** Pass after this many evaluations (1 = pass on first try). Default: 1 */\n passAfter?: number;\n /** Feedback to provide on failure */\n feedback?: string;\n /** Score to assign (0-1) */\n score?: number;\n}): ReflectionEvaluator {\n const passAfter = options?.passAfter ?? 1;\n const feedback = options?.feedback ?? \"Needs improvement\";\n const score = options?.score;\n let callCount = 0;\n\n return (_output: unknown, _context) => {\n callCount++;\n const passed = callCount >= passAfter;\n\n return {\n passed,\n feedback: passed ? undefined : feedback,\n score: score ?? (passed ? 1 : 0.5),\n };\n };\n}\n\n// ============================================================================\n// Scratchpad Test Helpers\n// ============================================================================\n\n/**\n * Assert that a scratchpad contains expected values.\n *\n * @example\n * ```typescript\n * assertScratchpadState(orchestrator.scratchpad!, {\n * \"plan.status\": \"complete\",\n * \"research.results\": expect.any(Array),\n * });\n * ```\n */\nexport function assertScratchpadState(\n scratchpad: Scratchpad,\n expected: Record<string, unknown>,\n): void {\n const all = scratchpad.getAll();\n for (const [key, expectedValue] of Object.entries(expected)) {\n const actual = all[key];\n if (actual !== expectedValue) {\n throw new Error(\n `Expected scratchpad key \"${key}\" to be ${JSON.stringify(expectedValue)}, got ${JSON.stringify(actual)}`,\n );\n }\n }\n}\n\n// ============================================================================\n// Derivation Test Helpers\n// ============================================================================\n\n/**\n * Assert that derived values match expected values.\n *\n * @example\n * ```typescript\n * assertDerivedValues(orchestrator, {\n * totalRuns: 3,\n * allComplete: true,\n * });\n * ```\n */\nexport function assertDerivedValues(\n orchestrator: MultiAgentOrchestrator,\n expected: Record<string, unknown>,\n): void {\n const derived = orchestrator.derived;\n for (const [key, expectedValue] of Object.entries(expected)) {\n const actual = derived[key];\n if (typeof expectedValue === \"object\" && expectedValue !== null) {\n // Sort keys for order-independent comparison\n const sortedStringify = (v: unknown): string =>\n JSON.stringify(v, Object.keys(v as Record<string, unknown>).sort());\n if (sortedStringify(actual) !== sortedStringify(expectedValue)) {\n throw new Error(\n `Expected derived value \"${key}\" to be ${JSON.stringify(expectedValue)}, got ${JSON.stringify(actual)}`,\n );\n }\n } else if (actual !== expectedValue) {\n throw new Error(\n `Expected derived value \"${key}\" to be ${JSON.stringify(expectedValue)}, got ${JSON.stringify(actual)}`,\n );\n }\n }\n}\n"]}
|
package/dist/testing.d.cts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { M as MultiAgentOrchestrator, a as MultiAgentOrchestratorOptions, A as AgentOrchestrator, O as OrchestratorOptions, b as MultiplexedStreamChunk, T as TaskRegistration, R as ReflectionEvaluator } from './orchestrator-types-DeIMRLR7.cjs';
|
|
2
|
+
import { A as ApprovalRequest, B as BreakpointModifications, I as InputGuardrailData, O as OutputGuardrailData, M as Message, T as ToolCallGuardrailData, a as ToolCall, G as GuardrailResult, b as AgentLike, c as AgentRunner, R as RunOptions, d as BreakpointRequest, C as Checkpoint, D as DagExecutionContext, e as DagNodeStatus, f as RerouteEvent, S as Scratchpad, g as DebugEventType, h as CheckpointStore, i as InMemoryCheckpointStore, j as DagNode, k as DagPattern, l as DebugEvent, m as GuardrailFn, n as GuardrailContext } from './types-DJ09LjZX.cjs';
|
|
3
|
+
import { D as DebugTimeline } from './debug-timeline-DpnRMnLU.cjs';
|
|
4
|
+
import { H as HealthMonitor } from './health-monitor-C6xoXrQz.cjs';
|
|
3
5
|
import '@directive-run/core';
|
|
4
6
|
import '@directive-run/core/plugins';
|
|
5
7
|
|
package/dist/testing.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { M as MultiAgentOrchestrator, a as MultiAgentOrchestratorOptions, A as AgentOrchestrator, O as OrchestratorOptions, b as MultiplexedStreamChunk, T as TaskRegistration, R as ReflectionEvaluator } from './orchestrator-types-DGBhL6mc.js';
|
|
2
|
+
import { A as ApprovalRequest, B as BreakpointModifications, I as InputGuardrailData, O as OutputGuardrailData, M as Message, T as ToolCallGuardrailData, a as ToolCall, G as GuardrailResult, b as AgentLike, c as AgentRunner, R as RunOptions, d as BreakpointRequest, C as Checkpoint, D as DagExecutionContext, e as DagNodeStatus, f as RerouteEvent, S as Scratchpad, g as DebugEventType, h as CheckpointStore, i as InMemoryCheckpointStore, j as DagNode, k as DagPattern, l as DebugEvent, m as GuardrailFn, n as GuardrailContext } from './types-DJ09LjZX.js';
|
|
3
|
+
import { D as DebugTimeline } from './debug-timeline-L13P-U2I.js';
|
|
4
|
+
import { H as HealthMonitor } from './health-monitor-qL9RNMH3.js';
|
|
3
5
|
import '@directive-run/core';
|
|
4
6
|
import '@directive-run/core/plugins';
|
|
5
7
|
|
package/dist/testing.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {a}from'./chunk-Q3PQLWBR.js';import {Da,ga,i,G}from'./chunk-RW4R3O5P.js';function b(r={}){let{defaultResponse:e={output:"mock response",totalTokens:10},responses:t={},recordCalls:n=true,onRun:o}=r,s=[],a=new Map(Object.entries(t)),i=e;return {run:async(l,c,g)=>{o?.(l,c),n&&s.push({agent:l,input:c,options:g,timestamp:Date.now()});let d=a.get(l.name)??i;if(d.generate){let p=d.generate(c,l);d={...d,...p};}if(d.error)throw d.error;d.delay&&d.delay>0&&await new Promise(p=>setTimeout(p,d.delay));let f=d.messages??[];for(let p of f)g?.onMessage?.(p);let m=d.toolCalls??[];for(let p of m)g?.onToolCall?.(p);return {output:d.output,messages:f,toolCalls:m,totalTokens:d.totalTokens??10}},getCalls:()=>[...s],getCallsFor:l=>s.filter(c=>c.agent.name===l),clearCalls:()=>s.length=0,setResponse:(l,c)=>a.set(l,c),setDefaultResponse:l=>i=l}}async function T(r,e,t){let n={agentName:"test-agent",input:"",...e},o={agentName:e.agentName??"test-agent",input:e.input??"",facts:t?.facts??{},...t},s=Date.now(),a=await r(n,o),i=Date.now()-s;return {...a,duration:i,testedData:n,assertPassed(){if(!a.passed)throw new Error(`Expected guardrail to pass, but it failed: ${a.reason}`)},assertFailed(u){if(a.passed)throw new Error("Expected guardrail to fail, but it passed");if(u!==void 0){if(typeof u=="string"&&!a.reason?.includes(u))throw new Error(`Expected failure reason to include "${u}", got: ${a.reason}`);if(u instanceof RegExp&&!u.test(a.reason??""))throw new Error(`Expected failure reason to match ${u}, got: ${a.reason}`)}},assertTransformed(u){if(a.transformed===void 0)throw new Error("Expected guardrail to transform input, but no transformation occurred");if(u!==void 0&&a.transformed!==u)throw new Error(`Expected transformation to be ${JSON.stringify(u)}, got: ${JSON.stringify(a.transformed)}`)}}}async function x(r,e){let t=[],n=[];for(let o=0;o<e.length;o++){let s=e[o],a=await T(r,s.input,s.context);t.push(a),(a.passed?a.transformed!==void 0?"transform":"pass":"fail")!==s.expect&&n.push({index:o,expected:s.expect,actual:a});}return {results:t,allPassed:()=>n.length===0,failures:()=>n}}function R(r={}){let{autoApprove:e,autoReject:t,delay:n=0,recordRequests:o=true}=r,s=[],a=new Map,i=[];return {async handle(u){o&&s.push(u);for(let l=i.length-1;l>=0;l--){let c=i[l];c.predicate(u)&&(i.splice(l,1),c.resolve(u));}return n>0&&await new Promise(l=>setTimeout(l,n)),t&&t(u)?"rejected":e?.(u)?"approved":new Promise(l=>{a.set(u.id,{request:u,resolve:l});})},getRequests:()=>[...s],clearRequests:()=>s.length=0,approve(u){let l=a.get(u);l&&(l.resolve("approved"),a.delete(u));},reject(u,l){let c=a.get(u);if(c){c.resolve("rejected"),a.delete(u);let g=s.find(d=>d.id===u);g&&(g.rejectionReason=l);}},waitForRequest(u,l=5e3){let c=s.find(u);return c?Promise.resolve(c):new Promise((g,d)=>{let f={predicate:u,resolve:p=>{clearTimeout(m),g(p);}},m=setTimeout(()=>{let p=i.indexOf(f);p>=0&&i.splice(p,1),d(new Error("Timeout waiting for approval request"));},l);i.push(f);})}}}function C(r={}){let{mockResponses:e,defaultMockResponse:t,...n}=r,o=b({responses:e,defaultResponse:t}),s=R(),a$1=a({...n,runner:o.run,onApprovalRequest:u=>{s.handle(u),n.onApprovalRequest?.(u);}}),i=Object.create(a$1);return i.mockRunner=o,i.approvalSimulator=s,i.getCalls=()=>o.getCalls(),i.getApprovalRequests=()=>s.getRequests(),i.resetAll=()=>{a$1.reset(),o.clearCalls(),s.clearRequests();},i}function O(){let r=[];return {plugin:{name:"constraint-recorder",onRequirementCreated(e){r.push({constraintId:e.constraintId,triggered:true,requirement:e.requirement,facts:e.facts,timestamp:Date.now()});}},getSnapshots:()=>[...r],clearSnapshots:()=>r.length=0}}function M(r,e){let t=r.facts;if(e.agentStatus!==void 0&&t.agent.status!==e.agentStatus)throw new Error(`Expected agent status to be "${e.agentStatus}", got "${t.agent.status}"`);if(e.tokenUsage!==void 0){let{min:n,max:o,exact:s}=e.tokenUsage;if(s!==void 0&&t.agent.tokenUsage!==s)throw new Error(`Expected token usage to be exactly ${s}, got ${t.agent.tokenUsage}`);if(n!==void 0&&t.agent.tokenUsage<n)throw new Error(`Expected token usage to be at least ${n}, got ${t.agent.tokenUsage}`);if(o!==void 0&&t.agent.tokenUsage>o)throw new Error(`Expected token usage to be at most ${o}, got ${t.agent.tokenUsage}`)}if(e.pendingApprovals!==void 0&&t.approval.pending.length!==e.pendingApprovals)throw new Error(`Expected ${e.pendingApprovals} pending approvals, got ${t.approval.pending.length}`);if(e.conversationLength!==void 0){let{min:n,max:o,exact:s}=e.conversationLength,a=t.conversation.length;if(s!==void 0&&a!==s)throw new Error(`Expected conversation length to be exactly ${s}, got ${a}`);if(n!==void 0&&a<n)throw new Error(`Expected conversation length to be at least ${n}, got ${a}`);if(o!==void 0&&a>o)throw new Error(`Expected conversation length to be at most ${o}, got ${a}`)}}function q(r=Date.now()){let e=r,t=r;return {now:()=>e,advance:n=>{e+=n;},set:n=>{e=n;},reset:()=>{e=t;}}}function D(r){let{mockResponses:e={},defaultMockResponse:t,mockTasks:n,...o}=r;if(n){let c=o.tasks??{};for(let[g,d]of Object.entries(n))c[g]||(c[g]=y(d.output,{delay:d.delay,shouldError:d.shouldError}));o.tasks=c;}let s={};for(let[c,g]of Object.entries(e)){let d=o.agents[c];d&&(s[d.agent.name]=g);}let a=b({responses:s,defaultResponse:t}),i=R(),u=Da({...o,runner:a.run,onApprovalRequest:c=>{i.handle(c),o.onApprovalRequest?.(c);}}),l=Object.create(u);return l.mockRunner=a,l.approvalSimulator=i,l.getCalls=()=>a.getCalls(),l.getApprovalRequests=()=>i.getRequests(),l.resetAll=()=>{u.reset(),a.clearCalls(),i.clearRequests();},l}function N(r,e){if(e.taskStatus)for(let[t,n]of Object.entries(e.taskStatus)){let o=r.getTaskState(t);if(!o)throw new Error(`Expected task "${t}" to exist, but it was not found`);if(o.status!==n)throw new Error(`Expected task "${t}" status to be "${n}", got "${o.status}"`)}if(e.agentStatus)for(let[t,n]of Object.entries(e.agentStatus)){let o=r.getAgentState(t);if(!o)throw new Error(`Expected agent "${t}" to exist, but it was not found`);if(o.status!==n)throw new Error(`Expected agent "${t}" status to be "${n}", got "${o.status}"`)}if(e.totalTokens){let{agentId:t,min:n,max:o}=e.totalTokens;if(t){let s=r.getAgentState(t);if(!s)throw new Error(`Expected agent "${t}" to exist, but it was not found`);if(n!==void 0&&s.totalTokens<n)throw new Error(`Expected agent "${t}" tokens to be at least ${n}, got ${s.totalTokens}`);if(o!==void 0&&s.totalTokens>o)throw new Error(`Expected agent "${t}" tokens to be at most ${o}, got ${s.totalTokens}`)}else {let s=r.getAllAgentStates(),a=Object.values(s).reduce((i,u)=>i+u.totalTokens,0);if(n!==void 0&&a<n)throw new Error(`Expected total tokens to be at least ${n}, got ${a}`);if(o!==void 0&&a>o)throw new Error(`Expected total tokens to be at most ${o}, got ${a}`)}}if(e.globalTokens){let{min:t,max:n}=e.globalTokens,o=r.totalTokens;if(t!==void 0&&o<t)throw new Error(`Expected global tokens to be at least ${t}, got ${o}`);if(n!==void 0&&o>n)throw new Error(`Expected global tokens to be at most ${n}, got ${o}`)}if(e.pendingHandoffs!==void 0){let t=r.getPendingHandoffs().length;if(t!==e.pendingHandoffs)throw new Error(`Expected ${e.pendingHandoffs} pending handoffs, got ${t}`)}}function y(r,e){return {run:async(t,n)=>{if(n.aborted)throw new Error("Task aborted");if(e?.delay&&e.delay>0&&await new Promise((o,s)=>{let a=setTimeout(o,e.delay);n.addEventListener("abort",()=>{clearTimeout(a),s(new Error("Task aborted"));},{once:true});}),e?.shouldError)throw new Error("Mock task error");return r},label:e?.label??"Mock Task",description:e?.description}}function P(r,e,t){return ga(r,e??(o=>o.outputs),t)}function I(r,e){if(e.nodeStatuses)for(let[t,n]of Object.entries(e.nodeStatuses)){let o=r.statuses[t];if(o!==n)throw new Error(`Expected node "${t}" status to be "${n}", got "${o}"`)}if(e.completedNodes){for(let t of e.completedNodes)if(r.statuses[t]!=="completed")throw new Error(`Expected node "${t}" to be completed, got "${r.statuses[t]}"`)}if(e.skippedNodes){for(let t of e.skippedNodes)if(r.statuses[t]!=="skipped")throw new Error(`Expected node "${t}" to be skipped, got "${r.statuses[t]}"`)}if(e.errorNodes){for(let t of e.errorNodes)if(r.statuses[t]!=="error")throw new Error(`Expected node "${t}" to be error, got "${r.statuses[t]}"`)}if(e.outputContains)for(let[t,n]of Object.entries(e.outputContains)){let o=r.outputs[t];if(o!==n)throw new Error(`Expected node "${t}" output to be ${JSON.stringify(n)}, got ${JSON.stringify(o)}`)}}function B(r,e){let t=i({maxEvents:e?.maxEvents??500});if(r)for(let n of r)t.record({timestamp:Date.now(),snapshotId:null,agentId:"",...n});return t}function F(r,e){let t=r.getEvents();if(e.totalEvents!==void 0&&t.length!==e.totalEvents)throw new Error(`Expected ${e.totalEvents} timeline events, got ${t.length}`);if(e.minEvents!==void 0&&t.length<e.minEvents)throw new Error(`Expected at least ${e.minEvents} timeline events, got ${t.length}`);if(e.maxEvents!==void 0&&t.length>e.maxEvents)throw new Error(`Expected at most ${e.maxEvents} timeline events, got ${t.length}`);if(e.eventTypes){for(let n of e.eventTypes)if(!t.some(s=>s.type===n))throw new Error(`Expected timeline to contain event of type "${n}", but none found`)}if(e.agentEvents)for(let[n,o]of Object.entries(e.agentEvents)){let s=r.getEventsForAgent(n).length;if(s!==o)throw new Error(`Expected ${o} events for agent "${n}", got ${s}`)}if(e.hasType&&!t.some(o=>o.type===e.hasType))throw new Error(`Expected timeline to contain event of type "${e.hasType}"`);if(e.doesNotHaveType&&t.some(o=>o.type===e.doesNotHaveType))throw new Error(`Expected timeline NOT to contain event of type "${e.doesNotHaveType}"`)}function H(r,e){let t=0,n=e?.failAfter??0;return async(o,s,a)=>{if(t++,n>0&&t<=n)return {output:"success",messages:[],toolCalls:[],totalTokens:10};throw e?.delay&&e.delay>0&&await new Promise(i=>setTimeout(i,e.delay)),r??new Error("Runner failed")}}function L(r,e){if(r.length===0)throw new Error("Expected at least one reroute event, but none occurred");if(e.minReroutes!==void 0&&r.length<e.minReroutes)throw new Error(`Expected at least ${e.minReroutes} reroute events, got ${r.length}`);if(e.fromAgent&&!r.some(n=>n.originalAgent===e.fromAgent))throw new Error(`Expected reroute from agent "${e.fromAgent}", but no matching event found`);if(e.toAgent&&!r.some(n=>n.reroutedTo===e.toAgent))throw new Error(`Expected reroute to agent "${e.toAgent}", but no matching event found`);if(e.reason&&!r.some(n=>typeof e.reason=="string"?n.reason.includes(e.reason):e.reason.test(n.reason)))throw new Error(`Expected reroute reason matching ${e.reason}, but no matching event found`)}function J(r,e,t){let n=r.getMetrics(e);if(t.minScore!==void 0&&n.healthScore<t.minScore)throw new Error(`Expected agent "${e}" health score to be at least ${t.minScore}, got ${n.healthScore}`);if(t.maxScore!==void 0&&n.healthScore>t.maxScore)throw new Error(`Expected agent "${e}" health score to be at most ${t.maxScore}, got ${n.healthScore}`);if(t.circuitState!==void 0&&n.circuitState!==t.circuitState)throw new Error(`Expected agent "${e}" circuit state to be "${t.circuitState}", got "${n.circuitState}"`);if(t.minSuccessRate!==void 0&&n.successRate<t.minSuccessRate)throw new Error(`Expected agent "${e}" success rate to be at least ${t.minSuccessRate}, got ${n.successRate}`)}function U(r=100){let e=new G({maxCheckpoints:r}),t=[];return {inner:e,saved:t,getLatest:()=>t[t.length-1],async save(n){return t.push(n),e.save(n)},load:n=>e.load(n),list:()=>e.list(),delete:n=>e.delete(n),clear:()=>e.clear(),prune:()=>e.prune()}}function _(r,e){if(e.orchestratorType!==void 0&&r.orchestratorType!==e.orchestratorType)throw new Error(`Expected checkpoint orchestratorType "${e.orchestratorType}", got "${r.orchestratorType}"`);if(e.hasSystemExport===true&&(!r.systemExport||r.systemExport===""))throw new Error("Expected checkpoint to have non-empty systemExport, but it was empty");if(e.hasTimeline===true&&r.timelineExport===null)throw new Error("Expected checkpoint to have timeline export, but it was null");if(e.hasTimeline===false&&r.timelineExport!==null)throw new Error("Expected checkpoint to have no timeline export, but it was present");if(e.hasMemory===true&&r.memoryExport===null)throw new Error("Expected checkpoint to have memory export, but it was null");if(e.hasMemory===false&&r.memoryExport!==null)throw new Error("Expected checkpoint to have no memory export, but it was present");if(e.label!==void 0&&r.label!==e.label)throw new Error(`Expected checkpoint label "${e.label}", got "${r.label}"`)}function V(r={}){let e=[],t=null,n=false;return {handler:s=>{if(e.push(s),!n)throw new Error("[Directive] BreakpointSimulator: handler called but attachTo() was never called. Breakpoints will not be resolved. Call simulator.attachTo(orchestrator) after creation.");let a=r.autoResumeDelay??0,i=()=>{t&&(r.cancel?t.cancelBreakpoint(s.id,r.cancelReason):t.resumeBreakpoint(s.id,r.modifications));};a>0?setTimeout(i,a):queueMicrotask(i);},hits:e,attachTo:s=>{t=s,n=true;}}}function W(r,e){if(e.count!==void 0&&r.length!==e.count)throw new Error(`Expected ${e.count} breakpoint hits, got ${r.length}`);if(e.type&&!r.some(n=>n.type===e.type)){let n=r.map(o=>o.type).join(", ");throw new Error(`Expected breakpoint of type "${e.type}", found types: [${n}]`)}if(e.agentId&&!r.some(n=>n.agentId===e.agentId)){let n=r.map(o=>o.agentId).join(", ");throw new Error(`Expected breakpoint for agent "${e.agentId}", found agents: [${n}]`)}}function z(r,e){return {safeParse:t=>r(t)?{success:true,data:t}:{success:false,error:{message:"Validation failed"}},description:e}}async function K(r){let e=[];for await(let t of r)e.push(t);return e}function Q(r,e){if(e.minChunks!==void 0&&r.length<e.minChunks)throw new Error(`Expected at least ${e.minChunks} chunks, got ${r.length}`);if(e.agentIds){let t=new Set(r.map(n=>n.agentId));for(let n of e.agentIds)if(!t.has(n))throw new Error(`Expected chunks from agent "${n}", found agents: [${[...t].join(", ")}]`)}if(e.hasDone===true&&!r.some(n=>n.chunk.type==="done"))throw new Error("Expected at least one 'done' chunk, found none");if(e.hasErrors===true&&!r.some(n=>n.chunk.type==="error"))throw new Error("Expected at least one 'error' chunk, found none");if(e.hasErrors===false&&r.some(n=>n.chunk.type==="error"))throw new Error("Expected no 'error' chunks, but found some")}function X(r){let e=r?.passAfter??1,t=r?.feedback??"Needs improvement",n=r?.score,o=0;return (s,a)=>{o++;let i=o>=e;return {passed:i,feedback:i?void 0:t,score:n??(i?1:.5)}}}function Y(r,e){let t=r.getAll();for(let[n,o]of Object.entries(e)){let s=t[n];if(s!==o)throw new Error(`Expected scratchpad key "${n}" to be ${JSON.stringify(o)}, got ${JSON.stringify(s)}`)}}function Z(r,e){let t=r.derived;for(let[n,o]of Object.entries(e)){let s=t[n];if(typeof o=="object"&&o!==null){let a=i=>JSON.stringify(i,Object.keys(i).sort());if(a(s)!==a(o))throw new Error(`Expected derived value "${n}" to be ${JSON.stringify(o)}, got ${JSON.stringify(s)}`)}else if(s!==o)throw new Error(`Expected derived value "${n}" to be ${JSON.stringify(o)}, got ${JSON.stringify(s)}`)}}export{J as assertAgentHealth,W as assertBreakpointHit,_ as assertCheckpoint,I as assertDagExecution,Z as assertDerivedValues,N as assertMultiAgentState,Q as assertMultiplexedStream,M as assertOrchestratorState,L as assertRerouted,Y as assertScratchpadState,F as assertTimelineEvents,K as collectMultiplexedStream,R as createApprovalSimulator,V as createBreakpointSimulator,O as createConstraintRecorder,H as createFailingRunner,b as createMockAgentRunner,z as createMockSchema,y as createMockTask,U as createTestCheckpointStore,P as createTestDag,D as createTestMultiAgentOrchestrator,C as createTestOrchestrator,X as createTestReflectionEvaluator,B as createTestTimeline,q as createTimeController,T as testGuardrail,x as testGuardrailBatch};//# sourceMappingURL=testing.js.map
|
|
1
|
+
import {a}from'./chunk-IUGSMTBE.js';import {ra,W as W$1,y as y$1}from'./chunk-LXUMJKGJ.js';import'./chunk-UR5BMWEN.js';import {a as a$1}from'./chunk-FBT73WFY.js';import'./chunk-UR4ZGO7V.js';function b(r={}){let{defaultResponse:e={output:"mock response",totalTokens:10},responses:t={},recordCalls:n=true,onRun:o}=r,s=[],a=new Map(Object.entries(t)),i=e;return {run:async(l,c,g)=>{o?.(l,c),n&&s.push({agent:l,input:c,options:g,timestamp:Date.now()});let d=a.get(l.name)??i;if(d.generate){let p=d.generate(c,l);d={...d,...p};}if(d.error)throw d.error;d.delay&&d.delay>0&&await new Promise(p=>setTimeout(p,d.delay));let f=d.messages??[];for(let p of f)g?.onMessage?.(p);let m=d.toolCalls??[];for(let p of m)g?.onToolCall?.(p);return {output:d.output,messages:f,toolCalls:m,totalTokens:d.totalTokens??10}},getCalls:()=>[...s],getCallsFor:l=>s.filter(c=>c.agent.name===l),clearCalls:()=>s.length=0,setResponse:(l,c)=>a.set(l,c),setDefaultResponse:l=>i=l}}async function T(r,e,t){let n={agentName:"test-agent",input:"",...e},o={agentName:e.agentName??"test-agent",input:e.input??"",facts:t?.facts??{},...t},s=Date.now(),a=await r(n,o),i=Date.now()-s;return {...a,duration:i,testedData:n,assertPassed(){if(!a.passed)throw new Error(`Expected guardrail to pass, but it failed: ${a.reason}`)},assertFailed(u){if(a.passed)throw new Error("Expected guardrail to fail, but it passed");if(u!==void 0){if(typeof u=="string"&&!a.reason?.includes(u))throw new Error(`Expected failure reason to include "${u}", got: ${a.reason}`);if(u instanceof RegExp&&!u.test(a.reason??""))throw new Error(`Expected failure reason to match ${u}, got: ${a.reason}`)}},assertTransformed(u){if(a.transformed===void 0)throw new Error("Expected guardrail to transform input, but no transformation occurred");if(u!==void 0&&a.transformed!==u)throw new Error(`Expected transformation to be ${JSON.stringify(u)}, got: ${JSON.stringify(a.transformed)}`)}}}async function x(r,e){let t=[],n=[];for(let o=0;o<e.length;o++){let s=e[o],a=await T(r,s.input,s.context);t.push(a),(a.passed?a.transformed!==void 0?"transform":"pass":"fail")!==s.expect&&n.push({index:o,expected:s.expect,actual:a});}return {results:t,allPassed:()=>n.length===0,failures:()=>n}}function R(r={}){let{autoApprove:e,autoReject:t,delay:n=0,recordRequests:o=true}=r,s=[],a=new Map,i=[];return {async handle(u){o&&s.push(u);for(let l=i.length-1;l>=0;l--){let c=i[l];c.predicate(u)&&(i.splice(l,1),c.resolve(u));}return n>0&&await new Promise(l=>setTimeout(l,n)),t&&t(u)?"rejected":e?.(u)?"approved":new Promise(l=>{a.set(u.id,{request:u,resolve:l});})},getRequests:()=>[...s],clearRequests:()=>s.length=0,approve(u){let l=a.get(u);l&&(l.resolve("approved"),a.delete(u));},reject(u,l){let c=a.get(u);if(c){c.resolve("rejected"),a.delete(u);let g=s.find(d=>d.id===u);g&&(g.rejectionReason=l);}},waitForRequest(u,l=5e3){let c=s.find(u);return c?Promise.resolve(c):new Promise((g,d)=>{let f={predicate:u,resolve:p=>{clearTimeout(m),g(p);}},m=setTimeout(()=>{let p=i.indexOf(f);p>=0&&i.splice(p,1),d(new Error("Timeout waiting for approval request"));},l);i.push(f);})}}}function C(r={}){let{mockResponses:e,defaultMockResponse:t,...n}=r,o=b({responses:e,defaultResponse:t}),s=R(),a$1=a({...n,runner:o.run,onApprovalRequest:u=>{s.handle(u),n.onApprovalRequest?.(u);}}),i=Object.create(a$1);return i.mockRunner=o,i.approvalSimulator=s,i.getCalls=()=>o.getCalls(),i.getApprovalRequests=()=>s.getRequests(),i.resetAll=()=>{a$1.reset(),o.clearCalls(),s.clearRequests();},i}function O(){let r=[];return {plugin:{name:"constraint-recorder",onRequirementCreated(e){r.push({constraintId:e.constraintId,triggered:true,requirement:e.requirement,facts:e.facts,timestamp:Date.now()});}},getSnapshots:()=>[...r],clearSnapshots:()=>r.length=0}}function M(r,e){let t=r.facts;if(e.agentStatus!==void 0&&t.agent.status!==e.agentStatus)throw new Error(`Expected agent status to be "${e.agentStatus}", got "${t.agent.status}"`);if(e.tokenUsage!==void 0){let{min:n,max:o,exact:s}=e.tokenUsage;if(s!==void 0&&t.agent.tokenUsage!==s)throw new Error(`Expected token usage to be exactly ${s}, got ${t.agent.tokenUsage}`);if(n!==void 0&&t.agent.tokenUsage<n)throw new Error(`Expected token usage to be at least ${n}, got ${t.agent.tokenUsage}`);if(o!==void 0&&t.agent.tokenUsage>o)throw new Error(`Expected token usage to be at most ${o}, got ${t.agent.tokenUsage}`)}if(e.pendingApprovals!==void 0&&t.approval.pending.length!==e.pendingApprovals)throw new Error(`Expected ${e.pendingApprovals} pending approvals, got ${t.approval.pending.length}`);if(e.conversationLength!==void 0){let{min:n,max:o,exact:s}=e.conversationLength,a=t.conversation.length;if(s!==void 0&&a!==s)throw new Error(`Expected conversation length to be exactly ${s}, got ${a}`);if(n!==void 0&&a<n)throw new Error(`Expected conversation length to be at least ${n}, got ${a}`);if(o!==void 0&&a>o)throw new Error(`Expected conversation length to be at most ${o}, got ${a}`)}}function q(r=Date.now()){let e=r,t=r;return {now:()=>e,advance:n=>{e+=n;},set:n=>{e=n;},reset:()=>{e=t;}}}function D(r){let{mockResponses:e={},defaultMockResponse:t,mockTasks:n,...o}=r;if(n){let c=o.tasks??{};for(let[g,d]of Object.entries(n))c[g]||(c[g]=y(d.output,{delay:d.delay,shouldError:d.shouldError}));o.tasks=c;}let s={};for(let[c,g]of Object.entries(e)){let d=o.agents[c];d&&(s[d.agent.name]=g);}let a=b({responses:s,defaultResponse:t}),i=R(),u=ra({...o,runner:a.run,onApprovalRequest:c=>{i.handle(c),o.onApprovalRequest?.(c);}}),l=Object.create(u);return l.mockRunner=a,l.approvalSimulator=i,l.getCalls=()=>a.getCalls(),l.getApprovalRequests=()=>i.getRequests(),l.resetAll=()=>{u.reset(),a.clearCalls(),i.clearRequests();},l}function N(r,e){if(e.taskStatus)for(let[t,n]of Object.entries(e.taskStatus)){let o=r.getTaskState(t);if(!o)throw new Error(`Expected task "${t}" to exist, but it was not found`);if(o.status!==n)throw new Error(`Expected task "${t}" status to be "${n}", got "${o.status}"`)}if(e.agentStatus)for(let[t,n]of Object.entries(e.agentStatus)){let o=r.getAgentState(t);if(!o)throw new Error(`Expected agent "${t}" to exist, but it was not found`);if(o.status!==n)throw new Error(`Expected agent "${t}" status to be "${n}", got "${o.status}"`)}if(e.totalTokens){let{agentId:t,min:n,max:o}=e.totalTokens;if(t){let s=r.getAgentState(t);if(!s)throw new Error(`Expected agent "${t}" to exist, but it was not found`);if(n!==void 0&&s.totalTokens<n)throw new Error(`Expected agent "${t}" tokens to be at least ${n}, got ${s.totalTokens}`);if(o!==void 0&&s.totalTokens>o)throw new Error(`Expected agent "${t}" tokens to be at most ${o}, got ${s.totalTokens}`)}else {let s=r.getAllAgentStates(),a=Object.values(s).reduce((i,u)=>i+u.totalTokens,0);if(n!==void 0&&a<n)throw new Error(`Expected total tokens to be at least ${n}, got ${a}`);if(o!==void 0&&a>o)throw new Error(`Expected total tokens to be at most ${o}, got ${a}`)}}if(e.globalTokens){let{min:t,max:n}=e.globalTokens,o=r.totalTokens;if(t!==void 0&&o<t)throw new Error(`Expected global tokens to be at least ${t}, got ${o}`);if(n!==void 0&&o>n)throw new Error(`Expected global tokens to be at most ${n}, got ${o}`)}if(e.pendingHandoffs!==void 0){let t=r.getPendingHandoffs().length;if(t!==e.pendingHandoffs)throw new Error(`Expected ${e.pendingHandoffs} pending handoffs, got ${t}`)}}function y(r,e){return {run:async(t,n)=>{if(n.aborted)throw new Error("Task aborted");if(e?.delay&&e.delay>0&&await new Promise((o,s)=>{let a=setTimeout(o,e.delay);n.addEventListener("abort",()=>{clearTimeout(a),s(new Error("Task aborted"));},{once:true});}),e?.shouldError)throw new Error("Mock task error");return r},label:e?.label??"Mock Task",description:e?.description}}function P(r,e,t){return W$1(r,e??(o=>o.outputs),t)}function I(r,e){if(e.nodeStatuses)for(let[t,n]of Object.entries(e.nodeStatuses)){let o=r.statuses[t];if(o!==n)throw new Error(`Expected node "${t}" status to be "${n}", got "${o}"`)}if(e.completedNodes){for(let t of e.completedNodes)if(r.statuses[t]!=="completed")throw new Error(`Expected node "${t}" to be completed, got "${r.statuses[t]}"`)}if(e.skippedNodes){for(let t of e.skippedNodes)if(r.statuses[t]!=="skipped")throw new Error(`Expected node "${t}" to be skipped, got "${r.statuses[t]}"`)}if(e.errorNodes){for(let t of e.errorNodes)if(r.statuses[t]!=="error")throw new Error(`Expected node "${t}" to be error, got "${r.statuses[t]}"`)}if(e.outputContains)for(let[t,n]of Object.entries(e.outputContains)){let o=r.outputs[t];if(o!==n)throw new Error(`Expected node "${t}" output to be ${JSON.stringify(n)}, got ${JSON.stringify(o)}`)}}function B(r,e){let t=a$1({maxEvents:e?.maxEvents??500});if(r)for(let n of r)t.record({timestamp:Date.now(),snapshotId:null,agentId:"",...n});return t}function F(r,e){let t=r.getEvents();if(e.totalEvents!==void 0&&t.length!==e.totalEvents)throw new Error(`Expected ${e.totalEvents} timeline events, got ${t.length}`);if(e.minEvents!==void 0&&t.length<e.minEvents)throw new Error(`Expected at least ${e.minEvents} timeline events, got ${t.length}`);if(e.maxEvents!==void 0&&t.length>e.maxEvents)throw new Error(`Expected at most ${e.maxEvents} timeline events, got ${t.length}`);if(e.eventTypes){for(let n of e.eventTypes)if(!t.some(s=>s.type===n))throw new Error(`Expected timeline to contain event of type "${n}", but none found`)}if(e.agentEvents)for(let[n,o]of Object.entries(e.agentEvents)){let s=r.getEventsForAgent(n).length;if(s!==o)throw new Error(`Expected ${o} events for agent "${n}", got ${s}`)}if(e.hasType&&!t.some(o=>o.type===e.hasType))throw new Error(`Expected timeline to contain event of type "${e.hasType}"`);if(e.doesNotHaveType&&t.some(o=>o.type===e.doesNotHaveType))throw new Error(`Expected timeline NOT to contain event of type "${e.doesNotHaveType}"`)}function H(r,e){let t=0,n=e?.failAfter??0;return async(o,s,a)=>{if(t++,n>0&&t<=n)return {output:"success",messages:[],toolCalls:[],totalTokens:10};throw e?.delay&&e.delay>0&&await new Promise(i=>setTimeout(i,e.delay)),r??new Error("Runner failed")}}function L(r,e){if(r.length===0)throw new Error("Expected at least one reroute event, but none occurred");if(e.minReroutes!==void 0&&r.length<e.minReroutes)throw new Error(`Expected at least ${e.minReroutes} reroute events, got ${r.length}`);if(e.fromAgent&&!r.some(n=>n.originalAgent===e.fromAgent))throw new Error(`Expected reroute from agent "${e.fromAgent}", but no matching event found`);if(e.toAgent&&!r.some(n=>n.reroutedTo===e.toAgent))throw new Error(`Expected reroute to agent "${e.toAgent}", but no matching event found`);if(e.reason&&!r.some(n=>typeof e.reason=="string"?n.reason.includes(e.reason):e.reason.test(n.reason)))throw new Error(`Expected reroute reason matching ${e.reason}, but no matching event found`)}function J(r,e,t){let n=r.getMetrics(e);if(t.minScore!==void 0&&n.healthScore<t.minScore)throw new Error(`Expected agent "${e}" health score to be at least ${t.minScore}, got ${n.healthScore}`);if(t.maxScore!==void 0&&n.healthScore>t.maxScore)throw new Error(`Expected agent "${e}" health score to be at most ${t.maxScore}, got ${n.healthScore}`);if(t.circuitState!==void 0&&n.circuitState!==t.circuitState)throw new Error(`Expected agent "${e}" circuit state to be "${t.circuitState}", got "${n.circuitState}"`);if(t.minSuccessRate!==void 0&&n.successRate<t.minSuccessRate)throw new Error(`Expected agent "${e}" success rate to be at least ${t.minSuccessRate}, got ${n.successRate}`)}function U(r=100){let e=new y$1({maxCheckpoints:r}),t=[];return {inner:e,saved:t,getLatest:()=>t[t.length-1],async save(n){return t.push(n),e.save(n)},load:n=>e.load(n),list:()=>e.list(),delete:n=>e.delete(n),clear:()=>e.clear(),prune:()=>e.prune()}}function _(r,e){if(e.orchestratorType!==void 0&&r.orchestratorType!==e.orchestratorType)throw new Error(`Expected checkpoint orchestratorType "${e.orchestratorType}", got "${r.orchestratorType}"`);if(e.hasSystemExport===true&&(!r.systemExport||r.systemExport===""))throw new Error("Expected checkpoint to have non-empty systemExport, but it was empty");if(e.hasTimeline===true&&r.timelineExport===null)throw new Error("Expected checkpoint to have timeline export, but it was null");if(e.hasTimeline===false&&r.timelineExport!==null)throw new Error("Expected checkpoint to have no timeline export, but it was present");if(e.hasMemory===true&&r.memoryExport===null)throw new Error("Expected checkpoint to have memory export, but it was null");if(e.hasMemory===false&&r.memoryExport!==null)throw new Error("Expected checkpoint to have no memory export, but it was present");if(e.label!==void 0&&r.label!==e.label)throw new Error(`Expected checkpoint label "${e.label}", got "${r.label}"`)}function V(r={}){let e=[],t=null,n=false;return {handler:s=>{if(e.push(s),!n)throw new Error("[Directive] BreakpointSimulator: handler called but attachTo() was never called. Breakpoints will not be resolved. Call simulator.attachTo(orchestrator) after creation.");let a=r.autoResumeDelay??0,i=()=>{t&&(r.cancel?t.cancelBreakpoint(s.id,r.cancelReason):t.resumeBreakpoint(s.id,r.modifications));};a>0?setTimeout(i,a):queueMicrotask(i);},hits:e,attachTo:s=>{t=s,n=true;}}}function W(r,e){if(e.count!==void 0&&r.length!==e.count)throw new Error(`Expected ${e.count} breakpoint hits, got ${r.length}`);if(e.type&&!r.some(n=>n.type===e.type)){let n=r.map(o=>o.type).join(", ");throw new Error(`Expected breakpoint of type "${e.type}", found types: [${n}]`)}if(e.agentId&&!r.some(n=>n.agentId===e.agentId)){let n=r.map(o=>o.agentId).join(", ");throw new Error(`Expected breakpoint for agent "${e.agentId}", found agents: [${n}]`)}}function z(r,e){return {safeParse:t=>r(t)?{success:true,data:t}:{success:false,error:{message:"Validation failed"}},description:e}}async function K(r){let e=[];for await(let t of r)e.push(t);return e}function Q(r,e){if(e.minChunks!==void 0&&r.length<e.minChunks)throw new Error(`Expected at least ${e.minChunks} chunks, got ${r.length}`);if(e.agentIds){let t=new Set(r.map(n=>n.agentId));for(let n of e.agentIds)if(!t.has(n))throw new Error(`Expected chunks from agent "${n}", found agents: [${[...t].join(", ")}]`)}if(e.hasDone===true&&!r.some(n=>n.chunk.type==="done"))throw new Error("Expected at least one 'done' chunk, found none");if(e.hasErrors===true&&!r.some(n=>n.chunk.type==="error"))throw new Error("Expected at least one 'error' chunk, found none");if(e.hasErrors===false&&r.some(n=>n.chunk.type==="error"))throw new Error("Expected no 'error' chunks, but found some")}function X(r){let e=r?.passAfter??1,t=r?.feedback??"Needs improvement",n=r?.score,o=0;return (s,a)=>{o++;let i=o>=e;return {passed:i,feedback:i?void 0:t,score:n??(i?1:.5)}}}function Y(r,e){let t=r.getAll();for(let[n,o]of Object.entries(e)){let s=t[n];if(s!==o)throw new Error(`Expected scratchpad key "${n}" to be ${JSON.stringify(o)}, got ${JSON.stringify(s)}`)}}function Z(r,e){let t=r.derived;for(let[n,o]of Object.entries(e)){let s=t[n];if(typeof o=="object"&&o!==null){let a=i=>JSON.stringify(i,Object.keys(i).sort());if(a(s)!==a(o))throw new Error(`Expected derived value "${n}" to be ${JSON.stringify(o)}, got ${JSON.stringify(s)}`)}else if(s!==o)throw new Error(`Expected derived value "${n}" to be ${JSON.stringify(o)}, got ${JSON.stringify(s)}`)}}export{J as assertAgentHealth,W as assertBreakpointHit,_ as assertCheckpoint,I as assertDagExecution,Z as assertDerivedValues,N as assertMultiAgentState,Q as assertMultiplexedStream,M as assertOrchestratorState,L as assertRerouted,Y as assertScratchpadState,F as assertTimelineEvents,K as collectMultiplexedStream,R as createApprovalSimulator,V as createBreakpointSimulator,O as createConstraintRecorder,H as createFailingRunner,b as createMockAgentRunner,z as createMockSchema,y as createMockTask,U as createTestCheckpointStore,P as createTestDag,D as createTestMultiAgentOrchestrator,C as createTestOrchestrator,X as createTestReflectionEvaluator,B as createTestTimeline,q as createTimeController,T as testGuardrail,x as testGuardrailBatch};//# sourceMappingURL=testing.js.map
|
|
2
2
|
//# sourceMappingURL=testing.js.map
|