zeitlich 0.2.46 → 0.2.47

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 (83) hide show
  1. package/README.md +64 -6
  2. package/dist/{activities-CyeiqK_f.d.cts → activities-CPwKoUlD.d.cts} +3 -3
  3. package/dist/{activities-Bm4TLTid.d.ts → activities-DlaBxNID.d.ts} +3 -3
  4. package/dist/adapters/thread/anthropic/index.cjs +105 -6
  5. package/dist/adapters/thread/anthropic/index.cjs.map +1 -1
  6. package/dist/adapters/thread/anthropic/index.d.cts +48 -9
  7. package/dist/adapters/thread/anthropic/index.d.ts +48 -9
  8. package/dist/adapters/thread/anthropic/index.js +104 -7
  9. package/dist/adapters/thread/anthropic/index.js.map +1 -1
  10. package/dist/adapters/thread/anthropic/workflow.cjs +38 -22
  11. package/dist/adapters/thread/anthropic/workflow.cjs.map +1 -1
  12. package/dist/adapters/thread/anthropic/workflow.d.cts +5 -4
  13. package/dist/adapters/thread/anthropic/workflow.d.ts +5 -4
  14. package/dist/adapters/thread/anthropic/workflow.js +38 -22
  15. package/dist/adapters/thread/anthropic/workflow.js.map +1 -1
  16. package/dist/adapters/thread/google-genai/index.d.cts +6 -5
  17. package/dist/adapters/thread/google-genai/index.d.ts +6 -5
  18. package/dist/adapters/thread/google-genai/workflow.cjs +38 -22
  19. package/dist/adapters/thread/google-genai/workflow.cjs.map +1 -1
  20. package/dist/adapters/thread/google-genai/workflow.d.cts +7 -5
  21. package/dist/adapters/thread/google-genai/workflow.d.ts +7 -5
  22. package/dist/adapters/thread/google-genai/workflow.js +38 -22
  23. package/dist/adapters/thread/google-genai/workflow.js.map +1 -1
  24. package/dist/adapters/thread/langchain/index.d.cts +6 -5
  25. package/dist/adapters/thread/langchain/index.d.ts +6 -5
  26. package/dist/adapters/thread/langchain/workflow.cjs +38 -22
  27. package/dist/adapters/thread/langchain/workflow.cjs.map +1 -1
  28. package/dist/adapters/thread/langchain/workflow.d.cts +5 -4
  29. package/dist/adapters/thread/langchain/workflow.d.ts +5 -4
  30. package/dist/adapters/thread/langchain/workflow.js +38 -22
  31. package/dist/adapters/thread/langchain/workflow.js.map +1 -1
  32. package/dist/{cold-store-CFHwemBJ.d.ts → cold-store-BDgJpwLI.d.ts} +8 -11
  33. package/dist/{cold-store-BC5L5Z8A.d.cts → cold-store-Z2wvK2cV.d.cts} +8 -11
  34. package/dist/index.cjs +264 -90
  35. package/dist/index.cjs.map +1 -1
  36. package/dist/index.d.cts +21 -9
  37. package/dist/index.d.ts +21 -9
  38. package/dist/index.js +265 -93
  39. package/dist/index.js.map +1 -1
  40. package/dist/proxy-CDh3Rsa7.d.cts +40 -0
  41. package/dist/proxy-Du8ggERu.d.ts +40 -0
  42. package/dist/{thread-manager-D33SUmZa.d.cts → thread-manager-BjoYYXgd.d.cts} +2 -2
  43. package/dist/{thread-manager-9tezUcLW.d.cts → thread-manager-D8zKNFZ9.d.cts} +2 -2
  44. package/dist/{thread-manager-B-zy3xrs.d.ts → thread-manager-DtHYws2F.d.ts} +2 -2
  45. package/dist/{thread-manager-DduoSkvJ.d.ts → thread-manager-Dw96FKH1.d.ts} +2 -2
  46. package/dist/{types-oxt8GN97.d.cts → types-BMJrsHo0.d.cts} +1 -1
  47. package/dist/{types-L5bvbF-n.d.ts → types-CtdOquo3.d.ts} +1 -1
  48. package/dist/{types-CnuN9T6t.d.cts → types-DNEl5uxQ.d.cts} +16 -0
  49. package/dist/{types-CwN6_tAL.d.ts → types-qQVZfhoT.d.ts} +16 -0
  50. package/dist/{workflow-DIaIV7L2.d.cts → workflow-BH9ImDGq.d.cts} +17 -2
  51. package/dist/{workflow-B1TOcHbt.d.ts → workflow-Cdw3-RNB.d.ts} +17 -2
  52. package/dist/workflow.cjs +33 -3
  53. package/dist/workflow.cjs.map +1 -1
  54. package/dist/workflow.d.cts +2 -2
  55. package/dist/workflow.d.ts +2 -2
  56. package/dist/workflow.js +33 -4
  57. package/dist/workflow.js.map +1 -1
  58. package/package.json +9 -3
  59. package/src/adapters/thread/anthropic/activities.ts +18 -11
  60. package/src/adapters/thread/anthropic/index.ts +8 -0
  61. package/src/adapters/thread/anthropic/model-invoker.test.ts +110 -0
  62. package/src/adapters/thread/anthropic/model-invoker.ts +26 -5
  63. package/src/adapters/thread/anthropic/prompt-cache.test.ts +134 -0
  64. package/src/adapters/thread/anthropic/prompt-cache.ts +163 -0
  65. package/src/adapters/thread/anthropic/proxy.ts +1 -0
  66. package/src/adapters/thread/google-genai/proxy.ts +1 -0
  67. package/src/adapters/thread/langchain/proxy.ts +1 -0
  68. package/src/index.ts +1 -1
  69. package/src/lib/subagent/define.ts +1 -0
  70. package/src/lib/subagent/handler.ts +11 -2
  71. package/src/lib/subagent/subagent.integration.test.ts +139 -0
  72. package/src/lib/subagent/types.ts +16 -0
  73. package/src/lib/thread/cold-store.test.ts +33 -5
  74. package/src/lib/thread/cold-store.ts +50 -31
  75. package/src/lib/thread/proxy.ts +79 -29
  76. package/src/tools/edit/handler.test.ts +177 -0
  77. package/src/tools/edit/handler.ts +249 -47
  78. package/src/tools/edit/tool.ts +40 -0
  79. package/src/tools/task-create/handler.ts +1 -1
  80. package/src/tools/task-update/handler.ts +1 -1
  81. package/src/workflow.ts +2 -2
  82. package/dist/proxy-BxFyd6cg.d.cts +0 -24
  83. package/dist/proxy-Cskmj4Yx.d.ts +0 -24
package/README.md CHANGED
@@ -8,7 +8,7 @@
8
8
 
9
9
  **Durable AI Agents for Temporal**
10
10
 
11
- Zeitlich is an opinionated framework for building reliable, stateful AI agents using [Temporal](https://temporal.io). It provides the building blocks for creating agents that can survive crashes, handle long-running tasks, and coordinate with other agents—all with full type safety.
11
+ Zeitlich is an opinionated harness for building reliable, stateful AI agents using [Temporal](https://temporal.io). It provides the building blocks for creating agents that can survive crashes, handle long-running tasks, and coordinate with other agents—all with full type safety.
12
12
 
13
13
  ## Why Zeitlich?
14
14
 
@@ -104,6 +104,7 @@ npm install zeitlich ioredis \
104
104
  - `@google/genai` >= 1.0.0 (optional — only when using the Google GenAI adapter)
105
105
  - `@aws-sdk/client-bedrock-agentcore` >= 3.900.0 (optional — only when using the Bedrock adapter)
106
106
  - `@aws-sdk/client-s3` >= 3.700.0 (optional — only when using the built-in S3 cold thread tier)
107
+ - `@aws-sdk/lib-storage` >= 3.700.0 (optional — paired with `@aws-sdk/client-s3` for multipart uploads in the S3 cold tier)
107
108
 
108
109
  > **Why peer deps?** Zeitlich's public API surfaces `@temporalio/*` types
109
110
  > (`UpdateDefinition`, `ChildWorkflowOptions`, `Duration`, etc.) directly. Peer
@@ -671,10 +672,10 @@ const continuedSession = await createSession({
671
672
 
672
673
  By default every thread lives in Redis with a 90-day TTL — both messages and the persisted state slice. For long-lived agents, that ties up hot memory for inactive conversations and ties durability to your Redis retention. Zeitlich's tiered storage moves cold threads to a durable archive (S3, R2, GCS, …) while keeping Redis as the hot tier only for the duration of a workflow run.
673
674
 
674
- | Tier | Backend | Lifetime |
675
- | ----- | ---------------------- | ------------------------------------------------- |
676
- | Hot | Redis | Only while a workflow run is active (configurable TTL) |
677
- | Cold | Pluggable `ColdThreadStore` (built-in S3) | Durable across runs |
675
+ | Tier | Backend | Lifetime |
676
+ | ---- | ----------------------------------------- | ------------------------------------------------------ |
677
+ | Hot | Redis | Only while a workflow run is active (configurable TTL) |
678
+ | Cold | Pluggable `ColdThreadStore` (built-in S3) | Durable across runs |
678
679
 
679
680
  The session wiring is fully automatic:
680
681
 
@@ -708,6 +709,30 @@ const adapter = createAnthropicAdapter({
708
709
 
709
710
  That's the only change required — `createSession`, all `ThreadInit` modes, and every adapter activity are already wired for the lifecycle. When `coldStore` is omitted, the adapter behaves identically to the Redis-only baseline.
710
711
 
712
+ ##### Anthropic prompt caching
713
+
714
+ The Anthropic adapter enables 5-minute ephemeral prompt caching by default. Before each `messages.stream()` call, it adds an explicit block-level `cache_control: { type: "ephemeral", ttl: "5m" }` marker to the last cacheable message content block. Zeitlich intentionally uses the block-level shape instead of Anthropic's top-level automatic cache-control parameter so the same request body works with Anthropic direct API clients and Anthropic-on-Bedrock `InvokeModel` clients.
715
+
716
+ ```typescript
717
+ const adapter = createAnthropicAdapter({
718
+ redis,
719
+ client: anthropic,
720
+ model: "claude-sonnet-4-20250514",
721
+ // Optional: 5m is the default; set explicitly if you prefer clarity.
722
+ promptCache: { ttl: "5m" },
723
+ });
724
+
725
+ // Disable if a model/provider route does not support prompt caching.
726
+ const uncachedAdapter = createAnthropicAdapter({
727
+ redis,
728
+ client: anthropic,
729
+ model: "claude-sonnet-4-20250514",
730
+ promptCache: false,
731
+ });
732
+ ```
733
+
734
+ If you already provide your own `cache_control` markers, Zeitlich preserves them and skips its automatic marker when the request already has the provider maximum of four cache breakpoints.
735
+
711
736
  ##### Custom backends
712
737
 
713
738
  `ColdThreadStore` is intentionally minimal:
@@ -715,7 +740,11 @@ That's the only change required — `createSession`, all `ThreadInit` modes, and
715
740
  ```typescript
716
741
  interface ColdThreadStore {
717
742
  read(threadKey: string, threadId: string): Promise<ThreadSnapshot | null>;
718
- write(threadKey: string, threadId: string, snapshot: ThreadSnapshot): Promise<void>;
743
+ write(
744
+ threadKey: string,
745
+ threadId: string,
746
+ snapshot: ThreadSnapshot
747
+ ): Promise<void>;
719
748
  delete(threadKey: string, threadId: string): Promise<void>;
720
749
  }
721
750
  ```
@@ -729,6 +758,23 @@ Any backend that can satisfy these three calls — Cloudflare R2, Google Cloud S
729
758
  - **`deleteHot: true` by default on flush.** Memory drops immediately; the next continue re-hydrates in one `GetObject`. Override per-call via the tiered manager if you want to keep the hot tier warm.
730
759
  - **`mode: "new"` overwrites the cold archive for that `threadId`.** A session entered with `mode: "new"` skips `hydrateThread`; on exit `flushThread` writes the fresh snapshot back, silently replacing any prior cold-tier blob at the same `(threadKey, threadId)`. To resume a thread, use `mode: "continue"` or `mode: "fork"` — passing a previously-used `threadId` with `mode: "new"` is destructive by design.
731
760
 
761
+ ##### Activity timeouts
762
+
763
+ `hydrateThread` and `flushThread` automatically get `startToCloseTimeout: "60s"` and `heartbeatTimeout: "15s"`. The S3 cold store uses multipart `Upload` for writes and streams the `GetObject` response on reads — each part completion / stream chunk emits a heartbeat, so a stalled upload or download trips `heartbeatTimeout` (15s) rather than waiting out `startToCloseTimeout` (60s). The Redis-only ops keep the tight `10s` baseline.
764
+
765
+ To override an individual op without inflating the rest:
766
+
767
+ ```typescript
768
+ const threadOps = proxyGoogleGenAIThreadOps(undefined, {
769
+ defaults: { startToCloseTimeout: "5s" }, // applied to every op
770
+ perOp: {
771
+ flushThread: { startToCloseTimeout: "180s" }, // overlays cold-tier defaults; heartbeatTimeout still inherited
772
+ },
773
+ });
774
+ ```
775
+
776
+ `perOp[op]` is layered shallow-rightmost over `defaults` and the built-in cold-tier overlays for `hydrateThread` / `flushThread` — so a partial override only replaces the fields you specify. A bare `ActivityOptions` object is also accepted and treated as `{ defaults: <that object> }`, with the cold-tier overlay still applied on top — to raise the cold-tier ceiling above `60s`, use `perOp.flushThread` / `perOp.hydrateThread`.
777
+
732
778
  #### Sandbox Initialization (`SandboxInit`)
733
779
 
734
780
  The `sandbox` field controls how a sandbox is created or reused:
@@ -833,6 +879,17 @@ Trade-off: cleanup is deferred to parent close (no eager GC of superseded thread
833
879
 
834
880
  The `thread` field accepts `"new"` (default), `"fork"`, or `"continue"`. When set to `"fork"` or `"continue"`, the parent agent can pass a `threadId` in a subsequent `Task` tool call to resume the conversation. The subagent returns its `threadId` in the response (surfaced as `[Thread ID: ...]`), which the parent can use for continuation.
835
881
 
882
+ The `newThreadSource` field controls what to do when the parent's tool call omits `threadId`. It accepts `"new"` (default — start a fresh thread) or `"from-parent"` (fork/continue the parent agent's own thread). Useful when you want a subagent that inherits the parent's conversation state by default without requiring the LLM to explicitly thread the id through:
883
+
884
+ ```typescript
885
+ export const researcherSubagent = defineSubagent(researcherWorkflow, {
886
+ thread: "fork",
887
+ newThreadSource: "from-parent", // no threadId → fork the parent's thread
888
+ });
889
+ ```
890
+
891
+ An explicit `threadId` from the parent's tool call always wins; `newThreadSource` only applies when none is provided. The field has no effect with `thread: "new"`.
892
+
836
893
  The `sandbox` field accepts `"none"` (default) or an object with `source`, `continuation`, and optional `init`/`shutdown` fields:
837
894
 
838
895
  - `source: "inherit"` — use the parent's sandbox. `continuation: "continue"` shares it directly; `"fork"` forks from it on every call.
@@ -1050,6 +1107,7 @@ Framework-agnostic utilities for activities, worker setup, and Node.js code:
1050
1107
  | --------------------------- | ------------------------------------------------------------------------------------------------------------------ |
1051
1108
  | `createRunAgentActivity` | Wraps a handler into a scope-prefixed `RunAgentActivity` with auto-fetched parent workflow state |
1052
1109
  | `withParentWorkflowState` | Wraps a tool handler into an `ActivityToolHandler` with auto-fetched parent workflow state |
1110
+ | `getActivityContext` | Safely returns `{ heartbeat, signal }` from the current Temporal activity, or `{}` outside one |
1053
1111
  | `createThreadManager` | Generic Redis-backed thread manager factory |
1054
1112
  | `createTieredThreadManager` | Redis hot + pluggable cold tier; adds `hydrate()` / `flush()` to `BaseThreadManager<T>` |
1055
1113
  | `createS3ColdStore` | Built-in `ColdThreadStore` backed by an `@aws-sdk/client-s3` `S3Client` |
@@ -1,8 +1,8 @@
1
1
  import Redis from 'ioredis';
2
2
  import { Part, Content, GoogleGenAI } from '@google/genai';
3
- import { a as ModelInvoker, b as PrefixedThreadOps, S as ScopedPrefix, R as RouterContext, c as ToolHandlerResponse, d as ActivityToolHandler } from './types-CnuN9T6t.cjs';
4
- import { C as ColdThreadStore } from './cold-store-BC5L5Z8A.cjs';
5
- import { T as ThreadManagerHooks, P as ProviderThreadManager } from './types-oxt8GN97.cjs';
3
+ import { a as ModelInvoker, b as PrefixedThreadOps, S as ScopedPrefix, R as RouterContext, c as ToolHandlerResponse, d as ActivityToolHandler } from './types-DNEl5uxQ.cjs';
4
+ import { C as ColdThreadStore } from './cold-store-Z2wvK2cV.cjs';
5
+ import { T as ThreadManagerHooks, P as ProviderThreadManager } from './types-BMJrsHo0.cjs';
6
6
  import { A as ADAPTER_ID } from './adapter-id-BB-mmrts.cjs';
7
7
 
8
8
  /** SDK-native content type for Google GenAI human messages */
@@ -1,8 +1,8 @@
1
1
  import Redis from 'ioredis';
2
2
  import { Part, Content, GoogleGenAI } from '@google/genai';
3
- import { a as ModelInvoker, b as PrefixedThreadOps, S as ScopedPrefix, R as RouterContext, c as ToolHandlerResponse, d as ActivityToolHandler } from './types-CwN6_tAL.js';
4
- import { C as ColdThreadStore } from './cold-store-CFHwemBJ.js';
5
- import { T as ThreadManagerHooks, P as ProviderThreadManager } from './types-L5bvbF-n.js';
3
+ import { a as ModelInvoker, b as PrefixedThreadOps, S as ScopedPrefix, R as RouterContext, c as ToolHandlerResponse, d as ActivityToolHandler } from './types-qQVZfhoT.js';
4
+ import { C as ColdThreadStore } from './cold-store-BDgJpwLI.js';
5
+ import { T as ThreadManagerHooks, P as ProviderThreadManager } from './types-CtdOquo3.js';
6
6
  import { A as ADAPTER_ID } from './adapter-id-BB-mmrts.js';
7
7
 
8
8
  /** SDK-native content type for Google GenAI human messages */
@@ -418,6 +418,94 @@ function createAnthropicThreadManager(config) {
418
418
  };
419
419
  return manager;
420
420
  }
421
+
422
+ // src/adapters/thread/anthropic/prompt-cache.ts
423
+ var DEFAULT_MAX_CACHE_BREAKPOINTS = 4;
424
+ var UNCACHEABLE_BLOCK_TYPES = /* @__PURE__ */ new Set(["thinking", "redacted_thinking"]);
425
+ function resolvePromptCacheOptions(promptCache) {
426
+ if (promptCache === false) return void 0;
427
+ if (promptCache === true || promptCache === void 0) return {};
428
+ return promptCache;
429
+ }
430
+ function addPromptCacheControl(payload, options = {}) {
431
+ const maxBreakpoints = options.maxBreakpoints ?? DEFAULT_MAX_CACHE_BREAKPOINTS;
432
+ if (maxBreakpoints <= 0) return payload;
433
+ if (countCacheControls(payload) >= maxBreakpoints) return payload;
434
+ const cacheControl = {
435
+ type: "ephemeral",
436
+ ttl: options.ttl ?? "5m"
437
+ };
438
+ const messages = addCacheControlToLastMessageBlock(
439
+ payload.messages,
440
+ cacheControl
441
+ );
442
+ if (messages === payload.messages) return payload;
443
+ return { ...payload, messages };
444
+ }
445
+ function addCacheControlToLastMessageBlock(messages, cacheControl) {
446
+ for (let messageIndex = messages.length - 1; messageIndex >= 0; messageIndex--) {
447
+ const message = messages[messageIndex];
448
+ if (!message) continue;
449
+ if (typeof message.content === "string") {
450
+ if (message.content.length === 0) continue;
451
+ return replaceMessage(messages, messageIndex, {
452
+ ...message,
453
+ content: [
454
+ { type: "text", text: message.content, cache_control: cacheControl }
455
+ ]
456
+ });
457
+ }
458
+ if (!Array.isArray(message.content)) continue;
459
+ for (let blockIndex = message.content.length - 1; blockIndex >= 0; blockIndex--) {
460
+ const block = message.content[blockIndex];
461
+ if (!isCacheableContentBlock(block)) continue;
462
+ if (hasCacheControl(block)) return messages;
463
+ const content = [...message.content];
464
+ content[blockIndex] = {
465
+ ...block,
466
+ cache_control: cacheControl
467
+ };
468
+ return replaceMessage(messages, messageIndex, { ...message, content });
469
+ }
470
+ }
471
+ return messages;
472
+ }
473
+ function replaceMessage(messages, index, message) {
474
+ const next = [...messages];
475
+ next[index] = message;
476
+ return next;
477
+ }
478
+ function isCacheableContentBlock(block) {
479
+ if (!isRecord(block)) return false;
480
+ const type = typeof block.type === "string" ? block.type : void 0;
481
+ if (type && UNCACHEABLE_BLOCK_TYPES.has(type)) return false;
482
+ if (type === "text" && block.text === "") return false;
483
+ return true;
484
+ }
485
+ function countCacheControls(payload) {
486
+ let count = 0;
487
+ for (const tool of payload.tools ?? []) {
488
+ if (hasCacheControl(tool)) count++;
489
+ }
490
+ if (Array.isArray(payload.system)) {
491
+ for (const block of payload.system) {
492
+ if (hasCacheControl(block)) count++;
493
+ }
494
+ }
495
+ for (const message of payload.messages) {
496
+ if (!Array.isArray(message.content)) continue;
497
+ for (const block of message.content) {
498
+ if (hasCacheControl(block)) count++;
499
+ }
500
+ }
501
+ return count;
502
+ }
503
+ function hasCacheControl(value) {
504
+ return isRecord(value) && value.cache_control != null;
505
+ }
506
+ function isRecord(value) {
507
+ return typeof value === "object" && value !== null && !Array.isArray(value);
508
+ }
421
509
  function getActivityContext() {
422
510
  try {
423
511
  const ctx = activity.Context.current();
@@ -440,6 +528,7 @@ function createAnthropicModelInvoker({
440
528
  client,
441
529
  model,
442
530
  maxTokens = 16384,
531
+ promptCache,
443
532
  hooks
444
533
  }) {
445
534
  return async function invokeAnthropicModel2(config) {
@@ -452,15 +541,20 @@ function createAnthropicModelInvoker({
452
541
  hooks
453
542
  });
454
543
  await thread.truncateFromId(assistantMessageId);
455
- const { messages, system } = await thread.prepareForInvocation();
544
+ const prepared = await thread.prepareForInvocation();
456
545
  const anthropicTools = toAnthropicTools(state.tools);
457
- const tools = anthropicTools.length > 0 ? anthropicTools : void 0;
546
+ const preparedPayload = {
547
+ ...prepared,
548
+ ...anthropicTools.length > 0 ? { tools: anthropicTools } : {}
549
+ };
550
+ const cacheOptions = resolvePromptCacheOptions(promptCache);
551
+ const payload = cacheOptions ? addPromptCacheControl(preparedPayload, cacheOptions) : preparedPayload;
458
552
  const params = {
459
553
  model,
460
554
  max_tokens: maxTokens,
461
- messages,
462
- ...system ? { system } : {},
463
- ...tools ? { tools } : {}
555
+ messages: payload.messages,
556
+ ...payload.system ? { system: payload.system } : {},
557
+ ...payload.tools ? { tools: payload.tools } : {}
464
558
  };
465
559
  const stream = client.messages.stream(params, { signal });
466
560
  for await (const _event of stream) {
@@ -491,6 +585,7 @@ async function invokeAnthropicModel({
491
585
  client,
492
586
  model,
493
587
  maxTokens,
588
+ promptCache,
494
589
  hooks,
495
590
  config
496
591
  }) {
@@ -499,6 +594,7 @@ async function invokeAnthropicModel({
499
594
  client,
500
595
  model,
501
596
  maxTokens,
597
+ promptCache,
502
598
  hooks
503
599
  });
504
600
  return invoker(config);
@@ -584,13 +680,14 @@ function createAnthropicAdapter(config) {
584
680
  Object.entries(threadOps).map(([k, v]) => [`${prefix}${cap(k)}`, v])
585
681
  );
586
682
  }
587
- const makeInvoker = (model, maxTokens) => {
683
+ const makeInvoker = (model, maxTokens, promptCache) => {
588
684
  const invokerConfig = {
589
685
  redis,
590
686
  client,
591
687
  model,
592
688
  ...maxTokens !== void 0 ? { maxTokens } : {},
593
689
  ...config.maxTokens !== void 0 && maxTokens === void 0 ? { maxTokens: config.maxTokens } : {},
690
+ ...promptCache !== void 0 ? { promptCache } : config.promptCache !== void 0 ? { promptCache: config.promptCache } : {},
594
691
  hooks: config.hooks
595
692
  };
596
693
  return createAnthropicModelInvoker(invokerConfig);
@@ -609,9 +706,11 @@ function createAnthropicAdapter(config) {
609
706
  }
610
707
 
611
708
  exports.ADAPTER_ID = ADAPTER_ID;
709
+ exports.addPromptCacheControl = addPromptCacheControl;
612
710
  exports.createAnthropicAdapter = createAnthropicAdapter;
613
711
  exports.createAnthropicModelInvoker = createAnthropicModelInvoker;
614
712
  exports.createAnthropicThreadManager = createAnthropicThreadManager;
615
713
  exports.invokeAnthropicModel = invokeAnthropicModel;
714
+ exports.resolvePromptCacheOptions = resolvePromptCacheOptions;
616
715
  //# sourceMappingURL=index.cjs.map
617
716
  //# sourceMappingURL=index.cjs.map