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 +1 @@
1
- {"version":3,"sources":["../../../../src/adapters/thread/anthropic/adapter-id.ts","../../../../src/lib/thread/keys.ts","../../../../src/lib/thread/manager.ts","../../../../src/lib/thread/snapshot.ts","../../../../src/lib/thread/tiered.ts","../../../../src/adapters/thread/anthropic/thread-manager.ts","../../../../src/adapters/thread/anthropic/prompt-cache.ts","../../../../src/lib/activity.ts","../../../../src/adapters/thread/anthropic/model-invoker.ts","../../../../src/adapters/thread/anthropic/activities.ts"],"names":["Context","invokeAnthropicModel"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Public adapter identity for the Anthropic thread adapter.\n *\n * This value is wire format — it appears as the prefix for Temporal\n * activity names (e.g. `anthropicCodingAgentInitializeThread`) and must\n * never change, since renaming it would orphan existing persisted\n * threads and break in-flight workflows.\n *\n * Re-exported from `zeitlich/adapters/thread/anthropic` so downstream\n * consumers can use the exact same literal the adapter uses internally,\n * typed as the narrow string literal `\"anthropic\"`.\n */\nexport const ADAPTER_ID = \"anthropic\" as const;\n\n/** Narrow string-literal type for {@link ADAPTER_ID}. */\nexport type AdapterId = typeof ADAPTER_ID;\n","/**\n * Public helpers for zeitlich's Redis thread storage layout.\n *\n * These are the exact string-building primitives zeitlich's internal thread\n * manager uses for every adapter. Downstream consumers that need to read a\n * persisted thread (for evaluation, observability, admin tooling, etc.)\n * should use these helpers rather than reconstructing the key layout by\n * hand — the layout is versioned with this module, so upgrading zeitlich\n * keeps the consumer in sync.\n *\n * The layout is adapter-agnostic: every thread adapter stores messages the\n * same way.\n *\n * @example\n * ```typescript\n * import {\n * getThreadListKey,\n * getThreadMetaKey,\n * THREAD_TTL_SECONDS,\n * } from 'zeitlich';\n *\n * const listKey = getThreadListKey('messages', threadId);\n * const metaKey = getThreadMetaKey('messages', threadId);\n * const ttl = await redis.ttl(listKey); // <= THREAD_TTL_SECONDS\n * ```\n */\n\n/**\n * TTL (in seconds) applied to every thread list and thread meta key that\n * zeitlich's {@link createThreadManager} writes. Exposed so downstream\n * consumers can size their Redis retention / query windows to match.\n *\n * Current value: 90 days.\n */\nexport const THREAD_TTL_SECONDS = 60 * 60 * 24 * 90;\n\n/**\n * Build the Redis list key that holds a thread's serialized messages.\n *\n * Mirrors the exact key used internally by zeitlich's thread manager,\n * so a consumer calling `redis.lrange(getThreadListKey(key, id), 0, -1)`\n * sees the same data the writer wrote.\n *\n * @param threadKey - Thread key (defaults to `\"messages\"` inside the\n * thread manager, but downstream adapters may pass\n * their own value).\n * @param threadId - Thread id as provided to the thread manager.\n */\nexport function getThreadListKey(\n threadKey: string,\n threadId: string\n): string {\n return `${threadKey}:thread:${threadId}`;\n}\n\n/**\n * Build the Redis key that stores a thread's existence marker / metadata.\n *\n * Zeitlich treats the presence of this key as \"thread has been\n * initialized\"; append/load/fork/truncate operations fail when it is\n * missing. Consumers can use it as a cheap existence probe without\n * scanning the message list.\n *\n * @param threadKey - Thread key (defaults to `\"messages\"` inside the\n * thread manager, but downstream adapters may pass\n * their own value).\n * @param threadId - Thread id as provided to the thread manager.\n */\nexport function getThreadMetaKey(\n threadKey: string,\n threadId: string\n): string {\n return `${threadKey}:meta:thread:${threadId}`;\n}\n\n/**\n * Build the Redis key that stores a thread's persisted state slice\n * (tasks + custom state) written by zeitlich's session loop on every\n * exit path.\n *\n * Consumers can read this key with `redis.get(getThreadStateKey(key, id))`\n * and `JSON.parse` the result into a {@link PersistedThreadState}.\n *\n * @param threadKey - Thread key (defaults to `\"messages\"` inside the\n * thread manager, but downstream adapters may pass\n * their own value).\n * @param threadId - Thread id as provided to the thread manager.\n */\nexport function getThreadStateKey(\n threadKey: string,\n threadId: string\n): string {\n return `${threadKey}:state:thread:${threadId}`;\n}\n\n/**\n * Build the Redis key that guards an idempotent append against a\n * duplicate write of the message (or message batch) identified by\n * `dedupId`. Zeitlich's thread manager writes one of these per\n * single-message append (and one per batch for multi-message appends),\n * keyed by the message id returned by the configured `idOf`.\n *\n * Note: the key layout intentionally does **not** include the\n * `threadKey` prefix — the dedup namespace is shared across thread\n * keys for a given `threadId`, mirroring the original internal\n * implementation.\n *\n * @param threadId - Thread id as provided to the thread manager.\n * @param dedupId - Joined message ids (single message id for the\n * common single-append case).\n */\nexport function getThreadDedupKey(threadId: string, dedupId: string): string {\n return `dedup:${dedupId}:thread:${threadId}`;\n}\n","import type { PersistedThreadState } from \"../state/types\";\nimport type { ThreadManagerConfig, BaseThreadManager } from \"./types\";\nimport {\n THREAD_TTL_SECONDS,\n getThreadListKey,\n getThreadMetaKey,\n getThreadStateKey,\n getThreadDedupKey,\n} from \"./keys\";\n\n/**\n * Lua script for atomic idempotent append.\n * Checks a dedup key; if it exists the message was already appended and we\n * return 0. Otherwise appends all messages to the list, sets TTL on both\n * the list and the dedup key, and returns 1.\n *\n * KEYS[1] = dedup key, KEYS[2] = list key\n * ARGV[1] = TTL seconds, ARGV[2..N] = serialised messages\n */\nconst APPEND_IDEMPOTENT_SCRIPT = `\nif redis.call('EXISTS', KEYS[1]) == 1 then\n return 0\nend\nfor i = 2, #ARGV do\n redis.call('RPUSH', KEYS[2], ARGV[i])\nend\nredis.call('EXPIRE', KEYS[2], tonumber(ARGV[1]))\nredis.call('SET', KEYS[1], '1', 'EX', tonumber(ARGV[1]))\nreturn 1\n`;\n\n/**\n * Creates a generic thread manager for handling conversation state in Redis.\n * Framework-agnostic — works with any serializable message type.\n */\nexport function createThreadManager<T>(\n config: ThreadManagerConfig<T>\n): BaseThreadManager<T> {\n const {\n redis,\n threadId,\n key = \"messages\",\n serialize = (m: T): string => JSON.stringify(m),\n deserialize = (raw: string): T => JSON.parse(raw) as T,\n idOf,\n ttlSeconds = THREAD_TTL_SECONDS,\n } = config;\n const redisKey = getThreadListKey(key, threadId);\n const metaKey = getThreadMetaKey(key, threadId);\n const stateKey = getThreadStateKey(key, threadId);\n const dedupKey = (id: string): string => getThreadDedupKey(threadId, id);\n\n async function assertThreadExists(): Promise<void> {\n const exists = await redis.exists(metaKey);\n if (!exists) {\n throw new Error(`Thread \"${threadId}\" (key: ${key}) does not exist`);\n }\n }\n\n return {\n async initialize(): Promise<void> {\n await redis.del(redisKey);\n await redis.set(metaKey, \"1\", \"EX\", ttlSeconds);\n },\n\n async load(): Promise<T[]> {\n await assertThreadExists();\n const data = await redis.lrange(redisKey, 0, -1);\n return data.map(deserialize);\n },\n\n async append(messages: T[]): Promise<void> {\n if (messages.length === 0) return;\n await assertThreadExists();\n\n if (idOf) {\n const dedupId = messages.map(idOf).join(\":\");\n await redis.eval(\n APPEND_IDEMPOTENT_SCRIPT,\n 2,\n dedupKey(dedupId),\n redisKey,\n String(ttlSeconds),\n ...messages.map(serialize)\n );\n } else {\n await redis.rpush(redisKey, ...messages.map(serialize));\n await redis.expire(redisKey, ttlSeconds);\n }\n },\n\n async fork(newThreadId: string): Promise<BaseThreadManager<T>> {\n await assertThreadExists();\n const data = await redis.lrange(redisKey, 0, -1);\n const stateRaw = await redis.get(stateKey);\n const forked = createThreadManager({\n ...config,\n threadId: newThreadId,\n });\n await forked.initialize();\n if (data.length > 0) {\n const newKey = getThreadListKey(key, newThreadId);\n await redis.rpush(newKey, ...data);\n await redis.expire(newKey, ttlSeconds);\n }\n if (stateRaw != null) {\n const newStateKey = getThreadStateKey(key, newThreadId);\n await redis.set(newStateKey, stateRaw, \"EX\", ttlSeconds);\n }\n return forked;\n },\n\n async replaceAll(messages: T[]): Promise<void> {\n await assertThreadExists();\n if (!idOf) {\n throw new Error(\n \"replaceAll requires the thread manager to be configured with `idOf`\"\n );\n }\n const existing = await redis.lrange(redisKey, 0, -1);\n const existingIds = existing\n .map((raw) => idOf(deserialize(raw)))\n .filter((id): id is string => typeof id === \"string\");\n await redis.del(redisKey);\n if (existingIds.length > 0) {\n await redis.del(...existingIds.map(dedupKey));\n }\n if (messages.length > 0) {\n await redis.rpush(redisKey, ...messages.map(serialize));\n await redis.expire(redisKey, ttlSeconds);\n }\n await redis.expire(metaKey, ttlSeconds);\n },\n\n async delete(): Promise<void> {\n await redis.del(redisKey, metaKey, stateKey);\n },\n\n async loadState(): Promise<PersistedThreadState | null> {\n const raw = await redis.get(stateKey);\n if (raw == null) return null;\n return JSON.parse(raw) as PersistedThreadState;\n },\n\n async saveState(state: PersistedThreadState): Promise<void> {\n await assertThreadExists();\n await redis.set(stateKey, JSON.stringify(state), \"EX\", ttlSeconds);\n },\n\n async deleteState(): Promise<void> {\n await redis.del(stateKey);\n },\n\n async length(): Promise<number> {\n await assertThreadExists();\n return redis.llen(redisKey);\n },\n\n async truncateFromId(messageId: string): Promise<void> {\n await assertThreadExists();\n if (!idOf) {\n throw new Error(\n \"truncateFromId requires the thread manager to be configured with `idOf`\"\n );\n }\n const data = await redis.lrange(redisKey, 0, -1);\n let idx = -1;\n const removedIds: string[] = [];\n for (let i = 0; i < data.length; i++) {\n const raw = data[i];\n if (raw === undefined) continue;\n const id = idOf(deserialize(raw));\n if (idx === -1 && id === messageId) idx = i;\n if (idx !== -1) removedIds.push(id);\n }\n if (idx === -1) return;\n if (idx === 0) {\n await redis.del(redisKey);\n await redis.expire(metaKey, ttlSeconds);\n } else {\n await redis.ltrim(redisKey, 0, idx - 1);\n await redis.expire(redisKey, ttlSeconds);\n }\n // Clear dedup markers for the removed messages so that a rewind\n // retry which reuses the same ids (e.g. the same assistantId) can\n // re-append without the idempotent-append Lua script treating it\n // as a duplicate.\n if (removedIds.length > 0) {\n await redis.del(...removedIds.map(dedupKey));\n }\n },\n };\n}\n","/**\n * Pure Redis I/O helpers for moving a thread between the hot tier\n * (Redis lists + meta + state + dedup markers) and the cold tier\n * (a single {@link ThreadSnapshot} blob in a {@link ColdThreadStore}).\n *\n * These helpers know nothing about S3 or the adapter-specific message\n * envelope — they operate on the raw Redis representation. The\n * tiered thread manager in `tiered.ts` is the only consumer.\n */\n\nimport type Redis from \"ioredis\";\nimport type { PersistedThreadState } from \"../state/types\";\nimport type { ThreadSnapshot } from \"./cold-store\";\nimport {\n THREAD_TTL_SECONDS,\n getThreadDedupKey,\n getThreadListKey,\n getThreadMetaKey,\n getThreadStateKey,\n} from \"./keys\";\n\n/** Inputs shared by every snapshot operation. */\ninterface SnapshotCommon {\n redis: Redis;\n threadKey: string;\n threadId: string;\n}\n\n/** Configuration for {@link encodeSnapshot}. */\nexport interface EncodeSnapshotConfig extends SnapshotCommon {\n /**\n * Extract a dedup id from each raw-serialized message currently in\n * the thread's Redis list. When omitted, the resulting snapshot has\n * an empty `dedupIds` array — idempotency guarantees are best-effort\n * once a thread crosses the hot/cold boundary.\n */\n idOf?: (raw: string) => string;\n}\n\n/**\n * Build a {@link ThreadSnapshot} from the current hot-tier state.\n *\n * Returns `null` when no thread exists in the hot tier (the meta key\n * is absent) — callers should treat that as \"nothing to flush\".\n */\nexport async function encodeSnapshot(\n config: EncodeSnapshotConfig\n): Promise<ThreadSnapshot | null> {\n const { redis, threadKey, threadId, idOf } = config;\n const metaKey = getThreadMetaKey(threadKey, threadId);\n if ((await redis.exists(metaKey)) === 0) {\n return null;\n }\n const listKey = getThreadListKey(threadKey, threadId);\n const stateKey = getThreadStateKey(threadKey, threadId);\n const messages = await redis.lrange(listKey, 0, -1);\n const stateRaw = await redis.get(stateKey);\n const state =\n stateRaw == null ? null : (JSON.parse(stateRaw) as PersistedThreadState);\n const dedupIds = idOf ? messages.map(idOf) : [];\n return { v: 1, messages, state, dedupIds };\n}\n\n/** Configuration for {@link applySnapshot}. */\nexport interface ApplySnapshotConfig extends SnapshotCommon {\n snapshot: ThreadSnapshot;\n /** TTL applied to every Redis key. Defaults to {@link THREAD_TTL_SECONDS}. */\n ttlSeconds?: number;\n}\n\n/**\n * Restore a {@link ThreadSnapshot} into the hot tier.\n *\n * Idempotent — if the meta key already exists the thread is already\n * hot and this is a no-op. The meta key is written **last** so a\n * crash mid-restore leaves the thread cold (`load` / `append` will\n * see \"thread does not exist\") and the next session's hydrate retries\n * cleanly.\n */\nexport async function applySnapshot(\n config: ApplySnapshotConfig\n): Promise<void> {\n const {\n redis,\n threadKey,\n threadId,\n snapshot,\n ttlSeconds = THREAD_TTL_SECONDS,\n } = config;\n const metaKey = getThreadMetaKey(threadKey, threadId);\n if ((await redis.exists(metaKey)) === 1) {\n return;\n }\n const listKey = getThreadListKey(threadKey, threadId);\n const stateKey = getThreadStateKey(threadKey, threadId);\n\n // Clear partial residue from any prior half-restored attempt.\n // Awaited *outside* the pipeline so a DEL failure (ACL deny,\n // CROSSSLOT, …) short-circuits before any writes hit the wire —\n // pipelines are non-atomic, so a queued DEL wouldn't stop later\n // commands from accumulating data behind a missing meta marker.\n await redis.del(listKey, stateKey);\n\n // Pipeline the data writes (list/state/dedup) in one round-trip.\n // Meta is written separately, only after every queued command\n // succeeded, preserving the \"meta-last\" crash-safety invariant —\n // a partial restore must leave meta absent so the next hydrate\n // retries cleanly.\n const pipeline = redis.pipeline();\n if (snapshot.messages.length > 0) {\n pipeline.rpush(listKey, ...snapshot.messages);\n pipeline.expire(listKey, ttlSeconds);\n }\n if (snapshot.state != null) {\n pipeline.set(stateKey, JSON.stringify(snapshot.state), \"EX\", ttlSeconds);\n }\n for (const id of snapshot.dedupIds) {\n pipeline.set(getThreadDedupKey(threadId, id), \"1\", \"EX\", ttlSeconds);\n }\n const results = await pipeline.exec();\n if (results) {\n const firstErr = results.find(([err]) => err)?.[0] ?? null;\n if (firstErr) {\n // Compensate: pipelines are non-atomic, so writes queued after\n // a failing command (notably dedup SETs) may have landed. Best-\n // effort clear every key we touched so a leftover dedup marker\n // can't silently skip a future append with the same id.\n await redis\n .del(\n listKey,\n stateKey,\n ...snapshot.dedupIds.map((id) => getThreadDedupKey(threadId, id))\n )\n .catch(() => undefined);\n throw firstErr;\n }\n }\n await redis.set(metaKey, \"1\", \"EX\", ttlSeconds);\n}\n\n/** Configuration for {@link clearHotTier}. */\nexport interface ClearHotTierConfig extends SnapshotCommon {\n /** Dedup ids to delete alongside the list / meta / state keys. */\n dedupIds?: string[];\n}\n\n/**\n * Delete every Redis key the thread manager wrote for `(threadKey,\n * threadId)`. Used by the tiered manager's `flush({ deleteHot: true })`\n * to drop hot-tier memory after a successful archive write.\n */\nexport async function clearHotTier(\n config: ClearHotTierConfig\n): Promise<void> {\n const { redis, threadKey, threadId, dedupIds = [] } = config;\n const keys = [\n getThreadListKey(threadKey, threadId),\n getThreadMetaKey(threadKey, threadId),\n getThreadStateKey(threadKey, threadId),\n ...dedupIds.map((id) => getThreadDedupKey(threadId, id)),\n ];\n await redis.del(...keys);\n}\n","/**\n * Tiered thread manager: Redis hot tier + pluggable cold tier.\n *\n * Wraps {@link createThreadManager} (Redis-only) and adds two\n * session-boundary operations:\n *\n * - `hydrate()` — when the thread is cold (no meta key in Redis),\n * restore the latest {@link ThreadSnapshot} from the cold store.\n * Idempotent; no-op when the thread is already hot or when no\n * snapshot exists.\n * - `flush({ deleteHot })` — write the current Redis state out to the\n * cold store as one snapshot, then (by default) `DEL` the hot-tier\n * keys so idle threads don't sit in Redis memory.\n *\n * All other operations (`append`, `load`, `fork`, `replaceAll`,\n * `truncateFromId`, state I/O) delegate unchanged to the underlying\n * Redis manager, so adapters and tests that use the\n * `BaseThreadManager<T>` interface keep working with zero changes.\n */\n\nimport { createThreadManager } from \"./manager\";\nimport { THREAD_TTL_SECONDS } from \"./keys\";\nimport type { BaseThreadManager, ThreadManagerConfig } from \"./types\";\nimport type { ColdThreadStore } from \"./cold-store\";\nimport {\n applySnapshot,\n clearHotTier,\n encodeSnapshot,\n} from \"./snapshot\";\n\n/** Configuration for {@link createTieredThreadManager}. */\nexport interface TieredThreadManagerConfig<T> extends ThreadManagerConfig<T> {\n /**\n * Cold-tier archive. When omitted, `hydrate()` and `flush()` are\n * no-ops and the manager behaves identically to\n * {@link createThreadManager}.\n */\n coldStore?: ColdThreadStore;\n}\n\n/** Options for {@link TieredThreadManager.flush}. */\nexport interface FlushOptions {\n /**\n * Delete the hot-tier Redis keys after a successful cold-tier\n * write. Defaults to `true` when a cold store is configured —\n * Redis is just a cache and a future continue/fork will\n * re-hydrate in a single round-trip.\n *\n * Set to `false` to keep the hot tier warm (useful for tests or\n * for \"hot-after-flush\" use cases where another session is expected\n * to pick the thread up immediately).\n */\n deleteHot?: boolean;\n}\n\n/**\n * Extension of {@link BaseThreadManager} with the two cold-tier\n * lifecycle methods.\n */\nexport interface TieredThreadManager<T> extends BaseThreadManager<T> {\n /**\n * Restore the latest cold-tier snapshot into Redis when the thread\n * is cold. Idempotent — safe to call from a retried activity.\n */\n hydrate(): Promise<void>;\n /**\n * Write the current Redis state to the cold tier and (optionally)\n * drop the hot-tier keys. Idempotent — last-writer-wins on the\n * cold side.\n */\n flush(opts?: FlushOptions): Promise<void>;\n}\n\n/**\n * Build a thread manager backed by Redis (hot) and an optional\n * pluggable cold store. See module docstring for the lifecycle\n * semantics.\n */\nexport function createTieredThreadManager<T>(\n config: TieredThreadManagerConfig<T>\n): TieredThreadManager<T> {\n const {\n redis,\n threadId,\n key = \"messages\",\n coldStore,\n idOf,\n deserialize = (raw: string): T => JSON.parse(raw) as T,\n ttlSeconds = THREAD_TTL_SECONDS,\n } = config;\n\n const base = createThreadManager<T>(config);\n\n // Snapshot-time `idOf` operates on raw Redis strings — we deserialize\n // here and forward to the configured (deserialized) `idOf`.\n const rawIdOf = idOf\n ? (raw: string): string => idOf(deserialize(raw))\n : undefined;\n\n return Object.assign(base, {\n async hydrate(): Promise<void> {\n if (!coldStore) return;\n const snapshot = await coldStore.read(key, threadId);\n if (!snapshot) return;\n await applySnapshot({\n redis,\n threadKey: key,\n threadId,\n snapshot,\n ttlSeconds,\n });\n },\n\n async flush(opts?: FlushOptions): Promise<void> {\n if (!coldStore) return;\n const snapshot = await encodeSnapshot({\n redis,\n threadKey: key,\n threadId,\n ...(rawIdOf ? { idOf: rawIdOf } : {}),\n });\n if (!snapshot) return;\n await coldStore.write(key, threadId, snapshot);\n const deleteHot = opts?.deleteHot ?? true;\n if (deleteHot) {\n await clearHotTier({\n redis,\n threadKey: key,\n threadId,\n dedupIds: snapshot.dedupIds,\n });\n }\n },\n });\n}\n","import type Redis from \"ioredis\";\nimport type Anthropic from \"@anthropic-ai/sdk\";\nimport type { JsonValue } from \"../../../lib/state/types\";\nimport { createThreadManager } from \"../../../lib/thread/manager\";\nimport type {\n ProviderThreadManager,\n ThreadManagerConfig,\n ThreadManagerHooks,\n} from \"../../../lib/thread/types\";\n\n/** SDK-native content type for Anthropic human messages */\nexport type AnthropicContent = string | Anthropic.Messages.ContentBlockParam[];\n\n/** SDK-native content type for Anthropic system prompts (supports cache_control blocks) */\nexport type AnthropicSystemContent =\n | string\n | Anthropic.Messages.TextBlockParam[];\n\n/** A MessageParam with a unique ID for idempotent Redis storage */\nexport interface StoredMessage {\n id: string;\n message: Anthropic.Messages.MessageParam;\n /** System messages are stored separately since Anthropic passes them via config */\n isSystem?: boolean;\n}\n\nexport type AnthropicThreadManagerHooks = ThreadManagerHooks<\n StoredMessage,\n Anthropic.Messages.MessageParam\n>;\n\nexport interface AnthropicThreadManagerConfig {\n redis: Redis;\n threadId: string;\n /** Thread key, defaults to 'messages' */\n key?: string;\n hooks?: AnthropicThreadManagerHooks;\n /**\n * Override the default thread TTL (90 days). When pairing the\n * adapter with a durable cold tier, a shorter TTL (hours) is\n * typically more appropriate.\n */\n ttlSeconds?: number;\n}\n\n/** Prepared payload ready to send to the Anthropic API */\nexport interface AnthropicInvocationPayload {\n messages: Anthropic.Messages.MessageParam[];\n system?: string | Anthropic.Messages.TextBlockParam[];\n}\n\n/** Thread manager with Anthropic MessageParam convenience helpers */\nexport interface AnthropicThreadManager extends ProviderThreadManager<\n StoredMessage,\n AnthropicContent,\n JsonValue,\n AnthropicSystemContent\n> {\n appendAssistantMessage(\n id: string,\n content: Anthropic.Messages.ContentBlock[]\n ): Promise<void>;\n prepareForInvocation(): Promise<AnthropicInvocationPayload>;\n}\n\n/** Extract the unique id from a {@link StoredMessage}. */\nexport function storedMessageId(msg: StoredMessage): string {\n return msg.id;\n}\n\n/** Normalise content into an array of ContentBlockParam */\nfunction toContentBlocks(\n content: AnthropicContent\n): Anthropic.Messages.ContentBlockParam[] {\n if (typeof content === \"string\") {\n return [{ type: \"text\", text: content }];\n }\n return content;\n}\n\n/**\n * Merge consecutive messages with the same role.\n * The Anthropic API requires alternating user/assistant turns; without\n * merging, multiple sequential tool-result messages would violate this.\n */\nfunction mergeConsecutiveMessages(\n messages: Anthropic.Messages.MessageParam[]\n): Anthropic.Messages.MessageParam[] {\n const merged: Anthropic.Messages.MessageParam[] = [];\n for (const msg of messages) {\n const last = merged[merged.length - 1];\n if (last && last.role === msg.role) {\n const lastContent = Array.isArray(last.content)\n ? last.content\n : [{ type: \"text\" as const, text: last.content }];\n const msgContent = Array.isArray(msg.content)\n ? msg.content\n : [{ type: \"text\" as const, text: msg.content }];\n last.content = [...lastContent, ...msgContent];\n } else {\n merged.push({\n ...msg,\n content: Array.isArray(msg.content) ? [...msg.content] : msg.content,\n });\n }\n }\n return merged;\n}\n\n/**\n * Creates an Anthropic-specific thread manager that stores StoredMessage\n * instances in Redis and provides convenience helpers for creating and\n * appending typed messages.\n */\nexport function createAnthropicThreadManager(\n config: AnthropicThreadManagerConfig\n): AnthropicThreadManager {\n const baseConfig: ThreadManagerConfig<StoredMessage> = {\n redis: config.redis,\n threadId: config.threadId,\n key: config.key,\n idOf: storedMessageId,\n ...(config.ttlSeconds !== undefined && { ttlSeconds: config.ttlSeconds }),\n };\n\n const base = createThreadManager(baseConfig);\n\n const helpers: Omit<AnthropicThreadManager, keyof typeof base> = {\n async appendUserMessage(\n id: string,\n content: AnthropicContent\n ): Promise<void> {\n await base.append([\n {\n id,\n message: { role: \"user\", content: toContentBlocks(content) },\n },\n ]);\n },\n\n async appendSystemMessage(\n id: string,\n content: AnthropicSystemContent\n ): Promise<void> {\n await base.initialize();\n await base.append([\n {\n id,\n // Stored under a user-role placeholder to satisfy the MessageParam\n // shape; the `isSystem` flag steers extraction in prepareForInvocation.\n message: {\n role: \"user\",\n content: content as Anthropic.Messages.MessageParam[\"content\"],\n },\n isSystem: true,\n },\n ]);\n },\n\n async appendAssistantMessage(\n id: string,\n content: Anthropic.Messages.ContentBlock[]\n ): Promise<void> {\n await base.append([\n {\n id,\n message: {\n role: \"assistant\",\n content:\n content as unknown as Anthropic.Messages.ContentBlockParam[],\n },\n },\n ]);\n },\n\n async appendToolResult(\n id: string,\n toolCallId: string,\n _toolName: string,\n content: JsonValue\n ): Promise<void> {\n const toolContent =\n typeof content === \"string\"\n ? content\n : Array.isArray(content)\n ? (content as unknown as Anthropic.Messages.ToolResultBlockParam[\"content\"])\n : JSON.stringify(content);\n await base.append([\n {\n id,\n message: {\n role: \"user\",\n content: [\n {\n type: \"tool_result\" as const,\n tool_use_id: toolCallId,\n content: toolContent,\n },\n ],\n },\n },\n ]);\n },\n\n async prepareForInvocation(): Promise<AnthropicInvocationPayload> {\n const stored = await base.load();\n const { onPrepareMessage, onPreparedMessage } = config.hooks ?? {};\n const mapped = onPrepareMessage\n ? stored.map((msg, i) => onPrepareMessage(msg, i, stored))\n : stored;\n\n let system: string | Anthropic.Messages.TextBlockParam[] | undefined;\n const conversationMessages: Anthropic.Messages.MessageParam[] = [];\n\n for (const item of mapped) {\n if (item.isSystem) {\n system = item.message.content as\n | string\n | Anthropic.Messages.TextBlockParam[];\n } else {\n conversationMessages.push(item.message);\n }\n }\n\n const messages = mergeConsecutiveMessages(conversationMessages);\n return {\n messages: onPreparedMessage\n ? messages.map((msg, i) => onPreparedMessage(msg, i, messages))\n : messages,\n ...(system ? { system } : {}),\n };\n },\n };\n\n const manager = Object.assign(base, helpers);\n\n const originalFork = manager.fork.bind(manager);\n manager.fork = async (\n newThreadId: string\n ): Promise<AnthropicThreadManager> => {\n await originalFork(newThreadId);\n const forked = createAnthropicThreadManager({\n ...config,\n threadId: newThreadId,\n });\n const { onForkPrepareThread, onForkTransform } = config.hooks ?? {};\n if (!onForkPrepareThread && !onForkTransform) {\n return forked;\n }\n let next = await forked.load();\n if (onForkPrepareThread) {\n next = await onForkPrepareThread(next);\n }\n if (onForkTransform) {\n next = next.map((msg, i) => onForkTransform(msg, i, next));\n }\n await forked.replaceAll(next);\n return forked;\n };\n\n return manager;\n}\n","import type Anthropic from \"@anthropic-ai/sdk\";\n\nexport interface AnthropicPromptCacheOptions {\n /** TTL for the cache checkpoint. Defaults to 5m. */\n ttl?: Anthropic.Messages.CacheControlEphemeral[\"ttl\"];\n /** Claude models support at most 4 cache breakpoints per request. */\n maxBreakpoints?: number;\n}\n\nexport type AnthropicPromptCacheConfig = boolean | AnthropicPromptCacheOptions;\n\ninterface PromptCachePayload {\n messages: Anthropic.Messages.MessageParam[];\n system?: string | Anthropic.Messages.TextBlockParam[];\n tools?: Anthropic.Messages.Tool[];\n}\n\ntype CacheControl = Anthropic.Messages.CacheControlEphemeral;\ntype CacheableRecord = Record<string, unknown> & {\n cache_control?: CacheControl | null;\n};\n\nconst DEFAULT_MAX_CACHE_BREAKPOINTS = 4;\nconst UNCACHEABLE_BLOCK_TYPES = new Set([\"thinking\", \"redacted_thinking\"]);\n\n/**\n * Resolve model-invoker prompt-cache config. Undefined means the default:\n * enabled with an explicit 5 minute TTL.\n */\nexport function resolvePromptCacheOptions(\n promptCache?: AnthropicPromptCacheConfig\n): AnthropicPromptCacheOptions | undefined {\n if (promptCache === false) return undefined;\n if (promptCache === true || promptCache === undefined) return {};\n return promptCache;\n}\n\n/**\n * Add an explicit `cache_control` marker to the final cacheable message block.\n *\n * This intentionally uses block-level cache control rather than Anthropic's\n * top-level automatic `cache_control` field because Amazon Bedrock does not\n * support the top-level form. The block-level shape is accepted by both the\n * Anthropic Messages API and Bedrock InvokeModel for Anthropic Claude models.\n */\nexport function addPromptCacheControl<TPayload extends PromptCachePayload>(\n payload: TPayload,\n options: AnthropicPromptCacheOptions = {}\n): TPayload {\n const maxBreakpoints =\n options.maxBreakpoints ?? DEFAULT_MAX_CACHE_BREAKPOINTS;\n if (maxBreakpoints <= 0) return payload;\n\n if (countCacheControls(payload) >= maxBreakpoints) return payload;\n\n const cacheControl: CacheControl = {\n type: \"ephemeral\",\n ttl: options.ttl ?? \"5m\",\n };\n const messages = addCacheControlToLastMessageBlock(\n payload.messages,\n cacheControl\n );\n\n if (messages === payload.messages) return payload;\n return { ...payload, messages };\n}\n\nfunction addCacheControlToLastMessageBlock(\n messages: Anthropic.Messages.MessageParam[],\n cacheControl: CacheControl\n): Anthropic.Messages.MessageParam[] {\n for (\n let messageIndex = messages.length - 1;\n messageIndex >= 0;\n messageIndex--\n ) {\n const message = messages[messageIndex];\n if (!message) continue;\n\n if (typeof message.content === \"string\") {\n if (message.content.length === 0) continue;\n return replaceMessage(messages, messageIndex, {\n ...message,\n content: [\n { type: \"text\", text: message.content, cache_control: cacheControl },\n ],\n });\n }\n\n if (!Array.isArray(message.content)) continue;\n\n for (\n let blockIndex = message.content.length - 1;\n blockIndex >= 0;\n blockIndex--\n ) {\n const block = message.content[blockIndex];\n if (!isCacheableContentBlock(block)) continue;\n if (hasCacheControl(block)) return messages;\n\n const content = [...message.content];\n content[blockIndex] = {\n ...(block as Record<string, unknown>),\n cache_control: cacheControl,\n } as Anthropic.Messages.ContentBlockParam;\n return replaceMessage(messages, messageIndex, { ...message, content });\n }\n }\n\n return messages;\n}\n\nfunction replaceMessage(\n messages: Anthropic.Messages.MessageParam[],\n index: number,\n message: Anthropic.Messages.MessageParam\n): Anthropic.Messages.MessageParam[] {\n const next = [...messages];\n next[index] = message;\n return next;\n}\n\nfunction isCacheableContentBlock(\n block: Anthropic.Messages.ContentBlockParam | undefined\n): block is Anthropic.Messages.ContentBlockParam & CacheableRecord {\n if (!isRecord(block)) return false;\n const type = typeof block.type === \"string\" ? block.type : undefined;\n if (type && UNCACHEABLE_BLOCK_TYPES.has(type)) return false;\n if (type === \"text\" && block.text === \"\") return false;\n return true;\n}\n\nfunction countCacheControls(payload: PromptCachePayload): number {\n let count = 0;\n\n for (const tool of payload.tools ?? []) {\n if (hasCacheControl(tool)) count++;\n }\n\n if (Array.isArray(payload.system)) {\n for (const block of payload.system) {\n if (hasCacheControl(block)) count++;\n }\n }\n\n for (const message of payload.messages) {\n if (!Array.isArray(message.content)) continue;\n for (const block of message.content) {\n if (hasCacheControl(block)) count++;\n }\n }\n\n return count;\n}\n\nfunction hasCacheControl(value: unknown): value is CacheableRecord {\n return isRecord(value) && value.cache_control != null;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n","import { Context } from \"@temporalio/activity\";\nimport type { WorkflowClient } from \"@temporalio/client\";\nimport type { BaseAgentState, RunAgentConfig } from \"./types\";\nimport type { JsonValue } from \"./state/types\";\nimport type {\n ActivityToolHandler,\n RouterContext,\n ToolHandlerResponse,\n} from \"./tool-router/types\";\n\n/**\n * Safely retrieve Temporal activity heartbeat and cancellation signal.\n * Returns empty object when called outside a Temporal activity (e.g. tests).\n */\nexport function getActivityContext(): {\n heartbeat?: () => void;\n signal?: AbortSignal;\n} {\n try {\n const ctx = Context.current();\n return { heartbeat: () => ctx.heartbeat(), signal: ctx.cancellationSignal };\n } catch {\n return {};\n }\n}\n\n/**\n * Query the parent workflow's state from within an activity.\n * Resolves the workflow handle from the current activity context.\n */\nexport async function queryParentWorkflowState<T>(\n client: WorkflowClient\n): Promise<T> {\n const { workflowExecution } = Context.current().info;\n\n if (!workflowExecution) {\n throw new Error(\"No workflow execution found\");\n }\n\n const handle = client.getHandle(\n workflowExecution.workflowId,\n workflowExecution.runId\n );\n return handle.query<T>(\"getAgentState\");\n}\n\n/**\n * Wraps a handler into a scope-prefixed `RunAgentActivity` by auto-fetching\n * the parent workflow's agent state before each invocation.\n *\n * Returns a `Record` with a single key `run<Scope>` so it can be spread\n * into the activities object alongside adapter activities.\n *\n * @param scope - Workflow scope used to derive the activity name.\n * `\"myAgentWorkflow\"` produces `{ runMyAgentWorkflow: fn }`.\n *\n * @example\n * ```typescript\n * import { createRunAgentActivity } from 'zeitlich';\n *\n * return {\n * ...adapter.createActivities(\"myAgentWorkflow\"),\n * ...createRunAgentActivity(client, adapter.invoker, \"myAgentWorkflow\"),\n * };\n * ```\n */\nexport function createRunAgentActivity<\n R,\n S extends BaseAgentState = BaseAgentState,\n>(\n client: WorkflowClient,\n handler: (config: RunAgentConfig & { state: S }) => Promise<R>,\n scope: string\n): Record<string, (config: RunAgentConfig) => Promise<R>> {\n const name = `run${scope.charAt(0).toUpperCase()}${scope.slice(1)}`;\n return {\n [name]: async (config: RunAgentConfig) => {\n const state = await queryParentWorkflowState<S>(client);\n return handler({ ...config, state });\n },\n };\n}\n\n/**\n * Context injected into tool handlers created via {@link withParentWorkflowState}.\n */\nexport interface AgentStateContext<\n S extends BaseAgentState = BaseAgentState,\n> extends RouterContext {\n state: S;\n}\n\n/**\n * Wraps a tool handler into an `ActivityToolHandler` by auto-fetching the\n * parent workflow's agent state before each invocation.\n *\n * @typeParam S - Custom agent state type (defaults to `BaseAgentState`)\n *\n * @example\n * ```typescript\n * import { withParentWorkflowState, type AgentStateContext } from 'zeitlich';\n *\n * // With custom state:\n * interface MyState extends BaseAgentState { customField: string }\n * const myHandler = withParentWorkflowState<MyArgs, MyResult, MyState>(\n * client,\n * async (args, ctx) => {\n * console.log(ctx.state.customField);\n * return { toolResponse: 'done', data: null };\n * },\n * );\n * ```\n */\nexport function withParentWorkflowState<\n TArgs,\n TResult,\n S extends BaseAgentState = BaseAgentState,\n TToolResponse = JsonValue,\n>(\n client: WorkflowClient,\n handler: (\n args: TArgs,\n context: AgentStateContext<S>\n ) => Promise<ToolHandlerResponse<TResult, TToolResponse>>\n): ActivityToolHandler<TArgs, TResult, RouterContext, TToolResponse> {\n return async (args, context) => {\n const state = await queryParentWorkflowState<S>(client);\n return handler(args, { ...context, state });\n };\n}\n","import type Redis from \"ioredis\";\nimport type Anthropic from \"@anthropic-ai/sdk\";\nimport type { SerializableToolDefinition } from \"../../../lib/types\";\nimport type { AgentResponse, ModelInvokerConfig } from \"../../../lib/model\";\nimport {\n createAnthropicThreadManager,\n type AnthropicThreadManagerHooks,\n} from \"./thread-manager\";\nimport {\n addPromptCacheControl,\n resolvePromptCacheOptions,\n type AnthropicPromptCacheConfig,\n} from \"./prompt-cache\";\nimport { getActivityContext } from \"../../../lib/activity\";\n\nexport interface AnthropicModelInvokerConfig {\n redis: Redis;\n client: Anthropic;\n model: string;\n /** Maximum tokens to generate. Defaults to 16384. */\n maxTokens?: number;\n /**\n * Controls Anthropic/Bedrock-compatible prompt caching. Defaults to enabled\n * with an explicit 5 minute TTL. Set to `false` to disable.\n */\n promptCache?: AnthropicPromptCacheConfig;\n hooks?: AnthropicThreadManagerHooks;\n}\n\nfunction toAnthropicTools(\n tools: SerializableToolDefinition[]\n): Anthropic.Messages.Tool[] {\n return tools.map((t) => ({\n name: t.name,\n description: t.description,\n input_schema: t.schema as Anthropic.Messages.Tool.InputSchema,\n }));\n}\n\n/**\n * Creates an Anthropic model invoker that satisfies the generic\n * `ModelInvoker<Anthropic.Messages.Message>` contract.\n *\n * Internally streams the response and emits Temporal heartbeats on each\n * event so that long-running LLM calls remain visible to the scheduler.\n * The caller is responsible for appending the response to the thread.\n *\n * @example\n * ```typescript\n * import { createAnthropicModelInvoker } from 'zeitlich/adapters/thread/anthropic';\n * import { createRunAgentActivity } from 'zeitlich';\n * import Anthropic from '@anthropic-ai/sdk';\n *\n * const client = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY });\n * const invoker = createAnthropicModelInvoker({\n * redis,\n * client,\n * model: 'claude-sonnet-4-20250514',\n * });\n *\n * return { ...createRunAgentActivity(client, invoker, \"myAgent\") };\n * ```\n */\nexport function createAnthropicModelInvoker({\n redis,\n client,\n model,\n maxTokens = 16384,\n promptCache,\n hooks,\n}: AnthropicModelInvokerConfig) {\n return async function invokeAnthropicModel(\n config: ModelInvokerConfig\n ): Promise<AgentResponse<Anthropic.Messages.Message>> {\n const { threadId, threadKey, state, assistantMessageId } = config;\n const { heartbeat, signal } = getActivityContext();\n\n const thread = createAnthropicThreadManager({\n redis,\n threadId,\n key: threadKey,\n hooks,\n });\n // Truncate the thread starting at the id the assistant message\n // will be stored under. On the happy path this is a no-op; on a\n // rewind retry or a Temporal workflow reset it wipes the prior\n // attempt's assistant + tool results so the LLM sees the same\n // pre-call state that it saw originally.\n await thread.truncateFromId(assistantMessageId);\n const prepared = await thread.prepareForInvocation();\n\n const anthropicTools = toAnthropicTools(state.tools);\n const preparedPayload = {\n ...prepared,\n ...(anthropicTools.length > 0 ? { tools: anthropicTools } : {}),\n };\n const cacheOptions = resolvePromptCacheOptions(promptCache);\n const payload = cacheOptions\n ? addPromptCacheControl(preparedPayload, cacheOptions)\n : preparedPayload;\n\n const params: Anthropic.MessageCreateParams = {\n model,\n max_tokens: maxTokens,\n messages: payload.messages,\n ...(payload.system ? { system: payload.system } : {}),\n ...(payload.tools ? { tools: payload.tools } : {}),\n };\n\n const stream = client.messages.stream(params, { signal });\n\n for await (const _event of stream) {\n heartbeat?.();\n }\n\n const response: Anthropic.Messages.Message = await stream.finalMessage();\n\n const toolCalls = response.content.filter(\n (block): block is Anthropic.Messages.ToolUseBlock =>\n block.type === \"tool_use\"\n );\n\n return {\n message: response,\n rawToolCalls: toolCalls.map((tc) => ({\n id: tc.id,\n name: tc.name,\n args: (tc.input as Record<string, unknown>) ?? {},\n })),\n usage: {\n inputTokens: response.usage.input_tokens,\n outputTokens: response.usage.output_tokens,\n cachedWriteTokens:\n response.usage.cache_creation_input_tokens ?? undefined,\n cachedReadTokens: response.usage.cache_read_input_tokens ?? undefined,\n },\n };\n };\n}\n\n/**\n * Standalone function for one-shot Anthropic model invocation.\n * Convenience wrapper around createAnthropicModelInvoker for cases\n * where you don't need to reuse the invoker.\n */\nexport async function invokeAnthropicModel({\n redis,\n client,\n model,\n maxTokens,\n promptCache,\n hooks,\n config,\n}: {\n redis: Redis;\n client: Anthropic;\n model: string;\n maxTokens?: number;\n promptCache?: AnthropicPromptCacheConfig;\n hooks?: AnthropicThreadManagerHooks;\n config: ModelInvokerConfig;\n}): Promise<AgentResponse<Anthropic.Messages.Message>> {\n const invoker = createAnthropicModelInvoker({\n redis,\n client,\n model,\n maxTokens,\n promptCache,\n hooks,\n });\n return invoker(config);\n}\n","import type Redis from \"ioredis\";\nimport type Anthropic from \"@anthropic-ai/sdk\";\nimport type { ToolResultConfig } from \"../../../lib/types\";\nimport type { PersistedThreadState } from \"../../../lib/state/types\";\nimport type {\n ActivityToolHandler,\n RouterContext,\n ToolHandlerResponse,\n} from \"../../../lib/tool-router/types\";\nimport type {\n ThreadOps,\n PrefixedThreadOps,\n ScopedPrefix,\n} from \"../../../lib/session/types\";\nimport type { ModelInvoker } from \"../../../lib/model\";\nimport { createTieredThreadManager } from \"../../../lib/thread/tiered\";\nimport type { ColdThreadStore } from \"../../../lib/thread/cold-store\";\nimport {\n createAnthropicThreadManager,\n storedMessageId,\n type AnthropicContent,\n type AnthropicSystemContent,\n type AnthropicThreadManagerHooks,\n type StoredMessage,\n} from \"./thread-manager\";\nimport {\n createAnthropicModelInvoker,\n type AnthropicModelInvokerConfig,\n} from \"./model-invoker\";\nimport type { AnthropicPromptCacheConfig } from \"./prompt-cache\";\nimport { ADAPTER_ID } from \"./adapter-id\";\n\nexport type AnthropicThreadOps<TScope extends string = \"\"> = PrefixedThreadOps<\n ScopedPrefix<TScope, typeof ADAPTER_ID>,\n AnthropicContent\n>;\n\nexport interface AnthropicAdapterConfig {\n redis: Redis;\n client: Anthropic;\n /** Default model name (e.g. 'claude-sonnet-4-20250514'). If omitted, use `createModelInvoker()` */\n model?: string;\n /** Maximum tokens to generate. Defaults to 16384. */\n maxTokens?: number;\n /**\n * Controls Anthropic/Bedrock-compatible prompt caching. Defaults to enabled\n * with an explicit 5 minute TTL. Set to `false` to disable.\n */\n promptCache?: AnthropicPromptCacheConfig;\n hooks?: AnthropicThreadManagerHooks;\n /**\n * Optional durable cold tier (e.g. S3, R2, GCS). When provided,\n * the session will hydrate the thread from cold storage on entry\n * (`continue`/`fork` modes) and flush it back on every exit path.\n * When omitted, the adapter is Redis-only and `hydrateThread`/\n * `flushThread` activities are no-ops.\n */\n coldStore?: ColdThreadStore;\n /**\n * Override the default Redis TTL (90 days) for thread keys. When\n * pairing the adapter with a `coldStore`, a shorter TTL (hours)\n * is typically more appropriate.\n */\n ttlSeconds?: number;\n}\n\n/**\n * Tool response type accepted by the Anthropic adapter.\n *\n * Handlers can return:\n * - **`string`** — plain text content for the tool result.\n * - **`Anthropic.Messages.ToolResultBlockParam[\"content\"]`** — array of content blocks\n * (e.g. `{ type: \"text\", text: \"...\" }`, `{ type: \"image\", source: { ... } }`).\n * Passed through as-is to the `tool_result` block.\n */\nexport type AnthropicToolResponse =\n Anthropic.Messages.ToolResultBlockParam[\"content\"];\n\nexport interface AnthropicAdapter {\n /** Model invoker using the default model (only available when `model` was provided) */\n invoker: ModelInvoker<Anthropic.Messages.Message>;\n /** Create an invoker for a specific model name (for multi-model setups) */\n createModelInvoker(\n model: string,\n maxTokens?: number,\n promptCache?: AnthropicPromptCacheConfig\n ): ModelInvoker<Anthropic.Messages.Message>;\n /**\n * Create prefixed thread activities for registration on the worker.\n *\n * @param scope - Workflow name appended to the adapter prefix.\n * Use different scopes for the main agent vs subagents to avoid collisions.\n *\n * @example\n * ```typescript\n * adapter.createActivities(\"codingAgent\")\n * // → { anthropicCodingAgentInitializeThread, anthropicCodingAgentAppendHumanMessage, … }\n *\n * adapter.createActivities(\"researchAgent\")\n * // → { anthropicResearchAgentInitializeThread, … }\n * ```\n */\n createActivities<S extends string = \"\">(scope?: S): AnthropicThreadOps<S>;\n\n /**\n * Identity wrapper that types a tool handler for this adapter.\n * Constrains `toolResponse` to {@link AnthropicToolResponse}.\n */\n wrapHandler<TArgs, TResult, TContext extends RouterContext = RouterContext>(\n handler: (\n args: TArgs,\n context: TContext\n ) => Promise<ToolHandlerResponse<TResult, AnthropicToolResponse>>\n ): ActivityToolHandler<TArgs, TResult, TContext, AnthropicToolResponse>;\n}\n\n/**\n * Creates an Anthropic adapter that bundles thread operations and model\n * invocation using the `@anthropic-ai/sdk`.\n *\n * Use `createActivities(scope)` to register scoped thread operations as\n * Temporal activities on the worker. The `invoker` (or invokers created via\n * `createModelInvoker`) should be wrapped with `createRunAgentActivity`.\n *\n * @example\n * ```typescript\n * import { createAnthropicAdapter } from 'zeitlich/adapters/thread/anthropic';\n * import { createRunAgentActivity } from 'zeitlich';\n * import Anthropic from '@anthropic-ai/sdk';\n *\n * const client = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY });\n * const adapter = createAnthropicAdapter({ redis, client, model: 'claude-sonnet-4-20250514' });\n *\n * export function createActivities(temporalClient: WorkflowClient) {\n * return {\n * ...adapter.createActivities(\"codingAgent\"),\n * ...createRunAgentActivity(temporalClient, adapter.invoker, \"codingAgent\"),\n * };\n * }\n * ```\n *\n * @example Multi-agent worker (main + subagent share the adapter)\n * ```typescript\n * export function createActivities(temporalClient: WorkflowClient) {\n * return {\n * ...adapter.createActivities(\"codingAgent\"),\n * ...adapter.createActivities(\"researchAgent\"),\n * ...createRunAgentActivity(temporalClient, adapter.invoker, \"codingAgent\"),\n * ...createRunAgentActivity(\n * temporalClient,\n * adapter.createModelInvoker('claude-sonnet-4-20250514'),\n * \"researchAgent\",\n * ),\n * };\n * }\n * ```\n */\nexport function createAnthropicAdapter(\n config: AnthropicAdapterConfig\n): AnthropicAdapter {\n const { redis, client } = config;\n\n /**\n * Common per-call config plumbed into both the provider thread\n * manager (for message I/O) and the tiered base manager (for\n * hot↔cold lifecycle ops). Keeping them in lockstep means a single\n * `coldStore` / `ttlSeconds` configuration controls every Redis\n * write the adapter does.\n */\n const baseExtras = {\n ...(config.ttlSeconds !== undefined && { ttlSeconds: config.ttlSeconds }),\n };\n\n const makeProviderThread = (threadId: string, threadKey?: string) =>\n createAnthropicThreadManager({\n redis,\n threadId,\n key: threadKey,\n ...baseExtras,\n });\n\n const makeTieredBase = (threadId: string, threadKey?: string) =>\n createTieredThreadManager<StoredMessage>({\n redis,\n threadId,\n key: threadKey,\n idOf: storedMessageId,\n ...baseExtras,\n ...(config.coldStore && { coldStore: config.coldStore }),\n });\n\n const threadOps: ThreadOps<AnthropicContent> = {\n async initializeThread(\n threadId: string,\n threadKey?: string\n ): Promise<void> {\n const thread = makeProviderThread(threadId, threadKey);\n await thread.initialize();\n },\n\n async appendHumanMessage(\n threadId: string,\n id: string,\n content: AnthropicContent,\n threadKey?: string\n ): Promise<void> {\n const thread = makeProviderThread(threadId, threadKey);\n await thread.appendUserMessage(id, content);\n },\n\n async appendSystemMessage(\n threadId: string,\n id: string,\n content: AnthropicSystemContent,\n threadKey?: string\n ): Promise<void> {\n const thread = makeProviderThread(threadId, threadKey);\n await thread.appendSystemMessage(id, content);\n },\n\n async appendToolResult(id: string, cfg: ToolResultConfig): Promise<void> {\n const { threadId, threadKey, toolCallId, toolName, content } = cfg;\n const thread = makeProviderThread(threadId, threadKey);\n await thread.appendToolResult(id, toolCallId, toolName, content);\n },\n\n async appendAgentMessage(\n threadId: string,\n id: string,\n message: Anthropic.Messages.Message,\n threadKey?: string\n ): Promise<void> {\n const thread = makeProviderThread(threadId, threadKey);\n await thread.appendAssistantMessage(id, message.content);\n },\n\n async forkThread(\n sourceThreadId: string,\n targetThreadId: string,\n threadKey?: string\n ): Promise<void> {\n const thread = createAnthropicThreadManager({\n redis,\n threadId: sourceThreadId,\n key: threadKey,\n hooks: config.hooks,\n ...baseExtras,\n });\n await thread.fork(targetThreadId);\n },\n\n async truncateThread(\n threadId: string,\n messageId: string,\n threadKey?: string\n ): Promise<void> {\n const thread = makeProviderThread(threadId, threadKey);\n await thread.truncateFromId(messageId);\n },\n\n async loadThreadState(\n threadId: string,\n threadKey?: string\n ): Promise<PersistedThreadState | null> {\n const thread = makeProviderThread(threadId, threadKey);\n return thread.loadState();\n },\n\n async saveThreadState(\n threadId: string,\n state: PersistedThreadState,\n threadKey?: string\n ): Promise<void> {\n const thread = makeProviderThread(threadId, threadKey);\n await thread.saveState(state);\n },\n\n async hydrateThread(threadId: string, threadKey?: string): Promise<void> {\n if (!config.coldStore) return;\n await makeTieredBase(threadId, threadKey).hydrate();\n },\n\n async flushThread(threadId: string, threadKey?: string): Promise<void> {\n if (!config.coldStore) return;\n await makeTieredBase(threadId, threadKey).flush();\n },\n };\n\n function createActivities<S extends string = \"\">(\n scope?: S\n ): AnthropicThreadOps<S> {\n const prefix = scope\n ? `${ADAPTER_ID}${scope.charAt(0).toUpperCase()}${scope.slice(1)}`\n : ADAPTER_ID;\n const cap = (s: string): string => s.charAt(0).toUpperCase() + s.slice(1);\n return Object.fromEntries(\n Object.entries(threadOps).map(([k, v]) => [`${prefix}${cap(k)}`, v])\n ) as AnthropicThreadOps<S>;\n }\n\n const makeInvoker = (\n model: string,\n maxTokens?: number,\n promptCache?: AnthropicPromptCacheConfig\n ): ModelInvoker<Anthropic.Messages.Message> => {\n const invokerConfig: AnthropicModelInvokerConfig = {\n redis,\n client,\n model,\n ...(maxTokens !== undefined ? { maxTokens } : {}),\n ...(config.maxTokens !== undefined && maxTokens === undefined\n ? { maxTokens: config.maxTokens }\n : {}),\n ...(promptCache !== undefined\n ? { promptCache }\n : config.promptCache !== undefined\n ? { promptCache: config.promptCache }\n : {}),\n hooks: config.hooks,\n };\n return createAnthropicModelInvoker(invokerConfig);\n };\n\n const invoker: ModelInvoker<Anthropic.Messages.Message> = config.model\n ? makeInvoker(config.model)\n : ((() => {\n throw new Error(\n \"No default model provided to createAnthropicAdapter. \" +\n \"Either pass `model` in the config or use `createModelInvoker(model)` instead.\"\n );\n }) as unknown as ModelInvoker<Anthropic.Messages.Message>);\n\n return {\n createActivities,\n invoker,\n createModelInvoker: makeInvoker,\n wrapHandler: (handler) => handler,\n };\n}\n"]}
1
+ {"version":3,"sources":["../../../../src/adapters/thread/anthropic/adapter-id.ts","../../../../src/lib/thread/keys.ts","../../../../src/lib/thread/manager.ts","../../../../src/lib/thread/snapshot.ts","../../../../src/lib/thread/tiered.ts","../../../../src/adapters/thread/anthropic/thread-manager.ts","../../../../src/adapters/thread/anthropic/prompt-cache.ts","../../../../src/lib/activity.ts","../../../../src/adapters/thread/anthropic/model-invoker.ts","../../../../src/adapters/thread/anthropic/activities.ts"],"names":["Context","invokeAnthropicModel"],"mappings":";;;;;AAYO,IAAM,UAAA,GAAa;;;ACsBnB,IAAM,kBAAA,GAAqB,EAAA,GAAK,EAAA,GAAK,EAAA,GAAK,EAAA;AAc1C,SAAS,gBAAA,CACd,WACA,QAAA,EACQ;AACR,EAAA,OAAO,CAAA,EAAG,SAAS,CAAA,QAAA,EAAW,QAAQ,CAAA,CAAA;AACxC;AAeO,SAAS,gBAAA,CACd,WACA,QAAA,EACQ;AACR,EAAA,OAAO,CAAA,EAAG,SAAS,CAAA,aAAA,EAAgB,QAAQ,CAAA,CAAA;AAC7C;AAeO,SAAS,iBAAA,CACd,WACA,QAAA,EACQ;AACR,EAAA,OAAO,CAAA,EAAG,SAAS,CAAA,cAAA,EAAiB,QAAQ,CAAA,CAAA;AAC9C;AAkBO,SAAS,iBAAA,CAAkB,UAAkB,OAAA,EAAyB;AAC3E,EAAA,OAAO,CAAA,MAAA,EAAS,OAAO,CAAA,QAAA,EAAW,QAAQ,CAAA,CAAA;AAC5C;;;AC9FA,IAAM,wBAAA,GAA2B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAgB1B,SAAS,oBACd,MAAA,EACsB;AACtB,EAAA,MAAM;AAAA,IACJ,KAAA;AAAA,IACA,QAAA;AAAA,IACA,GAAA,GAAM,UAAA;AAAA,IACN,SAAA,GAAY,CAAC,CAAA,KAAiB,IAAA,CAAK,UAAU,CAAC,CAAA;AAAA,IAC9C,WAAA,GAAc,CAAC,GAAA,KAAmB,IAAA,CAAK,MAAM,GAAG,CAAA;AAAA,IAChD,IAAA;AAAA,IACA,UAAA,GAAa;AAAA,GACf,GAAI,MAAA;AACJ,EAAA,MAAM,QAAA,GAAW,gBAAA,CAAiB,GAAA,EAAK,QAAQ,CAAA;AAC/C,EAAA,MAAM,OAAA,GAAU,gBAAA,CAAiB,GAAA,EAAK,QAAQ,CAAA;AAC9C,EAAA,MAAM,QAAA,GAAW,iBAAA,CAAkB,GAAA,EAAK,QAAQ,CAAA;AAChD,EAAA,MAAM,QAAA,GAAW,CAAC,EAAA,KAAuB,iBAAA,CAAkB,UAAU,EAAE,CAAA;AAEvE,EAAA,eAAe,kBAAA,GAAoC;AACjD,IAAA,MAAM,MAAA,GAAS,MAAM,KAAA,CAAM,MAAA,CAAO,OAAO,CAAA;AACzC,IAAA,IAAI,CAAC,MAAA,EAAQ;AACX,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,QAAA,EAAW,QAAQ,CAAA,QAAA,EAAW,GAAG,CAAA,gBAAA,CAAkB,CAAA;AAAA,IACrE;AAAA,EACF;AAEA,EAAA,OAAO;AAAA,IACL,MAAM,UAAA,GAA4B;AAChC,MAAA,MAAM,KAAA,CAAM,IAAI,QAAQ,CAAA;AACxB,MAAA,MAAM,MAAM,GAAA,CAAI,OAAA,EAAS,KAAK,EAAE,EAAA,EAAI,YAAY,CAAA;AAAA,IAClD,CAAA;AAAA,IAEA,MAAM,IAAA,GAAqB;AACzB,MAAA,MAAM,kBAAA,EAAmB;AACzB,MAAA,MAAM,OAAO,MAAM,KAAA,CAAM,MAAA,CAAO,QAAA,EAAU,GAAG,EAAE,CAAA;AAC/C,MAAA,OAAO,IAAA,CAAK,IAAI,WAAW,CAAA;AAAA,IAC7B,CAAA;AAAA,IAEA,MAAM,OAAO,QAAA,EAA8B;AACzC,MAAA,IAAI,QAAA,CAAS,WAAW,CAAA,EAAG;AAC3B,MAAA,MAAM,kBAAA,EAAmB;AAEzB,MAAA,IAAI,IAAA,EAAM;AACR,QAAA,MAAM,UAAU,QAAA,CAAS,GAAA,CAAI,IAAI,CAAA,CAAE,KAAK,GAAG,CAAA;AAC3C,QAAA,MAAM,KAAA,CAAM,KAAK,wBAAA,EAA0B;AAAA,UACzC,IAAA,EAAM,CAAC,QAAA,CAAS,OAAO,GAAG,QAAQ,CAAA;AAAA,UAClC,SAAA,EAAW,CAAC,MAAA,CAAO,UAAU,GAAG,GAAG,QAAA,CAAS,GAAA,CAAI,SAAS,CAAC;AAAA,SAC3D,CAAA;AAAA,MACH,CAAA,MAAO;AACL,QAAA,MAAM,MAAM,KAAA,CAAM,QAAA,EAAU,QAAA,CAAS,GAAA,CAAI,SAAS,CAAC,CAAA;AACnD,QAAA,MAAM,KAAA,CAAM,MAAA,CAAO,QAAA,EAAU,UAAU,CAAA;AAAA,MACzC;AAAA,IACF,CAAA;AAAA,IAEA,MAAM,KAAK,WAAA,EAAoD;AAC7D,MAAA,MAAM,kBAAA,EAAmB;AACzB,MAAA,MAAM,OAAO,MAAM,KAAA,CAAM,MAAA,CAAO,QAAA,EAAU,GAAG,EAAE,CAAA;AAC/C,MAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,GAAA,CAAI,QAAQ,CAAA;AACzC,MAAA,MAAM,SAAS,mBAAA,CAAoB;AAAA,QACjC,GAAG,MAAA;AAAA,QACH,QAAA,EAAU;AAAA,OACX,CAAA;AACD,MAAA,MAAM,OAAO,UAAA,EAAW;AACxB,MAAA,IAAI,IAAA,CAAK,SAAS,CAAA,EAAG;AACnB,QAAA,MAAM,MAAA,GAAS,gBAAA,CAAiB,GAAA,EAAK,WAAW,CAAA;AAChD,QAAA,MAAM,KAAA,CAAM,KAAA,CAAM,MAAA,EAAQ,IAAI,CAAA;AAC9B,QAAA,MAAM,KAAA,CAAM,MAAA,CAAO,MAAA,EAAQ,UAAU,CAAA;AAAA,MACvC;AACA,MAAA,IAAI,YAAY,IAAA,EAAM;AACpB,QAAA,MAAM,WAAA,GAAc,iBAAA,CAAkB,GAAA,EAAK,WAAW,CAAA;AACtD,QAAA,MAAM,MAAM,GAAA,CAAI,WAAA,EAAa,UAAU,EAAE,EAAA,EAAI,YAAY,CAAA;AAAA,MAC3D;AACA,MAAA,OAAO,MAAA;AAAA,IACT,CAAA;AAAA,IAEA,MAAM,WAAW,QAAA,EAA8B;AAC7C,MAAA,MAAM,kBAAA,EAAmB;AACzB,MAAA,IAAI,CAAC,IAAA,EAAM;AACT,QAAA,MAAM,IAAI,KAAA;AAAA,UACR;AAAA,SACF;AAAA,MACF;AACA,MAAA,MAAM,WAAW,MAAM,KAAA,CAAM,MAAA,CAAO,QAAA,EAAU,GAAG,EAAE,CAAA;AACnD,MAAA,MAAM,cAAc,QAAA,CACjB,GAAA,CAAI,CAAC,GAAA,KAAQ,KAAK,WAAA,CAAY,GAAG,CAAC,CAAC,EACnC,MAAA,CAAO,CAAC,EAAA,KAAqB,OAAO,OAAO,QAAQ,CAAA;AACtD,MAAA,MAAM,KAAA,CAAM,IAAI,QAAQ,CAAA;AACxB,MAAA,IAAI,WAAA,CAAY,SAAS,CAAA,EAAG;AAC1B,QAAA,MAAM,KAAA,CAAM,GAAA,CAAI,WAAA,CAAY,GAAA,CAAI,QAAQ,CAAC,CAAA;AAAA,MAC3C;AACA,MAAA,IAAI,QAAA,CAAS,SAAS,CAAA,EAAG;AACvB,QAAA,MAAM,MAAM,KAAA,CAAM,QAAA,EAAU,QAAA,CAAS,GAAA,CAAI,SAAS,CAAC,CAAA;AACnD,QAAA,MAAM,KAAA,CAAM,MAAA,CAAO,QAAA,EAAU,UAAU,CAAA;AAAA,MACzC;AACA,MAAA,MAAM,KAAA,CAAM,MAAA,CAAO,OAAA,EAAS,UAAU,CAAA;AAAA,IACxC,CAAA;AAAA,IAEA,MAAM,MAAA,GAAwB;AAC5B,MAAA,MAAM,MAAM,GAAA,CAAI,CAAC,QAAA,EAAU,OAAA,EAAS,QAAQ,CAAC,CAAA;AAAA,IAC/C,CAAA;AAAA,IAEA,MAAM,SAAA,GAAkD;AACtD,MAAA,MAAM,GAAA,GAAM,MAAM,KAAA,CAAM,GAAA,CAAI,QAAQ,CAAA;AACpC,MAAA,IAAI,GAAA,IAAO,MAAM,OAAO,IAAA;AACxB,MAAA,OAAO,IAAA,CAAK,MAAM,GAAG,CAAA;AAAA,IACvB,CAAA;AAAA,IAEA,MAAM,UAAU,KAAA,EAA4C;AAC1D,MAAA,MAAM,kBAAA,EAAmB;AACzB,MAAA,MAAM,KAAA,CAAM,GAAA,CAAI,QAAA,EAAU,IAAA,CAAK,SAAA,CAAU,KAAK,CAAA,EAAG,EAAE,EAAA,EAAI,UAAA,EAAY,CAAA;AAAA,IACrE,CAAA;AAAA,IAEA,MAAM,WAAA,GAA6B;AACjC,MAAA,MAAM,KAAA,CAAM,IAAI,QAAQ,CAAA;AAAA,IAC1B,CAAA;AAAA,IAEA,MAAM,MAAA,GAA0B;AAC9B,MAAA,MAAM,kBAAA,EAAmB;AACzB,MAAA,OAAO,KAAA,CAAM,KAAK,QAAQ,CAAA;AAAA,IAC5B,CAAA;AAAA,IAEA,MAAM,eAAe,SAAA,EAAkC;AACrD,MAAA,MAAM,kBAAA,EAAmB;AACzB,MAAA,IAAI,CAAC,IAAA,EAAM;AACT,QAAA,MAAM,IAAI,KAAA;AAAA,UACR;AAAA,SACF;AAAA,MACF;AACA,MAAA,MAAM,OAAO,MAAM,KAAA,CAAM,MAAA,CAAO,QAAA,EAAU,GAAG,EAAE,CAAA;AAC/C,MAAA,IAAI,GAAA,GAAM,EAAA;AACV,MAAA,MAAM,aAAuB,EAAC;AAC9B,MAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,IAAA,CAAK,QAAQ,CAAA,EAAA,EAAK;AACpC,QAAA,MAAM,GAAA,GAAM,KAAK,CAAC,CAAA;AAClB,QAAA,IAAI,QAAQ,MAAA,EAAW;AACvB,QAAA,MAAM,EAAA,GAAK,IAAA,CAAK,WAAA,CAAY,GAAG,CAAC,CAAA;AAChC,QAAA,IAAI,GAAA,KAAQ,EAAA,IAAM,EAAA,KAAO,SAAA,EAAW,GAAA,GAAM,CAAA;AAC1C,QAAA,IAAI,GAAA,KAAQ,EAAA,EAAI,UAAA,CAAW,IAAA,CAAK,EAAE,CAAA;AAAA,MACpC;AACA,MAAA,IAAI,QAAQ,EAAA,EAAI;AAChB,MAAA,IAAI,QAAQ,CAAA,EAAG;AACb,QAAA,MAAM,KAAA,CAAM,IAAI,QAAQ,CAAA;AACxB,QAAA,MAAM,KAAA,CAAM,MAAA,CAAO,OAAA,EAAS,UAAU,CAAA;AAAA,MACxC,CAAA,MAAO;AACL,QAAA,MAAM,KAAA,CAAM,KAAA,CAAM,QAAA,EAAU,CAAA,EAAG,MAAM,CAAC,CAAA;AACtC,QAAA,MAAM,KAAA,CAAM,MAAA,CAAO,QAAA,EAAU,UAAU,CAAA;AAAA,MACzC;AAKA,MAAA,IAAI,UAAA,CAAW,SAAS,CAAA,EAAG;AACzB,QAAA,MAAM,KAAA,CAAM,GAAA,CAAI,UAAA,CAAW,GAAA,CAAI,QAAQ,CAAC,CAAA;AAAA,MAC1C;AAAA,IACF;AAAA,GACF;AACF;;;AC/IA,eAAsB,eACpB,MAAA,EACgC;AAChC,EAAA,MAAM,EAAE,KAAA,EAAO,SAAA,EAAW,QAAA,EAAU,MAAK,GAAI,MAAA;AAC7C,EAAA,MAAM,OAAA,GAAU,gBAAA,CAAiB,SAAA,EAAW,QAAQ,CAAA;AACpD,EAAA,IAAK,MAAM,KAAA,CAAM,MAAA,CAAO,OAAO,MAAO,CAAA,EAAG;AACvC,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,MAAM,OAAA,GAAU,gBAAA,CAAiB,SAAA,EAAW,QAAQ,CAAA;AACpD,EAAA,MAAM,QAAA,GAAW,iBAAA,CAAkB,SAAA,EAAW,QAAQ,CAAA;AACtD,EAAA,MAAM,WAAW,MAAM,KAAA,CAAM,MAAA,CAAO,OAAA,EAAS,GAAG,EAAE,CAAA;AAClD,EAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,GAAA,CAAI,QAAQ,CAAA;AACzC,EAAA,MAAM,QACJ,QAAA,IAAY,IAAA,GAAO,IAAA,GAAQ,IAAA,CAAK,MAAM,QAAQ,CAAA;AAChD,EAAA,MAAM,WAAW,IAAA,GAAO,QAAA,CAAS,GAAA,CAAI,IAAI,IAAI,EAAC;AAC9C,EAAA,OAAO,EAAE,CAAA,EAAG,CAAA,EAAG,QAAA,EAAU,OAAO,QAAA,EAAS;AAC3C;AAkBA,eAAsB,cACpB,MAAA,EACe;AACf,EAAA,MAAM;AAAA,IACJ,KAAA;AAAA,IACA,SAAA;AAAA,IACA,QAAA;AAAA,IACA,QAAA;AAAA,IACA,UAAA,GAAa;AAAA,GACf,GAAI,MAAA;AACJ,EAAA,MAAM,OAAA,GAAU,gBAAA,CAAiB,SAAA,EAAW,QAAQ,CAAA;AACpD,EAAA,IAAK,MAAM,KAAA,CAAM,MAAA,CAAO,OAAO,MAAO,CAAA,EAAG;AACvC,IAAA;AAAA,EACF;AACA,EAAA,MAAM,OAAA,GAAU,gBAAA,CAAiB,SAAA,EAAW,QAAQ,CAAA;AACpD,EAAA,MAAM,QAAA,GAAW,iBAAA,CAAkB,SAAA,EAAW,QAAQ,CAAA;AAOtD,EAAA,MAAM,KAAA,CAAM,GAAA,CAAI,CAAC,OAAA,EAAS,QAAQ,CAAC,CAAA;AAOnC,EAAA,MAAM,QAAA,GAAW,MAAM,KAAA,EAAM;AAC7B,EAAA,IAAI,QAAA,CAAS,QAAA,CAAS,MAAA,GAAS,CAAA,EAAG;AAChC,IAAA,QAAA,CAAS,KAAA,CAAM,OAAA,EAAS,QAAA,CAAS,QAAQ,CAAA;AACzC,IAAA,QAAA,CAAS,MAAA,CAAO,SAAS,UAAU,CAAA;AAAA,EACrC;AACA,EAAA,IAAI,QAAA,CAAS,SAAS,IAAA,EAAM;AAC1B,IAAA,QAAA,CAAS,GAAA,CAAI,QAAA,EAAU,IAAA,CAAK,SAAA,CAAU,QAAA,CAAS,KAAK,CAAA,EAAG,EAAE,EAAA,EAAI,UAAA,EAAY,CAAA;AAAA,EAC3E;AACA,EAAA,KAAA,MAAW,EAAA,IAAM,SAAS,QAAA,EAAU;AAClC,IAAA,QAAA,CAAS,GAAA,CAAI,kBAAkB,QAAA,EAAU,EAAE,GAAG,GAAA,EAAK,EAAE,EAAA,EAAI,UAAA,EAAY,CAAA;AAAA,EACvE;AACA,EAAA,IAAI;AACF,IAAA,MAAM,SAAS,cAAA,EAAe;AAAA,EAChC,SAAS,GAAA,EAAK;AAOZ,IAAA,MAAM,MACH,GAAA,CAAI;AAAA,MACH,OAAA;AAAA,MACA,QAAA;AAAA,MACA,GAAG,SAAS,QAAA,CAAS,GAAA,CAAI,CAAC,EAAA,KAAO,iBAAA,CAAkB,QAAA,EAAU,EAAE,CAAC;AAAA,KACjE,CAAA,CACA,KAAA,CAAM,MAAM,MAAS,CAAA;AACxB,IAAA,MAAM,mBAAmB,GAAG,CAAA;AAAA,EAC9B;AACA,EAAA,MAAM,MAAM,GAAA,CAAI,OAAA,EAAS,KAAK,EAAE,EAAA,EAAI,YAAY,CAAA;AAClD;AASA,SAAS,mBAAmB,GAAA,EAAuB;AACjD,EAAA,IACE,GAAA,IAAO,IAAA,IACP,OAAO,GAAA,KAAQ,QAAA,IACf,SAAA,IAAa,GAAA,IACb,KAAA,CAAM,OAAA,CAAS,GAAA,CAA6B,OAAO,CAAA,EACnD;AACA,IAAA,MAAM,QAAA,GAAY,IAA+B,OAAA,CAAQ,IAAA;AAAA,MACvD,CAAC,MAAkB,CAAA,YAAa;AAAA,KAClC;AACA,IAAA,IAAI,UAAU,OAAO,QAAA;AAAA,EACvB;AACA,EAAA,OAAO,GAAA;AACT;AAaA,eAAsB,aACpB,MAAA,EACe;AACf,EAAA,MAAM,EAAE,KAAA,EAAO,SAAA,EAAW,UAAU,QAAA,GAAW,IAAG,GAAI,MAAA;AACtD,EAAA,MAAM,IAAA,GAAO;AAAA,IACX,gBAAA,CAAiB,WAAW,QAAQ,CAAA;AAAA,IACpC,gBAAA,CAAiB,WAAW,QAAQ,CAAA;AAAA,IACpC,iBAAA,CAAkB,WAAW,QAAQ,CAAA;AAAA,IACrC,GAAG,SAAS,GAAA,CAAI,CAAC,OAAO,iBAAA,CAAkB,QAAA,EAAU,EAAE,CAAC;AAAA,GACzD;AACA,EAAA,MAAM,KAAA,CAAM,IAAI,IAAI,CAAA;AACtB;;;AC1GO,SAAS,0BACd,MAAA,EACwB;AACxB,EAAA,MAAM;AAAA,IACJ,KAAA;AAAA,IACA,QAAA;AAAA,IACA,GAAA,GAAM,UAAA;AAAA,IACN,SAAA;AAAA,IACA,IAAA;AAAA,IACA,WAAA,GAAc,CAAC,GAAA,KAAmB,IAAA,CAAK,MAAM,GAAG,CAAA;AAAA,IAChD,UAAA,GAAa;AAAA,GACf,GAAI,MAAA;AAEJ,EAAA,MAAM,IAAA,GAAO,oBAAuB,MAAM,CAAA;AAI1C,EAAA,MAAM,OAAA,GAAU,OACZ,CAAC,GAAA,KAAwB,KAAK,WAAA,CAAY,GAAG,CAAC,CAAA,GAC9C,MAAA;AAEJ,EAAA,OAAO,MAAA,CAAO,OAAO,IAAA,EAAM;AAAA,IACzB,MAAM,OAAA,GAAyB;AAC7B,MAAA,IAAI,CAAC,SAAA,EAAW;AAChB,MAAA,MAAM,QAAA,GAAW,MAAM,SAAA,CAAU,IAAA,CAAK,KAAK,QAAQ,CAAA;AACnD,MAAA,IAAI,CAAC,QAAA,EAAU;AACf,MAAA,MAAM,aAAA,CAAc;AAAA,QAClB,KAAA;AAAA,QACA,SAAA,EAAW,GAAA;AAAA,QACX,QAAA;AAAA,QACA,QAAA;AAAA,QACA;AAAA,OACD,CAAA;AAAA,IACH,CAAA;AAAA,IAEA,MAAM,MAAM,IAAA,EAAoC;AAC9C,MAAA,IAAI,CAAC,SAAA,EAAW;AAChB,MAAA,MAAM,QAAA,GAAW,MAAM,cAAA,CAAe;AAAA,QACpC,KAAA;AAAA,QACA,SAAA,EAAW,GAAA;AAAA,QACX,QAAA;AAAA,QACA,GAAI,OAAA,GAAU,EAAE,IAAA,EAAM,OAAA,KAAY;AAAC,OACpC,CAAA;AACD,MAAA,IAAI,CAAC,QAAA,EAAU;AACf,MAAA,MAAM,SAAA,CAAU,KAAA,CAAM,GAAA,EAAK,QAAA,EAAU,QAAQ,CAAA;AAC7C,MAAA,MAAM,SAAA,GAAY,MAAM,SAAA,IAAa,IAAA;AACrC,MAAA,IAAI,SAAA,EAAW;AACb,QAAA,MAAM,YAAA,CAAa;AAAA,UACjB,KAAA;AAAA,UACA,SAAA,EAAW,GAAA;AAAA,UACX,QAAA;AAAA,UACA,UAAU,QAAA,CAAS;AAAA,SACpB,CAAA;AAAA,MACH;AAAA,IACF;AAAA,GACD,CAAA;AACH;;;ACpEO,SAAS,gBAAgB,GAAA,EAA4B;AAC1D,EAAA,OAAO,GAAA,CAAI,EAAA;AACb;AAGA,SAAS,gBACP,OAAA,EACwC;AACxC,EAAA,IAAI,OAAO,YAAY,QAAA,EAAU;AAC/B,IAAA,OAAO,CAAC,EAAE,IAAA,EAAM,MAAA,EAAQ,IAAA,EAAM,SAAS,CAAA;AAAA,EACzC;AACA,EAAA,OAAO,OAAA;AACT;AAOA,SAAS,yBACP,QAAA,EACmC;AACnC,EAAA,MAAM,SAA4C,EAAC;AACnD,EAAA,KAAA,MAAW,OAAO,QAAA,EAAU;AAC1B,IAAA,MAAM,IAAA,GAAO,MAAA,CAAO,MAAA,CAAO,MAAA,GAAS,CAAC,CAAA;AACrC,IAAA,IAAI,IAAA,IAAQ,IAAA,CAAK,IAAA,KAAS,GAAA,CAAI,IAAA,EAAM;AAClC,MAAA,MAAM,WAAA,GAAc,KAAA,CAAM,OAAA,CAAQ,IAAA,CAAK,OAAO,CAAA,GAC1C,IAAA,CAAK,OAAA,GACL,CAAC,EAAE,IAAA,EAAM,MAAA,EAAiB,IAAA,EAAM,IAAA,CAAK,SAAS,CAAA;AAClD,MAAA,MAAM,UAAA,GAAa,KAAA,CAAM,OAAA,CAAQ,GAAA,CAAI,OAAO,CAAA,GACxC,GAAA,CAAI,OAAA,GACJ,CAAC,EAAE,IAAA,EAAM,MAAA,EAAiB,IAAA,EAAM,GAAA,CAAI,SAAS,CAAA;AACjD,MAAA,IAAA,CAAK,OAAA,GAAU,CAAC,GAAG,WAAA,EAAa,GAAG,UAAU,CAAA;AAAA,IAC/C,CAAA,MAAO;AACL,MAAA,MAAA,CAAO,IAAA,CAAK;AAAA,QACV,GAAG,GAAA;AAAA,QACH,OAAA,EAAS,KAAA,CAAM,OAAA,CAAQ,GAAA,CAAI,OAAO,CAAA,GAAI,CAAC,GAAG,GAAA,CAAI,OAAO,CAAA,GAAI,GAAA,CAAI;AAAA,OAC9D,CAAA;AAAA,IACH;AAAA,EACF;AACA,EAAA,OAAO,MAAA;AACT;AAOO,SAAS,6BACd,MAAA,EACwB;AACxB,EAAA,MAAM,UAAA,GAAiD;AAAA,IACrD,OAAO,MAAA,CAAO,KAAA;AAAA,IACd,UAAU,MAAA,CAAO,QAAA;AAAA,IACjB,KAAK,MAAA,CAAO,GAAA;AAAA,IACZ,IAAA,EAAM,eAAA;AAAA,IACN,GAAI,MAAA,CAAO,UAAA,KAAe,UAAa,EAAE,UAAA,EAAY,OAAO,UAAA;AAAW,GACzE;AAEA,EAAA,MAAM,IAAA,GAAO,oBAAoB,UAAU,CAAA;AAE3C,EAAA,MAAM,OAAA,GAA2D;AAAA,IAC/D,MAAM,iBAAA,CACJ,EAAA,EACA,OAAA,EACe;AACf,MAAA,MAAM,KAAK,MAAA,CAAO;AAAA,QAChB;AAAA,UACE,EAAA;AAAA,UACA,SAAS,EAAE,IAAA,EAAM,QAAQ,OAAA,EAAS,eAAA,CAAgB,OAAO,CAAA;AAAE;AAC7D,OACD,CAAA;AAAA,IACH,CAAA;AAAA,IAEA,MAAM,mBAAA,CACJ,EAAA,EACA,OAAA,EACe;AACf,MAAA,MAAM,KAAK,UAAA,EAAW;AACtB,MAAA,MAAM,KAAK,MAAA,CAAO;AAAA,QAChB;AAAA,UACE,EAAA;AAAA;AAAA;AAAA,UAGA,OAAA,EAAS;AAAA,YACP,IAAA,EAAM,MAAA;AAAA,YACN;AAAA,WACF;AAAA,UACA,QAAA,EAAU;AAAA;AACZ,OACD,CAAA;AAAA,IACH,CAAA;AAAA,IAEA,MAAM,sBAAA,CACJ,EAAA,EACA,OAAA,EACe;AACf,MAAA,MAAM,KAAK,MAAA,CAAO;AAAA,QAChB;AAAA,UACE,EAAA;AAAA,UACA,OAAA,EAAS;AAAA,YACP,IAAA,EAAM,WAAA;AAAA,YACN;AAAA;AAEF;AACF,OACD,CAAA;AAAA,IACH,CAAA;AAAA,IAEA,MAAM,gBAAA,CACJ,EAAA,EACA,UAAA,EACA,WACA,OAAA,EACe;AACf,MAAA,MAAM,WAAA,GACJ,OAAO,OAAA,KAAY,QAAA,GACf,OAAA,GACA,KAAA,CAAM,OAAA,CAAQ,OAAO,CAAA,GAClB,OAAA,GACD,IAAA,CAAK,SAAA,CAAU,OAAO,CAAA;AAC9B,MAAA,MAAM,KAAK,MAAA,CAAO;AAAA,QAChB;AAAA,UACE,EAAA;AAAA,UACA,OAAA,EAAS;AAAA,YACP,IAAA,EAAM,MAAA;AAAA,YACN,OAAA,EAAS;AAAA,cACP;AAAA,gBACE,IAAA,EAAM,aAAA;AAAA,gBACN,WAAA,EAAa,UAAA;AAAA,gBACb,OAAA,EAAS;AAAA;AACX;AACF;AACF;AACF,OACD,CAAA;AAAA,IACH,CAAA;AAAA,IAEA,MAAM,oBAAA,GAA4D;AAChE,MAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,IAAA,EAAK;AAC/B,MAAA,MAAM,EAAE,gBAAA,EAAkB,iBAAA,EAAkB,GAAI,MAAA,CAAO,SAAS,EAAC;AACjE,MAAA,MAAM,MAAA,GAAS,gBAAA,GACX,MAAA,CAAO,GAAA,CAAI,CAAC,GAAA,EAAK,CAAA,KAAM,gBAAA,CAAiB,GAAA,EAAK,CAAA,EAAG,MAAM,CAAC,CAAA,GACvD,MAAA;AAEJ,MAAA,IAAI,MAAA;AACJ,MAAA,MAAM,uBAA0D,EAAC;AAEjE,MAAA,KAAA,MAAW,QAAQ,MAAA,EAAQ;AACzB,QAAA,IAAI,KAAK,QAAA,EAAU;AACjB,UAAA,MAAA,GAAS,KAAK,OAAA,CAAQ,OAAA;AAAA,QAGxB,CAAA,MAAO;AACL,UAAA,oBAAA,CAAqB,IAAA,CAAK,KAAK,OAAO,CAAA;AAAA,QACxC;AAAA,MACF;AAEA,MAAA,MAAM,QAAA,GAAW,yBAAyB,oBAAoB,CAAA;AAC9D,MAAA,OAAO;AAAA,QACL,QAAA,EAAU,iBAAA,GACN,QAAA,CAAS,GAAA,CAAI,CAAC,GAAA,EAAK,CAAA,KAAM,iBAAA,CAAkB,GAAA,EAAK,CAAA,EAAG,QAAQ,CAAC,CAAA,GAC5D,QAAA;AAAA,QACJ,GAAI,MAAA,GAAS,EAAE,MAAA,KAAW;AAAC,OAC7B;AAAA,IACF;AAAA,GACF;AAEA,EAAA,MAAM,OAAA,GAAU,MAAA,CAAO,MAAA,CAAO,IAAA,EAAM,OAAO,CAAA;AAE3C,EAAA,MAAM,YAAA,GAAe,OAAA,CAAQ,IAAA,CAAK,IAAA,CAAK,OAAO,CAAA;AAC9C,EAAA,OAAA,CAAQ,IAAA,GAAO,OACb,WAAA,KACoC;AACpC,IAAA,MAAM,aAAa,WAAW,CAAA;AAC9B,IAAA,MAAM,SAAS,4BAAA,CAA6B;AAAA,MAC1C,GAAG,MAAA;AAAA,MACH,QAAA,EAAU;AAAA,KACX,CAAA;AACD,IAAA,MAAM,EAAE,mBAAA,EAAqB,eAAA,EAAgB,GAAI,MAAA,CAAO,SAAS,EAAC;AAClE,IAAA,IAAI,CAAC,mBAAA,IAAuB,CAAC,eAAA,EAAiB;AAC5C,MAAA,OAAO,MAAA;AAAA,IACT;AACA,IAAA,IAAI,IAAA,GAAO,MAAM,MAAA,CAAO,IAAA,EAAK;AAC7B,IAAA,IAAI,mBAAA,EAAqB;AACvB,MAAA,IAAA,GAAO,MAAM,oBAAoB,IAAI,CAAA;AAAA,IACvC;AACA,IAAA,IAAI,eAAA,EAAiB;AACnB,MAAA,IAAA,GAAO,IAAA,CAAK,IAAI,CAAC,GAAA,EAAK,MAAM,eAAA,CAAgB,GAAA,EAAK,CAAA,EAAG,IAAI,CAAC,CAAA;AAAA,IAC3D;AACA,IAAA,MAAM,MAAA,CAAO,WAAW,IAAI,CAAA;AAC5B,IAAA,OAAO,MAAA;AAAA,EACT,CAAA;AAEA,EAAA,OAAO,OAAA;AACT;;;AC/OA,IAAM,6BAAA,GAAgC,CAAA;AACtC,IAAM,0CAA0B,IAAI,GAAA,CAAI,CAAC,UAAA,EAAY,mBAAmB,CAAC,CAAA;AAMlE,SAAS,0BACd,WAAA,EACyC;AACzC,EAAA,IAAI,WAAA,KAAgB,OAAO,OAAO,MAAA;AAClC,EAAA,IAAI,WAAA,KAAgB,IAAA,IAAQ,WAAA,KAAgB,MAAA,SAAkB,EAAC;AAC/D,EAAA,OAAO,WAAA;AACT;AAUO,SAAS,qBAAA,CACd,OAAA,EACA,OAAA,GAAuC,EAAC,EAC9B;AACV,EAAA,MAAM,cAAA,GACJ,QAAQ,cAAA,IAAkB,6BAAA;AAC5B,EAAA,IAAI,cAAA,IAAkB,GAAG,OAAO,OAAA;AAEhC,EAAA,IAAI,kBAAA,CAAmB,OAAO,CAAA,IAAK,cAAA,EAAgB,OAAO,OAAA;AAE1D,EAAA,MAAM,YAAA,GAA6B;AAAA,IACjC,IAAA,EAAM,WAAA;AAAA,IACN,GAAA,EAAK,QAAQ,GAAA,IAAO;AAAA,GACtB;AACA,EAAA,MAAM,QAAA,GAAW,iCAAA;AAAA,IACf,OAAA,CAAQ,QAAA;AAAA,IACR;AAAA,GACF;AAEA,EAAA,IAAI,QAAA,KAAa,OAAA,CAAQ,QAAA,EAAU,OAAO,OAAA;AAC1C,EAAA,OAAO,EAAE,GAAG,OAAA,EAAS,QAAA,EAAS;AAChC;AAEA,SAAS,iCAAA,CACP,UACA,YAAA,EACmC;AACnC,EAAA,KAAA,IACM,eAAe,QAAA,CAAS,MAAA,GAAS,CAAA,EACrC,YAAA,IAAgB,GAChB,YAAA,EAAA,EACA;AACA,IAAA,MAAM,OAAA,GAAU,SAAS,YAAY,CAAA;AACrC,IAAA,IAAI,CAAC,OAAA,EAAS;AAEd,IAAA,IAAI,OAAO,OAAA,CAAQ,OAAA,KAAY,QAAA,EAAU;AACvC,MAAA,IAAI,OAAA,CAAQ,OAAA,CAAQ,MAAA,KAAW,CAAA,EAAG;AAClC,MAAA,OAAO,cAAA,CAAe,UAAU,YAAA,EAAc;AAAA,QAC5C,GAAG,OAAA;AAAA,QACH,OAAA,EAAS;AAAA,UACP,EAAE,IAAA,EAAM,MAAA,EAAQ,MAAM,OAAA,CAAQ,OAAA,EAAS,eAAe,YAAA;AAAa;AACrE,OACD,CAAA;AAAA,IACH;AAEA,IAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,OAAA,CAAQ,OAAO,CAAA,EAAG;AAErC,IAAA,KAAA,IACM,aAAa,OAAA,CAAQ,OAAA,CAAQ,SAAS,CAAA,EAC1C,UAAA,IAAc,GACd,UAAA,EAAA,EACA;AACA,MAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,OAAA,CAAQ,UAAU,CAAA;AACxC,MAAA,IAAI,CAAC,uBAAA,CAAwB,KAAK,CAAA,EAAG;AACrC,MAAA,IAAI,eAAA,CAAgB,KAAK,CAAA,EAAG,OAAO,QAAA;AAEnC,MAAA,MAAM,OAAA,GAAU,CAAC,GAAG,OAAA,CAAQ,OAAO,CAAA;AACnC,MAAA,OAAA,CAAQ,UAAU,CAAA,GAAI;AAAA,QACpB,GAAI,KAAA;AAAA,QACJ,aAAA,EAAe;AAAA,OACjB;AACA,MAAA,OAAO,eAAe,QAAA,EAAU,YAAA,EAAc,EAAE,GAAG,OAAA,EAAS,SAAS,CAAA;AAAA,IACvE;AAAA,EACF;AAEA,EAAA,OAAO,QAAA;AACT;AAEA,SAAS,cAAA,CACP,QAAA,EACA,KAAA,EACA,OAAA,EACmC;AACnC,EAAA,MAAM,IAAA,GAAO,CAAC,GAAG,QAAQ,CAAA;AACzB,EAAA,IAAA,CAAK,KAAK,CAAA,GAAI,OAAA;AACd,EAAA,OAAO,IAAA;AACT;AAEA,SAAS,wBACP,KAAA,EACiE;AACjE,EAAA,IAAI,CAAC,QAAA,CAAS,KAAK,CAAA,EAAG,OAAO,KAAA;AAC7B,EAAA,MAAM,OAAO,OAAO,KAAA,CAAM,IAAA,KAAS,QAAA,GAAW,MAAM,IAAA,GAAO,MAAA;AAC3D,EAAA,IAAI,IAAA,IAAQ,uBAAA,CAAwB,GAAA,CAAI,IAAI,GAAG,OAAO,KAAA;AACtD,EAAA,IAAI,IAAA,KAAS,MAAA,IAAU,KAAA,CAAM,IAAA,KAAS,IAAI,OAAO,KAAA;AACjD,EAAA,OAAO,IAAA;AACT;AAEA,SAAS,mBAAmB,OAAA,EAAqC;AAC/D,EAAA,IAAI,KAAA,GAAQ,CAAA;AAEZ,EAAA,KAAA,MAAW,IAAA,IAAQ,OAAA,CAAQ,KAAA,IAAS,EAAC,EAAG;AACtC,IAAA,IAAI,eAAA,CAAgB,IAAI,CAAA,EAAG,KAAA,EAAA;AAAA,EAC7B;AAEA,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,OAAA,CAAQ,MAAM,CAAA,EAAG;AACjC,IAAA,KAAA,MAAW,KAAA,IAAS,QAAQ,MAAA,EAAQ;AAClC,MAAA,IAAI,eAAA,CAAgB,KAAK,CAAA,EAAG,KAAA,EAAA;AAAA,IAC9B;AAAA,EACF;AAEA,EAAA,KAAA,MAAW,OAAA,IAAW,QAAQ,QAAA,EAAU;AACtC,IAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,OAAA,CAAQ,OAAO,CAAA,EAAG;AACrC,IAAA,KAAA,MAAW,KAAA,IAAS,QAAQ,OAAA,EAAS;AACnC,MAAA,IAAI,eAAA,CAAgB,KAAK,CAAA,EAAG,KAAA,EAAA;AAAA,IAC9B;AAAA,EACF;AAEA,EAAA,OAAO,KAAA;AACT;AAEA,SAAS,gBAAgB,KAAA,EAA0C;AACjE,EAAA,OAAO,QAAA,CAAS,KAAK,CAAA,IAAK,KAAA,CAAM,aAAA,IAAiB,IAAA;AACnD;AAEA,SAAS,SAAS,KAAA,EAAkD;AAClE,EAAA,OAAO,OAAO,UAAU,QAAA,IAAY,KAAA,KAAU,QAAQ,CAAC,KAAA,CAAM,QAAQ,KAAK,CAAA;AAC5E;ACpJO,SAAS,kBAAA,GAGd;AACA,EAAA,IAAI;AACF,IAAA,MAAM,GAAA,GAAMA,iBAAQ,OAAA,EAAQ;AAC5B,IAAA,OAAO,EAAE,WAAW,MAAM,GAAA,CAAI,WAAU,EAAG,MAAA,EAAQ,IAAI,kBAAA,EAAmB;AAAA,EAC5E,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,EAAC;AAAA,EACV;AACF;;;ACKA,SAAS,iBACP,KAAA,EAC2B;AAC3B,EAAA,OAAO,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,MAAO;AAAA,IACvB,MAAM,CAAA,CAAE,IAAA;AAAA,IACR,aAAa,CAAA,CAAE,WAAA;AAAA,IACf,cAAc,CAAA,CAAE;AAAA,GAClB,CAAE,CAAA;AACJ;AA0BO,SAAS,2BAAA,CAA4B;AAAA,EAC1C,KAAA;AAAA,EACA,MAAA;AAAA,EACA,KAAA;AAAA,EACA,SAAA,GAAY,KAAA;AAAA,EACZ,WAAA;AAAA,EACA;AACF,CAAA,EAAgC;AAC9B,EAAA,OAAO,eAAeC,sBACpB,MAAA,EACoD;AACpD,IAAA,MAAM,EAAE,QAAA,EAAU,SAAA,EAAW,KAAA,EAAO,oBAAmB,GAAI,MAAA;AAC3D,IAAA,MAAM,EAAE,SAAA,EAAW,MAAA,EAAO,GAAI,kBAAA,EAAmB;AAEjD,IAAA,MAAM,SAAS,4BAAA,CAA6B;AAAA,MAC1C,KAAA;AAAA,MACA,QAAA;AAAA,MACA,GAAA,EAAK,SAAA;AAAA,MACL;AAAA,KACD,CAAA;AAMD,IAAA,MAAM,MAAA,CAAO,eAAe,kBAAkB,CAAA;AAC9C,IAAA,MAAM,QAAA,GAAW,MAAM,MAAA,CAAO,oBAAA,EAAqB;AAEnD,IAAA,MAAM,cAAA,GAAiB,gBAAA,CAAiB,KAAA,CAAM,KAAK,CAAA;AACnD,IAAA,MAAM,eAAA,GAAkB;AAAA,MACtB,GAAG,QAAA;AAAA,MACH,GAAI,eAAe,MAAA,GAAS,CAAA,GAAI,EAAE,KAAA,EAAO,cAAA,KAAmB;AAAC,KAC/D;AACA,IAAA,MAAM,YAAA,GAAe,0BAA0B,WAAW,CAAA;AAC1D,IAAA,MAAM,OAAA,GAAU,YAAA,GACZ,qBAAA,CAAsB,eAAA,EAAiB,YAAY,CAAA,GACnD,eAAA;AAEJ,IAAA,MAAM,MAAA,GAAwC;AAAA,MAC5C,KAAA;AAAA,MACA,UAAA,EAAY,SAAA;AAAA,MACZ,UAAU,OAAA,CAAQ,QAAA;AAAA,MAClB,GAAI,QAAQ,MAAA,GAAS,EAAE,QAAQ,OAAA,CAAQ,MAAA,KAAW,EAAC;AAAA,MACnD,GAAI,QAAQ,KAAA,GAAQ,EAAE,OAAO,OAAA,CAAQ,KAAA,KAAU;AAAC,KAClD;AAEA,IAAA,MAAM,SAAS,MAAA,CAAO,QAAA,CAAS,OAAO,MAAA,EAAQ,EAAE,QAAQ,CAAA;AAExD,IAAA,WAAA,MAAiB,UAAU,MAAA,EAAQ;AACjC,MAAA,SAAA,IAAY;AAAA,IACd;AAEA,IAAA,MAAM,QAAA,GAAuC,MAAM,MAAA,CAAO,YAAA,EAAa;AAEvE,IAAA,MAAM,SAAA,GAAY,SAAS,OAAA,CAAQ,MAAA;AAAA,MACjC,CAAC,KAAA,KACC,KAAA,CAAM,IAAA,KAAS;AAAA,KACnB;AAEA,IAAA,OAAO;AAAA,MACL,OAAA,EAAS,QAAA;AAAA,MACT,YAAA,EAAc,SAAA,CAAU,GAAA,CAAI,CAAC,EAAA,MAAQ;AAAA,QACnC,IAAI,EAAA,CAAG,EAAA;AAAA,QACP,MAAM,EAAA,CAAG,IAAA;AAAA,QACT,IAAA,EAAO,EAAA,CAAG,KAAA,IAAqC;AAAC,OAClD,CAAE,CAAA;AAAA,MACF,KAAA,EAAO;AAAA,QACL,WAAA,EAAa,SAAS,KAAA,CAAM,YAAA;AAAA,QAC5B,YAAA,EAAc,SAAS,KAAA,CAAM,aAAA;AAAA,QAC7B,iBAAA,EACE,QAAA,CAAS,KAAA,CAAM,2BAAA,IAA+B,MAAA;AAAA,QAChD,gBAAA,EAAkB,QAAA,CAAS,KAAA,CAAM,uBAAA,IAA2B;AAAA;AAC9D,KACF;AAAA,EACF,CAAA;AACF;AAOA,eAAsB,oBAAA,CAAqB;AAAA,EACzC,KAAA;AAAA,EACA,MAAA;AAAA,EACA,KAAA;AAAA,EACA,SAAA;AAAA,EACA,WAAA;AAAA,EACA,KAAA;AAAA,EACA;AACF,CAAA,EAQuD;AACrD,EAAA,MAAM,UAAU,2BAAA,CAA4B;AAAA,IAC1C,KAAA;AAAA,IACA,MAAA;AAAA,IACA,KAAA;AAAA,IACA,SAAA;AAAA,IACA,WAAA;AAAA,IACA;AAAA,GACD,CAAA;AACD,EAAA,OAAO,QAAQ,MAAM,CAAA;AACvB;;;ACdO,SAAS,uBACd,MAAA,EACkB;AAClB,EAAA,MAAM,EAAE,KAAA,EAAO,MAAA,EAAO,GAAI,MAAA;AAS1B,EAAA,MAAM,UAAA,GAAa;AAAA,IACjB,GAAI,MAAA,CAAO,UAAA,KAAe,UAAa,EAAE,UAAA,EAAY,OAAO,UAAA;AAAW,GACzE;AAEA,EAAA,MAAM,kBAAA,GAAqB,CAAC,QAAA,EAAkB,SAAA,KAC5C,4BAAA,CAA6B;AAAA,IAC3B,KAAA;AAAA,IACA,QAAA;AAAA,IACA,GAAA,EAAK,SAAA;AAAA,IACL,GAAG;AAAA,GACJ,CAAA;AAEH,EAAA,MAAM,cAAA,GAAiB,CAAC,QAAA,EAAkB,SAAA,KACxC,yBAAA,CAAyC;AAAA,IACvC,KAAA;AAAA,IACA,QAAA;AAAA,IACA,GAAA,EAAK,SAAA;AAAA,IACL,IAAA,EAAM,eAAA;AAAA,IACN,GAAG,UAAA;AAAA,IACH,GAAI,MAAA,CAAO,SAAA,IAAa,EAAE,SAAA,EAAW,OAAO,SAAA;AAAU,GACvD,CAAA;AAEH,EAAA,MAAM,SAAA,GAAyC;AAAA,IAC7C,MAAM,gBAAA,CACJ,QAAA,EACA,SAAA,EACe;AACf,MAAA,MAAM,MAAA,GAAS,kBAAA,CAAmB,QAAA,EAAU,SAAS,CAAA;AACrD,MAAA,MAAM,OAAO,UAAA,EAAW;AAAA,IAC1B,CAAA;AAAA,IAEA,MAAM,kBAAA,CACJ,QAAA,EACA,EAAA,EACA,SACA,SAAA,EACe;AACf,MAAA,MAAM,MAAA,GAAS,kBAAA,CAAmB,QAAA,EAAU,SAAS,CAAA;AACrD,MAAA,MAAM,MAAA,CAAO,iBAAA,CAAkB,EAAA,EAAI,OAAO,CAAA;AAAA,IAC5C,CAAA;AAAA,IAEA,MAAM,mBAAA,CACJ,QAAA,EACA,EAAA,EACA,SACA,SAAA,EACe;AACf,MAAA,MAAM,MAAA,GAAS,kBAAA,CAAmB,QAAA,EAAU,SAAS,CAAA;AACrD,MAAA,MAAM,MAAA,CAAO,mBAAA,CAAoB,EAAA,EAAI,OAAO,CAAA;AAAA,IAC9C,CAAA;AAAA,IAEA,MAAM,gBAAA,CAAiB,EAAA,EAAY,GAAA,EAAsC;AACvE,MAAA,MAAM,EAAE,QAAA,EAAU,SAAA,EAAW,UAAA,EAAY,QAAA,EAAU,SAAQ,GAAI,GAAA;AAC/D,MAAA,MAAM,MAAA,GAAS,kBAAA,CAAmB,QAAA,EAAU,SAAS,CAAA;AACrD,MAAA,MAAM,MAAA,CAAO,gBAAA,CAAiB,EAAA,EAAI,UAAA,EAAY,UAAU,OAAO,CAAA;AAAA,IACjE,CAAA;AAAA,IAEA,MAAM,kBAAA,CACJ,QAAA,EACA,EAAA,EACA,SACA,SAAA,EACe;AACf,MAAA,MAAM,MAAA,GAAS,kBAAA,CAAmB,QAAA,EAAU,SAAS,CAAA;AACrD,MAAA,MAAM,MAAA,CAAO,sBAAA,CAAuB,EAAA,EAAI,OAAA,CAAQ,OAAO,CAAA;AAAA,IACzD,CAAA;AAAA,IAEA,MAAM,UAAA,CACJ,cAAA,EACA,cAAA,EACA,SAAA,EACe;AACf,MAAA,MAAM,SAAS,4BAAA,CAA6B;AAAA,QAC1C,KAAA;AAAA,QACA,QAAA,EAAU,cAAA;AAAA,QACV,GAAA,EAAK,SAAA;AAAA,QACL,OAAO,MAAA,CAAO,KAAA;AAAA,QACd,GAAG;AAAA,OACJ,CAAA;AACD,MAAA,MAAM,MAAA,CAAO,KAAK,cAAc,CAAA;AAAA,IAClC,CAAA;AAAA,IAEA,MAAM,cAAA,CACJ,QAAA,EACA,SAAA,EACA,SAAA,EACe;AACf,MAAA,MAAM,MAAA,GAAS,kBAAA,CAAmB,QAAA,EAAU,SAAS,CAAA;AACrD,MAAA,MAAM,MAAA,CAAO,eAAe,SAAS,CAAA;AAAA,IACvC,CAAA;AAAA,IAEA,MAAM,eAAA,CACJ,QAAA,EACA,SAAA,EACsC;AACtC,MAAA,MAAM,MAAA,GAAS,kBAAA,CAAmB,QAAA,EAAU,SAAS,CAAA;AACrD,MAAA,OAAO,OAAO,SAAA,EAAU;AAAA,IAC1B,CAAA;AAAA,IAEA,MAAM,eAAA,CACJ,QAAA,EACA,KAAA,EACA,SAAA,EACe;AACf,MAAA,MAAM,MAAA,GAAS,kBAAA,CAAmB,QAAA,EAAU,SAAS,CAAA;AACrD,MAAA,MAAM,MAAA,CAAO,UAAU,KAAK,CAAA;AAAA,IAC9B,CAAA;AAAA,IAEA,MAAM,aAAA,CAAc,QAAA,EAAkB,SAAA,EAAmC;AACvE,MAAA,IAAI,CAAC,OAAO,SAAA,EAAW;AACvB,MAAA,MAAM,cAAA,CAAe,QAAA,EAAU,SAAS,CAAA,CAAE,OAAA,EAAQ;AAAA,IACpD,CAAA;AAAA,IAEA,MAAM,WAAA,CAAY,QAAA,EAAkB,SAAA,EAAmC;AACrE,MAAA,IAAI,CAAC,OAAO,SAAA,EAAW;AACvB,MAAA,MAAM,cAAA,CAAe,QAAA,EAAU,SAAS,CAAA,CAAE,KAAA,EAAM;AAAA,IAClD;AAAA,GACF;AAEA,EAAA,SAAS,iBACP,KAAA,EACuB;AACvB,IAAA,MAAM,SAAS,KAAA,GACX,CAAA,EAAG,UAAU,CAAA,EAAG,MAAM,MAAA,CAAO,CAAC,CAAA,CAAE,WAAA,EAAa,CAAA,EAAG,KAAA,CAAM,KAAA,CAAM,CAAC,CAAC,CAAA,CAAA,GAC9D,UAAA;AACJ,IAAA,MAAM,GAAA,GAAM,CAAC,CAAA,KAAsB,CAAA,CAAE,MAAA,CAAO,CAAC,CAAA,CAAE,WAAA,EAAY,GAAI,CAAA,CAAE,KAAA,CAAM,CAAC,CAAA;AACxE,IAAA,OAAO,MAAA,CAAO,WAAA;AAAA,MACZ,OAAO,OAAA,CAAQ,SAAS,EAAE,GAAA,CAAI,CAAC,CAAC,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA,EAAG,MAAM,CAAA,EAAG,GAAA,CAAI,CAAC,CAAC,CAAA,CAAA,EAAI,CAAC,CAAC;AAAA,KACrE;AAAA,EACF;AAEA,EAAA,MAAM,WAAA,GAAc,CAClB,KAAA,EACA,SAAA,EACA,WAAA,KAC6C;AAC7C,IAAA,MAAM,aAAA,GAA6C;AAAA,MACjD,KAAA;AAAA,MACA,MAAA;AAAA,MACA,KAAA;AAAA,MACA,GAAI,SAAA,KAAc,MAAA,GAAY,EAAE,SAAA,KAAc,EAAC;AAAA,MAC/C,GAAI,MAAA,CAAO,SAAA,KAAc,MAAA,IAAa,SAAA,KAAc,MAAA,GAChD,EAAE,SAAA,EAAW,MAAA,CAAO,SAAA,EAAU,GAC9B,EAAC;AAAA,MACL,GAAI,WAAA,KAAgB,MAAA,GAChB,EAAE,aAAY,GACd,MAAA,CAAO,WAAA,KAAgB,MAAA,GACrB,EAAE,WAAA,EAAa,MAAA,CAAO,WAAA,KACtB,EAAC;AAAA,MACP,OAAO,MAAA,CAAO;AAAA,KAChB;AACA,IAAA,OAAO,4BAA4B,aAAa,CAAA;AAAA,EAClD,CAAA;AAEA,EAAA,MAAM,UAAoD,MAAA,CAAO,KAAA,GAC7D,YAAY,MAAA,CAAO,KAAK,KACtB,MAAM;AACN,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KAEF;AAAA,EACF,CAAA,CAAA;AAEJ,EAAA,OAAO;AAAA,IACL,gBAAA;AAAA,IACA,OAAA;AAAA,IACA,kBAAA,EAAoB,WAAA;AAAA,IACpB,WAAA,EAAa,CAAC,OAAA,KAAY;AAAA,GAC5B;AACF","file":"index.cjs","sourcesContent":["/**\n * Public adapter identity for the Anthropic thread adapter.\n *\n * This value is wire format — it appears as the prefix for Temporal\n * activity names (e.g. `anthropicCodingAgentInitializeThread`) and must\n * never change, since renaming it would orphan existing persisted\n * threads and break in-flight workflows.\n *\n * Re-exported from `zeitlich/adapters/thread/anthropic` so downstream\n * consumers can use the exact same literal the adapter uses internally,\n * typed as the narrow string literal `\"anthropic\"`.\n */\nexport const ADAPTER_ID = \"anthropic\" as const;\n\n/** Narrow string-literal type for {@link ADAPTER_ID}. */\nexport type AdapterId = typeof ADAPTER_ID;\n","/**\n * Public helpers for zeitlich's Redis thread storage layout.\n *\n * These are the exact string-building primitives zeitlich's internal thread\n * manager uses for every adapter. Downstream consumers that need to read a\n * persisted thread (for evaluation, observability, admin tooling, etc.)\n * should use these helpers rather than reconstructing the key layout by\n * hand — the layout is versioned with this module, so upgrading zeitlich\n * keeps the consumer in sync.\n *\n * The layout is adapter-agnostic: every thread adapter stores messages the\n * same way.\n *\n * @example\n * ```typescript\n * import {\n * getThreadListKey,\n * getThreadMetaKey,\n * THREAD_TTL_SECONDS,\n * } from 'zeitlich';\n *\n * const listKey = getThreadListKey('messages', threadId);\n * const metaKey = getThreadMetaKey('messages', threadId);\n * const ttl = await redis.ttl(listKey); // <= THREAD_TTL_SECONDS\n * ```\n */\n\n/**\n * TTL (in seconds) applied to every thread list and thread meta key that\n * zeitlich's {@link createThreadManager} writes. Exposed so downstream\n * consumers can size their Redis retention / query windows to match.\n *\n * Current value: 90 days.\n */\nexport const THREAD_TTL_SECONDS = 60 * 60 * 24 * 90;\n\n/**\n * Build the Redis list key that holds a thread's serialized messages.\n *\n * Mirrors the exact key used internally by zeitlich's thread manager,\n * so a consumer calling `redis.lRange(getThreadListKey(key, id), 0, -1)`\n * sees the same data the writer wrote.\n *\n * @param threadKey - Thread key (defaults to `\"messages\"` inside the\n * thread manager, but downstream adapters may pass\n * their own value).\n * @param threadId - Thread id as provided to the thread manager.\n */\nexport function getThreadListKey(\n threadKey: string,\n threadId: string\n): string {\n return `${threadKey}:thread:${threadId}`;\n}\n\n/**\n * Build the Redis key that stores a thread's existence marker / metadata.\n *\n * Zeitlich treats the presence of this key as \"thread has been\n * initialized\"; append/load/fork/truncate operations fail when it is\n * missing. Consumers can use it as a cheap existence probe without\n * scanning the message list.\n *\n * @param threadKey - Thread key (defaults to `\"messages\"` inside the\n * thread manager, but downstream adapters may pass\n * their own value).\n * @param threadId - Thread id as provided to the thread manager.\n */\nexport function getThreadMetaKey(\n threadKey: string,\n threadId: string\n): string {\n return `${threadKey}:meta:thread:${threadId}`;\n}\n\n/**\n * Build the Redis key that stores a thread's persisted state slice\n * (tasks + custom state) written by zeitlich's session loop on every\n * exit path.\n *\n * Consumers can read this key with `redis.get(getThreadStateKey(key, id))`\n * and `JSON.parse` the result into a {@link PersistedThreadState}.\n *\n * @param threadKey - Thread key (defaults to `\"messages\"` inside the\n * thread manager, but downstream adapters may pass\n * their own value).\n * @param threadId - Thread id as provided to the thread manager.\n */\nexport function getThreadStateKey(\n threadKey: string,\n threadId: string\n): string {\n return `${threadKey}:state:thread:${threadId}`;\n}\n\n/**\n * Build the Redis key that guards an idempotent append against a\n * duplicate write of the message (or message batch) identified by\n * `dedupId`. Zeitlich's thread manager writes one of these per\n * single-message append (and one per batch for multi-message appends),\n * keyed by the message id returned by the configured `idOf`.\n *\n * Note: the key layout intentionally does **not** include the\n * `threadKey` prefix — the dedup namespace is shared across thread\n * keys for a given `threadId`, mirroring the original internal\n * implementation.\n *\n * @param threadId - Thread id as provided to the thread manager.\n * @param dedupId - Joined message ids (single message id for the\n * common single-append case).\n */\nexport function getThreadDedupKey(threadId: string, dedupId: string): string {\n return `dedup:${dedupId}:thread:${threadId}`;\n}\n","import type { PersistedThreadState } from \"../state/types\";\nimport type { ThreadManagerConfig, BaseThreadManager } from \"./types\";\nimport {\n THREAD_TTL_SECONDS,\n getThreadListKey,\n getThreadMetaKey,\n getThreadStateKey,\n getThreadDedupKey,\n} from \"./keys\";\n\n/**\n * Lua script for atomic idempotent append.\n * Checks a dedup key; if it exists the message was already appended and we\n * return 0. Otherwise appends all messages to the list, sets TTL on both\n * the list and the dedup key, and returns 1.\n *\n * KEYS[1] = dedup key, KEYS[2] = list key\n * ARGV[1] = TTL seconds, ARGV[2..N] = serialised messages\n */\nconst APPEND_IDEMPOTENT_SCRIPT = `\nif redis.call('EXISTS', KEYS[1]) == 1 then\n return 0\nend\nfor i = 2, #ARGV do\n redis.call('RPUSH', KEYS[2], ARGV[i])\nend\nredis.call('EXPIRE', KEYS[2], tonumber(ARGV[1]))\nredis.call('SET', KEYS[1], '1', 'EX', tonumber(ARGV[1]))\nreturn 1\n`;\n\n/**\n * Creates a generic thread manager for handling conversation state in Redis.\n * Framework-agnostic — works with any serializable message type.\n */\nexport function createThreadManager<T>(\n config: ThreadManagerConfig<T>\n): BaseThreadManager<T> {\n const {\n redis,\n threadId,\n key = \"messages\",\n serialize = (m: T): string => JSON.stringify(m),\n deserialize = (raw: string): T => JSON.parse(raw) as T,\n idOf,\n ttlSeconds = THREAD_TTL_SECONDS,\n } = config;\n const redisKey = getThreadListKey(key, threadId);\n const metaKey = getThreadMetaKey(key, threadId);\n const stateKey = getThreadStateKey(key, threadId);\n const dedupKey = (id: string): string => getThreadDedupKey(threadId, id);\n\n async function assertThreadExists(): Promise<void> {\n const exists = await redis.exists(metaKey);\n if (!exists) {\n throw new Error(`Thread \"${threadId}\" (key: ${key}) does not exist`);\n }\n }\n\n return {\n async initialize(): Promise<void> {\n await redis.del(redisKey);\n await redis.set(metaKey, \"1\", { EX: ttlSeconds });\n },\n\n async load(): Promise<T[]> {\n await assertThreadExists();\n const data = await redis.lRange(redisKey, 0, -1);\n return data.map(deserialize);\n },\n\n async append(messages: T[]): Promise<void> {\n if (messages.length === 0) return;\n await assertThreadExists();\n\n if (idOf) {\n const dedupId = messages.map(idOf).join(\":\");\n await redis.eval(APPEND_IDEMPOTENT_SCRIPT, {\n keys: [dedupKey(dedupId), redisKey],\n arguments: [String(ttlSeconds), ...messages.map(serialize)],\n });\n } else {\n await redis.rPush(redisKey, messages.map(serialize));\n await redis.expire(redisKey, ttlSeconds);\n }\n },\n\n async fork(newThreadId: string): Promise<BaseThreadManager<T>> {\n await assertThreadExists();\n const data = await redis.lRange(redisKey, 0, -1);\n const stateRaw = await redis.get(stateKey);\n const forked = createThreadManager({\n ...config,\n threadId: newThreadId,\n });\n await forked.initialize();\n if (data.length > 0) {\n const newKey = getThreadListKey(key, newThreadId);\n await redis.rPush(newKey, data);\n await redis.expire(newKey, ttlSeconds);\n }\n if (stateRaw != null) {\n const newStateKey = getThreadStateKey(key, newThreadId);\n await redis.set(newStateKey, stateRaw, { EX: ttlSeconds });\n }\n return forked;\n },\n\n async replaceAll(messages: T[]): Promise<void> {\n await assertThreadExists();\n if (!idOf) {\n throw new Error(\n \"replaceAll requires the thread manager to be configured with `idOf`\"\n );\n }\n const existing = await redis.lRange(redisKey, 0, -1);\n const existingIds = existing\n .map((raw) => idOf(deserialize(raw)))\n .filter((id): id is string => typeof id === \"string\");\n await redis.del(redisKey);\n if (existingIds.length > 0) {\n await redis.del(existingIds.map(dedupKey));\n }\n if (messages.length > 0) {\n await redis.rPush(redisKey, messages.map(serialize));\n await redis.expire(redisKey, ttlSeconds);\n }\n await redis.expire(metaKey, ttlSeconds);\n },\n\n async delete(): Promise<void> {\n await redis.del([redisKey, metaKey, stateKey]);\n },\n\n async loadState(): Promise<PersistedThreadState | null> {\n const raw = await redis.get(stateKey);\n if (raw == null) return null;\n return JSON.parse(raw) as PersistedThreadState;\n },\n\n async saveState(state: PersistedThreadState): Promise<void> {\n await assertThreadExists();\n await redis.set(stateKey, JSON.stringify(state), { EX: ttlSeconds });\n },\n\n async deleteState(): Promise<void> {\n await redis.del(stateKey);\n },\n\n async length(): Promise<number> {\n await assertThreadExists();\n return redis.lLen(redisKey);\n },\n\n async truncateFromId(messageId: string): Promise<void> {\n await assertThreadExists();\n if (!idOf) {\n throw new Error(\n \"truncateFromId requires the thread manager to be configured with `idOf`\"\n );\n }\n const data = await redis.lRange(redisKey, 0, -1);\n let idx = -1;\n const removedIds: string[] = [];\n for (let i = 0; i < data.length; i++) {\n const raw = data[i];\n if (raw === undefined) continue;\n const id = idOf(deserialize(raw));\n if (idx === -1 && id === messageId) idx = i;\n if (idx !== -1) removedIds.push(id);\n }\n if (idx === -1) return;\n if (idx === 0) {\n await redis.del(redisKey);\n await redis.expire(metaKey, ttlSeconds);\n } else {\n await redis.lTrim(redisKey, 0, idx - 1);\n await redis.expire(redisKey, ttlSeconds);\n }\n // Clear dedup markers for the removed messages so that a rewind\n // retry which reuses the same ids (e.g. the same assistantId) can\n // re-append without the idempotent-append Lua script treating it\n // as a duplicate.\n if (removedIds.length > 0) {\n await redis.del(removedIds.map(dedupKey));\n }\n },\n };\n}\n","/**\n * Pure Redis I/O helpers for moving a thread between the hot tier\n * (Redis lists + meta + state + dedup markers) and the cold tier\n * (a single {@link ThreadSnapshot} blob in a {@link ColdThreadStore}).\n *\n * These helpers know nothing about S3 or the adapter-specific message\n * envelope — they operate on the raw Redis representation. The\n * tiered thread manager in `tiered.ts` is the only consumer.\n */\n\nimport type { RedisClientType } from \"redis\";\nimport type { PersistedThreadState } from \"../state/types\";\nimport type { ThreadSnapshot } from \"./cold-store\";\nimport {\n THREAD_TTL_SECONDS,\n getThreadDedupKey,\n getThreadListKey,\n getThreadMetaKey,\n getThreadStateKey,\n} from \"./keys\";\n\n/** Inputs shared by every snapshot operation. */\ninterface SnapshotCommon {\n redis: RedisClientType;\n threadKey: string;\n threadId: string;\n}\n\n/** Configuration for {@link encodeSnapshot}. */\nexport interface EncodeSnapshotConfig extends SnapshotCommon {\n /**\n * Extract a dedup id from each raw-serialized message currently in\n * the thread's Redis list. When omitted, the resulting snapshot has\n * an empty `dedupIds` array — idempotency guarantees are best-effort\n * once a thread crosses the hot/cold boundary.\n */\n idOf?: (raw: string) => string;\n}\n\n/**\n * Build a {@link ThreadSnapshot} from the current hot-tier state.\n *\n * Returns `null` when no thread exists in the hot tier (the meta key\n * is absent) — callers should treat that as \"nothing to flush\".\n */\nexport async function encodeSnapshot(\n config: EncodeSnapshotConfig\n): Promise<ThreadSnapshot | null> {\n const { redis, threadKey, threadId, idOf } = config;\n const metaKey = getThreadMetaKey(threadKey, threadId);\n if ((await redis.exists(metaKey)) === 0) {\n return null;\n }\n const listKey = getThreadListKey(threadKey, threadId);\n const stateKey = getThreadStateKey(threadKey, threadId);\n const messages = await redis.lRange(listKey, 0, -1);\n const stateRaw = await redis.get(stateKey);\n const state =\n stateRaw == null ? null : (JSON.parse(stateRaw) as PersistedThreadState);\n const dedupIds = idOf ? messages.map(idOf) : [];\n return { v: 1, messages, state, dedupIds };\n}\n\n/** Configuration for {@link applySnapshot}. */\nexport interface ApplySnapshotConfig extends SnapshotCommon {\n snapshot: ThreadSnapshot;\n /** TTL applied to every Redis key. Defaults to {@link THREAD_TTL_SECONDS}. */\n ttlSeconds?: number;\n}\n\n/**\n * Restore a {@link ThreadSnapshot} into the hot tier.\n *\n * Idempotent — if the meta key already exists the thread is already\n * hot and this is a no-op. The meta key is written **last** so a\n * crash mid-restore leaves the thread cold (`load` / `append` will\n * see \"thread does not exist\") and the next session's hydrate retries\n * cleanly.\n */\nexport async function applySnapshot(\n config: ApplySnapshotConfig\n): Promise<void> {\n const {\n redis,\n threadKey,\n threadId,\n snapshot,\n ttlSeconds = THREAD_TTL_SECONDS,\n } = config;\n const metaKey = getThreadMetaKey(threadKey, threadId);\n if ((await redis.exists(metaKey)) === 1) {\n return;\n }\n const listKey = getThreadListKey(threadKey, threadId);\n const stateKey = getThreadStateKey(threadKey, threadId);\n\n // Clear partial residue from any prior half-restored attempt.\n // Awaited *outside* the pipeline so a DEL failure (ACL deny,\n // CROSSSLOT, …) short-circuits before any writes hit the wire —\n // pipelines are non-atomic, so a queued DEL wouldn't stop later\n // commands from accumulating data behind a missing meta marker.\n await redis.del([listKey, stateKey]);\n\n // Pipeline the data writes (list/state/dedup) in one round-trip via a\n // non-transactional `MULTI` (`execAsPipeline`). Meta is written\n // separately, only after every queued command succeeded, preserving\n // the \"meta-last\" crash-safety invariant — a partial restore must\n // leave meta absent so the next hydrate retries cleanly.\n const pipeline = redis.multi();\n if (snapshot.messages.length > 0) {\n pipeline.rPush(listKey, snapshot.messages);\n pipeline.expire(listKey, ttlSeconds);\n }\n if (snapshot.state != null) {\n pipeline.set(stateKey, JSON.stringify(snapshot.state), { EX: ttlSeconds });\n }\n for (const id of snapshot.dedupIds) {\n pipeline.set(getThreadDedupKey(threadId, id), \"1\", { EX: ttlSeconds });\n }\n try {\n await pipeline.execAsPipeline();\n } catch (err) {\n // Compensate: pipelines are non-atomic, so writes queued after a\n // failing command (notably dedup SETs) may have landed. Best-effort\n // clear every key we touched so a leftover dedup marker can't\n // silently skip a future append with the same id. node-redis\n // surfaces per-command failures by rejecting `execAsPipeline` with a\n // `MultiErrorReply`; we unwrap it to rethrow the first real error.\n await redis\n .del([\n listKey,\n stateKey,\n ...snapshot.dedupIds.map((id) => getThreadDedupKey(threadId, id)),\n ])\n .catch(() => undefined);\n throw firstPipelineError(err);\n }\n await redis.set(metaKey, \"1\", { EX: ttlSeconds });\n}\n\n/**\n * Unwrap node-redis's `MultiErrorReply` (thrown by `execAsPipeline` when\n * one or more queued commands fail) to the first underlying error so\n * callers see the actual Redis error (OOM, WRONGTYPE, …) rather than the\n * generic aggregate wrapper. The structural check avoids a hard runtime\n * dependency on the `redis` error class.\n */\nfunction firstPipelineError(err: unknown): unknown {\n if (\n err != null &&\n typeof err === \"object\" &&\n \"replies\" in err &&\n Array.isArray((err as { replies: unknown }).replies)\n ) {\n const firstErr = (err as { replies: unknown[] }).replies.find(\n (r): r is Error => r instanceof Error\n );\n if (firstErr) return firstErr;\n }\n return err;\n}\n\n/** Configuration for {@link clearHotTier}. */\nexport interface ClearHotTierConfig extends SnapshotCommon {\n /** Dedup ids to delete alongside the list / meta / state keys. */\n dedupIds?: string[];\n}\n\n/**\n * Delete every Redis key the thread manager wrote for `(threadKey,\n * threadId)`. Used by the tiered manager's `flush({ deleteHot: true })`\n * to drop hot-tier memory after a successful archive write.\n */\nexport async function clearHotTier(\n config: ClearHotTierConfig\n): Promise<void> {\n const { redis, threadKey, threadId, dedupIds = [] } = config;\n const keys = [\n getThreadListKey(threadKey, threadId),\n getThreadMetaKey(threadKey, threadId),\n getThreadStateKey(threadKey, threadId),\n ...dedupIds.map((id) => getThreadDedupKey(threadId, id)),\n ];\n await redis.del(keys);\n}\n","/**\n * Tiered thread manager: Redis hot tier + pluggable cold tier.\n *\n * Wraps {@link createThreadManager} (Redis-only) and adds two\n * session-boundary operations:\n *\n * - `hydrate()` — when the thread is cold (no meta key in Redis),\n * restore the latest {@link ThreadSnapshot} from the cold store.\n * Idempotent; no-op when the thread is already hot or when no\n * snapshot exists.\n * - `flush({ deleteHot })` — write the current Redis state out to the\n * cold store as one snapshot, then (by default) `DEL` the hot-tier\n * keys so idle threads don't sit in Redis memory.\n *\n * All other operations (`append`, `load`, `fork`, `replaceAll`,\n * `truncateFromId`, state I/O) delegate unchanged to the underlying\n * Redis manager, so adapters and tests that use the\n * `BaseThreadManager<T>` interface keep working with zero changes.\n */\n\nimport { createThreadManager } from \"./manager\";\nimport { THREAD_TTL_SECONDS } from \"./keys\";\nimport type { BaseThreadManager, ThreadManagerConfig } from \"./types\";\nimport type { ColdThreadStore } from \"./cold-store\";\nimport {\n applySnapshot,\n clearHotTier,\n encodeSnapshot,\n} from \"./snapshot\";\n\n/** Configuration for {@link createTieredThreadManager}. */\nexport interface TieredThreadManagerConfig<T> extends ThreadManagerConfig<T> {\n /**\n * Cold-tier archive. When omitted, `hydrate()` and `flush()` are\n * no-ops and the manager behaves identically to\n * {@link createThreadManager}.\n */\n coldStore?: ColdThreadStore;\n}\n\n/** Options for {@link TieredThreadManager.flush}. */\nexport interface FlushOptions {\n /**\n * Delete the hot-tier Redis keys after a successful cold-tier\n * write. Defaults to `true` when a cold store is configured —\n * Redis is just a cache and a future continue/fork will\n * re-hydrate in a single round-trip.\n *\n * Set to `false` to keep the hot tier warm (useful for tests or\n * for \"hot-after-flush\" use cases where another session is expected\n * to pick the thread up immediately).\n */\n deleteHot?: boolean;\n}\n\n/**\n * Extension of {@link BaseThreadManager} with the two cold-tier\n * lifecycle methods.\n */\nexport interface TieredThreadManager<T> extends BaseThreadManager<T> {\n /**\n * Restore the latest cold-tier snapshot into Redis when the thread\n * is cold. Idempotent — safe to call from a retried activity.\n */\n hydrate(): Promise<void>;\n /**\n * Write the current Redis state to the cold tier and (optionally)\n * drop the hot-tier keys. Idempotent — last-writer-wins on the\n * cold side.\n */\n flush(opts?: FlushOptions): Promise<void>;\n}\n\n/**\n * Build a thread manager backed by Redis (hot) and an optional\n * pluggable cold store. See module docstring for the lifecycle\n * semantics.\n */\nexport function createTieredThreadManager<T>(\n config: TieredThreadManagerConfig<T>\n): TieredThreadManager<T> {\n const {\n redis,\n threadId,\n key = \"messages\",\n coldStore,\n idOf,\n deserialize = (raw: string): T => JSON.parse(raw) as T,\n ttlSeconds = THREAD_TTL_SECONDS,\n } = config;\n\n const base = createThreadManager<T>(config);\n\n // Snapshot-time `idOf` operates on raw Redis strings — we deserialize\n // here and forward to the configured (deserialized) `idOf`.\n const rawIdOf = idOf\n ? (raw: string): string => idOf(deserialize(raw))\n : undefined;\n\n return Object.assign(base, {\n async hydrate(): Promise<void> {\n if (!coldStore) return;\n const snapshot = await coldStore.read(key, threadId);\n if (!snapshot) return;\n await applySnapshot({\n redis,\n threadKey: key,\n threadId,\n snapshot,\n ttlSeconds,\n });\n },\n\n async flush(opts?: FlushOptions): Promise<void> {\n if (!coldStore) return;\n const snapshot = await encodeSnapshot({\n redis,\n threadKey: key,\n threadId,\n ...(rawIdOf ? { idOf: rawIdOf } : {}),\n });\n if (!snapshot) return;\n await coldStore.write(key, threadId, snapshot);\n const deleteHot = opts?.deleteHot ?? true;\n if (deleteHot) {\n await clearHotTier({\n redis,\n threadKey: key,\n threadId,\n dedupIds: snapshot.dedupIds,\n });\n }\n },\n });\n}\n","import type { RedisClientType as Redis } from \"redis\";\nimport type Anthropic from \"@anthropic-ai/sdk\";\nimport type { JsonValue } from \"../../../lib/state/types\";\nimport { createThreadManager } from \"../../../lib/thread/manager\";\nimport type {\n ProviderThreadManager,\n ThreadManagerConfig,\n ThreadManagerHooks,\n} from \"../../../lib/thread/types\";\n\n/** SDK-native content type for Anthropic human messages */\nexport type AnthropicContent = string | Anthropic.Messages.ContentBlockParam[];\n\n/** SDK-native content type for Anthropic system prompts (supports cache_control blocks) */\nexport type AnthropicSystemContent =\n | string\n | Anthropic.Messages.TextBlockParam[];\n\n/** A MessageParam with a unique ID for idempotent Redis storage */\nexport interface StoredMessage {\n id: string;\n message: Anthropic.Messages.MessageParam;\n /** System messages are stored separately since Anthropic passes them via config */\n isSystem?: boolean;\n}\n\nexport type AnthropicThreadManagerHooks = ThreadManagerHooks<\n StoredMessage,\n Anthropic.Messages.MessageParam\n>;\n\nexport interface AnthropicThreadManagerConfig {\n redis: Redis;\n threadId: string;\n /** Thread key, defaults to 'messages' */\n key?: string;\n hooks?: AnthropicThreadManagerHooks;\n /**\n * Override the default thread TTL (90 days). When pairing the\n * adapter with a durable cold tier, a shorter TTL (hours) is\n * typically more appropriate.\n */\n ttlSeconds?: number;\n}\n\n/** Prepared payload ready to send to the Anthropic API */\nexport interface AnthropicInvocationPayload {\n messages: Anthropic.Messages.MessageParam[];\n system?: string | Anthropic.Messages.TextBlockParam[];\n}\n\n/** Thread manager with Anthropic MessageParam convenience helpers */\nexport interface AnthropicThreadManager extends ProviderThreadManager<\n StoredMessage,\n AnthropicContent,\n JsonValue,\n AnthropicSystemContent\n> {\n appendAssistantMessage(\n id: string,\n content: Anthropic.Messages.ContentBlock[]\n ): Promise<void>;\n prepareForInvocation(): Promise<AnthropicInvocationPayload>;\n}\n\n/** Extract the unique id from a {@link StoredMessage}. */\nexport function storedMessageId(msg: StoredMessage): string {\n return msg.id;\n}\n\n/** Normalise content into an array of ContentBlockParam */\nfunction toContentBlocks(\n content: AnthropicContent\n): Anthropic.Messages.ContentBlockParam[] {\n if (typeof content === \"string\") {\n return [{ type: \"text\", text: content }];\n }\n return content;\n}\n\n/**\n * Merge consecutive messages with the same role.\n * The Anthropic API requires alternating user/assistant turns; without\n * merging, multiple sequential tool-result messages would violate this.\n */\nfunction mergeConsecutiveMessages(\n messages: Anthropic.Messages.MessageParam[]\n): Anthropic.Messages.MessageParam[] {\n const merged: Anthropic.Messages.MessageParam[] = [];\n for (const msg of messages) {\n const last = merged[merged.length - 1];\n if (last && last.role === msg.role) {\n const lastContent = Array.isArray(last.content)\n ? last.content\n : [{ type: \"text\" as const, text: last.content }];\n const msgContent = Array.isArray(msg.content)\n ? msg.content\n : [{ type: \"text\" as const, text: msg.content }];\n last.content = [...lastContent, ...msgContent];\n } else {\n merged.push({\n ...msg,\n content: Array.isArray(msg.content) ? [...msg.content] : msg.content,\n });\n }\n }\n return merged;\n}\n\n/**\n * Creates an Anthropic-specific thread manager that stores StoredMessage\n * instances in Redis and provides convenience helpers for creating and\n * appending typed messages.\n */\nexport function createAnthropicThreadManager(\n config: AnthropicThreadManagerConfig\n): AnthropicThreadManager {\n const baseConfig: ThreadManagerConfig<StoredMessage> = {\n redis: config.redis,\n threadId: config.threadId,\n key: config.key,\n idOf: storedMessageId,\n ...(config.ttlSeconds !== undefined && { ttlSeconds: config.ttlSeconds }),\n };\n\n const base = createThreadManager(baseConfig);\n\n const helpers: Omit<AnthropicThreadManager, keyof typeof base> = {\n async appendUserMessage(\n id: string,\n content: AnthropicContent\n ): Promise<void> {\n await base.append([\n {\n id,\n message: { role: \"user\", content: toContentBlocks(content) },\n },\n ]);\n },\n\n async appendSystemMessage(\n id: string,\n content: AnthropicSystemContent\n ): Promise<void> {\n await base.initialize();\n await base.append([\n {\n id,\n // Stored under a user-role placeholder to satisfy the MessageParam\n // shape; the `isSystem` flag steers extraction in prepareForInvocation.\n message: {\n role: \"user\",\n content: content as Anthropic.Messages.MessageParam[\"content\"],\n },\n isSystem: true,\n },\n ]);\n },\n\n async appendAssistantMessage(\n id: string,\n content: Anthropic.Messages.ContentBlock[]\n ): Promise<void> {\n await base.append([\n {\n id,\n message: {\n role: \"assistant\",\n content:\n content as unknown as Anthropic.Messages.ContentBlockParam[],\n },\n },\n ]);\n },\n\n async appendToolResult(\n id: string,\n toolCallId: string,\n _toolName: string,\n content: JsonValue\n ): Promise<void> {\n const toolContent =\n typeof content === \"string\"\n ? content\n : Array.isArray(content)\n ? (content as unknown as Anthropic.Messages.ToolResultBlockParam[\"content\"])\n : JSON.stringify(content);\n await base.append([\n {\n id,\n message: {\n role: \"user\",\n content: [\n {\n type: \"tool_result\" as const,\n tool_use_id: toolCallId,\n content: toolContent,\n },\n ],\n },\n },\n ]);\n },\n\n async prepareForInvocation(): Promise<AnthropicInvocationPayload> {\n const stored = await base.load();\n const { onPrepareMessage, onPreparedMessage } = config.hooks ?? {};\n const mapped = onPrepareMessage\n ? stored.map((msg, i) => onPrepareMessage(msg, i, stored))\n : stored;\n\n let system: string | Anthropic.Messages.TextBlockParam[] | undefined;\n const conversationMessages: Anthropic.Messages.MessageParam[] = [];\n\n for (const item of mapped) {\n if (item.isSystem) {\n system = item.message.content as\n | string\n | Anthropic.Messages.TextBlockParam[];\n } else {\n conversationMessages.push(item.message);\n }\n }\n\n const messages = mergeConsecutiveMessages(conversationMessages);\n return {\n messages: onPreparedMessage\n ? messages.map((msg, i) => onPreparedMessage(msg, i, messages))\n : messages,\n ...(system ? { system } : {}),\n };\n },\n };\n\n const manager = Object.assign(base, helpers);\n\n const originalFork = manager.fork.bind(manager);\n manager.fork = async (\n newThreadId: string\n ): Promise<AnthropicThreadManager> => {\n await originalFork(newThreadId);\n const forked = createAnthropicThreadManager({\n ...config,\n threadId: newThreadId,\n });\n const { onForkPrepareThread, onForkTransform } = config.hooks ?? {};\n if (!onForkPrepareThread && !onForkTransform) {\n return forked;\n }\n let next = await forked.load();\n if (onForkPrepareThread) {\n next = await onForkPrepareThread(next);\n }\n if (onForkTransform) {\n next = next.map((msg, i) => onForkTransform(msg, i, next));\n }\n await forked.replaceAll(next);\n return forked;\n };\n\n return manager;\n}\n","import type Anthropic from \"@anthropic-ai/sdk\";\n\nexport interface AnthropicPromptCacheOptions {\n /** TTL for the cache checkpoint. Defaults to 5m. */\n ttl?: Anthropic.Messages.CacheControlEphemeral[\"ttl\"];\n /** Claude models support at most 4 cache breakpoints per request. */\n maxBreakpoints?: number;\n}\n\nexport type AnthropicPromptCacheConfig = boolean | AnthropicPromptCacheOptions;\n\ninterface PromptCachePayload {\n messages: Anthropic.Messages.MessageParam[];\n system?: string | Anthropic.Messages.TextBlockParam[];\n tools?: Anthropic.Messages.Tool[];\n}\n\ntype CacheControl = Anthropic.Messages.CacheControlEphemeral;\ntype CacheableRecord = Record<string, unknown> & {\n cache_control?: CacheControl | null;\n};\n\nconst DEFAULT_MAX_CACHE_BREAKPOINTS = 4;\nconst UNCACHEABLE_BLOCK_TYPES = new Set([\"thinking\", \"redacted_thinking\"]);\n\n/**\n * Resolve model-invoker prompt-cache config. Undefined means the default:\n * enabled with an explicit 5 minute TTL.\n */\nexport function resolvePromptCacheOptions(\n promptCache?: AnthropicPromptCacheConfig\n): AnthropicPromptCacheOptions | undefined {\n if (promptCache === false) return undefined;\n if (promptCache === true || promptCache === undefined) return {};\n return promptCache;\n}\n\n/**\n * Add an explicit `cache_control` marker to the final cacheable message block.\n *\n * This intentionally uses block-level cache control rather than Anthropic's\n * top-level automatic `cache_control` field because Amazon Bedrock does not\n * support the top-level form. The block-level shape is accepted by both the\n * Anthropic Messages API and Bedrock InvokeModel for Anthropic Claude models.\n */\nexport function addPromptCacheControl<TPayload extends PromptCachePayload>(\n payload: TPayload,\n options: AnthropicPromptCacheOptions = {}\n): TPayload {\n const maxBreakpoints =\n options.maxBreakpoints ?? DEFAULT_MAX_CACHE_BREAKPOINTS;\n if (maxBreakpoints <= 0) return payload;\n\n if (countCacheControls(payload) >= maxBreakpoints) return payload;\n\n const cacheControl: CacheControl = {\n type: \"ephemeral\",\n ttl: options.ttl ?? \"5m\",\n };\n const messages = addCacheControlToLastMessageBlock(\n payload.messages,\n cacheControl\n );\n\n if (messages === payload.messages) return payload;\n return { ...payload, messages };\n}\n\nfunction addCacheControlToLastMessageBlock(\n messages: Anthropic.Messages.MessageParam[],\n cacheControl: CacheControl\n): Anthropic.Messages.MessageParam[] {\n for (\n let messageIndex = messages.length - 1;\n messageIndex >= 0;\n messageIndex--\n ) {\n const message = messages[messageIndex];\n if (!message) continue;\n\n if (typeof message.content === \"string\") {\n if (message.content.length === 0) continue;\n return replaceMessage(messages, messageIndex, {\n ...message,\n content: [\n { type: \"text\", text: message.content, cache_control: cacheControl },\n ],\n });\n }\n\n if (!Array.isArray(message.content)) continue;\n\n for (\n let blockIndex = message.content.length - 1;\n blockIndex >= 0;\n blockIndex--\n ) {\n const block = message.content[blockIndex];\n if (!isCacheableContentBlock(block)) continue;\n if (hasCacheControl(block)) return messages;\n\n const content = [...message.content];\n content[blockIndex] = {\n ...(block as Record<string, unknown>),\n cache_control: cacheControl,\n } as Anthropic.Messages.ContentBlockParam;\n return replaceMessage(messages, messageIndex, { ...message, content });\n }\n }\n\n return messages;\n}\n\nfunction replaceMessage(\n messages: Anthropic.Messages.MessageParam[],\n index: number,\n message: Anthropic.Messages.MessageParam\n): Anthropic.Messages.MessageParam[] {\n const next = [...messages];\n next[index] = message;\n return next;\n}\n\nfunction isCacheableContentBlock(\n block: Anthropic.Messages.ContentBlockParam | undefined\n): block is Anthropic.Messages.ContentBlockParam & CacheableRecord {\n if (!isRecord(block)) return false;\n const type = typeof block.type === \"string\" ? block.type : undefined;\n if (type && UNCACHEABLE_BLOCK_TYPES.has(type)) return false;\n if (type === \"text\" && block.text === \"\") return false;\n return true;\n}\n\nfunction countCacheControls(payload: PromptCachePayload): number {\n let count = 0;\n\n for (const tool of payload.tools ?? []) {\n if (hasCacheControl(tool)) count++;\n }\n\n if (Array.isArray(payload.system)) {\n for (const block of payload.system) {\n if (hasCacheControl(block)) count++;\n }\n }\n\n for (const message of payload.messages) {\n if (!Array.isArray(message.content)) continue;\n for (const block of message.content) {\n if (hasCacheControl(block)) count++;\n }\n }\n\n return count;\n}\n\nfunction hasCacheControl(value: unknown): value is CacheableRecord {\n return isRecord(value) && value.cache_control != null;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n","import { Context } from \"@temporalio/activity\";\nimport type { WorkflowClient } from \"@temporalio/client\";\nimport type { BaseAgentState, RunAgentConfig } from \"./types\";\nimport type { JsonValue } from \"./state/types\";\nimport type {\n ActivityToolHandler,\n RouterContext,\n ToolHandlerResponse,\n} from \"./tool-router/types\";\n\n/**\n * Safely retrieve Temporal activity heartbeat and cancellation signal.\n * Returns empty object when called outside a Temporal activity (e.g. tests).\n */\nexport function getActivityContext(): {\n heartbeat?: () => void;\n signal?: AbortSignal;\n} {\n try {\n const ctx = Context.current();\n return { heartbeat: () => ctx.heartbeat(), signal: ctx.cancellationSignal };\n } catch {\n return {};\n }\n}\n\n/**\n * Query the parent workflow's state from within an activity.\n * Resolves the workflow handle from the current activity context.\n */\nexport async function queryParentWorkflowState<T>(\n client: WorkflowClient\n): Promise<T> {\n const { workflowExecution } = Context.current().info;\n\n if (!workflowExecution) {\n throw new Error(\"No workflow execution found\");\n }\n\n const handle = client.getHandle(\n workflowExecution.workflowId,\n workflowExecution.runId\n );\n return handle.query<T>(\"getAgentState\");\n}\n\n/**\n * Wraps a handler into a scope-prefixed `RunAgentActivity` by auto-fetching\n * the parent workflow's agent state before each invocation.\n *\n * Returns a `Record` with a single key `run<Scope>` so it can be spread\n * into the activities object alongside adapter activities.\n *\n * @param scope - Workflow scope used to derive the activity name.\n * `\"myAgentWorkflow\"` produces `{ runMyAgentWorkflow: fn }`.\n *\n * @example\n * ```typescript\n * import { createRunAgentActivity } from 'zeitlich';\n *\n * return {\n * ...adapter.createActivities(\"myAgentWorkflow\"),\n * ...createRunAgentActivity(client, adapter.invoker, \"myAgentWorkflow\"),\n * };\n * ```\n */\nexport function createRunAgentActivity<\n R,\n S extends BaseAgentState = BaseAgentState,\n>(\n client: WorkflowClient,\n handler: (config: RunAgentConfig & { state: S }) => Promise<R>,\n scope: string\n): Record<string, (config: RunAgentConfig) => Promise<R>> {\n const name = `run${scope.charAt(0).toUpperCase()}${scope.slice(1)}`;\n return {\n [name]: async (config: RunAgentConfig) => {\n const state = await queryParentWorkflowState<S>(client);\n return handler({ ...config, state });\n },\n };\n}\n\n/**\n * Context injected into tool handlers created via {@link withParentWorkflowState}.\n */\nexport interface AgentStateContext<\n S extends BaseAgentState = BaseAgentState,\n> extends RouterContext {\n state: S;\n}\n\n/**\n * Wraps a tool handler into an `ActivityToolHandler` by auto-fetching the\n * parent workflow's agent state before each invocation.\n *\n * @typeParam S - Custom agent state type (defaults to `BaseAgentState`)\n *\n * @example\n * ```typescript\n * import { withParentWorkflowState, type AgentStateContext } from 'zeitlich';\n *\n * // With custom state:\n * interface MyState extends BaseAgentState { customField: string }\n * const myHandler = withParentWorkflowState<MyArgs, MyResult, MyState>(\n * client,\n * async (args, ctx) => {\n * console.log(ctx.state.customField);\n * return { toolResponse: 'done', data: null };\n * },\n * );\n * ```\n */\nexport function withParentWorkflowState<\n TArgs,\n TResult,\n S extends BaseAgentState = BaseAgentState,\n TToolResponse = JsonValue,\n>(\n client: WorkflowClient,\n handler: (\n args: TArgs,\n context: AgentStateContext<S>\n ) => Promise<ToolHandlerResponse<TResult, TToolResponse>>\n): ActivityToolHandler<TArgs, TResult, RouterContext, TToolResponse> {\n return async (args, context) => {\n const state = await queryParentWorkflowState<S>(client);\n return handler(args, { ...context, state });\n };\n}\n","import type { RedisClientType as Redis } from \"redis\";\nimport type Anthropic from \"@anthropic-ai/sdk\";\nimport type { SerializableToolDefinition } from \"../../../lib/types\";\nimport type { AgentResponse, ModelInvokerConfig } from \"../../../lib/model\";\nimport {\n createAnthropicThreadManager,\n type AnthropicThreadManagerHooks,\n} from \"./thread-manager\";\nimport {\n addPromptCacheControl,\n resolvePromptCacheOptions,\n type AnthropicPromptCacheConfig,\n} from \"./prompt-cache\";\nimport { getActivityContext } from \"../../../lib/activity\";\n\nexport interface AnthropicModelInvokerConfig {\n redis: Redis;\n client: Anthropic;\n model: string;\n /** Maximum tokens to generate. Defaults to 16384. */\n maxTokens?: number;\n /**\n * Controls Anthropic/Bedrock-compatible prompt caching. Defaults to enabled\n * with an explicit 5 minute TTL. Set to `false` to disable.\n */\n promptCache?: AnthropicPromptCacheConfig;\n hooks?: AnthropicThreadManagerHooks;\n}\n\nfunction toAnthropicTools(\n tools: SerializableToolDefinition[]\n): Anthropic.Messages.Tool[] {\n return tools.map((t) => ({\n name: t.name,\n description: t.description,\n input_schema: t.schema as Anthropic.Messages.Tool.InputSchema,\n }));\n}\n\n/**\n * Creates an Anthropic model invoker that satisfies the generic\n * `ModelInvoker<Anthropic.Messages.Message>` contract.\n *\n * Internally streams the response and emits Temporal heartbeats on each\n * event so that long-running LLM calls remain visible to the scheduler.\n * The caller is responsible for appending the response to the thread.\n *\n * @example\n * ```typescript\n * import { createAnthropicModelInvoker } from 'zeitlich/adapters/thread/anthropic';\n * import { createRunAgentActivity } from 'zeitlich';\n * import Anthropic from '@anthropic-ai/sdk';\n *\n * const client = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY });\n * const invoker = createAnthropicModelInvoker({\n * redis,\n * client,\n * model: 'claude-sonnet-4-20250514',\n * });\n *\n * return { ...createRunAgentActivity(client, invoker, \"myAgent\") };\n * ```\n */\nexport function createAnthropicModelInvoker({\n redis,\n client,\n model,\n maxTokens = 16384,\n promptCache,\n hooks,\n}: AnthropicModelInvokerConfig) {\n return async function invokeAnthropicModel(\n config: ModelInvokerConfig\n ): Promise<AgentResponse<Anthropic.Messages.Message>> {\n const { threadId, threadKey, state, assistantMessageId } = config;\n const { heartbeat, signal } = getActivityContext();\n\n const thread = createAnthropicThreadManager({\n redis,\n threadId,\n key: threadKey,\n hooks,\n });\n // Truncate the thread starting at the id the assistant message\n // will be stored under. On the happy path this is a no-op; on a\n // rewind retry or a Temporal workflow reset it wipes the prior\n // attempt's assistant + tool results so the LLM sees the same\n // pre-call state that it saw originally.\n await thread.truncateFromId(assistantMessageId);\n const prepared = await thread.prepareForInvocation();\n\n const anthropicTools = toAnthropicTools(state.tools);\n const preparedPayload = {\n ...prepared,\n ...(anthropicTools.length > 0 ? { tools: anthropicTools } : {}),\n };\n const cacheOptions = resolvePromptCacheOptions(promptCache);\n const payload = cacheOptions\n ? addPromptCacheControl(preparedPayload, cacheOptions)\n : preparedPayload;\n\n const params: Anthropic.MessageCreateParams = {\n model,\n max_tokens: maxTokens,\n messages: payload.messages,\n ...(payload.system ? { system: payload.system } : {}),\n ...(payload.tools ? { tools: payload.tools } : {}),\n };\n\n const stream = client.messages.stream(params, { signal });\n\n for await (const _event of stream) {\n heartbeat?.();\n }\n\n const response: Anthropic.Messages.Message = await stream.finalMessage();\n\n const toolCalls = response.content.filter(\n (block): block is Anthropic.Messages.ToolUseBlock =>\n block.type === \"tool_use\"\n );\n\n return {\n message: response,\n rawToolCalls: toolCalls.map((tc) => ({\n id: tc.id,\n name: tc.name,\n args: (tc.input as Record<string, unknown>) ?? {},\n })),\n usage: {\n inputTokens: response.usage.input_tokens,\n outputTokens: response.usage.output_tokens,\n cachedWriteTokens:\n response.usage.cache_creation_input_tokens ?? undefined,\n cachedReadTokens: response.usage.cache_read_input_tokens ?? undefined,\n },\n };\n };\n}\n\n/**\n * Standalone function for one-shot Anthropic model invocation.\n * Convenience wrapper around createAnthropicModelInvoker for cases\n * where you don't need to reuse the invoker.\n */\nexport async function invokeAnthropicModel({\n redis,\n client,\n model,\n maxTokens,\n promptCache,\n hooks,\n config,\n}: {\n redis: Redis;\n client: Anthropic;\n model: string;\n maxTokens?: number;\n promptCache?: AnthropicPromptCacheConfig;\n hooks?: AnthropicThreadManagerHooks;\n config: ModelInvokerConfig;\n}): Promise<AgentResponse<Anthropic.Messages.Message>> {\n const invoker = createAnthropicModelInvoker({\n redis,\n client,\n model,\n maxTokens,\n promptCache,\n hooks,\n });\n return invoker(config);\n}\n","import type { RedisClientType as Redis } from \"redis\";\nimport type Anthropic from \"@anthropic-ai/sdk\";\nimport type { ToolResultConfig } from \"../../../lib/types\";\nimport type { PersistedThreadState } from \"../../../lib/state/types\";\nimport type {\n ActivityToolHandler,\n RouterContext,\n ToolHandlerResponse,\n} from \"../../../lib/tool-router/types\";\nimport type {\n ThreadOps,\n PrefixedThreadOps,\n ScopedPrefix,\n} from \"../../../lib/session/types\";\nimport type { ModelInvoker } from \"../../../lib/model\";\nimport { createTieredThreadManager } from \"../../../lib/thread/tiered\";\nimport type { ColdThreadStore } from \"../../../lib/thread/cold-store\";\nimport {\n createAnthropicThreadManager,\n storedMessageId,\n type AnthropicContent,\n type AnthropicSystemContent,\n type AnthropicThreadManagerHooks,\n type StoredMessage,\n} from \"./thread-manager\";\nimport {\n createAnthropicModelInvoker,\n type AnthropicModelInvokerConfig,\n} from \"./model-invoker\";\nimport type { AnthropicPromptCacheConfig } from \"./prompt-cache\";\nimport { ADAPTER_ID } from \"./adapter-id\";\n\nexport type AnthropicThreadOps<TScope extends string = \"\"> = PrefixedThreadOps<\n ScopedPrefix<TScope, typeof ADAPTER_ID>,\n AnthropicContent\n>;\n\nexport interface AnthropicAdapterConfig {\n redis: Redis;\n client: Anthropic;\n /** Default model name (e.g. 'claude-sonnet-4-20250514'). If omitted, use `createModelInvoker()` */\n model?: string;\n /** Maximum tokens to generate. Defaults to 16384. */\n maxTokens?: number;\n /**\n * Controls Anthropic/Bedrock-compatible prompt caching. Defaults to enabled\n * with an explicit 5 minute TTL. Set to `false` to disable.\n */\n promptCache?: AnthropicPromptCacheConfig;\n hooks?: AnthropicThreadManagerHooks;\n /**\n * Optional durable cold tier (e.g. S3, R2, GCS). When provided,\n * the session will hydrate the thread from cold storage on entry\n * (`continue`/`fork` modes) and flush it back on every exit path.\n * When omitted, the adapter is Redis-only and `hydrateThread`/\n * `flushThread` activities are no-ops.\n */\n coldStore?: ColdThreadStore;\n /**\n * Override the default Redis TTL (90 days) for thread keys. When\n * pairing the adapter with a `coldStore`, a shorter TTL (hours)\n * is typically more appropriate.\n */\n ttlSeconds?: number;\n}\n\n/**\n * Tool response type accepted by the Anthropic adapter.\n *\n * Handlers can return:\n * - **`string`** — plain text content for the tool result.\n * - **`Anthropic.Messages.ToolResultBlockParam[\"content\"]`** — array of content blocks\n * (e.g. `{ type: \"text\", text: \"...\" }`, `{ type: \"image\", source: { ... } }`).\n * Passed through as-is to the `tool_result` block.\n */\nexport type AnthropicToolResponse =\n Anthropic.Messages.ToolResultBlockParam[\"content\"];\n\nexport interface AnthropicAdapter {\n /** Model invoker using the default model (only available when `model` was provided) */\n invoker: ModelInvoker<Anthropic.Messages.Message>;\n /** Create an invoker for a specific model name (for multi-model setups) */\n createModelInvoker(\n model: string,\n maxTokens?: number,\n promptCache?: AnthropicPromptCacheConfig\n ): ModelInvoker<Anthropic.Messages.Message>;\n /**\n * Create prefixed thread activities for registration on the worker.\n *\n * @param scope - Workflow name appended to the adapter prefix.\n * Use different scopes for the main agent vs subagents to avoid collisions.\n *\n * @example\n * ```typescript\n * adapter.createActivities(\"codingAgent\")\n * // → { anthropicCodingAgentInitializeThread, anthropicCodingAgentAppendHumanMessage, … }\n *\n * adapter.createActivities(\"researchAgent\")\n * // → { anthropicResearchAgentInitializeThread, … }\n * ```\n */\n createActivities<S extends string = \"\">(scope?: S): AnthropicThreadOps<S>;\n\n /**\n * Identity wrapper that types a tool handler for this adapter.\n * Constrains `toolResponse` to {@link AnthropicToolResponse}.\n */\n wrapHandler<TArgs, TResult, TContext extends RouterContext = RouterContext>(\n handler: (\n args: TArgs,\n context: TContext\n ) => Promise<ToolHandlerResponse<TResult, AnthropicToolResponse>>\n ): ActivityToolHandler<TArgs, TResult, TContext, AnthropicToolResponse>;\n}\n\n/**\n * Creates an Anthropic adapter that bundles thread operations and model\n * invocation using the `@anthropic-ai/sdk`.\n *\n * Use `createActivities(scope)` to register scoped thread operations as\n * Temporal activities on the worker. The `invoker` (or invokers created via\n * `createModelInvoker`) should be wrapped with `createRunAgentActivity`.\n *\n * @example\n * ```typescript\n * import { createAnthropicAdapter } from 'zeitlich/adapters/thread/anthropic';\n * import { createRunAgentActivity } from 'zeitlich';\n * import Anthropic from '@anthropic-ai/sdk';\n *\n * const client = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY });\n * const adapter = createAnthropicAdapter({ redis, client, model: 'claude-sonnet-4-20250514' });\n *\n * export function createActivities(temporalClient: WorkflowClient) {\n * return {\n * ...adapter.createActivities(\"codingAgent\"),\n * ...createRunAgentActivity(temporalClient, adapter.invoker, \"codingAgent\"),\n * };\n * }\n * ```\n *\n * @example Multi-agent worker (main + subagent share the adapter)\n * ```typescript\n * export function createActivities(temporalClient: WorkflowClient) {\n * return {\n * ...adapter.createActivities(\"codingAgent\"),\n * ...adapter.createActivities(\"researchAgent\"),\n * ...createRunAgentActivity(temporalClient, adapter.invoker, \"codingAgent\"),\n * ...createRunAgentActivity(\n * temporalClient,\n * adapter.createModelInvoker('claude-sonnet-4-20250514'),\n * \"researchAgent\",\n * ),\n * };\n * }\n * ```\n */\nexport function createAnthropicAdapter(\n config: AnthropicAdapterConfig\n): AnthropicAdapter {\n const { redis, client } = config;\n\n /**\n * Common per-call config plumbed into both the provider thread\n * manager (for message I/O) and the tiered base manager (for\n * hot↔cold lifecycle ops). Keeping them in lockstep means a single\n * `coldStore` / `ttlSeconds` configuration controls every Redis\n * write the adapter does.\n */\n const baseExtras = {\n ...(config.ttlSeconds !== undefined && { ttlSeconds: config.ttlSeconds }),\n };\n\n const makeProviderThread = (threadId: string, threadKey?: string) =>\n createAnthropicThreadManager({\n redis,\n threadId,\n key: threadKey,\n ...baseExtras,\n });\n\n const makeTieredBase = (threadId: string, threadKey?: string) =>\n createTieredThreadManager<StoredMessage>({\n redis,\n threadId,\n key: threadKey,\n idOf: storedMessageId,\n ...baseExtras,\n ...(config.coldStore && { coldStore: config.coldStore }),\n });\n\n const threadOps: ThreadOps<AnthropicContent> = {\n async initializeThread(\n threadId: string,\n threadKey?: string\n ): Promise<void> {\n const thread = makeProviderThread(threadId, threadKey);\n await thread.initialize();\n },\n\n async appendHumanMessage(\n threadId: string,\n id: string,\n content: AnthropicContent,\n threadKey?: string\n ): Promise<void> {\n const thread = makeProviderThread(threadId, threadKey);\n await thread.appendUserMessage(id, content);\n },\n\n async appendSystemMessage(\n threadId: string,\n id: string,\n content: AnthropicSystemContent,\n threadKey?: string\n ): Promise<void> {\n const thread = makeProviderThread(threadId, threadKey);\n await thread.appendSystemMessage(id, content);\n },\n\n async appendToolResult(id: string, cfg: ToolResultConfig): Promise<void> {\n const { threadId, threadKey, toolCallId, toolName, content } = cfg;\n const thread = makeProviderThread(threadId, threadKey);\n await thread.appendToolResult(id, toolCallId, toolName, content);\n },\n\n async appendAgentMessage(\n threadId: string,\n id: string,\n message: Anthropic.Messages.Message,\n threadKey?: string\n ): Promise<void> {\n const thread = makeProviderThread(threadId, threadKey);\n await thread.appendAssistantMessage(id, message.content);\n },\n\n async forkThread(\n sourceThreadId: string,\n targetThreadId: string,\n threadKey?: string\n ): Promise<void> {\n const thread = createAnthropicThreadManager({\n redis,\n threadId: sourceThreadId,\n key: threadKey,\n hooks: config.hooks,\n ...baseExtras,\n });\n await thread.fork(targetThreadId);\n },\n\n async truncateThread(\n threadId: string,\n messageId: string,\n threadKey?: string\n ): Promise<void> {\n const thread = makeProviderThread(threadId, threadKey);\n await thread.truncateFromId(messageId);\n },\n\n async loadThreadState(\n threadId: string,\n threadKey?: string\n ): Promise<PersistedThreadState | null> {\n const thread = makeProviderThread(threadId, threadKey);\n return thread.loadState();\n },\n\n async saveThreadState(\n threadId: string,\n state: PersistedThreadState,\n threadKey?: string\n ): Promise<void> {\n const thread = makeProviderThread(threadId, threadKey);\n await thread.saveState(state);\n },\n\n async hydrateThread(threadId: string, threadKey?: string): Promise<void> {\n if (!config.coldStore) return;\n await makeTieredBase(threadId, threadKey).hydrate();\n },\n\n async flushThread(threadId: string, threadKey?: string): Promise<void> {\n if (!config.coldStore) return;\n await makeTieredBase(threadId, threadKey).flush();\n },\n };\n\n function createActivities<S extends string = \"\">(\n scope?: S\n ): AnthropicThreadOps<S> {\n const prefix = scope\n ? `${ADAPTER_ID}${scope.charAt(0).toUpperCase()}${scope.slice(1)}`\n : ADAPTER_ID;\n const cap = (s: string): string => s.charAt(0).toUpperCase() + s.slice(1);\n return Object.fromEntries(\n Object.entries(threadOps).map(([k, v]) => [`${prefix}${cap(k)}`, v])\n ) as AnthropicThreadOps<S>;\n }\n\n const makeInvoker = (\n model: string,\n maxTokens?: number,\n promptCache?: AnthropicPromptCacheConfig\n ): ModelInvoker<Anthropic.Messages.Message> => {\n const invokerConfig: AnthropicModelInvokerConfig = {\n redis,\n client,\n model,\n ...(maxTokens !== undefined ? { maxTokens } : {}),\n ...(config.maxTokens !== undefined && maxTokens === undefined\n ? { maxTokens: config.maxTokens }\n : {}),\n ...(promptCache !== undefined\n ? { promptCache }\n : config.promptCache !== undefined\n ? { promptCache: config.promptCache }\n : {}),\n hooks: config.hooks,\n };\n return createAnthropicModelInvoker(invokerConfig);\n };\n\n const invoker: ModelInvoker<Anthropic.Messages.Message> = config.model\n ? makeInvoker(config.model)\n : ((() => {\n throw new Error(\n \"No default model provided to createAnthropicAdapter. \" +\n \"Either pass `model` in the config or use `createModelInvoker(model)` instead.\"\n );\n }) as unknown as ModelInvoker<Anthropic.Messages.Message>);\n\n return {\n createActivities,\n invoker,\n createModelInvoker: makeInvoker,\n wrapHandler: (handler) => handler,\n };\n}\n"]}
@@ -1,18 +1,18 @@
1
1
  import { A as ADAPTER_ID } from '../../../adapter-id-CMwVrVqv.cjs';
2
2
  export { a as AdapterId } from '../../../adapter-id-CMwVrVqv.cjs';
3
- import Redis from 'ioredis';
3
+ import { RedisClientType } from 'redis';
4
4
  import Anthropic from '@anthropic-ai/sdk';
5
- import { a as ModelInvoker, b as PrefixedThreadOps, S as ScopedPrefix, R as RouterContext, c as ToolHandlerResponse, d as ActivityToolHandler, M as ModelInvokerConfig, A as AgentResponse } from '../../../types-DWeyCTYK.cjs';
6
- import { C as ColdThreadStore } from '../../../cold-store-UL13Sstw.cjs';
7
- import { A as AnthropicContent, a as AnthropicThreadManagerHooks } from '../../../thread-manager-R6c3lnJy.cjs';
8
- export { b as AnthropicInvocationPayload, c as AnthropicThreadManager, d as AnthropicThreadManagerConfig, S as StoredMessage, e as createAnthropicThreadManager } from '../../../thread-manager-R6c3lnJy.cjs';
5
+ import { a as ModelInvoker, b as PrefixedThreadOps, S as ScopedPrefix, R as RouterContext, c as ToolHandlerResponse, d as ActivityToolHandler, M as ModelInvokerConfig, A as AgentResponse } from '../../../types-DZnUqCAP.cjs';
6
+ import { C as ColdThreadStore } from '../../../cold-store-C0uvYTSi.cjs';
7
+ import { A as AnthropicContent, a as AnthropicThreadManagerHooks } from '../../../thread-manager-CzIs47uG.cjs';
8
+ export { b as AnthropicInvocationPayload, c as AnthropicThreadManager, d as AnthropicThreadManagerConfig, S as StoredMessage, e as createAnthropicThreadManager } from '../../../thread-manager-CzIs47uG.cjs';
9
9
  import '@temporalio/workflow';
10
10
  import '@temporalio/common/lib/interfaces';
11
11
  import 'zod';
12
- import '../../../types-CJ7tCdl6.cjs';
12
+ import '../../../types-D8W5TnSa.cjs';
13
13
  import '@temporalio/common';
14
14
  import '@aws-sdk/client-s3';
15
- import '../../../types-DDLPnxBh.cjs';
15
+ import '../../../types-d2RvEP6v.cjs';
16
16
 
17
17
  interface AnthropicPromptCacheOptions {
18
18
  /** TTL for the cache checkpoint. Defaults to 5m. */
@@ -43,7 +43,7 @@ declare function addPromptCacheControl<TPayload extends PromptCachePayload>(payl
43
43
 
44
44
  type AnthropicThreadOps<TScope extends string = ""> = PrefixedThreadOps<ScopedPrefix<TScope, typeof ADAPTER_ID>, AnthropicContent>;
45
45
  interface AnthropicAdapterConfig {
46
- redis: Redis;
46
+ redis: RedisClientType;
47
47
  client: Anthropic;
48
48
  /** Default model name (e.g. 'claude-sonnet-4-20250514'). If omitted, use `createModelInvoker()` */
49
49
  model?: string;
@@ -151,7 +151,7 @@ interface AnthropicAdapter {
151
151
  declare function createAnthropicAdapter(config: AnthropicAdapterConfig): AnthropicAdapter;
152
152
 
153
153
  interface AnthropicModelInvokerConfig {
154
- redis: Redis;
154
+ redis: RedisClientType;
155
155
  client: Anthropic;
156
156
  model: string;
157
157
  /** Maximum tokens to generate. Defaults to 16384. */
@@ -194,7 +194,7 @@ declare function createAnthropicModelInvoker({ redis, client, model, maxTokens,
194
194
  * where you don't need to reuse the invoker.
195
195
  */
196
196
  declare function invokeAnthropicModel({ redis, client, model, maxTokens, promptCache, hooks, config, }: {
197
- redis: Redis;
197
+ redis: RedisClientType;
198
198
  client: Anthropic;
199
199
  model: string;
200
200
  maxTokens?: number;
@@ -1,18 +1,18 @@
1
1
  import { A as ADAPTER_ID } from '../../../adapter-id-CMwVrVqv.js';
2
2
  export { a as AdapterId } from '../../../adapter-id-CMwVrVqv.js';
3
- import Redis from 'ioredis';
3
+ import { RedisClientType } from 'redis';
4
4
  import Anthropic from '@anthropic-ai/sdk';
5
- import { a as ModelInvoker, b as PrefixedThreadOps, S as ScopedPrefix, R as RouterContext, c as ToolHandlerResponse, d as ActivityToolHandler, M as ModelInvokerConfig, A as AgentResponse } from '../../../types-DwBYd0ij.js';
6
- import { C as ColdThreadStore } from '../../../cold-store-aD4TSKlU.js';
7
- import { A as AnthropicContent, a as AnthropicThreadManagerHooks } from '../../../thread-manager-DtEtbUkp.js';
8
- export { b as AnthropicInvocationPayload, c as AnthropicThreadManager, d as AnthropicThreadManagerConfig, S as StoredMessage, e as createAnthropicThreadManager } from '../../../thread-manager-DtEtbUkp.js';
5
+ import { a as ModelInvoker, b as PrefixedThreadOps, S as ScopedPrefix, R as RouterContext, c as ToolHandlerResponse, d as ActivityToolHandler, M as ModelInvokerConfig, A as AgentResponse } from '../../../types-YNesmGKV.js';
6
+ import { C as ColdThreadStore } from '../../../cold-store-CCnZYWjx.js';
7
+ import { A as AnthropicContent, a as AnthropicThreadManagerHooks } from '../../../thread-manager-SkSWRPRc.js';
8
+ export { b as AnthropicInvocationPayload, c as AnthropicThreadManager, d as AnthropicThreadManagerConfig, S as StoredMessage, e as createAnthropicThreadManager } from '../../../thread-manager-SkSWRPRc.js';
9
9
  import '@temporalio/workflow';
10
10
  import '@temporalio/common/lib/interfaces';
11
11
  import 'zod';
12
- import '../../../types-CJ7tCdl6.js';
12
+ import '../../../types-D8W5TnSa.js';
13
13
  import '@temporalio/common';
14
14
  import '@aws-sdk/client-s3';
15
- import '../../../types-DF4wzWQG.js';
15
+ import '../../../types-CbPnU4RM.js';
16
16
 
17
17
  interface AnthropicPromptCacheOptions {
18
18
  /** TTL for the cache checkpoint. Defaults to 5m. */
@@ -43,7 +43,7 @@ declare function addPromptCacheControl<TPayload extends PromptCachePayload>(payl
43
43
 
44
44
  type AnthropicThreadOps<TScope extends string = ""> = PrefixedThreadOps<ScopedPrefix<TScope, typeof ADAPTER_ID>, AnthropicContent>;
45
45
  interface AnthropicAdapterConfig {
46
- redis: Redis;
46
+ redis: RedisClientType;
47
47
  client: Anthropic;
48
48
  /** Default model name (e.g. 'claude-sonnet-4-20250514'). If omitted, use `createModelInvoker()` */
49
49
  model?: string;
@@ -151,7 +151,7 @@ interface AnthropicAdapter {
151
151
  declare function createAnthropicAdapter(config: AnthropicAdapterConfig): AnthropicAdapter;
152
152
 
153
153
  interface AnthropicModelInvokerConfig {
154
- redis: Redis;
154
+ redis: RedisClientType;
155
155
  client: Anthropic;
156
156
  model: string;
157
157
  /** Maximum tokens to generate. Defaults to 16384. */
@@ -194,7 +194,7 @@ declare function createAnthropicModelInvoker({ redis, client, model, maxTokens,
194
194
  * where you don't need to reuse the invoker.
195
195
  */
196
196
  declare function invokeAnthropicModel({ redis, client, model, maxTokens, promptCache, hooks, config, }: {
197
- redis: Redis;
197
+ redis: RedisClientType;
198
198
  client: Anthropic;
199
199
  model: string;
200
200
  maxTokens?: number;