@anuma/sdk 10.7.0 → 10.9.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.
package/dist/index.mjs CHANGED
@@ -1622,6 +1622,152 @@ function getImageModel(r) {
1622
1622
  return r.image_model;
1623
1623
  }
1624
1624
 
1625
+ // src/lib/chatStore/types.ts
1626
+ var ChatStoreError = class extends Error {
1627
+ constructor(message, status, code, retryAfterMs) {
1628
+ super(message);
1629
+ this.status = status;
1630
+ this.code = code;
1631
+ this.retryAfterMs = retryAfterMs;
1632
+ this.name = "ChatStoreError";
1633
+ }
1634
+ };
1635
+
1636
+ // src/lib/chatStore/vaultRecords.ts
1637
+ var PINNED_SORT_BASE = 2 ** 51;
1638
+ var maxBubbles = 3;
1639
+ var maxTurnIdBytes = 128;
1640
+ var maxBubbleBytes = 16384;
1641
+ var anumaOrigins = /* @__PURE__ */ new Set(["intro", "reply"]);
1642
+ function plain(value) {
1643
+ return JSON.parse(JSON.stringify(value ?? {}));
1644
+ }
1645
+ function number(value) {
1646
+ return typeof value === "number" ? value : void 0;
1647
+ }
1648
+ function readAnumaTurn(value) {
1649
+ if (!isObject(value)) return void 0;
1650
+ const { turnId, bubbles, origin } = value;
1651
+ if (typeof turnId !== "string" || turnId.length === 0 || new TextEncoder().encode(turnId).length > maxTurnIdBytes)
1652
+ return void 0;
1653
+ if (bubbles !== void 0 && (!Array.isArray(bubbles) || bubbles.length < 1 || bubbles.length > maxBubbles || !bubbles.every((b) => typeof b === "string") || bubbles.reduce((sum, b) => sum + new TextEncoder().encode(b).length, 0) > maxBubbleBytes))
1654
+ return void 0;
1655
+ if (origin !== void 0 && (typeof origin !== "string" || !anumaOrigins.has(origin)))
1656
+ return void 0;
1657
+ return {
1658
+ turnId,
1659
+ ...bubbles !== void 0 ? { bubbles: [...bubbles] } : {},
1660
+ ...origin !== void 0 ? { origin } : {}
1661
+ };
1662
+ }
1663
+ function isObject(value) {
1664
+ return value !== null && typeof value === "object" && !Array.isArray(value);
1665
+ }
1666
+ function conversationSortKey(data, createdAt) {
1667
+ const pinnedAt = number(data.pinnedAt);
1668
+ if (pinnedAt) return PINNED_SORT_BASE + pinnedAt;
1669
+ return number(data.lastActivityAt) ?? createdAt;
1670
+ }
1671
+
1672
+ // src/lib/chatStore/anuma.ts
1673
+ var ANUMA_CONVERSATION_ID = "anuma-1on1";
1674
+ var maxAttempts = 3;
1675
+ function anumaTurnContent(bubbles) {
1676
+ return bubbles.join("\n\n");
1677
+ }
1678
+ function anumaLastReadSortKey(conversation) {
1679
+ const record2 = conversation && "record" in conversation ? conversation.record : conversation;
1680
+ const state = record2?.data.anuma;
1681
+ if (!isObject(state)) return 0;
1682
+ const sortKey = state.lastReadSortKey;
1683
+ return Number.isSafeInteger(sortKey) && sortKey > 0 ? sortKey : 0;
1684
+ }
1685
+ function conflict(error) {
1686
+ return error instanceof ChatStoreError && error.code === "version_conflict";
1687
+ }
1688
+ function live(snapshot) {
1689
+ if (snapshot?.record.isDeleted)
1690
+ throw new ChatStoreError("Anuma conversation was deleted", 409, "conversation_deleted");
1691
+ return snapshot;
1692
+ }
1693
+ async function ensureAnumaConversation(store, options = {}) {
1694
+ const existing = live(await store.get("conversation", ANUMA_CONVERSATION_ID, options.signal));
1695
+ if (existing) return existing;
1696
+ const at = (options.now ?? Date.now)();
1697
+ const data = plain({ title: "Anuma", lastActivityAt: at, anuma: { lastReadSortKey: 0 } });
1698
+ try {
1699
+ const [created] = await store.putMany(
1700
+ [
1701
+ {
1702
+ expectedVersion: 0,
1703
+ record: {
1704
+ kind: "conversation",
1705
+ id: ANUMA_CONVERSATION_ID,
1706
+ conversationId: "",
1707
+ sortKey: conversationSortKey(data, at),
1708
+ createdAt: at,
1709
+ updatedAt: at,
1710
+ isDeleted: false,
1711
+ data
1712
+ }
1713
+ }
1714
+ ],
1715
+ options.signal
1716
+ );
1717
+ return created;
1718
+ } catch (error) {
1719
+ if (!conflict(error)) throw error;
1720
+ const winner = live(await store.get("conversation", ANUMA_CONVERSATION_ID, options.signal));
1721
+ if (!winner) throw error;
1722
+ return winner;
1723
+ }
1724
+ }
1725
+ async function markAnumaRead(store, sortKey, options = {}) {
1726
+ if (!Number.isSafeInteger(sortKey) || sortKey < 0)
1727
+ throw new ChatStoreError("Invalid Anuma read marker", 0, "invalid_record");
1728
+ const now = options.now ?? Date.now;
1729
+ for (let attempt = 1; ; attempt++) {
1730
+ const current = await ensureAnumaConversation(store, options);
1731
+ const read = anumaLastReadSortKey(current);
1732
+ if (sortKey <= read) return current;
1733
+ const record2 = current.record;
1734
+ const state = isObject(record2.data.anuma) ? record2.data.anuma : {};
1735
+ const data = plain({ ...record2.data, anuma: { ...state, lastReadSortKey: sortKey } });
1736
+ try {
1737
+ const [written] = await store.putMany(
1738
+ [
1739
+ {
1740
+ expectedVersion: current.version,
1741
+ record: {
1742
+ ...record2,
1743
+ data,
1744
+ sortKey: conversationSortKey(data, record2.createdAt),
1745
+ updatedAt: Math.max(record2.updatedAt, now())
1746
+ }
1747
+ }
1748
+ ],
1749
+ options.signal
1750
+ );
1751
+ return written;
1752
+ } catch (error) {
1753
+ if (!conflict(error) || attempt >= maxAttempts) throw error;
1754
+ }
1755
+ }
1756
+ }
1757
+ function countUnreadAnumaTurns(messages, lastReadSortKey) {
1758
+ const answered = Math.max(
1759
+ 0,
1760
+ ...messages.filter((m) => m.role === "user").map((m) => m.messageId)
1761
+ );
1762
+ const floor = Math.max(lastReadSortKey, answered);
1763
+ const turns = /* @__PURE__ */ new Set();
1764
+ for (const m of messages) {
1765
+ if (m.role !== "assistant" || m.messageId <= floor) continue;
1766
+ turns.add(m.anuma?.turnId ? `turn:${m.anuma.turnId}` : `message:${m.uniqueId}`);
1767
+ }
1768
+ return turns.size;
1769
+ }
1770
+
1625
1771
  // src/lib/memoryEngine/vector.ts
1626
1772
  function cosineSimilarity(a, b) {
1627
1773
  if (a.length !== b.length) return 0;
@@ -1825,17 +1971,6 @@ function createNearbyRequest(options, apiPath = "/api/private-memories") {
1825
1971
  return request;
1826
1972
  }
1827
1973
 
1828
- // src/lib/chatStore/types.ts
1829
- var ChatStoreError = class extends Error {
1830
- constructor(message, status, code, retryAfterMs) {
1831
- super(message);
1832
- this.status = status;
1833
- this.code = code;
1834
- this.retryAfterMs = retryAfterMs;
1835
- this.name = "ChatStoreError";
1836
- }
1837
- };
1838
-
1839
1974
  // src/lib/chatStore/remote.ts
1840
1975
  var kinds = /* @__PURE__ */ new Set(["conversation", "message", "summary", "project", "memory_links", "setting"]);
1841
1976
  var cipherPattern = /^enc:v\d+:(?:[0-9a-f]{2}){28,}$/i;
@@ -1995,7 +2130,7 @@ async function createRemoteChatStore(options) {
1995
2130
  if (!object(value) || !object(value.record) || !integer(value.version, 1) || typeof value.server_updated_at !== "string" || !Number.isFinite(Date.parse(value.server_updated_at)))
1996
2131
  invalid();
1997
2132
  const r = value.record;
1998
- const plain = {
2133
+ const plain2 = {
1999
2134
  kind: r.kind,
2000
2135
  id: r.id,
2001
2136
  conversationId: r.conversation_id,
@@ -2005,13 +2140,13 @@ async function createRemoteChatStore(options) {
2005
2140
  isDeleted: r.is_deleted,
2006
2141
  data: {}
2007
2142
  };
2008
- if (!validRecord(plain) || typeof r.payload !== "string" || r.payload.length > maxPayload)
2143
+ if (!validRecord(plain2) || typeof r.payload !== "string" || r.payload.length > maxPayload)
2009
2144
  invalid();
2010
- if (plain.isDeleted && r.payload === "")
2011
- return { record: plain, version: value.version, serverUpdatedAt: value.server_updated_at };
2145
+ if (plain2.isDeleted && r.payload === "")
2146
+ return { record: plain2, version: value.version, serverUpdatedAt: value.server_updated_at };
2012
2147
  if (!cipherPattern.test(r.payload)) invalid();
2013
2148
  const envelope = JSON.parse(await decrypt(r.payload));
2014
- if (!object(envelope) || envelope.schema !== 1 || envelope.account_id !== accountId || envelope.key_id !== keyId || !validRecord(envelope.record) || !sameMetadata(plain, envelope.record))
2149
+ if (!object(envelope) || envelope.schema !== 1 || envelope.account_id !== accountId || envelope.key_id !== keyId || !validRecord(envelope.record) || !sameMetadata(plain2, envelope.record))
2015
2150
  invalid();
2016
2151
  return {
2017
2152
  record: envelope.record,
@@ -4577,6 +4712,7 @@ async function selectServerSideTools(options) {
4577
4712
  return matchedTools.map(toResponsesFormat);
4578
4713
  }
4579
4714
  export {
4715
+ ANUMA_CONVERSATION_ID,
4580
4716
  BUILT_IN_TOOL_SETS,
4581
4717
  CHUNKS_DISCARDED_ORIGIN,
4582
4718
  ChatStoreError,
@@ -4599,6 +4735,8 @@ export {
4599
4735
  TOOL_RESULT_ORIGIN,
4600
4736
  activatedToolSetNames,
4601
4737
  analyzeStyle,
4738
+ anumaLastReadSortKey,
4739
+ anumaTurnContent,
4602
4740
  applyToolSets,
4603
4741
  attachFileContextToLastUserMessage,
4604
4742
  buildAttachedFilesText,
@@ -4608,6 +4746,7 @@ export {
4608
4746
  clearLazyTitleCache,
4609
4747
  consoleLogger,
4610
4748
  cosineInt8,
4749
+ countUnreadAnumaTurns,
4611
4750
  createRemoteChatStore,
4612
4751
  createServerToolsFilter,
4613
4752
  createStreamingDeAnonymizer,
@@ -4627,6 +4766,7 @@ export {
4627
4766
  deleteApiV1WalletsBindingByAddress,
4628
4767
  dequantizeEmbedding,
4629
4768
  encodeChunkVector,
4769
+ ensureAnumaConversation,
4630
4770
  expandToolSetsAdditive,
4631
4771
  extractReservationReceipts,
4632
4772
  formatFileProcessingNotes,
@@ -4672,6 +4812,7 @@ export {
4672
4812
  isAttachedFilesText,
4673
4813
  isPiiRedactor,
4674
4814
  loadSettings,
4815
+ markAnumaRead,
4675
4816
  noopLogger,
4676
4817
  patchApiV1DeveloperAppsByAppUuid,
4677
4818
  patchApiV1DeveloperAppsByAppUuidUsersByAddress,
@@ -4711,6 +4852,7 @@ export {
4711
4852
  putApiV1AdminPersonasById,
4712
4853
  putApiV1AgentsByIdPreference,
4713
4854
  quantizeEmbedding,
4855
+ readAnumaTurn,
4714
4856
  renderTemplate,
4715
4857
  resolvePiiRedactor,
4716
4858
  sanitizeQuotes,