@niadra/sdk 0.7.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +46 -0
- package/README.md +15 -6
- package/dist/ai-sdk.cjs +3 -4
- package/dist/ai-sdk.cjs.map +1 -1
- package/dist/ai-sdk.d.cts +3 -3
- package/dist/ai-sdk.d.ts +3 -3
- package/dist/ai-sdk.js +3 -4
- package/dist/ai-sdk.js.map +1 -1
- package/dist/anthropic.cjs +1 -1
- package/dist/anthropic.cjs.map +1 -1
- package/dist/anthropic.d.cts +4 -4
- package/dist/anthropic.d.ts +4 -4
- package/dist/anthropic.js +1 -1
- package/dist/anthropic.js.map +1 -1
- package/dist/bedrock.cjs +1 -1
- package/dist/bedrock.cjs.map +1 -1
- package/dist/bedrock.d.cts +4 -4
- package/dist/bedrock.d.ts +4 -4
- package/dist/bedrock.js +1 -1
- package/dist/bedrock.js.map +1 -1
- package/dist/cli.js +107 -51
- package/dist/cli.js.map +1 -1
- package/dist/{client-DsIxZxZk.d.cts → client-B_ip8T2o.d.cts} +69 -14
- package/dist/{client-DsIxZxZk.d.ts → client-B_ip8T2o.d.ts} +69 -14
- package/dist/cloudflare-agents.cjs +1 -1
- package/dist/cloudflare-agents.cjs.map +1 -1
- package/dist/cloudflare-agents.d.cts +3 -3
- package/dist/cloudflare-agents.d.ts +3 -3
- package/dist/cloudflare-agents.js +1 -1
- package/dist/cloudflare-agents.js.map +1 -1
- package/dist/elevenlabs.cjs +1 -1
- package/dist/elevenlabs.cjs.map +1 -1
- package/dist/elevenlabs.d.cts +5 -5
- package/dist/elevenlabs.d.ts +5 -5
- package/dist/elevenlabs.js +1 -1
- package/dist/elevenlabs.js.map +1 -1
- package/dist/genkit.cjs +1 -1
- package/dist/genkit.cjs.map +1 -1
- package/dist/genkit.d.cts +3 -3
- package/dist/genkit.d.ts +3 -3
- package/dist/genkit.js +1 -1
- package/dist/genkit.js.map +1 -1
- package/dist/google-adk.cjs +1 -1
- package/dist/google-adk.cjs.map +1 -1
- package/dist/google-adk.d.cts +3 -3
- package/dist/google-adk.d.ts +3 -3
- package/dist/google-adk.js +1 -1
- package/dist/google-adk.js.map +1 -1
- package/dist/google-genai.cjs +1 -1
- package/dist/google-genai.cjs.map +1 -1
- package/dist/google-genai.d.cts +4 -4
- package/dist/google-genai.d.ts +4 -4
- package/dist/google-genai.js +1 -1
- package/dist/google-genai.js.map +1 -1
- package/dist/index.cjs +106 -48
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -8
- package/dist/index.d.ts +6 -8
- package/dist/index.js +106 -48
- package/dist/index.js.map +1 -1
- package/dist/{intercept-D7qFCaRb.d.ts → intercept-CBaPK_-k.d.ts} +1 -1
- package/dist/{intercept-0_lJE6k1.d.cts → intercept-CxmBLfoj.d.cts} +1 -1
- package/dist/langchain.cjs +3 -4
- package/dist/langchain.cjs.map +1 -1
- package/dist/langchain.d.cts +3 -3
- package/dist/langchain.d.ts +3 -3
- package/dist/langchain.js +3 -4
- package/dist/langchain.js.map +1 -1
- package/dist/livekit.cjs +1 -1
- package/dist/livekit.cjs.map +1 -1
- package/dist/livekit.d.cts +3 -3
- package/dist/livekit.d.ts +3 -3
- package/dist/livekit.js +1 -1
- package/dist/livekit.js.map +1 -1
- package/dist/llamaindex.cjs +1 -1
- package/dist/llamaindex.cjs.map +1 -1
- package/dist/llamaindex.d.cts +3 -3
- package/dist/llamaindex.d.ts +3 -3
- package/dist/llamaindex.js +1 -1
- package/dist/llamaindex.js.map +1 -1
- package/dist/mastra.cjs +3 -4
- package/dist/mastra.cjs.map +1 -1
- package/dist/mastra.d.cts +3 -3
- package/dist/mastra.d.ts +3 -3
- package/dist/mastra.js +3 -4
- package/dist/mastra.js.map +1 -1
- package/dist/openai-agents.cjs +1 -1
- package/dist/openai-agents.cjs.map +1 -1
- package/dist/openai-agents.d.cts +3 -3
- package/dist/openai-agents.d.ts +3 -3
- package/dist/openai-agents.js +1 -1
- package/dist/openai-agents.js.map +1 -1
- package/dist/retell.cjs +1 -1
- package/dist/retell.cjs.map +1 -1
- package/dist/retell.d.cts +5 -5
- package/dist/retell.d.ts +5 -5
- package/dist/retell.js +1 -1
- package/dist/retell.js.map +1 -1
- package/dist/{shared-Bb5B59Bu.d.ts → shared-BLkAbvuf.d.ts} +1 -1
- package/dist/{shared-DTPWVlWm.d.cts → shared-DEkF2Y_z.d.cts} +1 -1
- package/dist/strands.cjs +1 -1
- package/dist/strands.cjs.map +1 -1
- package/dist/strands.d.cts +3 -3
- package/dist/strands.d.ts +3 -3
- package/dist/strands.js +1 -1
- package/dist/strands.js.map +1 -1
- package/dist/twilio.d.cts +4 -4
- package/dist/twilio.d.ts +4 -4
- package/dist/vapi.cjs +1 -1
- package/dist/vapi.cjs.map +1 -1
- package/dist/vapi.d.cts +5 -5
- package/dist/vapi.d.ts +5 -5
- package/dist/vapi.js +1 -1
- package/dist/vapi.js.map +1 -1
- package/dist/voltagent.cjs +1 -1
- package/dist/voltagent.cjs.map +1 -1
- package/dist/voltagent.d.cts +3 -3
- package/dist/voltagent.d.ts +3 -3
- package/dist/voltagent.js +1 -1
- package/dist/voltagent.js.map +1 -1
- package/dist/{webhook-1ozGyksG.d.ts → webhook-BaraTaA9.d.ts} +1 -1
- package/dist/{webhook-CG4om_DK.d.cts → webhook-CuR0Wckd.d.cts} +1 -1
- package/dist/whatsapp.d.cts +2 -2
- package/dist/whatsapp.d.ts +2 -2
- package/package.json +1 -1
package/dist/retell.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/tools.ts","../src/context.ts","../src/integrations/shared.ts","../src/integrations/webhook.ts","../src/integrations/retell.ts"],"names":["message"],"mappings":"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","file":"retell.js","sourcesContent":["import { NiadraAPIError, NiadraValidationError } from \"./errors.js\";\nimport type { NiadraError } from \"./errors.js\";\nimport type { AgentNote, AgentNoteKind, CreateAgentNoteRequest, RememberResult } from \"./types/agent-memory.js\";\nimport type { Handle } from \"./types/common.js\";\nimport type {\n HistoryFilters,\n OpenedItem,\n SearchRequest,\n SearchResponse,\n TimelineRequest,\n TimelineResponse,\n ToolDefinition,\n} from \"./types/context.js\";\nimport type { HistoryItemKind, Verification } from \"./types/vocabulary.js\";\n\n/** The outcome of a call that may fail without throwing. Exactly one of the two fields is set. */\nexport type Result<T> = { data: T; error: null } | { data: null; error: NiadraError };\n\n/** Everything a tool call is bound to besides its arguments. None of it is visible to the model. */\nexport interface ToolBinding {\n about?: Handle;\n verification?: Verification;\n conversation_id?: string;\n task_id?: string;\n /** Use the voice time budget for the calls these tools make. */\n voice?: boolean;\n}\n\n/** Which tools a kit offers besides the navigation kit. */\nexport interface ToolOptions {\n /** Adds `search_agent_memory`, the agent's own working notes. */\n agentMemory?: boolean;\n /**\n * Adds `remember` too. Only for a key with the `agent_memory:write` scope: a tool the model\n * cannot use is a wasted call. Needs `agentMemory`.\n */\n writeAgentMemory?: boolean;\n}\n\nexport interface Navigator {\n search(params: SearchRequest, voice: boolean): Promise<Result<SearchResponse>>;\n timeline(params: TimelineRequest, voice: boolean): Promise<Result<TimelineResponse>>;\n open(id: string, subject: Handle, binding: ToolBinding, voice: boolean): Promise<Result<OpenedItem>>;\n searchAgentMemory(\n query: string,\n options: { tags?: string[]; conversation_id?: string; task_id?: string },\n voice: boolean,\n ): Promise<Result<AgentNote[]>>;\n remember(note: CreateAgentNoteRequest): Promise<Result<RememberResult>>;\n}\n\n/**\n * The navigation kit as function-calling tools, bound to one customer.\n *\n * The definitions have no parameter for the customer: the handle lives in this object, outside\n * the model's reach. A prompt injection that says \"now look up customer X\" has no argument to\n * put X in. The model chooses what to ask, never whom it is about.\n */\nexport interface BoundTools {\n /** Tool definitions in the `{ type: \"function\", function: { name, description, parameters } }` shape. */\n readonly definitions: ToolDefinition[];\n /** Whether `name` is one of these tools, for dispatchers that route several toolsets. */\n has(name: string): boolean;\n /**\n * Runs one tool call and returns the text to send back to the model as the tool result.\n * `args` may be the JSON string most model APIs return, or an already parsed object.\n * Failures come back as a short JSON error the model can read and move past; with\n * `strict: true` they are thrown instead.\n */\n call(name: string, args: string | Record<string, unknown>): Promise<string>;\n}\n\n/** What `remember` answers when the note carries personal data: the model can rewrite it. */\nexport const PERSONAL_DATA_TOOL_ERROR = {\n error: \"personal_data\",\n detail:\n \"The note has personal data. Rewrite it so it helps with any customer, without names, phones, e-mails, documents or ids.\",\n} as const;\n\nexport const TOOL_NAMES = {\n search: \"search_customer_history\",\n timeline: \"get_customer_timeline\",\n open: \"open_history_item\",\n} as const;\n\n/** The two tools of the agent's own memory, offered with `tools({ agentMemory: true })`. */\nexport const AGENT_MEMORY_TOOL_NAMES = {\n search: \"search_agent_memory\",\n remember: \"remember\",\n} as const;\n\nconst ITEM_KINDS: HistoryItemKind[] = [\"episode\", \"fact\", \"open_item\", \"action\", \"object\", \"trait\"];\nconst NOTE_KINDS: AgentNoteKind[] = [\"procedure\", \"tool_note\", \"process_note\", \"pitfall\"];\n\n/**\n * The navigation kit, word for word the server's canonical definitions (`GET /v1/history/tools`)\n * and the Python SDK's: a model sees one toolset whatever language the agent is written in. The\n * server names the context's history line in the space's language; the SDKs ship its default.\n */\nexport const TOOL_DEFINITIONS: readonly ToolDefinition[] = [\n {\n \"type\": \"function\",\n \"function\": {\n \"name\": \"search_customer_history\",\n \"description\": \"Search everything that already happened with this customer: past conversations, promises, agent actions, orders and invoices. Use it when the customer refers to something earlier or asks whether a problem happened before. Do not call it when the answer is already in the context block, including its 'Do histórico' line, which already counts recurrences. Returns short items with date, channel and outcome, plus a recurrence count. Open one with open_history_item.\",\n \"parameters\": {\n \"type\": \"object\",\n \"properties\": {\n \"query\": {\n \"type\": \"string\",\n \"description\": \"What to look for, in the customer's words.\"\n },\n \"filters\": {\n \"type\": \"object\",\n \"properties\": {\n \"since\": {\n \"type\": \"string\",\n \"format\": \"date-time\"\n },\n \"until\": {\n \"type\": \"string\",\n \"format\": \"date-time\"\n },\n \"when\": {\n \"type\": \"string\",\n \"description\": \"The period in the customer's own words, as they said it: 'last week', 'semana passada', 'en marzo'.\"\n },\n \"channels\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\"\n }\n },\n \"categories\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\"\n }\n },\n \"item_kinds\": {\n \"type\": \"array\",\n \"items\": {\n \"enum\": [\n \"episode\",\n \"fact\",\n \"open_item\",\n \"action\",\n \"object\",\n \"trait\"\n ]\n }\n },\n \"outcome\": {\n \"type\": \"string\"\n }\n },\n \"additionalProperties\": false\n },\n \"max_tokens\": {\n \"type\": \"integer\",\n \"minimum\": 50,\n \"maximum\": 4000\n }\n },\n \"required\": [\n \"query\"\n ],\n \"additionalProperties\": false\n }\n }\n },\n {\n \"type\": \"function\",\n \"function\": {\n \"name\": \"get_customer_timeline\",\n \"description\": \"List this customer's conversations and agent actions in order, newest first, one line each. Use it to leaf through the history when you do not know what to search for. Pass next_cursor to continue. Prefer search_customer_history for a specific question.\",\n \"parameters\": {\n \"type\": \"object\",\n \"properties\": {\n \"cursor\": {\n \"type\": \"string\"\n },\n \"limit\": {\n \"type\": \"integer\",\n \"minimum\": 1,\n \"maximum\": 100\n },\n \"filters\": {\n \"type\": \"object\",\n \"properties\": {\n \"since\": {\n \"type\": \"string\",\n \"format\": \"date-time\"\n },\n \"until\": {\n \"type\": \"string\",\n \"format\": \"date-time\"\n },\n \"when\": {\n \"type\": \"string\",\n \"description\": \"The period in the customer's own words, as they said it: 'last week', 'semana passada', 'en marzo'.\"\n },\n \"channels\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\"\n }\n },\n \"categories\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\"\n }\n },\n \"item_kinds\": {\n \"type\": \"array\",\n \"items\": {\n \"enum\": [\n \"episode\",\n \"fact\",\n \"open_item\",\n \"action\",\n \"object\",\n \"trait\"\n ]\n }\n },\n \"outcome\": {\n \"type\": \"string\"\n }\n },\n \"additionalProperties\": false\n }\n },\n \"additionalProperties\": false\n }\n }\n },\n {\n \"type\": \"function\",\n \"function\": {\n \"name\": \"open_history_item\",\n \"description\": \"Open one conversation or business object returned by search_customer_history or get_customer_timeline: what was asked, what was promised and by whom, the outcome and what memory came from it. Use it only after a search or timeline pointed to the item.\",\n \"parameters\": {\n \"type\": \"object\",\n \"properties\": {\n \"id\": {\n \"type\": \"string\",\n \"description\": \"The item id, e.g. `episode:...`.\"\n }\n },\n \"required\": [\n \"id\"\n ],\n \"additionalProperties\": false\n }\n }\n }\n] as ToolDefinition[];\n\n/**\n * `search_agent_memory` and `remember`, word for word the server's canonical definitions. They\n * read and write the agent's working notes, never anything about a customer.\n */\nexport const AGENT_MEMORY_TOOL_DEFINITIONS: readonly ToolDefinition[] = [\n {\n \"type\": \"function\",\n \"function\": {\n \"name\": \"search_agent_memory\",\n \"description\": \"Search your own working notes: procedures, how the company's tools and processes behave, and known pitfalls. Use it before a task or a tool call you are unsure how to do. It holds nothing about customers; for the customer's history use search_customer_history.\",\n \"parameters\": {\n \"type\": \"object\",\n \"properties\": {\n \"query\": {\n \"type\": \"string\",\n \"description\": \"What you need to know how to do.\"\n },\n \"tags\": {\n \"type\": \"array\",\n \"maxItems\": 8,\n \"items\": {\n \"type\": \"string\",\n \"pattern\": \"^[a-z0-9][a-z0-9_.:-]{0,63}$\"\n },\n \"description\": \"Object types, operations or systems, e.g. `invoice`, `credit`, `erp`.\"\n }\n },\n \"required\": [\n \"query\"\n ],\n \"additionalProperties\": false\n }\n }\n },\n {\n \"type\": \"function\",\n \"function\": {\n \"name\": \"remember\",\n \"description\": \"Save a working note for yourself and future runs: a procedure that worked, how a tool or process behaves, or a pitfall to avoid. Never write anything about a customer here: no names, phones, e-mails, documents, ids or words from the conversation. A note with personal data is refused. Write it so it helps with any customer.\",\n \"parameters\": {\n \"type\": \"object\",\n \"properties\": {\n \"kind\": {\n \"enum\": [\n \"procedure\",\n \"tool_note\",\n \"process_note\",\n \"pitfall\"\n ]\n },\n \"title\": {\n \"type\": \"string\",\n \"maxLength\": 120\n },\n \"body\": {\n \"type\": \"string\",\n \"maxLength\": 2000\n },\n \"tags\": {\n \"type\": \"array\",\n \"maxItems\": 8,\n \"items\": {\n \"type\": \"string\",\n \"pattern\": \"^[a-z0-9][a-z0-9_.:-]{0,63}$\"\n },\n \"description\": \"Object types, operations or systems, e.g. `invoice`, `credit`, `erp`.\"\n }\n },\n \"required\": [\n \"kind\",\n \"title\",\n \"body\"\n ],\n \"additionalProperties\": false\n }\n }\n }\n] as ToolDefinition[];\n\nfunction parseArgs(args: string | Record<string, unknown>): Record<string, unknown> {\n if (typeof args !== \"string\") return args;\n if (args.trim() === \"\") return {};\n let parsed: unknown;\n try {\n parsed = JSON.parse(args);\n } catch {\n throw new NiadraValidationError(\"tool arguments are not valid JSON\");\n }\n if (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) {\n throw new NiadraValidationError(\"tool arguments must be a JSON object\");\n }\n return parsed as Record<string, unknown>;\n}\n\nfunction str(args: Record<string, unknown>, name: string): string | undefined {\n const value = args[name];\n return typeof value === \"string\" && value.length > 0 ? value : undefined;\n}\n\nfunction strings(args: Record<string, unknown>, name: string): string[] | undefined {\n const value = args[name];\n if (!Array.isArray(value)) return undefined;\n const list = value.filter((entry): entry is string => typeof entry === \"string\");\n return list.length > 0 ? list : undefined;\n}\n\nfunction int(args: Record<string, unknown>, name: string): number | undefined {\n const value = args[name];\n return typeof value === \"number\" && Number.isInteger(value) ? value : undefined;\n}\n\n/** The filters of a call: the `filters` object of the canonical definitions. */\nfunction filtersFrom(args: Record<string, unknown>): HistoryFilters {\n const nested = args.filters;\n const source: Record<string, unknown> =\n typeof nested === \"object\" && nested !== null && !Array.isArray(nested) ? (nested as Record<string, unknown>) : {};\n const filters: HistoryFilters = {};\n const since = str(source, \"since\");\n const until = str(source, \"until\");\n const when = str(source, \"when\");\n const channels = strings(source, \"channels\");\n const categories = strings(source, \"categories\");\n const kinds = strings(source, \"item_kinds\")\n ?.filter((kind): kind is HistoryItemKind => (ITEM_KINDS as string[]).includes(kind));\n const outcome = str(source, \"outcome\");\n if (since) filters.since = since;\n if (until) filters.until = until;\n if (when) filters.when = when.slice(0, 100);\n if (channels) filters.channels = channels;\n if (categories) filters.categories = categories;\n if (kinds?.length) filters.item_kinds = [...new Set(kinds)];\n if (outcome) filters.outcome = outcome;\n return filters;\n}\n\nfunction tagsFrom(args: Record<string, unknown>): string[] | undefined {\n return strings(args, \"tags\")?.slice(0, 8);\n}\n\n/** Builds the bound toolset. `strict` decides whether failures are thrown or described to the model. */\nexport function bindTools(\n subject: Handle,\n binding: ToolBinding,\n navigator: Navigator,\n strict: boolean,\n options: ToolOptions = {},\n): BoundTools {\n const voice = binding.voice ?? false;\n const memory = options.agentMemory ? AGENT_MEMORY_TOOL_DEFINITIONS.slice(0, options.writeAgentMemory ? 2 : 1) : [];\n const definitions: ToolDefinition[] = [...TOOL_DEFINITIONS, ...memory];\n const names = new Set(definitions.map((definition) => definition.function.name));\n\n async function run(name: string, args: Record<string, unknown>): Promise<Result<unknown>> {\n switch (name) {\n case TOOL_NAMES.search: {\n const query = str(args, \"query\");\n if (!query) throw new NiadraValidationError(\"search_customer_history needs a query\");\n const request: SearchRequest = { subject, query, filters: filtersFrom(args) };\n applyBinding(request, binding);\n if (binding.task_id) request.task_id = binding.task_id;\n const maxTokens = int(args, \"max_tokens\");\n if (maxTokens !== undefined) request.max_tokens = Math.min(4000, Math.max(50, maxTokens));\n const result = await navigator.search(request, voice);\n return result.error ? result : { data: compactSearch(result.data), error: null };\n }\n case TOOL_NAMES.timeline: {\n const request: TimelineRequest = { subject, filters: filtersFrom(args) };\n applyBinding(request, binding);\n const cursor = str(args, \"cursor\");\n if (cursor) request.cursor = cursor;\n const limit = int(args, \"limit\");\n if (limit !== undefined) request.limit = Math.min(100, Math.max(1, limit));\n return navigator.timeline(request, voice);\n }\n case TOOL_NAMES.open: {\n const id = str(args, \"id\");\n if (!id) throw new NiadraValidationError(\"open_history_item needs an id\");\n return navigator.open(id, subject, binding, voice);\n }\n case AGENT_MEMORY_TOOL_NAMES.search: {\n const query = str(args, \"query\");\n if (!query) throw new NiadraValidationError(\"search_agent_memory needs a query\");\n const scope: { tags?: string[]; conversation_id?: string; task_id?: string } = {};\n const tags = tagsFrom(args);\n if (tags) scope.tags = tags;\n if (binding.conversation_id) scope.conversation_id = binding.conversation_id;\n else if (binding.task_id) scope.task_id = binding.task_id;\n const result = await navigator.searchAgentMemory(query, scope, voice);\n return result.error ? result : { data: { notes: result.data.map(compactNote) }, error: null };\n }\n case AGENT_MEMORY_TOOL_NAMES.remember: {\n const kind = str(args, \"kind\");\n const title = str(args, \"title\");\n const body = str(args, \"body\");\n if (!kind || !(NOTE_KINDS as string[]).includes(kind) || !title || !body) {\n throw new NiadraValidationError(\"remember needs a kind, a title and a body\");\n }\n const note: CreateAgentNoteRequest = { kind: kind as AgentNoteKind, title, body };\n const tags = tagsFrom(args);\n if (tags) note.tags = tags;\n if (binding.conversation_id) note.evidence = { conversation_id: binding.conversation_id };\n else if (binding.task_id) note.evidence = { task_id: binding.task_id };\n const result = await navigator.remember(note);\n return result.error ? result : { data: remembered(result.data), error: null };\n }\n default:\n throw new NiadraValidationError(`unknown tool: ${name}`);\n }\n }\n\n return {\n definitions: definitions.map((definition) => cloneDefinition(definition)),\n has: (name) => names.has(name),\n async call(name, rawArgs) {\n let result: Result<unknown>;\n try {\n if (!names.has(name)) throw new NiadraValidationError(`unknown tool: ${name}`);\n result = await run(name, parseArgs(rawArgs));\n } catch (error) {\n // Even a strict client hands this one to the model: rewriting the note is the answer.\n if (error instanceof NiadraAPIError && isPersonalData(error)) return JSON.stringify(PERSONAL_DATA_TOOL_ERROR);\n if (strict) throw error;\n return JSON.stringify({ error: \"invalid_call\", detail: (error as Error).message });\n }\n if (result.error) {\n if (isPersonalData(result.error)) return JSON.stringify(PERSONAL_DATA_TOOL_ERROR);\n if (strict) throw result.error;\n const memory = name === AGENT_MEMORY_TOOL_NAMES.search || name === AGENT_MEMORY_TOOL_NAMES.remember;\n const detail = memory ? \"agent memory is unavailable right now\" : \"customer history is unavailable right now\";\n return JSON.stringify({ error: \"unavailable\", detail });\n }\n return JSON.stringify(result.data);\n },\n };\n}\n\n/** What the model needs of a note: the id, the kind, the title, the body and the tags. */\nfunction compactNote(note: AgentNote): Partial<AgentNote> {\n const { note_id, kind, title, body, tags } = note;\n return tags === undefined ? { note_id, kind, title, body } : { note_id, kind, title, body, tags };\n}\n\n/** A saved note, or a proposal a person still has to approve, as the model reads it. */\nfunction remembered(result: RememberResult): Record<string, unknown> {\n if (result.note) return { saved: true, note_id: result.note.note_id, version: result.note.version };\n return { saved: false, proposal_id: result.proposal_id ?? null, status: \"waiting for review\" };\n}\n\n/** The server refused a note with personal data: an answer for the model, not a failure. */\nfunction isPersonalData(error: NiadraError): boolean {\n return error instanceof NiadraAPIError && error.code === \"personal_data_in_agent_memory\";\n}\n\nfunction applyBinding(request: SearchRequest | TimelineRequest, binding: ToolBinding): void {\n if (binding.about) request.about = binding.about;\n if (binding.verification) request.verification = binding.verification;\n if (binding.conversation_id) request.conversation_id = binding.conversation_id;\n}\n\n/** Token accounting is for the caller, not the model; everything else the model can use. */\nfunction compactSearch(response: SearchResponse): Omit<SearchResponse, \"tokens_used\"> {\n const { tokens_used: _, ...rest } = response;\n return rest;\n}\n\nfunction cloneDefinition(definition: ToolDefinition): ToolDefinition {\n return JSON.parse(JSON.stringify(definition)) as ToolDefinition;\n}\n","import { NiadraValidationError } from \"./errors.js\";\nimport { includeText } from \"./constraints/text.js\";\nimport type { NiadraError } from \"./errors.js\";\nimport { toObjectRef } from \"./handles.js\";\nimport type { Handle, ObjectRef } from \"./types/common.js\";\nimport type {\n ContextFormat,\n ContextPack,\n ContextRequest,\n ContextResponse,\n CoordinationBlock,\n Include,\n LiveTurn,\n PrefetchRequest,\n TargetModel,\n} from \"./types/context.js\";\nimport type { ConstraintsBlock } from \"./types/signals.js\";\nimport type { StateView } from \"./types/state.js\";\nimport type { Verification, View } from \"./types/vocabulary.js\";\n\n/** Arguments of `context()`. Pass exactly one of `subject` or `object`. */\nexport interface ContextParams {\n /** The customer, by any handle the server knows. */\n subject?: Handle;\n /** A business object, such as an invoice, when the task is about the object rather than a person. */\n object?: ObjectRef | string;\n /** The account or partner the person acts for. Requires an active link between the two. */\n about?: Handle;\n /** Defaults to `chat`. */\n view?: View;\n /**\n * The level proven in this conversation. The server may answer with a lower effective level\n * when the source's ceiling is lower; see `response.verification`.\n */\n verification?: Verification;\n /** Enables the per-conversation cache and the server's pinning of the pack. */\n conversation_id?: string;\n /** For internal agents: the task plays the role of the conversation. */\n task_id?: string;\n /**\n * Other words than the turn to pick this read's slots by. Up to 2,000 characters. Wins over\n * `turn`, and like it never changes the pack.\n */\n query?: string;\n /**\n * The customer's last turn; a conversation passes it for you. It goes as `query` and the answer\n * adds `slots`, what the turn selected from memory, in `suffix`, while the pack stays the\n * conversation's pinned one (and is cached as without it).\n */\n turn?: string | null;\n /** Ask only for what changed since this source last read the subject. */\n delta?: boolean;\n /** The model that will read the pack, so the server can size it for that model's prompt cache. */\n target?: TargetModel;\n /** `json` also returns the pack as typed sections in `pack` (`context-pack.v1`). Defaults to `text`. */\n format?: ContextFormat;\n /**\n * Adds `why` to each of `pack.slots`, naming the retrieval channels that\n * ranked it, the fused score, the weights version and, for a derived line, the rule behind it.\n * Requires `format: \"json\"`. It changes nothing else: the pinned text, the slots chosen and the\n * receipt are the same bytes with or without it.\n */\n explain?: boolean;\n /**\n * Blocks read in the same round trip: `[\"constraints\"]` returns the subject's constraints block, `[\"state\"]`\n * the state of their objects. Each only where the space turned its feature on; a block the space does not\n * serve is left out and not asked again for a while, and the read goes on. The blocks are cached with the\n * pack, so a read that fails serves the last good ones too.\n */\n include?: Include[];\n}\n\n/** Arguments of `prefetch()`: who the turn is about, as in `context()`, and the turn so far. */\nexport interface PrefetchParams {\n subject?: Handle;\n object?: ObjectRef | string;\n about?: Handle;\n /** Defaults to `voice`, where partial transcripts come from. */\n view?: View;\n verification?: Verification;\n conversation_id?: string;\n task_id?: string;\n /** The partial transcript of the customer's turn. */\n text: string;\n}\n\n/** Per-call options shared by every read method. */\nexport interface RequestOptions {\n /** Overrides the method's default time budget, in milliseconds. */\n timeout?: number | undefined;\n /** Cancels the wait. A request shared with other callers keeps running for them. */\n signal?: AbortSignal | undefined;\n /** Extra headers, such as a W3C `traceparent`. */\n headers?: Record<string, string> | undefined;\n}\n\nexport interface ContextOptions extends RequestOptions {\n /** Pass `false` to skip the per-conversation cache for this call. */\n cache?: boolean | undefined;\n /** For `conversation.context()` and `task.context()`: blocks read in the same round trip. */\n include?: Include[] | undefined;\n /** For `conversation.context()` and `task.context()`: `json` also returns `pack`. */\n format?: ContextFormat | undefined;\n /**\n * For `conversation.context()` and `task.context()`: adds `why` to each of `pack.slots`.\n * Requires `format: \"json\"`.\n */\n explain?: boolean | undefined;\n}\n\n/**\n * Where a `context()` result came from.\n *\n * - `network`: a response the server just sent (or confirmed unchanged).\n * - `cache`: a pack younger than the cache TTL; no request was made.\n * - `stale`: an older pack returned at once while a background request refreshes it.\n * - `fallback`: the request failed and this is the last good pack for the conversation.\n * - `none`: nothing was available; `text` is empty and `error` says why.\n */\nexport type ContextSource = \"network\" | \"cache\" | \"stale\" | \"fallback\" | \"none\";\n\n/** What `context()` resolves to. Always usable: on failure `text` is an empty string. */\nexport interface ContextResult {\n /** The pack, ready for the system prompt. Empty when there is nothing to inject. */\n text: string;\n /**\n * The parts that change turn by turn and belong at the end of the prompt, after the\n * conversation: the live turns from other channels, this turn's slots (what the customer's last\n * turn selected from memory), the blocks asked for by `include` (the state view, the constraints) and the\n * delta, in that order, as the API places them. Empty when there are none.\n */\n suffix: string;\n /** Named values from the pack, for templates that place them individually. */\n variables: Record<string, string>;\n /** The pack as typed sections, when read with `format: \"json\"`; otherwise `null`. */\n pack: ContextPack | null;\n source: ContextSource;\n /** The response this result was built from; `null` when `source` is `none`. */\n response: ContextResponse | null;\n /** What went wrong, when `source` is `fallback` or `none`. */\n error: NiadraError | null;\n /** With `include: [\"constraints\"]`: the subject's constraints block. */\n constraints?: ConstraintsBlock | null;\n /** With `include: [\"state\"]`: the state of the subject's objects. */\n state?: StateView | null;\n /** With `include: [\"coordination\"]`: what coordination knows of the subject. */\n coordination?: CoordinationBlock | null;\n}\n\nconst VIEW = /^(voice|chat|brief|full|custom|account|partner|task:[a-z0-9_]{1,40})$/;\nconst MAX_QUERY = 2000;\n\n/** Validates the arguments and builds the wire request, without `known_etag`. */\nexport function buildContextRequest(params: ContextParams): ContextRequest {\n if ((params.subject === undefined) === (params.object === undefined)) {\n throw new NiadraValidationError(\"pass exactly one of `subject` or `object`\");\n }\n if (params.conversation_id && params.task_id) {\n throw new NiadraValidationError(\"pass `conversation_id` or `task_id`, not both\");\n }\n if (params.view !== undefined && !VIEW.test(params.view)) {\n throw new NiadraValidationError(\"unknown view; task views look like `task:billing`\");\n }\n if (params.query !== undefined && params.query.length > MAX_QUERY) {\n throw new NiadraValidationError(`query is longer than ${MAX_QUERY} characters`);\n }\n\n const request: ContextRequest = { view: params.view ?? \"chat\" };\n if (params.subject) request.subject = params.subject;\n if (params.object !== undefined) request.object = toObjectRef(params.object);\n if (params.about) request.about = params.about;\n if (params.verification) request.verification = params.verification;\n if (params.conversation_id) request.conversation_id = params.conversation_id;\n if (params.task_id) request.task_id = params.task_id;\n if (params.query) request.query = params.query;\n if (params.delta) request.delta = true;\n if (params.target) request.target = params.target;\n const format: string = params.format ?? \"text\";\n if (format !== \"text\" && format !== \"json\") throw new NiadraValidationError(\"format is `text` or `json`\");\n if (format === \"json\") request.format = \"json\";\n if (params.explain) {\n if (format !== \"json\") throw new NiadraValidationError('explain requires format: \"json\"');\n request.explain = true;\n }\n if (params.include?.length) request.include = [...new Set(params.include)];\n return request;\n}\n\n/** Validates the arguments of `prefetch()` and builds the wire request. */\nexport function buildPrefetchRequest(params: PrefetchParams): PrefetchRequest {\n if ((params.subject === undefined) === (params.object === undefined)) {\n throw new NiadraValidationError(\"pass exactly one of `subject` or `object`\");\n }\n if (params.conversation_id && params.task_id) {\n throw new NiadraValidationError(\"pass `conversation_id` or `task_id`, not both\");\n }\n if (params.view !== undefined && !VIEW.test(params.view)) {\n throw new NiadraValidationError(\"unknown view; task views look like `task:billing`\");\n }\n const text = params.text.trim();\n if (!text || text.length > MAX_QUERY) throw new NiadraValidationError(`text must be 1 to ${MAX_QUERY} characters`);\n const request: PrefetchRequest = { view: params.view ?? \"voice\", query: text };\n if (params.subject) request.subject = params.subject;\n if (params.object !== undefined) request.object = toObjectRef(params.object);\n if (params.about) request.about = params.about;\n if (params.verification) request.verification = params.verification;\n if (params.conversation_id) request.conversation_id = params.conversation_id;\n if (params.task_id) request.task_id = params.task_id;\n return request;\n}\n\n/** Packs are only cached inside a conversation or task, the unit the server pins them to. */\nexport function cacheScope(request: Pick<ContextRequest, \"conversation_id\" | \"task_id\">): string | null {\n if (request.conversation_id) return `conversation:${request.conversation_id}`;\n if (request.task_id) return `task:${request.task_id}`;\n return null;\n}\n\n/**\n * Every field that changes what the server would compile goes into the key, in a fixed order.\n * `delta` does not: a plain read and a delta read of one conversation get the same pinned\n * bytes, so they share one entry.\n */\nexport function cacheKey(request: ContextRequest): string {\n return JSON.stringify([\n request.subject ?? null,\n request.object ?? null,\n request.about ?? null,\n request.view ?? \"chat\",\n request.verification ?? \"V0\",\n request.conversation_id ?? null,\n request.task_id ?? null,\n request.query ?? null,\n request.target ?? null,\n request.format ?? \"text\",\n request.explain ?? false,\n request.include ?? null,\n ]);\n}\n\n/**\n * Applies a `not_modified` answer to the cached pack: the pinned text and its metadata stay,\n * while the parts outside the pin (live turns, delta, coverage, timing) come from the new answer.\n */\nexport function mergeNotModified(cached: ContextResponse, fresh: ContextResponse): ContextResponse {\n return {\n ...fresh,\n not_modified: false,\n text: cached.text ?? null,\n variables: cached.variables,\n version: cached.version,\n etag: cached.etag,\n manifest_hash: cached.manifest_hash ?? null,\n withheld: cached.withheld,\n cache: cached.cache ?? null,\n pack: cached.pack ?? null,\n // The blocks sit outside the pinned pack: a fresh block wins, and a missing one keeps the cached.\n constraints: fresh.constraints ?? cached.constraints ?? null,\n state: fresh.state ?? cached.state ?? null,\n coordination: fresh.coordination ?? cached.coordination ?? null,\n };\n}\n\nexport function resultFrom(\n response: ContextResponse,\n source: ContextSource,\n error: NiadraError | null = null,\n): ContextResult {\n // A conversation in the control group gets an empty pack on purpose; it is not an error.\n const holdout = response.path === \"holdout\";\n const text = holdout ? \"\" : (response.text ?? \"\");\n const pack = holdout ? null : (response.pack ?? null);\n const blocks = {\n constraints: response.constraints ?? null,\n state: response.state ?? null,\n coordination: response.coordination ?? null,\n };\n return { text, suffix: renderSuffix(response), variables: response.variables, pack, source, response, error, ...blocks };\n}\n\nexport function emptyResult(error: NiadraError | null): ContextResult {\n return { text: \"\", suffix: \"\", variables: {}, pack: null, source: \"none\", response: null, error, constraints: null, state: null, coordination: null };\n}\n\n/**\n * Renders the live turns, the slots and the delta for the end of the prompt, in that order. Kept\n * outside the pinned pack so that the prompt prefix stays byte-identical across turns and the\n * model provider's prompt cache keeps hitting. Returns an empty string when there is nothing to add.\n */\nexport function renderSuffix(response: ContextResponse): string {\n if (response.path === \"holdout\") return \"\";\n const included = includeText(response.text, response.state, response.constraints);\n return [renderLive(response), response.slots ?? \"\", included, response.delta ?? \"\"].filter(Boolean).join(\"\\n\\n\");\n}\n\n/**\n * Renders the live turns (recent turns from other channels that the pack has not absorbed\n * yet) as one tagged block, or an empty string when there are none. `complete=\"false\"` tells\n * the model the list may be missing turns because the server could not read all of them.\n */\nexport function renderLive(response: ContextResponse): string {\n if (response.path === \"holdout\" || response.live.length === 0) return \"\";\n const complete = response.live_complete ? \"\" : ' complete=\"false\"';\n const lines = response.live.map(renderLiveTurn).join(\"\\n\");\n return `<live_turns source=\"niadra\"${complete}>\\n${lines}\\n</live_turns>`;\n}\n\nfunction renderLiveTurn(turn: LiveTurn): string {\n return `[${utcSeconds(turn.at)}] ${turn.channel} · ${turn.speaker}: ${turn.text}`;\n}\n\n/** The same timestamp form in every SDK, whatever precision or offset the server sent. */\nfunction utcSeconds(at: string): string {\n const ms = Date.parse(at);\n return Number.isNaN(ms) ? at : `${new Date(ms).toISOString().slice(0, 19)}Z`;\n}\n","/**\n * What every framework adapter shares: the five primitives (context before the model call, the\n * turns, the tools, the verification and the handoff) wired the same way, and fail-open.\n *\n * Nothing here throws into the framework: a failed read gives an empty context, a failed write\n * is logged without content, and the agent keeps working without memory.\n */\n\nimport { recordedTool } from \"../capture/tool.js\";\nimport type { Played } from \"../replay/playback.js\";\nimport type { AgentMemoryParams } from \"../agent-memory.js\";\nimport type { TurnParams } from \"../agent-session.js\";\nimport type { CallCapture, TurnFrame } from \"../capture/frame.js\";\nimport type { ContextOptions, ContextResult } from \"../context.js\";\nimport { emptyResult } from \"../context.js\";\nimport type { Conversation, TurnOptions } from \"../conversation.js\";\nimport type { Logger } from \"../logger.js\";\nimport type { Task } from \"../task.js\";\nimport type { BoundTools } from \"../tools.js\";\nimport type { Handle } from \"../types/common.js\";\nimport type { Verification, VerifyMethod } from \"../types/vocabulary.js\";\n\n/** A customer conversation or an internal agent's task. */\nexport type Session = Conversation | Task;\n\n/** A session, or a function that finds the one the current call belongs to (`null` passes the call through). */\nexport type SessionResolver<S extends Session = Session> = S | (() => S | null | undefined);\n\n/** What the framework proved about the person, recorded with `verify()` before the first context read. */\nexport interface Proof {\n method: VerifyMethod;\n level: Verification;\n /** Defaults to the session's subject. */\n handle?: Handle;\n}\n\n/** A proof, or a function that reads it from the framework when the first context is needed. */\nexport type ProofSource =\n | Proof\n | null\n | undefined\n | (() => Proof | null | undefined | PromiseLike<Proof | null | undefined>);\n\n/**\n * The agent's own working notes: `true` puts the block before the customer's context and offers\n * `search_agent_memory`; `{ write: true }` also offers `remember` (for a key with the\n * `agent_memory:write` scope); the other fields go to `agentMemory()`.\n */\nexport type AgentMemoryOption = boolean | (AgentMemoryParams & { write?: boolean });\n\n/** What goes into the prompt for one model call. */\nexport interface Read {\n context: ContextResult;\n /** The agent's own notes, or an empty string. */\n memory: string;\n /** What goes after the instructions: the notes, then the customer's pack. */\n prefix: string;\n /** What goes at the end: live turns, the turn's slots and deltas. */\n suffix: string;\n}\n\n/** A tool as every framework needs it: the name, the text for the model, the JSON Schema and the call. */\ninterface ToolSpec {\n name: string;\n description: string;\n /** JSON Schema of the arguments. None of them names the customer. */\n parameters: Record<string, unknown>;\n /** Runs the call and returns the text for the model. Never rejects in fail-open mode. */\n execute(args: string | Record<string, unknown>): Promise<string>;\n}\n\nconst ATTESTED: Record<string, Verification> = { A: \"V2\", B: \"V1\", C: \"V1\" };\n\n/**\n * The proof a carrier's STIR/SHAKEN attestation gives a phone call: `A` proves V2, `B` and `C`\n * prove V1, anything else proves nothing (`null`). Accepts the bare letter or the forms carriers\n * and platforms send, such as Twilio's `TN-Validation-Passed-A`.\n */\nexport function attestationProof(attestation: string | null | undefined): Proof | null {\n if (!attestation) return null;\n const value = attestation.trim().toUpperCase();\n if (value.includes(\"FAILED\") || value.startsWith(\"NO-\")) return null;\n const letter = value.length === 1 ? value : /PASSED-([ABC])$/.exec(value)?.[1];\n const level = letter ? ATTESTED[letter] : undefined;\n return level ? { method: \"network_attestation\", level } : null;\n}\n\nexport function resolveSession<S extends Session>(source: SessionResolver<S>): S | null {\n if (typeof source !== \"function\") return source;\n try {\n return source() ?? null;\n } catch {\n return null;\n }\n}\n\nfunction isConversation(session: Session): session is Conversation {\n return \"customer\" in session && typeof session.customer === \"function\";\n}\n\n/** A phone number as an E.164 handle, or `null` when it does not look like one. */\nexport function phoneHandle(value: string | null | undefined): Handle | null {\n const raw = value?.trim().replace(/^tel:/i, \"\").replace(/[\\s().-]/g, \"\");\n if (!raw) return null;\n const e164 = raw.startsWith(\"+\") ? raw : `+${raw}`;\n return /^\\+[1-9]\\d{6,14}$/.test(e164) ? { type: \"phone_e164\", value: e164 } : null;\n}\n\nexport function errorName(error: unknown): string {\n return error instanceof Error ? error.name : typeof error;\n}\n\n/**\n * One session as an adapter drives it. Keeps the verification to a single call made before the\n * first context read, and turns every failure into a log line.\n */\nexport class Bridge {\n private proving: Promise<void> | null = null;\n /** `begin()` started the first read of a call: the first `context()` waits for it with `ready()`. */\n private begun = false;\n private opened = false;\n\n constructor(\n readonly session: Session,\n private readonly proof?: ProofSource,\n private readonly memory: AgentMemoryOption = false,\n ) {}\n\n /**\n * The context and, when enabled, the agent's notes, read side by side within the same budget.\n * Never rejects.\n */\n async read(options: ContextOptions = {}): Promise<Read> {\n const memoryParams = this.memory === false ? null : this.memory === true ? {} : withoutWrite(this.memory);\n const [context, memory] = await Promise.all([\n this.context(options),\n memoryParams ? this.agentMemory(memoryParams, options) : Promise.resolve(\"\"),\n ]);\n return { context, memory, prefix: [memory, context.text].filter(Boolean).join(\"\\n\\n\"), suffix: context.suffix };\n }\n\n get logger(): Logger {\n return this.session.logger;\n }\n\n /**\n * Starts the first read of a call now, in the background, after the proof when one was given (the\n * pack depends on the level it proves): at call start, so the read runs while the call is set up.\n * The first `context()` then waits for it within `timeouts.contextVoiceStart`. Never throws.\n */\n begin(): void {\n const session = this.session;\n if (!isConversation(session)) return;\n const start = (): void => {\n this.safe(\"start the first read\", () => {\n // False off the voice read path (a chat view, the cache off): reads go on as before.\n this.begun = session.begin();\n });\n };\n if (this.proof === undefined || this.proof === null) start();\n else void this.verifyOnce().then(start);\n }\n\n /** Verifies once (when a proof was given), then reads the context. Never rejects. */\n async context(options: ContextOptions = {}): Promise<ContextResult> {\n await this.verifyOnce();\n try {\n const session = this.session;\n if (this.begun && !this.opened && isConversation(session)) {\n this.opened = true;\n // The call's first read, begun at call start: waited for within its own, longer budget.\n await session.ready(options.timeout === undefined ? {} : { timeout: options.timeout });\n }\n return await this.session.context(options);\n } catch (error) {\n this.logger.warn(`could not read context (${errorName(error)})`);\n return emptyResult(null);\n }\n }\n\n /** Records that `context` went into the prompt, unless it was empty for a reason other than the holdout. */\n injected(context: ContextResult): void {\n if (!context.text && !context.suffix && context.response?.path !== \"holdout\") return;\n this.safe(\"mark the injection\", () => {\n this.session.markInjected(context);\n });\n }\n\n customer(text: string, options: TurnOptions = {}): void {\n const session = this.session;\n if (!text.trim() || !isConversation(session)) return;\n this.safe(\"record the customer's turn\", () => session.customer(text, options));\n }\n\n /** Sends the customer's turn so far, while they speak. In the background; never throws. */\n prefetch(text: string): void {\n const session = this.session;\n if (!text.trim() || !isConversation(session)) return;\n this.safe(\"prefetch the turn\", () => session.prefetch(text));\n }\n\n agent(text: string, options: TurnOptions = {}): void {\n if (!text.trim()) return;\n this.safe(\"record the agent's turn\", () => this.session.agent(text, options));\n }\n\n /** Records a transfer. Tasks have no transfer; the call is ignored for them. */\n async handoff(target: \"agent\" | \"human\", reason?: string): Promise<void> {\n const session = this.session;\n if (!isConversation(session)) return;\n try {\n await session.handoff(reason ? { target, reason } : { target });\n } catch (error) {\n this.logger.warn(`could not record the handoff (${errorName(error)})`);\n }\n }\n\n async end(): Promise<void> {\n try {\n await this.session.end();\n } catch (error) {\n this.logger.warn(`could not end the session (${errorName(error)})`);\n }\n }\n\n /** The navigation kit as plain specs (with the agent's memory tools when enabled), or none for a task about an object only. */\n tools(): ToolSpec[] {\n let bound: BoundTools | null;\n try {\n const memory = this.memory;\n bound = this.session.tools(memory === false ? {} : { agentMemory: true, writeAgentMemory: memory !== true && memory.write === true });\n } catch (error) {\n this.logger.warn(`could not build the tools (${errorName(error)})`);\n return [];\n }\n return bound ? toolSpecs(bound) : [];\n }\n\n private async agentMemory(params: AgentMemoryParams, options: ContextOptions): Promise<string> {\n try {\n const result = await this.session.agentMemory(params, options.timeout === undefined ? {} : { timeout: options.timeout });\n return result.text;\n } catch (error) {\n this.logger.warn(`could not read the agent's memory (${errorName(error)})`);\n return \"\";\n }\n }\n\n private async verifyOnce(): Promise<void> {\n if (this.proof === undefined || this.proof === null) return;\n this.proving ??= this.runVerify();\n await this.proving;\n }\n\n private async runVerify(): Promise<void> {\n try {\n const source = this.proof;\n const proof = typeof source === \"function\" ? await source() : source;\n if (!proof) return;\n await this.session.verify(proof);\n } catch (error) {\n this.logger.warn(`could not record the verification (${errorName(error)})`);\n }\n }\n\n private safe(what: string, run: () => unknown): void {\n try {\n run();\n } catch (error) {\n this.logger.warn(`could not ${what} (${errorName(error)})`);\n }\n }\n}\n\nfunction withoutWrite(option: AgentMemoryParams & { write?: boolean }): AgentMemoryParams {\n const { write: _, ...params } = option;\n return params;\n}\n\n/** The bound kit as specs. The customer stays inside `bound`; no parameter names them. */\nfunction toolSpecs(bound: BoundTools): ToolSpec[] {\n return bound.definitions.map(({ function: definition }) => ({\n name: definition.name,\n description: definition.description,\n parameters: definition.parameters,\n execute: (args) => bound.call(definition.name, args),\n }));\n}\n\n/** The text of a message content in the shapes model APIs use: a string, or a list of text parts. */\nexport function textOf(content: unknown): string {\n if (typeof content === \"string\") return content;\n if (!Array.isArray(content)) return \"\";\n const parts: string[] = [];\n for (const part of content as unknown[]) {\n if (typeof part === \"string\") parts.push(part);\n else if (isRecord(part) && typeof part.text === \"string\" && (part.type === undefined || part.type === \"text\")) {\n parts.push(part.text);\n }\n }\n return parts.join(\"\");\n}\n\nexport function isRecord(value: unknown): value is Record<PropertyKey, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\n/** A non-negative integer, or `null`. */\nexport function count(value: unknown): number | null {\n return typeof value === \"number\" && Number.isInteger(value) && value >= 0 ? value : null;\n}\n\n/**\n * The turn records an adapter keeps from its framework's callbacks, keyed by the framework's own ids (a\n * run, a request, a tool call id). A run starting while the session has a turn in progress (yours, from\n * `conversation.turn()`, or a replay's) records into it; otherwise the adapter opens its own turn and closes\n * it when the run ends. A tool call recorded here is taken over by a `tool()` wrapper running inside it, so\n * the call is recorded once. Every method does nothing when turns are off and never throws.\n */\nexport class TurnHooks {\n /** Runs held open at most; past it the oldest run's turn closes, incomplete (a run whose end never came). */\n static readonly MAX_OPEN = 100;\n private readonly frames = new Map<string, { frame: TurnFrame; own: boolean }>();\n private readonly calls = new Map<string, CallCapture>();\n\n constructor(\n readonly adapter: string,\n readonly enabled: boolean,\n ) {}\n\n /** The turn of the run `key`: the session's turn in progress, or a new one of its own. */\n open(session: Session, key: string, params: TurnParams = {}): TurnFrame | undefined {\n if (!this.enabled) return undefined;\n const held = this.frames.get(key);\n if (held !== undefined) return held.frame;\n try {\n const active = session.activeTurn();\n if (active !== undefined && !this.owns(active)) {\n this.frames.set(key, { frame: active, own: false });\n return active;\n }\n const frame = session.openTurn({ ...params, adapter: this.adapter });\n this.frames.set(key, { frame, own: true });\n if (this.frames.size > TurnHooks.MAX_OPEN) {\n const [oldest] = this.frames.keys();\n if (oldest !== undefined) {\n this.frames.get(oldest)?.frame.incomplete();\n this.close(oldest);\n }\n }\n return frame;\n } catch (error) {\n session.logger.warn(`could not open the turn (${errorName(error)})`);\n return undefined;\n }\n }\n\n /** The turn of `key`, else the session's turn in progress. */\n frame(session: Session, key?: string): TurnFrame | undefined {\n if (!this.enabled) return undefined;\n const held = key === undefined ? undefined : this.frames.get(key);\n const frame = held?.frame ?? session.activeTurn();\n return frame === undefined || frame.closed ? undefined : frame;\n }\n\n has(key: string): boolean {\n return this.frames.has(key);\n }\n\n private owns(frame: TurnFrame): boolean {\n for (const held of this.frames.values()) if (held.own && held.frame === frame) return true;\n return false;\n }\n\n /** Ends the run `key`: a turn the adapter opened closes; the calls it left open failed. */\n close(key: string, error?: unknown): void {\n const held = this.frames.get(key);\n if (held === undefined) return;\n this.frames.delete(key);\n for (const [callKey, call] of this.calls) {\n if (call.frame !== held.frame) continue;\n this.calls.delete(callKey);\n if (held.own) call.failed(error ?? \"error\");\n }\n if (held.own) held.frame.close(error);\n }\n\n /** A tool call starting, keyed by `callKey`; `callId` is the provider's id of the call, when there is one. */\n toolStart(session: Session, callKey: string, name: string, args: unknown, options: { frameKey?: string; callId?: string | null } = {}): void {\n const frame = this.frame(session, options.frameKey);\n if (frame === undefined) return;\n try {\n this.calls.set(callKey, frame.toolCall(name, args, { callId: options.callId ?? null, adoptable: true }));\n } catch {\n frame.incomplete();\n }\n }\n\n /**\n * In a replay, how a framework tool the adapter stands in for answers: the recorded result of a call with the\n * same arguments, or empty (a divergence), never the live tool. `null` outside a replay, and for a function\n * wrapped with `tool()`, which answers itself.\n */\n replayed(session: Session, name: string, args: unknown, fn?: unknown, frameKey?: string): Played | null {\n const frame = this.enabled ? this.frame(session, frameKey) : session.activeTurn();\n if (frame?.playback == null || (fn !== undefined && recordedTool(fn) !== null)) return null;\n return frame.playback.answer(name, args, false);\n }\n\n toolEnd(callKey: string, result?: unknown, error?: unknown): void {\n const call = this.calls.get(callKey);\n if (call === undefined) return;\n this.calls.delete(callKey);\n try {\n if (error !== undefined) call.failed(error);\n else call.result(result);\n } catch {\n call.frame.incomplete();\n }\n }\n\n /** A model call that ended, with its tokens when the framework reported them. */\n model(\n session: Session,\n model: string | null | undefined,\n tokens: { in?: number | null; out?: number | null; cached?: number | null } = {},\n frameKey?: string,\n ): void {\n const frame = this.frame(session, frameKey);\n if (frame === undefined) return;\n try {\n frame.modelCall(model, { tokensIn: tokens.in ?? null, tokensOut: tokens.out ?? null, tokensCached: tokens.cached ?? 0 });\n } catch {\n frame.incomplete();\n }\n }\n}\n","/**\n * Helpers for the webhook adapters (ElevenLabs, Vapi, WhatsApp, Twilio): signatures with Web\n * Crypto and header lookup. Only web APIs, so the handlers run on Node 20+, Deno, Bun, Cloudflare\n * Workers and the Vercel Edge Runtime alike.\n */\n\nimport type { Handle } from \"../types/common.js\";\nimport type { ContextStamp } from \"../types/events.js\";\nimport type { Verification } from \"../types/vocabulary.js\";\n\n/**\n * What a call's first webhook learned, for the webhooks that come later in the same call (tool\n * calls, the end-of-call report): who the caller is, the level they proved and the context stamp.\n */\nexport interface CallRecord {\n subject: Handle;\n verification: Verification;\n stamp?: ContextStamp | null;\n}\n\n/**\n * Where the webhook adapters keep a `CallRecord` between requests, by the platform's call id.\n * The default lives in this process's memory; on serverless or several instances, pass one backed\n * by your key-value store.\n */\nexport interface CallStore {\n get(id: string): CallRecord | undefined | PromiseLike<CallRecord | undefined>;\n set(id: string, record: CallRecord): void | PromiseLike<void>;\n}\n\n/** An in-memory `CallStore` that keeps the most recent `max` calls. */\nexport function memoryCallStore(max = 10_000): CallStore {\n const calls = new Map<string, CallRecord>();\n return {\n get: (id) => calls.get(id),\n set: (id, record) => {\n calls.delete(id);\n calls.set(id, record);\n if (calls.size > max) {\n const oldest = calls.keys().next().value;\n if (oldest !== undefined) calls.delete(oldest);\n }\n },\n };\n}\n\n/** Request headers as a `Headers` object or a plain record (any case). */\nexport type HeadersLike = Headers | Record<string, string | string[] | undefined>;\n\n/** What a handler answers: the HTTP status and a JSON-serializable body (`null` for no body). */\nexport interface WebhookResponse<B = unknown> {\n status: number;\n body: B;\n}\n\nexport function header(headers: HeadersLike, name: string): string | undefined {\n if (typeof (headers as Headers).get === \"function\") return (headers as Headers).get(name) ?? undefined;\n const wanted = name.toLowerCase();\n for (const [key, value] of Object.entries(headers as Record<string, string | string[] | undefined>)) {\n if (key.toLowerCase() !== wanted) continue;\n return Array.isArray(value) ? value[0] : value;\n }\n return undefined;\n}\n\nfunction subtle(): SubtleCrypto {\n const crypto = (globalThis as { crypto?: Crypto }).crypto;\n if (!crypto?.subtle) throw new Error(\"Web Crypto is not available on this runtime\");\n return crypto.subtle;\n}\n\nconst encoder = new TextEncoder();\n\nexport async function hmac(hash: \"SHA-1\" | \"SHA-256\", secret: string, message: string): Promise<Uint8Array> {\n const key = await subtle().importKey(\"raw\", encoder.encode(secret), { name: \"HMAC\", hash }, false, [\"sign\"]);\n return new Uint8Array(await subtle().sign(\"HMAC\", key, encoder.encode(message)));\n}\n\nexport function hex(bytes: Uint8Array): string {\n let out = \"\";\n for (const byte of bytes) out += byte.toString(16).padStart(2, \"0\");\n return out;\n}\n\nexport function base64(bytes: Uint8Array): string {\n let binary = \"\";\n for (const byte of bytes) binary += String.fromCharCode(byte);\n return btoa(binary);\n}\n\n/** Compares two strings in time that depends only on their length. */\nexport function safeEqual(a: string, b: string): boolean {\n const left = encoder.encode(a);\n const right = encoder.encode(b);\n if (left.length !== right.length) return false;\n let diff = 0;\n for (let i = 0; i < left.length; i++) diff |= (left[i] ?? 0) ^ (right[i] ?? 0);\n return diff === 0;\n}\n\n/** The raw body as text, whatever form the framework hands it in. */\nexport function bodyText(body: string | Uint8Array | ArrayBuffer): string {\n if (typeof body === \"string\") return body;\n return new TextDecoder().decode(body instanceof Uint8Array ? body : new Uint8Array(body));\n}\n\nexport function parseJson(text: string): unknown {\n try {\n return JSON.parse(text) as unknown;\n } catch {\n return undefined;\n }\n}\n","/**\n * Niadra for Retell AI, on the server side: a call reaches Retell, Retell calls your webhooks\n * (and, with a custom LLM, opens a websocket to your server), and these handlers answer them. No\n * Retell package is needed.\n *\n * - `inbound`: the inbound call webhook. Opens the conversation by Retell's `call_id`, records what\n * the call proved, starts the first read and waits for it within `timeouts.contextVoiceStart`\n * (the phone rings meanwhile), and answers it as dynamic variables: put\n * `{{niadra_context}}` in the agent's prompt (and `{{niadra_turn}}` where the live turns from other\n * channels go).\n * - `tool`: custom functions for the navigation kit. `toolConfigs()` writes them for Retell's\n * `general_tools`; the customer comes from the call, never from the model's arguments.\n * - `webhook`: the agent webhook. `call_started` keeps the caller of calls that had no inbound\n * webhook (outbound and web calls), `transfer_started` records a transfer to a person, and\n * `call_ended` records every utterance of `transcript_object` and ends the conversation.\n * - `llm(callId)`: for a custom LLM, one session per websocket (`/llm-websocket/:call_id`). It asks\n * for the call details, answers Retell's pings, records each utterance once a response is\n * required, and gives your model the messages with the context in place. The read sends the\n * caller's last utterance along, and each `update_only` event whose transcript ends with the\n * caller speaking sends that utterance so far with `prefetch()`, in the background: once its\n * words stop changing the SDK reads the turn with them, and the turn takes that read's slots; the\n * pack itself comes from memory at once. A prefetch never holds or fails a turn. Retell does not sign the\n * websocket, so the customer comes from a signed webhook of the same call (`inbound` or\n * `call_started`, kept in the store), never from the socket's `call_details`: anyone who reaches\n * the socket could name any caller there. Until a signed webhook registers the call, the model gets\n * no context and nothing is recorded. Set `trustCallDetails` only when the socket accepts Retell\n * alone (an IP allowlist, a secret in its URL).\n *\n * Every request is checked against `X-Retell-Signature` (HMAC-SHA256 of the raw body and its\n * timestamp, keyed with your Retell API key, within five minutes). Utterances carry the same\n * idempotency key on the websocket and in `call_ended`, so recording both ways stores them once.\n * Only web APIs: runs on Node, Deno, Bun, Cloudflare Workers and the Vercel Edge Runtime.\n *\n * @example\n * import { retell } from \"@niadra/sdk/retell\";\n *\n * const handlers = retell({ niadra, apiKey: process.env.RETELL_API_KEY! });\n * app.post(\"/retell/inbound\", async (c) => answer(c, await handlers.inbound(await c.req.text(), c.req.raw.headers)));\n * app.post(\"/retell/webhook\", async (c) => answer(c, await handlers.webhook(await c.req.text(), c.req.raw.headers)));\n * app.post(\"/retell/tools\", async (c) => answer(c, await handlers.tool(await c.req.text(), c.req.raw.headers)));\n *\n * // Custom LLM: one session per websocket Retell opens.\n * wss.on(\"connection\", (ws, request) => {\n * const session = handlers.llm(callIdFrom(request.url), { send: (event) => ws.send(JSON.stringify(event)), instructions: \"You are Acme's receptionist.\" });\n * session.open(\"Acme Energy, how can I help?\");\n * ws.on(\"message\", async (data) => {\n * const turn = await session.receive(JSON.parse(String(data)));\n * if (turn) turn.respond(await yourModel(turn.messages));\n * });\n * });\n */\n\nimport type { Niadra } from \"../client.js\";\nimport type { Conversation } from \"../conversation.js\";\nimport { AGENT_MEMORY_TOOL_DEFINITIONS, AGENT_MEMORY_TOOL_NAMES, TOOL_DEFINITIONS, TOOL_NAMES } from \"../tools.js\";\nimport type { Handle } from \"../types/common.js\";\nimport { Bridge, errorName, isRecord, phoneHandle } from \"./shared.js\";\nimport type { AgentMemoryOption, Proof } from \"./shared.js\";\nimport { bodyText, header, hex, hmac, memoryCallStore, parseJson, safeEqual } from \"./webhook.js\";\nimport type { CallRecord, CallStore, HeadersLike, WebhookResponse } from \"./webhook.js\";\n\nexport { attestationProof } from \"./shared.js\";\nexport type { AgentMemoryOption, Proof } from \"./shared.js\";\nexport { memoryCallStore } from \"./webhook.js\";\nexport type { CallRecord, CallStore, HeadersLike, WebhookResponse } from \"./webhook.js\";\n\n/** What the handlers read from a Retell call object (or from the inbound webhook). */\nexport interface RetellCall {\n /** Retell's `call_id`, used as the `conversation_id`. */\n id: string;\n fromNumber?: string | undefined;\n toNumber?: string | undefined;\n direction?: string | undefined;\n agentId?: string | undefined;\n /** The whole call object, for anything else you need (`metadata`, `retell_llm_dynamic_variables`). */\n call: Record<string, unknown>;\n}\n\nexport interface RetellOptions {\n niadra: Niadra;\n /** The Retell API key that signs the webhooks (the one marked for webhooks in the dashboard). Required. */\n apiKey: string;\n /** Who the customer is. Defaults to the caller of inbound calls and the callee of outbound ones, as E.164. */\n subject?: (call: RetellCall) => Handle | null | undefined;\n /** What the call proved, such as the carrier's attestation you read from your telephony provider. */\n verify?: (call: RetellCall) => Proof | null | undefined | PromiseLike<Proof | null | undefined>;\n /** Keeps the caller and level between the webhooks of one call. Defaults to an in-memory store. */\n store?: CallStore;\n /** More fields for the inbound answer, such as `override_agent_id` or more `dynamic_variables`. */\n inboundFields?: (call: RetellCall) => Record<string, unknown>;\n /** Runs custom functions that are not Niadra's, so one URL can serve all of them. */\n otherTool?: (name: string, args: Record<string, unknown>, call: RetellCall) => unknown;\n /** Time budget of each context read, in milliseconds. Defaults to the voice budget. */\n contextTimeout?: number;\n /** The clock for the signature's five-minute window, in milliseconds. */\n now?: () => number;\n /**\n * The agent's own notes as the dynamic variable `niadra_agent_memory` (put it before\n * `{{niadra_context}}`), before the pack in the custom LLM's messages, and its memory tools.\n */\n agentMemory?: AgentMemoryOption;\n /**\n * Lets the custom LLM websocket open the conversation from its own `call_details` when no signed\n * webhook registered the call. Retell does not sign the websocket: turn this on only when your\n * server accepts that socket from Retell alone. Defaults to `false`.\n */\n trustCallDetails?: boolean;\n}\n\n/** A chat message in the shape every chat completions API takes. */\nexport interface RetellMessage {\n role: \"system\" | \"user\" | \"assistant\";\n content: string;\n}\n\nexport interface RetellRespondOptions {\n /** `false` while streaming chunks; the last chunk (or an empty one) closes the response. Defaults to `true`. */\n complete?: boolean;\n /** Hangs up after this response. */\n endCall?: boolean;\n /** Transfers the call to this number after this response, recorded as a transfer to a person. */\n transferNumber?: string;\n}\n\n/** One response Retell is waiting for. */\nexport interface RetellTurn {\n responseId: number;\n interactionType: \"response_required\" | \"reminder_required\";\n /** Your instructions, the agent's notes and the pack, then the call so far, the suffix at the end of the last user message. */\n messages: RetellMessage[];\n /** The pack, or an empty string. */\n context: string;\n /** Live turns from other channels, the turn's slots and deltas, or an empty string. */\n suffix: string;\n /** Sends a response event to Retell for this turn. */\n respond(content: string, options?: RetellRespondOptions): void;\n}\n\nexport interface RetellLlmOptions {\n /** Sends one event to Retell over the websocket, such as `(event) => ws.send(JSON.stringify(event))`. */\n send: (event: Record<string, unknown>) => void;\n /** Your system prompt; the context goes right after it. */\n instructions?: string;\n}\n\n/** One custom LLM websocket. */\nexport interface RetellLlmSession {\n /** Sends the config (asking for the call details) and, when given, the agent's first words. */\n open(greeting?: string): void;\n /** Handles one event from Retell; resolves to a turn when Retell needs a response. Never rejects. */\n receive(event: unknown): Promise<RetellTurn | null>;\n /** Sends what is queued for Niadra. Call it when the websocket closes. */\n close(): Promise<void>;\n}\n\nexport interface RetellHandlers {\n /** The inbound call webhook, with the raw body: the signature covers the exact bytes. */\n inbound(rawBody: string | Uint8Array | ArrayBuffer, headers: HeadersLike): Promise<WebhookResponse>;\n /** The agent webhook (`call_started`, `call_ended`, `transfer_started`), with the raw body. */\n webhook(rawBody: string | Uint8Array | ArrayBuffer, headers: HeadersLike): Promise<WebhookResponse>;\n /** Custom function calls, with the raw body. */\n tool(rawBody: string | Uint8Array | ArrayBuffer, headers: HeadersLike): Promise<WebhookResponse>;\n /** A session for the custom LLM websocket of one call. */\n llm(callId: string, options: RetellLlmOptions): RetellLlmSession;\n /** The custom function configurations for Retell's `general_tools`, all pointing at your `tool` URL. */\n toolConfigs(options: { url: string; timeoutMs?: number }): Record<string, unknown>[];\n}\n\nconst OURS = new Set<string>([...Object.values(TOOL_NAMES), ...Object.values(AGENT_MEMORY_TOOL_NAMES)]);\nconst SIGNATURE_WINDOW_MS = 5 * 60 * 1000;\n\n/** The handlers for one Retell agent. */\nexport function retell(options: RetellOptions): RetellHandlers {\n const store = options.store ?? memoryCallStore();\n const now = options.now ?? Date.now;\n const logger = options.niadra.logger;\n const readOptions = options.contextTimeout ? { timeout: options.contextTimeout } : {};\n const transferred = new Set<string>();\n\n const subjectOf = (call: RetellCall): Handle | null => {\n try {\n if (options.subject) return options.subject(call) ?? null;\n return phoneHandle(call.direction === \"outbound\" ? call.toNumber : call.fromNumber);\n } catch {\n return null;\n }\n };\n\n const remember = async (id: string, record: CallRecord): Promise<void> => {\n try {\n await store.set(id, record);\n } catch (error) {\n logger.warn(`could not write the call store (${errorName(error)})`);\n }\n };\n\n /** The call's record from the store, or rebuilt from what this request carries (without verifying again). */\n const recall = async (call: RetellCall): Promise<CallRecord | null> => {\n try {\n const stored = await store.get(call.id);\n if (stored) return stored;\n } catch (error) {\n logger.warn(`could not read the call store (${errorName(error)})`);\n }\n const subject = subjectOf(call);\n return subject ? { subject, verification: \"V0\" } : null;\n };\n\n const open = (id: string, record: CallRecord): Conversation =>\n options.niadra.conversation({ subject: record.subject, channel: \"voice\", conversation_id: id, verification: record.verification });\n\n /** Opens the conversation for a call that has not been seen yet, verifying it once. */\n const start = (call: RetellCall): { bridge: Bridge; conversation: Conversation } | null => {\n const subject = subjectOf(call);\n if (!subject) return null;\n const conversation = options.niadra.conversation({ subject, channel: \"voice\", conversation_id: call.id });\n const bridge = new Bridge(conversation, options.verify ? () => options.verify?.(call) : undefined, options.agentMemory);\n bridge.begin(); // the call is starting: its first read runs meanwhile\n return { bridge, conversation };\n };\n\n const signed = async (text: string, headers: HeadersLike): Promise<boolean> =>\n validRetellSignature(text, header(headers, \"x-retell-signature\"), options.apiKey, now());\n\n async function inbound(rawBody: string | Uint8Array | ArrayBuffer, headers: HeadersLike): Promise<WebhookResponse> {\n const text = bodyText(rawBody);\n if (!(await signed(text, headers))) return { status: 401, body: { error: \"unauthorized\" } };\n const body = parseJson(text);\n const data = isRecord(body) && isRecord(body.call_inbound) ? body.call_inbound : null;\n if (!data) return { status: 400, body: { error: \"invalid_body\" } };\n const call = callOf({ ...data, direction: \"inbound\" });\n const variables: Record<string, string> = { niadra_context: \"\", niadra_turn: \"\" };\n if (options.agentMemory) variables.niadra_agent_memory = \"\";\n let extra: Record<string, unknown> = {};\n try {\n extra = call && options.inboundFields ? options.inboundFields(call) : {};\n } catch (error) {\n logger.warn(`could not build the inbound fields (${errorName(error)})`);\n }\n const answer = (): WebhookResponse => {\n const own = isRecord(extra.dynamic_variables) ? (extra.dynamic_variables as Record<string, unknown>) : {};\n return { status: 200, body: { call_inbound: { ...extra, dynamic_variables: { ...own, ...variables } } } };\n };\n const started = call ? start(call) : null;\n if (!call || !started) return answer();\n const read = await started.bridge.read(readOptions);\n started.bridge.injected(read.context);\n variables.niadra_context = read.context.text;\n variables.niadra_turn = read.suffix;\n if (options.agentMemory) variables.niadra_agent_memory = read.memory;\n await remember(call.id, { subject: started.conversation.subject, verification: started.conversation.verification, stamp: started.conversation.contextStamp });\n return answer();\n }\n\n async function webhook(rawBody: string | Uint8Array | ArrayBuffer, headers: HeadersLike): Promise<WebhookResponse> {\n const text = bodyText(rawBody);\n if (!(await signed(text, headers))) return { status: 401, body: { error: \"unauthorized\" } };\n const body = parseJson(text);\n const call = isRecord(body) ? callOf(body.call) : null;\n if (!isRecord(body) || typeof body.event !== \"string\" || !call) return { status: 400, body: { error: \"invalid_body\" } };\n switch (body.event) {\n case \"call_started\":\n return callStarted(call);\n case \"transfer_started\":\n await transfer(call);\n return { status: 200, body: {} };\n case \"call_ended\":\n return callEnded(call);\n default:\n return { status: 200, body: { ignored: true } };\n }\n }\n\n async function callStarted(call: RetellCall): Promise<WebhookResponse> {\n try {\n if (await store.get(call.id)) return { status: 200, body: {} };\n } catch (error) {\n logger.warn(`could not read the call store (${errorName(error)})`);\n }\n const started = start(call);\n if (started) {\n // Verifies through the context read's path, once, so later reads carry the level.\n await started.bridge.context(readOptions);\n await remember(call.id, { subject: started.conversation.subject, verification: started.conversation.verification, stamp: started.conversation.contextStamp });\n }\n return { status: 200, body: {} };\n }\n\n async function transfer(call: RetellCall): Promise<void> {\n if (transferred.has(call.id)) return;\n transferred.add(call.id);\n if (transferred.size > 10_000) transferred.clear();\n const record = await recall(call);\n if (record) await new Bridge(open(call.id, record)).handoff(\"human\", \"transfer\");\n }\n\n async function callEnded(call: RetellCall): Promise<WebhookResponse> {\n const record = await recall(call);\n if (!record) return { status: 200, body: { recorded: 0 } };\n const bridge = new Bridge(open(call.id, record));\n const started = typeof call.call.start_timestamp === \"number\" ? call.call.start_timestamp : null;\n const utterances = Array.isArray(call.call.transcript_object) ? (call.call.transcript_object as unknown[]) : [];\n let recorded = 0;\n for (const [index, utterance] of utterances.entries()) {\n if (recordUtterance(bridge, call.id, index, utterance, started, record)) recorded++;\n }\n if (call.call.disconnection_reason === \"call_transfer\") await transfer(call);\n await bridge.end();\n await options.niadra.flush();\n return { status: 200, body: { recorded } };\n }\n\n async function tool(rawBody: string | Uint8Array | ArrayBuffer, headers: HeadersLike): Promise<WebhookResponse> {\n const text = bodyText(rawBody);\n if (!(await signed(text, headers))) return { status: 401, body: { error: \"unauthorized\" } };\n const body = parseJson(text);\n const call = isRecord(body) ? callOf(body.call) : null;\n const name = isRecord(body) && typeof body.name === \"string\" ? body.name : \"\";\n if (!isRecord(body) || !call || !name) return { status: 400, body: { error: \"invalid_body\" } };\n const args: Record<string, unknown> = {};\n if (isRecord(body.args)) Object.assign(args, body.args);\n else for (const [key, value] of Object.entries(body)) if (key !== \"name\" && key !== \"call\") args[key] = value;\n\n if (!OURS.has(name)) {\n if (!options.otherTool) return { status: 200, body: { error: `unknown tool: ${name}` } };\n try {\n return { status: 200, body: (await options.otherTool(name, args, call)) ?? null };\n } catch (error) {\n logger.warn(`a tool outside Niadra failed (${errorName(error)})`);\n return { status: 200, body: { error: \"tool failed\" } };\n }\n }\n const record = await recall(call);\n const spec = record ? new Bridge(open(call.id, record), undefined, options.agentMemory).tools().find((candidate) => candidate.name === name) : undefined;\n if (!spec) return { status: 200, body: { error: \"unavailable\", detail: \"customer history is unavailable right now\" } };\n return { status: 200, body: parseJson(await spec.execute(args)) ?? null };\n }\n\n function llm(callId: string, config: RetellLlmOptions): RetellLlmSession {\n let bridge: Bridge | null = null;\n let record: CallRecord | null = null;\n let recorded = 0;\n const send = (event: Record<string, unknown>): void => {\n try {\n config.send(event);\n } catch (error) {\n logger.warn(`could not send to Retell (${errorName(error)})`);\n }\n };\n\n const ensure = async (call: RetellCall | null): Promise<Bridge | null> => {\n if (bridge) return bridge;\n let stored: CallRecord | undefined;\n try {\n stored = await store.get(callId);\n } catch (error) {\n logger.warn(`could not read the call store (${errorName(error)})`);\n }\n if (stored) {\n record = stored;\n bridge = new Bridge(open(callId, stored), undefined, options.agentMemory);\n bridge.begin(); // the socket opens as the call starts: its first read runs meanwhile\n return bridge;\n }\n // The socket is not signed: its call details never name the customer unless the server said so.\n const started = call && options.trustCallDetails ? start(call) : null;\n if (!started) return null;\n bridge = started.bridge;\n await bridge.context(readOptions);\n record = { subject: started.conversation.subject, verification: started.conversation.verification, stamp: started.conversation.contextStamp };\n await remember(callId, record);\n return bridge;\n };\n\n async function receive(event: unknown): Promise<RetellTurn | null> {\n try {\n if (!isRecord(event) || typeof event.interaction_type !== \"string\") return null;\n switch (event.interaction_type) {\n case \"ping_pong\":\n send({ response_type: \"ping_pong\", timestamp: event.timestamp });\n return null;\n case \"call_details\":\n await ensure(callOf(event.call));\n return null;\n case \"update_only\":\n await prefetchFor(event);\n return null;\n case \"response_required\":\n case \"reminder_required\":\n return await turnFor(event, event.interaction_type);\n default:\n return null;\n }\n } catch (error) {\n logger.warn(`could not handle a Retell event (${errorName(error)})`);\n return null;\n }\n }\n\n /** While the caller speaks, the transcript ends with their utterance so far: prefetch it. */\n async function prefetchFor(event: Record<PropertyKey, unknown>): Promise<void> {\n const transcript = Array.isArray(event.transcript) ? (event.transcript as unknown[]) : [];\n const last = transcript[transcript.length - 1];\n if (!isRecord(last) || last.role !== \"user\" || typeof last.content !== \"string\") return;\n const current = await ensure(null);\n current?.prefetch(last.content);\n }\n\n async function turnFor(event: Record<PropertyKey, unknown>, interactionType: RetellTurn[\"interactionType\"]): Promise<RetellTurn> {\n const responseId = typeof event.response_id === \"number\" ? event.response_id : 0;\n const transcript = Array.isArray(event.transcript) ? (event.transcript as unknown[]) : [];\n const current = await ensure(null);\n let prefix = \"\";\n let suffix = \"\";\n let context = \"\";\n if (current) {\n for (let index = recorded; index < transcript.length; index++) {\n recordUtterance(current, callId, index, transcript[index], null, record);\n }\n recorded = Math.max(recorded, transcript.length);\n const read = await current.read(readOptions);\n current.injected(read.context);\n ({ prefix, suffix } = read);\n context = read.context.text;\n }\n const messages: RetellMessage[] = [];\n if (config.instructions) messages.push({ role: \"system\", content: config.instructions });\n if (prefix) messages.push({ role: \"system\", content: prefix });\n for (const utterance of transcript) {\n if (!isRecord(utterance) || typeof utterance.content !== \"string\") continue;\n if (utterance.role === \"user\") messages.push({ role: \"user\", content: utterance.content });\n else if (utterance.role === \"agent\") messages.push({ role: \"assistant\", content: utterance.content });\n }\n if (suffix) {\n const last = messages.map((message) => message.role).lastIndexOf(\"user\");\n const message = messages[last];\n if (message) messages[last] = { role: \"user\", content: `${message.content}\\n\\n${suffix}` };\n else messages.push({ role: \"user\", content: suffix });\n }\n return {\n responseId,\n interactionType,\n messages,\n context,\n suffix,\n respond(content, respondOptions = {}) {\n const response: Record<string, unknown> = {\n response_type: \"response\",\n response_id: responseId,\n content,\n content_complete: respondOptions.complete ?? true,\n };\n if (respondOptions.endCall) response.end_call = true;\n if (respondOptions.transferNumber) {\n response.transfer_number = respondOptions.transferNumber;\n void transferOnce();\n }\n send(response);\n },\n };\n }\n\n async function transferOnce(): Promise<void> {\n if (transferred.has(callId)) return;\n transferred.add(callId);\n await bridge?.handoff(\"human\", \"transfer\");\n }\n\n return {\n open(greeting) {\n send({ response_type: \"config\", config: { auto_reconnect: true, call_details: true } });\n if (greeting) send({ response_type: \"response\", response_id: 0, content: greeting, content_complete: true });\n },\n receive,\n async close() {\n try {\n await options.niadra.flush();\n } catch (error) {\n logger.warn(`could not flush (${errorName(error)})`);\n }\n },\n };\n }\n\n function toolConfigs(config: { url: string; timeoutMs?: number }): Record<string, unknown>[] {\n const memory = options.agentMemory;\n const definitions = [\n ...TOOL_DEFINITIONS,\n ...(memory ? AGENT_MEMORY_TOOL_DEFINITIONS.slice(0, memory !== true && memory.write ? 2 : 1) : []),\n ];\n return definitions.map(({ function: definition }) => ({\n type: \"custom\",\n name: definition.name,\n description: definition.description,\n url: config.url,\n method: \"POST\",\n parameters: definition.parameters,\n speak_during_execution: false,\n speak_after_execution: true,\n timeout_ms: config.timeoutMs ?? 10_000,\n }));\n }\n\n return { inbound, webhook, tool, llm, toolConfigs };\n}\n\n/** Checks `X-Retell-Signature: v=<milliseconds>,d=<hex HMAC-SHA256 of body + milliseconds>` within five minutes. */\nexport async function validRetellSignature(body: string, signature: string | undefined, apiKey: string, now = Date.now()): Promise<boolean> {\n if (!signature || !apiKey) return false;\n const match = /^v=(\\d+),d=([0-9a-f]{64})$/i.exec(signature.trim());\n if (!match) return false;\n const [, stamp = \"\", digest = \"\"] = match;\n if (Math.abs(now - Number(stamp)) > SIGNATURE_WINDOW_MS) return false;\n return safeEqual(digest.toLowerCase(), hex(await hmac(\"SHA-256\", apiKey, body + stamp)));\n}\n\n/** Records one utterance with the key both the websocket and `call_ended` use. Returns whether it was recorded. */\nfunction recordUtterance(bridge: Bridge, callId: string, index: number, utterance: unknown, started: number | null, record: CallRecord | null): boolean {\n if (!isRecord(utterance) || typeof utterance.content !== \"string\" || !utterance.content.trim()) return false;\n const words = Array.isArray(utterance.words) ? (utterance.words as unknown[]) : [];\n const first = isRecord(words[0]) && typeof words[0].start === \"number\" ? words[0].start : null;\n const at = started !== null && first !== null ? new Date(started + first * 1000) : undefined;\n const base = { idempotency_key: `retell:${callId}:${String(index)}`, ...(at ? { occurred_at: at } : {}) };\n if (utterance.role === \"user\") {\n bridge.customer(utterance.content, base);\n return true;\n }\n if (utterance.role === \"agent\") {\n bridge.agent(utterance.content, record?.stamp ? { ...base, context_stamp: record.stamp } : base);\n return true;\n }\n return false;\n}\n\nfunction callOf(value: unknown): RetellCall | null {\n if (!isRecord(value) || typeof value.call_id !== \"string\" || !value.call_id) return null;\n const text = (key: string): string | undefined => {\n const field = value[key];\n return typeof field === \"string\" && field ? field : undefined;\n };\n return {\n id: value.call_id,\n fromNumber: text(\"from_number\"),\n toNumber: text(\"to_number\"),\n direction: text(\"direction\"),\n agentId: text(\"agent_id\"),\n call: value,\n };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/tools.ts","../src/context.ts","../src/integrations/shared.ts","../src/integrations/webhook.ts","../src/integrations/retell.ts"],"names":["message"],"mappings":"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","file":"retell.js","sourcesContent":["import { NiadraAPIError, NiadraValidationError } from \"./errors.js\";\nimport type { NiadraError } from \"./errors.js\";\nimport type { AgentNote, AgentNoteKind, CreateAgentNoteRequest, RememberResult } from \"./types/agent-memory.js\";\nimport type { Handle } from \"./types/common.js\";\nimport type {\n HistoryFilters,\n OpenedItem,\n SearchRequest,\n SearchResponse,\n TimelineRequest,\n TimelineResponse,\n ToolDefinition,\n} from \"./types/context.js\";\nimport type { HistoryItemKind, Verification } from \"./types/vocabulary.js\";\n\n/** The outcome of a call that may fail without throwing. Exactly one of the two fields is set. */\nexport type Result<T> = { data: T; error: null } | { data: null; error: NiadraError };\n\n/** Everything a tool call is bound to besides its arguments. None of it is visible to the model. */\nexport interface ToolBinding {\n about?: Handle;\n verification?: Verification;\n conversation_id?: string;\n task_id?: string;\n /** Use the voice time budget for the calls these tools make. */\n voice?: boolean;\n}\n\n/** Which tools a kit offers besides the navigation kit. */\nexport interface ToolOptions {\n /** Adds `search_agent_memory`, the agent's own working notes. */\n agentMemory?: boolean;\n /**\n * Adds `remember` too. Only for a key with the `agent_memory:write` scope: a tool the model\n * cannot use is a wasted call. Needs `agentMemory`.\n */\n writeAgentMemory?: boolean;\n}\n\nexport interface Navigator {\n search(params: SearchRequest, voice: boolean): Promise<Result<SearchResponse>>;\n timeline(params: TimelineRequest, voice: boolean): Promise<Result<TimelineResponse>>;\n open(id: string, subject: Handle, binding: ToolBinding, voice: boolean): Promise<Result<OpenedItem>>;\n searchAgentMemory(\n query: string,\n options: { tags?: string[]; conversation_id?: string; task_id?: string },\n voice: boolean,\n ): Promise<Result<AgentNote[]>>;\n remember(note: CreateAgentNoteRequest): Promise<Result<RememberResult>>;\n}\n\n/**\n * The navigation kit as function-calling tools, bound to one customer.\n *\n * The definitions have no parameter for the customer: the handle lives in this object, outside\n * the model's reach. A prompt injection that says \"now look up customer X\" has no argument to\n * put X in. The model chooses what to ask, never whom it is about.\n */\nexport interface BoundTools {\n /** Tool definitions in the `{ type: \"function\", function: { name, description, parameters } }` shape. */\n readonly definitions: ToolDefinition[];\n /** Whether `name` is one of these tools, for dispatchers that route several toolsets. */\n has(name: string): boolean;\n /**\n * Runs one tool call and returns the text to send back to the model as the tool result.\n * `args` may be the JSON string most model APIs return, or an already parsed object.\n * Failures come back as a short JSON error the model can read and move past; with\n * `strict: true` they are thrown instead.\n */\n call(name: string, args: string | Record<string, unknown>): Promise<string>;\n}\n\n/** What `remember` answers when the note carries personal data: the model can rewrite it. */\nexport const PERSONAL_DATA_TOOL_ERROR = {\n error: \"personal_data\",\n detail:\n \"The note has personal data. Rewrite it so it helps with any customer, without names, phones, e-mails, documents or ids.\",\n} as const;\n\nexport const TOOL_NAMES = {\n search: \"search_customer_history\",\n timeline: \"get_customer_timeline\",\n open: \"open_history_item\",\n} as const;\n\n/** The two tools of the agent's own memory, offered with `tools({ agentMemory: true })`. */\nexport const AGENT_MEMORY_TOOL_NAMES = {\n search: \"search_agent_memory\",\n remember: \"remember\",\n} as const;\n\nconst ITEM_KINDS: HistoryItemKind[] = [\"episode\", \"fact\", \"open_item\", \"action\", \"object\", \"trait\"];\nconst NOTE_KINDS: AgentNoteKind[] = [\"procedure\", \"tool_note\", \"process_note\", \"pitfall\"];\n\n/**\n * The navigation kit, word for word the server's canonical definitions (`GET /v1/history/tools`)\n * and the Python SDK's: a model sees one toolset whatever language the agent is written in. The\n * server names the context's history line in the space's language; the SDKs ship its default.\n */\nexport const TOOL_DEFINITIONS: readonly ToolDefinition[] = [\n {\n \"type\": \"function\",\n \"function\": {\n \"name\": \"search_customer_history\",\n \"description\": \"Search everything that already happened with this customer: past conversations, promises, agent actions, orders and invoices. Use it when the customer refers to something earlier or asks whether a problem happened before. Do not call it when the answer is already in the context block, including its 'Do histórico' line, which already counts recurrences. Returns short items with date, channel and outcome, plus a recurrence count. Open one with open_history_item.\",\n \"parameters\": {\n \"type\": \"object\",\n \"properties\": {\n \"query\": {\n \"type\": \"string\",\n \"description\": \"What to look for, in the customer's words.\"\n },\n \"filters\": {\n \"type\": \"object\",\n \"properties\": {\n \"since\": {\n \"type\": \"string\",\n \"format\": \"date-time\"\n },\n \"until\": {\n \"type\": \"string\",\n \"format\": \"date-time\"\n },\n \"when\": {\n \"type\": \"string\",\n \"description\": \"The period in the customer's own words, as they said it: 'last week', 'semana passada', 'en marzo'.\"\n },\n \"channels\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\"\n }\n },\n \"categories\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\"\n }\n },\n \"item_kinds\": {\n \"type\": \"array\",\n \"items\": {\n \"enum\": [\n \"episode\",\n \"fact\",\n \"open_item\",\n \"action\",\n \"object\",\n \"trait\"\n ]\n }\n },\n \"outcome\": {\n \"type\": \"string\"\n }\n },\n \"additionalProperties\": false\n },\n \"max_tokens\": {\n \"type\": \"integer\",\n \"minimum\": 50,\n \"maximum\": 4000\n }\n },\n \"required\": [\n \"query\"\n ],\n \"additionalProperties\": false\n }\n }\n },\n {\n \"type\": \"function\",\n \"function\": {\n \"name\": \"get_customer_timeline\",\n \"description\": \"List this customer's conversations and agent actions in order, newest first, one line each. Use it to leaf through the history when you do not know what to search for. Pass next_cursor to continue. Prefer search_customer_history for a specific question.\",\n \"parameters\": {\n \"type\": \"object\",\n \"properties\": {\n \"cursor\": {\n \"type\": \"string\"\n },\n \"limit\": {\n \"type\": \"integer\",\n \"minimum\": 1,\n \"maximum\": 100\n },\n \"filters\": {\n \"type\": \"object\",\n \"properties\": {\n \"since\": {\n \"type\": \"string\",\n \"format\": \"date-time\"\n },\n \"until\": {\n \"type\": \"string\",\n \"format\": \"date-time\"\n },\n \"when\": {\n \"type\": \"string\",\n \"description\": \"The period in the customer's own words, as they said it: 'last week', 'semana passada', 'en marzo'.\"\n },\n \"channels\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\"\n }\n },\n \"categories\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\"\n }\n },\n \"item_kinds\": {\n \"type\": \"array\",\n \"items\": {\n \"enum\": [\n \"episode\",\n \"fact\",\n \"open_item\",\n \"action\",\n \"object\",\n \"trait\"\n ]\n }\n },\n \"outcome\": {\n \"type\": \"string\"\n }\n },\n \"additionalProperties\": false\n }\n },\n \"additionalProperties\": false\n }\n }\n },\n {\n \"type\": \"function\",\n \"function\": {\n \"name\": \"open_history_item\",\n \"description\": \"Open one conversation or business object returned by search_customer_history or get_customer_timeline: what was asked, what was promised and by whom, the outcome and what memory came from it. Use it only after a search or timeline pointed to the item.\",\n \"parameters\": {\n \"type\": \"object\",\n \"properties\": {\n \"id\": {\n \"type\": \"string\",\n \"description\": \"The item id, e.g. `episode:...`.\"\n }\n },\n \"required\": [\n \"id\"\n ],\n \"additionalProperties\": false\n }\n }\n }\n] as ToolDefinition[];\n\n/**\n * `search_agent_memory` and `remember`, word for word the server's canonical definitions. They\n * read and write the agent's working notes, never anything about a customer.\n */\nexport const AGENT_MEMORY_TOOL_DEFINITIONS: readonly ToolDefinition[] = [\n {\n \"type\": \"function\",\n \"function\": {\n \"name\": \"search_agent_memory\",\n \"description\": \"Search your own working notes: procedures, how the company's tools and processes behave, and known pitfalls. Use it before a task or a tool call you are unsure how to do. It holds nothing about customers; for the customer's history use search_customer_history.\",\n \"parameters\": {\n \"type\": \"object\",\n \"properties\": {\n \"query\": {\n \"type\": \"string\",\n \"description\": \"What you need to know how to do.\"\n },\n \"tags\": {\n \"type\": \"array\",\n \"maxItems\": 8,\n \"items\": {\n \"type\": \"string\",\n \"pattern\": \"^[a-z0-9][a-z0-9_.:-]{0,63}$\"\n },\n \"description\": \"Object types, operations or systems, e.g. `invoice`, `credit`, `erp`.\"\n }\n },\n \"required\": [\n \"query\"\n ],\n \"additionalProperties\": false\n }\n }\n },\n {\n \"type\": \"function\",\n \"function\": {\n \"name\": \"remember\",\n \"description\": \"Save a working note for yourself and future runs: a procedure that worked, how a tool or process behaves, or a pitfall to avoid. Never write anything about a customer here: no names, phones, e-mails, documents, ids or words from the conversation. A note with personal data is refused. Write it so it helps with any customer.\",\n \"parameters\": {\n \"type\": \"object\",\n \"properties\": {\n \"kind\": {\n \"enum\": [\n \"procedure\",\n \"tool_note\",\n \"process_note\",\n \"pitfall\"\n ]\n },\n \"title\": {\n \"type\": \"string\",\n \"maxLength\": 120\n },\n \"body\": {\n \"type\": \"string\",\n \"maxLength\": 2000\n },\n \"tags\": {\n \"type\": \"array\",\n \"maxItems\": 8,\n \"items\": {\n \"type\": \"string\",\n \"pattern\": \"^[a-z0-9][a-z0-9_.:-]{0,63}$\"\n },\n \"description\": \"Object types, operations or systems, e.g. `invoice`, `credit`, `erp`.\"\n }\n },\n \"required\": [\n \"kind\",\n \"title\",\n \"body\"\n ],\n \"additionalProperties\": false\n }\n }\n }\n] as ToolDefinition[];\n\nfunction parseArgs(args: string | Record<string, unknown>): Record<string, unknown> {\n if (typeof args !== \"string\") return args;\n if (args.trim() === \"\") return {};\n let parsed: unknown;\n try {\n parsed = JSON.parse(args);\n } catch {\n throw new NiadraValidationError(\"tool arguments are not valid JSON\");\n }\n if (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) {\n throw new NiadraValidationError(\"tool arguments must be a JSON object\");\n }\n return parsed as Record<string, unknown>;\n}\n\nfunction str(args: Record<string, unknown>, name: string): string | undefined {\n const value = args[name];\n return typeof value === \"string\" && value.length > 0 ? value : undefined;\n}\n\nfunction strings(args: Record<string, unknown>, name: string): string[] | undefined {\n const value = args[name];\n if (!Array.isArray(value)) return undefined;\n const list = value.filter((entry): entry is string => typeof entry === \"string\");\n return list.length > 0 ? list : undefined;\n}\n\nfunction int(args: Record<string, unknown>, name: string): number | undefined {\n const value = args[name];\n return typeof value === \"number\" && Number.isInteger(value) ? value : undefined;\n}\n\n/** The filters of a call: the `filters` object of the canonical definitions. */\nfunction filtersFrom(args: Record<string, unknown>): HistoryFilters {\n const nested = args.filters;\n const source: Record<string, unknown> =\n typeof nested === \"object\" && nested !== null && !Array.isArray(nested) ? (nested as Record<string, unknown>) : {};\n const filters: HistoryFilters = {};\n const since = str(source, \"since\");\n const until = str(source, \"until\");\n const when = str(source, \"when\");\n const channels = strings(source, \"channels\");\n const categories = strings(source, \"categories\");\n const kinds = strings(source, \"item_kinds\")\n ?.filter((kind): kind is HistoryItemKind => (ITEM_KINDS as string[]).includes(kind));\n const outcome = str(source, \"outcome\");\n if (since) filters.since = since;\n if (until) filters.until = until;\n if (when) filters.when = when.slice(0, 100);\n if (channels) filters.channels = channels;\n if (categories) filters.categories = categories;\n if (kinds?.length) filters.item_kinds = [...new Set(kinds)];\n if (outcome) filters.outcome = outcome;\n return filters;\n}\n\nfunction tagsFrom(args: Record<string, unknown>): string[] | undefined {\n return strings(args, \"tags\")?.slice(0, 8);\n}\n\n/** Builds the bound toolset. `strict` decides whether failures are thrown or described to the model. */\nexport function bindTools(\n subject: Handle,\n binding: ToolBinding,\n navigator: Navigator,\n strict: boolean,\n options: ToolOptions = {},\n): BoundTools {\n const voice = binding.voice ?? false;\n const memory = options.agentMemory ? AGENT_MEMORY_TOOL_DEFINITIONS.slice(0, options.writeAgentMemory ? 2 : 1) : [];\n const definitions: ToolDefinition[] = [...TOOL_DEFINITIONS, ...memory];\n const names = new Set(definitions.map((definition) => definition.function.name));\n\n async function run(name: string, args: Record<string, unknown>): Promise<Result<unknown>> {\n switch (name) {\n case TOOL_NAMES.search: {\n const query = str(args, \"query\");\n if (!query) throw new NiadraValidationError(\"search_customer_history needs a query\");\n const request: SearchRequest = { subject, query, filters: filtersFrom(args) };\n applyBinding(request, binding);\n if (binding.task_id) request.task_id = binding.task_id;\n const maxTokens = int(args, \"max_tokens\");\n if (maxTokens !== undefined) request.max_tokens = Math.min(4000, Math.max(50, maxTokens));\n const result = await navigator.search(request, voice);\n return result.error ? result : { data: compactSearch(result.data), error: null };\n }\n case TOOL_NAMES.timeline: {\n const request: TimelineRequest = { subject, filters: filtersFrom(args) };\n applyBinding(request, binding);\n const cursor = str(args, \"cursor\");\n if (cursor) request.cursor = cursor;\n const limit = int(args, \"limit\");\n if (limit !== undefined) request.limit = Math.min(100, Math.max(1, limit));\n return navigator.timeline(request, voice);\n }\n case TOOL_NAMES.open: {\n const id = str(args, \"id\");\n if (!id) throw new NiadraValidationError(\"open_history_item needs an id\");\n return navigator.open(id, subject, binding, voice);\n }\n case AGENT_MEMORY_TOOL_NAMES.search: {\n const query = str(args, \"query\");\n if (!query) throw new NiadraValidationError(\"search_agent_memory needs a query\");\n const scope: { tags?: string[]; conversation_id?: string; task_id?: string } = {};\n const tags = tagsFrom(args);\n if (tags) scope.tags = tags;\n if (binding.conversation_id) scope.conversation_id = binding.conversation_id;\n else if (binding.task_id) scope.task_id = binding.task_id;\n const result = await navigator.searchAgentMemory(query, scope, voice);\n return result.error ? result : { data: { notes: result.data.map(compactNote) }, error: null };\n }\n case AGENT_MEMORY_TOOL_NAMES.remember: {\n const kind = str(args, \"kind\");\n const title = str(args, \"title\");\n const body = str(args, \"body\");\n if (!kind || !(NOTE_KINDS as string[]).includes(kind) || !title || !body) {\n throw new NiadraValidationError(\"remember needs a kind, a title and a body\");\n }\n const note: CreateAgentNoteRequest = { kind: kind as AgentNoteKind, title, body };\n const tags = tagsFrom(args);\n if (tags) note.tags = tags;\n if (binding.conversation_id) note.evidence = { conversation_id: binding.conversation_id };\n else if (binding.task_id) note.evidence = { task_id: binding.task_id };\n const result = await navigator.remember(note);\n return result.error ? result : { data: remembered(result.data), error: null };\n }\n default:\n throw new NiadraValidationError(`unknown tool: ${name}`);\n }\n }\n\n return {\n definitions: definitions.map((definition) => cloneDefinition(definition)),\n has: (name) => names.has(name),\n async call(name, rawArgs) {\n let result: Result<unknown>;\n try {\n if (!names.has(name)) throw new NiadraValidationError(`unknown tool: ${name}`);\n result = await run(name, parseArgs(rawArgs));\n } catch (error) {\n // Even a strict client hands this one to the model: rewriting the note is the answer.\n if (error instanceof NiadraAPIError && isPersonalData(error)) return JSON.stringify(PERSONAL_DATA_TOOL_ERROR);\n if (strict) throw error;\n return JSON.stringify({ error: \"invalid_call\", detail: (error as Error).message });\n }\n if (result.error) {\n if (isPersonalData(result.error)) return JSON.stringify(PERSONAL_DATA_TOOL_ERROR);\n if (strict) throw result.error;\n const memory = name === AGENT_MEMORY_TOOL_NAMES.search || name === AGENT_MEMORY_TOOL_NAMES.remember;\n const detail = memory ? \"agent memory is unavailable right now\" : \"customer history is unavailable right now\";\n return JSON.stringify({ error: \"unavailable\", detail });\n }\n return JSON.stringify(result.data);\n },\n };\n}\n\n/** What the model needs of a note: the id, the kind, the title, the body and the tags. */\nfunction compactNote(note: AgentNote): Partial<AgentNote> {\n const { note_id, kind, title, body, tags } = note;\n return tags === undefined ? { note_id, kind, title, body } : { note_id, kind, title, body, tags };\n}\n\n/** A saved note, or a proposal a person still has to approve, as the model reads it. */\nfunction remembered(result: RememberResult): Record<string, unknown> {\n if (result.note) return { saved: true, note_id: result.note.note_id, version: result.note.version };\n return { saved: false, proposal_id: result.proposal_id ?? null, status: \"waiting for review\" };\n}\n\n/** The server refused a note with personal data: an answer for the model, not a failure. */\nfunction isPersonalData(error: NiadraError): boolean {\n return error instanceof NiadraAPIError && error.code === \"personal_data_in_agent_memory\";\n}\n\nfunction applyBinding(request: SearchRequest | TimelineRequest, binding: ToolBinding): void {\n if (binding.about) request.about = binding.about;\n if (binding.verification) request.verification = binding.verification;\n if (binding.conversation_id) request.conversation_id = binding.conversation_id;\n}\n\n/** Token accounting is for the caller, not the model; everything else the model can use. */\nfunction compactSearch(response: SearchResponse): Omit<SearchResponse, \"tokens_used\"> {\n const { tokens_used: _, ...rest } = response;\n return rest;\n}\n\nfunction cloneDefinition(definition: ToolDefinition): ToolDefinition {\n return JSON.parse(JSON.stringify(definition)) as ToolDefinition;\n}\n","import { NiadraValidationError } from \"./errors.js\";\nimport { includeText } from \"./constraints/text.js\";\nimport type { NiadraError } from \"./errors.js\";\nimport { toObjectRef } from \"./handles.js\";\nimport type { Handle, ObjectRef } from \"./types/common.js\";\nimport type {\n ContextFormat,\n ContextPack,\n ContextRequest,\n ContextResponse,\n CoordinationBlock,\n Include,\n LiveTurn,\n PrefetchRequest,\n TargetModel,\n} from \"./types/context.js\";\nimport type { ConstraintsBlock } from \"./types/signals.js\";\nimport type { StateView } from \"./types/state.js\";\nimport type { Verification, View } from \"./types/vocabulary.js\";\n\n/** Arguments of `context()`. Pass exactly one of `subject` or `object`. */\nexport interface ContextParams {\n /** The customer, by any handle the server knows. */\n subject?: Handle;\n /** A business object, such as an invoice, when the task is about the object rather than a person. */\n object?: ObjectRef | string;\n /** The account or partner the person acts for. Requires an active link between the two. */\n about?: Handle;\n /** Defaults to `chat`. */\n view?: View;\n /**\n * The level proven in this conversation. The server may answer with a lower effective level\n * when the source's ceiling is lower; see `response.verification`.\n */\n verification?: Verification;\n /** Enables the per-conversation cache and the server's pinning of the pack. */\n conversation_id?: string;\n /** For internal agents: the task plays the role of the conversation. */\n task_id?: string;\n /**\n * Other words than the turn to pick this read's slots by. Up to 2,000 characters. Wins over\n * `turn`, and like it never changes the pack.\n */\n query?: string;\n /**\n * The customer's last turn; a conversation passes it for you. It goes as `query` and the answer\n * adds `slots`, what the turn selected from memory, in `suffix`, while the pack stays the\n * conversation's pinned one (and is cached as without it).\n */\n turn?: string | null;\n /** Ask only for what changed since this source last read the subject. */\n delta?: boolean;\n /** The model that will read the pack, so the server can size it for that model's prompt cache. */\n target?: TargetModel;\n /** `json` also returns the pack as typed sections in `pack` (`context-pack.v1`). Defaults to `text`. */\n format?: ContextFormat;\n /**\n * Adds `why` to each of `pack.slots`, naming the retrieval channels that\n * ranked it, the fused score, the weights version and, for a derived line, the rule behind it.\n * Requires `format: \"json\"`. It changes nothing else: the pinned text, the slots chosen and the\n * receipt are the same bytes with or without it.\n */\n explain?: boolean;\n /**\n * Blocks read in the same round trip: `[\"constraints\"]` returns the subject's constraints block, `[\"state\"]`\n * the state of their objects. Each only where the space turned its feature on; a block the space does not\n * serve is left out and not asked again for a while, and the read goes on. The blocks are cached with the\n * pack, so a read that fails serves the last good ones too.\n */\n include?: Include[];\n}\n\n/** Arguments of `prefetch()`: who the turn is about, as in `context()`, and the turn so far. */\nexport interface PrefetchParams {\n subject?: Handle;\n object?: ObjectRef | string;\n about?: Handle;\n /** Defaults to `voice`, where partial transcripts come from. */\n view?: View;\n verification?: Verification;\n conversation_id?: string;\n task_id?: string;\n /** The partial transcript of the customer's turn. */\n text: string;\n}\n\n/** Per-call options shared by every read method. */\nexport interface RequestOptions {\n /** Overrides the method's default time budget, in milliseconds. */\n timeout?: number | undefined;\n /** Cancels the wait. A request shared with other callers keeps running for them. */\n signal?: AbortSignal | undefined;\n /** Extra headers, such as a W3C `traceparent`. */\n headers?: Record<string, string> | undefined;\n}\n\nexport interface ContextOptions extends RequestOptions {\n /** Pass `false` to skip the per-conversation cache for this call. */\n cache?: boolean | undefined;\n /** For `conversation.context()` and `task.context()`: blocks read in the same round trip. */\n include?: Include[] | undefined;\n /** For `conversation.context()` and `task.context()`: `json` also returns `pack`. */\n format?: ContextFormat | undefined;\n /**\n * For `conversation.context()` and `task.context()`: adds `why` to each of `pack.slots`.\n * Requires `format: \"json\"`.\n */\n explain?: boolean | undefined;\n}\n\n/**\n * Where a `context()` result came from.\n *\n * - `network`: a response the server just sent (or confirmed unchanged).\n * - `cache`: a pack younger than the cache TTL; no request was made.\n * - `stale`: an older pack returned at once while a background request refreshes it.\n * - `fallback`: the request failed and this is the last good pack for the conversation.\n * - `none`: nothing was available; `text` is empty and `error` says why.\n */\nexport type ContextSource = \"network\" | \"cache\" | \"stale\" | \"fallback\" | \"none\";\n\n/** What `context()` resolves to. Always usable: on failure `text` is an empty string. */\nexport interface ContextResult {\n /** The pack, ready for the system prompt. Empty when there is nothing to inject. */\n text: string;\n /**\n * The parts that change turn by turn and belong at the end of the prompt, after the\n * conversation: the live turns from other channels, this turn's slots (what the customer's last\n * turn selected from memory), the blocks asked for by `include` (the state view, the constraints) and the\n * delta, in that order, as the API places them. Empty when there are none.\n */\n suffix: string;\n /** Named values from the pack, for templates that place them individually. */\n variables: Record<string, string>;\n /** The pack as typed sections, when read with `format: \"json\"`; otherwise `null`. */\n pack: ContextPack | null;\n source: ContextSource;\n /**\n * How long ago Niadra sent or confirmed the pack served, in milliseconds: 0 for an answer just received,\n * growing while a cached pack is served (`cache`, `stale`, or `fallback` with Niadra down), and `null` when\n * there is no pack.\n */\n ageMs: number | null;\n /** The response this result was built from; `null` when `source` is `none`. */\n response: ContextResponse | null;\n /** What went wrong, when `source` is `fallback` or `none`. */\n error: NiadraError | null;\n /** With `include: [\"constraints\"]`: the subject's constraints block. */\n constraints?: ConstraintsBlock | null;\n /** With `include: [\"state\"]`: the state of the subject's objects. */\n state?: StateView | null;\n /** With `include: [\"coordination\"]`: what coordination knows of the subject. */\n coordination?: CoordinationBlock | null;\n}\n\nconst VIEW = /^(voice|chat|brief|full|custom|account|partner|task:[a-z0-9_]{1,40})$/;\nconst MAX_QUERY = 2000;\n\n/** Validates the arguments and builds the wire request, without `known_etag`. */\nexport function buildContextRequest(params: ContextParams): ContextRequest {\n if ((params.subject === undefined) === (params.object === undefined)) {\n throw new NiadraValidationError(\"pass exactly one of `subject` or `object`\");\n }\n if (params.conversation_id && params.task_id) {\n throw new NiadraValidationError(\"pass `conversation_id` or `task_id`, not both\");\n }\n if (params.view !== undefined && !VIEW.test(params.view)) {\n throw new NiadraValidationError(\"unknown view; task views look like `task:billing`\");\n }\n if (params.query !== undefined && params.query.length > MAX_QUERY) {\n throw new NiadraValidationError(`query is longer than ${MAX_QUERY} characters`);\n }\n\n const request: ContextRequest = { view: params.view ?? \"chat\" };\n if (params.subject) request.subject = params.subject;\n if (params.object !== undefined) request.object = toObjectRef(params.object);\n if (params.about) request.about = params.about;\n if (params.verification) request.verification = params.verification;\n if (params.conversation_id) request.conversation_id = params.conversation_id;\n if (params.task_id) request.task_id = params.task_id;\n if (params.query) request.query = params.query;\n if (params.delta) request.delta = true;\n if (params.target) request.target = params.target;\n const format: string = params.format ?? \"text\";\n if (format !== \"text\" && format !== \"json\") throw new NiadraValidationError(\"format is `text` or `json`\");\n if (format === \"json\") request.format = \"json\";\n if (params.explain) {\n if (format !== \"json\") throw new NiadraValidationError('explain requires format: \"json\"');\n request.explain = true;\n }\n if (params.include?.length) request.include = [...new Set(params.include)];\n return request;\n}\n\n/** Validates the arguments of `prefetch()` and builds the wire request. */\nexport function buildPrefetchRequest(params: PrefetchParams): PrefetchRequest {\n if ((params.subject === undefined) === (params.object === undefined)) {\n throw new NiadraValidationError(\"pass exactly one of `subject` or `object`\");\n }\n if (params.conversation_id && params.task_id) {\n throw new NiadraValidationError(\"pass `conversation_id` or `task_id`, not both\");\n }\n if (params.view !== undefined && !VIEW.test(params.view)) {\n throw new NiadraValidationError(\"unknown view; task views look like `task:billing`\");\n }\n const text = params.text.trim();\n if (!text || text.length > MAX_QUERY) throw new NiadraValidationError(`text must be 1 to ${MAX_QUERY} characters`);\n const request: PrefetchRequest = { view: params.view ?? \"voice\", query: text };\n if (params.subject) request.subject = params.subject;\n if (params.object !== undefined) request.object = toObjectRef(params.object);\n if (params.about) request.about = params.about;\n if (params.verification) request.verification = params.verification;\n if (params.conversation_id) request.conversation_id = params.conversation_id;\n if (params.task_id) request.task_id = params.task_id;\n return request;\n}\n\n/** Packs are only cached inside a conversation or task, the unit the server pins them to. */\nexport function cacheScope(request: Pick<ContextRequest, \"conversation_id\" | \"task_id\">): string | null {\n if (request.conversation_id) return `conversation:${request.conversation_id}`;\n if (request.task_id) return `task:${request.task_id}`;\n return null;\n}\n\n/**\n * Every field that changes what the server would compile goes into the key, in a fixed order.\n * `delta` does not: a plain read and a delta read of one conversation get the same pinned\n * bytes, so they share one entry.\n */\nexport function cacheKey(request: ContextRequest): string {\n return JSON.stringify([\n request.subject ?? null,\n request.object ?? null,\n request.about ?? null,\n request.view ?? \"chat\",\n request.verification ?? \"V0\",\n request.conversation_id ?? null,\n request.task_id ?? null,\n request.query ?? null,\n request.target ?? null,\n request.format ?? \"text\",\n request.explain ?? false,\n request.include ?? null,\n ]);\n}\n\n/**\n * Applies a `not_modified` answer to the cached pack: the pinned text and its metadata stay,\n * while the parts outside the pin (live turns, delta, coverage, timing) come from the new answer.\n */\nexport function mergeNotModified(cached: ContextResponse, fresh: ContextResponse): ContextResponse {\n return {\n ...fresh,\n not_modified: false,\n text: cached.text ?? null,\n variables: cached.variables,\n version: cached.version,\n etag: cached.etag,\n manifest_hash: cached.manifest_hash ?? null,\n withheld: cached.withheld,\n cache: cached.cache ?? null,\n pack: cached.pack ?? null,\n // The blocks sit outside the pinned pack: a fresh block wins, and a missing one keeps the cached.\n constraints: fresh.constraints ?? cached.constraints ?? null,\n state: fresh.state ?? cached.state ?? null,\n coordination: fresh.coordination ?? cached.coordination ?? null,\n };\n}\n\nexport function resultFrom(\n response: ContextResponse,\n source: ContextSource,\n error: NiadraError | null = null,\n ageMs: number | null = 0,\n): ContextResult {\n // A conversation in the control group gets an empty pack on purpose; it is not an error.\n const holdout = response.path === \"holdout\";\n const text = holdout ? \"\" : (response.text ?? \"\");\n const pack = holdout ? null : (response.pack ?? null);\n const blocks = {\n constraints: response.constraints ?? null,\n state: response.state ?? null,\n coordination: response.coordination ?? null,\n };\n return { text, suffix: renderSuffix(response), variables: response.variables, pack, source, ageMs, response, error, ...blocks };\n}\n\nexport function emptyResult(error: NiadraError | null): ContextResult {\n return { text: \"\", suffix: \"\", variables: {}, pack: null, source: \"none\", ageMs: null, response: null, error, constraints: null, state: null, coordination: null };\n}\n\n/**\n * Renders the live turns, the slots and the delta for the end of the prompt, in that order. Kept\n * outside the pinned pack so that the prompt prefix stays byte-identical across turns and the\n * model provider's prompt cache keeps hitting. Returns an empty string when there is nothing to add.\n */\nexport function renderSuffix(response: ContextResponse): string {\n if (response.path === \"holdout\") return \"\";\n const included = includeText(response.text, response.state, response.constraints);\n return [renderLive(response), response.slots ?? \"\", included, response.delta ?? \"\"].filter(Boolean).join(\"\\n\\n\");\n}\n\n/**\n * Renders the live turns (recent turns from other channels that the pack has not absorbed\n * yet) as one tagged block, or an empty string when there are none. `complete=\"false\"` tells\n * the model the list may be missing turns because the server could not read all of them.\n */\nexport function renderLive(response: ContextResponse): string {\n if (response.path === \"holdout\" || response.live.length === 0) return \"\";\n const complete = response.live_complete ? \"\" : ' complete=\"false\"';\n const lines = response.live.map(renderLiveTurn).join(\"\\n\");\n return `<live_turns source=\"niadra\"${complete}>\\n${lines}\\n</live_turns>`;\n}\n\nfunction renderLiveTurn(turn: LiveTurn): string {\n return `[${utcSeconds(turn.at)}] ${turn.channel} · ${turn.speaker}: ${turn.text}`;\n}\n\n/** The same timestamp form in every SDK, whatever precision or offset the server sent. */\nfunction utcSeconds(at: string): string {\n const ms = Date.parse(at);\n return Number.isNaN(ms) ? at : `${new Date(ms).toISOString().slice(0, 19)}Z`;\n}\n","/**\n * What every framework adapter shares: the five primitives (context before the model call, the\n * turns, the tools, the verification and the handoff) wired the same way, and fail-open.\n *\n * Nothing here throws into the framework: a failed read gives an empty context, a failed write\n * is logged without content, and the agent keeps working without memory.\n */\n\nimport { recordedTool } from \"../capture/tool.js\";\nimport type { Played } from \"../replay/playback.js\";\nimport type { AgentMemoryParams } from \"../agent-memory.js\";\nimport type { TurnParams } from \"../agent-session.js\";\nimport type { CallCapture, TurnFrame } from \"../capture/frame.js\";\nimport type { ContextOptions, ContextResult } from \"../context.js\";\nimport { emptyResult } from \"../context.js\";\nimport type { Conversation, TurnOptions } from \"../conversation.js\";\nimport type { Logger } from \"../logger.js\";\nimport type { Task } from \"../task.js\";\nimport type { BoundTools } from \"../tools.js\";\nimport type { Handle } from \"../types/common.js\";\nimport type { Verification, VerifyMethod } from \"../types/vocabulary.js\";\n\n/** A customer conversation or an internal agent's task. */\nexport type Session = Conversation | Task;\n\n/** A session, or a function that finds the one the current call belongs to (`null` passes the call through). */\nexport type SessionResolver<S extends Session = Session> = S | (() => S | null | undefined);\n\n/** What the framework proved about the person, recorded with `verify()` before the first context read. */\nexport interface Proof {\n method: VerifyMethod;\n level: Verification;\n /** Defaults to the session's subject. */\n handle?: Handle;\n}\n\n/** A proof, or a function that reads it from the framework when the first context is needed. */\nexport type ProofSource =\n | Proof\n | null\n | undefined\n | (() => Proof | null | undefined | PromiseLike<Proof | null | undefined>);\n\n/**\n * The agent's own working notes: `true` puts the block before the customer's context and offers\n * `search_agent_memory`; `{ write: true }` also offers `remember` (for a key with the\n * `agent_memory:write` scope); the other fields go to `agentMemory()`.\n */\nexport type AgentMemoryOption = boolean | (AgentMemoryParams & { write?: boolean });\n\n/** What goes into the prompt for one model call. */\nexport interface Read {\n context: ContextResult;\n /** The agent's own notes, or an empty string. */\n memory: string;\n /** What goes after the instructions: the notes, then the customer's pack. */\n prefix: string;\n /** What goes at the end: live turns, the turn's slots and deltas. */\n suffix: string;\n}\n\n/** A tool as every framework needs it: the name, the text for the model, the JSON Schema and the call. */\ninterface ToolSpec {\n name: string;\n description: string;\n /** JSON Schema of the arguments. None of them names the customer. */\n parameters: Record<string, unknown>;\n /** Runs the call and returns the text for the model. Never rejects in fail-open mode. */\n execute(args: string | Record<string, unknown>): Promise<string>;\n}\n\nconst ATTESTED: Record<string, Verification> = { A: \"V2\", B: \"V1\", C: \"V1\" };\n\n/**\n * The proof a carrier's STIR/SHAKEN attestation gives a phone call: `A` proves V2, `B` and `C`\n * prove V1, anything else proves nothing (`null`). Accepts the bare letter or the forms carriers\n * and platforms send, such as Twilio's `TN-Validation-Passed-A`.\n */\nexport function attestationProof(attestation: string | null | undefined): Proof | null {\n if (!attestation) return null;\n const value = attestation.trim().toUpperCase();\n if (value.includes(\"FAILED\") || value.startsWith(\"NO-\")) return null;\n const letter = value.length === 1 ? value : /PASSED-([ABC])$/.exec(value)?.[1];\n const level = letter ? ATTESTED[letter] : undefined;\n return level ? { method: \"network_attestation\", level } : null;\n}\n\nexport function resolveSession<S extends Session>(source: SessionResolver<S>): S | null {\n if (typeof source !== \"function\") return source;\n try {\n return source() ?? null;\n } catch {\n return null;\n }\n}\n\nfunction isConversation(session: Session): session is Conversation {\n return \"customer\" in session && typeof session.customer === \"function\";\n}\n\n/** A phone number as an E.164 handle, or `null` when it does not look like one. */\nexport function phoneHandle(value: string | null | undefined): Handle | null {\n const raw = value?.trim().replace(/^tel:/i, \"\").replace(/[\\s().-]/g, \"\");\n if (!raw) return null;\n const e164 = raw.startsWith(\"+\") ? raw : `+${raw}`;\n return /^\\+[1-9]\\d{6,14}$/.test(e164) ? { type: \"phone_e164\", value: e164 } : null;\n}\n\nexport function errorName(error: unknown): string {\n return error instanceof Error ? error.name : typeof error;\n}\n\n/**\n * One session as an adapter drives it. Keeps the verification to a single call made before the\n * first context read, and turns every failure into a log line.\n */\nexport class Bridge {\n private proving: Promise<void> | null = null;\n /** `begin()` started the first read of a call: the first `context()` waits for it with `ready()`. */\n private begun = false;\n private opened = false;\n\n constructor(\n readonly session: Session,\n private readonly proof?: ProofSource,\n private readonly memory: AgentMemoryOption = false,\n ) {}\n\n /**\n * The context and, when enabled, the agent's notes, read side by side within the same budget.\n * Never rejects.\n */\n async read(options: ContextOptions = {}): Promise<Read> {\n const memoryParams = this.memory === false ? null : this.memory === true ? {} : withoutWrite(this.memory);\n const [context, memory] = await Promise.all([\n this.context(options),\n memoryParams ? this.agentMemory(memoryParams, options) : Promise.resolve(\"\"),\n ]);\n return { context, memory, prefix: [memory, context.text].filter(Boolean).join(\"\\n\\n\"), suffix: context.suffix };\n }\n\n get logger(): Logger {\n return this.session.logger;\n }\n\n /**\n * Starts the first read of a call now, in the background, after the proof when one was given (the\n * pack depends on the level it proves): at call start, so the read runs while the call is set up.\n * The first `context()` then waits for it within `timeouts.contextVoiceStart`. Never throws.\n */\n begin(): void {\n const session = this.session;\n if (!isConversation(session)) return;\n const start = (): void => {\n this.safe(\"start the first read\", () => {\n // False off the voice read path (a chat view, the cache off): reads go on as before.\n this.begun = session.begin();\n });\n };\n if (this.proof === undefined || this.proof === null) start();\n else void this.verifyOnce().then(start);\n }\n\n /** Verifies once (when a proof was given), then reads the context. Never rejects. */\n async context(options: ContextOptions = {}): Promise<ContextResult> {\n await this.verifyOnce();\n try {\n const session = this.session;\n if (this.begun && !this.opened && isConversation(session)) {\n this.opened = true;\n // The call's first read, begun at call start: waited for within its own, longer budget.\n await session.ready(options.timeout === undefined ? {} : { timeout: options.timeout });\n }\n return await this.session.context(options);\n } catch (error) {\n this.logger.warn(`could not read context (${errorName(error)})`);\n return emptyResult(null);\n }\n }\n\n /** Records that `context` went into the prompt, unless it was empty for a reason other than the holdout. */\n injected(context: ContextResult): void {\n if (!context.text && !context.suffix && context.response?.path !== \"holdout\") return;\n this.safe(\"mark the injection\", () => {\n this.session.markInjected(context);\n });\n }\n\n customer(text: string, options: TurnOptions = {}): void {\n const session = this.session;\n if (!text.trim() || !isConversation(session)) return;\n this.safe(\"record the customer's turn\", () => session.customer(text, options));\n }\n\n /** Sends the customer's turn so far, while they speak. In the background; never throws. */\n prefetch(text: string): void {\n const session = this.session;\n if (!text.trim() || !isConversation(session)) return;\n this.safe(\"prefetch the turn\", () => session.prefetch(text));\n }\n\n agent(text: string, options: TurnOptions = {}): void {\n if (!text.trim()) return;\n this.safe(\"record the agent's turn\", () => this.session.agent(text, options));\n }\n\n /** Records a transfer. Tasks have no transfer; the call is ignored for them. */\n async handoff(target: \"agent\" | \"human\", reason?: string): Promise<void> {\n const session = this.session;\n if (!isConversation(session)) return;\n try {\n await session.handoff(reason ? { target, reason } : { target });\n } catch (error) {\n this.logger.warn(`could not record the handoff (${errorName(error)})`);\n }\n }\n\n async end(): Promise<void> {\n try {\n await this.session.end();\n } catch (error) {\n this.logger.warn(`could not end the session (${errorName(error)})`);\n }\n }\n\n /** The navigation kit as plain specs (with the agent's memory tools when enabled), or none for a task about an object only. */\n tools(): ToolSpec[] {\n let bound: BoundTools | null;\n try {\n const memory = this.memory;\n bound = this.session.tools(memory === false ? {} : { agentMemory: true, writeAgentMemory: memory !== true && memory.write === true });\n } catch (error) {\n this.logger.warn(`could not build the tools (${errorName(error)})`);\n return [];\n }\n return bound ? toolSpecs(bound) : [];\n }\n\n private async agentMemory(params: AgentMemoryParams, options: ContextOptions): Promise<string> {\n try {\n const result = await this.session.agentMemory(params, options.timeout === undefined ? {} : { timeout: options.timeout });\n return result.text;\n } catch (error) {\n this.logger.warn(`could not read the agent's memory (${errorName(error)})`);\n return \"\";\n }\n }\n\n private async verifyOnce(): Promise<void> {\n if (this.proof === undefined || this.proof === null) return;\n this.proving ??= this.runVerify();\n await this.proving;\n }\n\n private async runVerify(): Promise<void> {\n try {\n const source = this.proof;\n const proof = typeof source === \"function\" ? await source() : source;\n if (!proof) return;\n await this.session.verify(proof);\n } catch (error) {\n this.logger.warn(`could not record the verification (${errorName(error)})`);\n }\n }\n\n private safe(what: string, run: () => unknown): void {\n try {\n run();\n } catch (error) {\n this.logger.warn(`could not ${what} (${errorName(error)})`);\n }\n }\n}\n\nfunction withoutWrite(option: AgentMemoryParams & { write?: boolean }): AgentMemoryParams {\n const { write: _, ...params } = option;\n return params;\n}\n\n/** The bound kit as specs. The customer stays inside `bound`; no parameter names them. */\nfunction toolSpecs(bound: BoundTools): ToolSpec[] {\n return bound.definitions.map(({ function: definition }) => ({\n name: definition.name,\n description: definition.description,\n parameters: definition.parameters,\n execute: (args) => bound.call(definition.name, args),\n }));\n}\n\n/** The text of a message content in the shapes model APIs use: a string, or a list of text parts. */\nexport function textOf(content: unknown): string {\n if (typeof content === \"string\") return content;\n if (!Array.isArray(content)) return \"\";\n const parts: string[] = [];\n for (const part of content as unknown[]) {\n if (typeof part === \"string\") parts.push(part);\n else if (isRecord(part) && typeof part.text === \"string\" && (part.type === undefined || part.type === \"text\")) {\n parts.push(part.text);\n }\n }\n return parts.join(\"\");\n}\n\nexport function isRecord(value: unknown): value is Record<PropertyKey, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\n/** A non-negative integer, or `null`. */\nexport function count(value: unknown): number | null {\n return typeof value === \"number\" && Number.isInteger(value) && value >= 0 ? value : null;\n}\n\n/**\n * The turn records an adapter keeps from its framework's callbacks, keyed by the framework's own ids (a\n * run, a request, a tool call id). A run starting while the session has a turn in progress (yours, from\n * `conversation.turn()`, or a replay's) records into it; otherwise the adapter opens its own turn and closes\n * it when the run ends. A tool call recorded here is taken over by a `tool()` wrapper running inside it, so\n * the call is recorded once. Every method does nothing when turns are off and never throws.\n */\nexport class TurnHooks {\n /** Runs held open at most; past it the oldest run's turn closes, incomplete (a run whose end never came). */\n static readonly MAX_OPEN = 100;\n private readonly frames = new Map<string, { frame: TurnFrame; own: boolean }>();\n private readonly calls = new Map<string, CallCapture>();\n\n constructor(\n readonly adapter: string,\n readonly enabled: boolean,\n ) {}\n\n /** The turn of the run `key`: the session's turn in progress, or a new one of its own. */\n open(session: Session, key: string, params: TurnParams = {}): TurnFrame | undefined {\n if (!this.enabled) return undefined;\n const held = this.frames.get(key);\n if (held !== undefined) return held.frame;\n try {\n const active = session.activeTurn();\n if (active !== undefined && !this.owns(active)) {\n this.frames.set(key, { frame: active, own: false });\n return active;\n }\n const frame = session.openTurn({ ...params, adapter: this.adapter });\n this.frames.set(key, { frame, own: true });\n if (this.frames.size > TurnHooks.MAX_OPEN) {\n const [oldest] = this.frames.keys();\n if (oldest !== undefined) {\n this.frames.get(oldest)?.frame.incomplete();\n this.close(oldest);\n }\n }\n return frame;\n } catch (error) {\n session.logger.warn(`could not open the turn (${errorName(error)})`);\n return undefined;\n }\n }\n\n /** The turn of `key`, else the session's turn in progress. */\n frame(session: Session, key?: string): TurnFrame | undefined {\n if (!this.enabled) return undefined;\n const held = key === undefined ? undefined : this.frames.get(key);\n const frame = held?.frame ?? session.activeTurn();\n return frame === undefined || frame.closed ? undefined : frame;\n }\n\n has(key: string): boolean {\n return this.frames.has(key);\n }\n\n private owns(frame: TurnFrame): boolean {\n for (const held of this.frames.values()) if (held.own && held.frame === frame) return true;\n return false;\n }\n\n /** Ends the run `key`: a turn the adapter opened closes; the calls it left open failed. */\n close(key: string, error?: unknown): void {\n const held = this.frames.get(key);\n if (held === undefined) return;\n this.frames.delete(key);\n for (const [callKey, call] of this.calls) {\n if (call.frame !== held.frame) continue;\n this.calls.delete(callKey);\n if (held.own) call.failed(error ?? \"error\");\n }\n if (held.own) held.frame.close(error);\n }\n\n /** A tool call starting, keyed by `callKey`; `callId` is the provider's id of the call, when there is one. */\n toolStart(session: Session, callKey: string, name: string, args: unknown, options: { frameKey?: string; callId?: string | null } = {}): void {\n const frame = this.frame(session, options.frameKey);\n if (frame === undefined) return;\n try {\n this.calls.set(callKey, frame.toolCall(name, args, { callId: options.callId ?? null, adoptable: true }));\n } catch {\n frame.incomplete();\n }\n }\n\n /**\n * In a replay, how a framework tool the adapter stands in for answers: the recorded result of a call with the\n * same arguments, or empty (a divergence), never the live tool. `null` outside a replay, and for a function\n * wrapped with `tool()`, which answers itself.\n */\n replayed(session: Session, name: string, args: unknown, fn?: unknown, frameKey?: string): Played | null {\n const frame = this.enabled ? this.frame(session, frameKey) : session.activeTurn();\n if (frame?.playback == null || (fn !== undefined && recordedTool(fn) !== null)) return null;\n return frame.playback.answer(name, args, false);\n }\n\n toolEnd(callKey: string, result?: unknown, error?: unknown): void {\n const call = this.calls.get(callKey);\n if (call === undefined) return;\n this.calls.delete(callKey);\n try {\n if (error !== undefined) call.failed(error);\n else call.result(result);\n } catch {\n call.frame.incomplete();\n }\n }\n\n /** A model call that ended, with its tokens when the framework reported them. */\n model(\n session: Session,\n model: string | null | undefined,\n tokens: { in?: number | null; out?: number | null; cached?: number | null } = {},\n frameKey?: string,\n ): void {\n const frame = this.frame(session, frameKey);\n if (frame === undefined) return;\n try {\n frame.modelCall(model, { tokensIn: tokens.in ?? null, tokensOut: tokens.out ?? null, tokensCached: tokens.cached ?? 0 });\n } catch {\n frame.incomplete();\n }\n }\n}\n","/**\n * Helpers for the webhook adapters (ElevenLabs, Vapi, WhatsApp, Twilio): signatures with Web\n * Crypto and header lookup. Only web APIs, so the handlers run on Node 20+, Deno, Bun, Cloudflare\n * Workers and the Vercel Edge Runtime alike.\n */\n\nimport type { Handle } from \"../types/common.js\";\nimport type { ContextStamp } from \"../types/events.js\";\nimport type { Verification } from \"../types/vocabulary.js\";\n\n/**\n * What a call's first webhook learned, for the webhooks that come later in the same call (tool\n * calls, the end-of-call report): who the caller is, the level they proved and the context stamp.\n */\nexport interface CallRecord {\n subject: Handle;\n verification: Verification;\n stamp?: ContextStamp | null;\n}\n\n/**\n * Where the webhook adapters keep a `CallRecord` between requests, by the platform's call id.\n * The default lives in this process's memory; on serverless or several instances, pass one backed\n * by your key-value store.\n */\nexport interface CallStore {\n get(id: string): CallRecord | undefined | PromiseLike<CallRecord | undefined>;\n set(id: string, record: CallRecord): void | PromiseLike<void>;\n}\n\n/** An in-memory `CallStore` that keeps the most recent `max` calls. */\nexport function memoryCallStore(max = 10_000): CallStore {\n const calls = new Map<string, CallRecord>();\n return {\n get: (id) => calls.get(id),\n set: (id, record) => {\n calls.delete(id);\n calls.set(id, record);\n if (calls.size > max) {\n const oldest = calls.keys().next().value;\n if (oldest !== undefined) calls.delete(oldest);\n }\n },\n };\n}\n\n/** Request headers as a `Headers` object or a plain record (any case). */\nexport type HeadersLike = Headers | Record<string, string | string[] | undefined>;\n\n/** What a handler answers: the HTTP status and a JSON-serializable body (`null` for no body). */\nexport interface WebhookResponse<B = unknown> {\n status: number;\n body: B;\n}\n\nexport function header(headers: HeadersLike, name: string): string | undefined {\n if (typeof (headers as Headers).get === \"function\") return (headers as Headers).get(name) ?? undefined;\n const wanted = name.toLowerCase();\n for (const [key, value] of Object.entries(headers as Record<string, string | string[] | undefined>)) {\n if (key.toLowerCase() !== wanted) continue;\n return Array.isArray(value) ? value[0] : value;\n }\n return undefined;\n}\n\nfunction subtle(): SubtleCrypto {\n const crypto = (globalThis as { crypto?: Crypto }).crypto;\n if (!crypto?.subtle) throw new Error(\"Web Crypto is not available on this runtime\");\n return crypto.subtle;\n}\n\nconst encoder = new TextEncoder();\n\nexport async function hmac(hash: \"SHA-1\" | \"SHA-256\", secret: string, message: string): Promise<Uint8Array> {\n const key = await subtle().importKey(\"raw\", encoder.encode(secret), { name: \"HMAC\", hash }, false, [\"sign\"]);\n return new Uint8Array(await subtle().sign(\"HMAC\", key, encoder.encode(message)));\n}\n\nexport function hex(bytes: Uint8Array): string {\n let out = \"\";\n for (const byte of bytes) out += byte.toString(16).padStart(2, \"0\");\n return out;\n}\n\nexport function base64(bytes: Uint8Array): string {\n let binary = \"\";\n for (const byte of bytes) binary += String.fromCharCode(byte);\n return btoa(binary);\n}\n\n/** Compares two strings in time that depends only on their length. */\nexport function safeEqual(a: string, b: string): boolean {\n const left = encoder.encode(a);\n const right = encoder.encode(b);\n if (left.length !== right.length) return false;\n let diff = 0;\n for (let i = 0; i < left.length; i++) diff |= (left[i] ?? 0) ^ (right[i] ?? 0);\n return diff === 0;\n}\n\n/** The raw body as text, whatever form the framework hands it in. */\nexport function bodyText(body: string | Uint8Array | ArrayBuffer): string {\n if (typeof body === \"string\") return body;\n return new TextDecoder().decode(body instanceof Uint8Array ? body : new Uint8Array(body));\n}\n\nexport function parseJson(text: string): unknown {\n try {\n return JSON.parse(text) as unknown;\n } catch {\n return undefined;\n }\n}\n","/**\n * Niadra for Retell AI, on the server side: a call reaches Retell, Retell calls your webhooks\n * (and, with a custom LLM, opens a websocket to your server), and these handlers answer them. No\n * Retell package is needed.\n *\n * - `inbound`: the inbound call webhook. Opens the conversation by Retell's `call_id`, records what\n * the call proved, starts the first read and waits for it within `timeouts.contextVoiceStart`\n * (the phone rings meanwhile), and answers it as dynamic variables: put\n * `{{niadra_context}}` in the agent's prompt (and `{{niadra_turn}}` where the live turns from other\n * channels go).\n * - `tool`: custom functions for the navigation kit. `toolConfigs()` writes them for Retell's\n * `general_tools`; the customer comes from the call, never from the model's arguments.\n * - `webhook`: the agent webhook. `call_started` keeps the caller of calls that had no inbound\n * webhook (outbound and web calls), `transfer_started` records a transfer to a person, and\n * `call_ended` records every utterance of `transcript_object` and ends the conversation.\n * - `llm(callId)`: for a custom LLM, one session per websocket (`/llm-websocket/:call_id`). It asks\n * for the call details, answers Retell's pings, records each utterance once a response is\n * required, and gives your model the messages with the context in place. The read sends the\n * caller's last utterance along, and each `update_only` event whose transcript ends with the\n * caller speaking sends that utterance so far with `prefetch()`, in the background: once its\n * words stop changing the SDK reads the turn with them, and the turn takes that read's slots; the\n * pack itself comes from memory at once. A prefetch never holds or fails a turn. Retell does not sign the\n * websocket, so the customer comes from a signed webhook of the same call (`inbound` or\n * `call_started`, kept in the store), never from the socket's `call_details`: anyone who reaches\n * the socket could name any caller there. Until a signed webhook registers the call, the model gets\n * no context and nothing is recorded. Set `trustCallDetails` only when the socket accepts Retell\n * alone (an IP allowlist, a secret in its URL).\n *\n * Every request is checked against `X-Retell-Signature` (HMAC-SHA256 of the raw body and its\n * timestamp, keyed with your Retell API key, within five minutes). Utterances carry the same\n * idempotency key on the websocket and in `call_ended`, so recording both ways stores them once.\n * Only web APIs: runs on Node, Deno, Bun, Cloudflare Workers and the Vercel Edge Runtime.\n *\n * @example\n * import { retell } from \"@niadra/sdk/retell\";\n *\n * const handlers = retell({ niadra, apiKey: process.env.RETELL_API_KEY! });\n * app.post(\"/retell/inbound\", async (c) => answer(c, await handlers.inbound(await c.req.text(), c.req.raw.headers)));\n * app.post(\"/retell/webhook\", async (c) => answer(c, await handlers.webhook(await c.req.text(), c.req.raw.headers)));\n * app.post(\"/retell/tools\", async (c) => answer(c, await handlers.tool(await c.req.text(), c.req.raw.headers)));\n *\n * // Custom LLM: one session per websocket Retell opens.\n * wss.on(\"connection\", (ws, request) => {\n * const session = handlers.llm(callIdFrom(request.url), { send: (event) => ws.send(JSON.stringify(event)), instructions: \"You are Acme's receptionist.\" });\n * session.open(\"Acme Energy, how can I help?\");\n * ws.on(\"message\", async (data) => {\n * const turn = await session.receive(JSON.parse(String(data)));\n * if (turn) turn.respond(await yourModel(turn.messages));\n * });\n * });\n */\n\nimport type { Niadra } from \"../client.js\";\nimport type { Conversation } from \"../conversation.js\";\nimport { AGENT_MEMORY_TOOL_DEFINITIONS, AGENT_MEMORY_TOOL_NAMES, TOOL_DEFINITIONS, TOOL_NAMES } from \"../tools.js\";\nimport type { Handle } from \"../types/common.js\";\nimport { Bridge, errorName, isRecord, phoneHandle } from \"./shared.js\";\nimport type { AgentMemoryOption, Proof } from \"./shared.js\";\nimport { bodyText, header, hex, hmac, memoryCallStore, parseJson, safeEqual } from \"./webhook.js\";\nimport type { CallRecord, CallStore, HeadersLike, WebhookResponse } from \"./webhook.js\";\n\nexport { attestationProof } from \"./shared.js\";\nexport type { AgentMemoryOption, Proof } from \"./shared.js\";\nexport { memoryCallStore } from \"./webhook.js\";\nexport type { CallRecord, CallStore, HeadersLike, WebhookResponse } from \"./webhook.js\";\n\n/** What the handlers read from a Retell call object (or from the inbound webhook). */\nexport interface RetellCall {\n /** Retell's `call_id`, used as the `conversation_id`. */\n id: string;\n fromNumber?: string | undefined;\n toNumber?: string | undefined;\n direction?: string | undefined;\n agentId?: string | undefined;\n /** The whole call object, for anything else you need (`metadata`, `retell_llm_dynamic_variables`). */\n call: Record<string, unknown>;\n}\n\nexport interface RetellOptions {\n niadra: Niadra;\n /** The Retell API key that signs the webhooks (the one marked for webhooks in the dashboard). Required. */\n apiKey: string;\n /** Who the customer is. Defaults to the caller of inbound calls and the callee of outbound ones, as E.164. */\n subject?: (call: RetellCall) => Handle | null | undefined;\n /** What the call proved, such as the carrier's attestation you read from your telephony provider. */\n verify?: (call: RetellCall) => Proof | null | undefined | PromiseLike<Proof | null | undefined>;\n /** Keeps the caller and level between the webhooks of one call. Defaults to an in-memory store. */\n store?: CallStore;\n /** More fields for the inbound answer, such as `override_agent_id` or more `dynamic_variables`. */\n inboundFields?: (call: RetellCall) => Record<string, unknown>;\n /** Runs custom functions that are not Niadra's, so one URL can serve all of them. */\n otherTool?: (name: string, args: Record<string, unknown>, call: RetellCall) => unknown;\n /** Time budget of each context read, in milliseconds. Defaults to the voice budget. */\n contextTimeout?: number;\n /** The clock for the signature's five-minute window, in milliseconds. */\n now?: () => number;\n /**\n * The agent's own notes as the dynamic variable `niadra_agent_memory` (put it before\n * `{{niadra_context}}`), before the pack in the custom LLM's messages, and its memory tools.\n */\n agentMemory?: AgentMemoryOption;\n /**\n * Lets the custom LLM websocket open the conversation from its own `call_details` when no signed\n * webhook registered the call. Retell does not sign the websocket: turn this on only when your\n * server accepts that socket from Retell alone. Defaults to `false`.\n */\n trustCallDetails?: boolean;\n}\n\n/** A chat message in the shape every chat completions API takes. */\nexport interface RetellMessage {\n role: \"system\" | \"user\" | \"assistant\";\n content: string;\n}\n\nexport interface RetellRespondOptions {\n /** `false` while streaming chunks; the last chunk (or an empty one) closes the response. Defaults to `true`. */\n complete?: boolean;\n /** Hangs up after this response. */\n endCall?: boolean;\n /** Transfers the call to this number after this response, recorded as a transfer to a person. */\n transferNumber?: string;\n}\n\n/** One response Retell is waiting for. */\nexport interface RetellTurn {\n responseId: number;\n interactionType: \"response_required\" | \"reminder_required\";\n /** Your instructions, the agent's notes and the pack, then the call so far, the suffix at the end of the last user message. */\n messages: RetellMessage[];\n /** The pack, or an empty string. */\n context: string;\n /** Live turns from other channels, the turn's slots and deltas, or an empty string. */\n suffix: string;\n /** Sends a response event to Retell for this turn. */\n respond(content: string, options?: RetellRespondOptions): void;\n}\n\nexport interface RetellLlmOptions {\n /** Sends one event to Retell over the websocket, such as `(event) => ws.send(JSON.stringify(event))`. */\n send: (event: Record<string, unknown>) => void;\n /** Your system prompt; the context goes right after it. */\n instructions?: string;\n}\n\n/** One custom LLM websocket. */\nexport interface RetellLlmSession {\n /** Sends the config (asking for the call details) and, when given, the agent's first words. */\n open(greeting?: string): void;\n /** Handles one event from Retell; resolves to a turn when Retell needs a response. Never rejects. */\n receive(event: unknown): Promise<RetellTurn | null>;\n /** Sends what is queued for Niadra. Call it when the websocket closes. */\n close(): Promise<void>;\n}\n\nexport interface RetellHandlers {\n /** The inbound call webhook, with the raw body: the signature covers the exact bytes. */\n inbound(rawBody: string | Uint8Array | ArrayBuffer, headers: HeadersLike): Promise<WebhookResponse>;\n /** The agent webhook (`call_started`, `call_ended`, `transfer_started`), with the raw body. */\n webhook(rawBody: string | Uint8Array | ArrayBuffer, headers: HeadersLike): Promise<WebhookResponse>;\n /** Custom function calls, with the raw body. */\n tool(rawBody: string | Uint8Array | ArrayBuffer, headers: HeadersLike): Promise<WebhookResponse>;\n /** A session for the custom LLM websocket of one call. */\n llm(callId: string, options: RetellLlmOptions): RetellLlmSession;\n /** The custom function configurations for Retell's `general_tools`, all pointing at your `tool` URL. */\n toolConfigs(options: { url: string; timeoutMs?: number }): Record<string, unknown>[];\n}\n\nconst OURS = new Set<string>([...Object.values(TOOL_NAMES), ...Object.values(AGENT_MEMORY_TOOL_NAMES)]);\nconst SIGNATURE_WINDOW_MS = 5 * 60 * 1000;\n\n/** The handlers for one Retell agent. */\nexport function retell(options: RetellOptions): RetellHandlers {\n const store = options.store ?? memoryCallStore();\n const now = options.now ?? Date.now;\n const logger = options.niadra.logger;\n const readOptions = options.contextTimeout ? { timeout: options.contextTimeout } : {};\n const transferred = new Set<string>();\n\n const subjectOf = (call: RetellCall): Handle | null => {\n try {\n if (options.subject) return options.subject(call) ?? null;\n return phoneHandle(call.direction === \"outbound\" ? call.toNumber : call.fromNumber);\n } catch {\n return null;\n }\n };\n\n const remember = async (id: string, record: CallRecord): Promise<void> => {\n try {\n await store.set(id, record);\n } catch (error) {\n logger.warn(`could not write the call store (${errorName(error)})`);\n }\n };\n\n /** The call's record from the store, or rebuilt from what this request carries (without verifying again). */\n const recall = async (call: RetellCall): Promise<CallRecord | null> => {\n try {\n const stored = await store.get(call.id);\n if (stored) return stored;\n } catch (error) {\n logger.warn(`could not read the call store (${errorName(error)})`);\n }\n const subject = subjectOf(call);\n return subject ? { subject, verification: \"V0\" } : null;\n };\n\n const open = (id: string, record: CallRecord): Conversation =>\n options.niadra.conversation({ subject: record.subject, channel: \"voice\", conversation_id: id, verification: record.verification });\n\n /** Opens the conversation for a call that has not been seen yet, verifying it once. */\n const start = (call: RetellCall): { bridge: Bridge; conversation: Conversation } | null => {\n const subject = subjectOf(call);\n if (!subject) return null;\n const conversation = options.niadra.conversation({ subject, channel: \"voice\", conversation_id: call.id });\n const bridge = new Bridge(conversation, options.verify ? () => options.verify?.(call) : undefined, options.agentMemory);\n bridge.begin(); // the call is starting: its first read runs meanwhile\n return { bridge, conversation };\n };\n\n const signed = async (text: string, headers: HeadersLike): Promise<boolean> =>\n validRetellSignature(text, header(headers, \"x-retell-signature\"), options.apiKey, now());\n\n async function inbound(rawBody: string | Uint8Array | ArrayBuffer, headers: HeadersLike): Promise<WebhookResponse> {\n const text = bodyText(rawBody);\n if (!(await signed(text, headers))) return { status: 401, body: { error: \"unauthorized\" } };\n const body = parseJson(text);\n const data = isRecord(body) && isRecord(body.call_inbound) ? body.call_inbound : null;\n if (!data) return { status: 400, body: { error: \"invalid_body\" } };\n const call = callOf({ ...data, direction: \"inbound\" });\n const variables: Record<string, string> = { niadra_context: \"\", niadra_turn: \"\" };\n if (options.agentMemory) variables.niadra_agent_memory = \"\";\n let extra: Record<string, unknown> = {};\n try {\n extra = call && options.inboundFields ? options.inboundFields(call) : {};\n } catch (error) {\n logger.warn(`could not build the inbound fields (${errorName(error)})`);\n }\n const answer = (): WebhookResponse => {\n const own = isRecord(extra.dynamic_variables) ? (extra.dynamic_variables as Record<string, unknown>) : {};\n return { status: 200, body: { call_inbound: { ...extra, dynamic_variables: { ...own, ...variables } } } };\n };\n const started = call ? start(call) : null;\n if (!call || !started) return answer();\n const read = await started.bridge.read(readOptions);\n started.bridge.injected(read.context);\n variables.niadra_context = read.context.text;\n variables.niadra_turn = read.suffix;\n if (options.agentMemory) variables.niadra_agent_memory = read.memory;\n await remember(call.id, { subject: started.conversation.subject, verification: started.conversation.verification, stamp: started.conversation.contextStamp });\n return answer();\n }\n\n async function webhook(rawBody: string | Uint8Array | ArrayBuffer, headers: HeadersLike): Promise<WebhookResponse> {\n const text = bodyText(rawBody);\n if (!(await signed(text, headers))) return { status: 401, body: { error: \"unauthorized\" } };\n const body = parseJson(text);\n const call = isRecord(body) ? callOf(body.call) : null;\n if (!isRecord(body) || typeof body.event !== \"string\" || !call) return { status: 400, body: { error: \"invalid_body\" } };\n switch (body.event) {\n case \"call_started\":\n return callStarted(call);\n case \"transfer_started\":\n await transfer(call);\n return { status: 200, body: {} };\n case \"call_ended\":\n return callEnded(call);\n default:\n return { status: 200, body: { ignored: true } };\n }\n }\n\n async function callStarted(call: RetellCall): Promise<WebhookResponse> {\n try {\n if (await store.get(call.id)) return { status: 200, body: {} };\n } catch (error) {\n logger.warn(`could not read the call store (${errorName(error)})`);\n }\n const started = start(call);\n if (started) {\n // Verifies through the context read's path, once, so later reads carry the level.\n await started.bridge.context(readOptions);\n await remember(call.id, { subject: started.conversation.subject, verification: started.conversation.verification, stamp: started.conversation.contextStamp });\n }\n return { status: 200, body: {} };\n }\n\n async function transfer(call: RetellCall): Promise<void> {\n if (transferred.has(call.id)) return;\n transferred.add(call.id);\n if (transferred.size > 10_000) transferred.clear();\n const record = await recall(call);\n if (record) await new Bridge(open(call.id, record)).handoff(\"human\", \"transfer\");\n }\n\n async function callEnded(call: RetellCall): Promise<WebhookResponse> {\n const record = await recall(call);\n if (!record) return { status: 200, body: { recorded: 0 } };\n const bridge = new Bridge(open(call.id, record));\n const started = typeof call.call.start_timestamp === \"number\" ? call.call.start_timestamp : null;\n const utterances = Array.isArray(call.call.transcript_object) ? (call.call.transcript_object as unknown[]) : [];\n let recorded = 0;\n for (const [index, utterance] of utterances.entries()) {\n if (recordUtterance(bridge, call.id, index, utterance, started, record)) recorded++;\n }\n if (call.call.disconnection_reason === \"call_transfer\") await transfer(call);\n await bridge.end();\n await options.niadra.flush();\n return { status: 200, body: { recorded } };\n }\n\n async function tool(rawBody: string | Uint8Array | ArrayBuffer, headers: HeadersLike): Promise<WebhookResponse> {\n const text = bodyText(rawBody);\n if (!(await signed(text, headers))) return { status: 401, body: { error: \"unauthorized\" } };\n const body = parseJson(text);\n const call = isRecord(body) ? callOf(body.call) : null;\n const name = isRecord(body) && typeof body.name === \"string\" ? body.name : \"\";\n if (!isRecord(body) || !call || !name) return { status: 400, body: { error: \"invalid_body\" } };\n const args: Record<string, unknown> = {};\n if (isRecord(body.args)) Object.assign(args, body.args);\n else for (const [key, value] of Object.entries(body)) if (key !== \"name\" && key !== \"call\") args[key] = value;\n\n if (!OURS.has(name)) {\n if (!options.otherTool) return { status: 200, body: { error: `unknown tool: ${name}` } };\n try {\n return { status: 200, body: (await options.otherTool(name, args, call)) ?? null };\n } catch (error) {\n logger.warn(`a tool outside Niadra failed (${errorName(error)})`);\n return { status: 200, body: { error: \"tool failed\" } };\n }\n }\n const record = await recall(call);\n const spec = record ? new Bridge(open(call.id, record), undefined, options.agentMemory).tools().find((candidate) => candidate.name === name) : undefined;\n if (!spec) return { status: 200, body: { error: \"unavailable\", detail: \"customer history is unavailable right now\" } };\n return { status: 200, body: parseJson(await spec.execute(args)) ?? null };\n }\n\n function llm(callId: string, config: RetellLlmOptions): RetellLlmSession {\n let bridge: Bridge | null = null;\n let record: CallRecord | null = null;\n let recorded = 0;\n const send = (event: Record<string, unknown>): void => {\n try {\n config.send(event);\n } catch (error) {\n logger.warn(`could not send to Retell (${errorName(error)})`);\n }\n };\n\n const ensure = async (call: RetellCall | null): Promise<Bridge | null> => {\n if (bridge) return bridge;\n let stored: CallRecord | undefined;\n try {\n stored = await store.get(callId);\n } catch (error) {\n logger.warn(`could not read the call store (${errorName(error)})`);\n }\n if (stored) {\n record = stored;\n bridge = new Bridge(open(callId, stored), undefined, options.agentMemory);\n bridge.begin(); // the socket opens as the call starts: its first read runs meanwhile\n return bridge;\n }\n // The socket is not signed: its call details never name the customer unless the server said so.\n const started = call && options.trustCallDetails ? start(call) : null;\n if (!started) return null;\n bridge = started.bridge;\n await bridge.context(readOptions);\n record = { subject: started.conversation.subject, verification: started.conversation.verification, stamp: started.conversation.contextStamp };\n await remember(callId, record);\n return bridge;\n };\n\n async function receive(event: unknown): Promise<RetellTurn | null> {\n try {\n if (!isRecord(event) || typeof event.interaction_type !== \"string\") return null;\n switch (event.interaction_type) {\n case \"ping_pong\":\n send({ response_type: \"ping_pong\", timestamp: event.timestamp });\n return null;\n case \"call_details\":\n await ensure(callOf(event.call));\n return null;\n case \"update_only\":\n await prefetchFor(event);\n return null;\n case \"response_required\":\n case \"reminder_required\":\n return await turnFor(event, event.interaction_type);\n default:\n return null;\n }\n } catch (error) {\n logger.warn(`could not handle a Retell event (${errorName(error)})`);\n return null;\n }\n }\n\n /** While the caller speaks, the transcript ends with their utterance so far: prefetch it. */\n async function prefetchFor(event: Record<PropertyKey, unknown>): Promise<void> {\n const transcript = Array.isArray(event.transcript) ? (event.transcript as unknown[]) : [];\n const last = transcript[transcript.length - 1];\n if (!isRecord(last) || last.role !== \"user\" || typeof last.content !== \"string\") return;\n const current = await ensure(null);\n current?.prefetch(last.content);\n }\n\n async function turnFor(event: Record<PropertyKey, unknown>, interactionType: RetellTurn[\"interactionType\"]): Promise<RetellTurn> {\n const responseId = typeof event.response_id === \"number\" ? event.response_id : 0;\n const transcript = Array.isArray(event.transcript) ? (event.transcript as unknown[]) : [];\n const current = await ensure(null);\n let prefix = \"\";\n let suffix = \"\";\n let context = \"\";\n if (current) {\n for (let index = recorded; index < transcript.length; index++) {\n recordUtterance(current, callId, index, transcript[index], null, record);\n }\n recorded = Math.max(recorded, transcript.length);\n const read = await current.read(readOptions);\n current.injected(read.context);\n ({ prefix, suffix } = read);\n context = read.context.text;\n }\n const messages: RetellMessage[] = [];\n if (config.instructions) messages.push({ role: \"system\", content: config.instructions });\n if (prefix) messages.push({ role: \"system\", content: prefix });\n for (const utterance of transcript) {\n if (!isRecord(utterance) || typeof utterance.content !== \"string\") continue;\n if (utterance.role === \"user\") messages.push({ role: \"user\", content: utterance.content });\n else if (utterance.role === \"agent\") messages.push({ role: \"assistant\", content: utterance.content });\n }\n if (suffix) {\n const last = messages.map((message) => message.role).lastIndexOf(\"user\");\n const message = messages[last];\n if (message) messages[last] = { role: \"user\", content: `${message.content}\\n\\n${suffix}` };\n else messages.push({ role: \"user\", content: suffix });\n }\n return {\n responseId,\n interactionType,\n messages,\n context,\n suffix,\n respond(content, respondOptions = {}) {\n const response: Record<string, unknown> = {\n response_type: \"response\",\n response_id: responseId,\n content,\n content_complete: respondOptions.complete ?? true,\n };\n if (respondOptions.endCall) response.end_call = true;\n if (respondOptions.transferNumber) {\n response.transfer_number = respondOptions.transferNumber;\n void transferOnce();\n }\n send(response);\n },\n };\n }\n\n async function transferOnce(): Promise<void> {\n if (transferred.has(callId)) return;\n transferred.add(callId);\n await bridge?.handoff(\"human\", \"transfer\");\n }\n\n return {\n open(greeting) {\n send({ response_type: \"config\", config: { auto_reconnect: true, call_details: true } });\n if (greeting) send({ response_type: \"response\", response_id: 0, content: greeting, content_complete: true });\n },\n receive,\n async close() {\n try {\n await options.niadra.flush();\n } catch (error) {\n logger.warn(`could not flush (${errorName(error)})`);\n }\n },\n };\n }\n\n function toolConfigs(config: { url: string; timeoutMs?: number }): Record<string, unknown>[] {\n const memory = options.agentMemory;\n const definitions = [\n ...TOOL_DEFINITIONS,\n ...(memory ? AGENT_MEMORY_TOOL_DEFINITIONS.slice(0, memory !== true && memory.write ? 2 : 1) : []),\n ];\n return definitions.map(({ function: definition }) => ({\n type: \"custom\",\n name: definition.name,\n description: definition.description,\n url: config.url,\n method: \"POST\",\n parameters: definition.parameters,\n speak_during_execution: false,\n speak_after_execution: true,\n timeout_ms: config.timeoutMs ?? 10_000,\n }));\n }\n\n return { inbound, webhook, tool, llm, toolConfigs };\n}\n\n/** Checks `X-Retell-Signature: v=<milliseconds>,d=<hex HMAC-SHA256 of body + milliseconds>` within five minutes. */\nexport async function validRetellSignature(body: string, signature: string | undefined, apiKey: string, now = Date.now()): Promise<boolean> {\n if (!signature || !apiKey) return false;\n const match = /^v=(\\d+),d=([0-9a-f]{64})$/i.exec(signature.trim());\n if (!match) return false;\n const [, stamp = \"\", digest = \"\"] = match;\n if (Math.abs(now - Number(stamp)) > SIGNATURE_WINDOW_MS) return false;\n return safeEqual(digest.toLowerCase(), hex(await hmac(\"SHA-256\", apiKey, body + stamp)));\n}\n\n/** Records one utterance with the key both the websocket and `call_ended` use. Returns whether it was recorded. */\nfunction recordUtterance(bridge: Bridge, callId: string, index: number, utterance: unknown, started: number | null, record: CallRecord | null): boolean {\n if (!isRecord(utterance) || typeof utterance.content !== \"string\" || !utterance.content.trim()) return false;\n const words = Array.isArray(utterance.words) ? (utterance.words as unknown[]) : [];\n const first = isRecord(words[0]) && typeof words[0].start === \"number\" ? words[0].start : null;\n const at = started !== null && first !== null ? new Date(started + first * 1000) : undefined;\n const base = { idempotency_key: `retell:${callId}:${String(index)}`, ...(at ? { occurred_at: at } : {}) };\n if (utterance.role === \"user\") {\n bridge.customer(utterance.content, base);\n return true;\n }\n if (utterance.role === \"agent\") {\n bridge.agent(utterance.content, record?.stamp ? { ...base, context_stamp: record.stamp } : base);\n return true;\n }\n return false;\n}\n\nfunction callOf(value: unknown): RetellCall | null {\n if (!isRecord(value) || typeof value.call_id !== \"string\" || !value.call_id) return null;\n const text = (key: string): string | undefined => {\n const field = value[key];\n return typeof field === \"string\" && field ? field : undefined;\n };\n return {\n id: value.call_id,\n fromNumber: text(\"from_number\"),\n toNumber: text(\"to_number\"),\n direction: text(\"direction\"),\n agentId: text(\"agent_id\"),\n call: value,\n };\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { n as AgentMemoryParams, gr as VerifyMethod, gn as Verification, g as Handle, bs as Conversation, fo as Task } from './client-B_ip8T2o.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* What every framework adapter shares: the five primitives (context before the model call, the
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { n as AgentMemoryParams, gr as VerifyMethod, gn as Verification, g as Handle, bs as Conversation, fo as Task } from './client-B_ip8T2o.cjs';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* What every framework adapter shares: the five primitives (context before the model call, the
|