@elie-laloum/outpost 4.2.0 → 5.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 (450) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/README.md +5 -3
  3. package/dist/{cli/init-authentication.constants.js → adapters/agents/authentication.constants.js} +1 -1
  4. package/dist/adapters/agents/authentication.constants.js.map +1 -0
  5. package/dist/adapters/agents/authentication.d.ts +2 -0
  6. package/dist/adapters/agents/authentication.js +52 -0
  7. package/dist/adapters/agents/authentication.js.map +1 -0
  8. package/dist/adapters/agents/claude-adapter.d.ts +2 -2
  9. package/dist/adapters/agents/claude-adapter.js +30 -2
  10. package/dist/adapters/agents/claude-adapter.js.map +1 -1
  11. package/dist/adapters/agents/claude-request.d.ts +2 -2
  12. package/dist/adapters/agents/claude-request.js +3 -3
  13. package/dist/adapters/agents/claude-request.js.map +1 -1
  14. package/dist/adapters/agents/codex-adapter.d.ts +2 -2
  15. package/dist/adapters/agents/codex-adapter.js +17 -1
  16. package/dist/adapters/agents/codex-adapter.js.map +1 -1
  17. package/dist/adapters/agents/codex-provider.d.ts +2 -2
  18. package/dist/adapters/agents/codex-provider.js +1 -1
  19. package/dist/adapters/agents/codex-provider.js.map +1 -1
  20. package/dist/adapters/agents/codex-request.d.ts +2 -2
  21. package/dist/adapters/agents/codex-request.js +3 -3
  22. package/dist/adapters/agents/codex-request.js.map +1 -1
  23. package/dist/adapters/agents/gemini-adapter.d.ts +2 -2
  24. package/dist/adapters/agents/gemini-adapter.js +20 -1
  25. package/dist/adapters/agents/gemini-adapter.js.map +1 -1
  26. package/dist/adapters/agents/gemini-request.d.ts +2 -1
  27. package/dist/adapters/agents/gemini-request.js +1 -1
  28. package/dist/adapters/agents/gemini-request.js.map +1 -1
  29. package/dist/adapters/agents/gemini.types.d.ts +2 -1
  30. package/dist/adapters/agents/gemini.types.js.map +1 -1
  31. package/dist/adapters/agents/model-support.constants.d.ts +6 -0
  32. package/dist/adapters/agents/model-support.constants.js +18 -0
  33. package/dist/adapters/agents/model-support.constants.js.map +1 -0
  34. package/dist/adapters/agents/model-support.d.ts +4 -0
  35. package/dist/adapters/agents/model-support.js +11 -0
  36. package/dist/adapters/agents/model-support.js.map +1 -0
  37. package/dist/adapters/agents/settings.types.d.ts +11 -3
  38. package/dist/adapters/agents/settings.types.js.map +1 -1
  39. package/dist/adapters/models/anthropic-model-provider.constants.d.ts +3 -0
  40. package/dist/adapters/models/anthropic-model-provider.constants.js +17 -0
  41. package/dist/adapters/models/anthropic-model-provider.constants.js.map +1 -0
  42. package/dist/adapters/models/anthropic-model-provider.d.ts +3 -0
  43. package/dist/adapters/models/anthropic-model-provider.js +31 -0
  44. package/dist/adapters/models/anthropic-model-provider.js.map +1 -0
  45. package/dist/adapters/models/anthropic-model-provider.types.d.ts +7 -0
  46. package/dist/adapters/models/anthropic-model-provider.types.js +2 -0
  47. package/dist/adapters/models/anthropic-model-provider.types.js.map +1 -0
  48. package/dist/adapters/models/anthropic-request.d.ts +4 -0
  49. package/dist/adapters/models/anthropic-request.js +81 -0
  50. package/dist/adapters/models/anthropic-request.js.map +1 -0
  51. package/dist/adapters/models/anthropic-response.d.ts +3 -0
  52. package/dist/adapters/models/anthropic-response.js +55 -0
  53. package/dist/adapters/models/anthropic-response.js.map +1 -0
  54. package/dist/adapters/models/anthropic-stream.d.ts +2 -0
  55. package/dist/adapters/models/anthropic-stream.js +96 -0
  56. package/dist/adapters/models/anthropic-stream.js.map +1 -0
  57. package/dist/adapters/models/http-provider.d.ts +3 -0
  58. package/dist/adapters/models/http-provider.js +113 -0
  59. package/dist/adapters/models/http-provider.js.map +1 -0
  60. package/dist/adapters/models/{openai-http.js → model-http.js} +1 -1
  61. package/dist/adapters/models/model-http.js.map +1 -0
  62. package/dist/adapters/models/model-protocol.types.d.ts +41 -0
  63. package/dist/adapters/models/model-protocol.types.js +2 -0
  64. package/dist/adapters/models/model-protocol.types.js.map +1 -0
  65. package/dist/adapters/models/model-request.d.ts +2 -0
  66. package/dist/adapters/models/model-request.js +18 -0
  67. package/dist/adapters/models/model-request.js.map +1 -0
  68. package/dist/adapters/models/model-response.d.ts +7 -0
  69. package/dist/adapters/models/model-response.js +41 -0
  70. package/dist/adapters/models/model-response.js.map +1 -0
  71. package/dist/adapters/models/{openai-compatible.constants.js → model.constants.js} +6 -1
  72. package/dist/adapters/models/model.constants.js.map +1 -0
  73. package/dist/adapters/models/openai-chat-stream.d.ts +2 -0
  74. package/dist/adapters/models/openai-chat-stream.js +66 -0
  75. package/dist/adapters/models/openai-chat-stream.js.map +1 -0
  76. package/dist/adapters/models/openai-chat.d.ts +4 -0
  77. package/dist/adapters/models/openai-chat.js +108 -0
  78. package/dist/adapters/models/openai-chat.js.map +1 -0
  79. package/dist/adapters/models/openai-model-provider.d.ts +3 -0
  80. package/dist/adapters/models/openai-model-provider.js +13 -0
  81. package/dist/adapters/models/openai-model-provider.js.map +1 -0
  82. package/dist/adapters/models/openai-model-provider.types.d.ts +4 -0
  83. package/dist/adapters/models/openai-model-provider.types.js +2 -0
  84. package/dist/adapters/models/openai-model-provider.types.js.map +1 -0
  85. package/dist/adapters/models/openai-protocols.d.ts +2 -0
  86. package/dist/adapters/models/openai-protocols.js +22 -0
  87. package/dist/adapters/models/openai-protocols.js.map +1 -0
  88. package/dist/adapters/models/openai-responses-stream.d.ts +2 -0
  89. package/dist/adapters/models/openai-responses-stream.js +35 -0
  90. package/dist/adapters/models/openai-responses-stream.js.map +1 -0
  91. package/dist/adapters/models/openai-responses.d.ts +4 -0
  92. package/dist/adapters/models/openai-responses.js +107 -0
  93. package/dist/adapters/models/openai-responses.js.map +1 -0
  94. package/dist/adapters/models/openai-usage.d.ts +3 -0
  95. package/dist/adapters/models/openai-usage.js +20 -0
  96. package/dist/adapters/models/openai-usage.js.map +1 -0
  97. package/dist/adapters/models/stop-reasons.constants.d.ts +4 -0
  98. package/dist/adapters/models/stop-reasons.constants.js +19 -0
  99. package/dist/adapters/models/stop-reasons.constants.js.map +1 -0
  100. package/dist/adapters/models/stream-events.d.ts +3 -0
  101. package/dist/adapters/models/stream-events.js +22 -0
  102. package/dist/adapters/models/stream-events.js.map +1 -0
  103. package/dist/adapters/tools/edit-tools.d.ts +2 -0
  104. package/dist/adapters/tools/edit-tools.js +84 -0
  105. package/dist/adapters/tools/edit-tools.js.map +1 -0
  106. package/dist/adapters/tools/file-tools.d.ts +2 -0
  107. package/dist/adapters/tools/file-tools.js +97 -0
  108. package/dist/adapters/tools/file-tools.js.map +1 -0
  109. package/dist/adapters/tools/git-tools.d.ts +2 -0
  110. package/dist/adapters/tools/git-tools.js +54 -0
  111. package/dist/adapters/tools/git-tools.js.map +1 -0
  112. package/dist/adapters/tools/sandbox-files.d.ts +10 -0
  113. package/dist/adapters/tools/sandbox-files.js +60 -0
  114. package/dist/adapters/tools/sandbox-files.js.map +1 -0
  115. package/dist/adapters/tools/search-tools.d.ts +2 -0
  116. package/dist/adapters/tools/search-tools.js +65 -0
  117. package/dist/adapters/tools/search-tools.js.map +1 -0
  118. package/dist/adapters/tools/shell-tools.d.ts +3 -0
  119. package/dist/adapters/tools/shell-tools.js +38 -0
  120. package/dist/adapters/tools/shell-tools.js.map +1 -0
  121. package/dist/adapters/tools/tools.constants.d.ts +11 -0
  122. package/dist/adapters/tools/tools.constants.js +17 -0
  123. package/dist/adapters/tools/tools.constants.js.map +1 -0
  124. package/dist/adapters/tools/tools.types.d.ts +41 -0
  125. package/dist/adapters/tools/tools.types.js +2 -0
  126. package/dist/adapters/tools/tools.types.js.map +1 -0
  127. package/dist/application/activity-watchdog.js +15 -2
  128. package/dist/application/activity-watchdog.js.map +1 -1
  129. package/dist/application/agent-bootstrap.d.ts +2 -2
  130. package/dist/application/agent-bootstrap.js +2 -0
  131. package/dist/application/agent-bootstrap.js.map +1 -1
  132. package/dist/application/agent-storage.d.ts +3 -2
  133. package/dist/application/agent-storage.js +9 -2
  134. package/dist/application/agent-storage.js.map +1 -1
  135. package/dist/application/agent-turn.d.ts +3 -3
  136. package/dist/application/agent-turn.js +7 -1
  137. package/dist/application/agent-turn.js.map +1 -1
  138. package/dist/application/attach.js +1 -0
  139. package/dist/application/attach.js.map +1 -1
  140. package/dist/application/custom-turn.d.ts +5 -0
  141. package/dist/application/custom-turn.js +190 -0
  142. package/dist/application/custom-turn.js.map +1 -0
  143. package/dist/application/dispatch-observation.d.ts +3 -0
  144. package/dist/application/dispatch-observation.js +51 -0
  145. package/dist/application/dispatch-observation.js.map +1 -0
  146. package/dist/application/dispatch-observation.types.d.ts +5 -0
  147. package/dist/application/dispatch-observation.types.js +2 -0
  148. package/dist/application/dispatch-observation.types.js.map +1 -0
  149. package/dist/application/dispatch-validation.d.ts +2 -2
  150. package/dist/application/dispatch-validation.js.map +1 -1
  151. package/dist/application/dispatch.js +8 -3
  152. package/dist/application/dispatch.js.map +1 -1
  153. package/dist/application/doctor-image.js +3 -3
  154. package/dist/application/doctor-image.js.map +1 -1
  155. package/dist/application/doctor-protocol.js +9 -4
  156. package/dist/application/doctor-protocol.js.map +1 -1
  157. package/dist/application/doctor-sandbox.js +4 -4
  158. package/dist/application/doctor-sandbox.js.map +1 -1
  159. package/dist/application/doctor-sandbox.types.d.ts +2 -2
  160. package/dist/application/doctor-sandbox.types.js.map +1 -1
  161. package/dist/application/doctor.constants.d.ts +1 -1
  162. package/dist/application/doctor.constants.js +1 -1
  163. package/dist/application/doctor.constants.js.map +1 -1
  164. package/dist/application/doctor.js +10 -9
  165. package/dist/application/doctor.js.map +1 -1
  166. package/dist/application/doctor.types.d.ts +3 -3
  167. package/dist/application/doctor.types.js.map +1 -1
  168. package/dist/application/execution.d.ts +2 -2
  169. package/dist/application/execution.js +1 -1
  170. package/dist/application/execution.js.map +1 -1
  171. package/dist/application/execution.types.d.ts +9 -2
  172. package/dist/application/execution.types.js.map +1 -1
  173. package/dist/application/harness-context.d.ts +2 -0
  174. package/dist/application/harness-context.js +54 -0
  175. package/dist/application/harness-context.js.map +1 -0
  176. package/dist/application/harness-history.d.ts +3 -0
  177. package/dist/application/harness-history.js +17 -0
  178. package/dist/application/harness-history.js.map +1 -0
  179. package/dist/application/harness-hooks.d.ts +9 -0
  180. package/dist/application/harness-hooks.js +90 -0
  181. package/dist/application/harness-hooks.js.map +1 -0
  182. package/dist/application/harness-loop.d.ts +2 -0
  183. package/dist/application/harness-loop.js +132 -0
  184. package/dist/application/harness-loop.js.map +1 -0
  185. package/dist/application/harness.types.d.ts +55 -0
  186. package/dist/application/harness.types.js +2 -0
  187. package/dist/application/harness.types.js.map +1 -0
  188. package/dist/application/lifecycle.constants.d.ts +1 -1
  189. package/dist/application/lifecycle.constants.js +1 -1
  190. package/dist/application/lifecycle.constants.js.map +1 -1
  191. package/dist/application/outpost.types.d.ts +6 -6
  192. package/dist/application/outpost.types.js.map +1 -1
  193. package/dist/application/remote-download.js +1 -1
  194. package/dist/application/remote-download.js.map +1 -1
  195. package/dist/application/sandbox-agents.js +12 -4
  196. package/dist/application/sandbox-agents.js.map +1 -1
  197. package/dist/application/sandbox-attach.js +5 -2
  198. package/dist/application/sandbox-attach.js.map +1 -1
  199. package/dist/application/sandbox-dispatch.js +3 -3
  200. package/dist/application/sandbox-dispatch.js.map +1 -1
  201. package/dist/application/sandbox-provision.js +13 -10
  202. package/dist/application/sandbox-provision.js.map +1 -1
  203. package/dist/application/sandbox-session.types.d.ts +8 -8
  204. package/dist/application/sandbox-session.types.js.map +1 -1
  205. package/dist/application/sandbox.js +6 -3
  206. package/dist/application/sandbox.js.map +1 -1
  207. package/dist/application/speculation.js +1 -1
  208. package/dist/application/speculation.js.map +1 -1
  209. package/dist/application/speculation.types.d.ts +3 -3
  210. package/dist/application/speculation.types.js.map +1 -1
  211. package/dist/application/tasks.types.d.ts +2 -2
  212. package/dist/application/tasks.types.js.map +1 -1
  213. package/dist/application/tool-execution.d.ts +3 -0
  214. package/dist/application/tool-execution.js +211 -0
  215. package/dist/application/tool-execution.js.map +1 -0
  216. package/dist/cli/commands.js +4 -2
  217. package/dist/cli/commands.js.map +1 -1
  218. package/dist/cli/doctor-command.js +6 -6
  219. package/dist/cli/doctor-command.js.map +1 -1
  220. package/dist/cli/init-authentication.js +6 -7
  221. package/dist/cli/init-authentication.js.map +1 -1
  222. package/dist/cli/init-command.js +3 -3
  223. package/dist/cli/init-command.js.map +1 -1
  224. package/dist/cli/main.constants.d.ts +4 -4
  225. package/dist/cli/main.constants.js +4 -4
  226. package/dist/cli/main.constants.js.map +1 -1
  227. package/dist/cli/recovery-command.js +1 -1
  228. package/dist/cli/recovery-command.js.map +1 -1
  229. package/dist/cli/scaffold-files.js +5 -4
  230. package/dist/cli/scaffold-files.js.map +1 -1
  231. package/dist/cli/scaffold-validation.js +13 -10
  232. package/dist/cli/scaffold-validation.js.map +1 -1
  233. package/dist/cli/scaffold.js +8 -4
  234. package/dist/cli/scaffold.js.map +1 -1
  235. package/dist/cli/scaffold.types.d.ts +1 -1
  236. package/dist/cli/scaffold.types.js.map +1 -1
  237. package/dist/cli/starters.js +8 -8
  238. package/dist/cli/starters.js.map +1 -1
  239. package/dist/domain/agent-model.d.ts +3 -0
  240. package/dist/domain/agent-model.js +22 -0
  241. package/dist/domain/agent-model.js.map +1 -0
  242. package/dist/domain/agent.d.ts +4 -0
  243. package/dist/domain/agent.js +32 -0
  244. package/dist/domain/agent.js.map +1 -0
  245. package/dist/domain/agent.types.d.ts +69 -2
  246. package/dist/domain/agent.types.js.map +1 -1
  247. package/dist/domain/context.constants.d.ts +7 -0
  248. package/dist/domain/context.constants.js +8 -0
  249. package/dist/domain/context.constants.js.map +1 -0
  250. package/dist/domain/context.d.ts +4 -0
  251. package/dist/domain/context.js +81 -0
  252. package/dist/domain/context.js.map +1 -0
  253. package/dist/domain/context.types.d.ts +26 -0
  254. package/dist/domain/context.types.js +2 -0
  255. package/dist/domain/context.types.js.map +1 -0
  256. package/dist/domain/dispatch-telemetry.types.d.ts +12 -0
  257. package/dist/domain/dispatch-telemetry.types.js +2 -0
  258. package/dist/domain/dispatch-telemetry.types.js.map +1 -0
  259. package/dist/domain/errors.types.d.ts +1 -1
  260. package/dist/domain/errors.types.js.map +1 -1
  261. package/dist/domain/glob.d.ts +2 -0
  262. package/dist/domain/glob.js +25 -0
  263. package/dist/domain/glob.js.map +1 -0
  264. package/dist/domain/glob.types.d.ts +1 -0
  265. package/dist/domain/glob.types.js +2 -0
  266. package/dist/domain/glob.types.js.map +1 -0
  267. package/dist/domain/harness.constants.d.ts +11 -0
  268. package/dist/domain/harness.constants.js +24 -0
  269. package/dist/domain/harness.constants.js.map +1 -0
  270. package/dist/domain/harness.d.ts +2 -0
  271. package/dist/domain/harness.js +89 -0
  272. package/dist/domain/harness.js.map +1 -0
  273. package/dist/domain/harness.types.d.ts +60 -0
  274. package/dist/domain/harness.types.js +2 -0
  275. package/dist/domain/harness.types.js.map +1 -0
  276. package/dist/domain/hook.constants.d.ts +3 -0
  277. package/dist/domain/hook.constants.js +10 -0
  278. package/dist/domain/hook.constants.js.map +1 -0
  279. package/dist/domain/hook.d.ts +3 -0
  280. package/dist/domain/hook.js +25 -0
  281. package/dist/domain/hook.js.map +1 -0
  282. package/dist/domain/hook.types.d.ts +66 -0
  283. package/dist/domain/hook.types.js +2 -0
  284. package/dist/domain/hook.types.js.map +1 -0
  285. package/dist/domain/instructions.d.ts +3 -0
  286. package/dist/domain/instructions.js +25 -0
  287. package/dist/domain/instructions.js.map +1 -0
  288. package/dist/domain/model-messages.d.ts +5 -0
  289. package/dist/domain/model-messages.js +81 -0
  290. package/dist/domain/model-messages.js.map +1 -0
  291. package/dist/domain/model-messages.types.d.ts +6 -0
  292. package/dist/domain/model-messages.types.js +2 -0
  293. package/dist/domain/model-messages.types.js.map +1 -0
  294. package/dist/domain/model.constants.d.ts +4 -0
  295. package/dist/domain/model.constants.js +16 -0
  296. package/dist/domain/model.constants.js.map +1 -0
  297. package/dist/domain/model.types.d.ts +59 -2
  298. package/dist/domain/model.types.js.map +1 -1
  299. package/dist/domain/permissions.d.ts +3 -0
  300. package/dist/domain/permissions.js +92 -0
  301. package/dist/domain/permissions.js.map +1 -0
  302. package/dist/domain/permissions.types.d.ts +34 -0
  303. package/dist/domain/permissions.types.js +2 -0
  304. package/dist/domain/permissions.types.js.map +1 -0
  305. package/dist/domain/response.js +3 -2
  306. package/dist/domain/response.js.map +1 -1
  307. package/dist/domain/response.types.d.ts +12 -0
  308. package/dist/domain/response.types.js.map +1 -1
  309. package/dist/domain/skill.constants.d.ts +2 -0
  310. package/dist/domain/skill.constants.js +8 -0
  311. package/dist/domain/skill.constants.js.map +1 -0
  312. package/dist/domain/skill.d.ts +8 -0
  313. package/dist/domain/skill.js +79 -0
  314. package/dist/domain/skill.js.map +1 -0
  315. package/dist/domain/skill.types.d.ts +18 -0
  316. package/dist/domain/skill.types.js +2 -0
  317. package/dist/domain/skill.types.js.map +1 -0
  318. package/dist/domain/standard-schema.d.ts +6 -0
  319. package/dist/domain/standard-schema.js +45 -0
  320. package/dist/domain/standard-schema.js.map +1 -0
  321. package/dist/domain/tool-schema.d.ts +3 -0
  322. package/dist/domain/tool-schema.js +109 -0
  323. package/dist/domain/tool-schema.js.map +1 -0
  324. package/dist/domain/tool.constants.d.ts +4 -0
  325. package/dist/domain/tool.constants.js +36 -0
  326. package/dist/domain/tool.constants.js.map +1 -0
  327. package/dist/domain/tool.d.ts +4 -0
  328. package/dist/domain/tool.js +66 -0
  329. package/dist/domain/tool.js.map +1 -0
  330. package/dist/domain/tool.types.d.ts +62 -0
  331. package/dist/domain/tool.types.js +2 -0
  332. package/dist/domain/tool.types.js.map +1 -0
  333. package/dist/domain/transcript.d.ts +4 -0
  334. package/dist/domain/transcript.js +48 -0
  335. package/dist/domain/transcript.js.map +1 -0
  336. package/dist/domain/transcript.types.d.ts +15 -0
  337. package/dist/domain/transcript.types.js +2 -0
  338. package/dist/domain/transcript.types.js.map +1 -0
  339. package/dist/domain/workflow/workflow-state.js +13 -6
  340. package/dist/domain/workflow/workflow-state.js.map +1 -1
  341. package/dist/domain/workflow.d.ts +1 -1
  342. package/dist/domain/workflow.js.map +1 -1
  343. package/dist/domain/workflow.types.d.ts +4 -0
  344. package/dist/domain/workflow.types.js.map +1 -1
  345. package/dist/index.d.ts +34 -8
  346. package/dist/index.js +19 -4
  347. package/dist/index.js.map +1 -1
  348. package/dist/infrastructure/conversations/harness-store.d.ts +3 -0
  349. package/dist/infrastructure/conversations/harness-store.js +27 -0
  350. package/dist/infrastructure/conversations/harness-store.js.map +1 -0
  351. package/dist/infrastructure/conversations/harness-transcript.d.ts +2 -0
  352. package/dist/infrastructure/conversations/harness-transcript.js +50 -0
  353. package/dist/infrastructure/conversations/harness-transcript.js.map +1 -0
  354. package/dist/infrastructure/conversations/harness-transcript.types.d.ts +18 -0
  355. package/dist/infrastructure/conversations/harness-transcript.types.js +2 -0
  356. package/dist/infrastructure/conversations/harness-transcript.types.js.map +1 -0
  357. package/dist/infrastructure/conversations.d.ts +4 -1
  358. package/dist/infrastructure/conversations.js +3 -0
  359. package/dist/infrastructure/conversations.js.map +1 -1
  360. package/dist/infrastructure/conversations.types.d.ts +1 -0
  361. package/dist/infrastructure/conversations.types.js.map +1 -1
  362. package/dist/infrastructure/custom-reporter.d.ts +2 -0
  363. package/dist/infrastructure/custom-reporter.js +33 -0
  364. package/dist/infrastructure/custom-reporter.js.map +1 -0
  365. package/dist/infrastructure/custom-reporter.types.d.ts +13 -0
  366. package/dist/infrastructure/custom-reporter.types.js +2 -0
  367. package/dist/infrastructure/custom-reporter.types.js.map +1 -0
  368. package/dist/infrastructure/git/git.constants.d.ts +1 -1
  369. package/dist/infrastructure/git/git.constants.js +1 -0
  370. package/dist/infrastructure/git/git.constants.js.map +1 -1
  371. package/dist/infrastructure/journal.constants.d.ts +1 -0
  372. package/dist/infrastructure/journal.constants.js +2 -0
  373. package/dist/infrastructure/journal.constants.js.map +1 -0
  374. package/dist/infrastructure/journal.js +4 -1
  375. package/dist/infrastructure/journal.js.map +1 -1
  376. package/dist/infrastructure/opentelemetry-dispatch.d.ts +6 -0
  377. package/dist/infrastructure/opentelemetry-dispatch.js +70 -0
  378. package/dist/infrastructure/opentelemetry-dispatch.js.map +1 -0
  379. package/dist/infrastructure/opentelemetry.constants.d.ts +3 -0
  380. package/dist/infrastructure/opentelemetry.constants.js +3 -0
  381. package/dist/infrastructure/opentelemetry.constants.js.map +1 -1
  382. package/dist/infrastructure/opentelemetry.js +4 -0
  383. package/dist/infrastructure/opentelemetry.js.map +1 -1
  384. package/dist/infrastructure/opentelemetry.types.d.ts +3 -3
  385. package/dist/infrastructure/opentelemetry.types.js.map +1 -1
  386. package/dist/infrastructure/reporter.js +27 -2
  387. package/dist/infrastructure/reporter.js.map +1 -1
  388. package/dist/infrastructure/resource-activity-inspection.js +3 -2
  389. package/dist/infrastructure/resource-activity-inspection.js.map +1 -1
  390. package/dist/infrastructure/resource-activity.js +2 -2
  391. package/dist/infrastructure/resource-activity.js.map +1 -1
  392. package/dist/infrastructure/resource-activity.types.d.ts +2 -2
  393. package/dist/infrastructure/resource-activity.types.js.map +1 -1
  394. package/dist/infrastructure/settings.d.ts +1 -1
  395. package/dist/infrastructure/settings.js +3 -3
  396. package/dist/infrastructure/settings.js.map +1 -1
  397. package/dist/infrastructure/sse.d.ts +2 -0
  398. package/dist/infrastructure/sse.js +64 -0
  399. package/dist/infrastructure/sse.js.map +1 -0
  400. package/dist/infrastructure/sse.types.d.ts +4 -0
  401. package/dist/infrastructure/sse.types.js +2 -0
  402. package/dist/infrastructure/sse.types.js.map +1 -0
  403. package/dist/infrastructure/transport-conversations.d.ts +2 -2
  404. package/dist/infrastructure/transport-conversations.js +8 -1
  405. package/dist/infrastructure/transport-conversations.js.map +1 -1
  406. package/dist/infrastructure/transport-journal.js +2 -1
  407. package/dist/infrastructure/transport-journal.js.map +1 -1
  408. package/dist/providers/agents.d.ts +3 -3
  409. package/dist/providers/agents.js +3 -3
  410. package/dist/providers/agents.js.map +1 -1
  411. package/dist/providers/daytona.d.ts +1 -1
  412. package/dist/providers/daytona.js +1 -1
  413. package/dist/providers/daytona.js.map +1 -1
  414. package/dist/providers/docker.d.ts +1 -1
  415. package/dist/providers/docker.js +1 -1
  416. package/dist/providers/docker.js.map +1 -1
  417. package/dist/providers/factories.d.ts +2 -2
  418. package/dist/providers/factories.js +3 -3
  419. package/dist/providers/factories.js.map +1 -1
  420. package/dist/providers/firecracker.d.ts +1 -1
  421. package/dist/providers/firecracker.js +1 -1
  422. package/dist/providers/firecracker.js.map +1 -1
  423. package/dist/providers/local.d.ts +1 -1
  424. package/dist/providers/local.js +1 -1
  425. package/dist/providers/local.js.map +1 -1
  426. package/dist/providers/podman.d.ts +1 -1
  427. package/dist/providers/podman.js +1 -1
  428. package/dist/providers/podman.js.map +1 -1
  429. package/dist/providers/vercel.d.ts +1 -1
  430. package/dist/providers/vercel.js +1 -1
  431. package/dist/providers/vercel.js.map +1 -1
  432. package/package.json +1 -1
  433. package/dist/adapters/models/openai-compatible.constants.js.map +0 -1
  434. package/dist/adapters/models/openai-compatible.d.ts +0 -3
  435. package/dist/adapters/models/openai-compatible.js +0 -78
  436. package/dist/adapters/models/openai-compatible.js.map +0 -1
  437. package/dist/adapters/models/openai-compatible.types.d.ts +0 -14
  438. package/dist/adapters/models/openai-compatible.types.js +0 -2
  439. package/dist/adapters/models/openai-compatible.types.js.map +0 -1
  440. package/dist/adapters/models/openai-http.js.map +0 -1
  441. package/dist/adapters/models/openai-request.d.ts +0 -4
  442. package/dist/adapters/models/openai-request.js +0 -46
  443. package/dist/adapters/models/openai-request.js.map +0 -1
  444. package/dist/adapters/models/openai-response.d.ts +0 -3
  445. package/dist/adapters/models/openai-response.js +0 -65
  446. package/dist/adapters/models/openai-response.js.map +0 -1
  447. package/dist/cli/init-authentication.constants.js.map +0 -1
  448. /package/dist/{cli/init-authentication.constants.d.ts → adapters/agents/authentication.constants.d.ts} +0 -0
  449. /package/dist/adapters/models/{openai-http.d.ts → model-http.d.ts} +0 -0
  450. /package/dist/adapters/models/{openai-compatible.constants.d.ts → model.constants.d.ts} +0 -0
@@ -0,0 +1,79 @@
1
+ import { invariant } from "./errors.js";
2
+ import { defineHarnessInstructions } from "./instructions.js";
3
+ import { TOOL_NAME_PATTERN } from "./model.constants.js";
4
+ import { SKILL_FIELDS, SKILL_LOADER } from "./skill.constants.js";
5
+ import { defineHarnessTool, harnessTools } from "./tool.js";
6
+ export function defineHarnessSkill(options) {
7
+ invariant(options !== null &&
8
+ typeof options === "object" &&
9
+ Object.keys(options).every((key) => SKILL_FIELDS.has(key)), "Skills accept name, description, instructions and tools");
10
+ invariant(typeof options.name === "string" && TOOL_NAME_PATTERN.test(options.name), "Skill names use 1 to 64 letters, digits, underscores or hyphens");
11
+ invariant(typeof options.description === "string" && options.description.trim(), "Skill description must be nonempty text");
12
+ return Object.freeze({
13
+ kind: "skill",
14
+ name: options.name,
15
+ description: options.description,
16
+ instructions: defineHarnessInstructions(options.instructions),
17
+ tools: harnessTools(options.tools ?? []),
18
+ });
19
+ }
20
+ export function harnessSkills(skills) {
21
+ if (skills === undefined)
22
+ return [];
23
+ invariant(Array.isArray(skills), "Skills must be an array");
24
+ const names = new Set();
25
+ for (const skill of skills) {
26
+ invariant(skill?.kind === "skill", "Declare skills with defineHarnessSkill");
27
+ invariant(!names.has(skill.name), `Duplicate skill name: ${skill.name}`);
28
+ names.add(skill.name);
29
+ }
30
+ return Object.freeze([...skills]);
31
+ }
32
+ export function skillCatalog(skills) {
33
+ return [
34
+ `Skills are available on demand. Call ${SKILL_LOADER} with a skill name to read its instructions and enable its tools before using them:`,
35
+ ...skills.map((skill) => `- ${skill.name}: ${skill.description}`),
36
+ ].join("\n");
37
+ }
38
+ export function skillLoader(skills) {
39
+ const byName = new Map(skills.map((skill) => [skill.name, skill]));
40
+ return defineHarnessTool({
41
+ name: SKILL_LOADER,
42
+ description: "Load a skill listed in the instructions: returns its instructions and enables its tools for the following steps.",
43
+ readOnly: true,
44
+ input: {
45
+ type: "object",
46
+ properties: { name: { enum: skills.map((skill) => skill.name) } },
47
+ required: ["name"],
48
+ additionalProperties: false,
49
+ },
50
+ async execute(input, context) {
51
+ const skill = byName.get(input.name);
52
+ const text = await skill.instructions.resolve({
53
+ sandbox: context.sandbox,
54
+ signal: context.signal,
55
+ model: context.model,
56
+ });
57
+ const tools = skill.tools.map((tool) => tool.name);
58
+ return tools.length
59
+ ? `${text}\n\nTools now available: ${tools.join(", ")}.`
60
+ : text;
61
+ },
62
+ });
63
+ }
64
+ export function loadedSkills(messages) {
65
+ const requested = new Map();
66
+ const loaded = new Set();
67
+ for (const message of messages)
68
+ for (const block of message.content) {
69
+ if (block.type === "tool-call" && block.name === SKILL_LOADER)
70
+ requested.set(block.id, String(block.input?.name));
71
+ if (block.type !== "tool-result" || block.isError)
72
+ continue;
73
+ const name = requested.get(block.callId);
74
+ if (name !== undefined)
75
+ loaded.add(name);
76
+ }
77
+ return loaded;
78
+ }
79
+ //# sourceMappingURL=skill.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill.js","sourceRoot":"","sources":["../../src/domain/skill.ts"],"names":[],"mappings":"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","sourcesContent":["import { invariant } from \"./errors.ts\";\nimport { defineHarnessInstructions } from \"./instructions.ts\";\nimport { TOOL_NAME_PATTERN } from \"./model.constants.ts\";\nimport type { ModelMessage } from \"./model.types.ts\";\nimport { SKILL_FIELDS, SKILL_LOADER } from \"./skill.constants.ts\";\nimport type {\n HarnessSkill,\n HarnessSkillOptions,\n SkillLoaderInput,\n} from \"./skill.types.ts\";\nimport { defineHarnessTool, harnessTools } from \"./tool.ts\";\nimport type { HarnessTool } from \"./tool.types.ts\";\n\nexport function defineHarnessSkill(options: HarnessSkillOptions): HarnessSkill {\n invariant(\n options !== null &&\n typeof options === \"object\" &&\n Object.keys(options).every((key) => SKILL_FIELDS.has(key)),\n \"Skills accept name, description, instructions and tools\",\n );\n invariant(\n typeof options.name === \"string\" && TOOL_NAME_PATTERN.test(options.name),\n \"Skill names use 1 to 64 letters, digits, underscores or hyphens\",\n );\n invariant(\n typeof options.description === \"string\" && options.description.trim(),\n \"Skill description must be nonempty text\",\n );\n return Object.freeze({\n kind: \"skill\",\n name: options.name,\n description: options.description,\n instructions: defineHarnessInstructions(options.instructions),\n tools: harnessTools(options.tools ?? []),\n });\n}\n\nexport function harnessSkills(\n skills: readonly HarnessSkill[] | undefined,\n): readonly HarnessSkill[] {\n if (skills === undefined) return [];\n invariant(Array.isArray(skills), \"Skills must be an array\");\n const names = new Set<string>();\n for (const skill of skills) {\n invariant(\n skill?.kind === \"skill\",\n \"Declare skills with defineHarnessSkill\",\n );\n invariant(!names.has(skill.name), `Duplicate skill name: ${skill.name}`);\n names.add(skill.name);\n }\n return Object.freeze([...skills]);\n}\n\nexport function skillCatalog(skills: readonly HarnessSkill[]): string {\n return [\n `Skills are available on demand. Call ${SKILL_LOADER} with a skill name to read its instructions and enable its tools before using them:`,\n ...skills.map((skill) => `- ${skill.name}: ${skill.description}`),\n ].join(\"\\n\");\n}\n\nexport function skillLoader(skills: readonly HarnessSkill[]): HarnessTool {\n const byName = new Map(skills.map((skill) => [skill.name, skill]));\n return defineHarnessTool({\n name: SKILL_LOADER,\n description:\n \"Load a skill listed in the instructions: returns its instructions and enables its tools for the following steps.\",\n readOnly: true,\n input: {\n type: \"object\",\n properties: { name: { enum: skills.map((skill) => skill.name) } },\n required: [\"name\"],\n additionalProperties: false,\n },\n async execute(input: SkillLoaderInput, context) {\n const skill = byName.get(input.name)!;\n const text = await skill.instructions.resolve({\n sandbox: context.sandbox,\n signal: context.signal,\n model: context.model,\n });\n const tools = skill.tools.map((tool) => tool.name);\n return tools.length\n ? `${text}\\n\\nTools now available: ${tools.join(\", \")}.`\n : text;\n },\n });\n}\n\nexport function loadedSkills(\n messages: readonly ModelMessage[],\n): ReadonlySet<string> {\n const requested = new Map<string, string>();\n const loaded = new Set<string>();\n for (const message of messages)\n for (const block of message.content) {\n if (block.type === \"tool-call\" && block.name === SKILL_LOADER)\n requested.set(\n block.id,\n String((block.input as SkillLoaderInput)?.name),\n );\n if (block.type !== \"tool-result\" || block.isError) continue;\n const name = requested.get(block.callId);\n if (name !== undefined) loaded.add(name);\n }\n return loaded;\n}\n"]}
@@ -0,0 +1,18 @@
1
+ import type { HarnessInstructions, HarnessInstructionSource } from "./harness.types.ts";
2
+ import type { HarnessTool, HarnessToolset } from "./tool.types.ts";
3
+ export interface HarnessSkillOptions {
4
+ readonly name: string;
5
+ readonly description: string;
6
+ readonly instructions: HarnessInstructionSource;
7
+ readonly tools?: readonly (HarnessTool | HarnessToolset)[];
8
+ }
9
+ export interface HarnessSkill {
10
+ readonly kind: "skill";
11
+ readonly name: string;
12
+ readonly description: string;
13
+ readonly instructions: HarnessInstructions;
14
+ readonly tools: readonly HarnessTool[];
15
+ }
16
+ export interface SkillLoaderInput {
17
+ readonly name: string;
18
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=skill.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill.types.js","sourceRoot":"","sources":["../../src/domain/skill.types.ts"],"names":[],"mappings":"","sourcesContent":["import type {\n HarnessInstructions,\n HarnessInstructionSource,\n} from \"./harness.types.ts\";\nimport type { HarnessTool, HarnessToolset } from \"./tool.types.ts\";\n\nexport interface HarnessSkillOptions {\n readonly name: string;\n readonly description: string;\n readonly instructions: HarnessInstructionSource;\n readonly tools?: readonly (HarnessTool | HarnessToolset)[];\n}\n\nexport interface HarnessSkill {\n readonly kind: \"skill\";\n readonly name: string;\n readonly description: string;\n readonly instructions: HarnessInstructions;\n readonly tools: readonly HarnessTool[];\n}\n\nexport interface SkillLoaderInput {\n readonly name: string;\n}\n"]}
@@ -0,0 +1,6 @@
1
+ import type { StandardResult, StandardValidator } from "./response.types.ts";
2
+ import type { JsonSchema, StandardJsonSchema } from "./tool.types.ts";
3
+ export declare function validateStandard<T>(schema: StandardValidator<T>, value: unknown): Promise<StandardResult<T>>;
4
+ export declare function isStandardJsonSchema(value: unknown): value is StandardJsonSchema<unknown>;
5
+ export declare function standardInputSchema(schema: StandardJsonSchema<unknown>): JsonSchema;
6
+ export declare function formatIssues(issues: readonly unknown[]): string;
@@ -0,0 +1,45 @@
1
+ import { invariant } from "./errors.js";
2
+ import { STANDARD_JSON_SCHEMA_TARGET } from "./tool.constants.js";
3
+ export async function validateStandard(schema, value) {
4
+ const result = await schema["~standard"].validate(value);
5
+ if (result.issues)
6
+ return { issues: result.issues };
7
+ return { value: result.value };
8
+ }
9
+ export function isStandardJsonSchema(value) {
10
+ if (value === null || typeof value !== "object" || !("~standard" in value))
11
+ return false;
12
+ const standard = value["~standard"];
13
+ return (typeof standard?.validate === "function" &&
14
+ typeof standard.jsonSchema
15
+ ?.input === "function");
16
+ }
17
+ export function standardInputSchema(schema) {
18
+ const converted = schema["~standard"].jsonSchema.input({
19
+ target: STANDARD_JSON_SCHEMA_TARGET,
20
+ });
21
+ invariant(converted !== null &&
22
+ typeof converted === "object" &&
23
+ !Array.isArray(converted) &&
24
+ converted.type === "object", "Standard schema must convert to a JSON Schema object");
25
+ const { $schema: _dialect, ...portable } = converted;
26
+ return Object.freeze(portable);
27
+ }
28
+ export function formatIssues(issues) {
29
+ return issues
30
+ .map((issue) => {
31
+ if (issue === null || typeof issue !== "object")
32
+ return String(issue);
33
+ const { message, path } = issue;
34
+ const location = Array.isArray(path)
35
+ ? path
36
+ .map((segment) => segment !== null && typeof segment === "object"
37
+ ? String(segment.key)
38
+ : String(segment))
39
+ .join(".")
40
+ : "";
41
+ return `${location ? `${location}: ` : ""}${String(message ?? JSON.stringify(issue))}`;
42
+ })
43
+ .join("; ");
44
+ }
45
+ //# sourceMappingURL=standard-schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"standard-schema.js","sourceRoot":"","sources":["../../src/domain/standard-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAC;AASlE,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,MAA4B,EAC5B,KAAc;IAEd,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IACzD,IAAI,MAAM,CAAC,MAAM;QAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC;IACpD,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,KAAc;IAEd,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,CAAC,WAAW,IAAI,KAAK,CAAC;QACxE,OAAO,KAAK,CAAC;IACf,MAAM,QAAQ,GAAG,KAAK,CAAC,WAAW,CAAwC,CAAC;IAC3E,OAAO,CACL,OAAO,QAAQ,EAAE,QAAQ,KAAK,UAAU;QACxC,OAAQ,QAAQ,CAAC,UAAkD;YACjE,EAAE,KAAK,KAAK,UAAU,CACzB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,mBAAmB,CACjC,MAAmC;IAEnC,MAAM,SAAS,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC;QACrD,MAAM,EAAE,2BAA2B;KACpC,CAAC,CAAC;IACH,SAAS,CACP,SAAS,KAAK,IAAI;QAChB,OAAO,SAAS,KAAK,QAAQ;QAC7B,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC;QACzB,SAAS,CAAC,IAAI,KAAK,QAAQ,EAC7B,sDAAsD,CACvD,CAAC;IACF,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,QAAQ,EAAE,GAAG,SAAS,CAAC;IACrD,OAAO,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,MAA0B;IACrD,OAAO,MAAM;SACV,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QACb,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ;YAAE,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;QACtE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,KAAsB,CAAC;QACjD,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;YAClC,CAAC,CAAC,IAAI;iBACD,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CACf,OAAO,KAAK,IAAI,IAAI,OAAO,OAAO,KAAK,QAAQ;gBAC7C,CAAC,CAAC,MAAM,CAAE,OAA+B,CAAC,GAAG,CAAC;gBAC9C,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CACpB;iBACA,IAAI,CAAC,GAAG,CAAC;YACd,CAAC,CAAC,EAAE,CAAC;QACP,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,MAAM,CAAC,OAAO,IAAI,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;IACzF,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC","sourcesContent":["import { invariant } from \"./errors.ts\";\nimport { STANDARD_JSON_SCHEMA_TARGET } from \"./tool.constants.ts\";\nimport type {\n StandardIssue,\n StandardPathSegment,\n StandardResult,\n StandardValidator,\n} from \"./response.types.ts\";\nimport type { JsonSchema, StandardJsonSchema } from \"./tool.types.ts\";\n\nexport async function validateStandard<T>(\n schema: StandardValidator<T>,\n value: unknown,\n): Promise<StandardResult<T>> {\n const result = await schema[\"~standard\"].validate(value);\n if (result.issues) return { issues: result.issues };\n return { value: result.value };\n}\n\nexport function isStandardJsonSchema(\n value: unknown,\n): value is StandardJsonSchema<unknown> {\n if (value === null || typeof value !== \"object\" || !(\"~standard\" in value))\n return false;\n const standard = value[\"~standard\"] as Record<string, unknown> | undefined;\n return (\n typeof standard?.validate === \"function\" &&\n typeof (standard.jsonSchema as Record<string, unknown> | undefined)\n ?.input === \"function\"\n );\n}\n\nexport function standardInputSchema(\n schema: StandardJsonSchema<unknown>,\n): JsonSchema {\n const converted = schema[\"~standard\"].jsonSchema.input({\n target: STANDARD_JSON_SCHEMA_TARGET,\n });\n invariant(\n converted !== null &&\n typeof converted === \"object\" &&\n !Array.isArray(converted) &&\n converted.type === \"object\",\n \"Standard schema must convert to a JSON Schema object\",\n );\n const { $schema: _dialect, ...portable } = converted;\n return Object.freeze(portable);\n}\n\nexport function formatIssues(issues: readonly unknown[]): string {\n return issues\n .map((issue) => {\n if (issue === null || typeof issue !== \"object\") return String(issue);\n const { message, path } = issue as StandardIssue;\n const location = Array.isArray(path)\n ? path\n .map((segment) =>\n segment !== null && typeof segment === \"object\"\n ? String((segment as StandardPathSegment).key)\n : String(segment),\n )\n .join(\".\")\n : \"\";\n return `${location ? `${location}: ` : \"\"}${String(message ?? JSON.stringify(issue))}`;\n })\n .join(\"; \");\n}\n"]}
@@ -0,0 +1,3 @@
1
+ import type { JsonSchema } from "./tool.types.ts";
2
+ export declare function validateSchemaDefinition(schema: unknown, root?: boolean): void;
3
+ export declare function schemaIssues(schema: JsonSchema, value: unknown, path?: string): readonly string[];
@@ -0,0 +1,109 @@
1
+ import { invariant } from "./errors.js";
2
+ import { JSON_SCHEMA_KEYWORDS, JSON_SCHEMA_TYPES } from "./tool.constants.js";
3
+ const plain = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
4
+ const same = (left, right) => JSON.stringify(left) === JSON.stringify(right);
5
+ const typeChecks = {
6
+ object: plain,
7
+ array: Array.isArray,
8
+ string: (value) => typeof value === "string",
9
+ number: (value) => typeof value === "number" && Number.isFinite(value),
10
+ integer: (value) => Number.isInteger(value),
11
+ boolean: (value) => typeof value === "boolean",
12
+ null: (value) => value === null,
13
+ };
14
+ const keywordChecks = {
15
+ enum: (schema, value, path) => schema.enum.some((option) => same(option, value))
16
+ ? []
17
+ : [`${path} must be one of ${JSON.stringify(schema.enum)}`],
18
+ const: (schema, value, path) => same(schema.const, value)
19
+ ? []
20
+ : [`${path} must equal ${JSON.stringify(schema.const)}`],
21
+ minLength: bound((value) => typeof value === "string" ? [...value].length : undefined)("minLength", (size, limit) => size >= limit, "at least", "characters"),
22
+ maxLength: bound((value) => typeof value === "string" ? [...value].length : undefined)("maxLength", (size, limit) => size <= limit, "at most", "characters"),
23
+ minimum: bound((value) => (typeof value === "number" ? value : undefined))("minimum", (size, limit) => size >= limit, "at least", ""),
24
+ maximum: bound((value) => (typeof value === "number" ? value : undefined))("maximum", (size, limit) => size <= limit, "at most", ""),
25
+ minItems: bound((value) => (Array.isArray(value) ? value.length : undefined))("minItems", (size, limit) => size >= limit, "at least", "items"),
26
+ maxItems: bound((value) => (Array.isArray(value) ? value.length : undefined))("maxItems", (size, limit) => size <= limit, "at most", "items"),
27
+ items: (schema, value, path) => Array.isArray(value)
28
+ ? value.flatMap((item, index) => schemaIssues(schema.items, item, `${path}[${index}]`))
29
+ : [],
30
+ required: (schema, value, path) => plain(value)
31
+ ? schema.required.flatMap((key) => Object.hasOwn(value, key) ? [] : [`${path}.${key} is required`])
32
+ : [],
33
+ properties: (schema, value, path) => plain(value)
34
+ ? Object.entries(schema.properties)
35
+ .filter(([key]) => Object.hasOwn(value, key))
36
+ .flatMap(([key, property]) => schemaIssues(property, value[key], `${path}.${key}`))
37
+ : [],
38
+ additionalProperties: (schema, value, path) => {
39
+ if (!plain(value))
40
+ return [];
41
+ const declared = plain(schema.properties) ? schema.properties : {};
42
+ const extra = Object.keys(value).filter((key) => !Object.hasOwn(declared, key));
43
+ if (schema.additionalProperties === false)
44
+ return extra.map((key) => `${path}.${key} is not allowed`);
45
+ if (!plain(schema.additionalProperties))
46
+ return [];
47
+ const additional = schema.additionalProperties;
48
+ return extra.flatMap((key) => schemaIssues(additional, value[key], `${path}.${key}`));
49
+ },
50
+ };
51
+ export function validateSchemaDefinition(schema, root = true) {
52
+ invariant(plain(schema), "Tool input schema must be a JSON Schema object");
53
+ invariant(Object.keys(schema).every((key) => JSON_SCHEMA_KEYWORDS.has(key)), `Unsupported JSON Schema keyword; use ${[...JSON_SCHEMA_KEYWORDS].join(", ")}`);
54
+ const types = schemaTypes(schema);
55
+ invariant(types.every((type) => JSON_SCHEMA_TYPES.has(type)), "Unsupported JSON Schema type");
56
+ invariant(!root || (types.length === 1 && types[0] === "object"), "Tool input schema must describe an object");
57
+ invariant(schema.required === undefined ||
58
+ (Array.isArray(schema.required) &&
59
+ schema.required.every((key) => typeof key === "string")), "JSON Schema required must list property names");
60
+ invariant(schema.enum === undefined || Array.isArray(schema.enum), "JSON Schema enum must be an array");
61
+ for (const keyword of [
62
+ "minLength",
63
+ "maxLength",
64
+ "minimum",
65
+ "maximum",
66
+ "minItems",
67
+ "maxItems",
68
+ ])
69
+ invariant(schema[keyword] === undefined ||
70
+ (typeof schema[keyword] === "number" &&
71
+ Number.isFinite(schema[keyword])), `JSON Schema ${keyword} must be a number`);
72
+ if (schema.properties !== undefined) {
73
+ invariant(plain(schema.properties), "JSON Schema properties must be an object");
74
+ for (const property of Object.values(schema.properties))
75
+ validateSchemaDefinition(property, false);
76
+ }
77
+ if (schema.items !== undefined)
78
+ validateSchemaDefinition(schema.items, false);
79
+ if (plain(schema.additionalProperties))
80
+ validateSchemaDefinition(schema.additionalProperties, false);
81
+ invariant(schema.additionalProperties === undefined ||
82
+ typeof schema.additionalProperties === "boolean" ||
83
+ plain(schema.additionalProperties), "JSON Schema additionalProperties must be a boolean or a schema");
84
+ }
85
+ export function schemaIssues(schema, value, path = "input") {
86
+ const types = schemaTypes(schema);
87
+ if (types.length && !types.some((type) => typeChecks[type](value)))
88
+ return [`${path} must be ${types.join(" or ")}`];
89
+ return Object.keys(schema)
90
+ .filter((keyword) => Object.hasOwn(keywordChecks, keyword))
91
+ .flatMap((keyword) => keywordChecks[keyword](schema, value, path));
92
+ }
93
+ function schemaTypes(schema) {
94
+ if (schema.type === undefined)
95
+ return [];
96
+ const types = Array.isArray(schema.type) ? schema.type : [schema.type];
97
+ invariant(types.every((type) => typeof type === "string"), "JSON Schema type must be a name or a list of names");
98
+ return types;
99
+ }
100
+ function bound(measure) {
101
+ return (keyword, accept, relation, unit) => (schema, value, path) => {
102
+ const size = measure(value);
103
+ const limit = typeof schema[keyword] === "number" ? schema[keyword] : undefined;
104
+ if (size === undefined || limit === undefined || accept(size, limit))
105
+ return [];
106
+ return [`${path} must be ${relation} ${limit}${unit ? ` ${unit}` : ""}`];
107
+ };
108
+ }
109
+ //# sourceMappingURL=tool-schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-schema.js","sourceRoot":"","sources":["../../src/domain/tool-schema.ts"],"names":[],"mappings":"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","sourcesContent":["import { invariant } from \"./errors.ts\";\nimport { JSON_SCHEMA_KEYWORDS, JSON_SCHEMA_TYPES } from \"./tool.constants.ts\";\nimport type { JsonSchema, SchemaKeywordCheck } from \"./tool.types.ts\";\n\nconst plain = (value: unknown): value is Readonly<Record<string, unknown>> =>\n value !== null && typeof value === \"object\" && !Array.isArray(value);\nconst same = (left: unknown, right: unknown) =>\n JSON.stringify(left) === JSON.stringify(right);\n\nconst typeChecks: Readonly<Record<string, (value: unknown) => boolean>> = {\n object: plain,\n array: Array.isArray,\n string: (value) => typeof value === \"string\",\n number: (value) => typeof value === \"number\" && Number.isFinite(value),\n integer: (value) => Number.isInteger(value),\n boolean: (value) => typeof value === \"boolean\",\n null: (value) => value === null,\n};\n\nconst keywordChecks: Readonly<Record<string, SchemaKeywordCheck>> = {\n enum: (schema, value, path) =>\n (schema.enum as readonly unknown[]).some((option) => same(option, value))\n ? []\n : [`${path} must be one of ${JSON.stringify(schema.enum)}`],\n const: (schema, value, path) =>\n same(schema.const, value)\n ? []\n : [`${path} must equal ${JSON.stringify(schema.const)}`],\n minLength: bound((value) =>\n typeof value === \"string\" ? [...value].length : undefined,\n )(\"minLength\", (size, limit) => size >= limit, \"at least\", \"characters\"),\n maxLength: bound((value) =>\n typeof value === \"string\" ? [...value].length : undefined,\n )(\"maxLength\", (size, limit) => size <= limit, \"at most\", \"characters\"),\n minimum: bound((value) => (typeof value === \"number\" ? value : undefined))(\n \"minimum\",\n (size, limit) => size >= limit,\n \"at least\",\n \"\",\n ),\n maximum: bound((value) => (typeof value === \"number\" ? value : undefined))(\n \"maximum\",\n (size, limit) => size <= limit,\n \"at most\",\n \"\",\n ),\n minItems: bound((value) => (Array.isArray(value) ? value.length : undefined))(\n \"minItems\",\n (size, limit) => size >= limit,\n \"at least\",\n \"items\",\n ),\n maxItems: bound((value) => (Array.isArray(value) ? value.length : undefined))(\n \"maxItems\",\n (size, limit) => size <= limit,\n \"at most\",\n \"items\",\n ),\n items: (schema, value, path) =>\n Array.isArray(value)\n ? value.flatMap((item, index) =>\n schemaIssues(schema.items as JsonSchema, item, `${path}[${index}]`),\n )\n : [],\n required: (schema, value, path) =>\n plain(value)\n ? (schema.required as readonly string[]).flatMap((key) =>\n Object.hasOwn(value, key) ? [] : [`${path}.${key} is required`],\n )\n : [],\n properties: (schema, value, path) =>\n plain(value)\n ? Object.entries(schema.properties as Record<string, JsonSchema>)\n .filter(([key]) => Object.hasOwn(value, key))\n .flatMap(([key, property]) =>\n schemaIssues(property, value[key], `${path}.${key}`),\n )\n : [],\n additionalProperties: (schema, value, path) => {\n if (!plain(value)) return [];\n const declared = plain(schema.properties) ? schema.properties : {};\n const extra = Object.keys(value).filter(\n (key) => !Object.hasOwn(declared, key),\n );\n if (schema.additionalProperties === false)\n return extra.map((key) => `${path}.${key} is not allowed`);\n if (!plain(schema.additionalProperties)) return [];\n const additional = schema.additionalProperties;\n return extra.flatMap((key) =>\n schemaIssues(additional, value[key], `${path}.${key}`),\n );\n },\n};\n\nexport function validateSchemaDefinition(schema: unknown, root = true): void {\n invariant(plain(schema), \"Tool input schema must be a JSON Schema object\");\n invariant(\n Object.keys(schema).every((key) => JSON_SCHEMA_KEYWORDS.has(key)),\n `Unsupported JSON Schema keyword; use ${[...JSON_SCHEMA_KEYWORDS].join(\", \")}`,\n );\n const types = schemaTypes(schema);\n invariant(\n types.every((type) => JSON_SCHEMA_TYPES.has(type)),\n \"Unsupported JSON Schema type\",\n );\n invariant(\n !root || (types.length === 1 && types[0] === \"object\"),\n \"Tool input schema must describe an object\",\n );\n invariant(\n schema.required === undefined ||\n (Array.isArray(schema.required) &&\n schema.required.every((key) => typeof key === \"string\")),\n \"JSON Schema required must list property names\",\n );\n invariant(\n schema.enum === undefined || Array.isArray(schema.enum),\n \"JSON Schema enum must be an array\",\n );\n for (const keyword of [\n \"minLength\",\n \"maxLength\",\n \"minimum\",\n \"maximum\",\n \"minItems\",\n \"maxItems\",\n ])\n invariant(\n schema[keyword] === undefined ||\n (typeof schema[keyword] === \"number\" &&\n Number.isFinite(schema[keyword])),\n `JSON Schema ${keyword} must be a number`,\n );\n if (schema.properties !== undefined) {\n invariant(\n plain(schema.properties),\n \"JSON Schema properties must be an object\",\n );\n for (const property of Object.values(schema.properties))\n validateSchemaDefinition(property, false);\n }\n if (schema.items !== undefined) validateSchemaDefinition(schema.items, false);\n if (plain(schema.additionalProperties))\n validateSchemaDefinition(schema.additionalProperties, false);\n invariant(\n schema.additionalProperties === undefined ||\n typeof schema.additionalProperties === \"boolean\" ||\n plain(schema.additionalProperties),\n \"JSON Schema additionalProperties must be a boolean or a schema\",\n );\n}\n\nexport function schemaIssues(\n schema: JsonSchema,\n value: unknown,\n path = \"input\",\n): readonly string[] {\n const types = schemaTypes(schema);\n if (types.length && !types.some((type) => typeChecks[type]!(value)))\n return [`${path} must be ${types.join(\" or \")}`];\n return Object.keys(schema)\n .filter((keyword) => Object.hasOwn(keywordChecks, keyword))\n .flatMap((keyword) => keywordChecks[keyword]!(schema, value, path));\n}\n\nfunction schemaTypes(schema: JsonSchema): readonly string[] {\n if (schema.type === undefined) return [];\n const types = Array.isArray(schema.type) ? schema.type : [schema.type];\n invariant(\n types.every((type) => typeof type === \"string\"),\n \"JSON Schema type must be a name or a list of names\",\n );\n return types;\n}\n\nfunction bound(measure: (value: unknown) => number | undefined) {\n return (\n keyword: string,\n accept: (size: number, limit: number) => boolean,\n relation: string,\n unit: string,\n ): SchemaKeywordCheck =>\n (schema, value, path) => {\n const size = measure(value);\n const limit =\n typeof schema[keyword] === \"number\" ? schema[keyword] : undefined;\n if (size === undefined || limit === undefined || accept(size, limit))\n return [];\n return [`${path} must be ${relation} ${limit}${unit ? ` ${unit}` : \"\"}`];\n };\n}\n"]}
@@ -0,0 +1,4 @@
1
+ export declare const JSON_SCHEMA_KEYWORDS: ReadonlySet<string>;
2
+ export declare const JSON_SCHEMA_TYPES: ReadonlySet<string>;
3
+ export declare const STANDARD_JSON_SCHEMA_TARGET = "draft-2020-12";
4
+ export declare const HARNESS_TOOL_FIELDS: ReadonlySet<string>;
@@ -0,0 +1,36 @@
1
+ export const JSON_SCHEMA_KEYWORDS = new Set([
2
+ "type",
3
+ "title",
4
+ "description",
5
+ "properties",
6
+ "required",
7
+ "additionalProperties",
8
+ "items",
9
+ "enum",
10
+ "const",
11
+ "minLength",
12
+ "maxLength",
13
+ "minimum",
14
+ "maximum",
15
+ "minItems",
16
+ "maxItems",
17
+ ]);
18
+ export const JSON_SCHEMA_TYPES = new Set([
19
+ "object",
20
+ "array",
21
+ "string",
22
+ "number",
23
+ "integer",
24
+ "boolean",
25
+ "null",
26
+ ]);
27
+ export const STANDARD_JSON_SCHEMA_TARGET = "draft-2020-12";
28
+ export const HARNESS_TOOL_FIELDS = new Set([
29
+ "name",
30
+ "description",
31
+ "input",
32
+ "readOnly",
33
+ "resources",
34
+ "execute",
35
+ ]);
36
+ //# sourceMappingURL=tool.constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool.constants.js","sourceRoot":"","sources":["../../src/domain/tool.constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,oBAAoB,GAAwB,IAAI,GAAG,CAAC;IAC/D,MAAM;IACN,OAAO;IACP,aAAa;IACb,YAAY;IACZ,UAAU;IACV,sBAAsB;IACtB,OAAO;IACP,MAAM;IACN,OAAO;IACP,WAAW;IACX,WAAW;IACX,SAAS;IACT,SAAS;IACT,UAAU;IACV,UAAU;CACX,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,iBAAiB,GAAwB,IAAI,GAAG,CAAC;IAC5D,QAAQ;IACR,OAAO;IACP,QAAQ;IACR,QAAQ;IACR,SAAS;IACT,SAAS;IACT,MAAM;CACP,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,2BAA2B,GAAG,eAAe,CAAC;AAE3D,MAAM,CAAC,MAAM,mBAAmB,GAAwB,IAAI,GAAG,CAAC;IAC9D,MAAM;IACN,aAAa;IACb,OAAO;IACP,UAAU;IACV,WAAW;IACX,SAAS;CACV,CAAC,CAAC","sourcesContent":["export const JSON_SCHEMA_KEYWORDS: ReadonlySet<string> = new Set([\n \"type\",\n \"title\",\n \"description\",\n \"properties\",\n \"required\",\n \"additionalProperties\",\n \"items\",\n \"enum\",\n \"const\",\n \"minLength\",\n \"maxLength\",\n \"minimum\",\n \"maximum\",\n \"minItems\",\n \"maxItems\",\n]);\n\nexport const JSON_SCHEMA_TYPES: ReadonlySet<string> = new Set([\n \"object\",\n \"array\",\n \"string\",\n \"number\",\n \"integer\",\n \"boolean\",\n \"null\",\n]);\n\nexport const STANDARD_JSON_SCHEMA_TARGET = \"draft-2020-12\";\n\nexport const HARNESS_TOOL_FIELDS: ReadonlySet<string> = new Set([\n \"name\",\n \"description\",\n \"input\",\n \"readOnly\",\n \"resources\",\n \"execute\",\n]);\n"]}
@@ -0,0 +1,4 @@
1
+ import type { HarnessTool, HarnessToolOptions, HarnessToolset, HarnessToolsetOptions } from "./tool.types.ts";
2
+ export declare function defineHarnessTool<Input>(options: HarnessToolOptions<Input>): HarnessTool<Input>;
3
+ export declare function defineHarnessToolset(options: HarnessToolsetOptions): HarnessToolset;
4
+ export declare function harnessTools(entries: readonly (HarnessTool | HarnessToolset)[]): readonly HarnessTool[];
@@ -0,0 +1,66 @@
1
+ import { invariant } from "./errors.js";
2
+ import { TOOL_NAME_PATTERN } from "./model.constants.js";
3
+ import { formatIssues, isStandardJsonSchema, standardInputSchema, validateStandard, } from "./standard-schema.js";
4
+ import { HARNESS_TOOL_FIELDS } from "./tool.constants.js";
5
+ import { schemaIssues, validateSchemaDefinition } from "./tool-schema.js";
6
+ export function defineHarnessTool(options) {
7
+ invariant(options !== null && typeof options === "object", "Tool options must be an object");
8
+ invariant(Object.keys(options).every((key) => HARNESS_TOOL_FIELDS.has(key)), "Unsupported tool option");
9
+ invariant(typeof options.name === "string" && TOOL_NAME_PATTERN.test(options.name), "Tool names use 1 to 64 letters, digits, underscores or hyphens");
10
+ invariant(typeof options.description === "string" && options.description.trim(), "Tool description must be nonempty text");
11
+ invariant(typeof options.execute === "function", "Tool execute must be a function");
12
+ invariant(options.readOnly === undefined || typeof options.readOnly === "boolean", "Tool readOnly must be boolean");
13
+ invariant(options.resources === undefined || typeof options.resources === "function", "Tool resources must be a function");
14
+ const standard = isStandardJsonSchema(options.input)
15
+ ? options.input
16
+ : undefined;
17
+ if (!standard)
18
+ validateSchemaDefinition(options.input);
19
+ const inputSchema = standard
20
+ ? standardInputSchema(standard)
21
+ : Object.freeze(structuredClone(options.input));
22
+ return Object.freeze({
23
+ kind: "tool",
24
+ name: options.name,
25
+ description: options.description,
26
+ readOnly: options.readOnly ?? false,
27
+ inputSchema,
28
+ async validate(value) {
29
+ if (standard) {
30
+ const result = await validateStandard(standard, value);
31
+ return "issues" in result
32
+ ? { issues: formatIssues(result.issues) }
33
+ : { value: result.value };
34
+ }
35
+ const issues = schemaIssues(inputSchema, value);
36
+ return issues.length
37
+ ? { issues: issues.join("; ") }
38
+ : { value: value };
39
+ },
40
+ resources: (value) => options.resources?.(value) ?? {},
41
+ execute: (value, context) => options.execute(value, context),
42
+ });
43
+ }
44
+ export function defineHarnessToolset(options) {
45
+ invariant(options !== null && typeof options === "object", "Toolset options must be an object");
46
+ invariant(typeof options.name === "string" && options.name.trim(), "Toolset name must be nonempty text");
47
+ return Object.freeze({
48
+ kind: "toolset",
49
+ name: options.name,
50
+ tools: harnessTools(options.tools),
51
+ });
52
+ }
53
+ export function harnessTools(entries) {
54
+ invariant(Array.isArray(entries), "Tools must be an array");
55
+ const tools = entries.flatMap((entry) => {
56
+ invariant(entry?.kind === "tool" || entry?.kind === "toolset", "Declare tools with defineHarnessTool or defineHarnessToolset");
57
+ return entry.kind === "tool" ? [entry] : entry.tools;
58
+ });
59
+ const names = new Set();
60
+ for (const tool of tools) {
61
+ invariant(!names.has(tool.name), `Duplicate tool name: ${tool.name}`);
62
+ names.add(tool.name);
63
+ }
64
+ return Object.freeze(tools);
65
+ }
66
+ //# sourceMappingURL=tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool.js","sourceRoot":"","sources":["../../src/domain/tool.ts"],"names":[],"mappings":"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","sourcesContent":["import { invariant } from \"./errors.ts\";\nimport { TOOL_NAME_PATTERN } from \"./model.constants.ts\";\nimport {\n formatIssues,\n isStandardJsonSchema,\n standardInputSchema,\n validateStandard,\n} from \"./standard-schema.ts\";\nimport { HARNESS_TOOL_FIELDS } from \"./tool.constants.ts\";\nimport { schemaIssues, validateSchemaDefinition } from \"./tool-schema.ts\";\nimport type {\n HarnessTool,\n HarnessToolContext,\n HarnessToolOptions,\n HarnessToolset,\n HarnessToolsetOptions,\n JsonSchema,\n StandardJsonSchema,\n ToolValidation,\n} from \"./tool.types.ts\";\n\nexport function defineHarnessTool<Input>(\n options: HarnessToolOptions<Input>,\n): HarnessTool<Input> {\n invariant(\n options !== null && typeof options === \"object\",\n \"Tool options must be an object\",\n );\n invariant(\n Object.keys(options).every((key) => HARNESS_TOOL_FIELDS.has(key)),\n \"Unsupported tool option\",\n );\n invariant(\n typeof options.name === \"string\" && TOOL_NAME_PATTERN.test(options.name),\n \"Tool names use 1 to 64 letters, digits, underscores or hyphens\",\n );\n invariant(\n typeof options.description === \"string\" && options.description.trim(),\n \"Tool description must be nonempty text\",\n );\n invariant(\n typeof options.execute === \"function\",\n \"Tool execute must be a function\",\n );\n invariant(\n options.readOnly === undefined || typeof options.readOnly === \"boolean\",\n \"Tool readOnly must be boolean\",\n );\n invariant(\n options.resources === undefined || typeof options.resources === \"function\",\n \"Tool resources must be a function\",\n );\n const standard = isStandardJsonSchema(options.input)\n ? (options.input as StandardJsonSchema<Input>)\n : undefined;\n if (!standard) validateSchemaDefinition(options.input);\n const inputSchema: JsonSchema = standard\n ? standardInputSchema(standard)\n : Object.freeze(structuredClone(options.input as JsonSchema));\n return Object.freeze({\n kind: \"tool\",\n name: options.name,\n description: options.description,\n readOnly: options.readOnly ?? false,\n inputSchema,\n async validate(value: unknown): Promise<ToolValidation<Input>> {\n if (standard) {\n const result = await validateStandard(standard, value);\n return \"issues\" in result\n ? { issues: formatIssues(result.issues) }\n : { value: result.value };\n }\n const issues = schemaIssues(inputSchema, value);\n return issues.length\n ? { issues: issues.join(\"; \") }\n : { value: value as Input };\n },\n resources: (value: Input) => options.resources?.(value) ?? {},\n execute: (value: Input, context: HarnessToolContext) =>\n options.execute(value, context),\n });\n}\n\nexport function defineHarnessToolset(\n options: HarnessToolsetOptions,\n): HarnessToolset {\n invariant(\n options !== null && typeof options === \"object\",\n \"Toolset options must be an object\",\n );\n invariant(\n typeof options.name === \"string\" && options.name.trim(),\n \"Toolset name must be nonempty text\",\n );\n return Object.freeze({\n kind: \"toolset\",\n name: options.name,\n tools: harnessTools(options.tools),\n });\n}\n\nexport function harnessTools(\n entries: readonly (HarnessTool | HarnessToolset)[],\n): readonly HarnessTool[] {\n invariant(Array.isArray(entries), \"Tools must be an array\");\n const tools = entries.flatMap((entry) => {\n invariant(\n entry?.kind === \"tool\" || entry?.kind === \"toolset\",\n \"Declare tools with defineHarnessTool or defineHarnessToolset\",\n );\n return entry.kind === \"tool\" ? [entry] : entry.tools;\n });\n const names = new Set<string>();\n for (const tool of tools) {\n invariant(!names.has(tool.name), `Duplicate tool name: ${tool.name}`);\n names.add(tool.name);\n }\n return Object.freeze(tools);\n}\n"]}
@@ -0,0 +1,62 @@
1
+ import type { AgentEvent } from "./agent.types.ts";
2
+ import type { AgentModel } from "./model.types.ts";
3
+ import type { ToolResources } from "./permissions.types.ts";
4
+ import type { StandardValidator } from "./response.types.ts";
5
+ import type { SandboxLease } from "./sandbox.types.ts";
6
+ export type JsonSchema = Readonly<Record<string, unknown>>;
7
+ export interface StandardJsonSchema<Input> {
8
+ readonly "~standard": StandardValidator<Input>["~standard"] & {
9
+ readonly jsonSchema: {
10
+ input(options: {
11
+ readonly target: string;
12
+ }): Record<string, unknown>;
13
+ };
14
+ };
15
+ }
16
+ export type HarnessToolEvent = Extract<AgentEvent, {
17
+ readonly kind: "text" | "warning" | "raw";
18
+ }>;
19
+ export interface HarnessToolContext {
20
+ readonly sandbox: SandboxLease;
21
+ readonly signal: AbortSignal;
22
+ readonly callId: string;
23
+ readonly model: AgentModel;
24
+ observe(event: HarnessToolEvent): void;
25
+ }
26
+ export type ToolOutput = string | {
27
+ readonly content: string;
28
+ readonly isError?: boolean;
29
+ };
30
+ export interface HarnessToolOptions<Input> {
31
+ readonly name: string;
32
+ readonly description: string;
33
+ readonly input: StandardJsonSchema<Input> | JsonSchema;
34
+ readonly readOnly?: boolean;
35
+ resources?(input: Input): ToolResources;
36
+ execute(input: Input, context: HarnessToolContext): ToolOutput | Promise<ToolOutput>;
37
+ }
38
+ export type ToolValidation<Input> = {
39
+ readonly value: Input;
40
+ } | {
41
+ readonly issues: string;
42
+ };
43
+ export interface HarnessTool<Input = unknown> {
44
+ readonly kind: "tool";
45
+ readonly name: string;
46
+ readonly description: string;
47
+ readonly readOnly: boolean;
48
+ readonly inputSchema: JsonSchema;
49
+ validate(value: unknown): Promise<ToolValidation<Input>>;
50
+ resources(input: Input): ToolResources;
51
+ execute(input: Input, context: HarnessToolContext): ToolOutput | Promise<ToolOutput>;
52
+ }
53
+ export interface HarnessToolsetOptions {
54
+ readonly name: string;
55
+ readonly tools: readonly (HarnessTool | HarnessToolset)[];
56
+ }
57
+ export interface HarnessToolset {
58
+ readonly kind: "toolset";
59
+ readonly name: string;
60
+ readonly tools: readonly HarnessTool[];
61
+ }
62
+ export type SchemaKeywordCheck = (schema: JsonSchema, value: unknown, path: string) => readonly string[];
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=tool.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool.types.js","sourceRoot":"","sources":["../../src/domain/tool.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { AgentEvent } from \"./agent.types.ts\";\nimport type { AgentModel } from \"./model.types.ts\";\nimport type { ToolResources } from \"./permissions.types.ts\";\nimport type { StandardValidator } from \"./response.types.ts\";\nimport type { SandboxLease } from \"./sandbox.types.ts\";\n\nexport type JsonSchema = Readonly<Record<string, unknown>>;\n\nexport interface StandardJsonSchema<Input> {\n readonly \"~standard\": StandardValidator<Input>[\"~standard\"] & {\n readonly jsonSchema: {\n input(options: { readonly target: string }): Record<string, unknown>;\n };\n };\n}\n\nexport type HarnessToolEvent = Extract<\n AgentEvent,\n { readonly kind: \"text\" | \"warning\" | \"raw\" }\n>;\n\nexport interface HarnessToolContext {\n readonly sandbox: SandboxLease;\n readonly signal: AbortSignal;\n readonly callId: string;\n readonly model: AgentModel;\n observe(event: HarnessToolEvent): void;\n}\n\nexport type ToolOutput =\n string | { readonly content: string; readonly isError?: boolean };\n\nexport interface HarnessToolOptions<Input> {\n readonly name: string;\n readonly description: string;\n readonly input: StandardJsonSchema<Input> | JsonSchema;\n readonly readOnly?: boolean;\n resources?(input: Input): ToolResources;\n execute(\n input: Input,\n context: HarnessToolContext,\n ): ToolOutput | Promise<ToolOutput>;\n}\n\nexport type ToolValidation<Input> =\n { readonly value: Input } | { readonly issues: string };\n\nexport interface HarnessTool<Input = unknown> {\n readonly kind: \"tool\";\n readonly name: string;\n readonly description: string;\n readonly readOnly: boolean;\n readonly inputSchema: JsonSchema;\n validate(value: unknown): Promise<ToolValidation<Input>>;\n resources(input: Input): ToolResources;\n execute(\n input: Input,\n context: HarnessToolContext,\n ): ToolOutput | Promise<ToolOutput>;\n}\n\nexport interface HarnessToolsetOptions {\n readonly name: string;\n readonly tools: readonly (HarnessTool | HarnessToolset)[];\n}\n\nexport interface HarnessToolset {\n readonly kind: \"toolset\";\n readonly name: string;\n readonly tools: readonly HarnessTool[];\n}\n\nexport type SchemaKeywordCheck = (\n schema: JsonSchema,\n value: unknown,\n path: string,\n) => readonly string[];\n"]}
@@ -0,0 +1,4 @@
1
+ import type { ModelMessage } from "./model.types.ts";
2
+ import type { TranscriptRecord } from "./transcript.types.ts";
3
+ export declare function parseTranscript(text: string): readonly TranscriptRecord[];
4
+ export declare function transcriptMessages(records: readonly TranscriptRecord[]): ModelMessage[];
@@ -0,0 +1,48 @@
1
+ import { OutpostError } from "./errors.js";
2
+ const folds = {
3
+ session: (messages) => messages,
4
+ message: (messages, record) => record.type === "message" ? [...messages, record.message] : messages,
5
+ compaction: (_messages, record) => record.type === "compaction" ? [...record.messages] : [],
6
+ };
7
+ export function parseTranscript(text) {
8
+ const records = text
9
+ .split("\n")
10
+ .filter((line) => line.trim())
11
+ .map((line) => {
12
+ try {
13
+ return JSON.parse(line);
14
+ }
15
+ catch {
16
+ throw new OutpostError("session", "Harness transcript is not valid JSONL");
17
+ }
18
+ });
19
+ const first = records[0];
20
+ if (first?.type !== "session" || first.version !== 1)
21
+ throw new OutpostError("session", "Unsupported harness transcript");
22
+ for (const record of records)
23
+ if (!Object.hasOwn(folds, record?.type))
24
+ throw new OutpostError("session", "Unsupported harness transcript record");
25
+ return records;
26
+ }
27
+ export function transcriptMessages(records) {
28
+ const messages = records.reduce((current, record) => folds[record.type](current, record), []);
29
+ const last = messages.at(-1);
30
+ const pending = last?.role === "assistant"
31
+ ? last.content.flatMap((block) => block.type === "tool-call" ? [block.id] : [])
32
+ : [];
33
+ if (!pending.length)
34
+ return messages;
35
+ return [
36
+ ...messages,
37
+ {
38
+ role: "user",
39
+ content: pending.map((callId) => ({
40
+ type: "tool-result",
41
+ callId,
42
+ content: "The tool call was interrupted before it produced a result.",
43
+ isError: true,
44
+ })),
45
+ },
46
+ ];
47
+ }
48
+ //# sourceMappingURL=transcript.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transcript.js","sourceRoot":"","sources":["../../src/domain/transcript.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAI3C,MAAM,KAAK,GAKP;IACF,OAAO,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ;IAC/B,OAAO,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,CAC5B,MAAM,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,QAAQ,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ;IACtE,UAAU,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,CAChC,MAAM,CAAC,IAAI,KAAK,YAAY,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE;CAC3D,CAAC;AAEF,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,MAAM,OAAO,GAAG,IAAI;SACjB,KAAK,CAAC,IAAI,CAAC;SACX,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;SAC7B,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACZ,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAqB,CAAC;QAC9C,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,IAAI,YAAY,CACpB,SAAS,EACT,uCAAuC,CACxC,CAAC;QACJ,CAAC;IACH,CAAC,CAAC,CAAC;IACL,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACzB,IAAI,KAAK,EAAE,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,OAAO,KAAK,CAAC;QAClD,MAAM,IAAI,YAAY,CAAC,SAAS,EAAE,gCAAgC,CAAC,CAAC;IACtE,KAAK,MAAM,MAAM,IAAI,OAAO;QAC1B,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC;YACrC,MAAM,IAAI,YAAY,CACpB,SAAS,EACT,uCAAuC,CACxC,CAAC;IACN,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,kBAAkB,CAChC,OAAoC;IAEpC,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAC7B,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,MAAM,CAAC,EACxD,EAAE,CACH,CAAC;IACF,MAAM,IAAI,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7B,MAAM,OAAO,GACX,IAAI,EAAE,IAAI,KAAK,WAAW;QACxB,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAC7B,KAAK,CAAC,IAAI,KAAK,WAAW,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAC7C;QACH,CAAC,CAAC,EAAE,CAAC;IACT,IAAI,CAAC,OAAO,CAAC,MAAM;QAAE,OAAO,QAAQ,CAAC;IACrC,OAAO;QACL,GAAG,QAAQ;QACX;YACE,IAAI,EAAE,MAAM;YACZ,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;gBAChC,IAAI,EAAE,aAAsB;gBAC5B,MAAM;gBACN,OAAO,EAAE,4DAA4D;gBACrE,OAAO,EAAE,IAAI;aACd,CAAC,CAAC;SACJ;KACF,CAAC;AACJ,CAAC","sourcesContent":["import { OutpostError } from \"./errors.ts\";\nimport type { ModelMessage } from \"./model.types.ts\";\nimport type { TranscriptRecord } from \"./transcript.types.ts\";\n\nconst folds: Readonly<\n Record<\n TranscriptRecord[\"type\"],\n (messages: ModelMessage[], record: TranscriptRecord) => ModelMessage[]\n >\n> = {\n session: (messages) => messages,\n message: (messages, record) =>\n record.type === \"message\" ? [...messages, record.message] : messages,\n compaction: (_messages, record) =>\n record.type === \"compaction\" ? [...record.messages] : [],\n};\n\nexport function parseTranscript(text: string): readonly TranscriptRecord[] {\n const records = text\n .split(\"\\n\")\n .filter((line) => line.trim())\n .map((line) => {\n try {\n return JSON.parse(line) as TranscriptRecord;\n } catch {\n throw new OutpostError(\n \"session\",\n \"Harness transcript is not valid JSONL\",\n );\n }\n });\n const first = records[0];\n if (first?.type !== \"session\" || first.version !== 1)\n throw new OutpostError(\"session\", \"Unsupported harness transcript\");\n for (const record of records)\n if (!Object.hasOwn(folds, record?.type))\n throw new OutpostError(\n \"session\",\n \"Unsupported harness transcript record\",\n );\n return records;\n}\n\nexport function transcriptMessages(\n records: readonly TranscriptRecord[],\n): ModelMessage[] {\n const messages = records.reduce<ModelMessage[]>(\n (current, record) => folds[record.type](current, record),\n [],\n );\n const last = messages.at(-1);\n const pending =\n last?.role === \"assistant\"\n ? last.content.flatMap((block) =>\n block.type === \"tool-call\" ? [block.id] : [],\n )\n : [];\n if (!pending.length) return messages;\n return [\n ...messages,\n {\n role: \"user\",\n content: pending.map((callId) => ({\n type: \"tool-result\" as const,\n callId,\n content: \"The tool call was interrupted before it produced a result.\",\n isError: true,\n })),\n },\n ];\n}\n"]}