@anuma/sdk 6.3.1 → 6.4.1

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.
@@ -123,7 +123,7 @@ import {
123
123
  upsertMessageOp,
124
124
  useEncryption,
125
125
  vaultMemoryToStored
126
- } from "./chunk-PBCULYOW.mjs";
126
+ } from "./chunk-WYARTNEN.mjs";
127
127
  import {
128
128
  PII_PATTERNS,
129
129
  PiiRedactor,
@@ -4986,6 +4986,153 @@ async function cleanupConversationSummary(database, conversationId) {
4986
4986
  }
4987
4987
  }
4988
4988
 
4989
+ // src/lib/chat/toolResultMessage.ts
4990
+ var HEADER = "[Tool Execution Results]\n\n";
4991
+ var FOOTER = "\n\nBased on these results, continue with the task.";
4992
+ var ENTRY_SEPARATOR = "\n\n";
4993
+ var TOOL_RESULT_FOOTER_LINE = FOOTER.trim();
4994
+ var MAX_PERSISTED_TOOL_RESULT_CHARS = 1e5;
4995
+ function buildToolResultContent(results) {
4996
+ const entries = results.map((r) => `Tool "${r.name}" returned: ${JSON.stringify(r.result)}`);
4997
+ const framing = HEADER.length + FOOTER.length + ENTRY_SEPARATOR.length * Math.max(0, entries.length - 1);
4998
+ const summary = capEntries(entries, MAX_PERSISTED_TOOL_RESULT_CHARS - framing).join(
4999
+ ENTRY_SEPARATOR
5000
+ );
5001
+ return `${HEADER}${summary}${FOOTER}`;
5002
+ }
5003
+ function capToolResultEntries(entries, budget) {
5004
+ return capEntries(entries, budget);
5005
+ }
5006
+ function capEntries(entries, budget) {
5007
+ const smallestFirst = entries.map((_, index) => index).sort((a, b) => entries[a].length - entries[b].length);
5008
+ const capped = [...entries];
5009
+ let remaining = budget;
5010
+ let unassigned = entries.length;
5011
+ for (const index of smallestFirst) {
5012
+ capped[index] = truncateEntry(entries[index], Math.floor(remaining / unassigned));
5013
+ remaining -= capped[index].length;
5014
+ unassigned--;
5015
+ }
5016
+ return capped;
5017
+ }
5018
+ function truncateEntry(entry, allowance) {
5019
+ if (entry.length <= allowance) return entry;
5020
+ const keep = allowance - truncationMarker(entry.length).length;
5021
+ if (keep <= 0) return entry.slice(0, Math.max(0, allowance));
5022
+ return `${entry.slice(0, keep)}${truncationMarker(entry.length - keep)}`;
5023
+ }
5024
+ function truncationMarker(omitted) {
5025
+ return `
5026
+
5027
+ ... (tool output truncated, ${omitted} characters omitted)`;
5028
+ }
5029
+
5030
+ // src/lib/chat/toolResults.ts
5031
+ var TOOL_RESULTS_PREFIX = "[Tool Execution Results]";
5032
+ var DISPLAY_CARD_PLACEHOLDER = "[displayed a card to the user with the tool result]";
5033
+ var TOOL_LINE = /^Tool "([^"]+)" returned: (.*)$/;
5034
+ var TOOL_RESULT_ORIGIN = "tool_result";
5035
+ function isToolResultsRow(row) {
5036
+ if (row.origin === TOOL_RESULT_ORIGIN) return true;
5037
+ if (typeof row.origin === "string") return false;
5038
+ if (row.role !== "user" || !row.content.startsWith(TOOL_RESULTS_PREFIX)) return false;
5039
+ return parseToolResultSegments(row.content).length > 0;
5040
+ }
5041
+ function parseToolResultSegments(content) {
5042
+ const segments = [];
5043
+ for (const raw of content.split("\n")) {
5044
+ const line = raw.trim();
5045
+ const match = TOOL_LINE.exec(line);
5046
+ if (match) {
5047
+ segments.push({ name: match[1], line });
5048
+ continue;
5049
+ }
5050
+ const current = segments[segments.length - 1];
5051
+ if (!current || line === "" || line === TOOL_RESULT_FOOTER_LINE) continue;
5052
+ if (line === TOOL_RESULTS_PREFIX) continue;
5053
+ current.line = `${current.line}
5054
+ ${line}`;
5055
+ }
5056
+ return segments;
5057
+ }
5058
+ function prepareToolResultsForReplay(rows, options) {
5059
+ if (options.fold) {
5060
+ return foldToolResultsRows(rows, {
5061
+ exclude: options.exclude,
5062
+ placeholder: options.placeholder
5063
+ });
5064
+ }
5065
+ return rows.filter((row) => !isToolResultsRow(row));
5066
+ }
5067
+ function foldToolResultsRows(rows, options) {
5068
+ const exclude = new Set(options?.exclude ?? []);
5069
+ const out = [];
5070
+ const pending = [];
5071
+ const assistantIndexById = /* @__PURE__ */ new Map();
5072
+ for (const row of rows) {
5073
+ if (isToolResultsRow(row)) {
5074
+ pending.push({ row, insertionPoint: out.length });
5075
+ continue;
5076
+ }
5077
+ out.push(row);
5078
+ if (row.role === "assistant" && row.uniqueId) {
5079
+ assistantIndexById.set(row.uniqueId, out.length - 1);
5080
+ }
5081
+ }
5082
+ const byTarget = /* @__PURE__ */ new Map();
5083
+ for (const { row, insertionPoint } of pending) {
5084
+ const target = resolveFoldTarget(out, row, insertionPoint, assistantIndexById);
5085
+ if (target === void 0) continue;
5086
+ const group = byTarget.get(target);
5087
+ if (group) group.push(row);
5088
+ else byTarget.set(target, [row]);
5089
+ }
5090
+ for (const [target, groupedRows] of byTarget) {
5091
+ const assistant = out[target];
5092
+ const kept = groupedRows.flatMap((row) => parseToolResultSegments(row.content)).filter((segment) => !exclude.has(segment.name));
5093
+ if (kept.length > 0) {
5094
+ out[target] = { ...assistant, content: appendToolResults(assistant.content, kept) };
5095
+ } else if (!assistant.content.trim() && options?.placeholder) {
5096
+ out[target] = { ...assistant, content: options.placeholder };
5097
+ }
5098
+ }
5099
+ return out;
5100
+ }
5101
+ function resolveFoldTarget(out, row, insertionPoint, assistantIndexById) {
5102
+ const linked = row.parentMessageId ? assistantIndexById.get(row.parentMessageId) : void 0;
5103
+ if (linked !== void 0) return linked;
5104
+ let previous;
5105
+ for (let i = insertionPoint - 1; i >= 0; i--) {
5106
+ if (out[i].role === "assistant") {
5107
+ previous = i;
5108
+ break;
5109
+ }
5110
+ }
5111
+ let next;
5112
+ for (let i = insertionPoint; i < out.length; i++) {
5113
+ if (out[i].role === "assistant") {
5114
+ next = i;
5115
+ break;
5116
+ }
5117
+ }
5118
+ if (previous === void 0) return next;
5119
+ if (next === void 0) return previous;
5120
+ return next - insertionPoint < insertionPoint - previous ? next : previous;
5121
+ }
5122
+ var MAX_FOLDED_APPENDIX_CHARS = 2e4;
5123
+ function appendToolResults(assistantContent, kept) {
5124
+ const framing = TOOL_RESULTS_PREFIX.length + 1 + (kept.length - 1);
5125
+ const capped = capToolResultEntries(
5126
+ kept.map((segment) => segment.line),
5127
+ MAX_FOLDED_APPENDIX_CHARS - framing
5128
+ );
5129
+ const appendix = `${TOOL_RESULTS_PREFIX}
5130
+ ${capped.join("\n")}`;
5131
+ return assistantContent.trim() ? `${assistantContent}
5132
+
5133
+ ${appendix}` : appendix;
5134
+ }
5135
+
4989
5136
  // src/lib/db/chat/lazyDecrypt.ts
4990
5137
  var LRU_CAPACITY = 256;
4991
5138
  var titleCache = /* @__PURE__ */ new Map();
@@ -10533,11 +10680,17 @@ function useChatStorage(options) {
10533
10680
  onPiiRedacted,
10534
10681
  nerDetector,
10535
10682
  onServerToolCall,
10536
- onToolCallArgumentsDelta
10683
+ onToolCallArgumentsDelta,
10684
+ toolResultsHistoryExclude,
10685
+ foldToolResultsInHistory
10537
10686
  } = options;
10538
10687
  const [currentConversationId, setCurrentConversationId] = useState4(
10539
10688
  initialConversationId || null
10540
10689
  );
10690
+ const toolResultsHistoryExcludeRef = useRef4(toolResultsHistoryExclude);
10691
+ toolResultsHistoryExcludeRef.current = toolResultsHistoryExclude;
10692
+ const foldToolResultsInHistoryRef = useRef4(foldToolResultsInHistory);
10693
+ foldToolResultsInHistoryRef.current = foldToolResultsInHistory;
10541
10694
  const nerDetectorRef = useRef4(nerDetector);
10542
10695
  nerDetectorRef.current = nerDetector;
10543
10696
  const resolvedPiiRedaction = useMemo(
@@ -11405,7 +11558,13 @@ function useChatStorage(options) {
11405
11558
  }
11406
11559
  if (includeHistory) {
11407
11560
  const validMessages = storedMessages.filter((msg) => !msg.error);
11408
- const limitedMessages = validMessages.slice(-maxHistoryMessages);
11561
+ const replayableMessages = prepareToolResultsForReplay(validMessages, {
11562
+ fold: foldToolResultsInHistoryRef.current === true,
11563
+ exclude: toolResultsHistoryExcludeRef.current,
11564
+ placeholder: DISPLAY_CARD_PLACEHOLDER
11565
+ });
11566
+ const limitedMessages = replayableMessages.slice(-maxHistoryMessages);
11567
+ const foldedHistory = limitedMessages;
11409
11568
  if (summarizeHistory && !getTokenRef.current) {
11410
11569
  getLogger().warn(
11411
11570
  "[summarize] summarizeHistory is enabled but getToken is not provided \u2014 summarization will be skipped"
@@ -11415,7 +11574,7 @@ function useChatStorage(options) {
11415
11574
  const { messagesToConvert, summarySystemMessage } = await maybeSummarizeHistory({
11416
11575
  database,
11417
11576
  conversationId: convId,
11418
- messages: limitedMessages,
11577
+ messages: foldedHistory,
11419
11578
  summarizeHistory,
11420
11579
  summaryTokenThreshold,
11421
11580
  summaryMinWindowMessages,
@@ -11785,6 +11944,7 @@ function useChatStorage(options) {
11785
11944
  uniqueId: effectiveAssistantUniqueId
11786
11945
  };
11787
11946
  let storedAssistantMessage;
11947
+ let assistantMsgQueueId;
11788
11948
  try {
11789
11949
  const assistantMsgResult = await writeOrQueue(
11790
11950
  "createMessage",
@@ -11794,6 +11954,7 @@ function useChatStorage(options) {
11794
11954
  userMsgQueueId ? [userMsgQueueId] : []
11795
11955
  );
11796
11956
  storedAssistantMessage = assistantMsgResult.result;
11957
+ assistantMsgQueueId = assistantMsgResult.queueId;
11797
11958
  if (!assistantMsgResult.queued) {
11798
11959
  void embedMessageAsync(storedAssistantMessage, maskForCall);
11799
11960
  }
@@ -11804,6 +11965,29 @@ function useChatStorage(options) {
11804
11965
  userMessage: storedUserMessage
11805
11966
  };
11806
11967
  }
11968
+ const autoToolResults = result.autoExecutedToolResults;
11969
+ let storedToolResultsMessage;
11970
+ if (autoToolResults && autoToolResults.length > 0) {
11971
+ const toolResultsOpts = {
11972
+ conversationId: convId,
11973
+ role: "user",
11974
+ content: buildToolResultContent(autoToolResults),
11975
+ model: "",
11976
+ parentMessageId: storedAssistantMessage.uniqueId,
11977
+ origin: TOOL_RESULT_ORIGIN
11978
+ };
11979
+ try {
11980
+ const toolResultsWrite = await writeOrQueue(
11981
+ "createMessage",
11982
+ toolResultsOpts,
11983
+ () => createMessageOp(storageCtx, toolResultsOpts),
11984
+ () => makeSyntheticStoredMessage(toolResultsOpts),
11985
+ assistantMsgQueueId ? [assistantMsgQueueId] : []
11986
+ );
11987
+ storedToolResultsMessage = toolResultsWrite.result;
11988
+ } catch {
11989
+ }
11990
+ }
11807
11991
  const refreshGetToken = getTokenRef.current;
11808
11992
  if (refreshGetToken) {
11809
11993
  Promise.resolve().then(() => shouldRefreshTools(getToolsChecksum(responseData), serverToolsConfig?.cache)).then((refresh) => {
@@ -11823,7 +12007,9 @@ function useChatStorage(options) {
11823
12007
  data: responseData,
11824
12008
  error: null,
11825
12009
  userMessage: storedUserMessage,
11826
- assistantMessage: storedAssistantMessage
12010
+ assistantMessage: storedAssistantMessage,
12011
+ autoExecutedToolResults: autoToolResults,
12012
+ toolResultsMessage: storedToolResultsMessage
11827
12013
  };
11828
12014
  },
11829
12015
  [
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  recall
3
- } from "./chunk-PBCULYOW.mjs";
3
+ } from "./chunk-WYARTNEN.mjs";
4
4
  import "./chunk-ILAWDQDE.mjs";
5
5
  import "./chunk-GYKJOWEO.mjs";
6
6
  export {
@@ -4924,6 +4924,12 @@ async function embedMessage(ctx, messageId, options) {
4924
4924
  if (message.origin === NON_EMBEDDABLE_ORIGIN) {
4925
4925
  return message;
4926
4926
  }
4927
+ if (isEncrypted(message.content)) {
4928
+ getLogger().warn(
4929
+ `memoryEngine: message ${messageId} is still encrypted (key unavailable?) \u2014 not embedded`
4930
+ );
4931
+ return message;
4932
+ }
4927
4933
  const embedding = await generateEmbedding(message.content, options);
4928
4934
  const embeddingModel = options.model ?? DEFAULT_API_EMBEDDING_MODEL;
4929
4935
  return updateMessageEmbeddingOp(ctx, messageId, embedding, embeddingModel);
@@ -4931,11 +4937,17 @@ async function embedMessage(ctx, messageId, options) {
4931
4937
  async function embedAllMessages(ctx, options, filter) {
4932
4938
  const embeddingModel = options.model ?? DEFAULT_API_EMBEDDING_MODEL;
4933
4939
  let embeddedCount = 0;
4940
+ let stillEncrypted = 0;
4941
+ let considered = 0;
4942
+ let sealedRowsSeen = 0;
4943
+ let rowsSeen = 0;
4934
4944
  const conversations = await getConversationsOp(ctx);
4935
4945
  const targetConversations = filter?.conversationId ? conversations.filter((c) => c.conversationId === filter.conversationId) : conversations;
4936
4946
  for (const conv of targetConversations) {
4937
4947
  const messages = await getMessagesOp(ctx, conv.conversationId);
4938
4948
  for (const message of messages) {
4949
+ rowsSeen++;
4950
+ if (isEncrypted(message.content)) sealedRowsSeen++;
4939
4951
  if (message.vector && message.vector.length > 0) {
4940
4952
  continue;
4941
4953
  }
@@ -4948,6 +4960,11 @@ async function embedAllMessages(ctx, options, filter) {
4948
4960
  if (message.origin === NON_EMBEDDABLE_ORIGIN) {
4949
4961
  continue;
4950
4962
  }
4963
+ considered++;
4964
+ if (isEncrypted(message.content)) {
4965
+ stillEncrypted++;
4966
+ continue;
4967
+ }
4951
4968
  const minLength = filter?.minContentLength ?? DEFAULT_MIN_CONTENT_LENGTH;
4952
4969
  if (message.content.length < minLength) {
4953
4970
  continue;
@@ -4962,6 +4979,13 @@ async function embedAllMessages(ctx, options, filter) {
4962
4979
  }
4963
4980
  }
4964
4981
  }
4982
+ if (stillEncrypted > 0 || sealedRowsSeen > 0) {
4983
+ getLogger().error(
4984
+ "memoryEngine: messages still encrypted (key unavailable?) \u2014 excluded from embedding",
4985
+ void 0,
4986
+ { stillEncrypted, considered, sealedRowsSeen, rowsSeen }
4987
+ );
4988
+ }
4965
4989
  return embeddedCount;
4966
4990
  }
4967
4991
  async function chunkAndEmbedMessage(ctx, messageId, options) {
@@ -4976,6 +5000,12 @@ async function chunkAndEmbedMessage(ctx, messageId, options) {
4976
5000
  if (message.origin === NON_EMBEDDABLE_ORIGIN) {
4977
5001
  return message;
4978
5002
  }
5003
+ if (isEncrypted(message.content)) {
5004
+ getLogger().warn(
5005
+ `memoryEngine: message ${messageId} is still encrypted (key unavailable?) \u2014 not embedded`
5006
+ );
5007
+ return message;
5008
+ }
4979
5009
  const embeddingModel = options.model ?? DEFAULT_API_EMBEDDING_MODEL;
4980
5010
  if (!shouldChunkMessage(message.content, chunkSize)) {
4981
5011
  const embedding = await generateEmbedding(message.content, options);
@@ -5000,9 +5030,15 @@ async function chunkAndEmbedAllMessages(ctx, options, filter) {
5000
5030
  const targetConversations = filter?.conversationId ? conversations.filter((c) => c.conversationId === filter.conversationId) : conversations;
5001
5031
  const shortMessages = [];
5002
5032
  const longMessages = [];
5033
+ let stillEncrypted = 0;
5034
+ let considered = 0;
5035
+ let sealedRowsSeen = 0;
5036
+ let rowsSeen = 0;
5003
5037
  for (const conv of targetConversations) {
5004
5038
  const messages = await getMessagesOp(ctx, conv.conversationId);
5005
5039
  for (const message of messages) {
5040
+ rowsSeen++;
5041
+ if (isEncrypted(message.content)) sealedRowsSeen++;
5006
5042
  const isStale = message.embeddingModel !== void 0 && message.embeddingModel !== null && message.embeddingModel !== embeddingModel;
5007
5043
  if (message.chunks && message.chunks.length > 0 && !isStale) continue;
5008
5044
  const hasVector = message.vector && message.vector.length > 0;
@@ -5010,6 +5046,11 @@ async function chunkAndEmbedAllMessages(ctx, options, filter) {
5010
5046
  if (filter?.roles && !filter.roles.includes(message.role)) continue;
5011
5047
  if (message.role === "system") continue;
5012
5048
  if (message.origin === NON_EMBEDDABLE_ORIGIN) continue;
5049
+ considered++;
5050
+ if (isEncrypted(message.content)) {
5051
+ stillEncrypted++;
5052
+ continue;
5053
+ }
5013
5054
  if (message.content.length < minLength) continue;
5014
5055
  if (shouldChunkMessage(message.content, chunkSize)) {
5015
5056
  longMessages.push({
@@ -5021,6 +5062,13 @@ async function chunkAndEmbedAllMessages(ctx, options, filter) {
5021
5062
  }
5022
5063
  }
5023
5064
  }
5065
+ if (stillEncrypted > 0 || sealedRowsSeen > 0) {
5066
+ getLogger().error(
5067
+ "memoryEngine: messages still encrypted (key unavailable?) \u2014 excluded from embedding",
5068
+ void 0,
5069
+ { stillEncrypted, considered, sealedRowsSeen, rowsSeen }
5070
+ );
5071
+ }
5024
5072
  let embeddedCount = 0;
5025
5073
  if (shortMessages.length > 0) {
5026
5074
  try {
@@ -6801,7 +6849,7 @@ function createMemoryVaultSearchTool(vaultCtx, embeddingOptions, cache, searchOp
6801
6849
  subQueries = decomp.subQueries;
6802
6850
  }
6803
6851
  }
6804
- const { recall: recall2 } = await import("./recall-PCM7H5TA.mjs");
6852
+ const { recall: recall2 } = await import("./recall-2J2755WC.mjs");
6805
6853
  let recallDegraded = [];
6806
6854
  const result = await recall2(
6807
6855
  query,