zeitlich 0.2.38 → 0.2.39

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-Bmu7XnaG.d.ts} +4 -6
  3. package/dist/{activities-CDcwkRZs.d.cts → activities-ByBFLvm2.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 +266 -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 +263 -49
  57. package/dist/index.js.map +1 -1
  58. package/dist/{proxy-D_3x7RN4.d.cts → proxy-BAKzNGRq.d.cts} +1 -1
  59. package/dist/{proxy-CUlKSvZS.d.ts → proxy-DO_MXbY4.d.ts} +1 -1
  60. package/dist/{thread-manager-CVu7o2cs.d.ts → thread-manager-CcRXasqs.d.ts} +2 -4
  61. package/dist/{thread-manager-HSwyh28L.d.cts → thread-manager-ClwSaUnj.d.cts} +2 -4
  62. package/dist/{thread-manager-c1gPopAG.d.ts → thread-manager-D-7lp1JK.d.ts} +2 -4
  63. package/dist/{thread-manager-wGi-LqIP.d.cts → thread-manager-Y8Ucf0Tf.d.cts} +2 -4
  64. package/dist/{types-C06FwR96.d.cts → types-Bcbiq8iv.d.cts} +162 -44
  65. package/dist/{types-BH_IRryz.d.ts → types-DpHTX-iO.d.ts} +54 -6
  66. package/dist/{types-DNr31FzL.d.ts → types-Dt8-HBBT.d.ts} +162 -44
  67. package/dist/{types-BaOw4hKI.d.cts → types-hFFi-Zd9.d.cts} +54 -6
  68. package/dist/{workflow-CSCkpwAL.d.ts → workflow-Bmf9EtDW.d.ts} +82 -2
  69. package/dist/{workflow-DuvMZ8Vm.d.cts → workflow-Bx9utBwb.d.cts} +82 -2
  70. package/dist/workflow.cjs +188 -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 +185 -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 +68 -28
  105. package/src/lib/session/types.ts +60 -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/proxy.ts","../../../../src/adapters/thread/google-genai/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,GAAS,CAAA,EAAG,aAAa,CAAA,EAAG,cAAc,MAAA,CAAO,CAAC,CAAA,CAAE,WAAA,EAAa,CAAA,EAAG,aAAA,CAAc,KAAA,CAAM,CAAC,CAAC,CAAA,CAAA;AAChG,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,CAAA;AAAA,IAChC,cAAA,EAAgB,IAAA,CAAK,CAAA,CAAE,gBAAgB,CAAC;AAAA,GAC1C;AACF;;;AChCA,IAAM,cAAA,GAAiB,aAAA;AAEhB,SAAS,yBAAA,CACd,OACA,OAAA,EACqD;AACrD,EAAA,OAAO,oBAAA;AAAA,IACL,cAAA;AAAA,IACA,KAAA;AAAA,IACA;AAAA,GACF;AACF","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 = `${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 truncateThread: acts[p(\"truncateThread\")],\n } as ActivityInterfaceFor<ThreadOps>;\n}\n","/**\n * Workflow-safe proxy for Google GenAI thread operations.\n *\n * Import this from `zeitlich/adapters/thread/google-genai/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 { proxyGoogleGenAIThreadOps } from 'zeitlich/adapters/thread/google-genai/workflow';\n *\n * // Auto-scoped to the current workflow name\n * const threadOps = proxyGoogleGenAIThreadOps();\n *\n * // Explicit scope override\n * const threadOps = proxyGoogleGenAIThreadOps(\"customScope\");\n * ```\n */\nimport { type ActivityInterfaceFor } from \"@temporalio/workflow\";\nimport type { ThreadOps } from \"../../../lib/session/types\";\nimport type { GoogleGenAIContent } from \"./thread-manager\";\nimport { createThreadOpsProxy } from \"../../../lib/thread/proxy\";\n\nconst ADAPTER_PREFIX = \"googleGenAI\";\n\nexport function proxyGoogleGenAIThreadOps(\n scope?: string,\n options?: Parameters<typeof createThreadOpsProxy>[2]\n): ActivityInterfaceFor<ThreadOps<GoogleGenAIContent>> {\n return createThreadOpsProxy(\n ADAPTER_PREFIX,\n scope,\n options\n ) as ActivityInterfaceFor<ThreadOps<GoogleGenAIContent>>;\n}\n"]}
1
+ {"version":3,"sources":["../../../../src/lib/thread/proxy.ts","../../../../src/adapters/thread/google-genai/adapter-id.ts","../../../../src/adapters/thread/google-genai/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,GAAS,CAAA,EAAG,aAAa,CAAA,EAAG,cAAc,MAAA,CAAO,CAAC,CAAA,CAAE,WAAA,EAAa,CAAA,EAAG,aAAA,CAAc,KAAA,CAAM,CAAC,CAAC,CAAA,CAAA;AAChG,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,CAAA;AAAA,IAChC,cAAA,EAAgB,IAAA,CAAK,CAAA,CAAE,gBAAgB,CAAC,CAAA;AAAA,IACxC,eAAA,EAAiB,IAAA,CAAK,CAAA,CAAE,iBAAiB,CAAC,CAAA;AAAA,IAC1C,eAAA,EAAiB,IAAA,CAAK,CAAA,CAAE,iBAAiB,CAAC;AAAA,GAC5C;AACF;;;AC/CO,IAAM,UAAA,GAAa;;;ACgBnB,SAAS,yBAAA,CACd,OACA,OAAA,EACqD;AACrD,EAAA,OAAO,oBAAA;AAAA,IACL,UAAA;AAAA,IACA,KAAA;AAAA,IACA;AAAA,GACF;AACF","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 = `${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 truncateThread: acts[p(\"truncateThread\")],\n loadThreadState: acts[p(\"loadThreadState\")],\n saveThreadState: acts[p(\"saveThreadState\")],\n } as ActivityInterfaceFor<ThreadOps>;\n}\n","/**\n * Public adapter identity for the Google GenAI thread adapter.\n *\n * This value is wire format — it appears as the prefix for Temporal\n * activity names (e.g. `googleGenAICodingAgentInitializeThread`) and\n * must never change, since renaming it would orphan existing persisted\n * threads and break in-flight workflows.\n *\n * Re-exported from `zeitlich/adapters/thread/google-genai` so downstream\n * consumers can use the exact same literal the adapter uses internally,\n * typed as the narrow string literal `\"googleGenAI\"`.\n */\nexport const ADAPTER_ID = \"googleGenAI\" as const;\n\n/** Narrow string-literal type for {@link ADAPTER_ID}. */\nexport type AdapterId = typeof ADAPTER_ID;\n","/**\n * Workflow-safe proxy for Google GenAI thread operations.\n *\n * Import this from `zeitlich/adapters/thread/google-genai/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 { proxyGoogleGenAIThreadOps } from 'zeitlich/adapters/thread/google-genai/workflow';\n *\n * // Auto-scoped to the current workflow name\n * const threadOps = proxyGoogleGenAIThreadOps();\n *\n * // Explicit scope override\n * const threadOps = proxyGoogleGenAIThreadOps(\"customScope\");\n * ```\n */\nimport { type ActivityInterfaceFor } from \"@temporalio/workflow\";\nimport type { ThreadOps } from \"../../../lib/session/types\";\nimport type { GoogleGenAIContent } from \"./thread-manager\";\nimport { createThreadOpsProxy } from \"../../../lib/thread/proxy\";\nimport { ADAPTER_ID } from \"./adapter-id\";\n\nexport { ADAPTER_ID, type AdapterId } from \"./adapter-id\";\n\nexport function proxyGoogleGenAIThreadOps(\n scope?: string,\n options?: Parameters<typeof createThreadOpsProxy>[2]\n): ActivityInterfaceFor<ThreadOps<GoogleGenAIContent>> {\n return createThreadOpsProxy(\n ADAPTER_ID,\n scope,\n options\n ) as ActivityInterfaceFor<ThreadOps<GoogleGenAIContent>>;\n}\n"]}
@@ -0,0 +1,16 @@
1
+ 'use strict';
2
+
3
+ // src/adapters/thread/langchain/adapter-id.ts
4
+ var ADAPTER_ID = "langChain";
5
+
6
+ // src/adapters/thread/google-genai/adapter-id.ts
7
+ var ADAPTER_ID2 = "googleGenAI";
8
+
9
+ // src/adapters/thread/anthropic/adapter-id.ts
10
+ var ADAPTER_ID3 = "anthropic";
11
+
12
+ exports.ANTHROPIC_ADAPTER_ID = ADAPTER_ID3;
13
+ exports.GOOGLE_GENAI_ADAPTER_ID = ADAPTER_ID2;
14
+ exports.LANGCHAIN_ADAPTER_ID = ADAPTER_ID;
15
+ //# sourceMappingURL=index.cjs.map
16
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/adapters/thread/langchain/adapter-id.ts","../../../src/adapters/thread/google-genai/adapter-id.ts","../../../src/adapters/thread/anthropic/adapter-id.ts"],"names":["ADAPTER_ID"],"mappings":";;;AAYO,IAAM,UAAA,GAAa;;;ACAnB,IAAMA,WAAAA,GAAa;;;ACAnB,IAAMA,WAAAA,GAAa","file":"index.cjs","sourcesContent":["/**\n * Public adapter identity for the LangChain thread adapter.\n *\n * This value is wire format — it appears as the prefix for Temporal\n * activity names (e.g. `langChainCodingAgentInitializeThread`) 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/langchain` so downstream\n * consumers can use the exact same literal the adapter uses internally,\n * typed as the narrow string literal `\"langChain\"`.\n */\nexport const ADAPTER_ID = \"langChain\" as const;\n\n/** Narrow string-literal type for {@link ADAPTER_ID}. */\nexport type AdapterId = typeof ADAPTER_ID;\n","/**\n * Public adapter identity for the Google GenAI thread adapter.\n *\n * This value is wire format — it appears as the prefix for Temporal\n * activity names (e.g. `googleGenAICodingAgentInitializeThread`) and\n * must never change, since renaming it would orphan existing persisted\n * threads and break in-flight workflows.\n *\n * Re-exported from `zeitlich/adapters/thread/google-genai` so downstream\n * consumers can use the exact same literal the adapter uses internally,\n * typed as the narrow string literal `\"googleGenAI\"`.\n */\nexport const ADAPTER_ID = \"googleGenAI\" as const;\n\n/** Narrow string-literal type for {@link ADAPTER_ID}. */\nexport type AdapterId = typeof ADAPTER_ID;\n","/**\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"]}
@@ -0,0 +1,34 @@
1
+ import { A as ADAPTER_ID } from '../../adapter-id-CbY2zeSt.cjs';
2
+ import { A as ADAPTER_ID$1 } from '../../adapter-id-BB-mmrts.cjs';
3
+ import { A as ADAPTER_ID$2 } from '../../adapter-id-CMwVrVqv.cjs';
4
+
5
+ /**
6
+ * Barrel re-exports for every built-in thread adapter's public identity.
7
+ *
8
+ * Downstream consumers reading persisted threads can import a narrow
9
+ * discriminated union of adapter identifiers without pulling the full
10
+ * adapter implementation (Redis, provider SDKs, etc.) as a dependency —
11
+ * each individual re-export resolves to an `adapter-id.ts` module with
12
+ * no runtime dependencies.
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * import {
17
+ * LANGCHAIN_ADAPTER_ID,
18
+ * GOOGLE_GENAI_ADAPTER_ID,
19
+ * ANTHROPIC_ADAPTER_ID,
20
+ * type ThreadAdapterId,
21
+ * } from 'zeitlich/adapters/thread';
22
+ *
23
+ * interface ThreadIdentity {
24
+ * adapter: ThreadAdapterId;
25
+ * threadKey: string;
26
+ * threadId: string;
27
+ * }
28
+ * ```
29
+ */
30
+
31
+ /** Narrow discriminated union of every built-in thread adapter id. */
32
+ type ThreadAdapterId = typeof ADAPTER_ID | typeof ADAPTER_ID$1 | typeof ADAPTER_ID$2;
33
+
34
+ export { ADAPTER_ID$2 as ANTHROPIC_ADAPTER_ID, ADAPTER_ID$1 as GOOGLE_GENAI_ADAPTER_ID, ADAPTER_ID as LANGCHAIN_ADAPTER_ID, type ThreadAdapterId };
@@ -0,0 +1,34 @@
1
+ import { A as ADAPTER_ID } from '../../adapter-id-CbY2zeSt.js';
2
+ import { A as ADAPTER_ID$1 } from '../../adapter-id-BB-mmrts.js';
3
+ import { A as ADAPTER_ID$2 } from '../../adapter-id-CMwVrVqv.js';
4
+
5
+ /**
6
+ * Barrel re-exports for every built-in thread adapter's public identity.
7
+ *
8
+ * Downstream consumers reading persisted threads can import a narrow
9
+ * discriminated union of adapter identifiers without pulling the full
10
+ * adapter implementation (Redis, provider SDKs, etc.) as a dependency —
11
+ * each individual re-export resolves to an `adapter-id.ts` module with
12
+ * no runtime dependencies.
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * import {
17
+ * LANGCHAIN_ADAPTER_ID,
18
+ * GOOGLE_GENAI_ADAPTER_ID,
19
+ * ANTHROPIC_ADAPTER_ID,
20
+ * type ThreadAdapterId,
21
+ * } from 'zeitlich/adapters/thread';
22
+ *
23
+ * interface ThreadIdentity {
24
+ * adapter: ThreadAdapterId;
25
+ * threadKey: string;
26
+ * threadId: string;
27
+ * }
28
+ * ```
29
+ */
30
+
31
+ /** Narrow discriminated union of every built-in thread adapter id. */
32
+ type ThreadAdapterId = typeof ADAPTER_ID | typeof ADAPTER_ID$1 | typeof ADAPTER_ID$2;
33
+
34
+ export { ADAPTER_ID$2 as ANTHROPIC_ADAPTER_ID, ADAPTER_ID$1 as GOOGLE_GENAI_ADAPTER_ID, ADAPTER_ID as LANGCHAIN_ADAPTER_ID, type ThreadAdapterId };
@@ -0,0 +1,12 @@
1
+ // src/adapters/thread/langchain/adapter-id.ts
2
+ var ADAPTER_ID = "langChain";
3
+
4
+ // src/adapters/thread/google-genai/adapter-id.ts
5
+ var ADAPTER_ID2 = "googleGenAI";
6
+
7
+ // src/adapters/thread/anthropic/adapter-id.ts
8
+ var ADAPTER_ID3 = "anthropic";
9
+
10
+ export { ADAPTER_ID3 as ANTHROPIC_ADAPTER_ID, ADAPTER_ID2 as GOOGLE_GENAI_ADAPTER_ID, ADAPTER_ID as LANGCHAIN_ADAPTER_ID };
11
+ //# sourceMappingURL=index.js.map
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/adapters/thread/langchain/adapter-id.ts","../../../src/adapters/thread/google-genai/adapter-id.ts","../../../src/adapters/thread/anthropic/adapter-id.ts"],"names":["ADAPTER_ID"],"mappings":";AAYO,IAAM,UAAA,GAAa;;;ACAnB,IAAMA,WAAAA,GAAa;;;ACAnB,IAAMA,WAAAA,GAAa","file":"index.js","sourcesContent":["/**\n * Public adapter identity for the LangChain thread adapter.\n *\n * This value is wire format — it appears as the prefix for Temporal\n * activity names (e.g. `langChainCodingAgentInitializeThread`) 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/langchain` so downstream\n * consumers can use the exact same literal the adapter uses internally,\n * typed as the narrow string literal `\"langChain\"`.\n */\nexport const ADAPTER_ID = \"langChain\" as const;\n\n/** Narrow string-literal type for {@link ADAPTER_ID}. */\nexport type AdapterId = typeof ADAPTER_ID;\n","/**\n * Public adapter identity for the Google GenAI thread adapter.\n *\n * This value is wire format — it appears as the prefix for Temporal\n * activity names (e.g. `googleGenAICodingAgentInitializeThread`) and\n * must never change, since renaming it would orphan existing persisted\n * threads and break in-flight workflows.\n *\n * Re-exported from `zeitlich/adapters/thread/google-genai` so downstream\n * consumers can use the exact same literal the adapter uses internally,\n * typed as the narrow string literal `\"googleGenAI\"`.\n */\nexport const ADAPTER_ID = \"googleGenAI\" as const;\n\n/** Narrow string-literal type for {@link ADAPTER_ID}. */\nexport type AdapterId = typeof ADAPTER_ID;\n","/**\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"]}
@@ -4,10 +4,22 @@ var messages = require('@langchain/core/messages');
4
4
  var crypto = require('crypto');
5
5
  var activity = require('@temporalio/activity');
6
6
 
7
- // src/adapters/thread/langchain/thread-manager.ts
7
+ // src/adapters/thread/langchain/adapter-id.ts
8
+ var ADAPTER_ID = "langChain";
8
9
 
9
- // src/lib/thread/manager.ts
10
+ // src/lib/thread/keys.ts
10
11
  var THREAD_TTL_SECONDS = 60 * 60 * 24 * 90;
12
+ function getThreadListKey(threadKey, threadId) {
13
+ return `${threadKey}:thread:${threadId}`;
14
+ }
15
+ function getThreadMetaKey(threadKey, threadId) {
16
+ return `${threadKey}:meta:thread:${threadId}`;
17
+ }
18
+ function getThreadStateKey(threadKey, threadId) {
19
+ return `${threadKey}:state:thread:${threadId}`;
20
+ }
21
+
22
+ // src/lib/thread/manager.ts
11
23
  var APPEND_IDEMPOTENT_SCRIPT = `
12
24
  if redis.call('EXISTS', KEYS[1]) == 1 then
13
25
  return 0
@@ -19,8 +31,8 @@ redis.call('EXPIRE', KEYS[2], tonumber(ARGV[1]))
19
31
  redis.call('SET', KEYS[1], '1', 'EX', tonumber(ARGV[1]))
20
32
  return 1
21
33
  `;
22
- function getThreadKey(threadId, key) {
23
- return `${key}:thread:${threadId}`;
34
+ function getDedupKey(threadId, id) {
35
+ return `dedup:${id}:thread:${threadId}`;
24
36
  }
25
37
  function createThreadManager(config) {
26
38
  const {
@@ -31,8 +43,9 @@ function createThreadManager(config) {
31
43
  deserialize = (raw) => JSON.parse(raw),
32
44
  idOf
33
45
  } = config;
34
- const redisKey = getThreadKey(threadId, key);
35
- const metaKey = getThreadKey(threadId, `${key}:meta`);
46
+ const redisKey = getThreadListKey(key, threadId);
47
+ const metaKey = getThreadMetaKey(key, threadId);
48
+ const stateKey = getThreadStateKey(key, threadId);
36
49
  async function assertThreadExists() {
37
50
  const exists = await redis.exists(metaKey);
38
51
  if (!exists) {
@@ -54,7 +67,7 @@ function createThreadManager(config) {
54
67
  await assertThreadExists();
55
68
  if (idOf) {
56
69
  const dedupId = messages.map(idOf).join(":");
57
- const dedupKey = getThreadKey(threadId, `dedup:${dedupId}`);
70
+ const dedupKey = getDedupKey(threadId, dedupId);
58
71
  await redis.eval(
59
72
  APPEND_IDEMPOTENT_SCRIPT,
60
73
  2,
@@ -71,34 +84,98 @@ function createThreadManager(config) {
71
84
  async fork(newThreadId) {
72
85
  await assertThreadExists();
73
86
  const data = await redis.lrange(redisKey, 0, -1);
87
+ const stateRaw = await redis.get(stateKey);
74
88
  const forked = createThreadManager({
75
89
  ...config,
76
90
  threadId: newThreadId
77
91
  });
78
92
  await forked.initialize();
79
93
  if (data.length > 0) {
80
- const newKey = getThreadKey(newThreadId, key);
94
+ const newKey = getThreadListKey(key, newThreadId);
81
95
  await redis.rpush(newKey, ...data);
82
96
  await redis.expire(newKey, THREAD_TTL_SECONDS);
83
97
  }
98
+ if (stateRaw != null) {
99
+ const newStateKey = getThreadStateKey(key, newThreadId);
100
+ await redis.set(newStateKey, stateRaw, "EX", THREAD_TTL_SECONDS);
101
+ }
84
102
  return forked;
85
103
  },
104
+ async replaceAll(messages) {
105
+ await assertThreadExists();
106
+ if (!idOf) {
107
+ throw new Error(
108
+ "replaceAll requires the thread manager to be configured with `idOf`"
109
+ );
110
+ }
111
+ const existing = await redis.lrange(redisKey, 0, -1);
112
+ const existingIds = existing.map((raw) => idOf(deserialize(raw))).filter((id) => typeof id === "string");
113
+ await redis.del(redisKey);
114
+ if (existingIds.length > 0) {
115
+ await redis.del(
116
+ ...existingIds.map((id) => getDedupKey(threadId, id))
117
+ );
118
+ }
119
+ if (messages.length > 0) {
120
+ await redis.rpush(redisKey, ...messages.map(serialize));
121
+ await redis.expire(redisKey, THREAD_TTL_SECONDS);
122
+ }
123
+ await redis.expire(metaKey, THREAD_TTL_SECONDS);
124
+ },
86
125
  async delete() {
87
- await redis.del(redisKey, metaKey);
126
+ await redis.del(redisKey, metaKey, stateKey);
127
+ },
128
+ async loadState() {
129
+ const raw = await redis.get(stateKey);
130
+ if (raw == null) return null;
131
+ return JSON.parse(raw);
132
+ },
133
+ async saveState(state) {
134
+ await assertThreadExists();
135
+ await redis.set(
136
+ stateKey,
137
+ JSON.stringify(state),
138
+ "EX",
139
+ THREAD_TTL_SECONDS
140
+ );
141
+ },
142
+ async deleteState() {
143
+ await redis.del(stateKey);
88
144
  },
89
145
  async length() {
90
146
  await assertThreadExists();
91
147
  return redis.llen(redisKey);
92
148
  },
93
- async truncate(length) {
149
+ async truncateFromId(messageId) {
94
150
  await assertThreadExists();
95
- if (length <= 0) {
151
+ if (!idOf) {
152
+ throw new Error(
153
+ "truncateFromId requires the thread manager to be configured with `idOf`"
154
+ );
155
+ }
156
+ const data = await redis.lrange(redisKey, 0, -1);
157
+ let idx = -1;
158
+ const removedIds = [];
159
+ for (let i = 0; i < data.length; i++) {
160
+ const raw = data[i];
161
+ if (raw === void 0) continue;
162
+ const id = idOf(deserialize(raw));
163
+ if (idx === -1 && id === messageId) idx = i;
164
+ if (idx !== -1) removedIds.push(id);
165
+ }
166
+ if (idx === -1) return;
167
+ if (idx === 0) {
96
168
  await redis.del(redisKey);
97
169
  await redis.expire(metaKey, THREAD_TTL_SECONDS);
98
170
  } else {
99
- await redis.ltrim(redisKey, 0, length - 1);
171
+ await redis.ltrim(redisKey, 0, idx - 1);
100
172
  await redis.expire(redisKey, THREAD_TTL_SECONDS);
101
173
  }
174
+ if (removedIds.length > 0) {
175
+ await redis.del(
176
+ ...removedIds.map((id) => getDedupKey(threadId, id))
177
+ );
178
+ }
102
179
  }
103
180
  };
104
181
  }
@@ -156,12 +233,33 @@ function createLangChainThreadManager(config) {
156
233
  const mapped = onPrepareMessage ? stored.map((msg, i) => onPrepareMessage(msg, i, stored)) : stored;
157
234
  const messages$1 = messages.mapStoredMessagesToChatMessages(mapped);
158
235
  return {
159
- messages: onPreparedMessage ? messages$1.map((msg, i) => onPreparedMessage(msg, i, messages$1)) : messages$1,
160
- storedLength: stored.length
236
+ messages: onPreparedMessage ? messages$1.map((msg, i) => onPreparedMessage(msg, i, messages$1)) : messages$1
161
237
  };
162
238
  }
163
239
  };
164
- return Object.assign(base, helpers);
240
+ const manager = Object.assign(base, helpers);
241
+ const originalFork = manager.fork.bind(manager);
242
+ manager.fork = async (newThreadId) => {
243
+ await originalFork(newThreadId);
244
+ const forked = createLangChainThreadManager({
245
+ ...config,
246
+ threadId: newThreadId
247
+ });
248
+ const { onForkPrepareThread, onForkTransform } = config.hooks ?? {};
249
+ if (!onForkPrepareThread && !onForkTransform) {
250
+ return forked;
251
+ }
252
+ let next = await forked.load();
253
+ if (onForkPrepareThread) {
254
+ next = await onForkPrepareThread(next);
255
+ }
256
+ if (onForkTransform) {
257
+ next = next.map((msg, i) => onForkTransform(msg, i, next));
258
+ }
259
+ await forked.replaceAll(next);
260
+ return forked;
261
+ };
262
+ return manager;
165
263
  }
166
264
 
167
265
  // node_modules/uuid/dist/esm/stringify.js
@@ -220,7 +318,7 @@ function getActivityContext() {
220
318
  // src/adapters/thread/langchain/model-invoker.ts
221
319
  function createLangChainModelInvoker({ redis, model, hooks }) {
222
320
  return async function invokeLangChainModel2(config) {
223
- const { threadId, threadKey, agentName, state, metadata } = config;
321
+ const { threadId, threadKey, agentName, state, metadata, assistantMessageId } = config;
224
322
  const { heartbeat, signal } = getActivityContext();
225
323
  const thread = createLangChainThreadManager({
226
324
  redis,
@@ -229,7 +327,8 @@ function createLangChainModelInvoker({ redis, model, hooks }) {
229
327
  hooks
230
328
  });
231
329
  const runId = v4_default();
232
- const { messages, storedLength } = await thread.prepareForInvocation();
330
+ await thread.truncateFromId(assistantMessageId);
331
+ const { messages } = await thread.prepareForInvocation();
233
332
  const heartbeatInterval = heartbeat ? setInterval(() => heartbeat(), 3e4) : void 0;
234
333
  try {
235
334
  const response = await model.invoke(messages, {
@@ -254,8 +353,7 @@ function createLangChainModelInvoker({ redis, model, hooks }) {
254
353
  reasonTokens: response.usage_metadata?.output_token_details?.reasoning,
255
354
  cachedWriteTokens: response.usage_metadata?.input_token_details?.cache_creation || providerUsage.cacheWriteInputTokens,
256
355
  cachedReadTokens: response.usage_metadata?.input_token_details?.cache_read || providerUsage.cacheReadInputTokens
257
- },
258
- threadLengthAtCall: storedLength
356
+ }
259
357
  };
260
358
  } finally {
261
359
  if (heartbeatInterval) clearInterval(heartbeatInterval);
@@ -273,7 +371,6 @@ async function invokeLangChainModel({
273
371
  }
274
372
 
275
373
  // src/adapters/thread/langchain/activities.ts
276
- var ADAPTER_PREFIX = "langChain";
277
374
  function createLangChainAdapter(config) {
278
375
  const { redis } = config;
279
376
  const threadOps = {
@@ -323,17 +420,34 @@ function createLangChainAdapter(config) {
323
420
  const thread = createLangChainThreadManager({
324
421
  redis,
325
422
  threadId: sourceThreadId,
326
- key: threadKey
423
+ key: threadKey,
424
+ hooks: config.hooks
327
425
  });
328
426
  await thread.fork(targetThreadId);
329
427
  },
330
- async truncateThread(threadId, length, threadKey) {
428
+ async truncateThread(threadId, messageId, threadKey) {
331
429
  const thread = createLangChainThreadManager({ redis, threadId, key: threadKey });
332
- await thread.truncate(length);
430
+ await thread.truncateFromId(messageId);
431
+ },
432
+ async loadThreadState(threadId, threadKey) {
433
+ const thread = createLangChainThreadManager({
434
+ redis,
435
+ threadId,
436
+ key: threadKey
437
+ });
438
+ return thread.loadState();
439
+ },
440
+ async saveThreadState(threadId, state, threadKey) {
441
+ const thread = createLangChainThreadManager({
442
+ redis,
443
+ threadId,
444
+ key: threadKey
445
+ });
446
+ await thread.saveState(state);
333
447
  }
334
448
  };
335
449
  function createActivities(scope) {
336
- const prefix = scope ? `${ADAPTER_PREFIX}${scope.charAt(0).toUpperCase()}${scope.slice(1)}` : ADAPTER_PREFIX;
450
+ const prefix = scope ? `${ADAPTER_ID}${scope.charAt(0).toUpperCase()}${scope.slice(1)}` : ADAPTER_ID;
337
451
  const cap = (s) => s.charAt(0).toUpperCase() + s.slice(1);
338
452
  return Object.fromEntries(
339
453
  Object.entries(threadOps).map(([k, v]) => [`${prefix}${cap(k)}`, v])
@@ -390,6 +504,7 @@ function appendCachePoint(block, { maxBlocks = 4 } = {}) {
390
504
  };
391
505
  }
392
506
 
507
+ exports.ADAPTER_ID = ADAPTER_ID;
393
508
  exports.appendCachePoint = appendCachePoint;
394
509
  exports.createLangChainAdapter = createLangChainAdapter;
395
510
  exports.createLangChainModelInvoker = createLangChainModelInvoker;