@anuma/sdk 10.8.0 → 10.10.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.
@@ -19113,7 +19113,7 @@ async function updateMessageErrorOp(ctx, uniqueId, error) {
19113
19113
  }
19114
19114
  await ctx.database.write(async () => {
19115
19115
  await message.update((msg) => {
19116
- msg._setRaw("error", error);
19116
+ msg._setRaw("error", error ?? "");
19117
19117
  });
19118
19118
  });
19119
19119
  return messageToStored(message, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner);
@@ -22327,6 +22327,13 @@ function createStreamAccumulator(initialModel) {
22327
22327
  function isAbortError(err) {
22328
22328
  return err instanceof Error && err.name === "AbortError";
22329
22329
  }
22330
+ var ProviderStreamError = class extends Error {
22331
+ constructor(message, code) {
22332
+ super(message);
22333
+ this.name = "ProviderStreamError";
22334
+ this.code = code;
22335
+ }
22336
+ };
22330
22337
  function getInStreamErrorMessage(chunk) {
22331
22338
  if (!chunk || typeof chunk !== "object") return null;
22332
22339
  const obj = chunk;
@@ -22613,7 +22620,7 @@ var CompletionsStrategy = class {
22613
22620
  processStreamChunk(chunk, accumulator) {
22614
22621
  const result = { content: null, thinking: null };
22615
22622
  const inStreamErr = getInStreamErrorMessage(chunk);
22616
- if (inStreamErr) throw new Error(inStreamErr);
22623
+ if (inStreamErr) throw new ProviderStreamError(inStreamErr);
22617
22624
  const rawChunk = chunk;
22618
22625
  const typedChunk = rawChunk.response && rawChunk.type === "response" ? rawChunk.response : chunk;
22619
22626
  if (typedChunk.id && !accumulator.responseId) {
@@ -23464,7 +23471,7 @@ var ResponsesStrategy = class {
23464
23471
  const result = { content: null, thinking: null };
23465
23472
  const typedChunk = chunk;
23466
23473
  const inStreamErr = getInStreamErrorMessage(chunk);
23467
- if (inStreamErr) throw new Error(inStreamErr);
23474
+ if (inStreamErr) throw new ProviderStreamError(inStreamErr);
23468
23475
  if (typedChunk.type === "response.failed") {
23469
23476
  const resp = typedChunk.response;
23470
23477
  const err = resp?.error;
@@ -23481,9 +23488,12 @@ var ResponsesStrategy = class {
23481
23488
  }
23482
23489
  }
23483
23490
  const label = code ? `[${code}] ` : "";
23484
- throw new Error(`${label}${message || "Upstream request failed"}`);
23491
+ throw new ProviderStreamError(
23492
+ `${label}${message || "Upstream request failed"}`,
23493
+ code || void 0
23494
+ );
23485
23495
  }
23486
- throw new Error("Upstream request failed (response.failed)");
23496
+ throw new ProviderStreamError("Upstream request failed (response.failed)");
23487
23497
  }
23488
23498
  if (typedChunk.type === "response" && typedChunk.response) {
23489
23499
  const resp = typedChunk.response;
@@ -24107,13 +24117,6 @@ function isRetriableStreamError(err) {
24107
24117
  if (msg.includes("connection refused") || msg.includes("connect error")) return true;
24108
24118
  return false;
24109
24119
  }
24110
- var ProviderStreamError = class extends Error {
24111
- constructor(message, code) {
24112
- super(message);
24113
- this.name = "ProviderStreamError";
24114
- this.code = code;
24115
- }
24116
- };
24117
24120
  function extractProviderStreamError(chunk) {
24118
24121
  if (!chunk || typeof chunk !== "object") return null;
24119
24122
  const errField = chunk.error;
@@ -24494,6 +24497,7 @@ async function runToolLoop(options) {
24494
24497
  thinking: redactor.deAnonymize(acc.thinking)
24495
24498
  }) : strategy.buildFinalResponse(acc);
24496
24499
  const finalContentText = (acc) => redactor ? redactor.deAnonymize(acc.content) : acc.content;
24500
+ let streamingAccumulator = null;
24497
24501
  try {
24498
24502
  let sseError = null;
24499
24503
  let apiTools = toolsToApiFormat(tools, resolved);
@@ -24645,6 +24649,7 @@ async function runToolLoop(options) {
24645
24649
  }
24646
24650
  });
24647
24651
  accumulator = createStreamAccumulator(model || void 0);
24652
+ streamingAccumulator = accumulator;
24648
24653
  contentSmoother = new StreamSmoother((text12) => {
24649
24654
  if (emitData) emitData(text12);
24650
24655
  }, smoothing);
@@ -25155,6 +25160,7 @@ Executing tool: ${toolInfo}
25155
25160
  }
25156
25161
  });
25157
25162
  currentAccumulator = createStreamAccumulator(model || void 0);
25163
+ streamingAccumulator = currentAccumulator;
25158
25164
  contContentSmoother = new StreamSmoother((text12) => {
25159
25165
  if (emitData) emitData(text12);
25160
25166
  }, smoothing);
@@ -25352,7 +25358,7 @@ Executing tool: ${toolInfo}
25352
25358
  const statusCode = err instanceof Error && "statusCode" in err ? err.statusCode : void 0;
25353
25359
  const connectionLost = !(err instanceof ProviderStreamError) && !(err instanceof SseError);
25354
25360
  return {
25355
- data: null,
25361
+ data: connectionLost && streamingAccumulator ? buildResponseFinal(streamingAccumulator) : null,
25356
25362
  error: errorMsg,
25357
25363
  statusCode,
25358
25364
  ...connectionLost ? { connectionLost: true } : {}
@@ -2301,6 +2301,8 @@ declare const INFERENCE_ID_HEADER = "X-Inference-ID";
2301
2301
  */
2302
2302
  type StreamResumeHandle = {
2303
2303
  inferenceId: string;
2304
+ /** The reply id the storage hook writes this turn's answer under, when it chose one. */
2305
+ assistantMessageId?: string;
2304
2306
  /** The RESOLVED api type (never "auto") — resolveApiType() already ran inside runToolLoop. */
2305
2307
  apiType: Exclude<ApiType, "auto">;
2306
2308
  model?: string;
@@ -3868,7 +3870,7 @@ declare function stripLegacyChunkTextOp(ctx: StorageOperationsContext): Promise<
3868
3870
  * sorted by `updatedAt`.
3869
3871
  */
3870
3872
  declare function encryptToolCallEventsOp(ctx: StorageOperationsContext): Promise<number>;
3871
- declare function updateMessageErrorOp(ctx: StorageOperationsContext, uniqueId: string, error: string): Promise<StoredMessage | null>;
3873
+ declare function updateMessageErrorOp(ctx: StorageOperationsContext, uniqueId: string, error: string | null): Promise<StoredMessage | null>;
3872
3874
  /**
3873
3875
  * Update the feedback (like/dislike) for a message.
3874
3876
  * Each regenerated response can have its own independent feedback.
@@ -4057,7 +4059,7 @@ interface ChatStorageAdapter {
4057
4059
  createMessage(options: CreateMessageOptions): Promise<StoredMessage>;
4058
4060
  updateMessageEmbedding(uniqueId: string, vector: number[], embeddingModel: string): Promise<StoredMessage | null>;
4059
4061
  updateMessageChunks(uniqueId: string, chunks: MessageChunk[], embeddingModel: string): Promise<StoredMessage | null>;
4060
- updateMessageError(uniqueId: string, error: string): Promise<StoredMessage | null>;
4062
+ updateMessageError(uniqueId: string, error: string | null): Promise<StoredMessage | null>;
4061
4063
  updateMessageFeedback(uniqueId: string, feedback: MessageFeedback): Promise<StoredMessage | null>;
4062
4064
  /**
4063
4065
  * Replace a message's attached media ids (`fileIds`). Used to attach a
@@ -7371,6 +7373,14 @@ type MessageFeedback = "like" | "dislike" | null;
7371
7373
  * would fail open.
7372
7374
  */
7373
7375
  type MessageOrigin = "tool_result" | "chunks_discarded" | "message";
7376
+ /** Why an Anuma 1:1 turn exists: a daily intro or a reply to the user. */
7377
+ type AnumaTurnOrigin = "intro" | "reply";
7378
+ /** One Anuma 1:1 turn: 1-3 ordered bubbles sealed inside the message payload. */
7379
+ interface AnumaTurn {
7380
+ turnId: string;
7381
+ bubbles?: string[];
7382
+ origin?: AnumaTurnOrigin;
7383
+ }
7374
7384
  /**
7375
7385
  * Metadata for files attached to messages.
7376
7386
  *
@@ -7539,6 +7549,8 @@ interface StoredMessage {
7539
7549
  toolCallEvents?: LlmapiToolCallEvent[];
7540
7550
  /** Provenance for synthetic rows; undefined for typed messages and pre-v44 rows */
7541
7551
  origin?: MessageOrigin;
7552
+ /** Anuma 1:1 turn fields; only vault chat backends store them. */
7553
+ anuma?: AnumaTurn;
7542
7554
  /**
7543
7555
  * Set when `content` could not be decrypted on read (#561).
7544
7556
  * The `content` field still holds the original ciphertext — never a
@@ -7714,6 +7726,8 @@ interface CreateMessageOptions {
7714
7726
  toolCallEvents?: LlmapiToolCallEvent[];
7715
7727
  /** Provenance for synthetic rows; set by the producer, never by user input */
7716
7728
  origin?: MessageOrigin;
7729
+ /** Anuma 1:1 turn fields; only vault chat backends store them. */
7730
+ anuma?: AnumaTurn;
7717
7731
  /**
7718
7732
  * Optional pre-generated unique ID for this message.
7719
7733
  * When provided, used as the WatermelonDB record ID instead of auto-generating one.
@@ -2301,6 +2301,8 @@ declare const INFERENCE_ID_HEADER = "X-Inference-ID";
2301
2301
  */
2302
2302
  type StreamResumeHandle = {
2303
2303
  inferenceId: string;
2304
+ /** The reply id the storage hook writes this turn's answer under, when it chose one. */
2305
+ assistantMessageId?: string;
2304
2306
  /** The RESOLVED api type (never "auto") — resolveApiType() already ran inside runToolLoop. */
2305
2307
  apiType: Exclude<ApiType, "auto">;
2306
2308
  model?: string;
@@ -3868,7 +3870,7 @@ declare function stripLegacyChunkTextOp(ctx: StorageOperationsContext): Promise<
3868
3870
  * sorted by `updatedAt`.
3869
3871
  */
3870
3872
  declare function encryptToolCallEventsOp(ctx: StorageOperationsContext): Promise<number>;
3871
- declare function updateMessageErrorOp(ctx: StorageOperationsContext, uniqueId: string, error: string): Promise<StoredMessage | null>;
3873
+ declare function updateMessageErrorOp(ctx: StorageOperationsContext, uniqueId: string, error: string | null): Promise<StoredMessage | null>;
3872
3874
  /**
3873
3875
  * Update the feedback (like/dislike) for a message.
3874
3876
  * Each regenerated response can have its own independent feedback.
@@ -4057,7 +4059,7 @@ interface ChatStorageAdapter {
4057
4059
  createMessage(options: CreateMessageOptions): Promise<StoredMessage>;
4058
4060
  updateMessageEmbedding(uniqueId: string, vector: number[], embeddingModel: string): Promise<StoredMessage | null>;
4059
4061
  updateMessageChunks(uniqueId: string, chunks: MessageChunk[], embeddingModel: string): Promise<StoredMessage | null>;
4060
- updateMessageError(uniqueId: string, error: string): Promise<StoredMessage | null>;
4062
+ updateMessageError(uniqueId: string, error: string | null): Promise<StoredMessage | null>;
4061
4063
  updateMessageFeedback(uniqueId: string, feedback: MessageFeedback): Promise<StoredMessage | null>;
4062
4064
  /**
4063
4065
  * Replace a message's attached media ids (`fileIds`). Used to attach a
@@ -7371,6 +7373,14 @@ type MessageFeedback = "like" | "dislike" | null;
7371
7373
  * would fail open.
7372
7374
  */
7373
7375
  type MessageOrigin = "tool_result" | "chunks_discarded" | "message";
7376
+ /** Why an Anuma 1:1 turn exists: a daily intro or a reply to the user. */
7377
+ type AnumaTurnOrigin = "intro" | "reply";
7378
+ /** One Anuma 1:1 turn: 1-3 ordered bubbles sealed inside the message payload. */
7379
+ interface AnumaTurn {
7380
+ turnId: string;
7381
+ bubbles?: string[];
7382
+ origin?: AnumaTurnOrigin;
7383
+ }
7374
7384
  /**
7375
7385
  * Metadata for files attached to messages.
7376
7386
  *
@@ -7539,6 +7549,8 @@ interface StoredMessage {
7539
7549
  toolCallEvents?: LlmapiToolCallEvent[];
7540
7550
  /** Provenance for synthetic rows; undefined for typed messages and pre-v44 rows */
7541
7551
  origin?: MessageOrigin;
7552
+ /** Anuma 1:1 turn fields; only vault chat backends store them. */
7553
+ anuma?: AnumaTurn;
7542
7554
  /**
7543
7555
  * Set when `content` could not be decrypted on read (#561).
7544
7556
  * The `content` field still holds the original ciphertext — never a
@@ -7714,6 +7726,8 @@ interface CreateMessageOptions {
7714
7726
  toolCallEvents?: LlmapiToolCallEvent[];
7715
7727
  /** Provenance for synthetic rows; set by the producer, never by user input */
7716
7728
  origin?: MessageOrigin;
7729
+ /** Anuma 1:1 turn fields; only vault chat backends store them. */
7730
+ anuma?: AnumaTurn;
7717
7731
  /**
7718
7732
  * Optional pre-generated unique ID for this message.
7719
7733
  * When provided, used as the WatermelonDB record ID instead of auto-generating one.
@@ -17405,7 +17405,7 @@ async function updateMessageErrorOp(ctx, uniqueId, error) {
17405
17405
  }
17406
17406
  await ctx.database.write(async () => {
17407
17407
  await message.update((msg) => {
17408
- msg._setRaw("error", error);
17408
+ msg._setRaw("error", error ?? "");
17409
17409
  });
17410
17410
  });
17411
17411
  return messageToStored(message, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner);
@@ -20596,6 +20596,13 @@ function createStreamAccumulator(initialModel) {
20596
20596
  function isAbortError(err) {
20597
20597
  return err instanceof Error && err.name === "AbortError";
20598
20598
  }
20599
+ var ProviderStreamError = class extends Error {
20600
+ constructor(message, code) {
20601
+ super(message);
20602
+ this.name = "ProviderStreamError";
20603
+ this.code = code;
20604
+ }
20605
+ };
20599
20606
  function getInStreamErrorMessage(chunk) {
20600
20607
  if (!chunk || typeof chunk !== "object") return null;
20601
20608
  const obj = chunk;
@@ -20882,7 +20889,7 @@ var CompletionsStrategy = class {
20882
20889
  processStreamChunk(chunk, accumulator) {
20883
20890
  const result = { content: null, thinking: null };
20884
20891
  const inStreamErr = getInStreamErrorMessage(chunk);
20885
- if (inStreamErr) throw new Error(inStreamErr);
20892
+ if (inStreamErr) throw new ProviderStreamError(inStreamErr);
20886
20893
  const rawChunk = chunk;
20887
20894
  const typedChunk = rawChunk.response && rawChunk.type === "response" ? rawChunk.response : chunk;
20888
20895
  if (typedChunk.id && !accumulator.responseId) {
@@ -21733,7 +21740,7 @@ var ResponsesStrategy = class {
21733
21740
  const result = { content: null, thinking: null };
21734
21741
  const typedChunk = chunk;
21735
21742
  const inStreamErr = getInStreamErrorMessage(chunk);
21736
- if (inStreamErr) throw new Error(inStreamErr);
21743
+ if (inStreamErr) throw new ProviderStreamError(inStreamErr);
21737
21744
  if (typedChunk.type === "response.failed") {
21738
21745
  const resp = typedChunk.response;
21739
21746
  const err = resp?.error;
@@ -21750,9 +21757,12 @@ var ResponsesStrategy = class {
21750
21757
  }
21751
21758
  }
21752
21759
  const label = code ? `[${code}] ` : "";
21753
- throw new Error(`${label}${message || "Upstream request failed"}`);
21760
+ throw new ProviderStreamError(
21761
+ `${label}${message || "Upstream request failed"}`,
21762
+ code || void 0
21763
+ );
21754
21764
  }
21755
- throw new Error("Upstream request failed (response.failed)");
21765
+ throw new ProviderStreamError("Upstream request failed (response.failed)");
21756
21766
  }
21757
21767
  if (typedChunk.type === "response" && typedChunk.response) {
21758
21768
  const resp = typedChunk.response;
@@ -22376,13 +22386,6 @@ function isRetriableStreamError(err) {
22376
22386
  if (msg.includes("connection refused") || msg.includes("connect error")) return true;
22377
22387
  return false;
22378
22388
  }
22379
- var ProviderStreamError = class extends Error {
22380
- constructor(message, code) {
22381
- super(message);
22382
- this.name = "ProviderStreamError";
22383
- this.code = code;
22384
- }
22385
- };
22386
22389
  function extractProviderStreamError(chunk) {
22387
22390
  if (!chunk || typeof chunk !== "object") return null;
22388
22391
  const errField = chunk.error;
@@ -22763,6 +22766,7 @@ async function runToolLoop(options) {
22763
22766
  thinking: redactor.deAnonymize(acc.thinking)
22764
22767
  }) : strategy.buildFinalResponse(acc);
22765
22768
  const finalContentText = (acc) => redactor ? redactor.deAnonymize(acc.content) : acc.content;
22769
+ let streamingAccumulator = null;
22766
22770
  try {
22767
22771
  let sseError = null;
22768
22772
  let apiTools = toolsToApiFormat(tools, resolved);
@@ -22914,6 +22918,7 @@ async function runToolLoop(options) {
22914
22918
  }
22915
22919
  });
22916
22920
  accumulator = createStreamAccumulator(model || void 0);
22921
+ streamingAccumulator = accumulator;
22917
22922
  contentSmoother = new StreamSmoother((text12) => {
22918
22923
  if (emitData) emitData(text12);
22919
22924
  }, smoothing);
@@ -23424,6 +23429,7 @@ Executing tool: ${toolInfo}
23424
23429
  }
23425
23430
  });
23426
23431
  currentAccumulator = createStreamAccumulator(model || void 0);
23432
+ streamingAccumulator = currentAccumulator;
23427
23433
  contContentSmoother = new StreamSmoother((text12) => {
23428
23434
  if (emitData) emitData(text12);
23429
23435
  }, smoothing);
@@ -23621,7 +23627,7 @@ Executing tool: ${toolInfo}
23621
23627
  const statusCode = err instanceof Error && "statusCode" in err ? err.statusCode : void 0;
23622
23628
  const connectionLost = !(err instanceof ProviderStreamError) && !(err instanceof SseError);
23623
23629
  return {
23624
- data: null,
23630
+ data: connectionLost && streamingAccumulator ? buildResponseFinal(streamingAccumulator) : null,
23625
23631
  error: errorMsg,
23626
23632
  statusCode,
23627
23633
  ...connectionLost ? { connectionLost: true } : {}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anuma/sdk",
3
- "version": "10.8.0",
3
+ "version": "10.10.0",
4
4
  "description": "",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.mjs",
@@ -129,7 +129,7 @@
129
129
  "spec": "openapi-ts && node scripts/patch-generated-client.mjs",
130
130
  "test": "vitest run",
131
131
  "test:browser": "vitest run --config vitest.browser.config.mts",
132
- "test:vault-conformance": "vitest run src/lib/chatStore/migrateChats.test.ts src/lib/chatStore/vaultBackend.contract.test.ts src/lib/chatStore/vaultBackend.test.ts src/lib/chatStore/vaultParity.test.ts src/react/useChatStorage.vaultParity.test.tsx",
132
+ "test:vault-conformance": "vitest run src/lib/chatStore/anuma.test.ts src/lib/chatStore/migrateChats.test.ts src/lib/chatStore/vaultBackend.contract.test.ts src/lib/chatStore/vaultBackend.test.ts src/lib/chatStore/vaultParity.test.ts src/react/useChatStorage.vaultParity.test.tsx",
133
133
  "build": "tsup",
134
134
  "prepublishOnly": "pnpm build",
135
135
  "docs": "typedoc",