@anuma/sdk 6.1.1 → 6.2.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.
@@ -1284,7 +1284,8 @@ function messageToStoredRaw(message, projection) {
1284
1284
  thinking: message.thinking,
1285
1285
  parentMessageId: message.parentMessageId,
1286
1286
  feedback: message.feedback || null,
1287
- toolCallEvents: parseJsonField(toolCallEventsRaw)
1287
+ toolCallEvents: parseJsonField(toolCallEventsRaw),
1288
+ origin: message.origin
1288
1289
  };
1289
1290
  }
1290
1291
  async function messageToStored(message, walletAddress, signMessage, embeddedWalletSigner, projection) {
@@ -1345,7 +1346,11 @@ function messageRawToStoredRaw(raw, projection) {
1345
1346
  thinking: raw.thinking,
1346
1347
  parentMessageId: raw.parent_message_id,
1347
1348
  feedback: raw.feedback || null,
1348
- toolCallEvents: parseJsonField(raw.tool_call_events)
1349
+ toolCallEvents: parseJsonField(raw.tool_call_events),
1350
+ // Load-bearing on this path specifically: getMessagesOp reads raws, and it is
1351
+ // what the deferred embedding sweep iterates, so the provenance gate depends
1352
+ // on `origin` surviving the raw mapper as well as the Model one.
1353
+ origin: raw.origin
1349
1354
  };
1350
1355
  }
1351
1356
  async function messageRawToStored(raw, walletAddress, signMessage, embeddedWalletSigner, projection) {
@@ -1667,6 +1672,7 @@ function applyMessageFields(msg, encryptedOpts) {
1667
1672
  const tceValue = typeof encryptedOpts.toolCallEvents === "string" ? encryptedOpts.toolCallEvents : JSON.stringify(encryptedOpts.toolCallEvents);
1668
1673
  msg._setRaw("tool_call_events", tceValue);
1669
1674
  }
1675
+ if (encryptedOpts.origin) msg._setRaw("origin", encryptedOpts.origin);
1670
1676
  }
1671
1677
  async function createMessageOp(ctx, opts) {
1672
1678
  if (opts.uniqueId) {
@@ -2009,7 +2015,8 @@ function makeSyntheticStoredMessage(opts) {
2009
2015
  thoughtProcess: opts.thoughtProcess,
2010
2016
  thinking: opts.thinking,
2011
2017
  parentMessageId: opts.parentMessageId,
2012
- toolCallEvents: opts.toolCallEvents
2018
+ toolCallEvents: opts.toolCallEvents,
2019
+ origin: opts.origin
2013
2020
  };
2014
2021
  }
2015
2022
  function makeSyntheticStoredConversation(opts, defaultTitle) {
@@ -4604,6 +4611,7 @@ async function generateEmbeddings(texts, options) {
4604
4611
 
4605
4612
  // src/lib/memoryEngine/embeddings.ts
4606
4613
  var DEFAULT_MIN_CONTENT_LENGTH = 10;
4614
+ var NON_EMBEDDABLE_ORIGIN = "tool_result";
4607
4615
  async function embedMessage(ctx, messageId, options) {
4608
4616
  const message = await getMessageOp(ctx, messageId);
4609
4617
  if (!message) {
@@ -4612,6 +4620,9 @@ async function embedMessage(ctx, messageId, options) {
4612
4620
  if (message.vector && message.vector.length > 0) {
4613
4621
  return message;
4614
4622
  }
4623
+ if (message.origin === NON_EMBEDDABLE_ORIGIN) {
4624
+ return message;
4625
+ }
4615
4626
  const embedding = await generateEmbedding(message.content, options);
4616
4627
  const embeddingModel = options.model ?? DEFAULT_API_EMBEDDING_MODEL;
4617
4628
  return updateMessageEmbeddingOp(ctx, messageId, embedding, embeddingModel);
@@ -4633,6 +4644,9 @@ async function embedAllMessages(ctx, options, filter) {
4633
4644
  if (message.role === "system") {
4634
4645
  continue;
4635
4646
  }
4647
+ if (message.origin === NON_EMBEDDABLE_ORIGIN) {
4648
+ continue;
4649
+ }
4636
4650
  const minLength = filter?.minContentLength ?? DEFAULT_MIN_CONTENT_LENGTH;
4637
4651
  if (message.content.length < minLength) {
4638
4652
  continue;
@@ -4658,6 +4672,9 @@ async function chunkAndEmbedMessage(ctx, messageId, options) {
4658
4672
  if (message.chunks && message.chunks.length > 0) {
4659
4673
  return message;
4660
4674
  }
4675
+ if (message.origin === NON_EMBEDDABLE_ORIGIN) {
4676
+ return message;
4677
+ }
4661
4678
  const embeddingModel = options.model ?? DEFAULT_API_EMBEDDING_MODEL;
4662
4679
  if (!shouldChunkMessage(message.content, chunkSize)) {
4663
4680
  const embedding = await generateEmbedding(message.content, options);
@@ -4691,6 +4708,7 @@ async function chunkAndEmbedAllMessages(ctx, options, filter) {
4691
4708
  if (hasVector && !filter?.rechunkExisting && !isStale) continue;
4692
4709
  if (filter?.roles && !filter.roles.includes(message.role)) continue;
4693
4710
  if (message.role === "system") continue;
4711
+ if (message.origin === NON_EMBEDDABLE_ORIGIN) continue;
4694
4712
  if (message.content.length < minLength) continue;
4695
4713
  if (shouldChunkMessage(message.content, chunkSize)) {
4696
4714
  longMessages.push({
@@ -6482,7 +6500,7 @@ function createMemoryVaultSearchTool(vaultCtx, embeddingOptions, cache, searchOp
6482
6500
  subQueries = decomp.subQueries;
6483
6501
  }
6484
6502
  }
6485
- const { recall: recall2 } = await import("./recall-2IOGTAFJ.mjs");
6503
+ const { recall: recall2 } = await import("./recall-ZIKIYARO.mjs");
6486
6504
  let recallDegraded = [];
6487
6505
  const result = await recall2(
6488
6506
  query,
@@ -1394,7 +1394,8 @@ function messageToStoredRaw(message, projection) {
1394
1394
  thinking: message.thinking,
1395
1395
  parentMessageId: message.parentMessageId,
1396
1396
  feedback: message.feedback || null,
1397
- toolCallEvents: parseJsonField(toolCallEventsRaw)
1397
+ toolCallEvents: parseJsonField(toolCallEventsRaw),
1398
+ origin: message.origin
1398
1399
  };
1399
1400
  }
1400
1401
  async function messageToStored(message, walletAddress, signMessage, embeddedWalletSigner, projection) {
@@ -1455,7 +1456,11 @@ function messageRawToStoredRaw(raw, projection) {
1455
1456
  thinking: raw.thinking,
1456
1457
  parentMessageId: raw.parent_message_id,
1457
1458
  feedback: raw.feedback || null,
1458
- toolCallEvents: parseJsonField(raw.tool_call_events)
1459
+ toolCallEvents: parseJsonField(raw.tool_call_events),
1460
+ // Load-bearing on this path specifically: getMessagesOp reads raws, and it is
1461
+ // what the deferred embedding sweep iterates, so the provenance gate depends
1462
+ // on `origin` surviving the raw mapper as well as the Model one.
1463
+ origin: raw.origin
1459
1464
  };
1460
1465
  }
1461
1466
  async function messageRawToStored(raw, walletAddress, signMessage, embeddedWalletSigner, projection) {
@@ -1777,6 +1782,7 @@ function applyMessageFields(msg, encryptedOpts) {
1777
1782
  const tceValue = typeof encryptedOpts.toolCallEvents === "string" ? encryptedOpts.toolCallEvents : JSON.stringify(encryptedOpts.toolCallEvents);
1778
1783
  msg._setRaw("tool_call_events", tceValue);
1779
1784
  }
1785
+ if (encryptedOpts.origin) msg._setRaw("origin", encryptedOpts.origin);
1780
1786
  }
1781
1787
  async function createMessageOp(ctx, opts) {
1782
1788
  if (opts.uniqueId) {
@@ -2119,7 +2125,8 @@ function makeSyntheticStoredMessage(opts) {
2119
2125
  thoughtProcess: opts.thoughtProcess,
2120
2126
  thinking: opts.thinking,
2121
2127
  parentMessageId: opts.parentMessageId,
2122
- toolCallEvents: opts.toolCallEvents
2128
+ toolCallEvents: opts.toolCallEvents,
2129
+ origin: opts.origin
2123
2130
  };
2124
2131
  }
2125
2132
  function makeSyntheticStoredConversation(opts, defaultTitle) {
@@ -3427,6 +3434,9 @@ async function embedMessage(ctx, messageId, options) {
3427
3434
  if (message.vector && message.vector.length > 0) {
3428
3435
  return message;
3429
3436
  }
3437
+ if (message.origin === NON_EMBEDDABLE_ORIGIN) {
3438
+ return message;
3439
+ }
3430
3440
  const embedding = await generateEmbedding(message.content, options);
3431
3441
  const embeddingModel = options.model ?? DEFAULT_API_EMBEDDING_MODEL;
3432
3442
  return updateMessageEmbeddingOp(ctx, messageId, embedding, embeddingModel);
@@ -3448,6 +3458,9 @@ async function embedAllMessages(ctx, options, filter) {
3448
3458
  if (message.role === "system") {
3449
3459
  continue;
3450
3460
  }
3461
+ if (message.origin === NON_EMBEDDABLE_ORIGIN) {
3462
+ continue;
3463
+ }
3451
3464
  const minLength = filter?.minContentLength ?? DEFAULT_MIN_CONTENT_LENGTH;
3452
3465
  if (message.content.length < minLength) {
3453
3466
  continue;
@@ -3473,6 +3486,9 @@ async function chunkAndEmbedMessage(ctx, messageId, options) {
3473
3486
  if (message.chunks && message.chunks.length > 0) {
3474
3487
  return message;
3475
3488
  }
3489
+ if (message.origin === NON_EMBEDDABLE_ORIGIN) {
3490
+ return message;
3491
+ }
3476
3492
  const embeddingModel = options.model ?? DEFAULT_API_EMBEDDING_MODEL;
3477
3493
  if (!shouldChunkMessage(message.content, chunkSize)) {
3478
3494
  const embedding = await generateEmbedding(message.content, options);
@@ -3506,6 +3522,7 @@ async function chunkAndEmbedAllMessages(ctx, options, filter) {
3506
3522
  if (hasVector && !filter?.rechunkExisting && !isStale) continue;
3507
3523
  if (filter?.roles && !filter.roles.includes(message.role)) continue;
3508
3524
  if (message.role === "system") continue;
3525
+ if (message.origin === NON_EMBEDDABLE_ORIGIN) continue;
3509
3526
  if (message.content.length < minLength) continue;
3510
3527
  if (shouldChunkMessage(message.content, chunkSize)) {
3511
3528
  longMessages.push({
@@ -3562,7 +3579,7 @@ async function chunkAndEmbedAllMessages(ctx, options, filter) {
3562
3579
  }
3563
3580
  return embeddedCount;
3564
3581
  }
3565
- var DEFAULT_MIN_CONTENT_LENGTH;
3582
+ var DEFAULT_MIN_CONTENT_LENGTH, NON_EMBEDDABLE_ORIGIN;
3566
3583
  var init_embeddings = __esm({
3567
3584
  "src/lib/memoryEngine/embeddings.ts"() {
3568
3585
  "use strict";
@@ -3573,6 +3590,7 @@ var init_embeddings = __esm({
3573
3590
  init_generate();
3574
3591
  init_generate();
3575
3592
  DEFAULT_MIN_CONTENT_LENGTH = 10;
3593
+ NON_EMBEDDABLE_ORIGIN = "tool_result";
3576
3594
  }
3577
3595
  });
3578
3596
 
@@ -14193,6 +14211,9 @@ __decorateClass([
14193
14211
  __decorateClass([
14194
14212
  (0, import_decorators.json)("tool_call_events", (raw) => raw)
14195
14213
  ], Message.prototype, "toolCallEvents", 2);
14214
+ __decorateClass([
14215
+ (0, import_decorators.text)("origin")
14216
+ ], Message.prototype, "origin", 2);
14196
14217
  var Conversation = class extends import_watermelondb3.Model {
14197
14218
  };
14198
14219
  Conversation.table = "conversations";
@@ -21427,7 +21448,7 @@ __decorateClass([
21427
21448
  ], VaultFolder.prototype, "context", 2);
21428
21449
 
21429
21450
  // src/lib/db/schema.ts
21430
- var SDK_SCHEMA_VERSION = 43;
21451
+ var SDK_SCHEMA_VERSION = 44;
21431
21452
  var sdkSchema = (0, import_watermelondb19.appSchema)({
21432
21453
  version: SDK_SCHEMA_VERSION,
21433
21454
  tables: [
@@ -21465,8 +21486,10 @@ var sdkSchema = (0, import_watermelondb19.appSchema)({
21465
21486
  // Parent message for branching
21466
21487
  { name: "feedback", type: "string", isOptional: true },
21467
21488
  // 'like' | 'dislike' | null
21468
- { name: "tool_call_events", type: "string", isOptional: true }
21489
+ { name: "tool_call_events", type: "string", isOptional: true },
21469
21490
  // JSON stringified LlmapiToolCallEvent[]
21491
+ { name: "origin", type: "string", isOptional: true }
21492
+ // MessageOrigin — provenance, NOT encrypted (see v44)
21470
21493
  ]
21471
21494
  }),
21472
21495
  (0, import_watermelondb19.tableSchema)({
@@ -22394,6 +22417,19 @@ var sdkMigrations = (0, import_migrations2.schemaMigrations)({
22394
22417
  "CREATE INDEX IF NOT EXISTS conversations_is_deleted_created_at ON conversations (is_deleted, created_at);"
22395
22418
  )
22396
22419
  ]
22420
+ },
22421
+ // v43 -> v44: Added origin column to history — the provenance tag the embedding
22422
+ // sweep reads to skip never-rendered tool-result rows. No backfill: NULL means
22423
+ // "legacy, provenance unknown" and keeps the pre-v44 behaviour of embedding the
22424
+ // row, so the only rows that stop being embedded are ones a v44+ producer tagged.
22425
+ {
22426
+ toVersion: 44,
22427
+ steps: [
22428
+ (0, import_migrations2.addColumns)({
22429
+ table: "history",
22430
+ columns: [{ name: "origin", type: "string", isOptional: true }]
22431
+ })
22432
+ ]
22397
22433
  }
22398
22434
  ]
22399
22435
  });
@@ -3389,6 +3389,22 @@ type ChatRole = "user" | "assistant" | "system";
3389
3389
  * - null/undefined: No feedback given
3390
3390
  */
3391
3391
  type MessageFeedback = "like" | "dislike" | null;
3392
+ /**
3393
+ * Which producer synthesised a message, for rows the user did not type and the
3394
+ * UI does not render. Set at write time by that producer; a union so further
3395
+ * synthetic kinds can be added without another column.
3396
+ *
3397
+ * - `tool_result`: the hidden `[Tool Execution Results]` row built from a
3398
+ * turn's auto-executed tool results. Skipped by the embedding sweep (see
3399
+ * `memoryEngine/embeddings`).
3400
+ * - undefined/null: a normal message, or any row written before v44.
3401
+ *
3402
+ * Stored in the plaintext `origin` column — never encrypted. The deferred
3403
+ * embedding sweep that has to honour it runs without wallet context, so an
3404
+ * encrypted flag would be unreadable exactly where it matters and the skip
3405
+ * would fail open.
3406
+ */
3407
+ type MessageOrigin = "tool_result";
3392
3408
  /**
3393
3409
  * Metadata for files attached to messages.
3394
3410
  *
@@ -3546,6 +3562,8 @@ interface StoredMessage {
3546
3562
  feedback?: MessageFeedback;
3547
3563
  /** Tool call events from the backend response (for reconstructing tool call history) */
3548
3564
  toolCallEvents?: LlmapiToolCallEvent[];
3565
+ /** Provenance for synthetic rows; undefined for typed messages and pre-v44 rows */
3566
+ origin?: MessageOrigin;
3549
3567
  /**
3550
3568
  * Set when `content` could not be decrypted on read (#561).
3551
3569
  * The `content` field still holds the original ciphertext — never a
@@ -3641,6 +3659,8 @@ interface CreateMessageOptions {
3641
3659
  parentMessageId?: string;
3642
3660
  /** Tool call events from the backend response (for reconstructing tool call history) */
3643
3661
  toolCallEvents?: LlmapiToolCallEvent[];
3662
+ /** Provenance for synthetic rows; set by the producer, never by user input */
3663
+ origin?: MessageOrigin;
3644
3664
  /**
3645
3665
  * Optional pre-generated unique ID for this message.
3646
3666
  * When provided, used as the WatermelonDB record ID instead of auto-generating one.
@@ -4174,6 +4194,8 @@ declare class Message extends Model {
4174
4194
  parentMessageId?: string;
4175
4195
  feedback?: MessageFeedback;
4176
4196
  toolCallEvents?: LlmapiToolCallEvent[];
4197
+ /** Plaintext by design — see MessageOrigin */
4198
+ origin?: MessageOrigin;
4177
4199
  }
4178
4200
  declare class Conversation extends Model {
4179
4201
  static table: string;
@@ -9161,8 +9183,20 @@ declare function useChatStorage(options: UseChatStorageOptions): UseChatStorageR
9161
9183
  * conversation list read filters is_deleted and orders by created_at DESC,
9162
9184
  * which previously meant a temp B-tree sort of the whole live set on every
9163
9185
  * read. Structural only — no column added, no data rewritten
9164
- */
9165
- declare const SDK_SCHEMA_VERSION = 43;
9186
+ * - v44: Added origin column to history — provenance of a row, set by the
9187
+ * producer that synthesised it (`tool_result` = the hidden
9188
+ * `[Tool Execution Results]` message written from autoExecutedToolResults).
9189
+ * The embedding sweep skips those rows: they are machine-readable API dumps
9190
+ * that are never rendered, and chunking one cost 52 MB of vectors (620
9191
+ * chunks) against 0.2 MB of content. A content-prefix test cannot do this
9192
+ * job — `content` is `enc:v3:` ciphertext by the time the sweep reads it, so
9193
+ * provenance has to be recorded at write time. Deliberately NOT encrypted:
9194
+ * the sweep that must honour it runs with no wallet context, and an
9195
+ * unreadable flag would fail open. Existing rows stay NULL (= legacy,
9196
+ * unknown provenance, embedded as before) with no backfill, matching the v37
9197
+ * read-time-fallback precedent
9198
+ */
9199
+ declare const SDK_SCHEMA_VERSION = 44;
9166
9200
  /**
9167
9201
  * Combined WatermelonDB schema for all SDK storage modules.
9168
9202
  *
@@ -9250,6 +9284,7 @@ declare const sdkSchema: Readonly<{
9250
9284
  * - v40 → v41: Added `visibility`, `twin_opt_in`, `published_at`, `geohash` columns to memory_vault for the People Nearby cross-user visibility axis (two-tier `private | public`; null/unknown grandfathered as 'private')
9251
9285
  * - v41 → v42: Added `topics` + `topics_updated_at` columns to memory_vault, making a memory's topics the durable synced record and `entity`/`memory_entity` a device-local index over it (null `topics` = pre-v42, backfilled from the row's current links by the sweep)
9252
9286
  * - v42 → v43: Added a composite `(is_deleted, created_at)` index to conversations so the list reads stop temp-sorting (structural only, no data rewritten)
9287
+ * - v43 → v44: Added `origin` column to history recording which producer synthesised a row, so the embedding sweep can skip never-rendered tool-result dumps (plaintext by design — the sweep has no wallet context; null = legacy, embedded as before)
9253
9288
  */
9254
9289
  declare const sdkMigrations: Readonly<{
9255
9290
  validated: true;
@@ -3389,6 +3389,22 @@ type ChatRole = "user" | "assistant" | "system";
3389
3389
  * - null/undefined: No feedback given
3390
3390
  */
3391
3391
  type MessageFeedback = "like" | "dislike" | null;
3392
+ /**
3393
+ * Which producer synthesised a message, for rows the user did not type and the
3394
+ * UI does not render. Set at write time by that producer; a union so further
3395
+ * synthetic kinds can be added without another column.
3396
+ *
3397
+ * - `tool_result`: the hidden `[Tool Execution Results]` row built from a
3398
+ * turn's auto-executed tool results. Skipped by the embedding sweep (see
3399
+ * `memoryEngine/embeddings`).
3400
+ * - undefined/null: a normal message, or any row written before v44.
3401
+ *
3402
+ * Stored in the plaintext `origin` column — never encrypted. The deferred
3403
+ * embedding sweep that has to honour it runs without wallet context, so an
3404
+ * encrypted flag would be unreadable exactly where it matters and the skip
3405
+ * would fail open.
3406
+ */
3407
+ type MessageOrigin = "tool_result";
3392
3408
  /**
3393
3409
  * Metadata for files attached to messages.
3394
3410
  *
@@ -3546,6 +3562,8 @@ interface StoredMessage {
3546
3562
  feedback?: MessageFeedback;
3547
3563
  /** Tool call events from the backend response (for reconstructing tool call history) */
3548
3564
  toolCallEvents?: LlmapiToolCallEvent[];
3565
+ /** Provenance for synthetic rows; undefined for typed messages and pre-v44 rows */
3566
+ origin?: MessageOrigin;
3549
3567
  /**
3550
3568
  * Set when `content` could not be decrypted on read (#561).
3551
3569
  * The `content` field still holds the original ciphertext — never a
@@ -3641,6 +3659,8 @@ interface CreateMessageOptions {
3641
3659
  parentMessageId?: string;
3642
3660
  /** Tool call events from the backend response (for reconstructing tool call history) */
3643
3661
  toolCallEvents?: LlmapiToolCallEvent[];
3662
+ /** Provenance for synthetic rows; set by the producer, never by user input */
3663
+ origin?: MessageOrigin;
3644
3664
  /**
3645
3665
  * Optional pre-generated unique ID for this message.
3646
3666
  * When provided, used as the WatermelonDB record ID instead of auto-generating one.
@@ -4174,6 +4194,8 @@ declare class Message extends Model {
4174
4194
  parentMessageId?: string;
4175
4195
  feedback?: MessageFeedback;
4176
4196
  toolCallEvents?: LlmapiToolCallEvent[];
4197
+ /** Plaintext by design — see MessageOrigin */
4198
+ origin?: MessageOrigin;
4177
4199
  }
4178
4200
  declare class Conversation extends Model {
4179
4201
  static table: string;
@@ -9161,8 +9183,20 @@ declare function useChatStorage(options: UseChatStorageOptions): UseChatStorageR
9161
9183
  * conversation list read filters is_deleted and orders by created_at DESC,
9162
9184
  * which previously meant a temp B-tree sort of the whole live set on every
9163
9185
  * read. Structural only — no column added, no data rewritten
9164
- */
9165
- declare const SDK_SCHEMA_VERSION = 43;
9186
+ * - v44: Added origin column to history — provenance of a row, set by the
9187
+ * producer that synthesised it (`tool_result` = the hidden
9188
+ * `[Tool Execution Results]` message written from autoExecutedToolResults).
9189
+ * The embedding sweep skips those rows: they are machine-readable API dumps
9190
+ * that are never rendered, and chunking one cost 52 MB of vectors (620
9191
+ * chunks) against 0.2 MB of content. A content-prefix test cannot do this
9192
+ * job — `content` is `enc:v3:` ciphertext by the time the sweep reads it, so
9193
+ * provenance has to be recorded at write time. Deliberately NOT encrypted:
9194
+ * the sweep that must honour it runs with no wallet context, and an
9195
+ * unreadable flag would fail open. Existing rows stay NULL (= legacy,
9196
+ * unknown provenance, embedded as before) with no backfill, matching the v37
9197
+ * read-time-fallback precedent
9198
+ */
9199
+ declare const SDK_SCHEMA_VERSION = 44;
9166
9200
  /**
9167
9201
  * Combined WatermelonDB schema for all SDK storage modules.
9168
9202
  *
@@ -9250,6 +9284,7 @@ declare const sdkSchema: Readonly<{
9250
9284
  * - v40 → v41: Added `visibility`, `twin_opt_in`, `published_at`, `geohash` columns to memory_vault for the People Nearby cross-user visibility axis (two-tier `private | public`; null/unknown grandfathered as 'private')
9251
9285
  * - v41 → v42: Added `topics` + `topics_updated_at` columns to memory_vault, making a memory's topics the durable synced record and `entity`/`memory_entity` a device-local index over it (null `topics` = pre-v42, backfilled from the row's current links by the sweep)
9252
9286
  * - v42 → v43: Added a composite `(is_deleted, created_at)` index to conversations so the list reads stop temp-sorting (structural only, no data rewritten)
9287
+ * - v43 → v44: Added `origin` column to history recording which producer synthesised a row, so the embedding sweep can skip never-rendered tool-result dumps (plaintext by design — the sweep has no wallet context; null = legacy, embedded as before)
9253
9288
  */
9254
9289
  declare const sdkMigrations: Readonly<{
9255
9290
  validated: true;
@@ -121,7 +121,7 @@ import {
121
121
  upsertMessageOp,
122
122
  useEncryption,
123
123
  vaultMemoryToStored
124
- } from "./chunk-VBPZDIFV.mjs";
124
+ } from "./chunk-NH5VY3G7.mjs";
125
125
  import {
126
126
  PII_PATTERNS,
127
127
  PiiRedactor,
@@ -5127,6 +5127,9 @@ __decorateClass([
5127
5127
  __decorateClass([
5128
5128
  json("tool_call_events", (raw) => raw)
5129
5129
  ], Message.prototype, "toolCallEvents", 2);
5130
+ __decorateClass([
5131
+ text("origin")
5132
+ ], Message.prototype, "origin", 2);
5130
5133
  var Conversation = class extends Model {
5131
5134
  };
5132
5135
  Conversation.table = "conversations";
@@ -12255,7 +12258,7 @@ __decorateClass([
12255
12258
  ], VaultFolder.prototype, "context", 2);
12256
12259
 
12257
12260
  // src/lib/db/schema.ts
12258
- var SDK_SCHEMA_VERSION = 43;
12261
+ var SDK_SCHEMA_VERSION = 44;
12259
12262
  var sdkSchema = appSchema2({
12260
12263
  version: SDK_SCHEMA_VERSION,
12261
12264
  tables: [
@@ -12293,8 +12296,10 @@ var sdkSchema = appSchema2({
12293
12296
  // Parent message for branching
12294
12297
  { name: "feedback", type: "string", isOptional: true },
12295
12298
  // 'like' | 'dislike' | null
12296
- { name: "tool_call_events", type: "string", isOptional: true }
12299
+ { name: "tool_call_events", type: "string", isOptional: true },
12297
12300
  // JSON stringified LlmapiToolCallEvent[]
12301
+ { name: "origin", type: "string", isOptional: true }
12302
+ // MessageOrigin — provenance, NOT encrypted (see v44)
12298
12303
  ]
12299
12304
  }),
12300
12305
  tableSchema2({
@@ -13222,6 +13227,19 @@ var sdkMigrations = schemaMigrations2({
13222
13227
  "CREATE INDEX IF NOT EXISTS conversations_is_deleted_created_at ON conversations (is_deleted, created_at);"
13223
13228
  )
13224
13229
  ]
13230
+ },
13231
+ // v43 -> v44: Added origin column to history — the provenance tag the embedding
13232
+ // sweep reads to skip never-rendered tool-result rows. No backfill: NULL means
13233
+ // "legacy, provenance unknown" and keeps the pre-v44 behaviour of embedding the
13234
+ // row, so the only rows that stop being embedded are ones a v44+ producer tagged.
13235
+ {
13236
+ toVersion: 44,
13237
+ steps: [
13238
+ addColumns2({
13239
+ table: "history",
13240
+ columns: [{ name: "origin", type: "string", isOptional: true }]
13241
+ })
13242
+ ]
13225
13243
  }
13226
13244
  ]
13227
13245
  });
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  recall
3
- } from "./chunk-VBPZDIFV.mjs";
3
+ } from "./chunk-NH5VY3G7.mjs";
4
4
  import "./chunk-ILAWDQDE.mjs";
5
5
  import "./chunk-GYKJOWEO.mjs";
6
6
  export {
@@ -1335,7 +1335,8 @@ function messageToStoredRaw(message, projection) {
1335
1335
  thinking: message.thinking,
1336
1336
  parentMessageId: message.parentMessageId,
1337
1337
  feedback: message.feedback || null,
1338
- toolCallEvents: parseJsonField(toolCallEventsRaw)
1338
+ toolCallEvents: parseJsonField(toolCallEventsRaw),
1339
+ origin: message.origin
1339
1340
  };
1340
1341
  }
1341
1342
  async function messageToStored(message, walletAddress, signMessage, embeddedWalletSigner, projection) {
@@ -1396,7 +1397,11 @@ function messageRawToStoredRaw(raw, projection) {
1396
1397
  thinking: raw.thinking,
1397
1398
  parentMessageId: raw.parent_message_id,
1398
1399
  feedback: raw.feedback || null,
1399
- toolCallEvents: parseJsonField(raw.tool_call_events)
1400
+ toolCallEvents: parseJsonField(raw.tool_call_events),
1401
+ // Load-bearing on this path specifically: getMessagesOp reads raws, and it is
1402
+ // what the deferred embedding sweep iterates, so the provenance gate depends
1403
+ // on `origin` surviving the raw mapper as well as the Model one.
1404
+ origin: raw.origin
1400
1405
  };
1401
1406
  }
1402
1407
  async function messageRawToStored(raw, walletAddress, signMessage, embeddedWalletSigner, projection) {
@@ -1742,6 +1747,7 @@ function applyMessageFields(msg, encryptedOpts) {
1742
1747
  const tceValue = typeof encryptedOpts.toolCallEvents === "string" ? encryptedOpts.toolCallEvents : JSON.stringify(encryptedOpts.toolCallEvents);
1743
1748
  msg._setRaw("tool_call_events", tceValue);
1744
1749
  }
1750
+ if (encryptedOpts.origin) msg._setRaw("origin", encryptedOpts.origin);
1745
1751
  }
1746
1752
  async function createMessageOp(ctx, opts) {
1747
1753
  if (opts.uniqueId) {
@@ -2137,7 +2143,8 @@ function makeSyntheticStoredMessage(opts) {
2137
2143
  thoughtProcess: opts.thoughtProcess,
2138
2144
  thinking: opts.thinking,
2139
2145
  parentMessageId: opts.parentMessageId,
2140
- toolCallEvents: opts.toolCallEvents
2146
+ toolCallEvents: opts.toolCallEvents,
2147
+ origin: opts.origin
2141
2148
  };
2142
2149
  }
2143
2150
  function makeSyntheticStoredConversation(opts, defaultTitle) {
@@ -4887,6 +4894,7 @@ async function generateEmbeddings(texts, options) {
4887
4894
 
4888
4895
  // src/lib/memoryEngine/embeddings.ts
4889
4896
  var DEFAULT_MIN_CONTENT_LENGTH = 10;
4897
+ var NON_EMBEDDABLE_ORIGIN = "tool_result";
4890
4898
  async function embedMessage(ctx, messageId, options) {
4891
4899
  const message = await getMessageOp(ctx, messageId);
4892
4900
  if (!message) {
@@ -4895,6 +4903,9 @@ async function embedMessage(ctx, messageId, options) {
4895
4903
  if (message.vector && message.vector.length > 0) {
4896
4904
  return message;
4897
4905
  }
4906
+ if (message.origin === NON_EMBEDDABLE_ORIGIN) {
4907
+ return message;
4908
+ }
4898
4909
  const embedding = await generateEmbedding(message.content, options);
4899
4910
  const embeddingModel = options.model ?? DEFAULT_API_EMBEDDING_MODEL;
4900
4911
  return updateMessageEmbeddingOp(ctx, messageId, embedding, embeddingModel);
@@ -4916,6 +4927,9 @@ async function embedAllMessages(ctx, options, filter) {
4916
4927
  if (message.role === "system") {
4917
4928
  continue;
4918
4929
  }
4930
+ if (message.origin === NON_EMBEDDABLE_ORIGIN) {
4931
+ continue;
4932
+ }
4919
4933
  const minLength = filter?.minContentLength ?? DEFAULT_MIN_CONTENT_LENGTH;
4920
4934
  if (message.content.length < minLength) {
4921
4935
  continue;
@@ -4941,6 +4955,9 @@ async function chunkAndEmbedMessage(ctx, messageId, options) {
4941
4955
  if (message.chunks && message.chunks.length > 0) {
4942
4956
  return message;
4943
4957
  }
4958
+ if (message.origin === NON_EMBEDDABLE_ORIGIN) {
4959
+ return message;
4960
+ }
4944
4961
  const embeddingModel = options.model ?? DEFAULT_API_EMBEDDING_MODEL;
4945
4962
  if (!shouldChunkMessage(message.content, chunkSize)) {
4946
4963
  const embedding = await generateEmbedding(message.content, options);
@@ -4974,6 +4991,7 @@ async function chunkAndEmbedAllMessages(ctx, options, filter) {
4974
4991
  if (hasVector && !filter?.rechunkExisting && !isStale) continue;
4975
4992
  if (filter?.roles && !filter.roles.includes(message.role)) continue;
4976
4993
  if (message.role === "system") continue;
4994
+ if (message.origin === NON_EMBEDDABLE_ORIGIN) continue;
4977
4995
  if (message.content.length < minLength) continue;
4978
4996
  if (shouldChunkMessage(message.content, chunkSize)) {
4979
4997
  longMessages.push({
@@ -6765,7 +6783,7 @@ function createMemoryVaultSearchTool(vaultCtx, embeddingOptions, cache, searchOp
6765
6783
  subQueries = decomp.subQueries;
6766
6784
  }
6767
6785
  }
6768
- const { recall: recall2 } = await import("./recall-KOKU2PPN.mjs");
6786
+ const { recall: recall2 } = await import("./recall-B7POS7NA.mjs");
6769
6787
  let recallDegraded = [];
6770
6788
  const result = await recall2(
6771
6789
  query,