kernl 0.2.0 → 0.6.0
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 +4 -5
- package/.turbo/turbo-check-types.log +4 -0
- package/CHANGELOG.md +147 -0
- package/LICENSE +1 -1
- package/dist/agent/__tests__/concurrency.test.d.ts +2 -0
- package/dist/agent/__tests__/concurrency.test.d.ts.map +1 -0
- package/dist/agent/__tests__/concurrency.test.js +152 -0
- package/dist/agent/__tests__/run.test.d.ts +2 -0
- package/dist/agent/__tests__/run.test.d.ts.map +1 -0
- package/dist/agent/__tests__/run.test.js +357 -0
- package/dist/agent/index.d.ts +1 -0
- package/dist/agent/index.d.ts.map +1 -0
- package/dist/agent.d.ts +32 -9
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +102 -14
- package/dist/api/__tests__/cursor-page.test.d.ts +2 -0
- package/dist/api/__tests__/cursor-page.test.d.ts.map +1 -0
- package/dist/api/__tests__/cursor-page.test.js +414 -0
- package/dist/api/__tests__/offset-page.test.d.ts +2 -0
- package/dist/api/__tests__/offset-page.test.d.ts.map +1 -0
- package/dist/api/__tests__/offset-page.test.js +510 -0
- package/dist/api/__tests__/threads.test.d.ts +2 -0
- package/dist/api/__tests__/threads.test.d.ts.map +1 -0
- package/dist/api/__tests__/threads.test.js +338 -0
- package/dist/api/models/index.d.ts +2 -0
- package/dist/api/models/index.d.ts.map +1 -0
- package/dist/api/models/thread.d.ts +120 -0
- package/dist/api/models/thread.d.ts.map +1 -0
- package/dist/api/pagination/base.d.ts +48 -0
- package/dist/api/pagination/base.d.ts.map +1 -0
- package/dist/api/pagination/base.js +45 -0
- package/dist/api/pagination/cursor.d.ts +44 -0
- package/dist/api/pagination/cursor.d.ts.map +1 -0
- package/dist/api/pagination/cursor.js +52 -0
- package/dist/api/pagination/offset.d.ts +42 -0
- package/dist/api/pagination/offset.d.ts.map +1 -0
- package/dist/api/pagination/offset.js +55 -0
- package/dist/api/resources/threads/events.d.ts +21 -0
- package/dist/api/resources/threads/events.d.ts.map +1 -0
- package/dist/api/resources/threads/events.js +24 -0
- package/dist/api/resources/threads/index.d.ts +4 -0
- package/dist/api/resources/threads/index.d.ts.map +1 -0
- package/dist/api/resources/threads/index.js +2 -0
- package/dist/api/resources/threads/threads.d.ts +57 -0
- package/dist/api/resources/threads/threads.d.ts.map +1 -0
- package/dist/api/resources/threads/threads.js +199 -0
- package/dist/api/resources/threads/types.d.ts +123 -0
- package/dist/api/resources/threads/types.d.ts.map +1 -0
- package/dist/api/resources/threads/utils.d.ts +18 -0
- package/dist/api/resources/threads/utils.d.ts.map +1 -0
- package/dist/api/resources/threads/utils.js +78 -0
- package/dist/context.d.ts +5 -1
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +6 -1
- package/dist/index.d.ts +9 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -0
- package/dist/internal.d.ts +4 -0
- package/dist/internal.d.ts.map +1 -0
- package/dist/internal.js +2 -0
- package/dist/kernl/index.d.ts +3 -0
- package/dist/kernl/index.d.ts.map +1 -0
- package/dist/kernl/index.js +2 -0
- package/dist/kernl/kernl.d.ts +64 -0
- package/dist/kernl/kernl.d.ts.map +1 -0
- package/dist/kernl/kernl.js +116 -0
- package/dist/kernl/threads.d.ts +110 -0
- package/dist/kernl/threads.d.ts.map +1 -0
- package/dist/kernl/threads.js +126 -0
- package/dist/kernl.d.ts +22 -6
- package/dist/kernl.d.ts.map +1 -1
- package/dist/kernl.js +73 -10
- package/dist/lib/env.d.ts +3 -3
- package/dist/lib/env.js +1 -1
- package/dist/mcp/__tests__/integration.test.js +8 -8
- package/dist/mcp/__tests__/utils.test.js +6 -6
- package/dist/mcp/http.d.ts +1 -1
- package/dist/mcp/http.d.ts.map +1 -1
- package/dist/mcp/http.js +9 -9
- package/dist/mcp/sse.d.ts +1 -1
- package/dist/mcp/sse.d.ts.map +1 -1
- package/dist/mcp/sse.js +7 -7
- package/dist/mcp/utils.d.ts +1 -1
- package/dist/mcp/utils.d.ts.map +1 -1
- package/dist/mcp/utils.js +4 -5
- package/dist/storage/__tests__/in-memory.test.d.ts +2 -0
- package/dist/storage/__tests__/in-memory.test.d.ts.map +1 -0
- package/dist/storage/__tests__/in-memory.test.js +455 -0
- package/dist/storage/base.d.ts +64 -0
- package/dist/storage/base.d.ts.map +1 -0
- package/dist/storage/base.js +4 -0
- package/dist/storage/in-memory.d.ts +62 -0
- package/dist/storage/in-memory.d.ts.map +1 -0
- package/dist/storage/in-memory.js +283 -0
- package/dist/storage/index.d.ts +10 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +7 -0
- package/dist/storage/thread.d.ts +123 -0
- package/dist/storage/thread.d.ts.map +1 -0
- package/dist/storage/thread.js +4 -0
- package/dist/task.d.ts +5 -3
- package/dist/task.d.ts.map +1 -1
- package/dist/task.js +10 -8
- package/dist/thread/__tests__/fixtures/mock-model.d.ts +1 -2
- package/dist/thread/__tests__/fixtures/mock-model.d.ts.map +1 -1
- package/dist/thread/__tests__/integration.test.js +73 -5
- package/dist/thread/__tests__/namespace.test.d.ts +2 -0
- package/dist/thread/__tests__/namespace.test.d.ts.map +1 -0
- package/dist/thread/__tests__/namespace.test.js +131 -0
- package/dist/thread/__tests__/thread-persistence.test.d.ts +2 -0
- package/dist/thread/__tests__/thread-persistence.test.d.ts.map +1 -0
- package/dist/thread/__tests__/thread-persistence.test.js +351 -0
- package/dist/thread/__tests__/thread.test.js +49 -51
- package/dist/thread/thread.d.ts +70 -18
- package/dist/thread/thread.d.ts.map +1 -1
- package/dist/thread/thread.js +211 -73
- package/dist/thread/utils.d.ts +36 -8
- package/dist/thread/utils.d.ts.map +1 -1
- package/dist/thread/utils.js +52 -8
- package/dist/tool/__tests__/fixtures.js +1 -1
- package/dist/tool/__tests__/toolkit.test.js +15 -12
- package/dist/tool/tool.js +3 -3
- package/dist/types/kernl.d.ts +42 -0
- package/dist/types/kernl.d.ts.map +1 -0
- package/dist/types/thread.d.ts +108 -22
- package/dist/types/thread.d.ts.map +1 -1
- package/dist/types/thread.js +12 -0
- package/package.json +11 -7
- package/src/agent/__tests__/concurrency.test.ts +194 -0
- package/src/agent/__tests__/run.test.ts +441 -0
- package/src/agent/index.ts +0 -0
- package/src/agent.ts +141 -24
- package/src/api/__tests__/cursor-page.test.ts +512 -0
- package/src/api/__tests__/offset-page.test.ts +624 -0
- package/src/api/__tests__/threads.test.ts +415 -0
- package/src/api/models/index.ts +6 -0
- package/src/api/models/thread.ts +138 -0
- package/src/api/pagination/base.ts +79 -0
- package/src/api/pagination/cursor.ts +86 -0
- package/src/api/pagination/offset.ts +89 -0
- package/src/api/resources/threads/events.ts +26 -0
- package/src/api/resources/threads/index.ts +9 -0
- package/src/api/resources/threads/threads.ts +256 -0
- package/src/api/resources/threads/types.ts +143 -0
- package/src/api/resources/threads/utils.ts +104 -0
- package/src/context.ts +10 -1
- package/src/index.ts +49 -1
- package/src/internal.ts +15 -0
- package/src/kernl.ts +86 -17
- package/src/mcp/__tests__/integration.test.ts +8 -9
- package/src/mcp/__tests__/utils.test.ts +6 -6
- package/src/mcp/http.ts +9 -9
- package/src/mcp/sse.ts +7 -7
- package/src/mcp/utils.ts +6 -5
- package/src/storage/__tests__/in-memory.test.ts +534 -0
- package/src/storage/base.ts +77 -0
- package/src/storage/in-memory.ts +372 -0
- package/src/storage/index.ts +21 -0
- package/src/storage/thread.ts +141 -0
- package/src/task.ts +12 -10
- package/src/thread/__tests__/fixtures/mock-model.ts +2 -4
- package/src/thread/__tests__/integration.test.ts +111 -10
- package/src/thread/__tests__/namespace.test.ts +158 -0
- package/src/thread/__tests__/thread-persistence.test.ts +367 -0
- package/src/thread/__tests__/thread.test.ts +52 -54
- package/src/thread/thread.ts +247 -96
- package/src/thread/utils.ts +76 -13
- package/src/tool/__tests__/fixtures.ts +1 -1
- package/src/tool/__tests__/toolkit.test.ts +15 -12
- package/src/tool/tool.ts +3 -3
- package/src/types/kernl.ts +51 -0
- package/src/types/thread.ts +139 -25
- package/vitest.config.ts +1 -0
- package/dist/env.d.ts +0 -45
- package/dist/env.d.ts.map +0 -1
- package/dist/env.js +0 -31
- package/dist/error.d.ts +0 -1
- package/dist/error.d.ts.map +0 -1
- package/dist/kernel.d.ts +0 -7
- package/dist/kernel.d.ts.map +0 -1
- package/dist/kernel.js +0 -7
- package/dist/lib/serde/__tests__/codec.test.d.ts +0 -2
- package/dist/lib/serde/__tests__/codec.test.d.ts.map +0 -1
- package/dist/lib/serde/__tests__/codec.test.js +0 -75
- package/dist/lib/serde/codec.d.ts +0 -12
- package/dist/lib/serde/codec.d.ts.map +0 -1
- package/dist/lib/serde/codec.js +0 -54
- package/dist/lib/serde/thread.d.ts +0 -1
- package/dist/lib/serde/thread.d.ts.map +0 -1
- package/dist/lib/serde/thread.js +0 -172
- package/dist/lib/serde/tool.d.ts +0 -36
- package/dist/lib/serde/tool.d.ts.map +0 -1
- package/dist/lib/utils.d.ts +0 -19
- package/dist/lib/utils.d.ts.map +0 -1
- package/dist/lib/utils.js +0 -41
- package/dist/logger.d.ts +0 -36
- package/dist/logger.d.ts.map +0 -1
- package/dist/logger.js +0 -43
- package/dist/mcp/__tests__/fixtures/echo-server.d.ts +0 -3
- package/dist/mcp/__tests__/fixtures/echo-server.d.ts.map +0 -1
- package/dist/mcp/__tests__/fixtures/echo-server.js +0 -92
- package/dist/mcp/__tests__/fixtures/math-server.d.ts +0 -3
- package/dist/mcp/__tests__/fixtures/math-server.d.ts.map +0 -1
- package/dist/mcp/__tests__/fixtures/math-server.js +0 -98
- package/dist/mcp/__tests__/fixtures/test-server.d.ts +0 -3
- package/dist/mcp/__tests__/fixtures/test-server.d.ts.map +0 -1
- package/dist/mcp/__tests__/fixtures/test-server.js +0 -163
- package/dist/mcp/__tests__/test-utils.d.ts +0 -17
- package/dist/mcp/__tests__/test-utils.d.ts.map +0 -1
- package/dist/mcp/__tests__/test-utils.js +0 -42
- package/dist/mcp/node.d.ts +0 -60
- package/dist/mcp/node.d.ts.map +0 -1
- package/dist/mcp/node.js +0 -297
- package/dist/model.d.ts +0 -175
- package/dist/model.d.ts.map +0 -1
- package/dist/providers/ai.d.ts +0 -1
- package/dist/providers/ai.d.ts.map +0 -1
- package/dist/providers/ai.js +0 -1
- package/dist/providers/default.d.ts +0 -16
- package/dist/providers/default.d.ts.map +0 -1
- package/dist/providers/default.js +0 -17
- package/dist/providers/registry.d.ts +0 -1
- package/dist/providers/registry.d.ts.map +0 -1
- package/dist/providers/registry.js +0 -1
- package/dist/sched/scheduler.d.ts +0 -20
- package/dist/sched/scheduler.d.ts.map +0 -1
- package/dist/sched/task.d.ts +0 -92
- package/dist/sched/task.d.ts.map +0 -1
- package/dist/sched/task.js +0 -102
- package/dist/serde/__tests__/codec.test.d.ts +0 -2
- package/dist/serde/__tests__/codec.test.d.ts.map +0 -1
- package/dist/serde/__tests__/codec.test.js +0 -75
- package/dist/serde/codec.d.ts +0 -12
- package/dist/serde/codec.d.ts.map +0 -1
- package/dist/serde/codec.js +0 -54
- package/dist/serde/json.d.ts +0 -8
- package/dist/serde/json.d.ts.map +0 -1
- package/dist/serde/json.js +0 -13
- package/dist/serde/thread.d.ts +0 -687
- package/dist/serde/thread.d.ts.map +0 -1
- package/dist/serde/thread.js +0 -158
- package/dist/serde/tool.d.ts +0 -36
- package/dist/serde/tool.d.ts.map +0 -1
- package/dist/session.d.ts +0 -1
- package/dist/session.d.ts.map +0 -1
- package/dist/session.js +0 -1
- package/dist/thread/__tests__/stream.test.d.ts +0 -2
- package/dist/thread/__tests__/stream.test.d.ts.map +0 -1
- package/dist/thread/__tests__/stream.test.js +0 -244
- package/dist/tool/mcp.d.ts +0 -75
- package/dist/tool/mcp.d.ts.map +0 -1
- package/dist/tool/mcp.js +0 -111
- package/dist/tools.d.ts +0 -362
- package/dist/tools.d.ts.map +0 -1
- package/dist/tools.js +0 -220
- package/dist/types/proto.d.ts +0 -1551
- package/dist/types/proto.d.ts.map +0 -1
- package/dist/types/proto.js +0 -531
- package/dist/usage.d.ts +0 -43
- package/dist/usage.d.ts.map +0 -1
- package/dist/usage.js +0 -61
- package/src/lib/serde/thread.ts +0 -188
- /package/dist/{error.js → agent/index.js} +0 -0
- /package/dist/{lib/serde/tool.js → api/models/index.js} +0 -0
- /package/dist/{model.js → api/models/thread.js} +0 -0
- /package/dist/{sched/scheduler.js → api/resources/threads/types.js} +0 -0
- /package/dist/{serde/tool.js → types/kernl.js} +0 -0
|
@@ -10,6 +10,7 @@ import { tool, Toolkit } from "@/tool";
|
|
|
10
10
|
import { Thread } from "../thread";
|
|
11
11
|
|
|
12
12
|
import type { ThreadEvent, ThreadStreamEvent } from "@/types/thread";
|
|
13
|
+
import type { LanguageModelItem } from "@kernl-sdk/protocol";
|
|
13
14
|
|
|
14
15
|
/**
|
|
15
16
|
* Integration tests for Thread streaming with real AI SDK providers.
|
|
@@ -44,7 +45,7 @@ describe.skipIf(SKIP_INTEGRATION_TESTS)(
|
|
|
44
45
|
model,
|
|
45
46
|
});
|
|
46
47
|
|
|
47
|
-
const input:
|
|
48
|
+
const input: LanguageModelItem[] = [
|
|
48
49
|
{
|
|
49
50
|
kind: "message",
|
|
50
51
|
id: "msg-1",
|
|
@@ -55,7 +56,7 @@ describe.skipIf(SKIP_INTEGRATION_TESTS)(
|
|
|
55
56
|
},
|
|
56
57
|
];
|
|
57
58
|
|
|
58
|
-
const thread = new Thread(
|
|
59
|
+
const thread = new Thread({ agent, input });
|
|
59
60
|
const events = [];
|
|
60
61
|
|
|
61
62
|
for await (const event of thread.stream()) {
|
|
@@ -116,7 +117,7 @@ describe.skipIf(SKIP_INTEGRATION_TESTS)(
|
|
|
116
117
|
model,
|
|
117
118
|
});
|
|
118
119
|
|
|
119
|
-
const input:
|
|
120
|
+
const input: LanguageModelItem[] = [
|
|
120
121
|
{
|
|
121
122
|
kind: "message",
|
|
122
123
|
id: "msg-1",
|
|
@@ -125,7 +126,7 @@ describe.skipIf(SKIP_INTEGRATION_TESTS)(
|
|
|
125
126
|
},
|
|
126
127
|
];
|
|
127
128
|
|
|
128
|
-
const thread = new Thread(
|
|
129
|
+
const thread = new Thread({ agent, input });
|
|
129
130
|
const streamEvents = [];
|
|
130
131
|
|
|
131
132
|
for await (const event of thread.stream()) {
|
|
@@ -200,7 +201,7 @@ describe.skipIf(SKIP_INTEGRATION_TESTS)(
|
|
|
200
201
|
toolkits: [toolkit],
|
|
201
202
|
});
|
|
202
203
|
|
|
203
|
-
const input:
|
|
204
|
+
const input: LanguageModelItem[] = [
|
|
204
205
|
{
|
|
205
206
|
kind: "message",
|
|
206
207
|
id: "msg-1",
|
|
@@ -209,7 +210,7 @@ describe.skipIf(SKIP_INTEGRATION_TESTS)(
|
|
|
209
210
|
},
|
|
210
211
|
];
|
|
211
212
|
|
|
212
|
-
const thread = new Thread(
|
|
213
|
+
const thread = new Thread({ agent, input });
|
|
213
214
|
const events: ThreadStreamEvent[] = [];
|
|
214
215
|
|
|
215
216
|
for await (const event of thread.stream()) {
|
|
@@ -266,6 +267,106 @@ describe.skipIf(SKIP_INTEGRATION_TESTS)(
|
|
|
266
267
|
},
|
|
267
268
|
30000,
|
|
268
269
|
);
|
|
270
|
+
|
|
271
|
+
it(
|
|
272
|
+
"should properly encode tool results with matching callIds for multi-turn",
|
|
273
|
+
async () => {
|
|
274
|
+
const multiplyTool = tool({
|
|
275
|
+
id: "multiply",
|
|
276
|
+
name: "multiply",
|
|
277
|
+
description: "Multiply two numbers",
|
|
278
|
+
parameters: z.object({
|
|
279
|
+
a: z.number().describe("First number"),
|
|
280
|
+
b: z.number().describe("Second number"),
|
|
281
|
+
}),
|
|
282
|
+
execute: async (ctx, { a, b }) => {
|
|
283
|
+
return a * b;
|
|
284
|
+
},
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
const toolkit = new Toolkit({
|
|
288
|
+
id: "math",
|
|
289
|
+
tools: [multiplyTool],
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
const agent = new Agent({
|
|
293
|
+
id: "test-multi-turn",
|
|
294
|
+
name: "Test Multi-Turn Agent",
|
|
295
|
+
instructions: "You are a helpful assistant that can do math.",
|
|
296
|
+
model,
|
|
297
|
+
toolkits: [toolkit],
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
const input: LanguageModelItem[] = [
|
|
301
|
+
{
|
|
302
|
+
kind: "message",
|
|
303
|
+
id: "msg-1",
|
|
304
|
+
role: "user",
|
|
305
|
+
content: [{ kind: "text", text: "What is 7 times 6?" }],
|
|
306
|
+
},
|
|
307
|
+
];
|
|
308
|
+
|
|
309
|
+
const thread = new Thread({ agent, input });
|
|
310
|
+
const events: ThreadStreamEvent[] = [];
|
|
311
|
+
|
|
312
|
+
// Collect all events from the stream
|
|
313
|
+
for await (const event of thread.stream()) {
|
|
314
|
+
events.push(event);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
// Find the tool call and result
|
|
318
|
+
const toolCalls = events.filter(
|
|
319
|
+
(e): e is Extract<ThreadStreamEvent, { kind: "tool-call" }> =>
|
|
320
|
+
e.kind === "tool-call",
|
|
321
|
+
);
|
|
322
|
+
const toolResults = events.filter(
|
|
323
|
+
(e): e is Extract<ThreadStreamEvent, { kind: "tool-result" }> =>
|
|
324
|
+
e.kind === "tool-result",
|
|
325
|
+
);
|
|
326
|
+
|
|
327
|
+
expect(toolCalls.length).toBeGreaterThan(0);
|
|
328
|
+
expect(toolResults.length).toBeGreaterThan(0);
|
|
329
|
+
|
|
330
|
+
const multiplyCall = toolCalls[0];
|
|
331
|
+
const multiplyResult = toolResults[0];
|
|
332
|
+
|
|
333
|
+
// Verify callId matches between tool call and result
|
|
334
|
+
expect(multiplyCall.callId).toBe(multiplyResult.callId);
|
|
335
|
+
expect(multiplyCall.toolId).toBe("multiply");
|
|
336
|
+
expect(multiplyResult.toolId).toBe("multiply");
|
|
337
|
+
|
|
338
|
+
// Verify the tool result has the correct structure
|
|
339
|
+
expect(multiplyResult.callId).toBeDefined();
|
|
340
|
+
expect(typeof multiplyResult.callId).toBe("string");
|
|
341
|
+
expect(multiplyResult.callId.length).toBeGreaterThan(0);
|
|
342
|
+
|
|
343
|
+
// Verify history contains both with matching callIds
|
|
344
|
+
const history = (thread as any).history as ThreadEvent[];
|
|
345
|
+
const historyToolCall = history.find(
|
|
346
|
+
(e) => e.kind === "tool-call" && e.toolId === "multiply",
|
|
347
|
+
);
|
|
348
|
+
const historyToolResult = history.find(
|
|
349
|
+
(e) => e.kind === "tool-result" && e.toolId === "multiply",
|
|
350
|
+
);
|
|
351
|
+
|
|
352
|
+
expect(historyToolCall).toBeDefined();
|
|
353
|
+
expect(historyToolResult).toBeDefined();
|
|
354
|
+
expect((historyToolCall as any).callId).toBe(
|
|
355
|
+
(historyToolResult as any).callId,
|
|
356
|
+
);
|
|
357
|
+
|
|
358
|
+
// Verify final response uses the tool result
|
|
359
|
+
const messages = events.filter((e) => e.kind === "message");
|
|
360
|
+
const assistantMessage = messages.find((m: any) => m.role === "assistant");
|
|
361
|
+
expect(assistantMessage).toBeDefined();
|
|
362
|
+
const textContent = (assistantMessage as any).content.find(
|
|
363
|
+
(c: any) => c.kind === "text",
|
|
364
|
+
);
|
|
365
|
+
expect(textContent).toBeDefined();
|
|
366
|
+
expect(textContent.text).toContain("42");
|
|
367
|
+
},
|
|
368
|
+
30000,
|
|
369
|
+
);
|
|
269
370
|
});
|
|
270
371
|
|
|
271
372
|
describe("execute()", () => {
|
|
@@ -279,7 +380,7 @@ describe.skipIf(SKIP_INTEGRATION_TESTS)(
|
|
|
279
380
|
model,
|
|
280
381
|
});
|
|
281
382
|
|
|
282
|
-
const input:
|
|
383
|
+
const input: LanguageModelItem[] = [
|
|
283
384
|
{
|
|
284
385
|
kind: "message",
|
|
285
386
|
id: "msg-1",
|
|
@@ -288,7 +389,7 @@ describe.skipIf(SKIP_INTEGRATION_TESTS)(
|
|
|
288
389
|
},
|
|
289
390
|
];
|
|
290
391
|
|
|
291
|
-
const thread = new Thread(
|
|
392
|
+
const thread = new Thread({ agent, input });
|
|
292
393
|
const result = await thread.execute();
|
|
293
394
|
|
|
294
395
|
// Should have a response
|
|
@@ -319,7 +420,7 @@ describe.skipIf(SKIP_INTEGRATION_TESTS)(
|
|
|
319
420
|
responseType: responseSchema,
|
|
320
421
|
});
|
|
321
422
|
|
|
322
|
-
const input:
|
|
423
|
+
const input: LanguageModelItem[] = [
|
|
323
424
|
{
|
|
324
425
|
kind: "message",
|
|
325
426
|
id: "msg-1",
|
|
@@ -333,7 +434,7 @@ describe.skipIf(SKIP_INTEGRATION_TESTS)(
|
|
|
333
434
|
},
|
|
334
435
|
];
|
|
335
436
|
|
|
336
|
-
const thread = new Thread(
|
|
437
|
+
const thread = new Thread({ agent, input });
|
|
337
438
|
const result = await thread.execute();
|
|
338
439
|
|
|
339
440
|
// Response should be validated and parsed
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
|
|
3
|
+
import { Thread } from "../thread";
|
|
4
|
+
import { Agent } from "@/agent";
|
|
5
|
+
import { Kernl } from "@/kernl";
|
|
6
|
+
import { Context } from "@/context";
|
|
7
|
+
import { InMemoryStorage } from "@/storage/in-memory";
|
|
8
|
+
import { createMockModel } from "./fixtures/mock-model";
|
|
9
|
+
import type { LanguageModelRequest, LanguageModelItem } from "@kernl-sdk/protocol";
|
|
10
|
+
|
|
11
|
+
// Helper to create user message input
|
|
12
|
+
function userMessage(text: string): LanguageModelItem[] {
|
|
13
|
+
return [
|
|
14
|
+
{
|
|
15
|
+
kind: "message" as const,
|
|
16
|
+
id: "msg-test",
|
|
17
|
+
role: "user" as const,
|
|
18
|
+
content: [{ kind: "text" as const, text }],
|
|
19
|
+
},
|
|
20
|
+
];
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
describe("Thread Namespaces", () => {
|
|
24
|
+
it("should use 'kernl' namespace by default", () => {
|
|
25
|
+
const model = createMockModel(async () => ({
|
|
26
|
+
content: [],
|
|
27
|
+
finishReason: "stop",
|
|
28
|
+
usage: { inputTokens: 0, outputTokens: 0, totalTokens: 0 },
|
|
29
|
+
warnings: [],
|
|
30
|
+
}));
|
|
31
|
+
|
|
32
|
+
const agent = new Agent({
|
|
33
|
+
id: "test",
|
|
34
|
+
name: "Test",
|
|
35
|
+
instructions: "Test agent",
|
|
36
|
+
model,
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
const thread = new Thread({ agent });
|
|
40
|
+
|
|
41
|
+
expect(thread.namespace).toBe("kernl");
|
|
42
|
+
expect(thread.context.namespace).toBe("kernl");
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it("should accept custom namespace in constructor", () => {
|
|
46
|
+
const model = createMockModel(async () => ({
|
|
47
|
+
content: [],
|
|
48
|
+
finishReason: "stop",
|
|
49
|
+
usage: { inputTokens: 0, outputTokens: 0, totalTokens: 0 },
|
|
50
|
+
warnings: [],
|
|
51
|
+
}));
|
|
52
|
+
|
|
53
|
+
const agent = new Agent({
|
|
54
|
+
id: "test",
|
|
55
|
+
name: "Test",
|
|
56
|
+
instructions: "Test agent",
|
|
57
|
+
model,
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
const thread = new Thread({
|
|
61
|
+
agent,
|
|
62
|
+
namespace: "tenant-123",
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
expect(thread.namespace).toBe("tenant-123");
|
|
66
|
+
expect(thread.context.namespace).toBe("tenant-123");
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it("should propagate namespace from agent.run() options", async () => {
|
|
70
|
+
const model = createMockModel(async (req: LanguageModelRequest) => {
|
|
71
|
+
return {
|
|
72
|
+
content: [
|
|
73
|
+
{
|
|
74
|
+
kind: "message" as const,
|
|
75
|
+
id: "msg_1",
|
|
76
|
+
role: "assistant" as const,
|
|
77
|
+
content: [{ kind: "text" as const, text: "Hello" }],
|
|
78
|
+
},
|
|
79
|
+
],
|
|
80
|
+
finishReason: "stop",
|
|
81
|
+
usage: { inputTokens: 2, outputTokens: 2, totalTokens: 4 },
|
|
82
|
+
warnings: [],
|
|
83
|
+
};
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
const agent = new Agent({
|
|
87
|
+
id: "test",
|
|
88
|
+
name: "Test",
|
|
89
|
+
instructions: "Test agent",
|
|
90
|
+
model,
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
// Mock storage to intercept the thread creation
|
|
94
|
+
const storage = new InMemoryStorage();
|
|
95
|
+
const kernl = new Kernl({ storage: { db: storage } });
|
|
96
|
+
kernl.register(agent);
|
|
97
|
+
|
|
98
|
+
const result = await agent.run("Hello", {
|
|
99
|
+
namespace: "custom-ns",
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
// Verify storage persistence
|
|
103
|
+
const threads = await storage.threads.list();
|
|
104
|
+
const persistedThread = threads[0];
|
|
105
|
+
|
|
106
|
+
expect(persistedThread).toBeDefined();
|
|
107
|
+
expect(persistedThread.namespace).toBe("custom-ns");
|
|
108
|
+
expect(persistedThread.context.namespace).toBe("custom-ns");
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
it("should filter threads by namespace in storage", async () => {
|
|
112
|
+
const model = createMockModel(async () => ({
|
|
113
|
+
content: [
|
|
114
|
+
{
|
|
115
|
+
kind: "message" as const,
|
|
116
|
+
id: "msg_ok",
|
|
117
|
+
role: "assistant" as const,
|
|
118
|
+
content: [{ kind: "text" as const, text: "ok" }],
|
|
119
|
+
},
|
|
120
|
+
],
|
|
121
|
+
finishReason: "stop",
|
|
122
|
+
usage: { inputTokens: 0, outputTokens: 0, totalTokens: 0 },
|
|
123
|
+
warnings: [],
|
|
124
|
+
}));
|
|
125
|
+
|
|
126
|
+
const agent = new Agent({
|
|
127
|
+
id: "test",
|
|
128
|
+
name: "Test",
|
|
129
|
+
instructions: "Test agent",
|
|
130
|
+
model,
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
const storage = new InMemoryStorage();
|
|
134
|
+
const kernl = new Kernl({ storage: { db: storage } });
|
|
135
|
+
kernl.register(agent);
|
|
136
|
+
|
|
137
|
+
// Create threads in different namespaces
|
|
138
|
+
await agent.run("Thread 1", { namespace: "ns-a" });
|
|
139
|
+
await agent.run("Thread 2", { namespace: "ns-b" });
|
|
140
|
+
await agent.run("Thread 3", { namespace: "ns-a" });
|
|
141
|
+
|
|
142
|
+
// Verify filtering
|
|
143
|
+
const nsAThreads = await storage.threads.list({
|
|
144
|
+
filter: { namespace: "ns-a" },
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
expect(nsAThreads).toHaveLength(2);
|
|
148
|
+
expect(nsAThreads.every(t => t.namespace === "ns-a")).toBe(true);
|
|
149
|
+
|
|
150
|
+
const nsBThreads = await storage.threads.list({
|
|
151
|
+
filter: { namespace: "ns-b" },
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
expect(nsBThreads).toHaveLength(1);
|
|
155
|
+
expect(nsBThreads[0].namespace).toBe("ns-b");
|
|
156
|
+
});
|
|
157
|
+
});
|
|
158
|
+
|