zeitlich 0.2.20 → 0.2.21
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/dist/adapters/sandbox/virtual/index.d.cts +3 -3
- package/dist/adapters/sandbox/virtual/index.d.ts +3 -3
- package/dist/adapters/thread/google-genai/index.cjs +70 -23
- package/dist/adapters/thread/google-genai/index.cjs.map +1 -1
- package/dist/adapters/thread/google-genai/index.d.cts +10 -10
- package/dist/adapters/thread/google-genai/index.d.ts +10 -10
- package/dist/adapters/thread/google-genai/index.js +70 -23
- package/dist/adapters/thread/google-genai/index.js.map +1 -1
- package/dist/adapters/thread/langchain/index.cjs +75 -70
- package/dist/adapters/thread/langchain/index.cjs.map +1 -1
- package/dist/adapters/thread/langchain/index.d.cts +10 -10
- package/dist/adapters/thread/langchain/index.d.ts +10 -10
- package/dist/adapters/thread/langchain/index.js +75 -70
- package/dist/adapters/thread/langchain/index.js.map +1 -1
- package/dist/index.cjs +54 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -6
- package/dist/index.d.ts +6 -6
- package/dist/index.js +54 -9
- package/dist/index.js.map +1 -1
- package/dist/{queries-KHj5Otv7.d.ts → queries-6Avfh74U.d.ts} +1 -1
- package/dist/{queries-nIdzTCDS.d.cts → queries-CHa2iv_I.d.cts} +1 -1
- package/dist/{types-By80IE1x.d.ts → types-BkAYmc96.d.ts} +4 -4
- package/dist/{types-DZ7BkA3-.d.cts → types-CES_30qx.d.cts} +4 -4
- package/dist/{types-Ct2igz9y.d.ts → types-YbL7JpEA.d.cts} +1 -1
- package/dist/{types-Ct2igz9y.d.cts → types-YbL7JpEA.d.ts} +1 -1
- package/dist/workflow.cjs +7 -8
- package/dist/workflow.cjs.map +1 -1
- package/dist/workflow.d.cts +6 -6
- package/dist/workflow.d.ts +6 -6
- package/dist/workflow.js +7 -8
- package/dist/workflow.js.map +1 -1
- package/package.json +1 -1
- package/src/adapters/thread/google-genai/activities.ts +11 -9
- package/src/adapters/thread/google-genai/model-invoker.ts +6 -11
- package/src/adapters/thread/google-genai/thread-manager.ts +44 -29
- package/src/adapters/thread/langchain/activities.ts +6 -4
- package/src/adapters/thread/langchain/thread-manager.ts +46 -22
- package/src/lib/session/session.ts +5 -4
- package/src/lib/session/types.ts +7 -2
- package/src/lib/tool-router/auto-append-sandbox.integration.test.ts +20 -21
- package/src/lib/tool-router/auto-append.ts +3 -2
- package/src/lib/tool-router/router-edge-cases.integration.test.ts +59 -23
- package/src/lib/tool-router/router.integration.test.ts +55 -23
- package/src/lib/tool-router/router.ts +4 -3
- package/src/lib/tool-router/types.ts +1 -1
package/package.json
CHANGED
|
@@ -68,7 +68,7 @@ export interface GoogleGenAIAdapter {
|
|
|
68
68
|
* ```
|
|
69
69
|
*/
|
|
70
70
|
export function createGoogleGenAIAdapter(
|
|
71
|
-
config: GoogleGenAIAdapterConfig
|
|
71
|
+
config: GoogleGenAIAdapterConfig
|
|
72
72
|
): GoogleGenAIAdapter {
|
|
73
73
|
const { redis, client } = config;
|
|
74
74
|
|
|
@@ -80,29 +80,31 @@ export function createGoogleGenAIAdapter(
|
|
|
80
80
|
|
|
81
81
|
async appendHumanMessage(
|
|
82
82
|
threadId: string,
|
|
83
|
-
|
|
83
|
+
id: string,
|
|
84
|
+
content: string | MessageContent
|
|
84
85
|
): Promise<void> {
|
|
85
86
|
const thread = createGoogleGenAIThreadManager({ redis, threadId });
|
|
86
|
-
await thread.appendUserMessage(content);
|
|
87
|
+
await thread.appendUserMessage(id, content);
|
|
87
88
|
},
|
|
88
89
|
|
|
89
90
|
async appendSystemMessage(
|
|
90
91
|
threadId: string,
|
|
91
|
-
|
|
92
|
+
id: string,
|
|
93
|
+
content: string
|
|
92
94
|
): Promise<void> {
|
|
93
95
|
const thread = createGoogleGenAIThreadManager({ redis, threadId });
|
|
94
|
-
await thread.appendSystemMessage(content);
|
|
96
|
+
await thread.appendSystemMessage(id, content);
|
|
95
97
|
},
|
|
96
98
|
|
|
97
|
-
async appendToolResult(cfg: ToolResultConfig): Promise<void> {
|
|
99
|
+
async appendToolResult(id: string, cfg: ToolResultConfig): Promise<void> {
|
|
98
100
|
const { threadId, toolCallId, toolName, content } = cfg;
|
|
99
101
|
const thread = createGoogleGenAIThreadManager({ redis, threadId });
|
|
100
|
-
await thread.appendToolResult(toolCallId, toolName, content);
|
|
102
|
+
await thread.appendToolResult(id, toolCallId, toolName, content);
|
|
101
103
|
},
|
|
102
104
|
|
|
103
105
|
async forkThread(
|
|
104
106
|
sourceThreadId: string,
|
|
105
|
-
targetThreadId: string
|
|
107
|
+
targetThreadId: string
|
|
106
108
|
): Promise<void> {
|
|
107
109
|
const thread = createGoogleGenAIThreadManager({
|
|
108
110
|
redis,
|
|
@@ -120,7 +122,7 @@ export function createGoogleGenAIAdapter(
|
|
|
120
122
|
: ((() => {
|
|
121
123
|
throw new Error(
|
|
122
124
|
"No default model provided to createGoogleGenAIAdapter. " +
|
|
123
|
-
"Either pass `model` in the config or use `createModelInvoker(model)` instead."
|
|
125
|
+
"Either pass `model` in the config or use `createModelInvoker(model)` instead."
|
|
124
126
|
);
|
|
125
127
|
}) as unknown as ModelInvoker<Content>);
|
|
126
128
|
|
|
@@ -1,13 +1,10 @@
|
|
|
1
1
|
import type Redis from "ioredis";
|
|
2
|
-
import type {
|
|
3
|
-
GoogleGenAI,
|
|
4
|
-
Content,
|
|
5
|
-
FunctionDeclaration,
|
|
6
|
-
} from "@google/genai";
|
|
2
|
+
import type { GoogleGenAI, Content, FunctionDeclaration } from "@google/genai";
|
|
7
3
|
import type { SerializableToolDefinition } from "../../../lib/types";
|
|
8
4
|
import type { AgentResponse } from "../../../lib/model";
|
|
9
5
|
import type { ModelInvokerConfig } from "../../../lib/model";
|
|
10
6
|
import { createGoogleGenAIThreadManager } from "./thread-manager";
|
|
7
|
+
import { v4 as uuidv4 } from "uuid";
|
|
11
8
|
|
|
12
9
|
export interface GoogleGenAIModelInvokerConfig {
|
|
13
10
|
redis: Redis;
|
|
@@ -16,7 +13,7 @@ export interface GoogleGenAIModelInvokerConfig {
|
|
|
16
13
|
}
|
|
17
14
|
|
|
18
15
|
function toFunctionDeclarations(
|
|
19
|
-
tools: SerializableToolDefinition[]
|
|
16
|
+
tools: SerializableToolDefinition[]
|
|
20
17
|
): FunctionDeclaration[] {
|
|
21
18
|
return tools.map((t) => ({
|
|
22
19
|
name: t.name,
|
|
@@ -73,7 +70,7 @@ export function createGoogleGenAIModelInvoker({
|
|
|
73
70
|
model,
|
|
74
71
|
}: GoogleGenAIModelInvokerConfig) {
|
|
75
72
|
return async function invokeGoogleGenAIModel(
|
|
76
|
-
config: ModelInvokerConfig
|
|
73
|
+
config: ModelInvokerConfig
|
|
77
74
|
): Promise<AgentResponse<Content>> {
|
|
78
75
|
const { threadId, state } = config;
|
|
79
76
|
|
|
@@ -97,9 +94,7 @@ export function createGoogleGenAIModelInvoker({
|
|
|
97
94
|
|
|
98
95
|
const functionDeclarations = toFunctionDeclarations(state.tools);
|
|
99
96
|
const tools =
|
|
100
|
-
functionDeclarations.length > 0
|
|
101
|
-
? [{ functionDeclarations }]
|
|
102
|
-
: undefined;
|
|
97
|
+
functionDeclarations.length > 0 ? [{ functionDeclarations }] : undefined;
|
|
103
98
|
|
|
104
99
|
const response = await client.models.generateContent({
|
|
105
100
|
model,
|
|
@@ -113,7 +108,7 @@ export function createGoogleGenAIModelInvoker({
|
|
|
113
108
|
const responseParts = response.candidates?.[0]?.content?.parts ?? [];
|
|
114
109
|
const modelContent: Content = { role: "model", parts: responseParts };
|
|
115
110
|
|
|
116
|
-
await thread.appendModelContent(responseParts);
|
|
111
|
+
await thread.appendModelContent(uuidv4(), responseParts);
|
|
117
112
|
|
|
118
113
|
const functionCalls = response.functionCalls ?? [];
|
|
119
114
|
|
|
@@ -21,23 +21,30 @@ export interface GoogleGenAIThreadManagerConfig {
|
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
/** Thread manager with Google GenAI Content convenience helpers */
|
|
24
|
-
export interface GoogleGenAIThreadManager
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
24
|
+
export interface GoogleGenAIThreadManager extends BaseThreadManager<StoredContent> {
|
|
25
|
+
createUserContent(
|
|
26
|
+
id: string,
|
|
27
|
+
content: string | MessageContent
|
|
28
|
+
): StoredContent;
|
|
29
|
+
createSystemContent(id: string, content: string): StoredContent;
|
|
30
|
+
createModelContent(id: string, parts: Part[]): StoredContent;
|
|
29
31
|
createToolResponseContent(
|
|
32
|
+
id: string,
|
|
30
33
|
toolCallId: string,
|
|
31
34
|
toolName: string,
|
|
32
|
-
content: ToolMessageContent
|
|
35
|
+
content: ToolMessageContent
|
|
33
36
|
): StoredContent;
|
|
34
|
-
appendUserMessage(
|
|
35
|
-
|
|
36
|
-
|
|
37
|
+
appendUserMessage(
|
|
38
|
+
id: string,
|
|
39
|
+
content: string | MessageContent
|
|
40
|
+
): Promise<void>;
|
|
41
|
+
appendSystemMessage(id: string, content: string): Promise<void>;
|
|
42
|
+
appendModelContent(id: string, parts: Part[]): Promise<void>;
|
|
37
43
|
appendToolResult(
|
|
44
|
+
id: string,
|
|
38
45
|
toolCallId: string,
|
|
39
46
|
toolName: string,
|
|
40
|
-
content: ToolMessageContent
|
|
47
|
+
content: ToolMessageContent
|
|
41
48
|
): Promise<void>;
|
|
42
49
|
}
|
|
43
50
|
|
|
@@ -47,7 +54,7 @@ function storedContentId(msg: StoredContent): string {
|
|
|
47
54
|
|
|
48
55
|
/** Convert zeitlich MessageContent to Google GenAI Part[] */
|
|
49
56
|
export function messageContentToParts(
|
|
50
|
-
content: string | MessageContent
|
|
57
|
+
content: string | MessageContent
|
|
51
58
|
): Part[] {
|
|
52
59
|
if (typeof content === "string") {
|
|
53
60
|
return [{ text: content }];
|
|
@@ -65,7 +72,7 @@ export function messageContentToParts(
|
|
|
65
72
|
|
|
66
73
|
/** Parse ToolMessageContent into a Record suitable for functionResponse */
|
|
67
74
|
function parseToolResponse(
|
|
68
|
-
content: ToolMessageContent
|
|
75
|
+
content: ToolMessageContent
|
|
69
76
|
): Record<string, unknown> {
|
|
70
77
|
if (typeof content === "string") {
|
|
71
78
|
try {
|
|
@@ -86,7 +93,7 @@ function parseToolResponse(
|
|
|
86
93
|
* appending typed Content messages.
|
|
87
94
|
*/
|
|
88
95
|
export function createGoogleGenAIThreadManager(
|
|
89
|
-
config: GoogleGenAIThreadManagerConfig
|
|
96
|
+
config: GoogleGenAIThreadManagerConfig
|
|
90
97
|
): GoogleGenAIThreadManager {
|
|
91
98
|
const baseConfig: ThreadManagerConfig<StoredContent> = {
|
|
92
99
|
redis: config.redis,
|
|
@@ -98,34 +105,38 @@ export function createGoogleGenAIThreadManager(
|
|
|
98
105
|
const base = createThreadManager(baseConfig);
|
|
99
106
|
|
|
100
107
|
const helpers = {
|
|
101
|
-
createUserContent(
|
|
108
|
+
createUserContent(
|
|
109
|
+
id: string,
|
|
110
|
+
content: string | MessageContent
|
|
111
|
+
): StoredContent {
|
|
102
112
|
return {
|
|
103
|
-
id
|
|
113
|
+
id,
|
|
104
114
|
content: { role: "user", parts: messageContentToParts(content) },
|
|
105
115
|
};
|
|
106
116
|
},
|
|
107
117
|
|
|
108
|
-
createSystemContent(content: string): StoredContent {
|
|
118
|
+
createSystemContent(id: string, content: string): StoredContent {
|
|
109
119
|
return {
|
|
110
|
-
id
|
|
120
|
+
id,
|
|
111
121
|
content: { role: "system", parts: [{ text: content }] },
|
|
112
122
|
};
|
|
113
123
|
},
|
|
114
124
|
|
|
115
|
-
createModelContent(parts: Part[]): StoredContent {
|
|
125
|
+
createModelContent(id: string, parts: Part[]): StoredContent {
|
|
116
126
|
return {
|
|
117
|
-
id
|
|
127
|
+
id,
|
|
118
128
|
content: { role: "model", parts },
|
|
119
129
|
};
|
|
120
130
|
},
|
|
121
131
|
|
|
122
132
|
createToolResponseContent(
|
|
133
|
+
id: string,
|
|
123
134
|
toolCallId: string,
|
|
124
135
|
toolName: string,
|
|
125
|
-
content: ToolMessageContent
|
|
136
|
+
content: ToolMessageContent
|
|
126
137
|
): StoredContent {
|
|
127
138
|
return {
|
|
128
|
-
id
|
|
139
|
+
id,
|
|
129
140
|
content: {
|
|
130
141
|
role: "user",
|
|
131
142
|
parts: [
|
|
@@ -141,26 +152,30 @@ export function createGoogleGenAIThreadManager(
|
|
|
141
152
|
};
|
|
142
153
|
},
|
|
143
154
|
|
|
144
|
-
async appendUserMessage(
|
|
145
|
-
|
|
155
|
+
async appendUserMessage(
|
|
156
|
+
id: string,
|
|
157
|
+
content: string | MessageContent
|
|
158
|
+
): Promise<void> {
|
|
159
|
+
await base.append([helpers.createUserContent(id, content)]);
|
|
146
160
|
},
|
|
147
161
|
|
|
148
|
-
async appendSystemMessage(content: string): Promise<void> {
|
|
162
|
+
async appendSystemMessage(id: string, content: string): Promise<void> {
|
|
149
163
|
await base.initialize();
|
|
150
|
-
await base.append([helpers.createSystemContent(content)]);
|
|
164
|
+
await base.append([helpers.createSystemContent(id, content)]);
|
|
151
165
|
},
|
|
152
166
|
|
|
153
|
-
async appendModelContent(parts: Part[]): Promise<void> {
|
|
154
|
-
await base.append([helpers.createModelContent(parts)]);
|
|
167
|
+
async appendModelContent(id: string, parts: Part[]): Promise<void> {
|
|
168
|
+
await base.append([helpers.createModelContent(id, parts)]);
|
|
155
169
|
},
|
|
156
170
|
|
|
157
171
|
async appendToolResult(
|
|
172
|
+
id: string,
|
|
158
173
|
toolCallId: string,
|
|
159
174
|
toolName: string,
|
|
160
|
-
content: ToolMessageContent
|
|
175
|
+
content: ToolMessageContent
|
|
161
176
|
): Promise<void> {
|
|
162
177
|
await base.append([
|
|
163
|
-
helpers.createToolResponseContent(toolCallId, toolName, content),
|
|
178
|
+
helpers.createToolResponseContent(id, toolCallId, toolName, content),
|
|
164
179
|
]);
|
|
165
180
|
},
|
|
166
181
|
};
|
|
@@ -74,24 +74,26 @@ export function createLangChainAdapter(
|
|
|
74
74
|
|
|
75
75
|
async appendHumanMessage(
|
|
76
76
|
threadId: string,
|
|
77
|
+
id: string,
|
|
77
78
|
content: string | MessageContent
|
|
78
79
|
): Promise<void> {
|
|
79
80
|
const thread = createLangChainThreadManager({ redis, threadId });
|
|
80
|
-
await thread.appendHumanMessage(content);
|
|
81
|
+
await thread.appendHumanMessage(id, content);
|
|
81
82
|
},
|
|
82
83
|
|
|
83
84
|
async appendSystemMessage(
|
|
84
85
|
threadId: string,
|
|
86
|
+
id: string,
|
|
85
87
|
content: string
|
|
86
88
|
): Promise<void> {
|
|
87
89
|
const thread = createLangChainThreadManager({ redis, threadId });
|
|
88
|
-
await thread.appendSystemMessage(content);
|
|
90
|
+
await thread.appendSystemMessage(id, content);
|
|
89
91
|
},
|
|
90
92
|
|
|
91
|
-
async appendToolResult(cfg: ToolResultConfig): Promise<void> {
|
|
93
|
+
async appendToolResult(id: string, cfg: ToolResultConfig): Promise<void> {
|
|
92
94
|
const { threadId, toolCallId, content } = cfg;
|
|
93
95
|
const thread = createLangChainThreadManager({ redis, threadId });
|
|
94
|
-
await thread.appendToolMessage(content, toolCallId);
|
|
96
|
+
await thread.appendToolMessage(id, content, toolCallId);
|
|
95
97
|
},
|
|
96
98
|
|
|
97
99
|
async forkThread(
|
|
@@ -9,7 +9,6 @@ import {
|
|
|
9
9
|
SystemMessage,
|
|
10
10
|
ToolMessage,
|
|
11
11
|
} from "@langchain/core/messages";
|
|
12
|
-
import { v4 as uuidv4 } from "uuid";
|
|
13
12
|
import {
|
|
14
13
|
createThreadManager,
|
|
15
14
|
type BaseThreadManager,
|
|
@@ -30,31 +29,44 @@ export interface LangChainThreadManagerConfig {
|
|
|
30
29
|
|
|
31
30
|
/** Thread manager with LangChain StoredMessage convenience helpers */
|
|
32
31
|
export interface LangChainThreadManager extends BaseThreadManager<StoredMessage> {
|
|
33
|
-
createHumanMessage(
|
|
34
|
-
|
|
32
|
+
createHumanMessage(
|
|
33
|
+
id: string,
|
|
34
|
+
content: string | MessageContent
|
|
35
|
+
): StoredMessage;
|
|
36
|
+
createSystemMessage(id: string, content: string): StoredMessage;
|
|
35
37
|
createAIMessage(
|
|
38
|
+
id: string,
|
|
36
39
|
content: string | MessageContent,
|
|
37
40
|
kwargs?: { header?: string; options?: string[]; multiSelect?: boolean }
|
|
38
41
|
): StoredMessage;
|
|
39
42
|
createToolMessage(
|
|
43
|
+
id: string,
|
|
40
44
|
content: LangChainToolMessageContent,
|
|
41
45
|
toolCallId: string
|
|
42
46
|
): StoredMessage;
|
|
43
|
-
appendHumanMessage(
|
|
44
|
-
|
|
47
|
+
appendHumanMessage(
|
|
48
|
+
id: string,
|
|
49
|
+
content: string | MessageContent
|
|
50
|
+
): Promise<void>;
|
|
51
|
+
appendSystemMessage(id: string, content: string): Promise<void>;
|
|
45
52
|
appendToolMessage(
|
|
53
|
+
id: string,
|
|
46
54
|
content: LangChainToolMessageContent,
|
|
47
55
|
toolCallId: string
|
|
48
56
|
): Promise<void>;
|
|
49
|
-
appendAIMessage(content: string | MessageContent): Promise<void>;
|
|
57
|
+
appendAIMessage(id: string, content: string | MessageContent): Promise<void>;
|
|
50
58
|
}
|
|
51
59
|
|
|
52
60
|
function storedMessageId(msg: StoredMessage): string {
|
|
53
|
-
if (msg.type === "tool") {
|
|
54
|
-
return msg.data.tool_call_id
|
|
61
|
+
if (msg.type === "tool" && msg.data.tool_call_id) {
|
|
62
|
+
return msg.data.tool_call_id;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (msg.data.id) {
|
|
66
|
+
return msg.data.id;
|
|
55
67
|
}
|
|
56
68
|
|
|
57
|
-
|
|
69
|
+
throw new Error("No id found for message");
|
|
58
70
|
}
|
|
59
71
|
|
|
60
72
|
/**
|
|
@@ -75,26 +87,30 @@ export function createLangChainThreadManager(
|
|
|
75
87
|
const base = createThreadManager(baseConfig);
|
|
76
88
|
|
|
77
89
|
const helpers = {
|
|
78
|
-
createHumanMessage(
|
|
90
|
+
createHumanMessage(
|
|
91
|
+
id: string,
|
|
92
|
+
content: string | MessageContent
|
|
93
|
+
): StoredMessage {
|
|
79
94
|
return new HumanMessage({
|
|
80
|
-
id
|
|
95
|
+
id,
|
|
81
96
|
content: content as string,
|
|
82
97
|
}).toDict();
|
|
83
98
|
},
|
|
84
99
|
|
|
85
|
-
createSystemMessage(content: string): StoredMessage {
|
|
100
|
+
createSystemMessage(id: string, content: string): StoredMessage {
|
|
86
101
|
return new SystemMessage({
|
|
87
|
-
id
|
|
102
|
+
id,
|
|
88
103
|
content: content as string,
|
|
89
104
|
}).toDict();
|
|
90
105
|
},
|
|
91
106
|
|
|
92
107
|
createAIMessage(
|
|
108
|
+
id: string,
|
|
93
109
|
content: string,
|
|
94
110
|
kwargs?: { header?: string; options?: string[]; multiSelect?: boolean }
|
|
95
111
|
): StoredMessage {
|
|
96
112
|
return new AIMessage({
|
|
97
|
-
id
|
|
113
|
+
id,
|
|
98
114
|
content,
|
|
99
115
|
additional_kwargs: kwargs
|
|
100
116
|
? {
|
|
@@ -107,36 +123,44 @@ export function createLangChainThreadManager(
|
|
|
107
123
|
},
|
|
108
124
|
|
|
109
125
|
createToolMessage(
|
|
126
|
+
id: string,
|
|
110
127
|
content: LangChainToolMessageContent,
|
|
111
128
|
toolCallId: string
|
|
112
129
|
): StoredMessage {
|
|
113
130
|
return new ToolMessage({
|
|
114
|
-
id
|
|
131
|
+
id,
|
|
115
132
|
content: content as MessageContent,
|
|
116
133
|
tool_call_id: toolCallId,
|
|
117
134
|
}).toDict();
|
|
118
135
|
},
|
|
119
136
|
|
|
120
|
-
async appendHumanMessage(
|
|
121
|
-
|
|
137
|
+
async appendHumanMessage(
|
|
138
|
+
id: string,
|
|
139
|
+
content: string | MessageContent
|
|
140
|
+
): Promise<void> {
|
|
141
|
+
const message = helpers.createHumanMessage(id, content);
|
|
122
142
|
await base.append([message]);
|
|
123
143
|
},
|
|
124
144
|
|
|
125
145
|
async appendToolMessage(
|
|
146
|
+
id: string,
|
|
126
147
|
content: LangChainToolMessageContent,
|
|
127
148
|
toolCallId: string
|
|
128
149
|
): Promise<void> {
|
|
129
|
-
const message = helpers.createToolMessage(content, toolCallId);
|
|
150
|
+
const message = helpers.createToolMessage(id, content, toolCallId);
|
|
130
151
|
await base.append([message]);
|
|
131
152
|
},
|
|
132
153
|
|
|
133
|
-
async appendAIMessage(
|
|
134
|
-
|
|
154
|
+
async appendAIMessage(
|
|
155
|
+
id: string,
|
|
156
|
+
content: string | MessageContent
|
|
157
|
+
): Promise<void> {
|
|
158
|
+
const message = helpers.createAIMessage(id, content as string);
|
|
135
159
|
await base.append([message]);
|
|
136
160
|
},
|
|
137
161
|
|
|
138
|
-
async appendSystemMessage(content: string): Promise<void> {
|
|
139
|
-
const message = helpers.createSystemMessage(content);
|
|
162
|
+
async appendSystemMessage(id: string, content: string): Promise<void> {
|
|
163
|
+
const message = helpers.createSystemMessage(id, content);
|
|
140
164
|
await base.initialize();
|
|
141
165
|
await base.append([message]);
|
|
142
166
|
},
|
|
@@ -15,6 +15,7 @@ import type { ParsedToolCallUnion, ToolMap } from "../tool-router/types";
|
|
|
15
15
|
import { getShortId } from "../thread/id";
|
|
16
16
|
import { buildSubagentRegistration } from "../subagent/register";
|
|
17
17
|
import { buildSkillRegistration } from "../skills/register";
|
|
18
|
+
import { uuid4 } from "@temporalio/workflow";
|
|
18
19
|
|
|
19
20
|
/**
|
|
20
21
|
* Creates an agent session that manages the agent loop: LLM invocation,
|
|
@@ -134,7 +135,7 @@ export const createSession = async <T extends ToolMap, M = unknown>({
|
|
|
134
135
|
threadId,
|
|
135
136
|
});
|
|
136
137
|
}
|
|
137
|
-
await appendHumanMessage(threadId, message);
|
|
138
|
+
await appendHumanMessage(threadId, uuid4(), message);
|
|
138
139
|
if (hooks.onPostHumanMessageAppend) {
|
|
139
140
|
await hooks.onPostHumanMessageAppend({
|
|
140
141
|
message,
|
|
@@ -176,12 +177,12 @@ export const createSession = async <T extends ToolMap, M = unknown>({
|
|
|
176
177
|
nonRetryable: true,
|
|
177
178
|
});
|
|
178
179
|
}
|
|
179
|
-
await appendSystemMessage(threadId, systemPrompt);
|
|
180
|
+
await appendSystemMessage(threadId, uuid4(), systemPrompt);
|
|
180
181
|
} else {
|
|
181
182
|
await initializeThread(threadId);
|
|
182
183
|
}
|
|
183
184
|
}
|
|
184
|
-
await appendHumanMessage(threadId, await buildContextMessage());
|
|
185
|
+
await appendHumanMessage(threadId, uuid4(), await buildContextMessage());
|
|
185
186
|
|
|
186
187
|
let exitReason: SessionExitReason = "completed";
|
|
187
188
|
|
|
@@ -222,7 +223,7 @@ export const createSession = async <T extends ToolMap, M = unknown>({
|
|
|
222
223
|
try {
|
|
223
224
|
parsedToolCalls.push(toolRouter.parseToolCall(tc));
|
|
224
225
|
} catch (error) {
|
|
225
|
-
await appendToolResult({
|
|
226
|
+
await appendToolResult(uuid4(), {
|
|
226
227
|
threadId,
|
|
227
228
|
toolCallId: tc.id ?? "",
|
|
228
229
|
toolName: tc.name,
|
package/src/lib/session/types.ts
CHANGED
|
@@ -27,12 +27,17 @@ export interface ThreadOps {
|
|
|
27
27
|
/** Append a human message to the thread */
|
|
28
28
|
appendHumanMessage(
|
|
29
29
|
threadId: string,
|
|
30
|
+
id: string,
|
|
30
31
|
content: string | MessageContent
|
|
31
32
|
): Promise<void>;
|
|
32
33
|
/** Append a tool result to the thread */
|
|
33
|
-
appendToolResult(config: ToolResultConfig): Promise<void>;
|
|
34
|
+
appendToolResult(id: string, config: ToolResultConfig): Promise<void>;
|
|
34
35
|
/** Append a system message to the thread */
|
|
35
|
-
appendSystemMessage(
|
|
36
|
+
appendSystemMessage(
|
|
37
|
+
threadId: string,
|
|
38
|
+
id: string,
|
|
39
|
+
content: string
|
|
40
|
+
): Promise<void>;
|
|
36
41
|
/** Copy all messages from sourceThreadId into a new thread at targetThreadId */
|
|
37
42
|
forkThread(sourceThreadId: string, targetThreadId: string): Promise<void>;
|
|
38
43
|
}
|
|
@@ -12,13 +12,13 @@ import type { Sandbox } from "../sandbox/types";
|
|
|
12
12
|
describe("withAutoAppend", () => {
|
|
13
13
|
it("appends tool result via threadHandler and sets resultAppended", async () => {
|
|
14
14
|
const appended: ToolResultConfig[] = [];
|
|
15
|
-
const threadHandler = async (config: ToolResultConfig) => {
|
|
15
|
+
const threadHandler = async (_id: string, config: ToolResultConfig) => {
|
|
16
16
|
appended.push(config);
|
|
17
17
|
};
|
|
18
18
|
|
|
19
19
|
const innerHandler = async (
|
|
20
20
|
args: { text: string },
|
|
21
|
-
_ctx: RouterContext
|
|
21
|
+
_ctx: RouterContext
|
|
22
22
|
): Promise<ToolHandlerResponse<{ echoed: string }>> => ({
|
|
23
23
|
toolResponse: `Echo: ${args.text}`,
|
|
24
24
|
data: { echoed: args.text },
|
|
@@ -32,7 +32,7 @@ describe("withAutoAppend", () => {
|
|
|
32
32
|
threadId: "thread-1",
|
|
33
33
|
toolCallId: "tc-1",
|
|
34
34
|
toolName: "Echo",
|
|
35
|
-
}
|
|
35
|
+
}
|
|
36
36
|
);
|
|
37
37
|
|
|
38
38
|
expect(result.resultAppended).toBe(true);
|
|
@@ -62,7 +62,7 @@ describe("withAutoAppend", () => {
|
|
|
62
62
|
|
|
63
63
|
const result = await wrapped(
|
|
64
64
|
{},
|
|
65
|
-
{ threadId: "t", toolCallId: "tc", toolName: "BigTool" }
|
|
65
|
+
{ threadId: "t", toolCallId: "tc", toolName: "BigTool" }
|
|
66
66
|
);
|
|
67
67
|
|
|
68
68
|
expect(result.toolResponse).toBe("Response appended via withAutoAppend");
|
|
@@ -81,10 +81,7 @@ describe("withAutoAppend", () => {
|
|
|
81
81
|
const wrapped = withAutoAppend(threadHandler, innerHandler);
|
|
82
82
|
|
|
83
83
|
await expect(
|
|
84
|
-
wrapped(
|
|
85
|
-
{},
|
|
86
|
-
{ threadId: "t", toolCallId: "tc", toolName: "Fail" },
|
|
87
|
-
),
|
|
84
|
+
wrapped({}, { threadId: "t", toolCallId: "tc", toolName: "Fail" })
|
|
88
85
|
).rejects.toThrow("handler failed");
|
|
89
86
|
|
|
90
87
|
expect(appendSpy).not.toHaveBeenCalled();
|
|
@@ -92,7 +89,7 @@ describe("withAutoAppend", () => {
|
|
|
92
89
|
|
|
93
90
|
it("uses correct context fields for thread handler config", async () => {
|
|
94
91
|
let capturedConfig: ToolResultConfig | null = null;
|
|
95
|
-
const threadHandler = async (config: ToolResultConfig) => {
|
|
92
|
+
const threadHandler = async (_id: string, config: ToolResultConfig) => {
|
|
96
93
|
capturedConfig = config;
|
|
97
94
|
};
|
|
98
95
|
|
|
@@ -110,7 +107,7 @@ describe("withAutoAppend", () => {
|
|
|
110
107
|
toolCallId: "my-tc",
|
|
111
108
|
toolName: "MyTool",
|
|
112
109
|
sandboxId: "sb-1",
|
|
113
|
-
}
|
|
110
|
+
}
|
|
114
111
|
);
|
|
115
112
|
|
|
116
113
|
expect(capturedConfig).toEqual({
|
|
@@ -177,7 +174,7 @@ describe("withSandbox", () => {
|
|
|
177
174
|
|
|
178
175
|
const handler = async (
|
|
179
176
|
_args: { text: string },
|
|
180
|
-
ctx: RouterContext & { sandbox: Sandbox; sandboxId: string }
|
|
177
|
+
ctx: RouterContext & { sandbox: Sandbox; sandboxId: string }
|
|
181
178
|
): Promise<ToolHandlerResponse<null>> => {
|
|
182
179
|
capturedSandbox = ctx.sandbox;
|
|
183
180
|
capturedSandboxId = ctx.sandboxId;
|
|
@@ -193,7 +190,7 @@ describe("withSandbox", () => {
|
|
|
193
190
|
toolCallId: "tc-1",
|
|
194
191
|
toolName: "Test",
|
|
195
192
|
sandboxId: "sb-42",
|
|
196
|
-
}
|
|
193
|
+
}
|
|
197
194
|
);
|
|
198
195
|
|
|
199
196
|
expect(result.toolResponse).toBe("ok");
|
|
@@ -219,7 +216,7 @@ describe("withSandbox", () => {
|
|
|
219
216
|
threadId: "thread-1",
|
|
220
217
|
toolCallId: "tc-1",
|
|
221
218
|
toolName: "Bash",
|
|
222
|
-
}
|
|
219
|
+
}
|
|
223
220
|
);
|
|
224
221
|
|
|
225
222
|
expect(result.toolResponse).toContain("No sandbox configured");
|
|
@@ -247,7 +244,7 @@ describe("withSandbox", () => {
|
|
|
247
244
|
toolCallId: "tc",
|
|
248
245
|
toolName: "Grep",
|
|
249
246
|
sandboxId: undefined,
|
|
250
|
-
}
|
|
247
|
+
}
|
|
251
248
|
);
|
|
252
249
|
|
|
253
250
|
expect(result.toolResponse).toContain("No sandbox configured");
|
|
@@ -276,8 +273,8 @@ describe("withSandbox", () => {
|
|
|
276
273
|
toolCallId: "tc",
|
|
277
274
|
toolName: "Test",
|
|
278
275
|
sandboxId: "sb-missing",
|
|
279
|
-
}
|
|
280
|
-
)
|
|
276
|
+
}
|
|
277
|
+
)
|
|
281
278
|
).rejects.toThrow("sandbox not found");
|
|
282
279
|
});
|
|
283
280
|
|
|
@@ -285,11 +282,13 @@ describe("withSandbox", () => {
|
|
|
285
282
|
const mockSandbox = createMockSandbox();
|
|
286
283
|
const manager = { getSandbox: async () => mockSandbox };
|
|
287
284
|
|
|
288
|
-
let capturedCtx:
|
|
285
|
+
let capturedCtx:
|
|
286
|
+
| (RouterContext & { sandbox: Sandbox; sandboxId: string })
|
|
287
|
+
| null = null;
|
|
289
288
|
|
|
290
289
|
const handler = async (
|
|
291
290
|
_args: unknown,
|
|
292
|
-
ctx: RouterContext & { sandbox: Sandbox; sandboxId: string }
|
|
291
|
+
ctx: RouterContext & { sandbox: Sandbox; sandboxId: string }
|
|
293
292
|
): Promise<ToolHandlerResponse<null>> => {
|
|
294
293
|
capturedCtx = ctx;
|
|
295
294
|
return { toolResponse: "ok", data: null };
|
|
@@ -304,7 +303,7 @@ describe("withSandbox", () => {
|
|
|
304
303
|
toolCallId: "my-tc",
|
|
305
304
|
toolName: "MyTool",
|
|
306
305
|
sandboxId: "my-sandbox",
|
|
307
|
-
}
|
|
306
|
+
}
|
|
308
307
|
);
|
|
309
308
|
|
|
310
309
|
expect(capturedCtx).toEqual(
|
|
@@ -314,7 +313,7 @@ describe("withSandbox", () => {
|
|
|
314
313
|
toolName: "MyTool",
|
|
315
314
|
sandboxId: "my-sandbox",
|
|
316
315
|
sandbox: mockSandbox,
|
|
317
|
-
})
|
|
316
|
+
})
|
|
318
317
|
);
|
|
319
318
|
});
|
|
320
319
|
|
|
@@ -335,7 +334,7 @@ describe("withSandbox", () => {
|
|
|
335
334
|
toolCallId: "tc",
|
|
336
335
|
toolName: "Test",
|
|
337
336
|
sandboxId: "",
|
|
338
|
-
}
|
|
337
|
+
}
|
|
339
338
|
);
|
|
340
339
|
|
|
341
340
|
expect(result.toolResponse).toContain("No sandbox configured");
|