@niadra/sdk 0.1.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 +28 -0
- package/LICENSE +201 -0
- package/README.md +361 -0
- package/dist/index.cjs +2389 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +1441 -0
- package/dist/index.d.ts +1441 -0
- package/dist/index.js +2355 -0
- package/dist/index.js.map +1 -0
- package/package.json +74 -0
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,1441 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The contract vocabulary. Every value here travels through the public API unchanged and
|
|
3
|
+
* never changes meaning within `/v1`, so the SDK mirrors it as string literal unions.
|
|
4
|
+
*/
|
|
5
|
+
/** What an event records: something said, something a system reported, or something an agent did. */
|
|
6
|
+
type EventKind = "message" | "system_event" | "action";
|
|
7
|
+
/** Who produced a turn. */
|
|
8
|
+
type Speaker = "customer" | "ai_agent" | "human_agent" | "system";
|
|
9
|
+
/** `internal` events (notes between agents, system traces) never reach a customer-facing view. */
|
|
10
|
+
type Visibility = "public" | "internal";
|
|
11
|
+
/** Subjects are people by default; accounts and partners are organizations. */
|
|
12
|
+
type SubjectKind = "person" | "account" | "partner";
|
|
13
|
+
/**
|
|
14
|
+
* How a handle identifies a subject. Scoped types (`wa_bsuid`, `system_id`, `gov_id_hmac`,
|
|
15
|
+
* `org_registry_hmac`) need `scope` so the same value in two namespaces never collides.
|
|
16
|
+
*/
|
|
17
|
+
type HandleType = "phone_e164" | "wa_id" | "wa_jid" | "wa_lid" | "wa_bsuid" | "email" | "gov_id_hmac" | "app_user_id" | "system_id" | "org_registry_hmac" | "email_domain" | "anon_id";
|
|
18
|
+
/** How an `identify` call learned that several handles belong together. */
|
|
19
|
+
type AssertionMethod = "explicit_identify" | "otp" | "login" | "system_import" | "same_event" | "co_occurrence" | "channel_rotation" | "accepted_suggestion" | "external_resolver" | "declared";
|
|
20
|
+
/**
|
|
21
|
+
* Session verification level. `V0` is an unverified contact and `V4` the strongest proof;
|
|
22
|
+
* `no_customer` marks internal work with no customer on the other side.
|
|
23
|
+
*/
|
|
24
|
+
type Verification = "V0" | "V1" | "V2" | "V3" | "V4" | "no_customer";
|
|
25
|
+
/** How a customer proved who they are in a `verify` call. */
|
|
26
|
+
type VerifyMethod = "otp_whatsapp" | "otp_sms" | "login" | "kba" | "network_attestation" | "human_agent";
|
|
27
|
+
/**
|
|
28
|
+
* Which read tier answered a `context()` call. `holdout` means the conversation fell in the
|
|
29
|
+
* control group: the pack is intentionally empty and the SDK treats it as a normal answer.
|
|
30
|
+
*/
|
|
31
|
+
type DeliveryPath = "t0" | "t1" | "t2" | "t3" | "t4" | "holdout" | "not_modified";
|
|
32
|
+
/** Kinds of history items the navigation calls can filter on. */
|
|
33
|
+
type HistoryItemKind = "episode" | "fact" | "open_item" | "action" | "system_event" | "object" | "trait";
|
|
34
|
+
/**
|
|
35
|
+
* The shape of the pack. Channel views (`voice`, `chat`) size it for the medium; `account`
|
|
36
|
+
* and `partner` read an organization; `task:<name>` views serve internal agents.
|
|
37
|
+
*/
|
|
38
|
+
type View = "voice" | "chat" | "brief" | "full" | "custom" | "account" | "partner" | `task:${string}`;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* An identifier of a subject in some channel or system: a phone number, an e-mail address,
|
|
42
|
+
* a CRM id. Handles carry personal data, so the SDK only ever sends them in request bodies.
|
|
43
|
+
*/
|
|
44
|
+
interface Handle {
|
|
45
|
+
type: HandleType;
|
|
46
|
+
/** Up to 320 characters. Phones are E.164 (`+5511987654321`). */
|
|
47
|
+
value: string;
|
|
48
|
+
/**
|
|
49
|
+
* Namespace for scoped identifiers: the WhatsApp Business account for `wa_bsuid`, the
|
|
50
|
+
* system for `system_id`, the country for `gov_id_hmac`.
|
|
51
|
+
*/
|
|
52
|
+
scope?: string | null;
|
|
53
|
+
/** Defaults to `person` on the server, except for organization-only handle types. */
|
|
54
|
+
subject_kind?: SubjectKind | null;
|
|
55
|
+
}
|
|
56
|
+
/** A business object in a system of record, such as `invoice` / `erp` / `0823`. */
|
|
57
|
+
interface ObjectRef {
|
|
58
|
+
type: string;
|
|
59
|
+
namespace: string;
|
|
60
|
+
id: string;
|
|
61
|
+
}
|
|
62
|
+
/** A participant of an event other than the speaker, for example the account a person acts for. */
|
|
63
|
+
interface Subject {
|
|
64
|
+
kind: SubjectKind;
|
|
65
|
+
role?: string | null;
|
|
66
|
+
/** Between 1 and 16 handles. */
|
|
67
|
+
handles: Handle[];
|
|
68
|
+
}
|
|
69
|
+
/** Whether a source is still sending. `silent` means it stopped, so the pack may be missing recent turns. */
|
|
70
|
+
interface SourceCoverage {
|
|
71
|
+
source_id: string;
|
|
72
|
+
status: "ok" | "silent" | (string & {});
|
|
73
|
+
last_event_at?: string | null;
|
|
74
|
+
}
|
|
75
|
+
/** RFC 9457 problem details, as returned with `application/problem+json`. */
|
|
76
|
+
interface Problem {
|
|
77
|
+
type: string;
|
|
78
|
+
title: string;
|
|
79
|
+
status: number;
|
|
80
|
+
detail?: string | null;
|
|
81
|
+
/** Stable code from the versioned error catalog, such as `rate_limited` or `wrong_cell`. */
|
|
82
|
+
code: string;
|
|
83
|
+
request_id?: string | null;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Base class of every error the SDK produces. In the default fail-open mode these errors are
|
|
88
|
+
* logged and returned in results rather than thrown; with `strict: true` they are thrown.
|
|
89
|
+
*/
|
|
90
|
+
declare class NiadraError extends Error {
|
|
91
|
+
readonly name: string;
|
|
92
|
+
}
|
|
93
|
+
/** The client was built without a usable API key, or with an option the SDK cannot honour. */
|
|
94
|
+
declare class NiadraConfigError extends NiadraError {
|
|
95
|
+
readonly name = "NiadraConfigError";
|
|
96
|
+
}
|
|
97
|
+
/** A request failed validation before it left the process. Nothing was sent. */
|
|
98
|
+
declare class NiadraValidationError extends NiadraError {
|
|
99
|
+
readonly name = "NiadraValidationError";
|
|
100
|
+
}
|
|
101
|
+
/** The request did not finish within its time budget. */
|
|
102
|
+
declare class NiadraTimeoutError extends NiadraError {
|
|
103
|
+
readonly timeoutMs: number;
|
|
104
|
+
readonly name = "NiadraTimeoutError";
|
|
105
|
+
constructor(timeoutMs: number);
|
|
106
|
+
}
|
|
107
|
+
/** The network call failed before an HTTP response arrived (DNS, TLS, reset connection). */
|
|
108
|
+
declare class NiadraConnectionError extends NiadraError {
|
|
109
|
+
readonly name = "NiadraConnectionError";
|
|
110
|
+
}
|
|
111
|
+
/** The request was cancelled through the caller's `AbortSignal`. */
|
|
112
|
+
declare class NiadraAbortError extends NiadraError {
|
|
113
|
+
readonly name = "NiadraAbortError";
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* The API answered with an error status. `code` comes from the problem document when the
|
|
117
|
+
* server sent one; `requestId` is what Niadra support needs to find the call.
|
|
118
|
+
*/
|
|
119
|
+
declare class NiadraAPIError extends NiadraError {
|
|
120
|
+
readonly name: string;
|
|
121
|
+
readonly status: number;
|
|
122
|
+
readonly code: string;
|
|
123
|
+
readonly requestId: string | null;
|
|
124
|
+
readonly problem: Problem | null;
|
|
125
|
+
/** How long the server asked callers to wait, from `Retry-After`, when it said so. */
|
|
126
|
+
readonly retryAfterMs: number | null;
|
|
127
|
+
constructor(status: number, problem: Problem | null, requestId: string | null, retryAfterMs?: number | null);
|
|
128
|
+
}
|
|
129
|
+
/** 401: the key is missing, malformed, rotated or revoked. */
|
|
130
|
+
declare class NiadraAuthenticationError extends NiadraAPIError {
|
|
131
|
+
readonly name = "NiadraAuthenticationError";
|
|
132
|
+
}
|
|
133
|
+
/** 403: the key is valid but lacks the scope, or its source was cut off. */
|
|
134
|
+
declare class NiadraPermissionError extends NiadraAPIError {
|
|
135
|
+
readonly name = "NiadraPermissionError";
|
|
136
|
+
}
|
|
137
|
+
/** 429: over the rate limit. Batches wait `retryAfterMs` before trying again. */
|
|
138
|
+
declare class NiadraRateLimitError extends NiadraAPIError {
|
|
139
|
+
readonly name = "NiadraRateLimitError";
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/** The read side: `POST /v1/context` and the history navigation calls. */
|
|
143
|
+
|
|
144
|
+
/** The model that will read the pack, so the server can aim at its prompt-cache floor. */
|
|
145
|
+
interface TargetModel {
|
|
146
|
+
provider: string;
|
|
147
|
+
model: string;
|
|
148
|
+
}
|
|
149
|
+
/** Body of `POST /v1/context`. Exactly one of `subject` or `object` is required. */
|
|
150
|
+
interface ContextRequest {
|
|
151
|
+
subject?: Handle | null;
|
|
152
|
+
object?: ObjectRef | null;
|
|
153
|
+
/** The account or partner the person acts for. */
|
|
154
|
+
about?: Handle | null;
|
|
155
|
+
view?: View;
|
|
156
|
+
verification?: Verification;
|
|
157
|
+
conversation_id?: string | null;
|
|
158
|
+
task_id?: string | null;
|
|
159
|
+
query?: string | null;
|
|
160
|
+
delta?: boolean;
|
|
161
|
+
target?: TargetModel | null;
|
|
162
|
+
known_etag?: string | null;
|
|
163
|
+
}
|
|
164
|
+
interface VerificationResult {
|
|
165
|
+
requested: Verification;
|
|
166
|
+
effective: Verification;
|
|
167
|
+
/** Why `effective` is lower than `requested`: `source_ceiling` or `not_proven`. */
|
|
168
|
+
reason?: string | null;
|
|
169
|
+
}
|
|
170
|
+
/** A recent turn from another channel that the compiled pack has not absorbed yet. */
|
|
171
|
+
interface LiveTurn {
|
|
172
|
+
at: string;
|
|
173
|
+
channel: string;
|
|
174
|
+
kind: EventKind;
|
|
175
|
+
speaker: string;
|
|
176
|
+
text: string;
|
|
177
|
+
source_id: string;
|
|
178
|
+
}
|
|
179
|
+
/** Where a prompt-cache breakpoint may go, and whether caching this pack is worth it. */
|
|
180
|
+
interface CacheDirectives {
|
|
181
|
+
/** Character offsets into `text` where a cache breakpoint may be placed. */
|
|
182
|
+
breakpoints: number[];
|
|
183
|
+
ttl_seconds?: number | null;
|
|
184
|
+
floor_tokens?: number | null;
|
|
185
|
+
cacheable: boolean;
|
|
186
|
+
/** Stable cache salt for self-hosted inference engines. */
|
|
187
|
+
salt: string;
|
|
188
|
+
}
|
|
189
|
+
/** Body of a `POST /v1/context` response. */
|
|
190
|
+
interface ContextResponse {
|
|
191
|
+
/** `true` when `known_etag` still matches; `text` is then omitted. */
|
|
192
|
+
not_modified: boolean;
|
|
193
|
+
text?: string | null;
|
|
194
|
+
variables: Record<string, string>;
|
|
195
|
+
version: string;
|
|
196
|
+
etag: string;
|
|
197
|
+
manifest_hash?: string | null;
|
|
198
|
+
as_of?: string | null;
|
|
199
|
+
lag_seconds?: number | null;
|
|
200
|
+
coverage: SourceCoverage[];
|
|
201
|
+
verification: VerificationResult;
|
|
202
|
+
/** How many items policy or verification kept out of the pack. */
|
|
203
|
+
withheld: number;
|
|
204
|
+
live: LiveTurn[];
|
|
205
|
+
live_complete: boolean;
|
|
206
|
+
delta?: string | null;
|
|
207
|
+
cache?: CacheDirectives | null;
|
|
208
|
+
timing: Record<string, number>;
|
|
209
|
+
path: DeliveryPath;
|
|
210
|
+
degraded: boolean;
|
|
211
|
+
}
|
|
212
|
+
interface HistoryFilters {
|
|
213
|
+
since?: string | null;
|
|
214
|
+
until?: string | null;
|
|
215
|
+
channels?: string[];
|
|
216
|
+
categories?: string[];
|
|
217
|
+
item_kinds?: HistoryItemKind[];
|
|
218
|
+
outcome?: string | null;
|
|
219
|
+
object?: ObjectRef | null;
|
|
220
|
+
}
|
|
221
|
+
/** Body of `POST /v1/history/search`. */
|
|
222
|
+
interface SearchRequest {
|
|
223
|
+
subject: Handle;
|
|
224
|
+
about?: Handle | null;
|
|
225
|
+
/** Between 1 and 2,000 characters. */
|
|
226
|
+
query: string;
|
|
227
|
+
filters?: HistoryFilters;
|
|
228
|
+
/** Token budget for the answer, between 50 and 4,000. Defaults to 800. */
|
|
229
|
+
max_tokens?: number;
|
|
230
|
+
verification?: Verification;
|
|
231
|
+
conversation_id?: string | null;
|
|
232
|
+
task_id?: string | null;
|
|
233
|
+
}
|
|
234
|
+
interface HistoryItem {
|
|
235
|
+
id: string;
|
|
236
|
+
kind: string;
|
|
237
|
+
text: string;
|
|
238
|
+
at: string;
|
|
239
|
+
channel?: string | null;
|
|
240
|
+
source_id?: string | null;
|
|
241
|
+
outcome?: string | null;
|
|
242
|
+
confidence?: number | null;
|
|
243
|
+
origin_event_id?: string | null;
|
|
244
|
+
}
|
|
245
|
+
/** How often the same kind of issue came back, computed by the same rule as the recurring-complaint pattern. */
|
|
246
|
+
interface Recurrence {
|
|
247
|
+
category: string;
|
|
248
|
+
occurrences: number;
|
|
249
|
+
window_days: number;
|
|
250
|
+
last_at?: string | null;
|
|
251
|
+
last_outcome?: string | null;
|
|
252
|
+
last_resolution?: string | null;
|
|
253
|
+
}
|
|
254
|
+
interface SearchResponse {
|
|
255
|
+
items: HistoryItem[];
|
|
256
|
+
recurrence?: Recurrence | null;
|
|
257
|
+
withheld: number;
|
|
258
|
+
as_of?: string | null;
|
|
259
|
+
tokens_used: number;
|
|
260
|
+
/** `text_only` when semantic search was unavailable and only keyword matching ran. */
|
|
261
|
+
degraded?: string | null;
|
|
262
|
+
}
|
|
263
|
+
/** Body of `POST /v1/history/timeline`. */
|
|
264
|
+
interface TimelineRequest {
|
|
265
|
+
subject: Handle;
|
|
266
|
+
about?: Handle | null;
|
|
267
|
+
filters?: HistoryFilters;
|
|
268
|
+
cursor?: string | null;
|
|
269
|
+
/** Between 1 and 100. Defaults to 20. */
|
|
270
|
+
limit?: number;
|
|
271
|
+
verification?: Verification;
|
|
272
|
+
conversation_id?: string | null;
|
|
273
|
+
}
|
|
274
|
+
interface TimelineResponse {
|
|
275
|
+
items: HistoryItem[];
|
|
276
|
+
next_cursor?: string | null;
|
|
277
|
+
withheld: number;
|
|
278
|
+
as_of?: string | null;
|
|
279
|
+
}
|
|
280
|
+
/** A commitment recorded in an episode, made by the company or by the customer. */
|
|
281
|
+
interface Commitment {
|
|
282
|
+
by: "company" | "customer";
|
|
283
|
+
what: string;
|
|
284
|
+
due_at?: string | null;
|
|
285
|
+
status: string;
|
|
286
|
+
}
|
|
287
|
+
/** One history item opened in full: structured summary, outcome and commitments. */
|
|
288
|
+
interface OpenedItem {
|
|
289
|
+
id: string;
|
|
290
|
+
kind: "episode" | "object";
|
|
291
|
+
summary: string;
|
|
292
|
+
requested?: string | null;
|
|
293
|
+
promises: Commitment[];
|
|
294
|
+
outcome?: string | null;
|
|
295
|
+
resolution?: string | null;
|
|
296
|
+
derived: HistoryItem[];
|
|
297
|
+
timeline: HistoryItem[];
|
|
298
|
+
/** Literal transcript excerpt. Only returned to keys with an elevated scope. */
|
|
299
|
+
excerpt?: string | null;
|
|
300
|
+
as_of?: string | null;
|
|
301
|
+
}
|
|
302
|
+
/** The derived state of a business object, from `GET /v1/objects/{type}/{namespace}/{id}`. */
|
|
303
|
+
interface ObjectState {
|
|
304
|
+
ref: ObjectRef;
|
|
305
|
+
state: Record<string, unknown>;
|
|
306
|
+
as_of: string;
|
|
307
|
+
source_id: string;
|
|
308
|
+
record_ref?: string | null;
|
|
309
|
+
open_items: HistoryItem[];
|
|
310
|
+
}
|
|
311
|
+
/** System events and agent actions about one object, newest first; never conversation content. */
|
|
312
|
+
interface ObjectTimeline {
|
|
313
|
+
ref: ObjectRef;
|
|
314
|
+
items: HistoryItem[];
|
|
315
|
+
next_cursor?: string | null;
|
|
316
|
+
as_of?: string | null;
|
|
317
|
+
}
|
|
318
|
+
/** A function-calling tool definition in the JSON Schema shape most model APIs accept. */
|
|
319
|
+
interface ToolDefinition {
|
|
320
|
+
type: "function";
|
|
321
|
+
function: {
|
|
322
|
+
name: string;
|
|
323
|
+
description: string;
|
|
324
|
+
parameters: Record<string, unknown>;
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/** Arguments of `context()`. Pass exactly one of `subject` or `object`. */
|
|
329
|
+
interface ContextParams {
|
|
330
|
+
/** The customer, by any handle the server knows. */
|
|
331
|
+
subject?: Handle;
|
|
332
|
+
/** A business object, such as an invoice, when the task is about the object rather than a person. */
|
|
333
|
+
object?: ObjectRef | string;
|
|
334
|
+
/** The account or partner the person acts for. Requires an active link between the two. */
|
|
335
|
+
about?: Handle;
|
|
336
|
+
/** Defaults to `chat`. */
|
|
337
|
+
view?: View;
|
|
338
|
+
/**
|
|
339
|
+
* The level proven in this conversation. The server may answer with a lower effective level
|
|
340
|
+
* when the source's ceiling is lower; see `response.verification`.
|
|
341
|
+
*/
|
|
342
|
+
verification?: Verification;
|
|
343
|
+
/** Enables the per-conversation cache and the server's pinning of the pack. */
|
|
344
|
+
conversation_id?: string;
|
|
345
|
+
/** For internal agents: the task plays the role of the conversation. */
|
|
346
|
+
task_id?: string;
|
|
347
|
+
/** What the turn is about, so selection can favour relevant history. Up to 2,000 characters. */
|
|
348
|
+
query?: string;
|
|
349
|
+
/** Ask only for what changed since this source last read the subject. */
|
|
350
|
+
delta?: boolean;
|
|
351
|
+
/** The model that will read the pack, so the server can size it for that model's prompt cache. */
|
|
352
|
+
target?: TargetModel;
|
|
353
|
+
}
|
|
354
|
+
/** Per-call options shared by every read method. */
|
|
355
|
+
interface RequestOptions {
|
|
356
|
+
/** Overrides the method's default time budget, in milliseconds. */
|
|
357
|
+
timeout?: number | undefined;
|
|
358
|
+
/** Cancels the wait. A request shared with other callers keeps running for them. */
|
|
359
|
+
signal?: AbortSignal | undefined;
|
|
360
|
+
/** Extra headers, such as a W3C `traceparent`. */
|
|
361
|
+
headers?: Record<string, string> | undefined;
|
|
362
|
+
}
|
|
363
|
+
interface ContextOptions extends RequestOptions {
|
|
364
|
+
/** Pass `false` to skip the per-conversation cache for this call. */
|
|
365
|
+
cache?: boolean | undefined;
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* Where a `context()` result came from.
|
|
369
|
+
*
|
|
370
|
+
* - `network`: a response the server just sent (or confirmed unchanged).
|
|
371
|
+
* - `cache`: a pack younger than the cache TTL; no request was made.
|
|
372
|
+
* - `stale`: an older pack returned at once while a background request refreshes it.
|
|
373
|
+
* - `fallback`: the request failed and this is the last good pack for the conversation.
|
|
374
|
+
* - `none`: nothing was available; `text` is empty and `error` says why.
|
|
375
|
+
*/
|
|
376
|
+
type ContextSource = "network" | "cache" | "stale" | "fallback" | "none";
|
|
377
|
+
/** What `context()` resolves to. Always usable: on failure `text` is an empty string. */
|
|
378
|
+
interface ContextResult {
|
|
379
|
+
/** The pack, ready for the system prompt. Empty when there is nothing to inject. */
|
|
380
|
+
text: string;
|
|
381
|
+
/**
|
|
382
|
+
* The parts that change turn by turn and belong at the end of the prompt, after the
|
|
383
|
+
* conversation: the delta and the live turns from other channels. Empty when there are none.
|
|
384
|
+
*/
|
|
385
|
+
suffix: string;
|
|
386
|
+
/** Named values from the pack, for templates that place them individually. */
|
|
387
|
+
variables: Record<string, string>;
|
|
388
|
+
source: ContextSource;
|
|
389
|
+
/** The response this result was built from; `null` when `source` is `none`. */
|
|
390
|
+
response: ContextResponse | null;
|
|
391
|
+
/** What went wrong, when `source` is `fallback` or `none`. */
|
|
392
|
+
error: NiadraError | null;
|
|
393
|
+
}
|
|
394
|
+
/**
|
|
395
|
+
* Renders the delta and the live turns for the end of the prompt. Kept outside the pinned
|
|
396
|
+
* pack so that the prompt prefix stays byte-identical across turns and the model provider's
|
|
397
|
+
* prompt cache keeps hitting. Returns an empty string when there is nothing to add.
|
|
398
|
+
*/
|
|
399
|
+
declare function renderSuffix(response: ContextResponse): string;
|
|
400
|
+
/**
|
|
401
|
+
* Renders the live turns (recent turns from other channels that the pack has not absorbed
|
|
402
|
+
* yet) as one tagged block, or an empty string when there are none. `complete="false"` tells
|
|
403
|
+
* the model the list may be missing turns because the server could not read all of them.
|
|
404
|
+
*/
|
|
405
|
+
declare function renderLive(response: ContextResponse): string;
|
|
406
|
+
|
|
407
|
+
/**
|
|
408
|
+
* The write side: items of `POST /v1/batch`. A batch mixes item types, and one bad item never
|
|
409
|
+
* fails the batch; the server answers 207 with one error per rejected item.
|
|
410
|
+
*/
|
|
411
|
+
|
|
412
|
+
/** Longest text the server accepts in `content.text` or `content.transcript`. */
|
|
413
|
+
declare const MAX_EVENT_TEXT = 200000;
|
|
414
|
+
/** Largest batch the server accepts. */
|
|
415
|
+
declare const MAX_BATCH_ITEMS = 500;
|
|
416
|
+
/** Largest file `POST /v1/media/uploads` reserves room for: 500 MiB. */
|
|
417
|
+
declare const MAX_MEDIA_BYTES: number;
|
|
418
|
+
interface SpeakerRef {
|
|
419
|
+
role: Speaker;
|
|
420
|
+
/** Agent or attendant id inside the source. */
|
|
421
|
+
id?: string | null;
|
|
422
|
+
}
|
|
423
|
+
interface Content {
|
|
424
|
+
type?: "text" | "audio" | "image" | "file";
|
|
425
|
+
text?: string | null;
|
|
426
|
+
/** Reference returned by `/v1/media/uploads`; the media itself never travels in the event. */
|
|
427
|
+
media_ref?: string | null;
|
|
428
|
+
/** Lowercase hex SHA-256 of the media. */
|
|
429
|
+
media_sha256?: string | null;
|
|
430
|
+
transcript?: string | null;
|
|
431
|
+
/** Speech-to-text confidence between 0 and 1. Low-confidence agent turns are not measured. */
|
|
432
|
+
stt_confidence?: number | null;
|
|
433
|
+
}
|
|
434
|
+
interface VoiceInfo {
|
|
435
|
+
ani?: string | null;
|
|
436
|
+
dnis?: string | null;
|
|
437
|
+
trunk?: string | null;
|
|
438
|
+
network_attestation?: "A" | "B" | "C" | null;
|
|
439
|
+
answered_at?: string | null;
|
|
440
|
+
ended_at?: string | null;
|
|
441
|
+
end_reason?: string | null;
|
|
442
|
+
recording_ref?: string | null;
|
|
443
|
+
turn_offset_ms?: number | null;
|
|
444
|
+
}
|
|
445
|
+
/**
|
|
446
|
+
* The open item an action fulfils. Pass either `item_id`, or `object` together with the
|
|
447
|
+
* canonical `operation`; the server rejects any other combination.
|
|
448
|
+
*/
|
|
449
|
+
interface Closes {
|
|
450
|
+
item_id?: string | null;
|
|
451
|
+
object?: ObjectRef | null;
|
|
452
|
+
operation?: string | null;
|
|
453
|
+
}
|
|
454
|
+
interface ActionInfo {
|
|
455
|
+
/** Canonical operation, such as `credit` or `reschedule`. */
|
|
456
|
+
operation: string;
|
|
457
|
+
/** What happened, up to 2,000 characters. */
|
|
458
|
+
result?: string | null;
|
|
459
|
+
purpose?: string | null;
|
|
460
|
+
closes?: Closes | null;
|
|
461
|
+
corrects_action_id?: string | null;
|
|
462
|
+
}
|
|
463
|
+
/**
|
|
464
|
+
* Which context the agent's prompt carried and when it went in. Set on the agent's own turns
|
|
465
|
+
* and actions, so measurement can tell a context that arrived after the agent spoke from one
|
|
466
|
+
* it had and did not use.
|
|
467
|
+
*/
|
|
468
|
+
interface ContextStamp {
|
|
469
|
+
/** The etag of the pack in the prompt; absent when the prompt carried no pack. */
|
|
470
|
+
etag?: string | null;
|
|
471
|
+
injected_at: string;
|
|
472
|
+
}
|
|
473
|
+
/** A message, a system event or an agent action, exactly as sent on the wire. */
|
|
474
|
+
interface EventItem {
|
|
475
|
+
type: "event";
|
|
476
|
+
kind: EventKind;
|
|
477
|
+
idempotency_key: string;
|
|
478
|
+
channel: string;
|
|
479
|
+
conversation_id?: string | null;
|
|
480
|
+
conversation_aliases?: string[];
|
|
481
|
+
task_id?: string | null;
|
|
482
|
+
handles?: Handle[];
|
|
483
|
+
subjects?: Subject[];
|
|
484
|
+
object_refs?: ObjectRef[];
|
|
485
|
+
speaker: SpeakerRef;
|
|
486
|
+
direction?: "inbound" | "outbound" | null;
|
|
487
|
+
content?: Content | null;
|
|
488
|
+
occurred_at: string;
|
|
489
|
+
visibility?: Visibility;
|
|
490
|
+
verification_hint?: Verification | null;
|
|
491
|
+
/** System events only, such as `invoice.credited`. */
|
|
492
|
+
canonical_type?: string | null;
|
|
493
|
+
/** Structured fields of a system event. */
|
|
494
|
+
fields?: Record<string, unknown>;
|
|
495
|
+
action?: ActionInfo | null;
|
|
496
|
+
corrects_event_id?: string | null;
|
|
497
|
+
voice?: VoiceInfo | null;
|
|
498
|
+
context_stamp?: ContextStamp | null;
|
|
499
|
+
}
|
|
500
|
+
/** States that several handles belong to the same subject. */
|
|
501
|
+
interface IdentifyItem {
|
|
502
|
+
type: "identify";
|
|
503
|
+
idempotency_key: string;
|
|
504
|
+
/** Between 2 and 16 handles. */
|
|
505
|
+
handles: Handle[];
|
|
506
|
+
method: AssertionMethod;
|
|
507
|
+
subject_kind: SubjectKind;
|
|
508
|
+
conversation_id?: string | null;
|
|
509
|
+
occurred_at: string;
|
|
510
|
+
}
|
|
511
|
+
/** Raises the verification level of one conversation or task. The server never infers it. */
|
|
512
|
+
interface VerifyItem {
|
|
513
|
+
type: "verify";
|
|
514
|
+
idempotency_key: string;
|
|
515
|
+
method: VerifyMethod;
|
|
516
|
+
level: Verification;
|
|
517
|
+
conversation_id?: string | null;
|
|
518
|
+
task_id?: string | null;
|
|
519
|
+
handle: Handle;
|
|
520
|
+
valid_until?: string | null;
|
|
521
|
+
occurred_at: string;
|
|
522
|
+
}
|
|
523
|
+
interface ConversationEndedItem {
|
|
524
|
+
type: "conversation.ended";
|
|
525
|
+
idempotency_key: string;
|
|
526
|
+
conversation_id: string;
|
|
527
|
+
occurred_at: string;
|
|
528
|
+
}
|
|
529
|
+
interface TaskEndedItem {
|
|
530
|
+
type: "task.ended";
|
|
531
|
+
idempotency_key: string;
|
|
532
|
+
task_id: string;
|
|
533
|
+
occurred_at: string;
|
|
534
|
+
}
|
|
535
|
+
/** A transfer to a human or another agent. */
|
|
536
|
+
interface HandoffItem {
|
|
537
|
+
type: "handoff";
|
|
538
|
+
idempotency_key: string;
|
|
539
|
+
conversation_id: string;
|
|
540
|
+
target: "human" | "agent";
|
|
541
|
+
target_source?: string | null;
|
|
542
|
+
reason?: string | null;
|
|
543
|
+
mode: "warm" | "cold";
|
|
544
|
+
occurred_at: string;
|
|
545
|
+
}
|
|
546
|
+
/** Periodic counter the SDK sends so the server can tell a quiet source from a broken one. */
|
|
547
|
+
interface HeartbeatItem {
|
|
548
|
+
type: "heartbeat";
|
|
549
|
+
window_start: string;
|
|
550
|
+
sent: number;
|
|
551
|
+
}
|
|
552
|
+
type BatchItem = EventItem | IdentifyItem | VerifyItem | ConversationEndedItem | TaskEndedItem | HandoffItem | HeartbeatItem;
|
|
553
|
+
interface BatchRequest {
|
|
554
|
+
items: BatchItem[];
|
|
555
|
+
}
|
|
556
|
+
interface ItemError {
|
|
557
|
+
/** Position of the rejected item in the batch that was sent. */
|
|
558
|
+
index: number;
|
|
559
|
+
code: string;
|
|
560
|
+
detail?: string | null;
|
|
561
|
+
}
|
|
562
|
+
interface BatchResponse {
|
|
563
|
+
accepted: number;
|
|
564
|
+
duplicates: number;
|
|
565
|
+
errors: ItemError[];
|
|
566
|
+
}
|
|
567
|
+
/** Body of `POST /v1/media/uploads`. */
|
|
568
|
+
interface MediaUploadRequest {
|
|
569
|
+
content_type: string;
|
|
570
|
+
/** Between 1 byte and 500 MiB. */
|
|
571
|
+
size_bytes: number;
|
|
572
|
+
/** Lowercase hex SHA-256 of the bytes. */
|
|
573
|
+
sha256: string;
|
|
574
|
+
/** Whose media it is. Stored under that person, so erasing them erases it too. */
|
|
575
|
+
subject?: Handle | null;
|
|
576
|
+
}
|
|
577
|
+
/** Where to send the bytes: a short-lived signed URL, and the reference events carry afterwards. */
|
|
578
|
+
interface MediaUploadResponse {
|
|
579
|
+
media_ref: string;
|
|
580
|
+
upload_url: string;
|
|
581
|
+
/** Send exactly these headers with the bytes; the store refuses anything else. */
|
|
582
|
+
upload_headers?: Record<string, string>;
|
|
583
|
+
expires_at: string;
|
|
584
|
+
}
|
|
585
|
+
type FeedbackAction = "retract_fact" | "correct_fact" | "resolve_open_item" | "conversation_outcome";
|
|
586
|
+
/** Body of `POST /v1/feedback`. The server records it as a `feedback.<action>` system event. */
|
|
587
|
+
interface FeedbackRequest {
|
|
588
|
+
idempotency_key: string;
|
|
589
|
+
subject: Handle;
|
|
590
|
+
action: FeedbackAction;
|
|
591
|
+
fact_id?: string | null;
|
|
592
|
+
open_item_id?: string | null;
|
|
593
|
+
conversation_id?: string | null;
|
|
594
|
+
/** Up to 2,000 characters. */
|
|
595
|
+
value?: string | null;
|
|
596
|
+
/** Up to 500 characters. */
|
|
597
|
+
reason?: string | null;
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
/**
|
|
601
|
+
* Turns what callers pass to `track()`, `identify()` and friends into batch items, applying the
|
|
602
|
+
* same shape rules the server enforces. Catching a malformed event here means it is dropped
|
|
603
|
+
* with a log line instead of occupying the queue and coming back as a 207 error.
|
|
604
|
+
*/
|
|
605
|
+
|
|
606
|
+
/** An ISO 8601 string or a `Date`. */
|
|
607
|
+
type Timestamp = string | Date;
|
|
608
|
+
/** Fields shared by everything `track()` records. */
|
|
609
|
+
interface EventBase {
|
|
610
|
+
/** Where it happened, such as `whatsapp`, `voice`, `app` or `erp`. */
|
|
611
|
+
channel: string;
|
|
612
|
+
/** Provider message id, when there is one; otherwise the SDK mints a UUIDv7. */
|
|
613
|
+
idempotency_key?: string;
|
|
614
|
+
conversation_id?: string | null;
|
|
615
|
+
/** Other ids the same conversation has in other systems. Up to 8. */
|
|
616
|
+
conversation_aliases?: string[];
|
|
617
|
+
task_id?: string | null;
|
|
618
|
+
/** Up to 16. An event needs at least one handle, subject or object. */
|
|
619
|
+
handles?: Handle[];
|
|
620
|
+
/** Up to 8. */
|
|
621
|
+
subjects?: Subject[];
|
|
622
|
+
/** Up to 16. Accepts `type:namespace:id` strings. */
|
|
623
|
+
object_refs?: (ObjectRef | string)[];
|
|
624
|
+
/** Defaults to now. */
|
|
625
|
+
occurred_at?: Timestamp;
|
|
626
|
+
visibility?: Visibility;
|
|
627
|
+
verification_hint?: Verification | null;
|
|
628
|
+
corrects_event_id?: string | null;
|
|
629
|
+
voice?: VoiceInfo | null;
|
|
630
|
+
/**
|
|
631
|
+
* Which context the agent acted on, for the agent's own turns and actions. Conversations and
|
|
632
|
+
* tasks set it from `markInjected()`.
|
|
633
|
+
*/
|
|
634
|
+
context_stamp?: ContextStamp | null;
|
|
635
|
+
}
|
|
636
|
+
/** An event for `track()`. `kind` defaults to `message`. */
|
|
637
|
+
interface TrackEvent extends EventBase {
|
|
638
|
+
kind?: EventKind;
|
|
639
|
+
/** Who produced it. A bare role is shorthand for `{ role }`. */
|
|
640
|
+
speaker: SpeakerRef | Speaker;
|
|
641
|
+
/** Defaults to `inbound` for customer messages and `outbound` for agent messages. */
|
|
642
|
+
direction?: "inbound" | "outbound" | null;
|
|
643
|
+
content?: Content | null;
|
|
644
|
+
/** Shorthand for `content: { type: "text", text }`. Cannot be combined with `content`. */
|
|
645
|
+
text?: string;
|
|
646
|
+
/** Required for `system_event`, such as `invoice.credited`. */
|
|
647
|
+
canonical_type?: string | null;
|
|
648
|
+
fields?: Record<string, unknown>;
|
|
649
|
+
/** Required for `action`, and only valid there. */
|
|
650
|
+
action?: ActionInfo | null;
|
|
651
|
+
}
|
|
652
|
+
/** An agent action for `action()`: what an agent did in a system of record. */
|
|
653
|
+
interface ActionEvent extends EventBase {
|
|
654
|
+
/** Canonical operation, such as `credit` or `reschedule`. */
|
|
655
|
+
operation: string;
|
|
656
|
+
/** What happened, up to 2,000 characters. */
|
|
657
|
+
result?: string | null;
|
|
658
|
+
purpose?: string | null;
|
|
659
|
+
/** The open item this action fulfils, which the server then marks resolved. */
|
|
660
|
+
closes?: Closes | null;
|
|
661
|
+
corrects_action_id?: string | null;
|
|
662
|
+
/** Defaults to `ai_agent`. */
|
|
663
|
+
speaker?: SpeakerRef | Speaker;
|
|
664
|
+
}
|
|
665
|
+
interface IdentifyParams {
|
|
666
|
+
/** Between 2 and 16 handles that belong to the same subject. */
|
|
667
|
+
handles: Handle[];
|
|
668
|
+
/** Defaults to `explicit_identify`. */
|
|
669
|
+
method?: AssertionMethod;
|
|
670
|
+
/** Defaults to `person`. */
|
|
671
|
+
subject_kind?: SubjectKind;
|
|
672
|
+
conversation_id?: string | null;
|
|
673
|
+
occurred_at?: Timestamp;
|
|
674
|
+
idempotency_key?: string;
|
|
675
|
+
}
|
|
676
|
+
interface VerifyParams {
|
|
677
|
+
/** The handle whose possession was proven. */
|
|
678
|
+
handle: Handle;
|
|
679
|
+
method: VerifyMethod;
|
|
680
|
+
/** The level reached. It applies to this conversation or task only. */
|
|
681
|
+
level: Verification;
|
|
682
|
+
conversation_id?: string | null;
|
|
683
|
+
task_id?: string | null;
|
|
684
|
+
/** When the proof stops counting. */
|
|
685
|
+
valid_until?: Timestamp | null;
|
|
686
|
+
occurred_at?: Timestamp;
|
|
687
|
+
idempotency_key?: string;
|
|
688
|
+
}
|
|
689
|
+
interface HandoffParams {
|
|
690
|
+
conversation_id: string;
|
|
691
|
+
target: "human" | "agent";
|
|
692
|
+
/** The source that takes over, when it is integrated with Niadra. */
|
|
693
|
+
target_source?: string | null;
|
|
694
|
+
reason?: string | null;
|
|
695
|
+
/** `warm` when the receiver gets a briefing. Defaults to `warm`. */
|
|
696
|
+
mode?: "warm" | "cold";
|
|
697
|
+
occurred_at?: Timestamp;
|
|
698
|
+
idempotency_key?: string;
|
|
699
|
+
}
|
|
700
|
+
/** Arguments of `feedback()`: a correction of what Niadra derived about a subject. */
|
|
701
|
+
interface FeedbackParams {
|
|
702
|
+
subject: Handle;
|
|
703
|
+
/**
|
|
704
|
+
* `retract_fact` or `correct_fact` (with `fact_id`, and `value` for the right one),
|
|
705
|
+
* `resolve_open_item` (with `open_item_id`) or `conversation_outcome` (with `conversation_id`
|
|
706
|
+
* and `value`).
|
|
707
|
+
*/
|
|
708
|
+
action: FeedbackAction;
|
|
709
|
+
fact_id?: string | null;
|
|
710
|
+
open_item_id?: string | null;
|
|
711
|
+
conversation_id?: string | null;
|
|
712
|
+
/** Up to 2,000 characters. */
|
|
713
|
+
value?: string | null;
|
|
714
|
+
/** Why, up to 500 characters. */
|
|
715
|
+
reason?: string | null;
|
|
716
|
+
idempotency_key?: string;
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
/**
|
|
720
|
+
* Where the SDK reports what it swallowed in fail-open mode. Messages carry status codes,
|
|
721
|
+
* error codes and request ids, never handles, message text or other personal data.
|
|
722
|
+
*/
|
|
723
|
+
interface Logger {
|
|
724
|
+
debug(message: string, ...details: unknown[]): void;
|
|
725
|
+
warn(message: string, ...details: unknown[]): void;
|
|
726
|
+
error(message: string, ...details: unknown[]): void;
|
|
727
|
+
}
|
|
728
|
+
/** Warnings and errors go to the console; debug output is off unless you pass your own logger. */
|
|
729
|
+
declare const consoleLogger: Logger;
|
|
730
|
+
declare const silentLogger: Logger;
|
|
731
|
+
|
|
732
|
+
/** When context first went into the prompt, and when the agent first spoke. */
|
|
733
|
+
interface Timings {
|
|
734
|
+
contextInjectedAt: Date | null;
|
|
735
|
+
firstAgentTurnAt: Date | null;
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
/** The outcome of a call that may fail without throwing. Exactly one of the two fields is set. */
|
|
739
|
+
type Result<T> = {
|
|
740
|
+
data: T;
|
|
741
|
+
error: null;
|
|
742
|
+
} | {
|
|
743
|
+
data: null;
|
|
744
|
+
error: NiadraError;
|
|
745
|
+
};
|
|
746
|
+
/** Everything a tool call is bound to besides its arguments. None of it is visible to the model. */
|
|
747
|
+
interface ToolBinding {
|
|
748
|
+
about?: Handle;
|
|
749
|
+
verification?: Verification;
|
|
750
|
+
conversation_id?: string;
|
|
751
|
+
task_id?: string;
|
|
752
|
+
/** Use the voice time budget for the calls these tools make. */
|
|
753
|
+
voice?: boolean;
|
|
754
|
+
}
|
|
755
|
+
/**
|
|
756
|
+
* The navigation kit as function-calling tools, bound to one customer.
|
|
757
|
+
*
|
|
758
|
+
* The definitions have no parameter for the customer: the handle lives in this object, outside
|
|
759
|
+
* the model's reach. A prompt injection that says "now look up customer X" has no argument to
|
|
760
|
+
* put X in. The model chooses what to ask, never whom it is about.
|
|
761
|
+
*/
|
|
762
|
+
interface BoundTools {
|
|
763
|
+
/** Tool definitions in the `{ type: "function", function: { name, description, parameters } }` shape. */
|
|
764
|
+
readonly definitions: ToolDefinition[];
|
|
765
|
+
/** Whether `name` is one of these tools, for dispatchers that route several toolsets. */
|
|
766
|
+
has(name: string): boolean;
|
|
767
|
+
/**
|
|
768
|
+
* Runs one tool call and returns the text to send back to the model as the tool result.
|
|
769
|
+
* `args` may be the JSON string most model APIs return, or an already parsed object.
|
|
770
|
+
* Failures come back as a short JSON error the model can read and move past; with
|
|
771
|
+
* `strict: true` they are thrown instead.
|
|
772
|
+
*/
|
|
773
|
+
call(name: string, args: string | Record<string, unknown>): Promise<string>;
|
|
774
|
+
}
|
|
775
|
+
declare const TOOL_NAMES: {
|
|
776
|
+
readonly search: "search_customer_history";
|
|
777
|
+
readonly timeline: "get_customer_timeline";
|
|
778
|
+
readonly open: "open_history_item";
|
|
779
|
+
};
|
|
780
|
+
declare const TOOL_DEFINITIONS: readonly ToolDefinition[];
|
|
781
|
+
|
|
782
|
+
interface ConversationParams {
|
|
783
|
+
/** The customer on the other side. */
|
|
784
|
+
subject: Handle;
|
|
785
|
+
/** Where the conversation happens, such as `whatsapp` or `voice`. */
|
|
786
|
+
channel: string;
|
|
787
|
+
/** Your id for the thread. A UUIDv7 is minted when omitted. */
|
|
788
|
+
conversation_id?: string;
|
|
789
|
+
/** Defaults to `voice` when the channel is `voice`, otherwise `chat`. */
|
|
790
|
+
view?: View;
|
|
791
|
+
/** The level already proven when the conversation starts. Defaults to `V0`. */
|
|
792
|
+
verification?: Verification;
|
|
793
|
+
/** The account or partner the customer acts for. */
|
|
794
|
+
about?: Handle;
|
|
795
|
+
target?: TargetModel;
|
|
796
|
+
}
|
|
797
|
+
/** Optional details of one captured turn. */
|
|
798
|
+
interface TurnOptions {
|
|
799
|
+
/** The provider's message id, which makes retries of the same turn harmless. */
|
|
800
|
+
idempotency_key?: string;
|
|
801
|
+
occurred_at?: Timestamp;
|
|
802
|
+
/** The agent or attendant id inside your system. */
|
|
803
|
+
speaker_id?: string;
|
|
804
|
+
visibility?: Visibility;
|
|
805
|
+
/** Marks the text as a speech-to-text transcript with this confidence, between 0 and 1. */
|
|
806
|
+
stt_confidence?: number;
|
|
807
|
+
voice?: VoiceInfo;
|
|
808
|
+
/** Overrides the stamp an agent turn would carry from `markInjected()`. */
|
|
809
|
+
context_stamp?: ContextStamp;
|
|
810
|
+
}
|
|
811
|
+
type ConversationEvent = Omit<TrackEvent, "channel" | "conversation_id"> & {
|
|
812
|
+
channel?: string;
|
|
813
|
+
};
|
|
814
|
+
type ConversationAction = Omit<ActionEvent, "channel" | "conversation_id"> & {
|
|
815
|
+
channel?: string;
|
|
816
|
+
};
|
|
817
|
+
interface ConversationHooks {
|
|
818
|
+
endConversation(id: string): Promise<WriteResult>;
|
|
819
|
+
}
|
|
820
|
+
/**
|
|
821
|
+
* One customer conversation.
|
|
822
|
+
*
|
|
823
|
+
* The server pins the pack to the conversation: every turn gets the same bytes, so the prompt
|
|
824
|
+
* prefix stays byte-identical and the model provider's prompt cache keeps hitting. After the
|
|
825
|
+
* first pack, each read also asks for the delta, what changed since this agent last looked
|
|
826
|
+
* (a new open item, an action another agent took). The server sends each delta once, so the
|
|
827
|
+
* conversation keeps them, in order, in `suffix`, with the live turns, for the end of the
|
|
828
|
+
* prompt. A successful `verify()` starts over from the pack the server pins for the new level.
|
|
829
|
+
*
|
|
830
|
+
* Call `markInjected()` when the pack goes into the prompt; the agent's later turns and actions
|
|
831
|
+
* carry that moment and the pack's etag as `context_stamp`. `wrap()` does it for you.
|
|
832
|
+
*
|
|
833
|
+
* @example
|
|
834
|
+
* const convo = niadra.conversation({ subject: handles.waId("5511987654321"), channel: "whatsapp" });
|
|
835
|
+
* convo.customer(inbound.text, { idempotency_key: inbound.id });
|
|
836
|
+
* const ctx = await convo.context();
|
|
837
|
+
* convo.markInjected(ctx);
|
|
838
|
+
* const reply = await llm(ctx.text, history, ctx.suffix);
|
|
839
|
+
* convo.agent(reply);
|
|
840
|
+
*/
|
|
841
|
+
declare class Conversation {
|
|
842
|
+
private readonly client;
|
|
843
|
+
private readonly params;
|
|
844
|
+
private readonly hooks;
|
|
845
|
+
readonly id: string;
|
|
846
|
+
readonly channel: string;
|
|
847
|
+
readonly subject: Handle;
|
|
848
|
+
private level;
|
|
849
|
+
private readonly view;
|
|
850
|
+
private readonly state;
|
|
851
|
+
private ending;
|
|
852
|
+
constructor(client: Niadra, params: ConversationParams, hooks: ConversationHooks);
|
|
853
|
+
/** The level in force for this conversation, raised by a successful `verify()`. */
|
|
854
|
+
get verification(): Verification;
|
|
855
|
+
/**
|
|
856
|
+
* When context first went into the prompt, and when the agent first spoke. Context injected
|
|
857
|
+
* after the agent's first turn is the "late context" signal the usage measurement reports.
|
|
858
|
+
*/
|
|
859
|
+
get timings(): Timings;
|
|
860
|
+
/** What the agent's next turn and action carry: the last `markInjected()`, or `null`. */
|
|
861
|
+
get contextStamp(): ContextStamp | null;
|
|
862
|
+
/** The last result `context()` returned for this conversation. */
|
|
863
|
+
get lastContext(): ContextResult | null;
|
|
864
|
+
/** Where `wrap()` reports what it swallowed: the client's logger. */
|
|
865
|
+
get logger(): Logger;
|
|
866
|
+
/**
|
|
867
|
+
* The pack for this turn: the pinned `text`, and a `suffix` with every delta since the pin
|
|
868
|
+
* and the current live turns. A read with `query` is compiled for that query and never
|
|
869
|
+
* pinned, so it leaves the conversation's deltas alone.
|
|
870
|
+
*/
|
|
871
|
+
context(options?: ContextOptions & {
|
|
872
|
+
query?: string;
|
|
873
|
+
}): Promise<ContextResult>;
|
|
874
|
+
/**
|
|
875
|
+
* Records that `context` (by default the last one this conversation returned) went into the
|
|
876
|
+
* prompt. Call it each time you build the prompt; `timings.contextInjectedAt` keeps the first.
|
|
877
|
+
*/
|
|
878
|
+
markInjected(context?: ContextResult | null, at?: Date): void;
|
|
879
|
+
/** Captures what the customer said. */
|
|
880
|
+
customer(text: string, options?: TurnOptions): string | null;
|
|
881
|
+
/** Captures what the AI agent said, stamped with the context its prompt carried. */
|
|
882
|
+
agent(text: string, options?: TurnOptions): string | null;
|
|
883
|
+
/** Captures what a human attendant said, for example after a handoff. */
|
|
884
|
+
human(text: string, options?: TurnOptions): string | null;
|
|
885
|
+
/** Records any event in this conversation. The customer's handle is attached unless you pass your own. */
|
|
886
|
+
track(event: ConversationEvent): string | null;
|
|
887
|
+
/** Records an action the agent took during this conversation, stamped like its turns. */
|
|
888
|
+
action(event: ConversationAction): string | null;
|
|
889
|
+
/**
|
|
890
|
+
* Records that the customer proved who they are, and raises the level for later reads.
|
|
891
|
+
* `handle` defaults to the conversation's subject.
|
|
892
|
+
*/
|
|
893
|
+
verify(params: {
|
|
894
|
+
method: VerifyMethod;
|
|
895
|
+
level: Verification;
|
|
896
|
+
handle?: Handle;
|
|
897
|
+
}): Promise<WriteResult>;
|
|
898
|
+
/** Records a transfer to a human or another agent. */
|
|
899
|
+
handoff(params: {
|
|
900
|
+
target: "human" | "agent";
|
|
901
|
+
target_source?: string;
|
|
902
|
+
reason?: string;
|
|
903
|
+
mode?: "warm" | "cold";
|
|
904
|
+
}): Promise<WriteResult>;
|
|
905
|
+
/**
|
|
906
|
+
* The navigation kit bound to this customer and conversation. The verification level is
|
|
907
|
+
* read at each call, so tools created before a `verify()` pick up the new level.
|
|
908
|
+
*/
|
|
909
|
+
tools(): BoundTools;
|
|
910
|
+
/** Emits `conversation.ended` and drops the conversation's cached packs. Safe to call twice. */
|
|
911
|
+
end(): Promise<WriteResult>;
|
|
912
|
+
private bind;
|
|
913
|
+
private turn;
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
/** Arguments of `uploadMedia()`. */
|
|
917
|
+
interface UploadParams {
|
|
918
|
+
/** The file itself. It is read into memory once, to hash it and send it. */
|
|
919
|
+
data: Uint8Array | ArrayBuffer | Blob;
|
|
920
|
+
/** Such as `audio/wav` or `image/png`. Storage checks it against the signed URL. */
|
|
921
|
+
content_type: string;
|
|
922
|
+
/**
|
|
923
|
+
* Whose file it is, whenever you know. It is then stored under that person, so erasing them
|
|
924
|
+
* erases it, even if no event ever references it.
|
|
925
|
+
*/
|
|
926
|
+
subject?: Handle;
|
|
927
|
+
}
|
|
928
|
+
/** A file handed to Niadra. Put `media_ref` and `media_sha256` in the event's `content`. */
|
|
929
|
+
interface MediaUpload {
|
|
930
|
+
media_ref: string;
|
|
931
|
+
media_sha256: string;
|
|
932
|
+
content_type: string;
|
|
933
|
+
size_bytes: number;
|
|
934
|
+
expires_at: string | null;
|
|
935
|
+
}
|
|
936
|
+
|
|
937
|
+
/** Paging of `objectTimeline()`. */
|
|
938
|
+
interface ObjectTimelineParams {
|
|
939
|
+
/** `next_cursor` from the previous page. */
|
|
940
|
+
cursor?: string;
|
|
941
|
+
/** Between 1 and 100. Defaults to 20. */
|
|
942
|
+
limit?: number;
|
|
943
|
+
}
|
|
944
|
+
|
|
945
|
+
/**
|
|
946
|
+
* Per-method time budgets in milliseconds. They are the SDK's own and deliberately short:
|
|
947
|
+
* managed agent platforms allow 7 to 10 seconds per turn and self-hosted frameworks allow no
|
|
948
|
+
* limit at all, so a slow memory call must never become a slow agent.
|
|
949
|
+
*/
|
|
950
|
+
interface Timeouts {
|
|
951
|
+
/** `context()` for every view except `voice`. */
|
|
952
|
+
context: number;
|
|
953
|
+
/** `context()` with `view: "voice"`, where the budget is a fraction of a spoken turn. */
|
|
954
|
+
contextVoice: number;
|
|
955
|
+
/** `search()`, `timeline()` and `open()`. */
|
|
956
|
+
navigation: number;
|
|
957
|
+
/** Navigation calls made through a voice conversation or voice-bound tools. */
|
|
958
|
+
navigationVoice: number;
|
|
959
|
+
/** Each attempt of a batch upload. Writes happen off the hot path, so this one is generous. */
|
|
960
|
+
write: number;
|
|
961
|
+
/** `subjectToken()`, usually called once when a session starts. */
|
|
962
|
+
token: number;
|
|
963
|
+
/** Each attempt of sending media bytes to storage in `uploadMedia()`, off the hot path. */
|
|
964
|
+
upload: number;
|
|
965
|
+
}
|
|
966
|
+
declare const DEFAULT_TIMEOUTS: Timeouts;
|
|
967
|
+
/** How `context()` reuses packs inside a conversation. */
|
|
968
|
+
interface CacheOptions {
|
|
969
|
+
/** A pack younger than this is returned without any request. */
|
|
970
|
+
ttlMs: number;
|
|
971
|
+
/**
|
|
972
|
+
* After `ttlMs`, the cached pack is still returned at once for this long while a single
|
|
973
|
+
* background request refreshes it.
|
|
974
|
+
*/
|
|
975
|
+
staleWhileRevalidateMs: number;
|
|
976
|
+
/**
|
|
977
|
+
* Oldest pack the SDK will fall back to when a request fails. Older packs are dropped
|
|
978
|
+
* rather than shown to a model as if they were current.
|
|
979
|
+
*/
|
|
980
|
+
maxStaleMs: number;
|
|
981
|
+
/** Least recently used packs are evicted past this many conversations. */
|
|
982
|
+
maxEntries: number;
|
|
983
|
+
}
|
|
984
|
+
declare const DEFAULT_CACHE: CacheOptions;
|
|
985
|
+
/** How `track()` and the other write methods batch events on their way to `POST /v1/batch`. */
|
|
986
|
+
interface QueueOptions {
|
|
987
|
+
/** Send as soon as this many items are waiting. */
|
|
988
|
+
flushAt: number;
|
|
989
|
+
/** Send whatever is waiting at least this often. */
|
|
990
|
+
flushIntervalMs: number;
|
|
991
|
+
/** Items per request. The server accepts up to 500. */
|
|
992
|
+
maxBatchSize: number;
|
|
993
|
+
/** Items held in memory before new ones are dropped. Keeps a long outage from exhausting memory. */
|
|
994
|
+
maxQueueSize: number;
|
|
995
|
+
/** Attempts per batch, including the first. 4xx answers other than 408, 421 and 429 are never retried. */
|
|
996
|
+
maxAttempts: number;
|
|
997
|
+
/** First backoff delay; each retry doubles it, with full jitter, up to `maxRetryDelayMs`. */
|
|
998
|
+
retryDelayMs: number;
|
|
999
|
+
maxRetryDelayMs: number;
|
|
1000
|
+
}
|
|
1001
|
+
declare const DEFAULT_QUEUE: QueueOptions;
|
|
1002
|
+
interface ClientOptions {
|
|
1003
|
+
/**
|
|
1004
|
+
* A source key, `nia_sk_<live|test>_<region>_<space>_<key_id>_<secret>`. Defaults to the
|
|
1005
|
+
* `NIADRA_API_KEY` environment variable where one exists. Without a key the client is a
|
|
1006
|
+
* no-op: every method resolves with an empty result and nothing is sent.
|
|
1007
|
+
*/
|
|
1008
|
+
apiKey?: string | undefined;
|
|
1009
|
+
/**
|
|
1010
|
+
* Overrides the address derived from the key, for the local emulator or a private endpoint.
|
|
1011
|
+
* Defaults to `NIADRA_BASE_URL`, then to `https://<space>.<region>.api.niadra.com`.
|
|
1012
|
+
*/
|
|
1013
|
+
baseURL?: string | undefined;
|
|
1014
|
+
timeouts?: Partial<Timeouts>;
|
|
1015
|
+
/** Pass `false` to send every `context()` call to the server. */
|
|
1016
|
+
cache?: Partial<CacheOptions> | false;
|
|
1017
|
+
queue?: Partial<QueueOptions>;
|
|
1018
|
+
/**
|
|
1019
|
+
* Throw errors instead of logging them and resolving with an empty result. Meant for tests
|
|
1020
|
+
* and development, where a silent failure hides a broken integration.
|
|
1021
|
+
*/
|
|
1022
|
+
strict?: boolean;
|
|
1023
|
+
/** Flush queued events when a Node process is about to exit. Defaults to `true`. */
|
|
1024
|
+
flushOnExit?: boolean;
|
|
1025
|
+
/** A `fetch` implementation. Defaults to the global one. */
|
|
1026
|
+
fetch?: typeof fetch;
|
|
1027
|
+
logger?: Logger;
|
|
1028
|
+
/** Extra headers sent with every request. */
|
|
1029
|
+
defaultHeaders?: Record<string, string>;
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1032
|
+
interface TaskParams {
|
|
1033
|
+
/** Your id for the task. A UUIDv7 is minted when omitted. */
|
|
1034
|
+
task_id?: string;
|
|
1035
|
+
/** The internal agent or system doing the work, such as `billing-agent`. */
|
|
1036
|
+
channel: string;
|
|
1037
|
+
/** The person the task is about. Pass this, `object`, or both. */
|
|
1038
|
+
subject?: Handle;
|
|
1039
|
+
/** The business object the task is about, as an `ObjectRef` or `type:namespace:id`. */
|
|
1040
|
+
object?: ObjectRef | string;
|
|
1041
|
+
about?: Handle;
|
|
1042
|
+
/** A task view such as `task:billing`. Defaults to `brief`. */
|
|
1043
|
+
view?: View;
|
|
1044
|
+
verification?: Verification;
|
|
1045
|
+
target?: TargetModel;
|
|
1046
|
+
}
|
|
1047
|
+
type TaskEvent = Omit<TrackEvent, "channel" | "task_id"> & {
|
|
1048
|
+
channel?: string;
|
|
1049
|
+
};
|
|
1050
|
+
type TaskAction = Omit<ActionEvent, "channel" | "task_id"> & {
|
|
1051
|
+
channel?: string;
|
|
1052
|
+
};
|
|
1053
|
+
interface TaskHooks {
|
|
1054
|
+
endTask(id: string): Promise<WriteResult>;
|
|
1055
|
+
/** `verify()` for a task, which may have no subject to default the handle to. */
|
|
1056
|
+
verifyTask(params: Omit<VerifyParams, "handle"> & {
|
|
1057
|
+
handle: Handle | undefined;
|
|
1058
|
+
}): Promise<WriteResult>;
|
|
1059
|
+
}
|
|
1060
|
+
/**
|
|
1061
|
+
* One unit of work by an internal agent: a collection run, a ticket triage, a refund. The task
|
|
1062
|
+
* plays the role a conversation plays for customer-facing agents: the server pins its pack,
|
|
1063
|
+
* deltas arrive and are kept the same way, it scopes the context cache, groups the events for
|
|
1064
|
+
* billing and closes with `task.ended`. Without `end()`, the server closes the task after 10
|
|
1065
|
+
* minutes of inactivity.
|
|
1066
|
+
*/
|
|
1067
|
+
declare class Task {
|
|
1068
|
+
private readonly client;
|
|
1069
|
+
private readonly params;
|
|
1070
|
+
private readonly hooks;
|
|
1071
|
+
readonly id: string;
|
|
1072
|
+
private readonly object;
|
|
1073
|
+
private level;
|
|
1074
|
+
private readonly state;
|
|
1075
|
+
private ending;
|
|
1076
|
+
constructor(client: Niadra, params: TaskParams, hooks: TaskHooks);
|
|
1077
|
+
/** When context first went into the prompt, and when the agent first acted. */
|
|
1078
|
+
get timings(): Timings;
|
|
1079
|
+
/** What the agent's next turn and action carry: the last `markInjected()`, or `null`. */
|
|
1080
|
+
get contextStamp(): ContextStamp | null;
|
|
1081
|
+
/** The last result `context()` returned for this task. */
|
|
1082
|
+
get lastContext(): ContextResult | null;
|
|
1083
|
+
/** Where `wrap()` reports what it swallowed: the client's logger. */
|
|
1084
|
+
get logger(): Logger;
|
|
1085
|
+
/**
|
|
1086
|
+
* Context for the task, centered on its object when it has one, otherwise on its subject.
|
|
1087
|
+
* Resolves with an empty result, never rejects, unless the client is strict.
|
|
1088
|
+
*/
|
|
1089
|
+
context(options?: ContextOptions & {
|
|
1090
|
+
query?: string;
|
|
1091
|
+
}): Promise<ContextResult>;
|
|
1092
|
+
/** Records that `context` (by default the last one this task returned) went into the prompt. */
|
|
1093
|
+
markInjected(context?: ContextResult | null, at?: Date): void;
|
|
1094
|
+
/** Captures what the agent answered, stamped with the context its prompt carried. */
|
|
1095
|
+
agent(text: string, options?: TurnOptions): string | null;
|
|
1096
|
+
/**
|
|
1097
|
+
* Records that the person the task is about proved who they are, and reads at the new level
|
|
1098
|
+
* from then on. `handle` defaults to the task's subject.
|
|
1099
|
+
*/
|
|
1100
|
+
verify(params: {
|
|
1101
|
+
method: VerifyMethod;
|
|
1102
|
+
level: Verification;
|
|
1103
|
+
handle?: Handle;
|
|
1104
|
+
}): Promise<WriteResult>;
|
|
1105
|
+
/** Records an event in this task, attaching the task's subject and object unless you pass your own. */
|
|
1106
|
+
track(event: TaskEvent): string | null;
|
|
1107
|
+
/** Records an action taken in a system of record, such as `credit` on an invoice, stamped like its turns. */
|
|
1108
|
+
action(event: TaskAction): string | null;
|
|
1109
|
+
/**
|
|
1110
|
+
* The navigation kit bound to the task's subject, or `null` for a task about an object only.
|
|
1111
|
+
* The verification level is read at each call, so tools created before a `verify()` pick up
|
|
1112
|
+
* the new level.
|
|
1113
|
+
*/
|
|
1114
|
+
tools(): BoundTools | null;
|
|
1115
|
+
/** Emits `task.ended` and drops the task's cached packs. Safe to call twice. */
|
|
1116
|
+
end(): Promise<WriteResult>;
|
|
1117
|
+
private bind;
|
|
1118
|
+
}
|
|
1119
|
+
|
|
1120
|
+
/**
|
|
1121
|
+
* Body of `POST /v1/subject-tokens`. The token binds one customer to a session so that an MCP
|
|
1122
|
+
* connection, or any client you hand it to, can read that customer and no other.
|
|
1123
|
+
*/
|
|
1124
|
+
interface SubjectTokenRequest {
|
|
1125
|
+
subject: Handle;
|
|
1126
|
+
about?: Handle | null;
|
|
1127
|
+
conversation_id?: string | null;
|
|
1128
|
+
task_id?: string | null;
|
|
1129
|
+
verification?: Verification;
|
|
1130
|
+
}
|
|
1131
|
+
/** A signed token valid for 15 minutes. Treat it as a credential: it reads this customer's memory. */
|
|
1132
|
+
interface SubjectToken {
|
|
1133
|
+
token: string;
|
|
1134
|
+
expires_at: string;
|
|
1135
|
+
}
|
|
1136
|
+
|
|
1137
|
+
/** What `identify()`, `verify()`, `handoff()` and the `end()` helpers resolve to. */
|
|
1138
|
+
type WriteResult = {
|
|
1139
|
+
ok: true;
|
|
1140
|
+
idempotency_key: string;
|
|
1141
|
+
error: null;
|
|
1142
|
+
} | {
|
|
1143
|
+
ok: false;
|
|
1144
|
+
idempotency_key: string | null;
|
|
1145
|
+
error: NiadraError;
|
|
1146
|
+
};
|
|
1147
|
+
/** Scope of `open()`: the same verification and conversation the rest of the session uses. */
|
|
1148
|
+
interface OpenParams {
|
|
1149
|
+
verification?: Verification;
|
|
1150
|
+
conversation_id?: string;
|
|
1151
|
+
task_id?: string;
|
|
1152
|
+
}
|
|
1153
|
+
/**
|
|
1154
|
+
* The Niadra client.
|
|
1155
|
+
*
|
|
1156
|
+
* Reads (`context`, `search`, `timeline`, `open`) run on the agent's hot path with short time
|
|
1157
|
+
* budgets of their own. Writes (`track` and friends) go through an in-memory queue and never
|
|
1158
|
+
* block the caller. By default every method is fail-open: an outage, a timeout or a bad
|
|
1159
|
+
* argument is logged and the method resolves with an empty result, so the agent keeps
|
|
1160
|
+
* working without memory rather than not working at all. Pass `strict: true` to throw instead.
|
|
1161
|
+
*
|
|
1162
|
+
* Create one client per process and share it; it holds the queue, the cache and the
|
|
1163
|
+
* connection pool.
|
|
1164
|
+
*
|
|
1165
|
+
* @example
|
|
1166
|
+
* const niadra = new Niadra({ apiKey: process.env.NIADRA_API_KEY });
|
|
1167
|
+
* const ctx = await niadra.context({ subject: handles.phone("+5511987654321"), conversation_id: "wa-8812" });
|
|
1168
|
+
*/
|
|
1169
|
+
declare class Niadra {
|
|
1170
|
+
/** `false` when the client was built without a usable key and sends nothing. */
|
|
1171
|
+
readonly enabled: boolean;
|
|
1172
|
+
private readonly core;
|
|
1173
|
+
private readonly timeouts;
|
|
1174
|
+
private readonly strict;
|
|
1175
|
+
/** Where the client reports what it swallows in fail-open mode. */
|
|
1176
|
+
readonly logger: Logger;
|
|
1177
|
+
private readonly disabledReason;
|
|
1178
|
+
private unregisterExit;
|
|
1179
|
+
constructor(options?: ClientOptions);
|
|
1180
|
+
private setup;
|
|
1181
|
+
/**
|
|
1182
|
+
* The customer's context pack, to place in the system prompt before calling the model.
|
|
1183
|
+
*
|
|
1184
|
+
* Inside a conversation (`conversation_id` or `task_id`), packs are cached: a recent one is
|
|
1185
|
+
* returned without a request, an older one is returned at once while a single background
|
|
1186
|
+
* request refreshes it, and when a request fails the last good pack is returned instead.
|
|
1187
|
+
* A 401 or 403 is not an outage: it drops the cached packs, so revoking a key also stops
|
|
1188
|
+
* what the process had already cached from reaching the model.
|
|
1189
|
+
*
|
|
1190
|
+
* A plain read and a `delta` read of one conversation share the cached pack. The server
|
|
1191
|
+
* sends each delta once, and so does the cache, even one a background refresh brought in;
|
|
1192
|
+
* `conversation()` and `task()` keep them across turns.
|
|
1193
|
+
*
|
|
1194
|
+
* Never rejects unless `strict` is set. On failure `text` is empty and `error` is set.
|
|
1195
|
+
*/
|
|
1196
|
+
context(params: ContextParams, options?: ContextOptions): Promise<ContextResult>;
|
|
1197
|
+
/**
|
|
1198
|
+
* Searches the customer's history by keywords and meaning, with filters by period, channel,
|
|
1199
|
+
* topic and kind. The answer includes how often the same kind of issue came back.
|
|
1200
|
+
*/
|
|
1201
|
+
search(params: SearchRequest, options?: RequestOptions): Promise<Result<SearchResponse>>;
|
|
1202
|
+
/** The customer's history in chronological order, one line per item, paginated by cursor. */
|
|
1203
|
+
timeline(params: TimelineRequest, options?: RequestOptions): Promise<Result<TimelineResponse>>;
|
|
1204
|
+
/**
|
|
1205
|
+
* Opens one history item from `search()` or `timeline()`: summary, request, commitments,
|
|
1206
|
+
* outcome and resolution. The literal transcript excerpt only comes back to keys with an
|
|
1207
|
+
* elevated scope.
|
|
1208
|
+
*/
|
|
1209
|
+
open(id: string, params?: OpenParams, options?: RequestOptions): Promise<Result<OpenedItem>>;
|
|
1210
|
+
/**
|
|
1211
|
+
* The derived state of a business object: what its systems of record reported last, `as_of`
|
|
1212
|
+
* when, and its open items, under this source's purpose.
|
|
1213
|
+
*
|
|
1214
|
+
* @example
|
|
1215
|
+
* const { data: invoice } = await niadra.objectState("invoice:erp:0823");
|
|
1216
|
+
*/
|
|
1217
|
+
objectState(object: ObjectRef | string, options?: RequestOptions): Promise<Result<ObjectState>>;
|
|
1218
|
+
/**
|
|
1219
|
+
* System events and agent actions about one object, newest first, one line each and never
|
|
1220
|
+
* conversation content. Pass `next_cursor` back as `cursor` to go on.
|
|
1221
|
+
*/
|
|
1222
|
+
objectTimeline(object: ObjectRef | string, params?: ObjectTimelineParams, options?: RequestOptions): Promise<Result<ObjectTimeline>>;
|
|
1223
|
+
/**
|
|
1224
|
+
* The navigation kit as function-calling tools with the customer bound outside the model's
|
|
1225
|
+
* reach. Hand `definitions` to any model API and pass its tool calls to `call()`.
|
|
1226
|
+
*
|
|
1227
|
+
* @example
|
|
1228
|
+
* const kit = niadra.tools(handles.phone("+5511987654321"), { conversation_id: "wa-8812" });
|
|
1229
|
+
* const output = await kit.call(toolCall.function.name, toolCall.function.arguments);
|
|
1230
|
+
*/
|
|
1231
|
+
tools(subject: Handle, binding?: ToolBinding): BoundTools;
|
|
1232
|
+
/**
|
|
1233
|
+
* Mints a signed, 15-minute token that binds one customer to a session. Your backend calls
|
|
1234
|
+
* this and hands the token to the MCP connection, so tools served over MCP can only ever
|
|
1235
|
+
* read that customer. Resolves with `data: null` on failure.
|
|
1236
|
+
*/
|
|
1237
|
+
subjectToken(params: SubjectTokenRequest, options?: RequestOptions): Promise<Result<SubjectToken>>;
|
|
1238
|
+
/**
|
|
1239
|
+
* Records a message, a system event or an agent action. Returns at once with the event's
|
|
1240
|
+
* idempotency key, or `null` when the event was dropped: invalid, unserializable, the queue
|
|
1241
|
+
* full or the client disabled. Delivery happens in the background; `flush()` waits for it.
|
|
1242
|
+
*/
|
|
1243
|
+
track(event: TrackEvent): string | null;
|
|
1244
|
+
/**
|
|
1245
|
+
* Records what an agent did in a system of record, such as a credit or a reschedule.
|
|
1246
|
+
* With `closes`, the action also resolves the open item it fulfils.
|
|
1247
|
+
*/
|
|
1248
|
+
action(event: ActionEvent): string | null;
|
|
1249
|
+
/**
|
|
1250
|
+
* States that several handles belong to the same subject. Sent right away rather than on the
|
|
1251
|
+
* next batch, so the next `context()` call already sees the merged profile.
|
|
1252
|
+
*/
|
|
1253
|
+
identify(params: IdentifyParams): Promise<WriteResult>;
|
|
1254
|
+
/**
|
|
1255
|
+
* Raises the verification level of one conversation or task after the customer proved who
|
|
1256
|
+
* they are. Sent right away, and drops the conversation's cached packs, because a pack
|
|
1257
|
+
* compiled for the old level may be missing what the new level allows.
|
|
1258
|
+
*/
|
|
1259
|
+
verify(params: VerifyParams): Promise<WriteResult>;
|
|
1260
|
+
/**
|
|
1261
|
+
* Corrects what Niadra derived about a subject: retracts or corrects a fact, resolves an open
|
|
1262
|
+
* item, or records how a conversation ended. Sent right away; the server records it as an
|
|
1263
|
+
* event, so the correction is audited like any other. A rejected correction resolves with
|
|
1264
|
+
* `ok: false`.
|
|
1265
|
+
*/
|
|
1266
|
+
feedback(params: FeedbackParams): Promise<WriteResult>;
|
|
1267
|
+
/**
|
|
1268
|
+
* Hands a file to Niadra, such as a call recording, and returns the reference its event
|
|
1269
|
+
* carries. Media never travels inside an event: this reserves an upload, sends the bytes
|
|
1270
|
+
* straight to storage over a short-lived signed URL, and resolves with `media_ref` and
|
|
1271
|
+
* `media_sha256` for the event's `content`.
|
|
1272
|
+
*
|
|
1273
|
+
* @example
|
|
1274
|
+
* const { data } = await niadra.uploadMedia({ data: recording, content_type: "audio/wav" });
|
|
1275
|
+
* if (data) convo.track({ speaker: "customer", content: { type: "audio", media_ref: data.media_ref, media_sha256: data.media_sha256 } });
|
|
1276
|
+
*/
|
|
1277
|
+
uploadMedia(params: UploadParams, options?: {
|
|
1278
|
+
signal?: AbortSignal;
|
|
1279
|
+
}): Promise<Result<MediaUpload>>;
|
|
1280
|
+
/** Records a transfer to a human or another agent. Sent right away, so the receiver can read context at once. */
|
|
1281
|
+
handoff(params: HandoffParams): Promise<WriteResult>;
|
|
1282
|
+
/**
|
|
1283
|
+
* A helper for one customer conversation: pins the pack across turns, captures turns and
|
|
1284
|
+
* emits `conversation.ended` when you call `end()`.
|
|
1285
|
+
*/
|
|
1286
|
+
conversation(params: ConversationParams): Conversation;
|
|
1287
|
+
/** A helper for one internal-agent task: binds `task_id` to reads and writes and emits `task.ended`. */
|
|
1288
|
+
task(params: TaskParams): Task;
|
|
1289
|
+
/**
|
|
1290
|
+
* Sends every queued event and resolves when done. Call it before a serverless function
|
|
1291
|
+
* returns, or pass it to `waitUntil()` on edge runtimes. Rejects only with `strict` set.
|
|
1292
|
+
*/
|
|
1293
|
+
flush(): Promise<void>;
|
|
1294
|
+
/**
|
|
1295
|
+
* Flushes, stops the background timer and releases the exit hook. Events tracked after
|
|
1296
|
+
* this are dropped. Call it from your own SIGTERM handler in long-running services.
|
|
1297
|
+
*/
|
|
1298
|
+
shutdown(): Promise<void>;
|
|
1299
|
+
private verifyWith;
|
|
1300
|
+
/** Throws under `strict`; otherwise logs what failed, never with content, and returns the error. */
|
|
1301
|
+
private swallow;
|
|
1302
|
+
private voiceBudget;
|
|
1303
|
+
private readSpec;
|
|
1304
|
+
private navigate;
|
|
1305
|
+
private fetchContext;
|
|
1306
|
+
/**
|
|
1307
|
+
* One request for a key, shared by every caller that needs it meanwhile. It sends the
|
|
1308
|
+
* cached ETag, so an unchanged pack costs a `not_modified` answer instead of the full text.
|
|
1309
|
+
* The caller's signal is deliberately not passed down: other callers may be waiting too.
|
|
1310
|
+
*/
|
|
1311
|
+
private revalidate;
|
|
1312
|
+
private contextFailure;
|
|
1313
|
+
/**
|
|
1314
|
+
* 401 means the key itself is no longer valid, so every cached pack goes. 403 is specific to
|
|
1315
|
+
* what was asked, so only that pack goes.
|
|
1316
|
+
*/
|
|
1317
|
+
private observeAuth;
|
|
1318
|
+
private forgetScope;
|
|
1319
|
+
private disabledError;
|
|
1320
|
+
private enqueue;
|
|
1321
|
+
private sendNow;
|
|
1322
|
+
private endScope;
|
|
1323
|
+
private sendBatch;
|
|
1324
|
+
}
|
|
1325
|
+
|
|
1326
|
+
/**
|
|
1327
|
+
* `wrap()` for OpenAI-compatible clients: the official `openai` package and any client with its
|
|
1328
|
+
* `chat.completions.create(body, options)` shape.
|
|
1329
|
+
*
|
|
1330
|
+
* Each `chat.completions.create` and `chat.completions.parse` call made through the wrapper,
|
|
1331
|
+
* streaming or not, gets the conversation's pack as a system message right after the caller's
|
|
1332
|
+
* leading system or developer messages, and the suffix (deltas and live turns) as a system
|
|
1333
|
+
* message at the end. The pack goes after the caller's instructions because those are the same
|
|
1334
|
+
* for every customer: kept first, they stay the cacheable prefix of the prompt. The injection is
|
|
1335
|
+
* stamped on the conversation, and the model's answer is recorded as the agent's turn.
|
|
1336
|
+
*
|
|
1337
|
+
* Nothing the wrapper does can fail the model call: a context that cannot be fetched is left
|
|
1338
|
+
* out, and a failure to record the answer is logged, without content, and swallowed.
|
|
1339
|
+
*/
|
|
1340
|
+
|
|
1341
|
+
/** What `wrap()` needs from a conversation or a task. Both implement it. */
|
|
1342
|
+
interface WrapSession {
|
|
1343
|
+
context(): Promise<ContextResult>;
|
|
1344
|
+
markInjected(context?: ContextResult | null): void;
|
|
1345
|
+
agent(text: string): string | null;
|
|
1346
|
+
readonly logger: Logger;
|
|
1347
|
+
}
|
|
1348
|
+
/** A session, or a function that finds the one the current call belongs to (`null` passes the call through). */
|
|
1349
|
+
type SessionSource = WrapSession | (() => WrapSession | null | undefined);
|
|
1350
|
+
/**
|
|
1351
|
+
* Returns a proxy of an OpenAI-compatible client that injects the conversation's context and
|
|
1352
|
+
* records the model's answers. The client itself is never modified.
|
|
1353
|
+
*
|
|
1354
|
+
* `.withResponse()` keeps working on intercepted calls and records the answer too;
|
|
1355
|
+
* `.asResponse()` returns the raw HTTP response, whose body the SDK cannot read, so nothing is
|
|
1356
|
+
* recorded then. Streams are recorded when they end, or when the caller stops reading them.
|
|
1357
|
+
*
|
|
1358
|
+
* @example
|
|
1359
|
+
* const openai = wrap(new OpenAI(), convo);
|
|
1360
|
+
* const completion = await openai.chat.completions.create({ model: "gpt-4.1", messages });
|
|
1361
|
+
*/
|
|
1362
|
+
declare function wrap<C extends object>(client: C, session: SessionSource): C;
|
|
1363
|
+
/**
|
|
1364
|
+
* Places the pack after the leading system or developer messages and the suffix at the end.
|
|
1365
|
+
* Returns a new array; `messages` is left as it was.
|
|
1366
|
+
*/
|
|
1367
|
+
declare function injectContext(context: ContextResult, messages: readonly unknown[]): unknown[];
|
|
1368
|
+
|
|
1369
|
+
interface HandleOptions {
|
|
1370
|
+
/** Overrides the subject kind the server would infer from the handle type. */
|
|
1371
|
+
subjectKind?: SubjectKind;
|
|
1372
|
+
}
|
|
1373
|
+
/**
|
|
1374
|
+
* Builders for the handle types the API accepts. They only assemble the object; the value is
|
|
1375
|
+
* normalized and validated on the server, which is the single source of truth for matching.
|
|
1376
|
+
*
|
|
1377
|
+
* @example
|
|
1378
|
+
* niadra.context({ subject: handles.phone("+5511987654321"), conversation_id: "wa-8812" })
|
|
1379
|
+
*/
|
|
1380
|
+
declare const handles: {
|
|
1381
|
+
/** A phone number in E.164 form, such as `+5511987654321`. */
|
|
1382
|
+
readonly phone: (e164: string, options?: HandleOptions) => Handle;
|
|
1383
|
+
readonly email: (address: string, options?: HandleOptions) => Handle;
|
|
1384
|
+
/** The WhatsApp id (`wa_id`) the Cloud API reports for a contact. */
|
|
1385
|
+
readonly waId: (value: string, options?: HandleOptions) => Handle;
|
|
1386
|
+
readonly waJid: (value: string, options?: HandleOptions) => Handle;
|
|
1387
|
+
readonly waLid: (value: string, options?: HandleOptions) => Handle;
|
|
1388
|
+
/** A business-scoped WhatsApp user id; `businessAccount` is the WhatsApp Business account it belongs to. */
|
|
1389
|
+
readonly waBsuid: (value: string, businessAccount: string, options?: HandleOptions) => Handle;
|
|
1390
|
+
/** The user id in your own app or site. */
|
|
1391
|
+
readonly appUserId: (value: string, options?: HandleOptions) => Handle;
|
|
1392
|
+
/** The id of a person or organization in a system of record; `system` names that system, such as `crm`. */
|
|
1393
|
+
readonly systemId: (value: string, system: string, options?: HandleOptions) => Handle;
|
|
1394
|
+
/** An HMAC of a national document number; `country` is its ISO 3166-1 alpha-2 code. */
|
|
1395
|
+
readonly govIdHmac: (value: string, country: string, options?: HandleOptions) => Handle;
|
|
1396
|
+
/** An HMAC of a company registry number. Identifies an organization. */
|
|
1397
|
+
readonly orgRegistryHmac: (value: string, country: string) => Handle;
|
|
1398
|
+
/** An e-mail domain, such as `acme.com`. Identifies an organization. */
|
|
1399
|
+
readonly emailDomain: (domain: string) => Handle;
|
|
1400
|
+
/** An anonymous visitor or device id, before the person is known. */
|
|
1401
|
+
readonly anonId: (value: string, options?: HandleOptions) => Handle;
|
|
1402
|
+
};
|
|
1403
|
+
/**
|
|
1404
|
+
* Accepts an `ObjectRef` or the `type:namespace:id` shorthand. The id may itself contain
|
|
1405
|
+
* colons (`invoice:erp:2026:0823`); only the first two separate the parts.
|
|
1406
|
+
*/
|
|
1407
|
+
declare function toObjectRef(object: ObjectRef | string): ObjectRef;
|
|
1408
|
+
|
|
1409
|
+
/** The parts of a source key the SDK needs to find the right endpoint. */
|
|
1410
|
+
interface ParsedApiKey {
|
|
1411
|
+
/** `live` keys reach production spaces, `test` keys reach sandbox spaces. */
|
|
1412
|
+
mode: "live" | "test";
|
|
1413
|
+
/** Data region, such as `sa-east-1`. */
|
|
1414
|
+
region: string;
|
|
1415
|
+
/** The space (project and environment) the key belongs to. */
|
|
1416
|
+
space: string;
|
|
1417
|
+
keyId: string;
|
|
1418
|
+
}
|
|
1419
|
+
/**
|
|
1420
|
+
* Parses `nia_sk_<live|test>_<region>_<space>_<key_id>_<secret>`.
|
|
1421
|
+
*
|
|
1422
|
+
* Region and space become DNS labels in the base URL, so they are held to lowercase letters,
|
|
1423
|
+
* digits and inner hyphens. The secret is everything after the fifth underscore and is never
|
|
1424
|
+
* returned. Returns `null` for anything that does not match, rather than guessing.
|
|
1425
|
+
*/
|
|
1426
|
+
declare function parseApiKey(apiKey: string): ParsedApiKey | null;
|
|
1427
|
+
/**
|
|
1428
|
+
* The stable address of a space: `https://<space>.<region>.api.niadra.com`. It never names a
|
|
1429
|
+
* cell; when a space moves between cells, the old cell answers 421 and the SDK retries.
|
|
1430
|
+
*/
|
|
1431
|
+
declare function baseURLFromKey(key: ParsedApiKey): string;
|
|
1432
|
+
|
|
1433
|
+
/**
|
|
1434
|
+
* A UUIDv7 (RFC 9562): time-ordered, so keys minted by one process sort in the order the
|
|
1435
|
+
* events happened. A 12-bit counter keeps keys monotonic within the same millisecond.
|
|
1436
|
+
*/
|
|
1437
|
+
declare function uuidv7(now?: number): string;
|
|
1438
|
+
|
|
1439
|
+
declare const VERSION = "0.1.0";
|
|
1440
|
+
|
|
1441
|
+
export { type ActionEvent, type ActionInfo, type AssertionMethod, type BatchItem, type BatchRequest, type BatchResponse, type BoundTools, type CacheDirectives, type CacheOptions, type ClientOptions, type Closes, type Commitment, type Content, type ContextOptions, type ContextParams, type ContextRequest, type ContextResponse, type ContextResult, type ContextSource, type ContextStamp, Conversation, type ConversationAction, type ConversationEndedItem, type ConversationEvent, type ConversationParams, DEFAULT_CACHE, DEFAULT_QUEUE, DEFAULT_TIMEOUTS, type DeliveryPath, type EventItem, type EventKind, type FeedbackAction, type FeedbackParams, type FeedbackRequest, type Handle, type HandleType, type HandoffItem, type HandoffParams, type HeartbeatItem, type HistoryFilters, type HistoryItem, type HistoryItemKind, type IdentifyItem, type IdentifyParams, type ItemError, type LiveTurn, type Logger, MAX_BATCH_ITEMS, MAX_EVENT_TEXT, MAX_MEDIA_BYTES, type MediaUpload, type MediaUploadRequest, type MediaUploadResponse, Niadra, NiadraAPIError, NiadraAbortError, NiadraAuthenticationError, NiadraConfigError, NiadraConnectionError, NiadraError, NiadraPermissionError, NiadraRateLimitError, NiadraTimeoutError, NiadraValidationError, type ObjectRef, type ObjectState, type ObjectTimeline, type ObjectTimelineParams, type OpenParams, type OpenedItem, type ParsedApiKey, type Problem, type QueueOptions, type Recurrence, type RequestOptions, type Result, type SearchRequest, type SearchResponse, type SessionSource, type SourceCoverage, type Speaker, type SpeakerRef, type Subject, type SubjectKind, type SubjectToken, type SubjectTokenRequest, TOOL_DEFINITIONS, TOOL_NAMES, type TargetModel, Task, type TaskAction, type TaskEndedItem, type TaskEvent, type TaskParams, type TimelineRequest, type TimelineResponse, type Timeouts, type Timestamp, type Timings, type ToolBinding, type ToolDefinition, type TrackEvent, type TurnOptions, type UploadParams, VERSION, type Verification, type VerificationResult, type VerifyItem, type VerifyMethod, type VerifyParams, type View, type Visibility, type VoiceInfo, type WrapSession, type WriteResult, baseURLFromKey, consoleLogger, handles, injectContext, parseApiKey, renderLive, renderSuffix, silentLogger, toObjectRef, uuidv7, wrap };
|