zeitlich 0.2.31 → 0.2.32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/dist/{activities-qPkJDAiq.d.cts → activities-DA-bQM12.d.cts} +2 -2
  2. package/dist/{activities-DRSdt8Y3.d.ts → activities-FIXVz7DT.d.ts} +2 -2
  3. package/dist/adapters/thread/anthropic/index.cjs +4 -48
  4. package/dist/adapters/thread/anthropic/index.cjs.map +1 -1
  5. package/dist/adapters/thread/anthropic/index.d.cts +6 -6
  6. package/dist/adapters/thread/anthropic/index.d.ts +6 -6
  7. package/dist/adapters/thread/anthropic/index.js +4 -48
  8. package/dist/adapters/thread/anthropic/index.js.map +1 -1
  9. package/dist/adapters/thread/anthropic/workflow.cjs +1 -0
  10. package/dist/adapters/thread/anthropic/workflow.cjs.map +1 -1
  11. package/dist/adapters/thread/anthropic/workflow.d.cts +4 -4
  12. package/dist/adapters/thread/anthropic/workflow.d.ts +4 -4
  13. package/dist/adapters/thread/anthropic/workflow.js +1 -0
  14. package/dist/adapters/thread/anthropic/workflow.js.map +1 -1
  15. package/dist/adapters/thread/google-genai/index.cjs +8 -48
  16. package/dist/adapters/thread/google-genai/index.cjs.map +1 -1
  17. package/dist/adapters/thread/google-genai/index.d.cts +6 -6
  18. package/dist/adapters/thread/google-genai/index.d.ts +6 -6
  19. package/dist/adapters/thread/google-genai/index.js +8 -48
  20. package/dist/adapters/thread/google-genai/index.js.map +1 -1
  21. package/dist/adapters/thread/google-genai/workflow.cjs +1 -0
  22. package/dist/adapters/thread/google-genai/workflow.cjs.map +1 -1
  23. package/dist/adapters/thread/google-genai/workflow.d.cts +4 -4
  24. package/dist/adapters/thread/google-genai/workflow.d.ts +4 -4
  25. package/dist/adapters/thread/google-genai/workflow.js +1 -0
  26. package/dist/adapters/thread/google-genai/workflow.js.map +1 -1
  27. package/dist/adapters/thread/langchain/index.cjs +5 -1
  28. package/dist/adapters/thread/langchain/index.cjs.map +1 -1
  29. package/dist/adapters/thread/langchain/index.d.cts +6 -5
  30. package/dist/adapters/thread/langchain/index.d.ts +6 -5
  31. package/dist/adapters/thread/langchain/index.js +5 -1
  32. package/dist/adapters/thread/langchain/index.js.map +1 -1
  33. package/dist/adapters/thread/langchain/workflow.cjs +1 -0
  34. package/dist/adapters/thread/langchain/workflow.cjs.map +1 -1
  35. package/dist/adapters/thread/langchain/workflow.d.cts +4 -4
  36. package/dist/adapters/thread/langchain/workflow.d.ts +4 -4
  37. package/dist/adapters/thread/langchain/workflow.js +1 -0
  38. package/dist/adapters/thread/langchain/workflow.js.map +1 -1
  39. package/dist/index.cjs +8 -5
  40. package/dist/index.cjs.map +1 -1
  41. package/dist/index.d.cts +6 -6
  42. package/dist/index.d.ts +6 -6
  43. package/dist/index.js +8 -5
  44. package/dist/index.js.map +1 -1
  45. package/dist/{proxy-BkvkV2oU.d.ts → proxy-Br4unLTC.d.ts} +1 -1
  46. package/dist/{proxy-BDQ3Rj6R.d.cts → proxy-CTCYWjkr.d.cts} +1 -1
  47. package/dist/{thread-manager-BLgvv9Gf.d.cts → thread-manager-CUubPYPH.d.cts} +1 -1
  48. package/dist/{thread-manager-DowU4ntB.d.cts → thread-manager-Cv_BR28i.d.cts} +1 -1
  49. package/dist/{thread-manager-Cv82H1wi.d.ts → thread-manager-DKWxHUzD.d.ts} +1 -1
  50. package/dist/{thread-manager-HsAYkyAV.d.ts → thread-manager-YJLoc1vH.d.ts} +1 -1
  51. package/dist/{types-CjeGWQm1.d.cts → types-Bpq5fDI5.d.cts} +7 -4
  52. package/dist/{types-D6UKZZtj.d.ts → types-BxiT8w9d.d.ts} +1 -1
  53. package/dist/{types-BmS-Huc0.d.ts → types-CheCTLeV.d.ts} +7 -4
  54. package/dist/{types-e_38QaKo.d.cts → types-NJDyMyUx.d.cts} +1 -1
  55. package/dist/{workflow-CNshfqSO.d.cts → workflow-BWKQcz9d.d.cts} +1 -1
  56. package/dist/{workflow-CTcrPZAV.d.ts → workflow-D8wK7TJY.d.ts} +1 -1
  57. package/dist/workflow.cjs +4 -1
  58. package/dist/workflow.cjs.map +1 -1
  59. package/dist/workflow.d.cts +2 -2
  60. package/dist/workflow.d.ts +2 -2
  61. package/dist/workflow.js +4 -1
  62. package/dist/workflow.js.map +1 -1
  63. package/package.json +1 -1
  64. package/src/adapters/thread/anthropic/activities.ts +10 -0
  65. package/src/adapters/thread/anthropic/model-invoker.ts +2 -5
  66. package/src/adapters/thread/google-genai/activities.ts +14 -0
  67. package/src/adapters/thread/google-genai/model-invoker.ts +2 -5
  68. package/src/adapters/thread/langchain/activities.ts +11 -0
  69. package/src/adapters/thread/langchain/model-invoker.ts +2 -3
  70. package/src/lib/.env +1 -0
  71. package/src/lib/model/types.ts +3 -2
  72. package/src/lib/session/session-edge-cases.integration.test.ts +6 -0
  73. package/src/lib/session/session.integration.test.ts +3 -0
  74. package/src/lib/session/session.ts +4 -0
  75. package/src/lib/session/types.ts +7 -0
  76. package/src/lib/thread/proxy.ts +1 -0
  77. package/src/lib/types.ts +1 -0
  78. package/src/lib/virtual-fs/manager.ts +3 -3
  79. package/src/lib/virtual-fs/proxy.ts +3 -3
  80. package/src/lib/virtual-fs/types.ts +1 -2
  81. package/src/lib/virtual-fs/with-virtual-fs.ts +4 -4
  82. package/src/tools/bash/.env +1 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/lib/thread/proxy.ts","../../../../src/adapters/thread/anthropic/proxy.ts"],"names":["workflowInfo","proxyActivities"],"mappings":";;;;;AAwBO,SAAS,oBAAA,CACd,aAAA,EACA,KAAA,EACA,OAAA,EACiC;AACjC,EAAA,MAAM,aAAA,GAAgB,KAAA,IAASA,qBAAA,EAAa,CAAE,YAAA;AAG9C,EAAA,MAAM,IAAA,GAAOC,wBAAA;AAAA,IACX,OAAA,IAAW;AAAA,MACT,mBAAA,EAAqB,KAAA;AAAA,MACrB,KAAA,EAAO;AAAA,QACL,eAAA,EAAiB,CAAA;AAAA,QACjB,eAAA,EAAiB,IAAA;AAAA,QACjB,eAAA,EAAiB,KAAA;AAAA,QACjB,kBAAA,EAAoB;AAAA;AACtB;AACF,GACF;AAEA,EAAA,MAAM,MAAA,GACJ,CAAA,EAAG,aAAa,CAAA,EAAG,cAAc,MAAA,CAAO,CAAC,CAAA,CAAE,WAAA,EAAa,CAAA,EAAG,aAAA,CAAc,KAAA,CAAM,CAAC,CAAC,CAAA,CAAA;AACnF,EAAA,MAAM,IAAI,CAAC,GAAA,KACT,CAAA,EAAG,MAAM,GAAG,GAAA,CAAI,MAAA,CAAO,CAAC,CAAA,CAAE,aAAa,CAAA,EAAG,GAAA,CAAI,KAAA,CAAM,CAAC,CAAC,CAAA,CAAA;AAExD,EAAA,OAAO;AAAA,IACL,gBAAA,EAAkB,IAAA,CAAK,CAAA,CAAE,kBAAkB,CAAC,CAAA;AAAA,IAC5C,kBAAA,EAAoB,IAAA,CAAK,CAAA,CAAE,oBAAoB,CAAC,CAAA;AAAA,IAChD,gBAAA,EAAkB,IAAA,CAAK,CAAA,CAAE,kBAAkB,CAAC,CAAA;AAAA,IAC5C,mBAAA,EAAqB,IAAA,CAAK,CAAA,CAAE,qBAAqB,CAAC,CAAA;AAAA,IAClD,UAAA,EAAY,IAAA,CAAK,CAAA,CAAE,YAAY,CAAC;AAAA,GAClC;AACF;;;AC/BA,IAAM,cAAA,GAAiB,WAAA;AAEhB,SAAS,uBAAA,CACd,OACA,OAAA,EACmD;AACnD,EAAA,OAAO,oBAAA,CAAqB,cAAA,EAAgB,KAAA,EAAO,OAAO,CAAA;AAC5D","file":"workflow.cjs","sourcesContent":["/**\n * Shared proxy helper for thread operations.\n *\n * Each adapter re-exports a thin wrapper that supplies its prefix and\n * casts the return type to carry the adapter's native content type.\n */\nimport {\n proxyActivities,\n workflowInfo,\n type ActivityInterfaceFor,\n} from \"@temporalio/workflow\";\nimport type { ThreadOps } from \"../session/types\";\n\n/**\n * Creates a workflow-safe Temporal activity proxy for {@link ThreadOps}.\n *\n * The proxy resolves activity names by combining the adapter prefix with\n * the workflow scope, so each adapter + workflow combination gets its own\n * namespace.\n *\n * @param adapterPrefix - Adapter identifier (e.g. \"anthropic\", \"googleGenAI\", \"langChain\")\n * @param scope - Optional workflow scope override. Defaults to `workflowInfo().workflowType`.\n * @param options - Optional Temporal `proxyActivities` options.\n */\nexport function createThreadOpsProxy(\n adapterPrefix: string,\n scope?: string,\n options?: Parameters<typeof proxyActivities>[0],\n): ActivityInterfaceFor<ThreadOps> {\n const resolvedScope = scope ?? workflowInfo().workflowType;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const acts = proxyActivities<Record<string, (...args: any[]) => any>>(\n options ?? {\n startToCloseTimeout: \"10s\",\n retry: {\n maximumAttempts: 6,\n initialInterval: \"5s\",\n maximumInterval: \"15m\",\n backoffCoefficient: 4,\n },\n },\n );\n\n const prefix =\n `${adapterPrefix}${resolvedScope.charAt(0).toUpperCase()}${resolvedScope.slice(1)}`;\n const p = (key: string): string =>\n `${prefix}${key.charAt(0).toUpperCase()}${key.slice(1)}`;\n\n return {\n initializeThread: acts[p(\"initializeThread\")],\n appendHumanMessage: acts[p(\"appendHumanMessage\")],\n appendToolResult: acts[p(\"appendToolResult\")],\n appendSystemMessage: acts[p(\"appendSystemMessage\")],\n forkThread: acts[p(\"forkThread\")],\n } as ActivityInterfaceFor<ThreadOps>;\n}\n","/**\n * Workflow-safe proxy for Anthropic thread operations.\n *\n * Import this from `zeitlich/adapters/thread/anthropic/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 { proxyAnthropicThreadOps } from 'zeitlich/adapters/thread/anthropic/workflow';\n *\n * // Auto-scoped to the current workflow name\n * const threadOps = proxyAnthropicThreadOps();\n *\n * // Explicit scope override\n * const threadOps = proxyAnthropicThreadOps(\"customScope\");\n * ```\n */\nimport { type ActivityInterfaceFor } from \"@temporalio/workflow\";\nimport type { ThreadOps } from \"../../../lib/session/types\";\nimport type { AnthropicContent } from \"./thread-manager\";\nimport { createThreadOpsProxy } from \"../../../lib/thread/proxy\";\n\nconst ADAPTER_PREFIX = \"anthropic\";\n\nexport function proxyAnthropicThreadOps(\n scope?: string,\n options?: Parameters<typeof createThreadOpsProxy>[2],\n): ActivityInterfaceFor<ThreadOps<AnthropicContent>> {\n return createThreadOpsProxy(ADAPTER_PREFIX, scope, options) as ActivityInterfaceFor<ThreadOps<AnthropicContent>>;\n}\n"]}
1
+ {"version":3,"sources":["../../../../src/lib/thread/proxy.ts","../../../../src/adapters/thread/anthropic/proxy.ts"],"names":["workflowInfo","proxyActivities"],"mappings":";;;;;AAwBO,SAAS,oBAAA,CACd,aAAA,EACA,KAAA,EACA,OAAA,EACiC;AACjC,EAAA,MAAM,aAAA,GAAgB,KAAA,IAASA,qBAAA,EAAa,CAAE,YAAA;AAG9C,EAAA,MAAM,IAAA,GAAOC,wBAAA;AAAA,IACX,OAAA,IAAW;AAAA,MACT,mBAAA,EAAqB,KAAA;AAAA,MACrB,KAAA,EAAO;AAAA,QACL,eAAA,EAAiB,CAAA;AAAA,QACjB,eAAA,EAAiB,IAAA;AAAA,QACjB,eAAA,EAAiB,KAAA;AAAA,QACjB,kBAAA,EAAoB;AAAA;AACtB;AACF,GACF;AAEA,EAAA,MAAM,MAAA,GACJ,CAAA,EAAG,aAAa,CAAA,EAAG,cAAc,MAAA,CAAO,CAAC,CAAA,CAAE,WAAA,EAAa,CAAA,EAAG,aAAA,CAAc,KAAA,CAAM,CAAC,CAAC,CAAA,CAAA;AACnF,EAAA,MAAM,IAAI,CAAC,GAAA,KACT,CAAA,EAAG,MAAM,GAAG,GAAA,CAAI,MAAA,CAAO,CAAC,CAAA,CAAE,aAAa,CAAA,EAAG,GAAA,CAAI,KAAA,CAAM,CAAC,CAAC,CAAA,CAAA;AAExD,EAAA,OAAO;AAAA,IACL,gBAAA,EAAkB,IAAA,CAAK,CAAA,CAAE,kBAAkB,CAAC,CAAA;AAAA,IAC5C,kBAAA,EAAoB,IAAA,CAAK,CAAA,CAAE,oBAAoB,CAAC,CAAA;AAAA,IAChD,gBAAA,EAAkB,IAAA,CAAK,CAAA,CAAE,kBAAkB,CAAC,CAAA;AAAA,IAC5C,kBAAA,EAAoB,IAAA,CAAK,CAAA,CAAE,oBAAoB,CAAC,CAAA;AAAA,IAChD,mBAAA,EAAqB,IAAA,CAAK,CAAA,CAAE,qBAAqB,CAAC,CAAA;AAAA,IAClD,UAAA,EAAY,IAAA,CAAK,CAAA,CAAE,YAAY,CAAC;AAAA,GAClC;AACF;;;AChCA,IAAM,cAAA,GAAiB,WAAA;AAEhB,SAAS,uBAAA,CACd,OACA,OAAA,EACmD;AACnD,EAAA,OAAO,oBAAA,CAAqB,cAAA,EAAgB,KAAA,EAAO,OAAO,CAAA;AAC5D","file":"workflow.cjs","sourcesContent":["/**\n * Shared proxy helper for thread operations.\n *\n * Each adapter re-exports a thin wrapper that supplies its prefix and\n * casts the return type to carry the adapter's native content type.\n */\nimport {\n proxyActivities,\n workflowInfo,\n type ActivityInterfaceFor,\n} from \"@temporalio/workflow\";\nimport type { ThreadOps } from \"../session/types\";\n\n/**\n * Creates a workflow-safe Temporal activity proxy for {@link ThreadOps}.\n *\n * The proxy resolves activity names by combining the adapter prefix with\n * the workflow scope, so each adapter + workflow combination gets its own\n * namespace.\n *\n * @param adapterPrefix - Adapter identifier (e.g. \"anthropic\", \"googleGenAI\", \"langChain\")\n * @param scope - Optional workflow scope override. Defaults to `workflowInfo().workflowType`.\n * @param options - Optional Temporal `proxyActivities` options.\n */\nexport function createThreadOpsProxy(\n adapterPrefix: string,\n scope?: string,\n options?: Parameters<typeof proxyActivities>[0],\n): ActivityInterfaceFor<ThreadOps> {\n const resolvedScope = scope ?? workflowInfo().workflowType;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const acts = proxyActivities<Record<string, (...args: any[]) => any>>(\n options ?? {\n startToCloseTimeout: \"10s\",\n retry: {\n maximumAttempts: 6,\n initialInterval: \"5s\",\n maximumInterval: \"15m\",\n backoffCoefficient: 4,\n },\n },\n );\n\n const prefix =\n `${adapterPrefix}${resolvedScope.charAt(0).toUpperCase()}${resolvedScope.slice(1)}`;\n const p = (key: string): string =>\n `${prefix}${key.charAt(0).toUpperCase()}${key.slice(1)}`;\n\n return {\n initializeThread: acts[p(\"initializeThread\")],\n appendHumanMessage: acts[p(\"appendHumanMessage\")],\n appendToolResult: acts[p(\"appendToolResult\")],\n appendAgentMessage: acts[p(\"appendAgentMessage\")],\n appendSystemMessage: acts[p(\"appendSystemMessage\")],\n forkThread: acts[p(\"forkThread\")],\n } as ActivityInterfaceFor<ThreadOps>;\n}\n","/**\n * Workflow-safe proxy for Anthropic thread operations.\n *\n * Import this from `zeitlich/adapters/thread/anthropic/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 { proxyAnthropicThreadOps } from 'zeitlich/adapters/thread/anthropic/workflow';\n *\n * // Auto-scoped to the current workflow name\n * const threadOps = proxyAnthropicThreadOps();\n *\n * // Explicit scope override\n * const threadOps = proxyAnthropicThreadOps(\"customScope\");\n * ```\n */\nimport { type ActivityInterfaceFor } from \"@temporalio/workflow\";\nimport type { ThreadOps } from \"../../../lib/session/types\";\nimport type { AnthropicContent } from \"./thread-manager\";\nimport { createThreadOpsProxy } from \"../../../lib/thread/proxy\";\n\nconst ADAPTER_PREFIX = \"anthropic\";\n\nexport function proxyAnthropicThreadOps(\n scope?: string,\n options?: Parameters<typeof createThreadOpsProxy>[2],\n): ActivityInterfaceFor<ThreadOps<AnthropicContent>> {\n return createThreadOpsProxy(ADAPTER_PREFIX, scope, options) as ActivityInterfaceFor<ThreadOps<AnthropicContent>>;\n}\n"]}
@@ -1,14 +1,14 @@
1
1
  import { ActivityInterfaceFor } from '@temporalio/workflow';
2
- import { T as ThreadOps } from '../../../types-CjeGWQm1.cjs';
3
- import { A as AnthropicContent } from '../../../thread-manager-BLgvv9Gf.cjs';
4
- import { c as createThreadOpsProxy } from '../../../proxy-BDQ3Rj6R.cjs';
2
+ import { T as ThreadOps } from '../../../types-Bpq5fDI5.cjs';
3
+ import { A as AnthropicContent } from '../../../thread-manager-CUubPYPH.cjs';
4
+ import { c as createThreadOpsProxy } from '../../../proxy-CTCYWjkr.cjs';
5
5
  import '@temporalio/common';
6
6
  import '@temporalio/common/lib/interfaces';
7
7
  import 'zod';
8
8
  import '../../../types-AujBIMMn.cjs';
9
9
  import 'ioredis';
10
10
  import '@anthropic-ai/sdk';
11
- import '../../../types-e_38QaKo.cjs';
11
+ import '../../../types-NJDyMyUx.cjs';
12
12
 
13
13
  /**
14
14
  * Workflow-safe proxy for Anthropic thread operations.
@@ -1,14 +1,14 @@
1
1
  import { ActivityInterfaceFor } from '@temporalio/workflow';
2
- import { T as ThreadOps } from '../../../types-BmS-Huc0.js';
3
- import { A as AnthropicContent } from '../../../thread-manager-HsAYkyAV.js';
4
- import { c as createThreadOpsProxy } from '../../../proxy-BkvkV2oU.js';
2
+ import { T as ThreadOps } from '../../../types-CheCTLeV.js';
3
+ import { A as AnthropicContent } from '../../../thread-manager-YJLoc1vH.js';
4
+ import { c as createThreadOpsProxy } from '../../../proxy-Br4unLTC.js';
5
5
  import '@temporalio/common';
6
6
  import '@temporalio/common/lib/interfaces';
7
7
  import 'zod';
8
8
  import '../../../types-AujBIMMn.js';
9
9
  import 'ioredis';
10
10
  import '@anthropic-ai/sdk';
11
- import '../../../types-D6UKZZtj.js';
11
+ import '../../../types-BxiT8w9d.js';
12
12
 
13
13
  /**
14
14
  * Workflow-safe proxy for Anthropic thread operations.
@@ -20,6 +20,7 @@ function createThreadOpsProxy(adapterPrefix, scope, options) {
20
20
  initializeThread: acts[p("initializeThread")],
21
21
  appendHumanMessage: acts[p("appendHumanMessage")],
22
22
  appendToolResult: acts[p("appendToolResult")],
23
+ appendAgentMessage: acts[p("appendAgentMessage")],
23
24
  appendSystemMessage: acts[p("appendSystemMessage")],
24
25
  forkThread: acts[p("forkThread")]
25
26
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/lib/thread/proxy.ts","../../../../src/adapters/thread/anthropic/proxy.ts"],"names":[],"mappings":";;;AAwBO,SAAS,oBAAA,CACd,aAAA,EACA,KAAA,EACA,OAAA,EACiC;AACjC,EAAA,MAAM,aAAA,GAAgB,KAAA,IAAS,YAAA,EAAa,CAAE,YAAA;AAG9C,EAAA,MAAM,IAAA,GAAO,eAAA;AAAA,IACX,OAAA,IAAW;AAAA,MACT,mBAAA,EAAqB,KAAA;AAAA,MACrB,KAAA,EAAO;AAAA,QACL,eAAA,EAAiB,CAAA;AAAA,QACjB,eAAA,EAAiB,IAAA;AAAA,QACjB,eAAA,EAAiB,KAAA;AAAA,QACjB,kBAAA,EAAoB;AAAA;AACtB;AACF,GACF;AAEA,EAAA,MAAM,MAAA,GACJ,CAAA,EAAG,aAAa,CAAA,EAAG,cAAc,MAAA,CAAO,CAAC,CAAA,CAAE,WAAA,EAAa,CAAA,EAAG,aAAA,CAAc,KAAA,CAAM,CAAC,CAAC,CAAA,CAAA;AACnF,EAAA,MAAM,IAAI,CAAC,GAAA,KACT,CAAA,EAAG,MAAM,GAAG,GAAA,CAAI,MAAA,CAAO,CAAC,CAAA,CAAE,aAAa,CAAA,EAAG,GAAA,CAAI,KAAA,CAAM,CAAC,CAAC,CAAA,CAAA;AAExD,EAAA,OAAO;AAAA,IACL,gBAAA,EAAkB,IAAA,CAAK,CAAA,CAAE,kBAAkB,CAAC,CAAA;AAAA,IAC5C,kBAAA,EAAoB,IAAA,CAAK,CAAA,CAAE,oBAAoB,CAAC,CAAA;AAAA,IAChD,gBAAA,EAAkB,IAAA,CAAK,CAAA,CAAE,kBAAkB,CAAC,CAAA;AAAA,IAC5C,mBAAA,EAAqB,IAAA,CAAK,CAAA,CAAE,qBAAqB,CAAC,CAAA;AAAA,IAClD,UAAA,EAAY,IAAA,CAAK,CAAA,CAAE,YAAY,CAAC;AAAA,GAClC;AACF;;;AC/BA,IAAM,cAAA,GAAiB,WAAA;AAEhB,SAAS,uBAAA,CACd,OACA,OAAA,EACmD;AACnD,EAAA,OAAO,oBAAA,CAAqB,cAAA,EAAgB,KAAA,EAAO,OAAO,CAAA;AAC5D","file":"workflow.js","sourcesContent":["/**\n * Shared proxy helper for thread operations.\n *\n * Each adapter re-exports a thin wrapper that supplies its prefix and\n * casts the return type to carry the adapter's native content type.\n */\nimport {\n proxyActivities,\n workflowInfo,\n type ActivityInterfaceFor,\n} from \"@temporalio/workflow\";\nimport type { ThreadOps } from \"../session/types\";\n\n/**\n * Creates a workflow-safe Temporal activity proxy for {@link ThreadOps}.\n *\n * The proxy resolves activity names by combining the adapter prefix with\n * the workflow scope, so each adapter + workflow combination gets its own\n * namespace.\n *\n * @param adapterPrefix - Adapter identifier (e.g. \"anthropic\", \"googleGenAI\", \"langChain\")\n * @param scope - Optional workflow scope override. Defaults to `workflowInfo().workflowType`.\n * @param options - Optional Temporal `proxyActivities` options.\n */\nexport function createThreadOpsProxy(\n adapterPrefix: string,\n scope?: string,\n options?: Parameters<typeof proxyActivities>[0],\n): ActivityInterfaceFor<ThreadOps> {\n const resolvedScope = scope ?? workflowInfo().workflowType;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const acts = proxyActivities<Record<string, (...args: any[]) => any>>(\n options ?? {\n startToCloseTimeout: \"10s\",\n retry: {\n maximumAttempts: 6,\n initialInterval: \"5s\",\n maximumInterval: \"15m\",\n backoffCoefficient: 4,\n },\n },\n );\n\n const prefix =\n `${adapterPrefix}${resolvedScope.charAt(0).toUpperCase()}${resolvedScope.slice(1)}`;\n const p = (key: string): string =>\n `${prefix}${key.charAt(0).toUpperCase()}${key.slice(1)}`;\n\n return {\n initializeThread: acts[p(\"initializeThread\")],\n appendHumanMessage: acts[p(\"appendHumanMessage\")],\n appendToolResult: acts[p(\"appendToolResult\")],\n appendSystemMessage: acts[p(\"appendSystemMessage\")],\n forkThread: acts[p(\"forkThread\")],\n } as ActivityInterfaceFor<ThreadOps>;\n}\n","/**\n * Workflow-safe proxy for Anthropic thread operations.\n *\n * Import this from `zeitlich/adapters/thread/anthropic/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 { proxyAnthropicThreadOps } from 'zeitlich/adapters/thread/anthropic/workflow';\n *\n * // Auto-scoped to the current workflow name\n * const threadOps = proxyAnthropicThreadOps();\n *\n * // Explicit scope override\n * const threadOps = proxyAnthropicThreadOps(\"customScope\");\n * ```\n */\nimport { type ActivityInterfaceFor } from \"@temporalio/workflow\";\nimport type { ThreadOps } from \"../../../lib/session/types\";\nimport type { AnthropicContent } from \"./thread-manager\";\nimport { createThreadOpsProxy } from \"../../../lib/thread/proxy\";\n\nconst ADAPTER_PREFIX = \"anthropic\";\n\nexport function proxyAnthropicThreadOps(\n scope?: string,\n options?: Parameters<typeof createThreadOpsProxy>[2],\n): ActivityInterfaceFor<ThreadOps<AnthropicContent>> {\n return createThreadOpsProxy(ADAPTER_PREFIX, scope, options) as ActivityInterfaceFor<ThreadOps<AnthropicContent>>;\n}\n"]}
1
+ {"version":3,"sources":["../../../../src/lib/thread/proxy.ts","../../../../src/adapters/thread/anthropic/proxy.ts"],"names":[],"mappings":";;;AAwBO,SAAS,oBAAA,CACd,aAAA,EACA,KAAA,EACA,OAAA,EACiC;AACjC,EAAA,MAAM,aAAA,GAAgB,KAAA,IAAS,YAAA,EAAa,CAAE,YAAA;AAG9C,EAAA,MAAM,IAAA,GAAO,eAAA;AAAA,IACX,OAAA,IAAW;AAAA,MACT,mBAAA,EAAqB,KAAA;AAAA,MACrB,KAAA,EAAO;AAAA,QACL,eAAA,EAAiB,CAAA;AAAA,QACjB,eAAA,EAAiB,IAAA;AAAA,QACjB,eAAA,EAAiB,KAAA;AAAA,QACjB,kBAAA,EAAoB;AAAA;AACtB;AACF,GACF;AAEA,EAAA,MAAM,MAAA,GACJ,CAAA,EAAG,aAAa,CAAA,EAAG,cAAc,MAAA,CAAO,CAAC,CAAA,CAAE,WAAA,EAAa,CAAA,EAAG,aAAA,CAAc,KAAA,CAAM,CAAC,CAAC,CAAA,CAAA;AACnF,EAAA,MAAM,IAAI,CAAC,GAAA,KACT,CAAA,EAAG,MAAM,GAAG,GAAA,CAAI,MAAA,CAAO,CAAC,CAAA,CAAE,aAAa,CAAA,EAAG,GAAA,CAAI,KAAA,CAAM,CAAC,CAAC,CAAA,CAAA;AAExD,EAAA,OAAO;AAAA,IACL,gBAAA,EAAkB,IAAA,CAAK,CAAA,CAAE,kBAAkB,CAAC,CAAA;AAAA,IAC5C,kBAAA,EAAoB,IAAA,CAAK,CAAA,CAAE,oBAAoB,CAAC,CAAA;AAAA,IAChD,gBAAA,EAAkB,IAAA,CAAK,CAAA,CAAE,kBAAkB,CAAC,CAAA;AAAA,IAC5C,kBAAA,EAAoB,IAAA,CAAK,CAAA,CAAE,oBAAoB,CAAC,CAAA;AAAA,IAChD,mBAAA,EAAqB,IAAA,CAAK,CAAA,CAAE,qBAAqB,CAAC,CAAA;AAAA,IAClD,UAAA,EAAY,IAAA,CAAK,CAAA,CAAE,YAAY,CAAC;AAAA,GAClC;AACF;;;AChCA,IAAM,cAAA,GAAiB,WAAA;AAEhB,SAAS,uBAAA,CACd,OACA,OAAA,EACmD;AACnD,EAAA,OAAO,oBAAA,CAAqB,cAAA,EAAgB,KAAA,EAAO,OAAO,CAAA;AAC5D","file":"workflow.js","sourcesContent":["/**\n * Shared proxy helper for thread operations.\n *\n * Each adapter re-exports a thin wrapper that supplies its prefix and\n * casts the return type to carry the adapter's native content type.\n */\nimport {\n proxyActivities,\n workflowInfo,\n type ActivityInterfaceFor,\n} from \"@temporalio/workflow\";\nimport type { ThreadOps } from \"../session/types\";\n\n/**\n * Creates a workflow-safe Temporal activity proxy for {@link ThreadOps}.\n *\n * The proxy resolves activity names by combining the adapter prefix with\n * the workflow scope, so each adapter + workflow combination gets its own\n * namespace.\n *\n * @param adapterPrefix - Adapter identifier (e.g. \"anthropic\", \"googleGenAI\", \"langChain\")\n * @param scope - Optional workflow scope override. Defaults to `workflowInfo().workflowType`.\n * @param options - Optional Temporal `proxyActivities` options.\n */\nexport function createThreadOpsProxy(\n adapterPrefix: string,\n scope?: string,\n options?: Parameters<typeof proxyActivities>[0],\n): ActivityInterfaceFor<ThreadOps> {\n const resolvedScope = scope ?? workflowInfo().workflowType;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const acts = proxyActivities<Record<string, (...args: any[]) => any>>(\n options ?? {\n startToCloseTimeout: \"10s\",\n retry: {\n maximumAttempts: 6,\n initialInterval: \"5s\",\n maximumInterval: \"15m\",\n backoffCoefficient: 4,\n },\n },\n );\n\n const prefix =\n `${adapterPrefix}${resolvedScope.charAt(0).toUpperCase()}${resolvedScope.slice(1)}`;\n const p = (key: string): string =>\n `${prefix}${key.charAt(0).toUpperCase()}${key.slice(1)}`;\n\n return {\n initializeThread: acts[p(\"initializeThread\")],\n appendHumanMessage: acts[p(\"appendHumanMessage\")],\n appendToolResult: acts[p(\"appendToolResult\")],\n appendAgentMessage: acts[p(\"appendAgentMessage\")],\n appendSystemMessage: acts[p(\"appendSystemMessage\")],\n forkThread: acts[p(\"forkThread\")],\n } as ActivityInterfaceFor<ThreadOps>;\n}\n","/**\n * Workflow-safe proxy for Anthropic thread operations.\n *\n * Import this from `zeitlich/adapters/thread/anthropic/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 { proxyAnthropicThreadOps } from 'zeitlich/adapters/thread/anthropic/workflow';\n *\n * // Auto-scoped to the current workflow name\n * const threadOps = proxyAnthropicThreadOps();\n *\n * // Explicit scope override\n * const threadOps = proxyAnthropicThreadOps(\"customScope\");\n * ```\n */\nimport { type ActivityInterfaceFor } from \"@temporalio/workflow\";\nimport type { ThreadOps } from \"../../../lib/session/types\";\nimport type { AnthropicContent } from \"./thread-manager\";\nimport { createThreadOpsProxy } from \"../../../lib/thread/proxy\";\n\nconst ADAPTER_PREFIX = \"anthropic\";\n\nexport function proxyAnthropicThreadOps(\n scope?: string,\n options?: Parameters<typeof createThreadOpsProxy>[2],\n): ActivityInterfaceFor<ThreadOps<AnthropicContent>> {\n return createThreadOpsProxy(ADAPTER_PREFIX, scope, options) as ActivityInterfaceFor<ThreadOps<AnthropicContent>>;\n}\n"]}
@@ -1,7 +1,5 @@
1
1
  'use strict';
2
2
 
3
- var crypto = require('crypto');
4
-
5
3
  // src/lib/thread/manager.ts
6
4
  var THREAD_TTL_SECONDS = 60 * 60 * 24 * 90;
7
5
  var APPEND_IDEMPOTENT_SCRIPT = `
@@ -177,51 +175,6 @@ function createGoogleGenAIThreadManager(config) {
177
175
  return Object.assign(base, helpers);
178
176
  }
179
177
 
180
- // node_modules/uuid/dist/esm/stringify.js
181
- var byteToHex = [];
182
- for (let i = 0; i < 256; ++i) {
183
- byteToHex.push((i + 256).toString(16).slice(1));
184
- }
185
- function unsafeStringify(arr, offset = 0) {
186
- return (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase();
187
- }
188
- var rnds8Pool = new Uint8Array(256);
189
- var poolPtr = rnds8Pool.length;
190
- function rng() {
191
- if (poolPtr > rnds8Pool.length - 16) {
192
- crypto.randomFillSync(rnds8Pool);
193
- poolPtr = 0;
194
- }
195
- return rnds8Pool.slice(poolPtr, poolPtr += 16);
196
- }
197
- var native_default = { randomUUID: crypto.randomUUID };
198
-
199
- // node_modules/uuid/dist/esm/v4.js
200
- function v4(options, buf, offset) {
201
- if (native_default.randomUUID && !buf && !options) {
202
- return native_default.randomUUID();
203
- }
204
- options = options || {};
205
- const rnds = options.random ?? options.rng?.() ?? rng();
206
- if (rnds.length < 16) {
207
- throw new Error("Random bytes length must be >= 16");
208
- }
209
- rnds[6] = rnds[6] & 15 | 64;
210
- rnds[8] = rnds[8] & 63 | 128;
211
- if (buf) {
212
- offset = offset || 0;
213
- if (offset < 0 || offset + 16 > buf.length) {
214
- throw new RangeError(`UUID byte range ${offset}:${offset + 15} is out of buffer bounds`);
215
- }
216
- for (let i = 0; i < 16; ++i) {
217
- buf[offset + i] = rnds[i];
218
- }
219
- return buf;
220
- }
221
- return unsafeStringify(rnds);
222
- }
223
- var v4_default = v4;
224
-
225
178
  // src/adapters/thread/google-genai/model-invoker.ts
226
179
  function toFunctionDeclarations(tools) {
227
180
  return tools.map((t) => ({
@@ -252,7 +205,6 @@ function createGoogleGenAIModelInvoker({
252
205
  });
253
206
  const responseParts = response.candidates?.[0]?.content?.parts ?? [];
254
207
  const modelContent = { role: "model", parts: responseParts };
255
- await thread.appendModelContent(v4_default(), responseParts);
256
208
  const functionCalls = response.functionCalls ?? [];
257
209
  return {
258
210
  message: modelContent,
@@ -323,6 +275,14 @@ function createGoogleGenAIAdapter(config) {
323
275
  content
324
276
  );
325
277
  },
278
+ async appendAgentMessage(threadId, id, message, threadKey) {
279
+ const thread = createGoogleGenAIThreadManager({
280
+ redis,
281
+ threadId,
282
+ key: threadKey
283
+ });
284
+ await thread.appendModelContent(id, message.parts ?? []);
285
+ },
326
286
  async forkThread(sourceThreadId, targetThreadId, threadKey) {
327
287
  const thread = createGoogleGenAIThreadManager({
328
288
  redis,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/lib/thread/manager.ts","../../../../src/adapters/thread/google-genai/thread-manager.ts","../../../../node_modules/uuid/dist/esm/stringify.js","../../../../node_modules/uuid/dist/esm/rng.js","../../../../node_modules/uuid/dist/esm/native.js","../../../../node_modules/uuid/dist/esm/v4.js","../../../../src/adapters/thread/google-genai/model-invoker.ts","../../../../src/adapters/thread/google-genai/activities.ts"],"names":["randomFillSync","randomUUID","invokeGoogleGenAIModel"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { ThreadManagerConfig, BaseThreadManager } from \"./types\";\n\nconst THREAD_TTL_SECONDS = 60 * 60 * 24 * 90; // 90 days\n\n/**\n * Lua script for atomic idempotent append.\n * Checks a dedup key; if it exists the message was already appended and we\n * return 0. Otherwise appends all messages to the list, sets TTL on both\n * the list and the dedup key, and returns 1.\n *\n * KEYS[1] = dedup key, KEYS[2] = list key\n * ARGV[1] = TTL seconds, ARGV[2..N] = serialised messages\n */\nconst APPEND_IDEMPOTENT_SCRIPT = `\nif redis.call('EXISTS', KEYS[1]) == 1 then\n return 0\nend\nfor i = 2, #ARGV do\n redis.call('RPUSH', KEYS[2], ARGV[i])\nend\nredis.call('EXPIRE', KEYS[2], tonumber(ARGV[1]))\nredis.call('SET', KEYS[1], '1', 'EX', tonumber(ARGV[1]))\nreturn 1\n`;\n\nfunction getThreadKey(threadId: string, key: string): string {\n return `${key}:thread:${threadId}`;\n}\n\n/**\n * Creates a generic thread manager for handling conversation state in Redis.\n * Framework-agnostic — works with any serializable message type.\n */\nexport function createThreadManager<T>(\n config: ThreadManagerConfig<T>\n): BaseThreadManager<T> {\n const {\n redis,\n threadId,\n key = \"messages\",\n serialize = (m: T): string => JSON.stringify(m),\n deserialize = (raw: string): T => JSON.parse(raw) as T,\n idOf,\n } = config;\n const redisKey = getThreadKey(threadId, key);\n const metaKey = getThreadKey(threadId, `${key}:meta`);\n\n async function assertThreadExists(): Promise<void> {\n const exists = await redis.exists(metaKey);\n if (!exists) {\n throw new Error(`Thread \"${threadId}\" (key: ${key}) does not exist`);\n }\n }\n\n return {\n async initialize(): Promise<void> {\n await redis.del(redisKey);\n await redis.set(metaKey, \"1\", \"EX\", THREAD_TTL_SECONDS);\n },\n\n async load(): Promise<T[]> {\n await assertThreadExists();\n const data = await redis.lrange(redisKey, 0, -1);\n return data.map(deserialize);\n },\n\n async append(messages: T[]): Promise<void> {\n if (messages.length === 0) return;\n await assertThreadExists();\n\n if (idOf) {\n const dedupId = messages.map(idOf).join(\":\");\n const dedupKey = getThreadKey(threadId, `dedup:${dedupId}`);\n await redis.eval(\n APPEND_IDEMPOTENT_SCRIPT,\n 2,\n dedupKey,\n redisKey,\n String(THREAD_TTL_SECONDS),\n ...messages.map(serialize)\n );\n } else {\n await redis.rpush(redisKey, ...messages.map(serialize));\n await redis.expire(redisKey, THREAD_TTL_SECONDS);\n }\n },\n\n async fork(newThreadId: string): Promise<BaseThreadManager<T>> {\n await assertThreadExists();\n const data = await redis.lrange(redisKey, 0, -1);\n const forked = createThreadManager({\n ...config,\n threadId: newThreadId,\n });\n await forked.initialize();\n if (data.length > 0) {\n const newKey = getThreadKey(newThreadId, key);\n await redis.rpush(newKey, ...data);\n await redis.expire(newKey, THREAD_TTL_SECONDS);\n }\n return forked;\n },\n\n async delete(): Promise<void> {\n await redis.del(redisKey, metaKey);\n },\n };\n}\n","import type Redis from \"ioredis\";\nimport type { Content, Part } from \"@google/genai\";\nimport { createThreadManager } from \"../../../lib/thread/manager\";\nimport type {\n ProviderThreadManager,\n ThreadManagerConfig,\n ThreadManagerHooks,\n} from \"../../../lib/thread/types\";\nimport type { GoogleGenAIToolResponse } from \"./activities\";\n\n/** SDK-native content type for Google GenAI human messages */\nexport type GoogleGenAIContent = string | Part[];\n\n/** A Content with a unique ID for idempotent Redis storage */\nexport interface StoredContent {\n id: string;\n content: Content;\n}\n\nexport type GoogleGenAIThreadManagerHooks = ThreadManagerHooks<StoredContent, Content>;\n\nexport interface GoogleGenAIThreadManagerConfig {\n redis: Redis;\n threadId: string;\n /** Thread key, defaults to 'messages' */\n key?: string;\n hooks?: GoogleGenAIThreadManagerHooks;\n}\n\n/** Prepared payload ready to send to the Google GenAI API */\nexport interface GoogleGenAIInvocationPayload {\n contents: Content[];\n systemInstruction?: string;\n}\n\n/** Thread manager with Google GenAI Content convenience helpers */\nexport interface GoogleGenAIThreadManager\n extends ProviderThreadManager<StoredContent, GoogleGenAIContent, GoogleGenAIToolResponse> {\n appendModelContent(id: string, parts: Part[]): Promise<void>;\n prepareForInvocation(): Promise<GoogleGenAIInvocationPayload>;\n}\n\nfunction storedContentId(msg: StoredContent): string {\n return msg.id;\n}\n\n/** Normalise content into Part[] */\nfunction toParts(content: GoogleGenAIContent): Part[] {\n if (typeof content === \"string\") {\n return [{ text: content }];\n }\n return content;\n}\n\n/** Convert a string or object into a Record suitable for functionResponse.response */\nfunction toFunctionResponse(content: string | Record<string, unknown>): Record<string, unknown> {\n if (typeof content === \"object\") {\n return content;\n }\n return { result: content };\n}\n\n/**\n * Merge consecutive Content objects sharing the same role.\n * The Gemini API requires alternating user/model turns; without\n * merging, multiple sequential tool-result messages would violate this.\n */\nfunction mergeConsecutiveContents(contents: Content[]): Content[] {\n const merged: Content[] = [];\n for (const content of contents) {\n const last = merged[merged.length - 1];\n if (last && last.role === content.role) {\n last.parts = [...(last.parts ?? []), ...(content.parts ?? [])];\n } else {\n merged.push({ ...content, parts: [...(content.parts ?? [])] });\n }\n }\n return merged;\n}\n\n/**\n * Creates a Google GenAI-specific thread manager that stores StoredContent\n * instances in Redis and provides convenience helpers for creating and\n * appending typed Content messages.\n */\nexport function createGoogleGenAIThreadManager(\n config: GoogleGenAIThreadManagerConfig,\n): GoogleGenAIThreadManager {\n const baseConfig: ThreadManagerConfig<StoredContent> = {\n redis: config.redis,\n threadId: config.threadId,\n key: config.key,\n idOf: storedContentId,\n };\n\n const base = createThreadManager(baseConfig);\n\n const helpers: Omit<GoogleGenAIThreadManager, keyof typeof base> = {\n async appendUserMessage(\n id: string,\n content: GoogleGenAIContent,\n ): Promise<void> {\n await base.append([{\n id,\n content: { role: \"user\", parts: toParts(content) },\n }]);\n },\n\n async appendSystemMessage(id: string, content: string): Promise<void> {\n await base.initialize();\n await base.append([{\n id,\n content: { role: \"system\", parts: [{ text: content }] },\n }]);\n },\n\n async appendModelContent(id: string, parts: Part[]): Promise<void> {\n await base.append([{\n id,\n content: { role: \"model\", parts },\n }]);\n },\n\n async appendToolResult(\n id: string,\n toolCallId: string,\n toolName: string,\n content: GoogleGenAIToolResponse,\n ): Promise<void> {\n const parts: Part[] = Array.isArray(content)\n ? content as Part[]\n : [{\n functionResponse: {\n id: toolCallId,\n name: toolName,\n response: toFunctionResponse(content),\n },\n }];\n\n await base.append([{\n id,\n content: { role: \"user\", parts },\n }]);\n },\n\n async prepareForInvocation(): Promise<GoogleGenAIInvocationPayload> {\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 systemInstruction: string | undefined;\n const conversationContents: Content[] = [];\n\n for (const item of mapped) {\n if (item.content.role === \"system\") {\n systemInstruction = item.content.parts?.[0]?.text;\n } else {\n conversationContents.push(item.content);\n }\n }\n\n const contents = mergeConsecutiveContents(conversationContents);\n return {\n contents: onPreparedMessage\n ? contents.map((msg, i) => onPreparedMessage(msg, i, contents))\n : contents,\n ...(systemInstruction ? { systemInstruction } : {}),\n };\n },\n };\n\n return Object.assign(base, helpers);\n}\n","import validate from './validate.js';\nconst byteToHex = [];\nfor (let i = 0; i < 256; ++i) {\n byteToHex.push((i + 0x100).toString(16).slice(1));\n}\nexport function unsafeStringify(arr, offset = 0) {\n return (byteToHex[arr[offset + 0]] +\n byteToHex[arr[offset + 1]] +\n byteToHex[arr[offset + 2]] +\n byteToHex[arr[offset + 3]] +\n '-' +\n byteToHex[arr[offset + 4]] +\n byteToHex[arr[offset + 5]] +\n '-' +\n byteToHex[arr[offset + 6]] +\n byteToHex[arr[offset + 7]] +\n '-' +\n byteToHex[arr[offset + 8]] +\n byteToHex[arr[offset + 9]] +\n '-' +\n byteToHex[arr[offset + 10]] +\n byteToHex[arr[offset + 11]] +\n byteToHex[arr[offset + 12]] +\n byteToHex[arr[offset + 13]] +\n byteToHex[arr[offset + 14]] +\n byteToHex[arr[offset + 15]]).toLowerCase();\n}\nfunction stringify(arr, offset = 0) {\n const uuid = unsafeStringify(arr, offset);\n if (!validate(uuid)) {\n throw TypeError('Stringified UUID is invalid');\n }\n return uuid;\n}\nexport default stringify;\n","import { randomFillSync } from 'crypto';\nconst rnds8Pool = new Uint8Array(256);\nlet poolPtr = rnds8Pool.length;\nexport default function rng() {\n if (poolPtr > rnds8Pool.length - 16) {\n randomFillSync(rnds8Pool);\n poolPtr = 0;\n }\n return rnds8Pool.slice(poolPtr, (poolPtr += 16));\n}\n","import { randomUUID } from 'crypto';\nexport default { randomUUID };\n","import native from './native.js';\nimport rng from './rng.js';\nimport { unsafeStringify } from './stringify.js';\nfunction v4(options, buf, offset) {\n if (native.randomUUID && !buf && !options) {\n return native.randomUUID();\n }\n options = options || {};\n const rnds = options.random ?? options.rng?.() ?? rng();\n if (rnds.length < 16) {\n throw new Error('Random bytes length must be >= 16');\n }\n rnds[6] = (rnds[6] & 0x0f) | 0x40;\n rnds[8] = (rnds[8] & 0x3f) | 0x80;\n if (buf) {\n offset = offset || 0;\n if (offset < 0 || offset + 16 > buf.length) {\n throw new RangeError(`UUID byte range ${offset}:${offset + 15} is out of buffer bounds`);\n }\n for (let i = 0; i < 16; ++i) {\n buf[offset + i] = rnds[i];\n }\n return buf;\n }\n return unsafeStringify(rnds);\n}\nexport default v4;\n","import type Redis from \"ioredis\";\nimport type { GoogleGenAI, Content, FunctionDeclaration } from \"@google/genai\";\nimport type { SerializableToolDefinition } from \"../../../lib/types\";\nimport type { AgentResponse, ModelInvokerConfig } from \"../../../lib/model\";\nimport { createGoogleGenAIThreadManager, type GoogleGenAIThreadManagerHooks } from \"./thread-manager\";\nimport { v4 as uuidv4 } from \"uuid\";\n\nexport interface GoogleGenAIModelInvokerConfig {\n redis: Redis;\n client: GoogleGenAI;\n model: string;\n hooks?: GoogleGenAIThreadManagerHooks;\n}\n\nfunction toFunctionDeclarations(\n tools: SerializableToolDefinition[],\n): FunctionDeclaration[] {\n return tools.map((t) => ({\n name: t.name,\n description: t.description,\n parametersJsonSchema: t.schema,\n }));\n}\n\n/**\n * Creates a Google GenAI model invoker that satisfies the generic\n * `ModelInvoker<Content>` contract.\n *\n * Loads the conversation thread from Redis, invokes the Gemini model via\n * `client.models.generateContent`, appends the AI response, and returns\n * a normalised AgentResponse.\n *\n * @example\n * ```typescript\n * import { createGoogleGenAIModelInvoker } from 'zeitlich/adapters/thread/google-genai';\n * import { createRunAgentActivity } from 'zeitlich';\n * import { GoogleGenAI } from '@google/genai';\n *\n * const client = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });\n * const invoker = createGoogleGenAIModelInvoker({\n * redis,\n * client,\n * model: 'gemini-2.5-flash',\n * });\n *\n * return { runAgent: createRunAgentActivity(client, invoker) };\n * ```\n */\nexport function createGoogleGenAIModelInvoker({\n redis,\n client,\n model,\n hooks,\n}: GoogleGenAIModelInvokerConfig) {\n return async function invokeGoogleGenAIModel(\n config: ModelInvokerConfig,\n ): Promise<AgentResponse<Content>> {\n const { threadId, threadKey, state } = config;\n\n const thread = createGoogleGenAIThreadManager({ redis, threadId, key: threadKey, hooks });\n const { contents, systemInstruction } =\n await thread.prepareForInvocation();\n\n const functionDeclarations = toFunctionDeclarations(state.tools);\n const tools =\n functionDeclarations.length > 0 ? [{ functionDeclarations }] : undefined;\n\n const response = await client.models.generateContent({\n model,\n contents,\n config: {\n ...(systemInstruction ? { systemInstruction } : {}),\n ...(tools ? { tools } : {}),\n },\n });\n\n const responseParts = response.candidates?.[0]?.content?.parts ?? [];\n const modelContent: Content = { role: \"model\", parts: responseParts };\n\n await thread.appendModelContent(uuidv4(), responseParts);\n\n const functionCalls = response.functionCalls ?? [];\n\n return {\n message: modelContent,\n rawToolCalls: functionCalls.map((fc) => ({\n id: fc.id,\n name: fc.name ?? \"\",\n args: fc.args ?? {},\n })),\n usage: {\n inputTokens: response.usageMetadata?.promptTokenCount,\n outputTokens: response.usageMetadata?.candidatesTokenCount,\n cachedReadTokens: response.usageMetadata?.cachedContentTokenCount,\n },\n };\n };\n}\n\n/**\n * Standalone function for one-shot Google GenAI model invocation.\n * Convenience wrapper around createGoogleGenAIModelInvoker for cases\n * where you don't need to reuse the invoker.\n */\nexport async function invokeGoogleGenAIModel({\n redis,\n client,\n model,\n hooks,\n config,\n}: {\n redis: Redis;\n client: GoogleGenAI;\n model: string;\n hooks?: GoogleGenAIThreadManagerHooks;\n config: ModelInvokerConfig;\n}): Promise<AgentResponse<Content>> {\n const invoker = createGoogleGenAIModelInvoker({ redis, client, model, hooks });\n return invoker(config);\n}\n","import type Redis from \"ioredis\";\nimport type { GoogleGenAI, Content, Part } from \"@google/genai\";\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 createGoogleGenAIThreadManager,\n type GoogleGenAIContent,\n type GoogleGenAIThreadManagerHooks,\n} from \"./thread-manager\";\nimport { createGoogleGenAIModelInvoker } from \"./model-invoker\";\n\nconst ADAPTER_PREFIX = \"googleGenAI\" as const;\n\nexport type GoogleGenAIThreadOps<TScope extends string = \"\"> =\n PrefixedThreadOps<\n ScopedPrefix<TScope, typeof ADAPTER_PREFIX>,\n GoogleGenAIContent\n >;\n\nexport interface GoogleGenAIAdapterConfig {\n redis: Redis;\n client?: GoogleGenAI;\n /** Default model name (e.g. 'gemini-2.5-flash'). If omitted, use `createModelInvoker()` */\n model?: string;\n hooks?: GoogleGenAIThreadManagerHooks;\n}\n\n/**\n * Tool response type accepted by the Google GenAI adapter.\n *\n * Handlers can return:\n * - **`string`** — plain text, wrapped in a `functionResponse` part.\n * - **`Record<string, unknown>`** — structured object used as `functionResponse.response`.\n * - **`Part[]`** — pre-built parts used directly as `Content.parts`.\n * The handler is responsible for building correct Part objects (e.g. `functionResponse`,\n * `inlineData`, `text`). Use `context.toolCallId` and `context.toolName` to construct\n * `functionResponse` parts.\n *\n * @example\n * ```typescript\n * adapter.wrapHandler(async (args, ctx) => ({\n * toolResponse: [\n * { functionResponse: { id: ctx.toolCallId, name: ctx.toolName, response: { result: \"done\" } } },\n * { inlineData: { data: base64, mimeType: \"image/png\" } },\n * ],\n * data: null,\n * }));\n * ```\n */\nexport type GoogleGenAIToolResponse = string | Record<string, unknown> | Part[];\n\nexport interface GoogleGenAIAdapter {\n /** Model invoker using the default model (only available when `model` was provided) */\n invoker: ModelInvoker<Content>;\n /** Create an invoker for a specific model name (for multi-model setups) */\n createModelInvoker(model: string, client: GoogleGenAI): ModelInvoker<Content>;\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 * // → { googleGenAICodingAgentInitializeThread, googleGenAICodingAgentAppendHumanMessage, … }\n *\n * adapter.createActivities(\"researchAgent\")\n * // → { googleGenAIResearchAgentInitializeThread, … }\n * ```\n */\n createActivities<S extends string = \"\">(scope?: S): GoogleGenAIThreadOps<S>;\n\n /**\n * Identity wrapper that types a tool handler for this adapter.\n * Constrains `toolResponse` to {@link GoogleGenAIToolResponse}.\n */\n wrapHandler<TArgs, TResult, TContext extends RouterContext = RouterContext>(\n handler: (\n args: TArgs,\n context: TContext\n ) => Promise<ToolHandlerResponse<TResult, GoogleGenAIToolResponse>>\n ): ActivityToolHandler<TArgs, TResult, TContext, GoogleGenAIToolResponse>;\n}\n\n/**\n * Creates a Google GenAI adapter that bundles thread operations and model\n * invocation using the `@google/genai` 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 { createGoogleGenAIAdapter } from 'zeitlich/adapters/thread/google-genai';\n * import { createRunAgentActivity } from 'zeitlich';\n * import { GoogleGenAI } from '@google/genai';\n *\n * const client = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });\n * const adapter = createGoogleGenAIAdapter({ redis, client, model: 'gemini-2.5-flash' });\n *\n * export function createActivities(temporalClient: WorkflowClient) {\n * return {\n * ...adapter.createActivities(\"codingAgent\"),\n * runCodingAgent: createRunAgentActivity(temporalClient, adapter.invoker),\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 * runCodingAgent: createRunAgentActivity(temporalClient, adapter.invoker),\n * runResearchAgent: createRunAgentActivity(\n * temporalClient,\n * adapter.createModelInvoker('gemini-2.5-pro'),\n * ),\n * };\n * }\n * ```\n */\nexport function createGoogleGenAIAdapter(\n config: GoogleGenAIAdapterConfig\n): GoogleGenAIAdapter {\n const { redis } = config;\n\n const threadOps: ThreadOps<GoogleGenAIContent> = {\n async initializeThread(\n threadId: string,\n threadKey?: string\n ): Promise<void> {\n const thread = createGoogleGenAIThreadManager({\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: GoogleGenAIContent,\n threadKey?: string\n ): Promise<void> {\n const thread = createGoogleGenAIThreadManager({\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: string,\n threadKey?: string\n ): Promise<void> {\n const thread = createGoogleGenAIThreadManager({\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 = createGoogleGenAIThreadManager({\n redis,\n threadId,\n key: threadKey,\n });\n await thread.appendToolResult(\n id,\n toolCallId,\n toolName,\n content as GoogleGenAIToolResponse\n );\n },\n\n async forkThread(\n sourceThreadId: string,\n targetThreadId: string,\n threadKey?: string\n ): Promise<void> {\n const thread = createGoogleGenAIThreadManager({\n redis,\n threadId: sourceThreadId,\n key: threadKey,\n });\n await thread.fork(targetThreadId);\n },\n };\n\n function createActivities<S extends string = \"\">(\n scope?: S\n ): GoogleGenAIThreadOps<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 GoogleGenAIThreadOps<S>;\n }\n\n const makeInvoker = (\n model: string,\n client: GoogleGenAI\n ): ModelInvoker<Content> =>\n createGoogleGenAIModelInvoker({ redis, client, model, hooks: config.hooks });\n\n const invoker: ModelInvoker<Content> =\n config.model && config.client\n ? makeInvoker(config.model, config.client)\n : ((() => {\n throw new Error(\n \"No default model provided to createGoogleGenAIAdapter. \" +\n \"Either pass `model` in the config or use `createModelInvoker(model)` instead.\"\n );\n }) as unknown as ModelInvoker<Content>);\n\n return {\n createActivities,\n invoker,\n createModelInvoker: makeInvoker,\n wrapHandler: (handler) => handler,\n };\n}\n"]}
1
+ {"version":3,"sources":["../../../../src/lib/thread/manager.ts","../../../../src/adapters/thread/google-genai/thread-manager.ts","../../../../src/adapters/thread/google-genai/model-invoker.ts","../../../../src/adapters/thread/google-genai/activities.ts"],"names":["invokeGoogleGenAIModel"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { ThreadManagerConfig, BaseThreadManager } from \"./types\";\n\nconst THREAD_TTL_SECONDS = 60 * 60 * 24 * 90; // 90 days\n\n/**\n * Lua script for atomic idempotent append.\n * Checks a dedup key; if it exists the message was already appended and we\n * return 0. Otherwise appends all messages to the list, sets TTL on both\n * the list and the dedup key, and returns 1.\n *\n * KEYS[1] = dedup key, KEYS[2] = list key\n * ARGV[1] = TTL seconds, ARGV[2..N] = serialised messages\n */\nconst APPEND_IDEMPOTENT_SCRIPT = `\nif redis.call('EXISTS', KEYS[1]) == 1 then\n return 0\nend\nfor i = 2, #ARGV do\n redis.call('RPUSH', KEYS[2], ARGV[i])\nend\nredis.call('EXPIRE', KEYS[2], tonumber(ARGV[1]))\nredis.call('SET', KEYS[1], '1', 'EX', tonumber(ARGV[1]))\nreturn 1\n`;\n\nfunction getThreadKey(threadId: string, key: string): string {\n return `${key}:thread:${threadId}`;\n}\n\n/**\n * Creates a generic thread manager for handling conversation state in Redis.\n * Framework-agnostic — works with any serializable message type.\n */\nexport function createThreadManager<T>(\n config: ThreadManagerConfig<T>\n): BaseThreadManager<T> {\n const {\n redis,\n threadId,\n key = \"messages\",\n serialize = (m: T): string => JSON.stringify(m),\n deserialize = (raw: string): T => JSON.parse(raw) as T,\n idOf,\n } = config;\n const redisKey = getThreadKey(threadId, key);\n const metaKey = getThreadKey(threadId, `${key}:meta`);\n\n async function assertThreadExists(): Promise<void> {\n const exists = await redis.exists(metaKey);\n if (!exists) {\n throw new Error(`Thread \"${threadId}\" (key: ${key}) does not exist`);\n }\n }\n\n return {\n async initialize(): Promise<void> {\n await redis.del(redisKey);\n await redis.set(metaKey, \"1\", \"EX\", THREAD_TTL_SECONDS);\n },\n\n async load(): Promise<T[]> {\n await assertThreadExists();\n const data = await redis.lrange(redisKey, 0, -1);\n return data.map(deserialize);\n },\n\n async append(messages: T[]): Promise<void> {\n if (messages.length === 0) return;\n await assertThreadExists();\n\n if (idOf) {\n const dedupId = messages.map(idOf).join(\":\");\n const dedupKey = getThreadKey(threadId, `dedup:${dedupId}`);\n await redis.eval(\n APPEND_IDEMPOTENT_SCRIPT,\n 2,\n dedupKey,\n redisKey,\n String(THREAD_TTL_SECONDS),\n ...messages.map(serialize)\n );\n } else {\n await redis.rpush(redisKey, ...messages.map(serialize));\n await redis.expire(redisKey, THREAD_TTL_SECONDS);\n }\n },\n\n async fork(newThreadId: string): Promise<BaseThreadManager<T>> {\n await assertThreadExists();\n const data = await redis.lrange(redisKey, 0, -1);\n const forked = createThreadManager({\n ...config,\n threadId: newThreadId,\n });\n await forked.initialize();\n if (data.length > 0) {\n const newKey = getThreadKey(newThreadId, key);\n await redis.rpush(newKey, ...data);\n await redis.expire(newKey, THREAD_TTL_SECONDS);\n }\n return forked;\n },\n\n async delete(): Promise<void> {\n await redis.del(redisKey, metaKey);\n },\n };\n}\n","import type Redis from \"ioredis\";\nimport type { Content, Part } from \"@google/genai\";\nimport { createThreadManager } from \"../../../lib/thread/manager\";\nimport type {\n ProviderThreadManager,\n ThreadManagerConfig,\n ThreadManagerHooks,\n} from \"../../../lib/thread/types\";\nimport type { GoogleGenAIToolResponse } from \"./activities\";\n\n/** SDK-native content type for Google GenAI human messages */\nexport type GoogleGenAIContent = string | Part[];\n\n/** A Content with a unique ID for idempotent Redis storage */\nexport interface StoredContent {\n id: string;\n content: Content;\n}\n\nexport type GoogleGenAIThreadManagerHooks = ThreadManagerHooks<StoredContent, Content>;\n\nexport interface GoogleGenAIThreadManagerConfig {\n redis: Redis;\n threadId: string;\n /** Thread key, defaults to 'messages' */\n key?: string;\n hooks?: GoogleGenAIThreadManagerHooks;\n}\n\n/** Prepared payload ready to send to the Google GenAI API */\nexport interface GoogleGenAIInvocationPayload {\n contents: Content[];\n systemInstruction?: string;\n}\n\n/** Thread manager with Google GenAI Content convenience helpers */\nexport interface GoogleGenAIThreadManager\n extends ProviderThreadManager<StoredContent, GoogleGenAIContent, GoogleGenAIToolResponse> {\n appendModelContent(id: string, parts: Part[]): Promise<void>;\n prepareForInvocation(): Promise<GoogleGenAIInvocationPayload>;\n}\n\nfunction storedContentId(msg: StoredContent): string {\n return msg.id;\n}\n\n/** Normalise content into Part[] */\nfunction toParts(content: GoogleGenAIContent): Part[] {\n if (typeof content === \"string\") {\n return [{ text: content }];\n }\n return content;\n}\n\n/** Convert a string or object into a Record suitable for functionResponse.response */\nfunction toFunctionResponse(content: string | Record<string, unknown>): Record<string, unknown> {\n if (typeof content === \"object\") {\n return content;\n }\n return { result: content };\n}\n\n/**\n * Merge consecutive Content objects sharing the same role.\n * The Gemini API requires alternating user/model turns; without\n * merging, multiple sequential tool-result messages would violate this.\n */\nfunction mergeConsecutiveContents(contents: Content[]): Content[] {\n const merged: Content[] = [];\n for (const content of contents) {\n const last = merged[merged.length - 1];\n if (last && last.role === content.role) {\n last.parts = [...(last.parts ?? []), ...(content.parts ?? [])];\n } else {\n merged.push({ ...content, parts: [...(content.parts ?? [])] });\n }\n }\n return merged;\n}\n\n/**\n * Creates a Google GenAI-specific thread manager that stores StoredContent\n * instances in Redis and provides convenience helpers for creating and\n * appending typed Content messages.\n */\nexport function createGoogleGenAIThreadManager(\n config: GoogleGenAIThreadManagerConfig,\n): GoogleGenAIThreadManager {\n const baseConfig: ThreadManagerConfig<StoredContent> = {\n redis: config.redis,\n threadId: config.threadId,\n key: config.key,\n idOf: storedContentId,\n };\n\n const base = createThreadManager(baseConfig);\n\n const helpers: Omit<GoogleGenAIThreadManager, keyof typeof base> = {\n async appendUserMessage(\n id: string,\n content: GoogleGenAIContent,\n ): Promise<void> {\n await base.append([{\n id,\n content: { role: \"user\", parts: toParts(content) },\n }]);\n },\n\n async appendSystemMessage(id: string, content: string): Promise<void> {\n await base.initialize();\n await base.append([{\n id,\n content: { role: \"system\", parts: [{ text: content }] },\n }]);\n },\n\n async appendModelContent(id: string, parts: Part[]): Promise<void> {\n await base.append([{\n id,\n content: { role: \"model\", parts },\n }]);\n },\n\n async appendToolResult(\n id: string,\n toolCallId: string,\n toolName: string,\n content: GoogleGenAIToolResponse,\n ): Promise<void> {\n const parts: Part[] = Array.isArray(content)\n ? content as Part[]\n : [{\n functionResponse: {\n id: toolCallId,\n name: toolName,\n response: toFunctionResponse(content),\n },\n }];\n\n await base.append([{\n id,\n content: { role: \"user\", parts },\n }]);\n },\n\n async prepareForInvocation(): Promise<GoogleGenAIInvocationPayload> {\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 systemInstruction: string | undefined;\n const conversationContents: Content[] = [];\n\n for (const item of mapped) {\n if (item.content.role === \"system\") {\n systemInstruction = item.content.parts?.[0]?.text;\n } else {\n conversationContents.push(item.content);\n }\n }\n\n const contents = mergeConsecutiveContents(conversationContents);\n return {\n contents: onPreparedMessage\n ? contents.map((msg, i) => onPreparedMessage(msg, i, contents))\n : contents,\n ...(systemInstruction ? { systemInstruction } : {}),\n };\n },\n };\n\n return Object.assign(base, helpers);\n}\n","import type Redis from \"ioredis\";\nimport type { GoogleGenAI, Content, FunctionDeclaration } from \"@google/genai\";\nimport type { SerializableToolDefinition } from \"../../../lib/types\";\nimport type { AgentResponse, ModelInvokerConfig } from \"../../../lib/model\";\nimport { createGoogleGenAIThreadManager, type GoogleGenAIThreadManagerHooks } from \"./thread-manager\";\n\nexport interface GoogleGenAIModelInvokerConfig {\n redis: Redis;\n client: GoogleGenAI;\n model: string;\n hooks?: GoogleGenAIThreadManagerHooks;\n}\n\nfunction toFunctionDeclarations(\n tools: SerializableToolDefinition[],\n): FunctionDeclaration[] {\n return tools.map((t) => ({\n name: t.name,\n description: t.description,\n parametersJsonSchema: t.schema,\n }));\n}\n\n/**\n * Creates a Google GenAI model invoker that satisfies the generic\n * `ModelInvoker<Content>` contract.\n *\n * Loads the conversation thread from Redis, invokes the Gemini model via\n * `client.models.generateContent`, and returns a normalised AgentResponse.\n * The caller is responsible for appending the response to the thread.\n *\n * @example\n * ```typescript\n * import { createGoogleGenAIModelInvoker } from 'zeitlich/adapters/thread/google-genai';\n * import { createRunAgentActivity } from 'zeitlich';\n * import { GoogleGenAI } from '@google/genai';\n *\n * const client = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });\n * const invoker = createGoogleGenAIModelInvoker({\n * redis,\n * client,\n * model: 'gemini-2.5-flash',\n * });\n *\n * return { runAgent: createRunAgentActivity(client, invoker) };\n * ```\n */\nexport function createGoogleGenAIModelInvoker({\n redis,\n client,\n model,\n hooks,\n}: GoogleGenAIModelInvokerConfig) {\n return async function invokeGoogleGenAIModel(\n config: ModelInvokerConfig,\n ): Promise<AgentResponse<Content>> {\n const { threadId, threadKey, state } = config;\n\n const thread = createGoogleGenAIThreadManager({ redis, threadId, key: threadKey, hooks });\n const { contents, systemInstruction } =\n await thread.prepareForInvocation();\n\n const functionDeclarations = toFunctionDeclarations(state.tools);\n const tools =\n functionDeclarations.length > 0 ? [{ functionDeclarations }] : undefined;\n\n const response = await client.models.generateContent({\n model,\n contents,\n config: {\n ...(systemInstruction ? { systemInstruction } : {}),\n ...(tools ? { tools } : {}),\n },\n });\n\n const responseParts = response.candidates?.[0]?.content?.parts ?? [];\n const modelContent: Content = { role: \"model\", parts: responseParts };\n\n const functionCalls = response.functionCalls ?? [];\n\n return {\n message: modelContent,\n rawToolCalls: functionCalls.map((fc) => ({\n id: fc.id,\n name: fc.name ?? \"\",\n args: fc.args ?? {},\n })),\n usage: {\n inputTokens: response.usageMetadata?.promptTokenCount,\n outputTokens: response.usageMetadata?.candidatesTokenCount,\n cachedReadTokens: response.usageMetadata?.cachedContentTokenCount,\n },\n };\n };\n}\n\n/**\n * Standalone function for one-shot Google GenAI model invocation.\n * Convenience wrapper around createGoogleGenAIModelInvoker for cases\n * where you don't need to reuse the invoker.\n */\nexport async function invokeGoogleGenAIModel({\n redis,\n client,\n model,\n hooks,\n config,\n}: {\n redis: Redis;\n client: GoogleGenAI;\n model: string;\n hooks?: GoogleGenAIThreadManagerHooks;\n config: ModelInvokerConfig;\n}): Promise<AgentResponse<Content>> {\n const invoker = createGoogleGenAIModelInvoker({ redis, client, model, hooks });\n return invoker(config);\n}\n","import type Redis from \"ioredis\";\nimport type { GoogleGenAI, Content, Part } from \"@google/genai\";\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 createGoogleGenAIThreadManager,\n type GoogleGenAIContent,\n type GoogleGenAIThreadManagerHooks,\n} from \"./thread-manager\";\nimport { createGoogleGenAIModelInvoker } from \"./model-invoker\";\n\nconst ADAPTER_PREFIX = \"googleGenAI\" as const;\n\nexport type GoogleGenAIThreadOps<TScope extends string = \"\"> =\n PrefixedThreadOps<\n ScopedPrefix<TScope, typeof ADAPTER_PREFIX>,\n GoogleGenAIContent\n >;\n\nexport interface GoogleGenAIAdapterConfig {\n redis: Redis;\n client?: GoogleGenAI;\n /** Default model name (e.g. 'gemini-2.5-flash'). If omitted, use `createModelInvoker()` */\n model?: string;\n hooks?: GoogleGenAIThreadManagerHooks;\n}\n\n/**\n * Tool response type accepted by the Google GenAI adapter.\n *\n * Handlers can return:\n * - **`string`** — plain text, wrapped in a `functionResponse` part.\n * - **`Record<string, unknown>`** — structured object used as `functionResponse.response`.\n * - **`Part[]`** — pre-built parts used directly as `Content.parts`.\n * The handler is responsible for building correct Part objects (e.g. `functionResponse`,\n * `inlineData`, `text`). Use `context.toolCallId` and `context.toolName` to construct\n * `functionResponse` parts.\n *\n * @example\n * ```typescript\n * adapter.wrapHandler(async (args, ctx) => ({\n * toolResponse: [\n * { functionResponse: { id: ctx.toolCallId, name: ctx.toolName, response: { result: \"done\" } } },\n * { inlineData: { data: base64, mimeType: \"image/png\" } },\n * ],\n * data: null,\n * }));\n * ```\n */\nexport type GoogleGenAIToolResponse = string | Record<string, unknown> | Part[];\n\nexport interface GoogleGenAIAdapter {\n /** Model invoker using the default model (only available when `model` was provided) */\n invoker: ModelInvoker<Content>;\n /** Create an invoker for a specific model name (for multi-model setups) */\n createModelInvoker(model: string, client: GoogleGenAI): ModelInvoker<Content>;\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 * // → { googleGenAICodingAgentInitializeThread, googleGenAICodingAgentAppendHumanMessage, … }\n *\n * adapter.createActivities(\"researchAgent\")\n * // → { googleGenAIResearchAgentInitializeThread, … }\n * ```\n */\n createActivities<S extends string = \"\">(scope?: S): GoogleGenAIThreadOps<S>;\n\n /**\n * Identity wrapper that types a tool handler for this adapter.\n * Constrains `toolResponse` to {@link GoogleGenAIToolResponse}.\n */\n wrapHandler<TArgs, TResult, TContext extends RouterContext = RouterContext>(\n handler: (\n args: TArgs,\n context: TContext\n ) => Promise<ToolHandlerResponse<TResult, GoogleGenAIToolResponse>>\n ): ActivityToolHandler<TArgs, TResult, TContext, GoogleGenAIToolResponse>;\n}\n\n/**\n * Creates a Google GenAI adapter that bundles thread operations and model\n * invocation using the `@google/genai` 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 { createGoogleGenAIAdapter } from 'zeitlich/adapters/thread/google-genai';\n * import { createRunAgentActivity } from 'zeitlich';\n * import { GoogleGenAI } from '@google/genai';\n *\n * const client = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });\n * const adapter = createGoogleGenAIAdapter({ redis, client, model: 'gemini-2.5-flash' });\n *\n * export function createActivities(temporalClient: WorkflowClient) {\n * return {\n * ...adapter.createActivities(\"codingAgent\"),\n * runCodingAgent: createRunAgentActivity(temporalClient, adapter.invoker),\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 * runCodingAgent: createRunAgentActivity(temporalClient, adapter.invoker),\n * runResearchAgent: createRunAgentActivity(\n * temporalClient,\n * adapter.createModelInvoker('gemini-2.5-pro'),\n * ),\n * };\n * }\n * ```\n */\nexport function createGoogleGenAIAdapter(\n config: GoogleGenAIAdapterConfig\n): GoogleGenAIAdapter {\n const { redis } = config;\n\n const threadOps: ThreadOps<GoogleGenAIContent> = {\n async initializeThread(\n threadId: string,\n threadKey?: string\n ): Promise<void> {\n const thread = createGoogleGenAIThreadManager({\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: GoogleGenAIContent,\n threadKey?: string\n ): Promise<void> {\n const thread = createGoogleGenAIThreadManager({\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: string,\n threadKey?: string\n ): Promise<void> {\n const thread = createGoogleGenAIThreadManager({\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 = createGoogleGenAIThreadManager({\n redis,\n threadId,\n key: threadKey,\n });\n await thread.appendToolResult(\n id,\n toolCallId,\n toolName,\n content as GoogleGenAIToolResponse\n );\n },\n\n async appendAgentMessage(\n threadId: string,\n id: string,\n message: Content,\n threadKey?: string,\n ): Promise<void> {\n const thread = createGoogleGenAIThreadManager({\n redis,\n threadId,\n key: threadKey,\n });\n await thread.appendModelContent(id, message.parts ?? []);\n },\n\n async forkThread(\n sourceThreadId: string,\n targetThreadId: string,\n threadKey?: string\n ): Promise<void> {\n const thread = createGoogleGenAIThreadManager({\n redis,\n threadId: sourceThreadId,\n key: threadKey,\n });\n await thread.fork(targetThreadId);\n },\n };\n\n function createActivities<S extends string = \"\">(\n scope?: S\n ): GoogleGenAIThreadOps<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 GoogleGenAIThreadOps<S>;\n }\n\n const makeInvoker = (\n model: string,\n client: GoogleGenAI\n ): ModelInvoker<Content> =>\n createGoogleGenAIModelInvoker({ redis, client, model, hooks: config.hooks });\n\n const invoker: ModelInvoker<Content> =\n config.model && config.client\n ? makeInvoker(config.model, config.client)\n : ((() => {\n throw new Error(\n \"No default model provided to createGoogleGenAIAdapter. \" +\n \"Either pass `model` in the config or use `createModelInvoker(model)` instead.\"\n );\n }) as unknown as ModelInvoker<Content>);\n\n return {\n createActivities,\n invoker,\n createModelInvoker: makeInvoker,\n wrapHandler: (handler) => handler,\n };\n}\n"]}
@@ -1,9 +1,9 @@
1
- import { G as GoogleGenAIThreadManagerHooks } from '../../../activities-qPkJDAiq.cjs';
2
- export { a as GoogleGenAIAdapter, b as GoogleGenAIAdapterConfig, c as GoogleGenAIContent, d as GoogleGenAIInvocationPayload, e as GoogleGenAIThreadManager, f as GoogleGenAIThreadManagerConfig, g as GoogleGenAIThreadOps, h as GoogleGenAIToolResponse, S as StoredContent, i as createGoogleGenAIAdapter, j as createGoogleGenAIThreadManager } from '../../../activities-qPkJDAiq.cjs';
1
+ import { G as GoogleGenAIThreadManagerHooks } from '../../../activities-DA-bQM12.cjs';
2
+ export { a as GoogleGenAIAdapter, b as GoogleGenAIAdapterConfig, c as GoogleGenAIContent, d as GoogleGenAIInvocationPayload, e as GoogleGenAIThreadManager, f as GoogleGenAIThreadManagerConfig, g as GoogleGenAIThreadOps, h as GoogleGenAIToolResponse, S as StoredContent, i as createGoogleGenAIAdapter, j as createGoogleGenAIThreadManager } from '../../../activities-DA-bQM12.cjs';
3
3
  import Redis from 'ioredis';
4
4
  import { GoogleGenAI, Content } from '@google/genai';
5
- import { M as ModelInvokerConfig, A as AgentResponse } from '../../../types-CjeGWQm1.cjs';
6
- import '../../../types-e_38QaKo.cjs';
5
+ import { M as ModelInvokerConfig, A as AgentResponse } from '../../../types-Bpq5fDI5.cjs';
6
+ import '../../../types-NJDyMyUx.cjs';
7
7
  import '@temporalio/common';
8
8
  import '@temporalio/workflow';
9
9
  import '@temporalio/common/lib/interfaces';
@@ -21,8 +21,8 @@ interface GoogleGenAIModelInvokerConfig {
21
21
  * `ModelInvoker<Content>` contract.
22
22
  *
23
23
  * Loads the conversation thread from Redis, invokes the Gemini model via
24
- * `client.models.generateContent`, appends the AI response, and returns
25
- * a normalised AgentResponse.
24
+ * `client.models.generateContent`, and returns a normalised AgentResponse.
25
+ * The caller is responsible for appending the response to the thread.
26
26
  *
27
27
  * @example
28
28
  * ```typescript
@@ -1,9 +1,9 @@
1
- import { G as GoogleGenAIThreadManagerHooks } from '../../../activities-DRSdt8Y3.js';
2
- export { a as GoogleGenAIAdapter, b as GoogleGenAIAdapterConfig, c as GoogleGenAIContent, d as GoogleGenAIInvocationPayload, e as GoogleGenAIThreadManager, f as GoogleGenAIThreadManagerConfig, g as GoogleGenAIThreadOps, h as GoogleGenAIToolResponse, S as StoredContent, i as createGoogleGenAIAdapter, j as createGoogleGenAIThreadManager } from '../../../activities-DRSdt8Y3.js';
1
+ import { G as GoogleGenAIThreadManagerHooks } from '../../../activities-FIXVz7DT.js';
2
+ export { a as GoogleGenAIAdapter, b as GoogleGenAIAdapterConfig, c as GoogleGenAIContent, d as GoogleGenAIInvocationPayload, e as GoogleGenAIThreadManager, f as GoogleGenAIThreadManagerConfig, g as GoogleGenAIThreadOps, h as GoogleGenAIToolResponse, S as StoredContent, i as createGoogleGenAIAdapter, j as createGoogleGenAIThreadManager } from '../../../activities-FIXVz7DT.js';
3
3
  import Redis from 'ioredis';
4
4
  import { GoogleGenAI, Content } from '@google/genai';
5
- import { M as ModelInvokerConfig, A as AgentResponse } from '../../../types-BmS-Huc0.js';
6
- import '../../../types-D6UKZZtj.js';
5
+ import { M as ModelInvokerConfig, A as AgentResponse } from '../../../types-CheCTLeV.js';
6
+ import '../../../types-BxiT8w9d.js';
7
7
  import '@temporalio/common';
8
8
  import '@temporalio/workflow';
9
9
  import '@temporalio/common/lib/interfaces';
@@ -21,8 +21,8 @@ interface GoogleGenAIModelInvokerConfig {
21
21
  * `ModelInvoker<Content>` contract.
22
22
  *
23
23
  * Loads the conversation thread from Redis, invokes the Gemini model via
24
- * `client.models.generateContent`, appends the AI response, and returns
25
- * a normalised AgentResponse.
24
+ * `client.models.generateContent`, and returns a normalised AgentResponse.
25
+ * The caller is responsible for appending the response to the thread.
26
26
  *
27
27
  * @example
28
28
  * ```typescript
@@ -1,5 +1,3 @@
1
- import { randomUUID, randomFillSync } from 'crypto';
2
-
3
1
  // src/lib/thread/manager.ts
4
2
  var THREAD_TTL_SECONDS = 60 * 60 * 24 * 90;
5
3
  var APPEND_IDEMPOTENT_SCRIPT = `
@@ -175,51 +173,6 @@ function createGoogleGenAIThreadManager(config) {
175
173
  return Object.assign(base, helpers);
176
174
  }
177
175
 
178
- // node_modules/uuid/dist/esm/stringify.js
179
- var byteToHex = [];
180
- for (let i = 0; i < 256; ++i) {
181
- byteToHex.push((i + 256).toString(16).slice(1));
182
- }
183
- function unsafeStringify(arr, offset = 0) {
184
- return (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase();
185
- }
186
- var rnds8Pool = new Uint8Array(256);
187
- var poolPtr = rnds8Pool.length;
188
- function rng() {
189
- if (poolPtr > rnds8Pool.length - 16) {
190
- randomFillSync(rnds8Pool);
191
- poolPtr = 0;
192
- }
193
- return rnds8Pool.slice(poolPtr, poolPtr += 16);
194
- }
195
- var native_default = { randomUUID };
196
-
197
- // node_modules/uuid/dist/esm/v4.js
198
- function v4(options, buf, offset) {
199
- if (native_default.randomUUID && !buf && !options) {
200
- return native_default.randomUUID();
201
- }
202
- options = options || {};
203
- const rnds = options.random ?? options.rng?.() ?? rng();
204
- if (rnds.length < 16) {
205
- throw new Error("Random bytes length must be >= 16");
206
- }
207
- rnds[6] = rnds[6] & 15 | 64;
208
- rnds[8] = rnds[8] & 63 | 128;
209
- if (buf) {
210
- offset = offset || 0;
211
- if (offset < 0 || offset + 16 > buf.length) {
212
- throw new RangeError(`UUID byte range ${offset}:${offset + 15} is out of buffer bounds`);
213
- }
214
- for (let i = 0; i < 16; ++i) {
215
- buf[offset + i] = rnds[i];
216
- }
217
- return buf;
218
- }
219
- return unsafeStringify(rnds);
220
- }
221
- var v4_default = v4;
222
-
223
176
  // src/adapters/thread/google-genai/model-invoker.ts
224
177
  function toFunctionDeclarations(tools) {
225
178
  return tools.map((t) => ({
@@ -250,7 +203,6 @@ function createGoogleGenAIModelInvoker({
250
203
  });
251
204
  const responseParts = response.candidates?.[0]?.content?.parts ?? [];
252
205
  const modelContent = { role: "model", parts: responseParts };
253
- await thread.appendModelContent(v4_default(), responseParts);
254
206
  const functionCalls = response.functionCalls ?? [];
255
207
  return {
256
208
  message: modelContent,
@@ -321,6 +273,14 @@ function createGoogleGenAIAdapter(config) {
321
273
  content
322
274
  );
323
275
  },
276
+ async appendAgentMessage(threadId, id, message, threadKey) {
277
+ const thread = createGoogleGenAIThreadManager({
278
+ redis,
279
+ threadId,
280
+ key: threadKey
281
+ });
282
+ await thread.appendModelContent(id, message.parts ?? []);
283
+ },
324
284
  async forkThread(sourceThreadId, targetThreadId, threadKey) {
325
285
  const thread = createGoogleGenAIThreadManager({
326
286
  redis,