zeitlich 0.2.36 → 0.2.37
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.
- package/README.md +146 -92
- package/dist/{activities-BVI2lTwr.d.ts → activities-Bb-nAjwQ.d.ts} +2 -2
- package/dist/{activities-hd4aNnZE.d.cts → activities-vkI4_3CC.d.cts} +2 -2
- package/dist/adapters/sandbox/bedrock/index.cjs +14 -11
- package/dist/adapters/sandbox/bedrock/index.cjs.map +1 -1
- package/dist/adapters/sandbox/bedrock/index.d.cts +4 -3
- package/dist/adapters/sandbox/bedrock/index.d.ts +4 -3
- package/dist/adapters/sandbox/bedrock/index.js +14 -11
- package/dist/adapters/sandbox/bedrock/index.js.map +1 -1
- package/dist/adapters/sandbox/bedrock/workflow.cjs +2 -0
- package/dist/adapters/sandbox/bedrock/workflow.cjs.map +1 -1
- package/dist/adapters/sandbox/bedrock/workflow.d.cts +2 -2
- package/dist/adapters/sandbox/bedrock/workflow.d.ts +2 -2
- package/dist/adapters/sandbox/bedrock/workflow.js +2 -0
- package/dist/adapters/sandbox/bedrock/workflow.js.map +1 -1
- package/dist/adapters/sandbox/daytona/index.cjs +8 -0
- package/dist/adapters/sandbox/daytona/index.cjs.map +1 -1
- package/dist/adapters/sandbox/daytona/index.d.cts +2 -1
- package/dist/adapters/sandbox/daytona/index.d.ts +2 -1
- package/dist/adapters/sandbox/daytona/index.js +8 -0
- package/dist/adapters/sandbox/daytona/index.js.map +1 -1
- package/dist/adapters/sandbox/daytona/workflow.cjs +2 -0
- package/dist/adapters/sandbox/daytona/workflow.cjs.map +1 -1
- package/dist/adapters/sandbox/daytona/workflow.d.cts +1 -1
- package/dist/adapters/sandbox/daytona/workflow.d.ts +1 -1
- package/dist/adapters/sandbox/daytona/workflow.js +2 -0
- package/dist/adapters/sandbox/daytona/workflow.js.map +1 -1
- package/dist/adapters/sandbox/e2b/index.cjs +59 -10
- package/dist/adapters/sandbox/e2b/index.cjs.map +1 -1
- package/dist/adapters/sandbox/e2b/index.d.cts +5 -3
- package/dist/adapters/sandbox/e2b/index.d.ts +5 -3
- package/dist/adapters/sandbox/e2b/index.js +59 -10
- package/dist/adapters/sandbox/e2b/index.js.map +1 -1
- package/dist/adapters/sandbox/e2b/workflow.cjs +2 -0
- package/dist/adapters/sandbox/e2b/workflow.cjs.map +1 -1
- package/dist/adapters/sandbox/e2b/workflow.d.cts +1 -1
- package/dist/adapters/sandbox/e2b/workflow.d.ts +1 -1
- package/dist/adapters/sandbox/e2b/workflow.js +2 -0
- package/dist/adapters/sandbox/e2b/workflow.js.map +1 -1
- package/dist/adapters/sandbox/inmemory/index.cjs +5 -0
- package/dist/adapters/sandbox/inmemory/index.cjs.map +1 -1
- package/dist/adapters/sandbox/inmemory/index.d.cts +2 -1
- package/dist/adapters/sandbox/inmemory/index.d.ts +2 -1
- package/dist/adapters/sandbox/inmemory/index.js +5 -0
- package/dist/adapters/sandbox/inmemory/index.js.map +1 -1
- package/dist/adapters/sandbox/inmemory/workflow.cjs +2 -0
- package/dist/adapters/sandbox/inmemory/workflow.cjs.map +1 -1
- package/dist/adapters/sandbox/inmemory/workflow.d.cts +1 -1
- package/dist/adapters/sandbox/inmemory/workflow.d.ts +1 -1
- package/dist/adapters/sandbox/inmemory/workflow.js +2 -0
- package/dist/adapters/sandbox/inmemory/workflow.js.map +1 -1
- package/dist/adapters/thread/anthropic/index.cjs +71 -36
- package/dist/adapters/thread/anthropic/index.cjs.map +1 -1
- package/dist/adapters/thread/anthropic/index.d.cts +5 -5
- package/dist/adapters/thread/anthropic/index.d.ts +5 -5
- package/dist/adapters/thread/anthropic/index.js +71 -36
- package/dist/adapters/thread/anthropic/index.js.map +1 -1
- package/dist/adapters/thread/anthropic/workflow.cjs +5 -1
- package/dist/adapters/thread/anthropic/workflow.cjs.map +1 -1
- package/dist/adapters/thread/anthropic/workflow.d.cts +5 -5
- package/dist/adapters/thread/anthropic/workflow.d.ts +5 -5
- package/dist/adapters/thread/anthropic/workflow.js +5 -1
- package/dist/adapters/thread/anthropic/workflow.js.map +1 -1
- package/dist/adapters/thread/google-genai/index.cjs +50 -25
- package/dist/adapters/thread/google-genai/index.cjs.map +1 -1
- package/dist/adapters/thread/google-genai/index.d.cts +5 -5
- package/dist/adapters/thread/google-genai/index.d.ts +5 -5
- package/dist/adapters/thread/google-genai/index.js +50 -25
- package/dist/adapters/thread/google-genai/index.js.map +1 -1
- package/dist/adapters/thread/google-genai/workflow.cjs +5 -1
- package/dist/adapters/thread/google-genai/workflow.cjs.map +1 -1
- package/dist/adapters/thread/google-genai/workflow.d.cts +5 -5
- package/dist/adapters/thread/google-genai/workflow.d.ts +5 -5
- package/dist/adapters/thread/google-genai/workflow.js +5 -1
- package/dist/adapters/thread/google-genai/workflow.js.map +1 -1
- package/dist/adapters/thread/langchain/index.cjs +34 -7
- package/dist/adapters/thread/langchain/index.cjs.map +1 -1
- package/dist/adapters/thread/langchain/index.d.cts +5 -5
- package/dist/adapters/thread/langchain/index.d.ts +5 -5
- package/dist/adapters/thread/langchain/index.js +34 -7
- package/dist/adapters/thread/langchain/index.js.map +1 -1
- package/dist/adapters/thread/langchain/workflow.cjs +5 -1
- package/dist/adapters/thread/langchain/workflow.cjs.map +1 -1
- package/dist/adapters/thread/langchain/workflow.d.cts +5 -5
- package/dist/adapters/thread/langchain/workflow.d.ts +5 -5
- package/dist/adapters/thread/langchain/workflow.js +5 -1
- package/dist/adapters/thread/langchain/workflow.js.map +1 -1
- package/dist/index.cjs +206 -120
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +17 -11
- package/dist/index.d.ts +17 -11
- package/dist/index.js +207 -121
- package/dist/index.js.map +1 -1
- package/dist/{proxy-BjdFGPTm.d.ts → proxy-0smGKvx8.d.ts} +1 -1
- package/dist/{proxy-7RnVaPdJ.d.cts → proxy-DEtowJyd.d.cts} +1 -1
- package/dist/{thread-manager-DjN5JYul.d.ts → thread-manager-3fszQih4.d.ts} +2 -2
- package/dist/{thread-manager-CbpiGq1L.d.ts → thread-manager-C-C4pI2z.d.ts} +2 -2
- package/dist/{thread-manager-BBzNgQWH.d.cts → thread-manager-CzYln2OC.d.cts} +2 -2
- package/dist/{thread-manager-DzXm9eeI.d.cts → thread-manager-D4vgzYrh.d.cts} +2 -2
- package/dist/{types-yiXmqedU.d.ts → types-B37hKoWA.d.ts} +1 -1
- package/dist/{types-DQ1l_gXL.d.cts → types-BO7Yju20.d.cts} +63 -14
- package/dist/{types-wiGLvxWf.d.ts → types-CNuWnvy9.d.ts} +1 -1
- package/dist/{types-CADc5V_P.d.ts → types-CPKDl-y_.d.ts} +63 -14
- package/dist/{types-Mc_4BCfT.d.cts → types-D08CXPh8.d.cts} +1 -1
- package/dist/{types-CBH54cwr.d.cts → types-DWEUmYAJ.d.cts} +1 -1
- package/dist/{types-DxCpFNv_.d.cts → types-tQL9njTu.d.cts} +25 -0
- package/dist/{types-DxCpFNv_.d.ts → types-tQL9njTu.d.ts} +25 -0
- package/dist/{workflow-P2pTSfKu.d.ts → workflow-CjXHbZZc.d.ts} +2 -2
- package/dist/{workflow-DhtWRovz.d.cts → workflow-Do_lzJpT.d.cts} +2 -2
- package/dist/workflow.cjs +182 -114
- package/dist/workflow.cjs.map +1 -1
- package/dist/workflow.d.cts +3 -3
- package/dist/workflow.d.ts +3 -3
- package/dist/workflow.js +183 -115
- package/dist/workflow.js.map +1 -1
- package/package.json +1 -1
- package/src/adapters/sandbox/bedrock/filesystem.ts +6 -12
- package/src/adapters/sandbox/bedrock/index.ts +10 -8
- package/src/adapters/sandbox/bedrock/proxy.ts +2 -0
- package/src/adapters/sandbox/daytona/index.ts +6 -0
- package/src/adapters/sandbox/daytona/proxy.ts +2 -0
- package/src/adapters/sandbox/e2b/filesystem.ts +5 -4
- package/src/adapters/sandbox/e2b/index.ts +63 -12
- package/src/adapters/sandbox/e2b/proxy.ts +2 -0
- package/src/adapters/sandbox/inmemory/index.ts +5 -0
- package/src/adapters/sandbox/inmemory/proxy.ts +2 -0
- package/src/adapters/thread/anthropic/activities.ts +49 -26
- package/src/adapters/thread/anthropic/model-invoker.ts +15 -6
- package/src/adapters/thread/anthropic/proxy.ts +6 -2
- package/src/adapters/thread/anthropic/thread-manager.test.ts +26 -7
- package/src/adapters/thread/anthropic/thread-manager.ts +60 -46
- package/src/adapters/thread/google-genai/activities.ts +7 -2
- package/src/adapters/thread/google-genai/model-invoker.ts +26 -8
- package/src/adapters/thread/google-genai/proxy.ts +6 -2
- package/src/adapters/thread/google-genai/thread-manager.test.ts +13 -3
- package/src/adapters/thread/google-genai/thread-manager.ts +54 -33
- package/src/adapters/thread/langchain/activities.ts +46 -24
- package/src/adapters/thread/langchain/hooks.test.ts +36 -49
- package/src/adapters/thread/langchain/hooks.ts +18 -5
- package/src/adapters/thread/langchain/model-invoker.ts +3 -3
- package/src/adapters/thread/langchain/proxy.ts +6 -2
- package/src/adapters/thread/langchain/thread-manager.test.ts +5 -1
- package/src/adapters/thread/langchain/thread-manager.ts +20 -9
- package/src/index.ts +4 -1
- package/src/lib/activity.ts +16 -6
- package/src/lib/hooks/types.ts +6 -6
- package/src/lib/lifecycle.ts +9 -1
- package/src/lib/model/proxy.ts +2 -2
- package/src/lib/observability/hooks.ts +4 -5
- package/src/lib/observability/index.ts +1 -4
- package/src/lib/sandbox/manager.ts +21 -4
- package/src/lib/sandbox/node-fs.ts +3 -6
- package/src/lib/sandbox/sandbox.test.ts +36 -3
- package/src/lib/sandbox/tree.integration.test.ts +10 -3
- package/src/lib/sandbox/types.ts +35 -1
- package/src/lib/session/session-edge-cases.integration.test.ts +51 -13
- package/src/lib/session/session.integration.test.ts +139 -0
- package/src/lib/session/session.ts +50 -19
- package/src/lib/session/types.ts +13 -5
- package/src/lib/skills/fs-provider.ts +12 -8
- package/src/lib/skills/handler.ts +1 -1
- package/src/lib/skills/parse.ts +3 -1
- package/src/lib/skills/register.ts +1 -3
- package/src/lib/skills/skills.integration.test.ts +25 -15
- package/src/lib/state/manager.integration.test.ts +12 -2
- package/src/lib/subagent/define.ts +1 -1
- package/src/lib/subagent/handler.ts +186 -71
- package/src/lib/subagent/index.ts +1 -5
- package/src/lib/subagent/register.ts +3 -2
- package/src/lib/subagent/signals.ts +1 -10
- package/src/lib/subagent/subagent.integration.test.ts +438 -156
- package/src/lib/subagent/tool.ts +4 -3
- package/src/lib/subagent/types.ts +50 -20
- package/src/lib/subagent/workflow.ts +9 -49
- package/src/lib/thread/id.test.ts +1 -1
- package/src/lib/thread/id.ts +1 -2
- package/src/lib/thread/proxy.ts +3 -4
- package/src/lib/thread/types.ts +11 -3
- package/src/lib/tool-router/index.ts +1 -5
- package/src/lib/tool-router/router-edge-cases.integration.test.ts +1 -1
- package/src/lib/tool-router/router.ts +3 -2
- package/src/lib/tool-router/types.ts +11 -3
- package/src/lib/tool-router/with-sandbox.ts +19 -5
- package/src/lib/virtual-fs/filesystem.ts +1 -1
- package/src/lib/virtual-fs/index.ts +5 -1
- package/src/lib/virtual-fs/mutations.ts +2 -4
- package/src/lib/virtual-fs/queries.ts +9 -5
- package/src/lib/virtual-fs/types.ts +4 -1
- package/src/lib/virtual-fs/virtual-fs.test.ts +9 -11
- package/src/lib/workflow.test.ts +7 -4
- package/src/lib/workflow.ts +1 -5
- package/src/tools/ask-user-question/tool.ts +1 -3
- package/src/tools/glob/handler.ts +1 -4
- package/src/tools/task-get/handler.ts +4 -5
- package/src/tools/task-list/handler.ts +1 -4
- package/src/tools/task-update/handler.ts +4 -5
- package/src/workflow.ts +20 -7
- package/tsup.config.ts +9 -6
- package/src/lib/.env +0 -1
- package/src/tools/bash/.env +0 -1
|
@@ -9,9 +9,7 @@ import type {
|
|
|
9
9
|
} from "../../../lib/thread/types";
|
|
10
10
|
|
|
11
11
|
/** SDK-native content type for Anthropic human messages */
|
|
12
|
-
export type AnthropicContent =
|
|
13
|
-
| string
|
|
14
|
-
| Anthropic.Messages.ContentBlockParam[];
|
|
12
|
+
export type AnthropicContent = string | Anthropic.Messages.ContentBlockParam[];
|
|
15
13
|
|
|
16
14
|
/** SDK-native content type for Anthropic system prompts (supports cache_control blocks) */
|
|
17
15
|
export type AnthropicSystemContent =
|
|
@@ -26,7 +24,10 @@ export interface StoredMessage {
|
|
|
26
24
|
isSystem?: boolean;
|
|
27
25
|
}
|
|
28
26
|
|
|
29
|
-
export type AnthropicThreadManagerHooks = ThreadManagerHooks<
|
|
27
|
+
export type AnthropicThreadManagerHooks = ThreadManagerHooks<
|
|
28
|
+
StoredMessage,
|
|
29
|
+
Anthropic.Messages.MessageParam
|
|
30
|
+
>;
|
|
30
31
|
|
|
31
32
|
export interface AnthropicThreadManagerConfig {
|
|
32
33
|
redis: Redis;
|
|
@@ -43,11 +44,15 @@ export interface AnthropicInvocationPayload {
|
|
|
43
44
|
}
|
|
44
45
|
|
|
45
46
|
/** Thread manager with Anthropic MessageParam convenience helpers */
|
|
46
|
-
export interface AnthropicThreadManager
|
|
47
|
-
|
|
47
|
+
export interface AnthropicThreadManager extends ProviderThreadManager<
|
|
48
|
+
StoredMessage,
|
|
49
|
+
AnthropicContent,
|
|
50
|
+
JsonValue,
|
|
51
|
+
AnthropicSystemContent
|
|
52
|
+
> {
|
|
48
53
|
appendAssistantMessage(
|
|
49
54
|
id: string,
|
|
50
|
-
content: Anthropic.Messages.ContentBlock[]
|
|
55
|
+
content: Anthropic.Messages.ContentBlock[]
|
|
51
56
|
): Promise<void>;
|
|
52
57
|
prepareForInvocation(): Promise<AnthropicInvocationPayload>;
|
|
53
58
|
}
|
|
@@ -58,7 +63,7 @@ function storedMessageId(msg: StoredMessage): string {
|
|
|
58
63
|
|
|
59
64
|
/** Normalise content into an array of ContentBlockParam */
|
|
60
65
|
function toContentBlocks(
|
|
61
|
-
content: AnthropicContent
|
|
66
|
+
content: AnthropicContent
|
|
62
67
|
): Anthropic.Messages.ContentBlockParam[] {
|
|
63
68
|
if (typeof content === "string") {
|
|
64
69
|
return [{ type: "text", text: content }];
|
|
@@ -72,7 +77,7 @@ function toContentBlocks(
|
|
|
72
77
|
* merging, multiple sequential tool-result messages would violate this.
|
|
73
78
|
*/
|
|
74
79
|
function mergeConsecutiveMessages(
|
|
75
|
-
messages: Anthropic.Messages.MessageParam[]
|
|
80
|
+
messages: Anthropic.Messages.MessageParam[]
|
|
76
81
|
): Anthropic.Messages.MessageParam[] {
|
|
77
82
|
const merged: Anthropic.Messages.MessageParam[] = [];
|
|
78
83
|
for (const msg of messages) {
|
|
@@ -88,9 +93,7 @@ function mergeConsecutiveMessages(
|
|
|
88
93
|
} else {
|
|
89
94
|
merged.push({
|
|
90
95
|
...msg,
|
|
91
|
-
content: Array.isArray(msg.content)
|
|
92
|
-
? [...msg.content]
|
|
93
|
-
: msg.content,
|
|
96
|
+
content: Array.isArray(msg.content) ? [...msg.content] : msg.content,
|
|
94
97
|
});
|
|
95
98
|
}
|
|
96
99
|
}
|
|
@@ -103,7 +106,7 @@ function mergeConsecutiveMessages(
|
|
|
103
106
|
* appending typed messages.
|
|
104
107
|
*/
|
|
105
108
|
export function createAnthropicThreadManager(
|
|
106
|
-
config: AnthropicThreadManagerConfig
|
|
109
|
+
config: AnthropicThreadManagerConfig
|
|
107
110
|
): AnthropicThreadManager {
|
|
108
111
|
const baseConfig: ThreadManagerConfig<StoredMessage> = {
|
|
109
112
|
redis: config.redis,
|
|
@@ -117,49 +120,56 @@ export function createAnthropicThreadManager(
|
|
|
117
120
|
const helpers: Omit<AnthropicThreadManager, keyof typeof base> = {
|
|
118
121
|
async appendUserMessage(
|
|
119
122
|
id: string,
|
|
120
|
-
content: AnthropicContent
|
|
123
|
+
content: AnthropicContent
|
|
121
124
|
): Promise<void> {
|
|
122
|
-
await base.append([
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
125
|
+
await base.append([
|
|
126
|
+
{
|
|
127
|
+
id,
|
|
128
|
+
message: { role: "user", content: toContentBlocks(content) },
|
|
129
|
+
},
|
|
130
|
+
]);
|
|
126
131
|
},
|
|
127
132
|
|
|
128
133
|
async appendSystemMessage(
|
|
129
134
|
id: string,
|
|
130
|
-
content: AnthropicSystemContent
|
|
135
|
+
content: AnthropicSystemContent
|
|
131
136
|
): Promise<void> {
|
|
132
137
|
await base.initialize();
|
|
133
|
-
await base.append([
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
138
|
+
await base.append([
|
|
139
|
+
{
|
|
140
|
+
id,
|
|
141
|
+
// Stored under a user-role placeholder to satisfy the MessageParam
|
|
142
|
+
// shape; the `isSystem` flag steers extraction in prepareForInvocation.
|
|
143
|
+
message: {
|
|
144
|
+
role: "user",
|
|
145
|
+
content: content as Anthropic.Messages.MessageParam["content"],
|
|
146
|
+
},
|
|
147
|
+
isSystem: true,
|
|
140
148
|
},
|
|
141
|
-
|
|
142
|
-
}]);
|
|
149
|
+
]);
|
|
143
150
|
},
|
|
144
151
|
|
|
145
152
|
async appendAssistantMessage(
|
|
146
153
|
id: string,
|
|
147
|
-
content: Anthropic.Messages.ContentBlock[]
|
|
154
|
+
content: Anthropic.Messages.ContentBlock[]
|
|
148
155
|
): Promise<void> {
|
|
149
|
-
await base.append([
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
156
|
+
await base.append([
|
|
157
|
+
{
|
|
158
|
+
id,
|
|
159
|
+
message: {
|
|
160
|
+
role: "assistant",
|
|
161
|
+
content:
|
|
162
|
+
content as unknown as Anthropic.Messages.ContentBlockParam[],
|
|
163
|
+
},
|
|
154
164
|
},
|
|
155
|
-
|
|
165
|
+
]);
|
|
156
166
|
},
|
|
157
167
|
|
|
158
168
|
async appendToolResult(
|
|
159
169
|
id: string,
|
|
160
170
|
toolCallId: string,
|
|
161
171
|
_toolName: string,
|
|
162
|
-
content: JsonValue
|
|
172
|
+
content: JsonValue
|
|
163
173
|
): Promise<void> {
|
|
164
174
|
const toolContent =
|
|
165
175
|
typeof content === "string"
|
|
@@ -167,17 +177,21 @@ export function createAnthropicThreadManager(
|
|
|
167
177
|
: Array.isArray(content)
|
|
168
178
|
? (content as unknown as Anthropic.Messages.ToolResultBlockParam["content"])
|
|
169
179
|
: JSON.stringify(content);
|
|
170
|
-
await base.append([
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
180
|
+
await base.append([
|
|
181
|
+
{
|
|
182
|
+
id,
|
|
183
|
+
message: {
|
|
184
|
+
role: "user",
|
|
185
|
+
content: [
|
|
186
|
+
{
|
|
187
|
+
type: "tool_result" as const,
|
|
188
|
+
tool_use_id: toolCallId,
|
|
189
|
+
content: toolContent,
|
|
190
|
+
},
|
|
191
|
+
],
|
|
192
|
+
},
|
|
179
193
|
},
|
|
180
|
-
|
|
194
|
+
]);
|
|
181
195
|
},
|
|
182
196
|
|
|
183
197
|
async prepareForInvocation(): Promise<AnthropicInvocationPayload> {
|
|
@@ -200,7 +200,7 @@ export function createGoogleGenAIAdapter(
|
|
|
200
200
|
threadId: string,
|
|
201
201
|
id: string,
|
|
202
202
|
message: Content,
|
|
203
|
-
threadKey?: string
|
|
203
|
+
threadKey?: string
|
|
204
204
|
): Promise<void> {
|
|
205
205
|
const thread = createGoogleGenAIThreadManager({
|
|
206
206
|
redis,
|
|
@@ -240,7 +240,12 @@ export function createGoogleGenAIAdapter(
|
|
|
240
240
|
model: string,
|
|
241
241
|
client: GoogleGenAI
|
|
242
242
|
): ModelInvoker<Content> =>
|
|
243
|
-
createGoogleGenAIModelInvoker({
|
|
243
|
+
createGoogleGenAIModelInvoker({
|
|
244
|
+
redis,
|
|
245
|
+
client,
|
|
246
|
+
model,
|
|
247
|
+
hooks: config.hooks,
|
|
248
|
+
});
|
|
244
249
|
|
|
245
250
|
const invoker: ModelInvoker<Content> =
|
|
246
251
|
config.model && config.client
|
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
import type Redis from "ioredis";
|
|
2
|
-
import type {
|
|
2
|
+
import type {
|
|
3
|
+
GoogleGenAI,
|
|
4
|
+
Content,
|
|
5
|
+
FunctionDeclaration,
|
|
6
|
+
Part,
|
|
7
|
+
GenerateContentResponse,
|
|
8
|
+
} from "@google/genai";
|
|
3
9
|
import type { SerializableToolDefinition } from "../../../lib/types";
|
|
4
10
|
import type { AgentResponse, ModelInvokerConfig } from "../../../lib/model";
|
|
5
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
createGoogleGenAIThreadManager,
|
|
13
|
+
type GoogleGenAIThreadManagerHooks,
|
|
14
|
+
} from "./thread-manager";
|
|
6
15
|
import { getActivityContext } from "../../../lib/activity";
|
|
7
16
|
|
|
8
17
|
export interface GoogleGenAIModelInvokerConfig {
|
|
@@ -13,7 +22,7 @@ export interface GoogleGenAIModelInvokerConfig {
|
|
|
13
22
|
}
|
|
14
23
|
|
|
15
24
|
function toFunctionDeclarations(
|
|
16
|
-
tools: SerializableToolDefinition[]
|
|
25
|
+
tools: SerializableToolDefinition[]
|
|
17
26
|
): FunctionDeclaration[] {
|
|
18
27
|
return tools.map((t) => ({
|
|
19
28
|
name: t.name,
|
|
@@ -53,14 +62,18 @@ export function createGoogleGenAIModelInvoker({
|
|
|
53
62
|
hooks,
|
|
54
63
|
}: GoogleGenAIModelInvokerConfig) {
|
|
55
64
|
return async function invokeGoogleGenAIModel(
|
|
56
|
-
config: ModelInvokerConfig
|
|
65
|
+
config: ModelInvokerConfig
|
|
57
66
|
): Promise<AgentResponse<Content>> {
|
|
58
67
|
const { threadId, threadKey, state } = config;
|
|
59
68
|
const { heartbeat, signal } = getActivityContext();
|
|
60
69
|
|
|
61
|
-
const thread = createGoogleGenAIThreadManager({
|
|
62
|
-
|
|
63
|
-
|
|
70
|
+
const thread = createGoogleGenAIThreadManager({
|
|
71
|
+
redis,
|
|
72
|
+
threadId,
|
|
73
|
+
key: threadKey,
|
|
74
|
+
hooks,
|
|
75
|
+
});
|
|
76
|
+
const { contents, systemInstruction } = await thread.prepareForInvocation();
|
|
64
77
|
|
|
65
78
|
const functionDeclarations = toFunctionDeclarations(state.tools);
|
|
66
79
|
const tools =
|
|
@@ -125,6 +138,11 @@ export async function invokeGoogleGenAIModel({
|
|
|
125
138
|
hooks?: GoogleGenAIThreadManagerHooks;
|
|
126
139
|
config: ModelInvokerConfig;
|
|
127
140
|
}): Promise<AgentResponse<Content>> {
|
|
128
|
-
const invoker = createGoogleGenAIModelInvoker({
|
|
141
|
+
const invoker = createGoogleGenAIModelInvoker({
|
|
142
|
+
redis,
|
|
143
|
+
client,
|
|
144
|
+
model,
|
|
145
|
+
hooks,
|
|
146
|
+
});
|
|
129
147
|
return invoker(config);
|
|
130
148
|
}
|
|
@@ -27,7 +27,11 @@ const ADAPTER_PREFIX = "googleGenAI";
|
|
|
27
27
|
|
|
28
28
|
export function proxyGoogleGenAIThreadOps(
|
|
29
29
|
scope?: string,
|
|
30
|
-
options?: Parameters<typeof createThreadOpsProxy>[2]
|
|
30
|
+
options?: Parameters<typeof createThreadOpsProxy>[2]
|
|
31
31
|
): ActivityInterfaceFor<ThreadOps<GoogleGenAIContent>> {
|
|
32
|
-
return createThreadOpsProxy(
|
|
32
|
+
return createThreadOpsProxy(
|
|
33
|
+
ADAPTER_PREFIX,
|
|
34
|
+
scope,
|
|
35
|
+
options
|
|
36
|
+
) as ActivityInterfaceFor<ThreadOps<GoogleGenAIContent>>;
|
|
33
37
|
}
|
|
@@ -39,7 +39,9 @@ describe("Google GenAI thread manager hooks", () => {
|
|
|
39
39
|
...msg,
|
|
40
40
|
content: {
|
|
41
41
|
...msg.content,
|
|
42
|
-
parts: [
|
|
42
|
+
parts: [
|
|
43
|
+
{ text: `[modified] ${msg.content.parts?.[0]?.text ?? ""}` },
|
|
44
|
+
],
|
|
43
45
|
},
|
|
44
46
|
};
|
|
45
47
|
});
|
|
@@ -54,7 +56,11 @@ describe("Google GenAI thread manager hooks", () => {
|
|
|
54
56
|
const { contents, systemInstruction } = await tm.prepareForInvocation();
|
|
55
57
|
|
|
56
58
|
expect(hook).toHaveBeenCalledTimes(3);
|
|
57
|
-
expect(hook).toHaveBeenCalledWith(systemContent, 0, [
|
|
59
|
+
expect(hook).toHaveBeenCalledWith(systemContent, 0, [
|
|
60
|
+
systemContent,
|
|
61
|
+
userContent,
|
|
62
|
+
modelContent,
|
|
63
|
+
]);
|
|
58
64
|
expect(systemInstruction).toEqual([{ text: "You are helpful." }]);
|
|
59
65
|
expect(contents[0]?.parts?.[0]?.text).toBe("[modified] Hello");
|
|
60
66
|
expect(contents[1]?.parts?.[0]?.text).toBe("[modified] Hi there!");
|
|
@@ -106,7 +112,11 @@ describe("Google GenAI thread manager hooks", () => {
|
|
|
106
112
|
|
|
107
113
|
await tm.prepareForInvocation();
|
|
108
114
|
|
|
109
|
-
const args = hook.mock.calls[0] as unknown as [
|
|
115
|
+
const args = hook.mock.calls[0] as unknown as [
|
|
116
|
+
Content,
|
|
117
|
+
number,
|
|
118
|
+
Content[],
|
|
119
|
+
];
|
|
110
120
|
expect(args[2]).toHaveLength(2);
|
|
111
121
|
});
|
|
112
122
|
});
|
|
@@ -20,7 +20,10 @@ export interface StoredContent {
|
|
|
20
20
|
content: Content;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
export type GoogleGenAIThreadManagerHooks = ThreadManagerHooks<
|
|
23
|
+
export type GoogleGenAIThreadManagerHooks = ThreadManagerHooks<
|
|
24
|
+
StoredContent,
|
|
25
|
+
Content
|
|
26
|
+
>;
|
|
24
27
|
|
|
25
28
|
export interface GoogleGenAIThreadManagerConfig {
|
|
26
29
|
redis: Redis;
|
|
@@ -37,8 +40,12 @@ export interface GoogleGenAIInvocationPayload {
|
|
|
37
40
|
}
|
|
38
41
|
|
|
39
42
|
/** Thread manager with Google GenAI Content convenience helpers */
|
|
40
|
-
export interface GoogleGenAIThreadManager
|
|
41
|
-
|
|
43
|
+
export interface GoogleGenAIThreadManager extends ProviderThreadManager<
|
|
44
|
+
StoredContent,
|
|
45
|
+
GoogleGenAIContent,
|
|
46
|
+
GoogleGenAIToolResponse,
|
|
47
|
+
GoogleGenAISystemContent
|
|
48
|
+
> {
|
|
42
49
|
appendModelContent(id: string, parts: Part[]): Promise<void>;
|
|
43
50
|
prepareForInvocation(): Promise<GoogleGenAIInvocationPayload>;
|
|
44
51
|
}
|
|
@@ -56,7 +63,9 @@ function toParts(content: GoogleGenAIContent): Part[] {
|
|
|
56
63
|
}
|
|
57
64
|
|
|
58
65
|
/** Convert a string or object into a Record suitable for functionResponse.response */
|
|
59
|
-
function toFunctionResponse(
|
|
66
|
+
function toFunctionResponse(
|
|
67
|
+
content: string | Record<string, unknown>
|
|
68
|
+
): Record<string, unknown> {
|
|
60
69
|
if (typeof content === "object") {
|
|
61
70
|
return content;
|
|
62
71
|
}
|
|
@@ -87,7 +96,7 @@ function mergeConsecutiveContents(contents: Content[]): Content[] {
|
|
|
87
96
|
* appending typed Content messages.
|
|
88
97
|
*/
|
|
89
98
|
export function createGoogleGenAIThreadManager(
|
|
90
|
-
config: GoogleGenAIThreadManagerConfig
|
|
99
|
+
config: GoogleGenAIThreadManagerConfig
|
|
91
100
|
): GoogleGenAIThreadManager {
|
|
92
101
|
const baseConfig: ThreadManagerConfig<StoredContent> = {
|
|
93
102
|
redis: config.redis,
|
|
@@ -101,54 +110,64 @@ export function createGoogleGenAIThreadManager(
|
|
|
101
110
|
const helpers: Omit<GoogleGenAIThreadManager, keyof typeof base> = {
|
|
102
111
|
async appendUserMessage(
|
|
103
112
|
id: string,
|
|
104
|
-
content: GoogleGenAIContent
|
|
113
|
+
content: GoogleGenAIContent
|
|
105
114
|
): Promise<void> {
|
|
106
|
-
await base.append([
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
115
|
+
await base.append([
|
|
116
|
+
{
|
|
117
|
+
id,
|
|
118
|
+
content: { role: "user", parts: toParts(content) },
|
|
119
|
+
},
|
|
120
|
+
]);
|
|
110
121
|
},
|
|
111
122
|
|
|
112
123
|
async appendSystemMessage(
|
|
113
124
|
id: string,
|
|
114
|
-
content: GoogleGenAISystemContent
|
|
125
|
+
content: GoogleGenAISystemContent
|
|
115
126
|
): Promise<void> {
|
|
116
127
|
const parts: Part[] =
|
|
117
128
|
typeof content === "string" ? [{ text: content }] : content;
|
|
118
129
|
await base.initialize();
|
|
119
|
-
await base.append([
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
130
|
+
await base.append([
|
|
131
|
+
{
|
|
132
|
+
id,
|
|
133
|
+
content: { role: "system", parts },
|
|
134
|
+
},
|
|
135
|
+
]);
|
|
123
136
|
},
|
|
124
137
|
|
|
125
138
|
async appendModelContent(id: string, parts: Part[]): Promise<void> {
|
|
126
|
-
await base.append([
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
139
|
+
await base.append([
|
|
140
|
+
{
|
|
141
|
+
id,
|
|
142
|
+
content: { role: "model", parts },
|
|
143
|
+
},
|
|
144
|
+
]);
|
|
130
145
|
},
|
|
131
146
|
|
|
132
147
|
async appendToolResult(
|
|
133
148
|
id: string,
|
|
134
149
|
toolCallId: string,
|
|
135
150
|
toolName: string,
|
|
136
|
-
content: GoogleGenAIToolResponse
|
|
151
|
+
content: GoogleGenAIToolResponse
|
|
137
152
|
): Promise<void> {
|
|
138
153
|
const parts: Part[] = Array.isArray(content)
|
|
139
|
-
? content as Part[]
|
|
140
|
-
: [
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
154
|
+
? (content as Part[])
|
|
155
|
+
: [
|
|
156
|
+
{
|
|
157
|
+
functionResponse: {
|
|
158
|
+
id: toolCallId,
|
|
159
|
+
name: toolName,
|
|
160
|
+
response: toFunctionResponse(content),
|
|
161
|
+
},
|
|
145
162
|
},
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
await base.append([
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
163
|
+
];
|
|
164
|
+
|
|
165
|
+
await base.append([
|
|
166
|
+
{
|
|
167
|
+
id,
|
|
168
|
+
content: { role: "user", parts },
|
|
169
|
+
},
|
|
170
|
+
]);
|
|
152
171
|
},
|
|
153
172
|
|
|
154
173
|
async prepareForInvocation(): Promise<GoogleGenAIInvocationPayload> {
|
|
@@ -174,7 +193,9 @@ export function createGoogleGenAIThreadManager(
|
|
|
174
193
|
contents: onPreparedMessage
|
|
175
194
|
? contents.map((msg, i) => onPreparedMessage(msg, i, contents))
|
|
176
195
|
: contents,
|
|
177
|
-
...(systemInstruction && systemInstruction.length > 0
|
|
196
|
+
...(systemInstruction && systemInstruction.length > 0
|
|
197
|
+
? { systemInstruction }
|
|
198
|
+
: {}),
|
|
178
199
|
};
|
|
179
200
|
},
|
|
180
201
|
};
|
|
@@ -24,8 +24,10 @@ import { createLangChainModelInvoker } from "./model-invoker";
|
|
|
24
24
|
|
|
25
25
|
const ADAPTER_PREFIX = "langChain" as const;
|
|
26
26
|
|
|
27
|
-
export type LangChainThreadOps<TScope extends string = ""> =
|
|
28
|
-
|
|
27
|
+
export type LangChainThreadOps<TScope extends string = ""> = PrefixedThreadOps<
|
|
28
|
+
ScopedPrefix<TScope, typeof ADAPTER_PREFIX>,
|
|
29
|
+
LangChainContent
|
|
30
|
+
>;
|
|
29
31
|
|
|
30
32
|
export interface LangChainAdapterConfig {
|
|
31
33
|
redis: Redis;
|
|
@@ -61,9 +63,7 @@ export interface LangChainAdapter {
|
|
|
61
63
|
* // → { langChainCodingAgentInitializeThread, langChainCodingAgentAppendHumanMessage, … }
|
|
62
64
|
* ```
|
|
63
65
|
*/
|
|
64
|
-
createActivities<S extends string = "">(
|
|
65
|
-
scope?: S,
|
|
66
|
-
): LangChainThreadOps<S>;
|
|
66
|
+
createActivities<S extends string = "">(scope?: S): LangChainThreadOps<S>;
|
|
67
67
|
|
|
68
68
|
/**
|
|
69
69
|
* Identity wrapper that types a tool handler for this adapter.
|
|
@@ -72,8 +72,8 @@ export interface LangChainAdapter {
|
|
|
72
72
|
wrapHandler<TArgs, TResult, TContext extends RouterContext = RouterContext>(
|
|
73
73
|
handler: (
|
|
74
74
|
args: TArgs,
|
|
75
|
-
context: TContext
|
|
76
|
-
) => Promise<ToolHandlerResponse<TResult, LangChainToolResponse
|
|
75
|
+
context: TContext
|
|
76
|
+
) => Promise<ToolHandlerResponse<TResult, LangChainToolResponse>>
|
|
77
77
|
): ActivityToolHandler<TArgs, TResult, TContext, LangChainToolResponse>;
|
|
78
78
|
}
|
|
79
79
|
|
|
@@ -113,13 +113,20 @@ export interface LangChainAdapter {
|
|
|
113
113
|
* ```
|
|
114
114
|
*/
|
|
115
115
|
export function createLangChainAdapter(
|
|
116
|
-
config: LangChainAdapterConfig
|
|
116
|
+
config: LangChainAdapterConfig
|
|
117
117
|
): LangChainAdapter {
|
|
118
118
|
const { redis } = config;
|
|
119
119
|
|
|
120
120
|
const threadOps: ThreadOps<LangChainContent> = {
|
|
121
|
-
async initializeThread(
|
|
122
|
-
|
|
121
|
+
async initializeThread(
|
|
122
|
+
threadId: string,
|
|
123
|
+
threadKey?: string
|
|
124
|
+
): Promise<void> {
|
|
125
|
+
const thread = createLangChainThreadManager({
|
|
126
|
+
redis,
|
|
127
|
+
threadId,
|
|
128
|
+
key: threadKey,
|
|
129
|
+
});
|
|
123
130
|
await thread.initialize();
|
|
124
131
|
},
|
|
125
132
|
|
|
@@ -127,9 +134,13 @@ export function createLangChainAdapter(
|
|
|
127
134
|
threadId: string,
|
|
128
135
|
id: string,
|
|
129
136
|
content: LangChainContent,
|
|
130
|
-
threadKey?: string
|
|
137
|
+
threadKey?: string
|
|
131
138
|
): Promise<void> {
|
|
132
|
-
const thread = createLangChainThreadManager({
|
|
139
|
+
const thread = createLangChainThreadManager({
|
|
140
|
+
redis,
|
|
141
|
+
threadId,
|
|
142
|
+
key: threadKey,
|
|
143
|
+
});
|
|
133
144
|
await thread.appendUserMessage(id, content);
|
|
134
145
|
},
|
|
135
146
|
|
|
@@ -137,15 +148,23 @@ export function createLangChainAdapter(
|
|
|
137
148
|
threadId: string,
|
|
138
149
|
id: string,
|
|
139
150
|
content: LangChainSystemContent,
|
|
140
|
-
threadKey?: string
|
|
151
|
+
threadKey?: string
|
|
141
152
|
): Promise<void> {
|
|
142
|
-
const thread = createLangChainThreadManager({
|
|
153
|
+
const thread = createLangChainThreadManager({
|
|
154
|
+
redis,
|
|
155
|
+
threadId,
|
|
156
|
+
key: threadKey,
|
|
157
|
+
});
|
|
143
158
|
await thread.appendSystemMessage(id, content);
|
|
144
159
|
},
|
|
145
160
|
|
|
146
161
|
async appendToolResult(id: string, cfg: ToolResultConfig): Promise<void> {
|
|
147
162
|
const { threadId, threadKey, toolCallId, content } = cfg;
|
|
148
|
-
const thread = createLangChainThreadManager({
|
|
163
|
+
const thread = createLangChainThreadManager({
|
|
164
|
+
redis,
|
|
165
|
+
threadId,
|
|
166
|
+
key: threadKey,
|
|
167
|
+
});
|
|
149
168
|
await thread.appendToolResult(id, toolCallId, "", content);
|
|
150
169
|
},
|
|
151
170
|
|
|
@@ -153,9 +172,13 @@ export function createLangChainAdapter(
|
|
|
153
172
|
threadId: string,
|
|
154
173
|
id: string,
|
|
155
174
|
message: StoredMessage,
|
|
156
|
-
threadKey?: string
|
|
175
|
+
threadKey?: string
|
|
157
176
|
): Promise<void> {
|
|
158
|
-
const thread = createLangChainThreadManager({
|
|
177
|
+
const thread = createLangChainThreadManager({
|
|
178
|
+
redis,
|
|
179
|
+
threadId,
|
|
180
|
+
key: threadKey,
|
|
181
|
+
});
|
|
159
182
|
const patched = { ...message, data: { ...message.data, id } };
|
|
160
183
|
await thread.append([patched]);
|
|
161
184
|
},
|
|
@@ -163,7 +186,7 @@ export function createLangChainAdapter(
|
|
|
163
186
|
async forkThread(
|
|
164
187
|
sourceThreadId: string,
|
|
165
188
|
targetThreadId: string,
|
|
166
|
-
threadKey?: string
|
|
189
|
+
threadKey?: string
|
|
167
190
|
): Promise<void> {
|
|
168
191
|
const thread = createLangChainThreadManager({
|
|
169
192
|
redis,
|
|
@@ -175,21 +198,20 @@ export function createLangChainAdapter(
|
|
|
175
198
|
};
|
|
176
199
|
|
|
177
200
|
function createActivities<S extends string = "">(
|
|
178
|
-
scope?: S
|
|
201
|
+
scope?: S
|
|
179
202
|
): LangChainThreadOps<S> {
|
|
180
203
|
const prefix = scope
|
|
181
204
|
? `${ADAPTER_PREFIX}${scope.charAt(0).toUpperCase()}${scope.slice(1)}`
|
|
182
205
|
: ADAPTER_PREFIX;
|
|
183
|
-
const cap = (s: string): string =>
|
|
184
|
-
s.charAt(0).toUpperCase() + s.slice(1);
|
|
206
|
+
const cap = (s: string): string => s.charAt(0).toUpperCase() + s.slice(1);
|
|
185
207
|
return Object.fromEntries(
|
|
186
|
-
Object.entries(threadOps).map(([k, v]) => [`${prefix}${cap(k)}`, v])
|
|
208
|
+
Object.entries(threadOps).map(([k, v]) => [`${prefix}${cap(k)}`, v])
|
|
187
209
|
) as LangChainThreadOps<S>;
|
|
188
210
|
}
|
|
189
211
|
|
|
190
212
|
const makeInvoker = (
|
|
191
213
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
192
|
-
model: BaseChatModel<any
|
|
214
|
+
model: BaseChatModel<any>
|
|
193
215
|
): ModelInvoker<StoredMessage> =>
|
|
194
216
|
createLangChainModelInvoker({ redis, model, hooks: config.hooks });
|
|
195
217
|
|
|
@@ -198,7 +220,7 @@ export function createLangChainAdapter(
|
|
|
198
220
|
: () => {
|
|
199
221
|
throw new Error(
|
|
200
222
|
"No default model provided to createLangChainAdapter. " +
|
|
201
|
-
"Either pass `model` in the config or use `createModelInvoker(model)` instead."
|
|
223
|
+
"Either pass `model` in the config or use `createModelInvoker(model)` instead."
|
|
202
224
|
);
|
|
203
225
|
};
|
|
204
226
|
|