@niadra/sdk 0.7.0 → 0.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +58 -0
- package/README.md +55 -7
- package/dist/ai-sdk.cjs +3 -4
- package/dist/ai-sdk.cjs.map +1 -1
- package/dist/ai-sdk.d.cts +3 -3
- package/dist/ai-sdk.d.ts +3 -3
- package/dist/ai-sdk.js +3 -4
- package/dist/ai-sdk.js.map +1 -1
- package/dist/anthropic.cjs +1 -1
- package/dist/anthropic.cjs.map +1 -1
- package/dist/anthropic.d.cts +4 -4
- package/dist/anthropic.d.ts +4 -4
- package/dist/anthropic.js +1 -1
- package/dist/anthropic.js.map +1 -1
- package/dist/bedrock.cjs +1 -1
- package/dist/bedrock.cjs.map +1 -1
- package/dist/bedrock.d.cts +4 -4
- package/dist/bedrock.d.ts +4 -4
- package/dist/bedrock.js +1 -1
- package/dist/bedrock.js.map +1 -1
- package/dist/cli.js +157 -60
- package/dist/cli.js.map +1 -1
- package/dist/{client-DsIxZxZk.d.cts → client-CWMxmJHs.d.cts} +91 -28
- package/dist/{client-DsIxZxZk.d.ts → client-CWMxmJHs.d.ts} +91 -28
- package/dist/cloudflare-agents.cjs +1 -1
- package/dist/cloudflare-agents.cjs.map +1 -1
- package/dist/cloudflare-agents.d.cts +3 -3
- package/dist/cloudflare-agents.d.ts +3 -3
- package/dist/cloudflare-agents.js +1 -1
- package/dist/cloudflare-agents.js.map +1 -1
- package/dist/elevenlabs.cjs +1 -1
- package/dist/elevenlabs.cjs.map +1 -1
- package/dist/elevenlabs.d.cts +5 -5
- package/dist/elevenlabs.d.ts +5 -5
- package/dist/elevenlabs.js +1 -1
- package/dist/elevenlabs.js.map +1 -1
- package/dist/genkit.cjs +1 -1
- package/dist/genkit.cjs.map +1 -1
- package/dist/genkit.d.cts +3 -3
- package/dist/genkit.d.ts +3 -3
- package/dist/genkit.js +1 -1
- package/dist/genkit.js.map +1 -1
- package/dist/google-adk.cjs +1 -1
- package/dist/google-adk.cjs.map +1 -1
- package/dist/google-adk.d.cts +3 -3
- package/dist/google-adk.d.ts +3 -3
- package/dist/google-adk.js +1 -1
- package/dist/google-adk.js.map +1 -1
- package/dist/google-genai.cjs +1 -1
- package/dist/google-genai.cjs.map +1 -1
- package/dist/google-genai.d.cts +4 -4
- package/dist/google-genai.d.ts +4 -4
- package/dist/google-genai.js +1 -1
- package/dist/google-genai.js.map +1 -1
- package/dist/index.cjs +156 -57
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -8
- package/dist/index.d.ts +6 -8
- package/dist/index.js +156 -57
- package/dist/index.js.map +1 -1
- package/dist/{intercept-D7qFCaRb.d.ts → intercept-Bv0nLpSw.d.ts} +1 -1
- package/dist/{intercept-0_lJE6k1.d.cts → intercept-CGngQI8B.d.cts} +1 -1
- package/dist/langchain.cjs +3 -4
- package/dist/langchain.cjs.map +1 -1
- package/dist/langchain.d.cts +3 -3
- package/dist/langchain.d.ts +3 -3
- package/dist/langchain.js +3 -4
- package/dist/langchain.js.map +1 -1
- package/dist/livekit.cjs +1 -1
- package/dist/livekit.cjs.map +1 -1
- package/dist/livekit.d.cts +3 -3
- package/dist/livekit.d.ts +3 -3
- package/dist/livekit.js +1 -1
- package/dist/livekit.js.map +1 -1
- package/dist/llamaindex.cjs +1 -1
- package/dist/llamaindex.cjs.map +1 -1
- package/dist/llamaindex.d.cts +3 -3
- package/dist/llamaindex.d.ts +3 -3
- package/dist/llamaindex.js +1 -1
- package/dist/llamaindex.js.map +1 -1
- package/dist/mastra.cjs +3 -4
- package/dist/mastra.cjs.map +1 -1
- package/dist/mastra.d.cts +3 -3
- package/dist/mastra.d.ts +3 -3
- package/dist/mastra.js +3 -4
- package/dist/mastra.js.map +1 -1
- package/dist/openai-agents.cjs +1 -1
- package/dist/openai-agents.cjs.map +1 -1
- package/dist/openai-agents.d.cts +3 -3
- package/dist/openai-agents.d.ts +3 -3
- package/dist/openai-agents.js +1 -1
- package/dist/openai-agents.js.map +1 -1
- package/dist/retell.cjs +1 -1
- package/dist/retell.cjs.map +1 -1
- package/dist/retell.d.cts +5 -5
- package/dist/retell.d.ts +5 -5
- package/dist/retell.js +1 -1
- package/dist/retell.js.map +1 -1
- package/dist/{shared-Bb5B59Bu.d.ts → shared-B4Ef2Wpg.d.ts} +1 -1
- package/dist/{shared-DTPWVlWm.d.cts → shared-Cq8mz-7m.d.cts} +1 -1
- package/dist/strands.cjs +1 -1
- package/dist/strands.cjs.map +1 -1
- package/dist/strands.d.cts +3 -3
- package/dist/strands.d.ts +3 -3
- package/dist/strands.js +1 -1
- package/dist/strands.js.map +1 -1
- package/dist/twilio.d.cts +4 -4
- package/dist/twilio.d.ts +4 -4
- package/dist/vapi.cjs +1 -1
- package/dist/vapi.cjs.map +1 -1
- package/dist/vapi.d.cts +5 -5
- package/dist/vapi.d.ts +5 -5
- package/dist/vapi.js +1 -1
- package/dist/vapi.js.map +1 -1
- package/dist/voltagent.cjs +1 -1
- package/dist/voltagent.cjs.map +1 -1
- package/dist/voltagent.d.cts +3 -3
- package/dist/voltagent.d.ts +3 -3
- package/dist/voltagent.js +1 -1
- package/dist/voltagent.js.map +1 -1
- package/dist/{webhook-CG4om_DK.d.cts → webhook-jTx_SegV.d.cts} +1 -1
- package/dist/{webhook-1ozGyksG.d.ts → webhook-z2TjUzjv.d.ts} +1 -1
- package/dist/whatsapp.d.cts +2 -2
- package/dist/whatsapp.d.ts +2 -2
- package/package.json +3 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,64 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this package are documented here. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and the package follows [Semantic Versioning](https://semver.org/).
|
|
4
4
|
|
|
5
|
+
## [Unreleased]
|
|
6
|
+
|
|
7
|
+
## [0.9.1] - 2026-10-02
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
|
|
11
|
+
- The canonical phone of the suppression list follows the revised rules of the suppression spec (3.1 and 3.4): Mexico's and Argentina's mobile prefixes, an 11-digit North American number, a carrier code, `(0)`, `tel:` and direction marks. The key the SDK computes for an opted-out contact matches the server's again.
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- A route or field the API deprecates answers with the `Deprecation`, `Sunset` and `Link` headers; the
|
|
16
|
+
client logs one warning per deprecated route per process through its `logger`, with the two dates and the
|
|
17
|
+
migration note, never the path.
|
|
18
|
+
|
|
19
|
+
## [0.9.0] - 2026-09-30
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
|
|
23
|
+
- `ContextResult.ageMs`: how long ago Niadra sent or confirmed the pack a read served. It is 0 for an answer
|
|
24
|
+
just received and grows while the cache serves the pack (`cache`, `stale`, or `fallback` with Niadra down).
|
|
25
|
+
- The chaos test (`test/chaos.test.ts`): Niadra's process killed, its network gone silent, answering 503 and
|
|
26
|
+
answering past the deadline, in the middle of a conversation.
|
|
27
|
+
- A state read's objects carry `derived`: the type's derived fields over its related objects (a look's
|
|
28
|
+
`all_pieces_available`), computed at the read, each with `v`, `logic`, `over` and `unknown`
|
|
29
|
+
(`DerivedState`). A shared object of a derived type carries `derived_status`, and its push's `inputs` name
|
|
30
|
+
shared objects.
|
|
31
|
+
|
|
32
|
+
### Fixed
|
|
33
|
+
|
|
34
|
+
- The local copy of the suppression list is read to its end against the server: a page shorter than the limit
|
|
35
|
+
ends a read, and its cursor is where the next read starts. The server names the cursor on the last page
|
|
36
|
+
too, so the copy read 50 pages of nothing and was never held: `mayContact()` and a check that Niadra did not
|
|
37
|
+
answer fell back on the purpose's direction. The stand-in cell answers as the server does.
|
|
38
|
+
- A batch of events that still fails after its attempts with an error that may pass goes back to the front of
|
|
39
|
+
the queue and leaves again after a pause, doubling up to a minute, instead of being dropped: what an agent
|
|
40
|
+
said during an outage longer than a few seconds reached Niadra only in part.
|
|
41
|
+
- A check about an outbound contact keeps the local copy of the suppression list, read in the background once
|
|
42
|
+
a minute. Before, only `mayContact()` read it, so an agent that only called `check()` had no copy when Niadra
|
|
43
|
+
went down, and a purpose that fails open (`service`, `transactional`) went out to a customer who had opted
|
|
44
|
+
out of it.
|
|
45
|
+
|
|
46
|
+
## [0.8.0] - 2026-09-30
|
|
47
|
+
|
|
48
|
+
### Added
|
|
49
|
+
|
|
50
|
+
- The claim guard takes the offers a context read served as evidence: each object in the constraints block's
|
|
51
|
+
`already_presented` carries the numbers it was last shown with (`values`: price, total, discount,
|
|
52
|
+
installment), each with its role and whether it may be claimed now, and `blockValues()` turns them into
|
|
53
|
+
values the guard checks a number against, as it checks a tool's result. An offer shown too long ago to claim makes the
|
|
54
|
+
number `stale`, and a price only the pack's text states is still `unsupported`. The constraints block's
|
|
55
|
+
`Shown` model gains `values` (`ShownValue`).
|
|
56
|
+
|
|
57
|
+
### Removed
|
|
58
|
+
|
|
59
|
+
- `tool(..., { binding })`, `new Counterfactual(..., { bindings })` and `niadra counterfactual --bindings`: a
|
|
60
|
+
tool's binding comes only from the space's `tool-bindings` document, which the SDK profile serves. A
|
|
61
|
+
counterfactual for a tool the space does not bind stops before calling it.
|
|
62
|
+
|
|
5
63
|
## [0.7.0] - 2026-09-30
|
|
6
64
|
|
|
7
65
|
The agent core. Every turn an agent takes is recorded in its own process; what it says is checked against
|
package/README.md
CHANGED
|
@@ -77,6 +77,45 @@ ESM and CommonJS builds with full type definitions; it only needs `fetch`.
|
|
|
77
77
|
| `objectState()`, `objectTimeline()` | a business object (an order, an invoice, a ticket) as the systems of record reported it |
|
|
78
78
|
| `feedback()` | a correction of what Niadra derived, audited like any other event |
|
|
79
79
|
|
|
80
|
+
## Benchmark
|
|
81
|
+
|
|
82
|
+
Niadra and ten other memory systems for agents (thirteen configurations) were measured on the same dataset, in the same AWS region
|
|
83
|
+
(us-east-2), with the same agent and the same judge for every system. The script, the dataset and every
|
|
84
|
+
result file are in this repository, under [`benchmarks/`](https://github.com/ainiadra/niadra-sdk-python/tree/main/benchmarks),
|
|
85
|
+
so anyone can run it again. The full page, with every metric and where Niadra does not lead, is at
|
|
86
|
+
[niadra.com/benchmark](https://niadra.com/benchmark).
|
|
87
|
+
|
|
88
|
+
Combined run of 01/10/2026 ([`2026-09-30-abb516`](https://github.com/ainiadra/niadra-sdk-python/tree/main/benchmarks/results/2026-09-30-abb516)),
|
|
89
|
+
cross-channel accuracy on the same 165 valid cases, judged by the same model:
|
|
90
|
+
|
|
91
|
+
| System | Accuracy | Model spend per 1,000 conversations |
|
|
92
|
+
|---|---|---|
|
|
93
|
+
| **Niadra** (3 repetitions) | **98.7%** | **US$ 0.36** |
|
|
94
|
+
| Hindsight | 86.7% | US$ 6.10 |
|
|
95
|
+
| Amazon Bedrock AgentCore Memory (3 repetitions) | 80% | US$ 7.50 (AWS public price, its models included) |
|
|
96
|
+
| Honcho (dialectic) | 79.4% | US$ 6.92 |
|
|
97
|
+
| Mem0 open source (3 repetitions) | 77.6% | US$ 1.88 |
|
|
98
|
+
| Memobase | 77% | US$ 4.13 |
|
|
99
|
+
| Supermemory local | 71.6% | US$ 5.78 |
|
|
100
|
+
| Cognee | 70.3% | US$ 6.95 |
|
|
101
|
+
| LangMem | 66.7% | US$ 3.70 |
|
|
102
|
+
| Graphiti | 52.8% | US$ 18.72 |
|
|
103
|
+
| MemOS | 51.6% | US$ 3.70 |
|
|
104
|
+
|
|
105
|
+
With a different user id on each channel (agents from different vendors), Mem0 open source drops to
|
|
106
|
+
28.5%, AgentCore Memory to 27.9%, and Niadra stays at 98.7%. Sensitive values reaching an unverified
|
|
107
|
+
conversation: Niadra 0 of 32; Mem0 and AgentCore Memory 32 of 32.
|
|
108
|
+
|
|
109
|
+
Typed state ([`typed/2026-09-30-b59a5d`](https://github.com/ainiadra/niadra-sdk-python/tree/main/benchmarks/results/typed/2026-09-30-b59a5d)):
|
|
110
|
+
with the state and constraints blocks, 84.9% correct [78, 90] against 36.6% without them; declared
|
|
111
|
+
constraints respected went from 0% to 94.4%, and what changed since the customer last saw it from 0% to
|
|
112
|
+
100%, with no extra tokens on a turn that asks for no block.
|
|
113
|
+
|
|
114
|
+
Where Niadra does not lead in that run: ingest acknowledgement against systems that write in the
|
|
115
|
+
background, opening a single history item, history search p95 against LangMem by a few ms, and tokens per
|
|
116
|
+
turn against readers that return answer text. The benchmark is produced by Niadra; that is why every input
|
|
117
|
+
and output is public.
|
|
118
|
+
|
|
80
119
|
## Questions people ask
|
|
81
120
|
|
|
82
121
|
**How do I give my AI agent memory of past conversations on other channels?** Record the turns
|
|
@@ -691,10 +730,11 @@ await convo.turn({ build: Niadra.build({ prompts: { store: "v16" }, model: "gpt-
|
|
|
691
730
|
without `include` keeps its suffix. With Niadra down, the last good blocks serve.
|
|
692
731
|
- **Coordination** decides by each purpose's direction when Niadra does not answer within 200 ms: a
|
|
693
732
|
customer's message and service go, marketing, retention, collection and an effect with a key wait, and
|
|
694
|
-
the local copy of the opt-out list always holds.
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
733
|
+
the local copy of the opt-out list always holds. Every check about an outbound contact keeps that copy,
|
|
734
|
+
read again in the background once a minute.
|
|
735
|
+
- **Tool bindings** live in the space's `tool-bindings` document and come in the SDK profile, never in code: a
|
|
736
|
+
tool measures the constraints block through the one served for its name, the counterfactual runs through it,
|
|
737
|
+
and its `capabilities.mask_output` decides the masking when the code leaves `maskOutput` unset.
|
|
698
738
|
- **The `niadra` command** (Node) runs `replay`, `counterfactual`, `resolver-worker` (the space's refresh
|
|
699
739
|
requests, read with your resolvers inside your boundary; a watch fires only on a value the worker
|
|
700
740
|
confirmed, and a resolver returns `NOT_FOUND` when the source no longer has the object), `types derive` and
|
|
@@ -714,10 +754,16 @@ Memory should make an agent better, never make it fail. By default:
|
|
|
714
754
|
| 401 or 403 | Not treated as an outage: the cached packs are dropped (all of them on 401, the one requested on 403) and `context()` returns empty. Revoking a key also stops what the process had cached. |
|
|
715
755
|
| 421 (the space moved to another cell) | Retried at once, up to three attempts. |
|
|
716
756
|
| 429 on a batch | Retried after `Retry-After`. |
|
|
717
|
-
| Batch failure | Retried with exponential backoff and jitter, three attempts. 4xx answers other than 408, 421 and 429 are never retried. A batch that still fails
|
|
757
|
+
| Batch failure | Retried with exponential backoff and jitter, three attempts. 4xx answers other than 408, 421 and 429 are never retried. A batch that still fails goes back to the front of the queue and leaves again after a pause that doubles, up to a minute, while Niadra stays down; each event keeps its idempotency key, so it is stored once. |
|
|
718
758
|
| Queue full (10,000 items) | New events are dropped and logged. |
|
|
719
759
|
| Server rejects one item of a batch (207) | Only that item fails; the rest are stored. |
|
|
720
760
|
|
|
761
|
+
With Niadra down, a read serves the conversation's last good pack (`source: "fallback"`) with `ageMs`
|
|
762
|
+
saying how old it is; the opt-out holds by the local copy of the suppression list; turn records, events
|
|
763
|
+
and declarations wait in their queues and leave once Niadra answers again, each stored once.
|
|
764
|
+
`test/chaos.test.ts` kills Niadra's process, silences its network, answers 503 and answers late in the
|
|
765
|
+
middle of a conversation, and checks all of it.
|
|
766
|
+
|
|
721
767
|
Every call you wait for has its own time budget for the whole call, retries and waits included, independent of your platform's:
|
|
722
768
|
|
|
723
769
|
| Call | Default |
|
|
@@ -729,7 +775,7 @@ Every call you wait for has its own time budget for the whole call, retries and
|
|
|
729
775
|
| `identify()`, `verify()`, `handoff()`, `feedback()` and the reservation in `uploadMedia()` | 5 s |
|
|
730
776
|
| The transfer in `uploadMedia()` | 60 s |
|
|
731
777
|
|
|
732
|
-
An `identify()`, `verify()` or `handoff()` that runs out of time resolves with
|
|
778
|
+
An `identify()`, `verify()` or `handoff()` that runs out of time, or that Niadra cannot take for now (a network error, a 5xx), resolves with that error and stays in the queue, which keeps sending it. `track()` never waits; each attempt of a background batch has 5 s. Override them with `timeouts`, or per call with `{ timeout }`. Pass `{ signal }` to cancel a call.
|
|
733
779
|
|
|
734
780
|
### The context cache
|
|
735
781
|
|
|
@@ -740,6 +786,8 @@ Inside a conversation or task, packs are cached in memory:
|
|
|
740
786
|
- when a request fails: the last good pack, if it is less than 30 minutes old;
|
|
741
787
|
- at most 1,000 packs, the least recently used evicted first.
|
|
742
788
|
|
|
789
|
+
`source` says which of these served the read, and `ageMs` how long ago Niadra sent or confirmed that pack.
|
|
790
|
+
|
|
743
791
|
Refreshes send the cached ETag, so an unchanged pack costs a `not_modified` answer instead of the
|
|
744
792
|
full text, and only one background refresh per pack runs at a time. A 401 or 403 is not an
|
|
745
793
|
outage: the cached packs go (all of them on 401, the one requested on 403), so cutting a vendor's
|
|
@@ -789,7 +837,7 @@ Include `requestId` when you contact support.
|
|
|
789
837
|
|
|
790
838
|
```sh
|
|
791
839
|
pnpm install
|
|
792
|
-
pnpm check # typecheck, lint, tests (the integrations with their frameworks' real types)
|
|
840
|
+
pnpm check # typecheck, lint, tests (the integrations with their frameworks' real types), audit of the runtime dependencies
|
|
793
841
|
pnpm build # ESM and CommonJS into dist/, one entry per integration
|
|
794
842
|
pnpm runtimes # the build on Deno, Bun, workerd and the Edge Runtime
|
|
795
843
|
pnpm --filter "./packages/*" check # the n8n and Flowise nodes
|
package/dist/ai-sdk.cjs
CHANGED
|
@@ -385,7 +385,7 @@ function thenable(value) {
|
|
|
385
385
|
function tool(name, fn, options = {}) {
|
|
386
386
|
const isAsync = isAsyncFunction(fn);
|
|
387
387
|
function bindingOf(frame) {
|
|
388
|
-
return
|
|
388
|
+
return (options.served ?? frame?.profile.bindings)?.(name) ?? null;
|
|
389
389
|
}
|
|
390
390
|
function masks(frame) {
|
|
391
391
|
return options.maskOutput ?? bindingOf(frame)?.capabilities?.mask_output ?? false;
|
|
@@ -500,8 +500,7 @@ function tool(name, fn, options = {}) {
|
|
|
500
500
|
const marker = {
|
|
501
501
|
name,
|
|
502
502
|
dryRun: options.dryRun ?? false,
|
|
503
|
-
provenance: options.provenance ?? null
|
|
504
|
-
binding: options.binding ?? null
|
|
503
|
+
provenance: options.provenance ?? null
|
|
505
504
|
};
|
|
506
505
|
Object.defineProperty(wrapped, RECORDED, { value: marker });
|
|
507
506
|
return wrapped;
|
|
@@ -527,7 +526,7 @@ function measure(frame, raw, args) {
|
|
|
527
526
|
|
|
528
527
|
// src/context.ts
|
|
529
528
|
function emptyResult(error) {
|
|
530
|
-
return { text: "", suffix: "", variables: {}, pack: null, source: "none", response: null, error, constraints: null, state: null, coordination: null };
|
|
529
|
+
return { text: "", suffix: "", variables: {}, pack: null, source: "none", ageMs: null, response: null, error, constraints: null, state: null, coordination: null };
|
|
531
530
|
}
|
|
532
531
|
|
|
533
532
|
// src/integrations/shared.ts
|