zeitlich 0.2.48 → 0.2.50

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 (126) hide show
  1. package/README.md +26 -23
  2. package/dist/{activities-DCaIPQBT.d.ts → activities-IuOIvPHO.d.ts} +6 -6
  3. package/dist/{activities-BlQR5gX4.d.cts → activities-cIlq1y1y.d.cts} +6 -6
  4. package/dist/adapters/sandbox/daytona/index.cjs.map +1 -1
  5. package/dist/adapters/sandbox/daytona/index.d.cts +3 -3
  6. package/dist/adapters/sandbox/daytona/index.d.ts +3 -3
  7. package/dist/adapters/sandbox/daytona/index.js.map +1 -1
  8. package/dist/adapters/sandbox/daytona/workflow.d.cts +2 -2
  9. package/dist/adapters/sandbox/daytona/workflow.d.ts +2 -2
  10. package/dist/adapters/sandbox/e2b/index.cjs.map +1 -1
  11. package/dist/adapters/sandbox/e2b/index.d.cts +1 -1
  12. package/dist/adapters/sandbox/e2b/index.d.ts +1 -1
  13. package/dist/adapters/sandbox/e2b/index.js.map +1 -1
  14. package/dist/adapters/sandbox/e2b/workflow.d.cts +1 -1
  15. package/dist/adapters/sandbox/e2b/workflow.d.ts +1 -1
  16. package/dist/adapters/thread/anthropic/index.cjs +45 -42
  17. package/dist/adapters/thread/anthropic/index.cjs.map +1 -1
  18. package/dist/adapters/thread/anthropic/index.d.cts +10 -10
  19. package/dist/adapters/thread/anthropic/index.d.ts +10 -10
  20. package/dist/adapters/thread/anthropic/index.js +45 -42
  21. package/dist/adapters/thread/anthropic/index.js.map +1 -1
  22. package/dist/adapters/thread/anthropic/workflow.d.cts +7 -7
  23. package/dist/adapters/thread/anthropic/workflow.d.ts +7 -7
  24. package/dist/adapters/thread/google-genai/index.cjs +117 -54
  25. package/dist/adapters/thread/google-genai/index.cjs.map +1 -1
  26. package/dist/adapters/thread/google-genai/index.d.cts +27 -23
  27. package/dist/adapters/thread/google-genai/index.d.ts +27 -23
  28. package/dist/adapters/thread/google-genai/index.js +117 -54
  29. package/dist/adapters/thread/google-genai/index.js.map +1 -1
  30. package/dist/adapters/thread/google-genai/workflow.d.cts +8 -8
  31. package/dist/adapters/thread/google-genai/workflow.d.ts +8 -8
  32. package/dist/adapters/thread/langchain/index.cjs +45 -42
  33. package/dist/adapters/thread/langchain/index.cjs.map +1 -1
  34. package/dist/adapters/thread/langchain/index.d.cts +10 -10
  35. package/dist/adapters/thread/langchain/index.d.ts +10 -10
  36. package/dist/adapters/thread/langchain/index.js +45 -42
  37. package/dist/adapters/thread/langchain/index.js.map +1 -1
  38. package/dist/adapters/thread/langchain/workflow.d.cts +7 -7
  39. package/dist/adapters/thread/langchain/workflow.d.ts +7 -7
  40. package/dist/{cold-store-UL13Sstw.d.cts → cold-store-C0uvYTSi.d.cts} +1 -1
  41. package/dist/{cold-store-aD4TSKlU.d.ts → cold-store-CCnZYWjx.d.ts} +1 -1
  42. package/dist/index.cjs +15063 -405
  43. package/dist/index.cjs.map +1 -1
  44. package/dist/index.d.cts +79 -83
  45. package/dist/index.d.ts +79 -83
  46. package/dist/index.js +15064 -402
  47. package/dist/index.js.map +1 -1
  48. package/dist/{proxy-BAty3CWM.d.cts → proxy-BVznA2_p.d.cts} +1 -1
  49. package/dist/{proxy-mbnwBhHw.d.ts → proxy-C4J1pNUk.d.ts} +1 -1
  50. package/dist/{thread-manager-CICj68PI.d.ts → thread-manager-BqjzWsP7.d.ts} +4 -4
  51. package/dist/{thread-manager-R6c3lnJy.d.cts → thread-manager-CzIs47uG.d.cts} +4 -4
  52. package/dist/{thread-manager-DsXvJ5cJ.d.cts → thread-manager-Dzl1fHhV.d.cts} +4 -4
  53. package/dist/{thread-manager-DtEtbUkp.d.ts → thread-manager-SkSWRPRc.d.ts} +4 -4
  54. package/dist/{types-gVa5XCWD.d.ts → types-BQvXWcft.d.ts} +1 -1
  55. package/dist/{types-DF4wzWQG.d.ts → types-CbPnU4RM.d.ts} +3 -3
  56. package/dist/{types-CJ7tCdl6.d.cts → types-D8W5TnSa.d.cts} +3 -3
  57. package/dist/{types-CJ7tCdl6.d.ts → types-D8W5TnSa.d.ts} +3 -3
  58. package/dist/{types-DwBYd0ij.d.ts → types-DZnUqCAP.d.cts} +709 -686
  59. package/dist/{types-CjY93AWZ.d.cts → types-OEN1xrFg.d.cts} +1 -1
  60. package/dist/{types-DWeyCTYK.d.cts → types-YNesmGKV.d.ts} +709 -686
  61. package/dist/{types-DDLPnxBh.d.cts → types-d2RvEP6v.d.cts} +3 -3
  62. package/dist/{workflow-DdaU7_j4.d.ts → workflow-B3oTe2_D.d.cts} +34 -3
  63. package/dist/{workflow-DVNPR7eX.d.cts → workflow-Bkzg0cjB.d.ts} +34 -3
  64. package/dist/workflow.cjs +15021 -362
  65. package/dist/workflow.cjs.map +1 -1
  66. package/dist/workflow.d.cts +3 -3
  67. package/dist/workflow.d.ts +3 -3
  68. package/dist/workflow.js +15022 -359
  69. package/dist/workflow.js.map +1 -1
  70. package/package.json +10 -37
  71. package/src/adapters/thread/anthropic/activities.ts +1 -1
  72. package/src/adapters/thread/anthropic/fork-transform.test.ts +17 -11
  73. package/src/adapters/thread/anthropic/model-invoker.test.ts +4 -3
  74. package/src/adapters/thread/anthropic/model-invoker.ts +1 -1
  75. package/src/adapters/thread/anthropic/thread-manager.test.ts +2 -2
  76. package/src/adapters/thread/anthropic/thread-manager.ts +1 -1
  77. package/src/adapters/thread/google-genai/activities.ts +1 -1
  78. package/src/adapters/thread/google-genai/fork-transform.test.ts +17 -11
  79. package/src/adapters/thread/google-genai/model-invoker.test.ts +337 -0
  80. package/src/adapters/thread/google-genai/model-invoker.ts +107 -23
  81. package/src/adapters/thread/google-genai/thread-manager.test.ts +2 -2
  82. package/src/adapters/thread/google-genai/thread-manager.ts +1 -1
  83. package/src/adapters/thread/langchain/activities.ts +1 -1
  84. package/src/adapters/thread/langchain/fork-transform.test.ts +17 -11
  85. package/src/adapters/thread/langchain/model-invoker.ts +1 -1
  86. package/src/adapters/thread/langchain/thread-manager.test.ts +2 -2
  87. package/src/adapters/thread/langchain/thread-manager.ts +1 -1
  88. package/src/index.ts +2 -2
  89. package/src/lib/sandbox/capability-types.test.ts +2 -2
  90. package/src/lib/sandbox/manager.ts +2 -6
  91. package/src/lib/sandbox/sandbox.test.ts +1 -1
  92. package/src/lib/sandbox/types.ts +2 -2
  93. package/src/lib/session/session.integration.test.ts +92 -0
  94. package/src/lib/session/session.ts +23 -0
  95. package/src/lib/subagent/handler.ts +23 -0
  96. package/src/lib/subagent/subagent.integration.test.ts +198 -0
  97. package/src/lib/thread/keys.test.ts +9 -9
  98. package/src/lib/thread/keys.ts +1 -1
  99. package/src/lib/thread/manager.test.ts +24 -14
  100. package/src/lib/thread/manager.ts +19 -23
  101. package/src/lib/thread/snapshot.test.ts +51 -43
  102. package/src/lib/thread/snapshot.ts +54 -32
  103. package/src/lib/thread/test-utils.ts +106 -59
  104. package/src/lib/thread/tiered.test.ts +1 -1
  105. package/src/lib/thread/types.ts +2 -2
  106. package/src/lib/tool-router/router.integration.test.ts +44 -0
  107. package/src/lib/tool-router/router.ts +149 -33
  108. package/src/lib/tool-router/types.ts +23 -0
  109. package/src/lib/workflow.ts +49 -0
  110. package/src/{adapters/sandbox/inmemory/proxy.ts → test-utils/in-memory-sandbox-proxy.ts} +5 -16
  111. package/src/{adapters/sandbox/inmemory/index.ts → test-utils/in-memory-sandbox.ts} +11 -3
  112. package/src/tools/bash/bash.test.ts +1 -1
  113. package/src/tools/edit/handler.test.ts +1 -1
  114. package/tsup.config.ts +2 -4
  115. package/dist/adapters/sandbox/inmemory/index.cjs +0 -214
  116. package/dist/adapters/sandbox/inmemory/index.cjs.map +0 -1
  117. package/dist/adapters/sandbox/inmemory/index.d.cts +0 -40
  118. package/dist/adapters/sandbox/inmemory/index.d.ts +0 -40
  119. package/dist/adapters/sandbox/inmemory/index.js +0 -211
  120. package/dist/adapters/sandbox/inmemory/index.js.map +0 -1
  121. package/dist/adapters/sandbox/inmemory/workflow.cjs +0 -36
  122. package/dist/adapters/sandbox/inmemory/workflow.cjs.map +0 -1
  123. package/dist/adapters/sandbox/inmemory/workflow.d.cts +0 -27
  124. package/dist/adapters/sandbox/inmemory/workflow.d.ts +0 -27
  125. package/dist/adapters/sandbox/inmemory/workflow.js +0 -34
  126. package/dist/adapters/sandbox/inmemory/workflow.js.map +0 -1
@@ -1,16 +1,16 @@
1
1
  import { ActivityInterfaceFor } from '@temporalio/workflow';
2
- import { T as ThreadOps } from '../../../types-DwBYd0ij.js';
3
- import { A as AnthropicContent } from '../../../thread-manager-DtEtbUkp.js';
4
- import { c as createThreadOpsProxy } from '../../../proxy-mbnwBhHw.js';
5
- export { T as ThreadOpsProxyOptions } from '../../../proxy-mbnwBhHw.js';
2
+ import { T as ThreadOps } from '../../../types-YNesmGKV.js';
3
+ import { A as AnthropicContent } from '../../../thread-manager-SkSWRPRc.js';
4
+ import { c as createThreadOpsProxy } from '../../../proxy-C4J1pNUk.js';
5
+ export { T as ThreadOpsProxyOptions } from '../../../proxy-C4J1pNUk.js';
6
6
  export { A as ADAPTER_ID, a as AdapterId } from '../../../adapter-id-CMwVrVqv.js';
7
7
  import '@temporalio/common/lib/interfaces';
8
8
  import 'zod';
9
- import '../../../types-CJ7tCdl6.js';
9
+ import '../../../types-D8W5TnSa.js';
10
10
  import '@temporalio/common';
11
- import 'ioredis';
11
+ import 'redis';
12
12
  import '@anthropic-ai/sdk';
13
- import '../../../types-DF4wzWQG.js';
13
+ import '../../../types-CbPnU4RM.js';
14
14
 
15
15
  /**
16
16
  * Workflow-safe proxy for Anthropic thread operations.
@@ -1,5 +1,6 @@
1
1
  'use strict';
2
2
 
3
+ var crypto = require('crypto');
3
4
  var activity = require('@temporalio/activity');
4
5
 
5
6
  // src/adapters/thread/google-genai/adapter-id.ts
@@ -55,11 +56,11 @@ function createThreadManager(config) {
55
56
  return {
56
57
  async initialize() {
57
58
  await redis.del(redisKey);
58
- await redis.set(metaKey, "1", "EX", ttlSeconds);
59
+ await redis.set(metaKey, "1", { EX: ttlSeconds });
59
60
  },
60
61
  async load() {
61
62
  await assertThreadExists();
62
- const data = await redis.lrange(redisKey, 0, -1);
63
+ const data = await redis.lRange(redisKey, 0, -1);
63
64
  return data.map(deserialize);
64
65
  },
65
66
  async append(messages) {
@@ -67,22 +68,18 @@ function createThreadManager(config) {
67
68
  await assertThreadExists();
68
69
  if (idOf) {
69
70
  const dedupId = messages.map(idOf).join(":");
70
- await redis.eval(
71
- APPEND_IDEMPOTENT_SCRIPT,
72
- 2,
73
- dedupKey(dedupId),
74
- redisKey,
75
- String(ttlSeconds),
76
- ...messages.map(serialize)
77
- );
71
+ await redis.eval(APPEND_IDEMPOTENT_SCRIPT, {
72
+ keys: [dedupKey(dedupId), redisKey],
73
+ arguments: [String(ttlSeconds), ...messages.map(serialize)]
74
+ });
78
75
  } else {
79
- await redis.rpush(redisKey, ...messages.map(serialize));
76
+ await redis.rPush(redisKey, messages.map(serialize));
80
77
  await redis.expire(redisKey, ttlSeconds);
81
78
  }
82
79
  },
83
80
  async fork(newThreadId) {
84
81
  await assertThreadExists();
85
- const data = await redis.lrange(redisKey, 0, -1);
82
+ const data = await redis.lRange(redisKey, 0, -1);
86
83
  const stateRaw = await redis.get(stateKey);
87
84
  const forked = createThreadManager({
88
85
  ...config,
@@ -91,12 +88,12 @@ function createThreadManager(config) {
91
88
  await forked.initialize();
92
89
  if (data.length > 0) {
93
90
  const newKey = getThreadListKey(key, newThreadId);
94
- await redis.rpush(newKey, ...data);
91
+ await redis.rPush(newKey, data);
95
92
  await redis.expire(newKey, ttlSeconds);
96
93
  }
97
94
  if (stateRaw != null) {
98
95
  const newStateKey = getThreadStateKey(key, newThreadId);
99
- await redis.set(newStateKey, stateRaw, "EX", ttlSeconds);
96
+ await redis.set(newStateKey, stateRaw, { EX: ttlSeconds });
100
97
  }
101
98
  return forked;
102
99
  },
@@ -107,20 +104,20 @@ function createThreadManager(config) {
107
104
  "replaceAll requires the thread manager to be configured with `idOf`"
108
105
  );
109
106
  }
110
- const existing = await redis.lrange(redisKey, 0, -1);
107
+ const existing = await redis.lRange(redisKey, 0, -1);
111
108
  const existingIds = existing.map((raw) => idOf(deserialize(raw))).filter((id) => typeof id === "string");
112
109
  await redis.del(redisKey);
113
110
  if (existingIds.length > 0) {
114
- await redis.del(...existingIds.map(dedupKey));
111
+ await redis.del(existingIds.map(dedupKey));
115
112
  }
116
113
  if (messages.length > 0) {
117
- await redis.rpush(redisKey, ...messages.map(serialize));
114
+ await redis.rPush(redisKey, messages.map(serialize));
118
115
  await redis.expire(redisKey, ttlSeconds);
119
116
  }
120
117
  await redis.expire(metaKey, ttlSeconds);
121
118
  },
122
119
  async delete() {
123
- await redis.del(redisKey, metaKey, stateKey);
120
+ await redis.del([redisKey, metaKey, stateKey]);
124
121
  },
125
122
  async loadState() {
126
123
  const raw = await redis.get(stateKey);
@@ -129,14 +126,14 @@ function createThreadManager(config) {
129
126
  },
130
127
  async saveState(state) {
131
128
  await assertThreadExists();
132
- await redis.set(stateKey, JSON.stringify(state), "EX", ttlSeconds);
129
+ await redis.set(stateKey, JSON.stringify(state), { EX: ttlSeconds });
133
130
  },
134
131
  async deleteState() {
135
132
  await redis.del(stateKey);
136
133
  },
137
134
  async length() {
138
135
  await assertThreadExists();
139
- return redis.llen(redisKey);
136
+ return redis.lLen(redisKey);
140
137
  },
141
138
  async truncateFromId(messageId) {
142
139
  await assertThreadExists();
@@ -145,7 +142,7 @@ function createThreadManager(config) {
145
142
  "truncateFromId requires the thread manager to be configured with `idOf`"
146
143
  );
147
144
  }
148
- const data = await redis.lrange(redisKey, 0, -1);
145
+ const data = await redis.lRange(redisKey, 0, -1);
149
146
  let idx = -1;
150
147
  const removedIds = [];
151
148
  for (let i = 0; i < data.length; i++) {
@@ -160,11 +157,11 @@ function createThreadManager(config) {
160
157
  await redis.del(redisKey);
161
158
  await redis.expire(metaKey, ttlSeconds);
162
159
  } else {
163
- await redis.ltrim(redisKey, 0, idx - 1);
160
+ await redis.lTrim(redisKey, 0, idx - 1);
164
161
  await redis.expire(redisKey, ttlSeconds);
165
162
  }
166
163
  if (removedIds.length > 0) {
167
- await redis.del(...removedIds.map(dedupKey));
164
+ await redis.del(removedIds.map(dedupKey));
168
165
  }
169
166
  }
170
167
  };
@@ -179,7 +176,7 @@ async function encodeSnapshot(config) {
179
176
  }
180
177
  const listKey = getThreadListKey(threadKey, threadId);
181
178
  const stateKey = getThreadStateKey(threadKey, threadId);
182
- const messages = await redis.lrange(listKey, 0, -1);
179
+ const messages = await redis.lRange(listKey, 0, -1);
183
180
  const stateRaw = await redis.get(stateKey);
184
181
  const state = stateRaw == null ? null : JSON.parse(stateRaw);
185
182
  const dedupIds = idOf ? messages.map(idOf) : [];
@@ -199,31 +196,38 @@ async function applySnapshot(config) {
199
196
  }
200
197
  const listKey = getThreadListKey(threadKey, threadId);
201
198
  const stateKey = getThreadStateKey(threadKey, threadId);
202
- await redis.del(listKey, stateKey);
203
- const pipeline = redis.pipeline();
199
+ await redis.del([listKey, stateKey]);
200
+ const pipeline = redis.multi();
204
201
  if (snapshot.messages.length > 0) {
205
- pipeline.rpush(listKey, ...snapshot.messages);
202
+ pipeline.rPush(listKey, snapshot.messages);
206
203
  pipeline.expire(listKey, ttlSeconds);
207
204
  }
208
205
  if (snapshot.state != null) {
209
- pipeline.set(stateKey, JSON.stringify(snapshot.state), "EX", ttlSeconds);
206
+ pipeline.set(stateKey, JSON.stringify(snapshot.state), { EX: ttlSeconds });
210
207
  }
211
208
  for (const id of snapshot.dedupIds) {
212
- pipeline.set(getThreadDedupKey(threadId, id), "1", "EX", ttlSeconds);
209
+ pipeline.set(getThreadDedupKey(threadId, id), "1", { EX: ttlSeconds });
213
210
  }
214
- const results = await pipeline.exec();
215
- if (results) {
216
- const firstErr = results.find(([err]) => err)?.[0] ?? null;
217
- if (firstErr) {
218
- await redis.del(
219
- listKey,
220
- stateKey,
221
- ...snapshot.dedupIds.map((id) => getThreadDedupKey(threadId, id))
222
- ).catch(() => void 0);
223
- throw firstErr;
224
- }
211
+ try {
212
+ await pipeline.execAsPipeline();
213
+ } catch (err) {
214
+ await redis.del([
215
+ listKey,
216
+ stateKey,
217
+ ...snapshot.dedupIds.map((id) => getThreadDedupKey(threadId, id))
218
+ ]).catch(() => void 0);
219
+ throw firstPipelineError(err);
225
220
  }
226
- await redis.set(metaKey, "1", "EX", ttlSeconds);
221
+ await redis.set(metaKey, "1", { EX: ttlSeconds });
222
+ }
223
+ function firstPipelineError(err) {
224
+ if (err != null && typeof err === "object" && "replies" in err && Array.isArray(err.replies)) {
225
+ const firstErr = err.replies.find(
226
+ (r) => r instanceof Error
227
+ );
228
+ if (firstErr) return firstErr;
229
+ }
230
+ return err;
227
231
  }
228
232
  async function clearHotTier(config) {
229
233
  const { redis, threadKey, threadId, dedupIds = [] } = config;
@@ -233,7 +237,7 @@ async function clearHotTier(config) {
233
237
  getThreadStateKey(threadKey, threadId),
234
238
  ...dedupIds.map((id) => getThreadDedupKey(threadId, id))
235
239
  ];
236
- await redis.del(...keys);
240
+ await redis.del(keys);
237
241
  }
238
242
 
239
243
  // src/lib/thread/tiered.ts
@@ -431,7 +435,9 @@ function createGoogleGenAIModelInvoker({
431
435
  redis,
432
436
  client,
433
437
  model,
434
- hooks
438
+ hooks,
439
+ config: generationConfig,
440
+ cache: cacheConfig
435
441
  }) {
436
442
  return async function invokeGoogleGenAIModel2(config) {
437
443
  const { threadId, threadKey, state, assistantMessageId } = config;
@@ -446,12 +452,57 @@ function createGoogleGenAIModelInvoker({
446
452
  const { contents, systemInstruction } = await thread.prepareForInvocation();
447
453
  const functionDeclarations = toFunctionDeclarations(state.tools);
448
454
  const tools = functionDeclarations.length > 0 ? [{ functionDeclarations }] : void 0;
455
+ const {
456
+ systemInstruction: _si,
457
+ tools: _t,
458
+ abortSignal: _as,
459
+ cachedContent: callerCachedContent,
460
+ toolConfig: callerToolConfig,
461
+ ...callerConfig
462
+ } = generationConfig ?? {};
463
+ let liveContents = contents;
464
+ let cachedContentName;
465
+ let cachedWriteTokens;
466
+ if (cacheConfig && cacheConfig.splitIndex > 0 && contents.length > cacheConfig.splitIndex) {
467
+ liveContents = contents.slice(cacheConfig.splitIndex);
468
+ const ttl = cacheConfig.ttlSeconds ?? 300;
469
+ const cacheRedisKey = `${threadKey ?? "messages"}:gemini-cache:${model}:${cacheConfig.splitIndex}:thread:${threadId}`;
470
+ cachedContentName = await redis.get(cacheRedisKey) ?? void 0;
471
+ if (!cachedContentName) {
472
+ const cacheInstance = await client.caches.create({
473
+ model,
474
+ config: {
475
+ contents: contents.slice(0, cacheConfig.splitIndex),
476
+ ...systemInstruction ? { systemInstruction } : {},
477
+ ...tools ? { tools } : {},
478
+ ...callerToolConfig ? { toolConfig: callerToolConfig } : {},
479
+ ttl: `${ttl}s`,
480
+ abortSignal: signal
481
+ }
482
+ });
483
+ if (!cacheInstance?.name) {
484
+ throw new Error("Gemini cache creation did not return a cache name");
485
+ }
486
+ cachedContentName = cacheInstance.name;
487
+ cachedWriteTokens = cacheInstance.usageMetadata?.totalTokenCount ?? void 0;
488
+ const redisTtl = ttl - 5;
489
+ if (redisTtl > 0) {
490
+ await redis.set(cacheRedisKey, cachedContentName, { EX: redisTtl });
491
+ }
492
+ }
493
+ }
449
494
  const stream = await client.models.generateContentStream({
450
495
  model,
451
- contents,
496
+ contents: liveContents,
452
497
  config: {
453
- ...systemInstruction ? { systemInstruction } : {},
454
- ...tools ? { tools } : {},
498
+ ...callerConfig,
499
+ ...cachedContentName ? { cachedContent: cachedContentName } : {
500
+ ...callerCachedContent ? { cachedContent: callerCachedContent } : {
501
+ ...systemInstruction ? { systemInstruction } : {},
502
+ ...tools ? { tools } : {}
503
+ },
504
+ ...callerToolConfig ? { toolConfig: callerToolConfig } : {}
505
+ },
455
506
  abortSignal: signal
456
507
  }
457
508
  });
@@ -465,19 +516,27 @@ function createGoogleGenAIModelInvoker({
465
516
  if (!lastChunk) {
466
517
  throw new Error("Google GenAI stream ended without producing any chunks");
467
518
  }
519
+ for (const part of allParts) {
520
+ if (part.functionCall && !part.functionCall.id) {
521
+ part.functionCall.id = crypto.randomBytes(8).toString("hex");
522
+ }
523
+ }
468
524
  const modelContent = { role: "model", parts: allParts };
469
- const functionCalls = lastChunk.functionCalls ?? [];
470
525
  return {
471
526
  message: modelContent,
472
- rawToolCalls: functionCalls.map((fc) => ({
473
- id: fc.id,
474
- name: fc.name ?? "",
475
- args: fc.args ?? {}
527
+ rawToolCalls: allParts.filter(
528
+ (p) => !!p.functionCall
529
+ ).map((p) => ({
530
+ id: p.functionCall.id,
531
+ name: p.functionCall.name ?? "",
532
+ args: p.functionCall.args ?? {}
476
533
  })),
477
534
  usage: {
478
535
  inputTokens: lastChunk.usageMetadata?.promptTokenCount,
479
536
  outputTokens: lastChunk.usageMetadata?.candidatesTokenCount,
480
- cachedReadTokens: lastChunk.usageMetadata?.cachedContentTokenCount
537
+ cachedWriteTokens,
538
+ cachedReadTokens: lastChunk.usageMetadata?.cachedContentTokenCount,
539
+ reasonTokens: lastChunk.usageMetadata?.thoughtsTokenCount
481
540
  }
482
541
  };
483
542
  };
@@ -487,13 +546,17 @@ async function invokeGoogleGenAIModel({
487
546
  client,
488
547
  model,
489
548
  hooks,
490
- config
549
+ config,
550
+ generationConfig,
551
+ cache
491
552
  }) {
492
553
  const invoker = createGoogleGenAIModelInvoker({
493
554
  redis,
494
555
  client,
495
556
  model,
496
- hooks
557
+ hooks,
558
+ config: generationConfig,
559
+ cache
497
560
  });
498
561
  return invoker(config);
499
562
  }