import type { BehaviorSubject } from 'rxjs'; import type { InboundMessage } from './platform'; /** Options for writing legacy LE-style agent environment values. */ export interface AgentEnvSetOptions { /** TTL in days, matching legacy `nn.agent.env(..., expire=days)`. */ expire?: number; } /** Legacy LE-style agent profile and global env shared by all dialogs of the agent. */ export interface AgentContext { /** Numeric NLU / LE agent id, when resolved by the host. */ id?: number; /** Omni / LE agent UUID, when resolved by the host. */ uuid?: string; /** Read/write agent-level env stored in Redis under `agent:{uuid}`. */ env?: { (): Promise>; (key: string): Promise; (key: string, value: unknown, options?: AgentEnvSetOptions): Promise; (values: Record, options?: AgentEnvSetOptions): Promise; }; /** * CMS / LE contact-rules default: `agent.recall_count`. * * Snapshot at script start (immutable for this session). Legacy parity: `nn.get_recall_count()`. * For the value that applies to the **current** dialog/call (including per-dialog overrides), * use top-level {@link ScriptDialogContext.recallCount}. */ recallCount?: number; /** * CMS / LE contact-rules default: `agent.delay`, converted to **seconds**. * * Snapshot at script start (immutable for this session). Legacy parity: `nn.get_recall_delay()` * (LE returns a time string; the host normalizes to seconds here). * For the effective delay on this dialog/call, use top-level {@link ScriptDialogContext.recallDelay}. */ recallDelay?: number; } /** Read LE/CMS global variables from `storage` with agent → company fallback. */ export type StorageContextApi = (...keys: string[]) => Promise>; /** * First-level **`context`** passed to every **`defineScript`** handler. * * Combines **identity** (dialog, script, agent), **telephony** (caller/destination), * **payload** (**`initialData`** vs **`dialogParams`**), **Voctiv platform** rows (**`dialogEntity`**), * and **runtime** (**`env$`**, **`runTime`**). The index signature allows extra host-specific keys. */ export interface ScriptDialogContext { /** Short language code, e.g. `"ru"`, `"en"`. */ lang: string; /** Full BCP-47 language tag, e.g. `"ru-RU"`, `"en-US"`. */ language: string; /** Business flag for routing (e.g. `"default"`, `"vip"`). */ flag: string; /** Unique dialog identifier (UUID). */ dialogUuid: string; /** Caller phone number or messaging source ID. */ msisdn: string; /** Inbound caller ID (same as msisdn for inbound calls). */ callerId: string; /** Called number (DID / destination for inbound calls). */ destinationNumber: string; /** * LE trunk id for this dialog/call — snapshot at script start. * * Resolved from `call.trunk_id`, inbound `X-Trunk-Id`, `dialog.params.trunk_id`, * then `agent.trunk_id`. Omitted when no trunk is configured. */ trunkId?: number; /** * LE `trunk.name` for {@link trunkId}, resolved by the host at script start. * * Available in online and headless runs when the platform trunk table is reachable. * Not a SIP wire header — for inbound id-only signalling use * `channel.sip.inviteSipHeaders['X-Trunk-Id']`. */ trunkName?: string; /** Script record ID in the system. */ scriptId: string; /** Human-readable script name. */ scriptName: string; /** Agent UUID from Omni platform (links script to an NLU agent). */ agentUuid?: string; /** * Numeric NLU agent id used for `platform.nlu.extract()` and legacy DB operations. * * Resolved by the server from LE dialog/call, Omni `nlu.agentId`, or optional env * (`NLU_DEFAULT_AGENT_ID` / `AGENT_ID`). Client/session params named `agent_id`, `agentId`, `agentUuid`, * and `agent_uuid` are stripped before context construction and cannot spoof it. * May be `0` when no agent id is configured; NLU and `platform.call()` will then fail. */ agentId: number; /** * Agent identity, CMS recall defaults, and legacy global agent env (`context.agent.env`). * * {@link AgentContext.recallCount} / {@link AgentContext.recallDelay} are agent-wide settings * from CMS. Top-level {@link ScriptDialogContext.recallCount} / {@link ScriptDialogContext.recallDelay} * are the **effective** values for this run (dialog/call params override agent defaults). */ agent?: AgentContext; /** * Read global variables configured in agent settings, then company-level globals. * Always returns an object containing every requested key. */ storage?: StorageContextApi; /** * **Snapshot** of dialog/session payload when the script run started. * * Shallow copy of the merge **`channelParams` + `sessionParams`** after the server removes * untrusted keys (e.g. client cannot spoof **`agentUuid`** here). **Do not mutate** — use * **`dialogParams`** for the live map. Compare with **`dialogParams`** to see what changed * during the call (if the host updates the live object). */ initialData: Record; /** * **Live** dialog/session parameter map for this run (same merge as **`initialData`** at start). * * The host may add or overwrite keys while the session progresses. For media scripts this * aligns with {@link import('./media-channel').MediaChannel.params} (Omni defaults, route, * Voctiv platform ASR/TTS: **`defaultAsrName`**, **`defaultTtsName`**, **`asrVendor`**, **`ttsVendor`**, * **`asrConfig`**, **`ttsConfig`**, **`authentication_data`**, **`legacyAsrKeysByName`** / * **`legacyTtsKeysByName`**, etc.). **Read/write** according to your integration; scripts should * treat unknown keys as opaque. */ dialogParams: Record; /** Whether Voctiv platform compatibility mode is active. */ legacyV3Compat: boolean; /** * `true` when the script runs without a real media channel (offline / queue / messaging). * * In this mode ASR/TTS/audio/SIP operations are inert or synthetic. Use text payloads, * `platform.nlu`, `platform.messaging`, `platform.call`, `channel.llm`, and `env$` * for background dialog logic. */ headless: boolean; /** * Persisted dialog environment for this conversation. ScriptEngine converts the * plain persisted `env` snapshot into this `BehaviorSubject` before invoking the script. * On the first call the value is `undefined`. * * **Read/write only via `env$`:** use `env$.getValue()`, `env$.next(partialOrNext)`, or * `env$.subscribe(...)`. Do not use a plain `context.env` — it is not provided. * * **Persistence:** On script completion (success or error), the runtime snapshots `env$` and * attaches it to the persisted result; the script return value must not carry env * (see {@link ScriptResult}). * * Session runners load the previous snapshot from Redis (`dialog:{uuid}`) at start and * persist the final `env$` snapshot after every run (SIP, WebSocket, headless). Same key * as legacy logic-executor `nn.env`. */ env$?: BehaviorSubject | undefined>; /** Raw `dialog` table row from the Voctiv platform database. */ dialogEntity?: Record; /** Raw `call` table row from the Voctiv platform database. */ callEntity?: Record; /** * Optional catalog of media keys exposed to the script (Voctiv platform / Omni), e.g. UUIDs or labels * for UI or logging. **Credentials** still come from **`dialogParams.authentication_data`** * (and the channel mirror); use **`name`** on {@link import('./asr-handle').AsrConfig} / * {@link import('./mixer').PlayOptions} to select **`key_storage.name`** when LE credential maps exist. */ availableMediaKeys?: string[]; /** * Routing hint from `dialog.params.entry_point` **at script start** (snapshot). * * Use with {@link getScriptPhase} to branch inside the same `defineScript` export. * Assigning this property does **not** persist — write via * {@link import('./platform').DialogApi.entryPoint} (`platform.dialog.entryPoint`). */ entryPoint?: string; /** * True when this live session started **before** the final 200 OK — the leg had * media (183 with SDP) but was not answered yet. Snapshot at script start: it * describes how the run began and does not flip when the answer arrives; use * `channel.sip.isAnswered` / `answered$` for the live state. * * Set by the host only for scripts that opted in via * {@link import('./call-options').ScriptCallOptions.outboundCallMode} `'from_invite'`, * and surfaced as {@link ScriptPhase} `'early'` by {@link getScriptPhase}. */ startedBeforeAnswer?: boolean; /** * True when this live session started with **no leg at all** — the script dials one * itself via `channel.sip.makeCall()`. Set only for scripts that opted in via * {@link import('./call-options').ScriptCallOptions.outboundCallMode} `'script_dial'`, and * surfaced as {@link ScriptPhase} `'dialing'` by {@link getScriptPhase}. * * Like {@link startedBeforeAnswer}, a snapshot of how the run began: it stays true after * the script opens a leg. */ startedWithoutLeg?: boolean; /** Current recall attempt number for this dialog (from `dialog.params.attempt`, starts at 0). */ attempt?: number; /** * Effective max recall attempts for **this** dialog/call. * * Resolved at script start: `dialog.params` / `call.params` (`recall_count`) override * {@link AgentContext.recallCount} from CMS. Omitted when no value is configured. * The host may default {@link import('./platform').ScheduleCallOptions.recallCount} from this * field when scheduling outbound calls without explicit recall options and without * {@link import('./platform').ScheduleCallOptions.onFailedCall}. */ recallCount?: number; /** * Effective delay in **seconds** between recall attempts for **this** dialog/call. * * Resolved at script start: `dialog.params` / `call.params` (`recall_delay`) override * {@link AgentContext.recallDelay} from CMS (`agent.delay` converted to seconds). * Omitted when no value is configured. The host may default * {@link import('./platform').ScheduleCallOptions.recallDelay} from this field under the same * conditions as {@link recallCount}. */ recallDelay?: number; /** * Inbound message that triggered this headless session. * * Present for messaging-driven offline runs, commonly with * `entryPoint === "on_message_api_received"`. The `payload` field is the raw * provider payload; normalize text defensively because transports may use * different keys such as `text`, `message`, `body`, or `content`. */ inboundMessage?: InboundMessage; /** * Async-phase execution budget: remaining time, extension pool, {@link ScriptRunTime.extend}. * Injected by the runtime; absent only in tests or non-standard hosts. */ runTime?: ScriptRunTime; /** Opaque NLU runtime config managed by ScriptEngine. */ _nlu?: unknown; [key: string]: unknown; } /** * Time budget for the script async phase (after VM load). Lets scripts check remaining time * and request limited extensions (capped by the runtime). */ export interface ScriptRunTime { /** Initial budget in ms before any {@link extend}. */ readonly budgetMs: number; /** Maximum total extra ms grantable across all {@link extend} calls for this session. */ readonly maxExtendMs: number; /** Milliseconds left until the runtime stops the async script phase. */ remainingMs(): number; /** Extension quota not yet granted (ms). */ remainingExtendMs(): number; /** * Grants up to `requestedMs` additional runtime, limited by remaining extension quota. * @returns Granted milliseconds (0 if nothing could be granted). */ extend(requestedMs: number): number; } /** * High-level phase of a script execution lifecycle. Useful for branching logic * between pre-call preparation, the live call, and post-call processing. */ export type ScriptPhase = 'before_call' | 'dialing' | 'early' | 'online' | 'after_call_success' | 'after_call_failed' | 'messaging' | 'recall' | 'headless_other'; /** * Determines which phase of the dialog lifecycle the script is currently executing in. * * - `before_call` — headless run that typically schedules an outbound call. * - `dialing` — live session that started with no leg: the script opens one itself with * `channel.sip.makeCall()` and talks on the channel that returns. Only scripts that opt * in via {@link import('./call-options').ScriptCallOptions.outboundCallMode} `'script_dial'` * ever see it. * - `early` — live SIP/media session that started before the final answer. Only scripts * that opt in via {@link import('./call-options').ScriptCallOptions.outboundCallMode} * `'from_invite'` ever see it; await `channel.sip.waitForAnswer()` to reach the * conversation. * - `online` — live SIP/media session (voice call active). * - `after_call_success` — headless run after a successful call completion. * - `after_call_failed` — headless run after call failure (no answer, reject, etc.). * - `messaging` — headless run triggered by an inbound message. * - `recall` — headless recall attempt. * - `headless_other` — any other headless invocation not matching the above. */ export declare function getScriptPhase(context: ScriptDialogContext): ScriptPhase; /** Error info attached to {@link ScriptResult} when a script fails. */ export interface ScriptError { /** * Machine-readable category, e.g. `script_error`, `script_load_failed`, `time_limit_exceeded`. */ code: string; /** Human-readable error description. */ message: string; /** Stack trace (when available). */ stack?: string; } /** * Value returned by a script function. Only `output` and `error` are valid fields. * Session state is updated via `context.env$`; the runtime snapshots it separately. * * This is **not** the LE `dialog.result` lifecycle column — that is * {@link import('./platform').DialogApi.result} (`platform.dialog.result`). */ export interface ScriptResult { /** * Output data for dialog_stats / host persistence. * Not {@link import('./platform').DialogApi.result}. */ output?: Record; /** Error details (auto-populated on script crash, or set manually). */ error?: ScriptError; } /** * Result after the runtime attaches the final `env$` snapshot (Voctiv platform persistence). * Scripts never construct this type — use {@link ScriptResult} from `defineScript` handlers. */ export interface PersistedScriptResult extends ScriptResult { env?: Record; } //# sourceMappingURL=script-context.d.ts.map