@niadra/sdk 0.1.1 → 0.7.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.
Files changed (133) hide show
  1. package/CHANGELOG.md +160 -68
  2. package/README.md +451 -22
  3. package/dist/ai-sdk.cjs +1037 -0
  4. package/dist/ai-sdk.cjs.map +1 -0
  5. package/dist/ai-sdk.d.cts +118 -0
  6. package/dist/ai-sdk.d.ts +118 -0
  7. package/dist/ai-sdk.js +1030 -0
  8. package/dist/ai-sdk.js.map +1 -0
  9. package/dist/anthropic.cjs +528 -0
  10. package/dist/anthropic.cjs.map +1 -0
  11. package/dist/anthropic.d.cts +35 -0
  12. package/dist/anthropic.d.ts +35 -0
  13. package/dist/anthropic.js +523 -0
  14. package/dist/anthropic.js.map +1 -0
  15. package/dist/bedrock.cjs +392 -0
  16. package/dist/bedrock.cjs.map +1 -0
  17. package/dist/bedrock.d.cts +25 -0
  18. package/dist/bedrock.d.ts +25 -0
  19. package/dist/bedrock.js +388 -0
  20. package/dist/bedrock.js.map +1 -0
  21. package/dist/cli.js +11045 -0
  22. package/dist/cli.js.map +1 -0
  23. package/dist/client-DsIxZxZk.d.cts +6905 -0
  24. package/dist/client-DsIxZxZk.d.ts +6905 -0
  25. package/dist/cloudflare-agents.cjs +626 -0
  26. package/dist/cloudflare-agents.cjs.map +1 -0
  27. package/dist/cloudflare-agents.d.cts +113 -0
  28. package/dist/cloudflare-agents.d.ts +113 -0
  29. package/dist/cloudflare-agents.js +622 -0
  30. package/dist/cloudflare-agents.js.map +1 -0
  31. package/dist/elevenlabs.cjs +738 -0
  32. package/dist/elevenlabs.cjs.map +1 -0
  33. package/dist/elevenlabs.d.cts +86 -0
  34. package/dist/elevenlabs.d.ts +86 -0
  35. package/dist/elevenlabs.js +733 -0
  36. package/dist/elevenlabs.js.map +1 -0
  37. package/dist/genkit.cjs +323 -0
  38. package/dist/genkit.cjs.map +1 -0
  39. package/dist/genkit.d.cts +67 -0
  40. package/dist/genkit.d.ts +67 -0
  41. package/dist/genkit.js +318 -0
  42. package/dist/genkit.js.map +1 -0
  43. package/dist/google-adk.cjs +705 -0
  44. package/dist/google-adk.cjs.map +1 -0
  45. package/dist/google-adk.d.cts +91 -0
  46. package/dist/google-adk.d.ts +91 -0
  47. package/dist/google-adk.js +701 -0
  48. package/dist/google-adk.js.map +1 -0
  49. package/dist/google-genai.cjs +422 -0
  50. package/dist/google-genai.cjs.map +1 -0
  51. package/dist/google-genai.d.cts +26 -0
  52. package/dist/google-genai.d.ts +26 -0
  53. package/dist/google-genai.js +418 -0
  54. package/dist/google-genai.js.map +1 -0
  55. package/dist/index.cjs +11421 -1895
  56. package/dist/index.cjs.map +1 -1
  57. package/dist/index.d.cts +959 -1294
  58. package/dist/index.d.ts +959 -1294
  59. package/dist/index.js +11368 -1896
  60. package/dist/index.js.map +1 -1
  61. package/dist/intercept-0_lJE6k1.d.cts +20 -0
  62. package/dist/intercept-D7qFCaRb.d.ts +20 -0
  63. package/dist/langchain.cjs +1077 -0
  64. package/dist/langchain.cjs.map +1 -0
  65. package/dist/langchain.d.cts +102 -0
  66. package/dist/langchain.d.ts +102 -0
  67. package/dist/langchain.js +1068 -0
  68. package/dist/langchain.js.map +1 -0
  69. package/dist/livekit.cjs +404 -0
  70. package/dist/livekit.cjs.map +1 -0
  71. package/dist/livekit.d.cts +113 -0
  72. package/dist/livekit.d.ts +113 -0
  73. package/dist/livekit.js +398 -0
  74. package/dist/livekit.js.map +1 -0
  75. package/dist/llamaindex.cjs +349 -0
  76. package/dist/llamaindex.cjs.map +1 -0
  77. package/dist/llamaindex.d.cts +92 -0
  78. package/dist/llamaindex.d.ts +92 -0
  79. package/dist/llamaindex.js +344 -0
  80. package/dist/llamaindex.js.map +1 -0
  81. package/dist/mastra.cjs +1082 -0
  82. package/dist/mastra.cjs.map +1 -0
  83. package/dist/mastra.d.cts +86 -0
  84. package/dist/mastra.d.ts +86 -0
  85. package/dist/mastra.js +1075 -0
  86. package/dist/mastra.js.map +1 -0
  87. package/dist/openai-agents.cjs +465 -0
  88. package/dist/openai-agents.cjs.map +1 -0
  89. package/dist/openai-agents.d.cts +75 -0
  90. package/dist/openai-agents.d.ts +75 -0
  91. package/dist/openai-agents.js +459 -0
  92. package/dist/openai-agents.js.map +1 -0
  93. package/dist/retell.cjs +846 -0
  94. package/dist/retell.cjs.map +1 -0
  95. package/dist/retell.d.cts +161 -0
  96. package/dist/retell.d.ts +161 -0
  97. package/dist/retell.js +841 -0
  98. package/dist/retell.js.map +1 -0
  99. package/dist/shared-Bb5B59Bu.d.ts +39 -0
  100. package/dist/shared-DTPWVlWm.d.cts +39 -0
  101. package/dist/strands.cjs +352 -0
  102. package/dist/strands.cjs.map +1 -0
  103. package/dist/strands.d.cts +72 -0
  104. package/dist/strands.d.ts +72 -0
  105. package/dist/strands.js +347 -0
  106. package/dist/strands.js.map +1 -0
  107. package/dist/twilio.cjs +174 -0
  108. package/dist/twilio.cjs.map +1 -0
  109. package/dist/twilio.d.cts +64 -0
  110. package/dist/twilio.d.ts +64 -0
  111. package/dist/twilio.js +167 -0
  112. package/dist/twilio.js.map +1 -0
  113. package/dist/vapi.cjs +661 -0
  114. package/dist/vapi.cjs.map +1 -0
  115. package/dist/vapi.d.cts +78 -0
  116. package/dist/vapi.d.ts +78 -0
  117. package/dist/vapi.js +656 -0
  118. package/dist/vapi.js.map +1 -0
  119. package/dist/voltagent.cjs +509 -0
  120. package/dist/voltagent.cjs.map +1 -0
  121. package/dist/voltagent.d.cts +70 -0
  122. package/dist/voltagent.d.ts +70 -0
  123. package/dist/voltagent.js +503 -0
  124. package/dist/voltagent.js.map +1 -0
  125. package/dist/webhook-1ozGyksG.d.ts +37 -0
  126. package/dist/webhook-CG4om_DK.d.cts +37 -0
  127. package/dist/whatsapp.cjs +214 -0
  128. package/dist/whatsapp.cjs.map +1 -0
  129. package/dist/whatsapp.d.cts +81 -0
  130. package/dist/whatsapp.d.ts +81 -0
  131. package/dist/whatsapp.js +207 -0
  132. package/dist/whatsapp.js.map +1 -0
  133. package/package.json +351 -6
package/dist/index.d.cts CHANGED
@@ -1,1382 +1,1047 @@
1
+ import { C as ConstraintsBlock, H as HardConstraint, N as NiadraError, a as ClaimRecord, b as ClaimCategory, I as InternalText, s as shingles, c as Niadra, R as Resolvers, d as ContextResponse, M as Mode, T as TurnPins, e as RawBinding, f as ContextResult, g as ModelUsage, L as Logger, S as SubjectKind, h as Handle, O as ObjectRef } from './client-DsIxZxZk.cjs';
2
+ export { A as AGENT_MEMORY_TOOL_DEFINITIONS, i as AGENT_MEMORY_TOOL_NAMES, j as ActionEvent, k as ActionInfo, l as Actions, m as Admin, n as AgentMemoryBlock, o as AgentMemoryParams, p as AgentMemoryResult, q as AgentMemorySearchRequest, r as AgentMemorySearchResponse, t as AgentMemorySource, u as AgentNote, v as AgentNoteKind, w as AgentNoteOrigin, x as AgentNoteProposal, y as AgentNoteStatus, z as AgentNoteVisibility, B as AgentSession, D as AgentState, E as AgentStateConflict, F as AgentStateHandle, G as AgentStateMeta, J as AgentStateMetaPage, K as AgentStateReadRequest, P as AgentStateScope, Q as AgentStateWrite, U as AgentStateWriteResult, V as AgentTurnOptions, W as AnchorEvidence, X as Api, Y as ArmComparison, Z as ArmOutcomes, _ as AskedAttribute, $ as AssertionMethod, a0 as AssertionOutcome, a1 as AssertionStats, a2 as Attribute, a3 as AttributeEntry, a4 as AttributionReport, a5 as AttributionRow, a6 as AttributionTotal, a7 as Backing, a8 as BackingReport, a9 as BackingSources, aa as BatchItem, ab as BatchRequest, ac as BatchResponse, ad as BiFile, ae as BiUpload, af as BiUploadRequest, ag as BlobError, ah as BlobStore, ai as BlockSubject, aj as BoundArg, ak as BoundTools, al as BudgetBlock, am as BudgetCut, an as BudgetPack, ao as BudgetUse, ap as CacheDirectives, aq as CacheOptions, ar as CallCapture, as as CaseClosed, at as CaseOpened, au as Change, av as ChangePage, aw as ChangeSinceSeen, ax as ChannelState, ay as CheckBatchRequest, az as CheckBatchResponse, aA as CheckOptions, aB as CheckRequest, aC as CheckResult, aD as ClaimCheck, aE as ClaimCheckOptions, aF as ClaimContractSummary, aG as ClaimEvidence, aH as ClaimEvidenceRef, aI as ClaimKind, aJ as ClaimOutputs, aK as ClaimParams, aL as ClaimRelease, aM as ClaimRequest, aN as ClaimValue, aO as ClaimVerdict, aP as ClaimVia, aQ as Claimed, aR as ClientOptions, aS as Closes, aT as Commitment, aU as CommitmentDecided, aV as CommitmentDecidedDetail, aW as CommitmentMade, aX as CommitmentMadeDetail, aY as CommitmentRef, aZ as CommitmentWithdrawn, a_ as CommitmentWithdrawnDetail, a$ as CompanyRule, b0 as Conflict, b1 as ConflictCounts, b2 as ConstraintOrigin, b3 as ConstraintsRequest, b4 as ContactBudget, b5 as ContactBudgetUse, b6 as ContactClaims, b7 as ContactCount, b8 as ContactGateway, b9 as ContactKey, ba as ContactKeys, bb as ContactMade, bc as ContactMadeDetail, bd as ContactTokenParams, be as ContactTokenRefusal, bf as Content, bg as ContentMarker, bh as ContentMode, bi as ContentRelease, bj as ContentReleaseResult, bk as ContentResolver, bl as ContextFormat, bm as ContextOptions, bn as ContextPack, bo as ContextParams, bp as ContextRequest, bq as ContextSource, br as ContextStamp, bs as ContextUseEntry, bt as Conversation, bu as ConversationAction, bv as ConversationEndedItem, bw as ConversationEvent, bx as ConversationParams, by as CoordinationBlock, bz as CoordinationOverview, bA as CoordinationReport, bB as CoordinationReportPage, bC as CorrectParams, bD as CorrectionAction, bE as CorrectionRequest, bF as CounterfactualCase, bG as CounterfactualEngaged, bH as CounterfactualEngagement, bI as CounterfactualRunCreate, bJ as CounterfactualRunPage, bK as CreateAgentNoteRequest, bL as DEFAULT_CACHE, bM as DEFAULT_QUEUE, bN as DEFAULT_TIMEOUTS, bO as DEFAULT_VOICE, bP as DELETE, bQ as DataIssue, bR as DataIssuePage, bS as Declarations, bT as DeclareRequest, bU as DeclareResult, bV as DeliveryPath, bW as Detect, bX as DriftChanges, bY as Effect, bZ as EffectCount, b_ as EffectDeclared, b$ as EffectDetail, c0 as EffectKind, c1 as EffectReserve, c2 as EffectSeen, c3 as EffectSettle, c4 as EffectState, c5 as EffectStatus, c6 as Engaged, c7 as EpisodeOut, c8 as Erasure, c9 as EventItem, ca as EventKind, cb as Evidence, cc as ExperimentReport, cd as ExperimentResult, ce as ExportPackage, cf as FAIL_CLOSED, cg as FactHistory, ch as FactOut, ci as Feature, cj as Feedback, ck as FeedbackAction, cl as FeedbackParams, cm as FeedbackRequest, cn as Fetched, co as FieldCoverage, cp as FieldState, cq as ForgetTarget, cr as GatewayOptions, cs as Guard, ct as GuardLike, cu as GuardOptions, cv as Guarded, cw as HandleType, cx as Handoff, cy as HandoffContext, cz as HandoffCreate, cA as HandoffDeclared, cB as HandoffDetail, cC as HandoffItem, cD as HandoffOutcome, cE as HandoffPackage, cF as HandoffParams, cG as HeartbeatItem, cH as HistoryFilters, cI as HistoryItem, cJ as HistoryItemKind, cK as IdentifyItem, cL as IdentifyParams, cM as IdentityCalibration, cN as Include, cO as Inference, cP as InferenceCorrection, cQ as InferencePage, cR as IngestStatus, cS as InterestState, cT as InterleavingReport, cU as InterleavingRow, cV as InterleavingTotal, cW as InternalText, cX as ItemError, cY as ItemVersion, cZ as KeyIdentity, c_ as LeaseDeclared, c$ as LeaseDetail, d0 as LegalHold, d1 as LegalHoldCreate, d2 as LegalHoldRelease, d3 as LiveTurn, d4 as Lock, d5 as MAX_BATCH_ITEMS, d6 as MAX_EVENT_TEXT, d7 as MAX_MEDIA_BYTES, d8 as MediaUpload, d9 as MediaUploadRequest, da as MediaUploadResponse, db as MemorySeen, dc as NOT_FOUND, dd as Natures, de as Negation, df as NiadraAPIError, dg as NiadraAbortError, dh as NiadraAuthenticationError, di as NiadraConfigError, dj as NiadraConnectionError, dk as NiadraContactTokenError, dl as NiadraPermissionError, dm as NiadraRateLimitError, dn as NiadraReplayRefusedError, dp as NiadraTimeoutError, dq as NiadraValidationError, dr as Notification, ds as NotificationPage, dt as ObjectCoverage, du as ObjectPush, dv as ObjectPushRequest, dw as ObjectPushResponse, dx as ObjectRead, dy as ObjectSnapshotResponse, dz as ObjectTimeline, dA as ObjectTimelineParams, dB as Observation, dC as OpenItemOut, dD as OpenItemRequest, dE as OpenObject, dF as OpenParams, dG as OpenedItem, dH as Origin, dI as OutcomeLink, dJ as OutcomePage, dK as OutcomeRequest, dL as OutcomeState, dM as Owner, dN as OwnershipClaim, dO as OwnershipCount, dP as PERSONAL_DATA_TOOL_ERROR, dQ as PackGuard, dR as PackLayer, dS as PackSection, dT as PackSlot, dU as PackSlotDerived, dV as PackStamp, dW as PowerRequest, dX as PowerResult, dY as Preference, dZ as PrefetchParams, d_ as PrefetchRequest, d$ as Presented, e0 as PresentedItem, e1 as PreviousValue, e2 as Problem, e3 as ProfileMatch, e4 as ProfileMemory, e5 as PromiseRef, e6 as PromoteRequest, e7 as PromoteResponse, e8 as ProposalStatus, e9 as Provenance, ea as QueueOptions, eb as ReadingResult, ec as ReconcileRequest, ed as ReconcileResult, ee as ReconciledLine, ef as RecordedToolOptions, eg as Recurrence, eh as Refetch, ei as RefreshRelease, ej as RefreshReleased, ek as RefreshRequest, el as RefreshRequestPage, em as Refusal, en as ReleaseDetail, eo as RememberParams, ep as RememberResult, eq as Rendered, er as ReplayAssertion, es as ReplayBlocker, et as ReplayCase, eu as ReplayCaseRequest, ev as ReplayHistoryEntry, ew as ReplayResult, ex as RequestOptions, ey as Resolved, ez as Resolver, eA as Result, eB as ResultObjects, eC as ReviewRequest, eD as ReviewRequestCreate, eE as ReviewRequestPage, eF as ReviewResolution, eG as Scenario, eH as ScenarioCreate, eI as ScenarioFromReport, eJ as ScenarioPage, eK as ScenarioRun, eL as ScenarioRunCreate, eM as ScenarioRunSummary, eN as ScenarioUpdate, eO as ScenarioVerdict, eP as SdkProfile, eQ as SearchRequest, eR as SearchResponse, eS as Seen, eT as SeenTokens, eU as ShadowRequest, eV as ShadowRun, eW as Shown, eX as SlotChannelRank, eY as SlotWhy, eZ as SoftConstraint, e_ as SourceCoverage, e$ as Speaker, f0 as SpeakerRef, f1 as StateMode, f2 as StateReadRequest, f3 as StateReadResponse, f4 as StateRef, f5 as StateVerifyRequest, f6 as StateVerifyResponse, f7 as StateView, f8 as StateViewRequest, f9 as StateWrite, fa as Subject, fb as SubjectToken, fc as SubjectTokenRequest, fd as Suppression, fe as SuppressionAdded, ff as SuppressionAddedDetail, fg as SuppressionLifted, fh as SuppressionLiftedDetail, fi as SuppressionPage, fj as SuppressionSalt, fk as TOOL_DEFINITIONS, fl as TOOL_NAMES, fm as TargetModel, fn as Task, fo as TaskAction, fp as TaskEndedItem, fq as TaskEvent, fr as TaskLockDeclared, fs as TaskLockDetail, ft as TaskParams, fu as TimeWindow, fv as TimelineRequest, fw as TimelineResponse, fx as Timeouts, fy as TimerState, fz as Timestamp, fA as Timings, fB as ToolBinding, fC as ToolCapabilities, fD as ToolDefinition, fE as ToolOptions, fF as TrackEvent, fG as TraitOut, fH as TurnAgent, fI as TurnBlob, fJ as TurnBuild, fK as TurnCall, fL as TurnCompilerPins, fM as TurnConstraints, fN as TurnCoordination, fO as TurnCost, fP as TurnEffect, fQ as TurnFlag, fR as TurnFrame, fS as TurnIndexEntry, fT as TurnIndexPage, fU as TurnKind, fV as TurnObservation, fW as TurnOptions, fX as TurnOutput, fY as TurnParams, fZ as TurnProvenance, f_ as TurnRead, f$ as TurnRecord, g0 as TurnRecorder, g1 as TurnRecordingOptions, g2 as TurnRecordingSummary, g3 as TurnSearchRequest, g4 as TurnSearchResponse, g5 as TurnSummary, g6 as TurnTokens, g7 as TurnView, g8 as TurnsRequest, g9 as TurnsResponse, ga as TypeCoverage, gb as TypeFingerprintRequest, gc as TypeFingerprintResponse, gd as UnbackedValue, ge as UnmetDemand, gf as UnmetDemandPage, gg as Unwatch, gh as UploadParams, gi as ValueEvidence, gj as ValueKind, gk as ValueState, gl as Verdict, gm as Verification, gn as VerificationResult, go as VerifyCheck, gp as VerifyItem, gq as VerifyMethod, gr as VerifyParams, gs as View, gt as Visibility, gu as VoiceInfo, gv as VoiceOptions, gw as Watch, gx as WhereExpression, gy as WorkingState, gz as WriteResult, gA as checkBacking, gB as consoleLogger, gC as currentCall, gD as currentTurn, gE as guardStream, gF as guardText, gG as recipientHash, gH as renderLive, gI as renderSuffix, gJ as silentLogger, gK as tool, gL as verifyContactToken, gM as violatesGuard } from './client-DsIxZxZk.cjs';
3
+
1
4
  /**
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.
5
+ * The constraints block rendered for one tool call (`spec/constraints.md`, sections 6 and 7): what the
6
+ * call's arguments can carry through the tool's binding, what they cannot (the residual), and, after the
7
+ * call, how much of what was sent the results honored. The server runs the same rules for
8
+ * `POST /v1/constraints` with a tool.
9
+ *
10
+ * - A hard constraint renders through the binding argument of its field: `in` and `eq` to the argument,
11
+ * `not_in` and `ne` to its negation parameter, a comparison or `between` only to an argument that
12
+ * declares it in `ops`. One value renders as itself, several as a list; `transform` changes the case of
13
+ * text.
14
+ * - A hard constraint that lost a conflict of the block is not rendered at all.
15
+ * - A constraint of a category holds only for a call of that category.
16
+ * - An attribute renders through the argument of its family (`size` for `size.pants`) when it applies:
17
+ * `always`, or `when_asked` and the person asked for it this turn.
18
+ * - What no argument can express is residual: the SDK filters it from the results when the tool
19
+ * overfetches, and it is otherwise unenforced. `exclude` is always residual.
20
+ * - Advisory mode (the default) changes nothing and suggests. Apply mode adds only what the call left out,
21
+ * and only a hard constraint said in this turn or this session, or an attribute the person said; it never
22
+ * overrides an argument the call set (the current utterance wins, and the clash is reported as a
23
+ * conflict), and never adds an inferred size.
24
+ * - A block for another beneficiary than the call's does not apply at all.
25
+ *
26
+ * The same rules as the Python SDK's `niadra.constraints.render`.
4
27
  */
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";
28
+
29
+ type Op = HardConstraint["op"];
30
+ /** One argument of a tool's binding (`tool-bindings`): the field it carries and how. */
31
+ interface BindingArg {
32
+ /** The field, `type.field`. */
33
+ attr: string;
34
+ param: string;
35
+ transform?: "lower" | "upper" | null;
36
+ /** The parameter that carries the field's negation (`not_in`, `ne`). */
37
+ negation?: string | null;
38
+ /** The comparisons the parameter accepts besides `in` and `eq`. */
39
+ ops?: readonly string[];
40
+ /** The attribute family of the field (`size`), from the type registry. */
41
+ family?: string | null;
42
+ }
43
+ interface Binding {
44
+ tool: string;
45
+ args: readonly BindingArg[];
46
+ /** The tool returns more than asked, so the SDK can filter the residual from its results. */
47
+ overfetch?: boolean;
48
+ }
49
+ /** The call the model made. */
50
+ interface Call$1 {
51
+ args: Readonly<Record<string, unknown>>;
52
+ /** Whose call it is: `self` (the default), `beneficiary:<id>` or `gift`. */
53
+ for?: string;
54
+ category?: string | null;
55
+ /** The attributes the person asked to use this turn ("in my size": `size`). */
56
+ asked?: readonly string[];
57
+ }
58
+ interface Rendering {
59
+ applies: boolean;
60
+ /** What the call sends: its own arguments, plus what apply mode added. */
61
+ args: Record<string, unknown>;
62
+ suggested: Record<string, unknown>;
63
+ injected: string[];
64
+ hardSent: string[];
65
+ residual: string[];
66
+ postFilter: string[];
67
+ /** A hard constraint and the argument the call set against it. */
68
+ conflicts: {
69
+ id: string;
70
+ param: string;
71
+ }[];
72
+ }
73
+ /** What the results show of the hard constraints sent: "sent, verifiable, violated", never only sent. */
74
+ interface Honored {
75
+ resultsChecked: number;
76
+ violations: number;
77
+ /** Results without the constrained field: without this count, conformance lies upward. */
78
+ unverifiable: number;
79
+ }
80
+ /** The block for one call of the tool `binding` describes. */
81
+ declare function render(block: ConstraintsBlock, binding: Binding, call: Call$1, mode?: "advisory" | "apply"): Rendering;
13
82
  /**
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.
83
+ * Each result item, keyed by `type.field`, is a violation when it breaks a hard constraint that was sent,
84
+ * and unverifiable when it breaks none but lacks the field of one.
16
85
  */
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";
86
+ declare function honored(block: ConstraintsBlock, sentIds: readonly string[], results: readonly Readonly<Record<string, unknown>>[]): Honored;
87
+ /** Whether `value` honors `op` over `values`; text is compared folded, numbers as exact decimals. */
88
+ declare function satisfies(op: Op, values: readonly unknown[], value: unknown): boolean;
89
+
20
90
  /**
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.
91
+ * The digest of a value a turn record carries: SHA-256 over its canonical JSON (RFC 8785).
92
+ *
93
+ * The canonical form leaves no whitespace, sorts object keys by their UTF-16 code units and writes numbers
94
+ * as ECMAScript does, so a producer in any language hashes the same value to the same digest. The Turn
95
+ * Record spec fixes it (section 6.2.1) with the vectors in `spec/vectors/turn-record-digest.v0.json`.
23
96
  */
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
97
  /**
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.
98
+ * `value` (JSON data: plain objects, arrays, strings, finite numbers, booleans and `null`) as its
99
+ * canonical JSON. A property whose value is `undefined` is left out, as `JSON.stringify` does; anything
100
+ * JSON cannot hold (`NaN`, a `bigint`, a `Date`) throws.
30
101
  */
31
- type DeliveryPath = "t0" | "t1" | "t2" | "t3" | "t4" | "holdout" | "not_modified";
102
+ declare function canonicalJson(value: unknown): string;
32
103
  /**
33
- * Kinds of history items the navigation calls can filter on. A system event is never an item: it
34
- * changes its object's state, so filter on `object`.
104
+ * `value`'s digest, written `sha256:<hex>`, and the size in bytes of its canonical JSON (UTF-8). Web
105
+ * Crypto hashes asynchronously, so the turn capture hashes when it sends, never on the agent's path.
35
106
  */
36
- type HistoryItemKind = "episode" | "fact" | "open_item" | "action" | "object" | "trait";
107
+ declare function jsonDigest(value: unknown): Promise<{
108
+ sha256: string;
109
+ size: number;
110
+ }>;
111
+
37
112
  /**
38
- * The shape of the pack. Channel views (`voice`, `chat`) size it for the medium; `account`
39
- * and `partner` read an organization; `task:<name>` views serve internal agents.
113
+ * The four logical values of a field (`spec/object-type.md`, section 5.4): not observed is never false.
40
114
  */
41
- type View = "voice" | "chat" | "brief" | "full" | "custom" | "account" | "partner" | `task:${string}`;
115
+ type Logic = "yes" | "no" | "unobserved" | "known_defect";
116
+ /** The two logical values that say nothing about the value. */
117
+ type UnknownLogic = "unobserved" | "known_defect";
42
118
 
43
119
  /**
44
- * An identifier of a subject in some channel or system: a phone number, an e-mail address,
45
- * a CRM id. Handles carry personal data, so the SDK only ever sends them in request bodies.
120
+ * niadra-expr: the language of the type registry's conditions, timers, keys and readings
121
+ * (`spec/object-type.md`, section 5).
122
+ *
123
+ * Small, deterministic and total: literals, names, comparison, `in`, `and`, `or`, `not`, `+`, `-` and a
124
+ * fixed set of functions; no loop, no I/O, and bounded text, tokens and nesting. Every value carries one of
125
+ * the four logical values, so a comparison with a value nobody observed is itself unobserved, never false.
126
+ * The server and both SDKs implement the same language and pass the same vectors
127
+ * (`spec/vectors/niadra-expr.v0.json`).
128
+ *
129
+ * `parse` reads the text, `compileExpression` also resolves its names against a type declaration (the
130
+ * registry's validation), and `evaluate` computes it over an `Environment`, the object's slots at one
131
+ * instant. Time is integer arithmetic, never the machine's time zone: a datetime is milliseconds since the
132
+ * epoch, a date the days since 1970-01-01, and the environment's UTC offset says where a day starts.
46
133
  */
47
- interface Handle {
48
- type: HandleType;
49
- /** Up to 320 characters. Phones are E.164 (`+5511987654321`). */
50
- value: string;
51
- /**
52
- * Namespace for scoped identifiers: the WhatsApp Business account for `wa_bsuid`, the
53
- * system for `system_id`, the country for `gov_id_hmac`.
54
- */
55
- scope?: string | null;
56
- /** Defaults to `person` on the server, except for organization-only handle types. */
57
- subject_kind?: SubjectKind | null;
58
- }
59
- /** A business object in a system of record, such as `invoice` / `erp` / `0823`. */
60
- interface ObjectRef {
61
- type: string;
62
- namespace: string;
63
- id: string;
64
- }
65
- /** A participant of an event other than the speaker, for example the account a person acts for. */
66
- interface Subject {
67
- kind: SubjectKind;
68
- role?: string | null;
69
- /** Between 1 and 16 handles. */
70
- handles: Handle[];
71
- }
72
- /** Whether a source is still sending. `silent` means it stopped, so the pack may be missing recent turns. */
73
- interface SourceCoverage {
74
- source_id: string;
75
- status: "ok" | "silent" | (string & {});
76
- last_event_at?: string | null;
77
- }
78
- /** RFC 9457 problem details, as returned with `application/problem+json`. */
79
- interface Problem {
80
- type: string;
81
- title: string;
82
- status: number;
83
- detail?: string | null;
84
- /** Stable code from the versioned error catalog, such as `rate_limited` or `wrong_cell`. */
85
- code: string;
86
- request_id?: string | null;
87
- }
88
134
 
135
+ /** The three errors of the language (`spec/object-type.md`, section 5.9). */
136
+ type ExprErrorCode = "expr_invalid" | "expr_type" | "expr_limit";
89
137
  /**
90
- * Base class of every error the SDK produces. In the default fail-open mode these errors are
91
- * logged and returned in results rather than thrown; with `strict: true` they are thrown.
138
+ * `expr_invalid`: the text is not a valid expression, or names what the type does not declare;
139
+ * `expr_type`: a value of the wrong kind, or out of its domain, met during evaluation; `expr_limit`: a bound
140
+ * of the language was exceeded. The message says what, in words; only the code is part of the contract.
92
141
  */
93
- declare class NiadraError extends Error {
94
- readonly name: string;
95
- }
96
- /** The client was built without a usable API key, or with an option the SDK cannot honour. */
97
- declare class NiadraConfigError extends NiadraError {
98
- readonly name = "NiadraConfigError";
99
- }
100
- /** A request failed validation before it left the process. Nothing was sent. */
101
- declare class NiadraValidationError extends NiadraError {
102
- readonly name = "NiadraValidationError";
103
- }
104
- /** The request did not finish within its time budget. */
105
- declare class NiadraTimeoutError extends NiadraError {
106
- readonly timeoutMs: number;
107
- readonly name = "NiadraTimeoutError";
108
- constructor(timeoutMs: number);
109
- }
110
- /** The network call failed before an HTTP response arrived (DNS, TLS, reset connection). */
111
- declare class NiadraConnectionError extends NiadraError {
112
- readonly name = "NiadraConnectionError";
113
- }
114
- /** The request was cancelled through the caller's `AbortSignal`. */
115
- declare class NiadraAbortError extends NiadraError {
116
- readonly name = "NiadraAbortError";
142
+ declare class ExprError extends NiadraError {
143
+ readonly code: ExprErrorCode;
144
+ readonly name = "ExprError";
145
+ constructor(code: ExprErrorCode, message: string);
146
+ }
147
+ /** The kind of a present value; business days and a quote exist only inside an expression. */
148
+ type Kind = "bool" | "number" | "string" | "duration" | "date" | "datetime" | "list" | "business_days" | "quote";
149
+ /** A named list of holidays and the weekdays that are never business days. */
150
+ interface Calendar {
151
+ /** Days since 1970-01-01, as `parseDate` gives them. */
152
+ readonly holidays?: ReadonlySet<number>;
153
+ /** ISO weekdays (1 is Monday) that are never business days; Saturday and Sunday unless given. */
154
+ readonly weekend?: ReadonlySet<number>;
155
+ }
156
+ /** A whole count of business days on a calendar, to add to or subtract from a date. */
157
+ interface BusinessDays {
158
+ readonly count: number;
159
+ readonly calendar: Calendar;
160
+ }
161
+ interface Unknown {
162
+ readonly logic: UnknownLogic;
163
+ readonly kind?: undefined;
164
+ }
165
+ interface Absent {
166
+ readonly logic: "no";
167
+ readonly kind?: undefined;
168
+ /** The declared name of the absence, when there is one. */
169
+ readonly absent?: string;
170
+ }
171
+ interface Bool {
172
+ readonly logic: "yes" | "no";
173
+ readonly kind: "bool";
174
+ readonly datum: boolean;
175
+ }
176
+ interface Present<K extends Kind, D> {
177
+ readonly logic: "yes";
178
+ readonly kind: K;
179
+ readonly datum: D;
180
+ }
181
+ type DateValue = Present<"date", number>;
182
+ type DatetimeValue = Present<"datetime", number>;
183
+ /**
184
+ * A value and its logical value. A known value is present (`yes`, or a boolean, `no` when false) or absent
185
+ * (`no` with no kind, and the declared name of the absence when there is one); an unknown one carries
186
+ * nothing.
187
+ *
188
+ * Data: a boolean, a number (an IEEE 754 double), a string, whole milliseconds for a duration, days since
189
+ * 1970-01-01 for a date, milliseconds since the epoch for a datetime, the values of a list, a count on a
190
+ * calendar for business days, and the slots of a quote by field.
191
+ */
192
+ type Value$1 = Unknown | Absent | Bool | Present<"number", number> | Present<"string", string> | Present<"duration", number> | DateValue | DatetimeValue | Present<"list", readonly Value$1[]> | Present<"business_days", BusinessDays> | Present<"quote", Readonly<Record<string, Slot>>>;
193
+ /**
194
+ * One field, computed value, time axis or input of an object as a reading sees it: the value, when a
195
+ * source observed it (`at`, milliseconds since the epoch), by whom, its value before the latest change, and
196
+ * the completeness level of a content field.
197
+ */
198
+ interface Slot {
199
+ readonly value: Value$1;
200
+ readonly at?: number;
201
+ /** `machine`, `human` or `source:<name>`. */
202
+ readonly observer?: string;
203
+ readonly was?: Value$1;
204
+ readonly completeness?: string;
117
205
  }
118
206
  /**
119
- * The API answered with an error status. `code` comes from the problem document when the
120
- * server sent one; `requestId` is what Niadra support needs to find the call.
207
+ * What an evaluation reads (`spec/object-type.md`, section 5.11): the current instant, the object's slots
208
+ * (fields, computed values and time axes by name), the declared inputs by dotted path, the absence names,
209
+ * the company's configuration by key, the reader's quotes by source, the calendars by name, and the
210
+ * context names.
121
211
  */
122
- declare class NiadraAPIError extends NiadraError {
212
+ interface Environment {
213
+ /** Milliseconds since the epoch. */
214
+ readonly now: number;
215
+ /** Minutes east of UTC, where a date's day starts; 0 unless given. */
216
+ readonly utcOffsetMin?: number;
217
+ readonly fields?: Readonly<Record<string, Slot>>;
218
+ readonly inputs?: Readonly<Record<string, Slot>>;
219
+ readonly absentNames?: ReadonlySet<string>;
220
+ readonly config?: Readonly<Record<string, Value$1>>;
221
+ readonly quotes?: Readonly<Record<string, Readonly<Record<string, Slot>>>>;
222
+ readonly calendars?: Readonly<Record<string, Calendar>>;
223
+ /** The lifecycle state; absent unless given. */
224
+ readonly state?: string;
225
+ readonly derivedStatus?: string;
226
+ /** 0 unless given. */
227
+ readonly watchCount?: number;
228
+ /** The read's purpose; `display` unless given. */
229
+ readonly purpose?: string;
230
+ /** The object's best position presented in the conversation. */
231
+ readonly presentedRank?: number;
232
+ }
233
+ /** `true` or `false`: `yes` or `no`, of kind `bool`. */
234
+ declare const boolean: (flag: boolean) => Value$1;
235
+ /** A value nobody observed, or one whose source is known to get it wrong. */
236
+ declare const unknown: (logic: UnknownLogic) => Value$1;
237
+ /** An absence: the source affirmed there is no value, under a declared name when it gives one. */
238
+ declare const absent: (name?: string) => Value$1;
239
+ interface NameNode {
240
+ readonly node: "name";
241
+ readonly parts: readonly [string, ...string[]];
242
+ }
243
+ type Comparison = "==" | "!=" | "<" | "<=" | ">" | ">=" | "in";
244
+ /** A call, with each function's arguments in their fixed form (`spec/object-type.md`, section 5.7). */
245
+ type Call = {
246
+ readonly node: "call";
247
+ readonly fn: "now";
248
+ } | {
249
+ readonly node: "call";
250
+ readonly fn: "age" | "observer" | "changed";
251
+ readonly ref: NameNode;
252
+ } | {
253
+ readonly node: "call";
254
+ readonly fn: "was" | "count";
255
+ readonly arg: Node;
256
+ } | {
257
+ readonly node: "call";
258
+ readonly fn: "business_days";
259
+ readonly count: Node;
260
+ readonly calendar: string;
261
+ } | {
262
+ readonly node: "call";
263
+ readonly fn: "quote";
264
+ readonly source: string;
265
+ } | {
266
+ readonly node: "call";
267
+ readonly fn: "presented_in_top";
268
+ readonly top: number;
269
+ } | {
270
+ readonly node: "call";
271
+ readonly fn: "sha256";
272
+ readonly args: readonly Node[];
273
+ };
274
+ /** The syntax tree of an expression (`spec/object-type.md`, section 5.3), as `parse` gives it. */
275
+ type Node = {
276
+ readonly node: "literal";
277
+ readonly value: Value$1;
278
+ } | {
279
+ readonly node: "logical";
280
+ readonly logic: Logic;
281
+ } | NameNode | {
282
+ readonly node: "member";
283
+ readonly target: Node;
123
284
  readonly name: string;
124
- readonly status: number;
125
- readonly code: string;
126
- readonly requestId: string | null;
127
- readonly problem: Problem | null;
128
- /** How long the server asked callers to wait, from `Retry-After`, when it said so. */
129
- readonly retryAfterMs: number | null;
130
- constructor(status: number, problem: Problem | null, requestId: string | null, retryAfterMs?: number | null);
131
- }
132
- /** 401: the key is missing, malformed, rotated or revoked. */
133
- declare class NiadraAuthenticationError extends NiadraAPIError {
134
- readonly name = "NiadraAuthenticationError";
135
- }
136
- /** 403: the key is valid but lacks the scope, or its source was cut off. */
137
- declare class NiadraPermissionError extends NiadraAPIError {
138
- readonly name = "NiadraPermissionError";
139
- }
140
- /** 429: over the rate limit. Batches wait `retryAfterMs` before trying again. */
141
- declare class NiadraRateLimitError extends NiadraAPIError {
142
- readonly name = "NiadraRateLimitError";
143
- }
144
-
145
- /** The read side: `POST /v1/context` and the history navigation calls. */
285
+ } | Call | {
286
+ readonly node: "list";
287
+ readonly items: readonly Node[];
288
+ } | {
289
+ readonly node: "not";
290
+ readonly operand: Node;
291
+ } | {
292
+ readonly node: "boolean";
293
+ readonly op: "and" | "or";
294
+ readonly operands: readonly Node[];
295
+ } | {
296
+ readonly node: "compare";
297
+ readonly op: Comparison;
298
+ readonly left: Node;
299
+ readonly right: Node;
300
+ } | {
301
+ readonly node: "arith";
302
+ readonly op: "+" | "-";
303
+ readonly left: Node;
304
+ readonly right: Node;
305
+ };
306
+ /** Names a type may not give a field, a value, a time axis or an absence (`spec/object-type.md`, section 5.5). */
307
+ declare const RESERVED: ReadonlySet<string>;
308
+ /** The syntax tree of an expression, or `ExprError` (`expr_invalid`, `expr_limit`). */
309
+ declare function parse(text: string): Node;
310
+ /**
311
+ * The value of a parsed expression over an environment, or `ExprError` (`expr_type`, `expr_limit`). A
312
+ * business-day count or a quote is a step, never a result.
313
+ */
314
+ declare function evaluate(node: Node, env: Environment): Value$1;
315
+ /** A `YYYY-MM-DD` date as days since 1970-01-01; a `RangeError` for anything else. */
316
+ declare function parseDate(text: string): number;
317
+ /** A day since 1970-01-01 as `YYYY-MM-DD`. */
318
+ declare function formatDate(days: number): string;
319
+ /**
320
+ * An RFC 3339 time with its offset as milliseconds since the epoch; digits below the millisecond are
321
+ * dropped. A `RangeError` for anything else, a time without an offset included.
322
+ */
323
+ declare function parseDatetime(text: string): number;
324
+ /** The canonical form of an instant: UTC, with milliseconds (`2026-09-29T12:00:00.000Z`). */
325
+ declare function formatDatetime(ms: number): string;
326
+ /**
327
+ * What a type declares, as the names of its expressions resolve: its fields with their kind (`null` when
328
+ * the declaration fixes none), the fields with completeness levels, computed values, time axes, absence
329
+ * names, inputs, states, and sources with their kind (`pull`, `quote`...).
330
+ */
331
+ interface Scope {
332
+ readonly fields?: Readonly<Record<string, Kind | null>>;
333
+ readonly completeness?: ReadonlySet<string>;
334
+ readonly values?: ReadonlySet<string>;
335
+ readonly axes?: ReadonlySet<string>;
336
+ readonly absentNames?: ReadonlySet<string>;
337
+ readonly inputs?: ReadonlySet<string>;
338
+ readonly states?: ReadonlySet<string>;
339
+ readonly sources?: Readonly<Record<string, string>>;
340
+ }
341
+ /** What an entry of a type expects its expression to give: anything, a condition, or a time. */
342
+ type Expect = "any" | "condition" | "time";
343
+ /**
344
+ * Parses and resolves an expression of a type declaration (`spec/object-type.md`, section 5.12);
345
+ * `expr_invalid` names what is wrong.
346
+ */
347
+ declare function compileExpression(text: string, scope: Scope, expect?: Expect): Node;
348
+ /** A duration literal (`30s`, `10min`, `24h`, `7d`) in milliseconds, as the declarations write them. */
349
+ declare function durationMs(text: string): number;
146
350
 
147
- /** The model that will read the pack, so the server can aim at its prompt-cache floor. */
148
- interface TargetModel {
149
- provider: string;
150
- model: string;
151
- }
152
- /** Body of `POST /v1/context`. Exactly one of `subject` or `object` is required. */
153
- interface ContextRequest {
154
- subject?: Handle | null;
155
- object?: ObjectRef | null;
156
- /** The account or partner the person acts for. */
157
- about?: Handle | null;
158
- view?: View;
159
- verification?: Verification;
160
- conversation_id?: string | null;
161
- task_id?: string | null;
162
- query?: string | null;
163
- delta?: boolean;
164
- target?: TargetModel | null;
165
- known_etag?: string | null;
166
- }
167
- interface VerificationResult {
168
- requested: Verification;
169
- effective: Verification;
170
- /** Why `effective` is lower than `requested`: `source_ceiling` or `not_proven`. */
171
- reason?: string | null;
172
- }
173
- /** A recent turn from another channel that the compiled pack has not absorbed yet. */
174
- interface LiveTurn {
175
- at: string;
176
- channel: string;
177
- kind: EventKind;
178
- speaker: string;
179
- text: string;
180
- source_id: string;
181
- }
182
- /** Where a prompt-cache breakpoint may go, and whether caching this pack is worth it. */
183
- interface CacheDirectives {
184
- /** Character offsets into `text` where a cache breakpoint may be placed. */
185
- breakpoints: number[];
186
- ttl_seconds?: number | null;
187
- floor_tokens?: number | null;
188
- cacheable: boolean;
189
- /** Stable cache salt for self-hosted inference engines. */
190
- salt: string;
191
- }
192
- /** Body of a `POST /v1/context` response. */
193
- interface ContextResponse {
194
- /** `true` when `known_etag` still matches; `text` is then omitted. */
195
- not_modified: boolean;
196
- text?: string | null;
197
- variables: Record<string, string>;
198
- version: string;
199
- etag: string;
200
- manifest_hash?: string | null;
201
- as_of?: string | null;
202
- lag_seconds?: number | null;
203
- coverage: SourceCoverage[];
204
- verification: VerificationResult;
205
- /** How many items policy or verification kept out of the pack. */
206
- withheld: number;
207
- live: LiveTurn[];
208
- live_complete: boolean;
209
- delta?: string | null;
210
- cache?: CacheDirectives | null;
211
- timing: Record<string, number>;
212
- path: DeliveryPath;
213
- degraded: boolean;
214
- }
215
- interface HistoryFilters {
216
- since?: string | null;
217
- until?: string | null;
218
- channels?: string[];
219
- categories?: string[];
220
- item_kinds?: HistoryItemKind[];
221
- outcome?: string | null;
222
- object?: ObjectRef | null;
223
- }
224
- /** Body of `POST /v1/history/search`. */
225
- interface SearchRequest {
226
- subject: Handle;
227
- about?: Handle | null;
228
- /** Between 1 and 2,000 characters. */
229
- query: string;
230
- filters?: HistoryFilters;
231
- /** Token budget for the answer, between 50 and 4,000. Defaults to 800. */
232
- max_tokens?: number;
233
- verification?: Verification;
234
- conversation_id?: string | null;
235
- task_id?: string | null;
236
- }
237
- interface HistoryItem {
238
- id: string;
239
- kind: string;
240
- text: string;
241
- at: string;
242
- channel?: string | null;
243
- source_id?: string | null;
244
- outcome?: string | null;
245
- confidence?: number | null;
246
- origin_event_id?: string | null;
247
- }
248
- /** How often the same kind of issue came back, computed by the same rule as the recurring-complaint pattern. */
249
- interface Recurrence {
250
- category: string;
251
- occurrences: number;
252
- window_days: number;
253
- last_at?: string | null;
254
- last_outcome?: string | null;
255
- last_resolution?: string | null;
256
- }
257
- interface SearchResponse {
258
- items: HistoryItem[];
259
- recurrence?: Recurrence | null;
260
- withheld: number;
261
- as_of?: string | null;
262
- tokens_used: number;
263
- /** `text_only` when semantic search was unavailable and only keyword matching ran. */
264
- degraded?: string | null;
265
- }
266
- /** Body of `POST /v1/history/timeline`. */
267
- interface TimelineRequest {
268
- subject: Handle;
269
- about?: Handle | null;
270
- filters?: HistoryFilters;
271
- cursor?: string | null;
272
- /** Between 1 and 100. Defaults to 20. */
273
- limit?: number;
274
- verification?: Verification;
275
- conversation_id?: string | null;
351
+ type expr_BusinessDays = BusinessDays;
352
+ type expr_Calendar = Calendar;
353
+ type expr_Environment = Environment;
354
+ type expr_Expect = Expect;
355
+ type expr_ExprError = ExprError;
356
+ declare const expr_ExprError: typeof ExprError;
357
+ type expr_ExprErrorCode = ExprErrorCode;
358
+ type expr_Kind = Kind;
359
+ type expr_Node = Node;
360
+ declare const expr_RESERVED: typeof RESERVED;
361
+ type expr_Scope = Scope;
362
+ type expr_Slot = Slot;
363
+ declare const expr_absent: typeof absent;
364
+ declare const expr_boolean: typeof boolean;
365
+ declare const expr_compileExpression: typeof compileExpression;
366
+ declare const expr_durationMs: typeof durationMs;
367
+ declare const expr_evaluate: typeof evaluate;
368
+ declare const expr_formatDate: typeof formatDate;
369
+ declare const expr_formatDatetime: typeof formatDatetime;
370
+ declare const expr_parse: typeof parse;
371
+ declare const expr_parseDate: typeof parseDate;
372
+ declare const expr_parseDatetime: typeof parseDatetime;
373
+ declare const expr_unknown: typeof unknown;
374
+ declare namespace expr {
375
+ export { type expr_BusinessDays as BusinessDays, type expr_Calendar as Calendar, type expr_Environment as Environment, type expr_Expect as Expect, expr_ExprError as ExprError, type expr_ExprErrorCode as ExprErrorCode, type expr_Kind as Kind, type expr_Node as Node, expr_RESERVED as RESERVED, type expr_Scope as Scope, type expr_Slot as Slot, type Value$1 as Value, expr_absent as absent, expr_boolean as boolean, expr_compileExpression as compileExpression, expr_durationMs as durationMs, expr_evaluate as evaluate, expr_formatDate as formatDate, expr_formatDatetime as formatDatetime, expr_parse as parse, expr_parseDate as parseDate, expr_parseDatetime as parseDatetime, expr_unknown as unknown };
276
376
  }
377
+
277
378
  /**
278
- * Body of `POST /v1/history/open`. A conversation id may be a phone number or an e-mail, and the
279
- * customer is personal data, so neither goes in a URL.
379
+ * Decimals for the amounts the parser reads: `R$ 511,06` is 51106 hundredths, never a float, so every SDK
380
+ * writes and compares the same `"511.06"`. Arithmetic and the written form keep 28 significant digits, as
381
+ * the default context of Python's `decimal` does.
280
382
  */
281
- interface OpenItemRequest {
282
- item_id: string;
283
- /** The customer the item must belong to; any other item answers 404. */
284
- subject?: Handle | null;
285
- verification?: Verification;
286
- conversation_id?: string | null;
287
- }
288
- interface TimelineResponse {
289
- items: HistoryItem[];
290
- next_cursor?: string | null;
291
- withheld: number;
292
- as_of?: string | null;
293
- }
294
- /** A commitment recorded in an episode, made by the company or by the customer. */
295
- interface Commitment {
296
- by: "company" | "customer";
297
- what: string;
298
- due_at?: string | null;
299
- status: string;
300
- }
301
- /** One history item opened in full: structured summary, outcome and commitments. */
302
- interface OpenedItem {
303
- id: string;
304
- kind: "episode" | "object";
305
- summary: string;
306
- requested?: string | null;
307
- promises: Commitment[];
308
- outcome?: string | null;
309
- resolution?: string | null;
310
- derived: HistoryItem[];
311
- timeline: HistoryItem[];
312
- /** The server no longer sends a transcript excerpt; the field stays for code that reads it. */
313
- excerpt?: string | null;
314
- as_of?: string | null;
315
- }
316
- /** The derived state of a business object, from `GET /v1/objects/{type}/{namespace}/{id}`. */
317
- interface ObjectState {
318
- ref: ObjectRef;
319
- state: Record<string, unknown>;
320
- as_of: string;
321
- source_id: string;
322
- record_ref?: string | null;
323
- open_items: HistoryItem[];
324
- }
325
- /** System events and agent actions about one object, newest first; never conversation content. */
326
- interface ObjectTimeline {
327
- ref: ObjectRef;
328
- items: HistoryItem[];
329
- next_cursor?: string | null;
330
- as_of?: string | null;
331
- }
332
- /** A function-calling tool definition in the JSON Schema shape most model APIs accept. */
333
- interface ToolDefinition {
334
- type: "function";
335
- function: {
336
- name: string;
337
- description: string;
338
- parameters: Record<string, unknown>;
339
- };
383
+ /** `digits / 10 ** scale`; a negative scale multiplies. */
384
+ interface Decimal {
385
+ readonly digits: bigint;
386
+ readonly scale: number;
340
387
  }
341
388
 
342
- /** Arguments of `context()`. Pass exactly one of `subject` or `object`. */
343
- interface ContextParams {
344
- /** The customer, by any handle the server knows. */
345
- subject?: Handle;
346
- /** A business object, such as an invoice, when the task is about the object rather than a person. */
347
- object?: ObjectRef | string;
348
- /** The account or partner the person acts for. Requires an active link between the two. */
349
- about?: Handle;
350
- /** Defaults to `chat`. */
351
- view?: View;
352
- /**
353
- * The level proven in this conversation. The server may answer with a lower effective level
354
- * when the source's ceiling is lower; see `response.verification`.
355
- */
356
- verification?: Verification;
357
- /** Enables the per-conversation cache and the server's pinning of the pack. */
358
- conversation_id?: string;
359
- /** For internal agents: the task plays the role of the conversation. */
360
- task_id?: string;
361
- /** What the turn is about, so selection can favour relevant history. Up to 2,000 characters. */
362
- query?: string;
363
- /** Ask only for what changed since this source last read the subject. */
364
- delta?: boolean;
365
- /** The model that will read the pack, so the server can size it for that model's prompt cache. */
366
- target?: TargetModel;
367
- }
368
- /** Per-call options shared by every read method. */
369
- interface RequestOptions {
370
- /** Overrides the method's default time budget, in milliseconds. */
371
- timeout?: number | undefined;
372
- /** Cancels the wait. A request shared with other callers keeps running for them. */
373
- signal?: AbortSignal | undefined;
374
- /** Extra headers, such as a W3C `traceparent`. */
375
- headers?: Record<string, string> | undefined;
376
- }
377
- interface ContextOptions extends RequestOptions {
378
- /** Pass `false` to skip the per-conversation cache for this call. */
379
- cache?: boolean | undefined;
380
- }
381
389
  /**
382
- * Where a `context()` result came from.
390
+ * Offsets, words and sentences of an output, as every part of the claim checker reads them.
383
391
  *
384
- * - `network`: a response the server just sent (or confirmed unchanged).
385
- * - `cache`: a pack younger than the cache TTL; no request was made.
386
- * - `stale`: an older pack returned at once while a background request refreshes it.
387
- * - `fallback`: the request failed and this is the last good pack for the conversation.
388
- * - `none`: nothing was available; `text` is empty and `error` says why.
392
+ * Offsets are Unicode code points (the claim contract spec, section 2). The checker reads a text as one
393
+ * UTF-16 unit per code point (`units`), so every index a regular expression returns is a code point offset.
394
+ * Its patterns read `\w`, `\d`, `\s` and `\b` as Python's `re` does on text (`pattern`): the SDKs and the
395
+ * server's reference checker find the same numbers in the same places.
389
396
  */
390
- type ContextSource = "network" | "cache" | "stale" | "fallback" | "none";
391
- /** What `context()` resolves to. Always usable: on failure `text` is an empty string. */
392
- interface ContextResult {
393
- /** The pack, ready for the system prompt. Empty when there is nothing to inject. */
394
- text: string;
395
- /**
396
- * The parts that change turn by turn and belong at the end of the prompt, after the
397
- * conversation: the delta and the live turns from other channels. Empty when there are none.
398
- */
399
- suffix: string;
400
- /** Named values from the pack, for templates that place them individually. */
401
- variables: Record<string, string>;
402
- source: ContextSource;
403
- /** The response this result was built from; `null` when `source` is `none`. */
404
- response: ContextResponse | null;
405
- /** What went wrong, when `source` is `fallback` or `none`. */
406
- error: NiadraError | null;
407
- }
397
+ /** A start and an end, in code points, end excluded. */
398
+ type Span = readonly [number, number];
399
+
408
400
  /**
409
- * Renders the delta and the live turns for the end of the prompt. Kept outside the pinned
410
- * pack so that the prompt prefix stays byte-identical across turns and the model provider's
411
- * prompt cache keeps hitting. Returns an empty string when there is nothing to add.
401
+ * Numbers written in words, in Portuguese, English and Spanish, from zero to the millions: "quinze", "dois
402
+ * mil e quinhentos", "twenty-five", "doscientos treinta". The parser reads them only right before a unit, a
403
+ * currency or a percent word ("quinze dias úteis", "trezentos reais"): a number word alone is never a number,
404
+ * because "um", "one" and "un" are also articles.
412
405
  */
413
- declare function renderSuffix(response: ContextResponse): string;
406
+
407
+ type Language = "pt" | "en" | "es";
408
+
414
409
  /**
415
- * Renders the live turns (recent turns from other channels that the pack has not absorbed
416
- * yet) as one tagged block, or an empty string when there are none. `complete="false"` tells
417
- * the model the list may be missing turns because the server could not read all of them.
410
+ * The numbers of an output, read by rules (the claim contract spec, section 5): each one with its class,
411
+ * its normalized value and its span, in Portuguese, English or Spanish.
412
+ *
413
+ * Every number of the text lands in at most one mention, found in this order, and a later step never takes
414
+ * what an earlier one took:
415
+ *
416
+ * 1. labels by shape: a case number, a postal code, a tax id, a phone, a time of day;
417
+ * 2. labels by the word before them: an order, a protocol, a statute's article, a size, a list position;
418
+ * 3. dates: ISO, numeric (day first in `pt` and `es`, month first in `en`), with month names, a month of a
419
+ * year, "dia 20";
420
+ * 4. amounts with what follows or precedes them: money (a currency before or after, a scale like "mil"),
421
+ * percent, duration, dose, quantity, installments ("10x"); written in digits, or in words right before
422
+ * the unit; two of them joined by "a", "to", "-" (or "e", "and", "y" after "entre", "between") make a
423
+ * range;
424
+ * 5. codes that mix letters and digits, and ordinals: labels;
425
+ * 6. the rest: a number with two decimals is money; an integer before a word is a count; five digits or
426
+ * more, a leading zero or a year are labels; anything else is not read.
427
+ *
428
+ * A label is never a claim and is never rewritten.
418
429
  */
419
- declare function renderLive(response: ContextResponse): string;
430
+
431
+ declare const LANGUAGES: readonly Language[];
432
+ /** What a number measures; a `label` names something instead. */
433
+ type MentionClass = "money" | "percent" | "date" | "duration" | "quantity" | "count" | "dosage" | "label";
434
+ /** A number's normalized value (the claim contract spec, section 5.3), as vectors and turn records write it. */
435
+ type Value = Readonly<Partial<Record<"amount" | "min" | "max" | "unit" | "date" | "date_from" | "date_to", string>>>;
436
+ interface MentionFields {
437
+ amount?: Decimal;
438
+ low?: Decimal;
439
+ high?: Decimal;
440
+ unit?: string | null;
441
+ date?: string;
442
+ dateFrom?: string;
443
+ dateTo?: string;
444
+ written?: "digits" | "words";
445
+ }
446
+ /** A number of an output: its class, its span in code points and its value. */
447
+ declare class Mention {
448
+ readonly cls: MentionClass;
449
+ readonly start: number;
450
+ readonly end: number;
451
+ /** Decimals as `decimalText` writes them. */
452
+ readonly amount: string | null;
453
+ readonly low: string | null;
454
+ readonly high: string | null;
455
+ readonly unit: string | null;
456
+ readonly date: string | null;
457
+ readonly dateFrom: string | null;
458
+ readonly dateTo: string | null;
459
+ readonly written: "digits" | "words";
460
+ constructor(cls: MentionClass, start: number, end: number, fields?: MentionFields);
461
+ /** The normalized value; a label has none. */
462
+ value(): Value | null;
463
+ get isRange(): boolean;
464
+ }
465
+ /** The numbers of `text` in the language `lang`, in the order they appear; offsets are code points. */
466
+ declare function mentions(text: string, lang: Language): readonly Mention[];
420
467
 
421
468
  /**
422
- * The write side: items of `POST /v1/batch`. A batch mixes item types, and one bad item never
423
- * fails the batch; the server answers 207 with one error per rejected item.
469
+ * A number's role, from the words around it (the claim contract spec, section 6): the same R$ 511,06 is a
470
+ * full price, a discounted one or a price per person by what the sentence says next to it.
471
+ *
472
+ * A role's term counts within `WINDOW` words of the number, in the same sentence, and belongs to the nearest
473
+ * number of the same class (to both when two are as near). The nearest term gives the role, and at the same
474
+ * distance a term of the number's own beats one it shares; two terms of different roles still tied leave the
475
+ * number without one, `ambiguous`, which is never approved.
424
476
  */
425
477
 
426
- /** Longest text the server accepts in `content.text` or `content.transcript`. */
427
- declare const MAX_EVENT_TEXT = 200000;
428
- /** Largest batch the server accepts. */
429
- declare const MAX_BATCH_ITEMS = 500;
430
- /** Largest file `POST /v1/media/uploads` reserves room for: 500 MiB. */
431
- declare const MAX_MEDIA_BYTES: number;
432
- interface SpeakerRef {
433
- role: Speaker;
434
- /** Agent or attendant id inside the source. */
435
- id?: string | null;
436
- }
437
- interface Content {
438
- type?: "text" | "audio" | "image" | "file";
439
- text?: string | null;
440
- /** Reference returned by `/v1/media/uploads`; the media itself never travels in the event. */
441
- media_ref?: string | null;
442
- /** Lowercase hex SHA-256 of the media. */
443
- media_sha256?: string | null;
444
- transcript?: string | null;
445
- /** Speech-to-text confidence between 0 and 1. Low-confidence agent turns are not measured. */
446
- stt_confidence?: number | null;
447
- }
448
- interface VoiceInfo {
449
- ani?: string | null;
450
- dnis?: string | null;
451
- trunk?: string | null;
452
- network_attestation?: "A" | "B" | "C" | null;
453
- answered_at?: string | null;
454
- ended_at?: string | null;
455
- end_reason?: string | null;
456
- recording_ref?: string | null;
457
- turn_offset_ms?: number | null;
458
- }
478
+ /** Words between a number and a term of its role, at most. */
479
+ declare const WINDOW = 6;
480
+ interface Role {
481
+ readonly name: string | null;
482
+ readonly status: "matched" | "ambiguous" | "none";
483
+ }
484
+ /** The role of each of `numbers` (a category's mentions, in order), by the terms of `roles`. */
485
+ declare function rolesOf(text: string, numbers: readonly Mention[], roles: Readonly<Record<string, readonly string[]>>): Role[];
486
+
459
487
  /**
460
- * The open item an action fulfils. Pass either `item_id`, or `object` together with the
461
- * canonical `operation`; the server rejects any other combination.
488
+ * The claim check (the claim contract spec, sections 4 to 8): the claims each category detects in an
489
+ * output, their nature, the verdict against what the turn holds, and the action the contract takes for the
490
+ * output's context.
491
+ *
492
+ * Detection: numbers of the category's classes (in a sentence with one of its terms, when it lists terms)
493
+ * that the output asserts (a hedged number, `hedges.ts`, is no claim), each occurrence of a term (when it
494
+ * lists terms and no classes), statute and precedent citations, and the sentences of named document
495
+ * sections. Nature, for a number: `quoted` inside quotation marks; `computed`
496
+ * when the turn holds a value of the same role, or the same value; `model` otherwise. Verdicts that stand
497
+ * (`matched`, `quoted_found`, `anchored`) take no action; `not_checked` is counted; every other one takes the
498
+ * category's action for the context, and `unsupported` the action its natures give to what the model said.
499
+ * A rewrite happens only when it is unequivocal (a stale copy of one field whose fresh value differs), and
500
+ * is a warning otherwise. Nothing is ever rewritten in an immutable output, and a block there sends the
501
+ * whole output to a person, untouched.
462
502
  */
463
- interface Closes {
464
- item_id?: string | null;
465
- object?: ObjectRef | null;
466
- operation?: string | null;
467
- }
468
- interface ActionInfo {
469
- /** Canonical operation, such as `credit` or `reschedule`. */
470
- operation: string;
471
- /** What happened, up to 2,000 characters. */
472
- result?: string | null;
473
- purpose?: string | null;
474
- closes?: Closes | null;
475
- corrects_action_id?: string | null;
503
+
504
+ type Verdict = ClaimRecord["verdict"];
505
+ /** What happened to a claim, as the turn record writes it. */
506
+ type Action = ClaimRecord["action"];
507
+ type Nature = NonNullable<ClaimRecord["nature"]>;
508
+ /** A value with provenance the turn holds: a field of a tool's result or of a state read. */
509
+ interface TurnValue {
510
+ readonly cls: MentionClass;
511
+ /** As `Mention.value()` writes it. */
512
+ readonly value: Value;
513
+ readonly role?: string | null;
514
+ /** True unless said otherwise. */
515
+ readonly fresh?: boolean;
516
+ readonly objectType?: string | null;
517
+ /** The field or computed value it is. */
518
+ readonly name?: string | null;
519
+ readonly callId?: string | null;
520
+ readonly ref?: string | null;
521
+ readonly declaredGaps?: readonly string[];
522
+ }
523
+ /** A passage an output cites, as the tool or the agent emitted it: where, what it quotes, from what. */
524
+ interface Anchor {
525
+ readonly start: number;
526
+ readonly end: number;
527
+ readonly quote: string;
528
+ readonly document: string;
529
+ }
530
+ /** What the turn holds to check an output against. */
531
+ interface Turn {
532
+ readonly values?: readonly TurnValue[];
533
+ /** The tools called in the turn. */
534
+ readonly tools?: readonly string[];
535
+ /** The documents in hand, by id: what quotes and anchors are checked against. */
536
+ readonly documents?: Readonly<Record<string, string>>;
537
+ readonly anchors?: readonly Anchor[];
538
+ /** The output's named sections, as spans, when it is a document. */
539
+ readonly sections?: Readonly<Record<string, readonly Span[]>>;
540
+ }
541
+ /** One claim a category found, its verdict and what happened to it. */
542
+ interface Finding {
543
+ readonly category: string;
544
+ readonly start: number;
545
+ readonly end: number;
546
+ readonly verdict: Verdict;
547
+ readonly action: Action;
548
+ /** For a number. */
549
+ readonly cls: MentionClass | null;
550
+ readonly nature: Nature | null;
551
+ readonly role: string | null;
552
+ readonly value: Value | null;
553
+ readonly evidence: TurnValue | Anchor | null;
554
+ }
555
+ /** The text the check reads, in its language and context (`chat`, `proposal`, `contestacao`). */
556
+ interface Output {
557
+ readonly text: string;
558
+ readonly lang: Language;
559
+ readonly context: string;
560
+ readonly immutable: boolean;
561
+ readonly agent?: string | null;
476
562
  }
477
563
  /**
478
- * Which context the agent's prompt carried and when it went in. Set on the agent's own turns
479
- * and actions, so measurement can tell a context that arrived after the agent spoke from one
480
- * it had and did not use.
564
+ * The same number: equal amounts (or ends of a range), or the same date; a unit only counts when both have
565
+ * one, so "511,06" is the R$ 511,06 of a tool's result.
481
566
  */
482
- interface ContextStamp {
483
- /** The etag of the pack in the prompt; absent when the prompt carried no pack. */
484
- etag?: string | null;
485
- injected_at: string;
486
- }
567
+ declare function sameValue(a: Value, b: Value): boolean;
487
568
  /**
488
- * What the model provider reported for the call behind an agent's turn. `wrap()` reads it from every
489
- * call it sees; without `wrap()`, pass it with the turn: `agent(text, { usage: response })` takes an
490
- * OpenAI or Anthropic response or a `ModelUsage`.
569
+ * `quoted` inside quotation marks; `computed` when the turn holds a value of the number's class with its
570
+ * role or its value; `model` otherwise.
491
571
  */
492
- interface ModelUsage {
493
- /** Who served the call, lowercase: `openai`, `anthropic`, a router or a cloud. */
494
- provider: string;
495
- /** The model the provider says answered, such as `gpt-4.1-2025-04-14`. */
496
- model: string;
497
- /** Every input token, cached ones included. */
498
- prompt_tokens: number;
499
- /** Input tokens read from the provider's prompt cache. */
500
- cached_tokens?: number;
501
- /** Input tokens written to the cache (Anthropic's cache creation). */
502
- cache_write_tokens?: number;
503
- }
504
- /** A message, a system event or an agent action, exactly as sent on the wire. */
505
- interface EventItem {
506
- type: "event";
507
- kind: EventKind;
508
- idempotency_key: string;
509
- channel: string;
510
- conversation_id?: string | null;
511
- conversation_aliases?: string[];
512
- task_id?: string | null;
513
- handles?: Handle[];
514
- subjects?: Subject[];
515
- object_refs?: ObjectRef[];
516
- speaker: SpeakerRef;
517
- direction?: "inbound" | "outbound" | null;
518
- content?: Content | null;
519
- occurred_at: string;
520
- visibility?: Visibility;
521
- verification_hint?: Verification | null;
522
- /** System events only, such as `invoice.credited`. */
523
- canonical_type?: string | null;
524
- /** Structured fields of a system event. */
525
- fields?: Record<string, unknown>;
526
- action?: ActionInfo | null;
527
- corrects_event_id?: string | null;
528
- voice?: VoiceInfo | null;
529
- context_stamp?: ContextStamp | null;
530
- /** The model call behind an `ai_agent` message: tokens and prompt cache. */
531
- usage?: ModelUsage | null;
532
- }
533
- /** States that several handles belong to the same subject. */
534
- interface IdentifyItem {
535
- type: "identify";
536
- idempotency_key: string;
537
- /** Between 2 and 16 handles. */
538
- handles: Handle[];
539
- method: AssertionMethod;
540
- subject_kind: SubjectKind;
541
- conversation_id?: string | null;
542
- occurred_at: string;
543
- }
544
- /** Raises the verification level of one conversation or task. The server never infers it. */
545
- interface VerifyItem {
546
- type: "verify";
547
- idempotency_key: string;
548
- method: VerifyMethod;
549
- level: Verification;
550
- conversation_id?: string | null;
551
- task_id?: string | null;
552
- handle: Handle;
553
- valid_until?: string | null;
554
- occurred_at: string;
555
- }
556
- interface ConversationEndedItem {
557
- type: "conversation.ended";
558
- idempotency_key: string;
559
- conversation_id: string;
560
- occurred_at: string;
561
- }
562
- interface TaskEndedItem {
563
- type: "task.ended";
564
- idempotency_key: string;
565
- task_id: string;
566
- occurred_at: string;
567
- }
568
- /** A transfer to a human or another agent. */
569
- interface HandoffItem {
570
- type: "handoff";
571
- idempotency_key: string;
572
- conversation_id: string;
573
- target: "human" | "agent";
574
- target_source?: string | null;
575
- reason?: string | null;
576
- mode: "warm" | "cold";
577
- occurred_at: string;
578
- }
579
- /** Periodic counter the SDK sends so the server can tell a quiet source from a broken one. */
580
- interface HeartbeatItem {
581
- type: "heartbeat";
582
- window_start: string;
583
- sent: number;
584
- }
585
- type BatchItem = EventItem | IdentifyItem | VerifyItem | ConversationEndedItem | TaskEndedItem | HandoffItem | HeartbeatItem;
586
- interface BatchRequest {
587
- items: BatchItem[];
588
- }
589
- interface ItemError {
590
- /** Position of the rejected item in the batch that was sent. */
591
- index: number;
592
- code: string;
593
- detail?: string | null;
594
- }
595
- interface BatchResponse {
596
- accepted: number;
597
- duplicates: number;
598
- errors: ItemError[];
599
- }
600
- /** Body of `POST /v1/media/uploads`. */
601
- interface MediaUploadRequest {
602
- content_type: string;
603
- /** Between 1 byte and 500 MiB. */
604
- size_bytes: number;
605
- /** Lowercase hex SHA-256 of the bytes. */
606
- sha256: string;
607
- /** Whose media it is. Stored under that person, so erasing them erases it too. */
608
- subject?: Handle | null;
609
- }
610
- /** Where to send the bytes: a short-lived signed URL, and the reference events carry afterwards. */
611
- interface MediaUploadResponse {
612
- media_ref: string;
613
- upload_url: string;
614
- /** Send exactly these headers with the bytes; the store refuses anything else. */
615
- upload_headers?: Record<string, string>;
616
- expires_at: string;
617
- }
618
- type FeedbackAction = "retract_fact" | "correct_fact" | "resolve_open_item" | "conversation_outcome";
619
- /** Body of `POST /v1/feedback`. The server records it as a `feedback.<action>` system event. */
620
- interface FeedbackRequest {
621
- idempotency_key: string;
622
- subject: Handle;
623
- action: FeedbackAction;
624
- fact_id?: string | null;
625
- open_item_id?: string | null;
626
- conversation_id?: string | null;
627
- /** Up to 2,000 characters. */
628
- value?: string | null;
629
- /** Up to 500 characters. */
630
- reason?: string | null;
631
- }
572
+ declare function natureOf(text: string, mention: Mention, role: Role, values: readonly TurnValue[]): Nature;
573
+ /** Every claim of `output` that a category detects, in the contract's order and then the text's. */
574
+ declare function check(categories: readonly ClaimCategory[], output: Output, turn?: Turn): Finding[];
575
+ /** The categories that detect anything in `output`: what a phrase of the negative corpus must never trigger. */
576
+ declare function detected(categories: readonly ClaimCategory[], output: Output): string[];
632
577
 
633
578
  /**
634
- * Turns what callers pass to `track()`, `identify()` and friends into batch items, applying the
635
- * same shape rules the server enforces. Catching a malformed event here means it is dropped
636
- * with a log line instead of occupying the queue and coming back as a 207 error.
579
+ * Hedges (the claim contract spec, section 5.4): a number the output says it cannot confirm, says as a value
580
+ * that no longer holds, or doubts, is not asserted, and no category detects it. "Não consigo confirmar se o
581
+ * frete de R$ 24,90 ainda vale" states no price.
582
+ *
583
+ * A number's clause is its sentence cut at clause breaks: a comma, semicolon or colon before a space, a
584
+ * parenthesis, a dash, and the clause words ("mas", "but", "porque"). A break inside a number does not count.
585
+ * A number is hedged when:
586
+ *
587
+ * 1. a denial stands before it in its clause ("não consigo confirmar", "I can't confirm", "whether");
588
+ * 2. it is the number of its clause nearest to a past marker ("o valor anterior", "previously listed"), on
589
+ * either side, within `WINDOW` words, with no word of the present between them ("now", "agora");
590
+ * 3. it is the number of its clause nearest before a doubt ("pode ter mudado", "has changed"), within
591
+ * `WINDOW` words;
592
+ * 4. its clause follows one that is only an opener ("Antes, ele estava em R$ 1.240,00");
593
+ * 5. its clause holds a past word ("foi", "was", "on file"), and a later clause of its sentence holds a
594
+ * denial followed by a word of continuity ("mas não consigo confirmar se esse total continua igual");
595
+ * 6. a negation stands right before it ("$689.00 per month, not $612.00").
596
+ *
597
+ * A hedge that governs something else leaves the number asserted: "O total é R$ 500, mas não consigo
598
+ * confirmar o prazo" states R$ 500. The words match whole words of the folded text, in sequence, with both
599
+ * apostrophes alike, and never inside a number.
637
600
  */
638
601
 
639
- /** An ISO 8601 string or a `Date`. */
640
- type Timestamp = string | Date;
641
- /** Fields shared by everything `track()` records. */
642
- interface EventBase {
643
- /** Where it happened, such as `whatsapp`, `voice`, `app` or `erp`. */
644
- channel: string;
645
- /** Provider message id, when there is one; otherwise the SDK mints a UUIDv7. */
646
- idempotency_key?: string;
647
- conversation_id?: string | null;
648
- /** Other ids the same conversation has in other systems. Up to 8. */
649
- conversation_aliases?: string[];
650
- task_id?: string | null;
651
- /** Up to 16. An event needs at least one handle, subject or object. */
652
- handles?: Handle[];
653
- /** Up to 8. */
654
- subjects?: Subject[];
655
- /** Up to 16. Accepts `type:namespace:id` strings. */
656
- object_refs?: (ObjectRef | string)[];
657
- /** Defaults to now. */
658
- occurred_at?: Timestamp;
659
- visibility?: Visibility;
660
- verification_hint?: Verification | null;
661
- corrects_event_id?: string | null;
662
- voice?: VoiceInfo | null;
663
- /**
664
- * Which context the agent acted on, for the agent's own turns and actions. Conversations and
665
- * tasks set it from `markInjected()`.
666
- */
667
- context_stamp?: ContextStamp | null;
668
- }
669
- /** An event for `track()`. `kind` defaults to `message`. */
670
- interface TrackEvent extends EventBase {
671
- kind?: EventKind;
672
- /** Who produced it. A bare role is shorthand for `{ role }`. */
673
- speaker: SpeakerRef | Speaker;
674
- /** Defaults to `inbound` for customer messages and `outbound` for agent messages. */
675
- direction?: "inbound" | "outbound" | null;
676
- content?: Content | null;
677
- /** Shorthand for `content: { type: "text", text }`. Cannot be combined with `content`. */
678
- text?: string;
679
- /** Required for `system_event`, such as `invoice.credited`. */
680
- canonical_type?: string | null;
681
- fields?: Record<string, unknown>;
682
- /** Required for `action`, and only valid there. */
683
- action?: ActionInfo | null;
684
- /** What the provider reported for the model call behind an `ai_agent` message; only valid there. */
685
- usage?: ModelUsage | null;
686
- }
687
- /** An agent action for `action()`: what an agent did in a system of record. */
688
- interface ActionEvent extends EventBase {
689
- /** Canonical operation, such as `credit` or `reschedule`. */
690
- operation: string;
691
- /** What happened, up to 2,000 characters. */
692
- result?: string | null;
693
- purpose?: string | null;
694
- /** The open item this action fulfils, which the server then marks resolved. */
695
- closes?: Closes | null;
696
- corrects_action_id?: string | null;
697
- /** Defaults to `ai_agent`. */
698
- speaker?: SpeakerRef | Speaker;
699
- }
700
- interface IdentifyParams {
701
- /** Between 2 and 16 handles that belong to the same subject. */
702
- handles: Handle[];
703
- /** Defaults to `explicit_identify`. */
704
- method?: AssertionMethod;
705
- /** Defaults to `person`. */
706
- subject_kind?: SubjectKind;
707
- conversation_id?: string | null;
708
- occurred_at?: Timestamp;
709
- idempotency_key?: string;
710
- }
711
- interface VerifyParams {
712
- /** The handle whose possession was proven. */
713
- handle: Handle;
714
- method: VerifyMethod;
715
- /** The level reached. It applies to this conversation or task only. */
716
- level: Verification;
717
- conversation_id?: string | null;
718
- task_id?: string | null;
719
- /** When the proof stops counting. */
720
- valid_until?: Timestamp | null;
721
- occurred_at?: Timestamp;
722
- idempotency_key?: string;
723
- }
724
- interface HandoffParams {
725
- conversation_id: string;
726
- target: "human" | "agent";
727
- /** The source that takes over, when it is integrated with Niadra. */
728
- target_source?: string | null;
729
- reason?: string | null;
730
- /** `warm` when the receiver gets a briefing. Defaults to `warm`. */
731
- mode?: "warm" | "cold";
732
- occurred_at?: Timestamp;
733
- idempotency_key?: string;
734
- }
735
- /** Arguments of `feedback()`: a correction of what Niadra derived about a subject. */
736
- interface FeedbackParams {
737
- subject: Handle;
738
- /**
739
- * `retract_fact` or `correct_fact` (with `fact_id`, and `value` for the right one),
740
- * `resolve_open_item` (with `open_item_id`) or `conversation_outcome` (with `conversation_id`
741
- * and `value`).
742
- */
743
- action: FeedbackAction;
744
- fact_id?: string | null;
745
- open_item_id?: string | null;
746
- conversation_id?: string | null;
747
- /** Up to 2,000 characters. */
748
- value?: string | null;
749
- /** Why, up to 500 characters. */
750
- reason?: string | null;
751
- idempotency_key?: string;
752
- }
602
+ /** The numbers of `numbers` (the output's mentions that are not labels) the output does not assert. */
603
+ declare function hedged(text: string, numbers: readonly Mention[]): ReadonlySet<Mention>;
753
604
 
754
605
  /**
755
- * Where the SDK reports what it swallowed in fail-open mode. Messages carry status codes,
756
- * error codes and request ids, never handles, message text or other personal data.
606
+ * The text anchor (the claim contract spec, section 9): how closely a quoted passage matches the document
607
+ * it cites.
608
+ *
609
+ * Both texts are normalized the same way: lower case, no accents, every run of anything but letters and
610
+ * digits one space, trimmed. The score is `1 - d / len(quote)`, where `d` is the fewest insertions, deletions
611
+ * and substitutions that turn the quote into some passage of the document (any start, any end), and an anchor
612
+ * holds at 0.90 or above. The distance runs as Myers' bit-parallel algorithm, linear in the document's length.
757
613
  */
758
- interface Logger {
759
- debug(message: string, ...details: unknown[]): void;
760
- warn(message: string, ...details: unknown[]): void;
761
- error(message: string, ...details: unknown[]): void;
762
- }
763
- /** Warnings and errors go to the console; debug output is off unless you pass your own logger. */
764
- declare const consoleLogger: Logger;
765
- declare const silentLogger: Logger;
614
+ /** An anchor holds at this score or above; a contract may ask for more, never less. */
615
+ declare const MIN_ANCHOR_MATCH = 0.9;
616
+ declare function normalize$1(text: string): string;
617
+ /** The edit distance between `pattern` and the passage of `text` nearest to it. */
618
+ declare function distance(pattern: string, text: string): number;
619
+ /** 1 when the normalized quote is a passage of the normalized document; 0 for an empty quote. */
620
+ declare function score(quote: string, document: string): number;
766
621
 
767
- /** When context first went into the prompt, and when the agent first spoke. */
768
- interface Timings {
769
- contextInjectedAt: Date | null;
770
- firstAgentTurnAt: Date | null;
771
- }
622
+ /**
623
+ * The claim contract's reference checker (`spec/claim-contract.md`), pure and without a model: the number and
624
+ * role parser, the hedges (a number the output does not assert), the category detection, the natures, verdicts
625
+ * and actions, and the text anchor. It passes the same conformance vectors as the server's and the Python
626
+ * SDK's (`spec/vectors/claim-*.v0.json`).
627
+ */
772
628
 
773
- /** The outcome of a call that may fail without throwing. Exactly one of the two fields is set. */
774
- type Result<T> = {
775
- data: T;
776
- error: null;
777
- } | {
778
- data: null;
779
- error: NiadraError;
780
- };
781
- /** Everything a tool call is bound to besides its arguments. None of it is visible to the model. */
782
- interface ToolBinding {
783
- about?: Handle;
784
- verification?: Verification;
785
- conversation_id?: string;
786
- task_id?: string;
787
- /** Use the voice time budget for the calls these tools make. */
788
- voice?: boolean;
629
+ type index_Action = Action;
630
+ type index_Anchor = Anchor;
631
+ type index_Finding = Finding;
632
+ declare const index_InternalText: typeof InternalText;
633
+ declare const index_LANGUAGES: typeof LANGUAGES;
634
+ type index_Language = Language;
635
+ declare const index_MIN_ANCHOR_MATCH: typeof MIN_ANCHOR_MATCH;
636
+ type index_Mention = Mention;
637
+ declare const index_Mention: typeof Mention;
638
+ type index_MentionClass = MentionClass;
639
+ type index_Nature = Nature;
640
+ type index_Output = Output;
641
+ type index_Role = Role;
642
+ type index_Span = Span;
643
+ type index_Turn = Turn;
644
+ type index_TurnValue = TurnValue;
645
+ type index_Value = Value;
646
+ type index_Verdict = Verdict;
647
+ declare const index_WINDOW: typeof WINDOW;
648
+ declare const index_check: typeof check;
649
+ declare const index_detected: typeof detected;
650
+ declare const index_distance: typeof distance;
651
+ declare const index_hedged: typeof hedged;
652
+ declare const index_mentions: typeof mentions;
653
+ declare const index_natureOf: typeof natureOf;
654
+ declare const index_rolesOf: typeof rolesOf;
655
+ declare const index_sameValue: typeof sameValue;
656
+ declare const index_score: typeof score;
657
+ declare const index_shingles: typeof shingles;
658
+ declare namespace index {
659
+ export { type index_Action as Action, type index_Anchor as Anchor, type index_Finding as Finding, index_InternalText as InternalText, index_LANGUAGES as LANGUAGES, type index_Language as Language, index_MIN_ANCHOR_MATCH as MIN_ANCHOR_MATCH, index_Mention as Mention, type index_MentionClass as MentionClass, type index_Nature as Nature, type index_Output as Output, type index_Role as Role, type index_Span as Span, type index_Turn as Turn, type index_TurnValue as TurnValue, type index_Value as Value, type index_Verdict as Verdict, index_WINDOW as WINDOW, index_check as check, index_detected as detected, index_distance as distance, index_hedged as hedged, index_mentions as mentions, index_natureOf as natureOf, normalize$1 as normalize, index_rolesOf as rolesOf, index_sameValue as sameValue, index_score as score, index_shingles as shingles };
789
660
  }
661
+
790
662
  /**
791
- * The navigation kit as function-calling tools, bound to one customer.
663
+ * A type derived from the company's own PostgreSQL schema (the object type spec, section 8), inside the
664
+ * company's boundary: the catalog is read, never a row, and neither the catalog nor the proposal leaves.
792
665
  *
793
- * The definitions have no parameter for the customer: the handle lives in this object, outside
794
- * the model's reach. A prompt injection that says "now look up customer X" has no argument to
795
- * put X in. The model chooses what to ask, never whom it is about.
666
+ * `derive()` turns one table's catalog into a proposed type, with the fingerprint of what it read and the
667
+ * review a person must do before the proposal goes up as a configuration change: triggers are code, and a
668
+ * CHECK that is not a list of values is not read. `changes()` is the drift report `niadra types derive
669
+ * --check` sends with the fingerprint: counts, and the names the declaration already holds, never the schema.
670
+ * It passes the spec's vectors (`spec/vectors/type-derive.v0.json`), as the Python SDK does.
796
671
  */
797
- interface BoundTools {
798
- /** Tool definitions in the `{ type: "function", function: { name, description, parameters } }` shape. */
799
- readonly definitions: ToolDefinition[];
800
- /** Whether `name` is one of these tools, for dispatchers that route several toolsets. */
801
- has(name: string): boolean;
802
- /**
803
- * Runs one tool call and returns the text to send back to the model as the tool result.
804
- * `args` may be the JSON string most model APIs return, or an already parsed object.
805
- * Failures come back as a short JSON error the model can read and move past; with
806
- * `strict: true` they are thrown instead.
807
- */
808
- call(name: string, args: string | Record<string, unknown>): Promise<string>;
672
+ type Json$2 = Record<string, unknown>;
673
+ /** A column as the catalog read lists it. */
674
+ interface CatalogColumn {
675
+ name: string;
676
+ type: string;
677
+ not_null: boolean;
678
+ enum?: string;
679
+ }
680
+ /** One table's catalog: its columns, keys, checks, enumerations and triggers, never a row. */
681
+ interface Catalog {
682
+ catalog: string;
683
+ table: string;
684
+ columns: CatalogColumn[];
685
+ primary_key: string[];
686
+ checks: string[];
687
+ enums: {
688
+ name: string;
689
+ labels: string[];
690
+ }[];
691
+ foreign_keys: {
692
+ columns: string[];
693
+ references: string;
694
+ referenced_columns: string[];
695
+ }[];
696
+ triggers: {
697
+ name: string;
698
+ definition: string;
699
+ enabled: boolean;
700
+ }[];
701
+ }
702
+ interface DeriveOptions {
703
+ /** The type's name; the table's by default. */
704
+ type?: string;
705
+ /** The system the type mirrors; `postgresql` by default. */
706
+ system?: string;
707
+ /** `subject` (the default) or `shared`: an agent's working state is never derived. */
708
+ ownership?: string;
709
+ }
710
+ /** A proposed type (it validates against `object-type.v0`), its catalog's fingerprint, and the review. */
711
+ interface Derived {
712
+ type: Json$2;
713
+ fingerprint: string;
714
+ review: Json$2[];
715
+ }
716
+ /** The counts `--check` sends with the fingerprint, and the declared fields they touch. */
717
+ interface Changes {
718
+ fields_added: number;
719
+ fields_removed: number;
720
+ fields_retyped: number;
721
+ states_added: number;
722
+ states_removed: number;
723
+ relations_added: number;
724
+ relations_removed: number;
725
+ key_changed: boolean;
726
+ fields: string[];
727
+ }
728
+ /** A catalog or an option the derivation refuses, named by `code`. */
729
+ declare class DeriveError extends Error {
730
+ readonly code: string;
731
+ constructor(code: string, message: string);
809
732
  }
810
- declare const TOOL_NAMES: {
811
- readonly search: "search_customer_history";
812
- readonly timeline: "get_customer_timeline";
813
- readonly open: "open_history_item";
814
- };
815
- declare const TOOL_DEFINITIONS: readonly ToolDefinition[];
733
+ /** The catalog in the order the fingerprint hashes (section 8.2), every order by UTF-16 code units. */
734
+ declare function normalize(catalog: Catalog): Catalog;
735
+ /** `sha256:<hex>` over the canonical JSON of the normalized catalog (section 8.3). */
736
+ declare function fingerprint(catalog: Catalog): Promise<string>;
737
+ /**
738
+ * A catalog name as a name of the type (section 8.5): A to Z lowercased, every other code point outside
739
+ * `[a-z0-9_]` one `_`, `c_` before a name that does not start with a letter, cut at `limit`, and `_` after a
740
+ * reserved word.
741
+ */
742
+ declare function toName(raw: string, limit?: number): string;
743
+ /** The proposed type of one table (section 8.4). */
744
+ declare function derive(catalog: Catalog, options?: DeriveOptions): Promise<Derived>;
745
+ /**
746
+ * What differs between the declaration and the type the live catalog derives (section 8.8): counts, and the
747
+ * declared fields the difference touches. Never a new name, a value or a definition.
748
+ */
749
+ declare function changes(declared: Json$2, live: Json$2): Changes;
750
+ /**
751
+ * The column and the values of a CHECK that holds a column to a list, as `pg_get_constraintdef` writes it
752
+ * (section 8.6): `CHECK ((status = ANY (ARRAY['open'::text, 'paid'::text])))`, the same with a cast of the
753
+ * column and of the array, or `CHECK ((status = 'open'::text))`. Anything else is null.
754
+ */
755
+ declare function listCheck(definition: string): [string, unknown[]] | null;
816
756
 
817
- interface ConversationParams {
818
- /** The customer on the other side. */
819
- subject: Handle;
820
- /** Where the conversation happens, such as `whatsapp` or `voice`. */
821
- channel: string;
822
- /** Your id for the thread. A UUIDv7 is minted when omitted. */
823
- conversation_id?: string;
824
- /** Defaults to `voice` when the channel is `voice`, otherwise `chat`. */
825
- view?: View;
826
- /** The level already proven when the conversation starts. Defaults to `V0`. */
827
- verification?: Verification;
828
- /** The account or partner the customer acts for. */
829
- about?: Handle;
830
- target?: TargetModel;
831
- }
832
- /** Optional details of one captured turn. */
833
- interface TurnOptions {
834
- /** The provider's message id, which makes retries of the same turn harmless. */
835
- idempotency_key?: string;
836
- occurred_at?: Timestamp;
837
- /** The agent or attendant id inside your system. */
838
- speaker_id?: string;
839
- visibility?: Visibility;
840
- /** Marks the text as a speech-to-text transcript with this confidence, between 0 and 1. */
841
- stt_confidence?: number;
842
- voice?: VoiceInfo;
843
- /** Overrides the stamp an agent turn would carry from `markInjected()`. */
844
- context_stamp?: ContextStamp;
845
- /**
846
- * Agent turns only: what the model provider reported for the call behind the answer, as the
847
- * provider's response (OpenAI or Anthropic) or a `ModelUsage`. `wrap()` passes it for you. A
848
- * response without usage is left out; the turn is recorded either way.
849
- */
850
- usage?: ModelUsage | object | null;
851
- }
852
- type ConversationEvent = Omit<TrackEvent, "channel" | "conversation_id"> & {
853
- channel?: string;
854
- };
855
- type ConversationAction = Omit<ActionEvent, "channel" | "conversation_id"> & {
856
- channel?: string;
857
- };
858
- interface ConversationHooks {
859
- endConversation(id: string): Promise<WriteResult>;
757
+ type derive$1_Catalog = Catalog;
758
+ type derive$1_CatalogColumn = CatalogColumn;
759
+ type derive$1_Changes = Changes;
760
+ type derive$1_DeriveError = DeriveError;
761
+ declare const derive$1_DeriveError: typeof DeriveError;
762
+ type derive$1_DeriveOptions = DeriveOptions;
763
+ type derive$1_Derived = Derived;
764
+ declare const derive$1_changes: typeof changes;
765
+ declare const derive$1_derive: typeof derive;
766
+ declare const derive$1_fingerprint: typeof fingerprint;
767
+ declare const derive$1_listCheck: typeof listCheck;
768
+ declare const derive$1_normalize: typeof normalize;
769
+ declare const derive$1_toName: typeof toName;
770
+ declare namespace derive$1 {
771
+ export { type derive$1_Catalog as Catalog, type derive$1_CatalogColumn as CatalogColumn, type derive$1_Changes as Changes, derive$1_DeriveError as DeriveError, type derive$1_DeriveOptions as DeriveOptions, type derive$1_Derived as Derived, derive$1_changes as changes, derive$1_derive as derive, derive$1_fingerprint as fingerprint, derive$1_listCheck as listCheck, derive$1_normalize as normalize, derive$1_toName as toName };
860
772
  }
773
+
861
774
  /**
862
- * One customer conversation.
863
- *
864
- * The server pins the pack to the conversation: every turn gets the same bytes, so the prompt
865
- * prefix stays byte-identical and the model provider's prompt cache keeps hitting. After the
866
- * first pack, each read also asks for the delta, what changed since this agent last looked
867
- * (a new open item, an action another agent took). The server sends each delta once, so the
868
- * conversation keeps them, in order, in `suffix`, with the live turns, for the end of the
869
- * prompt. A successful `verify()` starts over from the pack the server pins for the new level.
775
+ * The canonical destination of a handle and its key per reader (`spec/suppression-list.md`, sections 3
776
+ * and 4).
870
777
  *
871
- * Call `markInjected()` when the pack goes into the prompt; the agent's later turns and actions
872
- * carry that moment and the pack's etag as `context_stamp`. `wrap()` does it for you.
778
+ * A phone number, a WhatsApp id and an e-mail address each have one canonical form, `phone:+<E.164>` or
779
+ * `email:<address>`. The suppression list keys it with each reader's salt, and the contact token carries it
780
+ * keyed with the gateway's key as `rcpt` (`spec/contact-token.md`, section 4.1), so a reader matches the
781
+ * destination it is about to contact without the list ever carrying a handle.
873
782
  *
874
- * @example
875
- * const convo = niadra.conversation({ subject: handles.waId("5511987654321"), channel: "whatsapp" });
876
- * convo.customer(inbound.text, { idempotency_key: inbound.id });
877
- * const ctx = await convo.context();
878
- * convo.markInjected(ctx);
879
- * const reply = await llm(ctx.text, history, ctx.suffix);
880
- * convo.agent(reply);
783
+ * The same rules as the Python SDK's `niadra.coordination.destination`.
881
784
  */
882
- declare class Conversation {
883
- private readonly client;
884
- private readonly params;
885
- private readonly hooks;
886
- readonly id: string;
887
- readonly channel: string;
888
- readonly subject: Handle;
889
- private level;
890
- private readonly view;
891
- private readonly state;
892
- private ending;
893
- constructor(client: Niadra, params: ConversationParams, hooks: ConversationHooks);
894
- /** The level in force for this conversation, raised by a successful `verify()`. */
895
- get verification(): Verification;
896
- /**
897
- * When context first went into the prompt, and when the agent first spoke. Context injected
898
- * after the agent's first turn is the "late context" signal the usage measurement reports.
899
- */
900
- get timings(): Timings;
901
- /** What the agent's next turn and action carry: the last `markInjected()`, or `null`. */
902
- get contextStamp(): ContextStamp | null;
903
- /** The last result `context()` returned for this conversation. */
904
- get lastContext(): ContextResult | null;
905
- /** Where `wrap()` reports what it swallowed: the client's logger. */
906
- get logger(): Logger;
907
- /**
908
- * The pack for this turn: the pinned `text`, and a `suffix` with every delta since the pin
909
- * and the current live turns. A read with `query` is compiled for that query and never
910
- * pinned, so it leaves the conversation's deltas alone.
911
- */
912
- context(options?: ContextOptions & {
913
- query?: string;
914
- }): Promise<ContextResult>;
915
- /**
916
- * Records that `context` (by default the last one this conversation returned) went into the
917
- * prompt. Call it each time you build the prompt; `timings.contextInjectedAt` keeps the first.
918
- */
919
- markInjected(context?: ContextResult | null, at?: Date): void;
920
- /** Captures what the customer said. */
921
- customer(text: string, options?: TurnOptions): string | null;
922
- /** Captures what the AI agent said, stamped with the context its prompt carried. */
923
- agent(text: string, options?: TurnOptions): string | null;
924
- /** Captures what a human attendant said, for example after a handoff. */
925
- human(text: string, options?: TurnOptions): string | null;
926
- /** Records any event in this conversation. The customer's handle is attached unless you pass your own. */
927
- track(event: ConversationEvent): string | null;
928
- /** Records an action the agent took during this conversation, stamped like its turns. */
929
- action(event: ConversationAction): string | null;
930
- /**
931
- * Records that the customer proved who they are, and raises the level for later reads.
932
- * `handle` defaults to the conversation's subject.
933
- */
934
- verify(params: {
935
- method: VerifyMethod;
936
- level: Verification;
937
- handle?: Handle;
938
- }): Promise<WriteResult>;
939
- /** Records a transfer to a human or another agent. */
940
- handoff(params: {
941
- target: "human" | "agent";
942
- target_source?: string;
943
- reason?: string;
944
- mode?: "warm" | "cold";
945
- }): Promise<WriteResult>;
946
- /**
947
- * The navigation kit bound to this customer and conversation. The verification level is
948
- * read at each call, so tools created before a `verify()` pick up the new level.
949
- */
950
- tools(): BoundTools;
951
- /** Emits `conversation.ended` and drops the conversation's cached packs. Safe to call twice. */
952
- end(): Promise<WriteResult>;
953
- private bind;
954
- private turn;
955
- }
956
-
957
- /** Arguments of `uploadMedia()`. */
958
- interface UploadParams {
959
- /** The file itself. It is read into memory once, to hash it and send it. */
960
- data: Uint8Array | ArrayBuffer | Blob;
961
- /** Such as `audio/wav` or `image/png`. Storage checks it against the signed URL. */
962
- content_type: string;
963
- /**
964
- * Whose file it is, whenever you know. It is then stored under that person, so erasing them
965
- * erases it, even if no event ever references it.
966
- */
967
- subject?: Handle;
968
- }
969
- /** A file handed to Niadra. Put `media_ref` and `media_sha256` in the event's `content`. */
970
- interface MediaUpload {
971
- media_ref: string;
972
- media_sha256: string;
973
- content_type: string;
974
- size_bytes: number;
975
- expires_at: string | null;
976
- }
977
785
 
978
- /** Paging of `objectTimeline()`. */
979
- interface ObjectTimelineParams {
980
- /** `next_cursor` from the previous page. */
981
- cursor?: string;
982
- /** Between 1 and 100. Defaults to 20. */
983
- limit?: number;
786
+ /**
787
+ * A handle with no canonical destination: `invalid_handle` when the value is not a handle of its type,
788
+ * `unsupported_type` when the list does not cover the type.
789
+ */
790
+ declare class NiadraDestinationError extends NiadraError {
791
+ readonly code: "invalid_handle" | "unsupported_type";
792
+ readonly name = "NiadraDestinationError";
793
+ constructor(code: "invalid_handle" | "unsupported_type");
984
794
  }
795
+ /**
796
+ * The canonical form of a handle of `type` (`phone_e164`, `wa_id`, `wa_jid` or `email`), such as
797
+ * `phone:+5511987654321` for `"(11) 98765-4321"`. Throws `NiadraDestinationError`.
798
+ */
799
+ declare function canonicalDestination(type: string, value: string): string;
800
+ /**
801
+ * A canonical destination keyed with a reader's salt, in base64url as `GET /v1/suppressions/salt` gives it:
802
+ * the base64url of HMAC-SHA256 over its UTF-8 bytes, 43 characters. Web Crypto signs asynchronously.
803
+ */
804
+ declare function suppressionKey(salt: string, canonical: string): Promise<string>;
985
805
 
986
806
  /**
987
- * Per-method time budgets in milliseconds. They are the SDK's own and deliberately short:
988
- * managed agent platforms allow 7 to 10 seconds per turn and self-hosted frameworks allow no
989
- * limit at all, so a slow memory call must never become a slow agent.
807
+ * The exposure token (`spec/exposure-token.md`): `nx1.<id>.<position>.<verifier>`, the short string a card
808
+ * carries so that the order line the store's app copies it into names the list the agent showed and the
809
+ * card's place in it.
810
+ *
811
+ * The token carries no personal data. Its verifier catches a token copied wrong or cut short; it is not a
812
+ * signature. Building one is synchronous, so a card can carry it as it renders: the SHA-256 of the verifier
813
+ * is computed here, since Web Crypto only hashes asynchronously.
814
+ *
815
+ * The same rules as the Python SDK's `niadra.exposure`.
990
816
  */
991
- interface Timeouts {
992
- /** `context()` for every view except `voice`. */
993
- context: number;
994
- /** `context()` with `view: "voice"`, where the budget is a fraction of a spoken turn. */
995
- contextVoice: number;
996
- /** `search()`, `timeline()` and `open()`. */
997
- navigation: number;
998
- /** Navigation calls made through a voice conversation or voice-bound tools. */
999
- navigationVoice: number;
1000
- /**
1001
- * The whole of a write the caller waits for: `identify()`, `verify()`, `handoff()`,
1002
- * `feedback()` and the reservation in `uploadMedia()`, retries included. Also each attempt
1003
- * of a background batch, which never holds a caller.
1004
- */
1005
- write: number;
1006
- /** `subjectToken()`, usually called once when a session starts. */
1007
- token: number;
1008
- /** The whole of sending media bytes to storage in `uploadMedia()`, retries included. */
1009
- upload: number;
1010
- }
1011
- declare const DEFAULT_TIMEOUTS: Timeouts;
1012
- /** How `context()` reuses packs inside a conversation. */
1013
- interface CacheOptions {
1014
- /** A pack younger than this is returned without any request. */
1015
- ttlMs: number;
1016
- /**
1017
- * After `ttlMs`, the cached pack is still returned at once for this long while a single
1018
- * background request refreshes it.
1019
- */
1020
- staleWhileRevalidateMs: number;
1021
- /**
1022
- * Oldest pack the SDK will fall back to when a request fails. Older packs are dropped
1023
- * rather than shown to a model as if they were current.
1024
- */
1025
- maxStaleMs: number;
1026
- /** Least recently used packs are evicted past this many conversations. */
1027
- maxEntries: number;
1028
- }
1029
- declare const DEFAULT_CACHE: CacheOptions;
1030
- /** How `track()` and the other write methods batch events on their way to `POST /v1/batch`. */
1031
- interface QueueOptions {
1032
- /** Send as soon as this many items are waiting. */
1033
- flushAt: number;
1034
- /** Send whatever is waiting at least this often. */
1035
- flushIntervalMs: number;
1036
- /**
1037
- * Send a conversation turn (a message with a `conversation_id`) at most this long after it was
1038
- * queued, with whatever else is waiting. It is what the other agents read in `live`.
1039
- */
1040
- turnFlushIntervalMs: number;
1041
- /** Items per request. The server accepts up to 500. */
1042
- maxBatchSize: number;
1043
- /** Items held in memory before new ones are dropped. Keeps a long outage from exhausting memory. */
1044
- maxQueueSize: number;
1045
- /** Attempts per batch, including the first. 4xx answers other than 408, 421 and 429 are never retried. */
1046
- maxAttempts: number;
1047
- /** First backoff delay; each retry doubles it, with full jitter, up to `maxRetryDelayMs`. */
1048
- retryDelayMs: number;
1049
- maxRetryDelayMs: number;
1050
- }
1051
- declare const DEFAULT_QUEUE: QueueOptions;
1052
- interface ClientOptions {
1053
- /**
1054
- * A source key, `nia_sk_<live|test>_<region>_<space>_<key_id>_<secret>`. Defaults to the
1055
- * `NIADRA_API_KEY` environment variable where one exists. Without a key the client is a
1056
- * no-op: every method resolves with an empty result and nothing is sent.
1057
- */
1058
- apiKey?: string | undefined;
1059
- /**
1060
- * Overrides the address derived from the key, for the local emulator or a private endpoint.
1061
- * Defaults to `NIADRA_BASE_URL`, then to `https://<space>.<region>.api.niadra.com`.
1062
- */
1063
- baseURL?: string | undefined;
1064
- timeouts?: Partial<Timeouts>;
1065
- /** Pass `false` to send every `context()` call to the server. */
1066
- cache?: Partial<CacheOptions> | false;
1067
- queue?: Partial<QueueOptions>;
1068
- /**
1069
- * Throw errors instead of logging them and resolving with an empty result. Meant for tests
1070
- * and development, where a silent failure hides a broken integration.
1071
- */
1072
- strict?: boolean;
1073
- /** Flush queued events when a Node process is about to exit. Defaults to `true`. */
1074
- flushOnExit?: boolean;
1075
- /** A `fetch` implementation. Defaults to the global one. */
1076
- fetch?: typeof fetch;
1077
- logger?: Logger;
1078
- /** Extra headers sent with every request. */
1079
- defaultHeaders?: Record<string, string>;
1080
- }
1081
817
 
1082
- interface TaskParams {
1083
- /** Your id for the task. A UUIDv7 is minted when omitted. */
1084
- task_id?: string;
1085
- /** The internal agent or system doing the work, such as `billing-agent`. */
1086
- channel: string;
1087
- /** The person the task is about. Pass this, `object`, or both. */
1088
- subject?: Handle;
1089
- /** The business object the task is about, as an `ObjectRef` or `type:namespace:id`. */
1090
- object?: ObjectRef | string;
1091
- about?: Handle;
1092
- /** A task view such as `task:billing`. Defaults to `brief`. */
1093
- view?: View;
1094
- verification?: Verification;
1095
- target?: TargetModel;
818
+ /** Why a reader refuses a token: the first check of `spec/exposure-token.md`, section 4, that fails. */
819
+ type ExposureTokenRefusal = "malformed" | "unsupported_version" | "bad_position" | "bad_verifier";
820
+ /** A token a reader refuses, with the code of the first check it fails. */
821
+ declare class NiadraExposureTokenError extends NiadraError {
822
+ readonly code: ExposureTokenRefusal;
823
+ readonly name = "NiadraExposureTokenError";
824
+ constructor(code: ExposureTokenRefusal);
1096
825
  }
1097
- type TaskEvent = Omit<TrackEvent, "channel" | "task_id"> & {
1098
- channel?: string;
1099
- };
1100
- type TaskAction = Omit<ActionEvent, "channel" | "task_id"> & {
1101
- channel?: string;
826
+ /**
827
+ * The token of the card at `position` (1-based, up to 9999) of the exposure `exposureId`, a UUID: 33
828
+ * characters for the first card, at most 36.
829
+ */
830
+ declare function exposureToken(exposureId: string, position: number): string;
831
+ /** The exposure id, written as a UUID, and the position a token names. Throws `NiadraExposureTokenError`. */
832
+ declare function parseExposureToken(token: string): {
833
+ exposureId: string;
834
+ position: number;
1102
835
  };
1103
- interface TaskHooks {
1104
- endTask(id: string): Promise<WriteResult>;
1105
- /** `verify()` for a task, which may have no subject to default the handle to. */
1106
- verifyTask(params: Omit<VerifyParams, "handle"> & {
1107
- handle: Handle | undefined;
1108
- }): Promise<WriteResult>;
1109
- }
836
+
1110
837
  /**
1111
- * One unit of work by an internal agent: a collection run, a ticket triage, a refund. The task
1112
- * plays the role a conversation plays for customer-facing agents: the server pins its pack,
1113
- * deltas arrive and are kept the same way, it scopes the context cache, groups the events for
1114
- * billing and closes with `task.ended`. Without `end()`, the server closes the task after 10
1115
- * minutes of inactivity.
838
+ * Where the turn in progress lives: an `AsyncLocalStorage`, which follows promises, `await` and timers, so a
839
+ * tool called anywhere inside a turn lands in it, and two sub-agents started with `Promise.all` each keep
840
+ * their own.
841
+ *
842
+ * The SDK builds for every runtime and never imports `node:async_hooks` itself. It takes the class from
843
+ * `process.getBuiltinModule("node:async_hooks")` where that exists (Node 20.16 and later, Bun, Deno); a
844
+ * runtime without it passes the class to `useAsyncLocalStorage()`, as Cloudflare Workers do with the
845
+ * `nodejs_als` flag. Where there is none, `currentTurn()` is `undefined` and adapters pass the turn they
846
+ * opened explicitly: capture keeps working, only the implicit lookup is missing.
1116
847
  */
1117
- declare class Task {
1118
- private readonly client;
1119
- private readonly params;
1120
- private readonly hooks;
1121
- readonly id: string;
1122
- private readonly object;
1123
- private level;
1124
- private readonly state;
1125
- private ending;
1126
- constructor(client: Niadra, params: TaskParams, hooks: TaskHooks);
1127
- /** When context first went into the prompt, and when the agent first acted. */
1128
- get timings(): Timings;
1129
- /** What the agent's next turn and action carry: the last `markInjected()`, or `null`. */
1130
- get contextStamp(): ContextStamp | null;
1131
- /** The last result `context()` returned for this task. */
1132
- get lastContext(): ContextResult | null;
1133
- /** Where `wrap()` reports what it swallowed: the client's logger. */
1134
- get logger(): Logger;
1135
- /**
1136
- * Context for the task, centered on its object when it has one, otherwise on its subject.
1137
- * Resolves with an empty result, never rejects, unless the client is strict.
1138
- */
1139
- context(options?: ContextOptions & {
1140
- query?: string;
1141
- }): Promise<ContextResult>;
1142
- /** Records that `context` (by default the last one this task returned) went into the prompt. */
1143
- markInjected(context?: ContextResult | null, at?: Date): void;
1144
- /** Captures what the agent answered, stamped with the context its prompt carried. */
1145
- agent(text: string, options?: TurnOptions): string | null;
1146
- /**
1147
- * Records that the person the task is about proved who they are, and reads at the new level
1148
- * from then on. `handle` defaults to the task's subject.
1149
- */
1150
- verify(params: {
1151
- method: VerifyMethod;
1152
- level: Verification;
1153
- handle?: Handle;
1154
- }): Promise<WriteResult>;
1155
- /** Records an event in this task, attaching the task's subject and object unless you pass your own. */
1156
- track(event: TaskEvent): string | null;
1157
- /** Records an action taken in a system of record, such as `credit` on an invoice, stamped like its turns. */
1158
- action(event: TaskAction): string | null;
1159
- /**
1160
- * The navigation kit bound to the task's subject, or `null` for a task about an object only.
1161
- * The verification level is read at each call, so tools created before a `verify()` pick up
1162
- * the new level.
1163
- */
1164
- tools(): BoundTools | null;
1165
- /** Emits `task.ended` and drops the task's cached packs. Safe to call twice. */
1166
- end(): Promise<WriteResult>;
1167
- private bind;
1168
- }
848
+ interface AsyncStore<T> {
849
+ getStore(): T | undefined;
850
+ run<R>(store: T, fn: () => R): R;
851
+ enterWith(store: T): void;
852
+ }
853
+ type StoreClass = new <T>() => AsyncStore<T>;
854
+ /** The `AsyncLocalStorage` class to hold turns with, on a runtime where the SDK cannot find one itself. */
855
+ declare function useAsyncLocalStorage(storage: StoreClass): void;
1169
856
 
1170
857
  /**
1171
- * Body of `POST /v1/subject-tokens`. The token binds one customer to a session so that an MCP
1172
- * connection, or any client you hand it to, can read that customer and no other.
858
+ * The resolver worker: the space's refresh requests, served inside the company's boundary.
859
+ *
860
+ * Niadra never calls a company system. When a value must be read again (a claim waits on it, a timer is due,
861
+ * someone watches the object), Niadra queues a refresh request with the budget it admitted. The worker leases
862
+ * the waiting requests (`GET /v1/state/refresh-requests`, 60 s), reads each object with the company's resolver
863
+ * of its type (`niadra.resolvers`), at the resolver's rate and behind its circuit breaker, and pushes what it
864
+ * read (`POST /v1/objects/push`) with the request's id, which settles it.
865
+ *
866
+ * A watch fires only on a value its source confirmed: its `watch_revalidation` requests go first, and the
867
+ * answer decides every due watch of the object, even when the value did not change. A request the worker
868
+ * cannot answer, the object gone from the source (`NOT_FOUND`) or the resolver failing, is released at once
869
+ * (`POST .../release`), so a watch falls back to its type's rule without waiting out the leases. A request of a
870
+ * type with no resolver, or whose resolver's circuit is open, is left to its lease, for a worker that can read
871
+ * it. A worker that leases regularly is what tells Niadra a company worker is there to revalidate.
872
+ *
873
+ * ```ts
874
+ * const worker = new ResolverWorker(niadra);
875
+ * await worker.run(abortController.signal);
876
+ * ```
1173
877
  */
1174
- interface SubjectTokenRequest {
1175
- subject: Handle;
1176
- about?: Handle | null;
1177
- conversation_id?: string | null;
1178
- task_id?: string | null;
1179
- verification?: Verification;
1180
- }
1181
- /** A signed token valid for 15 minutes. Treat it as a credential: it reads this customer's memory. */
1182
- interface SubjectToken {
1183
- token: string;
1184
- expires_at: string;
878
+
879
+ declare class ResolverWorker {
880
+ private readonly niadra;
881
+ private readonly options;
882
+ pushed: number;
883
+ skipped: number;
884
+ released: number;
885
+ private readonly missing;
886
+ constructor(niadra: Niadra, options?: {
887
+ limit?: number;
888
+ pollMs?: number;
889
+ budgetMs?: number;
890
+ resolvers?: Resolvers;
891
+ });
892
+ private get resolvers();
893
+ /** Leases the waiting requests, resolves them and pushes what was read. Resolves with how many were pushed. */
894
+ runOnce(): Promise<number>;
895
+ /** Gives back a request the worker cannot answer; one that failed to go back waits out its lease. */
896
+ private release;
897
+ /** Serves requests until `signal` aborts, pausing when none wait, and longer while Niadra does not answer. */
898
+ run(signal?: AbortSignal): Promise<void>;
1185
899
  }
1186
900
 
1187
- /** What `identify()`, `verify()`, `handoff()` and the `end()` helpers resolve to. */
1188
- type WriteResult = {
1189
- ok: true;
1190
- idempotency_key: string;
1191
- error: null;
1192
- } | {
1193
- ok: false;
1194
- idempotency_key: string | null;
1195
- error: NiadraError;
1196
- };
1197
- /** Scope of `open()`: the same verification and conversation the rest of the session uses. */
1198
- interface OpenParams {
1199
- verification?: Verification;
1200
- conversation_id?: string;
1201
- /** Kept for callers of 0.1.0; the server never read it on this route, so it is not sent. */
1202
- task_id?: string;
1203
- /**
1204
- * The customer the item must belong to: the server opens it only when it is theirs, and answers
1205
- * 404 otherwise. `tools()` passes the bound customer.
1206
- */
1207
- subject?: Handle;
901
+ /**
902
+ * Replay inside the company's boundary (`spec/replay.md`): Niadra keeps the scenarios and decides the verdict;
903
+ * the company's CI runs the agent again on recorded turns.
904
+ *
905
+ * ```ts
906
+ * const run = await new Replayer(niadra, buildAgent, { build: Niadra.build({ prompts: { core: "v17" }, model: MODEL }) })
907
+ * .run(["sc_quote_after_price_change"], { runs: 5, vary: ["prompts"] });
908
+ * if (run.verdict === "regression") process.exit(1);
909
+ * ```
910
+ *
911
+ * For each turn of each scenario the runner asks for the case (`POST /v1/replay/cases`) with the build it runs,
912
+ * checks the pins itself, fetches every recorded value it needs (by pointer through `niadra.content`, or
913
+ * `read`) and checks its digest. It then runs the agent N times: `buildAgent()` makes a fresh agent, called
914
+ * with a `ReplayInput`. Inside the run, tools wrapped with `niadra.tool()` answer from the record when their
915
+ * arguments match a recorded call; nothing the agent sends, declares or checks leaves for Niadra, and a read
916
+ * returns the pack of the time. The assertions are evaluated on the replayed record, which stays here, and the
917
+ * results go to `POST /v1/scenario-runs`, which answers with the statistical verdict.
918
+ */
919
+
920
+ type Json$1 = Record<string, unknown>;
921
+ /** What a replayed agent receives: the turn's input (masked), the conversation before it, the pack of the time. */
922
+ interface ReplayInput {
923
+ turnId: string;
924
+ kind: string;
925
+ text: string | null;
926
+ history: Json$1[];
927
+ context: ContextResponse | null;
928
+ record: Json$1;
929
+ /** The execution's number, from 1. */
930
+ run: number;
931
+ paraphrase: boolean;
932
+ }
933
+ /** Answers one input: the text the agent emitted (or nothing), or a promise of it. */
934
+ type ReplayAgent = (input: ReplayInput) => unknown;
935
+ /**
936
+ * A run as Niadra judged it: `verdict` is the worst of its scenarios' (`pass`, `flaky`, `infrastructure_error`,
937
+ * `pin_mismatch`, `regression`), and `scenarios` holds each one's verdict with the statistics of each
938
+ * assertion. A report Niadra refused for a pin that does not match is `refused`, with no `runId`.
939
+ */
940
+ interface ReplayRun {
941
+ runId: string;
942
+ status: string;
943
+ verdict: string | null;
944
+ scenarios: Json$1[];
945
+ }
946
+ interface RunOptions {
947
+ runs?: number;
948
+ mode?: Mode;
949
+ vary?: string[];
950
+ /** A paraphrase of the input for run `n`: intermittent results must hold with other words too. */
951
+ paraphrase?: (text: string, run: number) => string;
952
+ }
953
+ /** The pins that differ (the replay spec, 4.2): every pin outside `vary` the recording requires, or both builds carry. */
954
+ declare function pinDifferences(recorded: Json$1, running: Json$1, required: readonly string[], vary: readonly string[]): Json$1[];
955
+ /** Runs scenarios: see the module. `read(pointer)` reads values kept by pointer, by default the client's content resolver. */
956
+ declare class Replayer {
957
+ private readonly niadra;
958
+ private readonly agentFactory;
959
+ private readonly options;
960
+ private readonly build;
961
+ constructor(niadra: Niadra, agentFactory: () => ReplayAgent, options?: {
962
+ build?: TurnPins;
963
+ read?: (pointer: string) => Promise<string>;
964
+ });
965
+ /** Runs each turn of the scenarios `runs` times and resolves with the run and its verdict. */
966
+ run(scenarioIds: readonly string[], options?: RunOptions): Promise<ReplayRun>;
967
+ private scenario;
968
+ private caseOf;
969
+ private execute;
1208
970
  }
971
+
1209
972
  /**
1210
- * The Niadra client.
973
+ * The tool counterfactual (`spec/counterfactual.md`): does one element of the constraints block change what a
974
+ * tool returns, beyond the tool's own noise? Run in the company's CI, inside its boundary.
1211
975
  *
1212
- * Reads (`context`, `search`, `timeline`, `open`) run on the agent's hot path with short time
1213
- * budgets of their own. Writes (`track` and friends) go through an in-memory queue and never
1214
- * block the caller. By default every method is fail-open: an outage, a timeout or a bad
1215
- * argument is logged and the method resolves with an empty result, so the agent keeps
1216
- * working without memory rather than not working at all. Pass `strict: true` to throw instead.
976
+ * ```ts
977
+ * const run = await new Counterfactual(niadra, { search_products: searchProducts }).run(turnIds, {
978
+ * tool: "search_products",
979
+ * element: "hard",
980
+ * });
981
+ * console.log(run.report.effect, run.report.limits);
982
+ * ```
1217
983
  *
1218
- * Create one client per process and share it; it holds the queue, the cache and the
1219
- * connection pool.
984
+ * For each recorded call of the tool whose arguments or post filter carried the element (the call recorded the
985
+ * block it `applied`, and the block is in the record), the runner renders the call again without the element and
986
+ * calls the tool three times at the same moment: the recorded arguments twice (the base, whose two lists measure
987
+ * the tool's own noise) and the variant once. A tool marked safe to run again (`tool(..., { dryRun: true })`, or
988
+ * `safe`) runs as it is; any other runs as its dry run (the binding's `capabilities.dry_run_param`), and one
989
+ * with no dry run is never called (`no_dry_run`). It compares the lists after the post filter (exclusions, when
990
+ * the binding overfetches) with `overlapAtK`, finds where the items the person engaged with went, and sends
991
+ * only positions and overlaps to `POST /v1/measure/counterfactual-runs`, which answers with the report.
1220
992
  *
1221
- * @example
1222
- * const niadra = new Niadra({ apiKey: process.env.NIADRA_API_KEY });
1223
- * const ctx = await niadra.context({ subject: handles.phone("+5511987654321"), conversation_id: "wa-8812" });
993
+ * The records come through the replay case route, so only turns that can be replayed are read. The element is
994
+ * `constraints` (the whole block), `hard`, `size` (its attributes) or `exclude`. The binding comes from
995
+ * `bindings`, the tool's own `binding` or the SDK profile; a result's objects are read with the binding's
996
+ * `results`, or else with the tool's `provenance`. It behaves as the Python SDK's `Counterfactual`.
1224
997
  */
1225
- declare class Niadra {
1226
- /** `false` when the client was built without a usable key and sends nothing. */
1227
- readonly enabled: boolean;
1228
- private readonly core;
1229
- private readonly timeouts;
1230
- private readonly strict;
1231
- /** Where the client reports what it swallows in fail-open mode. */
1232
- readonly logger: Logger;
1233
- private readonly disabledReason;
1234
- private unregisterExit;
1235
- constructor(options?: ClientOptions);
1236
- private setup;
1237
- /**
1238
- * The customer's context pack, to place in the system prompt before calling the model.
1239
- *
1240
- * Inside a conversation (`conversation_id` or `task_id`), packs are cached: a recent one is
1241
- * returned without a request, an older one is returned at once while a single background
1242
- * request refreshes it, and when a request fails the last good pack is returned instead.
1243
- * A 401 or 403 is not an outage: it drops the cached packs, so revoking a key also stops
1244
- * what the process had already cached from reaching the model.
1245
- *
1246
- * A plain read and a `delta` read of one conversation share the cached pack. The server
1247
- * sends each delta once, and so does the cache, even one a background refresh brought in;
1248
- * `conversation()` and `task()` keep them across turns.
1249
- *
1250
- * Never rejects unless `strict` is set. On failure `text` is empty and `error` is set.
1251
- */
1252
- context(params: ContextParams, options?: ContextOptions): Promise<ContextResult>;
1253
- /**
1254
- * Searches the customer's history by keywords and meaning, with filters by period, channel,
1255
- * topic and kind. The answer includes how often the same kind of issue came back.
1256
- */
1257
- search(params: SearchRequest, options?: RequestOptions): Promise<Result<SearchResponse>>;
1258
- /** The customer's history, newest first, one line per item, paginated by cursor. */
1259
- timeline(params: TimelineRequest, options?: RequestOptions): Promise<Result<TimelineResponse>>;
1260
- /**
1261
- * Opens one history item from `search()` or `timeline()`: summary, request, commitments,
1262
- * outcome and resolution. Sent as `POST /v1/history/open`: the conversation id and `subject` go
1263
- * in the body, never in a URL.
1264
- */
1265
- open(id: string, params?: OpenParams, options?: RequestOptions): Promise<Result<OpenedItem>>;
1266
- /**
1267
- * The derived state of a business object: what its systems of record reported last, `as_of`
1268
- * when, and its open items, under this source's purpose.
1269
- *
1270
- * @example
1271
- * const { data: invoice } = await niadra.objectState("invoice:erp:0823");
1272
- */
1273
- objectState(object: ObjectRef | string, options?: RequestOptions): Promise<Result<ObjectState>>;
1274
- /**
1275
- * System events and agent actions about one object, newest first, one line each and never
1276
- * conversation content. Pass `next_cursor` back as `cursor` to go on.
1277
- */
1278
- objectTimeline(object: ObjectRef | string, params?: ObjectTimelineParams, options?: RequestOptions): Promise<Result<ObjectTimeline>>;
1279
- /**
1280
- * The navigation kit as function-calling tools with the customer bound outside the model's
1281
- * reach. Hand `definitions` to any model API and pass its tool calls to `call()`.
1282
- *
1283
- * @example
1284
- * const kit = niadra.tools(handles.phone("+5511987654321"), { conversation_id: "wa-8812" });
1285
- * const output = await kit.call(toolCall.function.name, toolCall.function.arguments);
1286
- */
1287
- tools(subject: Handle, binding?: ToolBinding): BoundTools;
1288
- /**
1289
- * Mints a signed, 15-minute token that binds one customer to a session. Your backend calls
1290
- * this and hands the token to the MCP connection, so tools served over MCP can only ever
1291
- * read that customer. Resolves with `data: null` on failure.
1292
- */
1293
- subjectToken(params: SubjectTokenRequest, options?: RequestOptions): Promise<Result<SubjectToken>>;
1294
- /**
1295
- * Records a message, a system event or an agent action. Returns at once with the event's
1296
- * idempotency key, or `null` when the event was dropped: invalid, unserializable, the queue
1297
- * full or the client disabled. Delivery happens in the background; `flush()` waits for it.
1298
- */
1299
- track(event: TrackEvent): string | null;
1300
- /**
1301
- * Records what an agent did in a system of record, such as a credit or a reschedule.
1302
- * With `closes`, the action also resolves the open item it fulfils.
1303
- */
1304
- action(event: ActionEvent): string | null;
1305
- /**
1306
- * States that several handles belong to the same subject. Sent right away rather than on the
1307
- * next batch, so the next `context()` call already sees the merged profile.
1308
- */
1309
- identify(params: IdentifyParams): Promise<WriteResult>;
1310
- /**
1311
- * Raises the verification level of one conversation or task after the customer proved who
1312
- * they are. Sent right away, and drops the conversation's cached packs, because a pack
1313
- * compiled for the old level may be missing what the new level allows.
1314
- */
1315
- verify(params: VerifyParams): Promise<WriteResult>;
1316
- /**
1317
- * Corrects what Niadra derived about a subject: retracts or corrects a fact, resolves an open
1318
- * item, or records how a conversation ended. Sent right away; the server records it as an
1319
- * event, so the correction is audited like any other. A rejected correction resolves with
1320
- * `ok: false`.
1321
- */
1322
- feedback(params: FeedbackParams): Promise<WriteResult>;
1323
- /**
1324
- * Hands a file to Niadra, such as a call recording, and returns the reference its event
1325
- * carries. Media never travels inside an event: this reserves an upload, sends the bytes
1326
- * straight to storage over a short-lived signed URL, and resolves with `media_ref` and
1327
- * `media_sha256` for the event's `content`.
1328
- *
1329
- * @example
1330
- * const { data } = await niadra.uploadMedia({ data: recording, content_type: "audio/wav" });
1331
- * if (data) convo.track({ speaker: "customer", content: { type: "audio", media_ref: data.media_ref, media_sha256: data.media_sha256 } });
1332
- */
1333
- uploadMedia(params: UploadParams, options?: {
1334
- signal?: AbortSignal;
1335
- }): Promise<Result<MediaUpload>>;
1336
- /** Records a transfer to a human or another agent. Sent right away, so the receiver can read context at once. */
1337
- handoff(params: HandoffParams): Promise<WriteResult>;
1338
- /**
1339
- * A helper for one customer conversation: pins the pack across turns, captures turns and
1340
- * emits `conversation.ended` when you call `end()`.
1341
- */
1342
- conversation(params: ConversationParams): Conversation;
1343
- /** A helper for one internal-agent task: binds `task_id` to reads and writes and emits `task.ended`. */
1344
- task(params: TaskParams): Task;
1345
- /**
1346
- * Sends every queued event and resolves when done. Call it before a serverless function
1347
- * returns, or pass it to `waitUntil()` on edge runtimes. Rejects only with `strict` set.
1348
- */
1349
- flush(): Promise<void>;
1350
- /**
1351
- * Flushes, stops the background timer and releases the exit hook. Events tracked after
1352
- * this are dropped. Call it from your own SIGTERM handler in long-running services.
1353
- */
1354
- shutdown(): Promise<void>;
1355
- private verifyWith;
1356
- /** Throws under `strict`; otherwise logs what failed, never with content, and returns the error. */
1357
- private swallow;
1358
- private voiceBudget;
1359
- private readSpec;
1360
- private navigate;
1361
- private fetchContext;
1362
- /**
1363
- * One request for a key, shared by every caller that needs it meanwhile. It sends the
1364
- * cached ETag, so an unchanged pack costs a `not_modified` answer instead of the full text.
1365
- * The caller's signal is deliberately not passed down: other callers may be waiting too.
1366
- */
1367
- private revalidate;
1368
- private contextFailure;
1369
- /**
1370
- * 401 means the key itself is no longer valid, so every cached pack goes. 403 is specific to
1371
- * what was asked, so only that pack goes.
1372
- */
1373
- private observeAuth;
1374
- private forgetScope;
1375
- private disabledError;
1376
- private enqueue;
1377
- private sendNow;
1378
- private endScope;
1379
- private sendBatch;
998
+
999
+ type Element = "constraints" | "hard" | "size" | "exclude";
1000
+ type Json = Record<string, unknown>;
1001
+ type ToolFunction = (args: any) => unknown;
1002
+ /**
1003
+ * Depth-weighted average overlap of `a` and `b` down to `min(k, the longer list's length)`, with
1004
+ * `w(d) = 1 / log2(d + 1)`. An item repeated within a list counts once, at its first position. Two equal
1005
+ * lists overlap 1, and so do two empty lists; a list against an empty one overlaps 0.
1006
+ */
1007
+ declare function overlapAtK(a: readonly string[], b: readonly string[], k: number): number;
1008
+ /** What the run sent and what Niadra answered, with the calls the element did not touch and the turns unread. */
1009
+ interface CounterfactualRun {
1010
+ report: Json;
1011
+ cases: Json[];
1012
+ untouched: number;
1013
+ unread: number;
1014
+ }
1015
+ interface CounterfactualOptions {
1016
+ /** Reads values kept by pointer; by default the client's content resolver. */
1017
+ read?: (pointer: string) => Promise<string>;
1018
+ /** A tool's binding, by tool name. */
1019
+ bindings?: Readonly<Record<string, RawBinding>>;
1020
+ /** Tools that may run again as they are. */
1021
+ safe?: readonly string[];
1022
+ }
1023
+ interface CounterfactualRunOptions {
1024
+ tool: string;
1025
+ element: Element;
1026
+ scenarioIds?: readonly string[];
1027
+ k?: number;
1028
+ label?: string;
1029
+ }
1030
+ /**
1031
+ * The tool counterfactual. `tools` maps each tool's name to the company's function, called with the recorded
1032
+ * arguments (one object).
1033
+ */
1034
+ declare class Counterfactual {
1035
+ private readonly niadra;
1036
+ private readonly tools;
1037
+ private readonly options;
1038
+ constructor(niadra: Niadra, tools: Readonly<Record<string, ToolFunction>>, options?: CounterfactualOptions);
1039
+ /** Runs every recorded call of the tool the element touched; rejects when no call carried it. */
1040
+ run(turnIds: readonly string[], options: CounterfactualRunOptions): Promise<CounterfactualRun>;
1041
+ private case;
1042
+ private value;
1043
+ private served;
1044
+ private families;
1380
1045
  }
1381
1046
 
1382
1047
  /**
@@ -1530,6 +1195,6 @@ declare function baseURLFromKey(key: ParsedApiKey): string;
1530
1195
  */
1531
1196
  declare function uuidv7(now?: number): string;
1532
1197
 
1533
- declare const VERSION = "0.1.1";
1198
+ declare const VERSION = "0.7.0";
1534
1199
 
1535
- 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, type ModelUsage, Niadra, NiadraAPIError, NiadraAbortError, NiadraAuthenticationError, NiadraConfigError, NiadraConnectionError, NiadraError, NiadraPermissionError, NiadraRateLimitError, NiadraTimeoutError, NiadraValidationError, type ObjectRef, type ObjectState, type ObjectTimeline, type ObjectTimelineParams, type OpenItemRequest, 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, modelUsage, parseApiKey, providerOf, renderLive, renderSuffix, silentLogger, toObjectRef, tokenCounts, uuidv7, wrap };
1200
+ export { ClaimCategory, ClaimRecord, type Binding as ConstraintBinding, type BindingArg as ConstraintBindingArg, type Call$1 as ConstraintCall, type Rendering as ConstraintRendering, ConstraintsBlock, type Honored as ConstraintsHonored, ContextResponse, ContextResult, Counterfactual, type Element as CounterfactualElement, type CounterfactualOptions, type CounterfactualRun, type CounterfactualRunOptions, type ExposureTokenRefusal, Handle, HardConstraint, Logger, type Logic, ModelUsage, Niadra, NiadraDestinationError, NiadraError, NiadraExposureTokenError, ObjectRef, type ParsedApiKey, type ReplayAgent, type ReplayInput, Mode as ReplayMode, type RunOptions as ReplayOptions, type ReplayRun, Replayer, ResolverWorker, Resolvers, type SessionSource, SubjectKind, TurnPins, VERSION, type WrapSession, baseURLFromKey, canonicalDestination, canonicalJson, index as claims, exposureToken, expr, handles, honored as honoredConstraints, injectContext, derive$1 as introspect, jsonDigest, modelUsage, overlapAtK, parseApiKey, parseExposureToken, pinDifferences, providerOf, render as renderConstraints, satisfies as satisfiesConstraint, suppressionKey, toObjectRef, tokenCounts, useAsyncLocalStorage, uuidv7, wrap };