agency-lang 0.6.4 → 0.7.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 (843) hide show
  1. package/dist/lib/agents/agency-agent/agent.agency +595 -43
  2. package/dist/lib/agents/agency-agent/agent.js +5134 -2060
  3. package/dist/lib/agents/agency-agent/images/images.js +36 -15
  4. package/dist/lib/agents/agency-agent/lib/attachments.agency +115 -0
  5. package/dist/lib/agents/agency-agent/lib/attachments.js +791 -0
  6. package/dist/lib/agents/agency-agent/lib/config.agency +2 -0
  7. package/dist/lib/agents/agency-agent/lib/config.js +47 -15
  8. package/dist/lib/agents/agency-agent/lib/defaultPolicy.agency +28 -1
  9. package/dist/lib/agents/agency-agent/lib/defaultPolicy.js +64 -16
  10. package/dist/lib/agents/agency-agent/lib/modelFilters.agency +29 -0
  11. package/dist/lib/agents/agency-agent/lib/modelFilters.js +353 -0
  12. package/dist/lib/agents/agency-agent/lib/models.agency +214 -30
  13. package/dist/lib/agents/agency-agent/lib/models.js +1296 -278
  14. package/dist/lib/agents/agency-agent/lib/resolution.agency +191 -0
  15. package/dist/lib/agents/agency-agent/lib/resolution.js +1538 -0
  16. package/dist/lib/agents/agency-agent/lib/search.agency +471 -0
  17. package/dist/lib/agents/agency-agent/lib/search.js +2647 -0
  18. package/dist/lib/agents/agency-agent/lib/settings.agency +147 -0
  19. package/dist/lib/agents/agency-agent/lib/settings.js +956 -0
  20. package/dist/lib/agents/agency-agent/lib/slots.agency +34 -0
  21. package/dist/lib/agents/agency-agent/lib/slots.js +602 -0
  22. package/dist/lib/agents/agency-agent/lib/utils.js +38 -21
  23. package/dist/lib/agents/agency-agent/prompts/codeSample.agency +8 -4
  24. package/dist/lib/agents/agency-agent/prompts/codeSample.js +77 -45
  25. package/dist/lib/agents/agency-agent/prompts/design.md +13 -7
  26. package/dist/lib/agents/agency-agent/shared.agency +187 -27
  27. package/dist/lib/agents/agency-agent/shared.js +1399 -148
  28. package/dist/lib/agents/agency-agent/subagents/code.agency +46 -15
  29. package/dist/lib/agents/agency-agent/subagents/code.js +88 -48
  30. package/dist/lib/agents/agency-agent/subagents/explorer.agency +4 -2
  31. package/dist/lib/agents/agency-agent/subagents/explorer.js +57 -43
  32. package/dist/lib/agents/agency-agent/subagents/oracle.agency +4 -2
  33. package/dist/lib/agents/agency-agent/subagents/oracle.js +57 -43
  34. package/dist/lib/agents/agency-agent/subagents/research.agency +9 -10
  35. package/dist/lib/agents/agency-agent/subagents/research.js +55 -39
  36. package/dist/lib/agents/agency-agent/subagents/review.js +41 -24
  37. package/dist/lib/agents/agency-agent/subagents/shell.js +446 -0
  38. package/dist/lib/agents/agency-agent/tests/agentTurn.agency +222 -1
  39. package/dist/lib/agents/agency-agent/tests/agentTurn.js +2303 -30
  40. package/dist/lib/agents/agency-agent/tests/agentTurn.test.json +17 -1
  41. package/dist/lib/agents/agency-agent/tests/attachments.agency +187 -0
  42. package/dist/lib/agents/agency-agent/tests/attachments.js +3736 -0
  43. package/dist/lib/agents/agency-agent/tests/attachments.test.json +254 -0
  44. package/dist/lib/agents/agency-agent/tests/attachmentsTurn.agency +65 -0
  45. package/dist/lib/agents/agency-agent/tests/attachmentsTurn.js +1032 -0
  46. package/dist/lib/agents/agency-agent/tests/attachmentsTurn.test.json +110 -0
  47. package/dist/lib/agents/agency-agent/tests/execPolicy.js +47 -25
  48. package/dist/lib/agents/agency-agent/tests/gitPolicy.agency +53 -0
  49. package/dist/lib/agents/agency-agent/tests/gitPolicy.js +694 -0
  50. package/dist/lib/agents/agency-agent/tests/gitPolicy.test.json +7 -0
  51. package/dist/lib/agents/agency-agent/tests/imageTool.agency +51 -0
  52. package/dist/lib/agents/agency-agent/tests/imageTool.js +1111 -0
  53. package/dist/lib/agents/agency-agent/tests/imageTool.test.json +81 -0
  54. package/dist/lib/agents/agency-agent/tests/modelFilters.agency +32 -0
  55. package/dist/lib/agents/agency-agent/tests/modelFilters.js +723 -0
  56. package/dist/lib/agents/agency-agent/tests/modelFilters.test.json +7 -0
  57. package/dist/lib/agents/agency-agent/tests/models.agency +114 -0
  58. package/dist/lib/agents/agency-agent/tests/models.js +2143 -0
  59. package/dist/lib/agents/agency-agent/tests/models.test.json +49 -0
  60. package/dist/lib/agents/agency-agent/tests/resolution.agency +184 -0
  61. package/dist/lib/agents/agency-agent/tests/resolution.js +1498 -0
  62. package/dist/lib/agents/agency-agent/tests/resolution.test.json +13 -0
  63. package/dist/lib/agents/agency-agent/tests/search.agency +101 -0
  64. package/dist/lib/agents/agency-agent/tests/search.js +2095 -0
  65. package/dist/lib/agents/agency-agent/tests/search.test.json +19 -0
  66. package/dist/lib/agents/agency-agent/tests/settings.agency +87 -0
  67. package/dist/lib/agents/agency-agent/tests/settings.js +978 -0
  68. package/dist/lib/agents/agency-agent/tests/settings.test.json +26 -0
  69. package/dist/lib/agents/agency-agent/tests/slots.agency +22 -0
  70. package/dist/lib/agents/agency-agent/tests/slots.js +648 -0
  71. package/dist/lib/agents/agency-agent/tests/slots.test.json +10 -0
  72. package/dist/lib/agents/agency-agent/tests/toolWiring.js +41 -15
  73. package/dist/lib/agents/agency-agent/tests/turnFailure.agency +35 -0
  74. package/dist/lib/agents/agency-agent/tests/turnFailure.js +694 -0
  75. package/dist/lib/agents/agency-agent/tests/turnFailure.test.json +34 -0
  76. package/dist/lib/agents/docs/cli/cli/editor-integration.md +1 -1
  77. package/dist/lib/agents/docs/cli/cli/local.md +92 -0
  78. package/dist/lib/agents/docs/cli/cli/models.md +63 -0
  79. package/dist/lib/agents/docs/cli/cli/optimize.md +33 -1
  80. package/dist/lib/agents/docs/cli/cli/run.md +0 -29
  81. package/dist/lib/agents/docs/cli/editor-integration.md +1 -1
  82. package/dist/lib/agents/docs/cli/local.md +92 -0
  83. package/dist/lib/agents/docs/cli/models.md +63 -0
  84. package/dist/lib/agents/docs/cli/optimize.md +33 -1
  85. package/dist/lib/agents/docs/cli/run.md +0 -29
  86. package/dist/lib/agents/docs/guide/agency-config-file.md +205 -3
  87. package/dist/lib/agents/docs/guide/agency-packages.md +54 -0
  88. package/dist/lib/agents/docs/guide/agency-stdlib.md +14 -0
  89. package/dist/lib/agents/docs/guide/agency-vs-typescript.md +33 -0
  90. package/dist/lib/agents/docs/guide/attachments.md +56 -0
  91. package/dist/lib/agents/docs/guide/basic-syntax.md +204 -72
  92. package/dist/lib/agents/docs/guide/blocks.md +64 -34
  93. package/dist/lib/agents/docs/guide/build-integration.md +99 -0
  94. package/dist/lib/agents/docs/{appendix/appendix → guide}/builtins.md +27 -4
  95. package/dist/lib/agents/docs/{appendix/appendix → guide}/callbacks.md +55 -33
  96. package/dist/lib/agents/docs/guide/checkpointing.md +56 -27
  97. package/dist/lib/agents/docs/guide/cli-args.md +1 -1
  98. package/dist/lib/agents/docs/guide/common-functions.md +36 -0
  99. package/dist/lib/agents/docs/guide/compiling-and-running.md +62 -0
  100. package/dist/lib/agents/docs/guide/concurrency.md +49 -92
  101. package/dist/lib/agents/docs/guide/cross-thread-context.md +5 -7
  102. package/dist/lib/agents/docs/guide/custom-providers.md +195 -0
  103. package/dist/lib/agents/docs/guide/debugging.md +67 -0
  104. package/dist/lib/agents/docs/guide/developer-tools.md +90 -0
  105. package/dist/lib/agents/docs/guide/effects-and-raises.md +73 -92
  106. package/dist/lib/agents/docs/guide/effects.md +100 -0
  107. package/dist/lib/agents/docs/guide/error-handling.md +56 -44
  108. package/dist/lib/agents/docs/guide/exercise-1.md +32 -0
  109. package/dist/lib/agents/docs/guide/functions.md +71 -10
  110. package/dist/lib/agents/docs/guide/getting-started.md +5 -12
  111. package/dist/lib/agents/docs/guide/global-var-initialization.md +70 -0
  112. package/dist/lib/agents/docs/guide/global-vs-static.md +29 -34
  113. package/dist/lib/agents/docs/guide/guards.md +57 -108
  114. package/dist/lib/agents/docs/guide/guide/agency-config-file.md +205 -3
  115. package/dist/lib/agents/docs/guide/guide/agency-packages.md +54 -0
  116. package/dist/lib/agents/docs/guide/guide/agency-stdlib.md +14 -0
  117. package/dist/lib/agents/docs/guide/guide/agency-vs-typescript.md +33 -0
  118. package/dist/lib/agents/docs/guide/guide/attachments.md +56 -0
  119. package/dist/lib/agents/docs/guide/guide/basic-syntax.md +204 -72
  120. package/dist/lib/agents/docs/guide/guide/blocks.md +64 -34
  121. package/dist/lib/agents/docs/guide/guide/build-integration.md +99 -0
  122. package/dist/lib/agents/docs/{appendix → guide/guide}/builtins.md +27 -4
  123. package/dist/lib/agents/docs/{appendix → guide/guide}/callbacks.md +55 -33
  124. package/dist/lib/agents/docs/guide/guide/checkpointing.md +56 -27
  125. package/dist/lib/agents/docs/guide/guide/cli-args.md +1 -1
  126. package/dist/lib/agents/docs/guide/guide/common-functions.md +36 -0
  127. package/dist/lib/agents/docs/guide/guide/compiling-and-running.md +62 -0
  128. package/dist/lib/agents/docs/guide/guide/concurrency.md +49 -92
  129. package/dist/lib/agents/docs/guide/guide/cross-thread-context.md +5 -7
  130. package/dist/lib/agents/docs/guide/guide/custom-providers.md +195 -0
  131. package/dist/lib/agents/docs/guide/guide/debugging.md +67 -0
  132. package/dist/lib/agents/docs/guide/guide/developer-tools.md +90 -0
  133. package/dist/lib/agents/docs/guide/guide/effects-and-raises.md +73 -92
  134. package/dist/lib/agents/docs/guide/guide/effects.md +100 -0
  135. package/dist/lib/agents/docs/guide/guide/error-handling.md +56 -44
  136. package/dist/lib/agents/docs/guide/guide/exercise-1.md +32 -0
  137. package/dist/lib/agents/docs/guide/guide/functions.md +71 -10
  138. package/dist/lib/agents/docs/guide/guide/getting-started.md +5 -12
  139. package/dist/lib/agents/docs/guide/guide/global-var-initialization.md +70 -0
  140. package/dist/lib/agents/docs/guide/guide/global-vs-static.md +29 -34
  141. package/dist/lib/agents/docs/guide/guide/guards.md +57 -108
  142. package/dist/lib/agents/docs/guide/guide/handlers.md +109 -205
  143. package/dist/lib/agents/docs/guide/guide/image-generation.md +113 -0
  144. package/dist/lib/agents/docs/guide/guide/imports-and-packages.md +35 -95
  145. package/dist/lib/agents/docs/guide/guide/interrupts-from-typescript.md +84 -0
  146. package/dist/lib/agents/docs/guide/guide/interrupts-part-2.md +54 -0
  147. package/dist/lib/agents/docs/guide/guide/interrupts.md +98 -58
  148. package/dist/lib/agents/docs/guide/guide/llm-part-2.md +111 -0
  149. package/dist/lib/agents/docs/guide/guide/llm.md +53 -124
  150. package/dist/lib/agents/docs/guide/guide/memory.md +262 -249
  151. package/dist/lib/agents/docs/guide/guide/message-threads.md +111 -0
  152. package/dist/lib/agents/docs/guide/guide/nodes.md +32 -17
  153. package/dist/lib/agents/docs/guide/guide/observability.md +11 -4
  154. package/dist/lib/agents/docs/guide/guide/partial-application.md +40 -132
  155. package/dist/lib/agents/docs/guide/guide/pattern-matching.md +216 -43
  156. package/dist/lib/agents/docs/guide/guide/policies.md +11 -4
  157. package/dist/lib/agents/docs/guide/guide/schemas.md +22 -9
  158. package/dist/lib/agents/docs/guide/guide/state-isolation.md +139 -0
  159. package/dist/lib/agents/docs/guide/guide/streaming.md +28 -0
  160. package/dist/lib/agents/docs/guide/guide/tags.md +72 -0
  161. package/dist/lib/agents/docs/guide/guide/testing.md +167 -7
  162. package/dist/lib/agents/docs/guide/guide/troubleshooting.md +2 -53
  163. package/dist/lib/agents/docs/{appendix/appendix → guide/guide}/ts-helpers.md +48 -0
  164. package/dist/lib/agents/docs/guide/guide/ts-interop.md +16 -129
  165. package/dist/lib/agents/docs/guide/guide/type-validation.md +30 -172
  166. package/dist/lib/agents/docs/guide/guide/types.md +69 -84
  167. package/dist/lib/agents/docs/guide/guide/unused.md +178 -0
  168. package/dist/lib/agents/docs/guide/guide/unused2.md +258 -0
  169. package/dist/lib/agents/docs/guide/guide/value-parameterized-types.md +186 -0
  170. package/dist/lib/agents/docs/guide/guide/vscode-extension.md +33 -0
  171. package/dist/lib/agents/docs/guide/guide/why-agency.md +323 -0
  172. package/dist/lib/agents/docs/guide/handlers.md +109 -205
  173. package/dist/lib/agents/docs/guide/image-generation.md +113 -0
  174. package/dist/lib/agents/docs/guide/imports-and-packages.md +35 -95
  175. package/dist/lib/agents/docs/guide/interrupts-from-typescript.md +84 -0
  176. package/dist/lib/agents/docs/guide/interrupts-part-2.md +54 -0
  177. package/dist/lib/agents/docs/guide/interrupts.md +98 -58
  178. package/dist/lib/agents/docs/guide/llm-part-2.md +111 -0
  179. package/dist/lib/agents/docs/guide/llm.md +53 -124
  180. package/dist/lib/agents/docs/guide/memory.md +262 -249
  181. package/dist/lib/agents/docs/guide/message-threads.md +111 -0
  182. package/dist/lib/agents/docs/guide/nodes.md +32 -17
  183. package/dist/lib/agents/docs/guide/observability.md +11 -4
  184. package/dist/lib/agents/docs/guide/partial-application.md +40 -132
  185. package/dist/lib/agents/docs/guide/pattern-matching.md +216 -43
  186. package/dist/lib/agents/docs/guide/policies.md +11 -4
  187. package/dist/lib/agents/docs/guide/schemas.md +22 -9
  188. package/dist/lib/agents/docs/guide/state-isolation.md +139 -0
  189. package/dist/lib/agents/docs/guide/streaming.md +28 -0
  190. package/dist/lib/agents/docs/guide/tags.md +72 -0
  191. package/dist/lib/agents/docs/guide/testing.md +167 -7
  192. package/dist/lib/agents/docs/guide/troubleshooting.md +2 -53
  193. package/dist/lib/agents/docs/{appendix → guide}/ts-helpers.md +48 -0
  194. package/dist/lib/agents/docs/guide/ts-interop.md +16 -129
  195. package/dist/lib/agents/docs/guide/type-validation.md +30 -172
  196. package/dist/lib/agents/docs/guide/types.md +69 -84
  197. package/dist/lib/agents/docs/guide/unused.md +178 -0
  198. package/dist/lib/agents/docs/guide/unused2.md +258 -0
  199. package/dist/lib/agents/docs/guide/value-parameterized-types.md +186 -0
  200. package/dist/lib/agents/docs/guide/vscode-extension.md +33 -0
  201. package/dist/lib/agents/docs/guide/why-agency.md +323 -0
  202. package/dist/lib/agents/eval/goalJudge.js +35 -14
  203. package/dist/lib/agents/eval/judge.js +35 -14
  204. package/dist/lib/agents/eval/judgePairwise.agency +2 -2
  205. package/dist/lib/agents/eval/judgePairwise.js +35 -14
  206. package/dist/lib/agents/optimize/gepaReflect.js +35 -14
  207. package/dist/lib/agents/optimize/mutatePrompt.agency +2 -0
  208. package/dist/lib/agents/optimize/mutatePrompt.js +38 -15
  209. package/dist/lib/agents/policy/agent.agency +2 -2
  210. package/dist/lib/agents/policy/agent.js +94 -58
  211. package/dist/lib/agents/review/agent.js +41 -19
  212. package/dist/lib/backends/agencyGenerator.d.ts +14 -2
  213. package/dist/lib/backends/agencyGenerator.js +158 -53
  214. package/dist/lib/backends/agencyGenerator.matchBlock.test.js +106 -0
  215. package/dist/lib/backends/agencyGenerator.test.js +148 -0
  216. package/dist/lib/backends/effectDeclarationFormat.test.d.ts +1 -0
  217. package/dist/lib/backends/effectDeclarationFormat.test.js +32 -0
  218. package/dist/lib/backends/llmAttachmentCodegen.test.d.ts +1 -0
  219. package/dist/lib/backends/llmAttachmentCodegen.test.js +24 -0
  220. package/dist/lib/backends/llmNamedArgsCodegen.test.d.ts +1 -0
  221. package/dist/lib/backends/llmNamedArgsCodegen.test.js +40 -0
  222. package/dist/lib/backends/providerModules.codegen.test.d.ts +1 -0
  223. package/dist/lib/backends/{anthropicApiKey.codegen.test.js → providerModules.codegen.test.js} +12 -15
  224. package/dist/lib/backends/smoltalkDefaults.codegen.test.d.ts +1 -0
  225. package/dist/lib/backends/smoltalkDefaults.codegen.test.js +65 -0
  226. package/dist/lib/backends/typescriptBuilder.d.ts +82 -0
  227. package/dist/lib/backends/typescriptBuilder.integration.test.js +94 -4
  228. package/dist/lib/backends/typescriptBuilder.js +499 -158
  229. package/dist/lib/backends/typescriptGenerator/typeToString.js +8 -2
  230. package/dist/lib/backends/typescriptGenerator/typeToZodSchema.js +25 -28
  231. package/dist/lib/backends/typescriptGenerator/typeToZodSchema.test.js +73 -0
  232. package/dist/lib/cli/commands.d.ts +28 -0
  233. package/dist/lib/cli/commands.js +53 -4
  234. package/dist/lib/cli/doc.js +19 -0
  235. package/dist/lib/cli/doc.test.js +27 -1
  236. package/dist/lib/cli/eval/run.d.ts +18 -1
  237. package/dist/lib/cli/eval/run.js +55 -24
  238. package/dist/lib/cli/eval/run.workdir.test.d.ts +1 -0
  239. package/dist/lib/cli/eval/run.workdir.test.js +111 -0
  240. package/dist/lib/cli/fetchMockResolve.d.ts +6 -0
  241. package/dist/lib/cli/fetchMockResolve.js +51 -0
  242. package/dist/lib/cli/fetchMockResolve.test.d.ts +1 -0
  243. package/dist/lib/cli/fetchMockResolve.test.js +36 -0
  244. package/dist/lib/cli/hostedModels.d.ts +10 -0
  245. package/dist/lib/cli/hostedModels.js +61 -0
  246. package/dist/lib/cli/hostedModels.test.d.ts +1 -0
  247. package/dist/lib/cli/hostedModels.test.js +105 -0
  248. package/dist/lib/cli/local.d.ts +19 -0
  249. package/dist/lib/cli/local.js +109 -0
  250. package/dist/lib/cli/local.test.d.ts +1 -0
  251. package/dist/lib/cli/local.test.js +50 -0
  252. package/dist/lib/cli/pack.test.js +18 -0
  253. package/dist/lib/cli/precompile.d.ts +22 -0
  254. package/dist/lib/cli/precompile.js +125 -0
  255. package/dist/lib/cli/precompile.test.d.ts +1 -0
  256. package/dist/lib/cli/precompile.test.js +172 -0
  257. package/dist/lib/cli/test.js +55 -5
  258. package/dist/lib/cli/util.d.ts +8 -2
  259. package/dist/lib/cli/util.js +23 -6
  260. package/dist/lib/compiler/compile.js +5 -1
  261. package/dist/lib/compiler/compile.test.js +54 -1
  262. package/dist/lib/compiler/compileClosure.js +8 -9
  263. package/dist/lib/compiler/typecheck.js +10 -3
  264. package/dist/lib/config.d.ts +114 -6
  265. package/dist/lib/config.js +39 -3
  266. package/dist/lib/config.modelAliases.test.d.ts +1 -0
  267. package/dist/lib/config.modelAliases.test.js +11 -0
  268. package/dist/lib/config.providerModules.test.d.ts +1 -0
  269. package/dist/lib/config.providerModules.test.js +16 -0
  270. package/dist/lib/config.test.js +12 -0
  271. package/dist/lib/constants.d.ts +12 -0
  272. package/dist/lib/constants.js +12 -0
  273. package/dist/lib/effectDeclCollection.test.d.ts +1 -0
  274. package/dist/lib/effectDeclCollection.test.js +56 -0
  275. package/dist/lib/eval/runArtifacts.js +4 -10
  276. package/dist/lib/eval/runArtifacts.test.js +10 -22
  277. package/dist/lib/eval/runEvalInput.d.ts +11 -3
  278. package/dist/lib/eval/runEvalInput.js +16 -1
  279. package/dist/lib/eval/runTypes.d.ts +0 -4
  280. package/dist/lib/eval/runWorkdir.d.ts +25 -0
  281. package/dist/lib/eval/runWorkdir.js +46 -0
  282. package/dist/lib/eval/runWorkdir.test.d.ts +1 -0
  283. package/dist/lib/eval/runWorkdir.test.js +42 -0
  284. package/dist/lib/importPaths.d.ts +31 -1
  285. package/dist/lib/importPaths.js +88 -32
  286. package/dist/lib/importPaths.test.js +47 -4
  287. package/dist/lib/ir/builders.d.ts +6 -1
  288. package/dist/lib/ir/builders.js +3 -0
  289. package/dist/lib/ir/prettyPrint.js +31 -6
  290. package/dist/lib/ir/prettyPrint.test.js +70 -7
  291. package/dist/lib/ir/tsIR.d.ts +12 -2
  292. package/dist/lib/logsViewer/render.js +2 -0
  293. package/dist/lib/logsViewer/summary.js +13 -0
  294. package/dist/lib/logsViewer/summary.test.js +6 -0
  295. package/dist/lib/logsViewer/tree.js +38 -0
  296. package/dist/lib/logsViewer/tree.test.js +19 -0
  297. package/dist/lib/lowering/loweringError.d.ts +10 -0
  298. package/dist/lib/lowering/loweringError.js +13 -0
  299. package/dist/lib/lowering/patternLowering.ifExpr.test.d.ts +1 -0
  300. package/dist/lib/lowering/patternLowering.ifExpr.test.js +59 -0
  301. package/dist/lib/lowering/patternLowering.js +504 -30
  302. package/dist/lib/lowering/patternLowering.matchExpr.test.d.ts +1 -0
  303. package/dist/lib/lowering/patternLowering.matchExpr.test.js +572 -0
  304. package/dist/lib/lowering/patternLowering.test.js +102 -10
  305. package/dist/lib/lsp/codeAction.js +3 -3
  306. package/dist/lib/lsp/codeAction.test.js +13 -10
  307. package/dist/lib/lsp/completion.js +2 -2
  308. package/dist/lib/lsp/diagnostics.js +11 -4
  309. package/dist/lib/lsp/diagnostics.test.js +30 -0
  310. package/dist/lib/matchVal.d.ts +18 -0
  311. package/dist/lib/matchVal.js +26 -0
  312. package/dist/lib/optimize/artifacts.js +8 -35
  313. package/dist/lib/optimize/artifacts.test.js +12 -5
  314. package/dist/lib/optimize/baseOptimizer.d.ts +15 -9
  315. package/dist/lib/optimize/baseOptimizer.js +33 -27
  316. package/dist/lib/optimize/baseOptimizer.test.js +25 -15
  317. package/dist/lib/optimize/baseOptimizer.workdir.test.js +29 -24
  318. package/dist/lib/optimize/constraint.d.ts +45 -0
  319. package/dist/lib/optimize/constraint.js +78 -0
  320. package/dist/lib/optimize/constraint.test.d.ts +1 -0
  321. package/dist/lib/optimize/constraint.test.js +133 -0
  322. package/dist/lib/optimize/grading/scorecard.d.ts +6 -0
  323. package/dist/lib/optimize/grading/scorecard.js +8 -0
  324. package/dist/lib/optimize/mutator.js +2 -0
  325. package/dist/lib/optimize/mutator.test.js +37 -0
  326. package/dist/lib/optimize/optimizers/example.d.ts +4 -1
  327. package/dist/lib/optimize/optimizers/example.js +11 -12
  328. package/dist/lib/optimize/optimizers/example.test.js +2 -2
  329. package/dist/lib/optimize/optimizers/gepa.d.ts +1 -1
  330. package/dist/lib/optimize/optimizers/gepa.js +11 -10
  331. package/dist/lib/optimize/optimizers/gepa.test.js +5 -5
  332. package/dist/lib/optimize/optimizers/greedyReflective.d.ts +1 -1
  333. package/dist/lib/optimize/optimizers/greedyReflective.js +8 -7
  334. package/dist/lib/optimize/optimizers/greedyReflective.test.js +100 -2
  335. package/dist/lib/optimize/reporter.test.js +2 -0
  336. package/dist/lib/optimize/sourceMutator.d.ts +8 -4
  337. package/dist/lib/optimize/sourceMutator.js +63 -13
  338. package/dist/lib/optimize/sourceMutator.test.js +117 -0
  339. package/dist/lib/optimize/targets.d.ts +21 -3
  340. package/dist/lib/optimize/targets.js +119 -10
  341. package/dist/lib/optimize/targets.test.js +79 -5
  342. package/dist/lib/optimize/types.d.ts +8 -1
  343. package/dist/lib/optimize/workspace.d.ts +8 -30
  344. package/dist/lib/optimize/workspace.js +5 -78
  345. package/dist/lib/optimize/workspace.test.js +10 -70
  346. package/dist/lib/parseCache.d.ts +10 -0
  347. package/dist/lib/parseCache.js +58 -0
  348. package/dist/lib/parseCache.test.d.ts +1 -0
  349. package/dist/lib/parseCache.test.js +113 -0
  350. package/dist/lib/parser.js +27 -2
  351. package/dist/lib/parsers/dataStructures.test.js +86 -0
  352. package/dist/lib/parsers/debugMessagesLeak.test.d.ts +1 -0
  353. package/dist/lib/parsers/debugMessagesLeak.test.js +31 -0
  354. package/dist/lib/parsers/effectDeclaration.test.d.ts +1 -0
  355. package/dist/lib/parsers/effectDeclaration.test.js +107 -0
  356. package/dist/lib/parsers/function.test.js +39 -2
  357. package/dist/lib/parsers/ifExpression.test.d.ts +1 -0
  358. package/dist/lib/parsers/ifExpression.test.js +45 -0
  359. package/dist/lib/parsers/importStatement.test.js +49 -0
  360. package/dist/lib/parsers/literals.test.js +52 -0
  361. package/dist/lib/parsers/matchBlock.test.js +298 -59
  362. package/dist/lib/parsers/parsers.d.ts +21 -2
  363. package/dist/lib/parsers/parsers.js +232 -100
  364. package/dist/lib/parsers/pattern.test.js +10 -10
  365. package/dist/lib/parsers/typeHints.test.js +70 -0
  366. package/dist/lib/preprocessors/importResolver.d.ts +3 -1
  367. package/dist/lib/preprocessors/importResolver.js +37 -7
  368. package/dist/lib/preprocessors/importResolver.test.js +82 -0
  369. package/dist/lib/preprocessors/injectSchemaArgs.js +1 -2
  370. package/dist/lib/preprocessors/liftCallbacks.js +1 -1
  371. package/dist/lib/preprocessors/parallelDesugar.js +3 -2
  372. package/dist/lib/preprocessors/parallelDesugar.test.js +3 -2
  373. package/dist/lib/preprocessors/prunePreludeShadows.d.ts +22 -0
  374. package/dist/lib/preprocessors/prunePreludeShadows.js +55 -0
  375. package/dist/lib/preprocessors/prunePreludeShadows.test.d.ts +1 -0
  376. package/dist/lib/preprocessors/prunePreludeShadows.test.js +112 -0
  377. package/dist/lib/preprocessors/typescriptPreprocessor.core.test.js +25 -0
  378. package/dist/lib/preprocessors/typescriptPreprocessor.js +7 -5
  379. package/dist/lib/runtime/__tests__/testHelpers.js +0 -1
  380. package/dist/lib/runtime/agency.d.ts +3 -1
  381. package/dist/lib/runtime/agency.js +6 -7
  382. package/dist/lib/runtime/agencyFunction.js +13 -4
  383. package/dist/lib/runtime/agencyFunction.test.js +52 -0
  384. package/dist/lib/runtime/agencyInterrupt.test.js +91 -6
  385. package/dist/lib/runtime/agencyLlm.d.ts +14 -3
  386. package/dist/lib/runtime/agencyLlm.js +10 -0
  387. package/dist/lib/runtime/agencyLlm.test.js +17 -0
  388. package/dist/lib/runtime/callDepth.d.ts +36 -0
  389. package/dist/lib/runtime/callDepth.js +76 -0
  390. package/dist/lib/runtime/callDepth.test.d.ts +1 -0
  391. package/dist/lib/runtime/callDepth.test.js +67 -0
  392. package/dist/lib/runtime/callbackForwarding.d.ts +47 -0
  393. package/dist/lib/runtime/callbackForwarding.js +76 -0
  394. package/dist/lib/runtime/callbackForwarding.test.d.ts +1 -0
  395. package/dist/lib/runtime/callbackForwarding.test.js +72 -0
  396. package/dist/lib/runtime/configOverrides.d.ts +17 -5
  397. package/dist/lib/runtime/configOverrides.js +28 -6
  398. package/dist/lib/runtime/configOverrides.test.js +33 -0
  399. package/dist/lib/runtime/cost.d.ts +10 -0
  400. package/dist/lib/runtime/cost.js +17 -0
  401. package/dist/lib/runtime/costTelemetry.d.ts +24 -0
  402. package/dist/lib/runtime/costTelemetry.js +39 -0
  403. package/dist/lib/runtime/costTelemetry.test.d.ts +1 -0
  404. package/dist/lib/runtime/costTelemetry.test.js +92 -0
  405. package/dist/lib/runtime/deterministicClient.d.ts +9 -2
  406. package/dist/lib/runtime/deterministicClient.js +21 -1
  407. package/dist/lib/runtime/deterministicClient.test.js +29 -0
  408. package/dist/lib/runtime/eq.d.ts +12 -0
  409. package/dist/lib/runtime/eq.js +14 -0
  410. package/dist/lib/runtime/eq.test.d.ts +1 -0
  411. package/dist/lib/runtime/eq.test.js +32 -0
  412. package/dist/lib/runtime/errors.d.ts +20 -0
  413. package/dist/lib/runtime/errors.js +23 -0
  414. package/dist/lib/runtime/errors.test.js +18 -0
  415. package/dist/lib/runtime/fetchMock.d.ts +12 -0
  416. package/dist/lib/runtime/fetchMock.js +167 -0
  417. package/dist/lib/runtime/fetchMock.test.d.ts +1 -0
  418. package/dist/lib/runtime/fetchMock.test.js +145 -0
  419. package/dist/lib/runtime/hooks.d.ts +21 -3
  420. package/dist/lib/runtime/hooks.js +19 -0
  421. package/dist/lib/runtime/hooks.test.js +39 -2
  422. package/dist/lib/runtime/image-client.test.d.ts +1 -0
  423. package/dist/lib/runtime/image-client.test.js +22 -0
  424. package/dist/lib/runtime/index.d.ts +4 -1
  425. package/dist/lib/runtime/index.js +3 -1
  426. package/dist/lib/runtime/interrupts.d.ts +50 -0
  427. package/dist/lib/runtime/interrupts.js +206 -126
  428. package/dist/lib/runtime/interrupts.test.js +110 -1
  429. package/dist/lib/runtime/ipc.configOverrides.test.js +35 -17
  430. package/dist/lib/runtime/ipc.d.ts +238 -21
  431. package/dist/lib/runtime/ipc.js +622 -95
  432. package/dist/lib/runtime/ipc.test.js +453 -2
  433. package/dist/lib/runtime/llmClient.d.ts +71 -3
  434. package/dist/lib/runtime/llmClient.hostedTools.test.d.ts +1 -0
  435. package/dist/lib/runtime/llmClient.hostedTools.test.js +45 -0
  436. package/dist/lib/runtime/llmClient.js +71 -11
  437. package/dist/lib/runtime/llmClient.test.d.ts +1 -0
  438. package/dist/lib/runtime/llmClient.test.js +80 -0
  439. package/dist/lib/runtime/llmRetry.d.ts +65 -0
  440. package/dist/lib/runtime/llmRetry.js +158 -0
  441. package/dist/lib/runtime/llmRetry.test.d.ts +1 -0
  442. package/dist/lib/runtime/llmRetry.test.js +94 -0
  443. package/dist/lib/runtime/memory/manager.d.ts +25 -0
  444. package/dist/lib/runtime/memory/manager.js +115 -14
  445. package/dist/lib/runtime/memory/manager.test.js +60 -21
  446. package/dist/lib/runtime/memory/types.d.ts +7 -0
  447. package/dist/lib/runtime/node.js +10 -1
  448. package/dist/lib/runtime/prompt.attachments.test.d.ts +1 -0
  449. package/dist/lib/runtime/prompt.attachments.test.js +41 -0
  450. package/dist/lib/runtime/prompt.d.ts +65 -2
  451. package/dist/lib/runtime/prompt.js +276 -31
  452. package/dist/lib/runtime/prompt.test.js +170 -1
  453. package/dist/lib/runtime/promptRunner.d.ts +1 -1
  454. package/dist/lib/runtime/promptRunner.js +1 -1
  455. package/dist/lib/runtime/providerModules.d.ts +27 -0
  456. package/dist/lib/runtime/providerModules.js +87 -0
  457. package/dist/lib/runtime/providerModules.test.d.ts +1 -0
  458. package/dist/lib/runtime/providerModules.test.js +90 -0
  459. package/dist/lib/runtime/redactForStatelog.d.ts +20 -0
  460. package/dist/lib/runtime/redactForStatelog.js +32 -0
  461. package/dist/lib/runtime/redactForStatelog.test.d.ts +1 -0
  462. package/dist/lib/runtime/redactForStatelog.test.js +84 -0
  463. package/dist/lib/runtime/replyAttachments.d.ts +46 -0
  464. package/dist/lib/runtime/replyAttachments.js +143 -0
  465. package/dist/lib/runtime/replyAttachments.test.d.ts +1 -0
  466. package/dist/lib/runtime/replyAttachments.test.js +205 -0
  467. package/dist/lib/runtime/result.js +8 -0
  468. package/dist/lib/runtime/revivers/index.js +2 -0
  469. package/dist/lib/runtime/revivers/taggedReviver.d.ts +8 -0
  470. package/dist/lib/runtime/revivers/taggedReviver.js +30 -0
  471. package/dist/lib/runtime/revivers/taggedReviver.test.d.ts +1 -0
  472. package/dist/lib/runtime/revivers/taggedReviver.test.js +42 -0
  473. package/dist/lib/runtime/runBatch.js +33 -16
  474. package/dist/lib/runtime/runBatch.test.js +62 -0
  475. package/dist/lib/runtime/runner.d.ts +26 -4
  476. package/dist/lib/runtime/runner.js +125 -49
  477. package/dist/lib/runtime/runner.test.js +217 -1
  478. package/dist/lib/runtime/simpleOpenAIClient.js +1 -1
  479. package/dist/lib/runtime/state/context.d.ts +22 -12
  480. package/dist/lib/runtime/state/context.js +43 -14
  481. package/dist/lib/runtime/state/context.providerModules.test.d.ts +1 -0
  482. package/dist/lib/runtime/state/context.providerModules.test.js +38 -0
  483. package/dist/lib/runtime/state/globalStore.d.ts +42 -0
  484. package/dist/lib/runtime/state/globalStore.js +187 -2
  485. package/dist/lib/runtime/state/globalStore.tags.test.d.ts +1 -0
  486. package/dist/lib/runtime/state/globalStore.tags.test.js +211 -0
  487. package/dist/lib/runtime/state/stateStack.d.ts +34 -0
  488. package/dist/lib/runtime/state/stateStack.js +46 -0
  489. package/dist/lib/runtime/state/tagSymbol.d.ts +6 -0
  490. package/dist/lib/runtime/state/tagSymbol.js +49 -0
  491. package/dist/lib/runtime/state/tagSymbol.test.d.ts +1 -0
  492. package/dist/lib/runtime/state/tagSymbol.test.js +60 -0
  493. package/dist/lib/runtime/streaming.d.ts +7 -2
  494. package/dist/lib/runtime/streaming.js +31 -8
  495. package/dist/lib/runtime/subprocess-bootstrap.js +90 -35
  496. package/dist/lib/runtime/subprocessRunInfo.d.ts +46 -0
  497. package/dist/lib/runtime/subprocessRunInfo.js +53 -0
  498. package/dist/lib/runtime/subprocessRunInfo.test.d.ts +1 -0
  499. package/dist/lib/runtime/subprocessRunInfo.test.js +32 -0
  500. package/dist/lib/runtime/topsortCycleErrors.test.js +69 -0
  501. package/dist/lib/runtime/utils.d.ts +16 -2
  502. package/dist/lib/runtime/utils.js +13 -4
  503. package/dist/lib/runtime/utils.test.js +27 -0
  504. package/dist/lib/statelogClient.d.ts +40 -1
  505. package/dist/lib/statelogClient.js +98 -1
  506. package/dist/lib/statelogClient.redaction.test.d.ts +1 -0
  507. package/dist/lib/statelogClient.redaction.test.js +131 -0
  508. package/dist/lib/statelogClient.test.js +13 -0
  509. package/dist/lib/stdlib/abortable.d.ts +6 -0
  510. package/dist/lib/stdlib/abortable.js +26 -1
  511. package/dist/lib/stdlib/agency.d.ts +7 -2
  512. package/dist/lib/stdlib/agency.js +17 -13
  513. package/dist/lib/stdlib/agencyEval.js +7 -1
  514. package/dist/lib/stdlib/args.d.ts +4 -1
  515. package/dist/lib/stdlib/args.js +68 -0
  516. package/dist/lib/stdlib/builtins.d.ts +2 -1
  517. package/dist/lib/stdlib/builtins.js +22 -13
  518. package/dist/lib/stdlib/cli.d.ts +65 -0
  519. package/dist/lib/stdlib/cli.js +217 -39
  520. package/dist/lib/stdlib/git.d.ts +29 -0
  521. package/dist/lib/stdlib/git.js +80 -0
  522. package/dist/lib/stdlib/gitCore.d.ts +132 -0
  523. package/dist/lib/stdlib/gitCore.js +231 -0
  524. package/dist/lib/stdlib/gitParse.d.ts +17 -0
  525. package/dist/lib/stdlib/gitParse.js +259 -0
  526. package/dist/lib/stdlib/http.d.ts +5 -4
  527. package/dist/lib/stdlib/http.js +42 -1
  528. package/dist/lib/stdlib/image.d.ts +7 -0
  529. package/dist/lib/stdlib/image.js +80 -0
  530. package/dist/lib/stdlib/layout/ansi.js +35 -3
  531. package/dist/lib/stdlib/layout/axis.js +14 -5
  532. package/dist/lib/stdlib/layout/barchart.js +5 -5
  533. package/dist/lib/stdlib/layout/block.js +2 -2
  534. package/dist/lib/stdlib/layout/border.js +2 -2
  535. package/dist/lib/stdlib/layout/box.js +12 -4
  536. package/dist/lib/stdlib/layout/nodes.d.ts +0 -1
  537. package/dist/lib/stdlib/layout/nodes.js +40 -17
  538. package/dist/lib/stdlib/layout/render.js +7 -3
  539. package/dist/lib/stdlib/layout/sizing.d.ts +1 -0
  540. package/dist/lib/stdlib/layout/sizing.js +1 -1
  541. package/dist/lib/stdlib/layout/table.js +11 -11
  542. package/dist/lib/stdlib/layout.js +1 -1
  543. package/dist/lib/stdlib/llm.d.ts +54 -1
  544. package/dist/lib/stdlib/llm.js +104 -0
  545. package/dist/lib/stdlib/localModels.d.ts +209 -0
  546. package/dist/lib/stdlib/localModels.js +904 -0
  547. package/dist/lib/stdlib/mediaPathScan.d.ts +31 -0
  548. package/dist/lib/stdlib/mediaPathScan.js +79 -0
  549. package/dist/lib/stdlib/providers/llama-cpp.mjs +79 -0
  550. package/dist/lib/stdlib/providers/llamaModelConfig.d.ts +7 -0
  551. package/dist/lib/stdlib/providers/llamaModelConfig.js +7 -0
  552. package/dist/lib/stdlib/search.d.ts +7 -0
  553. package/dist/lib/stdlib/search.js +40 -0
  554. package/dist/lib/stdlib/shell.d.ts +1 -1
  555. package/dist/lib/stdlib/shell.js +4 -2
  556. package/dist/lib/stdlib/tag.d.ts +17 -0
  557. package/dist/lib/stdlib/tag.js +49 -0
  558. package/dist/lib/stdlib/thread.d.ts +38 -3
  559. package/dist/lib/stdlib/thread.js +71 -2
  560. package/dist/lib/stdlib/threads.d.ts +12 -0
  561. package/dist/lib/stdlib/threads.js +48 -17
  562. package/dist/lib/stdlib/version.d.ts +1 -1
  563. package/dist/lib/stdlib/version.js +1 -1
  564. package/dist/lib/symbolTable.d.ts +10 -1
  565. package/dist/lib/symbolTable.js +27 -7
  566. package/dist/lib/templates/backends/agency/template.d.ts +1 -1
  567. package/dist/lib/templates/backends/agency/template.js +1 -1
  568. package/dist/lib/templates/backends/typescriptGenerator/imports.d.ts +1 -1
  569. package/dist/lib/templates/backends/typescriptGenerator/imports.js +14 -2
  570. package/dist/lib/templates/backends/typescriptGenerator/runnerIfElse.d.ts +2 -1
  571. package/dist/lib/templates/backends/typescriptGenerator/runnerIfElse.js +1 -1
  572. package/dist/lib/typeChecker/assignability.d.ts +8 -0
  573. package/dist/lib/typeChecker/assignability.js +26 -4
  574. package/dist/lib/typeChecker/assignability.test.js +59 -1
  575. package/dist/lib/typeChecker/attachments.test.d.ts +1 -0
  576. package/dist/lib/typeChecker/attachments.test.js +45 -0
  577. package/dist/lib/typeChecker/builtinNamedArgs.test.js +30 -0
  578. package/dist/lib/typeChecker/builtins.js +134 -40
  579. package/dist/lib/typeChecker/checker.d.ts +25 -0
  580. package/dist/lib/typeChecker/checker.js +41 -4
  581. package/dist/lib/typeChecker/definiteReturns.d.ts +16 -0
  582. package/dist/lib/typeChecker/definiteReturns.js +52 -0
  583. package/dist/lib/typeChecker/definiteReturns.test.d.ts +1 -0
  584. package/dist/lib/typeChecker/definiteReturns.test.js +203 -0
  585. package/dist/lib/typeChecker/effectPayloadCheck.d.ts +17 -0
  586. package/dist/lib/typeChecker/effectPayloadCheck.js +181 -0
  587. package/dist/lib/typeChecker/effectPayloadCheck.test.d.ts +1 -0
  588. package/dist/lib/typeChecker/effectPayloadCheck.test.js +192 -0
  589. package/dist/lib/typeChecker/flow.d.ts +131 -0
  590. package/dist/lib/typeChecker/flow.js +248 -0
  591. package/dist/lib/typeChecker/flow.test.d.ts +1 -0
  592. package/dist/lib/typeChecker/flow.test.js +467 -0
  593. package/dist/lib/typeChecker/flowAssignments.test.d.ts +1 -0
  594. package/dist/lib/typeChecker/flowAssignments.test.js +84 -0
  595. package/dist/lib/typeChecker/flowBuilder.d.ts +32 -0
  596. package/dist/lib/typeChecker/flowBuilder.js +337 -0
  597. package/dist/lib/typeChecker/flowBuilder.test.d.ts +1 -0
  598. package/dist/lib/typeChecker/flowBuilder.test.js +215 -0
  599. package/dist/lib/typeChecker/flowNarrowing.test.d.ts +1 -0
  600. package/dist/lib/typeChecker/flowNarrowing.test.js +96 -0
  601. package/dist/lib/typeChecker/handlerBodyInterrupts.test.js +1 -1
  602. package/dist/lib/typeChecker/handlerParamTyping.d.ts +31 -0
  603. package/dist/lib/typeChecker/handlerParamTyping.js +108 -0
  604. package/dist/lib/typeChecker/handlerParamTyping.test.d.ts +1 -0
  605. package/dist/lib/typeChecker/handlerParamTyping.test.js +379 -0
  606. package/dist/lib/typeChecker/ifExpression.test.d.ts +1 -0
  607. package/dist/lib/typeChecker/ifExpression.test.js +49 -0
  608. package/dist/lib/typeChecker/index.js +43 -3
  609. package/dist/lib/typeChecker/inference.d.ts +6 -0
  610. package/dist/lib/typeChecker/inference.js +1 -1
  611. package/dist/lib/typeChecker/interruptAnalysis.d.ts +9 -0
  612. package/dist/lib/typeChecker/interruptAnalysis.js +21 -13
  613. package/dist/lib/typeChecker/literalType.d.ts +9 -0
  614. package/dist/lib/typeChecker/literalType.js +18 -0
  615. package/dist/lib/typeChecker/matchArmNarrowing.test.d.ts +1 -0
  616. package/dist/lib/typeChecker/matchArmNarrowing.test.js +172 -0
  617. package/dist/lib/typeChecker/matchExhaustiveness.d.ts +9 -0
  618. package/dist/lib/typeChecker/matchExhaustiveness.js +238 -0
  619. package/dist/lib/typeChecker/matchExhaustiveness.test.d.ts +1 -0
  620. package/dist/lib/typeChecker/matchExhaustiveness.test.js +404 -0
  621. package/dist/lib/typeChecker/matchExprTypes.d.ts +37 -0
  622. package/dist/lib/typeChecker/matchExprTypes.js +143 -0
  623. package/dist/lib/typeChecker/matchExpression.test.d.ts +1 -0
  624. package/dist/lib/typeChecker/matchExpression.test.js +240 -0
  625. package/dist/lib/typeChecker/memberPathNarrowing.test.d.ts +1 -0
  626. package/dist/lib/typeChecker/memberPathNarrowing.test.js +419 -0
  627. package/dist/lib/typeChecker/narrowing.d.ts +113 -0
  628. package/dist/lib/typeChecker/narrowing.js +396 -0
  629. package/dist/lib/typeChecker/narrowing.test.d.ts +1 -0
  630. package/dist/lib/typeChecker/narrowing.test.js +930 -0
  631. package/dist/lib/typeChecker/neverType.test.d.ts +1 -0
  632. package/dist/lib/typeChecker/neverType.test.js +19 -0
  633. package/dist/lib/typeChecker/nullNarrowing.test.d.ts +1 -0
  634. package/dist/lib/typeChecker/nullNarrowing.test.js +246 -0
  635. package/dist/lib/typeChecker/nullish.test.d.ts +1 -0
  636. package/dist/lib/typeChecker/nullish.test.js +16 -0
  637. package/dist/lib/typeChecker/pathSegments.d.ts +56 -0
  638. package/dist/lib/typeChecker/pathSegments.js +73 -0
  639. package/dist/lib/typeChecker/primitiveMembers.d.ts +2 -2
  640. package/dist/lib/typeChecker/primitiveMembers.js +5 -5
  641. package/dist/lib/typeChecker/primitives.d.ts +2 -1
  642. package/dist/lib/typeChecker/primitives.js +2 -1
  643. package/dist/lib/typeChecker/recordLike.d.ts +18 -0
  644. package/dist/lib/typeChecker/recordLike.js +27 -0
  645. package/dist/lib/typeChecker/resolveCall.js +4 -0
  646. package/dist/lib/typeChecker/resultUnion.d.ts +8 -0
  647. package/dist/lib/typeChecker/resultUnion.js +43 -0
  648. package/dist/lib/typeChecker/scope.d.ts +9 -1
  649. package/dist/lib/typeChecker/scope.js +25 -4
  650. package/dist/lib/typeChecker/scope.test.js +15 -0
  651. package/dist/lib/typeChecker/scopeVisibility.test.d.ts +1 -0
  652. package/dist/lib/typeChecker/scopeVisibility.test.js +138 -0
  653. package/dist/lib/typeChecker/scopes.d.ts +7 -0
  654. package/dist/lib/typeChecker/scopes.js +164 -113
  655. package/dist/lib/typeChecker/strictMemberAccess.test.d.ts +1 -0
  656. package/dist/lib/typeChecker/strictMemberAccess.test.js +221 -0
  657. package/dist/lib/typeChecker/synthesizer.js +257 -47
  658. package/dist/lib/typeChecker/typeCases.d.ts +28 -0
  659. package/dist/lib/typeChecker/typeCases.js +122 -0
  660. package/dist/lib/typeChecker/typeCases.test.d.ts +1 -0
  661. package/dist/lib/typeChecker/typeCases.test.js +150 -0
  662. package/dist/lib/typeChecker/types.d.ts +26 -0
  663. package/dist/lib/typeChecker/utils.d.ts +19 -0
  664. package/dist/lib/typeChecker/utils.js +50 -10
  665. package/dist/lib/typeChecker.test.js +351 -34
  666. package/dist/lib/types/dataStructures.d.ts +18 -1
  667. package/dist/lib/types/effectDeclaration.d.ts +11 -0
  668. package/dist/lib/types/effectDeclaration.js +1 -0
  669. package/dist/lib/types/function.d.ts +1 -1
  670. package/dist/lib/types/function.js +2 -0
  671. package/dist/lib/types/function.test.d.ts +1 -0
  672. package/dist/lib/types/function.test.js +11 -0
  673. package/dist/lib/types/ifElse.d.ts +4 -0
  674. package/dist/lib/types/importStatement.d.ts +4 -0
  675. package/dist/lib/types/matchBlock.d.ts +15 -3
  676. package/dist/lib/types/matchYield.d.ts +16 -0
  677. package/dist/lib/types/matchYield.js +1 -0
  678. package/dist/lib/types.d.ts +54 -3
  679. package/dist/lib/types.js +37 -0
  680. package/dist/lib/utils/mapBodies.js +1 -1
  681. package/dist/lib/utils/node.d.ts +30 -0
  682. package/dist/lib/utils/node.js +160 -3
  683. package/dist/lib/utils/projectTree.d.ts +13 -0
  684. package/dist/lib/utils/projectTree.js +42 -0
  685. package/dist/lib/utils/projectTree.test.d.ts +1 -0
  686. package/dist/lib/utils/projectTree.test.js +49 -0
  687. package/dist/lib/utils/termcolors.d.ts +1 -1
  688. package/dist/lib/utils/termcolors.js +1 -1
  689. package/dist/scripts/agency.js +27 -0
  690. package/dist/scripts/genModelHashes.d.ts +10 -0
  691. package/dist/scripts/genModelHashes.js +88 -0
  692. package/package.json +4 -2
  693. package/stdlib/agency/eval.agency +31 -59
  694. package/stdlib/agency/eval.js +56 -84
  695. package/stdlib/agency/local.agency +189 -0
  696. package/stdlib/agency/local.js +1685 -0
  697. package/stdlib/agency.agency +169 -98
  698. package/stdlib/agency.js +278 -286
  699. package/stdlib/agent.agency +69 -71
  700. package/stdlib/agent.js +352 -51
  701. package/stdlib/args.agency +30 -53
  702. package/stdlib/args.js +44 -20
  703. package/stdlib/array.agency +21 -221
  704. package/stdlib/array.js +116 -416
  705. package/stdlib/{keyring.agency → auth/keyring.agency} +17 -17
  706. package/stdlib/auth/keyring.js +810 -0
  707. package/stdlib/{oauth.agency → auth/oauth.agency} +24 -27
  708. package/stdlib/auth/oauth.js +873 -0
  709. package/stdlib/browser.js +13 -3
  710. package/stdlib/calendar.agency +29 -88
  711. package/stdlib/calendar.js +40 -25
  712. package/stdlib/capabilities.agency +7 -3
  713. package/stdlib/capabilities.js +41 -18
  714. package/stdlib/chart.js +21 -10
  715. package/stdlib/cli.js +139 -6
  716. package/stdlib/clipboard.agency +19 -2
  717. package/stdlib/clipboard.js +40 -19
  718. package/stdlib/concurrency.agency +34 -22
  719. package/stdlib/concurrency.js +45 -38
  720. package/stdlib/data/finance/dbnomics.agency +115 -0
  721. package/stdlib/data/finance/dbnomics.js +934 -0
  722. package/stdlib/data/finance/edgar.agency +172 -0
  723. package/stdlib/data/finance/edgar.js +1598 -0
  724. package/stdlib/data/finance/fred.agency +215 -0
  725. package/stdlib/data/finance/fred.js +2028 -0
  726. package/stdlib/data/finance/gdelt.agency +98 -0
  727. package/stdlib/data/finance/gdelt.js +873 -0
  728. package/stdlib/data/people/littlesis.agency +322 -0
  729. package/stdlib/data/people/littlesis.js +3221 -0
  730. package/stdlib/data/tech/hackernews.agency +344 -0
  731. package/stdlib/data/tech/hackernews.js +3814 -0
  732. package/stdlib/data/tech/yc.agency +253 -0
  733. package/stdlib/data/tech/yc.js +2913 -0
  734. package/stdlib/date.agency +34 -81
  735. package/stdlib/date.js +53 -39
  736. package/stdlib/email.js +13 -3
  737. package/stdlib/fs.agency +44 -16
  738. package/stdlib/fs.js +50 -37
  739. package/stdlib/git.agency +327 -0
  740. package/stdlib/git.js +3724 -0
  741. package/stdlib/http.agency +39 -14
  742. package/stdlib/http.js +39 -27
  743. package/stdlib/image.agency +44 -0
  744. package/stdlib/image.js +404 -0
  745. package/stdlib/imessage.js +13 -3
  746. package/stdlib/index.agency +318 -116
  747. package/stdlib/index.js +1762 -517
  748. package/stdlib/keyring.js +13 -3
  749. package/stdlib/layout.js +23 -12
  750. package/stdlib/llm.agency +115 -16
  751. package/stdlib/llm.js +726 -36
  752. package/stdlib/markdown.agency +38 -55
  753. package/stdlib/markdown.js +58 -66
  754. package/stdlib/math.agency +16 -0
  755. package/stdlib/math.js +175 -20
  756. package/stdlib/memory.agency +82 -90
  757. package/stdlib/memory.js +67 -114
  758. package/stdlib/{email.agency → messaging/email.agency} +11 -15
  759. package/stdlib/messaging/email.js +1112 -0
  760. package/stdlib/{imessage.agency → messaging/imessage.agency} +7 -8
  761. package/stdlib/messaging/imessage.js +387 -0
  762. package/stdlib/{sms.agency → messaging/sms.agency} +8 -8
  763. package/stdlib/messaging/sms.js +429 -0
  764. package/stdlib/oauth.js +13 -3
  765. package/stdlib/object.agency +52 -5
  766. package/stdlib/object.js +409 -26
  767. package/stdlib/path.agency +29 -4
  768. package/stdlib/path.js +54 -30
  769. package/stdlib/policy.agency +115 -198
  770. package/stdlib/policy.js +212 -154
  771. package/stdlib/schemas.js +13 -3
  772. package/stdlib/search.js +225 -6
  773. package/stdlib/shell.agency +51 -27
  774. package/stdlib/shell.js +75 -53
  775. package/stdlib/skills.agency +41 -20
  776. package/stdlib/skills.js +81 -43
  777. package/stdlib/sms.js +13 -3
  778. package/stdlib/speech.agency +42 -24
  779. package/stdlib/speech.js +46 -42
  780. package/stdlib/statelog.agency +64 -46
  781. package/stdlib/statelog.js +165 -66
  782. package/stdlib/strategy.agency +27 -0
  783. package/stdlib/strategy.js +158 -20
  784. package/stdlib/syntax.agency +34 -27
  785. package/stdlib/syntax.js +46 -46
  786. package/stdlib/system.agency +62 -23
  787. package/stdlib/system.js +210 -49
  788. package/stdlib/table.js +19 -8
  789. package/stdlib/tag.agency +62 -0
  790. package/stdlib/tag.js +966 -0
  791. package/stdlib/thread.agency +282 -67
  792. package/stdlib/thread.js +1522 -263
  793. package/stdlib/threads.js +18 -7
  794. package/stdlib/types.js +13 -3
  795. package/stdlib/{chart.agency → ui/chart.agency} +41 -48
  796. package/stdlib/ui/chart.js +993 -0
  797. package/stdlib/ui/cli.agency +119 -0
  798. package/stdlib/ui/cli.js +1096 -0
  799. package/stdlib/{layout.agency → ui/layout.agency} +110 -178
  800. package/stdlib/ui/layout.js +3740 -0
  801. package/stdlib/{table.agency → ui/table.agency} +49 -50
  802. package/stdlib/ui/table.js +1434 -0
  803. package/stdlib/ui.agency +194 -316
  804. package/stdlib/ui.js +442 -364
  805. package/stdlib/validation.agency +197 -0
  806. package/stdlib/validation.js +1707 -0
  807. package/stdlib/validators.js +13 -3
  808. package/stdlib/weather.agency +27 -4
  809. package/stdlib/weather.js +39 -21
  810. package/stdlib/web/browser.agency +52 -0
  811. package/stdlib/web/browser.js +431 -0
  812. package/stdlib/web/search.agency +101 -0
  813. package/stdlib/web/search.js +638 -0
  814. package/stdlib/wikipedia.agency +28 -3
  815. package/stdlib/wikipedia.js +46 -21
  816. package/dist/lib/agents/docs/appendix/agency-stdlib.md +0 -25
  817. package/dist/lib/agents/docs/appendix/agency-vs-typescript.md +0 -14
  818. package/dist/lib/agents/docs/appendix/appendix/agency-stdlib.md +0 -25
  819. package/dist/lib/agents/docs/appendix/appendix/agency-vs-typescript.md +0 -14
  820. package/dist/lib/agents/docs/appendix/appendix/vscode-extension.md +0 -11
  821. package/dist/lib/agents/docs/appendix/vscode-extension.md +0 -11
  822. package/dist/lib/agents/docs/guide/agents-101.md +0 -212
  823. package/dist/lib/agents/docs/guide/execution-model.md +0 -130
  824. package/dist/lib/agents/docs/guide/guide/agents-101.md +0 -212
  825. package/dist/lib/agents/docs/guide/guide/execution-model.md +0 -130
  826. package/dist/lib/agents/docs/guide/guide/message-history-and-threads.md +0 -88
  827. package/dist/lib/agents/docs/guide/guide/odds-and-ends.md +0 -41
  828. package/dist/lib/agents/docs/guide/guide/structured-interrupts.md +0 -49
  829. package/dist/lib/agents/docs/guide/message-history-and-threads.md +0 -88
  830. package/dist/lib/agents/docs/guide/odds-and-ends.md +0 -41
  831. package/dist/lib/agents/docs/guide/structured-interrupts.md +0 -49
  832. package/stdlib/browser.agency +0 -47
  833. package/stdlib/cli.agency +0 -132
  834. package/stdlib/schemas.agency +0 -37
  835. package/stdlib/search.agency +0 -57
  836. package/stdlib/threads.agency +0 -198
  837. package/stdlib/types.agency +0 -58
  838. package/stdlib/validators.agency +0 -150
  839. /package/dist/lib/agents/docs/{appendix → guide}/advanced-types.md +0 -0
  840. /package/dist/lib/agents/docs/{appendix/appendix → guide/guide}/advanced-types.md +0 -0
  841. /package/dist/lib/agents/docs/{appendix/appendix → guide/guide}/schema-parameter-injection.md +0 -0
  842. /package/dist/lib/agents/docs/{appendix → guide}/schema-parameter-injection.md +0 -0
  843. /package/dist/lib/backends/{anthropicApiKey.codegen.test.d.ts → agencyGenerator.matchBlock.test.d.ts} +0 -0
@@ -0,0 +1,904 @@
1
+ import * as fs from "node:fs";
2
+ import * as os from "node:os";
3
+ import * as path from "node:path";
4
+ import { createRequire } from "node:module";
5
+ import { execFileSync } from "node:child_process";
6
+ import { fileURLToPath, pathToFileURL } from "node:url";
7
+ import { createHash } from "node:crypto";
8
+ import { z } from "zod";
9
+ import { findFileUp } from "../importPaths.js";
10
+ import { loadProviderModuleByPath } from "../runtime/providerModules.js";
11
+ import { ttyColor } from "../utils/termcolors.js";
12
+ /** Curated short-name → ModelInfo catalog. Permissive licenses only
13
+ * (apache-2.0 / mit). Ordered roughly by size within each grouping. */
14
+ export const CURATED_LOCAL_MODELS = {
15
+ // ── General ─────────────────────────────────────────────────────────────
16
+ "smollm2-135m": {
17
+ uri: "hf:unsloth/SmolLM2-135M-Instruct-GGUF:Q4_K_M",
18
+ sha256: "ed5fa30c487b282ec156c29062f1222e5c20875a944ac98289dbd242e947f747",
19
+ params: "135M", sizeBytes: 105_000_000, category: "general",
20
+ contextWindow: 8192, license: "apache-2.0",
21
+ description: "Smallest practical chat model; used by our integration tests, runs anywhere.",
22
+ },
23
+ "qwen3.5-0.8b": {
24
+ uri: "hf:unsloth/Qwen3.5-0.8B-GGUF:Q4_K_M",
25
+ sha256: "bd258782e35f7f458f8aced1adc053e6e92e89bc735ba3be89d38a06121dc517",
26
+ params: "0.8B", sizeBytes: 500_000_000, category: "general",
27
+ contextWindow: 131072, license: "apache-2.0",
28
+ description: "Tiny model from Alibaba's current generation; good edge-device default.",
29
+ },
30
+ "qwen3.5-2b": {
31
+ uri: "hf:unsloth/Qwen3.5-2B-GGUF:Q4_K_M",
32
+ sha256: "aaf42c8b7c3cab2bf3d69c355048d4a0ee9973d48f16c731c0520ee914699223",
33
+ params: "2B", sizeBytes: 1_280_000_000, category: "general",
34
+ contextWindow: 131072, license: "apache-2.0",
35
+ description: "Most popular modern small general model; runs on CPU comfortably.",
36
+ },
37
+ "qwen3.5-4b": {
38
+ uri: "hf:unsloth/Qwen3.5-4B-GGUF:Q4_K_M",
39
+ sha256: "00fe7986ff5f6b463e62455821146049db6f9313603938a70800d1fb69ef11a4",
40
+ params: "4B", sizeBytes: 2_400_000_000, category: "general",
41
+ contextWindow: 131072, license: "apache-2.0",
42
+ description: "Strong multilingual small general workhorse from Alibaba.",
43
+ },
44
+ "gemma-4-e4b": {
45
+ uri: "hf:unsloth/gemma-4-E4B-it-GGUF:Q4_K_M",
46
+ sha256: "519b9793ed6ce0ff530f1b7c96e848e08e49e7af4d57bb97f76215963a54146d",
47
+ params: "4B (E4B)", sizeBytes: 4_980_000_000, category: "general",
48
+ contextWindow: 131072, license: "apache-2.0",
49
+ description: "Google's compact Gemma 4 (4.5B effective); ~5 GB, laptop-friendly multimodal model.",
50
+ },
51
+ "qwen3.5-9b": {
52
+ uri: "hf:unsloth/Qwen3.5-9B-GGUF:Q4_K_M",
53
+ sha256: "03b74727a860a56338e042c4420bb3f04b2fec5734175f4cb9fa853daf52b7e8",
54
+ params: "9B", sizeBytes: 5_500_000_000, category: "general",
55
+ contextWindow: 131072, license: "apache-2.0",
56
+ description: "Modern medium general model with strong tool use; 128K context.",
57
+ },
58
+ "gemma-4-12b": {
59
+ uri: "hf:unsloth/gemma-4-12b-it-GGUF:Q4_K_M",
60
+ sha256: "43fec98c5102b1c446b4ddd0a9439f1db3a2e1f2e0b8cd143ce1ea619a9403d6",
61
+ params: "12B", sizeBytes: 7_120_000_000, category: "general",
62
+ contextWindow: 262144, license: "apache-2.0",
63
+ description: "Google's mid-size Gemma 4 dense model; strong multilingual multimodal use, 256K context.",
64
+ },
65
+ "gpt-oss-20b": {
66
+ uri: "hf:unsloth/gpt-oss-20b-GGUF:Q4_K_M",
67
+ sha256: "c27536640e410032865dc68781d80a08b98f8db5e93575919af8ccc0568aeb4f",
68
+ params: "20B", sizeBytes: 12_000_000_000, category: "general",
69
+ contextWindow: 131072, license: "apache-2.0",
70
+ description: "OpenAI's open-weights release; balanced general model for ~16 GB machines.",
71
+ },
72
+ "mistral-small-3.1": {
73
+ uri: "hf:unsloth/Mistral-Small-3.1-24B-Instruct-2503-GGUF:Q4_K_M",
74
+ sha256: "6d670773c3908584349d41a5048d1472226b593c881fd394e8ac196c802e81e2",
75
+ params: "24B", sizeBytes: 14_000_000_000, category: "general",
76
+ contextWindow: 131072, license: "apache-2.0",
77
+ description: "Mistral's general 24B base model (also Devstral's foundation); broad utility.",
78
+ },
79
+ "qwen3.5-27b": {
80
+ uri: "hf:unsloth/Qwen3.5-27B-GGUF:Q4_K_M",
81
+ sha256: "84b5f7f112156d63836a01a69dc3f11a6ba63b10a23b8ca7a7efaf52d5a2d806",
82
+ params: "27B", sizeBytes: 16_000_000_000, category: "general",
83
+ contextWindow: 131072, license: "apache-2.0",
84
+ description: "Modern dense general 27B; the practical ceiling for most workstations.",
85
+ },
86
+ "gemma-4-26b-a4b": {
87
+ uri: "hf:unsloth/gemma-4-26B-A4B-it-GGUF:Q4_K_M",
88
+ sha256: "34c746b1d50ab813e29cd46c4796e3f43c741901a582f93a67b55b9fc9687b35",
89
+ params: "26B (A4B)", sizeBytes: 16_900_000_000, category: "general",
90
+ contextWindow: 262144, license: "apache-2.0",
91
+ description: "Google's Gemma 4 MoE (3.8B active); fast yet capable multimodal model, 256K context.",
92
+ },
93
+ "gemma-4-31b": {
94
+ uri: "hf:unsloth/gemma-4-31B-it-GGUF:Q4_K_M",
95
+ sha256: "9fdf3dc8b0384830b4402d151388c140bd8eb2abf8d60588d8224231198254a1",
96
+ params: "31B", sizeBytes: 18_300_000_000, category: "general",
97
+ contextWindow: 262144, license: "apache-2.0",
98
+ description: "Largest dense Gemma 4; top Gemma quality for high-RAM workstations, 256K context.",
99
+ },
100
+ // ── Reasoning ───────────────────────────────────────────────────────────
101
+ "deepseek-r1-distill-llama-8b": {
102
+ uri: "hf:unsloth/DeepSeek-R1-Distill-Llama-8B-GGUF:Q4_K_M",
103
+ sha256: "0addb1339a82385bcd973186cd80d18dcc71885d45eabd899781a118d03827d9",
104
+ params: "8B", sizeBytes: 4_920_000_000, category: "reasoning",
105
+ contextWindow: 131072, license: "mit",
106
+ description: "Chain-of-thought distill into Llama-8B; best small reasoning model.",
107
+ },
108
+ "phi-4-reasoning": {
109
+ uri: "hf:unsloth/Phi-4-reasoning-GGUF:Q4_K_M",
110
+ sha256: "960d3870b218f91116c55bf81dc313e6cdbce31b1047bb2bc8bc7ea47899b032",
111
+ params: "14B", sizeBytes: 9_050_000_000, category: "reasoning",
112
+ contextWindow: 32768, license: "mit",
113
+ description: "Microsoft's reasoning-tuned 14B; competitive with much larger models on math/logic.",
114
+ },
115
+ // ── Coding ──────────────────────────────────────────────────────────────
116
+ "devstral-small-2507": {
117
+ uri: "hf:mistralai/Devstral-Small-2507_gguf:Q4_K_M",
118
+ sha256: "1bcc2b1b7b7ea3168ba2dbe782432c464f2240598bd193930122c41b117c1796",
119
+ params: "24B", sizeBytes: 14_300_000_000, category: "coding",
120
+ contextWindow: 131072, license: "apache-2.0",
121
+ description: "Mistral's official coding-agent GGUF; #1 open-source on SWE-Bench at release.",
122
+ },
123
+ "qwen3-coder-30b-a3b": {
124
+ uri: "hf:unsloth/Qwen3-Coder-30B-A3B-Instruct-GGUF:Q4_K_M",
125
+ sha256: "fadc3e5f8d42bf7e894a785b05082e47daee4df26680389817e2093056f088ad",
126
+ params: "30B (A3B)", sizeBytes: 19_000_000_000, category: "coding",
127
+ contextWindow: 262144, license: "apache-2.0",
128
+ description: "Qwen's MoE coder (3.3B active); strong agentic coding + 256K context.",
129
+ },
130
+ // ── Embedding ───────────────────────────────────────────────────────────
131
+ "nomic-embed-text": {
132
+ uri: "hf:nomic-ai/nomic-embed-text-v1.5-GGUF:Q4_K_M",
133
+ sha256: "d4e388894e09cf3816e8b0896d81d265b55e7a9fff9ab03fe8bf4ef5e11295ac",
134
+ params: "137M", sizeBytes: 89_000_000, category: "embedding",
135
+ contextWindow: 8192, license: "apache-2.0",
136
+ description: "Returns 768-dim embeddings; pair with a chat model for RAG.",
137
+ },
138
+ };
139
+ /** Where downloaded models live, in precedence order:
140
+ * 1. `AGENCY_MODELS_DIR` env var (per-machine override).
141
+ * 2. `client.modelsDir` in the nearest `agency.json` (read at runtime, like
142
+ * `modelAliases`), so the CLI and the agent share one configurable dir.
143
+ * 3. `~/.agency-agent/models` (the default; shared with the agent so a CLI
144
+ * `agency local download` pre-populates what `agency agent --local-model`
145
+ * reuses). */
146
+ export function defaultCacheDir() {
147
+ if (process.env.AGENCY_MODELS_DIR) {
148
+ return process.env.AGENCY_MODELS_DIR;
149
+ }
150
+ const configured = readJson(resolveAliasConfigPath()).client?.modelsDir;
151
+ if (typeof configured === "string" && configured.length > 0) {
152
+ return configured;
153
+ }
154
+ return path.join(os.homedir(), ".agency-agent", "models");
155
+ }
156
+ /** Treat empty string as "caller wants the default cache dir". */
157
+ function resolveCacheDir(cacheDir) {
158
+ return cacheDir === "" ? defaultCacheDir() : cacheDir;
159
+ }
160
+ function isGgufPath(v) {
161
+ return v.endsWith(".gguf");
162
+ }
163
+ function isModelUri(v) {
164
+ return /^(hf:|https?:)/.test(v);
165
+ }
166
+ /** A model URI we'll accept from the *remote catalog*. Stricter than
167
+ * `isModelUri`: any `scheme://` URL must be `https://` (so an overridden or
168
+ * untrusted catalog can't point a download at a plaintext, MITM-able
169
+ * endpoint — not even an `http://…/x.gguf`). Otherwise accept an `hf:` URI or
170
+ * a local `.gguf` path. */
171
+ function isCatalogUri(v) {
172
+ if (/^[a-zA-Z][a-zA-Z0-9+.-]*:\/\//.test(v)) {
173
+ return /^https:\/\//.test(v);
174
+ }
175
+ return v.startsWith("hf:") || isGgufPath(v);
176
+ }
177
+ /** The agency.json that owns aliases: nearest `agency.json` walking up from
178
+ * `startDir` (cwd by default); falls back to `~/agency.json` when none is
179
+ * found. Exported so the CLI can echo it on every write. */
180
+ export function resolveAliasConfigPath(startDir = process.cwd()) {
181
+ return findFileUp(startDir, "agency.json") ?? path.join(os.homedir(), "agency.json");
182
+ }
183
+ /** Treat empty string as "caller wants resolveAliasConfigPath()". */
184
+ function resolveAliasFile(file) {
185
+ return file === "" ? resolveAliasConfigPath() : file;
186
+ }
187
+ /** Read a JSON file as a plain object. */
188
+ function readJson(file) {
189
+ if (!fs.existsSync(file)) {
190
+ return {};
191
+ }
192
+ try {
193
+ return JSON.parse(fs.readFileSync(file, "utf-8"));
194
+ }
195
+ catch (err) {
196
+ throw new Error(`Failed to parse ${file}: ${err.message}`);
197
+ }
198
+ }
199
+ /** Merge `client.modelAliases[name] = uri` (or remove it) into a config object using spread. */
200
+ function withAlias(cfg, name, uri) {
201
+ const existing = cfg.client?.modelAliases ?? {};
202
+ const nextAliases = { ...existing };
203
+ if (uri === undefined) {
204
+ delete nextAliases[name];
205
+ }
206
+ else {
207
+ nextAliases[name] = uri;
208
+ }
209
+ return {
210
+ ...cfg,
211
+ client: { ...(cfg.client ?? {}), modelAliases: nextAliases },
212
+ };
213
+ }
214
+ function writeJson(file, value) {
215
+ fs.writeFileSync(file, JSON.stringify(value, null, 2) + "\n");
216
+ }
217
+ /** The URI an alias points at, regardless of string/object form. */
218
+ export function aliasUri(value) {
219
+ return typeof value === "string" ? value : value.uri;
220
+ }
221
+ export function readModelAliases(file = "") {
222
+ const cfg = readJson(resolveAliasFile(file));
223
+ return (cfg.client?.modelAliases ?? {});
224
+ }
225
+ export function _resolveModelName(value, file = "") {
226
+ if (isGgufPath(value) || isModelUri(value)) {
227
+ return value;
228
+ }
229
+ const aliases = readModelAliases(file);
230
+ const aliasVal = aliases[value];
231
+ const aliasTarget = aliasVal === undefined ? undefined : aliasUri(aliasVal);
232
+ const curated = CURATED_LOCAL_MODELS[value];
233
+ const mapped = aliasTarget ?? curated?.uri;
234
+ if (!mapped) {
235
+ const names = [...Object.keys(CURATED_LOCAL_MODELS), ...Object.keys(aliases)].join(", ");
236
+ throw new Error(`Unknown local model "${value}". Known names: ${names || "(none)"}; ` +
237
+ `or pass a .gguf path or an "hf:" URI.`);
238
+ }
239
+ return mapped;
240
+ }
241
+ /** Project the optional display-metadata fields off any source shape
242
+ * (`ModelInfo`, or an alias which may be a bare URI string). A string alias
243
+ * carries no metadata, so it yields `{}` — which is why the call sites can
244
+ * pass an `AliasValue` directly without a `typeof` guard. Returns only
245
+ * defined fields so the spread doesn't introduce stray `undefined` keys. */
246
+ function metaFrom(src) {
247
+ if (typeof src === "string")
248
+ return {};
249
+ const out = {};
250
+ if (src.params !== undefined)
251
+ out.params = src.params;
252
+ if (src.sizeBytes !== undefined)
253
+ out.sizeBytes = src.sizeBytes;
254
+ if (src.category !== undefined)
255
+ out.category = src.category;
256
+ if (src.description !== undefined)
257
+ out.description = src.description;
258
+ if (src.contextWindow !== undefined)
259
+ out.contextWindow = src.contextWindow;
260
+ if (src.license !== undefined)
261
+ out.license = src.license;
262
+ if (src.sha256 !== undefined)
263
+ out.sha256 = src.sha256;
264
+ return out;
265
+ }
266
+ export function _listModelNames(file = "") {
267
+ const curatedEntries = Object.entries(CURATED_LOCAL_MODELS).map(([name, info]) => ({ name, target: info.uri, source: "curated", ...metaFrom(info) }));
268
+ const aliasEntries = Object.entries(readModelAliases(file)).map(([name, value]) => ({
269
+ name,
270
+ target: aliasUri(value),
271
+ source: "alias",
272
+ ...metaFrom(value),
273
+ }));
274
+ // Alias wins on name collision: the alias entry overwrites the curated one
275
+ // in the object literal because it comes later. `Object.values` then yields
276
+ // exactly one entry per name.
277
+ return Object.values(Object.fromEntries([...curatedEntries, ...aliasEntries].map((e) => [e.name, e])));
278
+ }
279
+ export function _aliasModel(name, uri, file = "") {
280
+ const resolved = resolveAliasFile(file);
281
+ writeJson(resolved, withAlias(readJson(resolved), name, uri));
282
+ return resolved;
283
+ }
284
+ /** Remove an alias. Bails early (no write) if file or alias missing. */
285
+ export function _unaliasModel(name, file = "") {
286
+ const resolved = resolveAliasFile(file);
287
+ if (!fs.existsSync(resolved)) {
288
+ return { file: resolved, removed: false };
289
+ }
290
+ const cfg = readJson(resolved);
291
+ if (!cfg.client?.modelAliases || !(name in cfg.client.modelAliases)) {
292
+ return { file: resolved, removed: false };
293
+ }
294
+ writeJson(resolved, withAlias(cfg, name, undefined));
295
+ return { file: resolved, removed: true };
296
+ }
297
+ export function _listDownloadedModels(cacheDir = "") {
298
+ const dir = resolveCacheDir(cacheDir);
299
+ if (!fs.existsSync(dir)) {
300
+ return [];
301
+ }
302
+ return fs
303
+ .readdirSync(dir)
304
+ .filter((f) => f.endsWith(".gguf"))
305
+ .map((f) => {
306
+ const p = path.join(dir, f);
307
+ return { name: f, path: p, sizeBytes: fs.statSync(p).size };
308
+ });
309
+ }
310
+ export function _removeModel(name, cacheDir = "") {
311
+ const p = path.join(resolveCacheDir(cacheDir), name);
312
+ if (!fs.existsSync(p)) {
313
+ return false;
314
+ }
315
+ fs.rmSync(p);
316
+ return true;
317
+ }
318
+ // =============================================================================
319
+ // Remote catalog — fetch + validate the GitHub-hosted model list.
320
+ // =============================================================================
321
+ export const DEFAULT_CATALOG_URL = "https://raw.githubusercontent.com/egonSchiele/agency-lang/main/packages/agency-lang/data/model-catalog.json";
322
+ const SUPPORTED_CATALOG_VERSION = 1;
323
+ /** Resolve the catalog URL: explicit arg → env → config → built-in default. */
324
+ export function resolveCatalogUrl(explicit = "", file = "") {
325
+ if (explicit !== "")
326
+ return explicit;
327
+ if (process.env.AGENCY_MODEL_CATALOG_URL)
328
+ return process.env.AGENCY_MODEL_CATALOG_URL;
329
+ const configured = readJson(resolveAliasFile(file)).client?.modelCatalogUrl;
330
+ if (typeof configured === "string" && configured.length > 0)
331
+ return configured;
332
+ return DEFAULT_CATALOG_URL;
333
+ }
334
+ const CATALOG_CATEGORIES = ["general", "coding", "reasoning", "embedding"];
335
+ /** Bound on how long the default fetcher will wait for the remote catalog
336
+ * before aborting. Long enough to tolerate slow CI mirrors; short enough
337
+ * that a hung server doesn't lock up the CLI. */
338
+ const CATALOG_FETCH_TIMEOUT_MS = 15_000;
339
+ /** Bound on catalog body size. The seed catalog is well under 10 KB; a
340
+ * 5 MB cap guards against a misconfigured URL serving an arbitrary file. */
341
+ const CATALOG_MAX_BYTES = 5_000_000;
342
+ // One catalog entry. zod does the structural validation + coercion; the merge
343
+ // reassembles a canonical-order object from `.data` (see `parseCatalog`). The
344
+ // metadata fields are `.optional().catch(undefined)` so a wrongly-typed field
345
+ // is dropped rather than failing the whole entry (lenient metadata); a
346
+ // missing/insecure `uri` fails the entry (it's then skipped + warned).
347
+ const CatalogModelSchema = z.object({
348
+ uri: z.string().refine(isCatalogUri, "uri must be an hf:/https: URI or a .gguf path"),
349
+ params: z.string().optional().catch(undefined),
350
+ sizeBytes: z.number().optional().catch(undefined),
351
+ category: z.enum(CATALOG_CATEGORIES).optional().catch(undefined),
352
+ contextWindow: z.number().optional().catch(undefined),
353
+ license: z.string().optional().catch(undefined),
354
+ description: z.string().optional().catch(undefined),
355
+ // Must be a 64-hex SHA-256; normalized to lowercase. A malformed value (from
356
+ // an untrusted catalog) is dropped via `.catch`, not stored as a bad pin.
357
+ sha256: z
358
+ .string()
359
+ .regex(/^[0-9a-fA-F]{64}$/)
360
+ .transform((s) => s.toLowerCase())
361
+ .optional()
362
+ .catch(undefined),
363
+ });
364
+ // Top-level catalog shape: a supported version + a name→entry object. Entries
365
+ // are validated individually (below) so one bad entry is skipped, not fatal.
366
+ const CatalogTopSchema = z.object({
367
+ version: z.literal(SUPPORTED_CATALOG_VERSION),
368
+ models: z.record(z.string(), z.unknown()),
369
+ });
370
+ /** Strip keys whose value is `undefined` so the resulting object is JSON-clean
371
+ * (no `"params": undefined` after `JSON.stringify`) and in canonical order. */
372
+ function compact(o) {
373
+ return Object.fromEntries(Object.entries(o).filter(([, v]) => v !== undefined));
374
+ }
375
+ /** Parse + validate the catalog JSON. Throws on blob-level problems (bad JSON,
376
+ * unsupported version, `models` not an object) so refresh aborts without
377
+ * touching agency.json. Skips an individual entry (with a warning) when its
378
+ * `uri` is missing/invalid; metadata fields with the wrong type are dropped
379
+ * but the entry is kept. */
380
+ export function parseCatalog(text) {
381
+ let raw;
382
+ try {
383
+ raw = JSON.parse(text);
384
+ }
385
+ catch (err) {
386
+ throw new Error(`catalog is not valid JSON: ${err.message}`);
387
+ }
388
+ const top = CatalogTopSchema.safeParse(raw);
389
+ if (!top.success) {
390
+ // Map zod's first issue to a precise, user-facing message.
391
+ const path = top.error.issues[0]?.path[0];
392
+ if (path === "version") {
393
+ throw new Error(`unsupported catalog version ${JSON.stringify(raw?.version)}; this ` +
394
+ `agency supports version ${SUPPORTED_CATALOG_VERSION}. Upgrade agency.`);
395
+ }
396
+ if (path === "models") {
397
+ throw new Error("catalog.models must be an object keyed by model name");
398
+ }
399
+ throw new Error("catalog must be a JSON object");
400
+ }
401
+ // Validate each entry independently; a bad entry is skipped + warned, not
402
+ // fatal. Rebuild a canonical-order `CatalogModel` from the validated data.
403
+ const entries = Object.entries(top.data.models).map(([name, entry]) => {
404
+ const parsed = CatalogModelSchema.safeParse(entry);
405
+ if (!parsed.success) {
406
+ console.warn(`[catalog] skipping "${name}": ${parsed.error.issues[0]?.message ?? "invalid entry"}`);
407
+ return null;
408
+ }
409
+ const d = parsed.data;
410
+ const model = {
411
+ uri: d.uri,
412
+ ...compact({
413
+ params: d.params,
414
+ sizeBytes: d.sizeBytes,
415
+ category: d.category,
416
+ contextWindow: d.contextWindow,
417
+ license: d.license,
418
+ description: d.description,
419
+ sha256: d.sha256,
420
+ }),
421
+ };
422
+ return [name, model];
423
+ });
424
+ return Object.fromEntries(entries.filter((e) => e !== null));
425
+ }
426
+ /** If `url` names a local file (a `file://` URL or a plain filesystem path —
427
+ * i.e. not an `hf:`/`http(s)://` URL), return its path; else null. Lets refresh
428
+ * read a catalog from disk (`agency local refresh ./catalog.json`), which also
429
+ * makes the merge logic integration-testable without a network round-trip. */
430
+ function catalogLocalPath(url) {
431
+ if (url.startsWith("file://"))
432
+ return fileURLToPath(url);
433
+ if (/^[a-zA-Z][a-zA-Z0-9+.-]*:\/\//.test(url) || url.startsWith("hf:"))
434
+ return null;
435
+ return url;
436
+ }
437
+ /** Read a local catalog file, enforcing the byte cap up front via `stat`. */
438
+ function readCatalogFile(path) {
439
+ const size = fs.statSync(path).size;
440
+ if (size > CATALOG_MAX_BYTES) {
441
+ throw new Error(`catalog file too large (${size} bytes; cap ${CATALOG_MAX_BYTES} bytes)`);
442
+ }
443
+ return fs.readFileSync(path, "utf-8");
444
+ }
445
+ /** Stream a response body, enforcing the byte cap as chunks arrive so a
446
+ * large/malicious body can't be fully buffered first. Mirrors the capped
447
+ * reader in `lib/stdlib/http.ts`; counts raw bytes (`byteLength`), not
448
+ * UTF-16 code units. */
449
+ async function readBodyCapped(res, url, maxBytes) {
450
+ if (!res.body)
451
+ return "";
452
+ const reader = res.body.getReader();
453
+ const decoder = new TextDecoder("utf-8");
454
+ const chunks = [];
455
+ let total = 0;
456
+ try {
457
+ while (true) {
458
+ const { done, value } = await reader.read();
459
+ if (done)
460
+ break;
461
+ total += value.byteLength;
462
+ if (total > maxBytes) {
463
+ await reader.cancel().catch(() => { });
464
+ throw new Error(`catalog from ${url} exceeds ${maxBytes} bytes`);
465
+ }
466
+ chunks.push(decoder.decode(value, { stream: true }));
467
+ }
468
+ }
469
+ finally {
470
+ try {
471
+ reader.releaseLock();
472
+ }
473
+ catch {
474
+ /* already released */
475
+ }
476
+ }
477
+ chunks.push(decoder.decode());
478
+ return chunks.join("");
479
+ }
480
+ /** Default fetcher: a local file path / `file://` URL is read from disk;
481
+ * otherwise an HTTPS-only GET with a bounded timeout and a streamed byte cap.
482
+ * `http:` (and other non-https URL schemes) are rejected. */
483
+ export async function fetchCatalog(url) {
484
+ const localPath = catalogLocalPath(url);
485
+ if (localPath !== null) {
486
+ return readCatalogFile(localPath);
487
+ }
488
+ if (!url.startsWith("https://")) {
489
+ throw new Error(`catalog URL must be https or a local file path: ${url}`);
490
+ }
491
+ const controller = new AbortController();
492
+ const timer = setTimeout(() => controller.abort(), CATALOG_FETCH_TIMEOUT_MS);
493
+ try {
494
+ const res = await fetch(url, { signal: controller.signal });
495
+ if (!res.ok) {
496
+ throw new Error(`fetch failed: HTTP ${res.status} ${res.statusText}`);
497
+ }
498
+ return await readBodyCapped(res, url, CATALOG_MAX_BYTES);
499
+ }
500
+ finally {
501
+ clearTimeout(timer);
502
+ }
503
+ }
504
+ /** Merge a complete `modelAliases` map into a config object (spread, like
505
+ * `withAlias` but replaces the whole map). */
506
+ function withModelAliases(cfg, aliases) {
507
+ return { ...cfg, client: { ...(cfg.client ?? {}), modelAliases: aliases } };
508
+ }
509
+ /** Stable JSON for value-equality. The merge writes objects with consistent
510
+ * key order via the spread below (`{ ...model, source: "remote" }`), so a
511
+ * deep equality check via `JSON.stringify` is sufficient for managed-entry
512
+ * diffing without pulling in `node:util.isDeepStrictEqual`. */
513
+ function sameManagedValue(prev, next) {
514
+ return JSON.stringify(prev) === JSON.stringify(next);
515
+ }
516
+ /** Classify one catalog entry against the previous state. Pure: no I/O, no
517
+ * mutation, deterministic. Tested via `_refreshCatalog`'s end-to-end tests. */
518
+ function classifyEntry(name, model, userAliases, oldManaged) {
519
+ // Own-property checks (not `name in ...` / bare index access): a catalog
520
+ // model named like a prototype member (`toString`, `__proto__`, …) must not
521
+ // be treated as a collision with — or a previous value from — an inherited
522
+ // property the user never set.
523
+ const has = (o, k) => Object.prototype.hasOwnProperty.call(o, k);
524
+ if (has(userAliases, name)) {
525
+ return {
526
+ kind: "skipped",
527
+ name,
528
+ entry: { name, keptUri: aliasUri(userAliases[name]), remoteUri: model.uri },
529
+ };
530
+ }
531
+ const value = { ...model, source: "remote" };
532
+ const prev = has(oldManaged, name) ? oldManaged[name] : undefined;
533
+ if (prev === undefined) {
534
+ return { kind: "added", name, value };
535
+ }
536
+ if (sameManagedValue(prev, value)) {
537
+ return { kind: "unchanged", name, value };
538
+ }
539
+ return { kind: "updated", name, value };
540
+ }
541
+ /** Predicate factory for declarative filtering by `Classification.kind`. */
542
+ function isKind(k) {
543
+ return (c) => c.kind === k;
544
+ }
545
+ /** Fetch + validate the catalog, then rewrite the `source:"remote"` aliases in
546
+ * agency.json from it. User-owned aliases are preserved and win on name
547
+ * collisions (the remote entry is skipped). Throws (leaving the file
548
+ * untouched) on fetch/parse/validation failure. */
549
+ export async function _refreshCatalog(opts = {}) {
550
+ const file = resolveAliasFile(opts.file ?? "");
551
+ const url = resolveCatalogUrl(opts.url ?? "", file);
552
+ const fetcher = opts.fetcher ?? fetchCatalog;
553
+ // Fetch + validate BEFORE reading/writing agency.json, so a failure leaves
554
+ // the file untouched.
555
+ const text = await fetcher(url);
556
+ const models = parseCatalog(text);
557
+ // Read aliases through the canonical helper (single source of truth for
558
+ // "how aliases come out of agency.json"). `cfg` is needed separately to
559
+ // round-trip non-alias fields back into the file on write.
560
+ const cfg = readJson(file);
561
+ const existing = readModelAliases(file);
562
+ // Partition existing aliases by who manages them.
563
+ const userAliases = Object.fromEntries(Object.entries(existing).filter(([, v]) => !(typeof v === "object" && v.source === "remote")));
564
+ const oldManaged = Object.fromEntries(Object.entries(existing).filter((e) => typeof e[1] === "object" && e[1].source === "remote"));
565
+ // The entire merge policy: classify each catalog entry once. Everything
566
+ // downstream is a filter/project on this array.
567
+ const classifications = Object.entries(models).map(([name, model]) => classifyEntry(name, model, userAliases, oldManaged));
568
+ const namesIn = (k) => classifications.filter(isKind(k)).map((c) => c.name);
569
+ const added = namesIn("added");
570
+ const updated = namesIn("updated");
571
+ const unchanged = namesIn("unchanged");
572
+ const skipped = classifications.filter(isKind("skipped")).map((c) => c.entry);
573
+ // What ends up in `client.modelAliases`: user aliases (untouched) plus
574
+ // every non-skipped classification's value.
575
+ const writtenManaged = Object.fromEntries(classifications.filter((c) => c.kind !== "skipped").map((c) => [c.name, c.value]));
576
+ const next = { ...userAliases, ...writtenManaged };
577
+ const surviving = [...added, ...updated, ...unchanged];
578
+ const removed = Object.keys(oldManaged).filter((n) => !surviving.includes(n));
579
+ writeJson(file, withModelAliases(cfg, next));
580
+ return {
581
+ url,
582
+ file,
583
+ added,
584
+ updated,
585
+ unchanged,
586
+ removed,
587
+ skipped,
588
+ modelCount: Object.keys(models).length,
589
+ };
590
+ }
591
+ // Cached so we don't shell out repeatedly per process.
592
+ let cachedGlobalRoots = null;
593
+ /** Discover global `node_modules` roots reported by `npm` and `pnpm`, in that
594
+ * order. Each entry is the directory printed by `<tool> root -g` (which is
595
+ * itself a `node_modules` dir, e.g. `/opt/homebrew/lib/node_modules` for
596
+ * Homebrew npm, `~/Library/pnpm/global/5/node_modules` for pnpm). Failures
597
+ * (tool not installed, exit non-zero, dir missing) are silently skipped. */
598
+ function globalNodeModulesRoots() {
599
+ if (cachedGlobalRoots !== null) {
600
+ return cachedGlobalRoots;
601
+ }
602
+ const roots = [];
603
+ for (const cmd of ["npm", "pnpm"]) {
604
+ try {
605
+ const out = execFileSync(cmd, ["root", "-g"], {
606
+ encoding: "utf-8",
607
+ stdio: ["ignore", "pipe", "ignore"],
608
+ }).trim();
609
+ if (out && fs.existsSync(out) && !roots.includes(out)) {
610
+ roots.push(out);
611
+ }
612
+ }
613
+ catch {
614
+ /* tool not installed or failed — skip */
615
+ }
616
+ }
617
+ cachedGlobalRoots = roots;
618
+ return roots;
619
+ }
620
+ /** Try to resolve `smoltalk-llama-cpp` from the given global `node_modules`
621
+ * roots. Each `root` is itself a `node_modules` directory (the convention
622
+ * `npm root -g` / `pnpm root -g` uses). Node's resolver looks for
623
+ * `<parent>/node_modules/<pkg>` for each parent dir it walks up, so the
624
+ * createRequire base must live in the root's PARENT directory — from
625
+ * `<root>/../_resolver.js` it correctly finds `<root>/smoltalk-llama-cpp/...`.
626
+ * Exported for unit-testing with a controllable list of roots. */
627
+ export function resolveSmoltalkLlamaCppFromRoots(roots) {
628
+ for (const root of roots) {
629
+ try {
630
+ const req = createRequire(path.join(root, "..", "_resolver.js"));
631
+ return req.resolve("smoltalk-llama-cpp");
632
+ }
633
+ catch {
634
+ /* not in this root — try the next */
635
+ }
636
+ }
637
+ return null;
638
+ }
639
+ /** Resolve `smoltalk-llama-cpp` to the absolute path of its main entry,
640
+ * searching:
641
+ * 1. The local `require` paths walking up from this file (covers in-workspace
642
+ * `pnpm add` and a user-project install).
643
+ * 2. Each global `node_modules` root reported by `npm root -g` / `pnpm root -g`
644
+ * (covers `npm i -g` and `pnpm add -g` — the documented install methods).
645
+ *
646
+ * Returns `null` if the package isn't reachable from any of those. */
647
+ export function resolveSmoltalkLlamaCppEntry() {
648
+ try {
649
+ return createRequire(import.meta.url).resolve("smoltalk-llama-cpp");
650
+ }
651
+ catch {
652
+ /* not local — try global install roots */
653
+ }
654
+ return resolveSmoltalkLlamaCppFromRoots(globalNodeModulesRoots());
655
+ }
656
+ /** True if smoltalk-llama-cpp is reachable from the local require paths OR
657
+ * from a global node_modules root (npm or pnpm). */
658
+ export function _localModelsSupported() {
659
+ return resolveSmoltalkLlamaCppEntry() !== null;
660
+ }
661
+ /** Whether the local-model commands should be allowed to run. True when
662
+ * smoltalk-llama-cpp is installed OR the caller has supplied their own
663
+ * provider module via AGENCY_LLAMA_PROVIDER_MODULE. Mirrors the gate inside
664
+ * `requireSupport()`; used by the CLI so `agency local download/list/remove`
665
+ * works in the override scenario (otherwise the CLI would exit 1 even though
666
+ * the underlying TS functions would happily run). */
667
+ export function hasLocalModelSupport() {
668
+ if (process.env.AGENCY_LLAMA_PROVIDER_MODULE) {
669
+ return true;
670
+ }
671
+ return _localModelsSupported();
672
+ }
673
+ /** Expose the resolved `smoltalk-llama-cpp` entry path to the bundled
674
+ * `llama-cpp.mjs` via the AGENCY_SMOLTALK_LLAMA_CPP_PATH env var, so that
675
+ * the bundled module can dynamically import it even when the package lives
676
+ * in a global `node_modules` that isn't on this file's resolution path.
677
+ * Idempotent. */
678
+ function exposeResolvedLlamaCppPath() {
679
+ if (process.env.AGENCY_SMOLTALK_LLAMA_CPP_PATH) {
680
+ return;
681
+ }
682
+ const entry = resolveSmoltalkLlamaCppEntry();
683
+ if (entry !== null) {
684
+ process.env.AGENCY_SMOLTALK_LLAMA_CPP_PATH = entry;
685
+ }
686
+ }
687
+ /** Absolute fs path of the bundled llama-cpp provider module. Tests/advanced
688
+ * callers can override via AGENCY_LLAMA_PROVIDER_MODULE (also an fs path).
689
+ * The override is normalized to an absolute path so `_downloadModel`'s
690
+ * `pathToFileURL(...)` call works even when callers pass a relative path
691
+ * (which `loadProviderModuleByPath` would itself happily resolve, but the
692
+ * download path bypasses that helper). */
693
+ function bundledLlamaModule() {
694
+ const override = process.env.AGENCY_LLAMA_PROVIDER_MODULE;
695
+ if (override !== undefined && override !== "") {
696
+ return path.isAbsolute(override) ? override : path.resolve(process.cwd(), override);
697
+ }
698
+ return fileURLToPath(new URL("./providers/llama-cpp.mjs", import.meta.url));
699
+ }
700
+ /** Guard the install-required commands. If the user set
701
+ * AGENCY_LLAMA_PROVIDER_MODULE they're supplying a provider module directly,
702
+ * so skip the smoltalk-llama-cpp resolve check. */
703
+ function requireSupport() {
704
+ if (process.env.AGENCY_LLAMA_PROVIDER_MODULE) {
705
+ return;
706
+ }
707
+ if (!_localModelsSupported()) {
708
+ throw new Error("Local models need smoltalk-llama-cpp — run: npm i -g smoltalk-llama-cpp");
709
+ }
710
+ }
711
+ /** Register the llama-cpp provider into agency's own smoltalk. */
712
+ export async function _registerLocalProvider() {
713
+ requireSupport();
714
+ exposeResolvedLlamaCppPath();
715
+ await loadProviderModuleByPath(bundledLlamaModule());
716
+ }
717
+ /** Stream-hash a file's SHA-256 (hex), never buffering the whole file. The
718
+ * `update` is guarded so a synchronous throw in the data handler rejects the
719
+ * promise instead of escaping it. */
720
+ export function fileSha256(filePath) {
721
+ return new Promise((resolve, reject) => {
722
+ const hash = createHash("sha256");
723
+ const stream = fs.createReadStream(filePath);
724
+ stream.on("error", reject);
725
+ stream.on("data", (chunk) => {
726
+ try {
727
+ hash.update(chunk);
728
+ }
729
+ catch (err) {
730
+ stream.destroy();
731
+ reject(err);
732
+ }
733
+ });
734
+ stream.on("end", () => resolve(hash.digest("hex")));
735
+ });
736
+ }
737
+ /** Verify `filePath` against the expected hex SHA-256. On mismatch, rename the
738
+ * file to `<filePath>.invalidSha` (kept for inspection; won't be picked up, so
739
+ * the next run re-downloads) and throw. A failed rename is logged (not
740
+ * swallowed) and reflected in the thrown message. */
741
+ export async function verifyModelFile(filePath, expected, name) {
742
+ // `fileSha256` returns lowercase hex; normalize the expected pin so a
743
+ // valid-but-uppercase hash (e.g. from a hand-written alias) still matches.
744
+ const want = expected.toLowerCase();
745
+ const actual = await fileSha256(filePath);
746
+ if (actual === want)
747
+ return;
748
+ const quarantine = `${filePath}.invalidSha`;
749
+ let moved = true;
750
+ try {
751
+ fs.renameSync(filePath, quarantine);
752
+ }
753
+ catch (err) {
754
+ moved = false;
755
+ console.warn(`Could not move "${filePath}" to "${quarantine}" after SHA-256 mismatch:`, err);
756
+ }
757
+ throw new Error(`SHA-256 verification failed for "${name}": expected ${expected}, got ${actual}. ` +
758
+ (moved
759
+ ? `The downloaded file was moved to ${quarantine} for inspection and will be re-downloaded next time.`
760
+ : `The downloaded file at ${filePath} could NOT be moved aside — delete it manually before re-running.`));
761
+ }
762
+ /** The pinned SHA-256 for a model name/alias, or undefined when none is known
763
+ * (raw uri/path, string alias, alias/curated without a hash, or a sharded
764
+ * model). An alias entry governs the name entirely — a user alias shadowing a
765
+ * curated name must NOT borrow the curated hash, but a user MAY opt in by
766
+ * setting their own `sha256` on the alias object. */
767
+ export function pinnedSha256(value, file = "") {
768
+ if (isGgufPath(value) || isModelUri(value))
769
+ return undefined;
770
+ const aliases = readModelAliases(file);
771
+ if (Object.hasOwn(aliases, value)) {
772
+ const v = aliases[value];
773
+ return typeof v === "object" ? v.sha256 : undefined;
774
+ }
775
+ return CURATED_LOCAL_MODELS[value]?.sha256;
776
+ }
777
+ /** Snapshot the cache dir, returning a probe that reports whether a resolved
778
+ * path is newly downloaded. node-llama-cpp stores models FLAT in `dir` with a
779
+ * prefixed filename — no per-repo subdirs (verified against its
780
+ * `buildHuggingFaceFilePrefix`) — so matching by basename is correct. */
781
+ export function snapshotFreshness(dir) {
782
+ const present = fs.existsSync(dir)
783
+ ? new Set(fs.readdirSync(dir).filter((f) => f.endsWith(".gguf")))
784
+ : new Set();
785
+ return (resolved) => !present.has(path.basename(resolved));
786
+ }
787
+ /** Resolve a name/uri/path to a local .gguf path, downloading if needed. */
788
+ export async function _downloadModel(value, cacheDir = "") {
789
+ requireSupport();
790
+ exposeResolvedLlamaCppPath();
791
+ const target = _resolveModelName(value);
792
+ const dir = resolveCacheDir(cacheDir);
793
+ const fsPath = bundledLlamaModule();
794
+ let mod;
795
+ try {
796
+ // eslint-disable-next-line no-restricted-syntax -- on-demand load of the optional provider module
797
+ mod = (await import(pathToFileURL(fsPath).href));
798
+ }
799
+ catch (err) {
800
+ throw new Error(`Failed to load the local-model provider: ${err.message}`);
801
+ }
802
+ if (typeof mod.resolveModel !== "function") {
803
+ throw new Error(`Local-model provider module must export resolveModel().`);
804
+ }
805
+ // Snapshot freshness BEFORE resolving so we verify the bytes only once, right
806
+ // after a real download (a cache hit is skipped — the file can't change on
807
+ // disk between runs).
808
+ const wasFresh = snapshotFreshness(dir);
809
+ const resolved = await mod.resolveModel(target, dir);
810
+ const expected = pinnedSha256(value);
811
+ if (expected !== undefined && wasFresh(resolved)) {
812
+ await verifyModelFile(resolved, expected, value);
813
+ }
814
+ return resolved;
815
+ }
816
+ /** Convenience: register the provider + ensure the model is downloaded. */
817
+ export async function _registerLocalModel(value, cacheDir = "") {
818
+ await _registerLocalProvider();
819
+ return await _downloadModel(value, cacheDir);
820
+ }
821
+ // =============================================================================
822
+ // Catalog rendering — shared by `agency local alias list` and the agent's
823
+ // bare `--local-model` discovery output, so both show an identical table.
824
+ // =============================================================================
825
+ const BYTES_PER_GB = 1e9;
826
+ export function formatGB(bytes) {
827
+ return `${(bytes / BYTES_PER_GB).toFixed(2)} GB`;
828
+ }
829
+ /** Context window in compact units: 8192 → "8K", 131072 → "128K", 1e7 → "10M". */
830
+ export function formatCtx(tokens) {
831
+ if (tokens >= 1_000_000)
832
+ return `${Math.round(tokens / 1_000_000)}M`;
833
+ if (tokens >= 1024)
834
+ return `${Math.round(tokens / 1024)}K`;
835
+ return `${tokens}`;
836
+ }
837
+ /** Width of a column: the longer of its header and its widest value. */
838
+ function colWidth(header, values) {
839
+ return Math.max(header.length, ...values.map((v) => v.length));
840
+ }
841
+ /** Render the usable-model list as an aligned table: a header row plus one
842
+ * fact row per curated model (params, category, size, context window,
843
+ * license), the description on a dimmed line below, a blank line between
844
+ * models. User aliases (which carry no metadata) follow in an ALIASES
845
+ * section as `name → target`. Returns the block as a string with no trailing
846
+ * newline (the caller's `console.log` adds exactly one). */
847
+ export function formatModelCatalog() {
848
+ const entries = _listModelNames();
849
+ const hasMetadata = (m) => m.params !== undefined ||
850
+ m.sizeBytes !== undefined ||
851
+ m.category !== undefined ||
852
+ m.contextWindow !== undefined ||
853
+ m.license !== undefined ||
854
+ m.description !== undefined;
855
+ const curated = entries.filter(hasMetadata); // table rows: built-ins + rich aliases
856
+ const aliases = entries.filter((m) => !hasMetadata(m)); // plain name→uri only
857
+ const lines = [];
858
+ if (curated.length > 0) {
859
+ const rows = curated.map((m) => ({
860
+ name: m.name,
861
+ params: m.params ?? "",
862
+ category: m.category ?? "",
863
+ size: m.sizeBytes ? formatGB(m.sizeBytes) : "?",
864
+ ctx: m.contextWindow ? formatCtx(m.contextWindow) : "",
865
+ license: m.license ?? "",
866
+ description: m.description ?? "",
867
+ }));
868
+ // Computed widths so columns fit the actual data (names range from ~10
869
+ // to ~28 chars). SIZE and CTX are numeric, so they right-align.
870
+ const w = {
871
+ name: colWidth("NAME", rows.map((r) => r.name)),
872
+ params: colWidth("PARAMS", rows.map((r) => r.params)),
873
+ category: colWidth("CATEGORY", rows.map((r) => r.category)),
874
+ size: colWidth("SIZE", rows.map((r) => r.size)),
875
+ ctx: colWidth("CTX", rows.map((r) => r.ctx)),
876
+ };
877
+ const row = (name, params, category, size, ctx, license) => `${name.padEnd(w.name)} ${params.padEnd(w.params)} ${category.padEnd(w.category)} ${size.padStart(w.size)} ${ctx.padStart(w.ctx)} ${license}`;
878
+ // LICENSE is the last column, so it needs no trailing pad.
879
+ lines.push(ttyColor.bold(row("NAME", "PARAMS", "CATEGORY", "SIZE", "CTX", "LICENSE")));
880
+ rows.forEach((r, i) => {
881
+ // Blank line *between* models, not after the last one, so the joined
882
+ // string has no trailing newline (console.log adds exactly one).
883
+ if (i > 0)
884
+ lines.push("");
885
+ lines.push(row(r.name, r.params, r.category, r.size, r.ctx, r.license));
886
+ if (r.description)
887
+ lines.push(ttyColor.dim(` ${r.description}`));
888
+ });
889
+ }
890
+ if (aliases.length > 0) {
891
+ if (lines.length > 0)
892
+ lines.push(""); // separate the table from ALIASES
893
+ lines.push(ttyColor.bold("ALIASES"));
894
+ for (const a of aliases) {
895
+ lines.push(`${a.name} → ${a.target}`);
896
+ }
897
+ }
898
+ return lines.join("\n");
899
+ }
900
+ /** Print the model catalog to stdout. The agent's bare `--local-model`
901
+ * path calls this through `std::agency/local`. */
902
+ export function _printLocalCatalog() {
903
+ console.log(formatModelCatalog());
904
+ }