kernl 0.2.0 → 0.6.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 (267) hide show
  1. package/.turbo/turbo-build.log +4 -5
  2. package/.turbo/turbo-check-types.log +4 -0
  3. package/CHANGELOG.md +147 -0
  4. package/LICENSE +1 -1
  5. package/dist/agent/__tests__/concurrency.test.d.ts +2 -0
  6. package/dist/agent/__tests__/concurrency.test.d.ts.map +1 -0
  7. package/dist/agent/__tests__/concurrency.test.js +152 -0
  8. package/dist/agent/__tests__/run.test.d.ts +2 -0
  9. package/dist/agent/__tests__/run.test.d.ts.map +1 -0
  10. package/dist/agent/__tests__/run.test.js +357 -0
  11. package/dist/agent/index.d.ts +1 -0
  12. package/dist/agent/index.d.ts.map +1 -0
  13. package/dist/agent.d.ts +32 -9
  14. package/dist/agent.d.ts.map +1 -1
  15. package/dist/agent.js +102 -14
  16. package/dist/api/__tests__/cursor-page.test.d.ts +2 -0
  17. package/dist/api/__tests__/cursor-page.test.d.ts.map +1 -0
  18. package/dist/api/__tests__/cursor-page.test.js +414 -0
  19. package/dist/api/__tests__/offset-page.test.d.ts +2 -0
  20. package/dist/api/__tests__/offset-page.test.d.ts.map +1 -0
  21. package/dist/api/__tests__/offset-page.test.js +510 -0
  22. package/dist/api/__tests__/threads.test.d.ts +2 -0
  23. package/dist/api/__tests__/threads.test.d.ts.map +1 -0
  24. package/dist/api/__tests__/threads.test.js +338 -0
  25. package/dist/api/models/index.d.ts +2 -0
  26. package/dist/api/models/index.d.ts.map +1 -0
  27. package/dist/api/models/thread.d.ts +120 -0
  28. package/dist/api/models/thread.d.ts.map +1 -0
  29. package/dist/api/pagination/base.d.ts +48 -0
  30. package/dist/api/pagination/base.d.ts.map +1 -0
  31. package/dist/api/pagination/base.js +45 -0
  32. package/dist/api/pagination/cursor.d.ts +44 -0
  33. package/dist/api/pagination/cursor.d.ts.map +1 -0
  34. package/dist/api/pagination/cursor.js +52 -0
  35. package/dist/api/pagination/offset.d.ts +42 -0
  36. package/dist/api/pagination/offset.d.ts.map +1 -0
  37. package/dist/api/pagination/offset.js +55 -0
  38. package/dist/api/resources/threads/events.d.ts +21 -0
  39. package/dist/api/resources/threads/events.d.ts.map +1 -0
  40. package/dist/api/resources/threads/events.js +24 -0
  41. package/dist/api/resources/threads/index.d.ts +4 -0
  42. package/dist/api/resources/threads/index.d.ts.map +1 -0
  43. package/dist/api/resources/threads/index.js +2 -0
  44. package/dist/api/resources/threads/threads.d.ts +57 -0
  45. package/dist/api/resources/threads/threads.d.ts.map +1 -0
  46. package/dist/api/resources/threads/threads.js +199 -0
  47. package/dist/api/resources/threads/types.d.ts +123 -0
  48. package/dist/api/resources/threads/types.d.ts.map +1 -0
  49. package/dist/api/resources/threads/utils.d.ts +18 -0
  50. package/dist/api/resources/threads/utils.d.ts.map +1 -0
  51. package/dist/api/resources/threads/utils.js +78 -0
  52. package/dist/context.d.ts +5 -1
  53. package/dist/context.d.ts.map +1 -1
  54. package/dist/context.js +6 -1
  55. package/dist/index.d.ts +9 -1
  56. package/dist/index.d.ts.map +1 -1
  57. package/dist/index.js +7 -0
  58. package/dist/internal.d.ts +4 -0
  59. package/dist/internal.d.ts.map +1 -0
  60. package/dist/internal.js +2 -0
  61. package/dist/kernl/index.d.ts +3 -0
  62. package/dist/kernl/index.d.ts.map +1 -0
  63. package/dist/kernl/index.js +2 -0
  64. package/dist/kernl/kernl.d.ts +64 -0
  65. package/dist/kernl/kernl.d.ts.map +1 -0
  66. package/dist/kernl/kernl.js +116 -0
  67. package/dist/kernl/threads.d.ts +110 -0
  68. package/dist/kernl/threads.d.ts.map +1 -0
  69. package/dist/kernl/threads.js +126 -0
  70. package/dist/kernl.d.ts +22 -6
  71. package/dist/kernl.d.ts.map +1 -1
  72. package/dist/kernl.js +73 -10
  73. package/dist/lib/env.d.ts +3 -3
  74. package/dist/lib/env.js +1 -1
  75. package/dist/mcp/__tests__/integration.test.js +8 -8
  76. package/dist/mcp/__tests__/utils.test.js +6 -6
  77. package/dist/mcp/http.d.ts +1 -1
  78. package/dist/mcp/http.d.ts.map +1 -1
  79. package/dist/mcp/http.js +9 -9
  80. package/dist/mcp/sse.d.ts +1 -1
  81. package/dist/mcp/sse.d.ts.map +1 -1
  82. package/dist/mcp/sse.js +7 -7
  83. package/dist/mcp/utils.d.ts +1 -1
  84. package/dist/mcp/utils.d.ts.map +1 -1
  85. package/dist/mcp/utils.js +4 -5
  86. package/dist/storage/__tests__/in-memory.test.d.ts +2 -0
  87. package/dist/storage/__tests__/in-memory.test.d.ts.map +1 -0
  88. package/dist/storage/__tests__/in-memory.test.js +455 -0
  89. package/dist/storage/base.d.ts +64 -0
  90. package/dist/storage/base.d.ts.map +1 -0
  91. package/dist/storage/base.js +4 -0
  92. package/dist/storage/in-memory.d.ts +62 -0
  93. package/dist/storage/in-memory.d.ts.map +1 -0
  94. package/dist/storage/in-memory.js +283 -0
  95. package/dist/storage/index.d.ts +10 -0
  96. package/dist/storage/index.d.ts.map +1 -0
  97. package/dist/storage/index.js +7 -0
  98. package/dist/storage/thread.d.ts +123 -0
  99. package/dist/storage/thread.d.ts.map +1 -0
  100. package/dist/storage/thread.js +4 -0
  101. package/dist/task.d.ts +5 -3
  102. package/dist/task.d.ts.map +1 -1
  103. package/dist/task.js +10 -8
  104. package/dist/thread/__tests__/fixtures/mock-model.d.ts +1 -2
  105. package/dist/thread/__tests__/fixtures/mock-model.d.ts.map +1 -1
  106. package/dist/thread/__tests__/integration.test.js +73 -5
  107. package/dist/thread/__tests__/namespace.test.d.ts +2 -0
  108. package/dist/thread/__tests__/namespace.test.d.ts.map +1 -0
  109. package/dist/thread/__tests__/namespace.test.js +131 -0
  110. package/dist/thread/__tests__/thread-persistence.test.d.ts +2 -0
  111. package/dist/thread/__tests__/thread-persistence.test.d.ts.map +1 -0
  112. package/dist/thread/__tests__/thread-persistence.test.js +351 -0
  113. package/dist/thread/__tests__/thread.test.js +49 -51
  114. package/dist/thread/thread.d.ts +70 -18
  115. package/dist/thread/thread.d.ts.map +1 -1
  116. package/dist/thread/thread.js +211 -73
  117. package/dist/thread/utils.d.ts +36 -8
  118. package/dist/thread/utils.d.ts.map +1 -1
  119. package/dist/thread/utils.js +52 -8
  120. package/dist/tool/__tests__/fixtures.js +1 -1
  121. package/dist/tool/__tests__/toolkit.test.js +15 -12
  122. package/dist/tool/tool.js +3 -3
  123. package/dist/types/kernl.d.ts +42 -0
  124. package/dist/types/kernl.d.ts.map +1 -0
  125. package/dist/types/thread.d.ts +108 -22
  126. package/dist/types/thread.d.ts.map +1 -1
  127. package/dist/types/thread.js +12 -0
  128. package/package.json +11 -7
  129. package/src/agent/__tests__/concurrency.test.ts +194 -0
  130. package/src/agent/__tests__/run.test.ts +441 -0
  131. package/src/agent/index.ts +0 -0
  132. package/src/agent.ts +141 -24
  133. package/src/api/__tests__/cursor-page.test.ts +512 -0
  134. package/src/api/__tests__/offset-page.test.ts +624 -0
  135. package/src/api/__tests__/threads.test.ts +415 -0
  136. package/src/api/models/index.ts +6 -0
  137. package/src/api/models/thread.ts +138 -0
  138. package/src/api/pagination/base.ts +79 -0
  139. package/src/api/pagination/cursor.ts +86 -0
  140. package/src/api/pagination/offset.ts +89 -0
  141. package/src/api/resources/threads/events.ts +26 -0
  142. package/src/api/resources/threads/index.ts +9 -0
  143. package/src/api/resources/threads/threads.ts +256 -0
  144. package/src/api/resources/threads/types.ts +143 -0
  145. package/src/api/resources/threads/utils.ts +104 -0
  146. package/src/context.ts +10 -1
  147. package/src/index.ts +49 -1
  148. package/src/internal.ts +15 -0
  149. package/src/kernl.ts +86 -17
  150. package/src/mcp/__tests__/integration.test.ts +8 -9
  151. package/src/mcp/__tests__/utils.test.ts +6 -6
  152. package/src/mcp/http.ts +9 -9
  153. package/src/mcp/sse.ts +7 -7
  154. package/src/mcp/utils.ts +6 -5
  155. package/src/storage/__tests__/in-memory.test.ts +534 -0
  156. package/src/storage/base.ts +77 -0
  157. package/src/storage/in-memory.ts +372 -0
  158. package/src/storage/index.ts +21 -0
  159. package/src/storage/thread.ts +141 -0
  160. package/src/task.ts +12 -10
  161. package/src/thread/__tests__/fixtures/mock-model.ts +2 -4
  162. package/src/thread/__tests__/integration.test.ts +111 -10
  163. package/src/thread/__tests__/namespace.test.ts +158 -0
  164. package/src/thread/__tests__/thread-persistence.test.ts +367 -0
  165. package/src/thread/__tests__/thread.test.ts +52 -54
  166. package/src/thread/thread.ts +247 -96
  167. package/src/thread/utils.ts +76 -13
  168. package/src/tool/__tests__/fixtures.ts +1 -1
  169. package/src/tool/__tests__/toolkit.test.ts +15 -12
  170. package/src/tool/tool.ts +3 -3
  171. package/src/types/kernl.ts +51 -0
  172. package/src/types/thread.ts +139 -25
  173. package/vitest.config.ts +1 -0
  174. package/dist/env.d.ts +0 -45
  175. package/dist/env.d.ts.map +0 -1
  176. package/dist/env.js +0 -31
  177. package/dist/error.d.ts +0 -1
  178. package/dist/error.d.ts.map +0 -1
  179. package/dist/kernel.d.ts +0 -7
  180. package/dist/kernel.d.ts.map +0 -1
  181. package/dist/kernel.js +0 -7
  182. package/dist/lib/serde/__tests__/codec.test.d.ts +0 -2
  183. package/dist/lib/serde/__tests__/codec.test.d.ts.map +0 -1
  184. package/dist/lib/serde/__tests__/codec.test.js +0 -75
  185. package/dist/lib/serde/codec.d.ts +0 -12
  186. package/dist/lib/serde/codec.d.ts.map +0 -1
  187. package/dist/lib/serde/codec.js +0 -54
  188. package/dist/lib/serde/thread.d.ts +0 -1
  189. package/dist/lib/serde/thread.d.ts.map +0 -1
  190. package/dist/lib/serde/thread.js +0 -172
  191. package/dist/lib/serde/tool.d.ts +0 -36
  192. package/dist/lib/serde/tool.d.ts.map +0 -1
  193. package/dist/lib/utils.d.ts +0 -19
  194. package/dist/lib/utils.d.ts.map +0 -1
  195. package/dist/lib/utils.js +0 -41
  196. package/dist/logger.d.ts +0 -36
  197. package/dist/logger.d.ts.map +0 -1
  198. package/dist/logger.js +0 -43
  199. package/dist/mcp/__tests__/fixtures/echo-server.d.ts +0 -3
  200. package/dist/mcp/__tests__/fixtures/echo-server.d.ts.map +0 -1
  201. package/dist/mcp/__tests__/fixtures/echo-server.js +0 -92
  202. package/dist/mcp/__tests__/fixtures/math-server.d.ts +0 -3
  203. package/dist/mcp/__tests__/fixtures/math-server.d.ts.map +0 -1
  204. package/dist/mcp/__tests__/fixtures/math-server.js +0 -98
  205. package/dist/mcp/__tests__/fixtures/test-server.d.ts +0 -3
  206. package/dist/mcp/__tests__/fixtures/test-server.d.ts.map +0 -1
  207. package/dist/mcp/__tests__/fixtures/test-server.js +0 -163
  208. package/dist/mcp/__tests__/test-utils.d.ts +0 -17
  209. package/dist/mcp/__tests__/test-utils.d.ts.map +0 -1
  210. package/dist/mcp/__tests__/test-utils.js +0 -42
  211. package/dist/mcp/node.d.ts +0 -60
  212. package/dist/mcp/node.d.ts.map +0 -1
  213. package/dist/mcp/node.js +0 -297
  214. package/dist/model.d.ts +0 -175
  215. package/dist/model.d.ts.map +0 -1
  216. package/dist/providers/ai.d.ts +0 -1
  217. package/dist/providers/ai.d.ts.map +0 -1
  218. package/dist/providers/ai.js +0 -1
  219. package/dist/providers/default.d.ts +0 -16
  220. package/dist/providers/default.d.ts.map +0 -1
  221. package/dist/providers/default.js +0 -17
  222. package/dist/providers/registry.d.ts +0 -1
  223. package/dist/providers/registry.d.ts.map +0 -1
  224. package/dist/providers/registry.js +0 -1
  225. package/dist/sched/scheduler.d.ts +0 -20
  226. package/dist/sched/scheduler.d.ts.map +0 -1
  227. package/dist/sched/task.d.ts +0 -92
  228. package/dist/sched/task.d.ts.map +0 -1
  229. package/dist/sched/task.js +0 -102
  230. package/dist/serde/__tests__/codec.test.d.ts +0 -2
  231. package/dist/serde/__tests__/codec.test.d.ts.map +0 -1
  232. package/dist/serde/__tests__/codec.test.js +0 -75
  233. package/dist/serde/codec.d.ts +0 -12
  234. package/dist/serde/codec.d.ts.map +0 -1
  235. package/dist/serde/codec.js +0 -54
  236. package/dist/serde/json.d.ts +0 -8
  237. package/dist/serde/json.d.ts.map +0 -1
  238. package/dist/serde/json.js +0 -13
  239. package/dist/serde/thread.d.ts +0 -687
  240. package/dist/serde/thread.d.ts.map +0 -1
  241. package/dist/serde/thread.js +0 -158
  242. package/dist/serde/tool.d.ts +0 -36
  243. package/dist/serde/tool.d.ts.map +0 -1
  244. package/dist/session.d.ts +0 -1
  245. package/dist/session.d.ts.map +0 -1
  246. package/dist/session.js +0 -1
  247. package/dist/thread/__tests__/stream.test.d.ts +0 -2
  248. package/dist/thread/__tests__/stream.test.d.ts.map +0 -1
  249. package/dist/thread/__tests__/stream.test.js +0 -244
  250. package/dist/tool/mcp.d.ts +0 -75
  251. package/dist/tool/mcp.d.ts.map +0 -1
  252. package/dist/tool/mcp.js +0 -111
  253. package/dist/tools.d.ts +0 -362
  254. package/dist/tools.d.ts.map +0 -1
  255. package/dist/tools.js +0 -220
  256. package/dist/types/proto.d.ts +0 -1551
  257. package/dist/types/proto.d.ts.map +0 -1
  258. package/dist/types/proto.js +0 -531
  259. package/dist/usage.d.ts +0 -43
  260. package/dist/usage.d.ts.map +0 -1
  261. package/dist/usage.js +0 -61
  262. package/src/lib/serde/thread.ts +0 -188
  263. /package/dist/{error.js → agent/index.js} +0 -0
  264. /package/dist/{lib/serde/tool.js → api/models/index.js} +0 -0
  265. /package/dist/{model.js → api/models/thread.js} +0 -0
  266. /package/dist/{sched/scheduler.js → api/resources/threads/types.js} +0 -0
  267. /package/dist/{serde/tool.js → types/kernl.js} +0 -0
@@ -0,0 +1,42 @@
1
+ import { LanguageModel } from "@kernl-sdk/protocol";
2
+ import { Agent } from "../agent";
3
+ import { KernlStorage } from "../storage";
4
+ /**
5
+ * Storage configuration for Kernl.
6
+ */
7
+ export interface StorageOptions {
8
+ /**
9
+ * Relational database storage (threads, tasks, traces).
10
+ */
11
+ db?: KernlStorage;
12
+ }
13
+ /**
14
+ * Configuration options for creating a Kernl instance.
15
+ */
16
+ export interface KernlOptions {
17
+ /**
18
+ * Storage configuration for persisting threads, tasks, and traces.
19
+ */
20
+ storage?: StorageOptions;
21
+ }
22
+ /**
23
+ * Agent registry interface.
24
+ *
25
+ * Satisfied by Map<string, Agent>.
26
+ */
27
+ export interface AgentRegistry {
28
+ get(id: string): Agent<any> | undefined;
29
+ }
30
+ /**
31
+ * Model registry interface.
32
+ *
33
+ * Satisfied by Map<string, LanguageModel>.
34
+ * Key format: "provider/modelId"
35
+ *
36
+ * TODO: Create an exhaustive model registry in the protocol package
37
+ * with all supported models and their metadata.
38
+ */
39
+ export interface ModelRegistry {
40
+ get(key: string): LanguageModel | undefined;
41
+ }
42
+ //# sourceMappingURL=kernl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kernl.d.ts","sourceRoot":"","sources":["../../src/types/kernl.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAEzC;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B;;OAEG;IACH,EAAE,CAAC,EAAE,YAAY,CAAC;CAMnB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B;;OAEG;IACH,OAAO,CAAC,EAAE,cAAc,CAAC;CAC1B;AAED;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC;CACzC;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,aAAa;IAC5B,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAAC;CAC7C"}
@@ -1,7 +1,18 @@
1
1
  import { ToolCall, LanguageModel, LanguageModelItem, LanguageModelStreamEvent, RUNNING, STOPPED, INTERRUPTIBLE, UNINTERRUPTIBLE, ZOMBIE, DEAD } from "@kernl-sdk/protocol";
2
2
  import { Task } from "../task";
3
3
  import { Context } from "../context";
4
+ import { Agent } from "../agent";
5
+ import type { AgentResponseType } from "./agent";
6
+ import type { ThreadStore } from "../storage";
7
+ /**
8
+ * Public/client-facing thread events (excludes internal system events).
9
+ */
10
+ export type PublicThreadEvent = LanguageModelItem & ThreadEventBase;
4
11
  export type TextResponse = "text";
12
+ /**
13
+ * Thread state values as a const array (for zod schemas).
14
+ */
15
+ export declare const THREAD_STATES: readonly ["running", "stopped", "interruptible", "uninterruptible", "zombie", "dead"];
5
16
  /**
6
17
  * Thread state discriminated union
7
18
  */
@@ -12,39 +23,66 @@ export type ThreadState = typeof RUNNING | typeof STOPPED | typeof INTERRUPTIBLE
12
23
  */
13
24
  export declare const REQUIRES_APPROVAL = "requires_approval";
14
25
  /**
15
- * ThreadEvent uses protocol types directly.
26
+ * Thread domain interface.
16
27
  *
17
- * (TODO): just an alias for LanguageModelItem for now, but there may be other thread events later
18
- * which don't go to the model.
28
+ * Represents the complete state of a Thread that can be stored and restored.
19
29
  */
20
- export type ThreadEvent = LanguageModelItem;
30
+ export interface IThread<TContext = unknown, TResponse extends AgentResponseType = "text"> {
31
+ tid: string;
32
+ agent: Agent<TContext, TResponse>;
33
+ model: LanguageModel;
34
+ context: Context<TContext>;
35
+ input: LanguageModelItem[];
36
+ history: ThreadEvent[];
37
+ task: Task<TContext> | null;
38
+ tick: number;
39
+ state: ThreadState;
40
+ namespace: string;
41
+ createdAt: Date;
42
+ updatedAt: Date;
43
+ metadata: Record<string, unknown> | null;
44
+ }
45
+ export interface CheckpointDelta {
46
+ state?: ThreadState;
47
+ tick?: number;
48
+ seq?: number;
49
+ events?: ThreadEvent[];
50
+ }
21
51
  /**
22
- * Stream events - use protocol definition directly.
52
+ * The inner data of a ThreadEvent without the headers
23
53
  */
24
- export type ThreadStreamEvent = LanguageModelStreamEvent;
54
+ export type ThreadEventInner = LanguageModelItem;
25
55
  /**
26
- * Set of actionable items extracted from a model response
56
+ * Base fields for all thread events - added to every LanguageModelItem when stored in thread.
27
57
  */
28
- export interface ActionSet {
29
- toolCalls: ToolCall[];
58
+ export interface ThreadEventBase {
59
+ id: string;
60
+ tid: string;
61
+ seq: number;
62
+ timestamp: Date;
63
+ metadata: Record<string, unknown>;
30
64
  }
31
65
  /**
32
- * Result of performing actions, including both executed results and pending approvals
66
+ * System event - runtime state changes (not sent to model).
33
67
  */
34
- export interface PerformActionsResult {
35
- /**
36
- * Action events generated from executing tools (tool results)
37
- */
38
- actions: ThreadEvent[];
39
- /**
40
- * Tool calls that require approval before execution
41
- */
42
- pendingApprovals: ToolCall[];
68
+ export interface ThreadSystemEvent extends ThreadEventBase {
69
+ readonly kind: "system";
43
70
  }
71
+ /**
72
+ * Thread events are append-only log entries ordered by seq.
73
+ *
74
+ * Events extend LanguageModelItem types with thread-specific metadata (tid, seq, timestamp).
75
+ * When sent to the model, we extract the LanguageModelItem by omitting the base fields.
76
+ */
77
+ export type ThreadEvent = (LanguageModelItem & ThreadEventBase) | ThreadSystemEvent;
78
+ /**
79
+ * Stream events - use protocol definition directly.
80
+ */
81
+ export type ThreadStreamEvent = LanguageModelStreamEvent;
44
82
  /**
45
83
  * Result of thread execution
46
84
  */
47
- export interface ThreadExecuteResult<TResponse = any> {
85
+ export interface ThreadExecuteResult<TResponse = unknown> {
48
86
  /**
49
87
  * The final parsed response from the agent
50
88
  */
@@ -54,12 +92,60 @@ export interface ThreadExecuteResult<TResponse = any> {
54
92
  */
55
93
  state: any;
56
94
  }
57
- export interface ThreadOptions<TContext> {
58
- context: Context<TContext>;
95
+ /**
96
+ * Options for constructing a Thread.
97
+ */
98
+ export interface ThreadOptions<TContext = unknown, TResponse extends AgentResponseType = "text"> {
99
+ agent: Agent<TContext, TResponse>;
100
+ input?: LanguageModelItem[];
101
+ history?: ThreadEvent[];
102
+ context?: Context<TContext>;
103
+ model?: LanguageModel;
104
+ task?: Task<TContext> | null;
105
+ namespace?: string;
106
+ tid?: string;
107
+ tick?: number;
108
+ state?: ThreadState;
109
+ storage?: ThreadStore;
110
+ createdAt?: Date;
111
+ updatedAt?: Date;
112
+ metadata?: Record<string, unknown> | null;
113
+ /**
114
+ * Internal flag indicating whether this thread already has a persisted
115
+ * row in storage. Storage implementations MUST set this to true when
116
+ * hydrating from a store. Callers creating new threads should omit it.
117
+ */
118
+ persisted?: boolean;
119
+ }
120
+ /**
121
+ * Options passed to agent.execute() and agent.stream().
122
+ */
123
+ export interface ThreadExecuteOptions<TContext> {
124
+ context?: Context<TContext>;
59
125
  model?: LanguageModel;
60
126
  task?: Task<TContext>;
61
127
  threadId?: string;
128
+ namespace?: string;
62
129
  maxTicks?: number;
63
130
  abort?: AbortSignal;
64
131
  }
132
+ /**
133
+ * Set of actionable items extracted from a model response
134
+ */
135
+ export interface ActionSet {
136
+ toolCalls: ToolCall[];
137
+ }
138
+ /**
139
+ * Result of performing actions, including both executed results and pending approvals
140
+ */
141
+ export interface PerformActionsResult {
142
+ /**
143
+ * Action events generated from executing tools (tool results)
144
+ */
145
+ actions: ThreadEventInner[];
146
+ /**
147
+ * Tool calls that require approval before execution
148
+ */
149
+ pendingApprovals: ToolCall[];
150
+ }
65
151
  //# sourceMappingURL=thread.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"thread.d.ts","sourceRoot":"","sources":["../../src/types/thread.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EACR,aAAa,EACb,iBAAiB,EACjB,wBAAwB,EACxB,OAAO,EACP,OAAO,EACP,aAAa,EACb,eAAe,EACf,MAAM,EACN,IAAI,EACL,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC;AAElC;;GAEG;AACH,MAAM,MAAM,WAAW,GACnB,OAAO,OAAO,GACd,OAAO,OAAO,GACd,OAAO,aAAa,GACpB,OAAO,eAAe,GACtB,OAAO,MAAM,GACb,OAAO,IAAI,CAAC;AAEhB;;;GAGG;AACH,eAAO,MAAM,iBAAiB,sBAAsB,CAAC;AAErD;;;;;GAKG;AACH,MAAM,MAAM,WAAW,GAAG,iBAAiB,CAAC;AAE5C;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG,wBAAwB,CAAC;AAEzD;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,SAAS,EAAE,QAAQ,EAAE,CAAC;CAEvB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC;;OAEG;IACH,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB;;OAEG;IACH,gBAAgB,EAAE,QAAQ,EAAE,CAAC;CAC9B;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB,CAAC,SAAS,GAAG,GAAG;IAClD;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;IACpB;;OAEG;IACH,KAAK,EAAE,GAAG,CAAC;CACZ;AAED,MAAM,WAAW,aAAa,CAAC,QAAQ;IACrC,OAAO,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC3B,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,IAAI,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,WAAW,CAAC;CAGrB"}
1
+ {"version":3,"file":"thread.d.ts","sourceRoot":"","sources":["../../src/types/thread.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,15 @@
1
+ import { RUNNING, STOPPED, INTERRUPTIBLE, UNINTERRUPTIBLE, ZOMBIE, DEAD, } from "@kernl-sdk/protocol";
2
+ /**
3
+ * Thread state values as a const array (for zod schemas).
4
+ */
5
+ export const THREAD_STATES = [
6
+ RUNNING,
7
+ STOPPED,
8
+ INTERRUPTIBLE,
9
+ UNINTERRUPTIBLE,
10
+ ZOMBIE,
11
+ DEAD,
12
+ ];
1
13
  /**
2
14
  * Thread-specific tool call state for approval workflow.
3
15
  * This extends the protocol states for internal thread use.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kernl",
3
- "version": "0.2.0",
3
+ "version": "0.6.0",
4
4
  "description": "A modern AI agent framework",
5
5
  "keywords": [
6
6
  "kernl",
@@ -13,26 +13,30 @@
13
13
  "license": "MIT",
14
14
  "repository": {
15
15
  "type": "git",
16
- "url": "https://github.com/dremnik/kernl.git",
16
+ "url": "https://github.com/kernl-sdk/kernl.git",
17
17
  "directory": "packages/kernl"
18
18
  },
19
- "homepage": "https://github.com/dremnik/kernl#readme",
19
+ "homepage": "https://github.com/kernl-sdk/kernl#readme",
20
20
  "bugs": {
21
- "url": "https://github.com/dremnik/kernl/issues"
21
+ "url": "https://github.com/kernl-sdk/kernl/issues"
22
22
  },
23
23
  "type": "module",
24
24
  "exports": {
25
25
  ".": {
26
26
  "types": "./dist/index.d.ts",
27
27
  "import": "./dist/index.js"
28
+ },
29
+ "./internal": {
30
+ "types": "./dist/internal.d.ts",
31
+ "import": "./dist/internal.js"
28
32
  }
29
33
  },
30
34
  "dependencies": {
31
35
  "@modelcontextprotocol/sdk": "^1.20.2",
32
36
  "pino": "^9.6.0",
33
37
  "zod": "^4.1.12",
34
- "@kernl-sdk/protocol": "0.2.0",
35
- "@kernl-sdk/shared": "^0.1.1"
38
+ "@kernl-sdk/protocol": "0.2.4",
39
+ "@kernl-sdk/shared": "^0.1.5"
36
40
  },
37
41
  "devDependencies": {
38
42
  "@ai-sdk/openai": "3.0.0-beta.57",
@@ -40,7 +44,7 @@
40
44
  "tsc-alias": "^1.8.10",
41
45
  "typescript": "5.9.2",
42
46
  "vitest": "^4.0.8",
43
- "@kernl-sdk/ai": "0.1.1"
47
+ "@kernl-sdk/ai": "0.2.5"
44
48
  },
45
49
  "scripts": {
46
50
  "build": "tsc && tsc-alias",
@@ -0,0 +1,194 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { Agent } from "@/agent";
3
+ import { Kernl } from "@/kernl";
4
+ import { createMockModel } from "@/thread/__tests__/fixtures/mock-model";
5
+ import { RuntimeError } from "@/lib/error";
6
+ import { message } from "@kernl-sdk/protocol";
7
+
8
+ describe("Concurrent execution prevention", () => {
9
+ // (TODO): this should work
10
+ it.skip("should prevent two Agent.run() calls with same threadId", async () => {
11
+ const model = createMockModel(async () => {
12
+ await new Promise((resolve) => setTimeout(resolve, 200));
13
+ return {
14
+ content: [message({ role: "assistant", text: "Done" })],
15
+ finishReason: "stop",
16
+ usage: { inputTokens: 2, outputTokens: 2, totalTokens: 4 },
17
+ warnings: [],
18
+ };
19
+ });
20
+
21
+ const agent = new Agent({
22
+ id: "test-agent",
23
+ name: "Test",
24
+ instructions: "Test",
25
+ model,
26
+ });
27
+
28
+ const kernl = new Kernl();
29
+ kernl.register(agent);
30
+
31
+ const tid = "concurrent-test-1";
32
+
33
+ // Start first run
34
+ const run1 = agent.run("First", { threadId: tid });
35
+
36
+ // Try second run immediately
37
+ await expect(agent.run("Second", { threadId: tid })).rejects.toThrow(
38
+ RuntimeError,
39
+ );
40
+
41
+ await expect(agent.run("Second", { threadId: tid })).rejects.toThrow(
42
+ /already running/,
43
+ );
44
+
45
+ // Wait for first to complete
46
+ await run1;
47
+
48
+ // Now third should work
49
+ await expect(agent.run("Third", { threadId: tid })).resolves.toBeDefined();
50
+ });
51
+
52
+ // (TODO): this should work
53
+ it.skip("should prevent Agent.stream() on thread already in Agent.run()", async () => {
54
+ const model = createMockModel(async () => {
55
+ await new Promise((resolve) => setTimeout(resolve, 200));
56
+ return {
57
+ content: [message({ role: "assistant", text: "Done" })],
58
+ finishReason: "stop",
59
+ usage: { inputTokens: 2, outputTokens: 2, totalTokens: 4 },
60
+ warnings: [],
61
+ };
62
+ });
63
+
64
+ const agent = new Agent({
65
+ id: "test-agent",
66
+ name: "Test",
67
+ instructions: "Test",
68
+ model,
69
+ });
70
+
71
+ const kernl = new Kernl();
72
+ kernl.register(agent);
73
+
74
+ const tid = "concurrent-test-2";
75
+
76
+ // Start run()
77
+ const runPromise = agent.run("Test", { threadId: tid });
78
+
79
+ // Try to stream same thread
80
+ const streamIterable = agent.stream("Test", { threadId: tid });
81
+ const streamIterator = streamIterable[Symbol.asyncIterator]();
82
+ await expect(streamIterator.next()).rejects.toThrow(RuntimeError);
83
+ await expect(streamIterator.next()).rejects.toThrow(/already running/);
84
+
85
+ await runPromise;
86
+ });
87
+
88
+ it("should prevent Agent.run() on thread already in Agent.stream()", async () => {
89
+ const model = createMockModel(async () => {
90
+ await new Promise((resolve) => setTimeout(resolve, 50));
91
+ return {
92
+ content: [message({ role: "assistant", text: "Done" })],
93
+ finishReason: "stop",
94
+ usage: { inputTokens: 2, outputTokens: 2, totalTokens: 4 },
95
+ warnings: [],
96
+ };
97
+ });
98
+
99
+ const agent = new Agent({
100
+ id: "test-agent",
101
+ name: "Test",
102
+ instructions: "Test",
103
+ model,
104
+ });
105
+
106
+ const kernl = new Kernl();
107
+ kernl.register(agent);
108
+
109
+ const tid = "concurrent-test-3";
110
+
111
+ // Start stream() but don't await - start consuming
112
+ const streamIterator = agent.stream("Test", { threadId: tid });
113
+ const streamPromise = (async () => {
114
+ for await (const _event of streamIterator) {
115
+ // consume
116
+ }
117
+ })();
118
+
119
+ // Give stream time to start
120
+ await new Promise((resolve) => setTimeout(resolve, 10));
121
+
122
+ // Try to run() same thread
123
+ await expect(agent.run("Test", { threadId: tid })).rejects.toThrow(
124
+ RuntimeError,
125
+ );
126
+
127
+ await streamPromise;
128
+ });
129
+
130
+ it("should allow different threadIds to run concurrently", async () => {
131
+ const model = createMockModel(async () => {
132
+ await new Promise((resolve) => setTimeout(resolve, 50));
133
+ return {
134
+ content: [message({ role: "assistant", text: "Done" })],
135
+ finishReason: "stop",
136
+ usage: { inputTokens: 2, outputTokens: 2, totalTokens: 4 },
137
+ warnings: [],
138
+ };
139
+ });
140
+
141
+ const agent = new Agent({
142
+ id: "test-agent",
143
+ name: "Test",
144
+ instructions: "Test",
145
+ model,
146
+ });
147
+
148
+ const kernl = new Kernl();
149
+ kernl.register(agent);
150
+
151
+ // These should all succeed
152
+ const results = await Promise.all([
153
+ agent.run("Test 1", { threadId: "thread-1" }),
154
+ agent.run("Test 2", { threadId: "thread-2" }),
155
+ agent.run("Test 3", { threadId: "thread-3" }),
156
+ ]);
157
+
158
+ expect(results).toHaveLength(3);
159
+ expect(results.every((r) => r.response === "Done")).toBe(true);
160
+ });
161
+
162
+ it("should allow same threadId after previous run completes", async () => {
163
+ const model = createMockModel(async () => ({
164
+ content: [message({ role: "assistant", text: "Done" })],
165
+ finishReason: "stop",
166
+ usage: { inputTokens: 2, outputTokens: 2, totalTokens: 4 },
167
+ warnings: [],
168
+ }));
169
+
170
+ const agent = new Agent({
171
+ id: "test-agent",
172
+ name: "Test",
173
+ instructions: "Test",
174
+ model,
175
+ });
176
+
177
+ const kernl = new Kernl();
178
+ kernl.register(agent);
179
+
180
+ const tid = "reuse-thread";
181
+
182
+ // First run
183
+ const result1 = await agent.run("First", { threadId: tid });
184
+ expect(result1.response).toBe("Done");
185
+
186
+ // Second run (should work since first completed)
187
+ const result2 = await agent.run("Second", { threadId: tid });
188
+ expect(result2.response).toBe("Done");
189
+
190
+ // Third run
191
+ const result3 = await agent.run("Third", { threadId: tid });
192
+ expect(result3.response).toBe("Done");
193
+ });
194
+ });