kernl 0.1.4 → 0.2.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 +5 -4
- package/CHANGELOG.md +12 -0
- package/dist/agent.d.ts +20 -3
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +60 -41
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/kernl.d.ts +27 -1
- package/dist/kernl.d.ts.map +1 -1
- package/dist/kernl.js +36 -2
- package/dist/mcp/__tests__/integration.test.js +16 -0
- package/dist/thread/__tests__/fixtures/mock-model.d.ts +7 -0
- package/dist/thread/__tests__/fixtures/mock-model.d.ts.map +1 -0
- package/dist/thread/__tests__/fixtures/mock-model.js +59 -0
- package/dist/thread/__tests__/integration.test.d.ts +2 -0
- package/dist/thread/__tests__/integration.test.d.ts.map +1 -0
- package/dist/thread/__tests__/integration.test.js +247 -0
- package/dist/thread/__tests__/stream.test.d.ts +2 -0
- package/dist/thread/__tests__/stream.test.d.ts.map +1 -0
- package/dist/thread/__tests__/stream.test.js +244 -0
- package/dist/thread/__tests__/thread.test.js +612 -763
- package/dist/thread/thread.d.ts +30 -25
- package/dist/thread/thread.d.ts.map +1 -1
- package/dist/thread/thread.js +114 -314
- package/dist/thread/utils.d.ts +16 -1
- package/dist/thread/utils.d.ts.map +1 -1
- package/dist/thread/utils.js +30 -0
- package/dist/tool/index.d.ts +1 -1
- package/dist/tool/index.d.ts.map +1 -1
- package/dist/tool/index.js +1 -1
- package/dist/tool/tool.d.ts.map +1 -1
- package/dist/tool/tool.js +6 -2
- package/dist/tool/toolkit.d.ts +7 -3
- package/dist/tool/toolkit.d.ts.map +1 -1
- package/dist/tool/toolkit.js +7 -3
- package/dist/types/agent.d.ts +5 -5
- package/dist/types/agent.d.ts.map +1 -1
- package/dist/types/thread.d.ts +10 -16
- package/dist/types/thread.d.ts.map +1 -1
- package/package.json +7 -5
- package/src/agent.ts +97 -86
- package/src/index.ts +1 -1
- package/src/kernl.ts +51 -2
- package/src/mcp/__tests__/integration.test.ts +17 -0
- package/src/thread/__tests__/fixtures/mock-model.ts +71 -0
- package/src/thread/__tests__/integration.test.ts +349 -0
- package/src/thread/__tests__/thread.test.ts +625 -775
- package/src/thread/thread.ts +134 -381
- package/src/thread/utils.ts +36 -1
- package/src/tool/index.ts +1 -1
- package/src/tool/tool.ts +6 -2
- package/src/tool/toolkit.ts +10 -3
- package/src/types/agent.ts +9 -6
- package/src/types/thread.ts +25 -17
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
>
|
|
4
|
-
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
> kernl@0.1.4 build /Users/andjones/Documents/projects/kernl/packages/kernl
|
|
4
|
+
> tsc && tsc-alias
|
|
5
|
+
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @kernl/core
|
|
2
2
|
|
|
3
|
+
## 0.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 91b1285: Add agent.run() and agent.stream() convenience methods for thread execution. Kernl now mediates all thread lifecycle with spawn/schedule methods.
|
|
8
|
+
- fffa89e: Refactor thread execution to support streaming and fix tool schema serialization. Adds new `stream()` method for async iteration over thread events, fixes tool parameter schemas to use JSON Schema instead of raw Zod schemas.
|
|
9
|
+
|
|
10
|
+
### Patch Changes
|
|
11
|
+
|
|
12
|
+
- Updated dependencies [fffa89e]
|
|
13
|
+
- @kernl-sdk/protocol@0.2.0
|
|
14
|
+
|
|
3
15
|
## 0.1.4
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
package/dist/agent.d.ts
CHANGED
|
@@ -2,17 +2,20 @@ import { LanguageModel, LanguageModelRequestSettings } from "@kernl-sdk/protocol
|
|
|
2
2
|
import type { Context, UnknownContext } from "./context";
|
|
3
3
|
import { InputGuardrail, OutputGuardrail } from "./guardrail";
|
|
4
4
|
import { AgentHooks } from "./lifecycle";
|
|
5
|
-
import {
|
|
5
|
+
import { BaseToolkit } from "./tool/toolkit";
|
|
6
6
|
import { Tool } from "./tool";
|
|
7
7
|
import type { AgentConfig, AgentResponseType } from "./types/agent";
|
|
8
|
-
import { TextResponse } from "./types/thread";
|
|
8
|
+
import type { TextResponse, ThreadOptions, ThreadExecuteResult, ThreadStreamEvent } from "./types/thread";
|
|
9
|
+
import type { Kernl } from "./kernl";
|
|
10
|
+
import type { ResolvedAgentResponse } from "./guardrail";
|
|
9
11
|
export declare class Agent<TContext = UnknownContext, TResponse extends AgentResponseType = TextResponse> extends AgentHooks<TContext, TResponse> implements AgentConfig<TContext, TResponse> {
|
|
12
|
+
private kernl?;
|
|
10
13
|
id: string;
|
|
11
14
|
name: string;
|
|
12
15
|
instructions: (context: Context<TContext>) => Promise<string> | string;
|
|
13
16
|
model: LanguageModel;
|
|
14
17
|
modelSettings: LanguageModelRequestSettings;
|
|
15
|
-
toolkits:
|
|
18
|
+
toolkits: BaseToolkit<TContext>[];
|
|
16
19
|
guardrails: {
|
|
17
20
|
input: InputGuardrail[];
|
|
18
21
|
output: OutputGuardrail<AgentResponseType>[];
|
|
@@ -20,6 +23,20 @@ export declare class Agent<TContext = UnknownContext, TResponse extends AgentRes
|
|
|
20
23
|
responseType: TResponse;
|
|
21
24
|
resetToolChoice: boolean;
|
|
22
25
|
constructor(config: AgentConfig<TContext, TResponse>);
|
|
26
|
+
/**
|
|
27
|
+
* Bind this agent to a kernl instance. Called by kernl.register().
|
|
28
|
+
*/
|
|
29
|
+
bind(kernl: Kernl): void;
|
|
30
|
+
/**
|
|
31
|
+
* Blocking execution - spawns or resumes thread and waits for completion
|
|
32
|
+
*/
|
|
33
|
+
run(instructions: string, options?: ThreadOptions<TContext>): Promise<ThreadExecuteResult<ResolvedAgentResponse<TResponse>>>;
|
|
34
|
+
/**
|
|
35
|
+
* Streaming execution - spawns or resumes thread and returns async iterator
|
|
36
|
+
*
|
|
37
|
+
* NOTE: streaming probably won't make sense in scheduling contexts so spawnStream etc. won't make sense
|
|
38
|
+
*/
|
|
39
|
+
stream(instructions: string, options?: ThreadOptions<TContext>): AsyncIterable<ThreadStreamEvent>;
|
|
23
40
|
/**
|
|
24
41
|
* Get a specific tool by ID from all toolkits.
|
|
25
42
|
*
|
package/dist/agent.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,4BAA4B,EAE7B,MAAM,qBAAqB,CAAC;AAE7B,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAK9B,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACpE,OAAO,KAAK,EACV,YAAY,EACZ,aAAa,EACb,mBAAmB,EACnB,iBAAiB,EAClB,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAEzD,qBAAa,KAAK,CACd,QAAQ,GAAG,cAAc,EACzB,SAAS,SAAS,iBAAiB,GAAG,YAAY,CAEpD,SAAQ,UAAU,CAAC,QAAQ,EAAE,SAAS,CACtC,YAAW,WAAW,CAAC,QAAQ,EAAE,SAAS,CAAC;IAE3C,OAAO,CAAC,KAAK,CAAC,CAAQ;IAEtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,QAAQ,CAAC,KAAK,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;IAEvE,KAAK,EAAE,aAAa,CAAC;IACrB,aAAa,EAAE,4BAA4B,CAAC;IAC5C,QAAQ,EAAE,WAAW,CAAC,QAAQ,CAAC,EAAE,CAAC;IAClC,UAAU,EAAE;QACV,KAAK,EAAE,cAAc,EAAE,CAAC;QACxB,MAAM,EAAE,eAAe,CAAC,iBAAiB,CAAC,EAAE,CAAC;KAC9C,CAAC;IACF,YAAY,EAAE,SAAS,CAAuB;IAC9C,eAAe,EAAE,OAAO,CAAC;gBAgBb,MAAM,EAAE,WAAW,CAAC,QAAQ,EAAE,SAAS,CAAC;IA0CpD;;OAEG;IACH,IAAI,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAIxB;;OAEG;IACG,GAAG,CACP,YAAY,EAAE,MAAM,EACpB,OAAO,CAAC,EAAE,aAAa,CAAC,QAAQ,CAAC,GAChC,OAAO,CAAC,mBAAmB,CAAC,qBAAqB,CAAC,SAAS,CAAC,CAAC,CAAC;IAqBjE;;;;OAIG;IACI,MAAM,CACX,YAAY,EAAE,MAAM,EACpB,OAAO,CAAC,EAAE,aAAa,CAAC,QAAQ,CAAC,GAChC,aAAa,CAAC,iBAAiB,CAAC;IAsBnC;;;;;OAKG;IACH,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,SAAS;IAQ5C;;;;;;;;;;OAUG;IACG,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,QAAQ,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;CAoBnE"}
|
package/dist/agent.js
CHANGED
|
@@ -1,13 +1,19 @@
|
|
|
1
|
+
import { message, } from "@kernl-sdk/protocol";
|
|
1
2
|
import { AgentHooks } from "./lifecycle";
|
|
2
|
-
|
|
3
|
+
import { Thread } from "./thread";
|
|
3
4
|
import { MisconfiguredError } from "./lib/error";
|
|
4
5
|
export class Agent extends AgentHooks {
|
|
6
|
+
kernl;
|
|
5
7
|
id;
|
|
6
8
|
name;
|
|
7
9
|
instructions;
|
|
8
10
|
model;
|
|
9
11
|
modelSettings;
|
|
10
12
|
toolkits;
|
|
13
|
+
guardrails;
|
|
14
|
+
responseType = "text";
|
|
15
|
+
resetToolChoice;
|
|
16
|
+
// toolUseBehavior: ToolUseBehavior; (TODO)
|
|
11
17
|
// --- (TODO) ---
|
|
12
18
|
// handoffDescription: string; // ??
|
|
13
19
|
// handoffs: (Agent<any, TResponse> | Handoff<any, TResponse>)[];
|
|
@@ -15,30 +21,10 @@ export class Agent extends AgentHooks {
|
|
|
15
21
|
// /* Process/thread-group–wide signal state shared by all threads in the group: shared pending signals, job control
|
|
16
22
|
// (stops/cont, group exit), rlimits, etc. */
|
|
17
23
|
// signal: *struct signal_struct;
|
|
18
|
-
//
|
|
24
|
+
//
|
|
25
|
+
// /* Table of signal handlers (sa_handler, sa_mask, flags) shared by threads
|
|
26
|
+
// (CLONE_SIGHAND). RCU-protected so readers can access it locklessly. */
|
|
19
27
|
// sighand: *struct sighand_struct __rcu;
|
|
20
|
-
guardrails;
|
|
21
|
-
responseType = "text";
|
|
22
|
-
resetToolChoice;
|
|
23
|
-
// toolUseBehavior: ToolUseBehavior; (TODO)
|
|
24
|
-
// /**
|
|
25
|
-
// * Create an Agent with handoffs and automatically infer the union type for TResponse from the handoff agents' response types.
|
|
26
|
-
// */
|
|
27
|
-
// static create<
|
|
28
|
-
// TResponse extends AgentResponseType = TextResponse,
|
|
29
|
-
// Handoffs extends readonly (Agent<any, any> | Handoff<any, any>)[] = [],
|
|
30
|
-
// >(
|
|
31
|
-
// config: AgentConfigWithHandoffs<TResponse, Handoffs>,
|
|
32
|
-
// ): Agent<UnknownContext, TResponse | HandoffsOutputUnion<Handoffs>> {
|
|
33
|
-
// return new Agent<UnknownContext, TResponse | HandoffsOutputUnion<Handoffs>>(
|
|
34
|
-
// {
|
|
35
|
-
// ...config,
|
|
36
|
-
// handoffs: config.handoffs as any,
|
|
37
|
-
// responseType: config.responseType,
|
|
38
|
-
// handoffresponseTypeWarningEnabled: false,
|
|
39
|
-
// },
|
|
40
|
-
// );
|
|
41
|
-
// }
|
|
42
28
|
constructor(config) {
|
|
43
29
|
super();
|
|
44
30
|
if (config.id.trim() === "") {
|
|
@@ -50,7 +36,7 @@ export class Agent extends AgentHooks {
|
|
|
50
36
|
typeof config.instructions === "function"
|
|
51
37
|
? config.instructions
|
|
52
38
|
: () => config.instructions;
|
|
53
|
-
this.model = config.model; // TODO:
|
|
39
|
+
this.model = config.model; // (TODO): include optional default setting for convenience like env.DEFAULT_LLM = "gpt-5"
|
|
54
40
|
this.modelSettings = config.modelSettings ?? {};
|
|
55
41
|
this.toolkits = config.toolkits ?? [];
|
|
56
42
|
for (const toolkit of this.toolkits) {
|
|
@@ -65,29 +51,62 @@ export class Agent extends AgentHooks {
|
|
|
65
51
|
// this.handoffDescription = config.handoffDescription ?? "";
|
|
66
52
|
// this.handoffs = config.handoffs ?? [];
|
|
67
53
|
// --- Runtime warning for handoff response type compatibility ---
|
|
68
|
-
// if (
|
|
69
|
-
//
|
|
70
|
-
// config.handoffresponseTypeWarningEnabled
|
|
71
|
-
// ) {
|
|
72
|
-
// if (this.handoffs && this.responseType) {
|
|
73
|
-
// const responseTypes = new Set<string>([
|
|
74
|
-
// JSON.stringify(this.responseType),
|
|
75
|
-
// ]);
|
|
76
|
-
// for (const h of this.handoffs) {
|
|
77
|
-
// if ("responseType" in h && h.responseType) {
|
|
78
|
-
// responseTypes.add(JSON.stringify(h.responseType));
|
|
79
|
-
// } else if ("agent" in h && h.agent.responseType) {
|
|
80
|
-
// responseTypes.add(JSON.stringify(h.agent.responseType));
|
|
81
|
-
// }
|
|
82
|
-
// }
|
|
54
|
+
// if (config.handoffresponseTypeWarningEnabled) {
|
|
55
|
+
// ...
|
|
83
56
|
// if (responseTypes.size > 1) {
|
|
84
57
|
// logger.warn(
|
|
85
|
-
// `[Agent] Warning: Handoff agents have different response types: ${Array.from(responseTypes).join(", ")}.
|
|
58
|
+
// `[Agent] Warning: Handoff agents have different response types: ${Array.from(responseTypes).join(", ")}.
|
|
59
|
+
// You can make it type-safe by using Agent.create({ ... }) method instead.`,
|
|
86
60
|
// );
|
|
87
61
|
// }
|
|
88
62
|
// }
|
|
89
63
|
// }
|
|
90
64
|
}
|
|
65
|
+
/**
|
|
66
|
+
* Bind this agent to a kernl instance. Called by kernl.register().
|
|
67
|
+
*/
|
|
68
|
+
bind(kernl) {
|
|
69
|
+
this.kernl = kernl;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Blocking execution - spawns or resumes thread and waits for completion
|
|
73
|
+
*/
|
|
74
|
+
async run(instructions, options) {
|
|
75
|
+
if (!this.kernl) {
|
|
76
|
+
throw new MisconfiguredError(`Agent ${this.id} not bound to kernl. Call kernl.register(agent) first.`);
|
|
77
|
+
}
|
|
78
|
+
const m = message({ role: "user", text: instructions });
|
|
79
|
+
const tid = options?.threadId;
|
|
80
|
+
// NOTE: may end up moving this to the kernl
|
|
81
|
+
let thread = tid ? this.kernl.threads.get(tid) : null;
|
|
82
|
+
if (!thread) {
|
|
83
|
+
thread = new Thread(this.kernl, this, [m], options);
|
|
84
|
+
return this.kernl.spawn(thread);
|
|
85
|
+
}
|
|
86
|
+
thread.append(m);
|
|
87
|
+
return this.kernl.schedule(thread);
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Streaming execution - spawns or resumes thread and returns async iterator
|
|
91
|
+
*
|
|
92
|
+
* NOTE: streaming probably won't make sense in scheduling contexts so spawnStream etc. won't make sense
|
|
93
|
+
*/
|
|
94
|
+
async *stream(instructions, options) {
|
|
95
|
+
if (!this.kernl) {
|
|
96
|
+
throw new MisconfiguredError(`Agent ${this.id} not bound to kernl. Call kernl.register(agent) first.`);
|
|
97
|
+
}
|
|
98
|
+
const m = message({ role: "user", text: instructions });
|
|
99
|
+
const tid = options?.threadId;
|
|
100
|
+
// NOTE: may end up moving this to the kernl
|
|
101
|
+
let thread = tid ? this.kernl.threads.get(tid) : null;
|
|
102
|
+
if (!thread) {
|
|
103
|
+
thread = new Thread(this.kernl, this, [m], options);
|
|
104
|
+
yield* this.kernl.spawnStream(thread);
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
thread.append(m);
|
|
108
|
+
yield* this.kernl.scheduleStream(thread);
|
|
109
|
+
}
|
|
91
110
|
/**
|
|
92
111
|
* Get a specific tool by ID from all toolkits.
|
|
93
112
|
*
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { Kernl } from "./kernl";
|
|
2
2
|
export { Agent } from "./agent";
|
|
3
3
|
export type { Context } from "./context";
|
|
4
|
-
export { tool, FunctionToolkit, MCPToolkit } from "./tool";
|
|
4
|
+
export { tool, Toolkit, FunctionToolkit, MCPToolkit } from "./tool";
|
|
5
5
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,YAAY,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,IAAI,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,YAAY,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC"}
|
package/dist/index.js
CHANGED
package/dist/kernl.d.ts
CHANGED
|
@@ -1,18 +1,44 @@
|
|
|
1
1
|
import { Agent } from "./agent";
|
|
2
2
|
import { UnknownContext } from "./context";
|
|
3
3
|
import { KernlHooks } from "./lifecycle";
|
|
4
|
+
import type { Thread } from "./thread";
|
|
4
5
|
import type { AgentResponseType } from "./types/agent";
|
|
6
|
+
import type { ThreadExecuteResult, ThreadStreamEvent } from "./types/thread";
|
|
7
|
+
import type { ResolvedAgentResponse } from "./guardrail";
|
|
5
8
|
/**
|
|
6
|
-
*
|
|
9
|
+
* The kernl - manages agent processes, scheduling, and task lifecycle
|
|
7
10
|
*
|
|
8
11
|
* Orchestrates agent execution, including guardrails, tool calls, session persistence, and
|
|
9
12
|
* tracing.
|
|
10
13
|
*/
|
|
11
14
|
export declare class Kernl extends KernlHooks<UnknownContext, AgentResponseType> {
|
|
12
15
|
private agents;
|
|
16
|
+
threads: Map<string, Thread<any, any>>;
|
|
13
17
|
/**
|
|
14
18
|
* Registers a new agent with the kernl instance.
|
|
15
19
|
*/
|
|
16
20
|
register(agent: Agent): void;
|
|
21
|
+
/**
|
|
22
|
+
* Spawn a new thread - blocking execution
|
|
23
|
+
*/
|
|
24
|
+
spawn<TContext, TResponse extends AgentResponseType>(thread: Thread<TContext, TResponse>): Promise<ThreadExecuteResult<ResolvedAgentResponse<TResponse>>>;
|
|
25
|
+
/**
|
|
26
|
+
* Schedule an existing thread - blocking execution
|
|
27
|
+
*
|
|
28
|
+
* NOTE: just blocks for now
|
|
29
|
+
*/
|
|
30
|
+
schedule<TContext, TResponse extends AgentResponseType>(thread: Thread<TContext, TResponse>): Promise<ThreadExecuteResult<ResolvedAgentResponse<TResponse>>>;
|
|
31
|
+
/**
|
|
32
|
+
* (TMP) - probably won't make sense with assync scheduling contexts
|
|
33
|
+
*
|
|
34
|
+
* Spawn a new thread - streaming execution
|
|
35
|
+
*/
|
|
36
|
+
spawnStream<TContext, TResponse extends AgentResponseType>(thread: Thread<TContext, TResponse>): AsyncIterable<ThreadStreamEvent>;
|
|
37
|
+
/**
|
|
38
|
+
* (TMP) - probably won't make sense with assync scheduling contexts
|
|
39
|
+
*
|
|
40
|
+
* Schedule an existing thread - streaming execution
|
|
41
|
+
*/
|
|
42
|
+
scheduleStream<TContext, TResponse extends AgentResponseType>(thread: Thread<TContext, TResponse>): AsyncIterable<ThreadStreamEvent>;
|
|
17
43
|
}
|
|
18
44
|
//# sourceMappingURL=kernl.d.ts.map
|
package/dist/kernl.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kernl.d.ts","sourceRoot":"","sources":["../src/kernl.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"kernl.d.ts","sourceRoot":"","sources":["../src/kernl.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAEvC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,KAAK,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAC7E,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAEzD;;;;;GAKG;AACH,qBAAa,KAAM,SAAQ,UAAU,CAAC,cAAc,EAAE,iBAAiB,CAAC;IACtE,OAAO,CAAC,MAAM,CAAiC;IAC/C,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAa;IAEnD;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAK5B;;OAEG;IACG,KAAK,CAAC,QAAQ,EAAE,SAAS,SAAS,iBAAiB,EACvD,MAAM,EAAE,MAAM,CAAC,QAAQ,EAAE,SAAS,CAAC,GAClC,OAAO,CAAC,mBAAmB,CAAC,qBAAqB,CAAC,SAAS,CAAC,CAAC,CAAC;IAKjE;;;;OAIG;IACG,QAAQ,CAAC,QAAQ,EAAE,SAAS,SAAS,iBAAiB,EAC1D,MAAM,EAAE,MAAM,CAAC,QAAQ,EAAE,SAAS,CAAC,GAClC,OAAO,CAAC,mBAAmB,CAAC,qBAAqB,CAAC,SAAS,CAAC,CAAC,CAAC;IAIjE;;;;OAIG;IACI,WAAW,CAAC,QAAQ,EAAE,SAAS,SAAS,iBAAiB,EAC9D,MAAM,EAAE,MAAM,CAAC,QAAQ,EAAE,SAAS,CAAC,GAClC,aAAa,CAAC,iBAAiB,CAAC;IAKnC;;;;OAIG;IACI,cAAc,CAAC,QAAQ,EAAE,SAAS,SAAS,iBAAiB,EACjE,MAAM,EAAE,MAAM,CAAC,QAAQ,EAAE,SAAS,CAAC,GAClC,aAAa,CAAC,iBAAiB,CAAC;CAGpC"}
|
package/dist/kernl.js
CHANGED
|
@@ -1,16 +1,50 @@
|
|
|
1
1
|
import { KernlHooks } from "./lifecycle";
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* The kernl - manages agent processes, scheduling, and task lifecycle
|
|
4
4
|
*
|
|
5
5
|
* Orchestrates agent execution, including guardrails, tool calls, session persistence, and
|
|
6
6
|
* tracing.
|
|
7
7
|
*/
|
|
8
8
|
export class Kernl extends KernlHooks {
|
|
9
9
|
agents = new Map();
|
|
10
|
+
threads = new Map();
|
|
10
11
|
/**
|
|
11
12
|
* Registers a new agent with the kernl instance.
|
|
12
13
|
*/
|
|
13
14
|
register(agent) {
|
|
14
|
-
|
|
15
|
+
this.agents.set(agent.id, agent);
|
|
16
|
+
agent.bind(this);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Spawn a new thread - blocking execution
|
|
20
|
+
*/
|
|
21
|
+
async spawn(thread) {
|
|
22
|
+
this.threads.set(thread.id, thread);
|
|
23
|
+
return await thread.execute();
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Schedule an existing thread - blocking execution
|
|
27
|
+
*
|
|
28
|
+
* NOTE: just blocks for now
|
|
29
|
+
*/
|
|
30
|
+
async schedule(thread) {
|
|
31
|
+
return await thread.execute();
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* (TMP) - probably won't make sense with assync scheduling contexts
|
|
35
|
+
*
|
|
36
|
+
* Spawn a new thread - streaming execution
|
|
37
|
+
*/
|
|
38
|
+
async *spawnStream(thread) {
|
|
39
|
+
this.threads.set(thread.id, thread);
|
|
40
|
+
yield* thread.stream();
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* (TMP) - probably won't make sense with assync scheduling contexts
|
|
44
|
+
*
|
|
45
|
+
* Schedule an existing thread - streaming execution
|
|
46
|
+
*/
|
|
47
|
+
async *scheduleStream(thread) {
|
|
48
|
+
yield* thread.stream();
|
|
15
49
|
}
|
|
16
50
|
}
|
|
@@ -8,7 +8,15 @@ import { Context } from "../../context";
|
|
|
8
8
|
import { tool } from "../../tool";
|
|
9
9
|
import { z } from "zod";
|
|
10
10
|
import { createMCPToolStaticFilter } from "../utils";
|
|
11
|
+
import { createMockModel } from "../../thread/__tests__/fixtures/mock-model";
|
|
11
12
|
const TEST_SERVER = path.join(__dirname, "fixtures", "server.ts");
|
|
13
|
+
// Mock model for tests that only need toolkit functionality
|
|
14
|
+
const mockModel = createMockModel(async () => ({
|
|
15
|
+
content: [],
|
|
16
|
+
finishReason: "stop",
|
|
17
|
+
usage: { inputTokens: 0, outputTokens: 0, totalTokens: 0 },
|
|
18
|
+
warnings: [],
|
|
19
|
+
}));
|
|
12
20
|
describe("MCP Integration Tests", () => {
|
|
13
21
|
describe("MCPToolkit Integration", () => {
|
|
14
22
|
let server;
|
|
@@ -128,6 +136,7 @@ describe("MCP Integration Tests", () => {
|
|
|
128
136
|
id: "test-agent",
|
|
129
137
|
name: "Test Agent",
|
|
130
138
|
instructions: "Test",
|
|
139
|
+
model: mockModel,
|
|
131
140
|
toolkits: [toolkit],
|
|
132
141
|
});
|
|
133
142
|
const context = new Context({});
|
|
@@ -158,6 +167,7 @@ describe("MCP Integration Tests", () => {
|
|
|
158
167
|
id: "test-agent",
|
|
159
168
|
name: "Test Agent",
|
|
160
169
|
instructions: "Test",
|
|
170
|
+
model: mockModel,
|
|
161
171
|
toolkits: [toolkit],
|
|
162
172
|
});
|
|
163
173
|
const context = new Context({});
|
|
@@ -189,6 +199,7 @@ describe("MCP Integration Tests", () => {
|
|
|
189
199
|
id: "test-agent",
|
|
190
200
|
name: "Test Agent",
|
|
191
201
|
instructions: "Test",
|
|
202
|
+
model: mockModel,
|
|
192
203
|
toolkits: [toolkit],
|
|
193
204
|
});
|
|
194
205
|
const context = new Context({ userId: "test-user" });
|
|
@@ -216,6 +227,7 @@ describe("MCP Integration Tests", () => {
|
|
|
216
227
|
id: "test-agent",
|
|
217
228
|
name: "Test Agent",
|
|
218
229
|
instructions: "Test",
|
|
230
|
+
model: mockModel,
|
|
219
231
|
toolkits: [mcpToolkit],
|
|
220
232
|
});
|
|
221
233
|
const context = new Context({});
|
|
@@ -239,6 +251,7 @@ describe("MCP Integration Tests", () => {
|
|
|
239
251
|
id: "test-agent",
|
|
240
252
|
name: "Test Agent",
|
|
241
253
|
instructions: "Test",
|
|
254
|
+
model: mockModel,
|
|
242
255
|
toolkits: [mcpToolkit],
|
|
243
256
|
});
|
|
244
257
|
// Populate toolkit cache
|
|
@@ -264,6 +277,7 @@ describe("MCP Integration Tests", () => {
|
|
|
264
277
|
id: "test-agent",
|
|
265
278
|
name: "Test Agent",
|
|
266
279
|
instructions: "Test",
|
|
280
|
+
model: mockModel,
|
|
267
281
|
toolkits: [mcpToolkit],
|
|
268
282
|
});
|
|
269
283
|
const context = new Context({});
|
|
@@ -308,6 +322,7 @@ describe("MCP Integration Tests", () => {
|
|
|
308
322
|
id: "test-agent",
|
|
309
323
|
name: "Test Agent",
|
|
310
324
|
instructions: "Test",
|
|
325
|
+
model: mockModel,
|
|
311
326
|
toolkits: [mcpToolkit, functionToolkit],
|
|
312
327
|
});
|
|
313
328
|
const context = new Context({});
|
|
@@ -349,6 +364,7 @@ describe("MCP Integration Tests", () => {
|
|
|
349
364
|
id: "test-agent",
|
|
350
365
|
name: "Test Agent",
|
|
351
366
|
instructions: "Test",
|
|
367
|
+
model: mockModel,
|
|
352
368
|
toolkits: [mcpToolkit, functionToolkit],
|
|
353
369
|
});
|
|
354
370
|
const context = new Context({});
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { LanguageModel, LanguageModelRequest, LanguageModelResponse } from "@kernl-sdk/protocol";
|
|
2
|
+
/**
|
|
3
|
+
* Creates a mock LanguageModel that automatically implements streaming
|
|
4
|
+
* based on the generate() implementation.
|
|
5
|
+
*/
|
|
6
|
+
export declare function createMockModel(generateFn: (req: LanguageModelRequest) => Promise<LanguageModelResponse>): LanguageModel;
|
|
7
|
+
//# sourceMappingURL=mock-model.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mock-model.d.ts","sourceRoot":"","sources":["../../../../src/thread/__tests__/fixtures/mock-model.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,oBAAoB,EACpB,qBAAqB,EAGtB,MAAM,qBAAqB,CAAC;AA+C7B;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,UAAU,EAAE,CAAC,GAAG,EAAE,oBAAoB,KAAK,OAAO,CAAC,qBAAqB,CAAC,GACxE,aAAa,CAWf"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Helper to convert LanguageModelResponse content to stream events.
|
|
3
|
+
* Yields both delta events (for streaming UX) and complete items (for history).
|
|
4
|
+
*/
|
|
5
|
+
async function* streamFromResponse(response) {
|
|
6
|
+
for (const item of response.content) {
|
|
7
|
+
if (item.kind === "message") {
|
|
8
|
+
// Stream message with text deltas
|
|
9
|
+
for (const contentItem of item.content) {
|
|
10
|
+
if (contentItem.kind === "text") {
|
|
11
|
+
// Yield text-start
|
|
12
|
+
yield {
|
|
13
|
+
kind: "text-start",
|
|
14
|
+
id: item.id,
|
|
15
|
+
};
|
|
16
|
+
// Yield text-delta
|
|
17
|
+
yield {
|
|
18
|
+
kind: "text-delta",
|
|
19
|
+
id: item.id,
|
|
20
|
+
text: contentItem.text,
|
|
21
|
+
};
|
|
22
|
+
// Yield text-end
|
|
23
|
+
yield {
|
|
24
|
+
kind: "text-end",
|
|
25
|
+
id: item.id,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
// Yield complete message
|
|
30
|
+
yield item;
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
// For tool-call, reasoning, tool-result - just yield as-is
|
|
34
|
+
yield item;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
// Yield finish event
|
|
38
|
+
yield {
|
|
39
|
+
kind: "finish",
|
|
40
|
+
finishReason: response.finishReason,
|
|
41
|
+
usage: response.usage,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Creates a mock LanguageModel that automatically implements streaming
|
|
46
|
+
* based on the generate() implementation.
|
|
47
|
+
*/
|
|
48
|
+
export function createMockModel(generateFn) {
|
|
49
|
+
return {
|
|
50
|
+
spec: "1.0",
|
|
51
|
+
provider: "test",
|
|
52
|
+
modelId: "test-model",
|
|
53
|
+
generate: generateFn,
|
|
54
|
+
stream: async function* (req) {
|
|
55
|
+
const response = await generateFn(req);
|
|
56
|
+
yield* streamFromResponse(response);
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"integration.test.d.ts","sourceRoot":"","sources":["../../../src/thread/__tests__/integration.test.ts"],"names":[],"mappings":""}
|