kernl 0.7.3 → 0.8.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 +1 -1
- package/CHANGELOG.md +24 -0
- package/dist/agent/__tests__/systools.test.js +13 -9
- package/dist/agent/types.d.ts +20 -12
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/agent.d.ts +12 -8
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +14 -14
- package/dist/api/resources/agents/agents.d.ts +5 -5
- package/dist/api/resources/agents/agents.d.ts.map +1 -1
- package/dist/api/resources/agents/agents.js +1 -1
- package/dist/guardrail.d.ts +19 -19
- package/dist/guardrail.d.ts.map +1 -1
- package/dist/kernl/kernl.d.ts +6 -6
- package/dist/kernl/kernl.d.ts.map +1 -1
- package/dist/lib/error.d.ts +3 -3
- package/dist/lib/error.d.ts.map +1 -1
- package/dist/lifecycle.d.ts +6 -6
- package/dist/lifecycle.d.ts.map +1 -1
- package/dist/memory/__tests__/encoder.test.d.ts +2 -0
- package/dist/memory/__tests__/encoder.test.d.ts.map +1 -0
- package/dist/memory/__tests__/encoder.test.js +120 -0
- package/dist/memory/codecs/domain.d.ts +5 -0
- package/dist/memory/codecs/domain.d.ts.map +1 -1
- package/dist/memory/codecs/domain.js +6 -0
- package/dist/memory/encoder.d.ts +25 -2
- package/dist/memory/encoder.d.ts.map +1 -1
- package/dist/memory/encoder.js +46 -5
- package/dist/memory/index.d.ts +2 -2
- package/dist/memory/index.d.ts.map +1 -1
- package/dist/memory/index.js +1 -1
- package/dist/memory/schema.d.ts.map +1 -1
- package/dist/memory/schema.js +5 -0
- package/dist/memory/types.d.ts +21 -4
- package/dist/memory/types.d.ts.map +1 -1
- package/dist/storage/in-memory.d.ts.map +1 -1
- package/dist/storage/in-memory.js +4 -2
- package/dist/thread/__tests__/integration.test.js +1 -1
- package/dist/thread/__tests__/thread.test.js +8 -8
- package/dist/thread/thread.d.ts +5 -5
- package/dist/thread/thread.d.ts.map +1 -1
- package/dist/thread/thread.js +13 -2
- package/dist/thread/types.d.ts +9 -6
- package/dist/thread/types.d.ts.map +1 -1
- package/dist/thread/utils.d.ts +7 -6
- package/dist/thread/utils.d.ts.map +1 -1
- package/dist/thread/utils.js +9 -8
- package/dist/tool/sys/memory.d.ts +1 -1
- package/dist/tool/sys/memory.d.ts.map +1 -1
- package/dist/tool/sys/memory.js +29 -8
- package/package.json +4 -3
- package/src/agent/__tests__/systools.test.ts +13 -9
- package/src/agent/types.ts +25 -29
- package/src/agent.ts +29 -28
- package/src/api/resources/agents/agents.ts +8 -8
- package/src/guardrail.ts +28 -28
- package/src/kernl/kernl.ts +12 -12
- package/src/lib/error.ts +3 -3
- package/src/lifecycle.ts +6 -6
- package/src/memory/__tests__/encoder.test.ts +153 -0
- package/src/memory/codecs/domain.ts +6 -0
- package/src/memory/encoder.ts +51 -6
- package/src/memory/index.ts +2 -1
- package/src/memory/schema.ts +5 -0
- package/src/memory/types.ts +20 -4
- package/src/storage/in-memory.ts +6 -2
- package/src/thread/__tests__/integration.test.ts +130 -146
- package/src/thread/__tests__/thread.test.ts +8 -8
- package/src/thread/thread.ts +21 -7
- package/src/thread/types.ts +9 -6
- package/src/thread/utils.ts +15 -14
- package/src/tool/sys/memory.ts +33 -9
package/dist/thread/types.d.ts
CHANGED
|
@@ -2,13 +2,16 @@ import { ToolCall, LanguageModel, LanguageModelItem, LanguageModelStreamEvent, R
|
|
|
2
2
|
import { Task } from "../task.js";
|
|
3
3
|
import { Context } from "../context.js";
|
|
4
4
|
import { Agent } from "../agent.js";
|
|
5
|
-
import type {
|
|
5
|
+
import type { AgentOutputType } from "../agent/types.js";
|
|
6
6
|
import type { ThreadStore } from "../storage/index.js";
|
|
7
7
|
/**
|
|
8
8
|
* Public/client-facing thread events (excludes internal system events).
|
|
9
9
|
*/
|
|
10
10
|
export type PublicThreadEvent = LanguageModelItem & ThreadEventBase;
|
|
11
|
-
|
|
11
|
+
/**
|
|
12
|
+
* Text output type - indicates the agent returns a plain string.
|
|
13
|
+
*/
|
|
14
|
+
export type TextOutput = "text";
|
|
12
15
|
/**
|
|
13
16
|
* Thread state values as a const array (for zod schemas).
|
|
14
17
|
*/
|
|
@@ -27,9 +30,9 @@ export declare const REQUIRES_APPROVAL = "requires_approval";
|
|
|
27
30
|
*
|
|
28
31
|
* Represents the complete state of a Thread that can be stored and restored.
|
|
29
32
|
*/
|
|
30
|
-
export interface IThread<TContext = unknown,
|
|
33
|
+
export interface IThread<TContext = unknown, TOutput extends AgentOutputType = "text"> {
|
|
31
34
|
tid: string;
|
|
32
|
-
agent: Agent<TContext,
|
|
35
|
+
agent: Agent<TContext, TOutput>;
|
|
33
36
|
model: LanguageModel;
|
|
34
37
|
context: Context<TContext>;
|
|
35
38
|
input: LanguageModelItem[];
|
|
@@ -95,8 +98,8 @@ export interface ThreadExecuteResult<TResponse = unknown> {
|
|
|
95
98
|
/**
|
|
96
99
|
* Options for constructing a Thread.
|
|
97
100
|
*/
|
|
98
|
-
export interface ThreadOptions<TContext = unknown,
|
|
99
|
-
agent: Agent<TContext,
|
|
101
|
+
export interface ThreadOptions<TContext = unknown, TOutput extends AgentOutputType = "text"> {
|
|
102
|
+
agent: Agent<TContext, TOutput>;
|
|
100
103
|
input?: LanguageModelItem[];
|
|
101
104
|
history?: ThreadEvent[];
|
|
102
105
|
context?: Context<TContext>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/thread/types.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EACR,aAAa,EACb,iBAAiB,EACjB,wBAAwB,EACxB,OAAO,EACP,OAAO,EACP,aAAa,EACb,eAAe,EACf,MAAM,EACN,IAAI,EACL,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAEhC,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/thread/types.ts"],"names":[],"mappings":"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"}
|
package/dist/thread/utils.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ResolvedAgentResponse } from "../guardrail.js";
|
|
2
2
|
import { ToolCall, LanguageModelItem } from "@kernl-sdk/protocol";
|
|
3
|
-
import type {
|
|
3
|
+
import type { AgentOutputType } from "../agent/types.js";
|
|
4
4
|
import type { ThreadEvent, ThreadStreamEvent, ActionSet, PublicThreadEvent } from "./types.js";
|
|
5
5
|
/**
|
|
6
6
|
* Create a ThreadEvent from a LanguageModelItem with thread metadata.
|
|
@@ -50,13 +50,14 @@ export declare function isPublicEvent(event: ThreadEvent): event is PublicThread
|
|
|
50
50
|
*/
|
|
51
51
|
export declare function getFinalResponse(items: LanguageModelItem[]): string | null;
|
|
52
52
|
/**
|
|
53
|
-
*
|
|
53
|
+
* Parse the final response according to the output type schema.
|
|
54
54
|
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
* - If
|
|
55
|
+
* This serves as a safety net validation after native structured output from the provider.
|
|
56
|
+
*
|
|
57
|
+
* - If output is "text", returns the text as-is
|
|
58
|
+
* - If output is a ZodType, parses and validates the text as JSON
|
|
58
59
|
*
|
|
59
60
|
* @throws {ModelBehaviorError} if structured output validation fails
|
|
60
61
|
*/
|
|
61
|
-
export declare function parseFinalResponse<
|
|
62
|
+
export declare function parseFinalResponse<TOutput extends AgentOutputType>(text: string, output: TOutput): ResolvedAgentResponse<TOutput>;
|
|
62
63
|
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/thread/utils.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAIzD,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAIlE,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/thread/utils.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAIzD,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAIlE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,KAAK,EACV,WAAW,EAEX,iBAAiB,EACjB,SAAS,EACT,iBAAiB,EAClB,MAAM,SAAS,CAAC;AAEjB;;;;;;;;;;;;;GAaG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC1B,IAAI,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAC/B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,IAAI,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC,GAAG,WAAW,CAad;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,iBAAiB,GAAG,KAAK,IAAI,QAAQ,CAE7E;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,iBAAiB,EAAE,GAAG,SAAS,GAAG,IAAI,CAG3E;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,iBAAiB,GAAG,KAAK,IAAI,iBAAiB,CAY7E;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,WAAW,GAAG,KAAK,IAAI,iBAAiB,CAc5E;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,iBAAiB,EAAE,GAAG,MAAM,GAAG,IAAI,CAc1E;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,SAAS,eAAe,EAChE,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,OAAO,GACd,qBAAqB,CAAC,OAAO,CAAC,CAsBhC"}
|
package/dist/thread/utils.js
CHANGED
|
@@ -95,22 +95,23 @@ export function getFinalResponse(items) {
|
|
|
95
95
|
return null;
|
|
96
96
|
}
|
|
97
97
|
/**
|
|
98
|
-
*
|
|
98
|
+
* Parse the final response according to the output type schema.
|
|
99
99
|
*
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
* - If
|
|
100
|
+
* This serves as a safety net validation after native structured output from the provider.
|
|
101
|
+
*
|
|
102
|
+
* - If output is "text", returns the text as-is
|
|
103
|
+
* - If output is a ZodType, parses and validates the text as JSON
|
|
103
104
|
*
|
|
104
105
|
* @throws {ModelBehaviorError} if structured output validation fails
|
|
105
106
|
*/
|
|
106
|
-
export function parseFinalResponse(text,
|
|
107
|
-
if (
|
|
107
|
+
export function parseFinalResponse(text, output) {
|
|
108
|
+
if (output === "text") {
|
|
108
109
|
return text; // text output - return as-is
|
|
109
110
|
}
|
|
110
111
|
// structured output - decode JSON and validate with schema
|
|
111
|
-
if (
|
|
112
|
+
if (output && typeof output === "object") {
|
|
112
113
|
// (TODO): prob better way of checking this here
|
|
113
|
-
const schema =
|
|
114
|
+
const schema = output;
|
|
114
115
|
try {
|
|
115
116
|
const validated = json(schema).decode(text); // (TODO): it would be nice if we could use `decodeSafe` here
|
|
116
117
|
return validated;
|
|
@@ -8,7 +8,7 @@ import { Toolkit } from "../toolkit.js";
|
|
|
8
8
|
/**
|
|
9
9
|
* Memory system toolkit.
|
|
10
10
|
*
|
|
11
|
-
* Provides
|
|
11
|
+
* Provides list_memories, create_memory, update_memory, and search_memories tools.
|
|
12
12
|
*/
|
|
13
13
|
export declare const memory: Toolkit<unknown>;
|
|
14
14
|
//# sourceMappingURL=memory.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../../src/tool/sys/memory.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../../src/tool/sys/memory.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AA2HrC;;;;GAIG;AACH,eAAO,MAAM,MAAM,kBAIjB,CAAC"}
|
package/dist/tool/sys/memory.js
CHANGED
|
@@ -8,12 +8,11 @@ import assert from "assert";
|
|
|
8
8
|
import { z } from "zod";
|
|
9
9
|
import { tool } from "../tool.js";
|
|
10
10
|
import { Toolkit } from "../toolkit.js";
|
|
11
|
-
// --- Tools ---
|
|
12
11
|
/**
|
|
13
12
|
* Search memories for relevant information using natural language.
|
|
14
13
|
*/
|
|
15
14
|
const search = tool({
|
|
16
|
-
id: "
|
|
15
|
+
id: "search_memories",
|
|
17
16
|
description: "Search your memories. " +
|
|
18
17
|
"Use this to recall facts, preferences, or context you've previously stored.",
|
|
19
18
|
parameters: z.object({
|
|
@@ -42,7 +41,7 @@ const search = tool({
|
|
|
42
41
|
* Store a new memory to persist across conversations.
|
|
43
42
|
*/
|
|
44
43
|
const create = tool({
|
|
45
|
-
id: "
|
|
44
|
+
id: "create_memory",
|
|
46
45
|
description: "Store a new memory. Use this to remember important facts, user preferences, " +
|
|
47
46
|
"or context that should persist across conversations.",
|
|
48
47
|
parameters: z.object({
|
|
@@ -50,22 +49,44 @@ const create = tool({
|
|
|
50
49
|
collection: z
|
|
51
50
|
.string()
|
|
52
51
|
.optional()
|
|
53
|
-
.describe("Category for organizing memories
|
|
52
|
+
.describe("Category for organizing memories"),
|
|
54
53
|
}),
|
|
55
54
|
execute: async (ctx, { content, collection }) => {
|
|
56
55
|
assert(ctx.agent, "ctx.agent required for memory tools");
|
|
57
56
|
const mem = await ctx.agent.memories.create({
|
|
58
|
-
collection
|
|
57
|
+
collection,
|
|
59
58
|
content: { text: content },
|
|
60
59
|
});
|
|
61
60
|
return { id: mem.id, stored: true };
|
|
62
61
|
},
|
|
63
62
|
});
|
|
63
|
+
/**
|
|
64
|
+
* Update an existing memory.
|
|
65
|
+
*/
|
|
66
|
+
const update = tool({
|
|
67
|
+
id: "update_memory",
|
|
68
|
+
description: "Update an existing memory. Use this to correct or modify previously " +
|
|
69
|
+
"stored facts or preferences.",
|
|
70
|
+
parameters: z.object({
|
|
71
|
+
id: z.string().describe("ID of the memory to update"),
|
|
72
|
+
content: z.string().optional().describe("New text content"),
|
|
73
|
+
collection: z.string().optional().describe("New collection category"),
|
|
74
|
+
}),
|
|
75
|
+
execute: async (ctx, { id, content, collection }) => {
|
|
76
|
+
assert(ctx.agent, "ctx.agent required for memory tools");
|
|
77
|
+
const mem = await ctx.agent.memories.update({
|
|
78
|
+
id,
|
|
79
|
+
content: content ? { text: content } : undefined,
|
|
80
|
+
collection,
|
|
81
|
+
});
|
|
82
|
+
return { id: mem.id, updated: true };
|
|
83
|
+
},
|
|
84
|
+
});
|
|
64
85
|
/**
|
|
65
86
|
* List stored memories, optionally filtered by collection.
|
|
66
87
|
*/
|
|
67
88
|
const list = tool({
|
|
68
|
-
id: "
|
|
89
|
+
id: "list_memories",
|
|
69
90
|
description: "List your stored memories. Use this to see what you've remembered, " +
|
|
70
91
|
"optionally filtered by collection.",
|
|
71
92
|
parameters: z.object({
|
|
@@ -94,10 +115,10 @@ const list = tool({
|
|
|
94
115
|
/**
|
|
95
116
|
* Memory system toolkit.
|
|
96
117
|
*
|
|
97
|
-
* Provides
|
|
118
|
+
* Provides list_memories, create_memory, update_memory, and search_memories tools.
|
|
98
119
|
*/
|
|
99
120
|
export const memory = new Toolkit({
|
|
100
121
|
id: "sys.memory",
|
|
101
122
|
description: "Tools for storing and retrieving agent memories",
|
|
102
|
-
tools: [list, create, search],
|
|
123
|
+
tools: [list, create, update, search],
|
|
103
124
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kernl",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "A modern AI agent framework",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"kernl",
|
|
@@ -34,9 +34,10 @@
|
|
|
34
34
|
"dependencies": {
|
|
35
35
|
"@modelcontextprotocol/sdk": "^1.20.2",
|
|
36
36
|
"pino": "^9.6.0",
|
|
37
|
+
"yaml": "^2.8.2",
|
|
37
38
|
"zod": "^4.1.12",
|
|
38
|
-
"@kernl-sdk/retrieval": "0.1.3",
|
|
39
39
|
"@kernl-sdk/protocol": "0.2.8",
|
|
40
|
+
"@kernl-sdk/retrieval": "0.1.3",
|
|
40
41
|
"@kernl-sdk/shared": "^0.3.0"
|
|
41
42
|
},
|
|
42
43
|
"devDependencies": {
|
|
@@ -45,7 +46,7 @@
|
|
|
45
46
|
"tsc-alias": "^1.8.10",
|
|
46
47
|
"typescript": "5.9.2",
|
|
47
48
|
"vitest": "^4.0.8",
|
|
48
|
-
"@kernl-sdk/ai": "0.
|
|
49
|
+
"@kernl-sdk/ai": "0.3.0"
|
|
49
50
|
},
|
|
50
51
|
"scripts": {
|
|
51
52
|
"clean": "rm -rf dist",
|
|
@@ -71,9 +71,10 @@ describe("Agent systools", () => {
|
|
|
71
71
|
const kernl = new Kernl();
|
|
72
72
|
kernl.register(agent);
|
|
73
73
|
|
|
74
|
-
expect(agent.tool("
|
|
75
|
-
expect(agent.tool("
|
|
76
|
-
expect(agent.tool("
|
|
74
|
+
expect(agent.tool("search_memories")).toBeDefined();
|
|
75
|
+
expect(agent.tool("create_memory")).toBeDefined();
|
|
76
|
+
expect(agent.tool("update_memory")).toBeDefined();
|
|
77
|
+
expect(agent.tool("list_memories")).toBeDefined();
|
|
77
78
|
});
|
|
78
79
|
|
|
79
80
|
it("includes memory tools in agent.tools() output", async () => {
|
|
@@ -92,9 +93,10 @@ describe("Agent systools", () => {
|
|
|
92
93
|
const tools = await agent.tools(ctx);
|
|
93
94
|
const ids = tools.map((t) => t.id);
|
|
94
95
|
|
|
95
|
-
expect(ids).toContain("
|
|
96
|
-
expect(ids).toContain("
|
|
97
|
-
expect(ids).toContain("
|
|
96
|
+
expect(ids).toContain("search_memories");
|
|
97
|
+
expect(ids).toContain("create_memory");
|
|
98
|
+
expect(ids).toContain("update_memory");
|
|
99
|
+
expect(ids).toContain("list_memories");
|
|
98
100
|
});
|
|
99
101
|
|
|
100
102
|
it("systools appear before user toolkits in tools() output", async () => {
|
|
@@ -113,9 +115,11 @@ describe("Agent systools", () => {
|
|
|
113
115
|
const tools = await agent.tools(ctx);
|
|
114
116
|
|
|
115
117
|
// Memory tools should be first (from systools)
|
|
116
|
-
|
|
117
|
-
expect(tools[
|
|
118
|
-
expect(tools[
|
|
118
|
+
// Order: list, create, update, search
|
|
119
|
+
expect(tools[0].id).toBe("list_memories");
|
|
120
|
+
expect(tools[1].id).toBe("create_memory");
|
|
121
|
+
expect(tools[2].id).toBe("update_memory");
|
|
122
|
+
expect(tools[3].id).toBe("search_memories");
|
|
119
123
|
});
|
|
120
124
|
});
|
|
121
125
|
|
package/src/agent/types.ts
CHANGED
|
@@ -1,30 +1,26 @@
|
|
|
1
1
|
import { type ZodType } from "zod";
|
|
2
2
|
|
|
3
|
-
import { Context, UnknownContext } from "@/context";
|
|
4
3
|
import {
|
|
5
4
|
LanguageModel,
|
|
6
5
|
LanguageModelRequestSettings,
|
|
7
6
|
} from "@kernl-sdk/protocol";
|
|
7
|
+
|
|
8
|
+
import { Context, UnknownContext } from "@/context";
|
|
8
9
|
import { InputGuardrail, OutputGuardrail } from "@/guardrail";
|
|
9
10
|
import { BaseToolkit } from "@/tool";
|
|
10
11
|
|
|
11
|
-
import {
|
|
12
|
+
import { TextOutput } from "@/thread/types";
|
|
12
13
|
|
|
13
14
|
/**
|
|
14
15
|
* Configuration for an agent.
|
|
15
16
|
*/
|
|
16
17
|
export interface AgentConfig<
|
|
17
18
|
TContext = UnknownContext,
|
|
18
|
-
|
|
19
|
+
TOutput extends AgentOutputType = TextOutput,
|
|
19
20
|
> {
|
|
20
|
-
/* The unique identifier for the agent
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
/* The name of the agent (defaults to ID if not provided) */
|
|
24
|
-
name: string;
|
|
25
|
-
|
|
26
|
-
/* A brief description of the agent's purpose */
|
|
27
|
-
description?: string;
|
|
21
|
+
id: string /* The unique identifier for the agent */;
|
|
22
|
+
name: string /* The name of the agent (defaults to ID if not provided) */;
|
|
23
|
+
description?: string /* A brief description of the agent's purpose */;
|
|
28
24
|
|
|
29
25
|
/**
|
|
30
26
|
* The instructions for the agent. Will be used as the "system prompt" when this agent is
|
|
@@ -38,12 +34,6 @@ export interface AgentConfig<
|
|
|
38
34
|
| string
|
|
39
35
|
| ((context: Context<TContext>) => Promise<string> | string);
|
|
40
36
|
|
|
41
|
-
// /**
|
|
42
|
-
// * A description of the agent. This is used when the agent is used as a handoff, so that an LLM
|
|
43
|
-
// * knows what it does and when to invoke it.
|
|
44
|
-
// */
|
|
45
|
-
// handoffDescription: string;
|
|
46
|
-
|
|
47
37
|
// /**
|
|
48
38
|
// * Handoffs are sub-agents that the agent can delegate to. You can provide a list of handoffs,
|
|
49
39
|
// * and the agent can choose to delegate to them if relevant. Allows for separation of concerns
|
|
@@ -63,6 +53,19 @@ export interface AgentConfig<
|
|
|
63
53
|
*/
|
|
64
54
|
modelSettings?: LanguageModelRequestSettings;
|
|
65
55
|
|
|
56
|
+
/**
|
|
57
|
+
* The type of the output that the agent will return.
|
|
58
|
+
*
|
|
59
|
+
* Can be either:
|
|
60
|
+
* - `"text"` (default): The agent returns a plain string response
|
|
61
|
+
* - A Zod schema: The agent returns structured output validated against the schema
|
|
62
|
+
*
|
|
63
|
+
* When a Zod schema is provided, the output is converted to JSON Schema and sent to the
|
|
64
|
+
* model for native structured output support. The response is then validated against
|
|
65
|
+
* the Zod schema as a safety net.
|
|
66
|
+
*/
|
|
67
|
+
output?: TOutput;
|
|
68
|
+
|
|
66
69
|
/**
|
|
67
70
|
* A list of toolkits the agent can use. Toolkits are collections of related tools
|
|
68
71
|
* that can be static (Toolkit) or dynamic (MCPToolkit).
|
|
@@ -100,12 +103,7 @@ export interface AgentConfig<
|
|
|
100
103
|
* A list of checks that run in parallel to the agent's execution on the input + output for the agent,
|
|
101
104
|
* depending on the configuration.
|
|
102
105
|
*/
|
|
103
|
-
guardrails?: AgentGuardrails<
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* The type of the response that the agent will return. If not provided, response will be a string.
|
|
107
|
-
*/
|
|
108
|
-
responseType?: TResponse;
|
|
106
|
+
guardrails?: AgentGuardrails<TOutput>;
|
|
109
107
|
|
|
110
108
|
// /**
|
|
111
109
|
// * (TODO): Not sure if this is really necessary.. need to see use case examples
|
|
@@ -137,9 +135,7 @@ export interface AgentConfig<
|
|
|
137
135
|
/**
|
|
138
136
|
* Guardrails for an agent.
|
|
139
137
|
*/
|
|
140
|
-
export interface AgentGuardrails<
|
|
141
|
-
TResponse extends AgentResponseType = TextResponse,
|
|
142
|
-
> {
|
|
138
|
+
export interface AgentGuardrails<TOutput extends AgentOutputType = TextOutput> {
|
|
143
139
|
/**
|
|
144
140
|
* A list of checks that run in parallel to the agent's execution, before generating a response.
|
|
145
141
|
* Runs only if the agent is the first agent in the chain.
|
|
@@ -149,14 +145,14 @@ export interface AgentGuardrails<
|
|
|
149
145
|
* A list of checks that run on the final output of the agent, after generating a response. Runs
|
|
150
146
|
* only if the agent produces a final output.
|
|
151
147
|
*/
|
|
152
|
-
output: OutputGuardrail<
|
|
148
|
+
output: OutputGuardrail<TOutput>[];
|
|
153
149
|
}
|
|
154
150
|
|
|
155
151
|
/**
|
|
156
|
-
* The type of the output
|
|
152
|
+
* The type of the output. If not provided, the output will be a string.
|
|
157
153
|
* 'text' is a special type that indicates the output will be a string.
|
|
158
154
|
*/
|
|
159
|
-
export type
|
|
155
|
+
export type AgentOutputType = TextOutput | ZodType;
|
|
160
156
|
|
|
161
157
|
/**
|
|
162
158
|
* Memory configuration for an agent.
|
package/src/agent.ts
CHANGED
|
@@ -25,6 +25,7 @@ import {
|
|
|
25
25
|
import { AgentHooks } from "./lifecycle";
|
|
26
26
|
import type {
|
|
27
27
|
AgentMemoryCreate,
|
|
28
|
+
AgentMemoryUpdate,
|
|
28
29
|
MemoryListOptions,
|
|
29
30
|
MemorySearchQuery,
|
|
30
31
|
} from "./memory";
|
|
@@ -36,10 +37,10 @@ import { MisconfiguredError, RuntimeError } from "./lib/error";
|
|
|
36
37
|
import type {
|
|
37
38
|
AgentConfig,
|
|
38
39
|
AgentMemoryConfig,
|
|
39
|
-
|
|
40
|
+
AgentOutputType,
|
|
40
41
|
} from "./agent/types";
|
|
41
42
|
import type {
|
|
42
|
-
|
|
43
|
+
TextOutput,
|
|
43
44
|
ThreadExecuteOptions,
|
|
44
45
|
ThreadExecuteResult,
|
|
45
46
|
ThreadStreamEvent,
|
|
@@ -47,10 +48,10 @@ import type {
|
|
|
47
48
|
|
|
48
49
|
export class Agent<
|
|
49
50
|
TContext = UnknownContext,
|
|
50
|
-
|
|
51
|
+
TOutput extends AgentOutputType = TextOutput,
|
|
51
52
|
>
|
|
52
|
-
extends AgentHooks<TContext,
|
|
53
|
-
implements AgentConfig<TContext,
|
|
53
|
+
extends AgentHooks<TContext, TOutput>
|
|
54
|
+
implements AgentConfig<TContext, TOutput>
|
|
54
55
|
{
|
|
55
56
|
private kernl?: Kernl;
|
|
56
57
|
|
|
@@ -68,25 +69,12 @@ export class Agent<
|
|
|
68
69
|
|
|
69
70
|
guardrails: {
|
|
70
71
|
input: InputGuardrail[];
|
|
71
|
-
output: OutputGuardrail<
|
|
72
|
+
output: OutputGuardrail<AgentOutputType>[];
|
|
72
73
|
};
|
|
73
|
-
|
|
74
|
+
output: TOutput = "text" as TOutput;
|
|
74
75
|
resetToolChoice: boolean;
|
|
75
76
|
|
|
76
|
-
|
|
77
|
-
// toolUseBehavior: ToolUseBehavior;
|
|
78
|
-
// handoffs: (Agent<any, TResponse> | Handoff<any, TResponse>)[];
|
|
79
|
-
// ----------
|
|
80
|
-
|
|
81
|
-
// /* Process/thread-group–wide signal state shared by all threads in the group: shared pending signals, job control
|
|
82
|
-
// (stops/cont, group exit), rlimits, etc. */
|
|
83
|
-
// signal: *struct signal_struct;
|
|
84
|
-
//
|
|
85
|
-
// /* Table of signal handlers (sa_handler, sa_mask, flags) shared by threads
|
|
86
|
-
// (CLONE_SIGHAND). RCU-protected so readers can access it locklessly. */
|
|
87
|
-
// sighand: *struct sighand_struct __rcu;
|
|
88
|
-
|
|
89
|
-
constructor(config: AgentConfig<TContext, TResponse>) {
|
|
77
|
+
constructor(config: AgentConfig<TContext, TOutput>) {
|
|
90
78
|
super();
|
|
91
79
|
if (config.id.trim() === "") {
|
|
92
80
|
throw new MisconfiguredError("Agent must have an id.");
|
|
@@ -110,8 +98,8 @@ export class Agent<
|
|
|
110
98
|
}
|
|
111
99
|
|
|
112
100
|
this.guardrails = config.guardrails ?? { input: [], output: [] };
|
|
113
|
-
if (config.
|
|
114
|
-
this.
|
|
101
|
+
if (config.output) {
|
|
102
|
+
this.output = config.output;
|
|
115
103
|
}
|
|
116
104
|
this.resetToolChoice = config.resetToolChoice ?? true;
|
|
117
105
|
// this.toolUseBehavior = config.toolUseBehavior ?? "run_llm_again";
|
|
@@ -141,7 +129,7 @@ export class Agent<
|
|
|
141
129
|
async run(
|
|
142
130
|
input: string | LanguageModelItem[],
|
|
143
131
|
options?: ThreadExecuteOptions<TContext>,
|
|
144
|
-
): Promise<ThreadExecuteResult<ResolvedAgentResponse<
|
|
132
|
+
): Promise<ThreadExecuteResult<ResolvedAgentResponse<TOutput>>> {
|
|
145
133
|
if (!this.kernl) {
|
|
146
134
|
throw new MisconfiguredError(
|
|
147
135
|
`Agent ${this.id} not bound to kernl. Call kernl.register(agent) first.`,
|
|
@@ -154,7 +142,7 @@ export class Agent<
|
|
|
154
142
|
: input;
|
|
155
143
|
const tid = options?.threadId;
|
|
156
144
|
|
|
157
|
-
let thread: Thread<TContext,
|
|
145
|
+
let thread: Thread<TContext, TOutput> | null = null;
|
|
158
146
|
|
|
159
147
|
if (tid) {
|
|
160
148
|
// no concurrent execution of same thread - correctness contract
|
|
@@ -167,7 +155,7 @@ export class Agent<
|
|
|
167
155
|
if (this.kernl.storage?.threads) {
|
|
168
156
|
thread = (await this.kernl.storage.threads.get(tid, {
|
|
169
157
|
history: true,
|
|
170
|
-
})) as Thread<TContext,
|
|
158
|
+
})) as Thread<TContext, TOutput> | null;
|
|
171
159
|
}
|
|
172
160
|
}
|
|
173
161
|
|
|
@@ -215,7 +203,7 @@ export class Agent<
|
|
|
215
203
|
: input;
|
|
216
204
|
const tid = options?.threadId;
|
|
217
205
|
|
|
218
|
-
let thread: Thread<TContext,
|
|
206
|
+
let thread: Thread<TContext, TOutput> | null = null;
|
|
219
207
|
|
|
220
208
|
if (tid) {
|
|
221
209
|
// no concurrent execution of same thread - correctness contract
|
|
@@ -228,7 +216,7 @@ export class Agent<
|
|
|
228
216
|
if (this.kernl.storage?.threads) {
|
|
229
217
|
thread = (await this.kernl.storage.threads.get(tid, {
|
|
230
218
|
history: true,
|
|
231
|
-
})) as Thread<TContext,
|
|
219
|
+
})) as Thread<TContext, TOutput> | null;
|
|
232
220
|
}
|
|
233
221
|
}
|
|
234
222
|
|
|
@@ -410,6 +398,19 @@ export class Agent<
|
|
|
410
398
|
metadata: params.metadata,
|
|
411
399
|
}),
|
|
412
400
|
|
|
401
|
+
/**
|
|
402
|
+
* Update an existing memory scoped to this agent.
|
|
403
|
+
*/
|
|
404
|
+
update: (params: AgentMemoryUpdate) =>
|
|
405
|
+
kmem.update({
|
|
406
|
+
id: params.id,
|
|
407
|
+
content: params.content,
|
|
408
|
+
collection: params.collection,
|
|
409
|
+
wmem: params.wmem,
|
|
410
|
+
smem: params.smem,
|
|
411
|
+
metadata: params.metadata,
|
|
412
|
+
}),
|
|
413
|
+
|
|
413
414
|
/**
|
|
414
415
|
* Search memories scoped to this agent.
|
|
415
416
|
*/
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Agent } from "@/agent";
|
|
2
|
-
import type {
|
|
2
|
+
import type { AgentOutputType } from "@/agent/types";
|
|
3
3
|
import type { UnknownContext } from "@/context";
|
|
4
|
-
import type {
|
|
4
|
+
import type { TextOutput } from "@/thread/types";
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Agents resource.
|
|
@@ -16,15 +16,15 @@ export class RAgents {
|
|
|
16
16
|
/**
|
|
17
17
|
* Get a live Agent instance by id.
|
|
18
18
|
*
|
|
19
|
-
* Callers are expected to know the concrete TContext/
|
|
19
|
+
* Callers are expected to know the concrete TContext/TOutput types
|
|
20
20
|
* for their own agents and can specify them via generics.
|
|
21
21
|
*/
|
|
22
22
|
get<
|
|
23
23
|
TContext = UnknownContext,
|
|
24
|
-
|
|
25
|
-
>(id: string): Agent<TContext,
|
|
24
|
+
TOutput extends AgentOutputType = TextOutput,
|
|
25
|
+
>(id: string): Agent<TContext, TOutput> | undefined {
|
|
26
26
|
const agent = this.registry.get(id);
|
|
27
|
-
return agent as Agent<TContext,
|
|
27
|
+
return agent as Agent<TContext, TOutput> | undefined;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
/**
|
|
@@ -40,10 +40,10 @@ export class RAgents {
|
|
|
40
40
|
* Since this is a heterogeneous collection, we expose the widest safe
|
|
41
41
|
* type parameters here.
|
|
42
42
|
*/
|
|
43
|
-
list(): Agent<UnknownContext,
|
|
43
|
+
list(): Agent<UnknownContext, AgentOutputType>[] {
|
|
44
44
|
return Array.from(this.registry.values()) as Agent<
|
|
45
45
|
UnknownContext,
|
|
46
|
-
|
|
46
|
+
AgentOutputType
|
|
47
47
|
>[];
|
|
48
48
|
}
|
|
49
49
|
|