zeitlich 0.2.38 → 0.2.40

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 (125) hide show
  1. package/README.md +18 -0
  2. package/dist/{activities-BKhMtKDd.d.ts → activities-CULxRzJ1.d.ts} +4 -6
  3. package/dist/{activities-CDcwkRZs.d.cts → activities-CvUrG3YG.d.cts} +4 -6
  4. package/dist/adapter-id-BB-mmrts.d.cts +17 -0
  5. package/dist/adapter-id-BB-mmrts.d.ts +17 -0
  6. package/dist/adapter-id-CMwVrVqv.d.cts +17 -0
  7. package/dist/adapter-id-CMwVrVqv.d.ts +17 -0
  8. package/dist/adapter-id-CbY2zeSt.d.cts +17 -0
  9. package/dist/adapter-id-CbY2zeSt.d.ts +17 -0
  10. package/dist/adapters/thread/anthropic/index.cjs +140 -23
  11. package/dist/adapters/thread/anthropic/index.cjs.map +1 -1
  12. package/dist/adapters/thread/anthropic/index.d.cts +8 -7
  13. package/dist/adapters/thread/anthropic/index.d.ts +8 -7
  14. package/dist/adapters/thread/anthropic/index.js +140 -24
  15. package/dist/adapters/thread/anthropic/index.js.map +1 -1
  16. package/dist/adapters/thread/anthropic/workflow.cjs +8 -3
  17. package/dist/adapters/thread/anthropic/workflow.cjs.map +1 -1
  18. package/dist/adapters/thread/anthropic/workflow.d.cts +5 -4
  19. package/dist/adapters/thread/anthropic/workflow.d.ts +5 -4
  20. package/dist/adapters/thread/anthropic/workflow.js +8 -4
  21. package/dist/adapters/thread/anthropic/workflow.js.map +1 -1
  22. package/dist/adapters/thread/google-genai/index.cjs +140 -23
  23. package/dist/adapters/thread/google-genai/index.cjs.map +1 -1
  24. package/dist/adapters/thread/google-genai/index.d.cts +5 -4
  25. package/dist/adapters/thread/google-genai/index.d.ts +5 -4
  26. package/dist/adapters/thread/google-genai/index.js +140 -24
  27. package/dist/adapters/thread/google-genai/index.js.map +1 -1
  28. package/dist/adapters/thread/google-genai/workflow.cjs +8 -3
  29. package/dist/adapters/thread/google-genai/workflow.cjs.map +1 -1
  30. package/dist/adapters/thread/google-genai/workflow.d.cts +5 -4
  31. package/dist/adapters/thread/google-genai/workflow.d.ts +5 -4
  32. package/dist/adapters/thread/google-genai/workflow.js +8 -4
  33. package/dist/adapters/thread/google-genai/workflow.js.map +1 -1
  34. package/dist/adapters/thread/index.cjs +16 -0
  35. package/dist/adapters/thread/index.cjs.map +1 -0
  36. package/dist/adapters/thread/index.d.cts +34 -0
  37. package/dist/adapters/thread/index.d.ts +34 -0
  38. package/dist/adapters/thread/index.js +12 -0
  39. package/dist/adapters/thread/index.js.map +1 -0
  40. package/dist/adapters/thread/langchain/index.cjs +139 -24
  41. package/dist/adapters/thread/langchain/index.cjs.map +1 -1
  42. package/dist/adapters/thread/langchain/index.d.cts +8 -7
  43. package/dist/adapters/thread/langchain/index.d.ts +8 -7
  44. package/dist/adapters/thread/langchain/index.js +139 -25
  45. package/dist/adapters/thread/langchain/index.js.map +1 -1
  46. package/dist/adapters/thread/langchain/workflow.cjs +8 -3
  47. package/dist/adapters/thread/langchain/workflow.cjs.map +1 -1
  48. package/dist/adapters/thread/langchain/workflow.d.cts +5 -4
  49. package/dist/adapters/thread/langchain/workflow.d.ts +5 -4
  50. package/dist/adapters/thread/langchain/workflow.js +8 -4
  51. package/dist/adapters/thread/langchain/workflow.js.map +1 -1
  52. package/dist/index.cjs +267 -48
  53. package/dist/index.cjs.map +1 -1
  54. package/dist/index.d.cts +6 -6
  55. package/dist/index.d.ts +6 -6
  56. package/dist/index.js +264 -49
  57. package/dist/index.js.map +1 -1
  58. package/dist/{proxy-D_3x7RN4.d.cts → proxy-5EbwzaY4.d.cts} +1 -1
  59. package/dist/{proxy-CUlKSvZS.d.ts → proxy-wZufFfBh.d.ts} +1 -1
  60. package/dist/{thread-manager-CVu7o2cs.d.ts → thread-manager-BNiIt5r8.d.ts} +2 -4
  61. package/dist/{thread-manager-c1gPopAG.d.ts → thread-manager-BoN5DOvG.d.cts} +2 -4
  62. package/dist/{thread-manager-wGi-LqIP.d.cts → thread-manager-BqBAIsED.d.ts} +2 -4
  63. package/dist/{thread-manager-HSwyh28L.d.cts → thread-manager-DF8WuCRs.d.cts} +2 -4
  64. package/dist/{types-BH_IRryz.d.ts → types-C7OoY7h8.d.ts} +54 -6
  65. package/dist/{types-C06FwR96.d.cts → types-Cn2r3ol3.d.cts} +163 -44
  66. package/dist/{types-BaOw4hKI.d.cts → types-CuISs0Ub.d.cts} +54 -6
  67. package/dist/{types-DNr31FzL.d.ts → types-DeQH84C_.d.ts} +163 -44
  68. package/dist/{workflow-CSCkpwAL.d.ts → workflow-C2MZZj5K.d.ts} +82 -2
  69. package/dist/{workflow-DuvMZ8Vm.d.cts → workflow-DhplIN65.d.cts} +82 -2
  70. package/dist/workflow.cjs +189 -37
  71. package/dist/workflow.cjs.map +1 -1
  72. package/dist/workflow.d.cts +2 -2
  73. package/dist/workflow.d.ts +2 -2
  74. package/dist/workflow.js +186 -38
  75. package/dist/workflow.js.map +1 -1
  76. package/package.json +11 -1
  77. package/src/adapters/thread/adapter-id.test.ts +42 -0
  78. package/src/adapters/thread/anthropic/activities.ts +33 -7
  79. package/src/adapters/thread/anthropic/adapter-id.ts +16 -0
  80. package/src/adapters/thread/anthropic/fork-transform.test.ts +291 -0
  81. package/src/adapters/thread/anthropic/index.ts +3 -0
  82. package/src/adapters/thread/anthropic/model-invoker.ts +8 -4
  83. package/src/adapters/thread/anthropic/proxy.ts +3 -2
  84. package/src/adapters/thread/anthropic/thread-manager.ts +27 -4
  85. package/src/adapters/thread/google-genai/activities.ts +33 -7
  86. package/src/adapters/thread/google-genai/adapter-id.ts +16 -0
  87. package/src/adapters/thread/google-genai/fork-transform.test.ts +149 -0
  88. package/src/adapters/thread/google-genai/index.ts +3 -0
  89. package/src/adapters/thread/google-genai/model-invoker.ts +7 -3
  90. package/src/adapters/thread/google-genai/proxy.ts +3 -2
  91. package/src/adapters/thread/google-genai/thread-manager.ts +27 -4
  92. package/src/adapters/thread/index.ts +39 -0
  93. package/src/adapters/thread/langchain/activities.ts +33 -7
  94. package/src/adapters/thread/langchain/adapter-id.ts +16 -0
  95. package/src/adapters/thread/langchain/fork-transform.test.ts +142 -0
  96. package/src/adapters/thread/langchain/index.ts +3 -0
  97. package/src/adapters/thread/langchain/model-invoker.ts +8 -3
  98. package/src/adapters/thread/langchain/proxy.ts +3 -2
  99. package/src/adapters/thread/langchain/thread-manager.ts +27 -4
  100. package/src/lib/lifecycle.ts +3 -1
  101. package/src/lib/model/types.ts +7 -10
  102. package/src/lib/session/session-edge-cases.integration.test.ts +131 -63
  103. package/src/lib/session/session.integration.test.ts +174 -5
  104. package/src/lib/session/session.ts +69 -28
  105. package/src/lib/session/types.ts +61 -9
  106. package/src/lib/state/index.ts +1 -0
  107. package/src/lib/state/manager.integration.test.ts +109 -0
  108. package/src/lib/state/manager.ts +38 -8
  109. package/src/lib/state/types.ts +25 -0
  110. package/src/lib/subagent/handler.ts +124 -11
  111. package/src/lib/subagent/index.ts +5 -1
  112. package/src/lib/subagent/subagent.integration.test.ts +528 -0
  113. package/src/lib/subagent/types.ts +63 -14
  114. package/src/lib/subagent/workflow.ts +29 -2
  115. package/src/lib/thread/index.ts +5 -0
  116. package/src/lib/thread/keys.test.ts +101 -0
  117. package/src/lib/thread/keys.ts +94 -0
  118. package/src/lib/thread/manager.test.ts +139 -0
  119. package/src/lib/thread/manager.ts +92 -14
  120. package/src/lib/thread/proxy.ts +2 -0
  121. package/src/lib/thread/types.ts +60 -6
  122. package/src/lib/tool-router/types.ts +16 -8
  123. package/src/lib/types.ts +12 -0
  124. package/src/workflow.ts +12 -1
  125. package/tsup.config.ts +1 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/lib/thread/manager.ts","../../../../src/adapters/thread/anthropic/thread-manager.ts","../../../../src/lib/activity.ts","../../../../src/adapters/thread/anthropic/model-invoker.ts","../../../../src/adapters/thread/anthropic/activities.ts"],"names":["Context","invokeAnthropicModel"],"mappings":"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","file":"index.cjs","sourcesContent":["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 Anthropic from \"@anthropic-ai/sdk\";\nimport type { JsonValue } from \"../../../lib/state/types\";\nimport { createThreadManager } from \"../../../lib/thread/manager\";\nimport type {\n ProviderThreadManager,\n ThreadManagerConfig,\n ThreadManagerHooks,\n} from \"../../../lib/thread/types\";\n\n/** SDK-native content type for Anthropic human messages */\nexport type AnthropicContent = string | Anthropic.Messages.ContentBlockParam[];\n\n/** SDK-native content type for Anthropic system prompts (supports cache_control blocks) */\nexport type AnthropicSystemContent =\n | string\n | Anthropic.Messages.TextBlockParam[];\n\n/** A MessageParam with a unique ID for idempotent Redis storage */\nexport interface StoredMessage {\n id: string;\n message: Anthropic.Messages.MessageParam;\n /** System messages are stored separately since Anthropic passes them via config */\n isSystem?: boolean;\n}\n\nexport type AnthropicThreadManagerHooks = ThreadManagerHooks<\n StoredMessage,\n Anthropic.Messages.MessageParam\n>;\n\nexport interface AnthropicThreadManagerConfig {\n redis: Redis;\n threadId: string;\n /** Thread key, defaults to 'messages' */\n key?: string;\n hooks?: AnthropicThreadManagerHooks;\n}\n\n/** Prepared payload ready to send to the Anthropic API */\nexport interface AnthropicInvocationPayload {\n messages: Anthropic.Messages.MessageParam[];\n system?: string | Anthropic.Messages.TextBlockParam[];\n /** Number of stored messages loaded from Redis before preparation. */\n storedLength: number;\n}\n\n/** Thread manager with Anthropic MessageParam convenience helpers */\nexport interface AnthropicThreadManager extends ProviderThreadManager<\n StoredMessage,\n AnthropicContent,\n JsonValue,\n AnthropicSystemContent\n> {\n appendAssistantMessage(\n id: string,\n content: Anthropic.Messages.ContentBlock[]\n ): Promise<void>;\n prepareForInvocation(): Promise<AnthropicInvocationPayload>;\n}\n\nfunction storedMessageId(msg: StoredMessage): string {\n return msg.id;\n}\n\n/** Normalise content into an array of ContentBlockParam */\nfunction toContentBlocks(\n content: AnthropicContent\n): Anthropic.Messages.ContentBlockParam[] {\n if (typeof content === \"string\") {\n return [{ type: \"text\", text: content }];\n }\n return content;\n}\n\n/**\n * Merge consecutive messages with the same role.\n * The Anthropic API requires alternating user/assistant turns; without\n * merging, multiple sequential tool-result messages would violate this.\n */\nfunction mergeConsecutiveMessages(\n messages: Anthropic.Messages.MessageParam[]\n): Anthropic.Messages.MessageParam[] {\n const merged: Anthropic.Messages.MessageParam[] = [];\n for (const msg of messages) {\n const last = merged[merged.length - 1];\n if (last && last.role === msg.role) {\n const lastContent = Array.isArray(last.content)\n ? last.content\n : [{ type: \"text\" as const, text: last.content }];\n const msgContent = Array.isArray(msg.content)\n ? msg.content\n : [{ type: \"text\" as const, text: msg.content }];\n last.content = [...lastContent, ...msgContent];\n } else {\n merged.push({\n ...msg,\n content: Array.isArray(msg.content) ? [...msg.content] : msg.content,\n });\n }\n }\n return merged;\n}\n\n/**\n * Creates an Anthropic-specific thread manager that stores StoredMessage\n * instances in Redis and provides convenience helpers for creating and\n * appending typed messages.\n */\nexport function createAnthropicThreadManager(\n config: AnthropicThreadManagerConfig\n): AnthropicThreadManager {\n const baseConfig: ThreadManagerConfig<StoredMessage> = {\n redis: config.redis,\n threadId: config.threadId,\n key: config.key,\n idOf: storedMessageId,\n };\n\n const base = createThreadManager(baseConfig);\n\n const helpers: Omit<AnthropicThreadManager, keyof typeof base> = {\n async appendUserMessage(\n id: string,\n content: AnthropicContent\n ): Promise<void> {\n await base.append([\n {\n id,\n message: { role: \"user\", content: toContentBlocks(content) },\n },\n ]);\n },\n\n async appendSystemMessage(\n id: string,\n content: AnthropicSystemContent\n ): Promise<void> {\n await base.initialize();\n await base.append([\n {\n id,\n // Stored under a user-role placeholder to satisfy the MessageParam\n // shape; the `isSystem` flag steers extraction in prepareForInvocation.\n message: {\n role: \"user\",\n content: content as Anthropic.Messages.MessageParam[\"content\"],\n },\n isSystem: true,\n },\n ]);\n },\n\n async appendAssistantMessage(\n id: string,\n content: Anthropic.Messages.ContentBlock[]\n ): Promise<void> {\n await base.append([\n {\n id,\n message: {\n role: \"assistant\",\n content:\n content as unknown as Anthropic.Messages.ContentBlockParam[],\n },\n },\n ]);\n },\n\n async appendToolResult(\n id: string,\n toolCallId: string,\n _toolName: string,\n content: JsonValue\n ): Promise<void> {\n const toolContent =\n typeof content === \"string\"\n ? content\n : Array.isArray(content)\n ? (content as unknown as Anthropic.Messages.ToolResultBlockParam[\"content\"])\n : JSON.stringify(content);\n await base.append([\n {\n id,\n message: {\n role: \"user\",\n content: [\n {\n type: \"tool_result\" as const,\n tool_use_id: toolCallId,\n content: toolContent,\n },\n ],\n },\n },\n ]);\n },\n\n async prepareForInvocation(): Promise<AnthropicInvocationPayload> {\n const stored = await base.load();\n const { onPrepareMessage, onPreparedMessage } = config.hooks ?? {};\n const mapped = onPrepareMessage\n ? stored.map((msg, i) => onPrepareMessage(msg, i, stored))\n : stored;\n\n let system: string | Anthropic.Messages.TextBlockParam[] | undefined;\n const conversationMessages: Anthropic.Messages.MessageParam[] = [];\n\n for (const item of mapped) {\n if (item.isSystem) {\n system = item.message.content as\n | string\n | Anthropic.Messages.TextBlockParam[];\n } else {\n conversationMessages.push(item.message);\n }\n }\n\n const messages = mergeConsecutiveMessages(conversationMessages);\n return {\n messages: onPreparedMessage\n ? messages.map((msg, i) => onPreparedMessage(msg, i, messages))\n : messages,\n ...(system ? { system } : {}),\n storedLength: stored.length,\n };\n },\n };\n\n return Object.assign(base, helpers);\n}\n","import { Context } from \"@temporalio/activity\";\nimport type { WorkflowClient } from \"@temporalio/client\";\nimport type { BaseAgentState, RunAgentConfig } from \"./types\";\nimport type { JsonValue } from \"./state/types\";\nimport type {\n ActivityToolHandler,\n RouterContext,\n ToolHandlerResponse,\n} from \"./tool-router/types\";\n\n/**\n * Safely retrieve Temporal activity heartbeat and cancellation signal.\n * Returns empty object when called outside a Temporal activity (e.g. tests).\n */\nexport function getActivityContext(): {\n heartbeat?: () => void;\n signal?: AbortSignal;\n} {\n try {\n const ctx = Context.current();\n return { heartbeat: () => ctx.heartbeat(), signal: ctx.cancellationSignal };\n } catch {\n return {};\n }\n}\n\n/**\n * Query the parent workflow's state from within an activity.\n * Resolves the workflow handle from the current activity context.\n */\nexport async function queryParentWorkflowState<T>(\n client: WorkflowClient\n): Promise<T> {\n const { workflowExecution } = Context.current().info;\n const handle = client.getHandle(\n workflowExecution.workflowId,\n workflowExecution.runId\n );\n return handle.query<T>(\"getAgentState\");\n}\n\n/**\n * Wraps a handler into a scope-prefixed `RunAgentActivity` by auto-fetching\n * the parent workflow's agent state before each invocation.\n *\n * Returns a `Record` with a single key `run<Scope>` so it can be spread\n * into the activities object alongside adapter activities.\n *\n * @param scope - Workflow scope used to derive the activity name.\n * `\"myAgentWorkflow\"` produces `{ runMyAgentWorkflow: fn }`.\n *\n * @example\n * ```typescript\n * import { createRunAgentActivity } from 'zeitlich';\n *\n * return {\n * ...adapter.createActivities(\"myAgentWorkflow\"),\n * ...createRunAgentActivity(client, adapter.invoker, \"myAgentWorkflow\"),\n * };\n * ```\n */\nexport function createRunAgentActivity<\n R,\n S extends BaseAgentState = BaseAgentState,\n>(\n client: WorkflowClient,\n handler: (config: RunAgentConfig & { state: S }) => Promise<R>,\n scope: string\n): Record<string, (config: RunAgentConfig) => Promise<R>> {\n const name = `run${scope.charAt(0).toUpperCase()}${scope.slice(1)}`;\n return {\n [name]: async (config: RunAgentConfig) => {\n const state = await queryParentWorkflowState<S>(client);\n return handler({ ...config, state });\n },\n };\n}\n\n/**\n * Context injected into tool handlers created via {@link withParentWorkflowState}.\n */\nexport interface AgentStateContext<\n S extends BaseAgentState = BaseAgentState,\n> extends RouterContext {\n state: S;\n}\n\n/**\n * Wraps a tool handler into an `ActivityToolHandler` by auto-fetching the\n * parent workflow's agent state before each invocation.\n *\n * @typeParam S - Custom agent state type (defaults to `BaseAgentState`)\n *\n * @example\n * ```typescript\n * import { withParentWorkflowState, type AgentStateContext } from 'zeitlich';\n *\n * // With custom state:\n * interface MyState extends BaseAgentState { customField: string }\n * const myHandler = withParentWorkflowState<MyArgs, MyResult, MyState>(\n * client,\n * async (args, ctx) => {\n * console.log(ctx.state.customField);\n * return { toolResponse: 'done', data: null };\n * },\n * );\n * ```\n */\nexport function withParentWorkflowState<\n TArgs,\n TResult,\n S extends BaseAgentState = BaseAgentState,\n TToolResponse = JsonValue,\n>(\n client: WorkflowClient,\n handler: (\n args: TArgs,\n context: AgentStateContext<S>\n ) => Promise<ToolHandlerResponse<TResult, TToolResponse>>\n): ActivityToolHandler<TArgs, TResult, RouterContext, TToolResponse> {\n return async (args, context) => {\n const state = await queryParentWorkflowState<S>(client);\n return handler(args, { ...context, state });\n };\n}\n","import type Redis from \"ioredis\";\nimport type Anthropic from \"@anthropic-ai/sdk\";\nimport type { SerializableToolDefinition } from \"../../../lib/types\";\nimport type { AgentResponse, ModelInvokerConfig } from \"../../../lib/model\";\nimport {\n createAnthropicThreadManager,\n type AnthropicThreadManagerHooks,\n} from \"./thread-manager\";\nimport { getActivityContext } from \"../../../lib/activity\";\n\nexport interface AnthropicModelInvokerConfig {\n redis: Redis;\n client: Anthropic;\n model: string;\n /** Maximum tokens to generate. Defaults to 16384. */\n maxTokens?: number;\n hooks?: AnthropicThreadManagerHooks;\n}\n\nfunction toAnthropicTools(\n tools: SerializableToolDefinition[]\n): Anthropic.Messages.Tool[] {\n return tools.map((t) => ({\n name: t.name,\n description: t.description,\n input_schema: t.schema as Anthropic.Messages.Tool.InputSchema,\n }));\n}\n\n/**\n * Creates an Anthropic model invoker that satisfies the generic\n * `ModelInvoker<Anthropic.Messages.Message>` contract.\n *\n * Internally streams the response and emits Temporal heartbeats on each\n * event so that long-running LLM calls remain visible to the scheduler.\n * The caller is responsible for appending the response to the thread.\n *\n * @example\n * ```typescript\n * import { createAnthropicModelInvoker } from 'zeitlich/adapters/thread/anthropic';\n * import { createRunAgentActivity } from 'zeitlich';\n * import Anthropic from '@anthropic-ai/sdk';\n *\n * const client = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY });\n * const invoker = createAnthropicModelInvoker({\n * redis,\n * client,\n * model: 'claude-sonnet-4-20250514',\n * });\n *\n * return { ...createRunAgentActivity(client, invoker, \"myAgent\") };\n * ```\n */\nexport function createAnthropicModelInvoker({\n redis,\n client,\n model,\n maxTokens = 16384,\n hooks,\n}: AnthropicModelInvokerConfig) {\n return async function invokeAnthropicModel(\n config: ModelInvokerConfig\n ): Promise<AgentResponse<Anthropic.Messages.Message>> {\n const { threadId, threadKey, state } = config;\n const { heartbeat, signal } = getActivityContext();\n\n const thread = createAnthropicThreadManager({\n redis,\n threadId,\n key: threadKey,\n hooks,\n });\n const { messages, system, storedLength } =\n await thread.prepareForInvocation();\n\n const anthropicTools = toAnthropicTools(state.tools);\n const tools = anthropicTools.length > 0 ? anthropicTools : undefined;\n\n const params: Anthropic.MessageCreateParams = {\n model,\n max_tokens: maxTokens,\n messages,\n ...(system ? { system } : {}),\n ...(tools ? { tools } : {}),\n };\n\n const stream = client.messages.stream(params, { signal });\n\n for await (const _event of stream) {\n heartbeat?.();\n }\n\n const response: Anthropic.Messages.Message = await stream.finalMessage();\n\n const toolCalls = response.content.filter(\n (block): block is Anthropic.Messages.ToolUseBlock =>\n block.type === \"tool_use\"\n );\n\n return {\n message: response,\n rawToolCalls: toolCalls.map((tc) => ({\n id: tc.id,\n name: tc.name,\n args: (tc.input as Record<string, unknown>) ?? {},\n })),\n usage: {\n inputTokens: response.usage.input_tokens,\n outputTokens: response.usage.output_tokens,\n cachedWriteTokens:\n response.usage.cache_creation_input_tokens ?? undefined,\n cachedReadTokens: response.usage.cache_read_input_tokens ?? undefined,\n },\n threadLengthAtCall: storedLength,\n };\n };\n}\n\n/**\n * Standalone function for one-shot Anthropic model invocation.\n * Convenience wrapper around createAnthropicModelInvoker for cases\n * where you don't need to reuse the invoker.\n */\nexport async function invokeAnthropicModel({\n redis,\n client,\n model,\n maxTokens,\n hooks,\n config,\n}: {\n redis: Redis;\n client: Anthropic;\n model: string;\n maxTokens?: number;\n hooks?: AnthropicThreadManagerHooks;\n config: ModelInvokerConfig;\n}): Promise<AgentResponse<Anthropic.Messages.Message>> {\n const invoker = createAnthropicModelInvoker({\n redis,\n client,\n model,\n maxTokens,\n hooks,\n });\n return invoker(config);\n}\n","import type Redis from \"ioredis\";\nimport type Anthropic from \"@anthropic-ai/sdk\";\nimport type { ToolResultConfig } from \"../../../lib/types\";\nimport type {\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 {\n createAnthropicThreadManager,\n type AnthropicContent,\n type AnthropicSystemContent,\n type AnthropicThreadManagerHooks,\n} from \"./thread-manager\";\nimport {\n createAnthropicModelInvoker,\n type AnthropicModelInvokerConfig,\n} from \"./model-invoker\";\n\nconst ADAPTER_PREFIX = \"anthropic\" as const;\n\nexport type AnthropicThreadOps<TScope extends string = \"\"> = PrefixedThreadOps<\n ScopedPrefix<TScope, typeof ADAPTER_PREFIX>,\n AnthropicContent\n>;\n\nexport interface AnthropicAdapterConfig {\n redis: Redis;\n client: Anthropic;\n /** Default model name (e.g. 'claude-sonnet-4-20250514'). If omitted, use `createModelInvoker()` */\n model?: string;\n /** Maximum tokens to generate. Defaults to 16384. */\n maxTokens?: number;\n hooks?: AnthropicThreadManagerHooks;\n}\n\n/**\n * Tool response type accepted by the Anthropic adapter.\n *\n * Handlers can return:\n * - **`string`** — plain text content for the tool result.\n * - **`Anthropic.Messages.ToolResultBlockParam[\"content\"]`** — array of content blocks\n * (e.g. `{ type: \"text\", text: \"...\" }`, `{ type: \"image\", source: { ... } }`).\n * Passed through as-is to the `tool_result` block.\n */\nexport type AnthropicToolResponse =\n Anthropic.Messages.ToolResultBlockParam[\"content\"];\n\nexport interface AnthropicAdapter {\n /** Model invoker using the default model (only available when `model` was provided) */\n invoker: ModelInvoker<Anthropic.Messages.Message>;\n /** Create an invoker for a specific model name (for multi-model setups) */\n createModelInvoker(\n model: string,\n maxTokens?: number\n ): ModelInvoker<Anthropic.Messages.Message>;\n /**\n * Create prefixed thread activities for registration on the worker.\n *\n * @param scope - Workflow name appended to the adapter prefix.\n * Use different scopes for the main agent vs subagents to avoid collisions.\n *\n * @example\n * ```typescript\n * adapter.createActivities(\"codingAgent\")\n * // → { anthropicCodingAgentInitializeThread, anthropicCodingAgentAppendHumanMessage, … }\n *\n * adapter.createActivities(\"researchAgent\")\n * // → { anthropicResearchAgentInitializeThread, … }\n * ```\n */\n createActivities<S extends string = \"\">(scope?: S): AnthropicThreadOps<S>;\n\n /**\n * Identity wrapper that types a tool handler for this adapter.\n * Constrains `toolResponse` to {@link AnthropicToolResponse}.\n */\n wrapHandler<TArgs, TResult, TContext extends RouterContext = RouterContext>(\n handler: (\n args: TArgs,\n context: TContext\n ) => Promise<ToolHandlerResponse<TResult, AnthropicToolResponse>>\n ): ActivityToolHandler<TArgs, TResult, TContext, AnthropicToolResponse>;\n}\n\n/**\n * Creates an Anthropic adapter that bundles thread operations and model\n * invocation using the `@anthropic-ai/sdk`.\n *\n * Use `createActivities(scope)` to register scoped thread operations as\n * Temporal activities on the worker. The `invoker` (or invokers created via\n * `createModelInvoker`) should be wrapped with `createRunAgentActivity`.\n *\n * @example\n * ```typescript\n * import { createAnthropicAdapter } from 'zeitlich/adapters/thread/anthropic';\n * import { createRunAgentActivity } from 'zeitlich';\n * import Anthropic from '@anthropic-ai/sdk';\n *\n * const client = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY });\n * const adapter = createAnthropicAdapter({ redis, client, model: 'claude-sonnet-4-20250514' });\n *\n * export function createActivities(temporalClient: WorkflowClient) {\n * return {\n * ...adapter.createActivities(\"codingAgent\"),\n * ...createRunAgentActivity(temporalClient, adapter.invoker, \"codingAgent\"),\n * };\n * }\n * ```\n *\n * @example Multi-agent worker (main + subagent share the adapter)\n * ```typescript\n * export function createActivities(temporalClient: WorkflowClient) {\n * return {\n * ...adapter.createActivities(\"codingAgent\"),\n * ...adapter.createActivities(\"researchAgent\"),\n * ...createRunAgentActivity(temporalClient, adapter.invoker, \"codingAgent\"),\n * ...createRunAgentActivity(\n * temporalClient,\n * adapter.createModelInvoker('claude-sonnet-4-20250514'),\n * \"researchAgent\",\n * ),\n * };\n * }\n * ```\n */\nexport function createAnthropicAdapter(\n config: AnthropicAdapterConfig\n): AnthropicAdapter {\n const { redis, client } = config;\n\n const threadOps: ThreadOps<AnthropicContent> = {\n async initializeThread(\n threadId: string,\n threadKey?: string\n ): Promise<void> {\n const thread = createAnthropicThreadManager({\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: AnthropicContent,\n threadKey?: string\n ): Promise<void> {\n const thread = createAnthropicThreadManager({\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: AnthropicSystemContent,\n threadKey?: string\n ): Promise<void> {\n const thread = createAnthropicThreadManager({\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, toolName, content } = cfg;\n const thread = createAnthropicThreadManager({\n redis,\n threadId,\n key: threadKey,\n });\n await thread.appendToolResult(id, toolCallId, toolName, content);\n },\n\n async appendAgentMessage(\n threadId: string,\n id: string,\n message: Anthropic.Messages.Message,\n threadKey?: string\n ): Promise<void> {\n const thread = createAnthropicThreadManager({\n redis,\n threadId,\n key: threadKey,\n });\n await thread.appendAssistantMessage(id, message.content);\n },\n\n async forkThread(\n sourceThreadId: string,\n targetThreadId: string,\n threadKey?: string\n ): Promise<void> {\n const thread = createAnthropicThreadManager({\n redis,\n threadId: sourceThreadId,\n key: threadKey,\n });\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 = createAnthropicThreadManager({ redis, threadId, key: threadKey });\n await thread.truncate(length);\n },\n };\n\n function createActivities<S extends string = \"\">(\n scope?: S\n ): AnthropicThreadOps<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 AnthropicThreadOps<S>;\n }\n\n const makeInvoker = (\n model: string,\n maxTokens?: number\n ): ModelInvoker<Anthropic.Messages.Message> => {\n const invokerConfig: AnthropicModelInvokerConfig = {\n redis,\n client,\n model,\n ...(maxTokens !== undefined ? { maxTokens } : {}),\n ...(config.maxTokens !== undefined && maxTokens === undefined\n ? { maxTokens: config.maxTokens }\n : {}),\n hooks: config.hooks,\n };\n return createAnthropicModelInvoker(invokerConfig);\n };\n\n const invoker: ModelInvoker<Anthropic.Messages.Message> = config.model\n ? makeInvoker(config.model)\n : ((() => {\n throw new Error(\n \"No default model provided to createAnthropicAdapter. \" +\n \"Either pass `model` in the config or use `createModelInvoker(model)` instead.\"\n );\n }) as unknown as ModelInvoker<Anthropic.Messages.Message>);\n\n return {\n createActivities,\n invoker,\n createModelInvoker: makeInvoker,\n wrapHandler: (handler) => handler,\n };\n}\n"]}
1
+ {"version":3,"sources":["../../../../src/adapters/thread/anthropic/adapter-id.ts","../../../../src/lib/thread/keys.ts","../../../../src/lib/thread/manager.ts","../../../../src/adapters/thread/anthropic/thread-manager.ts","../../../../src/lib/activity.ts","../../../../src/adapters/thread/anthropic/model-invoker.ts","../../../../src/adapters/thread/anthropic/activities.ts"],"names":["Context","invokeAnthropicModel"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Public adapter identity for the Anthropic thread adapter.\n *\n * This value is wire format — it appears as the prefix for Temporal\n * activity names (e.g. `anthropicCodingAgentInitializeThread`) and must\n * never change, since renaming it would orphan existing persisted\n * threads and break in-flight workflows.\n *\n * Re-exported from `zeitlich/adapters/thread/anthropic` so downstream\n * consumers can use the exact same literal the adapter uses internally,\n * typed as the narrow string literal `\"anthropic\"`.\n */\nexport const ADAPTER_ID = \"anthropic\" as const;\n\n/** Narrow string-literal type for {@link ADAPTER_ID}. */\nexport type AdapterId = typeof ADAPTER_ID;\n","/**\n * Public helpers for zeitlich's Redis thread storage layout.\n *\n * These are the exact string-building primitives zeitlich's internal thread\n * manager uses for every adapter. Downstream consumers that need to read a\n * persisted thread (for evaluation, observability, admin tooling, etc.)\n * should use these helpers rather than reconstructing the key layout by\n * hand — the layout is versioned with this module, so upgrading zeitlich\n * keeps the consumer in sync.\n *\n * The layout is adapter-agnostic: every thread adapter stores messages the\n * same way.\n *\n * @example\n * ```typescript\n * import {\n * getThreadListKey,\n * getThreadMetaKey,\n * THREAD_TTL_SECONDS,\n * } from 'zeitlich';\n *\n * const listKey = getThreadListKey('messages', threadId);\n * const metaKey = getThreadMetaKey('messages', threadId);\n * const ttl = await redis.ttl(listKey); // <= THREAD_TTL_SECONDS\n * ```\n */\n\n/**\n * TTL (in seconds) applied to every thread list and thread meta key that\n * zeitlich's {@link createThreadManager} writes. Exposed so downstream\n * consumers can size their Redis retention / query windows to match.\n *\n * Current value: 90 days.\n */\nexport const THREAD_TTL_SECONDS = 60 * 60 * 24 * 90;\n\n/**\n * Build the Redis list key that holds a thread's serialized messages.\n *\n * Mirrors the exact key used internally by zeitlich's thread manager,\n * so a consumer calling `redis.lrange(getThreadListKey(key, id), 0, -1)`\n * sees the same data the writer wrote.\n *\n * @param threadKey - Thread key (defaults to `\"messages\"` inside the\n * thread manager, but downstream adapters may pass\n * their own value).\n * @param threadId - Thread id as provided to the thread manager.\n */\nexport function getThreadListKey(\n threadKey: string,\n threadId: string\n): string {\n return `${threadKey}:thread:${threadId}`;\n}\n\n/**\n * Build the Redis key that stores a thread's existence marker / metadata.\n *\n * Zeitlich treats the presence of this key as \"thread has been\n * initialized\"; append/load/fork/truncate operations fail when it is\n * missing. Consumers can use it as a cheap existence probe without\n * scanning the message list.\n *\n * @param threadKey - Thread key (defaults to `\"messages\"` inside the\n * thread manager, but downstream adapters may pass\n * their own value).\n * @param threadId - Thread id as provided to the thread manager.\n */\nexport function getThreadMetaKey(\n threadKey: string,\n threadId: string\n): string {\n return `${threadKey}:meta:thread:${threadId}`;\n}\n\n/**\n * Build the Redis key that stores a thread's persisted state slice\n * (tasks + custom state) written by zeitlich's session loop on every\n * exit path.\n *\n * Consumers can read this key with `redis.get(getThreadStateKey(key, id))`\n * and `JSON.parse` the result into a {@link PersistedThreadState}.\n *\n * @param threadKey - Thread key (defaults to `\"messages\"` inside the\n * thread manager, but downstream adapters may pass\n * their own value).\n * @param threadId - Thread id as provided to the thread manager.\n */\nexport function getThreadStateKey(\n threadKey: string,\n threadId: string\n): string {\n return `${threadKey}:state:thread:${threadId}`;\n}\n","import type { PersistedThreadState } from \"../state/types\";\nimport type { ThreadManagerConfig, BaseThreadManager } from \"./types\";\nimport {\n THREAD_TTL_SECONDS,\n getThreadListKey,\n getThreadMetaKey,\n getThreadStateKey,\n} from \"./keys\";\n\n/**\n * Lua script for atomic idempotent append.\n * Checks a dedup key; if it exists the message was already appended and we\n * return 0. Otherwise appends all messages to the list, sets TTL on both\n * the list and the dedup key, and returns 1.\n *\n * KEYS[1] = dedup key, KEYS[2] = list key\n * ARGV[1] = TTL seconds, ARGV[2..N] = serialised messages\n */\nconst APPEND_IDEMPOTENT_SCRIPT = `\nif redis.call('EXISTS', KEYS[1]) == 1 then\n return 0\nend\nfor i = 2, #ARGV do\n redis.call('RPUSH', KEYS[2], ARGV[i])\nend\nredis.call('EXPIRE', KEYS[2], tonumber(ARGV[1]))\nredis.call('SET', KEYS[1], '1', 'EX', tonumber(ARGV[1]))\nreturn 1\n`;\n\nfunction getDedupKey(threadId: string, id: string): string {\n return `dedup:${id}: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 = getThreadListKey(key, threadId);\n const metaKey = getThreadMetaKey(key, threadId);\n const stateKey = getThreadStateKey(key, threadId);\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 = getDedupKey(threadId, 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 stateRaw = await redis.get(stateKey);\n const forked = createThreadManager({\n ...config,\n threadId: newThreadId,\n });\n await forked.initialize();\n if (data.length > 0) {\n const newKey = getThreadListKey(key, newThreadId);\n await redis.rpush(newKey, ...data);\n await redis.expire(newKey, THREAD_TTL_SECONDS);\n }\n if (stateRaw != null) {\n const newStateKey = getThreadStateKey(key, newThreadId);\n await redis.set(newStateKey, stateRaw, \"EX\", THREAD_TTL_SECONDS);\n }\n return forked;\n },\n\n async replaceAll(messages: T[]): Promise<void> {\n await assertThreadExists();\n if (!idOf) {\n throw new Error(\n \"replaceAll requires the thread manager to be configured with `idOf`\"\n );\n }\n const existing = await redis.lrange(redisKey, 0, -1);\n const existingIds = existing\n .map((raw) => idOf(deserialize(raw)))\n .filter((id): id is string => typeof id === \"string\");\n await redis.del(redisKey);\n if (existingIds.length > 0) {\n await redis.del(\n ...existingIds.map((id) => getDedupKey(threadId, id))\n );\n }\n if (messages.length > 0) {\n await redis.rpush(redisKey, ...messages.map(serialize));\n await redis.expire(redisKey, THREAD_TTL_SECONDS);\n }\n await redis.expire(metaKey, THREAD_TTL_SECONDS);\n },\n\n async delete(): Promise<void> {\n await redis.del(redisKey, metaKey, stateKey);\n },\n\n async loadState(): Promise<PersistedThreadState | null> {\n const raw = await redis.get(stateKey);\n if (raw == null) return null;\n return JSON.parse(raw) as PersistedThreadState;\n },\n\n async saveState(state: PersistedThreadState): Promise<void> {\n await assertThreadExists();\n await redis.set(\n stateKey,\n JSON.stringify(state),\n \"EX\",\n THREAD_TTL_SECONDS\n );\n },\n\n async deleteState(): Promise<void> {\n await redis.del(stateKey);\n },\n\n async length(): Promise<number> {\n await assertThreadExists();\n return redis.llen(redisKey);\n },\n\n async truncateFromId(messageId: string): Promise<void> {\n await assertThreadExists();\n if (!idOf) {\n throw new Error(\n \"truncateFromId requires the thread manager to be configured with `idOf`\"\n );\n }\n const data = await redis.lrange(redisKey, 0, -1);\n let idx = -1;\n const removedIds: string[] = [];\n for (let i = 0; i < data.length; i++) {\n const raw = data[i];\n if (raw === undefined) continue;\n const id = idOf(deserialize(raw));\n if (idx === -1 && id === messageId) idx = i;\n if (idx !== -1) removedIds.push(id);\n }\n if (idx === -1) return;\n if (idx === 0) {\n await redis.del(redisKey);\n await redis.expire(metaKey, THREAD_TTL_SECONDS);\n } else {\n await redis.ltrim(redisKey, 0, idx - 1);\n await redis.expire(redisKey, THREAD_TTL_SECONDS);\n }\n // Clear dedup markers for the removed messages so that a rewind\n // retry which reuses the same ids (e.g. the same assistantId) can\n // re-append without the idempotent-append Lua script treating it\n // as a duplicate.\n if (removedIds.length > 0) {\n await redis.del(\n ...removedIds.map((id) => getDedupKey(threadId, id))\n );\n }\n },\n };\n}\n","import type Redis from \"ioredis\";\nimport type Anthropic from \"@anthropic-ai/sdk\";\nimport type { JsonValue } from \"../../../lib/state/types\";\nimport { createThreadManager } from \"../../../lib/thread/manager\";\nimport type {\n ProviderThreadManager,\n ThreadManagerConfig,\n ThreadManagerHooks,\n} from \"../../../lib/thread/types\";\n\n/** SDK-native content type for Anthropic human messages */\nexport type AnthropicContent = string | Anthropic.Messages.ContentBlockParam[];\n\n/** SDK-native content type for Anthropic system prompts (supports cache_control blocks) */\nexport type AnthropicSystemContent =\n | string\n | Anthropic.Messages.TextBlockParam[];\n\n/** A MessageParam with a unique ID for idempotent Redis storage */\nexport interface StoredMessage {\n id: string;\n message: Anthropic.Messages.MessageParam;\n /** System messages are stored separately since Anthropic passes them via config */\n isSystem?: boolean;\n}\n\nexport type AnthropicThreadManagerHooks = ThreadManagerHooks<\n StoredMessage,\n Anthropic.Messages.MessageParam\n>;\n\nexport interface AnthropicThreadManagerConfig {\n redis: Redis;\n threadId: string;\n /** Thread key, defaults to 'messages' */\n key?: string;\n hooks?: AnthropicThreadManagerHooks;\n}\n\n/** Prepared payload ready to send to the Anthropic API */\nexport interface AnthropicInvocationPayload {\n messages: Anthropic.Messages.MessageParam[];\n system?: string | Anthropic.Messages.TextBlockParam[];\n}\n\n/** Thread manager with Anthropic MessageParam convenience helpers */\nexport interface AnthropicThreadManager extends ProviderThreadManager<\n StoredMessage,\n AnthropicContent,\n JsonValue,\n AnthropicSystemContent\n> {\n appendAssistantMessage(\n id: string,\n content: Anthropic.Messages.ContentBlock[]\n ): Promise<void>;\n prepareForInvocation(): Promise<AnthropicInvocationPayload>;\n}\n\nfunction storedMessageId(msg: StoredMessage): string {\n return msg.id;\n}\n\n/** Normalise content into an array of ContentBlockParam */\nfunction toContentBlocks(\n content: AnthropicContent\n): Anthropic.Messages.ContentBlockParam[] {\n if (typeof content === \"string\") {\n return [{ type: \"text\", text: content }];\n }\n return content;\n}\n\n/**\n * Merge consecutive messages with the same role.\n * The Anthropic API requires alternating user/assistant turns; without\n * merging, multiple sequential tool-result messages would violate this.\n */\nfunction mergeConsecutiveMessages(\n messages: Anthropic.Messages.MessageParam[]\n): Anthropic.Messages.MessageParam[] {\n const merged: Anthropic.Messages.MessageParam[] = [];\n for (const msg of messages) {\n const last = merged[merged.length - 1];\n if (last && last.role === msg.role) {\n const lastContent = Array.isArray(last.content)\n ? last.content\n : [{ type: \"text\" as const, text: last.content }];\n const msgContent = Array.isArray(msg.content)\n ? msg.content\n : [{ type: \"text\" as const, text: msg.content }];\n last.content = [...lastContent, ...msgContent];\n } else {\n merged.push({\n ...msg,\n content: Array.isArray(msg.content) ? [...msg.content] : msg.content,\n });\n }\n }\n return merged;\n}\n\n/**\n * Creates an Anthropic-specific thread manager that stores StoredMessage\n * instances in Redis and provides convenience helpers for creating and\n * appending typed messages.\n */\nexport function createAnthropicThreadManager(\n config: AnthropicThreadManagerConfig\n): AnthropicThreadManager {\n const baseConfig: ThreadManagerConfig<StoredMessage> = {\n redis: config.redis,\n threadId: config.threadId,\n key: config.key,\n idOf: storedMessageId,\n };\n\n const base = createThreadManager(baseConfig);\n\n const helpers: Omit<AnthropicThreadManager, keyof typeof base> = {\n async appendUserMessage(\n id: string,\n content: AnthropicContent\n ): Promise<void> {\n await base.append([\n {\n id,\n message: { role: \"user\", content: toContentBlocks(content) },\n },\n ]);\n },\n\n async appendSystemMessage(\n id: string,\n content: AnthropicSystemContent\n ): Promise<void> {\n await base.initialize();\n await base.append([\n {\n id,\n // Stored under a user-role placeholder to satisfy the MessageParam\n // shape; the `isSystem` flag steers extraction in prepareForInvocation.\n message: {\n role: \"user\",\n content: content as Anthropic.Messages.MessageParam[\"content\"],\n },\n isSystem: true,\n },\n ]);\n },\n\n async appendAssistantMessage(\n id: string,\n content: Anthropic.Messages.ContentBlock[]\n ): Promise<void> {\n await base.append([\n {\n id,\n message: {\n role: \"assistant\",\n content:\n content as unknown as Anthropic.Messages.ContentBlockParam[],\n },\n },\n ]);\n },\n\n async appendToolResult(\n id: string,\n toolCallId: string,\n _toolName: string,\n content: JsonValue\n ): Promise<void> {\n const toolContent =\n typeof content === \"string\"\n ? content\n : Array.isArray(content)\n ? (content as unknown as Anthropic.Messages.ToolResultBlockParam[\"content\"])\n : JSON.stringify(content);\n await base.append([\n {\n id,\n message: {\n role: \"user\",\n content: [\n {\n type: \"tool_result\" as const,\n tool_use_id: toolCallId,\n content: toolContent,\n },\n ],\n },\n },\n ]);\n },\n\n async prepareForInvocation(): Promise<AnthropicInvocationPayload> {\n const stored = await base.load();\n const { onPrepareMessage, onPreparedMessage } = config.hooks ?? {};\n const mapped = onPrepareMessage\n ? stored.map((msg, i) => onPrepareMessage(msg, i, stored))\n : stored;\n\n let system: string | Anthropic.Messages.TextBlockParam[] | undefined;\n const conversationMessages: Anthropic.Messages.MessageParam[] = [];\n\n for (const item of mapped) {\n if (item.isSystem) {\n system = item.message.content as\n | string\n | Anthropic.Messages.TextBlockParam[];\n } else {\n conversationMessages.push(item.message);\n }\n }\n\n const messages = mergeConsecutiveMessages(conversationMessages);\n return {\n messages: onPreparedMessage\n ? messages.map((msg, i) => onPreparedMessage(msg, i, messages))\n : messages,\n ...(system ? { system } : {}),\n };\n },\n };\n\n const manager = Object.assign(base, helpers);\n\n const originalFork = manager.fork.bind(manager);\n manager.fork = async (\n newThreadId: string\n ): Promise<AnthropicThreadManager> => {\n await originalFork(newThreadId);\n const forked = createAnthropicThreadManager({\n ...config,\n threadId: newThreadId,\n });\n const { onForkPrepareThread, onForkTransform } = config.hooks ?? {};\n if (!onForkPrepareThread && !onForkTransform) {\n return forked;\n }\n let next = await forked.load();\n if (onForkPrepareThread) {\n next = await onForkPrepareThread(next);\n }\n if (onForkTransform) {\n next = next.map((msg, i) => onForkTransform(msg, i, next));\n }\n await forked.replaceAll(next);\n return forked;\n };\n\n return manager;\n}\n","import { 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 Anthropic from \"@anthropic-ai/sdk\";\nimport type { SerializableToolDefinition } from \"../../../lib/types\";\nimport type { AgentResponse, ModelInvokerConfig } from \"../../../lib/model\";\nimport {\n createAnthropicThreadManager,\n type AnthropicThreadManagerHooks,\n} from \"./thread-manager\";\nimport { getActivityContext } from \"../../../lib/activity\";\n\nexport interface AnthropicModelInvokerConfig {\n redis: Redis;\n client: Anthropic;\n model: string;\n /** Maximum tokens to generate. Defaults to 16384. */\n maxTokens?: number;\n hooks?: AnthropicThreadManagerHooks;\n}\n\nfunction toAnthropicTools(\n tools: SerializableToolDefinition[]\n): Anthropic.Messages.Tool[] {\n return tools.map((t) => ({\n name: t.name,\n description: t.description,\n input_schema: t.schema as Anthropic.Messages.Tool.InputSchema,\n }));\n}\n\n/**\n * Creates an Anthropic model invoker that satisfies the generic\n * `ModelInvoker<Anthropic.Messages.Message>` contract.\n *\n * Internally streams the response and emits Temporal heartbeats on each\n * event so that long-running LLM calls remain visible to the scheduler.\n * The caller is responsible for appending the response to the thread.\n *\n * @example\n * ```typescript\n * import { createAnthropicModelInvoker } from 'zeitlich/adapters/thread/anthropic';\n * import { createRunAgentActivity } from 'zeitlich';\n * import Anthropic from '@anthropic-ai/sdk';\n *\n * const client = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY });\n * const invoker = createAnthropicModelInvoker({\n * redis,\n * client,\n * model: 'claude-sonnet-4-20250514',\n * });\n *\n * return { ...createRunAgentActivity(client, invoker, \"myAgent\") };\n * ```\n */\nexport function createAnthropicModelInvoker({\n redis,\n client,\n model,\n maxTokens = 16384,\n hooks,\n}: AnthropicModelInvokerConfig) {\n return async function invokeAnthropicModel(\n config: ModelInvokerConfig\n ): Promise<AgentResponse<Anthropic.Messages.Message>> {\n const { threadId, threadKey, state, assistantMessageId } = config;\n const { heartbeat, signal } = getActivityContext();\n\n const thread = createAnthropicThreadManager({\n redis,\n threadId,\n key: threadKey,\n hooks,\n });\n // Truncate the thread starting at the id the assistant message\n // will be stored under. On the happy path this is a no-op; on a\n // rewind retry or a Temporal workflow reset it wipes the prior\n // attempt's assistant + tool results so the LLM sees the same\n // pre-call state that it saw originally.\n await thread.truncateFromId(assistantMessageId);\n const { messages, system } = await thread.prepareForInvocation();\n\n const anthropicTools = toAnthropicTools(state.tools);\n const tools = anthropicTools.length > 0 ? anthropicTools : undefined;\n\n const params: Anthropic.MessageCreateParams = {\n model,\n max_tokens: maxTokens,\n messages,\n ...(system ? { system } : {}),\n ...(tools ? { tools } : {}),\n };\n\n const stream = client.messages.stream(params, { signal });\n\n for await (const _event of stream) {\n heartbeat?.();\n }\n\n const response: Anthropic.Messages.Message = await stream.finalMessage();\n\n const toolCalls = response.content.filter(\n (block): block is Anthropic.Messages.ToolUseBlock =>\n block.type === \"tool_use\"\n );\n\n return {\n message: response,\n rawToolCalls: toolCalls.map((tc) => ({\n id: tc.id,\n name: tc.name,\n args: (tc.input as Record<string, unknown>) ?? {},\n })),\n usage: {\n inputTokens: response.usage.input_tokens,\n outputTokens: response.usage.output_tokens,\n cachedWriteTokens:\n response.usage.cache_creation_input_tokens ?? undefined,\n cachedReadTokens: response.usage.cache_read_input_tokens ?? undefined,\n },\n };\n };\n}\n\n/**\n * Standalone function for one-shot Anthropic model invocation.\n * Convenience wrapper around createAnthropicModelInvoker for cases\n * where you don't need to reuse the invoker.\n */\nexport async function invokeAnthropicModel({\n redis,\n client,\n model,\n maxTokens,\n hooks,\n config,\n}: {\n redis: Redis;\n client: Anthropic;\n model: string;\n maxTokens?: number;\n hooks?: AnthropicThreadManagerHooks;\n config: ModelInvokerConfig;\n}): Promise<AgentResponse<Anthropic.Messages.Message>> {\n const invoker = createAnthropicModelInvoker({\n redis,\n client,\n model,\n maxTokens,\n hooks,\n });\n return invoker(config);\n}\n","import type Redis from \"ioredis\";\nimport type Anthropic from \"@anthropic-ai/sdk\";\nimport type { ToolResultConfig } from \"../../../lib/types\";\nimport type { PersistedThreadState } from \"../../../lib/state/types\";\nimport type {\n ActivityToolHandler,\n RouterContext,\n ToolHandlerResponse,\n} from \"../../../lib/tool-router/types\";\nimport type {\n ThreadOps,\n PrefixedThreadOps,\n ScopedPrefix,\n} from \"../../../lib/session/types\";\nimport type { ModelInvoker } from \"../../../lib/model\";\nimport {\n createAnthropicThreadManager,\n type AnthropicContent,\n type AnthropicSystemContent,\n type AnthropicThreadManagerHooks,\n} from \"./thread-manager\";\nimport {\n createAnthropicModelInvoker,\n type AnthropicModelInvokerConfig,\n} from \"./model-invoker\";\nimport { ADAPTER_ID } from \"./adapter-id\";\n\nexport type AnthropicThreadOps<TScope extends string = \"\"> = PrefixedThreadOps<\n ScopedPrefix<TScope, typeof ADAPTER_ID>,\n AnthropicContent\n>;\n\nexport interface AnthropicAdapterConfig {\n redis: Redis;\n client: Anthropic;\n /** Default model name (e.g. 'claude-sonnet-4-20250514'). If omitted, use `createModelInvoker()` */\n model?: string;\n /** Maximum tokens to generate. Defaults to 16384. */\n maxTokens?: number;\n hooks?: AnthropicThreadManagerHooks;\n}\n\n/**\n * Tool response type accepted by the Anthropic adapter.\n *\n * Handlers can return:\n * - **`string`** — plain text content for the tool result.\n * - **`Anthropic.Messages.ToolResultBlockParam[\"content\"]`** — array of content blocks\n * (e.g. `{ type: \"text\", text: \"...\" }`, `{ type: \"image\", source: { ... } }`).\n * Passed through as-is to the `tool_result` block.\n */\nexport type AnthropicToolResponse =\n Anthropic.Messages.ToolResultBlockParam[\"content\"];\n\nexport interface AnthropicAdapter {\n /** Model invoker using the default model (only available when `model` was provided) */\n invoker: ModelInvoker<Anthropic.Messages.Message>;\n /** Create an invoker for a specific model name (for multi-model setups) */\n createModelInvoker(\n model: string,\n maxTokens?: number\n ): ModelInvoker<Anthropic.Messages.Message>;\n /**\n * Create prefixed thread activities for registration on the worker.\n *\n * @param scope - Workflow name appended to the adapter prefix.\n * Use different scopes for the main agent vs subagents to avoid collisions.\n *\n * @example\n * ```typescript\n * adapter.createActivities(\"codingAgent\")\n * // → { anthropicCodingAgentInitializeThread, anthropicCodingAgentAppendHumanMessage, … }\n *\n * adapter.createActivities(\"researchAgent\")\n * // → { anthropicResearchAgentInitializeThread, … }\n * ```\n */\n createActivities<S extends string = \"\">(scope?: S): AnthropicThreadOps<S>;\n\n /**\n * Identity wrapper that types a tool handler for this adapter.\n * Constrains `toolResponse` to {@link AnthropicToolResponse}.\n */\n wrapHandler<TArgs, TResult, TContext extends RouterContext = RouterContext>(\n handler: (\n args: TArgs,\n context: TContext\n ) => Promise<ToolHandlerResponse<TResult, AnthropicToolResponse>>\n ): ActivityToolHandler<TArgs, TResult, TContext, AnthropicToolResponse>;\n}\n\n/**\n * Creates an Anthropic adapter that bundles thread operations and model\n * invocation using the `@anthropic-ai/sdk`.\n *\n * Use `createActivities(scope)` to register scoped thread operations as\n * Temporal activities on the worker. The `invoker` (or invokers created via\n * `createModelInvoker`) should be wrapped with `createRunAgentActivity`.\n *\n * @example\n * ```typescript\n * import { createAnthropicAdapter } from 'zeitlich/adapters/thread/anthropic';\n * import { createRunAgentActivity } from 'zeitlich';\n * import Anthropic from '@anthropic-ai/sdk';\n *\n * const client = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY });\n * const adapter = createAnthropicAdapter({ redis, client, model: 'claude-sonnet-4-20250514' });\n *\n * export function createActivities(temporalClient: WorkflowClient) {\n * return {\n * ...adapter.createActivities(\"codingAgent\"),\n * ...createRunAgentActivity(temporalClient, adapter.invoker, \"codingAgent\"),\n * };\n * }\n * ```\n *\n * @example Multi-agent worker (main + subagent share the adapter)\n * ```typescript\n * export function createActivities(temporalClient: WorkflowClient) {\n * return {\n * ...adapter.createActivities(\"codingAgent\"),\n * ...adapter.createActivities(\"researchAgent\"),\n * ...createRunAgentActivity(temporalClient, adapter.invoker, \"codingAgent\"),\n * ...createRunAgentActivity(\n * temporalClient,\n * adapter.createModelInvoker('claude-sonnet-4-20250514'),\n * \"researchAgent\",\n * ),\n * };\n * }\n * ```\n */\nexport function createAnthropicAdapter(\n config: AnthropicAdapterConfig\n): AnthropicAdapter {\n const { redis, client } = config;\n\n const threadOps: ThreadOps<AnthropicContent> = {\n async initializeThread(\n threadId: string,\n threadKey?: string\n ): Promise<void> {\n const thread = createAnthropicThreadManager({\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: AnthropicContent,\n threadKey?: string\n ): Promise<void> {\n const thread = createAnthropicThreadManager({\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: AnthropicSystemContent,\n threadKey?: string\n ): Promise<void> {\n const thread = createAnthropicThreadManager({\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, toolName, content } = cfg;\n const thread = createAnthropicThreadManager({\n redis,\n threadId,\n key: threadKey,\n });\n await thread.appendToolResult(id, toolCallId, toolName, content);\n },\n\n async appendAgentMessage(\n threadId: string,\n id: string,\n message: Anthropic.Messages.Message,\n threadKey?: string\n ): Promise<void> {\n const thread = createAnthropicThreadManager({\n redis,\n threadId,\n key: threadKey,\n });\n await thread.appendAssistantMessage(id, message.content);\n },\n\n async forkThread(\n sourceThreadId: string,\n targetThreadId: string,\n threadKey?: string\n ): Promise<void> {\n const thread = createAnthropicThreadManager({\n redis,\n threadId: sourceThreadId,\n key: threadKey,\n hooks: config.hooks,\n });\n await thread.fork(targetThreadId);\n },\n\n async truncateThread(\n threadId: string,\n messageId: string,\n threadKey?: string,\n ): Promise<void> {\n const thread = createAnthropicThreadManager({ redis, threadId, key: threadKey });\n await thread.truncateFromId(messageId);\n },\n\n async loadThreadState(\n threadId: string,\n threadKey?: string\n ): Promise<PersistedThreadState | null> {\n const thread = createAnthropicThreadManager({\n redis,\n threadId,\n key: threadKey,\n });\n return thread.loadState();\n },\n\n async saveThreadState(\n threadId: string,\n state: PersistedThreadState,\n threadKey?: string\n ): Promise<void> {\n const thread = createAnthropicThreadManager({\n redis,\n threadId,\n key: threadKey,\n });\n await thread.saveState(state);\n },\n };\n\n function createActivities<S extends string = \"\">(\n scope?: S\n ): AnthropicThreadOps<S> {\n const prefix = scope\n ? `${ADAPTER_ID}${scope.charAt(0).toUpperCase()}${scope.slice(1)}`\n : ADAPTER_ID;\n const cap = (s: string): string => s.charAt(0).toUpperCase() + s.slice(1);\n return Object.fromEntries(\n Object.entries(threadOps).map(([k, v]) => [`${prefix}${cap(k)}`, v])\n ) as AnthropicThreadOps<S>;\n }\n\n const makeInvoker = (\n model: string,\n maxTokens?: number\n ): ModelInvoker<Anthropic.Messages.Message> => {\n const invokerConfig: AnthropicModelInvokerConfig = {\n redis,\n client,\n model,\n ...(maxTokens !== undefined ? { maxTokens } : {}),\n ...(config.maxTokens !== undefined && maxTokens === undefined\n ? { maxTokens: config.maxTokens }\n : {}),\n hooks: config.hooks,\n };\n return createAnthropicModelInvoker(invokerConfig);\n };\n\n const invoker: ModelInvoker<Anthropic.Messages.Message> = config.model\n ? makeInvoker(config.model)\n : ((() => {\n throw new Error(\n \"No default model provided to createAnthropicAdapter. \" +\n \"Either pass `model` in the config or use `createModelInvoker(model)` instead.\"\n );\n }) as unknown as ModelInvoker<Anthropic.Messages.Message>);\n\n return {\n createActivities,\n invoker,\n createModelInvoker: makeInvoker,\n wrapHandler: (handler) => handler,\n };\n}\n"]}
@@ -1,17 +1,18 @@
1
+ import { A as ADAPTER_ID } from '../../../adapter-id-CMwVrVqv.cjs';
2
+ export { a as AdapterId } from '../../../adapter-id-CMwVrVqv.cjs';
1
3
  import Redis from 'ioredis';
2
4
  import Anthropic from '@anthropic-ai/sdk';
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
- import { A as AnthropicContent, a as AnthropicThreadManagerHooks } from '../../../thread-manager-HSwyh28L.cjs';
5
- export { b as AnthropicInvocationPayload, c as AnthropicThreadManager, d as AnthropicThreadManagerConfig, S as StoredMessage, e as createAnthropicThreadManager } from '../../../thread-manager-HSwyh28L.cjs';
5
+ import { a as ModelInvoker, b as PrefixedThreadOps, S as ScopedPrefix, R as RouterContext, c as ToolHandlerResponse, d as ActivityToolHandler, M as ModelInvokerConfig, A as AgentResponse } from '../../../types-Cn2r3ol3.cjs';
6
+ import { A as AnthropicContent, a as AnthropicThreadManagerHooks } from '../../../thread-manager-DF8WuCRs.cjs';
7
+ export { b as AnthropicInvocationPayload, c as AnthropicThreadManager, d as AnthropicThreadManagerConfig, S as StoredMessage, e as createAnthropicThreadManager } from '../../../thread-manager-DF8WuCRs.cjs';
6
8
  import '@temporalio/common';
7
9
  import '@temporalio/workflow';
8
10
  import '@temporalio/common/lib/interfaces';
9
11
  import 'zod';
10
12
  import '../../../types-yx0LzPGn.cjs';
11
- import '../../../types-BaOw4hKI.cjs';
13
+ import '../../../types-CuISs0Ub.cjs';
12
14
 
13
- declare const ADAPTER_PREFIX: "anthropic";
14
- type AnthropicThreadOps<TScope extends string = ""> = PrefixedThreadOps<ScopedPrefix<TScope, typeof ADAPTER_PREFIX>, AnthropicContent>;
15
+ type AnthropicThreadOps<TScope extends string = ""> = PrefixedThreadOps<ScopedPrefix<TScope, typeof ADAPTER_ID>, AnthropicContent>;
15
16
  interface AnthropicAdapterConfig {
16
17
  redis: Redis;
17
18
  client: Anthropic;
@@ -148,4 +149,4 @@ declare function invokeAnthropicModel({ redis, client, model, maxTokens, hooks,
148
149
  config: ModelInvokerConfig;
149
150
  }): Promise<AgentResponse<Anthropic.Messages.Message>>;
150
151
 
151
- export { type AnthropicAdapter, type AnthropicAdapterConfig, AnthropicContent, type AnthropicModelInvokerConfig, type AnthropicThreadOps, type AnthropicToolResponse, createAnthropicAdapter, createAnthropicModelInvoker, invokeAnthropicModel };
152
+ export { ADAPTER_ID, type AnthropicAdapter, type AnthropicAdapterConfig, AnthropicContent, type AnthropicModelInvokerConfig, type AnthropicThreadOps, type AnthropicToolResponse, createAnthropicAdapter, createAnthropicModelInvoker, invokeAnthropicModel };
@@ -1,17 +1,18 @@
1
+ import { A as ADAPTER_ID } from '../../../adapter-id-CMwVrVqv.js';
2
+ export { a as AdapterId } from '../../../adapter-id-CMwVrVqv.js';
1
3
  import Redis from 'ioredis';
2
4
  import Anthropic from '@anthropic-ai/sdk';
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
- import { A as AnthropicContent, a as AnthropicThreadManagerHooks } from '../../../thread-manager-CVu7o2cs.js';
5
- export { b as AnthropicInvocationPayload, c as AnthropicThreadManager, d as AnthropicThreadManagerConfig, S as StoredMessage, e as createAnthropicThreadManager } from '../../../thread-manager-CVu7o2cs.js';
5
+ import { a as ModelInvoker, b as PrefixedThreadOps, S as ScopedPrefix, R as RouterContext, c as ToolHandlerResponse, d as ActivityToolHandler, M as ModelInvokerConfig, A as AgentResponse } from '../../../types-DeQH84C_.js';
6
+ import { A as AnthropicContent, a as AnthropicThreadManagerHooks } from '../../../thread-manager-BNiIt5r8.js';
7
+ export { b as AnthropicInvocationPayload, c as AnthropicThreadManager, d as AnthropicThreadManagerConfig, S as StoredMessage, e as createAnthropicThreadManager } from '../../../thread-manager-BNiIt5r8.js';
6
8
  import '@temporalio/common';
7
9
  import '@temporalio/workflow';
8
10
  import '@temporalio/common/lib/interfaces';
9
11
  import 'zod';
10
12
  import '../../../types-yx0LzPGn.js';
11
- import '../../../types-BH_IRryz.js';
13
+ import '../../../types-C7OoY7h8.js';
12
14
 
13
- declare const ADAPTER_PREFIX: "anthropic";
14
- type AnthropicThreadOps<TScope extends string = ""> = PrefixedThreadOps<ScopedPrefix<TScope, typeof ADAPTER_PREFIX>, AnthropicContent>;
15
+ type AnthropicThreadOps<TScope extends string = ""> = PrefixedThreadOps<ScopedPrefix<TScope, typeof ADAPTER_ID>, AnthropicContent>;
15
16
  interface AnthropicAdapterConfig {
16
17
  redis: Redis;
17
18
  client: Anthropic;
@@ -148,4 +149,4 @@ declare function invokeAnthropicModel({ redis, client, model, maxTokens, hooks,
148
149
  config: ModelInvokerConfig;
149
150
  }): Promise<AgentResponse<Anthropic.Messages.Message>>;
150
151
 
151
- export { type AnthropicAdapter, type AnthropicAdapterConfig, AnthropicContent, type AnthropicModelInvokerConfig, type AnthropicThreadOps, type AnthropicToolResponse, createAnthropicAdapter, createAnthropicModelInvoker, invokeAnthropicModel };
152
+ export { ADAPTER_ID, type AnthropicAdapter, type AnthropicAdapterConfig, AnthropicContent, type AnthropicModelInvokerConfig, type AnthropicThreadOps, type AnthropicToolResponse, createAnthropicAdapter, createAnthropicModelInvoker, invokeAnthropicModel };
@@ -1,7 +1,21 @@
1
1
  import { Context } from '@temporalio/activity';
2
2
 
3
- // src/lib/thread/manager.ts
3
+ // src/adapters/thread/anthropic/adapter-id.ts
4
+ var ADAPTER_ID = "anthropic";
5
+
6
+ // src/lib/thread/keys.ts
4
7
  var THREAD_TTL_SECONDS = 60 * 60 * 24 * 90;
8
+ function getThreadListKey(threadKey, threadId) {
9
+ return `${threadKey}:thread:${threadId}`;
10
+ }
11
+ function getThreadMetaKey(threadKey, threadId) {
12
+ return `${threadKey}:meta:thread:${threadId}`;
13
+ }
14
+ function getThreadStateKey(threadKey, threadId) {
15
+ return `${threadKey}:state:thread:${threadId}`;
16
+ }
17
+
18
+ // src/lib/thread/manager.ts
5
19
  var APPEND_IDEMPOTENT_SCRIPT = `
6
20
  if redis.call('EXISTS', KEYS[1]) == 1 then
7
21
  return 0
@@ -13,8 +27,8 @@ redis.call('EXPIRE', KEYS[2], tonumber(ARGV[1]))
13
27
  redis.call('SET', KEYS[1], '1', 'EX', tonumber(ARGV[1]))
14
28
  return 1
15
29
  `;
16
- function getThreadKey(threadId, key) {
17
- return `${key}:thread:${threadId}`;
30
+ function getDedupKey(threadId, id) {
31
+ return `dedup:${id}:thread:${threadId}`;
18
32
  }
19
33
  function createThreadManager(config) {
20
34
  const {
@@ -25,8 +39,9 @@ function createThreadManager(config) {
25
39
  deserialize = (raw) => JSON.parse(raw),
26
40
  idOf
27
41
  } = config;
28
- const redisKey = getThreadKey(threadId, key);
29
- const metaKey = getThreadKey(threadId, `${key}:meta`);
42
+ const redisKey = getThreadListKey(key, threadId);
43
+ const metaKey = getThreadMetaKey(key, threadId);
44
+ const stateKey = getThreadStateKey(key, threadId);
30
45
  async function assertThreadExists() {
31
46
  const exists = await redis.exists(metaKey);
32
47
  if (!exists) {
@@ -48,7 +63,7 @@ function createThreadManager(config) {
48
63
  await assertThreadExists();
49
64
  if (idOf) {
50
65
  const dedupId = messages.map(idOf).join(":");
51
- const dedupKey = getThreadKey(threadId, `dedup:${dedupId}`);
66
+ const dedupKey = getDedupKey(threadId, dedupId);
52
67
  await redis.eval(
53
68
  APPEND_IDEMPOTENT_SCRIPT,
54
69
  2,
@@ -65,34 +80,98 @@ function createThreadManager(config) {
65
80
  async fork(newThreadId) {
66
81
  await assertThreadExists();
67
82
  const data = await redis.lrange(redisKey, 0, -1);
83
+ const stateRaw = await redis.get(stateKey);
68
84
  const forked = createThreadManager({
69
85
  ...config,
70
86
  threadId: newThreadId
71
87
  });
72
88
  await forked.initialize();
73
89
  if (data.length > 0) {
74
- const newKey = getThreadKey(newThreadId, key);
90
+ const newKey = getThreadListKey(key, newThreadId);
75
91
  await redis.rpush(newKey, ...data);
76
92
  await redis.expire(newKey, THREAD_TTL_SECONDS);
77
93
  }
94
+ if (stateRaw != null) {
95
+ const newStateKey = getThreadStateKey(key, newThreadId);
96
+ await redis.set(newStateKey, stateRaw, "EX", THREAD_TTL_SECONDS);
97
+ }
78
98
  return forked;
79
99
  },
100
+ async replaceAll(messages) {
101
+ await assertThreadExists();
102
+ if (!idOf) {
103
+ throw new Error(
104
+ "replaceAll requires the thread manager to be configured with `idOf`"
105
+ );
106
+ }
107
+ const existing = await redis.lrange(redisKey, 0, -1);
108
+ const existingIds = existing.map((raw) => idOf(deserialize(raw))).filter((id) => typeof id === "string");
109
+ await redis.del(redisKey);
110
+ if (existingIds.length > 0) {
111
+ await redis.del(
112
+ ...existingIds.map((id) => getDedupKey(threadId, id))
113
+ );
114
+ }
115
+ if (messages.length > 0) {
116
+ await redis.rpush(redisKey, ...messages.map(serialize));
117
+ await redis.expire(redisKey, THREAD_TTL_SECONDS);
118
+ }
119
+ await redis.expire(metaKey, THREAD_TTL_SECONDS);
120
+ },
80
121
  async delete() {
81
- await redis.del(redisKey, metaKey);
122
+ await redis.del(redisKey, metaKey, stateKey);
123
+ },
124
+ async loadState() {
125
+ const raw = await redis.get(stateKey);
126
+ if (raw == null) return null;
127
+ return JSON.parse(raw);
128
+ },
129
+ async saveState(state) {
130
+ await assertThreadExists();
131
+ await redis.set(
132
+ stateKey,
133
+ JSON.stringify(state),
134
+ "EX",
135
+ THREAD_TTL_SECONDS
136
+ );
137
+ },
138
+ async deleteState() {
139
+ await redis.del(stateKey);
82
140
  },
83
141
  async length() {
84
142
  await assertThreadExists();
85
143
  return redis.llen(redisKey);
86
144
  },
87
- async truncate(length) {
145
+ async truncateFromId(messageId) {
88
146
  await assertThreadExists();
89
- if (length <= 0) {
147
+ if (!idOf) {
148
+ throw new Error(
149
+ "truncateFromId requires the thread manager to be configured with `idOf`"
150
+ );
151
+ }
152
+ const data = await redis.lrange(redisKey, 0, -1);
153
+ let idx = -1;
154
+ const removedIds = [];
155
+ for (let i = 0; i < data.length; i++) {
156
+ const raw = data[i];
157
+ if (raw === void 0) continue;
158
+ const id = idOf(deserialize(raw));
159
+ if (idx === -1 && id === messageId) idx = i;
160
+ if (idx !== -1) removedIds.push(id);
161
+ }
162
+ if (idx === -1) return;
163
+ if (idx === 0) {
90
164
  await redis.del(redisKey);
91
165
  await redis.expire(metaKey, THREAD_TTL_SECONDS);
92
166
  } else {
93
- await redis.ltrim(redisKey, 0, length - 1);
167
+ await redis.ltrim(redisKey, 0, idx - 1);
94
168
  await redis.expire(redisKey, THREAD_TTL_SECONDS);
95
169
  }
170
+ if (removedIds.length > 0) {
171
+ await redis.del(
172
+ ...removedIds.map((id) => getDedupKey(threadId, id))
173
+ );
174
+ }
96
175
  }
97
176
  };
98
177
  }
@@ -201,12 +280,33 @@ function createAnthropicThreadManager(config) {
201
280
  const messages = mergeConsecutiveMessages(conversationMessages);
202
281
  return {
203
282
  messages: onPreparedMessage ? messages.map((msg, i) => onPreparedMessage(msg, i, messages)) : messages,
204
- ...system ? { system } : {},
205
- storedLength: stored.length
283
+ ...system ? { system } : {}
206
284
  };
207
285
  }
208
286
  };
209
- return Object.assign(base, helpers);
287
+ const manager = Object.assign(base, helpers);
288
+ const originalFork = manager.fork.bind(manager);
289
+ manager.fork = async (newThreadId) => {
290
+ await originalFork(newThreadId);
291
+ const forked = createAnthropicThreadManager({
292
+ ...config,
293
+ threadId: newThreadId
294
+ });
295
+ const { onForkPrepareThread, onForkTransform } = config.hooks ?? {};
296
+ if (!onForkPrepareThread && !onForkTransform) {
297
+ return forked;
298
+ }
299
+ let next = await forked.load();
300
+ if (onForkPrepareThread) {
301
+ next = await onForkPrepareThread(next);
302
+ }
303
+ if (onForkTransform) {
304
+ next = next.map((msg, i) => onForkTransform(msg, i, next));
305
+ }
306
+ await forked.replaceAll(next);
307
+ return forked;
308
+ };
309
+ return manager;
210
310
  }
211
311
  function getActivityContext() {
212
312
  try {
@@ -233,7 +333,7 @@ function createAnthropicModelInvoker({
233
333
  hooks
234
334
  }) {
235
335
  return async function invokeAnthropicModel2(config) {
236
- const { threadId, threadKey, state } = config;
336
+ const { threadId, threadKey, state, assistantMessageId } = config;
237
337
  const { heartbeat, signal } = getActivityContext();
238
338
  const thread = createAnthropicThreadManager({
239
339
  redis,
@@ -241,7 +341,8 @@ function createAnthropicModelInvoker({
241
341
  key: threadKey,
242
342
  hooks
243
343
  });
244
- const { messages, system, storedLength } = await thread.prepareForInvocation();
344
+ await thread.truncateFromId(assistantMessageId);
345
+ const { messages, system } = await thread.prepareForInvocation();
245
346
  const anthropicTools = toAnthropicTools(state.tools);
246
347
  const tools = anthropicTools.length > 0 ? anthropicTools : void 0;
247
348
  const params = {
@@ -271,8 +372,7 @@ function createAnthropicModelInvoker({
271
372
  outputTokens: response.usage.output_tokens,
272
373
  cachedWriteTokens: response.usage.cache_creation_input_tokens ?? void 0,
273
374
  cachedReadTokens: response.usage.cache_read_input_tokens ?? void 0
274
- },
275
- threadLengthAtCall: storedLength
375
+ }
276
376
  };
277
377
  };
278
378
  }
@@ -295,7 +395,6 @@ async function invokeAnthropicModel({
295
395
  }
296
396
 
297
397
  // src/adapters/thread/anthropic/activities.ts
298
- var ADAPTER_PREFIX = "anthropic";
299
398
  function createAnthropicAdapter(config) {
300
399
  const { redis, client } = config;
301
400
  const threadOps = {
@@ -344,17 +443,34 @@ function createAnthropicAdapter(config) {
344
443
  const thread = createAnthropicThreadManager({
345
444
  redis,
346
445
  threadId: sourceThreadId,
347
- key: threadKey
446
+ key: threadKey,
447
+ hooks: config.hooks
348
448
  });
349
449
  await thread.fork(targetThreadId);
350
450
  },
351
- async truncateThread(threadId, length, threadKey) {
451
+ async truncateThread(threadId, messageId, threadKey) {
352
452
  const thread = createAnthropicThreadManager({ redis, threadId, key: threadKey });
353
- await thread.truncate(length);
453
+ await thread.truncateFromId(messageId);
454
+ },
455
+ async loadThreadState(threadId, threadKey) {
456
+ const thread = createAnthropicThreadManager({
457
+ redis,
458
+ threadId,
459
+ key: threadKey
460
+ });
461
+ return thread.loadState();
462
+ },
463
+ async saveThreadState(threadId, state, threadKey) {
464
+ const thread = createAnthropicThreadManager({
465
+ redis,
466
+ threadId,
467
+ key: threadKey
468
+ });
469
+ await thread.saveState(state);
354
470
  }
355
471
  };
356
472
  function createActivities(scope) {
357
- const prefix = scope ? `${ADAPTER_PREFIX}${scope.charAt(0).toUpperCase()}${scope.slice(1)}` : ADAPTER_PREFIX;
473
+ const prefix = scope ? `${ADAPTER_ID}${scope.charAt(0).toUpperCase()}${scope.slice(1)}` : ADAPTER_ID;
358
474
  const cap = (s) => s.charAt(0).toUpperCase() + s.slice(1);
359
475
  return Object.fromEntries(
360
476
  Object.entries(threadOps).map(([k, v]) => [`${prefix}${cap(k)}`, v])
@@ -384,6 +500,6 @@ function createAnthropicAdapter(config) {
384
500
  };
385
501
  }
386
502
 
387
- export { createAnthropicAdapter, createAnthropicModelInvoker, createAnthropicThreadManager, invokeAnthropicModel };
503
+ export { ADAPTER_ID, createAnthropicAdapter, createAnthropicModelInvoker, createAnthropicThreadManager, invokeAnthropicModel };
388
504
  //# sourceMappingURL=index.js.map
389
505
  //# sourceMappingURL=index.js.map