@niadra/sdk 0.9.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.
Files changed (57) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +40 -1
  3. package/dist/ai-sdk.d.cts +3 -3
  4. package/dist/ai-sdk.d.ts +3 -3
  5. package/dist/anthropic.d.cts +4 -4
  6. package/dist/anthropic.d.ts +4 -4
  7. package/dist/bedrock.d.cts +4 -4
  8. package/dist/bedrock.d.ts +4 -4
  9. package/dist/cli.js +51 -10
  10. package/dist/cli.js.map +1 -1
  11. package/dist/{client-B_ip8T2o.d.cts → client-CWMxmJHs.d.cts} +22 -14
  12. package/dist/{client-B_ip8T2o.d.ts → client-CWMxmJHs.d.ts} +22 -14
  13. package/dist/cloudflare-agents.d.cts +3 -3
  14. package/dist/cloudflare-agents.d.ts +3 -3
  15. package/dist/elevenlabs.d.cts +5 -5
  16. package/dist/elevenlabs.d.ts +5 -5
  17. package/dist/genkit.d.cts +3 -3
  18. package/dist/genkit.d.ts +3 -3
  19. package/dist/google-adk.d.cts +3 -3
  20. package/dist/google-adk.d.ts +3 -3
  21. package/dist/google-genai.d.cts +4 -4
  22. package/dist/google-genai.d.ts +4 -4
  23. package/dist/index.cjs +51 -10
  24. package/dist/index.cjs.map +1 -1
  25. package/dist/index.d.cts +3 -3
  26. package/dist/index.d.ts +3 -3
  27. package/dist/index.js +51 -10
  28. package/dist/index.js.map +1 -1
  29. package/dist/{intercept-CBaPK_-k.d.ts → intercept-Bv0nLpSw.d.ts} +1 -1
  30. package/dist/{intercept-CxmBLfoj.d.cts → intercept-CGngQI8B.d.cts} +1 -1
  31. package/dist/langchain.d.cts +3 -3
  32. package/dist/langchain.d.ts +3 -3
  33. package/dist/livekit.d.cts +3 -3
  34. package/dist/livekit.d.ts +3 -3
  35. package/dist/llamaindex.d.cts +3 -3
  36. package/dist/llamaindex.d.ts +3 -3
  37. package/dist/mastra.d.cts +3 -3
  38. package/dist/mastra.d.ts +3 -3
  39. package/dist/openai-agents.d.cts +3 -3
  40. package/dist/openai-agents.d.ts +3 -3
  41. package/dist/retell.d.cts +5 -5
  42. package/dist/retell.d.ts +5 -5
  43. package/dist/{shared-BLkAbvuf.d.ts → shared-B4Ef2Wpg.d.ts} +1 -1
  44. package/dist/{shared-DEkF2Y_z.d.cts → shared-Cq8mz-7m.d.cts} +1 -1
  45. package/dist/strands.d.cts +3 -3
  46. package/dist/strands.d.ts +3 -3
  47. package/dist/twilio.d.cts +4 -4
  48. package/dist/twilio.d.ts +4 -4
  49. package/dist/vapi.d.cts +5 -5
  50. package/dist/vapi.d.ts +5 -5
  51. package/dist/voltagent.d.cts +3 -3
  52. package/dist/voltagent.d.ts +3 -3
  53. package/dist/{webhook-CuR0Wckd.d.cts → webhook-jTx_SegV.d.cts} +1 -1
  54. package/dist/{webhook-BaraTaA9.d.ts → webhook-z2TjUzjv.d.ts} +1 -1
  55. package/dist/whatsapp.d.cts +2 -2
  56. package/dist/whatsapp.d.ts +2 -2
  57. package/package.json +3 -2
package/CHANGELOG.md CHANGED
@@ -4,6 +4,18 @@ All notable changes to this package are documented here. The format follows [Kee
4
4
 
5
5
  ## [Unreleased]
6
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
+
7
19
  ## [0.9.0] - 2026-09-30
8
20
 
9
21
  ### Added
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
@@ -798,7 +837,7 @@ Include `requestId` when you contact support.
798
837
 
799
838
  ```sh
800
839
  pnpm install
801
- 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
802
841
  pnpm build # ESM and CommonJS into dist/, one entry per integration
803
842
  pnpm runtimes # the build on Deno, Bun, workerd and the Edge Runtime
804
843
  pnpm --filter "./packages/*" check # the n8n and Flowise nodes
package/dist/ai-sdk.d.cts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { ToolSet } from 'ai';
2
- import { f as ModelUsage, fZ as TurnParams, fS as TurnFrame } from './client-B_ip8T2o.cjs';
3
- import { a as ProofSource, A as AgentMemoryOption, b as Session, S as SessionResolver } from './shared-DEkF2Y_z.cjs';
4
- export { P as Proof, c as attestationProof } from './shared-DEkF2Y_z.cjs';
2
+ import { f as ModelUsage, fZ as TurnParams, fS as TurnFrame } from './client-CWMxmJHs.cjs';
3
+ import { a as ProofSource, A as AgentMemoryOption, b as Session, S as SessionResolver } from './shared-Cq8mz-7m.cjs';
4
+ export { P as Proof, c as attestationProof } from './shared-Cq8mz-7m.cjs';
5
5
 
6
6
  /**
7
7
  * Niadra for the Vercel AI SDK (`ai` 5, 6 and 7), the idiomatic way: a language model middleware
package/dist/ai-sdk.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { ToolSet } from 'ai';
2
- import { f as ModelUsage, fZ as TurnParams, fS as TurnFrame } from './client-B_ip8T2o.js';
3
- import { a as ProofSource, A as AgentMemoryOption, b as Session, S as SessionResolver } from './shared-BLkAbvuf.js';
4
- export { P as Proof, c as attestationProof } from './shared-BLkAbvuf.js';
2
+ import { f as ModelUsage, fZ as TurnParams, fS as TurnFrame } from './client-CWMxmJHs.js';
3
+ import { a as ProofSource, A as AgentMemoryOption, b as Session, S as SessionResolver } from './shared-B4Ef2Wpg.js';
4
+ export { P as Proof, c as attestationProof } from './shared-B4Ef2Wpg.js';
5
5
 
6
6
  /**
7
7
  * Niadra for the Vercel AI SDK (`ai` 5, 6 and 7), the idiomatic way: a language model middleware
@@ -1,7 +1,7 @@
1
- import { W as WrapOptions } from './intercept-CxmBLfoj.cjs';
2
- import { S as SessionResolver } from './shared-DEkF2Y_z.cjs';
3
- export { A as AgentMemoryOption, P as Proof, a as ProofSource, b as Session, c as attestationProof } from './shared-DEkF2Y_z.cjs';
4
- import './client-B_ip8T2o.cjs';
1
+ import { W as WrapOptions } from './intercept-CGngQI8B.cjs';
2
+ import { S as SessionResolver } from './shared-Cq8mz-7m.cjs';
3
+ export { A as AgentMemoryOption, P as Proof, a as ProofSource, b as Session, c as attestationProof } from './shared-Cq8mz-7m.cjs';
4
+ import './client-CWMxmJHs.cjs';
5
5
 
6
6
  /**
7
7
  * Niadra for the Anthropic TypeScript SDK (`@anthropic-ai/sdk`), as `wrap()` is for OpenAI.
@@ -1,7 +1,7 @@
1
- import { W as WrapOptions } from './intercept-CBaPK_-k.js';
2
- import { S as SessionResolver } from './shared-BLkAbvuf.js';
3
- export { A as AgentMemoryOption, P as Proof, a as ProofSource, b as Session, c as attestationProof } from './shared-BLkAbvuf.js';
4
- import './client-B_ip8T2o.js';
1
+ import { W as WrapOptions } from './intercept-Bv0nLpSw.js';
2
+ import { S as SessionResolver } from './shared-B4Ef2Wpg.js';
3
+ export { A as AgentMemoryOption, P as Proof, a as ProofSource, b as Session, c as attestationProof } from './shared-B4Ef2Wpg.js';
4
+ import './client-CWMxmJHs.js';
5
5
 
6
6
  /**
7
7
  * Niadra for the Anthropic TypeScript SDK (`@anthropic-ai/sdk`), as `wrap()` is for OpenAI.
@@ -1,7 +1,7 @@
1
- import { f as ModelUsage } from './client-B_ip8T2o.cjs';
2
- import { W as WrapOptions } from './intercept-CxmBLfoj.cjs';
3
- import { S as SessionResolver } from './shared-DEkF2Y_z.cjs';
4
- export { A as AgentMemoryOption, P as Proof, a as ProofSource, b as Session, c as attestationProof } from './shared-DEkF2Y_z.cjs';
1
+ import { f as ModelUsage } from './client-CWMxmJHs.cjs';
2
+ import { W as WrapOptions } from './intercept-CGngQI8B.cjs';
3
+ import { S as SessionResolver } from './shared-Cq8mz-7m.cjs';
4
+ export { A as AgentMemoryOption, P as Proof, a as ProofSource, b as Session, c as attestationProof } from './shared-Cq8mz-7m.cjs';
5
5
 
6
6
  /**
7
7
  * Niadra for Amazon Bedrock's Converse API (`@aws-sdk/client-bedrock-runtime`), as `wrap()` is for
package/dist/bedrock.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- import { f as ModelUsage } from './client-B_ip8T2o.js';
2
- import { W as WrapOptions } from './intercept-CBaPK_-k.js';
3
- import { S as SessionResolver } from './shared-BLkAbvuf.js';
4
- export { A as AgentMemoryOption, P as Proof, a as ProofSource, b as Session, c as attestationProof } from './shared-BLkAbvuf.js';
1
+ import { f as ModelUsage } from './client-CWMxmJHs.js';
2
+ import { W as WrapOptions } from './intercept-Bv0nLpSw.js';
3
+ import { S as SessionResolver } from './shared-B4Ef2Wpg.js';
4
+ export { A as AgentMemoryOption, P as Proof, a as ProofSource, b as Session, c as attestationProof } from './shared-B4Ef2Wpg.js';
5
5
 
6
6
  /**
7
7
  * Niadra for Amazon Bedrock's Converse API (`@aws-sdk/client-bedrock-runtime`), as `wrap()` is for
package/dist/cli.js CHANGED
@@ -503,7 +503,7 @@ function internalRecord(span, ref, act) {
503
503
  }
504
504
 
505
505
  // src/version.ts
506
- var VERSION = "0.9.0";
506
+ var VERSION = "0.9.1";
507
507
 
508
508
  // src/transport.ts
509
509
  var RETRYABLE_WRITE_STATUS = /* @__PURE__ */ new Set([408, 421, 429, 500, 502, 503, 504]);
@@ -597,6 +597,7 @@ var Transport = class {
597
597
  } catch (error) {
598
598
  throw deadline.explain(error);
599
599
  }
600
+ warnIfDeprecated(this.config.logger, init.method ?? "GET", url, response.headers);
600
601
  const requestId = response.headers.get("x-request-id");
601
602
  let payload;
602
603
  try {
@@ -666,6 +667,29 @@ var Deadline = class {
666
667
  return new NiadraConnectionError(`connection failed: ${message}`, { cause: error });
667
668
  }
668
669
  };
670
+ var VERSIONING_DOCS = "https://docs.niadra.com/en/security/api-versioning";
671
+ var DEPRECATION_LINK = /<([^>]*)>[^,]*;\s*rel="?deprecation"?/gi;
672
+ var deprecationsSeen = /* @__PURE__ */ new Set();
673
+ function warnIfDeprecated(logger, method, url, headers) {
674
+ const since = headers.get("deprecation");
675
+ if (since === null) return;
676
+ const links = [...(headers.get("link") ?? "").matchAll(DEPRECATION_LINK)].map((match) => match[1] ?? "");
677
+ const key2 = `${method} ${links.join(" ") || (url.split("?")[0] ?? url)}`;
678
+ if (deprecationsSeen.has(key2)) return;
679
+ deprecationsSeen.add(key2);
680
+ const sunset = headers.get("sunset");
681
+ logger.warn(
682
+ `the API deprecated a ${method} route this client calls, since ${deprecatedSince(since)}; it stops answering on ${sunset === null ? "a date not announced yet" : sunsetDay(sunset)}. See ${links.join(", ") || VERSIONING_DOCS}`
683
+ );
684
+ }
685
+ function deprecatedSince(value) {
686
+ const seconds = Number(value.trim().replace(/^@/, ""));
687
+ return Number.isInteger(seconds) ? new Date(seconds * 1e3).toISOString().slice(0, 10) : value;
688
+ }
689
+ function sunsetDay(value) {
690
+ const time = Date.parse(value);
691
+ return Number.isNaN(time) ? value : new Date(time).toISOString().slice(0, 10);
692
+ }
669
693
  async function readBody(response) {
670
694
  const text2 = await response.text();
671
695
  if (text2.length === 0) return null;
@@ -4376,26 +4400,42 @@ async function suppressionKey(salt, canonical) {
4376
4400
  const key2 = await subtle.importKey("raw", saltBytes(salt), { name: "HMAC", hash: "SHA-256" }, false, ["sign"]);
4377
4401
  return toBase64url(new Uint8Array(await subtle.sign("HMAC", key2, new TextEncoder().encode(canonical))));
4378
4402
  }
4403
+ var AREA_CODES = new Set(
4404
+ "11 12 13 14 15 16 17 18 19 21 22 24 27 28 31 32 33 34 35 37 38 41 42 43 44 45 46 47 48 49 51 53 54 55 61 62 63 64 65 66 67 68 69 71 73 74 75 77 79 81 82 83 84 85 86 87 88 89 91 92 93 94 95 96 97 98 99".split(" ")
4405
+ );
4406
+ var FORMAT_CHARACTERS = new RegExp("\\p{Cf}", "gu");
4379
4407
  function phone(value) {
4380
- const raw = value.trim().replace(SEPARATORS2, "");
4381
- const international = raw.startsWith("+") || raw.startsWith("00");
4408
+ let text2 = value.normalize("NFKC").replace(FORMAT_CHARACTERS, "").trim();
4409
+ if (text2.slice(0, 4).toLowerCase() === "tel:") text2 = text2.slice(4);
4410
+ const international = text2.startsWith("+") || text2.startsWith("00");
4411
+ if (international) text2 = text2.replaceAll("(0)", "");
4412
+ const raw = text2.replace(SEPARATORS2, "");
4382
4413
  let digits = raw.startsWith("+") ? raw.slice(1) : international ? raw.slice(2) : raw;
4383
4414
  if (!DIGITS2.test(digits)) throw new NiadraDestinationError("invalid_handle");
4384
- const national = digits.replace(/^0+/, "");
4385
- if (!international && (national.length === 10 || national.length === 11) && isArea(national.slice(0, 2))) {
4386
- digits = `55${national}`;
4415
+ if (!international) {
4416
+ const national = digits.replace(/^0+/, "");
4417
+ if (isBrazilianNational(national)) {
4418
+ digits = `55${national}`;
4419
+ } else if (digits.startsWith("0") && (national.length === 12 || national.length === 13)) {
4420
+ if (isBrazilianNational(national.slice(2))) digits = `55${national.slice(2)}`;
4421
+ }
4387
4422
  }
4388
4423
  if (digits.length < 8 || digits.length > 15 || digits.startsWith("0")) {
4389
4424
  throw new NiadraDestinationError("invalid_handle");
4390
4425
  }
4391
4426
  const rest = digits.slice(2);
4392
- if (digits.startsWith("55") && rest.length === 10 && isArea(rest.slice(0, 2)) && "6789".includes(rest.charAt(2))) {
4427
+ if (digits.startsWith("55") && rest.length === 10 && AREA_CODES.has(rest.slice(0, 2)) && "6789".includes(rest.charAt(2))) {
4393
4428
  digits = `55${rest.slice(0, 2)}9${rest.slice(2)}`;
4394
4429
  }
4430
+ if (digits.length === 13 && (digits.startsWith("521") || digits.startsWith("549"))) {
4431
+ digits = digits.slice(0, 2) + digits.slice(3);
4432
+ }
4395
4433
  return `phone:+${digits}`;
4396
4434
  }
4397
- function isArea(code) {
4398
- return /^[1-9]{2}$/.test(code);
4435
+ function isBrazilianNational(national) {
4436
+ if (!AREA_CODES.has(national.slice(0, 2))) return false;
4437
+ if (national.length === 10) return "23456789".includes(national.charAt(2));
4438
+ return national.length === 11 && national.charAt(2) === "9";
4399
4439
  }
4400
4440
  function saltBytes(salt) {
4401
4441
  const bytes = fromBase64url(salt);
@@ -8456,7 +8496,8 @@ var Niadra = class _Niadra {
8456
8496
  baseURL,
8457
8497
  apiKey,
8458
8498
  fetch: fetchImpl,
8459
- defaultHeaders: options.defaultHeaders ?? {}
8499
+ defaultHeaders: options.defaultHeaders ?? {},
8500
+ logger: this.logger
8460
8501
  });
8461
8502
  const queueOptions = { ...DEFAULT_QUEUE, ...options.queue };
8462
8503
  queueOptions.maxBatchSize = Math.min(queueOptions.maxBatchSize, 499);