kernl 0.10.0 → 0.11.1
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/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +22 -0
- package/dist/agent/base.d.ts +5 -1
- package/dist/agent/base.d.ts.map +1 -1
- package/dist/agent/base.js +8 -0
- package/dist/agent.d.ts +1 -1
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +15 -2
- package/dist/context.d.ts +2 -0
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +2 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/kernl/kernl.d.ts +1 -2
- package/dist/kernl/kernl.d.ts.map +1 -1
- package/dist/kernl/kernl.js +61 -1
- package/dist/lifecycle/__tests__/hooks.test.d.ts +2 -0
- package/dist/lifecycle/__tests__/hooks.test.d.ts.map +1 -0
- package/dist/lifecycle/__tests__/hooks.test.js +553 -0
- package/dist/lifecycle.d.ts +224 -107
- package/dist/lifecycle.d.ts.map +1 -1
- package/dist/lifecycle.js +2 -3
- package/dist/thread/__tests__/thread.test.js +2 -2
- package/dist/thread/thread.d.ts +4 -2
- package/dist/thread/thread.d.ts.map +1 -1
- package/dist/thread/thread.js +77 -8
- package/dist/thread/types.d.ts +1 -1
- package/dist/thread/types.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/agent/base.ts +13 -1
- package/src/agent.ts +17 -3
- package/src/context.ts +2 -0
- package/src/index.ts +12 -0
- package/src/kernl/kernl.ts +67 -3
- package/src/lifecycle/__tests__/hooks.test.ts +668 -0
- package/src/lifecycle.ts +295 -119
- package/src/thread/__tests__/thread.test.ts +2 -2
- package/src/thread/thread.ts +90 -10
- package/src/thread/types.ts +1 -1
package/src/lifecycle.ts
CHANGED
|
@@ -1,131 +1,307 @@
|
|
|
1
1
|
import { Emitter } from "@kernl-sdk/shared";
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
TOutput extends AgentOutputType = TextOutput,
|
|
14
|
-
> = {
|
|
15
|
-
/**
|
|
16
|
-
* @param context - The context of the run
|
|
17
|
-
*/
|
|
18
|
-
agent_start: [context: Context<TContext>, agent: Agent<TContext, TOutput>];
|
|
19
|
-
/**
|
|
20
|
-
* @param context - The context of the run
|
|
21
|
-
* @param output - The output of the agent
|
|
22
|
-
*/
|
|
23
|
-
agent_end: [context: Context<TContext>, output: string];
|
|
24
|
-
// /**
|
|
25
|
-
// * @param context - The context of the run
|
|
26
|
-
// * @param agent - The agent that is handing off
|
|
27
|
-
// * @param nextAgent - The next agent to run
|
|
28
|
-
// */
|
|
29
|
-
// agent_handoff: [context: Context<TContext>, nextAgent: Agent<any, any>];
|
|
30
|
-
/**
|
|
31
|
-
* @param context - The context of the run
|
|
32
|
-
* @param agent - The agent that is starting a tool
|
|
33
|
-
* @param tool - The tool that is starting
|
|
34
|
-
*/
|
|
35
|
-
agent_tool_start: [
|
|
36
|
-
context: Context<TContext>,
|
|
37
|
-
tool: Tool<any>,
|
|
38
|
-
details: { toolCall: ToolCall },
|
|
39
|
-
];
|
|
40
|
-
/**
|
|
41
|
-
* @param context - The context of the run
|
|
42
|
-
* @param agent - The agent that is ending a tool
|
|
43
|
-
* @param tool - The tool that is ending
|
|
44
|
-
* @param result - The result of the tool
|
|
45
|
-
*/
|
|
46
|
-
agent_tool_end: [
|
|
47
|
-
context: Context<TContext>,
|
|
48
|
-
tool: Tool<any>,
|
|
49
|
-
result: string,
|
|
50
|
-
details: { toolCall: ToolCall },
|
|
51
|
-
];
|
|
52
|
-
};
|
|
3
|
+
import type {
|
|
4
|
+
LanguageModelUsage,
|
|
5
|
+
LanguageModelFinishReason,
|
|
6
|
+
LanguageModelRequestSettings,
|
|
7
|
+
ToolCallState,
|
|
8
|
+
} from "@kernl-sdk/protocol";
|
|
9
|
+
import type { Context } from "@/context";
|
|
10
|
+
import type { ThreadState } from "@/thread/types";
|
|
11
|
+
|
|
12
|
+
// --- Thread Events ---
|
|
53
13
|
|
|
54
14
|
/**
|
|
55
|
-
*
|
|
56
|
-
* of the agent.
|
|
15
|
+
* Emitted when a thread starts execution.
|
|
57
16
|
*/
|
|
58
|
-
export
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
17
|
+
export interface ThreadStartEvent<TContext = unknown> {
|
|
18
|
+
readonly kind: "thread.start";
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* The thread ID.
|
|
22
|
+
*/
|
|
23
|
+
threadId: string;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* The agent executing this thread.
|
|
27
|
+
*/
|
|
28
|
+
agentId: string;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* The namespace of the thread.
|
|
32
|
+
*/
|
|
33
|
+
namespace: string;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* The context for this execution.
|
|
37
|
+
*
|
|
38
|
+
* NOTE: Includes `context.agent` reference for tools - may be optimized in future.
|
|
39
|
+
*/
|
|
40
|
+
context: Context<TContext>;
|
|
41
|
+
}
|
|
62
42
|
|
|
63
43
|
/**
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
* Unlike AgentHookEvents (which are emitted by individual agents with implicit context),
|
|
67
|
-
* KernlHookEvents explicitly include the agent reference in all events since it needs to
|
|
68
|
-
* coordinate multiple agents and listeners need to know which agent triggered each event.
|
|
44
|
+
* Emitted when a thread stops execution.
|
|
69
45
|
*/
|
|
70
|
-
export
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
*
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
*
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
46
|
+
export interface ThreadStopEvent<TContext = unknown, TOutput = unknown> {
|
|
47
|
+
readonly kind: "thread.stop";
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* The thread ID.
|
|
51
|
+
*/
|
|
52
|
+
threadId: string;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* The agent that executed this thread.
|
|
56
|
+
*/
|
|
57
|
+
agentId: string;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* The namespace of the thread.
|
|
61
|
+
*/
|
|
62
|
+
namespace: string;
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* The context for this execution.
|
|
66
|
+
*
|
|
67
|
+
* NOTE: Includes `context.agent` reference for tools - may be optimized in future.
|
|
68
|
+
*/
|
|
69
|
+
context: Context<TContext>;
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Final state of the thread.
|
|
73
|
+
*/
|
|
74
|
+
state: ThreadState;
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* The outcome of the execution.
|
|
78
|
+
*/
|
|
79
|
+
outcome: "success" | "error" | "cancelled";
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* The result if outcome is "success".
|
|
83
|
+
*/
|
|
84
|
+
result?: TOutput;
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Error message if outcome is "error".
|
|
88
|
+
*/
|
|
89
|
+
error?: string;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// --- Model Events ---
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Emitted when a model call starts.
|
|
96
|
+
*/
|
|
97
|
+
export interface ModelCallStartEvent<TContext = unknown> {
|
|
98
|
+
readonly kind: "model.call.start";
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* The model provider.
|
|
102
|
+
*/
|
|
103
|
+
provider: string;
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* The model ID.
|
|
107
|
+
*/
|
|
108
|
+
modelId: string;
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Request settings passed to the model.
|
|
112
|
+
*/
|
|
113
|
+
settings: LanguageModelRequestSettings;
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Thread ID if called within a thread context.
|
|
117
|
+
*/
|
|
118
|
+
threadId?: string;
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Agent ID if called within an agent context.
|
|
122
|
+
*/
|
|
123
|
+
agentId?: string;
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Execution context if available.
|
|
127
|
+
*
|
|
128
|
+
* NOTE: Includes `context.agent` reference for tools - may be optimized in future.
|
|
129
|
+
*/
|
|
130
|
+
context?: Context<TContext>;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Emitted when a model call ends.
|
|
135
|
+
*/
|
|
136
|
+
export interface ModelCallEndEvent<TContext = unknown> {
|
|
137
|
+
readonly kind: "model.call.end";
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* The model provider.
|
|
141
|
+
*/
|
|
142
|
+
provider: string;
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* The model ID.
|
|
146
|
+
*/
|
|
147
|
+
modelId: string;
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Reason the model stopped generating.
|
|
151
|
+
*/
|
|
152
|
+
finishReason: LanguageModelFinishReason;
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Token usage for this call.
|
|
156
|
+
*/
|
|
157
|
+
usage?: LanguageModelUsage;
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Thread ID if called within a thread context.
|
|
161
|
+
*/
|
|
162
|
+
threadId?: string;
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Agent ID if called within an agent context.
|
|
166
|
+
*/
|
|
167
|
+
agentId?: string;
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Execution context if available.
|
|
171
|
+
*
|
|
172
|
+
* NOTE: Includes `context.agent` reference for tools - may be optimized in future.
|
|
173
|
+
*/
|
|
174
|
+
context?: Context<TContext>;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// --- Tool Events ---
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Emitted when a tool call starts.
|
|
181
|
+
*/
|
|
182
|
+
export interface ToolCallStartEvent<TContext = unknown> {
|
|
183
|
+
readonly kind: "tool.call.start";
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* The thread ID.
|
|
187
|
+
*/
|
|
188
|
+
threadId: string;
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* The agent executing this tool.
|
|
192
|
+
*/
|
|
193
|
+
agentId: string;
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* The context for this execution.
|
|
197
|
+
*
|
|
198
|
+
* NOTE: Includes `context.agent` reference for tools - may be optimized in future.
|
|
199
|
+
*/
|
|
200
|
+
context: Context<TContext>;
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* The tool being called.
|
|
204
|
+
*/
|
|
205
|
+
toolId: string;
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Unique identifier for this call.
|
|
209
|
+
*/
|
|
210
|
+
callId: string;
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Arguments passed to the tool (parsed JSON).
|
|
214
|
+
*/
|
|
215
|
+
args: Record<string, unknown>;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Emitted when a tool call ends.
|
|
220
|
+
*/
|
|
221
|
+
export interface ToolCallEndEvent<TContext = unknown> {
|
|
222
|
+
readonly kind: "tool.call.end";
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* The thread ID.
|
|
226
|
+
*/
|
|
227
|
+
threadId: string;
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* The agent that executed this tool.
|
|
231
|
+
*/
|
|
232
|
+
agentId: string;
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* The context for this execution.
|
|
236
|
+
*
|
|
237
|
+
* NOTE: Includes `context.agent` reference for tools - may be optimized in future.
|
|
238
|
+
*/
|
|
239
|
+
context: Context<TContext>;
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* The tool that was called.
|
|
243
|
+
*/
|
|
244
|
+
toolId: string;
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Unique identifier for this call.
|
|
248
|
+
*/
|
|
249
|
+
callId: string;
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Final state of the tool call.
|
|
253
|
+
*/
|
|
254
|
+
state: ToolCallState;
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Result if state is "completed".
|
|
258
|
+
*/
|
|
259
|
+
result?: string;
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Error message if state is "failed", null if successful.
|
|
263
|
+
*/
|
|
264
|
+
error: string | null;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// --- Union ---
|
|
268
|
+
|
|
269
|
+
export type LifecycleEvent<TContext = unknown, TOutput = unknown> =
|
|
270
|
+
| ThreadStartEvent<TContext>
|
|
271
|
+
| ThreadStopEvent<TContext, TOutput>
|
|
272
|
+
| ModelCallStartEvent<TContext>
|
|
273
|
+
| ModelCallEndEvent<TContext>
|
|
274
|
+
| ToolCallStartEvent<TContext>
|
|
275
|
+
| ToolCallEndEvent<TContext>;
|
|
276
|
+
|
|
277
|
+
// --- Event Maps ---
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Event map for agent-level lifecycle hooks (typed).
|
|
281
|
+
*/
|
|
282
|
+
export type AgentHookEvents<TContext = unknown, TOutput = unknown> = {
|
|
283
|
+
"thread.start": [event: ThreadStartEvent<TContext>];
|
|
284
|
+
"thread.stop": [event: ThreadStopEvent<TContext, TOutput>];
|
|
285
|
+
"model.call.start": [event: ModelCallStartEvent<TContext>];
|
|
286
|
+
"model.call.end": [event: ModelCallEndEvent<TContext>];
|
|
287
|
+
"tool.call.start": [event: ToolCallStartEvent<TContext>];
|
|
288
|
+
"tool.call.end": [event: ToolCallEndEvent<TContext>];
|
|
123
289
|
};
|
|
124
290
|
|
|
125
291
|
/**
|
|
126
|
-
* Event
|
|
292
|
+
* Event map for Kernl-level lifecycle hooks (untyped).
|
|
293
|
+
*/
|
|
294
|
+
export type KernlHookEvents = AgentHookEvents<unknown, unknown>;
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Event emitter for agent-level lifecycle events.
|
|
298
|
+
*/
|
|
299
|
+
export class AgentHooks<
|
|
300
|
+
TContext = unknown,
|
|
301
|
+
TOutput = unknown,
|
|
302
|
+
> extends Emitter<AgentHookEvents<TContext, TOutput>> {}
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* Event emitter for Kernl-level lifecycle events.
|
|
127
306
|
*/
|
|
128
|
-
export class KernlHooks<
|
|
129
|
-
TContext = UnknownContext,
|
|
130
|
-
TOutput extends AgentOutputType = TextOutput,
|
|
131
|
-
> extends Emitter<KernlHookEvents<TContext, TOutput>> {}
|
|
307
|
+
export class KernlHooks extends Emitter<KernlHookEvents> {}
|
|
@@ -316,7 +316,7 @@ describe("Thread", () => {
|
|
|
316
316
|
toolId: "simple",
|
|
317
317
|
state: IN_PROGRESS,
|
|
318
318
|
callId: "call_1",
|
|
319
|
-
arguments: "first",
|
|
319
|
+
arguments: JSON.stringify({ value: "first" }),
|
|
320
320
|
},
|
|
321
321
|
],
|
|
322
322
|
finishReason: "stop",
|
|
@@ -343,7 +343,7 @@ describe("Thread", () => {
|
|
|
343
343
|
toolId: "simple",
|
|
344
344
|
state: IN_PROGRESS,
|
|
345
345
|
callId: "call_2",
|
|
346
|
-
arguments: "second",
|
|
346
|
+
arguments: JSON.stringify({ value: "second" }),
|
|
347
347
|
},
|
|
348
348
|
],
|
|
349
349
|
finishReason: "stop",
|
package/src/thread/thread.ts
CHANGED
|
@@ -19,6 +19,8 @@ import {
|
|
|
19
19
|
LanguageModel,
|
|
20
20
|
LanguageModelItem,
|
|
21
21
|
LanguageModelRequest,
|
|
22
|
+
type LanguageModelUsage,
|
|
23
|
+
type LanguageModelFinishReason,
|
|
22
24
|
} from "@kernl-sdk/protocol";
|
|
23
25
|
import { randomID, filter } from "@kernl-sdk/shared/lib";
|
|
24
26
|
|
|
@@ -90,8 +92,8 @@ export class Thread<
|
|
|
90
92
|
readonly tid: string;
|
|
91
93
|
readonly namespace: string;
|
|
92
94
|
readonly agent: Agent<TContext, TOutput>;
|
|
93
|
-
|
|
94
|
-
|
|
95
|
+
context: Context<TContext>;
|
|
96
|
+
model: LanguageModel; /* inherited from the agent unless specified */
|
|
95
97
|
readonly parent: Task<TContext> | null; /* parent task which spawned this thread */
|
|
96
98
|
readonly createdAt: Date;
|
|
97
99
|
readonly updatedAt: Date;
|
|
@@ -200,7 +202,7 @@ export class Thread<
|
|
|
200
202
|
*/
|
|
201
203
|
private async *_execute(): AsyncGenerator<ThreadStreamEvent, void> {
|
|
202
204
|
for (;;) {
|
|
203
|
-
let err =
|
|
205
|
+
let err: Error | undefined = undefined;
|
|
204
206
|
|
|
205
207
|
if (this.abort?.signal.aborted) {
|
|
206
208
|
return;
|
|
@@ -209,7 +211,7 @@ export class Thread<
|
|
|
209
211
|
const events = [];
|
|
210
212
|
for await (const e of this.tick()) {
|
|
211
213
|
if (e.kind === "error") {
|
|
212
|
-
err =
|
|
214
|
+
err = e.error;
|
|
213
215
|
logger.error(e.error); // (TODO): onError callback in options
|
|
214
216
|
}
|
|
215
217
|
// we don't want deltas in the history
|
|
@@ -220,9 +222,9 @@ export class Thread<
|
|
|
220
222
|
yield e;
|
|
221
223
|
}
|
|
222
224
|
|
|
223
|
-
// if an error event occurred →
|
|
225
|
+
// if an error event occurred → throw it
|
|
224
226
|
if (err) {
|
|
225
|
-
|
|
227
|
+
throw err;
|
|
226
228
|
}
|
|
227
229
|
|
|
228
230
|
// if model returns a message with no action intentions → terminal state
|
|
@@ -276,21 +278,59 @@ export class Thread<
|
|
|
276
278
|
|
|
277
279
|
const req = await this.prepareModelRequest(this.history);
|
|
278
280
|
|
|
281
|
+
this.agent.emit("model.call.start", {
|
|
282
|
+
kind: "model.call.start",
|
|
283
|
+
provider: this.model.provider,
|
|
284
|
+
modelId: this.model.modelId,
|
|
285
|
+
settings: req.settings ?? {},
|
|
286
|
+
threadId: this.tid,
|
|
287
|
+
agentId: this.agent.id,
|
|
288
|
+
context: this.context,
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
let usage: LanguageModelUsage | undefined;
|
|
292
|
+
let finishReason: LanguageModelFinishReason = "unknown";
|
|
293
|
+
|
|
279
294
|
try {
|
|
280
295
|
if (this.model.stream) {
|
|
281
|
-
const
|
|
282
|
-
|
|
283
|
-
|
|
296
|
+
for await (const event of this.model.stream(req)) {
|
|
297
|
+
if (event.kind === "finish") {
|
|
298
|
+
usage = event.usage;
|
|
299
|
+
finishReason = event.finishReason;
|
|
300
|
+
}
|
|
301
|
+
yield event;
|
|
284
302
|
}
|
|
285
303
|
} else {
|
|
286
304
|
// fallback: blocking generate, yield events as batch
|
|
287
305
|
const res = await this.model.generate(req);
|
|
306
|
+
usage = res.usage;
|
|
307
|
+
finishReason = res.finishReason;
|
|
288
308
|
for (const event of res.content) {
|
|
289
309
|
yield event;
|
|
290
310
|
}
|
|
291
|
-
// (TODO): this.stats.usage.add(res.usage)
|
|
292
311
|
}
|
|
312
|
+
|
|
313
|
+
this.agent.emit("model.call.end", {
|
|
314
|
+
kind: "model.call.end",
|
|
315
|
+
provider: this.model.provider,
|
|
316
|
+
modelId: this.model.modelId,
|
|
317
|
+
finishReason,
|
|
318
|
+
usage,
|
|
319
|
+
threadId: this.tid,
|
|
320
|
+
agentId: this.agent.id,
|
|
321
|
+
context: this.context,
|
|
322
|
+
});
|
|
293
323
|
} catch (error) {
|
|
324
|
+
this.agent.emit("model.call.end", {
|
|
325
|
+
kind: "model.call.end",
|
|
326
|
+
provider: this.model.provider,
|
|
327
|
+
modelId: this.model.modelId,
|
|
328
|
+
finishReason: "error",
|
|
329
|
+
threadId: this.tid,
|
|
330
|
+
agentId: this.agent.id,
|
|
331
|
+
context: this.context,
|
|
332
|
+
});
|
|
333
|
+
|
|
294
334
|
yield {
|
|
295
335
|
kind: "error",
|
|
296
336
|
error: error instanceof Error ? error : new Error(String(error)),
|
|
@@ -369,6 +409,8 @@ export class Thread<
|
|
|
369
409
|
|
|
370
410
|
/**
|
|
371
411
|
* Cancel the running thread
|
|
412
|
+
*
|
|
413
|
+
* TODO: Emit thread.stop with outcome: 'cancelled' when cancelled
|
|
372
414
|
*/
|
|
373
415
|
cancel() {
|
|
374
416
|
this.abort?.abort();
|
|
@@ -430,6 +472,18 @@ export class Thread<
|
|
|
430
472
|
private async executeTools(calls: ToolCall[]): Promise<ThreadEventInner[]> {
|
|
431
473
|
return await Promise.all(
|
|
432
474
|
calls.map(async (call: ToolCall) => {
|
|
475
|
+
const parsedArgs = JSON.parse(call.arguments || "{}");
|
|
476
|
+
|
|
477
|
+
this.agent.emit("tool.call.start", {
|
|
478
|
+
kind: "tool.call.start",
|
|
479
|
+
threadId: this.tid,
|
|
480
|
+
agentId: this.agent.id,
|
|
481
|
+
context: this.context,
|
|
482
|
+
toolId: call.toolId,
|
|
483
|
+
callId: call.callId,
|
|
484
|
+
args: parsedArgs,
|
|
485
|
+
});
|
|
486
|
+
|
|
433
487
|
try {
|
|
434
488
|
const tool = this.agent.tool(call.toolId);
|
|
435
489
|
if (!tool) {
|
|
@@ -449,6 +503,21 @@ export class Thread<
|
|
|
449
503
|
ctx.approve(call.callId); // mark this call as approved
|
|
450
504
|
const res = await tool.invoke(ctx, call.arguments, call.callId);
|
|
451
505
|
|
|
506
|
+
this.agent.emit("tool.call.end", {
|
|
507
|
+
kind: "tool.call.end",
|
|
508
|
+
threadId: this.tid,
|
|
509
|
+
agentId: this.agent.id,
|
|
510
|
+
context: this.context,
|
|
511
|
+
toolId: call.toolId,
|
|
512
|
+
callId: call.callId,
|
|
513
|
+
state: res.state,
|
|
514
|
+
result:
|
|
515
|
+
typeof res.result === "string"
|
|
516
|
+
? res.result
|
|
517
|
+
: JSON.stringify(res.result),
|
|
518
|
+
error: res.error,
|
|
519
|
+
});
|
|
520
|
+
|
|
452
521
|
return {
|
|
453
522
|
kind: "tool-result" as const,
|
|
454
523
|
callId: call.callId,
|
|
@@ -458,6 +527,17 @@ export class Thread<
|
|
|
458
527
|
error: res.error,
|
|
459
528
|
};
|
|
460
529
|
} catch (error) {
|
|
530
|
+
this.agent.emit("tool.call.end", {
|
|
531
|
+
kind: "tool.call.end",
|
|
532
|
+
threadId: this.tid,
|
|
533
|
+
agentId: this.agent.id,
|
|
534
|
+
context: this.context,
|
|
535
|
+
toolId: call.toolId,
|
|
536
|
+
callId: call.callId,
|
|
537
|
+
state: FAILED,
|
|
538
|
+
error: error instanceof Error ? error.message : String(error),
|
|
539
|
+
});
|
|
540
|
+
|
|
461
541
|
return {
|
|
462
542
|
kind: "tool-result" as const,
|
|
463
543
|
callId: call.callId,
|
package/src/thread/types.ts
CHANGED
|
@@ -179,7 +179,7 @@ export interface ThreadOptions<
|
|
|
179
179
|
* Options passed to agent.execute() and agent.stream().
|
|
180
180
|
*/
|
|
181
181
|
export interface ThreadExecuteOptions<TContext> {
|
|
182
|
-
context?:
|
|
182
|
+
context?: TContext;
|
|
183
183
|
model?: LanguageModel;
|
|
184
184
|
task?: Task<TContext>;
|
|
185
185
|
threadId?: string;
|