@genesislcap/ai-assistant 15.5.0 → 15.6.1-ts7-migration.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.
Files changed (64) hide show
  1. package/dist/ai-assistant.api.json +45 -2
  2. package/dist/ai-assistant.d.ts +14 -2
  3. package/dist/chat-driver.cjs +45 -24
  4. package/dist/chat-driver.cjs.map +2 -2
  5. package/dist/chat-driver.mjs +45 -24
  6. package/dist/chat-driver.mjs.map +2 -2
  7. package/dist/custom-elements.json +11 -0
  8. package/dist/dts/channel/ai-activity-bus.d.ts.map +1 -1
  9. package/dist/dts/components/activity-halo/activity-halo.d.ts.map +1 -1
  10. package/dist/dts/components/agent-picker/agent-picker.d.ts.map +1 -1
  11. package/dist/dts/components/agent-picker/agent-picker.template.d.ts.map +1 -1
  12. package/dist/dts/components/chat-bubble/chat-bubble.d.ts.map +1 -1
  13. package/dist/dts/components/chat-driver/chat-driver.d.ts +12 -0
  14. package/dist/dts/components/chat-driver/chat-driver.d.ts.map +1 -1
  15. package/dist/dts/components/chat-interaction-wrapper/chat-interaction-wrapper.d.ts.map +1 -1
  16. package/dist/dts/components/chat-markdown/chat-markdown.d.ts.map +1 -1
  17. package/dist/dts/components/flowing-waves-indicator.d.ts.map +1 -1
  18. package/dist/dts/components/halo-overlay.d.ts.map +1 -1
  19. package/dist/dts/components/orchestrating-driver/orchestrating-driver.d.ts.map +1 -1
  20. package/dist/dts/components/popout-manager/popout-manager.d.ts.map +1 -1
  21. package/dist/dts/components/settings-modal/settings-modal.template.d.ts.map +1 -1
  22. package/dist/dts/components/waves-indicator.d.ts.map +1 -1
  23. package/dist/dts/main/main.d.ts.map +1 -1
  24. package/dist/dts/main/main.template.d.ts.map +1 -1
  25. package/dist/dts/main/main.types.d.ts +2 -2
  26. package/dist/dts/main/main.types.d.ts.map +1 -1
  27. package/dist/dts/state/ai-assistant-slice.d.ts +1 -1
  28. package/dist/dts/state/persistence/session-persistence-provider.d.ts.map +1 -1
  29. package/dist/dts/state/persistence/session-persister.d.ts.map +1 -1
  30. package/dist/dts/state/session-store.d.ts +1 -1
  31. package/dist/dts/suggestions/chat-suggestions.d.ts.map +1 -1
  32. package/dist/dts/utils/animated-panel-toggle.d.ts.map +1 -1
  33. package/dist/dts/utils/condense-history.d.ts +18 -0
  34. package/dist/dts/utils/condense-history.d.ts.map +1 -1
  35. package/dist/dts/utils/message-partition.d.ts.map +1 -1
  36. package/dist/esm/components/agent-picker/agent-picker.js +2 -1
  37. package/dist/esm/components/agent-picker/agent-picker.template.js +2 -2
  38. package/dist/esm/components/chat-bubble/chat-bubble.js +2 -1
  39. package/dist/esm/components/chat-driver/align-event-globals.js +1 -0
  40. package/dist/esm/components/chat-driver/chat-driver.js +32 -29
  41. package/dist/esm/components/chat-driver/chat-driver.test.js +7 -13
  42. package/dist/esm/components/orchestrating-driver/orchestrating-driver.js +5 -5
  43. package/dist/esm/components/popout-manager/popout-manager.js +4 -1
  44. package/dist/esm/components/settings-modal/settings-modal.template.js +5 -8
  45. package/dist/esm/main/main.js +129 -91
  46. package/dist/esm/main/main.template.js +10 -16
  47. package/dist/esm/state/debug-event-log.js +2 -1
  48. package/dist/esm/state/persistence/session-persister.js +13 -10
  49. package/dist/esm/state/persistence/session-snapshot.js +3 -2
  50. package/dist/esm/utils/collect-session-models.test.js +2 -1
  51. package/dist/esm/utils/condense-history.js +34 -4
  52. package/dist/esm/utils/condense-history.test.js +110 -19
  53. package/dist/esm/utils/flatten-sub-agent-messages.js +4 -3
  54. package/dist/esm/utils/history-transform.js +2 -1
  55. package/dist/esm/utils/resolve-cost-history-config.js +4 -3
  56. package/dist/esm/utils/resolve-preference-baseline.js +2 -1
  57. package/dist/esm/utils/sum-usage.js +7 -6
  58. package/dist/tsconfig.tsbuildinfo +1 -1
  59. package/dist/tsdoc-metadata.json +1 -1
  60. package/package.json +17 -17
  61. package/src/components/chat-driver/chat-driver.ts +15 -0
  62. package/src/utils/condense-history.test.ts +166 -0
  63. package/src/utils/condense-history.ts +56 -3
  64. package/tsconfig.json +2 -1
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "metadata": {
3
3
  "toolPackage": "@microsoft/api-extractor",
4
- "toolVersion": "7.52.10",
4
+ "toolVersion": "7.58.12",
5
5
  "schemaVersion": 1011,
6
6
  "oldestForwardsCompatibleVersion": 1001,
7
7
  "tsdocConfig": {
@@ -114,6 +114,22 @@
114
114
  "tagName": "@virtual",
115
115
  "syntaxKind": "modifier"
116
116
  },
117
+ {
118
+ "tagName": "@jsx",
119
+ "syntaxKind": "block"
120
+ },
121
+ {
122
+ "tagName": "@jsxRuntime",
123
+ "syntaxKind": "block"
124
+ },
125
+ {
126
+ "tagName": "@jsxFrag",
127
+ "syntaxKind": "block"
128
+ },
129
+ {
130
+ "tagName": "@jsxImportSource",
131
+ "syntaxKind": "block"
132
+ },
117
133
  {
118
134
  "tagName": "@betaDocumentation",
119
135
  "syntaxKind": "modifier"
@@ -2065,7 +2081,7 @@
2065
2081
  },
2066
2082
  {
2067
2083
  "kind": "Content",
2068
- "text": "{\n readonly SessionCleared: \"session-cleared\";\n readonly ChatHeaderMouseDown: \"chat-header-mousedown\";\n}"
2084
+ "text": "{\n readonly SessionCleared: 'session-cleared';\n readonly ChatHeaderMouseDown: 'chat-header-mousedown';\n}"
2069
2085
  }
2070
2086
  ],
2071
2087
  "fileUrlPath": "src/main/main.types.ts",
@@ -5662,6 +5678,33 @@
5662
5678
  "endIndex": 2
5663
5679
  }
5664
5680
  },
5681
+ {
5682
+ "kind": "PropertySignature",
5683
+ "canonicalReference": "@genesislcap/ai-assistant!ChatDriverConfig#condenseBatchCalls:member",
5684
+ "docComment": "/**\n * Collapse `condenseWhen` payloads in batches of this many model-calls rather than as soon as each trigger fires. A positive integer; decimals are floored and anything below `1` becomes `1`. Default `1` — collapse immediately, the historical behaviour.\n *\n * Condensation rewrites history in place, so collapsing continuously breaks the provider's prompt cache on nearly every call of a re-read loop. Raising this trades up to that many calls' worth of extra context for one cache break per batch.\n */\n",
5685
+ "excerptTokens": [
5686
+ {
5687
+ "kind": "Content",
5688
+ "text": "condenseBatchCalls?: "
5689
+ },
5690
+ {
5691
+ "kind": "Content",
5692
+ "text": "number"
5693
+ },
5694
+ {
5695
+ "kind": "Content",
5696
+ "text": ";"
5697
+ }
5698
+ ],
5699
+ "isReadonly": false,
5700
+ "isOptional": true,
5701
+ "releaseTag": "Beta",
5702
+ "name": "condenseBatchCalls",
5703
+ "propertyTypeTokenRange": {
5704
+ "startIndex": 1,
5705
+ "endIndex": 2
5706
+ }
5707
+ },
5665
5708
  {
5666
5709
  "kind": "PropertySignature",
5667
5710
  "canonicalReference": "@genesislcap/ai-assistant!ChatDriverConfig#maxFoldOperations:member",
@@ -405,9 +405,9 @@ export declare interface AiAssistantAnimationDef {
405
405
  */
406
406
  export declare const AiAssistantEvent: {
407
407
  /** Session wiped via the lifecycle menu's Clear. `detail`: `SessionClearedDetail`. */
408
- readonly SessionCleared: "session-cleared";
408
+ readonly SessionCleared: 'session-cleared';
409
409
  /** Header pressed in `popout-mode="expand"` (drag-to-popout hosts). `detail`: `ChatHeaderMouseDownDetail`. */
410
- readonly ChatHeaderMouseDown: "chat-header-mousedown";
410
+ readonly ChatHeaderMouseDown: 'chat-header-mousedown';
411
411
  };
412
412
 
413
413
  /**
@@ -1377,6 +1377,8 @@ export declare class ChatDriver extends EventTarget implements AiDriver {
1377
1377
  private unsubscribeRegistry?;
1378
1378
  /** Hard cap on tool-loop iterations. */
1379
1379
  private readonly maxToolIterations;
1380
+ /** Model-calls per condensation batch; `1` collapses as soon as a trigger fires. */
1381
+ private readonly condenseBatchCalls;
1380
1382
  /** Session identity used to file meta events onto the shared debug-log timeline. */
1381
1383
  private readonly sessionKey;
1382
1384
  /** Injected activity bus; defaults to a no-op off-browser (Node/tests/headless). */
@@ -1713,6 +1715,16 @@ export declare interface ChatDriverConfig {
1713
1715
  maxToolIterations?: number;
1714
1716
  /** Hard cap on fold operations. Default `5`. */
1715
1717
  maxFoldOperations?: number;
1718
+ /**
1719
+ * Collapse `condenseWhen` payloads in batches of this many model-calls rather than as
1720
+ * soon as each trigger fires. A positive integer; decimals are floored and anything
1721
+ * below `1` becomes `1`. Default `1` — collapse immediately, the historical behaviour.
1722
+ *
1723
+ * Condensation rewrites history in place, so collapsing continuously breaks the
1724
+ * provider's prompt cache on nearly every call of a re-read loop. Raising this trades
1725
+ * up to that many calls' worth of extra context for one cache break per batch.
1726
+ */
1727
+ condenseBatchCalls?: number;
1716
1728
  /** Ring-buffer size for per-turn snapshots. Default `400`. */
1717
1729
  maxTurnSnapshots?: number;
1718
1730
  /** Session identity used to file meta events onto the shared debug-log timeline. */
@@ -1149,7 +1149,8 @@ function readFramedBody(stream, onChunk, vendorLabel, stallTimeout) {
1149
1149
  var MAX_RETRIES = 5;
1150
1150
  function postWithRetry(options) {
1151
1151
  return __awaiter(this, void 0, void 0, function* () {
1152
- var _a, _b, _c, _d;
1152
+ var _a, _b;
1153
+ var _c, _d;
1153
1154
  const { url, headers, body, credentials, vendorLabel, retryableStatuses, timeout, stallTimeout, backoffBaseMs, signal } = options;
1154
1155
  const backoff = (attempt) => abortableDelay(backoffBaseMs * (1 << attempt), signal);
1155
1156
  for (let attempt = 0; attempt <= MAX_RETRIES; attempt += 1) {
@@ -1504,7 +1505,8 @@ var AnthropicTransport = class _AnthropicTransport {
1504
1505
  * the payload tidy.
1505
1506
  */
1506
1507
  toAnthropicMessages(history, userMessage, attachments) {
1507
- var _a, _b, _c;
1508
+ var _a, _b;
1509
+ var _c;
1508
1510
  const messages = [];
1509
1511
  const pushBlock = (role, block) => {
1510
1512
  const last = messages[messages.length - 1];
@@ -1534,13 +1536,13 @@ var AnthropicTransport = class _AnthropicTransport {
1534
1536
  type: "tool_use",
1535
1537
  id: tc.id,
1536
1538
  name: tc.name,
1537
- input: (_b = tc.args) !== null && _b !== void 0 ? _b : {}
1539
+ input: (_c = tc.args) !== null && _c !== void 0 ? _c : {}
1538
1540
  });
1539
1541
  }
1540
1542
  continue;
1541
1543
  }
1542
1544
  const role = msg.role === "user" ? "user" : "assistant";
1543
- if (role === "user" && ((_c = msg.attachments) === null || _c === void 0 ? void 0 : _c.length)) {
1545
+ if (role === "user" && ((_b = msg.attachments) === null || _b === void 0 ? void 0 : _b.length)) {
1544
1546
  pushBlock(role, { type: "text", text: msg.content });
1545
1547
  for (const att of msg.attachments) {
1546
1548
  pushBlock(role, { type: "text", text: `[File: ${att.name}]
@@ -2016,7 +2018,8 @@ var GeminiTransport = class _GeminiTransport {
2016
2018
  // ── ChatTransport (multi-turn chat) ────────────────────────────────────
2017
2019
  sendChatMessage(history, userMessage, options) {
2018
2020
  return __awaiter(this, void 0, void 0, function* () {
2019
- var _a, _b;
2021
+ var _a;
2022
+ var _b;
2020
2023
  const contents = this.toGeminiContents(history, userMessage, options === null || options === void 0 ? void 0 : options.attachments);
2021
2024
  if (options === null || options === void 0 ? void 0 : options.tailContext) {
2022
2025
  contents.push({ role: "user", parts: [{ text: options.tailContext }] });
@@ -2080,7 +2083,8 @@ var GeminiTransport = class _GeminiTransport {
2080
2083
  return totalCost;
2081
2084
  }
2082
2085
  toGeminiContents(history, userMessage, attachments) {
2083
- var _a, _b, _c;
2086
+ var _a, _b;
2087
+ var _c;
2084
2088
  const contents = [];
2085
2089
  const toolCallNameById = /* @__PURE__ */ new Map();
2086
2090
  for (const msg of history) {
@@ -2088,7 +2092,7 @@ var GeminiTransport = class _GeminiTransport {
2088
2092
  continue;
2089
2093
  const role = msg.role === "user" ? "user" : "model";
2090
2094
  if (msg.toolResult) {
2091
- const fnName = (_a = toolCallNameById.get(msg.toolResult.toolCallId)) !== null && _a !== void 0 ? _a : msg.toolResult.toolCallId;
2095
+ const fnName = (_c = toolCallNameById.get(msg.toolResult.toolCallId)) !== null && _c !== void 0 ? _c : msg.toolResult.toolCallId;
2092
2096
  contents.push({
2093
2097
  role: "user",
2094
2098
  parts: [
@@ -2100,7 +2104,7 @@ var GeminiTransport = class _GeminiTransport {
2100
2104
  }
2101
2105
  ]
2102
2106
  });
2103
- } else if ((_b = msg.toolCalls) === null || _b === void 0 ? void 0 : _b.length) {
2107
+ } else if ((_a = msg.toolCalls) === null || _a === void 0 ? void 0 : _a.length) {
2104
2108
  for (const tc of msg.toolCalls) {
2105
2109
  toolCallNameById.set(tc.id, tc.name);
2106
2110
  }
@@ -2119,7 +2123,7 @@ var GeminiTransport = class _GeminiTransport {
2119
2123
  return part;
2120
2124
  })
2121
2125
  });
2122
- } else if (role === "user" && ((_c = msg.attachments) === null || _c === void 0 ? void 0 : _c.length)) {
2126
+ } else if (role === "user" && ((_b = msg.attachments) === null || _b === void 0 ? void 0 : _b.length)) {
2123
2127
  const msgAttachmentParts = msg.attachments.map((att) => ({
2124
2128
  text: `[File: ${att.name}]
2125
2129
  ${att.content}`
@@ -2172,11 +2176,12 @@ ${att.content}`
2172
2176
  };
2173
2177
  }
2174
2178
  fromGeminiResponse(response, offeredToolNames = /* @__PURE__ */ new Set()) {
2175
- var _a, _b, _c, _d;
2179
+ var _a, _b;
2180
+ var _c, _d;
2176
2181
  const { inputTokens, outputTokens, thoughtsTokens, cacheReadTokens, cost } = this.usageFromGemini(response.usageMetadata);
2177
2182
  const candidates = response === null || response === void 0 ? void 0 : response.candidates;
2178
2183
  const firstCandidate = candidates === null || candidates === void 0 ? void 0 : candidates[0];
2179
- const parts = (_b = (_a = firstCandidate === null || firstCandidate === void 0 ? void 0 : firstCandidate.content) === null || _a === void 0 ? void 0 : _a.parts) !== null && _b !== void 0 ? _b : [];
2184
+ const parts = (_c = (_a = firstCandidate === null || firstCandidate === void 0 ? void 0 : firstCandidate.content) === null || _a === void 0 ? void 0 : _a.parts) !== null && _c !== void 0 ? _c : [];
2180
2185
  const toolCalls = [];
2181
2186
  const thoughtParts = [];
2182
2187
  const textParts = [];
@@ -2189,7 +2194,7 @@ ${att.content}`
2189
2194
  toolCalls.push({
2190
2195
  id: crypto.randomUUID(),
2191
2196
  name: part.functionCall.name,
2192
- args: (_c = part.functionCall.args) !== null && _c !== void 0 ? _c : {},
2197
+ args: (_d = part.functionCall.args) !== null && _d !== void 0 ? _d : {},
2193
2198
  providerMetadata: { [GEMINI_PROVIDER_KEY]: state }
2194
2199
  });
2195
2200
  } else if (part.thought && part.text) {
@@ -2227,7 +2232,7 @@ ${att.content}`
2227
2232
  base.cacheReadTokens = cacheReadTokens;
2228
2233
  if (cost != null)
2229
2234
  base.cost = cost;
2230
- const blockReason = (_d = response.promptFeedback) === null || _d === void 0 ? void 0 : _d.blockReason;
2235
+ const blockReason = (_b = response.promptFeedback) === null || _b === void 0 ? void 0 : _b.blockReason;
2231
2236
  if (finishReason != null || thoughtsTokens != null || blockReason != null) {
2232
2237
  base.responseMeta = {
2233
2238
  finishReason,
@@ -2273,9 +2278,10 @@ ${att.content}`
2273
2278
  * without answering" signature.
2274
2279
  */
2275
2280
  logAbnormalResponse(response, parsed) {
2276
- var _a, _b, _c;
2277
- const usage = (_a = response.usageMetadata) !== null && _a !== void 0 ? _a : {};
2278
- const candidate = (_c = (_b = response.candidates) === null || _b === void 0 ? void 0 : _b[0]) !== null && _c !== void 0 ? _c : {};
2281
+ var _a;
2282
+ var _b, _c;
2283
+ const usage = (_b = response.usageMetadata) !== null && _b !== void 0 ? _b : {};
2284
+ const candidate = (_c = (_a = response.candidates) === null || _a === void 0 ? void 0 : _a[0]) !== null && _c !== void 0 ? _c : {};
2279
2285
  logger.warn("GeminiTransport: blank/non-STOP response", {
2280
2286
  model: this.model,
2281
2287
  finishReason: parsed.finishReason,
@@ -2379,7 +2385,8 @@ var EmptyAIProviderRegistry = class _EmptyAIProviderRegistry {
2379
2385
  }
2380
2386
  getStatus(name) {
2381
2387
  return __awaiter(this, void 0, void 0, function* () {
2382
- var _a, _b, _c;
2388
+ var _a, _b;
2389
+ var _c;
2383
2390
  if (name !== void 0 && name !== _EmptyAIProviderRegistry.DEFAULT_NAME)
2384
2391
  return null;
2385
2392
  return (_c = yield (_b = (_a = this.noopProvider).getStatus) === null || _b === void 0 ? void 0 : _b.call(_a)) !== null && _c !== void 0 ? _c : null;
@@ -2387,7 +2394,8 @@ var EmptyAIProviderRegistry = class _EmptyAIProviderRegistry {
2387
2394
  }
2388
2395
  listStatuses() {
2389
2396
  return __awaiter(this, void 0, void 0, function* () {
2390
- var _a, _b, _c;
2397
+ var _a, _b;
2398
+ var _c;
2391
2399
  const status = (_c = yield (_b = (_a = this.noopProvider).getStatus) === null || _b === void 0 ? void 0 : _b.call(_a)) !== null && _c !== void 0 ? _c : null;
2392
2400
  return [{ name: _EmptyAIProviderRegistry.DEFAULT_NAME, isDefault: true, status }];
2393
2401
  });
@@ -2431,7 +2439,8 @@ var MutableAIProviderRegistry = class _MutableAIProviderRegistry {
2431
2439
  }
2432
2440
  getStatus(name) {
2433
2441
  return __awaiter(this, void 0, void 0, function* () {
2434
- var _a, _b;
2442
+ var _a;
2443
+ var _b;
2435
2444
  const provider = name === void 0 ? this.default() : this.providers.get(name);
2436
2445
  if (!provider)
2437
2446
  return null;
@@ -2442,7 +2451,8 @@ var MutableAIProviderRegistry = class _MutableAIProviderRegistry {
2442
2451
  return __awaiter(this, void 0, void 0, function* () {
2443
2452
  const entries = [...this.providers.entries()];
2444
2453
  return Promise.all(entries.map((_a) => __awaiter(this, [_a], void 0, function* ([name, provider]) {
2445
- var _b, _c;
2454
+ var _b;
2455
+ var _c;
2446
2456
  return {
2447
2457
  name,
2448
2458
  isDefault: name === this._defaultName,
@@ -2840,9 +2850,15 @@ function triggerLabel(trigger) {
2840
2850
  function estimateTokensSaved(origLen, stubLen) {
2841
2851
  return Math.max(0, Math.ceil((origLen - stubLen) / APPROX_CHARS_PER_TOKEN));
2842
2852
  }
2853
+ function marksDiscontinuity(kind) {
2854
+ return kind === "agentEnd" || kind === "phaseEnd";
2855
+ }
2843
2856
  function applyCondensation(history, policies, ctx, onCondensed) {
2844
2857
  if (policies.size === 0) return history;
2845
2858
  const triggersOf = (entry) => Array.isArray(entry.policy.on) ? entry.policy.on : [entry.policy.on];
2859
+ const batchCalls = Math.max(1, Math.floor(ctx.batchCalls ?? 1));
2860
+ const asOf = batchCalls === 1 ? ctx.modelCall : Math.floor(ctx.modelCall / batchCalls) * batchCalls;
2861
+ const withinBatch = (entry) => batchCalls === 1 || entry.iteration <= asOf;
2846
2862
  const latestByKey = /* @__PURE__ */ new Map();
2847
2863
  const nameById = /* @__PURE__ */ new Map();
2848
2864
  for (const msg of history) {
@@ -2850,7 +2866,7 @@ function applyCondensation(history, policies, ctx, onCondensed) {
2850
2866
  for (const tc of msg.toolCalls) {
2851
2867
  nameById.set(tc.id, tc.name);
2852
2868
  const entry = policies.get(tc.id);
2853
- if (!entry) continue;
2869
+ if (!entry || !withinBatch(entry)) continue;
2854
2870
  for (const t of triggersOf(entry)) {
2855
2871
  if (t.kind === "superseded") latestByKey.set(t.by, tc.id);
2856
2872
  }
@@ -2862,7 +2878,7 @@ function applyCondensation(history, policies, ctx, onCondensed) {
2862
2878
  // past the last allowed view: turns:1 → seen once, then gone. Monotonic
2863
2879
  // clock, so this holds across turn boundaries too.
2864
2880
  case "age":
2865
- return ctx.modelCall - entry.iteration > trig.turns;
2881
+ return asOf - entry.iteration > trig.turns;
2866
2882
  case "turnEnd":
2867
2883
  return ctx.turn > entry.turn;
2868
2884
  case "agentEnd":
@@ -2876,7 +2892,9 @@ function applyCondensation(history, policies, ctx, onCondensed) {
2876
2892
  return latestByKey.get(trig.by) !== toolCallId;
2877
2893
  }
2878
2894
  };
2879
- const firstFired = (toolCallId, entry) => triggersOf(entry).find((t) => triggerFires(toolCallId, entry, t));
2895
+ const firstFired = (toolCallId, entry) => triggersOf(entry).find(
2896
+ (t) => (marksDiscontinuity(t.kind) || withinBatch(entry)) && triggerFires(toolCallId, entry, t)
2897
+ );
2880
2898
  return history.map((msg) => {
2881
2899
  if (msg.toolCalls?.length) {
2882
2900
  let changed = false;
@@ -3257,11 +3275,13 @@ var ChatDriver = class _ChatDriver extends EventTarget {
3257
3275
  primerHistory,
3258
3276
  maxToolIterations = DEFAULT_MAX_TOOL_ITERATIONS,
3259
3277
  maxFoldOperations = DEFAULT_MAX_FOLD_OPERATIONS,
3278
+ condenseBatchCalls = 1,
3260
3279
  maxTurnSnapshots = DEFAULT_MAX_TURN_SNAPSHOTS,
3261
3280
  sessionKey = "",
3262
3281
  activityBus = NOOP_ACTIVITY_BUS
3263
3282
  } = config;
3264
3283
  this.maxToolIterations = maxToolIterations;
3284
+ this.condenseBatchCalls = condenseBatchCalls;
3265
3285
  this.sessionKey = sessionKey;
3266
3286
  this.activityBus = activityBus;
3267
3287
  if (typeof toolHandlers === "function") {
@@ -4500,7 +4520,8 @@ Output format (strict):
4500
4520
  activationEnded: (activation) => activation < this.currentActivation,
4501
4521
  // A call's phase has ended once the app declared a later phase epoch
4502
4522
  // current via `endPhase()`.
4503
- phaseEnded: (phaseEpoch) => phaseEpoch < this.currentPhaseEpoch
4523
+ phaseEnded: (phaseEpoch) => phaseEpoch < this.currentPhaseEpoch,
4524
+ batchCalls: this.condenseBatchCalls
4504
4525
  },
4505
4526
  (detail) => recordMetaEvent(this.sessionKey, "context.condensed", detail)
4506
4527
  );