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
@@ -1,5 +1,4 @@
1
-
2
- 
3
- > kernl@0.1.4 build /Users/andjones/Documents/projects/kernl/packages/kernl
4
- > tsc && tsc-alias
5
-
1
+
2
+ > kernl@0.5.1 build /Users/andjones/Documents/projects/kernl/packages/kernl
3
+ > tsc && tsc-alias
4
+
@@ -0,0 +1,4 @@
1
+
2
+ > @kernl-sdk/core@0.2.2 check-types /Users/andjones/Documents/projects/kernl/packages/kernl
3
+ > tsc --noEmit
4
+
package/CHANGELOG.md CHANGED
@@ -1,5 +1,152 @@
1
1
  # @kernl/core
2
2
 
3
+ ## 0.6.0
4
+
5
+ ### Minor Changes
6
+
7
+ - Migrate packages from GitHub Packages to npm registry.
8
+
9
+ **Breaking change for `kernl` (formerly `@kernl-sdk/core`):**
10
+
11
+ The core package has been renamed from `@kernl-sdk/core` to `kernl`. Update your imports:
12
+
13
+ ```diff
14
+ - import { Agent, Kernl } from "@kernl-sdk/core";
15
+ + import { Agent, Kernl } from "kernl";
16
+ ```
17
+
18
+ All other packages remain under the `@kernl-sdk` scope and are now publicly available on npm.
19
+
20
+ ### Patch Changes
21
+
22
+ - Updated dependencies
23
+ - @kernl-sdk/shared@0.1.5
24
+ - @kernl-sdk/protocol@0.2.4
25
+
26
+ ## 0.5.1
27
+
28
+ ### Patch Changes
29
+
30
+ - 08ab8a0: Fix duplicate thread inserts when streaming from hydrated threads by making
31
+ storage-backed Thread instances explicitly marked as persisted, and ensure
32
+ Postgres integration tests cover the no-double-insert behavior.
33
+
34
+ ## 0.5.0
35
+
36
+ ### Minor Changes
37
+
38
+ - ad56b86: Introduce the public Kernl threads API surface (`kernl.threads` and
39
+ `agent.threads`) for listing, getting, deleting, and reading history, backed
40
+ by simple `Thread` and `ThreadEvent` models.
41
+
42
+ Add explicit thread creation and update APIs, including first-class `title`
43
+ support (stored in `metadata.title`) and structured `context` / `metadata`
44
+ patch semantics, and tighten thread persistence behavior in core + storage
45
+ implementations to keep context and metadata consistent across in-memory and
46
+ Postgres stores.
47
+
48
+ ## 0.4.6
49
+
50
+ ### Patch Changes
51
+
52
+ - Add PublicThreadEvent type to filter internal system events from client-facing APIs. ThreadResource.history and ThreadsResource.history() now return only public events (messages, tool calls, tool results), excluding internal system events.
53
+
54
+ ## 0.4.5
55
+
56
+ ### Patch Changes
57
+
58
+ - 8e3bac1: Add ThreadResource public API type that separates the public thread interface from internal Thread execution primitive. ThreadsResource methods now return ThreadResource with serialized data instead of Thread class instances. Add createdAt/updatedAt timestamps to threads.
59
+
60
+ ## 0.4.4
61
+
62
+ ### Patch Changes
63
+
64
+ - ba8119d: Fix Kernl type exports - remove duplicate old Kernl definition from dist root that was missing the threads property. The correct Kernl class with ThreadsResource is now properly exported.
65
+
66
+ ## 0.4.3
67
+
68
+ ### Patch Changes
69
+
70
+ - f536b15: Add clean public API for thread management with ThreadsResource class and agent-scoped thread access. Users can now access threads via `kernl.threads.get/list/delete/history()` or use agent-scoped helpers like `agent.threads.list()` that automatically filter to that agent's threads.
71
+
72
+ ## 0.4.2
73
+
74
+ ### Patch Changes
75
+
76
+ - Updated dependencies
77
+ - @kernl-sdk/shared@0.1.4
78
+ - @kernl-sdk/protocol@0.2.3
79
+
80
+ ## 0.4.1
81
+
82
+ ### Patch Changes
83
+
84
+ - feat: implement lazy storage initialization
85
+
86
+ Storage is now automatically initialized on first agent execution. The `ensureInitialized()` method is called internally by spawn/schedule methods, so users never have to manually call `storage.init()`. Initialization is idempotent and concurrency-safe.
87
+
88
+ ## 0.4.0
89
+
90
+ ### Minor Changes
91
+
92
+ - feat: add storage infrastructure with automatic initialization
93
+
94
+ Adds comprehensive storage infrastructure to Kernl:
95
+ - New `KernlStorage` and `ThreadStore` interfaces for persistent thread management
96
+ - Automatic lazy initialization of storage on first agent execution
97
+ - Thread checkpointing at key lifecycle points (start, post-tools, terminal-tick, stop)
98
+ - Thread resumption support - pass `{ threadId }` to agent.run() or agent.stream()
99
+ - In-memory storage implementation as default (no setup required)
100
+ - PostgreSQL storage adapter via `@kernl/pg`
101
+ - LibSQL storage adapter via `@kernl/libsql`
102
+ - Full support for thread history queries and event filtering
103
+
104
+ ## 0.3.2
105
+
106
+ ### Patch Changes
107
+
108
+ - fix: MCP tool schema compatibility with OpenAI
109
+
110
+ Fixed MCP tool parameter schema serialization to match AI SDK pattern. Empty-parameter MCP tools now generate schemas with `{ type: "object", properties: {}, additionalProperties: false }` which satisfies OpenAI's strict validation requirements.
111
+
112
+ ## 0.3.1
113
+
114
+ ### Patch Changes
115
+
116
+ - e90f8bb: fix: handle model stream errors gracefully
117
+
118
+ Thread.stream() now properly catches and converts model errors (like missing API keys) to error events, preventing the UI from hanging. Errors are logged via logger.error() and sent to clients as error chunks.
119
+
120
+ ## 0.3.0
121
+
122
+ ### Minor Changes
123
+
124
+ - Allow Agent.run() and Agent.stream() to accept LanguageModelItem[] as input
125
+ - Update run() and stream() methods to accept `string | LanguageModelItem[]`
126
+ - Convert string inputs to message items internally for backwards compatibility
127
+ - Enable passing decoded UI messages directly to agent methods for multi-turn conversations
128
+
129
+ ## 0.2.2
130
+
131
+ ### Patch Changes
132
+
133
+ - 2c62c0a: Migrate from @kernl to @kernl-sdk scope
134
+
135
+ All packages have been migrated to the @kernl-sdk scope for publishing to GitHub Packages under the kernl-sdk organization.
136
+
137
+ - Updated dependencies [2c62c0a]
138
+ - @kernl-sdk/shared@0.1.3
139
+ - @kernl-sdk/protocol@0.2.2
140
+
141
+ ## 0.2.1
142
+
143
+ ### Patch Changes
144
+
145
+ - Minor bug fixes and improvements
146
+ - Updated dependencies
147
+ - @kernl-sdk/protocol@0.2.1
148
+ - @kernl-sdk/shared@0.1.2
149
+
3
150
  ## 0.2.0
4
151
 
5
152
  ### Minor Changes
package/LICENSE CHANGED
@@ -186,7 +186,7 @@
186
186
  same "printed page" as the copyright notice for easier
187
187
  identification within third-party archives.
188
188
 
189
- Copyright [yyyy] [name of copyright owner]
189
+ Copyright 2025 Andrew Jones
190
190
 
191
191
  Licensed under the Apache License, Version 2.0 (the "License");
192
192
  you may not use this file except in compliance with the License.
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=concurrency.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"concurrency.test.d.ts","sourceRoot":"","sources":["../../../src/agent/__tests__/concurrency.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,152 @@
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
+ describe("Concurrent execution prevention", () => {
8
+ // (TODO): this should work
9
+ it.skip("should prevent two Agent.run() calls with same threadId", async () => {
10
+ const model = createMockModel(async () => {
11
+ await new Promise((resolve) => setTimeout(resolve, 200));
12
+ return {
13
+ content: [message({ role: "assistant", text: "Done" })],
14
+ finishReason: "stop",
15
+ usage: { inputTokens: 2, outputTokens: 2, totalTokens: 4 },
16
+ warnings: [],
17
+ };
18
+ });
19
+ const agent = new Agent({
20
+ id: "test-agent",
21
+ name: "Test",
22
+ instructions: "Test",
23
+ model,
24
+ });
25
+ const kernl = new Kernl();
26
+ kernl.register(agent);
27
+ const tid = "concurrent-test-1";
28
+ // Start first run
29
+ const run1 = agent.run("First", { threadId: tid });
30
+ // Try second run immediately
31
+ await expect(agent.run("Second", { threadId: tid })).rejects.toThrow(RuntimeError);
32
+ await expect(agent.run("Second", { threadId: tid })).rejects.toThrow(/already running/);
33
+ // Wait for first to complete
34
+ await run1;
35
+ // Now third should work
36
+ await expect(agent.run("Third", { threadId: tid })).resolves.toBeDefined();
37
+ });
38
+ // (TODO): this should work
39
+ it.skip("should prevent Agent.stream() on thread already in Agent.run()", async () => {
40
+ const model = createMockModel(async () => {
41
+ await new Promise((resolve) => setTimeout(resolve, 200));
42
+ return {
43
+ content: [message({ role: "assistant", text: "Done" })],
44
+ finishReason: "stop",
45
+ usage: { inputTokens: 2, outputTokens: 2, totalTokens: 4 },
46
+ warnings: [],
47
+ };
48
+ });
49
+ const agent = new Agent({
50
+ id: "test-agent",
51
+ name: "Test",
52
+ instructions: "Test",
53
+ model,
54
+ });
55
+ const kernl = new Kernl();
56
+ kernl.register(agent);
57
+ const tid = "concurrent-test-2";
58
+ // Start run()
59
+ const runPromise = agent.run("Test", { threadId: tid });
60
+ // Try to stream same thread
61
+ const streamIterable = agent.stream("Test", { threadId: tid });
62
+ const streamIterator = streamIterable[Symbol.asyncIterator]();
63
+ await expect(streamIterator.next()).rejects.toThrow(RuntimeError);
64
+ await expect(streamIterator.next()).rejects.toThrow(/already running/);
65
+ await runPromise;
66
+ });
67
+ it("should prevent Agent.run() on thread already in Agent.stream()", async () => {
68
+ const model = createMockModel(async () => {
69
+ await new Promise((resolve) => setTimeout(resolve, 50));
70
+ return {
71
+ content: [message({ role: "assistant", text: "Done" })],
72
+ finishReason: "stop",
73
+ usage: { inputTokens: 2, outputTokens: 2, totalTokens: 4 },
74
+ warnings: [],
75
+ };
76
+ });
77
+ const agent = new Agent({
78
+ id: "test-agent",
79
+ name: "Test",
80
+ instructions: "Test",
81
+ model,
82
+ });
83
+ const kernl = new Kernl();
84
+ kernl.register(agent);
85
+ const tid = "concurrent-test-3";
86
+ // Start stream() but don't await - start consuming
87
+ const streamIterator = agent.stream("Test", { threadId: tid });
88
+ const streamPromise = (async () => {
89
+ for await (const _event of streamIterator) {
90
+ // consume
91
+ }
92
+ })();
93
+ // Give stream time to start
94
+ await new Promise((resolve) => setTimeout(resolve, 10));
95
+ // Try to run() same thread
96
+ await expect(agent.run("Test", { threadId: tid })).rejects.toThrow(RuntimeError);
97
+ await streamPromise;
98
+ });
99
+ it("should allow different threadIds to run concurrently", async () => {
100
+ const model = createMockModel(async () => {
101
+ await new Promise((resolve) => setTimeout(resolve, 50));
102
+ return {
103
+ content: [message({ role: "assistant", text: "Done" })],
104
+ finishReason: "stop",
105
+ usage: { inputTokens: 2, outputTokens: 2, totalTokens: 4 },
106
+ warnings: [],
107
+ };
108
+ });
109
+ const agent = new Agent({
110
+ id: "test-agent",
111
+ name: "Test",
112
+ instructions: "Test",
113
+ model,
114
+ });
115
+ const kernl = new Kernl();
116
+ kernl.register(agent);
117
+ // These should all succeed
118
+ const results = await Promise.all([
119
+ agent.run("Test 1", { threadId: "thread-1" }),
120
+ agent.run("Test 2", { threadId: "thread-2" }),
121
+ agent.run("Test 3", { threadId: "thread-3" }),
122
+ ]);
123
+ expect(results).toHaveLength(3);
124
+ expect(results.every((r) => r.response === "Done")).toBe(true);
125
+ });
126
+ it("should allow same threadId after previous run completes", async () => {
127
+ const model = createMockModel(async () => ({
128
+ content: [message({ role: "assistant", text: "Done" })],
129
+ finishReason: "stop",
130
+ usage: { inputTokens: 2, outputTokens: 2, totalTokens: 4 },
131
+ warnings: [],
132
+ }));
133
+ const agent = new Agent({
134
+ id: "test-agent",
135
+ name: "Test",
136
+ instructions: "Test",
137
+ model,
138
+ });
139
+ const kernl = new Kernl();
140
+ kernl.register(agent);
141
+ const tid = "reuse-thread";
142
+ // First run
143
+ const result1 = await agent.run("First", { threadId: tid });
144
+ expect(result1.response).toBe("Done");
145
+ // Second run (should work since first completed)
146
+ const result2 = await agent.run("Second", { threadId: tid });
147
+ expect(result2.response).toBe("Done");
148
+ // Third run
149
+ const result3 = await agent.run("Third", { threadId: tid });
150
+ expect(result3.response).toBe("Done");
151
+ });
152
+ });
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=run.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.test.d.ts","sourceRoot":"","sources":["../../../src/agent/__tests__/run.test.ts"],"names":[],"mappings":""}