@botbotgo/runtime 1.0.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 (313) hide show
  1. package/.github/workflows/ci.yml +46 -0
  2. package/.github/workflows/release.yml +79 -0
  3. package/README.md +71 -0
  4. package/config/examples/memory.yaml +39 -0
  5. package/config/examples/model.yaml +21 -0
  6. package/config/examples/runtime.yaml +44 -0
  7. package/config/examples/skills.yaml +8 -0
  8. package/config/examples/tool.yaml +16 -0
  9. package/dist/config/index.d.ts +7 -0
  10. package/dist/config/index.d.ts.map +1 -0
  11. package/dist/config/index.js +4 -0
  12. package/dist/config/index.js.map +1 -0
  13. package/dist/config/loader.d.ts +41 -0
  14. package/dist/config/loader.d.ts.map +1 -0
  15. package/dist/config/loader.js +140 -0
  16. package/dist/config/loader.js.map +1 -0
  17. package/dist/config/resolveRuntimeConfig.d.ts +83 -0
  18. package/dist/config/resolveRuntimeConfig.d.ts.map +1 -0
  19. package/dist/config/resolveRuntimeConfig.js +85 -0
  20. package/dist/config/resolveRuntimeConfig.js.map +1 -0
  21. package/dist/config/resources.d.ts +112 -0
  22. package/dist/config/resources.d.ts.map +1 -0
  23. package/dist/config/resources.js +20 -0
  24. package/dist/config/resources.js.map +1 -0
  25. package/dist/config/runtimeConfigLoader.d.ts +28 -0
  26. package/dist/config/runtimeConfigLoader.d.ts.map +1 -0
  27. package/dist/config/runtimeConfigLoader.js +38 -0
  28. package/dist/config/runtimeConfigLoader.js.map +1 -0
  29. package/dist/index.d.ts +9 -0
  30. package/dist/index.d.ts.map +1 -0
  31. package/dist/index.js +5 -0
  32. package/dist/index.js.map +1 -0
  33. package/dist/runtime/agentMiddleware.d.ts +3 -0
  34. package/dist/runtime/agentMiddleware.d.ts.map +1 -0
  35. package/dist/runtime/agentMiddleware.js +2 -0
  36. package/dist/runtime/agentMiddleware.js.map +1 -0
  37. package/dist/runtime/bootstrap/runtimeFactory.d.ts +7 -0
  38. package/dist/runtime/bootstrap/runtimeFactory.d.ts.map +1 -0
  39. package/dist/runtime/bootstrap/runtimeFactory.js +139 -0
  40. package/dist/runtime/bootstrap/runtimeFactory.js.map +1 -0
  41. package/dist/runtime/bootstrap/runtimeModuleInitializer.d.ts +5 -0
  42. package/dist/runtime/bootstrap/runtimeModuleInitializer.d.ts.map +1 -0
  43. package/dist/runtime/bootstrap/runtimeModuleInitializer.js +32 -0
  44. package/dist/runtime/bootstrap/runtimeModuleInitializer.js.map +1 -0
  45. package/dist/runtime/context/agentContext.d.ts +5 -0
  46. package/dist/runtime/context/agentContext.d.ts.map +1 -0
  47. package/dist/runtime/context/agentContext.js +19 -0
  48. package/dist/runtime/context/agentContext.js.map +1 -0
  49. package/dist/runtime/context/globalContext.d.ts +19 -0
  50. package/dist/runtime/context/globalContext.d.ts.map +1 -0
  51. package/dist/runtime/context/globalContext.js +47 -0
  52. package/dist/runtime/context/globalContext.js.map +1 -0
  53. package/dist/runtime/events/eventPublisher.d.ts +15 -0
  54. package/dist/runtime/events/eventPublisher.d.ts.map +1 -0
  55. package/dist/runtime/events/eventPublisher.js +23 -0
  56. package/dist/runtime/events/eventPublisher.js.map +1 -0
  57. package/dist/runtime/execution/agentRunExecutor.d.ts +38 -0
  58. package/dist/runtime/execution/agentRunExecutor.d.ts.map +1 -0
  59. package/dist/runtime/execution/agentRunExecutor.js +378 -0
  60. package/dist/runtime/execution/agentRunExecutor.js.map +1 -0
  61. package/dist/runtime/execution/agentRunExecutor.types.d.ts +37 -0
  62. package/dist/runtime/execution/agentRunExecutor.types.d.ts.map +1 -0
  63. package/dist/runtime/execution/agentRunExecutor.types.js +2 -0
  64. package/dist/runtime/execution/agentRunExecutor.types.js.map +1 -0
  65. package/dist/runtime/execution/agentRunProgress.d.ts +8 -0
  66. package/dist/runtime/execution/agentRunProgress.d.ts.map +1 -0
  67. package/dist/runtime/execution/agentRunProgress.js +46 -0
  68. package/dist/runtime/execution/agentRunProgress.js.map +1 -0
  69. package/dist/runtime/execution/agentRunState.d.ts +44 -0
  70. package/dist/runtime/execution/agentRunState.d.ts.map +1 -0
  71. package/dist/runtime/execution/agentRunState.js +17 -0
  72. package/dist/runtime/execution/agentRunState.js.map +1 -0
  73. package/dist/runtime/execution/policies/runCompletionPolicy.d.ts +5 -0
  74. package/dist/runtime/execution/policies/runCompletionPolicy.d.ts.map +1 -0
  75. package/dist/runtime/execution/policies/runCompletionPolicy.js +30 -0
  76. package/dist/runtime/execution/policies/runCompletionPolicy.js.map +1 -0
  77. package/dist/runtime/execution/policies/runErrorPolicy.d.ts +7 -0
  78. package/dist/runtime/execution/policies/runErrorPolicy.d.ts.map +1 -0
  79. package/dist/runtime/execution/policies/runErrorPolicy.js +40 -0
  80. package/dist/runtime/execution/policies/runErrorPolicy.js.map +1 -0
  81. package/dist/runtime/execution/policies/runPromptBuilder.d.ts +10 -0
  82. package/dist/runtime/execution/policies/runPromptBuilder.d.ts.map +1 -0
  83. package/dist/runtime/execution/policies/runPromptBuilder.js +34 -0
  84. package/dist/runtime/execution/policies/runPromptBuilder.js.map +1 -0
  85. package/dist/runtime/execution/policies/runSummaryFormatter.d.ts +6 -0
  86. package/dist/runtime/execution/policies/runSummaryFormatter.d.ts.map +1 -0
  87. package/dist/runtime/execution/policies/runSummaryFormatter.js +47 -0
  88. package/dist/runtime/execution/policies/runSummaryFormatter.js.map +1 -0
  89. package/dist/runtime/execution/policies/runtimeDelay.d.ts +4 -0
  90. package/dist/runtime/execution/policies/runtimeDelay.d.ts.map +1 -0
  91. package/dist/runtime/execution/policies/runtimeDelay.js +6 -0
  92. package/dist/runtime/execution/policies/runtimeDelay.js.map +1 -0
  93. package/dist/runtime/execution/policies/toolConfigReader.d.ts +8 -0
  94. package/dist/runtime/execution/policies/toolConfigReader.d.ts.map +1 -0
  95. package/dist/runtime/execution/policies/toolConfigReader.js +91 -0
  96. package/dist/runtime/execution/policies/toolConfigReader.js.map +1 -0
  97. package/dist/runtime/human-loop/consoleHumanLoop.d.ts +21 -0
  98. package/dist/runtime/human-loop/consoleHumanLoop.d.ts.map +1 -0
  99. package/dist/runtime/human-loop/consoleHumanLoop.js +102 -0
  100. package/dist/runtime/human-loop/consoleHumanLoop.js.map +1 -0
  101. package/dist/runtime/human-loop/humanLoop.d.ts +44 -0
  102. package/dist/runtime/human-loop/humanLoop.d.ts.map +1 -0
  103. package/dist/runtime/human-loop/humanLoop.js +36 -0
  104. package/dist/runtime/human-loop/humanLoop.js.map +1 -0
  105. package/dist/runtime/index.d.ts +10 -0
  106. package/dist/runtime/index.d.ts.map +1 -0
  107. package/dist/runtime/index.js +6 -0
  108. package/dist/runtime/index.js.map +1 -0
  109. package/dist/runtime/middleware/agentToolMiddleware.d.ts +30 -0
  110. package/dist/runtime/middleware/agentToolMiddleware.d.ts.map +1 -0
  111. package/dist/runtime/middleware/agentToolMiddleware.js +259 -0
  112. package/dist/runtime/middleware/agentToolMiddleware.js.map +1 -0
  113. package/dist/runtime/middleware/commandPolicy.d.ts +8 -0
  114. package/dist/runtime/middleware/commandPolicy.d.ts.map +1 -0
  115. package/dist/runtime/middleware/commandPolicy.js +55 -0
  116. package/dist/runtime/middleware/commandPolicy.js.map +1 -0
  117. package/dist/runtime/middleware/frameworkPrompt.d.ts +4 -0
  118. package/dist/runtime/middleware/frameworkPrompt.d.ts.map +1 -0
  119. package/dist/runtime/middleware/frameworkPrompt.js +44 -0
  120. package/dist/runtime/middleware/frameworkPrompt.js.map +1 -0
  121. package/dist/runtime/middleware/index.d.ts +4 -0
  122. package/dist/runtime/middleware/index.d.ts.map +1 -0
  123. package/dist/runtime/middleware/index.js +3 -0
  124. package/dist/runtime/middleware/index.js.map +1 -0
  125. package/dist/runtime/middleware/skillPathMap.d.ts +3 -0
  126. package/dist/runtime/middleware/skillPathMap.d.ts.map +1 -0
  127. package/dist/runtime/middleware/skillPathMap.js +44 -0
  128. package/dist/runtime/middleware/skillPathMap.js.map +1 -0
  129. package/dist/runtime/middleware/toolArgsNormalizer.d.ts +21 -0
  130. package/dist/runtime/middleware/toolArgsNormalizer.d.ts.map +1 -0
  131. package/dist/runtime/middleware/toolArgsNormalizer.js +227 -0
  132. package/dist/runtime/middleware/toolArgsNormalizer.js.map +1 -0
  133. package/dist/runtime/middleware/toolCallGuard.d.ts +8 -0
  134. package/dist/runtime/middleware/toolCallGuard.d.ts.map +1 -0
  135. package/dist/runtime/middleware/toolCallGuard.js +60 -0
  136. package/dist/runtime/middleware/toolCallGuard.js.map +1 -0
  137. package/dist/runtime/middleware/toolFsHandlers.d.ts +12 -0
  138. package/dist/runtime/middleware/toolFsHandlers.d.ts.map +1 -0
  139. package/dist/runtime/middleware/toolFsHandlers.js +79 -0
  140. package/dist/runtime/middleware/toolFsHandlers.js.map +1 -0
  141. package/dist/runtime/middleware/toolRequestParser.d.ts +14 -0
  142. package/dist/runtime/middleware/toolRequestParser.d.ts.map +1 -0
  143. package/dist/runtime/middleware/toolRequestParser.js +72 -0
  144. package/dist/runtime/middleware/toolRequestParser.js.map +1 -0
  145. package/dist/runtime/middleware/types.d.ts +87 -0
  146. package/dist/runtime/middleware/types.d.ts.map +1 -0
  147. package/dist/runtime/middleware/types.js +3 -0
  148. package/dist/runtime/middleware/types.js.map +1 -0
  149. package/dist/runtime/providers/backendResolver.d.ts +26 -0
  150. package/dist/runtime/providers/backendResolver.d.ts.map +1 -0
  151. package/dist/runtime/providers/backendResolver.js +73 -0
  152. package/dist/runtime/providers/backendResolver.js.map +1 -0
  153. package/dist/runtime/providers/index.d.ts +14 -0
  154. package/dist/runtime/providers/index.d.ts.map +1 -0
  155. package/dist/runtime/providers/index.js +10 -0
  156. package/dist/runtime/providers/index.js.map +1 -0
  157. package/dist/runtime/providers/langchainRuntime.d.ts +11 -0
  158. package/dist/runtime/providers/langchainRuntime.d.ts.map +1 -0
  159. package/dist/runtime/providers/langchainRuntime.js +45 -0
  160. package/dist/runtime/providers/langchainRuntime.js.map +1 -0
  161. package/dist/runtime/providers/localShellBackend.d.ts +10 -0
  162. package/dist/runtime/providers/localShellBackend.d.ts.map +1 -0
  163. package/dist/runtime/providers/localShellBackend.js +23 -0
  164. package/dist/runtime/providers/localShellBackend.js.map +1 -0
  165. package/dist/runtime/providers/openaiDeepAgent.d.ts +9 -0
  166. package/dist/runtime/providers/openaiDeepAgent.d.ts.map +1 -0
  167. package/dist/runtime/providers/openaiDeepAgent.js +7 -0
  168. package/dist/runtime/providers/openaiDeepAgent.js.map +1 -0
  169. package/dist/runtime/providers/openaiLocalAgent.d.ts +17 -0
  170. package/dist/runtime/providers/openaiLocalAgent.d.ts.map +1 -0
  171. package/dist/runtime/providers/openaiLocalAgent.js +26 -0
  172. package/dist/runtime/providers/openaiLocalAgent.js.map +1 -0
  173. package/dist/runtime/providers/openaiLocalAgentFactory.d.ts +36 -0
  174. package/dist/runtime/providers/openaiLocalAgentFactory.d.ts.map +1 -0
  175. package/dist/runtime/providers/openaiLocalAgentFactory.js +139 -0
  176. package/dist/runtime/providers/openaiLocalAgentFactory.js.map +1 -0
  177. package/dist/runtime/providers/shared/agentProbe.d.ts +4 -0
  178. package/dist/runtime/providers/shared/agentProbe.d.ts.map +1 -0
  179. package/dist/runtime/providers/shared/agentProbe.js +17 -0
  180. package/dist/runtime/providers/shared/agentProbe.js.map +1 -0
  181. package/dist/runtime/providers/shared/moduleFallback.d.ts +2 -0
  182. package/dist/runtime/providers/shared/moduleFallback.d.ts.map +1 -0
  183. package/dist/runtime/providers/shared/moduleFallback.js +34 -0
  184. package/dist/runtime/providers/shared/moduleFallback.js.map +1 -0
  185. package/dist/runtime/providers/shared/resourceCloser.d.ts +6 -0
  186. package/dist/runtime/providers/shared/resourceCloser.d.ts.map +1 -0
  187. package/dist/runtime/providers/shared/resourceCloser.js +30 -0
  188. package/dist/runtime/providers/shared/resourceCloser.js.map +1 -0
  189. package/dist/runtime/runtimeService.d.ts +109 -0
  190. package/dist/runtime/runtimeService.d.ts.map +1 -0
  191. package/dist/runtime/runtimeService.js +90 -0
  192. package/dist/runtime/runtimeService.js.map +1 -0
  193. package/dist/runtime/stream/agentMessages.d.ts +40 -0
  194. package/dist/runtime/stream/agentMessages.d.ts.map +1 -0
  195. package/dist/runtime/stream/agentMessages.js +44 -0
  196. package/dist/runtime/stream/agentMessages.js.map +1 -0
  197. package/dist/runtime/stream/agentStream.d.ts +31 -0
  198. package/dist/runtime/stream/agentStream.d.ts.map +1 -0
  199. package/dist/runtime/stream/agentStream.js +106 -0
  200. package/dist/runtime/stream/agentStream.js.map +1 -0
  201. package/dist/runtime/stream/messageSummary.d.ts +20 -0
  202. package/dist/runtime/stream/messageSummary.d.ts.map +1 -0
  203. package/dist/runtime/stream/messageSummary.js +150 -0
  204. package/dist/runtime/stream/messageSummary.js.map +1 -0
  205. package/dist/runtime/stream/runArtifacts.d.ts +9 -0
  206. package/dist/runtime/stream/runArtifacts.d.ts.map +1 -0
  207. package/dist/runtime/stream/runArtifacts.js +48 -0
  208. package/dist/runtime/stream/runArtifacts.js.map +1 -0
  209. package/dist/state/index.d.ts +7 -0
  210. package/dist/state/index.d.ts.map +1 -0
  211. package/dist/state/index.js +4 -0
  212. package/dist/state/index.js.map +1 -0
  213. package/dist/state/runState.d.ts +36 -0
  214. package/dist/state/runState.d.ts.map +1 -0
  215. package/dist/state/runState.js +51 -0
  216. package/dist/state/runState.js.map +1 -0
  217. package/dist/state/todos.d.ts +19 -0
  218. package/dist/state/todos.d.ts.map +1 -0
  219. package/dist/state/todos.js +45 -0
  220. package/dist/state/todos.js.map +1 -0
  221. package/dist/state/workspaceRunSession.d.ts +32 -0
  222. package/dist/state/workspaceRunSession.d.ts.map +1 -0
  223. package/dist/state/workspaceRunSession.js +67 -0
  224. package/dist/state/workspaceRunSession.js.map +1 -0
  225. package/dist/state/workspaceState.d.ts +94 -0
  226. package/dist/state/workspaceState.d.ts.map +1 -0
  227. package/dist/state/workspaceState.js +119 -0
  228. package/dist/state/workspaceState.js.map +1 -0
  229. package/dist/types.d.ts +2 -0
  230. package/dist/types.d.ts.map +1 -0
  231. package/dist/types.js +2 -0
  232. package/dist/types.js.map +1 -0
  233. package/example/.tsbuildinfo +1 -0
  234. package/example/build/.tsbuildinfo +1 -0
  235. package/example/config/memory.yaml +35 -0
  236. package/example/config/model.yaml +14 -0
  237. package/example/config/runtime.yaml +46 -0
  238. package/example/config/tool.yaml +24 -0
  239. package/example/index.ts +159 -0
  240. package/example/package-lock.json +1396 -0
  241. package/example/package.json +26 -0
  242. package/example/serve-output.mjs +52 -0
  243. package/example/tsconfig.json +19 -0
  244. package/package.json +73 -0
  245. package/scripts/resolve-deps.js +40 -0
  246. package/src/config/index.ts +29 -0
  247. package/src/config/loader.ts +174 -0
  248. package/src/config/resolveRuntimeConfig.ts +160 -0
  249. package/src/config/resources.ts +152 -0
  250. package/src/config/runtimeConfigLoader.ts +68 -0
  251. package/src/external-modules.d.ts +20 -0
  252. package/src/index.ts +36 -0
  253. package/src/runtime/agentMiddleware.ts +6 -0
  254. package/src/runtime/bootstrap/runtimeFactory.ts +212 -0
  255. package/src/runtime/bootstrap/runtimeModuleInitializer.ts +34 -0
  256. package/src/runtime/context/agentContext.ts +24 -0
  257. package/src/runtime/context/globalContext.ts +70 -0
  258. package/src/runtime/events/eventPublisher.ts +45 -0
  259. package/src/runtime/execution/agentRunExecutor.ts +499 -0
  260. package/src/runtime/execution/agentRunExecutor.types.ts +39 -0
  261. package/src/runtime/execution/agentRunProgress.ts +67 -0
  262. package/src/runtime/execution/agentRunState.ts +66 -0
  263. package/src/runtime/execution/policies/runCompletionPolicy.ts +30 -0
  264. package/src/runtime/execution/policies/runErrorPolicy.ts +50 -0
  265. package/src/runtime/execution/policies/runPromptBuilder.ts +39 -0
  266. package/src/runtime/execution/policies/runSummaryFormatter.ts +57 -0
  267. package/src/runtime/execution/policies/runtimeDelay.ts +5 -0
  268. package/src/runtime/execution/policies/toolConfigReader.ts +107 -0
  269. package/src/runtime/human-loop/consoleHumanLoop.ts +113 -0
  270. package/src/runtime/human-loop/humanLoop.ts +90 -0
  271. package/src/runtime/index.ts +36 -0
  272. package/src/runtime/middleware/agentToolMiddleware.ts +329 -0
  273. package/src/runtime/middleware/commandPolicy.ts +65 -0
  274. package/src/runtime/middleware/frameworkPrompt.ts +51 -0
  275. package/src/runtime/middleware/index.ts +7 -0
  276. package/src/runtime/middleware/skillPathMap.ts +49 -0
  277. package/src/runtime/middleware/toolArgsNormalizer.ts +277 -0
  278. package/src/runtime/middleware/toolCallGuard.ts +73 -0
  279. package/src/runtime/middleware/toolFsHandlers.ts +94 -0
  280. package/src/runtime/middleware/toolRequestParser.ts +84 -0
  281. package/src/runtime/middleware/types.ts +91 -0
  282. package/src/runtime/providers/backendResolver.ts +127 -0
  283. package/src/runtime/providers/index.ts +19 -0
  284. package/src/runtime/providers/langchainRuntime.ts +67 -0
  285. package/src/runtime/providers/localShellBackend.ts +54 -0
  286. package/src/runtime/providers/openaiDeepAgent.ts +17 -0
  287. package/src/runtime/providers/openaiLocalAgent.ts +35 -0
  288. package/src/runtime/providers/openaiLocalAgentFactory.ts +185 -0
  289. package/src/runtime/providers/shared/agentProbe.ts +24 -0
  290. package/src/runtime/providers/shared/moduleFallback.ts +41 -0
  291. package/src/runtime/providers/shared/resourceCloser.ts +30 -0
  292. package/src/runtime/runtimeService.ts +205 -0
  293. package/src/runtime/stream/agentMessages.ts +72 -0
  294. package/src/runtime/stream/agentStream.ts +168 -0
  295. package/src/runtime/stream/messageSummary.ts +164 -0
  296. package/src/runtime/stream/runArtifacts.ts +72 -0
  297. package/src/state/index.ts +19 -0
  298. package/src/state/runState.ts +84 -0
  299. package/src/state/todos.ts +59 -0
  300. package/src/state/workspaceRunSession.ts +96 -0
  301. package/src/state/workspaceState.ts +199 -0
  302. package/src/types/easynet-agent-common.d.ts +62 -0
  303. package/src/types.ts +1 -0
  304. package/test/integration/runtime-live.integration.test.ts +30 -0
  305. package/test/unit/config/loader.test.ts +429 -0
  306. package/test/unit/runtime/agentContext.test.ts +23 -0
  307. package/test/unit/runtime/agentRuntime.test.ts +99 -0
  308. package/test/unit/runtime/consoleHumanLoop.test.ts +52 -0
  309. package/test/unit/runtime/events.test.ts +11 -0
  310. package/test/unit/runtime/globalContext.test.ts +34 -0
  311. package/test/unit/runtime/humanLoop.test.ts +104 -0
  312. package/test/unit/runtime/toolArgsNormalizer.test.ts +136 -0
  313. package/tsconfig.json +18 -0
@@ -0,0 +1,429 @@
1
+ import { describe, it } from "node:test";
2
+ import assert from "node:assert";
3
+ import { join } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import {
6
+ loadFromString,
7
+ loadFromFile,
8
+ loadFromDirectory,
9
+ parseResource,
10
+ parseAllResources,
11
+ ConfigError,
12
+ } from "../../../src/config/loader.ts";
13
+ import { resolveAgentConfig, buildDeepAgentOptions } from "../../../src/config/resolveRuntimeConfig.ts";
14
+ import { loadAgentRuntimeConfig } from "../../../src/config/runtimeConfigLoader.ts";
15
+ import {
16
+ isAgentRuntimeConfig,
17
+ isMemoryConfig,
18
+ isSkillsConfig,
19
+ type AgentRuntimeConfigResource,
20
+ type MemoryConfigResource,
21
+ type SkillsConfigResource,
22
+ } from "../../../src/config/resources.ts";
23
+
24
+ function projectRoot(): string {
25
+ return join(fileURLToPath(import.meta.url), "..", "..", "..", "..");
26
+ }
27
+
28
+ const MEMORY_YAML = `
29
+ apiVersion: botbotgo.world/v1
30
+ kind: MemoryConfig
31
+ metadata:
32
+ name: agent-memory-default
33
+ spec:
34
+ memory:
35
+ thread:
36
+ store:
37
+ type: in_memory
38
+ allowWrite: true
39
+ maxItems: 20
40
+ sessionCompaction:
41
+ enabled: true
42
+ maxTokens: 3000
43
+ keepRecentTurns: 12
44
+ summaryKey: __session_summary__
45
+ checkEveryTurns: 3
46
+ cross_thread:
47
+ store:
48
+ type: in_memory
49
+ allowWrite: true
50
+ maxItems: 20
51
+ knowledge:
52
+ store:
53
+ type: in_memory
54
+ allowWrite: true
55
+ maxItems: 20
56
+ observability:
57
+ trace: false
58
+ privacy:
59
+ forbiddenMetadataKeys:
60
+ - password
61
+ - api_key
62
+ `;
63
+
64
+ const SKILLS_YAML = `
65
+ apiVersion: botbotgo.world/v1
66
+ kind: SkillsConfig
67
+ metadata:
68
+ name: default-skills
69
+ spec:
70
+ skills:
71
+ file:./skills: {}
72
+ file:~/.deepagents/agent/skills: {}
73
+ `;
74
+
75
+ const RUNTIME_YAML = `
76
+ apiVersion: botbotgo.world/v1
77
+ kind: AgentRuntimeConfig
78
+ metadata:
79
+ name: default-runtime
80
+ spec:
81
+ artifacts:
82
+ - key: report
83
+ path: output/report.html
84
+ stateDirName: .agent
85
+ legacyOutputState: true
86
+ executeTimeoutMs: 45000
87
+ blockTaskTool: false
88
+ systemPrompt: You are a runtime test agent.
89
+ llmIdleTimeoutMs: 300000
90
+ backend:
91
+ type: local_shell
92
+ timeoutMs: 20000
93
+ maxOutputBytes: 1048576
94
+ incompleteRunMaxRetries: 2
95
+ malformedToolCallMaxRetries: 1
96
+ idleTimeoutMaxRetries: 1
97
+ heartbeatIntervalMs: 10000
98
+ debug:
99
+ run: true
100
+ workspace: true
101
+ toolCall: true
102
+ stream: false
103
+ close: true
104
+ eventLogLevel: tools
105
+ `;
106
+
107
+ describe("config/loader", () => {
108
+ it("parseResource parses MemoryConfig", () => {
109
+ const r = parseResource(MEMORY_YAML) as MemoryConfigResource;
110
+ assert.strictEqual(r.kind, "MemoryConfig");
111
+ assert.strictEqual(r.metadata.name, "agent-memory-default");
112
+ assert.strictEqual(r.spec.memory.thread.store.type, "in_memory");
113
+ assert.strictEqual(r.spec.memory.thread.maxItems, 20);
114
+ assert.deepStrictEqual(r.spec.privacy?.forbiddenMetadataKeys, [
115
+ "password",
116
+ "api_key",
117
+ ]);
118
+ });
119
+
120
+ it("parseResource parses SkillsConfig", () => {
121
+ const r = parseResource(SKILLS_YAML) as SkillsConfigResource;
122
+ assert.strictEqual(r.kind, "SkillsConfig");
123
+ assert.ok(r.spec.skills["file:./skills"]);
124
+ assert.ok(r.spec.skills["file:~/.deepagents/agent/skills"]);
125
+ });
126
+
127
+ it("parseResource parses AgentRuntimeConfig", () => {
128
+ const r = parseResource(RUNTIME_YAML) as AgentRuntimeConfigResource;
129
+ assert.strictEqual(r.kind, "AgentRuntimeConfig");
130
+ assert.strictEqual(r.spec.systemPrompt, "You are a runtime test agent.");
131
+ assert.strictEqual(r.spec.backend?.type, "local_shell");
132
+ assert.strictEqual(r.spec.malformedToolCallMaxRetries, 1);
133
+ assert.strictEqual(r.spec.debug?.toolCall, true);
134
+ assert.strictEqual(r.spec.debug?.stream, false);
135
+ assert.strictEqual(r.spec.eventLogLevel, "tools");
136
+ });
137
+
138
+ it("loadFromString parses single-doc YAML", () => {
139
+ const r = loadFromString(MEMORY_YAML);
140
+ assert.strictEqual(r.kind, "MemoryConfig");
141
+ });
142
+
143
+ it("rejects invalid apiVersion", () => {
144
+ assert.throws(
145
+ () =>
146
+ parseResource(`
147
+ apiVersion: v1
148
+ kind: MemoryConfig
149
+ metadata:
150
+ name: x
151
+ spec:
152
+ memory:
153
+ thread:
154
+ store: { type: in_memory }
155
+ allowWrite: true
156
+ maxItems: 1
157
+ cross_thread:
158
+ store: { type: in_memory }
159
+ allowWrite: true
160
+ maxItems: 1
161
+ knowledge:
162
+ store: { type: in_memory }
163
+ allowWrite: true
164
+ maxItems: 1
165
+ `),
166
+ (err: unknown) => err instanceof ConfigError && err.message.includes("apiVersion")
167
+ );
168
+ });
169
+
170
+ it("rejects unsupported kind", () => {
171
+ assert.throws(
172
+ () =>
173
+ parseResource(`
174
+ apiVersion: botbotgo.world/v1
175
+ kind: UnknownKind
176
+ metadata:
177
+ name: x
178
+ spec: {}
179
+ `),
180
+ (err: unknown) => err instanceof ConfigError && err.message.includes("kind")
181
+ );
182
+ });
183
+
184
+ it("parseAllResources returns multiple docs", () => {
185
+ const multi = MEMORY_YAML + "\n---\n" + SKILLS_YAML;
186
+ const list = parseAllResources(multi);
187
+ assert.strictEqual(list.length, 2);
188
+ assert.strictEqual(list[0].kind, "MemoryConfig");
189
+ assert.strictEqual(list[1].kind, "SkillsConfig");
190
+ });
191
+
192
+ it("loadFromFile loads MemoryConfig from disk", async () => {
193
+ const path = join(projectRoot(), "config", "examples", "memory.yaml");
194
+ const r = await loadFromFile(path) as MemoryConfigResource;
195
+ assert.strictEqual(r.kind, "MemoryConfig");
196
+ assert.strictEqual(r.metadata.name, "agent-memory-default");
197
+ assert.strictEqual(r.spec.memory.thread.store.type, "in_memory");
198
+ assert.deepStrictEqual(r.spec.privacy?.forbiddenMetadataKeys, [
199
+ "password",
200
+ "api_key",
201
+ "secret",
202
+ "token",
203
+ ]);
204
+ });
205
+
206
+ it("loadFromDirectory loads all YAML resources from config/examples", async () => {
207
+ const dir = join(projectRoot(), "config", "examples");
208
+ const resources = await loadFromDirectory(dir, { ignoreInvalid: true });
209
+ assert.ok(resources.length >= 3);
210
+ const kinds = resources.map((r) => r.kind).sort();
211
+ assert.ok(kinds.includes("AgentRuntimeConfig"));
212
+ assert.ok(kinds.includes("MemoryConfig"));
213
+ assert.ok(kinds.includes("SkillsConfig"));
214
+ });
215
+
216
+ it("loadFromFile throws ConfigError with path when file not found", async () => {
217
+ const path = join(projectRoot(), "config", "nonexistent.yaml");
218
+ await assert.rejects(
219
+ async () => loadFromFile(path),
220
+ (err: unknown) => {
221
+ return err instanceof ConfigError && err.path === path;
222
+ }
223
+ );
224
+ });
225
+
226
+ it("parseResource rejects empty YAML", () => {
227
+ assert.throws(
228
+ () => parseResource(""),
229
+ (err: unknown) => err instanceof ConfigError && err.message.includes("empty")
230
+ );
231
+ });
232
+
233
+ it("parseResource rejects missing metadata.name", () => {
234
+ assert.throws(
235
+ () =>
236
+ parseResource(`
237
+ apiVersion: botbotgo.world/v1
238
+ kind: MemoryConfig
239
+ metadata: {}
240
+ spec:
241
+ memory:
242
+ thread:
243
+ store: { type: in_memory }
244
+ allowWrite: true
245
+ maxItems: 1
246
+ cross_thread:
247
+ store: { type: in_memory }
248
+ allowWrite: true
249
+ maxItems: 1
250
+ knowledge:
251
+ store: { type: in_memory }
252
+ allowWrite: true
253
+ maxItems: 1
254
+ `),
255
+ (err: unknown) => err instanceof ConfigError
256
+ );
257
+ });
258
+
259
+ it("parseAllResources with ignoreInvalid skips invalid doc and returns valid ones", () => {
260
+ const yaml = `
261
+ apiVersion: botbotgo.world/v1
262
+ kind: MemoryConfig
263
+ metadata:
264
+ name: valid
265
+ spec:
266
+ memory:
267
+ thread:
268
+ store: { type: in_memory }
269
+ allowWrite: true
270
+ maxItems: 1
271
+ cross_thread:
272
+ store: { type: in_memory }
273
+ allowWrite: true
274
+ maxItems: 1
275
+ knowledge:
276
+ store: { type: in_memory }
277
+ allowWrite: true
278
+ maxItems: 1
279
+ ---
280
+ apiVersion: v1
281
+ kind: Bad
282
+ metadata: { name: bad }
283
+ spec: {}
284
+ ---
285
+ apiVersion: botbotgo.world/v1
286
+ kind: SkillsConfig
287
+ metadata:
288
+ name: skills
289
+ spec:
290
+ skills:
291
+ file:./a: {}
292
+ `;
293
+ const list = parseAllResources(yaml, { ignoreInvalid: true });
294
+ assert.strictEqual(list.length, 2);
295
+ assert.strictEqual(list[0].kind, "MemoryConfig");
296
+ assert.strictEqual(list[1].kind, "SkillsConfig");
297
+ });
298
+
299
+ it("isMemoryConfig and isSkillsConfig type guards", () => {
300
+ const memory = parseResource(MEMORY_YAML);
301
+ const skills = parseResource(SKILLS_YAML);
302
+ const runtime = parseResource(RUNTIME_YAML);
303
+ assert.strictEqual(isMemoryConfig(memory), true);
304
+ assert.strictEqual(isSkillsConfig(memory), false);
305
+ assert.strictEqual(isAgentRuntimeConfig(memory), false);
306
+ assert.strictEqual(isSkillsConfig(skills), true);
307
+ assert.strictEqual(isMemoryConfig(skills), false);
308
+ assert.strictEqual(isAgentRuntimeConfig(skills), false);
309
+ assert.strictEqual(isAgentRuntimeConfig(runtime), true);
310
+ });
311
+ });
312
+
313
+ describe("deepagents", () => {
314
+ it("resolveAgentConfig merges MemoryConfig and SkillsConfig", () => {
315
+ const resources = [
316
+ parseResource(MEMORY_YAML) as MemoryConfigResource,
317
+ parseResource(SKILLS_YAML) as SkillsConfigResource,
318
+ parseResource(RUNTIME_YAML) as AgentRuntimeConfigResource,
319
+ ];
320
+ const resolved = resolveAgentConfig(resources);
321
+ assert.ok(resolved.memory);
322
+ assert.strictEqual(resolved.memory!.thread.store.type, "in_memory");
323
+ assert.strictEqual(resolved.memory!.thread.sessionCompaction?.summaryKey, "__session_summary__");
324
+ assert.deepStrictEqual(resolved.skills, []);
325
+ assert.strictEqual(resolved.observability.trace, false);
326
+ assert.deepStrictEqual(resolved.privacy.forbiddenMetadataKeys, ["password", "api_key"]);
327
+ assert.strictEqual(resolved.runtime.backend?.type, "local_shell");
328
+ assert.strictEqual(resolved.runtime.backend?.timeoutMs, 20000);
329
+ assert.strictEqual(resolved.runtime.incompleteRunMaxRetries, 2);
330
+ assert.strictEqual(resolved.runtime.executeTimeoutMs, 45000);
331
+ assert.strictEqual(resolved.runtime.systemPrompt, "You are a runtime test agent.");
332
+ assert.strictEqual(resolved.runtime.llmIdleTimeoutMs, 300000);
333
+ assert.strictEqual(resolved.runtime.heartbeatIntervalMs, 10000);
334
+ assert.strictEqual(resolved.runtime.debug?.run, true);
335
+ assert.strictEqual(resolved.runtime.debug?.stream, false);
336
+ assert.strictEqual(resolved.runtime.eventLogLevel, "tools");
337
+ assert.strictEqual(resolved.runtime.artifacts?.[0]?.path, "output/report.html");
338
+ });
339
+
340
+ it("buildDeepAgentOptions returns skills array and _resolved", () => {
341
+ const resources = [
342
+ parseResource(SKILLS_YAML) as SkillsConfigResource,
343
+ ];
344
+ const resolved = resolveAgentConfig(resources);
345
+ const opts = buildDeepAgentOptions(resolved);
346
+ assert.deepStrictEqual(opts.skills, []);
347
+ assert.strictEqual(opts._resolved, resolved);
348
+ });
349
+
350
+ it("resolveAgentConfig with empty resources returns defaults", () => {
351
+ const resolved = resolveAgentConfig([]);
352
+ assert.strictEqual(resolved.skills.length, 0);
353
+ assert.strictEqual(resolved.memory, null);
354
+ assert.strictEqual(resolved.observability.trace, false);
355
+ assert.deepStrictEqual(resolved.privacy.forbiddenMetadataKeys, []);
356
+ assert.deepStrictEqual(resolved.runtime, {});
357
+ });
358
+
359
+ it("resolveAgentConfig with only MemoryConfig has no skills", () => {
360
+ const resources = [parseResource(MEMORY_YAML) as MemoryConfigResource];
361
+ const resolved = resolveAgentConfig(resources);
362
+ assert.deepStrictEqual(resolved.skills, []);
363
+ assert.ok(resolved.memory);
364
+ assert.deepStrictEqual(resolved.privacy.forbiddenMetadataKeys, ["password", "api_key"]);
365
+ });
366
+
367
+ it("resolveAgentConfig with only SkillsConfig has no memory", () => {
368
+ const resources = [parseResource(SKILLS_YAML) as SkillsConfigResource];
369
+ const resolved = resolveAgentConfig(resources);
370
+ assert.strictEqual(resolved.memory, null);
371
+ assert.deepStrictEqual(resolved.skills, []);
372
+ });
373
+
374
+ it("resolveAgentConfig ignores SkillsConfig source resolution", () => {
375
+ const skills2 = `
376
+ apiVersion: botbotgo.world/v1
377
+ kind: SkillsConfig
378
+ metadata:
379
+ name: extra
380
+ spec:
381
+ skills:
382
+ file:/extra/skills: {}
383
+ `;
384
+ const resources = [
385
+ parseResource(SKILLS_YAML) as SkillsConfigResource,
386
+ parseResource(skills2) as SkillsConfigResource,
387
+ ];
388
+ const resolved = resolveAgentConfig(resources);
389
+ assert.deepStrictEqual(resolved.skills, []);
390
+ });
391
+
392
+ it("buildDeepAgentOptions with no skills returns empty skills array", () => {
393
+ const resolved = resolveAgentConfig([]);
394
+ const opts = buildDeepAgentOptions(resolved);
395
+ assert.deepStrictEqual(opts.skills, []);
396
+ assert.strictEqual(opts._resolved.memory, null);
397
+ });
398
+ });
399
+
400
+ describe("loadAgentRuntimeConfig", () => {
401
+ it("loads from configDir without resolving skill roots", async () => {
402
+ const root = projectRoot();
403
+ const configDir = join(root, "config", "examples");
404
+ const runtimeConfig = await loadAgentRuntimeConfig({
405
+ configDir,
406
+ ignoreInvalid: true,
407
+ });
408
+ assert.ok(runtimeConfig.resolved);
409
+ assert.ok(runtimeConfig.resolved.memory);
410
+ assert.deepStrictEqual(runtimeConfig.resolved.skills, []);
411
+ });
412
+
413
+ it("accepts pre-loaded resources without resolving SkillsConfig entries", async () => {
414
+ const resources = [
415
+ parseResource(SKILLS_YAML) as SkillsConfigResource,
416
+ ];
417
+ const runtimeConfig = await loadAgentRuntimeConfig({
418
+ resources,
419
+ });
420
+ assert.strictEqual(runtimeConfig.resolved.skills.length, 0);
421
+ });
422
+
423
+ it("throws when no config source provided", async () => {
424
+ await assert.rejects(
425
+ async () => loadAgentRuntimeConfig({}),
426
+ (err: unknown) => (err as Error).message.includes("configPath") || (err as Error).message.includes("configDir") || (err as Error).message.includes("resources")
427
+ );
428
+ });
429
+ });
@@ -0,0 +1,23 @@
1
+ import test from "node:test";
2
+ import assert from "node:assert/strict";
3
+ import { AgentContextTokens, getDefaultAgentContext } from "@botbotgo/common/context";
4
+ import {
5
+ requireAgentRuntimeChatModel,
6
+ requireAgentRuntimeMemory,
7
+ requireAgentRuntimeTools,
8
+ } from "../../../src/runtime/context/agentContext.ts";
9
+
10
+ test("agent-runtime2 reads dependencies from AgentContext", () => {
11
+ const context = getDefaultAgentContext();
12
+ const chatModel = { kind: "chat" };
13
+ const memory = { kind: "memory" };
14
+ const tools = [{ name: "tool-a" }];
15
+
16
+ context.set(AgentContextTokens.ChatModel, chatModel);
17
+ context.set(AgentContextTokens.Memory, memory);
18
+ context.set(AgentContextTokens.Tools, tools);
19
+
20
+ assert.equal(requireAgentRuntimeChatModel(), chatModel);
21
+ assert.equal(requireAgentRuntimeMemory(), memory);
22
+ assert.equal(requireAgentRuntimeTools(), tools);
23
+ });
@@ -0,0 +1,99 @@
1
+ import test from "node:test";
2
+ import assert from "node:assert/strict";
3
+ import { mkdir, rm, writeFile } from "node:fs/promises";
4
+ import { tmpdir } from "node:os";
5
+ import { join } from "node:path";
6
+ import { createAgentEventBus } from "@botbotgo/common/events";
7
+ import { AgentRuntimeService } from "../../../src/runtime/runtimeService.ts";
8
+ import { AgentRuntimeEventPublisher } from "../../../src/runtime/events/eventPublisher.ts";
9
+ import { AgentRunExecutor } from "../../../src/runtime/execution/agentRunExecutor.ts";
10
+
11
+ test("runtime eventListener setter replaces subscriptions", () => {
12
+ const runtime = new AgentRuntimeService({
13
+ rootDir: "/tmp/runtime",
14
+ runLogger: () => {},
15
+ events: new AgentRuntimeEventPublisher(createAgentEventBus()),
16
+ runtimeConfig: {} as never,
17
+ middleware: {},
18
+ workspace: {
19
+ prepareRun: (() => {
20
+ throw new Error("not used");
21
+ }) as never,
22
+ } as never,
23
+ runtimeAgent: {
24
+ agent: {},
25
+ close: async () => {},
26
+ } as never,
27
+ });
28
+
29
+ const received: string[] = [];
30
+ runtime.eventListener = (event) => {
31
+ received.push(`first:${event.name}`);
32
+ };
33
+ runtime.events.publish({
34
+ name: "event.one",
35
+ from: "a",
36
+ to: "b",
37
+ });
38
+
39
+ runtime.eventListener = (event) => {
40
+ received.push(`second:${event.name}`);
41
+ };
42
+ runtime.events.publish({
43
+ name: "event.two",
44
+ from: "a",
45
+ to: "b",
46
+ });
47
+
48
+ runtime.eventListener = undefined;
49
+ runtime.events.publish({
50
+ name: "event.three",
51
+ from: "a",
52
+ to: "b",
53
+ });
54
+
55
+ assert.deepEqual(received, ["first:event.one", "second:event.two"]);
56
+ });
57
+
58
+ test("AgentRunExecutor applies custom artifactValidator without use-case-specific framework logic", async () => {
59
+ const rootDir = join(tmpdir(), `agent-runtime2-validator-${Date.now()}`);
60
+ const outputDir = join(rootDir, "output");
61
+ const artifactPath = join(outputDir, "result.json");
62
+ await mkdir(outputDir, { recursive: true });
63
+ await writeFile(artifactPath, "{\"ok\":true}\n", "utf8");
64
+
65
+ const executor = new AgentRunExecutor({
66
+ rootDir,
67
+ workspace: {
68
+ artifactFiles: { result: artifactPath },
69
+ runStateFile: join(rootDir, ".agent", "run-state.json"),
70
+ todosFile: join(rootDir, ".agent", "todos.json"),
71
+ prepareRun: async () => ({
72
+ threadId: "t-1",
73
+ input: { messages: [] },
74
+ config: { configurable: { thread_id: "t-1" } },
75
+ previousState: undefined,
76
+ start: async () => {},
77
+ update: async () => {},
78
+ finish: async () => {},
79
+ }),
80
+ } as never,
81
+ events: new AgentRuntimeEventPublisher(createAgentEventBus()),
82
+ runLogger: () => {},
83
+ artifactValidator: () => false,
84
+ });
85
+
86
+ await assert.rejects(
87
+ executor.runStream({
88
+ prompt: "write to output/result.json",
89
+ incompleteRunMaxRetries: 0,
90
+ summarizeChunk: () => "done",
91
+ createStream: async function* () {
92
+ yield { ok: true };
93
+ },
94
+ }),
95
+ /Run ended before completion/,
96
+ );
97
+
98
+ await rm(rootDir, { recursive: true, force: true });
99
+ });
@@ -0,0 +1,52 @@
1
+ import test from "node:test";
2
+ import assert from "node:assert/strict";
3
+ import { ConsoleHumanLoopService } from "../../../src/runtime/human-loop/consoleHumanLoop.ts";
4
+ import type { HumanLoopRequest } from "../../../src/runtime/human-loop/humanLoop.ts";
5
+
6
+ const baseRequest: HumanLoopRequest = {
7
+ id: "req-1",
8
+ kind: "tool_approval",
9
+ threadId: "thread-1",
10
+ toolCallId: "call-1",
11
+ toolName: "execute",
12
+ title: "Approval required for execute",
13
+ description: "Command: printf unsafe",
14
+ args: { command: "printf unsafe" },
15
+ rootDir: "/workspace",
16
+ createdAt: "2026-03-06T00:00:00.000Z",
17
+ riskLevel: "high",
18
+ };
19
+
20
+ test("ConsoleHumanLoopService approves after prompt", async () => {
21
+ const questions: string[] = [];
22
+ const lines: string[] = [];
23
+ const service = new ConsoleHumanLoopService({
24
+ prompt: async (question) => {
25
+ questions.push(question);
26
+ return "a";
27
+ },
28
+ writer: (line) => {
29
+ lines.push(line);
30
+ },
31
+ });
32
+
33
+ const decision = await service.request(baseRequest);
34
+
35
+ assert.equal(decision.action, "approve");
36
+ assert.equal(questions[0], "Approve, reject, or revise? [a/r/e]: ");
37
+ assert.match(lines.join("\n"), /\[human-loop\] Approval required for execute/);
38
+ });
39
+
40
+ test("ConsoleHumanLoopService revises args from JSON input", async () => {
41
+ const answers = ["e", "{\"command\":\"printf safe\"}", "Use safe command."];
42
+ const service = new ConsoleHumanLoopService({
43
+ prompt: async () => answers.shift() ?? "",
44
+ writer: () => {},
45
+ });
46
+
47
+ const decision = await service.request(baseRequest);
48
+
49
+ assert.equal(decision.action, "revise");
50
+ assert.deepEqual(decision.revisedArgs, { command: "printf safe" });
51
+ assert.equal(decision.message, "Use safe command.");
52
+ });
@@ -0,0 +1,11 @@
1
+ import test from "node:test";
2
+ import assert from "node:assert/strict";
3
+ import { createAgentEventBus } from "@botbotgo/common";
4
+ import { AgentRuntimeEventPublisher } from "../../../src/runtime/events/eventPublisher.ts";
5
+
6
+ test("runtime event publisher reuses AgentContext event bus", () => {
7
+ const eventBus = createAgentEventBus();
8
+ const publisher = new AgentRuntimeEventPublisher();
9
+
10
+ assert.equal(publisher.bus, eventBus);
11
+ });
@@ -0,0 +1,34 @@
1
+ import test from "node:test";
2
+ import assert from "node:assert/strict";
3
+ import {
4
+ clearAgentRuntimeGlobalContext,
5
+ getAgentRuntimeGlobal,
6
+ getOrRegisterAgentRuntimeGlobal,
7
+ registerAgentRuntimeGlobal,
8
+ } from "../../../src/runtime/context/globalContext.ts";
9
+
10
+ test("global context shares registered values", () => {
11
+ clearAgentRuntimeGlobalContext();
12
+ const value = { ok: true };
13
+
14
+ registerAgentRuntimeGlobal("runtime:test:value", value);
15
+
16
+ assert.equal(getAgentRuntimeGlobal("runtime:test:value"), value);
17
+ });
18
+
19
+ test("global context reuses lazily registered values", () => {
20
+ clearAgentRuntimeGlobalContext();
21
+ let created = 0;
22
+
23
+ const first = getOrRegisterAgentRuntimeGlobal("runtime:test:lazy", () => {
24
+ created += 1;
25
+ return { created };
26
+ });
27
+ const second = getOrRegisterAgentRuntimeGlobal("runtime:test:lazy", () => {
28
+ created += 1;
29
+ return { created };
30
+ });
31
+
32
+ assert.equal(created, 1);
33
+ assert.equal(first, second);
34
+ });