zeitlich 0.2.30 → 0.2.32

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 (84) hide show
  1. package/dist/{activities-BeveyY9b.d.cts → activities-DA-bQM12.d.cts} +2 -2
  2. package/dist/{activities-NT3rcw66.d.ts → activities-FIXVz7DT.d.ts} +2 -2
  3. package/dist/adapters/thread/anthropic/index.cjs +4 -48
  4. package/dist/adapters/thread/anthropic/index.cjs.map +1 -1
  5. package/dist/adapters/thread/anthropic/index.d.cts +6 -6
  6. package/dist/adapters/thread/anthropic/index.d.ts +6 -6
  7. package/dist/adapters/thread/anthropic/index.js +4 -48
  8. package/dist/adapters/thread/anthropic/index.js.map +1 -1
  9. package/dist/adapters/thread/anthropic/workflow.cjs +1 -0
  10. package/dist/adapters/thread/anthropic/workflow.cjs.map +1 -1
  11. package/dist/adapters/thread/anthropic/workflow.d.cts +4 -4
  12. package/dist/adapters/thread/anthropic/workflow.d.ts +4 -4
  13. package/dist/adapters/thread/anthropic/workflow.js +1 -0
  14. package/dist/adapters/thread/anthropic/workflow.js.map +1 -1
  15. package/dist/adapters/thread/google-genai/index.cjs +8 -48
  16. package/dist/adapters/thread/google-genai/index.cjs.map +1 -1
  17. package/dist/adapters/thread/google-genai/index.d.cts +6 -6
  18. package/dist/adapters/thread/google-genai/index.d.ts +6 -6
  19. package/dist/adapters/thread/google-genai/index.js +8 -48
  20. package/dist/adapters/thread/google-genai/index.js.map +1 -1
  21. package/dist/adapters/thread/google-genai/workflow.cjs +1 -0
  22. package/dist/adapters/thread/google-genai/workflow.cjs.map +1 -1
  23. package/dist/adapters/thread/google-genai/workflow.d.cts +4 -4
  24. package/dist/adapters/thread/google-genai/workflow.d.ts +4 -4
  25. package/dist/adapters/thread/google-genai/workflow.js +1 -0
  26. package/dist/adapters/thread/google-genai/workflow.js.map +1 -1
  27. package/dist/adapters/thread/langchain/index.cjs +5 -1
  28. package/dist/adapters/thread/langchain/index.cjs.map +1 -1
  29. package/dist/adapters/thread/langchain/index.d.cts +6 -5
  30. package/dist/adapters/thread/langchain/index.d.ts +6 -5
  31. package/dist/adapters/thread/langchain/index.js +5 -1
  32. package/dist/adapters/thread/langchain/index.js.map +1 -1
  33. package/dist/adapters/thread/langchain/workflow.cjs +1 -0
  34. package/dist/adapters/thread/langchain/workflow.cjs.map +1 -1
  35. package/dist/adapters/thread/langchain/workflow.d.cts +4 -4
  36. package/dist/adapters/thread/langchain/workflow.d.ts +4 -4
  37. package/dist/adapters/thread/langchain/workflow.js +1 -0
  38. package/dist/adapters/thread/langchain/workflow.js.map +1 -1
  39. package/dist/index.cjs +34 -7
  40. package/dist/index.cjs.map +1 -1
  41. package/dist/index.d.cts +6 -6
  42. package/dist/index.d.ts +6 -6
  43. package/dist/index.js +34 -7
  44. package/dist/index.js.map +1 -1
  45. package/dist/{proxy-BgswT47M.d.ts → proxy-Br4unLTC.d.ts} +1 -1
  46. package/dist/{proxy-OJihshQF.d.cts → proxy-CTCYWjkr.d.cts} +1 -1
  47. package/dist/{thread-manager-lfN0V-gH.d.cts → thread-manager-CUubPYPH.d.cts} +1 -1
  48. package/dist/{thread-manager-DH0zv05W.d.cts → thread-manager-Cv_BR28i.d.cts} +1 -1
  49. package/dist/{thread-manager-iUplxEZt.d.ts → thread-manager-DKWxHUzD.d.ts} +1 -1
  50. package/dist/{thread-manager-BS477gj8.d.ts → thread-manager-YJLoc1vH.d.ts} +1 -1
  51. package/dist/{types-DVdT5ybA.d.cts → types-Bpq5fDI5.d.cts} +13 -5
  52. package/dist/{types-CCIc7Eam.d.ts → types-BxiT8w9d.d.ts} +1 -1
  53. package/dist/{types-D90Q5aOh.d.ts → types-CheCTLeV.d.ts} +13 -5
  54. package/dist/{types-DgIVPOa1.d.cts → types-NJDyMyUx.d.cts} +1 -1
  55. package/dist/{workflow-Cj4DxGdM.d.cts → workflow-BWKQcz9d.d.cts} +1 -1
  56. package/dist/{workflow-CzrBdCcJ.d.ts → workflow-D8wK7TJY.d.ts} +1 -1
  57. package/dist/workflow.cjs +17 -2
  58. package/dist/workflow.cjs.map +1 -1
  59. package/dist/workflow.d.cts +2 -2
  60. package/dist/workflow.d.ts +2 -2
  61. package/dist/workflow.js +17 -2
  62. package/dist/workflow.js.map +1 -1
  63. package/package.json +1 -1
  64. package/src/adapters/thread/anthropic/activities.ts +10 -0
  65. package/src/adapters/thread/anthropic/model-invoker.ts +2 -5
  66. package/src/adapters/thread/google-genai/activities.ts +14 -0
  67. package/src/adapters/thread/google-genai/model-invoker.ts +2 -5
  68. package/src/adapters/thread/langchain/activities.ts +11 -0
  69. package/src/adapters/thread/langchain/model-invoker.ts +2 -3
  70. package/src/lib/.env +1 -0
  71. package/src/lib/model/types.ts +3 -2
  72. package/src/lib/session/session-edge-cases.integration.test.ts +6 -0
  73. package/src/lib/session/session.integration.test.ts +3 -0
  74. package/src/lib/session/session.ts +19 -1
  75. package/src/lib/session/types.ts +7 -0
  76. package/src/lib/thread/proxy.ts +1 -0
  77. package/src/lib/types.ts +3 -0
  78. package/src/lib/virtual-fs/filesystem.ts +15 -0
  79. package/src/lib/virtual-fs/manager.ts +3 -3
  80. package/src/lib/virtual-fs/proxy.ts +3 -3
  81. package/src/lib/virtual-fs/types.ts +3 -2
  82. package/src/lib/virtual-fs/virtual-fs.test.ts +64 -0
  83. package/src/lib/virtual-fs/with-virtual-fs.ts +4 -3
  84. package/src/tools/bash/.env +1 -0
@@ -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/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\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> {\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(id: string, content: string): Promise<void> {\n await base.initialize();\n await base.append([\n new SystemMessage({ id, content }).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 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 { createLangChainThreadManager, type LangChainThreadManagerHooks } from \"./thread-manager\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport interface LangChainModelInvokerConfig<TModel extends BaseChatModel<any> = BaseChatModel<any>> {\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 * Loads the conversation thread from Redis, invokes a LangChain chat model,\n * appends the AI response, and returns a normalised AgentResponse.\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 { runAgent: createRunAgentActivity(client, invoker) };\n * ```\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function createLangChainModelInvoker<TModel extends BaseChatModel<any> = BaseChatModel<any>>(\n { redis, model, hooks }: LangChainModelInvokerConfig<TModel>,\n) {\n return async function invokeLangChainModel(\n config: ModelInvokerConfig,\n ): Promise<AgentResponse<StoredMessage>> {\n const { threadId, threadKey, agentName, state, metadata } = config;\n\n const thread = createLangChainThreadManager({ redis, threadId, key: threadKey, hooks });\n const runId = uuidv4();\n\n const { messages } = await thread.prepareForInvocation();\n const response = await model.invoke(\n messages,\n {\n runName: agentName,\n runId,\n metadata: { thread_id: `${agentName}-${threadId}`, ...metadata },\n tools: state.tools,\n },\n );\n\n await thread.append([response.toDict()]);\n\n const toolCalls = response.tool_calls ?? [];\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: response.usage_metadata?.output_token_details?.reasoning,\n cachedWriteTokens:\n response.usage_metadata?.input_token_details?.cache_creation,\n cachedReadTokens:\n response.usage_metadata?.input_token_details?.cache_read,\n },\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<TModel extends BaseChatModel<any> = BaseChatModel<any>>({\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 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 * runCodingAgent: createRunAgentActivity(client, adapter.invoker),\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 * runCodingAgent: createRunAgentActivity(client, adapter.invoker),\n * runResearchAgent: createRunAgentActivity(client, adapter.createModelInvoker(claude)),\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: string,\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 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/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\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> {\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(id: string, content: string): Promise<void> {\n await base.initialize();\n await base.append([\n new SystemMessage({ id, content }).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 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 { createLangChainThreadManager, type LangChainThreadManagerHooks } from \"./thread-manager\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport interface LangChainModelInvokerConfig<TModel extends BaseChatModel<any> = BaseChatModel<any>> {\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 * Loads the conversation thread from Redis, invokes a LangChain chat model,\n * and returns a normalised AgentResponse.\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 { runAgent: createRunAgentActivity(client, invoker) };\n * ```\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function createLangChainModelInvoker<TModel extends BaseChatModel<any> = BaseChatModel<any>>(\n { redis, model, hooks }: LangChainModelInvokerConfig<TModel>,\n) {\n return async function invokeLangChainModel(\n config: ModelInvokerConfig,\n ): Promise<AgentResponse<StoredMessage>> {\n const { threadId, threadKey, agentName, state, metadata } = config;\n\n const thread = createLangChainThreadManager({ redis, threadId, key: threadKey, hooks });\n const runId = uuidv4();\n\n const { messages } = await thread.prepareForInvocation();\n const response = await model.invoke(\n messages,\n {\n runName: agentName,\n runId,\n metadata: { thread_id: `${agentName}-${threadId}`, ...metadata },\n tools: state.tools,\n },\n );\n\n const toolCalls = response.tool_calls ?? [];\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: response.usage_metadata?.output_token_details?.reasoning,\n cachedWriteTokens:\n response.usage_metadata?.input_token_details?.cache_creation,\n cachedReadTokens:\n response.usage_metadata?.input_token_details?.cache_read,\n },\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<TModel extends BaseChatModel<any> = BaseChatModel<any>>({\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 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 * runCodingAgent: createRunAgentActivity(client, adapter.invoker),\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 * runCodingAgent: createRunAgentActivity(client, adapter.invoker),\n * runResearchAgent: createRunAgentActivity(client, adapter.createModelInvoker(claude)),\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: string,\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"]}
@@ -22,6 +22,7 @@ function createThreadOpsProxy(adapterPrefix, scope, options) {
22
22
  initializeThread: acts[p("initializeThread")],
23
23
  appendHumanMessage: acts[p("appendHumanMessage")],
24
24
  appendToolResult: acts[p("appendToolResult")],
25
+ appendAgentMessage: acts[p("appendAgentMessage")],
25
26
  appendSystemMessage: acts[p("appendSystemMessage")],
26
27
  forkThread: acts[p("forkThread")]
27
28
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/lib/thread/proxy.ts","../../../../src/adapters/thread/langchain/proxy.ts"],"names":["workflowInfo","proxyActivities"],"mappings":";;;;;AAwBO,SAAS,oBAAA,CACd,aAAA,EACA,KAAA,EACA,OAAA,EACiC;AACjC,EAAA,MAAM,aAAA,GAAgB,KAAA,IAASA,qBAAA,EAAa,CAAE,YAAA;AAG9C,EAAA,MAAM,IAAA,GAAOC,wBAAA;AAAA,IACX,OAAA,IAAW;AAAA,MACT,mBAAA,EAAqB,KAAA;AAAA,MACrB,KAAA,EAAO;AAAA,QACL,eAAA,EAAiB,CAAA;AAAA,QACjB,eAAA,EAAiB,IAAA;AAAA,QACjB,eAAA,EAAiB,KAAA;AAAA,QACjB,kBAAA,EAAoB;AAAA;AACtB;AACF,GACF;AAEA,EAAA,MAAM,MAAA,GACJ,CAAA,EAAG,aAAa,CAAA,EAAG,cAAc,MAAA,CAAO,CAAC,CAAA,CAAE,WAAA,EAAa,CAAA,EAAG,aAAA,CAAc,KAAA,CAAM,CAAC,CAAC,CAAA,CAAA;AACnF,EAAA,MAAM,IAAI,CAAC,GAAA,KACT,CAAA,EAAG,MAAM,GAAG,GAAA,CAAI,MAAA,CAAO,CAAC,CAAA,CAAE,aAAa,CAAA,EAAG,GAAA,CAAI,KAAA,CAAM,CAAC,CAAC,CAAA,CAAA;AAExD,EAAA,OAAO;AAAA,IACL,gBAAA,EAAkB,IAAA,CAAK,CAAA,CAAE,kBAAkB,CAAC,CAAA;AAAA,IAC5C,kBAAA,EAAoB,IAAA,CAAK,CAAA,CAAE,oBAAoB,CAAC,CAAA;AAAA,IAChD,gBAAA,EAAkB,IAAA,CAAK,CAAA,CAAE,kBAAkB,CAAC,CAAA;AAAA,IAC5C,mBAAA,EAAqB,IAAA,CAAK,CAAA,CAAE,qBAAqB,CAAC,CAAA;AAAA,IAClD,UAAA,EAAY,IAAA,CAAK,CAAA,CAAE,YAAY,CAAC;AAAA,GAClC;AACF;;;AC/BA,IAAM,cAAA,GAAiB,WAAA;AAEhB,SAAS,uBAAA,CACd,OACA,OAAA,EACmD;AACnD,EAAA,OAAO,oBAAA,CAAqB,cAAA,EAAgB,KAAA,EAAO,OAAO,CAAA;AAC5D","file":"workflow.cjs","sourcesContent":["/**\n * Shared proxy helper for thread operations.\n *\n * Each adapter re-exports a thin wrapper that supplies its prefix and\n * casts the return type to carry the adapter's native content type.\n */\nimport {\n proxyActivities,\n workflowInfo,\n type ActivityInterfaceFor,\n} from \"@temporalio/workflow\";\nimport type { ThreadOps } from \"../session/types\";\n\n/**\n * Creates a workflow-safe Temporal activity proxy for {@link ThreadOps}.\n *\n * The proxy resolves activity names by combining the adapter prefix with\n * the workflow scope, so each adapter + workflow combination gets its own\n * namespace.\n *\n * @param adapterPrefix - Adapter identifier (e.g. \"anthropic\", \"googleGenAI\", \"langChain\")\n * @param scope - Optional workflow scope override. Defaults to `workflowInfo().workflowType`.\n * @param options - Optional Temporal `proxyActivities` options.\n */\nexport function createThreadOpsProxy(\n adapterPrefix: string,\n scope?: string,\n options?: Parameters<typeof proxyActivities>[0],\n): ActivityInterfaceFor<ThreadOps> {\n const resolvedScope = scope ?? workflowInfo().workflowType;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const acts = proxyActivities<Record<string, (...args: any[]) => any>>(\n options ?? {\n startToCloseTimeout: \"10s\",\n retry: {\n maximumAttempts: 6,\n initialInterval: \"5s\",\n maximumInterval: \"15m\",\n backoffCoefficient: 4,\n },\n },\n );\n\n const prefix =\n `${adapterPrefix}${resolvedScope.charAt(0).toUpperCase()}${resolvedScope.slice(1)}`;\n const p = (key: string): string =>\n `${prefix}${key.charAt(0).toUpperCase()}${key.slice(1)}`;\n\n return {\n initializeThread: acts[p(\"initializeThread\")],\n appendHumanMessage: acts[p(\"appendHumanMessage\")],\n appendToolResult: acts[p(\"appendToolResult\")],\n appendSystemMessage: acts[p(\"appendSystemMessage\")],\n forkThread: acts[p(\"forkThread\")],\n } as ActivityInterfaceFor<ThreadOps>;\n}\n","/**\n * Workflow-safe proxy for LangChain thread operations.\n *\n * Import this from `zeitlich/adapters/thread/langchain/workflow`\n * in your Temporal workflow files.\n *\n * By default the scope is derived from `workflowInfo().workflowType`,\n * so activities are automatically namespaced per workflow.\n *\n * @example\n * ```typescript\n * import { proxyLangChainThreadOps } from 'zeitlich/adapters/thread/langchain/workflow';\n *\n * // Auto-scoped to the current workflow name\n * const threadOps = proxyLangChainThreadOps();\n *\n * // Explicit scope override\n * const threadOps = proxyLangChainThreadOps(\"customScope\");\n * ```\n */\nimport { type ActivityInterfaceFor } from \"@temporalio/workflow\";\nimport type { ThreadOps } from \"../../../lib/session/types\";\nimport type { LangChainContent } from \"./thread-manager\";\nimport { createThreadOpsProxy } from \"../../../lib/thread/proxy\";\n\nconst ADAPTER_PREFIX = \"langChain\";\n\nexport function proxyLangChainThreadOps(\n scope?: string,\n options?: Parameters<typeof createThreadOpsProxy>[2],\n): ActivityInterfaceFor<ThreadOps<LangChainContent>> {\n return createThreadOpsProxy(ADAPTER_PREFIX, scope, options) as ActivityInterfaceFor<ThreadOps<LangChainContent>>;\n}\n"]}
1
+ {"version":3,"sources":["../../../../src/lib/thread/proxy.ts","../../../../src/adapters/thread/langchain/proxy.ts"],"names":["workflowInfo","proxyActivities"],"mappings":";;;;;AAwBO,SAAS,oBAAA,CACd,aAAA,EACA,KAAA,EACA,OAAA,EACiC;AACjC,EAAA,MAAM,aAAA,GAAgB,KAAA,IAASA,qBAAA,EAAa,CAAE,YAAA;AAG9C,EAAA,MAAM,IAAA,GAAOC,wBAAA;AAAA,IACX,OAAA,IAAW;AAAA,MACT,mBAAA,EAAqB,KAAA;AAAA,MACrB,KAAA,EAAO;AAAA,QACL,eAAA,EAAiB,CAAA;AAAA,QACjB,eAAA,EAAiB,IAAA;AAAA,QACjB,eAAA,EAAiB,KAAA;AAAA,QACjB,kBAAA,EAAoB;AAAA;AACtB;AACF,GACF;AAEA,EAAA,MAAM,MAAA,GACJ,CAAA,EAAG,aAAa,CAAA,EAAG,cAAc,MAAA,CAAO,CAAC,CAAA,CAAE,WAAA,EAAa,CAAA,EAAG,aAAA,CAAc,KAAA,CAAM,CAAC,CAAC,CAAA,CAAA;AACnF,EAAA,MAAM,IAAI,CAAC,GAAA,KACT,CAAA,EAAG,MAAM,GAAG,GAAA,CAAI,MAAA,CAAO,CAAC,CAAA,CAAE,aAAa,CAAA,EAAG,GAAA,CAAI,KAAA,CAAM,CAAC,CAAC,CAAA,CAAA;AAExD,EAAA,OAAO;AAAA,IACL,gBAAA,EAAkB,IAAA,CAAK,CAAA,CAAE,kBAAkB,CAAC,CAAA;AAAA,IAC5C,kBAAA,EAAoB,IAAA,CAAK,CAAA,CAAE,oBAAoB,CAAC,CAAA;AAAA,IAChD,gBAAA,EAAkB,IAAA,CAAK,CAAA,CAAE,kBAAkB,CAAC,CAAA;AAAA,IAC5C,kBAAA,EAAoB,IAAA,CAAK,CAAA,CAAE,oBAAoB,CAAC,CAAA;AAAA,IAChD,mBAAA,EAAqB,IAAA,CAAK,CAAA,CAAE,qBAAqB,CAAC,CAAA;AAAA,IAClD,UAAA,EAAY,IAAA,CAAK,CAAA,CAAE,YAAY,CAAC;AAAA,GAClC;AACF;;;AChCA,IAAM,cAAA,GAAiB,WAAA;AAEhB,SAAS,uBAAA,CACd,OACA,OAAA,EACmD;AACnD,EAAA,OAAO,oBAAA,CAAqB,cAAA,EAAgB,KAAA,EAAO,OAAO,CAAA;AAC5D","file":"workflow.cjs","sourcesContent":["/**\n * Shared proxy helper for thread operations.\n *\n * Each adapter re-exports a thin wrapper that supplies its prefix and\n * casts the return type to carry the adapter's native content type.\n */\nimport {\n proxyActivities,\n workflowInfo,\n type ActivityInterfaceFor,\n} from \"@temporalio/workflow\";\nimport type { ThreadOps } from \"../session/types\";\n\n/**\n * Creates a workflow-safe Temporal activity proxy for {@link ThreadOps}.\n *\n * The proxy resolves activity names by combining the adapter prefix with\n * the workflow scope, so each adapter + workflow combination gets its own\n * namespace.\n *\n * @param adapterPrefix - Adapter identifier (e.g. \"anthropic\", \"googleGenAI\", \"langChain\")\n * @param scope - Optional workflow scope override. Defaults to `workflowInfo().workflowType`.\n * @param options - Optional Temporal `proxyActivities` options.\n */\nexport function createThreadOpsProxy(\n adapterPrefix: string,\n scope?: string,\n options?: Parameters<typeof proxyActivities>[0],\n): ActivityInterfaceFor<ThreadOps> {\n const resolvedScope = scope ?? workflowInfo().workflowType;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const acts = proxyActivities<Record<string, (...args: any[]) => any>>(\n options ?? {\n startToCloseTimeout: \"10s\",\n retry: {\n maximumAttempts: 6,\n initialInterval: \"5s\",\n maximumInterval: \"15m\",\n backoffCoefficient: 4,\n },\n },\n );\n\n const prefix =\n `${adapterPrefix}${resolvedScope.charAt(0).toUpperCase()}${resolvedScope.slice(1)}`;\n const p = (key: string): string =>\n `${prefix}${key.charAt(0).toUpperCase()}${key.slice(1)}`;\n\n return {\n initializeThread: acts[p(\"initializeThread\")],\n appendHumanMessage: acts[p(\"appendHumanMessage\")],\n appendToolResult: acts[p(\"appendToolResult\")],\n appendAgentMessage: acts[p(\"appendAgentMessage\")],\n appendSystemMessage: acts[p(\"appendSystemMessage\")],\n forkThread: acts[p(\"forkThread\")],\n } as ActivityInterfaceFor<ThreadOps>;\n}\n","/**\n * Workflow-safe proxy for LangChain thread operations.\n *\n * Import this from `zeitlich/adapters/thread/langchain/workflow`\n * in your Temporal workflow files.\n *\n * By default the scope is derived from `workflowInfo().workflowType`,\n * so activities are automatically namespaced per workflow.\n *\n * @example\n * ```typescript\n * import { proxyLangChainThreadOps } from 'zeitlich/adapters/thread/langchain/workflow';\n *\n * // Auto-scoped to the current workflow name\n * const threadOps = proxyLangChainThreadOps();\n *\n * // Explicit scope override\n * const threadOps = proxyLangChainThreadOps(\"customScope\");\n * ```\n */\nimport { type ActivityInterfaceFor } from \"@temporalio/workflow\";\nimport type { ThreadOps } from \"../../../lib/session/types\";\nimport type { LangChainContent } from \"./thread-manager\";\nimport { createThreadOpsProxy } from \"../../../lib/thread/proxy\";\n\nconst ADAPTER_PREFIX = \"langChain\";\n\nexport function proxyLangChainThreadOps(\n scope?: string,\n options?: Parameters<typeof createThreadOpsProxy>[2],\n): ActivityInterfaceFor<ThreadOps<LangChainContent>> {\n return createThreadOpsProxy(ADAPTER_PREFIX, scope, options) as ActivityInterfaceFor<ThreadOps<LangChainContent>>;\n}\n"]}
@@ -1,14 +1,14 @@
1
1
  import { ActivityInterfaceFor } from '@temporalio/workflow';
2
- import { T as ThreadOps } from '../../../types-DVdT5ybA.cjs';
3
- import { L as LangChainContent } from '../../../thread-manager-DH0zv05W.cjs';
4
- import { c as createThreadOpsProxy } from '../../../proxy-OJihshQF.cjs';
2
+ import { T as ThreadOps } from '../../../types-Bpq5fDI5.cjs';
3
+ import { L as LangChainContent } from '../../../thread-manager-Cv_BR28i.cjs';
4
+ import { c as createThreadOpsProxy } from '../../../proxy-CTCYWjkr.cjs';
5
5
  import '@temporalio/common';
6
6
  import '@temporalio/common/lib/interfaces';
7
7
  import 'zod';
8
8
  import '../../../types-AujBIMMn.cjs';
9
9
  import 'ioredis';
10
10
  import '@langchain/core/messages';
11
- import '../../../types-DgIVPOa1.cjs';
11
+ import '../../../types-NJDyMyUx.cjs';
12
12
 
13
13
  /**
14
14
  * Workflow-safe proxy for LangChain thread operations.
@@ -1,14 +1,14 @@
1
1
  import { ActivityInterfaceFor } from '@temporalio/workflow';
2
- import { T as ThreadOps } from '../../../types-D90Q5aOh.js';
3
- import { L as LangChainContent } from '../../../thread-manager-iUplxEZt.js';
4
- import { c as createThreadOpsProxy } from '../../../proxy-BgswT47M.js';
2
+ import { T as ThreadOps } from '../../../types-CheCTLeV.js';
3
+ import { L as LangChainContent } from '../../../thread-manager-DKWxHUzD.js';
4
+ import { c as createThreadOpsProxy } from '../../../proxy-Br4unLTC.js';
5
5
  import '@temporalio/common';
6
6
  import '@temporalio/common/lib/interfaces';
7
7
  import 'zod';
8
8
  import '../../../types-AujBIMMn.js';
9
9
  import 'ioredis';
10
10
  import '@langchain/core/messages';
11
- import '../../../types-CCIc7Eam.js';
11
+ import '../../../types-BxiT8w9d.js';
12
12
 
13
13
  /**
14
14
  * Workflow-safe proxy for LangChain thread operations.
@@ -20,6 +20,7 @@ function createThreadOpsProxy(adapterPrefix, scope, options) {
20
20
  initializeThread: acts[p("initializeThread")],
21
21
  appendHumanMessage: acts[p("appendHumanMessage")],
22
22
  appendToolResult: acts[p("appendToolResult")],
23
+ appendAgentMessage: acts[p("appendAgentMessage")],
23
24
  appendSystemMessage: acts[p("appendSystemMessage")],
24
25
  forkThread: acts[p("forkThread")]
25
26
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/lib/thread/proxy.ts","../../../../src/adapters/thread/langchain/proxy.ts"],"names":[],"mappings":";;;AAwBO,SAAS,oBAAA,CACd,aAAA,EACA,KAAA,EACA,OAAA,EACiC;AACjC,EAAA,MAAM,aAAA,GAAgB,KAAA,IAAS,YAAA,EAAa,CAAE,YAAA;AAG9C,EAAA,MAAM,IAAA,GAAO,eAAA;AAAA,IACX,OAAA,IAAW;AAAA,MACT,mBAAA,EAAqB,KAAA;AAAA,MACrB,KAAA,EAAO;AAAA,QACL,eAAA,EAAiB,CAAA;AAAA,QACjB,eAAA,EAAiB,IAAA;AAAA,QACjB,eAAA,EAAiB,KAAA;AAAA,QACjB,kBAAA,EAAoB;AAAA;AACtB;AACF,GACF;AAEA,EAAA,MAAM,MAAA,GACJ,CAAA,EAAG,aAAa,CAAA,EAAG,cAAc,MAAA,CAAO,CAAC,CAAA,CAAE,WAAA,EAAa,CAAA,EAAG,aAAA,CAAc,KAAA,CAAM,CAAC,CAAC,CAAA,CAAA;AACnF,EAAA,MAAM,IAAI,CAAC,GAAA,KACT,CAAA,EAAG,MAAM,GAAG,GAAA,CAAI,MAAA,CAAO,CAAC,CAAA,CAAE,aAAa,CAAA,EAAG,GAAA,CAAI,KAAA,CAAM,CAAC,CAAC,CAAA,CAAA;AAExD,EAAA,OAAO;AAAA,IACL,gBAAA,EAAkB,IAAA,CAAK,CAAA,CAAE,kBAAkB,CAAC,CAAA;AAAA,IAC5C,kBAAA,EAAoB,IAAA,CAAK,CAAA,CAAE,oBAAoB,CAAC,CAAA;AAAA,IAChD,gBAAA,EAAkB,IAAA,CAAK,CAAA,CAAE,kBAAkB,CAAC,CAAA;AAAA,IAC5C,mBAAA,EAAqB,IAAA,CAAK,CAAA,CAAE,qBAAqB,CAAC,CAAA;AAAA,IAClD,UAAA,EAAY,IAAA,CAAK,CAAA,CAAE,YAAY,CAAC;AAAA,GAClC;AACF;;;AC/BA,IAAM,cAAA,GAAiB,WAAA;AAEhB,SAAS,uBAAA,CACd,OACA,OAAA,EACmD;AACnD,EAAA,OAAO,oBAAA,CAAqB,cAAA,EAAgB,KAAA,EAAO,OAAO,CAAA;AAC5D","file":"workflow.js","sourcesContent":["/**\n * Shared proxy helper for thread operations.\n *\n * Each adapter re-exports a thin wrapper that supplies its prefix and\n * casts the return type to carry the adapter's native content type.\n */\nimport {\n proxyActivities,\n workflowInfo,\n type ActivityInterfaceFor,\n} from \"@temporalio/workflow\";\nimport type { ThreadOps } from \"../session/types\";\n\n/**\n * Creates a workflow-safe Temporal activity proxy for {@link ThreadOps}.\n *\n * The proxy resolves activity names by combining the adapter prefix with\n * the workflow scope, so each adapter + workflow combination gets its own\n * namespace.\n *\n * @param adapterPrefix - Adapter identifier (e.g. \"anthropic\", \"googleGenAI\", \"langChain\")\n * @param scope - Optional workflow scope override. Defaults to `workflowInfo().workflowType`.\n * @param options - Optional Temporal `proxyActivities` options.\n */\nexport function createThreadOpsProxy(\n adapterPrefix: string,\n scope?: string,\n options?: Parameters<typeof proxyActivities>[0],\n): ActivityInterfaceFor<ThreadOps> {\n const resolvedScope = scope ?? workflowInfo().workflowType;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const acts = proxyActivities<Record<string, (...args: any[]) => any>>(\n options ?? {\n startToCloseTimeout: \"10s\",\n retry: {\n maximumAttempts: 6,\n initialInterval: \"5s\",\n maximumInterval: \"15m\",\n backoffCoefficient: 4,\n },\n },\n );\n\n const prefix =\n `${adapterPrefix}${resolvedScope.charAt(0).toUpperCase()}${resolvedScope.slice(1)}`;\n const p = (key: string): string =>\n `${prefix}${key.charAt(0).toUpperCase()}${key.slice(1)}`;\n\n return {\n initializeThread: acts[p(\"initializeThread\")],\n appendHumanMessage: acts[p(\"appendHumanMessage\")],\n appendToolResult: acts[p(\"appendToolResult\")],\n appendSystemMessage: acts[p(\"appendSystemMessage\")],\n forkThread: acts[p(\"forkThread\")],\n } as ActivityInterfaceFor<ThreadOps>;\n}\n","/**\n * Workflow-safe proxy for LangChain thread operations.\n *\n * Import this from `zeitlich/adapters/thread/langchain/workflow`\n * in your Temporal workflow files.\n *\n * By default the scope is derived from `workflowInfo().workflowType`,\n * so activities are automatically namespaced per workflow.\n *\n * @example\n * ```typescript\n * import { proxyLangChainThreadOps } from 'zeitlich/adapters/thread/langchain/workflow';\n *\n * // Auto-scoped to the current workflow name\n * const threadOps = proxyLangChainThreadOps();\n *\n * // Explicit scope override\n * const threadOps = proxyLangChainThreadOps(\"customScope\");\n * ```\n */\nimport { type ActivityInterfaceFor } from \"@temporalio/workflow\";\nimport type { ThreadOps } from \"../../../lib/session/types\";\nimport type { LangChainContent } from \"./thread-manager\";\nimport { createThreadOpsProxy } from \"../../../lib/thread/proxy\";\n\nconst ADAPTER_PREFIX = \"langChain\";\n\nexport function proxyLangChainThreadOps(\n scope?: string,\n options?: Parameters<typeof createThreadOpsProxy>[2],\n): ActivityInterfaceFor<ThreadOps<LangChainContent>> {\n return createThreadOpsProxy(ADAPTER_PREFIX, scope, options) as ActivityInterfaceFor<ThreadOps<LangChainContent>>;\n}\n"]}
1
+ {"version":3,"sources":["../../../../src/lib/thread/proxy.ts","../../../../src/adapters/thread/langchain/proxy.ts"],"names":[],"mappings":";;;AAwBO,SAAS,oBAAA,CACd,aAAA,EACA,KAAA,EACA,OAAA,EACiC;AACjC,EAAA,MAAM,aAAA,GAAgB,KAAA,IAAS,YAAA,EAAa,CAAE,YAAA;AAG9C,EAAA,MAAM,IAAA,GAAO,eAAA;AAAA,IACX,OAAA,IAAW;AAAA,MACT,mBAAA,EAAqB,KAAA;AAAA,MACrB,KAAA,EAAO;AAAA,QACL,eAAA,EAAiB,CAAA;AAAA,QACjB,eAAA,EAAiB,IAAA;AAAA,QACjB,eAAA,EAAiB,KAAA;AAAA,QACjB,kBAAA,EAAoB;AAAA;AACtB;AACF,GACF;AAEA,EAAA,MAAM,MAAA,GACJ,CAAA,EAAG,aAAa,CAAA,EAAG,cAAc,MAAA,CAAO,CAAC,CAAA,CAAE,WAAA,EAAa,CAAA,EAAG,aAAA,CAAc,KAAA,CAAM,CAAC,CAAC,CAAA,CAAA;AACnF,EAAA,MAAM,IAAI,CAAC,GAAA,KACT,CAAA,EAAG,MAAM,GAAG,GAAA,CAAI,MAAA,CAAO,CAAC,CAAA,CAAE,aAAa,CAAA,EAAG,GAAA,CAAI,KAAA,CAAM,CAAC,CAAC,CAAA,CAAA;AAExD,EAAA,OAAO;AAAA,IACL,gBAAA,EAAkB,IAAA,CAAK,CAAA,CAAE,kBAAkB,CAAC,CAAA;AAAA,IAC5C,kBAAA,EAAoB,IAAA,CAAK,CAAA,CAAE,oBAAoB,CAAC,CAAA;AAAA,IAChD,gBAAA,EAAkB,IAAA,CAAK,CAAA,CAAE,kBAAkB,CAAC,CAAA;AAAA,IAC5C,kBAAA,EAAoB,IAAA,CAAK,CAAA,CAAE,oBAAoB,CAAC,CAAA;AAAA,IAChD,mBAAA,EAAqB,IAAA,CAAK,CAAA,CAAE,qBAAqB,CAAC,CAAA;AAAA,IAClD,UAAA,EAAY,IAAA,CAAK,CAAA,CAAE,YAAY,CAAC;AAAA,GAClC;AACF;;;AChCA,IAAM,cAAA,GAAiB,WAAA;AAEhB,SAAS,uBAAA,CACd,OACA,OAAA,EACmD;AACnD,EAAA,OAAO,oBAAA,CAAqB,cAAA,EAAgB,KAAA,EAAO,OAAO,CAAA;AAC5D","file":"workflow.js","sourcesContent":["/**\n * Shared proxy helper for thread operations.\n *\n * Each adapter re-exports a thin wrapper that supplies its prefix and\n * casts the return type to carry the adapter's native content type.\n */\nimport {\n proxyActivities,\n workflowInfo,\n type ActivityInterfaceFor,\n} from \"@temporalio/workflow\";\nimport type { ThreadOps } from \"../session/types\";\n\n/**\n * Creates a workflow-safe Temporal activity proxy for {@link ThreadOps}.\n *\n * The proxy resolves activity names by combining the adapter prefix with\n * the workflow scope, so each adapter + workflow combination gets its own\n * namespace.\n *\n * @param adapterPrefix - Adapter identifier (e.g. \"anthropic\", \"googleGenAI\", \"langChain\")\n * @param scope - Optional workflow scope override. Defaults to `workflowInfo().workflowType`.\n * @param options - Optional Temporal `proxyActivities` options.\n */\nexport function createThreadOpsProxy(\n adapterPrefix: string,\n scope?: string,\n options?: Parameters<typeof proxyActivities>[0],\n): ActivityInterfaceFor<ThreadOps> {\n const resolvedScope = scope ?? workflowInfo().workflowType;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const acts = proxyActivities<Record<string, (...args: any[]) => any>>(\n options ?? {\n startToCloseTimeout: \"10s\",\n retry: {\n maximumAttempts: 6,\n initialInterval: \"5s\",\n maximumInterval: \"15m\",\n backoffCoefficient: 4,\n },\n },\n );\n\n const prefix =\n `${adapterPrefix}${resolvedScope.charAt(0).toUpperCase()}${resolvedScope.slice(1)}`;\n const p = (key: string): string =>\n `${prefix}${key.charAt(0).toUpperCase()}${key.slice(1)}`;\n\n return {\n initializeThread: acts[p(\"initializeThread\")],\n appendHumanMessage: acts[p(\"appendHumanMessage\")],\n appendToolResult: acts[p(\"appendToolResult\")],\n appendAgentMessage: acts[p(\"appendAgentMessage\")],\n appendSystemMessage: acts[p(\"appendSystemMessage\")],\n forkThread: acts[p(\"forkThread\")],\n } as ActivityInterfaceFor<ThreadOps>;\n}\n","/**\n * Workflow-safe proxy for LangChain thread operations.\n *\n * Import this from `zeitlich/adapters/thread/langchain/workflow`\n * in your Temporal workflow files.\n *\n * By default the scope is derived from `workflowInfo().workflowType`,\n * so activities are automatically namespaced per workflow.\n *\n * @example\n * ```typescript\n * import { proxyLangChainThreadOps } from 'zeitlich/adapters/thread/langchain/workflow';\n *\n * // Auto-scoped to the current workflow name\n * const threadOps = proxyLangChainThreadOps();\n *\n * // Explicit scope override\n * const threadOps = proxyLangChainThreadOps(\"customScope\");\n * ```\n */\nimport { type ActivityInterfaceFor } from \"@temporalio/workflow\";\nimport type { ThreadOps } from \"../../../lib/session/types\";\nimport type { LangChainContent } from \"./thread-manager\";\nimport { createThreadOpsProxy } from \"../../../lib/thread/proxy\";\n\nconst ADAPTER_PREFIX = \"langChain\";\n\nexport function proxyLangChainThreadOps(\n scope?: string,\n options?: Parameters<typeof createThreadOpsProxy>[2],\n): ActivityInterfaceFor<ThreadOps<LangChainContent>> {\n return createThreadOpsProxy(ADAPTER_PREFIX, scope, options) as ActivityInterfaceFor<ThreadOps<LangChainContent>>;\n}\n"]}
package/dist/index.cjs CHANGED
@@ -735,6 +735,7 @@ async function createSession({
735
735
  appendHumanMessage,
736
736
  initializeThread,
737
737
  appendSystemMessage,
738
+ appendAgentMessage,
738
739
  forkThread
739
740
  } = threadOps;
740
741
  const plugins = [];
@@ -843,8 +844,21 @@ async function createSession({
843
844
  });
844
845
  }
845
846
  const result = await virtualFsOps.resolveFileTree(virtualFsConfig.ctx);
847
+ const skillFiles = skills ? collectSkillFiles(skills) : void 0;
848
+ const fileTree = skillFiles ? [
849
+ ...result.fileTree,
850
+ ...Object.entries(skillFiles).map(([path, content]) => ({
851
+ id: `skill:${path}`,
852
+ path,
853
+ size: content.length,
854
+ mtime: (/* @__PURE__ */ new Date()).toISOString(),
855
+ metadata: {}
856
+ }))
857
+ ] : result.fileTree;
846
858
  stateManager.mergeUpdate({
847
- fileTree: result.fileTree
859
+ fileTree,
860
+ virtualFsCtx: virtualFsConfig.ctx,
861
+ ...skillFiles && { inlineFiles: skillFiles }
848
862
  });
849
863
  }
850
864
  if (hooks.onSessionStart) {
@@ -897,6 +911,7 @@ async function createSession({
897
911
  agentName,
898
912
  metadata
899
913
  });
914
+ await appendAgentMessage(threadId, workflow.uuid4(), message, threadKey);
900
915
  if (usage) {
901
916
  stateManager.updateUsage(usage);
902
917
  }
@@ -1540,7 +1555,7 @@ function proxyVirtualFsOps(scope, options) {
1540
1555
  }
1541
1556
  }
1542
1557
  );
1543
- const prefix = resolvedScope;
1558
+ const prefix = `virtualFs${resolvedScope.charAt(0).toUpperCase()}${resolvedScope.slice(1)}`;
1544
1559
  const p = (key) => `${prefix}${key.charAt(0).toUpperCase()}${key.slice(1)}`;
1545
1560
  return {
1546
1561
  resolveFileTree: acts[p("resolveFileTree")]
@@ -2371,7 +2386,7 @@ function inferDirectories(entries, workspaceBase) {
2371
2386
  return dirs;
2372
2387
  }
2373
2388
  var VirtualFileSystem = class {
2374
- constructor(tree, resolver, ctx, workspaceBase = "/") {
2389
+ constructor(tree, resolver, ctx, workspaceBase = "/", inlineFiles) {
2375
2390
  this.resolver = resolver;
2376
2391
  this.ctx = ctx;
2377
2392
  this.workspaceBase = normalisePath(workspaceBase);
@@ -2379,11 +2394,18 @@ var VirtualFileSystem = class {
2379
2394
  tree.map((e) => [normalisePath(e.path, this.workspaceBase), e])
2380
2395
  );
2381
2396
  this.directories = inferDirectories(tree, this.workspaceBase);
2397
+ this.inlineFiles = new Map(
2398
+ inlineFiles ? Object.entries(inlineFiles).map(([p, c]) => [
2399
+ normalisePath(p, this.workspaceBase),
2400
+ c
2401
+ ]) : []
2402
+ );
2382
2403
  }
2383
2404
  workspaceBase;
2384
2405
  entries;
2385
2406
  directories;
2386
2407
  mutations = [];
2408
+ inlineFiles;
2387
2409
  /** Return all mutations accumulated during this invocation. */
2388
2410
  getMutations() {
2389
2411
  return this.mutations;
@@ -2397,12 +2419,16 @@ var VirtualFileSystem = class {
2397
2419
  // --------------------------------------------------------------------------
2398
2420
  async readFile(path) {
2399
2421
  const norm = normalisePath(path, this.workspaceBase);
2422
+ const inline = this.inlineFiles.get(norm);
2423
+ if (inline !== void 0) return inline;
2400
2424
  const entry = this.entries.get(norm);
2401
2425
  if (!entry) throw new Error(`ENOENT: no such file: ${path}`);
2402
2426
  return this.resolver.readFile(entry.id, this.ctx, entry.metadata);
2403
2427
  }
2404
2428
  async readFileBuffer(path) {
2405
2429
  const norm = normalisePath(path, this.workspaceBase);
2430
+ const inline = this.inlineFiles.get(norm);
2431
+ if (inline !== void 0) return new TextEncoder().encode(inline);
2406
2432
  const entry = this.entries.get(norm);
2407
2433
  if (!entry) throw new Error(`ENOENT: no such file: ${path}`);
2408
2434
  return this.resolver.readFileBuffer(entry.id, this.ctx, entry.metadata);
@@ -2633,7 +2659,7 @@ var VirtualFileSystem = class {
2633
2659
  function withVirtualFs(client, resolver, handler) {
2634
2660
  return async (args, context) => {
2635
2661
  const state = await queryParentWorkflowState(client);
2636
- const { fileTree, ctx, workspaceBase } = state;
2662
+ const { fileTree, virtualFsCtx, inlineFiles } = state;
2637
2663
  if (!fileTree) {
2638
2664
  return {
2639
2665
  toolResponse: `Error: No fileTree in agent state. The ${context.toolName} tool requires a virtual filesystem.`,
@@ -2643,8 +2669,9 @@ function withVirtualFs(client, resolver, handler) {
2643
2669
  const virtualFs = new VirtualFileSystem(
2644
2670
  fileTree,
2645
2671
  resolver,
2646
- ctx,
2647
- workspaceBase ?? "/"
2672
+ virtualFsCtx,
2673
+ "/",
2674
+ inlineFiles
2648
2675
  );
2649
2676
  const response = await handler(args, { ...context, virtualFs });
2650
2677
  const mutations = virtualFs.getMutations();
@@ -2666,7 +2693,7 @@ function createVirtualFsActivities(resolver, scope) {
2666
2693
  return { fileTree };
2667
2694
  }
2668
2695
  };
2669
- const prefix = scope;
2696
+ const prefix = `virtualFs${scope.charAt(0).toUpperCase()}${scope.slice(1)}`;
2670
2697
  const cap = (s) => s.charAt(0).toUpperCase() + s.slice(1);
2671
2698
  return Object.fromEntries(
2672
2699
  Object.entries(ops).map(([k, v]) => [`${prefix}${cap(k)}`, v])