import type { StepId } from "../contracts/conversation.js"; import type { AgentEvent } from "../contracts/events.js"; import type { Usage } from "../contracts/provider.js"; export function textDeltaEvent(conversationId: string, turnId: string, delta: string): AgentEvent { return { type: "text-delta", conversationId, turnId, delta }; } export function reasoningDeltaEvent( conversationId: string, turnId: string, delta: string, ): AgentEvent { return { type: "reasoning-delta", conversationId, turnId, delta }; } export function toolCallEvent( conversationId: string, turnId: string, stepId: StepId, toolCallId: string, toolName: string, input: unknown, ): AgentEvent { return { type: "tool-call", conversationId, turnId, stepId, toolCallId, toolName, input }; } export function toolResultEvent( conversationId: string, turnId: string, stepId: StepId, toolCallId: string, toolName: string, content: string, isError: boolean, durationMs?: number, ): AgentEvent { const base = { type: "tool-result" as const, conversationId, turnId, stepId, toolCallId, toolName, content, isError, }; if (durationMs !== undefined) { return { ...base, durationMs }; } return base; } export function toolOutputEvent( conversationId: string, turnId: string, toolCallId: string, data: string, stream: "stdout" | "stderr", ): AgentEvent { return { type: "tool-output", conversationId, turnId, toolCallId, data, stream }; } export function usageEvent( conversationId: string, turnId: string, usage: Usage, stepId?: StepId, ): AgentEvent { if (stepId !== undefined) { return { type: "usage", conversationId, turnId, usage, stepId }; } return { type: "usage", conversationId, turnId, usage }; } export function turnStartEvent(conversationId: string, turnId: string): AgentEvent { return { type: "turn-start", conversationId, turnId }; } export function stepCompleteEvent( conversationId: string, turnId: string, stepId: StepId, timing?: { ttftMs?: number; decodeMs?: number; genTotalMs?: number }, ): AgentEvent { if (timing !== undefined) { if (timing.ttftMs !== undefined) { if (timing.decodeMs !== undefined && timing.genTotalMs !== undefined) { return { type: "step-complete", conversationId, turnId, stepId, ttftMs: timing.ttftMs, decodeMs: timing.decodeMs, genTotalMs: timing.genTotalMs, }; } if (timing.genTotalMs !== undefined) { return { type: "step-complete", conversationId, turnId, stepId, ttftMs: timing.ttftMs, genTotalMs: timing.genTotalMs, }; } return { type: "step-complete", conversationId, turnId, stepId, ttftMs: timing.ttftMs }; } if (timing.genTotalMs !== undefined) { return { type: "step-complete", conversationId, turnId, stepId, genTotalMs: timing.genTotalMs, }; } } return { type: "step-complete", conversationId, turnId, stepId }; } export function doneEvent( conversationId: string, turnId: string, reason: string, durationMs?: number, usage?: Usage, contextSize?: number, ): AgentEvent { if (durationMs !== undefined && usage !== undefined && contextSize !== undefined) { return { type: "done", conversationId, turnId, reason, durationMs, usage, contextSize }; } if (durationMs !== undefined && usage !== undefined) { return { type: "done", conversationId, turnId, reason, durationMs, usage }; } if (durationMs !== undefined && contextSize !== undefined) { return { type: "done", conversationId, turnId, reason, durationMs, contextSize }; } if (usage !== undefined && contextSize !== undefined) { return { type: "done", conversationId, turnId, reason, usage, contextSize }; } if (durationMs !== undefined) { return { type: "done", conversationId, turnId, reason, durationMs }; } if (usage !== undefined) { return { type: "done", conversationId, turnId, reason, usage }; } if (contextSize !== undefined) { return { type: "done", conversationId, turnId, reason, contextSize }; } return { type: "done", conversationId, turnId, reason }; } export function errorEvent( conversationId: string, turnId: string, message: string, code?: string, ): AgentEvent { if (code !== undefined) { return { type: "error", conversationId, turnId, message, code }; } return { type: "error", conversationId, turnId, message }; } export function providerRetryEvent( conversationId: string, turnId: string, attempt: number, delayMs: number, message: string, code?: string, ): AgentEvent { if (code !== undefined) { return { type: "provider-retry", conversationId, turnId, attempt, delayMs, message, code }; } return { type: "provider-retry", conversationId, turnId, attempt, delayMs, message }; }