/** * Backend-internal handler types. * * `QueryParams` and `QueryResult` describe the callback-shaped contract * each backend's `handler.ts` exposes internally. They are NOT core * abstractions — `ChatBackend.runChatTurn` (in * `core/agent-runtime/capabilities.ts`) is the canonical surface every * consumer outside `src/backend/` talks to. These types exist only * because the per-backend handlers keep an internal callback-driven * stream loop that `handler-to-events.ts` adapts onto the native * `AsyncIterable` shape at the factory boundary. * * Living in `backend/shared/` keeps `core/types.ts` clean of any * implementation-detail shapes, so the dispatcher / cron / triggers / * frontends never accidentally couple to the callback contract. */ // ── Query lifecycle (backend-internal) ────────────────────────────────────── /** Parameters for a backend AI query. */ export type QueryParams = { chatId: string; /** * Model id resolved by the dispatcher for this chat/backend. Backends should * use this instead of re-reading chat settings so UI state, send-time guards, * and actual runtime model stay in lockstep. */ model?: string; text: string; senderName: string; /** Sender's platform handle without `@` (Telegram username, Discord username). */ senderHandle?: string; isGroup?: boolean; /** * Provider message ID. Telegram is numeric; Discord snowflakes are strings. */ messageId?: number | string; onStreamDelta?: (accumulated: string, phase?: "thinking" | "text") => void; onTextBlock?: (text: string) => Promise; /** * Callback backends report a tool call as one already-resolved unit — * their SDKs surface it at (or after) terminal status, with no separate * start/finish pair. `meta.failed` marks a call whose terminal status was * an error, so consumers can render it as failed rather than successful. * * Backends whose SDK exposes a live start signal should prefer the * `onToolStart` / `onToolEnd` pair below and only fall back to this * for calls whose start was never observed. */ onToolUse?: ( toolName: string, input: Record, meta?: { failed?: boolean }, ) => void; /** * Live tool lifecycle (backends with start signals — Codex emits * `item.started`). `callId` is the SDK's stable item id: the same id * must be passed to `onToolEnd` so consumers can pair the two and * measure a real duration. Without this pair, `onToolUse` collapses * call+result into one instant and every tool renders as 0ms. */ onToolStart?: ( callId: string, toolName: string, input: Record, ) => void; /** Terminal counterpart to [onToolStart]; ignored for unknown ids. */ onToolEnd?: ( callId: string, toolName: string, meta?: { failed?: boolean }, ) => void; }; /** Result of a backend AI query. */ export type QueryResult = { text: string; durationMs: number; inputTokens: number; outputTokens: number; cacheRead: number; cacheWrite: number; };