@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.cjs CHANGED
@@ -60,6 +60,7 @@ var init_clientConfig = __esm({
60
60
  // src/index.ts
61
61
  var index_exports = {};
62
62
  __export(index_exports, {
63
+ ANUMA_CONVERSATION_ID: () => ANUMA_CONVERSATION_ID,
63
64
  BUILT_IN_TOOL_SETS: () => BUILT_IN_TOOL_SETS,
64
65
  CHUNKS_DISCARDED_ORIGIN: () => CHUNKS_DISCARDED_ORIGIN,
65
66
  ChatStoreError: () => ChatStoreError,
@@ -82,6 +83,8 @@ __export(index_exports, {
82
83
  TOOL_RESULT_ORIGIN: () => TOOL_RESULT_ORIGIN,
83
84
  activatedToolSetNames: () => activatedToolSetNames,
84
85
  analyzeStyle: () => analyzeStyle,
86
+ anumaLastReadSortKey: () => anumaLastReadSortKey,
87
+ anumaTurnContent: () => anumaTurnContent,
85
88
  applyToolSets: () => applyToolSets,
86
89
  attachFileContextToLastUserMessage: () => attachFileContextToLastUserMessage,
87
90
  buildAttachedFilesText: () => buildAttachedFilesText,
@@ -91,6 +94,7 @@ __export(index_exports, {
91
94
  clearLazyTitleCache: () => clearLazyTitleCache,
92
95
  consoleLogger: () => consoleLogger,
93
96
  cosineInt8: () => cosineInt8,
97
+ countUnreadAnumaTurns: () => countUnreadAnumaTurns,
94
98
  createRemoteChatStore: () => createRemoteChatStore,
95
99
  createServerToolsFilter: () => createServerToolsFilter,
96
100
  createStreamingDeAnonymizer: () => createStreamingDeAnonymizer,
@@ -110,6 +114,7 @@ __export(index_exports, {
110
114
  deleteApiV1WalletsBindingByAddress: () => deleteApiV1WalletsBindingByAddress,
111
115
  dequantizeEmbedding: () => dequantizeEmbedding,
112
116
  encodeChunkVector: () => encodeChunkVector,
117
+ ensureAnumaConversation: () => ensureAnumaConversation,
113
118
  expandToolSetsAdditive: () => expandToolSetsAdditive,
114
119
  extractReservationReceipts: () => extractReservationReceipts,
115
120
  formatFileProcessingNotes: () => formatFileProcessingNotes,
@@ -155,6 +160,7 @@ __export(index_exports, {
155
160
  isAttachedFilesText: () => isAttachedFilesText,
156
161
  isPiiRedactor: () => isPiiRedactor,
157
162
  loadSettings: () => loadSettings,
163
+ markAnumaRead: () => markAnumaRead,
158
164
  noopLogger: () => noopLogger,
159
165
  patchApiV1DeveloperAppsByAppUuid: () => patchApiV1DeveloperAppsByAppUuid,
160
166
  patchApiV1DeveloperAppsByAppUuidUsersByAddress: () => patchApiV1DeveloperAppsByAppUuidUsersByAddress,
@@ -194,6 +200,7 @@ __export(index_exports, {
194
200
  putApiV1AdminPersonasById: () => putApiV1AdminPersonasById,
195
201
  putApiV1AgentsByIdPreference: () => putApiV1AgentsByIdPreference,
196
202
  quantizeEmbedding: () => quantizeEmbedding,
203
+ readAnumaTurn: () => readAnumaTurn,
197
204
  renderTemplate: () => renderTemplate,
198
205
  resolvePiiRedactor: () => resolvePiiRedactor,
199
206
  sanitizeQuotes: () => sanitizeQuotes,
@@ -1827,6 +1834,152 @@ function getImageModel(r) {
1827
1834
  return r.image_model;
1828
1835
  }
1829
1836
 
1837
+ // src/lib/chatStore/types.ts
1838
+ var ChatStoreError = class extends Error {
1839
+ constructor(message, status, code, retryAfterMs) {
1840
+ super(message);
1841
+ this.status = status;
1842
+ this.code = code;
1843
+ this.retryAfterMs = retryAfterMs;
1844
+ this.name = "ChatStoreError";
1845
+ }
1846
+ };
1847
+
1848
+ // src/lib/chatStore/vaultRecords.ts
1849
+ var PINNED_SORT_BASE = 2 ** 51;
1850
+ var maxBubbles = 3;
1851
+ var maxTurnIdBytes = 128;
1852
+ var maxBubbleBytes = 16384;
1853
+ var anumaOrigins = /* @__PURE__ */ new Set(["intro", "reply"]);
1854
+ function plain(value) {
1855
+ return JSON.parse(JSON.stringify(value ?? {}));
1856
+ }
1857
+ function number(value) {
1858
+ return typeof value === "number" ? value : void 0;
1859
+ }
1860
+ function readAnumaTurn(value) {
1861
+ if (!isObject(value)) return void 0;
1862
+ const { turnId, bubbles, origin } = value;
1863
+ if (typeof turnId !== "string" || turnId.length === 0 || new TextEncoder().encode(turnId).length > maxTurnIdBytes)
1864
+ return void 0;
1865
+ 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))
1866
+ return void 0;
1867
+ if (origin !== void 0 && (typeof origin !== "string" || !anumaOrigins.has(origin)))
1868
+ return void 0;
1869
+ return {
1870
+ turnId,
1871
+ ...bubbles !== void 0 ? { bubbles: [...bubbles] } : {},
1872
+ ...origin !== void 0 ? { origin } : {}
1873
+ };
1874
+ }
1875
+ function isObject(value) {
1876
+ return value !== null && typeof value === "object" && !Array.isArray(value);
1877
+ }
1878
+ function conversationSortKey(data, createdAt) {
1879
+ const pinnedAt = number(data.pinnedAt);
1880
+ if (pinnedAt) return PINNED_SORT_BASE + pinnedAt;
1881
+ return number(data.lastActivityAt) ?? createdAt;
1882
+ }
1883
+
1884
+ // src/lib/chatStore/anuma.ts
1885
+ var ANUMA_CONVERSATION_ID = "anuma-1on1";
1886
+ var maxAttempts = 3;
1887
+ function anumaTurnContent(bubbles) {
1888
+ return bubbles.join("\n\n");
1889
+ }
1890
+ function anumaLastReadSortKey(conversation) {
1891
+ const record2 = conversation && "record" in conversation ? conversation.record : conversation;
1892
+ const state = record2?.data.anuma;
1893
+ if (!isObject(state)) return 0;
1894
+ const sortKey = state.lastReadSortKey;
1895
+ return Number.isSafeInteger(sortKey) && sortKey > 0 ? sortKey : 0;
1896
+ }
1897
+ function conflict(error) {
1898
+ return error instanceof ChatStoreError && error.code === "version_conflict";
1899
+ }
1900
+ function live(snapshot) {
1901
+ if (snapshot?.record.isDeleted)
1902
+ throw new ChatStoreError("Anuma conversation was deleted", 409, "conversation_deleted");
1903
+ return snapshot;
1904
+ }
1905
+ async function ensureAnumaConversation(store, options = {}) {
1906
+ const existing = live(await store.get("conversation", ANUMA_CONVERSATION_ID, options.signal));
1907
+ if (existing) return existing;
1908
+ const at = (options.now ?? Date.now)();
1909
+ const data = plain({ title: "Anuma", lastActivityAt: at, anuma: { lastReadSortKey: 0 } });
1910
+ try {
1911
+ const [created] = await store.putMany(
1912
+ [
1913
+ {
1914
+ expectedVersion: 0,
1915
+ record: {
1916
+ kind: "conversation",
1917
+ id: ANUMA_CONVERSATION_ID,
1918
+ conversationId: "",
1919
+ sortKey: conversationSortKey(data, at),
1920
+ createdAt: at,
1921
+ updatedAt: at,
1922
+ isDeleted: false,
1923
+ data
1924
+ }
1925
+ }
1926
+ ],
1927
+ options.signal
1928
+ );
1929
+ return created;
1930
+ } catch (error) {
1931
+ if (!conflict(error)) throw error;
1932
+ const winner = live(await store.get("conversation", ANUMA_CONVERSATION_ID, options.signal));
1933
+ if (!winner) throw error;
1934
+ return winner;
1935
+ }
1936
+ }
1937
+ async function markAnumaRead(store, sortKey, options = {}) {
1938
+ if (!Number.isSafeInteger(sortKey) || sortKey < 0)
1939
+ throw new ChatStoreError("Invalid Anuma read marker", 0, "invalid_record");
1940
+ const now = options.now ?? Date.now;
1941
+ for (let attempt = 1; ; attempt++) {
1942
+ const current = await ensureAnumaConversation(store, options);
1943
+ const read = anumaLastReadSortKey(current);
1944
+ if (sortKey <= read) return current;
1945
+ const record2 = current.record;
1946
+ const state = isObject(record2.data.anuma) ? record2.data.anuma : {};
1947
+ const data = plain({ ...record2.data, anuma: { ...state, lastReadSortKey: sortKey } });
1948
+ try {
1949
+ const [written] = await store.putMany(
1950
+ [
1951
+ {
1952
+ expectedVersion: current.version,
1953
+ record: {
1954
+ ...record2,
1955
+ data,
1956
+ sortKey: conversationSortKey(data, record2.createdAt),
1957
+ updatedAt: Math.max(record2.updatedAt, now())
1958
+ }
1959
+ }
1960
+ ],
1961
+ options.signal
1962
+ );
1963
+ return written;
1964
+ } catch (error) {
1965
+ if (!conflict(error) || attempt >= maxAttempts) throw error;
1966
+ }
1967
+ }
1968
+ }
1969
+ function countUnreadAnumaTurns(messages, lastReadSortKey) {
1970
+ const answered = Math.max(
1971
+ 0,
1972
+ ...messages.filter((m) => m.role === "user").map((m) => m.messageId)
1973
+ );
1974
+ const floor = Math.max(lastReadSortKey, answered);
1975
+ const turns = /* @__PURE__ */ new Set();
1976
+ for (const m of messages) {
1977
+ if (m.role !== "assistant" || m.messageId <= floor) continue;
1978
+ turns.add(m.anuma?.turnId ? `turn:${m.anuma.turnId}` : `message:${m.uniqueId}`);
1979
+ }
1980
+ return turns.size;
1981
+ }
1982
+
1830
1983
  // src/lib/memoryEngine/vector.ts
1831
1984
  function cosineSimilarity(a, b) {
1832
1985
  if (a.length !== b.length) return 0;
@@ -2030,17 +2183,6 @@ function createNearbyRequest(options, apiPath = "/api/private-memories") {
2030
2183
  return request;
2031
2184
  }
2032
2185
 
2033
- // src/lib/chatStore/types.ts
2034
- var ChatStoreError = class extends Error {
2035
- constructor(message, status, code, retryAfterMs) {
2036
- super(message);
2037
- this.status = status;
2038
- this.code = code;
2039
- this.retryAfterMs = retryAfterMs;
2040
- this.name = "ChatStoreError";
2041
- }
2042
- };
2043
-
2044
2186
  // src/lib/chatStore/remote.ts
2045
2187
  var kinds = /* @__PURE__ */ new Set(["conversation", "message", "summary", "project", "memory_links", "setting"]);
2046
2188
  var cipherPattern = /^enc:v\d+:(?:[0-9a-f]{2}){28,}$/i;
@@ -2200,7 +2342,7 @@ async function createRemoteChatStore(options) {
2200
2342
  if (!object(value) || !object(value.record) || !integer(value.version, 1) || typeof value.server_updated_at !== "string" || !Number.isFinite(Date.parse(value.server_updated_at)))
2201
2343
  invalid();
2202
2344
  const r = value.record;
2203
- const plain = {
2345
+ const plain2 = {
2204
2346
  kind: r.kind,
2205
2347
  id: r.id,
2206
2348
  conversationId: r.conversation_id,
@@ -2210,13 +2352,13 @@ async function createRemoteChatStore(options) {
2210
2352
  isDeleted: r.is_deleted,
2211
2353
  data: {}
2212
2354
  };
2213
- if (!validRecord(plain) || typeof r.payload !== "string" || r.payload.length > maxPayload)
2355
+ if (!validRecord(plain2) || typeof r.payload !== "string" || r.payload.length > maxPayload)
2214
2356
  invalid();
2215
- if (plain.isDeleted && r.payload === "")
2216
- return { record: plain, version: value.version, serverUpdatedAt: value.server_updated_at };
2357
+ if (plain2.isDeleted && r.payload === "")
2358
+ return { record: plain2, version: value.version, serverUpdatedAt: value.server_updated_at };
2217
2359
  if (!cipherPattern.test(r.payload)) invalid();
2218
2360
  const envelope = JSON.parse(await decrypt(r.payload));
2219
- if (!object(envelope) || envelope.schema !== 1 || envelope.account_id !== accountId || envelope.key_id !== keyId || !validRecord(envelope.record) || !sameMetadata(plain, envelope.record))
2361
+ if (!object(envelope) || envelope.schema !== 1 || envelope.account_id !== accountId || envelope.key_id !== keyId || !validRecord(envelope.record) || !sameMetadata(plain2, envelope.record))
2220
2362
  invalid();
2221
2363
  return {
2222
2364
  record: envelope.record,
@@ -4786,6 +4928,7 @@ async function selectServerSideTools(options) {
4786
4928
  }
4787
4929
  // Annotate the CommonJS export names for ESM import in node:
4788
4930
  0 && (module.exports = {
4931
+ ANUMA_CONVERSATION_ID,
4789
4932
  BUILT_IN_TOOL_SETS,
4790
4933
  CHUNKS_DISCARDED_ORIGIN,
4791
4934
  ChatStoreError,
@@ -4808,6 +4951,8 @@ async function selectServerSideTools(options) {
4808
4951
  TOOL_RESULT_ORIGIN,
4809
4952
  activatedToolSetNames,
4810
4953
  analyzeStyle,
4954
+ anumaLastReadSortKey,
4955
+ anumaTurnContent,
4811
4956
  applyToolSets,
4812
4957
  attachFileContextToLastUserMessage,
4813
4958
  buildAttachedFilesText,
@@ -4817,6 +4962,7 @@ async function selectServerSideTools(options) {
4817
4962
  clearLazyTitleCache,
4818
4963
  consoleLogger,
4819
4964
  cosineInt8,
4965
+ countUnreadAnumaTurns,
4820
4966
  createRemoteChatStore,
4821
4967
  createServerToolsFilter,
4822
4968
  createStreamingDeAnonymizer,
@@ -4836,6 +4982,7 @@ async function selectServerSideTools(options) {
4836
4982
  deleteApiV1WalletsBindingByAddress,
4837
4983
  dequantizeEmbedding,
4838
4984
  encodeChunkVector,
4985
+ ensureAnumaConversation,
4839
4986
  expandToolSetsAdditive,
4840
4987
  extractReservationReceipts,
4841
4988
  formatFileProcessingNotes,
@@ -4881,6 +5028,7 @@ async function selectServerSideTools(options) {
4881
5028
  isAttachedFilesText,
4882
5029
  isPiiRedactor,
4883
5030
  loadSettings,
5031
+ markAnumaRead,
4884
5032
  noopLogger,
4885
5033
  patchApiV1DeveloperAppsByAppUuid,
4886
5034
  patchApiV1DeveloperAppsByAppUuidUsersByAddress,
@@ -4920,6 +5068,7 @@ async function selectServerSideTools(options) {
4920
5068
  putApiV1AdminPersonasById,
4921
5069
  putApiV1AgentsByIdPreference,
4922
5070
  quantizeEmbedding,
5071
+ readAnumaTurn,
4923
5072
  renderTemplate,
4924
5073
  resolvePiiRedactor,
4925
5074
  sanitizeQuotes,