@anuma/sdk 6.30.2 → 6.31.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.
@@ -14957,10 +14957,23 @@ var require_stepsForMigration = __commonJS({
14957
14957
  });
14958
14958
 
14959
14959
  // src/lib/logger.ts
14960
+ function getLoggerState() {
14961
+ try {
14962
+ return loggerGlobal[LOGGER_STATE_KEY] ?? (loggerGlobal[LOGGER_STATE_KEY] = fallbackLoggerState);
14963
+ } catch {
14964
+ if (!fallbackWarned) {
14965
+ fallbackWarned = true;
14966
+ fallbackLoggerState.logger.warn(
14967
+ "@anuma/sdk: the global object rejects new properties. This entrypoint keeps its own logger, so setLogger does not reach other entrypoints."
14968
+ );
14969
+ }
14970
+ return fallbackLoggerState;
14971
+ }
14972
+ }
14960
14973
  function getLogger() {
14961
- return currentLogger;
14974
+ return getLoggerState().logger;
14962
14975
  }
14963
- var consoleLogger, currentLogger;
14976
+ var consoleLogger, LOGGER_STATE_KEY, loggerGlobal, fallbackLoggerState, fallbackWarned;
14964
14977
  var init_logger = __esm({
14965
14978
  "src/lib/logger.ts"() {
14966
14979
  "use strict";
@@ -14970,7 +14983,10 @@ var init_logger = __esm({
14970
14983
  warn: console.warn.bind(console),
14971
14984
  error: console.error.bind(console)
14972
14985
  };
14973
- currentLogger = consoleLogger;
14986
+ LOGGER_STATE_KEY = /* @__PURE__ */ Symbol.for("@anuma/sdk/logger/v1");
14987
+ loggerGlobal = globalThis;
14988
+ fallbackLoggerState = { logger: consoleLogger };
14989
+ fallbackWarned = false;
14974
14990
  }
14975
14991
  });
14976
14992
 
@@ -20814,6 +20830,9 @@ async function updateMessageEmbeddingOp(ctx, uniqueId, vector, embeddingModel) {
20814
20830
  await ctx.database.write(async () => {
20815
20831
  await message.update((msg) => {
20816
20832
  msg._setRaw("vector", JSON.stringify(vector));
20833
+ if (msg.origin === "chunks_discarded" && vector.length > 0) {
20834
+ msg._setRaw("origin", "message");
20835
+ }
20817
20836
  msg._setRaw("embedding_model", embeddingModel);
20818
20837
  });
20819
20838
  });
@@ -20830,6 +20849,9 @@ async function updateMessageChunksOp(ctx, uniqueId, chunks, embeddingModel) {
20830
20849
  await ctx.database.write(async () => {
20831
20850
  await message.update((msg) => {
20832
20851
  msg._setRaw("chunks", JSON.stringify(storedChunks));
20852
+ if (msg.origin === "chunks_discarded" && storedChunks.length > 0 && storedChunks.every((chunk) => chunk.vector.length > 0)) {
20853
+ msg._setRaw("origin", "message");
20854
+ }
20833
20855
  msg._setRaw("embedding_model", embeddingModel);
20834
20856
  });
20835
20857
  });
@@ -22865,7 +22887,7 @@ async function getMemoriesNeedingTopicExtractionOp(ctx, options) {
22865
22887
  const id = raw.id;
22866
22888
  const topics = parseTopics(raw.topics);
22867
22889
  const linked = linkedNames.get(id);
22868
- if (topics !== null && topics.length > 0 && linksDivergeFromTopics(topics, linked ?? /* @__PURE__ */ new Set())) {
22890
+ if (topics !== null && linksDivergeFromTopics(topics, linked ?? /* @__PURE__ */ new Set())) {
22869
22891
  topicsToRelinkAll.push(id);
22870
22892
  continue;
22871
22893
  }
@@ -22959,18 +22981,20 @@ async function relinkMemoryTopicsOp(ctx, memoryIds) {
22959
22981
  }
22960
22982
  const relinked = [];
22961
22983
  for (const id of Array.from(new Set(memoryIds))) {
22962
- let record;
22963
- try {
22964
- record = await ctx.vaultMemoryCollection.find(id);
22965
- } catch {
22966
- continue;
22967
- }
22968
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) continue;
22969
- const topics = parseTopics(record.topics);
22970
- if (topics === null || topics.length === 0) continue;
22971
22984
  try {
22972
- await relinkMemoryEntitiesFromTopicsOp(entityCtx, id, topics);
22973
- relinked.push(id);
22985
+ await ctx.database.write(async (writer) => {
22986
+ let record;
22987
+ try {
22988
+ record = await ctx.vaultMemoryCollection.find(id);
22989
+ } catch {
22990
+ return;
22991
+ }
22992
+ if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) return;
22993
+ const topics = parseTopics(record.topics);
22994
+ if (topics === null) return;
22995
+ await writer.callWriter(() => relinkMemoryEntitiesFromTopicsOp(entityCtx, id, topics));
22996
+ relinked.push(id);
22997
+ });
22974
22998
  } catch (err) {
22975
22999
  getLogger().warn("[memory/topics] relink failed", err);
22976
23000
  }
@@ -35701,6 +35725,7 @@ function toolsToApiFormat(tools, apiType) {
35701
35725
  executor: _executor,
35702
35726
  skipContinuation: _skipContinuation,
35703
35727
  removeAfterExecution: _removeAfterExecution,
35728
+ removeAfterResult: _removeAfterResult,
35704
35729
  executorTimeout: _executorTimeout,
35705
35730
  dependsOn: _dependsOn,
35706
35731
  deAnonymizeArgs: _deAnonymizeArgs,
@@ -38145,9 +38170,11 @@ Executing tool: ${toolInfo}
38145
38170
  }
38146
38171
  if (tools && apiTools) {
38147
38172
  const successfullyExecutedNames = /* @__PURE__ */ new Set();
38173
+ const successfulResults = [];
38148
38174
  for (const r of executionResults) {
38149
38175
  if (!r.error && !isToolErrorResult(r.result) && "name" in r && r.name) {
38150
38176
  successfullyExecutedNames.add(r.name);
38177
+ successfulResults.push(r.result);
38151
38178
  }
38152
38179
  }
38153
38180
  if (successfullyExecutedNames.size > 0) {
@@ -38156,7 +38183,15 @@ Executing tool: ${toolInfo}
38156
38183
  const tc = t;
38157
38184
  const func = tc.function;
38158
38185
  const toolName2 = typeof func?.name === "string" ? func.name : typeof tc.name === "string" ? tc.name : void 0;
38159
- if (tc.removeAfterExecution === true && toolName2 && successfullyExecutedNames.has(toolName2)) {
38186
+ if (!toolName2) continue;
38187
+ const removeAfterResult = tc.removeAfterResult;
38188
+ if (tc.removeAfterExecution === true && successfullyExecutedNames.has(toolName2) || typeof removeAfterResult === "function" && successfulResults.some((result) => {
38189
+ try {
38190
+ return removeAfterResult(result);
38191
+ } catch {
38192
+ return false;
38193
+ }
38194
+ })) {
38160
38195
  toolsToRemove.add(toolName2);
38161
38196
  }
38162
38197
  }
@@ -2706,6 +2706,21 @@ type ToolConfig = LlmapiChatCompletionTool & {
2706
2706
  * execution fails, allowing the model to retry.
2707
2707
  */
2708
2708
  removeAfterExecution?: boolean;
2709
+ /**
2710
+ * Remove this tool for the rest of the turn once ANY tool returns a
2711
+ * successful result this predicate accepts — its own or another's. Errors
2712
+ * never count, as for `removeAfterExecution`.
2713
+ *
2714
+ * Only results of tools executed on this client are offered; tools the
2715
+ * portal runs server-side never reach the predicate. A predicate that throws
2716
+ * is treated as not matching.
2717
+ *
2718
+ * For a family of tools that has to leave together: when one of them
2719
+ * declines an out-of-scope request, the model otherwise works through its
2720
+ * siblings round after round until the round cap. Give every member the same
2721
+ * predicate and the first refusal removes the whole family.
2722
+ */
2723
+ removeAfterResult?: (result: unknown) => boolean;
2709
2724
  /**
2710
2725
  * Timeout in milliseconds for this tool's executor.
2711
2726
  * Overrides the default 30-second timeout.
@@ -3546,6 +3561,7 @@ type MessageFeedback = "like" | "dislike" | null;
3546
3561
  * - `tool_result`: the hidden `[Tool Execution Results]` row built from a
3547
3562
  * turn's auto-executed tool results. Skipped by the embedding sweep (see
3548
3563
  * `memoryEngine/embeddings`) AND hidden from the transcript.
3564
+ * - `message`: an ordinary message with an index after explicit repair.
3549
3565
  * - `chunks_discarded`: an ordinary, still-rendered message whose chunk vectors
3550
3566
  * were built over `enc:v3:` ciphertext (sdk#864) and have been discarded
3551
3567
  * rather than re-embedded at the user's own expense (client#5618). Skipped by
@@ -3558,7 +3574,7 @@ type MessageFeedback = "like" | "dislike" | null;
3558
3574
  * encrypted flag would be unreadable exactly where it matters and the skip
3559
3575
  * would fail open.
3560
3576
  */
3561
- type MessageOrigin = "tool_result" | "chunks_discarded";
3577
+ type MessageOrigin = "tool_result" | "chunks_discarded" | "message";
3562
3578
  /**
3563
3579
  * Metadata for files attached to messages.
3564
3580
  *
@@ -7120,7 +7136,8 @@ declare function stampTopicsExtractedAtOp(ctx: VaultMemoryOperationsContext, mem
7120
7136
  * `topics_user_managed` in particular is left exactly as it arrived, so the
7121
7137
  * autotagger stays off a curated memory whose links this just restored.
7122
7138
  *
7123
- * Skips deleted, foreign-user, and record-less rows. Returns the ids relinked.
7139
+ * Skips deleted rows, foreign-user rows, and rows with null topics.
7140
+ * Empty topics remove stale links. Returns the relinked IDs.
7124
7141
  */
7125
7142
  declare function relinkMemoryTopicsOp(ctx: VaultMemoryOperationsContext, memoryIds: readonly string[]): Promise<string[]>;
7126
7143
  /**
@@ -8096,9 +8113,8 @@ declare function embedAllMessages(ctx: StorageOperationsContext, options: Embedd
8096
8113
  * to an explicit user action, never to a background pass. Opens that marker
8097
8114
  * only — `tool_result` rows stay excluded.
8098
8115
  *
8099
- * Per call, not a state change: a row that re-indexes successfully keeps its
8100
- * marker, so a later pass that omits this flag skips it again. See
8101
- * {@link CHUNKS_DISCARDED_ORIGIN}.
8116
+ * A successful repair clears the marker. Later model migrations include
8117
+ * the repaired row without this flag. See {@link CHUNKS_DISCARDED_ORIGIN}.
8102
8118
  */
8103
8119
  reembedDiscarded?: boolean;
8104
8120
  }): Promise<number>;
@@ -8156,9 +8172,8 @@ declare function chunkAndEmbedAllMessages(ctx: StorageOperationsContext, options
8156
8172
  * chunks nor vector, so it never reaches that check and falls straight to the
8157
8173
  * origin gate.
8158
8174
  *
8159
- * Per call, not a state change: a row that re-indexes successfully keeps its
8160
- * marker, so a later pass that omits this flag skips it again. See
8161
- * {@link CHUNKS_DISCARDED_ORIGIN}.
8175
+ * A successful repair clears the marker. Later model migrations include
8176
+ * the repaired row without this flag. See {@link CHUNKS_DISCARDED_ORIGIN}.
8162
8177
  */
8163
8178
  reembedDiscarded?: boolean;
8164
8179
  }): Promise<number>;
@@ -2706,6 +2706,21 @@ type ToolConfig = LlmapiChatCompletionTool & {
2706
2706
  * execution fails, allowing the model to retry.
2707
2707
  */
2708
2708
  removeAfterExecution?: boolean;
2709
+ /**
2710
+ * Remove this tool for the rest of the turn once ANY tool returns a
2711
+ * successful result this predicate accepts — its own or another's. Errors
2712
+ * never count, as for `removeAfterExecution`.
2713
+ *
2714
+ * Only results of tools executed on this client are offered; tools the
2715
+ * portal runs server-side never reach the predicate. A predicate that throws
2716
+ * is treated as not matching.
2717
+ *
2718
+ * For a family of tools that has to leave together: when one of them
2719
+ * declines an out-of-scope request, the model otherwise works through its
2720
+ * siblings round after round until the round cap. Give every member the same
2721
+ * predicate and the first refusal removes the whole family.
2722
+ */
2723
+ removeAfterResult?: (result: unknown) => boolean;
2709
2724
  /**
2710
2725
  * Timeout in milliseconds for this tool's executor.
2711
2726
  * Overrides the default 30-second timeout.
@@ -3546,6 +3561,7 @@ type MessageFeedback = "like" | "dislike" | null;
3546
3561
  * - `tool_result`: the hidden `[Tool Execution Results]` row built from a
3547
3562
  * turn's auto-executed tool results. Skipped by the embedding sweep (see
3548
3563
  * `memoryEngine/embeddings`) AND hidden from the transcript.
3564
+ * - `message`: an ordinary message with an index after explicit repair.
3549
3565
  * - `chunks_discarded`: an ordinary, still-rendered message whose chunk vectors
3550
3566
  * were built over `enc:v3:` ciphertext (sdk#864) and have been discarded
3551
3567
  * rather than re-embedded at the user's own expense (client#5618). Skipped by
@@ -3558,7 +3574,7 @@ type MessageFeedback = "like" | "dislike" | null;
3558
3574
  * encrypted flag would be unreadable exactly where it matters and the skip
3559
3575
  * would fail open.
3560
3576
  */
3561
- type MessageOrigin = "tool_result" | "chunks_discarded";
3577
+ type MessageOrigin = "tool_result" | "chunks_discarded" | "message";
3562
3578
  /**
3563
3579
  * Metadata for files attached to messages.
3564
3580
  *
@@ -7120,7 +7136,8 @@ declare function stampTopicsExtractedAtOp(ctx: VaultMemoryOperationsContext, mem
7120
7136
  * `topics_user_managed` in particular is left exactly as it arrived, so the
7121
7137
  * autotagger stays off a curated memory whose links this just restored.
7122
7138
  *
7123
- * Skips deleted, foreign-user, and record-less rows. Returns the ids relinked.
7139
+ * Skips deleted rows, foreign-user rows, and rows with null topics.
7140
+ * Empty topics remove stale links. Returns the relinked IDs.
7124
7141
  */
7125
7142
  declare function relinkMemoryTopicsOp(ctx: VaultMemoryOperationsContext, memoryIds: readonly string[]): Promise<string[]>;
7126
7143
  /**
@@ -8096,9 +8113,8 @@ declare function embedAllMessages(ctx: StorageOperationsContext, options: Embedd
8096
8113
  * to an explicit user action, never to a background pass. Opens that marker
8097
8114
  * only — `tool_result` rows stay excluded.
8098
8115
  *
8099
- * Per call, not a state change: a row that re-indexes successfully keeps its
8100
- * marker, so a later pass that omits this flag skips it again. See
8101
- * {@link CHUNKS_DISCARDED_ORIGIN}.
8116
+ * A successful repair clears the marker. Later model migrations include
8117
+ * the repaired row without this flag. See {@link CHUNKS_DISCARDED_ORIGIN}.
8102
8118
  */
8103
8119
  reembedDiscarded?: boolean;
8104
8120
  }): Promise<number>;
@@ -8156,9 +8172,8 @@ declare function chunkAndEmbedAllMessages(ctx: StorageOperationsContext, options
8156
8172
  * chunks nor vector, so it never reaches that check and falls straight to the
8157
8173
  * origin gate.
8158
8174
  *
8159
- * Per call, not a state change: a row that re-indexes successfully keeps its
8160
- * marker, so a later pass that omits this flag skips it again. See
8161
- * {@link CHUNKS_DISCARDED_ORIGIN}.
8175
+ * A successful repair clears the marker. Later model migrations include
8176
+ * the repaired row without this flag. See {@link CHUNKS_DISCARDED_ORIGIN}.
8162
8177
  */
8163
8178
  reembedDiscarded?: boolean;
8164
8179
  }): Promise<number>;
@@ -13,7 +13,7 @@ import {
13
13
  taskTypeHeader,
14
14
  validateEndpointOverride,
15
15
  withInternalFlowMarker
16
- } from "./chunk-7GHESNOH.mjs";
16
+ } from "./chunk-KSYV7UO2.mjs";
17
17
  import {
18
18
  BASE_URL,
19
19
  __commonJS,
@@ -19108,6 +19108,9 @@ async function updateMessageEmbeddingOp(ctx, uniqueId, vector, embeddingModel) {
19108
19108
  await ctx.database.write(async () => {
19109
19109
  await message.update((msg) => {
19110
19110
  msg._setRaw("vector", JSON.stringify(vector));
19111
+ if (msg.origin === "chunks_discarded" && vector.length > 0) {
19112
+ msg._setRaw("origin", "message");
19113
+ }
19111
19114
  msg._setRaw("embedding_model", embeddingModel);
19112
19115
  });
19113
19116
  });
@@ -19124,6 +19127,9 @@ async function updateMessageChunksOp(ctx, uniqueId, chunks, embeddingModel) {
19124
19127
  await ctx.database.write(async () => {
19125
19128
  await message.update((msg) => {
19126
19129
  msg._setRaw("chunks", JSON.stringify(storedChunks));
19130
+ if (msg.origin === "chunks_discarded" && storedChunks.length > 0 && storedChunks.every((chunk) => chunk.vector.length > 0)) {
19131
+ msg._setRaw("origin", "message");
19132
+ }
19127
19133
  msg._setRaw("embedding_model", embeddingModel);
19128
19134
  });
19129
19135
  });
@@ -21153,7 +21159,7 @@ async function getMemoriesNeedingTopicExtractionOp(ctx, options) {
21153
21159
  const id = raw.id;
21154
21160
  const topics = parseTopics(raw.topics);
21155
21161
  const linked = linkedNames.get(id);
21156
- if (topics !== null && topics.length > 0 && linksDivergeFromTopics(topics, linked ?? /* @__PURE__ */ new Set())) {
21162
+ if (topics !== null && linksDivergeFromTopics(topics, linked ?? /* @__PURE__ */ new Set())) {
21157
21163
  topicsToRelinkAll.push(id);
21158
21164
  continue;
21159
21165
  }
@@ -21247,18 +21253,20 @@ async function relinkMemoryTopicsOp(ctx, memoryIds) {
21247
21253
  }
21248
21254
  const relinked = [];
21249
21255
  for (const id of Array.from(new Set(memoryIds))) {
21250
- let record;
21251
21256
  try {
21252
- record = await ctx.vaultMemoryCollection.find(id);
21253
- } catch {
21254
- continue;
21255
- }
21256
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) continue;
21257
- const topics = parseTopics(record.topics);
21258
- if (topics === null || topics.length === 0) continue;
21259
- try {
21260
- await relinkMemoryEntitiesFromTopicsOp(entityCtx, id, topics);
21261
- relinked.push(id);
21257
+ await ctx.database.write(async (writer) => {
21258
+ let record;
21259
+ try {
21260
+ record = await ctx.vaultMemoryCollection.find(id);
21261
+ } catch {
21262
+ return;
21263
+ }
21264
+ if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) return;
21265
+ const topics = parseTopics(record.topics);
21266
+ if (topics === null) return;
21267
+ await writer.callWriter(() => relinkMemoryEntitiesFromTopicsOp(entityCtx, id, topics));
21268
+ relinked.push(id);
21269
+ });
21262
21270
  } catch (err) {
21263
21271
  getLogger().warn("[memory/topics] relink failed", err);
21264
21272
  }
@@ -28020,7 +28028,7 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
28020
28028
  content: m.content,
28021
28029
  similarity: m.similarity
28022
28030
  }));
28023
- const { consolidateMemory: doConsolidate } = await import("./consolidate-3RNRDM75.mjs");
28031
+ const { consolidateMemory: doConsolidate } = await import("./consolidate-MCNBSUXD.mjs");
28024
28032
  const decision = await doConsolidate(trimmed, candidates, consolidateOptions);
28025
28033
  if (decision.action === "create") return decision.fallbackReason ? null : { create: true };
28026
28034
  if (decision.action === "supersede" && decision.content) {
@@ -33920,6 +33928,7 @@ function toolsToApiFormat(tools, apiType) {
33920
33928
  executor: _executor,
33921
33929
  skipContinuation: _skipContinuation,
33922
33930
  removeAfterExecution: _removeAfterExecution,
33931
+ removeAfterResult: _removeAfterResult,
33923
33932
  executorTimeout: _executorTimeout,
33924
33933
  dependsOn: _dependsOn,
33925
33934
  deAnonymizeArgs: _deAnonymizeArgs,
@@ -36364,9 +36373,11 @@ Executing tool: ${toolInfo}
36364
36373
  }
36365
36374
  if (tools && apiTools) {
36366
36375
  const successfullyExecutedNames = /* @__PURE__ */ new Set();
36376
+ const successfulResults = [];
36367
36377
  for (const r of executionResults) {
36368
36378
  if (!r.error && !isToolErrorResult(r.result) && "name" in r && r.name) {
36369
36379
  successfullyExecutedNames.add(r.name);
36380
+ successfulResults.push(r.result);
36370
36381
  }
36371
36382
  }
36372
36383
  if (successfullyExecutedNames.size > 0) {
@@ -36375,7 +36386,15 @@ Executing tool: ${toolInfo}
36375
36386
  const tc = t;
36376
36387
  const func = tc.function;
36377
36388
  const toolName2 = typeof func?.name === "string" ? func.name : typeof tc.name === "string" ? tc.name : void 0;
36378
- if (tc.removeAfterExecution === true && toolName2 && successfullyExecutedNames.has(toolName2)) {
36389
+ if (!toolName2) continue;
36390
+ const removeAfterResult = tc.removeAfterResult;
36391
+ if (tc.removeAfterExecution === true && successfullyExecutedNames.has(toolName2) || typeof removeAfterResult === "function" && successfulResults.some((result) => {
36392
+ try {
36393
+ return removeAfterResult(result);
36394
+ } catch {
36395
+ return false;
36396
+ }
36397
+ })) {
36379
36398
  toolsToRemove.add(toolName2);
36380
36399
  }
36381
36400
  }
@@ -1170,9 +1170,25 @@ var consoleLogger = {
1170
1170
  warn: console.warn.bind(console),
1171
1171
  error: console.error.bind(console)
1172
1172
  };
1173
- var currentLogger = consoleLogger;
1173
+ var LOGGER_STATE_KEY = /* @__PURE__ */ Symbol.for("@anuma/sdk/logger/v1");
1174
+ var loggerGlobal = globalThis;
1175
+ var fallbackLoggerState = { logger: consoleLogger };
1176
+ var fallbackWarned = false;
1177
+ function getLoggerState() {
1178
+ try {
1179
+ return loggerGlobal[LOGGER_STATE_KEY] ?? (loggerGlobal[LOGGER_STATE_KEY] = fallbackLoggerState);
1180
+ } catch {
1181
+ if (!fallbackWarned) {
1182
+ fallbackWarned = true;
1183
+ fallbackLoggerState.logger.warn(
1184
+ "@anuma/sdk: the global object rejects new properties. This entrypoint keeps its own logger, so setLogger does not reach other entrypoints."
1185
+ );
1186
+ }
1187
+ return fallbackLoggerState;
1188
+ }
1189
+ }
1174
1190
  function getLogger() {
1175
- return currentLogger;
1191
+ return getLoggerState().logger;
1176
1192
  }
1177
1193
 
1178
1194
  // src/tools/googleDrive.ts
@@ -40,6 +40,21 @@ type ToolConfig = LlmapiChatCompletionTool & {
40
40
  * execution fails, allowing the model to retry.
41
41
  */
42
42
  removeAfterExecution?: boolean;
43
+ /**
44
+ * Remove this tool for the rest of the turn once ANY tool returns a
45
+ * successful result this predicate accepts — its own or another's. Errors
46
+ * never count, as for `removeAfterExecution`.
47
+ *
48
+ * Only results of tools executed on this client are offered; tools the
49
+ * portal runs server-side never reach the predicate. A predicate that throws
50
+ * is treated as not matching.
51
+ *
52
+ * For a family of tools that has to leave together: when one of them
53
+ * declines an out-of-scope request, the model otherwise works through its
54
+ * siblings round after round until the round cap. Give every member the same
55
+ * predicate and the first refusal removes the whole family.
56
+ */
57
+ removeAfterResult?: (result: unknown) => boolean;
43
58
  /**
44
59
  * Timeout in milliseconds for this tool's executor.
45
60
  * Overrides the default 30-second timeout.
@@ -40,6 +40,21 @@ type ToolConfig = LlmapiChatCompletionTool & {
40
40
  * execution fails, allowing the model to retry.
41
41
  */
42
42
  removeAfterExecution?: boolean;
43
+ /**
44
+ * Remove this tool for the rest of the turn once ANY tool returns a
45
+ * successful result this predicate accepts — its own or another's. Errors
46
+ * never count, as for `removeAfterExecution`.
47
+ *
48
+ * Only results of tools executed on this client are offered; tools the
49
+ * portal runs server-side never reach the predicate. A predicate that throws
50
+ * is treated as not matching.
51
+ *
52
+ * For a family of tools that has to leave together: when one of them
53
+ * declines an out-of-scope request, the model otherwise works through its
54
+ * siblings round after round until the round cap. Give every member the same
55
+ * predicate and the first refusal removes the whole family.
56
+ */
57
+ removeAfterResult?: (result: unknown) => boolean;
43
58
  /**
44
59
  * Timeout in milliseconds for this tool's executor.
45
60
  * Overrides the default 30-second timeout.
@@ -1014,9 +1014,25 @@ var consoleLogger = {
1014
1014
  warn: console.warn.bind(console),
1015
1015
  error: console.error.bind(console)
1016
1016
  };
1017
- var currentLogger = consoleLogger;
1017
+ var LOGGER_STATE_KEY = /* @__PURE__ */ Symbol.for("@anuma/sdk/logger/v1");
1018
+ var loggerGlobal = globalThis;
1019
+ var fallbackLoggerState = { logger: consoleLogger };
1020
+ var fallbackWarned = false;
1021
+ function getLoggerState() {
1022
+ try {
1023
+ return loggerGlobal[LOGGER_STATE_KEY] ?? (loggerGlobal[LOGGER_STATE_KEY] = fallbackLoggerState);
1024
+ } catch {
1025
+ if (!fallbackWarned) {
1026
+ fallbackWarned = true;
1027
+ fallbackLoggerState.logger.warn(
1028
+ "@anuma/sdk: the global object rejects new properties. This entrypoint keeps its own logger, so setLogger does not reach other entrypoints."
1029
+ );
1030
+ }
1031
+ return fallbackLoggerState;
1032
+ }
1033
+ }
1018
1034
  function getLogger() {
1019
- return currentLogger;
1035
+ return getLoggerState().logger;
1020
1036
  }
1021
1037
 
1022
1038
  // src/tools/googleDrive.ts
@@ -1270,9 +1270,25 @@ var consoleLogger = {
1270
1270
  warn: console.warn.bind(console),
1271
1271
  error: console.error.bind(console)
1272
1272
  };
1273
- var currentLogger = consoleLogger;
1273
+ var LOGGER_STATE_KEY = /* @__PURE__ */ Symbol.for("@anuma/sdk/logger/v1");
1274
+ var loggerGlobal = globalThis;
1275
+ var fallbackLoggerState = { logger: consoleLogger };
1276
+ var fallbackWarned = false;
1277
+ function getLoggerState() {
1278
+ try {
1279
+ return loggerGlobal[LOGGER_STATE_KEY] ?? (loggerGlobal[LOGGER_STATE_KEY] = fallbackLoggerState);
1280
+ } catch {
1281
+ if (!fallbackWarned) {
1282
+ fallbackWarned = true;
1283
+ fallbackLoggerState.logger.warn(
1284
+ "@anuma/sdk: the global object rejects new properties. This entrypoint keeps its own logger, so setLogger does not reach other entrypoints."
1285
+ );
1286
+ }
1287
+ return fallbackLoggerState;
1288
+ }
1289
+ }
1274
1290
  function getLogger() {
1275
- return currentLogger;
1291
+ return getLoggerState().logger;
1276
1292
  }
1277
1293
 
1278
1294
  // src/lib/memoryEngine/chunking.ts
@@ -1662,6 +1678,9 @@ function clientToolToResponsesFormat(tool) {
1662
1678
  ...toolConfig.removeAfterExecution !== void 0 && {
1663
1679
  removeAfterExecution: toolConfig.removeAfterExecution
1664
1680
  },
1681
+ ...toolConfig.removeAfterResult !== void 0 && {
1682
+ removeAfterResult: toolConfig.removeAfterResult
1683
+ },
1665
1684
  ...toolConfig.executorTimeout !== void 0 && {
1666
1685
  executorTimeout: toolConfig.executorTimeout
1667
1686
  },
@@ -1695,6 +1714,9 @@ function clientToolToCompletionsFormat(tool) {
1695
1714
  ...toolConfig.removeAfterExecution !== void 0 && {
1696
1715
  removeAfterExecution: toolConfig.removeAfterExecution
1697
1716
  },
1717
+ ...toolConfig.removeAfterResult !== void 0 && {
1718
+ removeAfterResult: toolConfig.removeAfterResult
1719
+ },
1698
1720
  ...toolConfig.executorTimeout !== void 0 && {
1699
1721
  executorTimeout: toolConfig.executorTimeout
1700
1722
  },
@@ -32,6 +32,21 @@ type ToolConfig = LlmapiChatCompletionTool & {
32
32
  * execution fails, allowing the model to retry.
33
33
  */
34
34
  removeAfterExecution?: boolean;
35
+ /**
36
+ * Remove this tool for the rest of the turn once ANY tool returns a
37
+ * successful result this predicate accepts — its own or another's. Errors
38
+ * never count, as for `removeAfterExecution`.
39
+ *
40
+ * Only results of tools executed on this client are offered; tools the
41
+ * portal runs server-side never reach the predicate. A predicate that throws
42
+ * is treated as not matching.
43
+ *
44
+ * For a family of tools that has to leave together: when one of them
45
+ * declines an out-of-scope request, the model otherwise works through its
46
+ * siblings round after round until the round cap. Give every member the same
47
+ * predicate and the first refusal removes the whole family.
48
+ */
49
+ removeAfterResult?: (result: unknown) => boolean;
35
50
  /**
36
51
  * Timeout in milliseconds for this tool's executor.
37
52
  * Overrides the default 30-second timeout.
@@ -32,6 +32,21 @@ type ToolConfig = LlmapiChatCompletionTool & {
32
32
  * execution fails, allowing the model to retry.
33
33
  */
34
34
  removeAfterExecution?: boolean;
35
+ /**
36
+ * Remove this tool for the rest of the turn once ANY tool returns a
37
+ * successful result this predicate accepts — its own or another's. Errors
38
+ * never count, as for `removeAfterExecution`.
39
+ *
40
+ * Only results of tools executed on this client are offered; tools the
41
+ * portal runs server-side never reach the predicate. A predicate that throws
42
+ * is treated as not matching.
43
+ *
44
+ * For a family of tools that has to leave together: when one of them
45
+ * declines an out-of-scope request, the model otherwise works through its
46
+ * siblings round after round until the round cap. Give every member the same
47
+ * predicate and the first refusal removes the whole family.
48
+ */
49
+ removeAfterResult?: (result: unknown) => boolean;
35
50
  /**
36
51
  * Timeout in milliseconds for this tool's executor.
37
52
  * Overrides the default 30-second timeout.
@@ -1148,9 +1148,25 @@ var consoleLogger = {
1148
1148
  warn: console.warn.bind(console),
1149
1149
  error: console.error.bind(console)
1150
1150
  };
1151
- var currentLogger = consoleLogger;
1151
+ var LOGGER_STATE_KEY = /* @__PURE__ */ Symbol.for("@anuma/sdk/logger/v1");
1152
+ var loggerGlobal = globalThis;
1153
+ var fallbackLoggerState = { logger: consoleLogger };
1154
+ var fallbackWarned = false;
1155
+ function getLoggerState() {
1156
+ try {
1157
+ return loggerGlobal[LOGGER_STATE_KEY] ?? (loggerGlobal[LOGGER_STATE_KEY] = fallbackLoggerState);
1158
+ } catch {
1159
+ if (!fallbackWarned) {
1160
+ fallbackWarned = true;
1161
+ fallbackLoggerState.logger.warn(
1162
+ "@anuma/sdk: the global object rejects new properties. This entrypoint keeps its own logger, so setLogger does not reach other entrypoints."
1163
+ );
1164
+ }
1165
+ return fallbackLoggerState;
1166
+ }
1167
+ }
1152
1168
  function getLogger() {
1153
- return currentLogger;
1169
+ return getLoggerState().logger;
1154
1170
  }
1155
1171
 
1156
1172
  // src/lib/memoryEngine/chunking.ts
@@ -1540,6 +1556,9 @@ function clientToolToResponsesFormat(tool) {
1540
1556
  ...toolConfig.removeAfterExecution !== void 0 && {
1541
1557
  removeAfterExecution: toolConfig.removeAfterExecution
1542
1558
  },
1559
+ ...toolConfig.removeAfterResult !== void 0 && {
1560
+ removeAfterResult: toolConfig.removeAfterResult
1561
+ },
1543
1562
  ...toolConfig.executorTimeout !== void 0 && {
1544
1563
  executorTimeout: toolConfig.executorTimeout
1545
1564
  },
@@ -1573,6 +1592,9 @@ function clientToolToCompletionsFormat(tool) {
1573
1592
  ...toolConfig.removeAfterExecution !== void 0 && {
1574
1593
  removeAfterExecution: toolConfig.removeAfterExecution
1575
1594
  },
1595
+ ...toolConfig.removeAfterResult !== void 0 && {
1596
+ removeAfterResult: toolConfig.removeAfterResult
1597
+ },
1576
1598
  ...toolConfig.executorTimeout !== void 0 && {
1577
1599
  executorTimeout: toolConfig.executorTimeout
1578
1600
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anuma/sdk",
3
- "version": "6.30.2",
3
+ "version": "6.31.0",
4
4
  "description": "",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.mjs",
@@ -154,7 +154,7 @@
154
154
  "check:excluded-suites": "node scripts/assert-excluded-suites-still-fail.mjs",
155
155
  "knip": "knip",
156
156
  "check:export-consumers": "node scripts/assert-export-consumers.mjs",
157
- "check-exports": "publint && attw --pack --ignore-rules no-resolution false-cjs && node scripts/assert-no-client-self-import.mjs",
157
+ "check-exports": "publint && attw --pack --ignore-rules no-resolution false-cjs && node scripts/assert-no-client-self-import.mjs && node scripts/assert-shared-logger.mjs",
158
158
  "check": "pnpm run lint && pnpm run knip && pnpm run check:export-consumers && pnpm run format && pnpm run generate",
159
159
  "eval:extraction": "tsx test/memory/src/extraction/benchmark.test.ts",
160
160
  "eval:topic": "tsx test/memory/src/topic/benchmark.ts",