import { type AuraTTSOptions } from "./auraTTS"; import { type DeepgramSttOptions } from "./deepgramStt"; import type { Transport } from "./transport"; import { type TwilioWsTransportOptions } from "./transports/twilioWs"; export type CallerActionSpeak = { type: "speak"; text: string; /** Override the AI caller's TTS voice for this utterance. */ voice?: string; /** Cut off and barge-in over any in-flight service audio first. */ interrupt?: boolean; }; export type CallerActionSilence = { type: "silence"; /** How long to stay silent before doing anything else. */ ms: number; }; export type CallerActionHangup = { type: "hangup"; reason?: string; }; export type CallerAction = CallerActionSpeak | CallerActionSilence | CallerActionHangup; export type ConversationTurn = { speaker: "caller" | "service"; text: string; at: number; }; export type ScenarioContext = { /** Every utterance so far in chronological order. */ transcript: ConversationTurn[]; /** Total elapsed ms since the transport opened. */ elapsedMs: number; /** Most recent service utterance (or null if still waiting on greeting). */ lastServiceUtterance: string | null; /** How many caller turns have fired so far. */ callerTurnCount: number; }; export type ScenarioDecide = (ctx: ScenarioContext) => Promise | CallerAction; export type Scenario = { /** Short human label — `happy-path`, `adversarial`, etc. */ id: string; /** Hard ceiling on the whole conversation. */ maxDurationMs: number; /** Called when the service finishes an utterance (or after `idleMs` of no service speech). */ decide: ScenarioDecide; /** When the service stops emitting media for this long, wake decide() anyway. Default 1500. */ idleMs?: number; /** Max wait for the service to START responding after a caller speak. Default 8000. */ responseStartTimeoutMs?: number; }; export type RunScenarioOptions = { /** Pre-built transport (twilio-ws, discord, your own). */ transport: Transport; scenario: Scenario; tts: AuraTTSOptions; stt: DeepgramSttOptions; /** Optional logger; defaults to console.info. */ log?: (line: string) => void; }; export type ScenarioReport = { scenario: string; transport: string; transcript: ConversationTurn[]; callerTurns: number; serviceTurns: number; durationMs: number; endedReason: "scenario_hangup" | "timeout" | "transport_closed" | "error"; error?: { message: string; }; /** Content-integrity of the audio the CALLER heard (STT of the service's * speech). `duplicateServiceTurns` > 0 means the service repeated an * utterance verbatim back-to-back — the "repeated the last statement twice" / * overlapping-audio garble as actually heard over the wire. */ audioIntegrity: { serviceTurns: number; duplicateServiceTurns: number; mediaFrames: number; ok: boolean; }; }; export declare const runScenario: (options: RunScenarioOptions) => Promise; export type RunTwilioScenarioOptions = Omit & TwilioWsTransportOptions; export declare const runTwilioScenario: (options: RunTwilioScenarioOptions) => Promise; //# sourceMappingURL=aiCaller.d.ts.map