kernl 0.6.3 → 0.7.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.
Files changed (53) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +14 -0
  3. package/dist/agent/__tests__/systools.test.d.ts +2 -0
  4. package/dist/agent/__tests__/systools.test.d.ts.map +1 -0
  5. package/dist/agent/__tests__/systools.test.js +121 -0
  6. package/dist/agent/types.d.ts +17 -0
  7. package/dist/agent/types.d.ts.map +1 -1
  8. package/dist/agent.d.ts +14 -4
  9. package/dist/agent.d.ts.map +1 -1
  10. package/dist/agent.js +42 -13
  11. package/dist/api/resources/agents/agents.d.ts +38 -0
  12. package/dist/api/resources/agents/agents.d.ts.map +1 -0
  13. package/dist/api/resources/agents/agents.js +44 -0
  14. package/dist/api/resources/agents/index.d.ts +2 -0
  15. package/dist/api/resources/agents/index.d.ts.map +1 -0
  16. package/dist/api/resources/agents/index.js +1 -0
  17. package/dist/context.d.ts +6 -0
  18. package/dist/context.d.ts.map +1 -1
  19. package/dist/context.js +5 -0
  20. package/dist/kernl/kernl.d.ts +4 -2
  21. package/dist/kernl/kernl.d.ts.map +1 -1
  22. package/dist/kernl/kernl.js +11 -8
  23. package/dist/memory/memory.d.ts +5 -1
  24. package/dist/memory/memory.d.ts.map +1 -1
  25. package/dist/memory/memory.js +6 -0
  26. package/dist/thread/thread.d.ts.map +1 -1
  27. package/dist/thread/thread.js +3 -1
  28. package/dist/tool/index.d.ts +1 -0
  29. package/dist/tool/index.d.ts.map +1 -1
  30. package/dist/tool/index.js +2 -0
  31. package/dist/tool/sys/index.d.ts +7 -0
  32. package/dist/tool/sys/index.d.ts.map +1 -0
  33. package/dist/tool/sys/index.js +6 -0
  34. package/dist/tool/sys/memory.d.ts +14 -0
  35. package/dist/tool/sys/memory.d.ts.map +1 -0
  36. package/dist/tool/sys/memory.js +103 -0
  37. package/dist/tool/tool.d.ts +1 -1
  38. package/dist/tool/tool.d.ts.map +1 -1
  39. package/dist/tool/tool.js +2 -2
  40. package/package.json +1 -1
  41. package/src/agent/__tests__/systools.test.ts +146 -0
  42. package/src/agent/types.ts +21 -0
  43. package/src/agent.ts +70 -38
  44. package/src/api/resources/agents/agents.ts +56 -0
  45. package/src/api/resources/agents/index.ts +1 -0
  46. package/src/context.ts +8 -0
  47. package/src/kernl/kernl.ts +11 -8
  48. package/src/memory/memory.ts +8 -0
  49. package/src/thread/thread.ts +3 -1
  50. package/src/tool/index.ts +3 -0
  51. package/src/tool/sys/index.ts +7 -0
  52. package/src/tool/sys/memory.ts +120 -0
  53. package/src/tool/tool.ts +8 -4
@@ -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
  // ----------------------
@@ -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 agents: Map<string, Agent> = new Map();
31
- private models: Map<string, LanguageModel> = new Map();
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; /* Threads resource */
38
- readonly memories: Memory; /* Memory system */
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.agents, models: this.models });
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.agents.set(agent.id, agent);
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.models.has(key)) {
87
- this.models.set(key, agent.model);
89
+ if (!this._models.has(key)) {
90
+ this._models.set(key, agent.model);
88
91
  }
89
92
  }
90
93
 
@@ -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
  */
@@ -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: this.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
@@ -8,3 +8,6 @@ export type {
8
8
  ToolkitFilter,
9
9
  ToolkitFilterContext,
10
10
  } from "./types";
11
+
12
+ // --- system toolkits ---
13
+ export { memory } from "./sys";
@@ -0,0 +1,7 @@
1
+ /**
2
+ * System toolkits.
3
+ *
4
+ * These are internal toolkits that can be enabled via agent config flags.
5
+ */
6
+
7
+ export { memory } from "./memory";
@@ -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, // Use empty object if no parameters (matches AI SDK)
206
+ }) as any, // use empty object if no parameters (matches AI SDK)
203
207
  };
204
208
  }
205
209
  }