@anuma/sdk 6.33.1 → 6.33.2

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 (45) hide show
  1. package/dist/design/index.cjs +0 -2
  2. package/dist/design/index.d.mts +0 -7
  3. package/dist/design/index.d.ts +0 -7
  4. package/dist/design/index.mjs +0 -2
  5. package/dist/expo/{chunk-XD6WOQ5I.mjs → chunk-GQBTAM6Y.mjs} +0 -70
  6. package/dist/expo/{consolidate-7DBUHQRK.mjs → consolidate-3H2WY3FU.mjs} +1 -8
  7. package/dist/expo/index.cjs +15394 -16278
  8. package/dist/expo/index.d.mts +5734 -6660
  9. package/dist/expo/index.d.ts +5734 -6660
  10. package/dist/expo/index.mjs +15231 -16034
  11. package/dist/index.cjs +2258 -2411
  12. package/dist/index.d.mts +914 -1054
  13. package/dist/index.d.ts +914 -1054
  14. package/dist/index.mjs +2258 -2409
  15. package/dist/memory/context.d.mts +0 -73
  16. package/dist/memory/context.d.ts +0 -73
  17. package/dist/next/index.cjs +1 -8
  18. package/dist/next/index.mjs +1 -8
  19. package/dist/pii/transformers.d.mts +0 -32
  20. package/dist/pii/transformers.d.ts +0 -32
  21. package/dist/react/{chunk-XNQRJBIH.mjs → chunk-UFO4W3JX.mjs} +0 -70
  22. package/dist/react/{consolidate-5DVINCUE.mjs → consolidate-RHIAUBT4.mjs} +1 -8
  23. package/dist/react/index.cjs +32415 -33395
  24. package/dist/react/index.d.mts +13354 -14553
  25. package/dist/react/index.d.ts +13354 -14553
  26. package/dist/react/index.mjs +32556 -33457
  27. package/dist/server/{chunk-KSYV7UO2.mjs → chunk-4RGGAOAJ.mjs} +835 -905
  28. package/dist/server/{consolidate-MCNBSUXD.mjs → consolidate-YEGACWLR.mjs} +1 -8
  29. package/dist/server/index.cjs +22313 -23120
  30. package/dist/server/index.d.mts +5353 -6300
  31. package/dist/server/index.d.ts +5353 -6300
  32. package/dist/server/index.mjs +18789 -19531
  33. package/dist/telemetry/index.cjs +0 -9
  34. package/dist/telemetry/index.d.mts +88 -198
  35. package/dist/telemetry/index.d.ts +88 -198
  36. package/dist/telemetry/index.mjs +0 -9
  37. package/dist/tools/index.cjs +13036 -13347
  38. package/dist/tools/index.d.mts +2434 -2729
  39. package/dist/tools/index.d.ts +2434 -2729
  40. package/dist/tools/index.mjs +13036 -13347
  41. package/dist/tools/selection/index.cjs +0 -116
  42. package/dist/tools/selection/index.d.mts +0 -159
  43. package/dist/tools/selection/index.d.ts +0 -159
  44. package/dist/tools/selection/index.mjs +0 -116
  45. package/package.json +1 -1
@@ -174,44 +174,6 @@ interface EntityOperationsContext {
174
174
  allowUnscopedRows?: boolean;
175
175
  }
176
176
 
177
- /**
178
- * Shared portal LLM call for the memory pipeline.
179
- *
180
- * The three LLM-driven steps (`extractFacts`, `consolidateMemory`,
181
- * `decomposeQuery`) share the same shape: POST to `/api/v1/chat/completions`
182
- * with a system+user prompt and `response_format: json_object`, parse
183
- * `choices[0].message.content` as JSON, validate, return null on any failure.
184
- * This helper owns the fetch+timeout+parse+log boilerplate so each caller
185
- * stays focused on its prompt and validator.
186
- *
187
- * PROMPT CACHING. The portal inserts explicit prompt-cache breakpoints only for
188
- * `anthropic/` models. Its request schema does carry OpenAI's
189
- * `prompt_cache_key`, but that is a routing hint for OpenAI's own implicit
190
- * cache rather than a switch that enables caching, and we deliberately don't
191
- * send it: the memory pipeline runs open-weights models by default (gpt-oss for
192
- * extraction/topics, ling for consolidation), and this module already has one
193
- * hard lesson about OpenAI-standard fields a non-OpenAI provider hard-400s on
194
- * (`response_format`, below). Revisit only with a verified per-provider gate.
195
- *
196
- * So on the models this pipeline actually uses, the only cache that can hit is
197
- * the provider's own implicit prefix cache — which makes prefix stability the
198
- * one lever a caller controls. Messages are assembled system-first (below), so
199
- * every caller must pass a CONSTANT `systemPrompt` and keep all per-call
200
- * material in `userMessage`: a single interpolated timestamp, id, or count in a
201
- * system prompt shifts every byte after it and misses the cache on every
202
- * request thereafter. The memory callers are regression-gated on that property
203
- * in `promptPrefixStability.test.ts`.
204
- *
205
- * Whether those implicit caches hit is observable: each successful response
206
- * logs the portal's reported token counts at debug level, including
207
- * `portal.cached_tokens` (the prompt tokens the provider served from cache —
208
- * the portal omits the field when there was no hit). See {@link logPortalUsage}.
209
- *
210
- * There is no batch/async-bulk route on the portal, so a backfill or reindex
211
- * has no discounted-throughput path either; its only levers are the same stable
212
- * prefix and caller-side batching (e.g. topicExtract's 10-memories-per-call).
213
- */
214
-
215
177
  /**
216
178
  * Auth for portal LLM calls (extraction, consolidation, decomposition,
217
179
  * reflection). Mirrors `memoryEngine`'s `EmbeddingOptions` dual-auth:
@@ -231,16 +193,6 @@ interface PortalLlmAuth {
231
193
  getToken?: () => Promise<string | null>;
232
194
  }
233
195
 
234
- /**
235
- * Linear recency decay multiplier — applied post-fusion to nudge fresh
236
- * memories above stale ones with otherwise comparable scores.
237
- *
238
- * Formula:
239
- * multiplier(ageDays) = max(floor, 1 - perYearDecay * (ageDays / 365))
240
- *
241
- * Memories without an `updatedAt` get a neutral 0.5 (Hindsight pattern —
242
- * neither boost nor penalty when freshness is unknown).
243
- */
244
196
  interface RecencyOptions {
245
197
  /** Override "now" — useful for deterministic tests and back-dated benchmarks. */
246
198
  now?: Date;
@@ -263,16 +215,6 @@ interface RecencyOptions {
263
215
  */
264
216
  type ObservationTrend = "new" | "strengthening" | "stable" | "weakening" | "stale";
265
217
 
266
- /**
267
- * Unified memory layer types — the Recall / Retain API.
268
- *
269
- * This module defines the public surface for the new unified memory layer
270
- * that sits above `memoryVault` (curated facts) and `memoryEngine` (raw
271
- * conversation chunks). Callers should prefer these types over the legacy
272
- * `VaultSearchResult` / `ChunkSearchResult` shapes; the underlying stores
273
- * may converge later, the API will not.
274
- */
275
-
276
218
  type MemoryKind = "fact" | "chunk";
277
219
  /**
278
220
  * Budget controls retrieval depth/cost. Higher budgets enable more
@@ -704,21 +646,6 @@ interface RecallDiagnostics {
704
646
  degraded: RecallDegradation[];
705
647
  }
706
648
 
707
- /**
708
- * Auto-extraction worker — W2.
709
- *
710
- * After each assistant turn, this pipeline reads the recent conversation,
711
- * asks an LLM to identify durable user facts, and writes them to the
712
- * vault via retain(). The user never needs to ask Anuma to remember
713
- * something — durable facts are captured automatically.
714
- *
715
- * Two-stage pipeline (extract → retain). The retain step uses
716
- * write-time auto-merge (W4) so the same fact re-observed in a later
717
- * conversation increments proof_count instead of duplicating.
718
- *
719
- * Spec: see `tasks/hackathon/auto-extraction-prompt.md`.
720
- */
721
-
722
649
  declare const FACT_TYPES: readonly ["identity", "preference", "relationship", "plan", "ongoing_context", "constraint", "other"];
723
650
  type FactType = (typeof FACT_TYPES)[number];
724
651
 
@@ -174,44 +174,6 @@ interface EntityOperationsContext {
174
174
  allowUnscopedRows?: boolean;
175
175
  }
176
176
 
177
- /**
178
- * Shared portal LLM call for the memory pipeline.
179
- *
180
- * The three LLM-driven steps (`extractFacts`, `consolidateMemory`,
181
- * `decomposeQuery`) share the same shape: POST to `/api/v1/chat/completions`
182
- * with a system+user prompt and `response_format: json_object`, parse
183
- * `choices[0].message.content` as JSON, validate, return null on any failure.
184
- * This helper owns the fetch+timeout+parse+log boilerplate so each caller
185
- * stays focused on its prompt and validator.
186
- *
187
- * PROMPT CACHING. The portal inserts explicit prompt-cache breakpoints only for
188
- * `anthropic/` models. Its request schema does carry OpenAI's
189
- * `prompt_cache_key`, but that is a routing hint for OpenAI's own implicit
190
- * cache rather than a switch that enables caching, and we deliberately don't
191
- * send it: the memory pipeline runs open-weights models by default (gpt-oss for
192
- * extraction/topics, ling for consolidation), and this module already has one
193
- * hard lesson about OpenAI-standard fields a non-OpenAI provider hard-400s on
194
- * (`response_format`, below). Revisit only with a verified per-provider gate.
195
- *
196
- * So on the models this pipeline actually uses, the only cache that can hit is
197
- * the provider's own implicit prefix cache — which makes prefix stability the
198
- * one lever a caller controls. Messages are assembled system-first (below), so
199
- * every caller must pass a CONSTANT `systemPrompt` and keep all per-call
200
- * material in `userMessage`: a single interpolated timestamp, id, or count in a
201
- * system prompt shifts every byte after it and misses the cache on every
202
- * request thereafter. The memory callers are regression-gated on that property
203
- * in `promptPrefixStability.test.ts`.
204
- *
205
- * Whether those implicit caches hit is observable: each successful response
206
- * logs the portal's reported token counts at debug level, including
207
- * `portal.cached_tokens` (the prompt tokens the provider served from cache —
208
- * the portal omits the field when there was no hit). See {@link logPortalUsage}.
209
- *
210
- * There is no batch/async-bulk route on the portal, so a backfill or reindex
211
- * has no discounted-throughput path either; its only levers are the same stable
212
- * prefix and caller-side batching (e.g. topicExtract's 10-memories-per-call).
213
- */
214
-
215
177
  /**
216
178
  * Auth for portal LLM calls (extraction, consolidation, decomposition,
217
179
  * reflection). Mirrors `memoryEngine`'s `EmbeddingOptions` dual-auth:
@@ -231,16 +193,6 @@ interface PortalLlmAuth {
231
193
  getToken?: () => Promise<string | null>;
232
194
  }
233
195
 
234
- /**
235
- * Linear recency decay multiplier — applied post-fusion to nudge fresh
236
- * memories above stale ones with otherwise comparable scores.
237
- *
238
- * Formula:
239
- * multiplier(ageDays) = max(floor, 1 - perYearDecay * (ageDays / 365))
240
- *
241
- * Memories without an `updatedAt` get a neutral 0.5 (Hindsight pattern —
242
- * neither boost nor penalty when freshness is unknown).
243
- */
244
196
  interface RecencyOptions {
245
197
  /** Override "now" — useful for deterministic tests and back-dated benchmarks. */
246
198
  now?: Date;
@@ -263,16 +215,6 @@ interface RecencyOptions {
263
215
  */
264
216
  type ObservationTrend = "new" | "strengthening" | "stable" | "weakening" | "stale";
265
217
 
266
- /**
267
- * Unified memory layer types — the Recall / Retain API.
268
- *
269
- * This module defines the public surface for the new unified memory layer
270
- * that sits above `memoryVault` (curated facts) and `memoryEngine` (raw
271
- * conversation chunks). Callers should prefer these types over the legacy
272
- * `VaultSearchResult` / `ChunkSearchResult` shapes; the underlying stores
273
- * may converge later, the API will not.
274
- */
275
-
276
218
  type MemoryKind = "fact" | "chunk";
277
219
  /**
278
220
  * Budget controls retrieval depth/cost. Higher budgets enable more
@@ -704,21 +646,6 @@ interface RecallDiagnostics {
704
646
  degraded: RecallDegradation[];
705
647
  }
706
648
 
707
- /**
708
- * Auto-extraction worker — W2.
709
- *
710
- * After each assistant turn, this pipeline reads the recent conversation,
711
- * asks an LLM to identify durable user facts, and writes them to the
712
- * vault via retain(). The user never needs to ask Anuma to remember
713
- * something — durable facts are captured automatically.
714
- *
715
- * Two-stage pipeline (extract → retain). The retain step uses
716
- * write-time auto-merge (W4) so the same fact re-observed in a later
717
- * conversation increments proof_count instead of duplicating.
718
- *
719
- * Spec: see `tasks/hackathon/auto-extraction-prompt.md`.
720
- */
721
-
722
649
  declare const FACT_TYPES: readonly ["identity", "preference", "relationship", "plan", "ongoing_context", "constraint", "other"];
723
650
  type FactType = (typeof FACT_TYPES)[number];
724
651
 
@@ -26,14 +26,7 @@ module.exports = __toCommonJS(index_exports);
26
26
  var withAnuma = (nextConfig = {}) => {
27
27
  return {
28
28
  ...nextConfig,
29
- serverExternalPackages: [
30
- ...nextConfig.serverExternalPackages ?? [],
31
- "sharp",
32
- // exceljs pulls in unzipper → fstream which calls process.umask() at
33
- // module init time, crashing Cloudflare Workers and other edge runtimes.
34
- // Externalizing prevents the server bundler from including it in SSR.
35
- "exceljs"
36
- ],
29
+ serverExternalPackages: [...nextConfig.serverExternalPackages ?? [], "sharp", "exceljs"],
37
30
  webpack: (config, options) => {
38
31
  const { isServer } = options;
39
32
  if (!isServer) {
@@ -2,14 +2,7 @@
2
2
  var withAnuma = (nextConfig = {}) => {
3
3
  return {
4
4
  ...nextConfig,
5
- serverExternalPackages: [
6
- ...nextConfig.serverExternalPackages ?? [],
7
- "sharp",
8
- // exceljs pulls in unzipper → fstream which calls process.umask() at
9
- // module init time, crashing Cloudflare Workers and other edge runtimes.
10
- // Externalizing prevents the server bundler from including it in SSR.
11
- "exceljs"
12
- ],
5
+ serverExternalPackages: [...nextConfig.serverExternalPackages ?? [], "sharp", "exceljs"],
13
6
  webpack: (config, options) => {
14
7
  const { isServer } = options;
15
8
  if (!isServer) {
@@ -6,23 +6,6 @@
6
6
  */
7
7
  type PiiCategory = "EMAIL" | "PHONE" | "SSN" | "CREDIT_CARD" | "IP_ADDRESS" | "API_KEY" | "US_ADDRESS" | "DATE_OF_BIRTH";
8
8
 
9
- /**
10
- * NER detector contract for PII redaction.
11
- *
12
- * The regex layer in {@link ./patterns} handles *structured* PII (email, phone,
13
- * SSN, credit card, …). It cannot detect *unstructured* PII — person names,
14
- * locations, organizations — which need a named-entity-recognition model.
15
- *
16
- * Rather than bundle a model (and a runtime) into the SDK, we define a small
17
- * runtime-agnostic contract: a {@link NerDetector} takes text and returns the
18
- * spans it found. Consumers supply an implementation appropriate to their
19
- * platform — a Transformers.js model in the browser/Node (see
20
- * `./detectors/transformers`), an `onnxruntime-react-native` model on mobile,
21
- * a remote service, or a fake in tests. The SDK keeps detection *on-device* by
22
- * never calling out itself; it only consumes the spans a detector returns and
23
- * merges them into the existing placeholder map.
24
- */
25
-
26
9
  /**
27
10
  * A character-offset span of detected PII. `start`/`end` are indices into the
28
11
  * text passed to {@link NerDetector.detect} (`end` exclusive). `category`
@@ -51,21 +34,6 @@ interface NerDetector {
51
34
  detect(text: string): Promise<PiiSpan[]>;
52
35
  }
53
36
 
54
- /**
55
- * Reference {@link NerDetector} backed by Transformers.js (`@huggingface/transformers`).
56
- *
57
- * Runs a quantized BERT NER model fully on-device (browser via the
58
- * onnxruntime-web/WASM backend, or Node) — no network call, so PII never leaves
59
- * the device. The model is loaded lazily on first `detect()` and cached, so
60
- * importing this module is cheap and apps that never enable NER pay nothing.
61
- *
62
- * `@huggingface/transformers` is an OPTIONAL peer dependency: it is `import()`-ed
63
- * dynamically (matching `lib/memory/reranker.ts`) so it is only required when a
64
- * caller actually constructs this detector. React Native cannot use this
65
- * detector (its WASM backend doesn't run under Hermes) — supply an
66
- * `onnxruntime-react-native`-based {@link NerDetector} there instead.
67
- */
68
-
69
37
  interface TransformersNerDetectorOptions {
70
38
  /** Hugging Face model id. Default: `Xenova/bert-base-NER`. */
71
39
  model?: string;
@@ -6,23 +6,6 @@
6
6
  */
7
7
  type PiiCategory = "EMAIL" | "PHONE" | "SSN" | "CREDIT_CARD" | "IP_ADDRESS" | "API_KEY" | "US_ADDRESS" | "DATE_OF_BIRTH";
8
8
 
9
- /**
10
- * NER detector contract for PII redaction.
11
- *
12
- * The regex layer in {@link ./patterns} handles *structured* PII (email, phone,
13
- * SSN, credit card, …). It cannot detect *unstructured* PII — person names,
14
- * locations, organizations — which need a named-entity-recognition model.
15
- *
16
- * Rather than bundle a model (and a runtime) into the SDK, we define a small
17
- * runtime-agnostic contract: a {@link NerDetector} takes text and returns the
18
- * spans it found. Consumers supply an implementation appropriate to their
19
- * platform — a Transformers.js model in the browser/Node (see
20
- * `./detectors/transformers`), an `onnxruntime-react-native` model on mobile,
21
- * a remote service, or a fake in tests. The SDK keeps detection *on-device* by
22
- * never calling out itself; it only consumes the spans a detector returns and
23
- * merges them into the existing placeholder map.
24
- */
25
-
26
9
  /**
27
10
  * A character-offset span of detected PII. `start`/`end` are indices into the
28
11
  * text passed to {@link NerDetector.detect} (`end` exclusive). `category`
@@ -51,21 +34,6 @@ interface NerDetector {
51
34
  detect(text: string): Promise<PiiSpan[]>;
52
35
  }
53
36
 
54
- /**
55
- * Reference {@link NerDetector} backed by Transformers.js (`@huggingface/transformers`).
56
- *
57
- * Runs a quantized BERT NER model fully on-device (browser via the
58
- * onnxruntime-web/WASM backend, or Node) — no network call, so PII never leaves
59
- * the device. The model is loaded lazily on first `detect()` and cached, so
60
- * importing this module is cheap and apps that never enable NER pay nothing.
61
- *
62
- * `@huggingface/transformers` is an OPTIONAL peer dependency: it is `import()`-ed
63
- * dynamically (matching `lib/memory/reranker.ts`) so it is only required when a
64
- * caller actually constructs this detector. React Native cannot use this
65
- * detector (its WASM backend doesn't run under Hermes) — supply an
66
- * `onnxruntime-react-native`-based {@link NerDetector} there instead.
67
- */
68
-
69
37
  interface TransformersNerDetectorOptions {
70
38
  /** Hugging Face model id. Default: `Xenova/bert-base-NER`. */
71
39
  model?: string;
@@ -59,15 +59,10 @@ function luhnCheck(digits) {
59
59
  return sum % 10 === 0;
60
60
  }
61
61
  var PII_PATTERNS = [
62
- // Email — standard RFC-ish pattern.
63
- // Quantifiers are bounded (local-part ≤ 64, domain ≤ 255, TLD ≤ 24 —
64
- // all at or above real RFC 5321 limits) so the engine cannot backtrack
65
- // quadratically on adversarial input like "a.a.a.a…" with no "@".
66
62
  {
67
63
  category: "EMAIL",
68
64
  regex: /\b[a-zA-Z0-9._%+-]{1,64}@[a-zA-Z0-9.-]{1,255}\.[a-zA-Z]{2,24}\b/g
69
65
  },
70
- // SSN — US Social Security Number, dashed form (must run before phone)
71
66
  {
72
67
  category: "SSN",
73
68
  regex: /\b\d{3}-\d{2}-\d{4}\b/g,
@@ -77,9 +72,6 @@ var PII_PATTERNS = [
77
72
  return area !== 0 && area !== 666 && area < 900;
78
73
  }
79
74
  },
80
- // SSN — dashless or space-separated form. Only redacted with an "SSN" /
81
- // "social security" cue nearby: a bare 9-digit run is too ambiguous
82
- // (ZIP+4, account numbers, etc.) to redact unconditionally.
83
75
  {
84
76
  category: "SSN",
85
77
  regex: /\b\d{3}[ ]?\d{2}[ ]?\d{4}\b/g,
@@ -91,8 +83,6 @@ var PII_PATTERNS = [
91
83
  return area !== 0 && area !== 666 && area < 900;
92
84
  }
93
85
  },
94
- // Credit card numbers — 13-19 contiguous digits or groups of 4 separated by spaces/dashes
95
- // Must run before phone to avoid partial matches
96
86
  {
97
87
  category: "CREDIT_CARD",
98
88
  regex: /\b\d{4}[\s-]\d{4}[\s-]\d{4}[\s-]\d{1,7}\b|\b\d{13,19}\b/g,
@@ -102,7 +92,6 @@ var PII_PATTERNS = [
102
92
  return luhnCheck(digits);
103
93
  }
104
94
  },
105
- // IPv4 addresses (must run before phone to avoid partial matches)
106
95
  {
107
96
  category: "IP_ADDRESS",
108
97
  regex: /\b(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\b/g,
@@ -110,31 +99,15 @@ var PII_PATTERNS = [
110
99
  return match !== "0.0.0.0" && match !== "127.0.0.1" && match !== "255.255.255.255";
111
100
  }
112
101
  },
113
- // IPv6 addresses — full and compressed (::) forms. Each alternative requires
114
- // either a full 8-group address or a "::" compression, so ordinary
115
- // colon-separated text (timestamps like 12:34:56) does not match. Loopback
116
- // (::1) and unspecified (::) are excluded.
117
102
  {
118
103
  category: "IP_ADDRESS",
119
104
  regex: /(?:(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|(?:[0-9a-fA-F]{1,4}:){1,7}:|(?:[0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|(?:[0-9a-fA-F]{1,4}:){1,5}(?::[0-9a-fA-F]{1,4}){1,2}|(?:[0-9a-fA-F]{1,4}:){1,4}(?::[0-9a-fA-F]{1,4}){1,3}|(?:[0-9a-fA-F]{1,4}:){1,3}(?::[0-9a-fA-F]{1,4}){1,4}|(?:[0-9a-fA-F]{1,4}:){1,2}(?::[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:(?::[0-9a-fA-F]{1,4}){1,6}|:(?:(?::[0-9a-fA-F]{1,4}){1,7}|:))/g,
120
105
  validate: (match) => match !== "::1" && match !== "::"
121
106
  },
122
- // Phone numbers. The separated form requires separator characters (dashes,
123
- // spaces, dots, parens) to avoid matching bare digit sequences that are
124
- // actually credit cards, IPs, or years. A second alternative matches E.164
125
- // (a leading "+" then 10–15 digits, e.g. +14155552671), which is
126
- // unambiguous; a bare 10-digit run with no "+" and no separators is
127
- // intentionally not matched to avoid false positives.
128
107
  {
129
108
  category: "PHONE",
130
109
  regex: /(?:\+\d{1,3}[\s.-])?\(?\d{3}\)?[\s.-]\d{3}[\s.-]\d{4}\b|\+\d{10,15}\b/g
131
110
  },
132
- // API keys / secrets — long token with a key-like prefix. The validator
133
- // requires entropy (at least one digit, or a mix of upper- and lower-case)
134
- // so long all-lowercase prose identifiers like
135
- // "accessibility_is_important_for_everyone" or
136
- // "access-control-list-management-feature" are not redacted. Real keys and
137
- // tokens essentially always contain digits or mixed case.
138
111
  {
139
112
  category: "API_KEY",
140
113
  regex: /\b(?:sk|pk|api|key|token|secret|bearer|access)[_-]?[a-zA-Z0-9_-]{20,}\b/gi,
@@ -144,13 +117,6 @@ var PII_PATTERNS = [
144
117
  return hasDigit || hasMixedCase;
145
118
  }
146
119
  },
147
- // US street addresses — house number + Title-Case street name + suffix.
148
- // Intentionally NOT case-insensitive: the `[A-Z][a-z]+` guard requires
149
- // properly-capitalized street words, so "123 main street", "100 MAIN
150
- // STREET" and prose like "3 blocks down the road" / "5 minutes to drive"
151
- // are not treated as addresses. Whitespace is `[ \t]` only (no newline
152
- // spanning), and the suffix must end the segment (punctuation / newline /
153
- // end of string) so "Driveway" or "Wayfair" don't match on the suffix.
154
120
  {
155
121
  category: "US_ADDRESS",
156
122
  regex: /\b\d{1,5}[ \t]+(?:[A-Z][a-z]+[ \t]+){1,3}(?:St(?:reet)?|Ave(?:nue)?|Blvd|Boulevard|Dr(?:ive)?|Ln|Lane|Rd|Road|Ct|Court|Pl(?:ace)?|Way|Cir(?:cle)?|Pkwy|Parkway|Hwy|Highway)\.?(?=[\s,.;:!?)]|$)/g,
@@ -158,11 +124,6 @@ var PII_PATTERNS = [
158
124
  return !/^0/.test(match.trim());
159
125
  }
160
126
  },
161
- // Dates of birth — common US date formats. Only redacted when a birth-date
162
- // cue ("DOB", "born", "birthday", "date of birth") appears just before the
163
- // date, so ordinary calendar dates ("meeting 12/25/2024", deadlines,
164
- // invoices) are left intact for the model. A calendar validator also rejects
165
- // impossible dates like 02/31/1990.
166
127
  {
167
128
  category: "DATE_OF_BIRTH",
168
129
  regex: /\b(?:(?:0?[1-9]|1[0-2])[/-](?:0?[1-9]|[12]\d|3[01])[/-](?:19|20)\d{2})\b/g,
@@ -343,12 +304,6 @@ var PiiRedactor = class {
343
304
  maskText(text) {
344
305
  return this.scan(text, (category) => `[${category}]`).text;
345
306
  }
346
- // ───────────────────────────────────────────────────────────────────────
347
- // Async (regex + NER) path. Mirrors the sync API but additionally folds in
348
- // an optional {@link NerDetector}'s spans. When no detector is configured,
349
- // each async method delegates to its sync counterpart and is byte-for-byte
350
- // identical — so it is a safe drop-in.
351
- // ───────────────────────────────────────────────────────────────────────
352
307
  /** All regex matches as spans on the ORIGINAL text (priority 0). Uses the
353
308
  * same {@link findMatches} guards as the sync scan. */
354
309
  collectRegexSpans(text) {
@@ -892,16 +847,7 @@ async function attemptPortalJson(req, endpoint) {
892
847
  const usesPrefill = req.transport !== "responses" && req.model.startsWith("anthropic/");
893
848
  const prefill = usesPrefill ? "{" : "";
894
849
  const messages = [
895
- // Every caller of this helper is a first-party BACKGROUND op (fact extraction,
896
- // topic sweep, consolidation, classifiers, graph traversal, query
897
- // decomposition). Marking here — the one place they all funnel through — is what
898
- // keeps the portal's detector reading them as genuine rather than markerless.
899
- // See ../internalFlowMarker.
900
850
  { role: "system", content: withInternalFlowMarker(req.systemPrompt) },
901
- // Retry-only. Kept as a SEPARATE message rather than appended to the system
902
- // prompt so the marked prompt above stays byte-identical across attempts —
903
- // the portal's internal-flow detector reads that one, and rewriting it on a
904
- // retry would change what the detector sees for reasons unrelated to auth.
905
851
  ...req.reinforceJsonContract ? [{ role: "system", content: JSON_CONTRACT_REMINDER }] : [],
906
852
  { role: "user", content: req.userMessage }
907
853
  ];
@@ -911,22 +857,8 @@ async function attemptPortalJson(req, endpoint) {
911
857
  const timer = setTimeout(() => controller.abort(), timeoutMs);
912
858
  const requestBody = req.transport === "responses" ? {
913
859
  model: req.model,
914
- // Same system+user pair under the Responses-API field name. No prefill
915
- // entry to strip: `usesPrefill` is false on this transport, so it was
916
- // never pushed and the response-side restore is disarmed with it. An
917
- // earlier version pushed it and sliced it back off here, which left
918
- // `prefill` truthy and the restore still armed — the fix belonged at
919
- // the decision, not at the two symptoms.
920
860
  input: messages,
921
861
  ...req.reasoning && { reasoning: req.reasoning },
922
- // NO response_format. The Responses API spells structured output
923
- // differently (`text.format`), and it is unverified against this
924
- // portal — so this transport relies on the same strict-JSON system
925
- // prompt plus `extractJsonCandidate` that every response_format-
926
- // rejecting model already relies on. Verified end to end on dev:
927
- // luna returns clean parseable JSON here without it. Add the field
928
- // only with a per-provider check, exactly as RESPONSE_FORMAT_OK was
929
- // earned.
930
862
  ...responsesExtra(req.extra)
931
863
  } : {
932
864
  model: req.model,
@@ -941,8 +873,6 @@ async function attemptPortalJson(req, endpoint) {
941
873
  try {
942
874
  response = await fetchImpl(`${baseUrl}${endpoint}`, {
943
875
  method: "POST",
944
- // Attached HERE, at the one transport every background memory op shares, so
945
- // a new flow gets the provenance by construction rather than by remembering.
946
876
  headers: {
947
877
  ...authHeaders,
948
878
  ...taskTypeHeader(req.taskType),
@@ -2,7 +2,7 @@ import {
2
2
  callPortalJsonCompletion,
3
3
  notifyConsolidationFallback,
4
4
  resolvePiiRedactor
5
- } from "./chunk-XNQRJBIH.mjs";
5
+ } from "./chunk-UFO4W3JX.mjs";
6
6
  import "./chunk-GYKJOWEO.mjs";
7
7
 
8
8
  // src/lib/memory/consolidate.ts
@@ -80,12 +80,6 @@ ${candidateText}`;
80
80
  systemPrompt: SYSTEM_PROMPT,
81
81
  userMessage,
82
82
  tag: "memory/consolidate",
83
- // Retry TRANSIENT failures only (network/timeout/5xx/429/empty) before
84
- // degrading to create — a transient blip would otherwise leave a
85
- // permanent below-floor paraphrase that never self-heals (see
86
- // DEFAULT_CONSOLIDATE_ATTEMPTS). The happy path still resolves in one
87
- // attempt; terminal failures (400/auth) and schema violations never
88
- // retry. A total budget keeps a hanging portal from stalling retain.
89
83
  maxAttempts: options.maxAttempts ?? DEFAULT_CONSOLIDATE_ATTEMPTS,
90
84
  totalTimeoutMs: options.totalTimeoutMs ?? DEFAULT_CONSOLIDATE_TOTAL_TIMEOUT_MS,
91
85
  ...options.backoffMs && { backoffMs: options.backoffMs },
@@ -162,7 +156,6 @@ function validate(parsed, newContent, validIds) {
162
156
  const positional = Array.isArray(obj.targetSubjects) ? obj.targetSubjects : [];
163
157
  const statedSubjects = [
164
158
  ...positional.map((s) => subjectKey(s)),
165
- // The singular pair, which is the whole story for a one-target supersede.
166
159
  subjectKey(obj.targetSubject)
167
160
  ];
168
161
  if (statedSubjects.some((s) => s.length > 0 && s !== newSubject)) {