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.
Files changed (257) hide show
  1. package/.turbo/turbo-build.log +5 -0
  2. package/CHANGELOG.md +53 -0
  3. package/LICENSE +201 -0
  4. package/dist/agent.d.ts +43 -0
  5. package/dist/agent.d.ts.map +1 -0
  6. package/dist/agent.js +130 -0
  7. package/dist/context.d.ts +70 -0
  8. package/dist/context.d.ts.map +1 -0
  9. package/dist/context.js +111 -0
  10. package/dist/env.d.ts +45 -0
  11. package/dist/env.d.ts.map +1 -0
  12. package/dist/env.js +31 -0
  13. package/dist/error.d.ts +1 -0
  14. package/dist/error.d.ts.map +1 -0
  15. package/dist/error.js +1 -0
  16. package/dist/guardrail.d.ts +178 -0
  17. package/dist/guardrail.d.ts.map +1 -0
  18. package/dist/guardrail.js +34 -0
  19. package/dist/index.d.ts +4 -0
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.js +2 -0
  22. package/dist/kernel.d.ts +7 -0
  23. package/dist/kernel.d.ts.map +1 -0
  24. package/dist/kernel.js +7 -0
  25. package/dist/kernl.d.ts +18 -0
  26. package/dist/kernl.d.ts.map +1 -0
  27. package/dist/kernl.js +16 -0
  28. package/dist/lib/env.d.ts +43 -0
  29. package/dist/lib/env.d.ts.map +1 -0
  30. package/dist/lib/env.js +29 -0
  31. package/dist/lib/error.d.ts +88 -0
  32. package/dist/lib/error.d.ts.map +1 -0
  33. package/dist/lib/error.js +117 -0
  34. package/dist/lib/logger.d.ts +36 -0
  35. package/dist/lib/logger.d.ts.map +1 -0
  36. package/dist/lib/logger.js +43 -0
  37. package/dist/lib/serde/__tests__/codec.test.d.ts +2 -0
  38. package/dist/lib/serde/__tests__/codec.test.d.ts.map +1 -0
  39. package/dist/lib/serde/__tests__/codec.test.js +75 -0
  40. package/dist/lib/serde/codec.d.ts +12 -0
  41. package/dist/lib/serde/codec.d.ts.map +1 -0
  42. package/dist/lib/serde/codec.js +54 -0
  43. package/dist/lib/serde/json.d.ts +8 -0
  44. package/dist/lib/serde/json.d.ts.map +1 -0
  45. package/dist/lib/serde/json.js +13 -0
  46. package/dist/lib/serde/thread.d.ts +1 -0
  47. package/dist/lib/serde/thread.d.ts.map +1 -0
  48. package/dist/lib/serde/thread.js +172 -0
  49. package/dist/lib/serde/tool.d.ts +36 -0
  50. package/dist/lib/serde/tool.d.ts.map +1 -0
  51. package/dist/lib/serde/tool.js +1 -0
  52. package/dist/lib/utils.d.ts +19 -0
  53. package/dist/lib/utils.d.ts.map +1 -0
  54. package/dist/lib/utils.js +41 -0
  55. package/dist/lifecycle.d.ts +133 -0
  56. package/dist/lifecycle.d.ts.map +1 -0
  57. package/dist/lifecycle.js +29 -0
  58. package/dist/logger.d.ts +36 -0
  59. package/dist/logger.d.ts.map +1 -0
  60. package/dist/logger.js +43 -0
  61. package/dist/mcp/__tests__/base.test.d.ts +2 -0
  62. package/dist/mcp/__tests__/base.test.d.ts.map +1 -0
  63. package/dist/mcp/__tests__/base.test.js +268 -0
  64. package/dist/mcp/__tests__/fixtures/echo-server.d.ts +3 -0
  65. package/dist/mcp/__tests__/fixtures/echo-server.d.ts.map +1 -0
  66. package/dist/mcp/__tests__/fixtures/echo-server.js +92 -0
  67. package/dist/mcp/__tests__/fixtures/math-server.d.ts +3 -0
  68. package/dist/mcp/__tests__/fixtures/math-server.d.ts.map +1 -0
  69. package/dist/mcp/__tests__/fixtures/math-server.js +98 -0
  70. package/dist/mcp/__tests__/fixtures/server.d.ts +3 -0
  71. package/dist/mcp/__tests__/fixtures/server.d.ts.map +1 -0
  72. package/dist/mcp/__tests__/fixtures/server.js +162 -0
  73. package/dist/mcp/__tests__/fixtures/test-server.d.ts +3 -0
  74. package/dist/mcp/__tests__/fixtures/test-server.d.ts.map +1 -0
  75. package/dist/mcp/__tests__/fixtures/test-server.js +163 -0
  76. package/dist/mcp/__tests__/fixtures/utils.d.ts +17 -0
  77. package/dist/mcp/__tests__/fixtures/utils.d.ts.map +1 -0
  78. package/dist/mcp/__tests__/fixtures/utils.js +42 -0
  79. package/dist/mcp/__tests__/integration.test.d.ts +2 -0
  80. package/dist/mcp/__tests__/integration.test.d.ts.map +1 -0
  81. package/dist/mcp/__tests__/integration.test.js +360 -0
  82. package/dist/mcp/__tests__/stdio.test.d.ts +2 -0
  83. package/dist/mcp/__tests__/stdio.test.d.ts.map +1 -0
  84. package/dist/mcp/__tests__/stdio.test.js +180 -0
  85. package/dist/mcp/__tests__/test-utils.d.ts +17 -0
  86. package/dist/mcp/__tests__/test-utils.d.ts.map +1 -0
  87. package/dist/mcp/__tests__/test-utils.js +42 -0
  88. package/dist/mcp/__tests__/utils.test.d.ts +2 -0
  89. package/dist/mcp/__tests__/utils.test.d.ts.map +1 -0
  90. package/dist/mcp/__tests__/utils.test.js +300 -0
  91. package/dist/mcp/base.d.ts +88 -0
  92. package/dist/mcp/base.d.ts.map +1 -0
  93. package/dist/mcp/base.js +68 -0
  94. package/dist/mcp/http.d.ts +34 -0
  95. package/dist/mcp/http.d.ts.map +1 -0
  96. package/dist/mcp/http.js +100 -0
  97. package/dist/mcp/node.d.ts +60 -0
  98. package/dist/mcp/node.d.ts.map +1 -0
  99. package/dist/mcp/node.js +297 -0
  100. package/dist/mcp/sse.d.ts +34 -0
  101. package/dist/mcp/sse.d.ts.map +1 -0
  102. package/dist/mcp/sse.js +97 -0
  103. package/dist/mcp/stdio.d.ts +32 -0
  104. package/dist/mcp/stdio.d.ts.map +1 -0
  105. package/dist/mcp/stdio.js +96 -0
  106. package/dist/mcp/types.d.ts +172 -0
  107. package/dist/mcp/types.d.ts.map +1 -0
  108. package/dist/mcp/types.js +16 -0
  109. package/dist/mcp/utils.d.ts +23 -0
  110. package/dist/mcp/utils.d.ts.map +1 -0
  111. package/dist/mcp/utils.js +44 -0
  112. package/dist/model.d.ts +175 -0
  113. package/dist/model.d.ts.map +1 -0
  114. package/dist/model.js +1 -0
  115. package/dist/providers/ai.d.ts +1 -0
  116. package/dist/providers/ai.d.ts.map +1 -0
  117. package/dist/providers/ai.js +1 -0
  118. package/dist/providers/default.d.ts +16 -0
  119. package/dist/providers/default.d.ts.map +1 -0
  120. package/dist/providers/default.js +17 -0
  121. package/dist/providers/registry.d.ts +1 -0
  122. package/dist/providers/registry.d.ts.map +1 -0
  123. package/dist/providers/registry.js +1 -0
  124. package/dist/sched/scheduler.d.ts +20 -0
  125. package/dist/sched/scheduler.d.ts.map +1 -0
  126. package/dist/sched/scheduler.js +1 -0
  127. package/dist/sched/task.d.ts +92 -0
  128. package/dist/sched/task.d.ts.map +1 -0
  129. package/dist/sched/task.js +102 -0
  130. package/dist/serde/__tests__/codec.test.d.ts +2 -0
  131. package/dist/serde/__tests__/codec.test.d.ts.map +1 -0
  132. package/dist/serde/__tests__/codec.test.js +75 -0
  133. package/dist/serde/codec.d.ts +12 -0
  134. package/dist/serde/codec.d.ts.map +1 -0
  135. package/dist/serde/codec.js +54 -0
  136. package/dist/serde/json.d.ts +8 -0
  137. package/dist/serde/json.d.ts.map +1 -0
  138. package/dist/serde/json.js +13 -0
  139. package/dist/serde/thread.d.ts +687 -0
  140. package/dist/serde/thread.d.ts.map +1 -0
  141. package/dist/serde/thread.js +158 -0
  142. package/dist/serde/tool.d.ts +36 -0
  143. package/dist/serde/tool.d.ts.map +1 -0
  144. package/dist/serde/tool.js +1 -0
  145. package/dist/session.d.ts +1 -0
  146. package/dist/session.d.ts.map +1 -0
  147. package/dist/session.js +1 -0
  148. package/dist/task.d.ts +87 -0
  149. package/dist/task.d.ts.map +1 -0
  150. package/dist/task.js +97 -0
  151. package/dist/thread/__tests__/mock.d.ts +28 -0
  152. package/dist/thread/__tests__/mock.d.ts.map +1 -0
  153. package/dist/thread/__tests__/mock.js +74 -0
  154. package/dist/thread/__tests__/thread.test.d.ts +2 -0
  155. package/dist/thread/__tests__/thread.test.d.ts.map +1 -0
  156. package/dist/thread/__tests__/thread.test.js +1412 -0
  157. package/dist/thread/index.d.ts +2 -0
  158. package/dist/thread/index.d.ts.map +1 -0
  159. package/dist/thread/index.js +1 -0
  160. package/dist/thread/thread.d.ts +66 -0
  161. package/dist/thread/thread.d.ts.map +1 -0
  162. package/dist/thread/thread.js +472 -0
  163. package/dist/thread/utils.d.ts +19 -0
  164. package/dist/thread/utils.d.ts.map +1 -0
  165. package/dist/thread/utils.js +50 -0
  166. package/dist/tool/__tests__/fixtures.d.ts +45 -0
  167. package/dist/tool/__tests__/fixtures.d.ts.map +1 -0
  168. package/dist/tool/__tests__/fixtures.js +97 -0
  169. package/dist/tool/__tests__/tool.test.d.ts +2 -0
  170. package/dist/tool/__tests__/tool.test.d.ts.map +1 -0
  171. package/dist/tool/__tests__/tool.test.js +172 -0
  172. package/dist/tool/__tests__/toolkit.test.d.ts +2 -0
  173. package/dist/tool/__tests__/toolkit.test.d.ts.map +1 -0
  174. package/dist/tool/__tests__/toolkit.test.js +134 -0
  175. package/dist/tool/index.d.ts +4 -0
  176. package/dist/tool/index.d.ts.map +1 -0
  177. package/dist/tool/index.js +2 -0
  178. package/dist/tool/mcp.d.ts +75 -0
  179. package/dist/tool/mcp.d.ts.map +1 -0
  180. package/dist/tool/mcp.js +111 -0
  181. package/dist/tool/tool.d.ts +95 -0
  182. package/dist/tool/tool.d.ts.map +1 -0
  183. package/dist/tool/tool.js +176 -0
  184. package/dist/tool/toolkit.d.ts +121 -0
  185. package/dist/tool/toolkit.d.ts.map +1 -0
  186. package/dist/tool/toolkit.js +180 -0
  187. package/dist/tool/types.d.ts +187 -0
  188. package/dist/tool/types.d.ts.map +1 -0
  189. package/dist/tool/types.js +1 -0
  190. package/dist/tools.d.ts +362 -0
  191. package/dist/tools.d.ts.map +1 -0
  192. package/dist/tools.js +220 -0
  193. package/dist/trace/processor.d.ts +1 -0
  194. package/dist/trace/processor.d.ts.map +1 -0
  195. package/dist/trace/processor.js +1 -0
  196. package/dist/trace/traces.d.ts +1 -0
  197. package/dist/trace/traces.d.ts.map +1 -0
  198. package/dist/trace/traces.js +73 -0
  199. package/dist/trace/utils.d.ts +22 -0
  200. package/dist/trace/utils.d.ts.map +1 -0
  201. package/dist/trace/utils.js +30 -0
  202. package/dist/types/agent.d.ts +91 -0
  203. package/dist/types/agent.d.ts.map +1 -0
  204. package/dist/types/agent.js +1 -0
  205. package/dist/types/proto.d.ts +1551 -0
  206. package/dist/types/proto.d.ts.map +1 -0
  207. package/dist/types/proto.js +531 -0
  208. package/dist/types/thread.d.ts +71 -0
  209. package/dist/types/thread.d.ts.map +1 -0
  210. package/dist/types/thread.js +5 -0
  211. package/dist/usage.d.ts +43 -0
  212. package/dist/usage.d.ts.map +1 -0
  213. package/dist/usage.js +61 -0
  214. package/package.json +52 -0
  215. package/src/agent.ts +203 -0
  216. package/src/context.ts +265 -0
  217. package/src/guardrail.ts +277 -0
  218. package/src/index.ts +3 -0
  219. package/src/kernl.ts +22 -0
  220. package/src/lib/env.ts +36 -0
  221. package/src/lib/error.ts +158 -0
  222. package/src/lib/logger.ts +78 -0
  223. package/src/lib/serde/json.ts +18 -0
  224. package/src/lib/serde/thread.ts +188 -0
  225. package/src/lifecycle.ts +181 -0
  226. package/src/mcp/__tests__/base.test.ts +344 -0
  227. package/src/mcp/__tests__/fixtures/server.ts +179 -0
  228. package/src/mcp/__tests__/fixtures/utils.ts +58 -0
  229. package/src/mcp/__tests__/integration.test.ts +447 -0
  230. package/src/mcp/__tests__/stdio.test.ts +236 -0
  231. package/src/mcp/__tests__/utils.test.ts +360 -0
  232. package/src/mcp/base.ts +162 -0
  233. package/src/mcp/http.ts +147 -0
  234. package/src/mcp/sse.ts +137 -0
  235. package/src/mcp/stdio.ts +136 -0
  236. package/src/mcp/types.ts +202 -0
  237. package/src/mcp/utils.ts +62 -0
  238. package/src/task.ts +119 -0
  239. package/src/thread/__tests__/mock.ts +95 -0
  240. package/src/thread/__tests__/thread.test.ts +1574 -0
  241. package/src/thread/index.ts +1 -0
  242. package/src/thread/thread.ts +611 -0
  243. package/src/thread/utils.ts +67 -0
  244. package/src/tool/__tests__/fixtures.ts +106 -0
  245. package/src/tool/__tests__/tool.test.ts +235 -0
  246. package/src/tool/__tests__/toolkit.test.ts +174 -0
  247. package/src/tool/index.ts +10 -0
  248. package/src/tool/tool.ts +264 -0
  249. package/src/tool/toolkit.ts +234 -0
  250. package/src/tool/types.ts +243 -0
  251. package/src/trace/processor.ts +0 -0
  252. package/src/trace/traces.ts +86 -0
  253. package/src/trace/utils.ts +38 -0
  254. package/src/types/agent.ts +145 -0
  255. package/src/types/thread.ts +86 -0
  256. package/tsconfig.json +13 -0
  257. package/vitest.config.ts +14 -0
@@ -0,0 +1,243 @@
1
+ import { z, type ZodType } from "zod";
2
+
3
+ import { Agent } from "@/agent";
4
+ import { Context, UnknownContext } from "@/context";
5
+ import { MCPServer } from "@/mcp/base";
6
+ import type { ToolCallState } from "@kernl/protocol";
7
+
8
+ import type { FunctionTool, HostedTool } from "./tool";
9
+
10
+ /**
11
+ * A tool that can be called by the model.
12
+ * @template TContext The context passed to the tool
13
+ */
14
+ export type Tool<TContext = UnknownContext> =
15
+ | FunctionTool<TContext, any, any>
16
+ | HostedTool;
17
+
18
+ /**
19
+ * Configuration options for creating a tool.
20
+ *
21
+ * @param TContext The context of the tool
22
+ * @param TParameters The parameters of the tool
23
+ * @param TResult The result type of the tool
24
+ */
25
+ export type ToolConfig<
26
+ TContext = UnknownContext,
27
+ TParameters extends ToolInputParameters = undefined,
28
+ TResult = unknown,
29
+ > = {
30
+ /**
31
+ * Unique identifier for the tool (required)
32
+ */
33
+ id: string;
34
+
35
+ /**
36
+ * Optional friendly name for the tool
37
+ */
38
+ name?: string;
39
+
40
+ /**
41
+ * The description of the tool that helps the model understand when to use it.
42
+ */
43
+ description: string;
44
+
45
+ /**
46
+ * A Zod object schema describing the tool parameters, or undefined for string input.
47
+ */
48
+ parameters: TParameters;
49
+
50
+ /**
51
+ * Execution mode - 'blocking' waits for completion, 'async' lets the agent continue to execute while executing.
52
+ * Defaults to 'blocking'.
53
+ */
54
+ mode?: "blocking" | "async";
55
+
56
+ /**
57
+ * The function to invoke when the tool is called.
58
+ */
59
+ execute: ToolExecuteFunction<TContext, TParameters, TResult>;
60
+
61
+ /**
62
+ * The function to invoke when an error occurs while running the tool.
63
+ */
64
+ errorfn?: ToolErrorFunction | null;
65
+
66
+ /**
67
+ * Whether the tool requires human approval before it can be called.
68
+ */
69
+ requiresApproval?: boolean | ToolApprovalFunction<TParameters>;
70
+
71
+ /**
72
+ * Determines whether the tool should be exposed to the model for the current run.
73
+ */
74
+ isEnabled?: ToolEnabledOption<TContext>;
75
+ };
76
+
77
+ /**
78
+ * Context provided to toolkit filters during tool resolution.
79
+ */
80
+ export interface ToolkitFilterContext<TContext = UnknownContext> {
81
+ context: Context<TContext>;
82
+ agent: Agent<TContext, any>;
83
+ toolkitId: string;
84
+ }
85
+
86
+ /**
87
+ * Toolkit-level filter for tools.
88
+ *
89
+ * Operates at the application layer on converted Tool objects.
90
+ * Use this for dynamic, context-aware filtering based on runtime state
91
+ * (e.g., user permissions, current workflow, etc.).
92
+ *
93
+ * This is the second filter in the pipeline (after MCPToolFilter for MCP tools).
94
+ *
95
+ * @example
96
+ * ```typescript
97
+ * const toolkit = new MCPToolkit({
98
+ * id: "github",
99
+ * server: githubServer,
100
+ * filter: async (ctx, tool) => {
101
+ * // Only allow read tools for non-admin users
102
+ * if (!ctx.context.data.isAdmin) {
103
+ * return tool.id.startsWith("read_");
104
+ * }
105
+ * return true;
106
+ * }
107
+ * });
108
+ * ```
109
+ */
110
+ export type ToolkitFilter<TContext = UnknownContext> = (
111
+ context: ToolkitFilterContext<TContext>,
112
+ tool: Tool<TContext>,
113
+ ) => Promise<boolean> | boolean;
114
+
115
+ /**
116
+ * Configuration for FunctionToolkit.
117
+ */
118
+ export interface FunctionToolkitConfig<TContext = UnknownContext> {
119
+ /**
120
+ * Unique identifier for this toolkit.
121
+ */
122
+ id: string;
123
+
124
+ /**
125
+ * Array of tools to include in this toolkit.
126
+ */
127
+ tools: Tool<TContext>[];
128
+ }
129
+
130
+ /**
131
+ * Configuration for MCPToolkit.
132
+ */
133
+ export interface MCPToolkitConfig<TContext = UnknownContext> {
134
+ /**
135
+ * Unique identifier for this toolkit.
136
+ */
137
+ id: string;
138
+
139
+ /**
140
+ * The MCP server instance to wrap.
141
+ */
142
+ server: MCPServer;
143
+
144
+ /**
145
+ * Toolkit-level filter to control which tools are exposed to the agent.
146
+ * Defaults to allowing all tools if not provided.
147
+ *
148
+ * This is applied after the server's toolFilter (if any). Use this for
149
+ * dynamic, context-aware filtering. Use server.toolFilter for static filtering.
150
+ */
151
+ filter?: ToolkitFilter<TContext>;
152
+ }
153
+
154
+ /**
155
+ * Type of tool
156
+ */
157
+ export type ToolType = "function" | "hosted-tool";
158
+
159
+ /**
160
+ * The result of invoking a function tool. Either the actual output of the execution or a tool
161
+ * approval request.
162
+ *
163
+ * These get passed for example to the `toolUseBehavior` option of the `Agent` constructor.
164
+ */
165
+ export type ToolResult<TResult = unknown> = {
166
+ state: ToolCallState;
167
+ /**
168
+ * The result of the tool call.
169
+ */
170
+ result: TResult | undefined;
171
+ /**
172
+ * Error message if state is "error"
173
+ */
174
+ error: string | null;
175
+ };
176
+
177
+ /**
178
+ * The parameters of a tool.
179
+ * Either undefined (tool takes string input) or a Zod schema.
180
+ */
181
+ export type ToolInputParameters = ZodType | undefined;
182
+
183
+ /**
184
+ * The arguments to a tool - inferred from the Zod schema or string.
185
+ */
186
+ export type ToolExecuteArgument<TParameters extends ToolInputParameters> =
187
+ TParameters extends ZodType ? z.infer<TParameters> : string;
188
+
189
+ /**
190
+ * The function to invoke when the tool is called.
191
+ *
192
+ * @param context An instance of the current RunContext
193
+ * @param params The arguments to the tool (see ToolExecuteArgument)
194
+ */
195
+ export type ToolExecuteFunction<
196
+ TContext = UnknownContext,
197
+ TParameters extends ToolInputParameters = undefined,
198
+ TResult = unknown,
199
+ > = (
200
+ context: Context<TContext>,
201
+ params: ToolExecuteArgument<TParameters>,
202
+ ) => Promise<TResult> | TResult;
203
+
204
+ /**
205
+ * A function that determines if a tool call should be approved.
206
+ *
207
+ * @param context The current execution context
208
+ * @param input The input to the tool
209
+ * @param callId The ID of the tool call
210
+ * @returns True if the tool call should be approved, false otherwise
211
+ */
212
+ export type ToolApprovalFunction<TParameters extends ToolInputParameters> = (
213
+ context: Context,
214
+ input: ToolExecuteArgument<TParameters>,
215
+ callId?: string,
216
+ ) => Promise<boolean>;
217
+
218
+ export type ToolEnabledFunction<TContext = UnknownContext> = (
219
+ context: Context<TContext>,
220
+ agent: Agent<any, any>, // (TODO): why would we need to take an agent here?
221
+ ) => Promise<boolean>;
222
+
223
+ export type ToolEnabledPredicate<TContext = UnknownContext> = (args: {
224
+ context: Context<TContext>;
225
+ agent: Agent<any, any>; // (TODO): why take an agent here? other options?
226
+ }) => boolean | Promise<boolean>;
227
+
228
+ type ToolEnabledOption<Context = UnknownContext> =
229
+ | boolean
230
+ | ToolEnabledPredicate<Context>;
231
+
232
+ /**
233
+ * The function to invoke when an error occurs while running the tool. This can be used to define
234
+ * what the model should receive as tool output in case of an error. It can be used to provide
235
+ * for example additional context or a fallback value.
236
+ *
237
+ * @param context An instance of the current RunContext
238
+ * @param error The error that occurred
239
+ */
240
+ export type ToolErrorFunction = (
241
+ context: Context,
242
+ error: Error | unknown,
243
+ ) => string;
File without changes
@@ -0,0 +1,86 @@
1
+ // import { defaultProcessor, TracingProcessor } from "./processor";
2
+ // import { generateTraceId } from "./utils";
3
+
4
+ // export type TraceOptions = {
5
+ // traceId?: string;
6
+ // name?: string;
7
+ // groupId?: string;
8
+ // metadata?: Record<string, any>;
9
+ // started?: boolean;
10
+ // };
11
+
12
+ // export class Trace {
13
+ // public type = "trace" as const;
14
+ // public traceId: string;
15
+ // public name: string;
16
+ // public groupId: string | null = null;
17
+ // public metadata?: Record<string, any>;
18
+
19
+ // #processor: TracingProcessor;
20
+ // #started: boolean;
21
+
22
+ // constructor(options: TraceOptions, processor?: TracingProcessor) {
23
+ // this.traceId = options.traceId ?? generateTraceId();
24
+ // this.name = options.name ?? "Agent workflow";
25
+ // this.groupId = options.groupId ?? null;
26
+ // this.metadata = options.metadata ?? {};
27
+ // this.#processor = processor ?? defaultProcessor();
28
+ // this.#started = options.started ?? false;
29
+ // }
30
+
31
+ // async start() {
32
+ // if (this.#started) {
33
+ // return;
34
+ // }
35
+
36
+ // this.#started = true;
37
+ // await this.#processor.onTraceStart(this);
38
+ // }
39
+
40
+ // async end() {
41
+ // if (!this.#started) {
42
+ // return;
43
+ // }
44
+
45
+ // this.#started = false;
46
+ // await this.#processor.onTraceEnd(this);
47
+ // }
48
+
49
+ // clone(): Trace {
50
+ // return new Trace({
51
+ // traceId: this.traceId,
52
+ // name: this.name,
53
+ // groupId: this.groupId ?? undefined,
54
+ // metadata: this.metadata,
55
+ // started: this.#started,
56
+ // });
57
+ // }
58
+
59
+ // toJSON(): object | null {
60
+ // return {
61
+ // object: this.type,
62
+ // id: this.traceId,
63
+ // workflow_name: this.name, // (TODO): why workflow?
64
+ // group_id: this.groupId,
65
+ // metadata: this.metadata,
66
+ // };
67
+ // }
68
+ // }
69
+
70
+ // export class NoopTrace extends Trace {
71
+ // constructor() {
72
+ // super({});
73
+ // }
74
+
75
+ // async start(): Promise<void> {
76
+ // return;
77
+ // }
78
+
79
+ // async end(): Promise<void> {
80
+ // return;
81
+ // }
82
+
83
+ // toJSON(): object | null {
84
+ // return null;
85
+ // }
86
+ // }
@@ -0,0 +1,38 @@
1
+ import { randomID } from "@kernl/shared/lib";
2
+
3
+ /**
4
+ * Generate a trace ID using 16 random bytes (128-bit, 32 hex chars).
5
+ * @returns A trace ID prefixed with `trace_`.
6
+ */
7
+ export function generateTraceId(): string {
8
+ return `trace_${randomID(16)}`;
9
+ }
10
+
11
+ /**
12
+ * Generate a span ID using 12 random bytes (96-bit, 24 hex chars).
13
+ * @returns A span ID prefixed with `span_`.
14
+ */
15
+ export function generateSpanId(): string {
16
+ return `span_${randomID(12)}`;
17
+ }
18
+
19
+ /**
20
+ * Generate a group ID using 12 random bytes (96-bit, 24 hex chars).
21
+ * @returns A group ID prefixed with `group_`.
22
+ */
23
+ export function generateGroupId(): string {
24
+ return `group_${randomID(12)}`;
25
+ }
26
+
27
+ /**
28
+ * Remove fields that start with an underscore from an object.
29
+ * @param obj - The object to remove private fields from.
30
+ * @returns A new object with private fields removed.
31
+ */
32
+ export function removePrivateFields(
33
+ obj: Record<string, any>,
34
+ ): Record<string, any> {
35
+ return Object.fromEntries(
36
+ Object.entries(obj).filter(([key]) => !key.startsWith("_")),
37
+ );
38
+ }
@@ -0,0 +1,145 @@
1
+ import { type ZodType } from "zod";
2
+
3
+ import { Context, UnknownContext } from "@/context";
4
+ import { LanguageModel, LanguageModelRequestSettings } from "@kernl/protocol";
5
+ import { InputGuardrail, OutputGuardrail } from "@/guardrail";
6
+ import { Toolkit } from "@/tool";
7
+
8
+ import { TextResponse } from "./thread";
9
+
10
+ /**
11
+ * Configuration for an agent.
12
+ */
13
+ export interface AgentConfig<
14
+ TContext = UnknownContext,
15
+ TResponse extends AgentResponseType = TextResponse,
16
+ > {
17
+ /* The unique identifier for the agent */
18
+ id: string;
19
+
20
+ /* The name of the agent (defaults to ID if not provided) */
21
+ name: string;
22
+
23
+ /**
24
+ * The instructions for the agent. Will be used as the "system prompt" when this agent is
25
+ * invoked. Describes what the agent should do, and how it responds.
26
+ *
27
+ * Can either be a string, or a function that dynamically generates instructions for the agent.
28
+ * If you provide a function, it will be called with the context and the agent instance. It
29
+ * must return a string.
30
+ */
31
+ instructions:
32
+ | string
33
+ | ((context: Context<TContext>) => Promise<string> | string);
34
+
35
+ // /**
36
+ // * A description of the agent. This is used when the agent is used as a handoff, so that an LLM
37
+ // * knows what it does and when to invoke it.
38
+ // */
39
+ // handoffDescription: string;
40
+
41
+ // /**
42
+ // * Handoffs are sub-agents that the agent can delegate to. You can provide a list of handoffs,
43
+ // * and the agent can choose to delegate to them if relevant. Allows for separation of concerns
44
+ // * and modularity.
45
+ // */
46
+ // handoffs: (Agent<any, any> | Handoff<any, TResponse>)[];
47
+
48
+ /**
49
+ * The model implementation to use when invoking the LLM.
50
+ *
51
+ * By default, if not set, the agent will use a default model that throws an error when called.
52
+ */
53
+ model?: LanguageModel;
54
+
55
+ /**
56
+ * Configures model-specific tuning parameters (e.g. temperature, top_p, etc.)
57
+ */
58
+ modelSettings?: LanguageModelRequestSettings;
59
+
60
+ /**
61
+ * A list of toolkits the agent can use. Toolkits are collections of related tools
62
+ * that can be static (FunctionToolkit) or dynamic (MCPToolkit).
63
+ *
64
+ * @example
65
+ * ```typescript
66
+ * const myTools = new FunctionToolkit({
67
+ * id: "custom",
68
+ * tools: [tool1, tool2]
69
+ * });
70
+ *
71
+ * const github = new MCPToolkit({
72
+ * id: "github",
73
+ * server: githubServer
74
+ * });
75
+ *
76
+ * const agent = new Agent({
77
+ * name: "Assistant",
78
+ * instructions: "...",
79
+ * toolkits: [myTools, github]
80
+ * });
81
+ * ```
82
+ */
83
+ toolkits?: Toolkit<TContext>[];
84
+
85
+ /**
86
+ * A list of checks that run in parallel to the agent's execution on the input + output for the agent,
87
+ * depending on the configuration.
88
+ */
89
+ guardrails?: AgentGuardrails<TResponse>;
90
+
91
+ /**
92
+ * The type of the response that the agent will return. If not provided, response will be a string.
93
+ */
94
+ responseType?: TResponse;
95
+
96
+ // /**
97
+ // * (TODO): Not sure if this is really necessary.. need to see use case examples
98
+ // *
99
+ // * This lets you configure how tool use is handled.
100
+ // * - `run_llm_again`: The default behavior. Tools are run, and then the LLM receives the results
101
+ // * and gets to respond.
102
+ // * - `stop_on_first_tool`: The output of the first tool call is used as the final output. This means
103
+ // * that the LLM does not process the result of the tool call.
104
+ // * - A list of tool names: The agent will stop running if any of the tools in the list are called.
105
+ // * The final output will be the output of the first matching tool call. The LLM does not process
106
+ // * the result of the tool call.
107
+ // * - A function: if you pass a function, it will be called with the run context and the list of
108
+ // * tool results. It must return a `ToolsToFinalOutputResult`, which determines whether the tool
109
+ // * call resulted in a final output.
110
+ // *
111
+ // * NOTE: This configuration is specific to `FunctionTools`. Hosted tools, such as file search, web
112
+ // * search, etc. are always processed by the LLM
113
+ // */
114
+ // toolUseBehavior: ToolUseBehavior;
115
+
116
+ /**
117
+ * Whether to reset the tool choice to the default value after a tool has been called. Defaults
118
+ * to `true`. This ensures that the agent doesn't enter an infinite loop of tool usage.
119
+ */
120
+ resetToolChoice?: boolean;
121
+ }
122
+
123
+ /**
124
+ * Guardrails for an agent.
125
+ */
126
+ export interface AgentGuardrails<
127
+ TResponse extends AgentResponseType = TextResponse,
128
+ > {
129
+ /**
130
+ * A list of checks that run in parallel to the agent's execution, before generating a response.
131
+ * Runs only if the agent is the first agent in the chain.
132
+ */
133
+ input: InputGuardrail[];
134
+ /**
135
+ * A list of checks that run on the final output of the agent, after generating a response. Runs
136
+ * only if the agent produces a final output.
137
+ */
138
+ output: OutputGuardrail<TResponse>[];
139
+ }
140
+
141
+ /**
142
+ * The type of the output object. If not provided, the output will be a string.
143
+ * 'text' is a special type that indicates the output will be a string.
144
+ */
145
+ export type AgentResponseType = TextResponse | ZodType;
@@ -0,0 +1,86 @@
1
+ import {
2
+ ToolCall,
3
+ LanguageModel,
4
+ LanguageModelItem,
5
+ LanguageModelStreamEvent,
6
+ } from "@kernl/protocol";
7
+
8
+ import { Task } from "@/task";
9
+ import { Context } from "@/context";
10
+
11
+ /**
12
+ * Thread-specific tool call state for approval workflow.
13
+ * This extends the protocol states for internal thread use.
14
+ */
15
+ export const REQUIRES_APPROVAL = "requires_approval";
16
+
17
+ /**
18
+ * ThreadEvent uses protocol types directly.
19
+ *
20
+ * (TODO): just an alias for LanguageModelItem for now, but there may be other thread events later
21
+ * which don't go to the model.
22
+ */
23
+ export type ThreadEvent = LanguageModelItem;
24
+
25
+ /**
26
+ * Stream events - use protocol definition directly.
27
+ */
28
+ export type ThreadStreamEvent = LanguageModelStreamEvent;
29
+
30
+ /**
31
+ * Set of actionable items extracted from a model response
32
+ */
33
+ export interface ActionSet {
34
+ toolCalls: ToolCall[];
35
+ // Future: other actions, mcpRequests, etc.
36
+ }
37
+
38
+ /**
39
+ * Result of a single tick of execution
40
+ */
41
+ export interface TickResult {
42
+ /**
43
+ * Events to add to thread history
44
+ */
45
+ events: ThreadEvent[];
46
+ /**
47
+ * Action intentions that need to be performed as a result of this tick
48
+ */
49
+ intentions: ActionSet | null;
50
+ }
51
+
52
+ /**
53
+ * Result of performing actions, including both executed results and pending approvals
54
+ */
55
+ export interface PerformActionsResult {
56
+ /**
57
+ * Action events generated from executing tools (tool results)
58
+ */
59
+ actions: ThreadEvent[];
60
+ /**
61
+ * Tool calls that require approval before execution
62
+ */
63
+ pendingApprovals: ToolCall[];
64
+ }
65
+
66
+ /**
67
+ * Result of thread execution
68
+ */
69
+ export interface ThreadExecuteResult<TResponse = any> {
70
+ /**
71
+ * The final parsed response from the agent
72
+ */
73
+ response: TResponse;
74
+ /**
75
+ * The thread state at completion
76
+ */
77
+ state: any; // Will be ThreadState, but avoiding circular dependency
78
+ }
79
+
80
+ export interface ThreadOptions<TContext> {
81
+ context: Context<TContext>;
82
+ task?: Task<TContext>;
83
+ model?: LanguageModel;
84
+ }
85
+
86
+ export type TextResponse = "text";
package/tsconfig.json ADDED
@@ -0,0 +1,13 @@
1
+ {
2
+ "extends": "../../tsconfig.base.json",
3
+ "compilerOptions": {
4
+ "outDir": "./dist",
5
+ "rootDir": "./src",
6
+ "baseUrl": ".",
7
+ "paths": {
8
+ "@/*": ["./src/*"]
9
+ }
10
+ },
11
+ "include": ["src/**/*"],
12
+ "exclude": ["node_modules", "dist"]
13
+ }
@@ -0,0 +1,14 @@
1
+ import { defineConfig } from "vitest/config";
2
+ import path from "path";
3
+
4
+ export default defineConfig({
5
+ test: {
6
+ globals: true,
7
+ environment: "node",
8
+ },
9
+ resolve: {
10
+ alias: {
11
+ "@": path.resolve(__dirname, "./src"),
12
+ },
13
+ },
14
+ });