zeitlich 0.2.36 → 0.2.38

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 (204) hide show
  1. package/README.md +146 -92
  2. package/dist/{activities-BVI2lTwr.d.ts → activities-BKhMtKDd.d.ts} +4 -2
  3. package/dist/{activities-hd4aNnZE.d.cts → activities-CDcwkRZs.d.cts} +4 -2
  4. package/dist/adapters/sandbox/bedrock/index.cjs +17 -14
  5. package/dist/adapters/sandbox/bedrock/index.cjs.map +1 -1
  6. package/dist/adapters/sandbox/bedrock/index.d.cts +7 -6
  7. package/dist/adapters/sandbox/bedrock/index.d.ts +7 -6
  8. package/dist/adapters/sandbox/bedrock/index.js +17 -14
  9. package/dist/adapters/sandbox/bedrock/index.js.map +1 -1
  10. package/dist/adapters/sandbox/bedrock/workflow.cjs +2 -0
  11. package/dist/adapters/sandbox/bedrock/workflow.cjs.map +1 -1
  12. package/dist/adapters/sandbox/bedrock/workflow.d.cts +2 -2
  13. package/dist/adapters/sandbox/bedrock/workflow.d.ts +2 -2
  14. package/dist/adapters/sandbox/bedrock/workflow.js +2 -0
  15. package/dist/adapters/sandbox/bedrock/workflow.js.map +1 -1
  16. package/dist/adapters/sandbox/daytona/index.cjs +11 -3
  17. package/dist/adapters/sandbox/daytona/index.cjs.map +1 -1
  18. package/dist/adapters/sandbox/daytona/index.d.cts +5 -4
  19. package/dist/adapters/sandbox/daytona/index.d.ts +5 -4
  20. package/dist/adapters/sandbox/daytona/index.js +11 -3
  21. package/dist/adapters/sandbox/daytona/index.js.map +1 -1
  22. package/dist/adapters/sandbox/daytona/workflow.cjs +2 -0
  23. package/dist/adapters/sandbox/daytona/workflow.cjs.map +1 -1
  24. package/dist/adapters/sandbox/daytona/workflow.d.cts +1 -1
  25. package/dist/adapters/sandbox/daytona/workflow.d.ts +1 -1
  26. package/dist/adapters/sandbox/daytona/workflow.js +2 -0
  27. package/dist/adapters/sandbox/daytona/workflow.js.map +1 -1
  28. package/dist/adapters/sandbox/e2b/index.cjs +73 -12
  29. package/dist/adapters/sandbox/e2b/index.cjs.map +1 -1
  30. package/dist/adapters/sandbox/e2b/index.d.cts +26 -4
  31. package/dist/adapters/sandbox/e2b/index.d.ts +26 -4
  32. package/dist/adapters/sandbox/e2b/index.js +73 -12
  33. package/dist/adapters/sandbox/e2b/index.js.map +1 -1
  34. package/dist/adapters/sandbox/e2b/workflow.cjs +2 -0
  35. package/dist/adapters/sandbox/e2b/workflow.cjs.map +1 -1
  36. package/dist/adapters/sandbox/e2b/workflow.d.cts +1 -1
  37. package/dist/adapters/sandbox/e2b/workflow.d.ts +1 -1
  38. package/dist/adapters/sandbox/e2b/workflow.js +2 -0
  39. package/dist/adapters/sandbox/e2b/workflow.js.map +1 -1
  40. package/dist/adapters/sandbox/inmemory/index.cjs +8 -3
  41. package/dist/adapters/sandbox/inmemory/index.cjs.map +1 -1
  42. package/dist/adapters/sandbox/inmemory/index.d.cts +5 -4
  43. package/dist/adapters/sandbox/inmemory/index.d.ts +5 -4
  44. package/dist/adapters/sandbox/inmemory/index.js +8 -3
  45. package/dist/adapters/sandbox/inmemory/index.js.map +1 -1
  46. package/dist/adapters/sandbox/inmemory/workflow.cjs +2 -0
  47. package/dist/adapters/sandbox/inmemory/workflow.cjs.map +1 -1
  48. package/dist/adapters/sandbox/inmemory/workflow.d.cts +1 -1
  49. package/dist/adapters/sandbox/inmemory/workflow.d.ts +1 -1
  50. package/dist/adapters/sandbox/inmemory/workflow.js +2 -0
  51. package/dist/adapters/sandbox/inmemory/workflow.js.map +1 -1
  52. package/dist/adapters/thread/anthropic/index.cjs +94 -39
  53. package/dist/adapters/thread/anthropic/index.cjs.map +1 -1
  54. package/dist/adapters/thread/anthropic/index.d.cts +5 -5
  55. package/dist/adapters/thread/anthropic/index.d.ts +5 -5
  56. package/dist/adapters/thread/anthropic/index.js +94 -39
  57. package/dist/adapters/thread/anthropic/index.js.map +1 -1
  58. package/dist/adapters/thread/anthropic/workflow.cjs +7 -2
  59. package/dist/adapters/thread/anthropic/workflow.cjs.map +1 -1
  60. package/dist/adapters/thread/anthropic/workflow.d.cts +5 -5
  61. package/dist/adapters/thread/anthropic/workflow.d.ts +5 -5
  62. package/dist/adapters/thread/anthropic/workflow.js +7 -2
  63. package/dist/adapters/thread/anthropic/workflow.js.map +1 -1
  64. package/dist/adapters/thread/google-genai/index.cjs +77 -28
  65. package/dist/adapters/thread/google-genai/index.cjs.map +1 -1
  66. package/dist/adapters/thread/google-genai/index.d.cts +5 -5
  67. package/dist/adapters/thread/google-genai/index.d.ts +5 -5
  68. package/dist/adapters/thread/google-genai/index.js +77 -28
  69. package/dist/adapters/thread/google-genai/index.js.map +1 -1
  70. package/dist/adapters/thread/google-genai/workflow.cjs +7 -2
  71. package/dist/adapters/thread/google-genai/workflow.cjs.map +1 -1
  72. package/dist/adapters/thread/google-genai/workflow.d.cts +5 -5
  73. package/dist/adapters/thread/google-genai/workflow.d.ts +5 -5
  74. package/dist/adapters/thread/google-genai/workflow.js +7 -2
  75. package/dist/adapters/thread/google-genai/workflow.js.map +1 -1
  76. package/dist/adapters/thread/langchain/index.cjs +57 -10
  77. package/dist/adapters/thread/langchain/index.cjs.map +1 -1
  78. package/dist/adapters/thread/langchain/index.d.cts +5 -5
  79. package/dist/adapters/thread/langchain/index.d.ts +5 -5
  80. package/dist/adapters/thread/langchain/index.js +57 -10
  81. package/dist/adapters/thread/langchain/index.js.map +1 -1
  82. package/dist/adapters/thread/langchain/workflow.cjs +7 -2
  83. package/dist/adapters/thread/langchain/workflow.cjs.map +1 -1
  84. package/dist/adapters/thread/langchain/workflow.d.cts +5 -5
  85. package/dist/adapters/thread/langchain/workflow.d.ts +5 -5
  86. package/dist/adapters/thread/langchain/workflow.js +7 -2
  87. package/dist/adapters/thread/langchain/workflow.js.map +1 -1
  88. package/dist/index.cjs +322 -146
  89. package/dist/index.cjs.map +1 -1
  90. package/dist/index.d.cts +20 -14
  91. package/dist/index.d.ts +20 -14
  92. package/dist/index.js +323 -147
  93. package/dist/index.js.map +1 -1
  94. package/dist/{proxy-BjdFGPTm.d.ts → proxy-CUlKSvZS.d.ts} +1 -1
  95. package/dist/{proxy-7RnVaPdJ.d.cts → proxy-D_3x7RN4.d.cts} +1 -1
  96. package/dist/{thread-manager-CbpiGq1L.d.ts → thread-manager-CVu7o2cs.d.ts} +4 -2
  97. package/dist/{thread-manager-DzXm9eeI.d.cts → thread-manager-HSwyh28L.d.cts} +4 -2
  98. package/dist/{thread-manager-BBzNgQWH.d.cts → thread-manager-c1gPopAG.d.ts} +4 -2
  99. package/dist/{thread-manager-DjN5JYul.d.ts → thread-manager-wGi-LqIP.d.cts} +4 -2
  100. package/dist/{types-Mc_4BCfT.d.cts → types-BH_IRryz.d.ts} +10 -1
  101. package/dist/{types-yiXmqedU.d.ts → types-BaOw4hKI.d.cts} +10 -1
  102. package/dist/{types-DQ1l_gXL.d.cts → types-C06FwR96.d.cts} +121 -17
  103. package/dist/{types-wiGLvxWf.d.ts → types-DAsQ21Rt.d.ts} +1 -1
  104. package/dist/{types-CADc5V_P.d.ts → types-DNr31FzL.d.ts} +121 -17
  105. package/dist/{types-CBH54cwr.d.cts → types-lm8tMNJQ.d.cts} +1 -1
  106. package/dist/{types-DxCpFNv_.d.cts → types-yx0LzPGn.d.cts} +44 -5
  107. package/dist/{types-DxCpFNv_.d.ts → types-yx0LzPGn.d.ts} +44 -5
  108. package/dist/{workflow-DhtWRovz.d.cts → workflow-CSCkpwAL.d.ts} +2 -2
  109. package/dist/{workflow-P2pTSfKu.d.ts → workflow-DuvMZ8Vm.d.cts} +2 -2
  110. package/dist/workflow.cjs +274 -130
  111. package/dist/workflow.cjs.map +1 -1
  112. package/dist/workflow.d.cts +3 -3
  113. package/dist/workflow.d.ts +3 -3
  114. package/dist/workflow.js +275 -131
  115. package/dist/workflow.js.map +1 -1
  116. package/package.json +2 -2
  117. package/src/adapters/sandbox/bedrock/filesystem.ts +6 -12
  118. package/src/adapters/sandbox/bedrock/index.ts +22 -11
  119. package/src/adapters/sandbox/bedrock/proxy.ts +2 -0
  120. package/src/adapters/sandbox/daytona/index.ts +18 -3
  121. package/src/adapters/sandbox/daytona/proxy.ts +2 -0
  122. package/src/adapters/sandbox/e2b/filesystem.ts +5 -4
  123. package/src/adapters/sandbox/e2b/index.ts +87 -14
  124. package/src/adapters/sandbox/e2b/proxy.ts +2 -0
  125. package/src/adapters/sandbox/e2b/types.ts +16 -0
  126. package/src/adapters/sandbox/inmemory/index.ts +17 -3
  127. package/src/adapters/sandbox/inmemory/proxy.ts +2 -0
  128. package/src/adapters/thread/anthropic/activities.ts +58 -26
  129. package/src/adapters/thread/anthropic/model-invoker.ts +18 -7
  130. package/src/adapters/thread/anthropic/proxy.ts +6 -2
  131. package/src/adapters/thread/anthropic/thread-manager.test.ts +26 -7
  132. package/src/adapters/thread/anthropic/thread-manager.ts +63 -46
  133. package/src/adapters/thread/google-genai/activities.ts +20 -2
  134. package/src/adapters/thread/google-genai/model-invoker.ts +27 -7
  135. package/src/adapters/thread/google-genai/proxy.ts +6 -2
  136. package/src/adapters/thread/google-genai/thread-manager.test.ts +13 -3
  137. package/src/adapters/thread/google-genai/thread-manager.ts +57 -33
  138. package/src/adapters/thread/langchain/activities.ts +55 -24
  139. package/src/adapters/thread/langchain/hooks.test.ts +36 -49
  140. package/src/adapters/thread/langchain/hooks.ts +18 -5
  141. package/src/adapters/thread/langchain/model-invoker.ts +5 -4
  142. package/src/adapters/thread/langchain/proxy.ts +6 -2
  143. package/src/adapters/thread/langchain/thread-manager.test.ts +5 -1
  144. package/src/adapters/thread/langchain/thread-manager.ts +23 -9
  145. package/src/index.ts +4 -1
  146. package/src/lib/activity.ts +16 -6
  147. package/src/lib/hooks/types.ts +6 -6
  148. package/src/lib/lifecycle.ts +18 -3
  149. package/src/lib/model/proxy.ts +2 -2
  150. package/src/lib/model/types.ts +10 -0
  151. package/src/lib/observability/hooks.ts +4 -5
  152. package/src/lib/observability/index.ts +1 -4
  153. package/src/lib/sandbox/manager.ts +45 -20
  154. package/src/lib/sandbox/node-fs.ts +3 -6
  155. package/src/lib/sandbox/sandbox.test.ts +36 -3
  156. package/src/lib/sandbox/tree.integration.test.ts +10 -3
  157. package/src/lib/sandbox/types.ts +60 -6
  158. package/src/lib/session/session-edge-cases.integration.test.ts +316 -14
  159. package/src/lib/session/session.integration.test.ts +161 -1
  160. package/src/lib/session/session.ts +106 -21
  161. package/src/lib/session/types.ts +25 -5
  162. package/src/lib/skills/fs-provider.ts +12 -8
  163. package/src/lib/skills/handler.ts +1 -1
  164. package/src/lib/skills/parse.ts +3 -1
  165. package/src/lib/skills/register.ts +1 -3
  166. package/src/lib/skills/skills.integration.test.ts +25 -15
  167. package/src/lib/state/manager.integration.test.ts +12 -2
  168. package/src/lib/subagent/define.ts +1 -1
  169. package/src/lib/subagent/handler.ts +186 -71
  170. package/src/lib/subagent/index.ts +1 -5
  171. package/src/lib/subagent/register.ts +3 -2
  172. package/src/lib/subagent/signals.ts +1 -10
  173. package/src/lib/subagent/subagent.integration.test.ts +526 -248
  174. package/src/lib/subagent/tool.ts +4 -3
  175. package/src/lib/subagent/types.ts +50 -20
  176. package/src/lib/subagent/workflow.ts +9 -49
  177. package/src/lib/thread/id.test.ts +1 -1
  178. package/src/lib/thread/id.ts +1 -2
  179. package/src/lib/thread/manager.ts +18 -0
  180. package/src/lib/thread/proxy.ts +4 -4
  181. package/src/lib/thread/types.ts +20 -3
  182. package/src/lib/tool-router/index.ts +3 -5
  183. package/src/lib/tool-router/router-edge-cases.integration.test.ts +93 -1
  184. package/src/lib/tool-router/router.integration.test.ts +12 -0
  185. package/src/lib/tool-router/router.ts +90 -16
  186. package/src/lib/tool-router/types.ts +45 -4
  187. package/src/lib/tool-router/with-sandbox.ts +19 -5
  188. package/src/lib/virtual-fs/filesystem.ts +1 -1
  189. package/src/lib/virtual-fs/index.ts +5 -1
  190. package/src/lib/virtual-fs/mutations.ts +2 -4
  191. package/src/lib/virtual-fs/queries.ts +9 -5
  192. package/src/lib/virtual-fs/types.ts +4 -1
  193. package/src/lib/virtual-fs/virtual-fs.test.ts +9 -11
  194. package/src/lib/workflow.test.ts +7 -4
  195. package/src/lib/workflow.ts +1 -5
  196. package/src/tools/ask-user-question/tool.ts +1 -3
  197. package/src/tools/glob/handler.ts +1 -4
  198. package/src/tools/task-get/handler.ts +4 -5
  199. package/src/tools/task-list/handler.ts +1 -4
  200. package/src/tools/task-update/handler.ts +4 -5
  201. package/src/workflow.ts +22 -7
  202. package/tsup.config.ts +9 -6
  203. package/src/lib/.env +0 -1
  204. package/src/tools/bash/.env +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/lib/thread/manager.ts","../../../../src/adapters/thread/langchain/thread-manager.ts","../../../../node_modules/uuid/dist/esm/stringify.js","../../../../node_modules/uuid/dist/esm/rng.js","../../../../node_modules/uuid/dist/esm/native.js","../../../../node_modules/uuid/dist/esm/v4.js","../../../../src/lib/activity.ts","../../../../src/adapters/thread/langchain/model-invoker.ts","../../../../src/adapters/thread/langchain/activities.ts","../../../../src/adapters/thread/langchain/hooks.ts"],"names":["HumanMessage","SystemMessage","AIMessage","ToolMessage","messages","mapStoredMessagesToChatMessages","randomFillSync","randomUUID","Context","invokeLangChainModel","content"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { ThreadManagerConfig, BaseThreadManager } from \"./types\";\n\nconst THREAD_TTL_SECONDS = 60 * 60 * 24 * 90; // 90 days\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\nfunction getThreadKey(threadId: string, key: string): string {\n return `${key}:thread:${threadId}`;\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 } = config;\n const redisKey = getThreadKey(threadId, key);\n const metaKey = getThreadKey(threadId, `${key}:meta`);\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\", THREAD_TTL_SECONDS);\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 const dedupKey = getThreadKey(threadId, `dedup:${dedupId}`);\n await redis.eval(\n APPEND_IDEMPOTENT_SCRIPT,\n 2,\n dedupKey,\n redisKey,\n String(THREAD_TTL_SECONDS),\n ...messages.map(serialize)\n );\n } else {\n await redis.rpush(redisKey, ...messages.map(serialize));\n await redis.expire(redisKey, THREAD_TTL_SECONDS);\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 forked = createThreadManager({\n ...config,\n threadId: newThreadId,\n });\n await forked.initialize();\n if (data.length > 0) {\n const newKey = getThreadKey(newThreadId, key);\n await redis.rpush(newKey, ...data);\n await redis.expire(newKey, THREAD_TTL_SECONDS);\n }\n return forked;\n },\n\n async delete(): Promise<void> {\n await redis.del(redisKey, metaKey);\n },\n };\n}\n","import type Redis from \"ioredis\";\nimport type { JsonValue } from \"../../../lib/state/types\";\nimport {\n AIMessage,\n type BaseMessage,\n HumanMessage,\n type MessageContent,\n type StoredMessage,\n SystemMessage,\n ToolMessage,\n mapStoredMessagesToChatMessages,\n} from \"@langchain/core/messages\";\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 LangChain human messages */\nexport type LangChainContent = string | MessageContent;\n\n/** SDK-native content type for LangChain system messages */\nexport type LangChainSystemContent = string | MessageContent;\n\nexport type LangChainThreadManagerHooks = ThreadManagerHooks<StoredMessage, BaseMessage>;\n\nexport interface LangChainThreadManagerConfig {\n redis: Redis;\n threadId: string;\n /** Thread key, defaults to 'messages' */\n key?: string;\n hooks?: LangChainThreadManagerHooks;\n}\n\n/** Prepared payload ready to send to a LangChain chat model */\nexport interface LangChainInvocationPayload {\n messages: BaseMessage[];\n}\n\n/** Thread manager with LangChain StoredMessage convenience helpers */\nexport interface LangChainThreadManager\n extends ProviderThreadManager<StoredMessage, LangChainContent, JsonValue, LangChainSystemContent> {\n appendAIMessage(id: string, content: string | MessageContent): Promise<void>;\n prepareForInvocation(): Promise<LangChainInvocationPayload>;\n}\n\nfunction storedMessageId(msg: StoredMessage): string {\n if (msg.type === \"tool\" && msg.data.tool_call_id) {\n return msg.data.tool_call_id;\n }\n\n if (msg.data.id) {\n return msg.data.id;\n }\n\n throw new Error(\"No id found for message\");\n}\n\n/**\n * Creates a LangChain-specific thread manager that stores StoredMessage\n * instances in Redis and provides convenience helpers for creating and\n * appending typed LangChain messages.\n */\nexport function createLangChainThreadManager(\n config: LangChainThreadManagerConfig,\n): LangChainThreadManager {\n const baseConfig: ThreadManagerConfig<StoredMessage> = {\n redis: config.redis,\n threadId: config.threadId,\n key: config.key,\n idOf: storedMessageId,\n };\n\n const base = createThreadManager(baseConfig);\n\n const helpers: Omit<LangChainThreadManager, keyof typeof base> = {\n async appendUserMessage(\n id: string,\n content: LangChainContent,\n ): Promise<void> {\n await base.append([\n new HumanMessage({ id, content: content as MessageContent }).toDict(),\n ]);\n },\n\n async appendSystemMessage(\n id: string,\n content: LangChainSystemContent,\n ): Promise<void> {\n await base.initialize();\n await base.append([\n new SystemMessage({\n id,\n content: content as MessageContent,\n }).toDict(),\n ]);\n },\n\n async appendAIMessage(\n id: string,\n content: string | MessageContent,\n ): Promise<void> {\n await base.append([\n new AIMessage({ id, content: content as MessageContent }).toDict(),\n ]);\n },\n\n async appendToolResult(\n id: string,\n _toolCallId: string,\n _toolName: string,\n content: JsonValue,\n ): Promise<void> {\n await base.append([\n new ToolMessage({ id, content: content as MessageContent, tool_call_id: _toolCallId }).toDict(),\n ]);\n },\n\n async prepareForInvocation(): Promise<LangChainInvocationPayload> {\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 const messages = mapStoredMessagesToChatMessages(mapped);\n return {\n messages: onPreparedMessage\n ? messages.map((msg, i) => onPreparedMessage(msg, i, messages))\n : messages,\n };\n },\n };\n\n return Object.assign(base, helpers);\n}\n","import validate from './validate.js';\nconst byteToHex = [];\nfor (let i = 0; i < 256; ++i) {\n byteToHex.push((i + 0x100).toString(16).slice(1));\n}\nexport function unsafeStringify(arr, offset = 0) {\n return (byteToHex[arr[offset + 0]] +\n byteToHex[arr[offset + 1]] +\n byteToHex[arr[offset + 2]] +\n byteToHex[arr[offset + 3]] +\n '-' +\n byteToHex[arr[offset + 4]] +\n byteToHex[arr[offset + 5]] +\n '-' +\n byteToHex[arr[offset + 6]] +\n byteToHex[arr[offset + 7]] +\n '-' +\n byteToHex[arr[offset + 8]] +\n byteToHex[arr[offset + 9]] +\n '-' +\n byteToHex[arr[offset + 10]] +\n byteToHex[arr[offset + 11]] +\n byteToHex[arr[offset + 12]] +\n byteToHex[arr[offset + 13]] +\n byteToHex[arr[offset + 14]] +\n byteToHex[arr[offset + 15]]).toLowerCase();\n}\nfunction stringify(arr, offset = 0) {\n const uuid = unsafeStringify(arr, offset);\n if (!validate(uuid)) {\n throw TypeError('Stringified UUID is invalid');\n }\n return uuid;\n}\nexport default stringify;\n","import { randomFillSync } from 'crypto';\nconst rnds8Pool = new Uint8Array(256);\nlet poolPtr = rnds8Pool.length;\nexport default function rng() {\n if (poolPtr > rnds8Pool.length - 16) {\n randomFillSync(rnds8Pool);\n poolPtr = 0;\n }\n return rnds8Pool.slice(poolPtr, (poolPtr += 16));\n}\n","import { randomUUID } from 'crypto';\nexport default { randomUUID };\n","import native from './native.js';\nimport rng from './rng.js';\nimport { unsafeStringify } from './stringify.js';\nfunction v4(options, buf, offset) {\n if (native.randomUUID && !buf && !options) {\n return native.randomUUID();\n }\n options = options || {};\n const rnds = options.random ?? options.rng?.() ?? rng();\n if (rnds.length < 16) {\n throw new Error('Random bytes length must be >= 16');\n }\n rnds[6] = (rnds[6] & 0x0f) | 0x40;\n rnds[8] = (rnds[8] & 0x3f) | 0x80;\n if (buf) {\n offset = offset || 0;\n if (offset < 0 || offset + 16 > buf.length) {\n throw new RangeError(`UUID byte range ${offset}:${offset + 15} is out of buffer bounds`);\n }\n for (let i = 0; i < 16; ++i) {\n buf[offset + i] = rnds[i];\n }\n return buf;\n }\n return unsafeStringify(rnds);\n}\nexport default v4;\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 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<R, S extends BaseAgentState = BaseAgentState>(\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<S extends BaseAgentState = BaseAgentState> 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<TArgs, TResult, S extends BaseAgentState = BaseAgentState, TToolResponse = JsonValue>(\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 { AgentResponse, ModelInvokerConfig } from \"../../../lib/model\";\nimport type { StoredMessage } from \"@langchain/core/messages\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport type { BaseChatModel } from \"@langchain/core/language_models/chat_models\";\nimport {\n createLangChainThreadManager,\n type LangChainThreadManagerHooks,\n} from \"./thread-manager\";\nimport { getActivityContext } from \"../../../lib/activity\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport interface LangChainModelInvokerConfig<\n TModel extends BaseChatModel<any> = BaseChatModel<any>,\n> {\n redis: Redis;\n model: TModel;\n hooks?: LangChainThreadManagerHooks;\n}\n\n/**\n * Creates a LangChain-based model invoker that satisfies the generic\n * `ModelInvoker<StoredMessage>` contract.\n *\n * Uses interval-based Temporal heartbeats during model.invoke() to keep\n * long-running LLM calls visible to the scheduler. LangChain's streaming\n * chunk accumulation is unreliable across providers (e.g. reasoning_content\n * blocks don't merge correctly), so we use invoke() for correctness.\n * The caller is responsible for appending the response to the thread.\n *\n * @example\n * ```typescript\n * import { createLangChainModelInvoker } from 'zeitlich/adapters/thread/langchain';\n * import { createRunAgentActivity } from 'zeitlich';\n * import { ChatAnthropic } from '@langchain/anthropic';\n *\n * const model = new ChatAnthropic({ model: \"claude-sonnet-4-6\" });\n * const invoker = createLangChainModelInvoker({ redis, model });\n *\n * return { ...createRunAgentActivity(client, invoker, \"myAgent\") };\n * ```\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function createLangChainModelInvoker<\n TModel extends BaseChatModel<any> = BaseChatModel<any>,\n>({ redis, model, hooks }: LangChainModelInvokerConfig<TModel>) {\n return async function invokeLangChainModel(\n config: ModelInvokerConfig\n ): Promise<AgentResponse<StoredMessage>> {\n const { threadId, threadKey, agentName, state, metadata } = config;\n const { heartbeat, signal } = getActivityContext();\n\n const thread = createLangChainThreadManager({\n redis,\n threadId,\n key: threadKey,\n hooks,\n });\n const runId = uuidv4();\n\n const { messages } = await thread.prepareForInvocation();\n\n const heartbeatInterval = heartbeat\n ? setInterval(() => heartbeat(), 30_000)\n : undefined;\n\n try {\n const response = await model.invoke(messages, {\n runName: agentName,\n runId,\n metadata: { thread_id: `${agentName}-${threadId}`, ...metadata },\n tools: state.tools,\n signal,\n });\n\n const toolCalls = response.tool_calls ?? [];\n\n const providerUsage =\n (response.response_metadata?.usage as Record<string, unknown>) ?? {};\n\n return {\n message: response.toDict(),\n rawToolCalls: toolCalls.map((tc) => ({\n id: tc.id,\n name: tc.name,\n args: tc.args,\n })),\n usage: {\n inputTokens: response.usage_metadata?.input_tokens,\n outputTokens: response.usage_metadata?.output_tokens,\n reasonTokens:\n response.usage_metadata?.output_token_details?.reasoning,\n cachedWriteTokens:\n response.usage_metadata?.input_token_details?.cache_creation ||\n (providerUsage.cacheWriteInputTokens as number | undefined),\n cachedReadTokens:\n response.usage_metadata?.input_token_details?.cache_read ||\n (providerUsage.cacheReadInputTokens as number | undefined),\n },\n };\n } finally {\n if (heartbeatInterval) clearInterval(heartbeatInterval);\n }\n };\n}\n\n/**\n * Standalone function for one-shot LangChain model invocation.\n * Convenience wrapper around createLangChainModelInvoker for cases where\n * you don't need to reuse the invoker.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport async function invokeLangChainModel<\n TModel extends BaseChatModel<any> = BaseChatModel<any>,\n>({\n redis,\n model,\n hooks,\n config,\n}: {\n redis: Redis;\n config: ModelInvokerConfig;\n model: TModel;\n hooks?: LangChainThreadManagerHooks;\n}): Promise<AgentResponse<StoredMessage>> {\n const invoker = createLangChainModelInvoker({ redis, model, hooks });\n return invoker(config);\n}\n","import type Redis from \"ioredis\";\nimport type { ToolResultConfig } from \"../../../lib/types\";\nimport type { MessageContent } from \"@langchain/core/messages\";\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 type { StoredMessage } from \"@langchain/core/messages\";\nimport type { BaseChatModel } from \"@langchain/core/language_models/chat_models\";\nimport {\n createLangChainThreadManager,\n type LangChainContent,\n type LangChainSystemContent,\n type LangChainThreadManagerHooks,\n} from \"./thread-manager\";\nimport { createLangChainModelInvoker } from \"./model-invoker\";\n\nconst ADAPTER_PREFIX = \"langChain\" as const;\n\nexport type LangChainThreadOps<TScope extends string = \"\"> =\n PrefixedThreadOps<ScopedPrefix<TScope, typeof ADAPTER_PREFIX>, LangChainContent>;\n\nexport interface LangChainAdapterConfig {\n redis: Redis;\n /** Optional default model — if omitted, use `createModelInvoker()` to create invokers later */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n model?: BaseChatModel<any>;\n hooks?: LangChainThreadManagerHooks;\n}\n\n/**\n * Tool response type accepted by the LangChain adapter.\n *\n * Content is passed directly to `ToolMessage` as `MessageContent`.\n * Handlers can return a string or an array of content blocks\n * (e.g. `{ type: \"text\", text: \"...\" }`, `{ type: \"image_url\", image_url: { ... } }`).\n */\nexport type LangChainToolResponse = MessageContent;\n\nexport interface LangChainAdapter {\n /** Model invoker using the default model (only available when `model` was provided) */\n invoker: ModelInvoker<StoredMessage>;\n /** Create an invoker for a specific model (for multi-model setups) */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n createModelInvoker(model: BaseChatModel<any>): ModelInvoker<StoredMessage>;\n /**\n * Create prefixed thread activities for registration on the worker.\n *\n * @param scope - Workflow name appended to the adapter prefix.\n *\n * @example\n * ```typescript\n * adapter.createActivities(\"codingAgent\")\n * // → { langChainCodingAgentInitializeThread, langChainCodingAgentAppendHumanMessage, … }\n * ```\n */\n createActivities<S extends string = \"\">(\n scope?: S,\n ): LangChainThreadOps<S>;\n\n /**\n * Identity wrapper that types a tool handler for this adapter.\n * Constrains `toolResponse` to {@link LangChainToolResponse}.\n */\n wrapHandler<TArgs, TResult, TContext extends RouterContext = RouterContext>(\n handler: (\n args: TArgs,\n context: TContext,\n ) => Promise<ToolHandlerResponse<TResult, LangChainToolResponse>>,\n ): ActivityToolHandler<TArgs, TResult, TContext, LangChainToolResponse>;\n}\n\n/**\n * Creates a LangChain adapter that bundles thread operations and model\n * invocation using a consistent message format (StoredMessage).\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 { createLangChainAdapter } from 'zeitlich/adapters/thread/langchain';\n * import { createRunAgentActivity } from 'zeitlich';\n *\n * const adapter = createLangChainAdapter({ redis, model });\n *\n * export function createActivities(client: WorkflowClient) {\n * return {\n * ...adapter.createActivities(\"codingAgent\"),\n * ...createRunAgentActivity(client, adapter.invoker, \"codingAgent\"),\n * };\n * }\n * ```\n *\n * @example Multi-agent worker\n * ```typescript\n * export function createActivities(client: WorkflowClient) {\n * return {\n * ...adapter.createActivities(\"codingAgent\"),\n * ...adapter.createActivities(\"researchAgent\"),\n * ...createRunAgentActivity(client, adapter.invoker, \"codingAgent\"),\n * ...createRunAgentActivity(client, adapter.createModelInvoker(claude), \"researchAgent\"),\n * };\n * }\n * ```\n */\nexport function createLangChainAdapter(\n config: LangChainAdapterConfig,\n): LangChainAdapter {\n const { redis } = config;\n\n const threadOps: ThreadOps<LangChainContent> = {\n async initializeThread(threadId: string, threadKey?: string): Promise<void> {\n const thread = createLangChainThreadManager({ redis, threadId, key: threadKey });\n await thread.initialize();\n },\n\n async appendHumanMessage(\n threadId: string,\n id: string,\n content: LangChainContent,\n threadKey?: string,\n ): Promise<void> {\n const thread = createLangChainThreadManager({ redis, threadId, key: threadKey });\n await thread.appendUserMessage(id, content);\n },\n\n async appendSystemMessage(\n threadId: string,\n id: string,\n content: LangChainSystemContent,\n threadKey?: string,\n ): Promise<void> {\n const thread = createLangChainThreadManager({ redis, threadId, key: threadKey });\n await thread.appendSystemMessage(id, content);\n },\n\n async appendToolResult(id: string, cfg: ToolResultConfig): Promise<void> {\n const { threadId, threadKey, toolCallId, content } = cfg;\n const thread = createLangChainThreadManager({ redis, threadId, key: threadKey });\n await thread.appendToolResult(id, toolCallId, \"\", content);\n },\n\n async appendAgentMessage(\n threadId: string,\n id: string,\n message: StoredMessage,\n threadKey?: string,\n ): Promise<void> {\n const thread = createLangChainThreadManager({ redis, threadId, key: threadKey });\n const patched = { ...message, data: { ...message.data, id } };\n await thread.append([patched]);\n },\n\n async forkThread(\n sourceThreadId: string,\n targetThreadId: string,\n threadKey?: string,\n ): Promise<void> {\n const thread = createLangChainThreadManager({\n redis,\n threadId: sourceThreadId,\n key: threadKey,\n });\n await thread.fork(targetThreadId);\n },\n };\n\n function createActivities<S extends string = \"\">(\n scope?: S,\n ): LangChainThreadOps<S> {\n const prefix = scope\n ? `${ADAPTER_PREFIX}${scope.charAt(0).toUpperCase()}${scope.slice(1)}`\n : ADAPTER_PREFIX;\n const cap = (s: string): string =>\n s.charAt(0).toUpperCase() + s.slice(1);\n return Object.fromEntries(\n Object.entries(threadOps).map(([k, v]) => [`${prefix}${cap(k)}`, v]),\n ) as LangChainThreadOps<S>;\n }\n\n const makeInvoker = (\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n model: BaseChatModel<any>,\n ): ModelInvoker<StoredMessage> =>\n createLangChainModelInvoker({ redis, model, hooks: config.hooks });\n\n const invoker: ModelInvoker<StoredMessage> = config.model\n ? makeInvoker(config.model)\n : () => {\n throw new Error(\n \"No default model provided to createLangChainAdapter. \" +\n \"Either pass `model` in the config or use `createModelInvoker(model)` instead.\",\n );\n };\n\n return {\n createActivities,\n invoker,\n createModelInvoker: makeInvoker,\n wrapHandler: (handler) => handler,\n };\n}\n","import type { BaseMessage, MessageContent } from \"@langchain/core/messages\";\n\ntype ContentBlock = MessageContent extends (infer U)[] | string ? U : never;\n\n/**\n * Creates an `onPreparedMessage` hook that appends a cache-point content\n * block to the last message in the thread, and strips excess cache-point\n * blocks from earlier messages so the total never exceeds `maxBlocks`.\n *\n * Older cache-point blocks are removed first, keeping the most recent\n * `maxBlocks - 1` positions plus the last message's block.\n */\nexport function appendCachePoint(\n block: ContentBlock,\n { maxBlocks = 4 }: { maxBlocks?: number } = {},\n): (message: BaseMessage, index: number, messages: readonly BaseMessage[]) => BaseMessage {\n return (message, index, messages) => {\n const isLast = index === messages.length - 1;\n\n if (isLast) {\n const { content } = message;\n if (Array.isArray(content)) {\n if (content.some((b) => b.type === block.type)) return message;\n message.content = [...content, block];\n } else if (typeof content === \"string\") {\n message.content = [{ type: \"text\", text: content }, block] satisfies MessageContent;\n }\n return message;\n }\n\n const { content } = message;\n if (!Array.isArray(content) || !content.some((b) => b.type === block.type)) {\n return message;\n }\n\n // Count cache blocks in messages after this one (excluding the last,\n // which always gets one) plus 1 for the last message itself.\n let cacheBlocksAfter = 1;\n for (let i = index + 1; i < messages.length - 1; i++) {\n const msg = messages[i];\n if (!msg) continue;\n const c = msg.content;\n if (Array.isArray(c) && c.some((b: ContentBlock) => b.type === block.type)) {\n cacheBlocksAfter++;\n }\n }\n\n if (cacheBlocksAfter >= maxBlocks) {\n message.content = content.filter((b) => b.type !== block.type);\n }\n\n return message;\n };\n}\n"]}
1
+ {"version":3,"sources":["../../../../src/lib/thread/manager.ts","../../../../src/adapters/thread/langchain/thread-manager.ts","../../../../node_modules/uuid/dist/esm/stringify.js","../../../../node_modules/uuid/dist/esm/rng.js","../../../../node_modules/uuid/dist/esm/native.js","../../../../node_modules/uuid/dist/esm/v4.js","../../../../src/lib/activity.ts","../../../../src/adapters/thread/langchain/model-invoker.ts","../../../../src/adapters/thread/langchain/activities.ts","../../../../src/adapters/thread/langchain/hooks.ts"],"names":["HumanMessage","SystemMessage","AIMessage","ToolMessage","messages","mapStoredMessagesToChatMessages","randomFillSync","randomUUID","Context","invokeLangChainModel","content"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { ThreadManagerConfig, BaseThreadManager } from \"./types\";\n\nconst THREAD_TTL_SECONDS = 60 * 60 * 24 * 90; // 90 days\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\nfunction getThreadKey(threadId: string, key: string): string {\n return `${key}:thread:${threadId}`;\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 } = config;\n const redisKey = getThreadKey(threadId, key);\n const metaKey = getThreadKey(threadId, `${key}:meta`);\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\", THREAD_TTL_SECONDS);\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 const dedupKey = getThreadKey(threadId, `dedup:${dedupId}`);\n await redis.eval(\n APPEND_IDEMPOTENT_SCRIPT,\n 2,\n dedupKey,\n redisKey,\n String(THREAD_TTL_SECONDS),\n ...messages.map(serialize)\n );\n } else {\n await redis.rpush(redisKey, ...messages.map(serialize));\n await redis.expire(redisKey, THREAD_TTL_SECONDS);\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 forked = createThreadManager({\n ...config,\n threadId: newThreadId,\n });\n await forked.initialize();\n if (data.length > 0) {\n const newKey = getThreadKey(newThreadId, key);\n await redis.rpush(newKey, ...data);\n await redis.expire(newKey, THREAD_TTL_SECONDS);\n }\n return forked;\n },\n\n async delete(): Promise<void> {\n await redis.del(redisKey, metaKey);\n },\n\n async length(): Promise<number> {\n await assertThreadExists();\n return redis.llen(redisKey);\n },\n\n async truncate(length: number): Promise<void> {\n await assertThreadExists();\n if (length <= 0) {\n await redis.del(redisKey);\n await redis.expire(metaKey, THREAD_TTL_SECONDS);\n } else {\n await redis.ltrim(redisKey, 0, length - 1);\n await redis.expire(redisKey, THREAD_TTL_SECONDS);\n }\n // Dedup keys for removed messages are left to expire via their TTL.\n // Post-truncate appends use fresh ids so collisions do not occur in practice.\n },\n };\n}\n","import type Redis from \"ioredis\";\nimport type { JsonValue } from \"../../../lib/state/types\";\nimport {\n AIMessage,\n type BaseMessage,\n HumanMessage,\n type MessageContent,\n type StoredMessage,\n SystemMessage,\n ToolMessage,\n mapStoredMessagesToChatMessages,\n} from \"@langchain/core/messages\";\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 LangChain human messages */\nexport type LangChainContent = string | MessageContent;\n\n/** SDK-native content type for LangChain system messages */\nexport type LangChainSystemContent = string | MessageContent;\n\nexport type LangChainThreadManagerHooks = ThreadManagerHooks<\n StoredMessage,\n BaseMessage\n>;\n\nexport interface LangChainThreadManagerConfig {\n redis: Redis;\n threadId: string;\n /** Thread key, defaults to 'messages' */\n key?: string;\n hooks?: LangChainThreadManagerHooks;\n}\n\n/** Prepared payload ready to send to a LangChain chat model */\nexport interface LangChainInvocationPayload {\n messages: BaseMessage[];\n /** Number of stored messages loaded from Redis before preparation. */\n storedLength: number;\n}\n\n/** Thread manager with LangChain StoredMessage convenience helpers */\nexport interface LangChainThreadManager extends ProviderThreadManager<\n StoredMessage,\n LangChainContent,\n JsonValue,\n LangChainSystemContent\n> {\n appendAIMessage(id: string, content: string | MessageContent): Promise<void>;\n prepareForInvocation(): Promise<LangChainInvocationPayload>;\n}\n\nfunction storedMessageId(msg: StoredMessage): string {\n if (msg.type === \"tool\" && msg.data.tool_call_id) {\n return msg.data.tool_call_id;\n }\n\n if (msg.data.id) {\n return msg.data.id;\n }\n\n throw new Error(\"No id found for message\");\n}\n\n/**\n * Creates a LangChain-specific thread manager that stores StoredMessage\n * instances in Redis and provides convenience helpers for creating and\n * appending typed LangChain messages.\n */\nexport function createLangChainThreadManager(\n config: LangChainThreadManagerConfig\n): LangChainThreadManager {\n const baseConfig: ThreadManagerConfig<StoredMessage> = {\n redis: config.redis,\n threadId: config.threadId,\n key: config.key,\n idOf: storedMessageId,\n };\n\n const base = createThreadManager(baseConfig);\n\n const helpers: Omit<LangChainThreadManager, keyof typeof base> = {\n async appendUserMessage(\n id: string,\n content: LangChainContent\n ): Promise<void> {\n await base.append([\n new HumanMessage({ id, content: content as MessageContent }).toDict(),\n ]);\n },\n\n async appendSystemMessage(\n id: string,\n content: LangChainSystemContent\n ): Promise<void> {\n await base.initialize();\n await base.append([\n new SystemMessage({\n id,\n content: content as MessageContent,\n }).toDict(),\n ]);\n },\n\n async appendAIMessage(\n id: string,\n content: string | MessageContent\n ): Promise<void> {\n await base.append([\n new AIMessage({ id, content: content as MessageContent }).toDict(),\n ]);\n },\n\n async appendToolResult(\n id: string,\n _toolCallId: string,\n _toolName: string,\n content: JsonValue\n ): Promise<void> {\n await base.append([\n new ToolMessage({\n id,\n content: content as MessageContent,\n tool_call_id: _toolCallId,\n }).toDict(),\n ]);\n },\n\n async prepareForInvocation(): Promise<LangChainInvocationPayload> {\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 const messages = mapStoredMessagesToChatMessages(mapped);\n return {\n messages: onPreparedMessage\n ? messages.map((msg, i) => onPreparedMessage(msg, i, messages))\n : messages,\n storedLength: stored.length,\n };\n },\n };\n\n return Object.assign(base, helpers);\n}\n","import validate from './validate.js';\nconst byteToHex = [];\nfor (let i = 0; i < 256; ++i) {\n byteToHex.push((i + 0x100).toString(16).slice(1));\n}\nexport function unsafeStringify(arr, offset = 0) {\n return (byteToHex[arr[offset + 0]] +\n byteToHex[arr[offset + 1]] +\n byteToHex[arr[offset + 2]] +\n byteToHex[arr[offset + 3]] +\n '-' +\n byteToHex[arr[offset + 4]] +\n byteToHex[arr[offset + 5]] +\n '-' +\n byteToHex[arr[offset + 6]] +\n byteToHex[arr[offset + 7]] +\n '-' +\n byteToHex[arr[offset + 8]] +\n byteToHex[arr[offset + 9]] +\n '-' +\n byteToHex[arr[offset + 10]] +\n byteToHex[arr[offset + 11]] +\n byteToHex[arr[offset + 12]] +\n byteToHex[arr[offset + 13]] +\n byteToHex[arr[offset + 14]] +\n byteToHex[arr[offset + 15]]).toLowerCase();\n}\nfunction stringify(arr, offset = 0) {\n const uuid = unsafeStringify(arr, offset);\n if (!validate(uuid)) {\n throw TypeError('Stringified UUID is invalid');\n }\n return uuid;\n}\nexport default stringify;\n","import { randomFillSync } from 'crypto';\nconst rnds8Pool = new Uint8Array(256);\nlet poolPtr = rnds8Pool.length;\nexport default function rng() {\n if (poolPtr > rnds8Pool.length - 16) {\n randomFillSync(rnds8Pool);\n poolPtr = 0;\n }\n return rnds8Pool.slice(poolPtr, (poolPtr += 16));\n}\n","import { randomUUID } from 'crypto';\nexport default { randomUUID };\n","import native from './native.js';\nimport rng from './rng.js';\nimport { unsafeStringify } from './stringify.js';\nfunction v4(options, buf, offset) {\n if (native.randomUUID && !buf && !options) {\n return native.randomUUID();\n }\n options = options || {};\n const rnds = options.random ?? options.rng?.() ?? rng();\n if (rnds.length < 16) {\n throw new Error('Random bytes length must be >= 16');\n }\n rnds[6] = (rnds[6] & 0x0f) | 0x40;\n rnds[8] = (rnds[8] & 0x3f) | 0x80;\n if (buf) {\n offset = offset || 0;\n if (offset < 0 || offset + 16 > buf.length) {\n throw new RangeError(`UUID byte range ${offset}:${offset + 15} is out of buffer bounds`);\n }\n for (let i = 0; i < 16; ++i) {\n buf[offset + i] = rnds[i];\n }\n return buf;\n }\n return unsafeStringify(rnds);\n}\nexport default v4;\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 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 { AgentResponse, ModelInvokerConfig } from \"../../../lib/model\";\nimport type { StoredMessage } from \"@langchain/core/messages\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport type { BaseChatModel } from \"@langchain/core/language_models/chat_models\";\nimport {\n createLangChainThreadManager,\n type LangChainThreadManagerHooks,\n} from \"./thread-manager\";\nimport { getActivityContext } from \"../../../lib/activity\";\n\n \nexport interface LangChainModelInvokerConfig<\n TModel extends BaseChatModel<any> = BaseChatModel<any>,\n> {\n redis: Redis;\n model: TModel;\n hooks?: LangChainThreadManagerHooks;\n}\n\n/**\n * Creates a LangChain-based model invoker that satisfies the generic\n * `ModelInvoker<StoredMessage>` contract.\n *\n * Uses interval-based Temporal heartbeats during model.invoke() to keep\n * long-running LLM calls visible to the scheduler. LangChain's streaming\n * chunk accumulation is unreliable across providers (e.g. reasoning_content\n * blocks don't merge correctly), so we use invoke() for correctness.\n * The caller is responsible for appending the response to the thread.\n *\n * @example\n * ```typescript\n * import { createLangChainModelInvoker } from 'zeitlich/adapters/thread/langchain';\n * import { createRunAgentActivity } from 'zeitlich';\n * import { ChatAnthropic } from '@langchain/anthropic';\n *\n * const model = new ChatAnthropic({ model: \"claude-sonnet-4-6\" });\n * const invoker = createLangChainModelInvoker({ redis, model });\n *\n * return { ...createRunAgentActivity(client, invoker, \"myAgent\") };\n * ```\n */\n \nexport function createLangChainModelInvoker<\n TModel extends BaseChatModel<any> = BaseChatModel<any>,\n>({ redis, model, hooks }: LangChainModelInvokerConfig<TModel>) {\n return async function invokeLangChainModel(\n config: ModelInvokerConfig\n ): Promise<AgentResponse<StoredMessage>> {\n const { threadId, threadKey, agentName, state, metadata } = config;\n const { heartbeat, signal } = getActivityContext();\n\n const thread = createLangChainThreadManager({\n redis,\n threadId,\n key: threadKey,\n hooks,\n });\n const runId = uuidv4();\n\n const { messages, storedLength } = await thread.prepareForInvocation();\n\n const heartbeatInterval = heartbeat\n ? setInterval(() => heartbeat(), 30_000)\n : undefined;\n\n try {\n const response = await model.invoke(messages, {\n runName: agentName,\n runId,\n metadata: { thread_id: `${agentName}-${threadId}`, ...metadata },\n tools: state.tools,\n signal,\n });\n\n const toolCalls = response.tool_calls ?? [];\n\n const providerUsage =\n (response.response_metadata?.usage as Record<string, unknown>) ?? {};\n\n return {\n message: response.toDict(),\n rawToolCalls: toolCalls.map((tc) => ({\n id: tc.id,\n name: tc.name,\n args: tc.args,\n })),\n usage: {\n inputTokens: response.usage_metadata?.input_tokens,\n outputTokens: response.usage_metadata?.output_tokens,\n reasonTokens:\n response.usage_metadata?.output_token_details?.reasoning,\n cachedWriteTokens:\n response.usage_metadata?.input_token_details?.cache_creation ||\n (providerUsage.cacheWriteInputTokens as number | undefined),\n cachedReadTokens:\n response.usage_metadata?.input_token_details?.cache_read ||\n (providerUsage.cacheReadInputTokens as number | undefined),\n },\n threadLengthAtCall: storedLength,\n };\n } finally {\n if (heartbeatInterval) clearInterval(heartbeatInterval);\n }\n };\n}\n\n/**\n * Standalone function for one-shot LangChain model invocation.\n * Convenience wrapper around createLangChainModelInvoker for cases where\n * you don't need to reuse the invoker.\n */\n \nexport async function invokeLangChainModel<\n TModel extends BaseChatModel<any> = BaseChatModel<any>,\n>({\n redis,\n model,\n hooks,\n config,\n}: {\n redis: Redis;\n config: ModelInvokerConfig;\n model: TModel;\n hooks?: LangChainThreadManagerHooks;\n}): Promise<AgentResponse<StoredMessage>> {\n const invoker = createLangChainModelInvoker({ redis, model, hooks });\n return invoker(config);\n}\n","import type Redis from \"ioredis\";\nimport type { ToolResultConfig } from \"../../../lib/types\";\nimport type { MessageContent } from \"@langchain/core/messages\";\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 type { StoredMessage } from \"@langchain/core/messages\";\nimport type { BaseChatModel } from \"@langchain/core/language_models/chat_models\";\nimport {\n createLangChainThreadManager,\n type LangChainContent,\n type LangChainSystemContent,\n type LangChainThreadManagerHooks,\n} from \"./thread-manager\";\nimport { createLangChainModelInvoker } from \"./model-invoker\";\n\nconst ADAPTER_PREFIX = \"langChain\" as const;\n\nexport type LangChainThreadOps<TScope extends string = \"\"> = PrefixedThreadOps<\n ScopedPrefix<TScope, typeof ADAPTER_PREFIX>,\n LangChainContent\n>;\n\nexport interface LangChainAdapterConfig {\n redis: Redis;\n /** Optional default model — if omitted, use `createModelInvoker()` to create invokers later */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n model?: BaseChatModel<any>;\n hooks?: LangChainThreadManagerHooks;\n}\n\n/**\n * Tool response type accepted by the LangChain adapter.\n *\n * Content is passed directly to `ToolMessage` as `MessageContent`.\n * Handlers can return a string or an array of content blocks\n * (e.g. `{ type: \"text\", text: \"...\" }`, `{ type: \"image_url\", image_url: { ... } }`).\n */\nexport type LangChainToolResponse = MessageContent;\n\nexport interface LangChainAdapter {\n /** Model invoker using the default model (only available when `model` was provided) */\n invoker: ModelInvoker<StoredMessage>;\n /** Create an invoker for a specific model (for multi-model setups) */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n createModelInvoker(model: BaseChatModel<any>): ModelInvoker<StoredMessage>;\n /**\n * Create prefixed thread activities for registration on the worker.\n *\n * @param scope - Workflow name appended to the adapter prefix.\n *\n * @example\n * ```typescript\n * adapter.createActivities(\"codingAgent\")\n * // → { langChainCodingAgentInitializeThread, langChainCodingAgentAppendHumanMessage, … }\n * ```\n */\n createActivities<S extends string = \"\">(scope?: S): LangChainThreadOps<S>;\n\n /**\n * Identity wrapper that types a tool handler for this adapter.\n * Constrains `toolResponse` to {@link LangChainToolResponse}.\n */\n wrapHandler<TArgs, TResult, TContext extends RouterContext = RouterContext>(\n handler: (\n args: TArgs,\n context: TContext\n ) => Promise<ToolHandlerResponse<TResult, LangChainToolResponse>>\n ): ActivityToolHandler<TArgs, TResult, TContext, LangChainToolResponse>;\n}\n\n/**\n * Creates a LangChain adapter that bundles thread operations and model\n * invocation using a consistent message format (StoredMessage).\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 { createLangChainAdapter } from 'zeitlich/adapters/thread/langchain';\n * import { createRunAgentActivity } from 'zeitlich';\n *\n * const adapter = createLangChainAdapter({ redis, model });\n *\n * export function createActivities(client: WorkflowClient) {\n * return {\n * ...adapter.createActivities(\"codingAgent\"),\n * ...createRunAgentActivity(client, adapter.invoker, \"codingAgent\"),\n * };\n * }\n * ```\n *\n * @example Multi-agent worker\n * ```typescript\n * export function createActivities(client: WorkflowClient) {\n * return {\n * ...adapter.createActivities(\"codingAgent\"),\n * ...adapter.createActivities(\"researchAgent\"),\n * ...createRunAgentActivity(client, adapter.invoker, \"codingAgent\"),\n * ...createRunAgentActivity(client, adapter.createModelInvoker(claude), \"researchAgent\"),\n * };\n * }\n * ```\n */\nexport function createLangChainAdapter(\n config: LangChainAdapterConfig\n): LangChainAdapter {\n const { redis } = config;\n\n const threadOps: ThreadOps<LangChainContent> = {\n async initializeThread(\n threadId: string,\n threadKey?: string\n ): Promise<void> {\n const thread = createLangChainThreadManager({\n redis,\n threadId,\n key: threadKey,\n });\n await thread.initialize();\n },\n\n async appendHumanMessage(\n threadId: string,\n id: string,\n content: LangChainContent,\n threadKey?: string\n ): Promise<void> {\n const thread = createLangChainThreadManager({\n redis,\n threadId,\n key: threadKey,\n });\n await thread.appendUserMessage(id, content);\n },\n\n async appendSystemMessage(\n threadId: string,\n id: string,\n content: LangChainSystemContent,\n threadKey?: string\n ): Promise<void> {\n const thread = createLangChainThreadManager({\n redis,\n threadId,\n key: threadKey,\n });\n await thread.appendSystemMessage(id, content);\n },\n\n async appendToolResult(id: string, cfg: ToolResultConfig): Promise<void> {\n const { threadId, threadKey, toolCallId, content } = cfg;\n const thread = createLangChainThreadManager({\n redis,\n threadId,\n key: threadKey,\n });\n await thread.appendToolResult(id, toolCallId, \"\", content);\n },\n\n async appendAgentMessage(\n threadId: string,\n id: string,\n message: StoredMessage,\n threadKey?: string\n ): Promise<void> {\n const thread = createLangChainThreadManager({\n redis,\n threadId,\n key: threadKey,\n });\n const patched = { ...message, data: { ...message.data, id } };\n await thread.append([patched]);\n },\n\n async forkThread(\n sourceThreadId: string,\n targetThreadId: string,\n threadKey?: string\n ): Promise<void> {\n const thread = createLangChainThreadManager({\n redis,\n threadId: sourceThreadId,\n key: threadKey,\n });\n await thread.fork(targetThreadId);\n },\n\n async truncateThread(\n threadId: string,\n length: number,\n threadKey?: string,\n ): Promise<void> {\n const thread = createLangChainThreadManager({ redis, threadId, key: threadKey });\n await thread.truncate(length);\n },\n };\n\n function createActivities<S extends string = \"\">(\n scope?: S\n ): LangChainThreadOps<S> {\n const prefix = scope\n ? `${ADAPTER_PREFIX}${scope.charAt(0).toUpperCase()}${scope.slice(1)}`\n : ADAPTER_PREFIX;\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 LangChainThreadOps<S>;\n }\n\n const makeInvoker = (\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n model: BaseChatModel<any>\n ): ModelInvoker<StoredMessage> =>\n createLangChainModelInvoker({ redis, model, hooks: config.hooks });\n\n const invoker: ModelInvoker<StoredMessage> = config.model\n ? makeInvoker(config.model)\n : () => {\n throw new Error(\n \"No default model provided to createLangChainAdapter. \" +\n \"Either pass `model` in the config or use `createModelInvoker(model)` instead.\"\n );\n };\n\n return {\n createActivities,\n invoker,\n createModelInvoker: makeInvoker,\n wrapHandler: (handler) => handler,\n };\n}\n","import type { BaseMessage, MessageContent } from \"@langchain/core/messages\";\n\ntype ContentBlock = MessageContent extends (infer U)[] | string ? U : never;\n\n/**\n * Creates an `onPreparedMessage` hook that appends a cache-point content\n * block to the last message in the thread, and strips excess cache-point\n * blocks from earlier messages so the total never exceeds `maxBlocks`.\n *\n * Older cache-point blocks are removed first, keeping the most recent\n * `maxBlocks - 1` positions plus the last message's block.\n */\nexport function appendCachePoint(\n block: ContentBlock,\n { maxBlocks = 4 }: { maxBlocks?: number } = {}\n): (\n message: BaseMessage,\n index: number,\n messages: readonly BaseMessage[]\n) => BaseMessage {\n return (message, index, messages) => {\n const isLast = index === messages.length - 1;\n\n if (isLast) {\n const { content } = message;\n if (Array.isArray(content)) {\n if (content.some((b) => b.type === block.type)) return message;\n message.content = [...content, block];\n } else if (typeof content === \"string\") {\n message.content = [\n { type: \"text\", text: content },\n block,\n ] satisfies MessageContent;\n }\n return message;\n }\n\n const { content } = message;\n if (\n !Array.isArray(content) ||\n !content.some((b) => b.type === block.type)\n ) {\n return message;\n }\n\n // Count cache blocks in messages after this one (excluding the last,\n // which always gets one) plus 1 for the last message itself.\n let cacheBlocksAfter = 1;\n for (let i = index + 1; i < messages.length - 1; i++) {\n const msg = messages[i];\n if (!msg) continue;\n const c = msg.content;\n if (\n Array.isArray(c) &&\n c.some((b: ContentBlock) => b.type === block.type)\n ) {\n cacheBlocksAfter++;\n }\n }\n\n if (cacheBlocksAfter >= maxBlocks) {\n message.content = content.filter((b) => b.type !== block.type);\n }\n\n return message;\n };\n}\n"]}
@@ -1,15 +1,15 @@
1
1
  import Redis from 'ioredis';
2
2
  import { StoredMessage, MessageContent, BaseMessage } from '@langchain/core/messages';
3
- import { a as ModelInvoker, P as PrefixedThreadOps, S as ScopedPrefix, R as RouterContext, b as ToolHandlerResponse, c as ActivityToolHandler, M as ModelInvokerConfig, A as AgentResponse } from '../../../types-DQ1l_gXL.cjs';
3
+ import { a as ModelInvoker, P as PrefixedThreadOps, S as ScopedPrefix, R as RouterContext, b as ToolHandlerResponse, c as ActivityToolHandler, M as ModelInvokerConfig, A as AgentResponse } from '../../../types-C06FwR96.cjs';
4
4
  import { BaseChatModel } from '@langchain/core/language_models/chat_models';
5
- import { L as LangChainContent, a as LangChainThreadManagerHooks } from '../../../thread-manager-BBzNgQWH.cjs';
6
- export { b as LangChainInvocationPayload, c as LangChainThreadManager, d as LangChainThreadManagerConfig, e as createLangChainThreadManager } from '../../../thread-manager-BBzNgQWH.cjs';
5
+ import { L as LangChainContent, a as LangChainThreadManagerHooks } from '../../../thread-manager-wGi-LqIP.cjs';
6
+ export { b as LangChainInvocationPayload, c as LangChainThreadManager, d as LangChainThreadManagerConfig, e as createLangChainThreadManager } from '../../../thread-manager-wGi-LqIP.cjs';
7
7
  import '@temporalio/common';
8
8
  import '@temporalio/workflow';
9
9
  import '@temporalio/common/lib/interfaces';
10
10
  import 'zod';
11
- import '../../../types-DxCpFNv_.cjs';
12
- import '../../../types-Mc_4BCfT.cjs';
11
+ import '../../../types-yx0LzPGn.cjs';
12
+ import '../../../types-BaOw4hKI.cjs';
13
13
 
14
14
  declare const ADAPTER_PREFIX: "langChain";
15
15
  type LangChainThreadOps<TScope extends string = ""> = PrefixedThreadOps<ScopedPrefix<TScope, typeof ADAPTER_PREFIX>, LangChainContent>;
@@ -1,15 +1,15 @@
1
1
  import Redis from 'ioredis';
2
2
  import { StoredMessage, MessageContent, BaseMessage } from '@langchain/core/messages';
3
- import { a as ModelInvoker, P as PrefixedThreadOps, S as ScopedPrefix, R as RouterContext, b as ToolHandlerResponse, c as ActivityToolHandler, M as ModelInvokerConfig, A as AgentResponse } from '../../../types-CADc5V_P.js';
3
+ import { a as ModelInvoker, P as PrefixedThreadOps, S as ScopedPrefix, R as RouterContext, b as ToolHandlerResponse, c as ActivityToolHandler, M as ModelInvokerConfig, A as AgentResponse } from '../../../types-DNr31FzL.js';
4
4
  import { BaseChatModel } from '@langchain/core/language_models/chat_models';
5
- import { L as LangChainContent, a as LangChainThreadManagerHooks } from '../../../thread-manager-DjN5JYul.js';
6
- export { b as LangChainInvocationPayload, c as LangChainThreadManager, d as LangChainThreadManagerConfig, e as createLangChainThreadManager } from '../../../thread-manager-DjN5JYul.js';
5
+ import { L as LangChainContent, a as LangChainThreadManagerHooks } from '../../../thread-manager-c1gPopAG.js';
6
+ export { b as LangChainInvocationPayload, c as LangChainThreadManager, d as LangChainThreadManagerConfig, e as createLangChainThreadManager } from '../../../thread-manager-c1gPopAG.js';
7
7
  import '@temporalio/common';
8
8
  import '@temporalio/workflow';
9
9
  import '@temporalio/common/lib/interfaces';
10
10
  import 'zod';
11
- import '../../../types-DxCpFNv_.js';
12
- import '../../../types-yiXmqedU.js';
11
+ import '../../../types-yx0LzPGn.js';
12
+ import '../../../types-BH_IRryz.js';
13
13
 
14
14
  declare const ADAPTER_PREFIX: "langChain";
15
15
  type LangChainThreadOps<TScope extends string = ""> = PrefixedThreadOps<ScopedPrefix<TScope, typeof ADAPTER_PREFIX>, LangChainContent>;
@@ -83,6 +83,20 @@ function createThreadManager(config) {
83
83
  },
84
84
  async delete() {
85
85
  await redis.del(redisKey, metaKey);
86
+ },
87
+ async length() {
88
+ await assertThreadExists();
89
+ return redis.llen(redisKey);
90
+ },
91
+ async truncate(length) {
92
+ await assertThreadExists();
93
+ if (length <= 0) {
94
+ await redis.del(redisKey);
95
+ await redis.expire(metaKey, THREAD_TTL_SECONDS);
96
+ } else {
97
+ await redis.ltrim(redisKey, 0, length - 1);
98
+ await redis.expire(redisKey, THREAD_TTL_SECONDS);
99
+ }
86
100
  }
87
101
  };
88
102
  }
@@ -127,7 +141,11 @@ function createLangChainThreadManager(config) {
127
141
  },
128
142
  async appendToolResult(id, _toolCallId, _toolName, content) {
129
143
  await base.append([
130
- new ToolMessage({ id, content, tool_call_id: _toolCallId }).toDict()
144
+ new ToolMessage({
145
+ id,
146
+ content,
147
+ tool_call_id: _toolCallId
148
+ }).toDict()
131
149
  ]);
132
150
  },
133
151
  async prepareForInvocation() {
@@ -136,7 +154,8 @@ function createLangChainThreadManager(config) {
136
154
  const mapped = onPrepareMessage ? stored.map((msg, i) => onPrepareMessage(msg, i, stored)) : stored;
137
155
  const messages = mapStoredMessagesToChatMessages(mapped);
138
156
  return {
139
- messages: onPreparedMessage ? messages.map((msg, i) => onPreparedMessage(msg, i, messages)) : messages
157
+ messages: onPreparedMessage ? messages.map((msg, i) => onPreparedMessage(msg, i, messages)) : messages,
158
+ storedLength: stored.length
140
159
  };
141
160
  }
142
161
  };
@@ -208,7 +227,7 @@ function createLangChainModelInvoker({ redis, model, hooks }) {
208
227
  hooks
209
228
  });
210
229
  const runId = v4_default();
211
- const { messages } = await thread.prepareForInvocation();
230
+ const { messages, storedLength } = await thread.prepareForInvocation();
212
231
  const heartbeatInterval = heartbeat ? setInterval(() => heartbeat(), 3e4) : void 0;
213
232
  try {
214
233
  const response = await model.invoke(messages, {
@@ -233,7 +252,8 @@ function createLangChainModelInvoker({ redis, model, hooks }) {
233
252
  reasonTokens: response.usage_metadata?.output_token_details?.reasoning,
234
253
  cachedWriteTokens: response.usage_metadata?.input_token_details?.cache_creation || providerUsage.cacheWriteInputTokens,
235
254
  cachedReadTokens: response.usage_metadata?.input_token_details?.cache_read || providerUsage.cacheReadInputTokens
236
- }
255
+ },
256
+ threadLengthAtCall: storedLength
237
257
  };
238
258
  } finally {
239
259
  if (heartbeatInterval) clearInterval(heartbeatInterval);
@@ -256,24 +276,44 @@ function createLangChainAdapter(config) {
256
276
  const { redis } = config;
257
277
  const threadOps = {
258
278
  async initializeThread(threadId, threadKey) {
259
- const thread = createLangChainThreadManager({ redis, threadId, key: threadKey });
279
+ const thread = createLangChainThreadManager({
280
+ redis,
281
+ threadId,
282
+ key: threadKey
283
+ });
260
284
  await thread.initialize();
261
285
  },
262
286
  async appendHumanMessage(threadId, id, content, threadKey) {
263
- const thread = createLangChainThreadManager({ redis, threadId, key: threadKey });
287
+ const thread = createLangChainThreadManager({
288
+ redis,
289
+ threadId,
290
+ key: threadKey
291
+ });
264
292
  await thread.appendUserMessage(id, content);
265
293
  },
266
294
  async appendSystemMessage(threadId, id, content, threadKey) {
267
- const thread = createLangChainThreadManager({ redis, threadId, key: threadKey });
295
+ const thread = createLangChainThreadManager({
296
+ redis,
297
+ threadId,
298
+ key: threadKey
299
+ });
268
300
  await thread.appendSystemMessage(id, content);
269
301
  },
270
302
  async appendToolResult(id, cfg) {
271
303
  const { threadId, threadKey, toolCallId, content } = cfg;
272
- const thread = createLangChainThreadManager({ redis, threadId, key: threadKey });
304
+ const thread = createLangChainThreadManager({
305
+ redis,
306
+ threadId,
307
+ key: threadKey
308
+ });
273
309
  await thread.appendToolResult(id, toolCallId, "", content);
274
310
  },
275
311
  async appendAgentMessage(threadId, id, message, threadKey) {
276
- const thread = createLangChainThreadManager({ redis, threadId, key: threadKey });
312
+ const thread = createLangChainThreadManager({
313
+ redis,
314
+ threadId,
315
+ key: threadKey
316
+ });
277
317
  const patched = { ...message, data: { ...message.data, id } };
278
318
  await thread.append([patched]);
279
319
  },
@@ -284,6 +324,10 @@ function createLangChainAdapter(config) {
284
324
  key: threadKey
285
325
  });
286
326
  await thread.fork(targetThreadId);
327
+ },
328
+ async truncateThread(threadId, length, threadKey) {
329
+ const thread = createLangChainThreadManager({ redis, threadId, key: threadKey });
330
+ await thread.truncate(length);
287
331
  }
288
332
  };
289
333
  function createActivities(scope) {
@@ -317,7 +361,10 @@ function appendCachePoint(block, { maxBlocks = 4 } = {}) {
317
361
  if (content2.some((b) => b.type === block.type)) return message;
318
362
  message.content = [...content2, block];
319
363
  } else if (typeof content2 === "string") {
320
- message.content = [{ type: "text", text: content2 }, block];
364
+ message.content = [
365
+ { type: "text", text: content2 },
366
+ block
367
+ ];
321
368
  }
322
369
  return message;
323
370
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/lib/thread/manager.ts","../../../../src/adapters/thread/langchain/thread-manager.ts","../../../../node_modules/uuid/dist/esm/stringify.js","../../../../node_modules/uuid/dist/esm/rng.js","../../../../node_modules/uuid/dist/esm/native.js","../../../../node_modules/uuid/dist/esm/v4.js","../../../../src/lib/activity.ts","../../../../src/adapters/thread/langchain/model-invoker.ts","../../../../src/adapters/thread/langchain/activities.ts","../../../../src/adapters/thread/langchain/hooks.ts"],"names":["invokeLangChainModel","content"],"mappings":"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","file":"index.js","sourcesContent":["import type { ThreadManagerConfig, BaseThreadManager } from \"./types\";\n\nconst THREAD_TTL_SECONDS = 60 * 60 * 24 * 90; // 90 days\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\nfunction getThreadKey(threadId: string, key: string): string {\n return `${key}:thread:${threadId}`;\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 } = config;\n const redisKey = getThreadKey(threadId, key);\n const metaKey = getThreadKey(threadId, `${key}:meta`);\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\", THREAD_TTL_SECONDS);\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 const dedupKey = getThreadKey(threadId, `dedup:${dedupId}`);\n await redis.eval(\n APPEND_IDEMPOTENT_SCRIPT,\n 2,\n dedupKey,\n redisKey,\n String(THREAD_TTL_SECONDS),\n ...messages.map(serialize)\n );\n } else {\n await redis.rpush(redisKey, ...messages.map(serialize));\n await redis.expire(redisKey, THREAD_TTL_SECONDS);\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 forked = createThreadManager({\n ...config,\n threadId: newThreadId,\n });\n await forked.initialize();\n if (data.length > 0) {\n const newKey = getThreadKey(newThreadId, key);\n await redis.rpush(newKey, ...data);\n await redis.expire(newKey, THREAD_TTL_SECONDS);\n }\n return forked;\n },\n\n async delete(): Promise<void> {\n await redis.del(redisKey, metaKey);\n },\n };\n}\n","import type Redis from \"ioredis\";\nimport type { JsonValue } from \"../../../lib/state/types\";\nimport {\n AIMessage,\n type BaseMessage,\n HumanMessage,\n type MessageContent,\n type StoredMessage,\n SystemMessage,\n ToolMessage,\n mapStoredMessagesToChatMessages,\n} from \"@langchain/core/messages\";\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 LangChain human messages */\nexport type LangChainContent = string | MessageContent;\n\n/** SDK-native content type for LangChain system messages */\nexport type LangChainSystemContent = string | MessageContent;\n\nexport type LangChainThreadManagerHooks = ThreadManagerHooks<StoredMessage, BaseMessage>;\n\nexport interface LangChainThreadManagerConfig {\n redis: Redis;\n threadId: string;\n /** Thread key, defaults to 'messages' */\n key?: string;\n hooks?: LangChainThreadManagerHooks;\n}\n\n/** Prepared payload ready to send to a LangChain chat model */\nexport interface LangChainInvocationPayload {\n messages: BaseMessage[];\n}\n\n/** Thread manager with LangChain StoredMessage convenience helpers */\nexport interface LangChainThreadManager\n extends ProviderThreadManager<StoredMessage, LangChainContent, JsonValue, LangChainSystemContent> {\n appendAIMessage(id: string, content: string | MessageContent): Promise<void>;\n prepareForInvocation(): Promise<LangChainInvocationPayload>;\n}\n\nfunction storedMessageId(msg: StoredMessage): string {\n if (msg.type === \"tool\" && msg.data.tool_call_id) {\n return msg.data.tool_call_id;\n }\n\n if (msg.data.id) {\n return msg.data.id;\n }\n\n throw new Error(\"No id found for message\");\n}\n\n/**\n * Creates a LangChain-specific thread manager that stores StoredMessage\n * instances in Redis and provides convenience helpers for creating and\n * appending typed LangChain messages.\n */\nexport function createLangChainThreadManager(\n config: LangChainThreadManagerConfig,\n): LangChainThreadManager {\n const baseConfig: ThreadManagerConfig<StoredMessage> = {\n redis: config.redis,\n threadId: config.threadId,\n key: config.key,\n idOf: storedMessageId,\n };\n\n const base = createThreadManager(baseConfig);\n\n const helpers: Omit<LangChainThreadManager, keyof typeof base> = {\n async appendUserMessage(\n id: string,\n content: LangChainContent,\n ): Promise<void> {\n await base.append([\n new HumanMessage({ id, content: content as MessageContent }).toDict(),\n ]);\n },\n\n async appendSystemMessage(\n id: string,\n content: LangChainSystemContent,\n ): Promise<void> {\n await base.initialize();\n await base.append([\n new SystemMessage({\n id,\n content: content as MessageContent,\n }).toDict(),\n ]);\n },\n\n async appendAIMessage(\n id: string,\n content: string | MessageContent,\n ): Promise<void> {\n await base.append([\n new AIMessage({ id, content: content as MessageContent }).toDict(),\n ]);\n },\n\n async appendToolResult(\n id: string,\n _toolCallId: string,\n _toolName: string,\n content: JsonValue,\n ): Promise<void> {\n await base.append([\n new ToolMessage({ id, content: content as MessageContent, tool_call_id: _toolCallId }).toDict(),\n ]);\n },\n\n async prepareForInvocation(): Promise<LangChainInvocationPayload> {\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 const messages = mapStoredMessagesToChatMessages(mapped);\n return {\n messages: onPreparedMessage\n ? messages.map((msg, i) => onPreparedMessage(msg, i, messages))\n : messages,\n };\n },\n };\n\n return Object.assign(base, helpers);\n}\n","import validate from './validate.js';\nconst byteToHex = [];\nfor (let i = 0; i < 256; ++i) {\n byteToHex.push((i + 0x100).toString(16).slice(1));\n}\nexport function unsafeStringify(arr, offset = 0) {\n return (byteToHex[arr[offset + 0]] +\n byteToHex[arr[offset + 1]] +\n byteToHex[arr[offset + 2]] +\n byteToHex[arr[offset + 3]] +\n '-' +\n byteToHex[arr[offset + 4]] +\n byteToHex[arr[offset + 5]] +\n '-' +\n byteToHex[arr[offset + 6]] +\n byteToHex[arr[offset + 7]] +\n '-' +\n byteToHex[arr[offset + 8]] +\n byteToHex[arr[offset + 9]] +\n '-' +\n byteToHex[arr[offset + 10]] +\n byteToHex[arr[offset + 11]] +\n byteToHex[arr[offset + 12]] +\n byteToHex[arr[offset + 13]] +\n byteToHex[arr[offset + 14]] +\n byteToHex[arr[offset + 15]]).toLowerCase();\n}\nfunction stringify(arr, offset = 0) {\n const uuid = unsafeStringify(arr, offset);\n if (!validate(uuid)) {\n throw TypeError('Stringified UUID is invalid');\n }\n return uuid;\n}\nexport default stringify;\n","import { randomFillSync } from 'crypto';\nconst rnds8Pool = new Uint8Array(256);\nlet poolPtr = rnds8Pool.length;\nexport default function rng() {\n if (poolPtr > rnds8Pool.length - 16) {\n randomFillSync(rnds8Pool);\n poolPtr = 0;\n }\n return rnds8Pool.slice(poolPtr, (poolPtr += 16));\n}\n","import { randomUUID } from 'crypto';\nexport default { randomUUID };\n","import native from './native.js';\nimport rng from './rng.js';\nimport { unsafeStringify } from './stringify.js';\nfunction v4(options, buf, offset) {\n if (native.randomUUID && !buf && !options) {\n return native.randomUUID();\n }\n options = options || {};\n const rnds = options.random ?? options.rng?.() ?? rng();\n if (rnds.length < 16) {\n throw new Error('Random bytes length must be >= 16');\n }\n rnds[6] = (rnds[6] & 0x0f) | 0x40;\n rnds[8] = (rnds[8] & 0x3f) | 0x80;\n if (buf) {\n offset = offset || 0;\n if (offset < 0 || offset + 16 > buf.length) {\n throw new RangeError(`UUID byte range ${offset}:${offset + 15} is out of buffer bounds`);\n }\n for (let i = 0; i < 16; ++i) {\n buf[offset + i] = rnds[i];\n }\n return buf;\n }\n return unsafeStringify(rnds);\n}\nexport default v4;\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 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<R, S extends BaseAgentState = BaseAgentState>(\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<S extends BaseAgentState = BaseAgentState> 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<TArgs, TResult, S extends BaseAgentState = BaseAgentState, TToolResponse = JsonValue>(\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 { AgentResponse, ModelInvokerConfig } from \"../../../lib/model\";\nimport type { StoredMessage } from \"@langchain/core/messages\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport type { BaseChatModel } from \"@langchain/core/language_models/chat_models\";\nimport {\n createLangChainThreadManager,\n type LangChainThreadManagerHooks,\n} from \"./thread-manager\";\nimport { getActivityContext } from \"../../../lib/activity\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport interface LangChainModelInvokerConfig<\n TModel extends BaseChatModel<any> = BaseChatModel<any>,\n> {\n redis: Redis;\n model: TModel;\n hooks?: LangChainThreadManagerHooks;\n}\n\n/**\n * Creates a LangChain-based model invoker that satisfies the generic\n * `ModelInvoker<StoredMessage>` contract.\n *\n * Uses interval-based Temporal heartbeats during model.invoke() to keep\n * long-running LLM calls visible to the scheduler. LangChain's streaming\n * chunk accumulation is unreliable across providers (e.g. reasoning_content\n * blocks don't merge correctly), so we use invoke() for correctness.\n * The caller is responsible for appending the response to the thread.\n *\n * @example\n * ```typescript\n * import { createLangChainModelInvoker } from 'zeitlich/adapters/thread/langchain';\n * import { createRunAgentActivity } from 'zeitlich';\n * import { ChatAnthropic } from '@langchain/anthropic';\n *\n * const model = new ChatAnthropic({ model: \"claude-sonnet-4-6\" });\n * const invoker = createLangChainModelInvoker({ redis, model });\n *\n * return { ...createRunAgentActivity(client, invoker, \"myAgent\") };\n * ```\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function createLangChainModelInvoker<\n TModel extends BaseChatModel<any> = BaseChatModel<any>,\n>({ redis, model, hooks }: LangChainModelInvokerConfig<TModel>) {\n return async function invokeLangChainModel(\n config: ModelInvokerConfig\n ): Promise<AgentResponse<StoredMessage>> {\n const { threadId, threadKey, agentName, state, metadata } = config;\n const { heartbeat, signal } = getActivityContext();\n\n const thread = createLangChainThreadManager({\n redis,\n threadId,\n key: threadKey,\n hooks,\n });\n const runId = uuidv4();\n\n const { messages } = await thread.prepareForInvocation();\n\n const heartbeatInterval = heartbeat\n ? setInterval(() => heartbeat(), 30_000)\n : undefined;\n\n try {\n const response = await model.invoke(messages, {\n runName: agentName,\n runId,\n metadata: { thread_id: `${agentName}-${threadId}`, ...metadata },\n tools: state.tools,\n signal,\n });\n\n const toolCalls = response.tool_calls ?? [];\n\n const providerUsage =\n (response.response_metadata?.usage as Record<string, unknown>) ?? {};\n\n return {\n message: response.toDict(),\n rawToolCalls: toolCalls.map((tc) => ({\n id: tc.id,\n name: tc.name,\n args: tc.args,\n })),\n usage: {\n inputTokens: response.usage_metadata?.input_tokens,\n outputTokens: response.usage_metadata?.output_tokens,\n reasonTokens:\n response.usage_metadata?.output_token_details?.reasoning,\n cachedWriteTokens:\n response.usage_metadata?.input_token_details?.cache_creation ||\n (providerUsage.cacheWriteInputTokens as number | undefined),\n cachedReadTokens:\n response.usage_metadata?.input_token_details?.cache_read ||\n (providerUsage.cacheReadInputTokens as number | undefined),\n },\n };\n } finally {\n if (heartbeatInterval) clearInterval(heartbeatInterval);\n }\n };\n}\n\n/**\n * Standalone function for one-shot LangChain model invocation.\n * Convenience wrapper around createLangChainModelInvoker for cases where\n * you don't need to reuse the invoker.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport async function invokeLangChainModel<\n TModel extends BaseChatModel<any> = BaseChatModel<any>,\n>({\n redis,\n model,\n hooks,\n config,\n}: {\n redis: Redis;\n config: ModelInvokerConfig;\n model: TModel;\n hooks?: LangChainThreadManagerHooks;\n}): Promise<AgentResponse<StoredMessage>> {\n const invoker = createLangChainModelInvoker({ redis, model, hooks });\n return invoker(config);\n}\n","import type Redis from \"ioredis\";\nimport type { ToolResultConfig } from \"../../../lib/types\";\nimport type { MessageContent } from \"@langchain/core/messages\";\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 type { StoredMessage } from \"@langchain/core/messages\";\nimport type { BaseChatModel } from \"@langchain/core/language_models/chat_models\";\nimport {\n createLangChainThreadManager,\n type LangChainContent,\n type LangChainSystemContent,\n type LangChainThreadManagerHooks,\n} from \"./thread-manager\";\nimport { createLangChainModelInvoker } from \"./model-invoker\";\n\nconst ADAPTER_PREFIX = \"langChain\" as const;\n\nexport type LangChainThreadOps<TScope extends string = \"\"> =\n PrefixedThreadOps<ScopedPrefix<TScope, typeof ADAPTER_PREFIX>, LangChainContent>;\n\nexport interface LangChainAdapterConfig {\n redis: Redis;\n /** Optional default model — if omitted, use `createModelInvoker()` to create invokers later */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n model?: BaseChatModel<any>;\n hooks?: LangChainThreadManagerHooks;\n}\n\n/**\n * Tool response type accepted by the LangChain adapter.\n *\n * Content is passed directly to `ToolMessage` as `MessageContent`.\n * Handlers can return a string or an array of content blocks\n * (e.g. `{ type: \"text\", text: \"...\" }`, `{ type: \"image_url\", image_url: { ... } }`).\n */\nexport type LangChainToolResponse = MessageContent;\n\nexport interface LangChainAdapter {\n /** Model invoker using the default model (only available when `model` was provided) */\n invoker: ModelInvoker<StoredMessage>;\n /** Create an invoker for a specific model (for multi-model setups) */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n createModelInvoker(model: BaseChatModel<any>): ModelInvoker<StoredMessage>;\n /**\n * Create prefixed thread activities for registration on the worker.\n *\n * @param scope - Workflow name appended to the adapter prefix.\n *\n * @example\n * ```typescript\n * adapter.createActivities(\"codingAgent\")\n * // → { langChainCodingAgentInitializeThread, langChainCodingAgentAppendHumanMessage, … }\n * ```\n */\n createActivities<S extends string = \"\">(\n scope?: S,\n ): LangChainThreadOps<S>;\n\n /**\n * Identity wrapper that types a tool handler for this adapter.\n * Constrains `toolResponse` to {@link LangChainToolResponse}.\n */\n wrapHandler<TArgs, TResult, TContext extends RouterContext = RouterContext>(\n handler: (\n args: TArgs,\n context: TContext,\n ) => Promise<ToolHandlerResponse<TResult, LangChainToolResponse>>,\n ): ActivityToolHandler<TArgs, TResult, TContext, LangChainToolResponse>;\n}\n\n/**\n * Creates a LangChain adapter that bundles thread operations and model\n * invocation using a consistent message format (StoredMessage).\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 { createLangChainAdapter } from 'zeitlich/adapters/thread/langchain';\n * import { createRunAgentActivity } from 'zeitlich';\n *\n * const adapter = createLangChainAdapter({ redis, model });\n *\n * export function createActivities(client: WorkflowClient) {\n * return {\n * ...adapter.createActivities(\"codingAgent\"),\n * ...createRunAgentActivity(client, adapter.invoker, \"codingAgent\"),\n * };\n * }\n * ```\n *\n * @example Multi-agent worker\n * ```typescript\n * export function createActivities(client: WorkflowClient) {\n * return {\n * ...adapter.createActivities(\"codingAgent\"),\n * ...adapter.createActivities(\"researchAgent\"),\n * ...createRunAgentActivity(client, adapter.invoker, \"codingAgent\"),\n * ...createRunAgentActivity(client, adapter.createModelInvoker(claude), \"researchAgent\"),\n * };\n * }\n * ```\n */\nexport function createLangChainAdapter(\n config: LangChainAdapterConfig,\n): LangChainAdapter {\n const { redis } = config;\n\n const threadOps: ThreadOps<LangChainContent> = {\n async initializeThread(threadId: string, threadKey?: string): Promise<void> {\n const thread = createLangChainThreadManager({ redis, threadId, key: threadKey });\n await thread.initialize();\n },\n\n async appendHumanMessage(\n threadId: string,\n id: string,\n content: LangChainContent,\n threadKey?: string,\n ): Promise<void> {\n const thread = createLangChainThreadManager({ redis, threadId, key: threadKey });\n await thread.appendUserMessage(id, content);\n },\n\n async appendSystemMessage(\n threadId: string,\n id: string,\n content: LangChainSystemContent,\n threadKey?: string,\n ): Promise<void> {\n const thread = createLangChainThreadManager({ redis, threadId, key: threadKey });\n await thread.appendSystemMessage(id, content);\n },\n\n async appendToolResult(id: string, cfg: ToolResultConfig): Promise<void> {\n const { threadId, threadKey, toolCallId, content } = cfg;\n const thread = createLangChainThreadManager({ redis, threadId, key: threadKey });\n await thread.appendToolResult(id, toolCallId, \"\", content);\n },\n\n async appendAgentMessage(\n threadId: string,\n id: string,\n message: StoredMessage,\n threadKey?: string,\n ): Promise<void> {\n const thread = createLangChainThreadManager({ redis, threadId, key: threadKey });\n const patched = { ...message, data: { ...message.data, id } };\n await thread.append([patched]);\n },\n\n async forkThread(\n sourceThreadId: string,\n targetThreadId: string,\n threadKey?: string,\n ): Promise<void> {\n const thread = createLangChainThreadManager({\n redis,\n threadId: sourceThreadId,\n key: threadKey,\n });\n await thread.fork(targetThreadId);\n },\n };\n\n function createActivities<S extends string = \"\">(\n scope?: S,\n ): LangChainThreadOps<S> {\n const prefix = scope\n ? `${ADAPTER_PREFIX}${scope.charAt(0).toUpperCase()}${scope.slice(1)}`\n : ADAPTER_PREFIX;\n const cap = (s: string): string =>\n s.charAt(0).toUpperCase() + s.slice(1);\n return Object.fromEntries(\n Object.entries(threadOps).map(([k, v]) => [`${prefix}${cap(k)}`, v]),\n ) as LangChainThreadOps<S>;\n }\n\n const makeInvoker = (\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n model: BaseChatModel<any>,\n ): ModelInvoker<StoredMessage> =>\n createLangChainModelInvoker({ redis, model, hooks: config.hooks });\n\n const invoker: ModelInvoker<StoredMessage> = config.model\n ? makeInvoker(config.model)\n : () => {\n throw new Error(\n \"No default model provided to createLangChainAdapter. \" +\n \"Either pass `model` in the config or use `createModelInvoker(model)` instead.\",\n );\n };\n\n return {\n createActivities,\n invoker,\n createModelInvoker: makeInvoker,\n wrapHandler: (handler) => handler,\n };\n}\n","import type { BaseMessage, MessageContent } from \"@langchain/core/messages\";\n\ntype ContentBlock = MessageContent extends (infer U)[] | string ? U : never;\n\n/**\n * Creates an `onPreparedMessage` hook that appends a cache-point content\n * block to the last message in the thread, and strips excess cache-point\n * blocks from earlier messages so the total never exceeds `maxBlocks`.\n *\n * Older cache-point blocks are removed first, keeping the most recent\n * `maxBlocks - 1` positions plus the last message's block.\n */\nexport function appendCachePoint(\n block: ContentBlock,\n { maxBlocks = 4 }: { maxBlocks?: number } = {},\n): (message: BaseMessage, index: number, messages: readonly BaseMessage[]) => BaseMessage {\n return (message, index, messages) => {\n const isLast = index === messages.length - 1;\n\n if (isLast) {\n const { content } = message;\n if (Array.isArray(content)) {\n if (content.some((b) => b.type === block.type)) return message;\n message.content = [...content, block];\n } else if (typeof content === \"string\") {\n message.content = [{ type: \"text\", text: content }, block] satisfies MessageContent;\n }\n return message;\n }\n\n const { content } = message;\n if (!Array.isArray(content) || !content.some((b) => b.type === block.type)) {\n return message;\n }\n\n // Count cache blocks in messages after this one (excluding the last,\n // which always gets one) plus 1 for the last message itself.\n let cacheBlocksAfter = 1;\n for (let i = index + 1; i < messages.length - 1; i++) {\n const msg = messages[i];\n if (!msg) continue;\n const c = msg.content;\n if (Array.isArray(c) && c.some((b: ContentBlock) => b.type === block.type)) {\n cacheBlocksAfter++;\n }\n }\n\n if (cacheBlocksAfter >= maxBlocks) {\n message.content = content.filter((b) => b.type !== block.type);\n }\n\n return message;\n };\n}\n"]}
1
+ {"version":3,"sources":["../../../../src/lib/thread/manager.ts","../../../../src/adapters/thread/langchain/thread-manager.ts","../../../../node_modules/uuid/dist/esm/stringify.js","../../../../node_modules/uuid/dist/esm/rng.js","../../../../node_modules/uuid/dist/esm/native.js","../../../../node_modules/uuid/dist/esm/v4.js","../../../../src/lib/activity.ts","../../../../src/adapters/thread/langchain/model-invoker.ts","../../../../src/adapters/thread/langchain/activities.ts","../../../../src/adapters/thread/langchain/hooks.ts"],"names":["invokeLangChainModel","content"],"mappings":"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","file":"index.js","sourcesContent":["import type { ThreadManagerConfig, BaseThreadManager } from \"./types\";\n\nconst THREAD_TTL_SECONDS = 60 * 60 * 24 * 90; // 90 days\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\nfunction getThreadKey(threadId: string, key: string): string {\n return `${key}:thread:${threadId}`;\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 } = config;\n const redisKey = getThreadKey(threadId, key);\n const metaKey = getThreadKey(threadId, `${key}:meta`);\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\", THREAD_TTL_SECONDS);\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 const dedupKey = getThreadKey(threadId, `dedup:${dedupId}`);\n await redis.eval(\n APPEND_IDEMPOTENT_SCRIPT,\n 2,\n dedupKey,\n redisKey,\n String(THREAD_TTL_SECONDS),\n ...messages.map(serialize)\n );\n } else {\n await redis.rpush(redisKey, ...messages.map(serialize));\n await redis.expire(redisKey, THREAD_TTL_SECONDS);\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 forked = createThreadManager({\n ...config,\n threadId: newThreadId,\n });\n await forked.initialize();\n if (data.length > 0) {\n const newKey = getThreadKey(newThreadId, key);\n await redis.rpush(newKey, ...data);\n await redis.expire(newKey, THREAD_TTL_SECONDS);\n }\n return forked;\n },\n\n async delete(): Promise<void> {\n await redis.del(redisKey, metaKey);\n },\n\n async length(): Promise<number> {\n await assertThreadExists();\n return redis.llen(redisKey);\n },\n\n async truncate(length: number): Promise<void> {\n await assertThreadExists();\n if (length <= 0) {\n await redis.del(redisKey);\n await redis.expire(metaKey, THREAD_TTL_SECONDS);\n } else {\n await redis.ltrim(redisKey, 0, length - 1);\n await redis.expire(redisKey, THREAD_TTL_SECONDS);\n }\n // Dedup keys for removed messages are left to expire via their TTL.\n // Post-truncate appends use fresh ids so collisions do not occur in practice.\n },\n };\n}\n","import type Redis from \"ioredis\";\nimport type { JsonValue } from \"../../../lib/state/types\";\nimport {\n AIMessage,\n type BaseMessage,\n HumanMessage,\n type MessageContent,\n type StoredMessage,\n SystemMessage,\n ToolMessage,\n mapStoredMessagesToChatMessages,\n} from \"@langchain/core/messages\";\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 LangChain human messages */\nexport type LangChainContent = string | MessageContent;\n\n/** SDK-native content type for LangChain system messages */\nexport type LangChainSystemContent = string | MessageContent;\n\nexport type LangChainThreadManagerHooks = ThreadManagerHooks<\n StoredMessage,\n BaseMessage\n>;\n\nexport interface LangChainThreadManagerConfig {\n redis: Redis;\n threadId: string;\n /** Thread key, defaults to 'messages' */\n key?: string;\n hooks?: LangChainThreadManagerHooks;\n}\n\n/** Prepared payload ready to send to a LangChain chat model */\nexport interface LangChainInvocationPayload {\n messages: BaseMessage[];\n /** Number of stored messages loaded from Redis before preparation. */\n storedLength: number;\n}\n\n/** Thread manager with LangChain StoredMessage convenience helpers */\nexport interface LangChainThreadManager extends ProviderThreadManager<\n StoredMessage,\n LangChainContent,\n JsonValue,\n LangChainSystemContent\n> {\n appendAIMessage(id: string, content: string | MessageContent): Promise<void>;\n prepareForInvocation(): Promise<LangChainInvocationPayload>;\n}\n\nfunction storedMessageId(msg: StoredMessage): string {\n if (msg.type === \"tool\" && msg.data.tool_call_id) {\n return msg.data.tool_call_id;\n }\n\n if (msg.data.id) {\n return msg.data.id;\n }\n\n throw new Error(\"No id found for message\");\n}\n\n/**\n * Creates a LangChain-specific thread manager that stores StoredMessage\n * instances in Redis and provides convenience helpers for creating and\n * appending typed LangChain messages.\n */\nexport function createLangChainThreadManager(\n config: LangChainThreadManagerConfig\n): LangChainThreadManager {\n const baseConfig: ThreadManagerConfig<StoredMessage> = {\n redis: config.redis,\n threadId: config.threadId,\n key: config.key,\n idOf: storedMessageId,\n };\n\n const base = createThreadManager(baseConfig);\n\n const helpers: Omit<LangChainThreadManager, keyof typeof base> = {\n async appendUserMessage(\n id: string,\n content: LangChainContent\n ): Promise<void> {\n await base.append([\n new HumanMessage({ id, content: content as MessageContent }).toDict(),\n ]);\n },\n\n async appendSystemMessage(\n id: string,\n content: LangChainSystemContent\n ): Promise<void> {\n await base.initialize();\n await base.append([\n new SystemMessage({\n id,\n content: content as MessageContent,\n }).toDict(),\n ]);\n },\n\n async appendAIMessage(\n id: string,\n content: string | MessageContent\n ): Promise<void> {\n await base.append([\n new AIMessage({ id, content: content as MessageContent }).toDict(),\n ]);\n },\n\n async appendToolResult(\n id: string,\n _toolCallId: string,\n _toolName: string,\n content: JsonValue\n ): Promise<void> {\n await base.append([\n new ToolMessage({\n id,\n content: content as MessageContent,\n tool_call_id: _toolCallId,\n }).toDict(),\n ]);\n },\n\n async prepareForInvocation(): Promise<LangChainInvocationPayload> {\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 const messages = mapStoredMessagesToChatMessages(mapped);\n return {\n messages: onPreparedMessage\n ? messages.map((msg, i) => onPreparedMessage(msg, i, messages))\n : messages,\n storedLength: stored.length,\n };\n },\n };\n\n return Object.assign(base, helpers);\n}\n","import validate from './validate.js';\nconst byteToHex = [];\nfor (let i = 0; i < 256; ++i) {\n byteToHex.push((i + 0x100).toString(16).slice(1));\n}\nexport function unsafeStringify(arr, offset = 0) {\n return (byteToHex[arr[offset + 0]] +\n byteToHex[arr[offset + 1]] +\n byteToHex[arr[offset + 2]] +\n byteToHex[arr[offset + 3]] +\n '-' +\n byteToHex[arr[offset + 4]] +\n byteToHex[arr[offset + 5]] +\n '-' +\n byteToHex[arr[offset + 6]] +\n byteToHex[arr[offset + 7]] +\n '-' +\n byteToHex[arr[offset + 8]] +\n byteToHex[arr[offset + 9]] +\n '-' +\n byteToHex[arr[offset + 10]] +\n byteToHex[arr[offset + 11]] +\n byteToHex[arr[offset + 12]] +\n byteToHex[arr[offset + 13]] +\n byteToHex[arr[offset + 14]] +\n byteToHex[arr[offset + 15]]).toLowerCase();\n}\nfunction stringify(arr, offset = 0) {\n const uuid = unsafeStringify(arr, offset);\n if (!validate(uuid)) {\n throw TypeError('Stringified UUID is invalid');\n }\n return uuid;\n}\nexport default stringify;\n","import { randomFillSync } from 'crypto';\nconst rnds8Pool = new Uint8Array(256);\nlet poolPtr = rnds8Pool.length;\nexport default function rng() {\n if (poolPtr > rnds8Pool.length - 16) {\n randomFillSync(rnds8Pool);\n poolPtr = 0;\n }\n return rnds8Pool.slice(poolPtr, (poolPtr += 16));\n}\n","import { randomUUID } from 'crypto';\nexport default { randomUUID };\n","import native from './native.js';\nimport rng from './rng.js';\nimport { unsafeStringify } from './stringify.js';\nfunction v4(options, buf, offset) {\n if (native.randomUUID && !buf && !options) {\n return native.randomUUID();\n }\n options = options || {};\n const rnds = options.random ?? options.rng?.() ?? rng();\n if (rnds.length < 16) {\n throw new Error('Random bytes length must be >= 16');\n }\n rnds[6] = (rnds[6] & 0x0f) | 0x40;\n rnds[8] = (rnds[8] & 0x3f) | 0x80;\n if (buf) {\n offset = offset || 0;\n if (offset < 0 || offset + 16 > buf.length) {\n throw new RangeError(`UUID byte range ${offset}:${offset + 15} is out of buffer bounds`);\n }\n for (let i = 0; i < 16; ++i) {\n buf[offset + i] = rnds[i];\n }\n return buf;\n }\n return unsafeStringify(rnds);\n}\nexport default v4;\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 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 { AgentResponse, ModelInvokerConfig } from \"../../../lib/model\";\nimport type { StoredMessage } from \"@langchain/core/messages\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport type { BaseChatModel } from \"@langchain/core/language_models/chat_models\";\nimport {\n createLangChainThreadManager,\n type LangChainThreadManagerHooks,\n} from \"./thread-manager\";\nimport { getActivityContext } from \"../../../lib/activity\";\n\n \nexport interface LangChainModelInvokerConfig<\n TModel extends BaseChatModel<any> = BaseChatModel<any>,\n> {\n redis: Redis;\n model: TModel;\n hooks?: LangChainThreadManagerHooks;\n}\n\n/**\n * Creates a LangChain-based model invoker that satisfies the generic\n * `ModelInvoker<StoredMessage>` contract.\n *\n * Uses interval-based Temporal heartbeats during model.invoke() to keep\n * long-running LLM calls visible to the scheduler. LangChain's streaming\n * chunk accumulation is unreliable across providers (e.g. reasoning_content\n * blocks don't merge correctly), so we use invoke() for correctness.\n * The caller is responsible for appending the response to the thread.\n *\n * @example\n * ```typescript\n * import { createLangChainModelInvoker } from 'zeitlich/adapters/thread/langchain';\n * import { createRunAgentActivity } from 'zeitlich';\n * import { ChatAnthropic } from '@langchain/anthropic';\n *\n * const model = new ChatAnthropic({ model: \"claude-sonnet-4-6\" });\n * const invoker = createLangChainModelInvoker({ redis, model });\n *\n * return { ...createRunAgentActivity(client, invoker, \"myAgent\") };\n * ```\n */\n \nexport function createLangChainModelInvoker<\n TModel extends BaseChatModel<any> = BaseChatModel<any>,\n>({ redis, model, hooks }: LangChainModelInvokerConfig<TModel>) {\n return async function invokeLangChainModel(\n config: ModelInvokerConfig\n ): Promise<AgentResponse<StoredMessage>> {\n const { threadId, threadKey, agentName, state, metadata } = config;\n const { heartbeat, signal } = getActivityContext();\n\n const thread = createLangChainThreadManager({\n redis,\n threadId,\n key: threadKey,\n hooks,\n });\n const runId = uuidv4();\n\n const { messages, storedLength } = await thread.prepareForInvocation();\n\n const heartbeatInterval = heartbeat\n ? setInterval(() => heartbeat(), 30_000)\n : undefined;\n\n try {\n const response = await model.invoke(messages, {\n runName: agentName,\n runId,\n metadata: { thread_id: `${agentName}-${threadId}`, ...metadata },\n tools: state.tools,\n signal,\n });\n\n const toolCalls = response.tool_calls ?? [];\n\n const providerUsage =\n (response.response_metadata?.usage as Record<string, unknown>) ?? {};\n\n return {\n message: response.toDict(),\n rawToolCalls: toolCalls.map((tc) => ({\n id: tc.id,\n name: tc.name,\n args: tc.args,\n })),\n usage: {\n inputTokens: response.usage_metadata?.input_tokens,\n outputTokens: response.usage_metadata?.output_tokens,\n reasonTokens:\n response.usage_metadata?.output_token_details?.reasoning,\n cachedWriteTokens:\n response.usage_metadata?.input_token_details?.cache_creation ||\n (providerUsage.cacheWriteInputTokens as number | undefined),\n cachedReadTokens:\n response.usage_metadata?.input_token_details?.cache_read ||\n (providerUsage.cacheReadInputTokens as number | undefined),\n },\n threadLengthAtCall: storedLength,\n };\n } finally {\n if (heartbeatInterval) clearInterval(heartbeatInterval);\n }\n };\n}\n\n/**\n * Standalone function for one-shot LangChain model invocation.\n * Convenience wrapper around createLangChainModelInvoker for cases where\n * you don't need to reuse the invoker.\n */\n \nexport async function invokeLangChainModel<\n TModel extends BaseChatModel<any> = BaseChatModel<any>,\n>({\n redis,\n model,\n hooks,\n config,\n}: {\n redis: Redis;\n config: ModelInvokerConfig;\n model: TModel;\n hooks?: LangChainThreadManagerHooks;\n}): Promise<AgentResponse<StoredMessage>> {\n const invoker = createLangChainModelInvoker({ redis, model, hooks });\n return invoker(config);\n}\n","import type Redis from \"ioredis\";\nimport type { ToolResultConfig } from \"../../../lib/types\";\nimport type { MessageContent } from \"@langchain/core/messages\";\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 type { StoredMessage } from \"@langchain/core/messages\";\nimport type { BaseChatModel } from \"@langchain/core/language_models/chat_models\";\nimport {\n createLangChainThreadManager,\n type LangChainContent,\n type LangChainSystemContent,\n type LangChainThreadManagerHooks,\n} from \"./thread-manager\";\nimport { createLangChainModelInvoker } from \"./model-invoker\";\n\nconst ADAPTER_PREFIX = \"langChain\" as const;\n\nexport type LangChainThreadOps<TScope extends string = \"\"> = PrefixedThreadOps<\n ScopedPrefix<TScope, typeof ADAPTER_PREFIX>,\n LangChainContent\n>;\n\nexport interface LangChainAdapterConfig {\n redis: Redis;\n /** Optional default model — if omitted, use `createModelInvoker()` to create invokers later */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n model?: BaseChatModel<any>;\n hooks?: LangChainThreadManagerHooks;\n}\n\n/**\n * Tool response type accepted by the LangChain adapter.\n *\n * Content is passed directly to `ToolMessage` as `MessageContent`.\n * Handlers can return a string or an array of content blocks\n * (e.g. `{ type: \"text\", text: \"...\" }`, `{ type: \"image_url\", image_url: { ... } }`).\n */\nexport type LangChainToolResponse = MessageContent;\n\nexport interface LangChainAdapter {\n /** Model invoker using the default model (only available when `model` was provided) */\n invoker: ModelInvoker<StoredMessage>;\n /** Create an invoker for a specific model (for multi-model setups) */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n createModelInvoker(model: BaseChatModel<any>): ModelInvoker<StoredMessage>;\n /**\n * Create prefixed thread activities for registration on the worker.\n *\n * @param scope - Workflow name appended to the adapter prefix.\n *\n * @example\n * ```typescript\n * adapter.createActivities(\"codingAgent\")\n * // → { langChainCodingAgentInitializeThread, langChainCodingAgentAppendHumanMessage, … }\n * ```\n */\n createActivities<S extends string = \"\">(scope?: S): LangChainThreadOps<S>;\n\n /**\n * Identity wrapper that types a tool handler for this adapter.\n * Constrains `toolResponse` to {@link LangChainToolResponse}.\n */\n wrapHandler<TArgs, TResult, TContext extends RouterContext = RouterContext>(\n handler: (\n args: TArgs,\n context: TContext\n ) => Promise<ToolHandlerResponse<TResult, LangChainToolResponse>>\n ): ActivityToolHandler<TArgs, TResult, TContext, LangChainToolResponse>;\n}\n\n/**\n * Creates a LangChain adapter that bundles thread operations and model\n * invocation using a consistent message format (StoredMessage).\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 { createLangChainAdapter } from 'zeitlich/adapters/thread/langchain';\n * import { createRunAgentActivity } from 'zeitlich';\n *\n * const adapter = createLangChainAdapter({ redis, model });\n *\n * export function createActivities(client: WorkflowClient) {\n * return {\n * ...adapter.createActivities(\"codingAgent\"),\n * ...createRunAgentActivity(client, adapter.invoker, \"codingAgent\"),\n * };\n * }\n * ```\n *\n * @example Multi-agent worker\n * ```typescript\n * export function createActivities(client: WorkflowClient) {\n * return {\n * ...adapter.createActivities(\"codingAgent\"),\n * ...adapter.createActivities(\"researchAgent\"),\n * ...createRunAgentActivity(client, adapter.invoker, \"codingAgent\"),\n * ...createRunAgentActivity(client, adapter.createModelInvoker(claude), \"researchAgent\"),\n * };\n * }\n * ```\n */\nexport function createLangChainAdapter(\n config: LangChainAdapterConfig\n): LangChainAdapter {\n const { redis } = config;\n\n const threadOps: ThreadOps<LangChainContent> = {\n async initializeThread(\n threadId: string,\n threadKey?: string\n ): Promise<void> {\n const thread = createLangChainThreadManager({\n redis,\n threadId,\n key: threadKey,\n });\n await thread.initialize();\n },\n\n async appendHumanMessage(\n threadId: string,\n id: string,\n content: LangChainContent,\n threadKey?: string\n ): Promise<void> {\n const thread = createLangChainThreadManager({\n redis,\n threadId,\n key: threadKey,\n });\n await thread.appendUserMessage(id, content);\n },\n\n async appendSystemMessage(\n threadId: string,\n id: string,\n content: LangChainSystemContent,\n threadKey?: string\n ): Promise<void> {\n const thread = createLangChainThreadManager({\n redis,\n threadId,\n key: threadKey,\n });\n await thread.appendSystemMessage(id, content);\n },\n\n async appendToolResult(id: string, cfg: ToolResultConfig): Promise<void> {\n const { threadId, threadKey, toolCallId, content } = cfg;\n const thread = createLangChainThreadManager({\n redis,\n threadId,\n key: threadKey,\n });\n await thread.appendToolResult(id, toolCallId, \"\", content);\n },\n\n async appendAgentMessage(\n threadId: string,\n id: string,\n message: StoredMessage,\n threadKey?: string\n ): Promise<void> {\n const thread = createLangChainThreadManager({\n redis,\n threadId,\n key: threadKey,\n });\n const patched = { ...message, data: { ...message.data, id } };\n await thread.append([patched]);\n },\n\n async forkThread(\n sourceThreadId: string,\n targetThreadId: string,\n threadKey?: string\n ): Promise<void> {\n const thread = createLangChainThreadManager({\n redis,\n threadId: sourceThreadId,\n key: threadKey,\n });\n await thread.fork(targetThreadId);\n },\n\n async truncateThread(\n threadId: string,\n length: number,\n threadKey?: string,\n ): Promise<void> {\n const thread = createLangChainThreadManager({ redis, threadId, key: threadKey });\n await thread.truncate(length);\n },\n };\n\n function createActivities<S extends string = \"\">(\n scope?: S\n ): LangChainThreadOps<S> {\n const prefix = scope\n ? `${ADAPTER_PREFIX}${scope.charAt(0).toUpperCase()}${scope.slice(1)}`\n : ADAPTER_PREFIX;\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 LangChainThreadOps<S>;\n }\n\n const makeInvoker = (\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n model: BaseChatModel<any>\n ): ModelInvoker<StoredMessage> =>\n createLangChainModelInvoker({ redis, model, hooks: config.hooks });\n\n const invoker: ModelInvoker<StoredMessage> = config.model\n ? makeInvoker(config.model)\n : () => {\n throw new Error(\n \"No default model provided to createLangChainAdapter. \" +\n \"Either pass `model` in the config or use `createModelInvoker(model)` instead.\"\n );\n };\n\n return {\n createActivities,\n invoker,\n createModelInvoker: makeInvoker,\n wrapHandler: (handler) => handler,\n };\n}\n","import type { BaseMessage, MessageContent } from \"@langchain/core/messages\";\n\ntype ContentBlock = MessageContent extends (infer U)[] | string ? U : never;\n\n/**\n * Creates an `onPreparedMessage` hook that appends a cache-point content\n * block to the last message in the thread, and strips excess cache-point\n * blocks from earlier messages so the total never exceeds `maxBlocks`.\n *\n * Older cache-point blocks are removed first, keeping the most recent\n * `maxBlocks - 1` positions plus the last message's block.\n */\nexport function appendCachePoint(\n block: ContentBlock,\n { maxBlocks = 4 }: { maxBlocks?: number } = {}\n): (\n message: BaseMessage,\n index: number,\n messages: readonly BaseMessage[]\n) => BaseMessage {\n return (message, index, messages) => {\n const isLast = index === messages.length - 1;\n\n if (isLast) {\n const { content } = message;\n if (Array.isArray(content)) {\n if (content.some((b) => b.type === block.type)) return message;\n message.content = [...content, block];\n } else if (typeof content === \"string\") {\n message.content = [\n { type: \"text\", text: content },\n block,\n ] satisfies MessageContent;\n }\n return message;\n }\n\n const { content } = message;\n if (\n !Array.isArray(content) ||\n !content.some((b) => b.type === block.type)\n ) {\n return message;\n }\n\n // Count cache blocks in messages after this one (excluding the last,\n // which always gets one) plus 1 for the last message itself.\n let cacheBlocksAfter = 1;\n for (let i = index + 1; i < messages.length - 1; i++) {\n const msg = messages[i];\n if (!msg) continue;\n const c = msg.content;\n if (\n Array.isArray(c) &&\n c.some((b: ContentBlock) => b.type === block.type)\n ) {\n cacheBlocksAfter++;\n }\n }\n\n if (cacheBlocksAfter >= maxBlocks) {\n message.content = content.filter((b) => b.type !== block.type);\n }\n\n return message;\n };\n}\n"]}