kernl 0.1.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 +5 -0
- package/CHANGELOG.md +53 -0
- package/LICENSE +201 -0
- package/dist/agent.d.ts +43 -0
- package/dist/agent.d.ts.map +1 -0
- package/dist/agent.js +130 -0
- package/dist/context.d.ts +70 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +111 -0
- package/dist/env.d.ts +45 -0
- package/dist/env.d.ts.map +1 -0
- package/dist/env.js +31 -0
- package/dist/error.d.ts +1 -0
- package/dist/error.d.ts.map +1 -0
- package/dist/error.js +1 -0
- package/dist/guardrail.d.ts +178 -0
- package/dist/guardrail.d.ts.map +1 -0
- package/dist/guardrail.js +34 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/kernel.d.ts +7 -0
- package/dist/kernel.d.ts.map +1 -0
- package/dist/kernel.js +7 -0
- package/dist/kernl.d.ts +18 -0
- package/dist/kernl.d.ts.map +1 -0
- package/dist/kernl.js +16 -0
- package/dist/lib/env.d.ts +43 -0
- package/dist/lib/env.d.ts.map +1 -0
- package/dist/lib/env.js +29 -0
- package/dist/lib/error.d.ts +88 -0
- package/dist/lib/error.d.ts.map +1 -0
- package/dist/lib/error.js +117 -0
- package/dist/lib/logger.d.ts +36 -0
- package/dist/lib/logger.d.ts.map +1 -0
- package/dist/lib/logger.js +43 -0
- package/dist/lib/serde/__tests__/codec.test.d.ts +2 -0
- package/dist/lib/serde/__tests__/codec.test.d.ts.map +1 -0
- package/dist/lib/serde/__tests__/codec.test.js +75 -0
- package/dist/lib/serde/codec.d.ts +12 -0
- package/dist/lib/serde/codec.d.ts.map +1 -0
- package/dist/lib/serde/codec.js +54 -0
- package/dist/lib/serde/json.d.ts +8 -0
- package/dist/lib/serde/json.d.ts.map +1 -0
- package/dist/lib/serde/json.js +13 -0
- package/dist/lib/serde/thread.d.ts +1 -0
- package/dist/lib/serde/thread.d.ts.map +1 -0
- package/dist/lib/serde/thread.js +172 -0
- package/dist/lib/serde/tool.d.ts +36 -0
- package/dist/lib/serde/tool.d.ts.map +1 -0
- package/dist/lib/serde/tool.js +1 -0
- package/dist/lib/utils.d.ts +19 -0
- package/dist/lib/utils.d.ts.map +1 -0
- package/dist/lib/utils.js +41 -0
- package/dist/lifecycle.d.ts +133 -0
- package/dist/lifecycle.d.ts.map +1 -0
- package/dist/lifecycle.js +29 -0
- package/dist/logger.d.ts +36 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +43 -0
- package/dist/mcp/__tests__/base.test.d.ts +2 -0
- package/dist/mcp/__tests__/base.test.d.ts.map +1 -0
- package/dist/mcp/__tests__/base.test.js +268 -0
- package/dist/mcp/__tests__/fixtures/echo-server.d.ts +3 -0
- package/dist/mcp/__tests__/fixtures/echo-server.d.ts.map +1 -0
- package/dist/mcp/__tests__/fixtures/echo-server.js +92 -0
- package/dist/mcp/__tests__/fixtures/math-server.d.ts +3 -0
- package/dist/mcp/__tests__/fixtures/math-server.d.ts.map +1 -0
- package/dist/mcp/__tests__/fixtures/math-server.js +98 -0
- package/dist/mcp/__tests__/fixtures/server.d.ts +3 -0
- package/dist/mcp/__tests__/fixtures/server.d.ts.map +1 -0
- package/dist/mcp/__tests__/fixtures/server.js +162 -0
- package/dist/mcp/__tests__/fixtures/test-server.d.ts +3 -0
- package/dist/mcp/__tests__/fixtures/test-server.d.ts.map +1 -0
- package/dist/mcp/__tests__/fixtures/test-server.js +163 -0
- package/dist/mcp/__tests__/fixtures/utils.d.ts +17 -0
- package/dist/mcp/__tests__/fixtures/utils.d.ts.map +1 -0
- package/dist/mcp/__tests__/fixtures/utils.js +42 -0
- package/dist/mcp/__tests__/integration.test.d.ts +2 -0
- package/dist/mcp/__tests__/integration.test.d.ts.map +1 -0
- package/dist/mcp/__tests__/integration.test.js +360 -0
- package/dist/mcp/__tests__/stdio.test.d.ts +2 -0
- package/dist/mcp/__tests__/stdio.test.d.ts.map +1 -0
- package/dist/mcp/__tests__/stdio.test.js +180 -0
- package/dist/mcp/__tests__/test-utils.d.ts +17 -0
- package/dist/mcp/__tests__/test-utils.d.ts.map +1 -0
- package/dist/mcp/__tests__/test-utils.js +42 -0
- package/dist/mcp/__tests__/utils.test.d.ts +2 -0
- package/dist/mcp/__tests__/utils.test.d.ts.map +1 -0
- package/dist/mcp/__tests__/utils.test.js +300 -0
- package/dist/mcp/base.d.ts +88 -0
- package/dist/mcp/base.d.ts.map +1 -0
- package/dist/mcp/base.js +68 -0
- package/dist/mcp/http.d.ts +34 -0
- package/dist/mcp/http.d.ts.map +1 -0
- package/dist/mcp/http.js +100 -0
- package/dist/mcp/node.d.ts +60 -0
- package/dist/mcp/node.d.ts.map +1 -0
- package/dist/mcp/node.js +297 -0
- package/dist/mcp/sse.d.ts +34 -0
- package/dist/mcp/sse.d.ts.map +1 -0
- package/dist/mcp/sse.js +97 -0
- package/dist/mcp/stdio.d.ts +32 -0
- package/dist/mcp/stdio.d.ts.map +1 -0
- package/dist/mcp/stdio.js +96 -0
- package/dist/mcp/types.d.ts +172 -0
- package/dist/mcp/types.d.ts.map +1 -0
- package/dist/mcp/types.js +16 -0
- package/dist/mcp/utils.d.ts +23 -0
- package/dist/mcp/utils.d.ts.map +1 -0
- package/dist/mcp/utils.js +44 -0
- package/dist/model.d.ts +175 -0
- package/dist/model.d.ts.map +1 -0
- package/dist/model.js +1 -0
- package/dist/providers/ai.d.ts +1 -0
- package/dist/providers/ai.d.ts.map +1 -0
- package/dist/providers/ai.js +1 -0
- package/dist/providers/default.d.ts +16 -0
- package/dist/providers/default.d.ts.map +1 -0
- package/dist/providers/default.js +17 -0
- package/dist/providers/registry.d.ts +1 -0
- package/dist/providers/registry.d.ts.map +1 -0
- package/dist/providers/registry.js +1 -0
- package/dist/sched/scheduler.d.ts +20 -0
- package/dist/sched/scheduler.d.ts.map +1 -0
- package/dist/sched/scheduler.js +1 -0
- package/dist/sched/task.d.ts +92 -0
- package/dist/sched/task.d.ts.map +1 -0
- package/dist/sched/task.js +102 -0
- package/dist/serde/__tests__/codec.test.d.ts +2 -0
- package/dist/serde/__tests__/codec.test.d.ts.map +1 -0
- package/dist/serde/__tests__/codec.test.js +75 -0
- package/dist/serde/codec.d.ts +12 -0
- package/dist/serde/codec.d.ts.map +1 -0
- package/dist/serde/codec.js +54 -0
- package/dist/serde/json.d.ts +8 -0
- package/dist/serde/json.d.ts.map +1 -0
- package/dist/serde/json.js +13 -0
- package/dist/serde/thread.d.ts +687 -0
- package/dist/serde/thread.d.ts.map +1 -0
- package/dist/serde/thread.js +158 -0
- package/dist/serde/tool.d.ts +36 -0
- package/dist/serde/tool.d.ts.map +1 -0
- package/dist/serde/tool.js +1 -0
- package/dist/session.d.ts +1 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +1 -0
- package/dist/task.d.ts +87 -0
- package/dist/task.d.ts.map +1 -0
- package/dist/task.js +97 -0
- package/dist/thread/__tests__/mock.d.ts +28 -0
- package/dist/thread/__tests__/mock.d.ts.map +1 -0
- package/dist/thread/__tests__/mock.js +74 -0
- package/dist/thread/__tests__/thread.test.d.ts +2 -0
- package/dist/thread/__tests__/thread.test.d.ts.map +1 -0
- package/dist/thread/__tests__/thread.test.js +1412 -0
- package/dist/thread/index.d.ts +2 -0
- package/dist/thread/index.d.ts.map +1 -0
- package/dist/thread/index.js +1 -0
- package/dist/thread/thread.d.ts +66 -0
- package/dist/thread/thread.d.ts.map +1 -0
- package/dist/thread/thread.js +472 -0
- package/dist/thread/utils.d.ts +19 -0
- package/dist/thread/utils.d.ts.map +1 -0
- package/dist/thread/utils.js +50 -0
- package/dist/tool/__tests__/fixtures.d.ts +45 -0
- package/dist/tool/__tests__/fixtures.d.ts.map +1 -0
- package/dist/tool/__tests__/fixtures.js +97 -0
- package/dist/tool/__tests__/tool.test.d.ts +2 -0
- package/dist/tool/__tests__/tool.test.d.ts.map +1 -0
- package/dist/tool/__tests__/tool.test.js +172 -0
- package/dist/tool/__tests__/toolkit.test.d.ts +2 -0
- package/dist/tool/__tests__/toolkit.test.d.ts.map +1 -0
- package/dist/tool/__tests__/toolkit.test.js +134 -0
- package/dist/tool/index.d.ts +4 -0
- package/dist/tool/index.d.ts.map +1 -0
- package/dist/tool/index.js +2 -0
- package/dist/tool/mcp.d.ts +75 -0
- package/dist/tool/mcp.d.ts.map +1 -0
- package/dist/tool/mcp.js +111 -0
- package/dist/tool/tool.d.ts +95 -0
- package/dist/tool/tool.d.ts.map +1 -0
- package/dist/tool/tool.js +176 -0
- package/dist/tool/toolkit.d.ts +121 -0
- package/dist/tool/toolkit.d.ts.map +1 -0
- package/dist/tool/toolkit.js +180 -0
- package/dist/tool/types.d.ts +187 -0
- package/dist/tool/types.d.ts.map +1 -0
- package/dist/tool/types.js +1 -0
- package/dist/tools.d.ts +362 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +220 -0
- package/dist/trace/processor.d.ts +1 -0
- package/dist/trace/processor.d.ts.map +1 -0
- package/dist/trace/processor.js +1 -0
- package/dist/trace/traces.d.ts +1 -0
- package/dist/trace/traces.d.ts.map +1 -0
- package/dist/trace/traces.js +73 -0
- package/dist/trace/utils.d.ts +22 -0
- package/dist/trace/utils.d.ts.map +1 -0
- package/dist/trace/utils.js +30 -0
- package/dist/types/agent.d.ts +91 -0
- package/dist/types/agent.d.ts.map +1 -0
- package/dist/types/agent.js +1 -0
- package/dist/types/proto.d.ts +1551 -0
- package/dist/types/proto.d.ts.map +1 -0
- package/dist/types/proto.js +531 -0
- package/dist/types/thread.d.ts +71 -0
- package/dist/types/thread.d.ts.map +1 -0
- package/dist/types/thread.js +5 -0
- package/dist/usage.d.ts +43 -0
- package/dist/usage.d.ts.map +1 -0
- package/dist/usage.js +61 -0
- package/package.json +52 -0
- package/src/agent.ts +203 -0
- package/src/context.ts +265 -0
- package/src/guardrail.ts +277 -0
- package/src/index.ts +3 -0
- package/src/kernl.ts +22 -0
- package/src/lib/env.ts +36 -0
- package/src/lib/error.ts +158 -0
- package/src/lib/logger.ts +78 -0
- package/src/lib/serde/json.ts +18 -0
- package/src/lib/serde/thread.ts +188 -0
- package/src/lifecycle.ts +181 -0
- package/src/mcp/__tests__/base.test.ts +344 -0
- package/src/mcp/__tests__/fixtures/server.ts +179 -0
- package/src/mcp/__tests__/fixtures/utils.ts +58 -0
- package/src/mcp/__tests__/integration.test.ts +447 -0
- package/src/mcp/__tests__/stdio.test.ts +236 -0
- package/src/mcp/__tests__/utils.test.ts +360 -0
- package/src/mcp/base.ts +162 -0
- package/src/mcp/http.ts +147 -0
- package/src/mcp/sse.ts +137 -0
- package/src/mcp/stdio.ts +136 -0
- package/src/mcp/types.ts +202 -0
- package/src/mcp/utils.ts +62 -0
- package/src/task.ts +119 -0
- package/src/thread/__tests__/mock.ts +95 -0
- package/src/thread/__tests__/thread.test.ts +1574 -0
- package/src/thread/index.ts +1 -0
- package/src/thread/thread.ts +611 -0
- package/src/thread/utils.ts +67 -0
- package/src/tool/__tests__/fixtures.ts +106 -0
- package/src/tool/__tests__/tool.test.ts +235 -0
- package/src/tool/__tests__/toolkit.test.ts +174 -0
- package/src/tool/index.ts +10 -0
- package/src/tool/tool.ts +264 -0
- package/src/tool/toolkit.ts +234 -0
- package/src/tool/types.ts +243 -0
- package/src/trace/processor.ts +0 -0
- package/src/trace/traces.ts +86 -0
- package/src/trace/utils.ts +38 -0
- package/src/types/agent.ts +145 -0
- package/src/types/thread.ts +86 -0
- package/tsconfig.json +13 -0
- package/vitest.config.ts +14 -0
package/src/mcp/types.ts
ADDED
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { Tool } from "@modelcontextprotocol/sdk/types.js";
|
|
3
|
+
|
|
4
|
+
import { Agent } from "@/agent";
|
|
5
|
+
import { Context, UnknownContext } from "@/context";
|
|
6
|
+
import { Logger } from "@/lib/logger";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* MCP tool type from the SDK.
|
|
10
|
+
* We use the SDK's type directly to avoid compatibility issues.
|
|
11
|
+
*/
|
|
12
|
+
export type MCPTool = Tool;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Custom MCP tool schema definition with stricter contracts.
|
|
16
|
+
* NOTE: Currently not used, but kept for potential future runtime validation.
|
|
17
|
+
* If needed, we could parse SDK tools through this schema to enforce stricter requirements.
|
|
18
|
+
*/
|
|
19
|
+
export const MCPToolSchema = z.object({
|
|
20
|
+
name: z.string(),
|
|
21
|
+
description: z.string().optional(),
|
|
22
|
+
inputSchema: z.object({
|
|
23
|
+
type: z.literal("object"),
|
|
24
|
+
properties: z.record(z.string(), z.any()),
|
|
25
|
+
required: z.array(z.string()),
|
|
26
|
+
additionalProperties: z.boolean(),
|
|
27
|
+
}),
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Context provided to server-level tool filters during tool resolution.
|
|
32
|
+
*/
|
|
33
|
+
export interface MCPToolFilterContext<TContext = UnknownContext> {
|
|
34
|
+
context: Context<TContext>;
|
|
35
|
+
agent: Agent<TContext, any>;
|
|
36
|
+
serverId: string;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Server-level filter for MCP tools.
|
|
41
|
+
*
|
|
42
|
+
* Operates at the protocol layer on raw MCPTool objects before conversion.
|
|
43
|
+
* Use this for static, security-focused filtering (e.g., "never expose tool X").
|
|
44
|
+
*
|
|
45
|
+
* This is the first filter in the pipeline. For dynamic, context-aware filtering,
|
|
46
|
+
* use ToolkitFilter on MCPToolkit instead.
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```typescript
|
|
50
|
+
* const server = new MCPServerStdio({
|
|
51
|
+
* command: "npx",
|
|
52
|
+
* args: ["-y", "some-server"],
|
|
53
|
+
* toolFilter: async (ctx, tool) => {
|
|
54
|
+
* // Never expose dangerous tools
|
|
55
|
+
* return !tool.name.startsWith("dangerous_");
|
|
56
|
+
* }
|
|
57
|
+
* });
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
60
|
+
export type MCPToolFilter<TContext = UnknownContext> = (
|
|
61
|
+
context: MCPToolFilterContext<TContext>,
|
|
62
|
+
tool: MCPTool,
|
|
63
|
+
) => Promise<boolean>;
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Static tool filter using allowlist and blocklist of tool names.
|
|
67
|
+
*/
|
|
68
|
+
export interface MCPToolFilterStatic {
|
|
69
|
+
allowedToolNames?: string[];
|
|
70
|
+
blockedToolNames?: string[];
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* JSON-RPC 2.0 request message.
|
|
75
|
+
*/
|
|
76
|
+
export interface JsonRpcRequest {
|
|
77
|
+
jsonrpc: "2.0";
|
|
78
|
+
id: number;
|
|
79
|
+
method: string;
|
|
80
|
+
params?: Record<string, unknown>;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* JSON-RPC 2.0 notification message (no response expected).
|
|
85
|
+
*/
|
|
86
|
+
export interface JsonRpcNotification {
|
|
87
|
+
jsonrpc: "2.0";
|
|
88
|
+
method: string;
|
|
89
|
+
params?: Record<string, unknown>;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* JSON-RPC 2.0 response message.
|
|
94
|
+
*/
|
|
95
|
+
export interface JsonRpcResponse {
|
|
96
|
+
jsonrpc: "2.0";
|
|
97
|
+
id: number;
|
|
98
|
+
result?: any;
|
|
99
|
+
error?: any;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Response from calling an MCP tool.
|
|
104
|
+
*/
|
|
105
|
+
export interface CallToolResponse extends JsonRpcResponse {
|
|
106
|
+
result: {
|
|
107
|
+
content: { type: string; text: string }[];
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
export type CallToolResult = CallToolResponse["result"];
|
|
111
|
+
export type CallToolResultContent = CallToolResult["content"];
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Response from MCP server initialization.
|
|
115
|
+
*/
|
|
116
|
+
export interface InitializeResponse extends JsonRpcResponse {
|
|
117
|
+
result: {
|
|
118
|
+
protocolVersion: string;
|
|
119
|
+
capabilities: {
|
|
120
|
+
tools: Record<string, unknown>;
|
|
121
|
+
};
|
|
122
|
+
serverInfo: {
|
|
123
|
+
name: string;
|
|
124
|
+
version: string;
|
|
125
|
+
};
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
export type InitializeResult = InitializeResponse["result"];
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Base configuration options for stdio-based MCP servers.
|
|
132
|
+
*/
|
|
133
|
+
export interface BaseMCPServerStdioOptions {
|
|
134
|
+
env?: Record<string, string>;
|
|
135
|
+
cwd?: string;
|
|
136
|
+
cacheToolsList?: boolean;
|
|
137
|
+
clientSessionTimeoutSeconds?: number;
|
|
138
|
+
id?: string;
|
|
139
|
+
encoding?: string;
|
|
140
|
+
encodingErrorHandler?: "strict" | "ignore" | "replace";
|
|
141
|
+
logger?: Logger;
|
|
142
|
+
toolFilter?: MCPToolFilter;
|
|
143
|
+
timeout?: number;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Stdio MCP server options with command and args.
|
|
148
|
+
*/
|
|
149
|
+
export interface MCPServerStdioOptions extends BaseMCPServerStdioOptions {
|
|
150
|
+
command: string;
|
|
151
|
+
args?: string[];
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Configuration options for streamable HTTP MCP servers.
|
|
156
|
+
*/
|
|
157
|
+
export interface MCPServerStreamableHttpOptions {
|
|
158
|
+
url: string;
|
|
159
|
+
cacheToolsList?: boolean;
|
|
160
|
+
clientSessionTimeoutSeconds?: number;
|
|
161
|
+
id?: string;
|
|
162
|
+
logger?: Logger;
|
|
163
|
+
toolFilter?: MCPToolFilter;
|
|
164
|
+
timeout?: number;
|
|
165
|
+
|
|
166
|
+
// ----------------------------------------------------
|
|
167
|
+
// OAuth
|
|
168
|
+
// import { OAuthClientProvider } from '@modelcontextprotocol/sdk/client/auth.js';
|
|
169
|
+
authProvider?: any;
|
|
170
|
+
// RequestInit
|
|
171
|
+
requestInit?: any;
|
|
172
|
+
// Custom fetch implementation used for all network requests.
|
|
173
|
+
// import { FetchLike } from '@modelcontextprotocol/sdk/shared/transport.js';
|
|
174
|
+
fetch?: any;
|
|
175
|
+
// import { StreamableHTTPReconnectionOptions } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
|
|
176
|
+
reconnectionOptions?: any;
|
|
177
|
+
sessionId?: string;
|
|
178
|
+
// ----------------------------------------------------
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Configuration options for Server-Sent Events (SSE) MCP servers.
|
|
183
|
+
*/
|
|
184
|
+
export interface MCPServerSSEOptions {
|
|
185
|
+
url: string;
|
|
186
|
+
cacheToolsList?: boolean;
|
|
187
|
+
clientSessionTimeoutSeconds?: number;
|
|
188
|
+
id?: string;
|
|
189
|
+
logger?: Logger;
|
|
190
|
+
toolFilter?: MCPToolFilter;
|
|
191
|
+
timeout?: number;
|
|
192
|
+
|
|
193
|
+
// ----------------------------------------------------
|
|
194
|
+
// OAuth
|
|
195
|
+
// import { OAuthClientProvider } from '@modelcontextprotocol/sdk/client/auth.js';
|
|
196
|
+
authProvider?: any;
|
|
197
|
+
// RequestInit
|
|
198
|
+
requestInit?: any;
|
|
199
|
+
// import { SSEReconnectionOptions } from '@modelcontextprotocol/sdk/client/sse.js';
|
|
200
|
+
eventSourceInit?: any;
|
|
201
|
+
// ----------------------------------------------------
|
|
202
|
+
}
|
package/src/mcp/utils.ts
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
import { UnknownContext } from "@/context";
|
|
4
|
+
import { tool } from "@/tool";
|
|
5
|
+
|
|
6
|
+
import { MCPServer } from "./base";
|
|
7
|
+
import type { MCPTool, MCPToolFilter } from "./types";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Converts an MCP tool definition into a function tool usable by the SDK.
|
|
11
|
+
*/
|
|
12
|
+
export function mcpToFunctionTool(server: MCPServer, mcpTool: MCPTool) {
|
|
13
|
+
async function invoke(_ctx: UnknownContext, input: any) {
|
|
14
|
+
const content = await server.callTool(mcpTool.name, input);
|
|
15
|
+
return content.length === 1 ? content[0] : content;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// MCP tools accept an object with any properties based on their inputSchema
|
|
19
|
+
// We use z.record(z.any()) to represent this flexible schema
|
|
20
|
+
const parameters = mcpTool.inputSchema
|
|
21
|
+
? z.record(z.string(), z.any())
|
|
22
|
+
: undefined;
|
|
23
|
+
|
|
24
|
+
return tool({
|
|
25
|
+
id: mcpTool.name,
|
|
26
|
+
name: mcpTool.name,
|
|
27
|
+
description: mcpTool.description ?? "",
|
|
28
|
+
parameters,
|
|
29
|
+
execute: invoke,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// ----------------------------
|
|
34
|
+
// Tool filters
|
|
35
|
+
// ----------------------------
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Creates a static tool filter from allowed and blocked tool name lists.
|
|
39
|
+
* Returns a filter function that can be used with MCP servers.
|
|
40
|
+
*/
|
|
41
|
+
export function createMCPToolStaticFilter<TContext = UnknownContext>(options?: {
|
|
42
|
+
allowed?: string[];
|
|
43
|
+
blocked?: string[];
|
|
44
|
+
}): MCPToolFilter<TContext> | undefined {
|
|
45
|
+
if (!options?.allowed && !options?.blocked) {
|
|
46
|
+
return undefined;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const allowedToolNames = options.allowed ?? [];
|
|
50
|
+
const blockedToolNames = options.blocked ?? [];
|
|
51
|
+
|
|
52
|
+
return async (_ctx, tool) => {
|
|
53
|
+
const allowed =
|
|
54
|
+
allowedToolNames.length > 0 ? allowedToolNames.includes(tool.name) : true;
|
|
55
|
+
const blocked =
|
|
56
|
+
blockedToolNames.length > 0
|
|
57
|
+
? blockedToolNames.includes(tool.name)
|
|
58
|
+
: false;
|
|
59
|
+
|
|
60
|
+
return allowed && !blocked;
|
|
61
|
+
};
|
|
62
|
+
}
|
package/src/task.ts
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import type { Agent } from "@/agent";
|
|
2
|
+
import type { Context, UnknownContext } from "@/context";
|
|
3
|
+
|
|
4
|
+
import type { Thread } from "@/thread";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* A Task represents a unit of work scheduled by the kernl.
|
|
8
|
+
* Analogous to task_struct in the Linux kernel.
|
|
9
|
+
*/
|
|
10
|
+
export class Task<TContext = UnknownContext, TResult = unknown> {
|
|
11
|
+
pid: string /* process ID - unique identifier for this task */;
|
|
12
|
+
// tgid: string | null; /* task groupid */
|
|
13
|
+
// prio: TaskPriority;
|
|
14
|
+
instructions:
|
|
15
|
+
| string
|
|
16
|
+
| ((context: Context<TContext>) => string) /* dynamic instructions */;
|
|
17
|
+
// sched: TaskSched; /* scheduling (timers, timeouts, deadlines) */
|
|
18
|
+
state: TaskState /* current state of the task */;
|
|
19
|
+
owner: Agent<TContext> /* agent that currently owns this task */;
|
|
20
|
+
|
|
21
|
+
context: Context<TContext> /* execution context propagated throughout call graph */;
|
|
22
|
+
// cred: Credentials; /* Effective (overridable) subjective task credentials (COW): */
|
|
23
|
+
// realcred: Credentials; /* Objective and real subjective task credentials (COW): */
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Might want the ability to pick up a new thread of execution from a compressed task checkpoint instead of including
|
|
27
|
+
* all of the events from the old threads (which may no longer be useful if they completed with good artifacts + reasoning / action summaries).
|
|
28
|
+
* At that point its really more about tracing.
|
|
29
|
+
*/
|
|
30
|
+
threads: Thread<TContext>[] /* all threads associated with this task */;
|
|
31
|
+
current: Thread<TContext> | null /* current executing thread (if any) */;
|
|
32
|
+
result: TResult | null /* final result of the task */;
|
|
33
|
+
// checkpoints: TaskCheckpoint<TContext>[]; /* checkpoints for resuming execution */
|
|
34
|
+
|
|
35
|
+
// TODO: Deferred fields for later implementation
|
|
36
|
+
// tgid: string; // Thread group ID
|
|
37
|
+
// limits: TaskLimits; // Resource limits (max ticks, tokens, timeout)
|
|
38
|
+
// nsproxy: NamespaceProxy; // Namespace isolation
|
|
39
|
+
|
|
40
|
+
constructor(init: {
|
|
41
|
+
pid: string;
|
|
42
|
+
instructions: string | ((context: Context<TContext>) => string);
|
|
43
|
+
state: TaskState;
|
|
44
|
+
owner: Agent<TContext>;
|
|
45
|
+
context: Context<TContext>;
|
|
46
|
+
}) {
|
|
47
|
+
this.pid = init.pid;
|
|
48
|
+
this.instructions = init.instructions;
|
|
49
|
+
this.state = init.state;
|
|
50
|
+
this.owner = init.owner;
|
|
51
|
+
this.context = init.context;
|
|
52
|
+
this.threads = [];
|
|
53
|
+
this.current = null;
|
|
54
|
+
this.result = null;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* The various states that a task may be in.
|
|
60
|
+
*/
|
|
61
|
+
export enum TaskState {
|
|
62
|
+
/**
|
|
63
|
+
* Task is either:
|
|
64
|
+
* - Currently executing
|
|
65
|
+
* - In run queue waiting to be scheduled (might want to differentiate between running + queued here)
|
|
66
|
+
*/
|
|
67
|
+
RUNNING = "running",
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Task is sleeping/blocked, waiting for a condition.
|
|
71
|
+
* Can be woken up by:
|
|
72
|
+
* - The condition being met (e.g., approval granted)
|
|
73
|
+
* - A signal (e.g., user cancellation)
|
|
74
|
+
*
|
|
75
|
+
* Examples:
|
|
76
|
+
* - Waiting for tool approval
|
|
77
|
+
* - Waiting for user input
|
|
78
|
+
* - Sleeping on a timer
|
|
79
|
+
*/
|
|
80
|
+
INTERRUPTIBLE = "interruptible",
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Task is sleeping/blocked and CANNOT be interrupted by signals.
|
|
84
|
+
* Only wakes when the condition is met.
|
|
85
|
+
*
|
|
86
|
+
* Examples:
|
|
87
|
+
* - Waiting for critical I/O (model API call)
|
|
88
|
+
* - Waiting for resource that MUST complete
|
|
89
|
+
*
|
|
90
|
+
* Use sparingly - these tasks can't be cancelled!
|
|
91
|
+
*/
|
|
92
|
+
UNINTERRUPTIBLE = "uninterruptible",
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Task has been stopped by a signal (SIGSTOP).
|
|
96
|
+
* Will remain stopped until explicitly continued (SIGCONT).
|
|
97
|
+
*
|
|
98
|
+
* Examples:
|
|
99
|
+
* - User explicitly paused the agent
|
|
100
|
+
* - Debugger attached
|
|
101
|
+
*/
|
|
102
|
+
STOPPED = "stopped",
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Task has finished execution but hasn't been cleaned up yet.
|
|
106
|
+
* Waiting for parent to read exit status (wait/waitpid).
|
|
107
|
+
*
|
|
108
|
+
* Examples:
|
|
109
|
+
* - Agent completed but result not yet retrieved
|
|
110
|
+
* - Child agent finished, parent needs to collect result
|
|
111
|
+
*/
|
|
112
|
+
ZOMBIE = "zombie",
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Task is being removed from the system.
|
|
116
|
+
* Final cleanup in progress, about to be fully deleted.
|
|
117
|
+
*/
|
|
118
|
+
DEAD = "dead",
|
|
119
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import {
|
|
2
|
+
LanguageModel,
|
|
3
|
+
LanguageModelRequest,
|
|
4
|
+
LanguageModelResponse,
|
|
5
|
+
LanguageModelResponseItem,
|
|
6
|
+
LanguageModelItem,
|
|
7
|
+
} from "@kernl/protocol";
|
|
8
|
+
import type { ThreadStreamEvent } from "@/types/thread";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* A mock language model that echoes the user input back as an assistant message.
|
|
12
|
+
* Useful for testing the execution flow without calling a real LLM.
|
|
13
|
+
*
|
|
14
|
+
* (TODO): Support tool calls for testing.
|
|
15
|
+
*/
|
|
16
|
+
export class MockLanguageModel implements LanguageModel {
|
|
17
|
+
readonly spec = "1.0" as const;
|
|
18
|
+
readonly provider = "mock";
|
|
19
|
+
readonly modelId = "mock-model";
|
|
20
|
+
|
|
21
|
+
async generate(
|
|
22
|
+
request: LanguageModelRequest,
|
|
23
|
+
): Promise<LanguageModelResponse> {
|
|
24
|
+
// Extract user message text from input
|
|
25
|
+
const userText = this.extractUserText(request.input);
|
|
26
|
+
|
|
27
|
+
// Create assistant message that echoes the input
|
|
28
|
+
const content: LanguageModelResponseItem[] = [
|
|
29
|
+
{
|
|
30
|
+
kind: "message",
|
|
31
|
+
id: this.generateId(),
|
|
32
|
+
role: "assistant",
|
|
33
|
+
content: [
|
|
34
|
+
{
|
|
35
|
+
kind: "text",
|
|
36
|
+
text: userText,
|
|
37
|
+
},
|
|
38
|
+
],
|
|
39
|
+
},
|
|
40
|
+
];
|
|
41
|
+
|
|
42
|
+
// Return with fake usage stats
|
|
43
|
+
return {
|
|
44
|
+
content,
|
|
45
|
+
finishReason: "stop",
|
|
46
|
+
usage: {
|
|
47
|
+
inputTokens: this.countTokens(userText),
|
|
48
|
+
outputTokens: this.countTokens(userText),
|
|
49
|
+
totalTokens: this.countTokens(userText) * 2,
|
|
50
|
+
},
|
|
51
|
+
warnings: [],
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
async *stream(
|
|
56
|
+
request: LanguageModelRequest,
|
|
57
|
+
): AsyncIterable<ThreadStreamEvent> {
|
|
58
|
+
// TODO: Implement streaming (not needed for hello world)
|
|
59
|
+
throw new Error("MockLanguageModel.stream() not implemented yet");
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Extract text from the input (LanguageModelItem[])
|
|
64
|
+
*/
|
|
65
|
+
private extractUserText(input: LanguageModelItem[]): string {
|
|
66
|
+
// Extract text from LanguageModelItem array
|
|
67
|
+
const text: string[] = [];
|
|
68
|
+
for (const item of input) {
|
|
69
|
+
if (item.kind === "message" && item.role === "user") {
|
|
70
|
+
for (const part of item.content) {
|
|
71
|
+
if (part.kind === "text") {
|
|
72
|
+
text.push(part.text);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return text.join(" ");
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Simple token counter (fake approximation)
|
|
83
|
+
*/
|
|
84
|
+
private countTokens(text: string): number {
|
|
85
|
+
// Rough approximation: 1 token H 4 characters
|
|
86
|
+
return Math.ceil(text.length / 4);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Generate a simple ID for messages
|
|
91
|
+
*/
|
|
92
|
+
private generateId(): string {
|
|
93
|
+
return `msg_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
|
|
94
|
+
}
|
|
95
|
+
}
|