kernl 0.6.3 → 0.7.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 +23 -0
- package/dist/agent/__tests__/systools.test.d.ts +2 -0
- package/dist/agent/__tests__/systools.test.d.ts.map +1 -0
- package/dist/agent/__tests__/systools.test.js +121 -0
- package/dist/agent/types.d.ts +17 -0
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/agent.d.ts +14 -4
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +45 -30
- package/dist/api/resources/agents/agents.d.ts +38 -0
- package/dist/api/resources/agents/agents.d.ts.map +1 -0
- package/dist/api/resources/agents/agents.js +44 -0
- package/dist/api/resources/agents/index.d.ts +2 -0
- package/dist/api/resources/agents/index.d.ts.map +1 -0
- package/dist/api/resources/agents/index.js +1 -0
- package/dist/context.d.ts +6 -0
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +5 -0
- package/dist/kernl/kernl.d.ts +4 -2
- package/dist/kernl/kernl.d.ts.map +1 -1
- package/dist/kernl/kernl.js +11 -8
- package/dist/memory/memory.d.ts +5 -1
- package/dist/memory/memory.d.ts.map +1 -1
- package/dist/memory/memory.js +6 -0
- package/dist/thread/thread.d.ts.map +1 -1
- package/dist/thread/thread.js +3 -1
- package/dist/tool/index.d.ts +1 -0
- package/dist/tool/index.d.ts.map +1 -1
- package/dist/tool/index.js +2 -0
- package/dist/tool/sys/index.d.ts +7 -0
- package/dist/tool/sys/index.d.ts.map +1 -0
- package/dist/tool/sys/index.js +6 -0
- package/dist/tool/sys/memory.d.ts +14 -0
- package/dist/tool/sys/memory.d.ts.map +1 -0
- package/dist/tool/sys/memory.js +103 -0
- package/dist/tool/tool.d.ts +1 -1
- package/dist/tool/tool.d.ts.map +1 -1
- package/dist/tool/tool.js +2 -2
- package/package.json +5 -5
- package/src/agent/__tests__/systools.test.ts +146 -0
- package/src/agent/types.ts +21 -0
- package/src/agent.ts +70 -38
- package/src/api/resources/agents/agents.ts +56 -0
- package/src/api/resources/agents/index.ts +1 -0
- package/src/context.ts +8 -0
- package/src/kernl/kernl.ts +11 -8
- package/src/memory/memory.ts +8 -0
- package/src/thread/thread.ts +3 -1
- package/src/tool/index.ts +3 -0
- package/src/tool/sys/index.ts +7 -0
- package/src/tool/sys/memory.ts +120 -0
- package/src/tool/tool.ts +8 -4
package/src/agent.ts
CHANGED
|
@@ -15,7 +15,7 @@ import type {
|
|
|
15
15
|
RThreadUpdateParams,
|
|
16
16
|
} from "@/api/resources/threads/types";
|
|
17
17
|
import type { Context, UnknownContext } from "./context";
|
|
18
|
-
import { Tool } from "./tool";
|
|
18
|
+
import { Tool, memory } from "./tool";
|
|
19
19
|
import { BaseToolkit } from "./tool/toolkit";
|
|
20
20
|
import {
|
|
21
21
|
InputGuardrail,
|
|
@@ -23,17 +23,27 @@ import {
|
|
|
23
23
|
type ResolvedAgentResponse,
|
|
24
24
|
} from "./guardrail";
|
|
25
25
|
import { AgentHooks } from "./lifecycle";
|
|
26
|
+
import type {
|
|
27
|
+
AgentMemoryCreate,
|
|
28
|
+
MemoryListOptions,
|
|
29
|
+
MemorySearchQuery,
|
|
30
|
+
} from "./memory";
|
|
26
31
|
|
|
32
|
+
import { randomID } from "@kernl-sdk/shared/lib";
|
|
27
33
|
import { MisconfiguredError, RuntimeError } from "./lib/error";
|
|
28
|
-
|
|
34
|
+
|
|
35
|
+
/* types */
|
|
36
|
+
import type {
|
|
37
|
+
AgentConfig,
|
|
38
|
+
AgentMemoryConfig,
|
|
39
|
+
AgentResponseType,
|
|
40
|
+
} from "./agent/types";
|
|
29
41
|
import type {
|
|
30
42
|
TextResponse,
|
|
31
43
|
ThreadExecuteOptions,
|
|
32
44
|
ThreadExecuteResult,
|
|
33
45
|
ThreadStreamEvent,
|
|
34
|
-
} from "
|
|
35
|
-
import type { AgentMemoryCreate, MemorySearchQuery } from "./memory";
|
|
36
|
-
import { randomID } from "@kernl-sdk/shared/lib";
|
|
46
|
+
} from "./thread/types";
|
|
37
47
|
|
|
38
48
|
export class Agent<
|
|
39
49
|
TContext = UnknownContext,
|
|
@@ -46,12 +56,15 @@ export class Agent<
|
|
|
46
56
|
|
|
47
57
|
id: string;
|
|
48
58
|
name: string;
|
|
59
|
+
description?: string;
|
|
49
60
|
instructions: (context: Context<TContext>) => Promise<string> | string;
|
|
50
61
|
|
|
51
62
|
model: LanguageModel;
|
|
52
63
|
modelSettings: LanguageModelRequestSettings;
|
|
53
|
-
toolkits: BaseToolkit<TContext>[];
|
|
54
64
|
// actions: ActionSet; /* TODO */
|
|
65
|
+
toolkits: BaseToolkit<TContext>[];
|
|
66
|
+
systools: BaseToolkit<TContext>[];
|
|
67
|
+
memory: AgentMemoryConfig;
|
|
55
68
|
|
|
56
69
|
guardrails: {
|
|
57
70
|
input: InputGuardrail[];
|
|
@@ -59,10 +72,9 @@ export class Agent<
|
|
|
59
72
|
};
|
|
60
73
|
responseType: TResponse = "text" as TResponse;
|
|
61
74
|
resetToolChoice: boolean;
|
|
62
|
-
// toolUseBehavior: ToolUseBehavior; (TODO)
|
|
63
75
|
|
|
64
76
|
// --- (TODO) ---
|
|
65
|
-
//
|
|
77
|
+
// toolUseBehavior: ToolUseBehavior;
|
|
66
78
|
// handoffs: (Agent<any, TResponse> | Handoff<any, TResponse>)[];
|
|
67
79
|
// ----------
|
|
68
80
|
|
|
@@ -81,6 +93,7 @@ export class Agent<
|
|
|
81
93
|
}
|
|
82
94
|
this.id = config.id;
|
|
83
95
|
this.name = config.name;
|
|
96
|
+
this.description = config.description;
|
|
84
97
|
this.instructions =
|
|
85
98
|
typeof config.instructions === "function"
|
|
86
99
|
? config.instructions
|
|
@@ -89,6 +102,9 @@ export class Agent<
|
|
|
89
102
|
this.modelSettings = config.modelSettings ?? {};
|
|
90
103
|
|
|
91
104
|
this.toolkits = config.toolkits ?? [];
|
|
105
|
+
this.systools = [];
|
|
106
|
+
this.memory = config.memory ?? { enabled: false };
|
|
107
|
+
|
|
92
108
|
for (const toolkit of this.toolkits) {
|
|
93
109
|
toolkit.bind(this);
|
|
94
110
|
}
|
|
@@ -99,21 +115,6 @@ export class Agent<
|
|
|
99
115
|
}
|
|
100
116
|
this.resetToolChoice = config.resetToolChoice ?? true;
|
|
101
117
|
// this.toolUseBehavior = config.toolUseBehavior ?? "run_llm_again";
|
|
102
|
-
|
|
103
|
-
// this.handoffDescription = config.handoffDescription ?? "";
|
|
104
|
-
// this.handoffs = config.handoffs ?? [];
|
|
105
|
-
|
|
106
|
-
// --- Runtime warning for handoff response type compatibility ---
|
|
107
|
-
// if (config.handoffresponseTypeWarningEnabled) {
|
|
108
|
-
// ...
|
|
109
|
-
// if (responseTypes.size > 1) {
|
|
110
|
-
// logger.warn(
|
|
111
|
-
// `[Agent] Warning: Handoff agents have different response types: ${Array.from(responseTypes).join(", ")}.
|
|
112
|
-
// You can make it type-safe by using Agent.create({ ... }) method instead.`,
|
|
113
|
-
// );
|
|
114
|
-
// }
|
|
115
|
-
// }
|
|
116
|
-
// }
|
|
117
118
|
}
|
|
118
119
|
|
|
119
120
|
/**
|
|
@@ -121,6 +122,14 @@ export class Agent<
|
|
|
121
122
|
*/
|
|
122
123
|
bind(kernl: Kernl): void {
|
|
123
124
|
this.kernl = kernl;
|
|
125
|
+
|
|
126
|
+
// initialize system toolkits
|
|
127
|
+
if (this.memory.enabled) {
|
|
128
|
+
// safety: system tools only rely on ctx.agent, not ctx.context
|
|
129
|
+
const toolkit = memory as unknown as BaseToolkit<TContext>;
|
|
130
|
+
this.systools.push(toolkit);
|
|
131
|
+
toolkit.bind(this);
|
|
132
|
+
}
|
|
124
133
|
}
|
|
125
134
|
|
|
126
135
|
/**
|
|
@@ -247,12 +256,18 @@ export class Agent<
|
|
|
247
256
|
/**
|
|
248
257
|
* @internal
|
|
249
258
|
*
|
|
250
|
-
* Get a specific tool by ID from
|
|
259
|
+
* Get a specific tool by ID from systools and toolkits.
|
|
251
260
|
*
|
|
252
261
|
* @param id The tool ID to look up
|
|
253
262
|
* @returns The tool if found, undefined otherwise
|
|
254
263
|
*/
|
|
255
264
|
tool(id: string): Tool<TContext> | undefined {
|
|
265
|
+
// Check systools first
|
|
266
|
+
for (const toolkit of this.systools) {
|
|
267
|
+
const tool = toolkit.get(id);
|
|
268
|
+
if (tool) return tool;
|
|
269
|
+
}
|
|
270
|
+
// Then user toolkits
|
|
256
271
|
for (const toolkit of this.toolkits) {
|
|
257
272
|
const tool = toolkit.get(id);
|
|
258
273
|
if (tool) return tool;
|
|
@@ -263,7 +278,7 @@ export class Agent<
|
|
|
263
278
|
/**
|
|
264
279
|
* @internal
|
|
265
280
|
*
|
|
266
|
-
* Get all tools available from
|
|
281
|
+
* Get all tools available from systools and toolkits for the given context.
|
|
267
282
|
* Checks for duplicate tool IDs across toolkits and throws an error if found.
|
|
268
283
|
*
|
|
269
284
|
* (TODO): Consider returning toolkits alongside tools so we can serialize them
|
|
@@ -274,24 +289,22 @@ export class Agent<
|
|
|
274
289
|
* @throws {MisconfiguredError} If duplicate tool IDs are found across toolkits
|
|
275
290
|
*/
|
|
276
291
|
async tools(context: Context<TContext>): Promise<Tool<TContext>[]> {
|
|
277
|
-
const
|
|
278
|
-
const toolIds = new Set<string>();
|
|
292
|
+
const all: Tool<TContext>[] = [];
|
|
279
293
|
|
|
280
|
-
for (const toolkit of this.toolkits) {
|
|
281
|
-
|
|
294
|
+
for (const toolkit of [...this.systools, ...this.toolkits]) {
|
|
295
|
+
all.push(...(await toolkit.list(context)));
|
|
296
|
+
}
|
|
282
297
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
throw new MisconfiguredError(
|
|
286
|
-
`Duplicate tool IDs found across toolkits: ${duplicates.join(", ")}`,
|
|
287
|
-
);
|
|
288
|
-
}
|
|
298
|
+
const ids = all.map((t) => t.id);
|
|
299
|
+
const duplicates = ids.filter((id, i) => ids.indexOf(id) !== i);
|
|
289
300
|
|
|
290
|
-
|
|
291
|
-
|
|
301
|
+
if (duplicates.length > 0) {
|
|
302
|
+
throw new MisconfiguredError(
|
|
303
|
+
`Duplicate tool IDs found: ${[...new Set(duplicates)].join(", ")}`,
|
|
304
|
+
);
|
|
292
305
|
}
|
|
293
306
|
|
|
294
|
-
return
|
|
307
|
+
return all;
|
|
295
308
|
}
|
|
296
309
|
|
|
297
310
|
/**
|
|
@@ -359,6 +372,24 @@ export class Agent<
|
|
|
359
372
|
const kmem = this.kernl.memories;
|
|
360
373
|
|
|
361
374
|
return {
|
|
375
|
+
/**
|
|
376
|
+
* List memories scoped to this agent.
|
|
377
|
+
*/
|
|
378
|
+
list: (
|
|
379
|
+
params?: Omit<MemoryListOptions, "filter"> & {
|
|
380
|
+
collection?: string;
|
|
381
|
+
limit?: number;
|
|
382
|
+
// (TODO): we might want to add the filter back here
|
|
383
|
+
},
|
|
384
|
+
) =>
|
|
385
|
+
kmem.list({
|
|
386
|
+
filter: {
|
|
387
|
+
scope: { agentId },
|
|
388
|
+
collections: params?.collection ? [params.collection] : undefined,
|
|
389
|
+
},
|
|
390
|
+
limit: params?.limit,
|
|
391
|
+
}),
|
|
392
|
+
|
|
362
393
|
/**
|
|
363
394
|
* Create a new memory scoped to this agent.
|
|
364
395
|
*/
|
|
@@ -384,6 +415,7 @@ export class Agent<
|
|
|
384
415
|
*/
|
|
385
416
|
search: (
|
|
386
417
|
params: Omit<MemorySearchQuery, "filter"> & {
|
|
418
|
+
// (TODO): is this correct?
|
|
387
419
|
filter?: Omit<NonNullable<MemorySearchQuery["filter"]>, "scope"> & {
|
|
388
420
|
scope?: Omit<
|
|
389
421
|
NonNullable<NonNullable<MemorySearchQuery["filter"]>["scope"]>,
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { Agent } from "@/agent";
|
|
2
|
+
import type { AgentResponseType } from "@/agent/types";
|
|
3
|
+
import type { UnknownContext } from "@/context";
|
|
4
|
+
import type { TextResponse } from "@/thread/types";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Agents resource.
|
|
8
|
+
*
|
|
9
|
+
* Thin facade over the in-process agent registry, returning live Agent instances.
|
|
10
|
+
*
|
|
11
|
+
* Note: agents are code, not persisted data; this is process-local.
|
|
12
|
+
*/
|
|
13
|
+
export class RAgents {
|
|
14
|
+
constructor(private readonly registry: Map<string, Agent>) {}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Get a live Agent instance by id.
|
|
18
|
+
*
|
|
19
|
+
* Callers are expected to know the concrete TContext/TResponse types
|
|
20
|
+
* for their own agents and can specify them via generics.
|
|
21
|
+
*/
|
|
22
|
+
get<
|
|
23
|
+
TContext = UnknownContext,
|
|
24
|
+
TResponse extends AgentResponseType = TextResponse,
|
|
25
|
+
>(id: string): Agent<TContext, TResponse> | undefined {
|
|
26
|
+
const agent = this.registry.get(id);
|
|
27
|
+
return agent as Agent<TContext, TResponse> | undefined;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Check if an agent with the given id is registered.
|
|
32
|
+
*/
|
|
33
|
+
has(id: string): boolean {
|
|
34
|
+
return this.registry.has(id);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* List all registered agents as live instances.
|
|
39
|
+
*
|
|
40
|
+
* Since this is a heterogeneous collection, we expose the widest safe
|
|
41
|
+
* type parameters here.
|
|
42
|
+
*/
|
|
43
|
+
list(): Agent<UnknownContext, AgentResponseType>[] {
|
|
44
|
+
return Array.from(this.registry.values()) as Agent<
|
|
45
|
+
UnknownContext,
|
|
46
|
+
AgentResponseType
|
|
47
|
+
>[];
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Unregister an agent at runtime.
|
|
52
|
+
*/
|
|
53
|
+
unregister(id: string): boolean {
|
|
54
|
+
return this.registry.delete(id);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { RAgents } from "./agents";
|
package/src/context.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { Agent } from "@/agent";
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* Context that is being passed around as part of the session is unknown
|
|
3
5
|
*/
|
|
@@ -18,6 +20,12 @@ export class Context<TContext = UnknownContext> {
|
|
|
18
20
|
*/
|
|
19
21
|
context: TContext;
|
|
20
22
|
|
|
23
|
+
/**
|
|
24
|
+
* The agent executing this context.
|
|
25
|
+
* Set by the thread during execution.
|
|
26
|
+
*/
|
|
27
|
+
agent?: Agent<TContext, any>;
|
|
28
|
+
|
|
21
29
|
// ----------------------
|
|
22
30
|
// TEMPORARY: Tool approval tracking until actions system is refined
|
|
23
31
|
// ----------------------
|
package/src/kernl/kernl.ts
CHANGED
|
@@ -8,6 +8,7 @@ import type { Thread } from "@/thread";
|
|
|
8
8
|
import type { ResolvedAgentResponse } from "@/guardrail";
|
|
9
9
|
import { InMemoryStorage, type KernlStorage } from "@/storage";
|
|
10
10
|
import { RThreads } from "@/api/resources/threads";
|
|
11
|
+
import { RAgents } from "@/api/resources/agents";
|
|
11
12
|
import {
|
|
12
13
|
Memory,
|
|
13
14
|
MemoryByteEncoder,
|
|
@@ -27,21 +28,23 @@ import type { KernlOptions } from "./types";
|
|
|
27
28
|
* tracing.
|
|
28
29
|
*/
|
|
29
30
|
export class Kernl extends KernlHooks<UnknownContext, AgentResponseType> {
|
|
30
|
-
private
|
|
31
|
-
private
|
|
31
|
+
private readonly _agents: Map<string, Agent> = new Map();
|
|
32
|
+
private readonly _models: Map<string, LanguageModel> = new Map();
|
|
32
33
|
|
|
33
34
|
readonly storage: KernlStorage;
|
|
34
35
|
athreads: Map<string, Thread<any, any>> = new Map(); /* active threads */
|
|
35
36
|
|
|
36
37
|
// --- public API ---
|
|
37
|
-
readonly threads: RThreads;
|
|
38
|
-
readonly
|
|
38
|
+
readonly threads: RThreads;
|
|
39
|
+
readonly agents: RAgents;
|
|
40
|
+
readonly memories: Memory;
|
|
39
41
|
|
|
40
42
|
constructor(options: KernlOptions = {}) {
|
|
41
43
|
super();
|
|
42
44
|
this.storage = options.storage?.db ?? new InMemoryStorage();
|
|
43
|
-
this.storage.bind({ agents: this.
|
|
45
|
+
this.storage.bind({ agents: this._agents, models: this._models });
|
|
44
46
|
this.threads = new RThreads(this.storage.threads);
|
|
47
|
+
this.agents = new RAgents(this._agents);
|
|
45
48
|
|
|
46
49
|
// initialize memory
|
|
47
50
|
const embeddingModel =
|
|
@@ -76,15 +79,15 @@ export class Kernl extends KernlHooks<UnknownContext, AgentResponseType> {
|
|
|
76
79
|
* Registers a new agent with the kernl instance.
|
|
77
80
|
*/
|
|
78
81
|
register(agent: Agent): void {
|
|
79
|
-
this.
|
|
82
|
+
this._agents.set(agent.id, agent);
|
|
80
83
|
agent.bind(this);
|
|
81
84
|
|
|
82
85
|
// (TODO): implement exhaustive model registry in protocol/ package
|
|
83
86
|
//
|
|
84
87
|
// auto-populate model registry for storage hydration
|
|
85
88
|
const key = `${agent.model.provider}/${agent.model.modelId}`;
|
|
86
|
-
if (!this.
|
|
87
|
-
this.
|
|
89
|
+
if (!this._models.has(key)) {
|
|
90
|
+
this._models.set(key, agent.model);
|
|
88
91
|
}
|
|
89
92
|
}
|
|
90
93
|
|
package/src/memory/memory.ts
CHANGED
|
@@ -9,6 +9,7 @@ import type {
|
|
|
9
9
|
MemoryScope,
|
|
10
10
|
MemoryConfig,
|
|
11
11
|
MemorySearchQuery,
|
|
12
|
+
MemoryListOptions,
|
|
12
13
|
MemoryByteCodec,
|
|
13
14
|
IndexMemoryRecord,
|
|
14
15
|
WorkingMemorySnapshot,
|
|
@@ -100,6 +101,13 @@ export class Memory {
|
|
|
100
101
|
});
|
|
101
102
|
}
|
|
102
103
|
|
|
104
|
+
/**
|
|
105
|
+
* List memories matching the filter.
|
|
106
|
+
*/
|
|
107
|
+
async list(options?: MemoryListOptions): Promise<MemoryRecord[]> {
|
|
108
|
+
return this.store.list(options);
|
|
109
|
+
}
|
|
110
|
+
|
|
103
111
|
/**
|
|
104
112
|
* Repair indexing for a memory without modifying the DB row.
|
|
105
113
|
*/
|
package/src/thread/thread.ts
CHANGED
|
@@ -112,6 +112,7 @@ export class Thread<
|
|
|
112
112
|
this.agent = options.agent;
|
|
113
113
|
this.context =
|
|
114
114
|
options.context ?? new Context<TContext>(this.namespace, {} as TContext);
|
|
115
|
+
this.context.agent = options.agent;
|
|
115
116
|
this.parent = options.task ?? null;
|
|
116
117
|
this.model = options.model ?? options.agent.model;
|
|
117
118
|
this.storage = options.storage;
|
|
@@ -335,7 +336,7 @@ export class Thread<
|
|
|
335
336
|
state: this.state,
|
|
336
337
|
tick: this._tick,
|
|
337
338
|
context: this.context,
|
|
338
|
-
metadata
|
|
339
|
+
// no metadata - not owned by checkpoint
|
|
339
340
|
});
|
|
340
341
|
}
|
|
341
342
|
|
|
@@ -441,6 +442,7 @@ export class Thread<
|
|
|
441
442
|
// (TMP) - passing the approval status through the context until actions system
|
|
442
443
|
// is refined
|
|
443
444
|
const ctx = new Context(this.namespace, this.context.context);
|
|
445
|
+
ctx.agent = this.agent;
|
|
444
446
|
ctx.approve(call.callId); // mark this call as approved
|
|
445
447
|
const res = await tool.invoke(ctx, call.arguments, call.callId);
|
|
446
448
|
|
package/src/tool/index.ts
CHANGED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Memory system toolkit.
|
|
3
|
+
*
|
|
4
|
+
* Provides tools for agents to store and retrieve memories.
|
|
5
|
+
* Enabled via `memory: true` in agent config.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import assert from "assert";
|
|
9
|
+
import { z } from "zod";
|
|
10
|
+
|
|
11
|
+
import { tool } from "../tool";
|
|
12
|
+
import { Toolkit } from "../toolkit";
|
|
13
|
+
|
|
14
|
+
// --- Tools ---
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Search memories for relevant information using natural language.
|
|
18
|
+
*/
|
|
19
|
+
const search = tool({
|
|
20
|
+
id: "memories.search",
|
|
21
|
+
description:
|
|
22
|
+
"Search your memories. " +
|
|
23
|
+
"Use this to recall facts, preferences, or context you've previously stored.",
|
|
24
|
+
parameters: z.object({
|
|
25
|
+
query: z.string().describe("Natural language search query"),
|
|
26
|
+
limit: z
|
|
27
|
+
.number()
|
|
28
|
+
.int()
|
|
29
|
+
.positive()
|
|
30
|
+
.optional()
|
|
31
|
+
.describe("Max results (default: 10)"),
|
|
32
|
+
}),
|
|
33
|
+
execute: async (ctx, { query, limit }) => {
|
|
34
|
+
assert(ctx.agent, "ctx.agent required for memory tools");
|
|
35
|
+
|
|
36
|
+
const mems = await ctx.agent.memories.search({
|
|
37
|
+
query,
|
|
38
|
+
limit: limit ?? 10,
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
return mems.map((h) => ({
|
|
42
|
+
id: h.document?.id,
|
|
43
|
+
text: h.document?.text,
|
|
44
|
+
score: h.score,
|
|
45
|
+
}));
|
|
46
|
+
},
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Store a new memory to persist across conversations.
|
|
51
|
+
*/
|
|
52
|
+
const create = tool({
|
|
53
|
+
id: "memories.create",
|
|
54
|
+
description:
|
|
55
|
+
"Store a new memory. Use this to remember important facts, user preferences, " +
|
|
56
|
+
"or context that should persist across conversations.",
|
|
57
|
+
parameters: z.object({
|
|
58
|
+
content: z.string().describe("Text content to remember"),
|
|
59
|
+
collection: z
|
|
60
|
+
.string()
|
|
61
|
+
.optional()
|
|
62
|
+
.describe("Category for organizing memories (default: 'facts')"),
|
|
63
|
+
}),
|
|
64
|
+
execute: async (ctx, { content, collection }) => {
|
|
65
|
+
assert(ctx.agent, "ctx.agent required for memory tools");
|
|
66
|
+
|
|
67
|
+
const mem = await ctx.agent.memories.create({
|
|
68
|
+
collection: collection ?? "facts",
|
|
69
|
+
content: { text: content },
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
return { id: mem.id, stored: true };
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* List stored memories, optionally filtered by collection.
|
|
78
|
+
*/
|
|
79
|
+
const list = tool({
|
|
80
|
+
id: "memories.list",
|
|
81
|
+
description:
|
|
82
|
+
"List your stored memories. Use this to see what you've remembered, " +
|
|
83
|
+
"optionally filtered by collection.",
|
|
84
|
+
parameters: z.object({
|
|
85
|
+
collection: z.string().optional().describe("Filter by collection name"),
|
|
86
|
+
limit: z
|
|
87
|
+
.number()
|
|
88
|
+
.int()
|
|
89
|
+
.positive()
|
|
90
|
+
.optional()
|
|
91
|
+
.describe("Max results (default: 20)"),
|
|
92
|
+
}),
|
|
93
|
+
execute: async (ctx, { collection, limit }) => {
|
|
94
|
+
assert(ctx.agent, "ctx.agent required for memory tools");
|
|
95
|
+
|
|
96
|
+
const mems = await ctx.agent.memories.list({
|
|
97
|
+
collection,
|
|
98
|
+
limit: limit ?? 20,
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
return mems.map((r) => ({
|
|
102
|
+
id: r.id,
|
|
103
|
+
collection: r.collection,
|
|
104
|
+
text: r.content.text,
|
|
105
|
+
}));
|
|
106
|
+
},
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
// --- Toolkit ---
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Memory system toolkit.
|
|
113
|
+
*
|
|
114
|
+
* Provides memories.search, memories.create, and memories.list tools.
|
|
115
|
+
*/
|
|
116
|
+
export const memory = new Toolkit({
|
|
117
|
+
id: "sys.memory",
|
|
118
|
+
description: "Tools for storing and retrieving agent memories",
|
|
119
|
+
tools: [list, create, search],
|
|
120
|
+
});
|
package/src/tool/tool.ts
CHANGED
|
@@ -3,12 +3,16 @@ import { Context, UnknownContext } from "@/context";
|
|
|
3
3
|
|
|
4
4
|
import { ModelBehaviorError } from "@/lib/error";
|
|
5
5
|
import { logger } from "@/lib/logger";
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
FAILED,
|
|
9
|
+
COMPLETED,
|
|
10
|
+
INTERRUPTIBLE,
|
|
11
|
+
type LanguageModelTool,
|
|
12
|
+
} from "@kernl-sdk/protocol";
|
|
6
13
|
import { json } from "@kernl-sdk/shared/lib";
|
|
7
|
-
import { FAILED, COMPLETED, INTERRUPTIBLE } from "@kernl-sdk/protocol";
|
|
8
|
-
import type { LanguageModelTool } from "@kernl-sdk/protocol";
|
|
9
14
|
|
|
10
15
|
import type {
|
|
11
|
-
ToolType,
|
|
12
16
|
ToolConfig,
|
|
13
17
|
ToolApprovalFunction,
|
|
14
18
|
ToolEnabledFunction,
|
|
@@ -199,7 +203,7 @@ export class FunctionTool<
|
|
|
199
203
|
description: this.description,
|
|
200
204
|
parameters: z.toJSONSchema(this.parameters ?? z.object({}), {
|
|
201
205
|
target: "draft-7",
|
|
202
|
-
}) as any, //
|
|
206
|
+
}) as any, // use empty object if no parameters (matches AI SDK)
|
|
203
207
|
};
|
|
204
208
|
}
|
|
205
209
|
}
|