/** * KHAELOR * File: tests/anthropic/fixtures.ts * Description: Recorded/mock Anthropic SSE event sequences for network-free Model Runtime tests. * * Author: Simon-Pierre Boucher * Contact: contact@spboucher.ai */ import type { RawMessageStreamEvent } from "@anthropic-ai/sdk/resources/messages"; export const REQUEST_ID = "msg_01TESTFIXTURE0000000000"; /** Turn a recorded array into the async iterable the SDK stream would provide. */ export async function* asRawStream( events: RawMessageStreamEvent[], ): AsyncGenerator { for (const event of events) { yield event; } } export function messageStart(overrides?: { id?: string; input_tokens?: number; output_tokens?: number; cache_read_input_tokens?: number | null; cache_creation_input_tokens?: number | null; }): RawMessageStreamEvent { return { type: "message_start", message: { id: overrides?.id ?? REQUEST_ID, type: "message", role: "assistant", model: "claude-sonnet-5", content: [], stop_reason: null, stop_sequence: null, usage: { input_tokens: overrides?.input_tokens ?? 120, output_tokens: overrides?.output_tokens ?? 1, cache_creation_input_tokens: overrides?.cache_creation_input_tokens ?? 0, cache_read_input_tokens: overrides?.cache_read_input_tokens ?? 0, cache_creation: null, server_tool_use: null, service_tier: "standard", }, }, } as unknown as RawMessageStreamEvent; } export function textBlockStart(index: number): RawMessageStreamEvent { return { type: "content_block_start", index, content_block: { type: "text", text: "", citations: null }, } as unknown as RawMessageStreamEvent; } export function textDelta(index: number, text: string): RawMessageStreamEvent { return { type: "content_block_delta", index, delta: { type: "text_delta", text }, } as RawMessageStreamEvent; } export function thinkingBlockStart(index: number): RawMessageStreamEvent { return { type: "content_block_start", index, content_block: { type: "thinking", thinking: "", signature: "" }, } as RawMessageStreamEvent; } export function thinkingDelta(index: number, thinking: string): RawMessageStreamEvent { return { type: "content_block_delta", index, delta: { type: "thinking_delta", thinking }, } as RawMessageStreamEvent; } export function signatureDelta(index: number, signature: string): RawMessageStreamEvent { return { type: "content_block_delta", index, delta: { type: "signature_delta", signature }, } as RawMessageStreamEvent; } export function toolUseBlockStart(index: number, id: string, name: string): RawMessageStreamEvent { return { type: "content_block_start", index, content_block: { type: "tool_use", id, name, input: {} }, } as RawMessageStreamEvent; } export function inputJsonDelta(index: number, partialJson: string): RawMessageStreamEvent { return { type: "content_block_delta", index, delta: { type: "input_json_delta", partial_json: partialJson }, } as RawMessageStreamEvent; } export function blockStop(index: number): RawMessageStreamEvent { return { type: "content_block_stop", index } as RawMessageStreamEvent; } export function messageDelta(overrides?: { stop_reason?: "end_turn" | "tool_use" | "max_tokens" | "refusal" | "stop_sequence"; output_tokens?: number; input_tokens?: number | null; cache_read_input_tokens?: number | null; cache_creation_input_tokens?: number | null; }): RawMessageStreamEvent { return { type: "message_delta", delta: { stop_reason: overrides?.stop_reason ?? "end_turn", stop_sequence: null }, usage: { output_tokens: overrides?.output_tokens ?? 12, input_tokens: overrides?.input_tokens ?? null, cache_creation_input_tokens: overrides?.cache_creation_input_tokens ?? null, cache_read_input_tokens: overrides?.cache_read_input_tokens ?? null, server_tool_use: null, }, } as unknown as RawMessageStreamEvent; } export function messageStop(): RawMessageStreamEvent { return { type: "message_stop" } as RawMessageStreamEvent; } /** A complete plain-text stream: "Hello" + " world". */ export function simpleTextStream(): RawMessageStreamEvent[] { return [ messageStart(), textBlockStart(0), textDelta(0, "Hello"), textDelta(0, " world"), blockStop(0), messageDelta({ stop_reason: "end_turn", output_tokens: 8 }), messageStop(), ]; } /** Thinking block, then text, then a tool call whose input spans three JSON chunks. */ export function toolCallStream(): RawMessageStreamEvent[] { return [ messageStart({ input_tokens: 300, cache_read_input_tokens: 200 }), thinkingBlockStart(0), thinkingDelta(0, "Consider the"), thinkingDelta(0, " weather."), signatureDelta(0, "sig-abc"), blockStop(0), textBlockStart(1), textDelta(1, "Checking the weather."), blockStop(1), toolUseBlockStart(2, "toolu_01AAA", "get_weather"), inputJsonDelta(2, '{"city":'), inputJsonDelta(2, ' "Par'), inputJsonDelta(2, 'is"}'), blockStop(2), messageDelta({ stop_reason: "tool_use", output_tokens: 47 }), messageStop(), ]; }