agency-lang 0.8.1 → 0.10.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 (1133) hide show
  1. package/dist/lib/agents/agency-agent/agent.agency +110 -1848
  2. package/dist/lib/agents/agency-agent/agent.js +865 -10821
  3. package/dist/lib/agents/agency-agent/images/images.js +17 -6
  4. package/dist/lib/agents/agency-agent/lib/args.agency +88 -0
  5. package/dist/lib/agents/agency-agent/lib/args.js +407 -0
  6. package/dist/lib/agents/agency-agent/lib/attachments.js +108 -25
  7. package/dist/lib/agents/agency-agent/lib/budget.agency +213 -0
  8. package/dist/lib/agents/agency-agent/lib/budget.js +1504 -0
  9. package/dist/lib/agents/agency-agent/lib/capabilities.agency +22 -20
  10. package/dist/lib/agents/agency-agent/lib/capabilities.js +217 -59
  11. package/dist/lib/agents/agency-agent/lib/capabilitiesUi.agency +330 -0
  12. package/dist/lib/agents/agency-agent/lib/capabilitiesUi.js +2621 -0
  13. package/dist/lib/agents/agency-agent/lib/commandPalette.agency +38 -0
  14. package/dist/lib/agents/agency-agent/lib/commandPalette.js +503 -0
  15. package/dist/lib/agents/agency-agent/lib/config.js +29 -12
  16. package/dist/lib/agents/agency-agent/lib/coordinator.agency +373 -0
  17. package/dist/lib/agents/agency-agent/lib/coordinator.js +2377 -0
  18. package/dist/lib/agents/agency-agent/lib/header.agency +82 -0
  19. package/dist/lib/agents/agency-agent/lib/header.js +1069 -0
  20. package/dist/lib/agents/agency-agent/lib/images.agency +62 -0
  21. package/dist/lib/agents/agency-agent/lib/images.js +730 -0
  22. package/dist/lib/agents/agency-agent/lib/mcp.agency +103 -0
  23. package/dist/lib/agents/agency-agent/lib/mcp.js +1324 -0
  24. package/dist/lib/agents/agency-agent/lib/modelFilters.js +21 -7
  25. package/dist/lib/agents/agency-agent/lib/models.agency +7 -6
  26. package/dist/lib/agents/agency-agent/lib/models.js +228 -86
  27. package/dist/lib/agents/agency-agent/lib/policy.agency +111 -0
  28. package/dist/lib/agents/agency-agent/lib/policy.js +1080 -0
  29. package/dist/lib/agents/agency-agent/lib/repl.agency +415 -0
  30. package/dist/lib/agents/agency-agent/lib/repl.js +3174 -0
  31. package/dist/lib/agents/agency-agent/lib/resolution.js +208 -61
  32. package/dist/lib/agents/agency-agent/lib/search.agency +21 -3
  33. package/dist/lib/agents/agency-agent/lib/search.js +496 -80
  34. package/dist/lib/agents/agency-agent/lib/session.agency +331 -0
  35. package/dist/lib/agents/agency-agent/lib/session.js +2071 -0
  36. package/dist/lib/agents/agency-agent/lib/settings.js +185 -54
  37. package/dist/lib/agents/agency-agent/lib/slots.agency +0 -1
  38. package/dist/lib/agents/agency-agent/lib/slots.js +58 -17
  39. package/dist/lib/agents/agency-agent/lib/trace.agency +150 -0
  40. package/dist/lib/agents/agency-agent/lib/trace.js +2057 -0
  41. package/dist/lib/agents/agency-agent/lib/utils/renderLLMCallResponse.agency +27 -0
  42. package/dist/lib/agents/agency-agent/lib/utils/renderLLMCallResponse.js +361 -0
  43. package/dist/lib/agents/agency-agent/lib/utils.agency +54 -0
  44. package/dist/lib/agents/agency-agent/lib/utils.js +650 -41
  45. package/dist/lib/agents/agency-agent/prompts/code.md +268 -0
  46. package/dist/lib/agents/agency-agent/prompts/codeSample.js +46 -21
  47. package/dist/lib/agents/agency-agent/prompts/main-large.md +170 -0
  48. package/dist/lib/agents/agency-agent/prompts/main-small.md +30 -0
  49. package/dist/lib/agents/agency-agent/prompts/oneShot.md +21 -0
  50. package/dist/lib/agents/agency-agent/shared.agency +1 -4
  51. package/dist/lib/agents/agency-agent/shared.js +380 -107
  52. package/dist/lib/agents/agency-agent/subagents/brainstorm.agency +201 -0
  53. package/dist/lib/agents/agency-agent/subagents/brainstorm.js +1652 -0
  54. package/dist/lib/agents/agency-agent/subagents/code.agency +378 -431
  55. package/dist/lib/agents/agency-agent/subagents/code.js +3203 -645
  56. package/dist/lib/agents/agency-agent/subagents/explorer.agency +19 -132
  57. package/dist/lib/agents/agency-agent/subagents/explorer.js +103 -242
  58. package/dist/lib/agents/agency-agent/subagents/oracle.agency +23 -104
  59. package/dist/lib/agents/agency-agent/subagents/oracle.js +103 -222
  60. package/dist/lib/agents/agency-agent/subagents/research.agency +57 -155
  61. package/dist/lib/agents/agency-agent/subagents/research.js +156 -257
  62. package/dist/lib/agents/agency-agent/subagents/review.agency +78 -41
  63. package/dist/lib/agents/agency-agent/subagents/review.js +723 -178
  64. package/dist/lib/agents/agency-agent/subagents/supervisor.agency +378 -0
  65. package/dist/lib/agents/agency-agent/subagents/supervisor.js +2486 -0
  66. package/dist/lib/agents/agency-agent/subagents/verify.js +249 -204
  67. package/dist/lib/agents/agency-agent/tests/agentDir.js +33 -9
  68. package/dist/lib/agents/agency-agent/tests/agentTurn.agency +31 -4
  69. package/dist/lib/agents/agency-agent/tests/agentTurn.js +992 -247
  70. package/dist/lib/agents/agency-agent/tests/agentTurn.test.json +33 -3
  71. package/dist/lib/agents/agency-agent/tests/attachments.agency +6 -1
  72. package/dist/lib/agents/agency-agent/tests/attachments.js +364 -285
  73. package/dist/lib/agents/agency-agent/tests/attachmentsTurn.agency +5 -10
  74. package/dist/lib/agents/agency-agent/tests/attachmentsTurn.js +178 -175
  75. package/dist/lib/agents/agency-agent/tests/attachmentsTurn.test.json +0 -16
  76. package/dist/lib/agents/agency-agent/tests/brainstorm.agency +94 -0
  77. package/dist/lib/agents/agency-agent/tests/brainstorm.js +1235 -0
  78. package/dist/lib/agents/agency-agent/tests/brainstorm.test.json +59 -0
  79. package/dist/lib/agents/agency-agent/tests/capabilities.js +271 -87
  80. package/dist/lib/agents/agency-agent/tests/execPolicy.js +213 -63
  81. package/dist/lib/agents/agency-agent/tests/gitPolicy.js +137 -41
  82. package/dist/lib/agents/agency-agent/tests/imageTool.agency +1 -1
  83. package/dist/lib/agents/agency-agent/tests/imageTool.js +140 -38
  84. package/dist/lib/agents/agency-agent/tests/mcpGating.js +56 -21
  85. package/dist/lib/agents/agency-agent/tests/memoryWiring.js +108 -27
  86. package/dist/lib/agents/agency-agent/tests/modelFilters.js +98 -42
  87. package/dist/lib/agents/agency-agent/tests/models.js +192 -97
  88. package/dist/lib/agents/agency-agent/tests/models.test.json +4 -4
  89. package/dist/lib/agents/agency-agent/tests/oneShotRounds.js +104 -39
  90. package/dist/lib/agents/agency-agent/tests/resolution.js +538 -143
  91. package/dist/lib/agents/agency-agent/tests/resolution.test.json +2 -2
  92. package/dist/lib/agents/agency-agent/tests/search.js +496 -147
  93. package/dist/lib/agents/agency-agent/tests/settings.agency +5 -1
  94. package/dist/lib/agents/agency-agent/tests/settings.js +173 -88
  95. package/dist/lib/agents/agency-agent/tests/slots.js +28 -21
  96. package/dist/lib/agents/agency-agent/tests/subagentFailure.js +749 -0
  97. package/dist/lib/agents/agency-agent/tests/supervisor.agency +197 -0
  98. package/dist/lib/agents/agency-agent/tests/supervisor.js +2713 -0
  99. package/dist/lib/agents/agency-agent/tests/supervisor.test.json +169 -0
  100. package/dist/lib/agents/agency-agent/tests/toolWiring.agency +23 -4
  101. package/dist/lib/agents/agency-agent/tests/toolWiring.js +313 -29
  102. package/dist/lib/agents/agency-agent/tests/toolWiring.test.json +14 -0
  103. package/dist/lib/agents/agency-agent/tests/turnFailure.agency +8 -3
  104. package/dist/lib/agents/agency-agent/tests/turnFailure.js +108 -47
  105. package/dist/lib/agents/eval/goalJudge.agency +4 -2
  106. package/dist/lib/agents/eval/goalJudge.js +24 -11
  107. package/dist/lib/agents/eval/judge.agency +4 -2
  108. package/dist/lib/agents/eval/judge.js +22 -11
  109. package/dist/lib/agents/eval/judgePairwise.js +20 -9
  110. package/dist/lib/agents/optimize/gepaReflect.js +20 -9
  111. package/dist/lib/agents/optimize/mutatePrompt.js +20 -9
  112. package/dist/lib/agents/policy/agent.agency +5 -4
  113. package/dist/lib/agents/policy/agent.js +237 -63
  114. package/dist/lib/agents/review/agent.agency +2 -2
  115. package/dist/lib/agents/review/agent.js +81 -16
  116. package/dist/lib/analysis/bodyFacts.d.ts +52 -0
  117. package/dist/lib/analysis/bodyFacts.js +87 -0
  118. package/dist/lib/analysis/effectPropagation.test.js +167 -0
  119. package/dist/lib/analysis/effects.d.ts +66 -0
  120. package/dist/lib/analysis/effects.js +238 -0
  121. package/dist/lib/analysis/effects.test.d.ts +1 -0
  122. package/dist/lib/analysis/effects.test.js +247 -0
  123. package/dist/lib/analysis/effectsOracle.test.d.ts +1 -0
  124. package/dist/lib/analysis/effectsOracle.test.js +74 -0
  125. package/dist/lib/analysis/interrupts.js +6 -1
  126. package/dist/lib/backends/agencyGenerator.d.ts +52 -6
  127. package/dist/lib/backends/agencyGenerator.finalizeBlock.test.d.ts +1 -0
  128. package/dist/lib/backends/agencyGenerator.finalizeBlock.test.js +36 -0
  129. package/dist/lib/backends/agencyGenerator.guardBlock.test.d.ts +1 -0
  130. package/dist/lib/backends/agencyGenerator.guardBlock.test.js +33 -0
  131. package/dist/lib/backends/agencyGenerator.hole.test.d.ts +1 -0
  132. package/dist/lib/backends/agencyGenerator.hole.test.js +61 -0
  133. package/dist/lib/backends/agencyGenerator.js +264 -18
  134. package/dist/lib/backends/agencyGenerator.matchBlock.test.js +41 -0
  135. package/dist/lib/backends/agencyGenerator.roundtrip.test.d.ts +1 -0
  136. package/dist/lib/backends/agencyGenerator.roundtrip.test.js +250 -0
  137. package/dist/lib/backends/agencyGenerator.splice.test.d.ts +1 -0
  138. package/dist/lib/backends/agencyGenerator.splice.test.js +43 -0
  139. package/dist/lib/backends/agencyGenerator.test.js +52 -0
  140. package/dist/lib/backends/draftSchemaCodegen.test.d.ts +1 -0
  141. package/dist/lib/backends/draftSchemaCodegen.test.js +70 -0
  142. package/dist/lib/backends/finalizeBinderCodegen.test.d.ts +1 -0
  143. package/dist/lib/backends/finalizeBinderCodegen.test.js +26 -0
  144. package/dist/lib/backends/frameClaims.test.d.ts +1 -0
  145. package/dist/lib/backends/frameClaims.test.js +58 -0
  146. package/dist/lib/backends/functionContainsDestructiveBlock.d.ts +22 -0
  147. package/dist/lib/backends/functionContainsDestructiveBlock.js +30 -0
  148. package/dist/lib/backends/functionContainsDestructiveBlock.test.d.ts +1 -0
  149. package/dist/lib/backends/functionContainsDestructiveBlock.test.js +31 -0
  150. package/dist/lib/backends/holeRefusal.test.d.ts +1 -0
  151. package/dist/lib/backends/holeRefusal.test.js +58 -0
  152. package/dist/lib/backends/typescriptBuilder/destructiveTracking.d.ts +19 -12
  153. package/dist/lib/backends/typescriptBuilder/destructiveTracking.js +31 -17
  154. package/dist/lib/backends/typescriptBuilder/destructiveTracking.test.js +15 -8
  155. package/dist/lib/backends/typescriptBuilder/finalizeCodegen.d.ts +104 -0
  156. package/dist/lib/backends/typescriptBuilder/finalizeCodegen.js +146 -0
  157. package/dist/lib/backends/typescriptBuilder/nameClassifier.d.ts +2 -11
  158. package/dist/lib/backends/typescriptBuilder/nameClassifier.js +7 -31
  159. package/dist/lib/backends/typescriptBuilder/scopeManager.d.ts +11 -0
  160. package/dist/lib/backends/typescriptBuilder/scopeManager.js +34 -0
  161. package/dist/lib/backends/typescriptBuilder/scopeManager.test.js +36 -0
  162. package/dist/lib/backends/typescriptBuilder/sectionAssembler.js +11 -11
  163. package/dist/lib/backends/typescriptBuilder/stepPathTracker.js +2 -1
  164. package/dist/lib/backends/typescriptBuilder.d.ts +45 -5
  165. package/dist/lib/backends/typescriptBuilder.js +308 -60
  166. package/dist/lib/backends/typescriptGenerator/typeToString.js +1 -1
  167. package/dist/lib/backends/typescriptGenerator/validationDescriptor.js +42 -16
  168. package/dist/lib/cli/agent.d.ts +4 -1
  169. package/dist/lib/cli/agent.js +2 -2
  170. package/dist/lib/cli/budget.d.ts +19 -0
  171. package/dist/lib/cli/budget.js +44 -0
  172. package/dist/lib/cli/budget.test.d.ts +1 -0
  173. package/dist/lib/cli/budget.test.js +46 -0
  174. package/dist/lib/cli/budgetRun.spawn.test.d.ts +1 -0
  175. package/dist/lib/cli/budgetRun.spawn.test.js +109 -0
  176. package/dist/lib/cli/bundle.test.js +2 -2
  177. package/dist/lib/cli/commands.d.ts +3 -0
  178. package/dist/lib/cli/commands.js +11 -2
  179. package/dist/lib/cli/definition.js +3 -2
  180. package/dist/lib/cli/diagnosticsDocs.js +46 -2
  181. package/dist/lib/cli/diagnosticsDocs.test.js +24 -2
  182. package/dist/lib/cli/doc.d.ts +1 -0
  183. package/dist/lib/cli/doc.js +53 -12
  184. package/dist/lib/cli/doc.test.js +134 -5
  185. package/dist/lib/cli/doctor.js +2 -2
  186. package/dist/lib/cli/doctor.test.js +3 -3
  187. package/dist/lib/cli/events.test.js +2 -1
  188. package/dist/lib/cli/expectedCompileError.d.ts +30 -0
  189. package/dist/lib/cli/expectedCompileError.js +58 -0
  190. package/dist/lib/cli/expectedCompileError.test.d.ts +1 -0
  191. package/dist/lib/cli/expectedCompileError.test.js +81 -0
  192. package/dist/lib/cli/explain.js +37 -0
  193. package/dist/lib/cli/explain.test.js +28 -2
  194. package/dist/lib/cli/lint.d.ts +4 -0
  195. package/dist/lib/cli/lint.js +11 -0
  196. package/dist/lib/cli/lint.test.d.ts +1 -0
  197. package/dist/lib/cli/lint.test.js +18 -0
  198. package/dist/lib/cli/literate.d.ts +1 -1
  199. package/dist/lib/cli/literate.js +89 -9
  200. package/dist/lib/cli/literate.test.js +96 -1
  201. package/dist/lib/cli/policy.d.ts +2 -0
  202. package/dist/lib/cli/policy.js +1 -1
  203. package/dist/lib/cli/policyCrossModule.test.d.ts +1 -0
  204. package/dist/lib/cli/policyCrossModule.test.js +30 -0
  205. package/dist/lib/cli/precompile.js +16 -7
  206. package/dist/lib/cli/precompile.test.js +22 -0
  207. package/dist/lib/cli/runAgencyAgent.js +4 -3
  208. package/dist/lib/cli/runBundledAgent.d.ts +4 -1
  209. package/dist/lib/cli/runBundledAgent.js +23 -7
  210. package/dist/lib/cli/runBundledAgent.test.js +40 -8
  211. package/dist/lib/cli/serve.js +16 -28
  212. package/dist/lib/cli/test.d.ts +8 -2
  213. package/dist/lib/cli/test.js +194 -10
  214. package/dist/lib/cli/test.test.d.ts +1 -0
  215. package/dist/lib/cli/test.test.js +76 -0
  216. package/dist/lib/cli/util.d.ts +2 -1
  217. package/dist/lib/cli/util.js +10 -4
  218. package/dist/lib/compilationUnit.js +8 -4
  219. package/dist/lib/compiler/buildSession.js +14 -1
  220. package/dist/lib/compiler/compile.js +24 -1
  221. package/dist/lib/compiler/compileClosure.d.ts +14 -1
  222. package/dist/lib/compiler/compileClosure.js +13 -1
  223. package/dist/lib/compiler/initDepGraph.js +3 -2
  224. package/dist/lib/compiler/splice/cache.d.ts +60 -0
  225. package/dist/lib/compiler/splice/cache.js +126 -0
  226. package/dist/lib/compiler/splice/cache.test.d.ts +1 -0
  227. package/dist/lib/compiler/splice/cache.test.js +124 -0
  228. package/dist/lib/compiler/splice/eligibility.d.ts +114 -0
  229. package/dist/lib/compiler/splice/eligibility.js +253 -0
  230. package/dist/lib/compiler/splice/eligibility.test.d.ts +1 -0
  231. package/dist/lib/compiler/splice/eligibility.test.js +153 -0
  232. package/dist/lib/compiler/splice/generatorEffects.d.ts +18 -0
  233. package/dist/lib/compiler/splice/generatorEffects.js +210 -0
  234. package/dist/lib/compiler/splice/rebuild.test.d.ts +1 -0
  235. package/dist/lib/compiler/splice/rebuild.test.js +124 -0
  236. package/dist/lib/compiler/splice/report.d.ts +12 -0
  237. package/dist/lib/compiler/splice/report.js +20 -0
  238. package/dist/lib/compiler/splice/runGenerator.d.ts +43 -0
  239. package/dist/lib/compiler/splice/runGenerator.js +385 -0
  240. package/dist/lib/compiler/splice/runGenerator.test.d.ts +1 -0
  241. package/dist/lib/compiler/splice/runGenerator.test.js +216 -0
  242. package/dist/lib/compiler/splice/types.d.ts +28 -0
  243. package/dist/lib/compiler/splice/types.js +1 -0
  244. package/dist/lib/compiler/typecheck.d.ts +10 -0
  245. package/dist/lib/compiler/typecheck.js +28 -7
  246. package/dist/lib/compiler/typecheckEffects.test.d.ts +1 -0
  247. package/dist/lib/compiler/typecheckEffects.test.js +35 -0
  248. package/dist/lib/config.d.ts +18 -1
  249. package/dist/lib/config.js +19 -3
  250. package/dist/lib/config.test.js +7 -1
  251. package/dist/lib/constants.d.ts +21 -0
  252. package/dist/lib/constants.js +21 -0
  253. package/dist/lib/debugger/uiState.test.js +1 -0
  254. package/dist/lib/formatter.comprehension.test.d.ts +1 -0
  255. package/dist/lib/formatter.comprehension.test.js +34 -0
  256. package/dist/lib/formatter.test.js +36 -0
  257. package/dist/lib/ir/builders.js +4 -8
  258. package/dist/lib/ir/prettyPrint.js +11 -1
  259. package/dist/lib/linter/diagnosticExplanations.d.ts +3 -0
  260. package/dist/lib/linter/diagnosticExplanations.js +20 -0
  261. package/dist/lib/linter/diagnostics.d.ts +35 -0
  262. package/dist/lib/linter/diagnostics.js +43 -0
  263. package/dist/lib/linter/diagnostics.test.d.ts +1 -0
  264. package/dist/lib/linter/diagnostics.test.js +23 -0
  265. package/dist/lib/linter/registry.d.ts +14 -0
  266. package/dist/lib/linter/registry.js +28 -0
  267. package/dist/lib/linter/registry.test.d.ts +1 -0
  268. package/dist/lib/linter/registry.test.js +23 -0
  269. package/dist/lib/linter/rules/importFixes.d.ts +8 -0
  270. package/dist/lib/linter/rules/importFixes.js +71 -0
  271. package/dist/lib/linter/rules/missingDocstring.d.ts +2 -0
  272. package/dist/lib/linter/rules/missingDocstring.js +27 -0
  273. package/dist/lib/linter/rules/missingDocstring.test.d.ts +1 -0
  274. package/dist/lib/linter/rules/missingDocstring.test.js +62 -0
  275. package/dist/lib/linter/rules/redundantPreludeImport.d.ts +2 -0
  276. package/dist/lib/linter/rules/redundantPreludeImport.js +50 -0
  277. package/dist/lib/linter/rules/redundantPreludeImport.test.d.ts +1 -0
  278. package/dist/lib/linter/rules/redundantPreludeImport.test.js +74 -0
  279. package/dist/lib/linter/rules/unusedImports.d.ts +26 -0
  280. package/dist/lib/linter/rules/unusedImports.fix.test.d.ts +1 -0
  281. package/dist/lib/linter/rules/unusedImports.fix.test.js +86 -0
  282. package/dist/lib/linter/rules/unusedImports.js +102 -0
  283. package/dist/lib/linter/rules/unusedImports.test.d.ts +1 -0
  284. package/dist/lib/linter/rules/unusedImports.test.js +107 -0
  285. package/dist/lib/linter/rules/util.d.ts +36 -0
  286. package/dist/lib/linter/rules/util.js +93 -0
  287. package/dist/lib/linter/rules/util.test.d.ts +1 -0
  288. package/dist/lib/linter/rules/util.test.js +37 -0
  289. package/dist/lib/linter/types.d.ts +41 -0
  290. package/dist/lib/linter/types.js +1 -0
  291. package/dist/lib/lowering/comprehensionDesugar.d.ts +26 -0
  292. package/dist/lib/lowering/comprehensionDesugar.js +228 -0
  293. package/dist/lib/lowering/comprehensionDesugar.locations.test.d.ts +1 -0
  294. package/dist/lib/lowering/comprehensionDesugar.locations.test.js +57 -0
  295. package/dist/lib/lowering/comprehensionDesugar.test.d.ts +1 -0
  296. package/dist/lib/lowering/comprehensionDesugar.test.js +171 -0
  297. package/dist/lib/lowering/patternGuards.tripwire.test.d.ts +27 -0
  298. package/dist/lib/lowering/patternGuards.tripwire.test.js +362 -0
  299. package/dist/lib/lowering/patternLowering.js +303 -28
  300. package/dist/lib/lowering/patternLowering.test.js +120 -7
  301. package/dist/lib/lsp/builtinHover.js +4 -3
  302. package/dist/lib/lsp/codeAction.d.ts +13 -1
  303. package/dist/lib/lsp/codeAction.js +70 -1
  304. package/dist/lib/lsp/codeAction.test.js +86 -0
  305. package/dist/lib/lsp/completion.js +2 -1
  306. package/dist/lib/lsp/diagnostics.d.ts +4 -0
  307. package/dist/lib/lsp/diagnostics.js +116 -18
  308. package/dist/lib/lsp/diagnostics.test.js +254 -0
  309. package/dist/lib/lsp/documentState.d.ts +10 -0
  310. package/dist/lib/lsp/documentStateCache.d.ts +50 -0
  311. package/dist/lib/lsp/documentStateCache.js +47 -0
  312. package/dist/lib/lsp/documentStateCache.test.d.ts +1 -0
  313. package/dist/lib/lsp/documentStateCache.test.js +95 -0
  314. package/dist/lib/lsp/documentSymbol.js +3 -2
  315. package/dist/lib/lsp/inlayHint.js +2 -1
  316. package/dist/lib/lsp/scopeResolution.d.ts +17 -0
  317. package/dist/lib/lsp/scopeResolution.js +42 -22
  318. package/dist/lib/lsp/semanticTokens.d.ts +32 -0
  319. package/dist/lib/lsp/semanticTokens.js +220 -0
  320. package/dist/lib/lsp/semanticTokens.test.d.ts +1 -0
  321. package/dist/lib/lsp/semanticTokens.test.js +338 -0
  322. package/dist/lib/lsp/semantics.js +7 -6
  323. package/dist/lib/lsp/server.js +136 -13
  324. package/dist/lib/lsp/typeResolution.js +2 -1
  325. package/dist/lib/optimize/targets.js +3 -2
  326. package/dist/lib/parseCache.d.ts +10 -0
  327. package/dist/lib/parseCache.js +13 -0
  328. package/dist/lib/parseCache.test.js +26 -1
  329. package/dist/lib/parser.d.ts +1 -1
  330. package/dist/lib/parser.js +67 -8
  331. package/dist/lib/parser.test.js +12 -3
  332. package/dist/lib/parsers/chainNewlineBoundary.test.d.ts +1 -0
  333. package/dist/lib/parsers/chainNewlineBoundary.test.js +121 -0
  334. package/dist/lib/parsers/codeLiteral.test.d.ts +1 -0
  335. package/dist/lib/parsers/codeLiteral.test.js +241 -0
  336. package/dist/lib/parsers/comprehension.test.d.ts +1 -0
  337. package/dist/lib/parsers/comprehension.test.js +325 -0
  338. package/dist/lib/parsers/destructiveBlock.test.d.ts +1 -0
  339. package/dist/lib/parsers/destructiveBlock.test.js +36 -0
  340. package/dist/lib/parsers/finalizeBinder.test.d.ts +1 -0
  341. package/dist/lib/parsers/finalizeBinder.test.js +59 -0
  342. package/dist/lib/parsers/finalizeBlock.test.d.ts +1 -0
  343. package/dist/lib/parsers/finalizeBlock.test.js +37 -0
  344. package/dist/lib/parsers/guardBlock.test.d.ts +1 -0
  345. package/dist/lib/parsers/guardBlock.test.js +81 -0
  346. package/dist/lib/parsers/hashRemoved.test.d.ts +1 -0
  347. package/dist/lib/parsers/hashRemoved.test.js +11 -0
  348. package/dist/lib/parsers/hole.test.d.ts +1 -0
  349. package/dist/lib/parsers/hole.test.js +171 -0
  350. package/dist/lib/parsers/literalDelimiter.test.d.ts +1 -0
  351. package/dist/lib/parsers/literalDelimiter.test.js +60 -0
  352. package/dist/lib/parsers/matchBlock.test.js +100 -0
  353. package/dist/lib/parsers/objectTypeTags.test.js +0 -13
  354. package/dist/lib/parsers/parsers.d.ts +108 -6
  355. package/dist/lib/parsers/parsers.js +829 -55
  356. package/dist/lib/parsers/pattern.test.js +235 -4
  357. package/dist/lib/parsers/splice.test.d.ts +1 -0
  358. package/dist/lib/parsers/splice.test.js +81 -0
  359. package/dist/lib/parsers/typeHints.test.js +1 -300
  360. package/dist/lib/perf/compile.perf.test.d.ts +1 -0
  361. package/dist/lib/perf/compile.perf.test.js +76 -0
  362. package/dist/lib/perf/doc.perf.test.d.ts +1 -0
  363. package/dist/lib/perf/doc.perf.test.js +30 -0
  364. package/dist/lib/perf/fixtures.d.ts +25 -0
  365. package/dist/lib/perf/fixtures.js +100 -0
  366. package/dist/lib/perf/fixtures.test.d.ts +1 -0
  367. package/dist/lib/perf/fixtures.test.js +37 -0
  368. package/dist/lib/perf/fmt.perf.test.d.ts +1 -0
  369. package/dist/lib/perf/fmt.perf.test.js +16 -0
  370. package/dist/lib/perf/harness.d.ts +31 -0
  371. package/dist/lib/perf/harness.js +114 -0
  372. package/dist/lib/perf/harness.perf.test.d.ts +1 -0
  373. package/dist/lib/perf/harness.perf.test.js +45 -0
  374. package/dist/lib/perf/harness.test.d.ts +1 -0
  375. package/dist/lib/perf/harness.test.js +79 -0
  376. package/dist/lib/perf/lint.perf.test.d.ts +1 -0
  377. package/dist/lib/perf/lint.perf.test.js +76 -0
  378. package/dist/lib/perf/lsp.perf.test.d.ts +1 -0
  379. package/dist/lib/perf/lsp.perf.test.js +60 -0
  380. package/dist/lib/perf/parse.perf.test.d.ts +1 -0
  381. package/dist/lib/perf/parse.perf.test.js +20 -0
  382. package/dist/lib/perf/symbolTable.perf.test.d.ts +1 -0
  383. package/dist/lib/perf/symbolTable.perf.test.js +63 -0
  384. package/dist/lib/perf/typecheck.perf.test.d.ts +1 -0
  385. package/dist/lib/perf/typecheck.perf.test.js +35 -0
  386. package/dist/lib/prelude.d.ts +27 -0
  387. package/dist/lib/prelude.js +62 -0
  388. package/dist/lib/prelude.test.d.ts +1 -0
  389. package/dist/lib/prelude.test.js +41 -0
  390. package/dist/lib/preprocessors/expandSplices.d.ts +14 -0
  391. package/dist/lib/preprocessors/expandSplices.js +451 -0
  392. package/dist/lib/preprocessors/expandSplices.test.d.ts +1 -0
  393. package/dist/lib/preprocessors/expandSplices.test.js +287 -0
  394. package/dist/lib/preprocessors/guardDesugar.d.ts +37 -0
  395. package/dist/lib/preprocessors/guardDesugar.js +98 -0
  396. package/dist/lib/preprocessors/guardDesugar.test.d.ts +1 -0
  397. package/dist/lib/preprocessors/guardDesugar.test.js +158 -0
  398. package/dist/lib/preprocessors/hoistCalls.d.ts +83 -0
  399. package/dist/lib/preprocessors/hoistCalls.js +354 -0
  400. package/dist/lib/preprocessors/hoistCalls.test.d.ts +1 -0
  401. package/dist/lib/preprocessors/hoistCalls.test.js +385 -0
  402. package/dist/lib/preprocessors/importResolver.d.ts +13 -0
  403. package/dist/lib/preprocessors/importResolver.js +188 -102
  404. package/dist/lib/preprocessors/importResolver.test.js +115 -0
  405. package/dist/lib/preprocessors/liftCallbacks.js +8 -3
  406. package/dist/lib/preprocessors/liftCallbacks.test.js +1 -1
  407. package/dist/lib/preprocessors/parallelDesugar.js +17 -1
  408. package/dist/lib/preprocessors/parallelDesugar.test.js +24 -0
  409. package/dist/lib/preprocessors/prunePreludeShadows.d.ts +0 -20
  410. package/dist/lib/preprocessors/prunePreludeShadows.js +18 -3
  411. package/dist/lib/preprocessors/typescriptPreprocessor.js +37 -7
  412. package/dist/lib/runtime/__tests__/testHelpers.js +2 -1
  413. package/dist/lib/runtime/abortedResult.d.ts +100 -0
  414. package/dist/lib/runtime/abortedResult.js +217 -0
  415. package/dist/lib/runtime/abortedResult.test.d.ts +1 -0
  416. package/dist/lib/runtime/abortedResult.test.js +295 -0
  417. package/dist/lib/runtime/agency.test.js +9 -0
  418. package/dist/lib/runtime/agencyFunction.d.ts +8 -0
  419. package/dist/lib/runtime/agencyFunction.js +32 -2
  420. package/dist/lib/runtime/agencyFunction.test.js +39 -0
  421. package/dist/lib/runtime/agencyInterrupt.js +1 -0
  422. package/dist/lib/runtime/agencyInterrupt.test.js +79 -53
  423. package/dist/lib/runtime/asyncContext.d.ts +2 -26
  424. package/dist/lib/runtime/asyncContext.js +12 -14
  425. package/dist/lib/runtime/asyncContext.test.js +1 -25
  426. package/dist/lib/runtime/blockNames.d.ts +28 -0
  427. package/dist/lib/runtime/blockNames.js +40 -0
  428. package/dist/lib/runtime/blockNames.test.d.ts +1 -0
  429. package/dist/lib/runtime/blockNames.test.js +32 -0
  430. package/dist/lib/runtime/budgetExit.d.ts +20 -0
  431. package/dist/lib/runtime/budgetExit.js +35 -0
  432. package/dist/lib/runtime/budgetExit.test.d.ts +1 -0
  433. package/dist/lib/runtime/budgetExit.test.js +59 -0
  434. package/dist/lib/runtime/call.js +77 -0
  435. package/dist/lib/runtime/clock.d.ts +48 -0
  436. package/dist/lib/runtime/clock.js +71 -0
  437. package/dist/lib/runtime/clock.test.d.ts +1 -0
  438. package/dist/lib/runtime/clock.test.js +118 -0
  439. package/dist/lib/runtime/configOverrides.test.js +1 -1
  440. package/dist/lib/runtime/crossModuleInitRegistry.d.ts +24 -0
  441. package/dist/lib/runtime/crossModuleInitRegistry.js +32 -0
  442. package/dist/lib/runtime/crossModuleInitRegistry.test.d.ts +1 -0
  443. package/dist/lib/runtime/crossModuleInitRegistry.test.js +31 -0
  444. package/dist/lib/runtime/deterministicClient.d.ts +9 -1
  445. package/dist/lib/runtime/deterministicClient.js +23 -1
  446. package/dist/lib/runtime/effectMerge.d.ts +31 -0
  447. package/dist/lib/runtime/effectMerge.js +93 -0
  448. package/dist/lib/runtime/effectMerge.test.d.ts +1 -0
  449. package/dist/lib/runtime/effectMerge.test.js +92 -0
  450. package/dist/lib/runtime/errors.d.ts +8 -0
  451. package/dist/lib/runtime/errors.js +10 -0
  452. package/dist/lib/runtime/executingHandlers.d.ts +7 -0
  453. package/dist/lib/runtime/executingHandlers.js +47 -0
  454. package/dist/lib/runtime/executingHandlers.test.d.ts +1 -0
  455. package/dist/lib/runtime/executingHandlers.test.js +51 -0
  456. package/dist/lib/runtime/guard.clock.test.d.ts +1 -0
  457. package/dist/lib/runtime/guard.clock.test.js +78 -0
  458. package/dist/lib/runtime/guard.d.ts +268 -35
  459. package/dist/lib/runtime/guard.js +386 -62
  460. package/dist/lib/runtime/guard.test.js +235 -23
  461. package/dist/lib/runtime/guardScope.d.ts +74 -0
  462. package/dist/lib/runtime/guardScope.js +140 -0
  463. package/dist/lib/runtime/guardScope.test.d.ts +1 -0
  464. package/dist/lib/runtime/guardScope.test.js +228 -0
  465. package/dist/lib/runtime/guardTripInterrupt.d.ts +61 -0
  466. package/dist/lib/runtime/guardTripInterrupt.inHandler.test.d.ts +1 -0
  467. package/dist/lib/runtime/guardTripInterrupt.inHandler.test.js +47 -0
  468. package/dist/lib/runtime/guardTripInterrupt.js +295 -0
  469. package/dist/lib/runtime/index.d.ts +8 -3
  470. package/dist/lib/runtime/index.js +8 -3
  471. package/dist/lib/runtime/interrupts.d.ts +14 -10
  472. package/dist/lib/runtime/interrupts.executingHandlers.test.d.ts +1 -0
  473. package/dist/lib/runtime/interrupts.executingHandlers.test.js +112 -0
  474. package/dist/lib/runtime/interrupts.js +162 -32
  475. package/dist/lib/runtime/interrupts.test.js +64 -16
  476. package/dist/lib/runtime/intrinsicToolSchema.test.d.ts +1 -0
  477. package/dist/lib/runtime/intrinsicToolSchema.test.js +188 -0
  478. package/dist/lib/runtime/intrinsicTools.d.ts +91 -0
  479. package/dist/lib/runtime/intrinsicTools.js +82 -0
  480. package/dist/lib/runtime/ipc.js +8 -2
  481. package/dist/lib/runtime/jsonValue.d.ts +15 -0
  482. package/dist/lib/runtime/jsonValue.js +66 -0
  483. package/dist/lib/runtime/jsonValue.test.d.ts +1 -0
  484. package/dist/lib/runtime/jsonValue.test.js +52 -0
  485. package/dist/lib/runtime/memory/cacheEntry.d.ts +10 -0
  486. package/dist/lib/runtime/memory/cacheEntry.js +10 -0
  487. package/dist/lib/runtime/memory/compaction.d.ts +8 -3
  488. package/dist/lib/runtime/memory/compaction.js +10 -4
  489. package/dist/lib/runtime/memory/compaction.test.js +32 -18
  490. package/dist/lib/runtime/memory/manager.js +23 -5
  491. package/dist/lib/runtime/memory/manager.test.js +91 -0
  492. package/dist/lib/runtime/node.d.ts +2 -6
  493. package/dist/lib/runtime/node.js +23 -21
  494. package/dist/lib/runtime/prompt.d.ts +18 -0
  495. package/dist/lib/runtime/prompt.js +428 -238
  496. package/dist/lib/runtime/promptLabels.test.d.ts +1 -0
  497. package/dist/lib/runtime/promptLabels.test.js +159 -0
  498. package/dist/lib/runtime/promptRunner.d.ts +7 -2
  499. package/dist/lib/runtime/promptRunner.js +1 -0
  500. package/dist/lib/runtime/promptRunner.test.js +3 -3
  501. package/dist/lib/runtime/requireLength.d.ts +15 -0
  502. package/dist/lib/runtime/requireLength.js +21 -0
  503. package/dist/lib/runtime/result.d.ts +6 -4
  504. package/dist/lib/runtime/result.js +37 -2
  505. package/dist/lib/runtime/result.test.js +58 -0
  506. package/dist/lib/runtime/resumableScope.js +4 -4
  507. package/dist/lib/runtime/revivers/functionRefReviver.d.ts +7 -1
  508. package/dist/lib/runtime/revivers/functionRefReviver.js +192 -15
  509. package/dist/lib/runtime/revivers/functionRefReviver.test.js +268 -3
  510. package/dist/lib/runtime/rewind.d.ts +0 -2
  511. package/dist/lib/runtime/rewind.js +3 -4
  512. package/dist/lib/runtime/rootBudget.d.ts +13 -0
  513. package/dist/lib/runtime/rootBudget.js +52 -0
  514. package/dist/lib/runtime/rootBudget.test.d.ts +1 -0
  515. package/dist/lib/runtime/rootBudget.test.js +70 -0
  516. package/dist/lib/runtime/runBatch.js +191 -14
  517. package/dist/lib/runtime/runBatch.test.js +30 -1
  518. package/dist/lib/runtime/runPolicyHandler.d.ts +1 -1
  519. package/dist/lib/runtime/runPolicyHandler.js +5 -1
  520. package/dist/lib/runtime/runner.d.ts +9 -0
  521. package/dist/lib/runtime/runner.js +110 -21
  522. package/dist/lib/runtime/runner.test.js +99 -3
  523. package/dist/lib/runtime/saveDraftTool.d.ts +15 -0
  524. package/dist/lib/runtime/saveDraftTool.js +72 -0
  525. package/dist/lib/runtime/saveDraftTool.test.d.ts +1 -0
  526. package/dist/lib/runtime/saveDraftTool.test.js +123 -0
  527. package/dist/lib/runtime/state/checkpointStore.test.js +1 -0
  528. package/dist/lib/runtime/state/context.clock.test.d.ts +1 -0
  529. package/dist/lib/runtime/state/context.clock.test.js +47 -0
  530. package/dist/lib/runtime/state/context.d.ts +36 -3
  531. package/dist/lib/runtime/state/context.js +47 -3
  532. package/dist/lib/runtime/state/globalStore.js +7 -0
  533. package/dist/lib/runtime/state/messageThread.d.ts +104 -2
  534. package/dist/lib/runtime/state/messageThread.js +183 -5
  535. package/dist/lib/runtime/state/messageThread.test.js +240 -0
  536. package/dist/lib/runtime/state/pendingPromiseStore.d.ts +10 -1
  537. package/dist/lib/runtime/state/pendingPromiseStore.js +22 -1
  538. package/dist/lib/runtime/state/pendingPromiseStore.test.js +41 -0
  539. package/dist/lib/runtime/state/schemas.d.ts +3 -0
  540. package/dist/lib/runtime/state/schemas.js +3 -0
  541. package/dist/lib/runtime/state/stateStack.d.ts +234 -6
  542. package/dist/lib/runtime/state/stateStack.executingHandlers.test.d.ts +1 -0
  543. package/dist/lib/runtime/state/stateStack.executingHandlers.test.js +42 -0
  544. package/dist/lib/runtime/state/stateStack.js +390 -11
  545. package/dist/lib/runtime/state/stateStack.test.js +75 -1
  546. package/dist/lib/runtime/state/stateStack.tripwire.test.d.ts +1 -0
  547. package/dist/lib/runtime/state/stateStack.tripwire.test.js +47 -0
  548. package/dist/lib/runtime/template/code.d.ts +19 -0
  549. package/dist/lib/runtime/template/code.js +12 -0
  550. package/dist/lib/runtime/template/codeLiteral.d.ts +10 -0
  551. package/dist/lib/runtime/template/codeLiteral.js +40 -0
  552. package/dist/lib/runtime/template/combine.test.d.ts +1 -0
  553. package/dist/lib/runtime/template/combine.test.js +97 -0
  554. package/dist/lib/runtime/template/escaping.test.d.ts +1 -0
  555. package/dist/lib/runtime/template/escaping.test.js +107 -0
  556. package/dist/lib/runtime/template/fill.d.ts +19 -0
  557. package/dist/lib/runtime/template/fill.js +247 -0
  558. package/dist/lib/runtime/template/fill.test.d.ts +1 -0
  559. package/dist/lib/runtime/template/fill.test.js +318 -0
  560. package/dist/lib/runtime/template/hygiene.d.ts +89 -0
  561. package/dist/lib/runtime/template/hygiene.js +426 -0
  562. package/dist/lib/runtime/template/hygiene.test.d.ts +1 -0
  563. package/dist/lib/runtime/template/hygiene.test.js +253 -0
  564. package/dist/lib/runtime/template/lift.d.ts +10 -0
  565. package/dist/lib/runtime/template/lift.js +47 -0
  566. package/dist/lib/runtime/template/literals.d.ts +17 -0
  567. package/dist/lib/runtime/template/literals.js +44 -0
  568. package/dist/lib/runtime/template/origin.d.ts +30 -0
  569. package/dist/lib/runtime/template/origin.js +47 -0
  570. package/dist/lib/runtime/threadRepair.d.ts +76 -5
  571. package/dist/lib/runtime/threadRepair.js +153 -31
  572. package/dist/lib/runtime/threadRepair.test.js +177 -3
  573. package/dist/lib/runtime/toolMessageProvider.test.d.ts +1 -0
  574. package/dist/lib/runtime/toolMessageProvider.test.js +69 -0
  575. package/dist/lib/runtime/trace/eventLog.d.ts +1 -0
  576. package/dist/lib/runtime/trace/eventLog.js +2 -0
  577. package/dist/lib/runtime/trace/eventLog.test.js +29 -25
  578. package/dist/lib/runtime/trace/traceReader.test.js +4 -3
  579. package/dist/lib/runtime/trace/traceWriter.test.js +2 -2
  580. package/dist/lib/runtime/turnBoundary.d.ts +81 -0
  581. package/dist/lib/runtime/turnBoundary.js +89 -0
  582. package/dist/lib/runtime/turnBoundary.test.d.ts +1 -0
  583. package/dist/lib/runtime/turnBoundary.test.js +191 -0
  584. package/dist/lib/runtime/typeTest.d.ts +5 -0
  585. package/dist/lib/runtime/typeTest.js +21 -0
  586. package/dist/lib/runtime/typeTest.test.d.ts +1 -0
  587. package/dist/lib/runtime/typeTest.test.js +43 -0
  588. package/dist/lib/runtime/types.d.ts +19 -1
  589. package/dist/lib/runtime/utils.d.ts +7 -0
  590. package/dist/lib/runtime/utils.js +102 -16
  591. package/dist/lib/runtime/utils.test.js +224 -7
  592. package/dist/lib/runtime/validateChain.d.ts +12 -0
  593. package/dist/lib/runtime/validateChain.js +24 -0
  594. package/dist/lib/runtime/validateChain.test.js +78 -0
  595. package/dist/lib/serve/createServeHandler.d.ts +34 -0
  596. package/dist/lib/serve/createServeHandler.js +43 -0
  597. package/dist/lib/serve/createServeHandler.test.d.ts +1 -0
  598. package/dist/lib/serve/createServeHandler.test.js +115 -0
  599. package/dist/lib/serve/http/adapter.d.ts +8 -7
  600. package/dist/lib/serve/http/adapter.js +6 -2
  601. package/dist/lib/serve/http/adapter.test.js +7 -3
  602. package/dist/lib/serve/http/functionFrame.integration.test.js +0 -1
  603. package/dist/lib/serve/metadata.d.ts +22 -0
  604. package/dist/lib/serve/metadata.js +33 -0
  605. package/dist/lib/serve/metadata.test.d.ts +1 -0
  606. package/dist/lib/serve/metadata.test.js +46 -0
  607. package/dist/lib/serve/public.d.ts +8 -0
  608. package/dist/lib/serve/public.js +4 -0
  609. package/dist/lib/serve/public.test.d.ts +1 -0
  610. package/dist/lib/serve/public.test.js +16 -0
  611. package/dist/lib/sourceIsText.test.d.ts +1 -0
  612. package/dist/lib/sourceIsText.test.js +40 -0
  613. package/dist/lib/statelogClient.d.ts +38 -4
  614. package/dist/lib/statelogClient.js +34 -1
  615. package/dist/lib/stdlib/abortable.js +34 -0
  616. package/dist/lib/stdlib/agency.d.ts +27 -0
  617. package/dist/lib/stdlib/agency.js +207 -2
  618. package/dist/lib/stdlib/appleNotes.d.ts +111 -0
  619. package/dist/lib/stdlib/appleNotes.js +314 -0
  620. package/dist/lib/stdlib/assertContained.js +3 -4
  621. package/dist/lib/stdlib/builtins.d.ts +27 -0
  622. package/dist/lib/stdlib/builtins.js +89 -9
  623. package/dist/lib/stdlib/cli.d.ts +149 -0
  624. package/dist/lib/stdlib/cli.js +488 -84
  625. package/dist/lib/stdlib/date.d.ts +15 -12
  626. package/dist/lib/stdlib/date.js +131 -122
  627. package/dist/lib/stdlib/expandPath.d.ts +5 -3
  628. package/dist/lib/stdlib/expandPath.js +5 -3
  629. package/dist/lib/stdlib/fs.js +7 -7
  630. package/dist/lib/stdlib/git.d.ts +4 -0
  631. package/dist/lib/stdlib/git.js +24 -1
  632. package/dist/lib/stdlib/http.js +8 -0
  633. package/dist/lib/stdlib/imessage.js +24 -23
  634. package/dist/lib/stdlib/jsonValue.d.ts +5 -0
  635. package/dist/lib/stdlib/jsonValue.js +12 -0
  636. package/dist/lib/stdlib/layout/table.js +22 -4
  637. package/dist/lib/stdlib/markdown.d.ts +8 -0
  638. package/dist/lib/stdlib/markdown.js +238 -0
  639. package/dist/lib/stdlib/memory.d.ts +2 -2
  640. package/dist/lib/stdlib/memory.js +2 -2
  641. package/dist/lib/stdlib/policy.js +1 -1
  642. package/dist/lib/stdlib/resolveDir.d.ts +9 -8
  643. package/dist/lib/stdlib/resolveDir.js +13 -13
  644. package/dist/lib/stdlib/resolvePath.d.ts +8 -16
  645. package/dist/lib/stdlib/resolvePath.js +10 -52
  646. package/dist/lib/stdlib/safeBash.d.ts +1 -0
  647. package/dist/lib/stdlib/safeBash.js +1 -0
  648. package/dist/lib/stdlib/shell.js +15 -14
  649. package/dist/lib/stdlib/skills.d.ts +22 -16
  650. package/dist/lib/stdlib/skills.js +32 -20
  651. package/dist/lib/stdlib/speech.js +3 -3
  652. package/dist/lib/stdlib/statelog.js +1 -1
  653. package/dist/lib/stdlib/system.d.ts +0 -8
  654. package/dist/lib/stdlib/system.js +2 -12
  655. package/dist/lib/stdlib/template.d.ts +32 -0
  656. package/dist/lib/stdlib/template.js +81 -0
  657. package/dist/lib/stdlib/thread.d.ts +28 -7
  658. package/dist/lib/stdlib/thread.js +122 -27
  659. package/dist/lib/stdlib/wikipedia.js +17 -3
  660. package/dist/lib/symbolTable.d.ts +27 -1
  661. package/dist/lib/symbolTable.importModule.test.d.ts +1 -0
  662. package/dist/lib/symbolTable.importModule.test.js +54 -0
  663. package/dist/lib/symbolTable.js +123 -16
  664. package/dist/lib/symbolTable.test.js +68 -8
  665. package/dist/lib/templates/applescript/notes/accountWalk.d.ts +4 -0
  666. package/dist/lib/templates/applescript/notes/accountWalk.js +18 -0
  667. package/dist/lib/templates/applescript/notes/appendBody.d.ts +6 -0
  668. package/dist/lib/templates/applescript/notes/appendBody.js +15 -0
  669. package/dist/lib/templates/applescript/notes/appendScoped.d.ts +6 -0
  670. package/dist/lib/templates/applescript/notes/appendScoped.js +12 -0
  671. package/dist/lib/templates/applescript/notes/appendUnscoped.d.ts +6 -0
  672. package/dist/lib/templates/applescript/notes/appendUnscoped.js +12 -0
  673. package/dist/lib/templates/applescript/notes/create.d.ts +6 -0
  674. package/dist/lib/templates/applescript/notes/create.js +20 -0
  675. package/dist/lib/templates/applescript/notes/deleteScoped.d.ts +4 -0
  676. package/dist/lib/templates/applescript/notes/deleteScoped.js +13 -0
  677. package/dist/lib/templates/applescript/notes/deleteUnscoped.d.ts +4 -0
  678. package/dist/lib/templates/applescript/notes/deleteUnscoped.js +13 -0
  679. package/dist/lib/templates/applescript/notes/folderExists.d.ts +4 -0
  680. package/dist/lib/templates/applescript/notes/folderExists.js +11 -0
  681. package/dist/lib/templates/applescript/notes/listAll.d.ts +6 -0
  682. package/dist/lib/templates/applescript/notes/listAll.js +16 -0
  683. package/dist/lib/templates/applescript/notes/listFolders.d.ts +4 -0
  684. package/dist/lib/templates/applescript/notes/listFolders.js +20 -0
  685. package/dist/lib/templates/applescript/notes/listInFolder.d.ts +6 -0
  686. package/dist/lib/templates/applescript/notes/listInFolder.js +16 -0
  687. package/dist/lib/templates/applescript/notes/noteRow.d.ts +6 -0
  688. package/dist/lib/templates/applescript/notes/noteRow.js +13 -0
  689. package/dist/lib/templates/applescript/notes/preflight.d.ts +6 -0
  690. package/dist/lib/templates/applescript/notes/preflight.js +16 -0
  691. package/dist/lib/templates/applescript/notes/readScoped.d.ts +4 -0
  692. package/dist/lib/templates/applescript/notes/readScoped.js +13 -0
  693. package/dist/lib/templates/applescript/notes/readUnscoped.d.ts +4 -0
  694. package/dist/lib/templates/applescript/notes/readUnscoped.js +13 -0
  695. package/dist/lib/templates/applescript/notes/searchAll.d.ts +6 -0
  696. package/dist/lib/templates/applescript/notes/searchAll.js +16 -0
  697. package/dist/lib/templates/applescript/notes/searchInFolder.d.ts +6 -0
  698. package/dist/lib/templates/applescript/notes/searchInFolder.js +16 -0
  699. package/dist/lib/templates/applescript/notes/withTimeout.d.ts +7 -0
  700. package/dist/lib/templates/applescript/notes/withTimeout.js +13 -0
  701. package/dist/lib/templates/backends/agency/template.d.ts +2 -1
  702. package/dist/lib/templates/backends/agency/template.js +1 -1
  703. package/dist/lib/templates/backends/typescriptGenerator/blockSetup.d.ts +4 -2
  704. package/dist/lib/templates/backends/typescriptGenerator/blockSetup.js +13 -1
  705. package/dist/lib/templates/backends/typescriptGenerator/finalizeClosure.d.ts +10 -0
  706. package/dist/lib/templates/backends/typescriptGenerator/finalizeClosure.js +14 -0
  707. package/dist/lib/templates/backends/typescriptGenerator/forkBlockSetup.d.ts +2 -2
  708. package/dist/lib/templates/backends/typescriptGenerator/forkBlockSetup.js +3 -0
  709. package/dist/lib/templates/backends/typescriptGenerator/functionCatchFailure.d.ts +2 -1
  710. package/dist/lib/templates/backends/typescriptGenerator/functionCatchFailure.js +6 -1
  711. package/dist/lib/templates/backends/typescriptGenerator/imports.d.ts +1 -1
  712. package/dist/lib/templates/backends/typescriptGenerator/imports.js +12 -10
  713. package/dist/lib/templates/backends/typescriptGenerator/withHandlerWrapper.d.ts +9 -0
  714. package/dist/lib/templates/backends/typescriptGenerator/withHandlerWrapper.js +14 -0
  715. package/dist/lib/templates/runtime/guardTripMessage.d.ts +9 -0
  716. package/dist/lib/templates/runtime/guardTripMessage.js +9 -0
  717. package/dist/lib/typeChecker/anySentinelRetired.test.d.ts +1 -0
  718. package/dist/lib/typeChecker/anySentinelRetired.test.js +53 -0
  719. package/dist/lib/typeChecker/assignability.d.ts +3 -3
  720. package/dist/lib/typeChecker/assignability.js +84 -14
  721. package/dist/lib/typeChecker/assignability.test.js +14 -1
  722. package/dist/lib/typeChecker/builtinGenerics.js +13 -6
  723. package/dist/lib/typeChecker/builtinGenerics.test.js +13 -1
  724. package/dist/lib/typeChecker/builtinVariables.test.d.ts +1 -0
  725. package/dist/lib/typeChecker/builtinVariables.test.js +53 -0
  726. package/dist/lib/typeChecker/builtins.d.ts +6 -0
  727. package/dist/lib/typeChecker/builtins.js +43 -24
  728. package/dist/lib/typeChecker/callbackCallEffects.test.js +4 -15
  729. package/dist/lib/typeChecker/checker.d.ts +1 -1
  730. package/dist/lib/typeChecker/checker.js +91 -28
  731. package/dist/lib/typeChecker/codeLiteral.test.d.ts +1 -0
  732. package/dist/lib/typeChecker/codeLiteral.test.js +160 -0
  733. package/dist/lib/typeChecker/conflictingMarkers.js +2 -1
  734. package/dist/lib/typeChecker/crossModuleEffectDiagnostics.test.d.ts +1 -0
  735. package/dist/lib/typeChecker/crossModuleEffectDiagnostics.test.js +80 -0
  736. package/dist/lib/typeChecker/definiteReturns.js +7 -0
  737. package/dist/lib/typeChecker/diagnosticExplanations.js +138 -2
  738. package/dist/lib/typeChecker/diagnostics.d.ts +141 -1
  739. package/dist/lib/typeChecker/diagnostics.js +138 -1
  740. package/dist/lib/typeChecker/effectPayloadCheck.js +2 -1
  741. package/dist/lib/typeChecker/effectSets.js +2 -1
  742. package/dist/lib/typeChecker/finalize.test.d.ts +1 -0
  743. package/dist/lib/typeChecker/finalize.test.js +312 -0
  744. package/dist/lib/typeChecker/finalizeBinder.d.ts +21 -0
  745. package/dist/lib/typeChecker/finalizeBinder.js +70 -0
  746. package/dist/lib/typeChecker/finalizeBinder.test.d.ts +1 -0
  747. package/dist/lib/typeChecker/finalizeBinder.test.js +132 -0
  748. package/dist/lib/typeChecker/finalizeChecks.d.ts +16 -0
  749. package/dist/lib/typeChecker/finalizeChecks.js +161 -0
  750. package/dist/lib/typeChecker/fixtureTypeCheck.integration.test.js +3 -0
  751. package/dist/lib/typeChecker/flow.js +14 -12
  752. package/dist/lib/typeChecker/flow.test.js +12 -11
  753. package/dist/lib/typeChecker/flowBuilder.js +34 -2
  754. package/dist/lib/typeChecker/forkRaceReturnTypes.test.d.ts +1 -0
  755. package/dist/lib/typeChecker/forkRaceReturnTypes.test.js +260 -0
  756. package/dist/lib/typeChecker/functionTypeRaises.js +2 -1
  757. package/dist/lib/typeChecker/functionValueEffects.js +2 -1
  758. package/dist/lib/typeChecker/guardConstruct.test.d.ts +1 -0
  759. package/dist/lib/typeChecker/guardConstruct.test.js +143 -0
  760. package/dist/lib/typeChecker/handlerParamTyping.d.ts +1 -1
  761. package/dist/lib/typeChecker/handlerParamTyping.js +1 -1
  762. package/dist/lib/typeChecker/holes.test.d.ts +1 -0
  763. package/dist/lib/typeChecker/holes.test.js +75 -0
  764. package/dist/lib/typeChecker/index.d.ts +1 -1
  765. package/dist/lib/typeChecker/index.js +64 -12
  766. package/dist/lib/typeChecker/inference.d.ts +1 -1
  767. package/dist/lib/typeChecker/inference.js +13 -15
  768. package/dist/lib/typeChecker/interruptAnalysis.d.ts +0 -17
  769. package/dist/lib/typeChecker/interruptAnalysis.js +47 -122
  770. package/dist/lib/typeChecker/matchExhaustiveness.js +64 -2
  771. package/dist/lib/typeChecker/matchExhaustiveness.test.js +71 -0
  772. package/dist/lib/typeChecker/matchExprTypes.js +7 -8
  773. package/dist/lib/typeChecker/missingImportDiagnostic.d.ts +12 -0
  774. package/dist/lib/typeChecker/missingImportDiagnostic.js +69 -0
  775. package/dist/lib/typeChecker/missingImportDiagnostic.test.d.ts +1 -0
  776. package/dist/lib/typeChecker/missingImportDiagnostic.test.js +183 -0
  777. package/dist/lib/typeChecker/narrowing.d.ts +3 -0
  778. package/dist/lib/typeChecker/narrowing.js +25 -2
  779. package/dist/lib/typeChecker/raisesDiagnostic.d.ts +2 -2
  780. package/dist/lib/typeChecker/raisesDiagnostic.js +2 -2
  781. package/dist/lib/typeChecker/reservedNameDeclaration.test.js +21 -1
  782. package/dist/lib/typeChecker/resolveCall.js +26 -21
  783. package/dist/lib/typeChecker/resolveType.test.js +92 -1
  784. package/dist/lib/typeChecker/resolveVariable.d.ts +4 -2
  785. package/dist/lib/typeChecker/resolveVariable.js +7 -2
  786. package/dist/lib/typeChecker/saveDraft.test.d.ts +1 -0
  787. package/dist/lib/typeChecker/saveDraft.test.js +139 -0
  788. package/dist/lib/typeChecker/scope.d.ts +5 -1
  789. package/dist/lib/typeChecker/scope.js +6 -0
  790. package/dist/lib/typeChecker/scope.test.js +9 -8
  791. package/dist/lib/typeChecker/scopes.js +51 -14
  792. package/dist/lib/typeChecker/spliceDiagnostics.test.d.ts +1 -0
  793. package/dist/lib/typeChecker/spliceDiagnostics.test.js +67 -0
  794. package/dist/lib/typeChecker/strictMemberAccess.test.js +62 -0
  795. package/dist/lib/typeChecker/synthesizer.d.ts +5 -2
  796. package/dist/lib/typeChecker/synthesizer.js +293 -72
  797. package/dist/lib/typeChecker/templateHoles.d.ts +17 -0
  798. package/dist/lib/typeChecker/templateHoles.js +30 -0
  799. package/dist/lib/typeChecker/testUtils.d.ts +2 -1
  800. package/dist/lib/typeChecker/testUtils.js +3 -3
  801. package/dist/lib/typeChecker/toolArgArrayType.test.d.ts +1 -0
  802. package/dist/lib/typeChecker/toolArgArrayType.test.js +128 -0
  803. package/dist/lib/typeChecker/typeCases.d.ts +1 -1
  804. package/dist/lib/typeChecker/typeCases.js +3 -2
  805. package/dist/lib/typeChecker/typeCases.test.js +2 -1
  806. package/dist/lib/typeChecker/typePatterns.test.d.ts +1 -0
  807. package/dist/lib/typeChecker/typePatterns.test.js +238 -0
  808. package/dist/lib/typeChecker/types.d.ts +10 -10
  809. package/dist/lib/typeChecker/undefinedFunctionDiagnostic.js +4 -0
  810. package/dist/lib/typeChecker/undefinedFunctionDiagnostic.test.js +43 -0
  811. package/dist/lib/typeChecker/utils.d.ts +7 -2
  812. package/dist/lib/typeChecker/utils.js +6 -4
  813. package/dist/lib/types/base.d.ts +8 -0
  814. package/dist/lib/types/blockArgument.d.ts +8 -1
  815. package/dist/lib/types/codeLiteral.d.ts +13 -0
  816. package/dist/lib/types/codeLiteral.js +1 -0
  817. package/dist/lib/types/comprehension.d.ts +55 -0
  818. package/dist/lib/types/comprehension.js +32 -0
  819. package/dist/lib/types/finalizeBlock.d.ts +19 -0
  820. package/dist/lib/types/finalizeBlock.js +1 -0
  821. package/dist/lib/types/function.d.ts +15 -1
  822. package/dist/lib/types/graphNode.d.ts +4 -1
  823. package/dist/lib/types/guardBlock.d.ts +25 -0
  824. package/dist/lib/types/guardBlock.js +1 -0
  825. package/dist/lib/types/hole.d.ts +26 -0
  826. package/dist/lib/types/hole.js +18 -0
  827. package/dist/lib/types/importStatement.d.ts +4 -1
  828. package/dist/lib/types/importStatement.js +9 -2
  829. package/dist/lib/types/markDestructiveRan.d.ts +8 -0
  830. package/dist/lib/types/markDestructiveRan.js +1 -0
  831. package/dist/lib/types/parallelBlock.d.ts +5 -0
  832. package/dist/lib/types/pattern.d.ts +14 -4
  833. package/dist/lib/types/splice.d.ts +20 -0
  834. package/dist/lib/types/splice.js +1 -0
  835. package/dist/lib/types/typeHints.d.ts +11 -0
  836. package/dist/lib/types.d.ts +21 -3
  837. package/dist/lib/types.js +12 -0
  838. package/dist/lib/utils/agencyTempDir.d.ts +19 -0
  839. package/dist/lib/utils/agencyTempDir.js +26 -0
  840. package/dist/lib/utils/bodySlots.d.ts +17 -1
  841. package/dist/lib/utils/bodySlots.js +58 -2
  842. package/dist/lib/utils/bodySlots.test.d.ts +1 -0
  843. package/dist/lib/utils/bodySlots.test.js +33 -0
  844. package/dist/lib/utils/docStringText.d.ts +7 -0
  845. package/dist/lib/utils/docStringText.js +7 -0
  846. package/dist/lib/utils/expressionSlots.d.ts +91 -0
  847. package/dist/lib/utils/expressionSlots.js +322 -0
  848. package/dist/lib/utils/expressionSlots.test.d.ts +1 -0
  849. package/dist/lib/utils/expressionSlots.test.js +505 -0
  850. package/dist/lib/utils/holes.d.ts +41 -0
  851. package/dist/lib/utils/holes.js +68 -0
  852. package/dist/lib/utils/identifierSlots.d.ts +71 -0
  853. package/dist/lib/utils/identifierSlots.js +173 -0
  854. package/dist/lib/utils/identifierSlots.test.d.ts +1 -0
  855. package/dist/lib/utils/identifierSlots.test.js +148 -0
  856. package/dist/lib/utils/iteration.d.ts +37 -0
  857. package/dist/lib/utils/iteration.js +9 -0
  858. package/dist/lib/utils/iteration.test.d.ts +1 -0
  859. package/dist/lib/utils/iteration.test.js +26 -0
  860. package/dist/lib/utils/moduleDoc.d.ts +18 -0
  861. package/dist/lib/utils/moduleDoc.js +56 -0
  862. package/dist/lib/utils/node.js +104 -87
  863. package/dist/scripts/agency.js +147 -24
  864. package/dist/scripts/agency.test.js +30 -1
  865. package/package.json +11 -3
  866. package/stdlib/agency/eval.js +70 -19
  867. package/stdlib/agency/local.agency +1 -0
  868. package/stdlib/agency/local.js +68 -22
  869. package/stdlib/agency.agency +154 -298
  870. package/stdlib/agency.js +751 -1375
  871. package/stdlib/agent.agency +2 -296
  872. package/stdlib/agent.js +30 -1167
  873. package/stdlib/agents/agency/coding.agency +313 -0
  874. package/stdlib/agents/agency/coding.js +2345 -0
  875. package/stdlib/agents/agency/expert.agency +98 -0
  876. package/stdlib/agents/agency/expert.js +967 -0
  877. package/stdlib/agents/agency/researcher.agency +109 -0
  878. package/stdlib/agents/agency/researcher.js +976 -0
  879. package/stdlib/agents/agency/review.agency +143 -0
  880. package/stdlib/agents/agency/review.js +1602 -0
  881. package/stdlib/agents/agency/verifier.agency +131 -0
  882. package/stdlib/agents/agency/verifier.js +1241 -0
  883. package/stdlib/agents/coding.agency +148 -0
  884. package/stdlib/agents/coding.js +1099 -0
  885. package/stdlib/agents/data.agency +150 -0
  886. package/stdlib/agents/data.js +1017 -0
  887. package/stdlib/agents/expert.agency +111 -0
  888. package/stdlib/agents/expert.js +970 -0
  889. package/stdlib/agents/explorer.agency +199 -0
  890. package/stdlib/agents/explorer.js +1098 -0
  891. package/stdlib/agents/lib/expertGuidance.agency +40 -0
  892. package/stdlib/agents/lib/expertGuidance.js +644 -0
  893. package/stdlib/agents/lib/feedback.agency +89 -0
  894. package/stdlib/agents/lib/feedback.js +1216 -0
  895. package/stdlib/agents/lib/search.agency +65 -0
  896. package/stdlib/agents/lib/search.js +794 -0
  897. package/stdlib/agents/lib/shared.agency +59 -0
  898. package/stdlib/agents/lib/shared.js +606 -0
  899. package/stdlib/agents/lib/toolkits.agency +198 -0
  900. package/stdlib/agents/lib/toolkits.js +1720 -0
  901. package/stdlib/agents/oracle.agency +172 -0
  902. package/stdlib/agents/oracle.js +1081 -0
  903. package/stdlib/agents/planner.agency +284 -0
  904. package/stdlib/agents/planner.js +3103 -0
  905. package/stdlib/agents/researcher.agency +169 -0
  906. package/stdlib/agents/researcher.js +1380 -0
  907. package/stdlib/agents/review.agency +117 -0
  908. package/stdlib/agents/review.js +1040 -0
  909. package/stdlib/agents/skills/coding/gh-auth.md +65 -0
  910. package/stdlib/agents/skills/coding/gh-pr-and-issues.md +150 -0
  911. package/stdlib/agents/skills/coding/gh-repos-and-releases.md +87 -0
  912. package/stdlib/agents/skills/data/finding-identifiers.md +26 -0
  913. package/stdlib/agents/verifier.agency +155 -0
  914. package/stdlib/agents/verifier.js +1247 -0
  915. package/stdlib/args.js +21 -7
  916. package/stdlib/array.agency +1 -0
  917. package/stdlib/array.js +37 -19
  918. package/stdlib/auth/keyring.agency +8 -4
  919. package/stdlib/auth/keyring.js +32 -11
  920. package/stdlib/auth/oauth.agency +5 -2
  921. package/stdlib/auth/oauth.js +30 -11
  922. package/stdlib/calendar.agency +27 -21
  923. package/stdlib/calendar.js +38 -13
  924. package/stdlib/capabilities.agency +9 -0
  925. package/stdlib/capabilities.js +23 -6
  926. package/stdlib/clipboard.agency +4 -2
  927. package/stdlib/clipboard.js +31 -9
  928. package/stdlib/concurrency.agency +52 -0
  929. package/stdlib/concurrency.js +311 -8
  930. package/stdlib/data/finance/dbnomics.js +141 -38
  931. package/stdlib/data/finance/edgar.agency +1 -0
  932. package/stdlib/data/finance/edgar.js +221 -56
  933. package/stdlib/data/finance/fred.agency +1 -0
  934. package/stdlib/data/finance/fred.js +372 -108
  935. package/stdlib/data/finance/gdelt.js +136 -41
  936. package/stdlib/data/people/littlesis.agency +2 -2
  937. package/stdlib/data/people/littlesis.js +517 -159
  938. package/stdlib/data/tech/hackernews.js +661 -200
  939. package/stdlib/data/tech/yc.js +489 -145
  940. package/stdlib/data/usaspending.agency +1 -0
  941. package/stdlib/data/usaspending.js +369 -131
  942. package/stdlib/data/wikidata.js +492 -152
  943. package/stdlib/date.agency +136 -87
  944. package/stdlib/date.js +735 -427
  945. package/stdlib/docs/agent/index.md +105 -0
  946. package/stdlib/docs/agent/mcp.md +134 -0
  947. package/stdlib/docs/agent/memory.md +58 -0
  948. package/stdlib/docs/agent/models.md +85 -0
  949. package/stdlib/docs/agent/project-context.md +28 -0
  950. package/stdlib/docs/cli/agent.md +7 -0
  951. package/stdlib/docs/cli/editor-integration.md +23 -0
  952. package/stdlib/docs/cli/format.md +2 -0
  953. package/stdlib/docs/cli/lint.md +42 -0
  954. package/stdlib/docs/cli/run.md +2 -0
  955. package/stdlib/docs/diagnostics/effects.md +12 -10
  956. package/stdlib/docs/diagnostics/index.md +43 -3
  957. package/stdlib/docs/diagnostics/lint.md +48 -0
  958. package/stdlib/docs/diagnostics/match.md +10 -0
  959. package/stdlib/docs/diagnostics/names.md +30 -0
  960. package/stdlib/docs/diagnostics/templates.md +174 -0
  961. package/stdlib/docs/diagnostics/tools.md +93 -0
  962. package/stdlib/docs/diagnostics/types-aliases.md +10 -0
  963. package/stdlib/docs/guide/basic-syntax.md +27 -2
  964. package/stdlib/docs/guide/builtins.md +13 -0
  965. package/stdlib/docs/guide/comprehensions.md +111 -0
  966. package/stdlib/docs/guide/concurrency.md +4 -2
  967. package/stdlib/docs/guide/guards.md +141 -44
  968. package/stdlib/docs/guide/handlers.md +32 -2
  969. package/stdlib/docs/guide/llm-part-2.md +20 -3
  970. package/stdlib/docs/guide/llm.md +5 -3
  971. package/stdlib/docs/guide/match-expressions.md +208 -0
  972. package/stdlib/docs/guide/memory.md +3 -3
  973. package/stdlib/docs/guide/partial-results.md +175 -0
  974. package/stdlib/docs/guide/pattern-matching.md +227 -194
  975. package/stdlib/docs/guide/splices.md +94 -0
  976. package/stdlib/docs/guide/state-isolation.md +10 -4
  977. package/stdlib/docs/guide/template-agency.md +381 -0
  978. package/stdlib/docs/guide/ts-helpers.md +28 -0
  979. package/stdlib/docs/guide/type-validation.md +19 -0
  980. package/stdlib/docs/guide/types.md +18 -2
  981. package/stdlib/docs/stdlib/agency/eval.md +513 -0
  982. package/stdlib/docs/stdlib/agency/local.md +319 -0
  983. package/stdlib/docs/stdlib/agency.md +972 -0
  984. package/stdlib/docs/stdlib/agent.md +121 -0
  985. package/stdlib/docs/stdlib/agents/agency/coding.md +118 -0
  986. package/stdlib/docs/stdlib/agents/agency/expert.md +78 -0
  987. package/stdlib/docs/stdlib/agents/agency/researcher.md +75 -0
  988. package/stdlib/docs/stdlib/agents/agency/review.md +96 -0
  989. package/stdlib/docs/stdlib/agents/agency/verifier.md +75 -0
  990. package/stdlib/docs/stdlib/agents/coding.md +81 -0
  991. package/stdlib/docs/stdlib/agents/data.md +75 -0
  992. package/stdlib/docs/stdlib/agents/expert.md +80 -0
  993. package/stdlib/docs/stdlib/agents/explorer.md +81 -0
  994. package/stdlib/docs/stdlib/agents/lib/expertGuidance.md +87 -0
  995. package/stdlib/docs/stdlib/agents/lib/feedback.md +127 -0
  996. package/stdlib/docs/stdlib/agents/lib/search.md +64 -0
  997. package/stdlib/docs/stdlib/agents/lib/shared.md +83 -0
  998. package/stdlib/docs/stdlib/agents/lib/toolkits.md +192 -0
  999. package/stdlib/docs/stdlib/agents/oracle.md +83 -0
  1000. package/stdlib/docs/stdlib/agents/planner.md +168 -0
  1001. package/stdlib/docs/stdlib/agents/researcher.md +77 -0
  1002. package/stdlib/docs/stdlib/agents/review.md +77 -0
  1003. package/stdlib/docs/stdlib/agents/verifier.md +77 -0
  1004. package/stdlib/docs/stdlib/args.md +235 -0
  1005. package/stdlib/docs/stdlib/array.md +11 -0
  1006. package/stdlib/docs/stdlib/auth/keyring.md +149 -0
  1007. package/stdlib/docs/stdlib/auth/oauth.md +183 -0
  1008. package/stdlib/docs/stdlib/calendar.md +279 -0
  1009. package/stdlib/docs/stdlib/capabilities.md +193 -0
  1010. package/stdlib/docs/stdlib/clipboard.md +71 -0
  1011. package/stdlib/docs/stdlib/concurrency.md +94 -0
  1012. package/stdlib/docs/stdlib/data/finance/dbnomics.md +112 -0
  1013. package/stdlib/docs/stdlib/data/finance/edgar.md +133 -0
  1014. package/stdlib/docs/stdlib/data/finance/fred.md +224 -0
  1015. package/stdlib/docs/stdlib/data/finance/gdelt.md +99 -0
  1016. package/stdlib/docs/stdlib/data/people/littlesis.md +219 -0
  1017. package/stdlib/docs/stdlib/data/tech/hackernews.md +219 -0
  1018. package/stdlib/docs/stdlib/data/tech/yc.md +206 -0
  1019. package/stdlib/docs/stdlib/data/usaspending.md +174 -0
  1020. package/stdlib/docs/stdlib/data/wikidata.md +168 -0
  1021. package/stdlib/docs/stdlib/date.md +433 -0
  1022. package/stdlib/docs/stdlib/fs.md +283 -0
  1023. package/stdlib/docs/stdlib/git.md +916 -0
  1024. package/stdlib/docs/stdlib/http.md +207 -0
  1025. package/stdlib/docs/stdlib/image.md +68 -0
  1026. package/stdlib/docs/stdlib/index.md +746 -0
  1027. package/stdlib/docs/stdlib/llm.md +260 -0
  1028. package/stdlib/docs/stdlib/markdown.md +605 -0
  1029. package/stdlib/docs/stdlib/math.md +109 -0
  1030. package/stdlib/docs/stdlib/mcp.md +128 -0
  1031. package/stdlib/docs/stdlib/memory.md +310 -0
  1032. package/stdlib/docs/stdlib/messaging/email.md +226 -0
  1033. package/stdlib/docs/stdlib/messaging/imessage.md +69 -0
  1034. package/stdlib/docs/stdlib/messaging/sms.md +79 -0
  1035. package/stdlib/docs/stdlib/notes/apple.md +428 -0
  1036. package/stdlib/docs/stdlib/object.md +195 -0
  1037. package/stdlib/docs/stdlib/path.md +165 -0
  1038. package/stdlib/docs/stdlib/policy.md +727 -0
  1039. package/stdlib/docs/stdlib/safeBash/actions.md +236 -0
  1040. package/stdlib/docs/stdlib/safeBash.md +398 -0
  1041. package/stdlib/docs/stdlib/shell.md +405 -0
  1042. package/stdlib/docs/stdlib/skills.md +239 -0
  1043. package/stdlib/docs/stdlib/speech.md +160 -0
  1044. package/stdlib/docs/stdlib/statelog.md +249 -0
  1045. package/stdlib/docs/stdlib/strategy.md +195 -0
  1046. package/stdlib/docs/stdlib/supervise.md +87 -0
  1047. package/stdlib/docs/stdlib/syntax.md +295 -0
  1048. package/stdlib/docs/stdlib/system.md +293 -0
  1049. package/stdlib/docs/stdlib/tag.md +150 -0
  1050. package/stdlib/docs/stdlib/thread.md +430 -0
  1051. package/stdlib/docs/stdlib/ui/chart.md +147 -0
  1052. package/stdlib/docs/stdlib/ui/cli.md +154 -0
  1053. package/stdlib/docs/stdlib/ui/layout.md +408 -0
  1054. package/stdlib/docs/stdlib/ui/table.md +194 -0
  1055. package/stdlib/docs/stdlib/ui.md +883 -0
  1056. package/stdlib/docs/stdlib/validation.md +613 -0
  1057. package/stdlib/docs/stdlib/weather.md +109 -0
  1058. package/stdlib/docs/stdlib/web/browser.md +80 -0
  1059. package/stdlib/docs/stdlib/web/search.md +132 -0
  1060. package/stdlib/docs/stdlib/wikipedia.md +123 -0
  1061. package/stdlib/fs.agency +25 -12
  1062. package/stdlib/fs.js +98 -57
  1063. package/stdlib/git.agency +110 -24
  1064. package/stdlib/git.js +807 -164
  1065. package/stdlib/http.js +25 -9
  1066. package/stdlib/image.agency +3 -1
  1067. package/stdlib/image.js +22 -8
  1068. package/stdlib/index.agency +114 -7
  1069. package/stdlib/index.js +1206 -208
  1070. package/stdlib/llm.agency +1 -0
  1071. package/stdlib/llm.js +63 -16
  1072. package/stdlib/markdown.agency +27 -0
  1073. package/stdlib/markdown.js +157 -12
  1074. package/stdlib/math.agency +4 -0
  1075. package/stdlib/math.js +34 -16
  1076. package/stdlib/mcp.agency +6 -6
  1077. package/stdlib/mcp.js +35 -16
  1078. package/stdlib/memory.agency +15 -12
  1079. package/stdlib/memory.js +152 -49
  1080. package/stdlib/messaging/email.agency +54 -47
  1081. package/stdlib/messaging/email.js +32 -10
  1082. package/stdlib/messaging/imessage.agency +7 -5
  1083. package/stdlib/messaging/imessage.js +24 -8
  1084. package/stdlib/messaging/sms.agency +10 -8
  1085. package/stdlib/messaging/sms.js +24 -8
  1086. package/stdlib/notes/apple.agency +361 -0
  1087. package/stdlib/notes/apple.js +2060 -0
  1088. package/stdlib/object.js +181 -55
  1089. package/stdlib/path.js +33 -13
  1090. package/stdlib/policy.agency +43 -11
  1091. package/stdlib/policy.js +341 -90
  1092. package/stdlib/safeBash/actions.agency +166 -0
  1093. package/stdlib/safeBash/actions.js +805 -0
  1094. package/stdlib/safeBash.agency +975 -0
  1095. package/stdlib/safeBash.js +6955 -0
  1096. package/stdlib/shell.agency +45 -13
  1097. package/stdlib/shell.js +78 -41
  1098. package/stdlib/skills.agency +116 -37
  1099. package/stdlib/skills.js +878 -147
  1100. package/stdlib/speech.js +30 -9
  1101. package/stdlib/statelog.agency +1 -0
  1102. package/stdlib/statelog.js +43 -14
  1103. package/stdlib/strategy.agency +40 -0
  1104. package/stdlib/strategy.js +325 -20
  1105. package/stdlib/supervise.agency +116 -0
  1106. package/stdlib/supervise.js +501 -0
  1107. package/stdlib/syntax.js +27 -10
  1108. package/stdlib/system.agency +0 -21
  1109. package/stdlib/system.js +52 -124
  1110. package/stdlib/tag.js +31 -12
  1111. package/stdlib/thread.agency +59 -70
  1112. package/stdlib/thread.js +498 -145
  1113. package/stdlib/ui/chart.agency +1 -0
  1114. package/stdlib/ui/chart.js +69 -29
  1115. package/stdlib/ui/cli.agency +35 -0
  1116. package/stdlib/ui/cli.js +270 -17
  1117. package/stdlib/ui/layout.js +229 -93
  1118. package/stdlib/ui/table.agency +1 -0
  1119. package/stdlib/ui/table.js +105 -53
  1120. package/stdlib/ui.agency +1 -0
  1121. package/stdlib/ui.js +997 -309
  1122. package/stdlib/validation.agency +38 -0
  1123. package/stdlib/validation.js +317 -18
  1124. package/stdlib/weather.agency +2 -0
  1125. package/stdlib/weather.js +28 -12
  1126. package/stdlib/web/browser.js +21 -7
  1127. package/stdlib/web/search.js +23 -8
  1128. package/stdlib/wikipedia.js +25 -9
  1129. package/dist/lib/agents/agency-agent/lib/defaultPolicy.js +0 -1066
  1130. package/dist/lib/agents/agency-agent/prompts/system.md +0 -4
  1131. package/dist/lib/agents/agency-agent/subagents/verify.agency +0 -112
  1132. package/dist/lib/typeChecker/handlerBodyInterrupts.test.js +0 -171
  1133. /package/dist/lib/{typeChecker/handlerBodyInterrupts.test.d.ts → analysis/effectPropagation.test.d.ts} +0 -0
@@ -1,17 +1,10 @@
1
- import { getVersion } from "std::agency"
2
- import {
3
- printLocalCatalog,
4
- localModelsSupported,
5
- listModelNames,
6
- } from "std::agency/local"
1
+ import { localModelsSupported, listModelNames } from "std::agency/local"
7
2
  import { parseArgs } from "std::args"
8
3
  import { map } from "std::array"
9
4
  import { today } from "std::date"
10
5
  import { generateImage } from "std::image"
11
- import { applyAgentCwd, setAgentCwd } from "std::index"
12
6
  import { listHostedModels, hostedModelInfo, setLlmOptions } from "std::llm"
13
7
  import { setMemoryId, disableMemory } from "std::memory"
14
- import { keys } from "std::object"
15
8
  import { basename, dirname } from "std::path"
16
9
  import {
17
10
  ScopedRuleFields,
@@ -24,7 +17,6 @@ import {
24
17
  builtinPolicyNames,
25
18
  BUILTIN_POLICIES,
26
19
  } from "std::policy"
27
- import { loadMcpToolsWithStatus, mergeMcpServers, isMcpAvailable, readProjectMcpConfig } from "std::mcp"
28
20
  import { exists } from "std::shell"
29
21
  import { commandsDir, expandSlash } from "std::skills"
30
22
  import { highlight } from "std::syntax"
@@ -45,19 +37,42 @@ import {
45
37
  clearScreen,
46
38
  clearHistory,
47
39
  } from "std::ui/cli"
48
- import { box, render } from "std::ui/layout"
49
40
 
50
- import { figs, title } from "./images/images.agency"
41
+ import { parseAgentArgs } from "./lib/args.agency"
51
42
  import { detectAttachments, modalityFilter } from "./lib/attachments.agency"
43
+ import { showCapabilities, editCapabilities } from "./lib/capabilitiesUi.agency"
44
+ import { mergedPalette, projectCommands } from "./lib/commandPalette.agency"
52
45
  import {
53
46
  POLICY_PATH,
54
47
  SESSION_POLICY_PATH,
55
48
  HISTORY_PATH,
56
49
  ALWAYS_FIELDS,
57
50
  } from "./lib/config.agency"
51
+ import {
52
+ runTurn,
53
+ setGroundingContext,
54
+ loadAgentsMd,
55
+ maybeEnableMemory,
56
+ checkMainPrompts,
57
+ START_AGENTS,
58
+ } from "./lib/coordinator.agency"
59
+ import { getHeader } from "./lib/header.agency"
60
+ import { generateImageFile } from "./lib/images.agency"
61
+ import { getMcpTools, maybeLoadMcp, mcpSlashCommand } from "./lib/mcp.agency"
58
62
  import { filterHostedModels, ModelFilters } from "./lib/modelFilters.agency"
59
- import { parseModelFlag, parseModelSpec, knownProviders, embeddingSpecHasProvider, missingProviderEnvVar, Resolved } from "./lib/models.agency"
60
- import { SLOTS } from "./lib/slots.agency"
63
+ import {
64
+ parseModelFlag,
65
+ parseModelSpec,
66
+ knownProviders,
67
+ missingProviderEnvVar,
68
+ Resolved,
69
+ } from "./lib/models.agency"
70
+ import {
71
+ givePolicyChoice,
72
+ printPolicyHelp,
73
+ getPolicyForAgent,
74
+ } from "./lib/policy.agency"
75
+ import { startInteractive, renderAgentResponse } from "./lib/repl.agency"
61
76
  import {
62
77
  buildLayers,
63
78
  resolveAll,
@@ -72,21 +87,30 @@ import {
72
87
  availableBackendItems,
73
88
  } from "./lib/search.agency"
74
89
  import {
75
- CAPABILITY_FIELDS,
76
- CapabilityPatch,
77
- mergeCapabilityOverride,
78
- removeCapabilityField,
79
- providerLacksEmbeddings,
80
- } from "./lib/capabilities.agency"
90
+ Session,
91
+ switchModel,
92
+ reactToSlotChange,
93
+ modelChoiceItems,
94
+ parseModelsFilters,
95
+ markMemoryEmbeddingsPinned,
96
+ pickModelsForAgent,
97
+ } from "./lib/session.agency"
81
98
  import {
82
- Settings,
83
99
  getCapabilitySettings,
84
100
  getModelSettings,
85
- getMcpServers,
86
101
  loadSettings,
87
102
  saveSettings,
88
103
  } from "./lib/settings.agency"
89
- import { truncate, formatArgs, formatToolResponse } from "./lib/utils.agency"
104
+ import { SLOTS } from "./lib/slots.agency"
105
+ import { setDebug, setVerbose, setInteractive } from "./lib/trace.agency"
106
+ import {
107
+ truncate,
108
+ formatArgs,
109
+ formatToolResponse,
110
+ retryReasonLabel,
111
+ formatTurnFailure,
112
+ } from "./lib/utils.agency"
113
+ import { renderLLMCallResponse } from "./lib/utils/renderLLMCallResponse.agency"
90
114
  import {
91
115
  configureModels,
92
116
  configureLocalModel,
@@ -106,7 +130,6 @@ import {
106
130
  overrideFromResolved,
107
131
  embeddingsOverride,
108
132
  providerEnvMissing,
109
- demoteProvider,
110
133
  } from "./shared.agency"
111
134
  import { codeAgent, setCodeOneShot } from "./subagents/code.agency"
112
135
  import { explorerAgent } from "./subagents/explorer.agency"
@@ -123,1527 +146,27 @@ import { reviewAgent } from "./subagents/review.agency"
123
146
  //
124
147
  //import { clearMessages, pushMessage, repl } from "std::ui"
125
148
 
126
- /*
127
- * Agency Agent helps users create and modify Agency code.
128
- *
129
- * Multi-thread architecture: the agent splits work across two
130
- * specialists, each with its own thread / system prompt / tool set:
131
- * - `code.agency` — writes, edits, typechecks, runs code
132
- * - `research.agency` — looks up docs, fetches URLs, browses web
133
- *
134
- * The standard library does the heavy lifting:
135
- * - `std::agent.route` runs the per-turn hop loop, owns the
136
- * handoff signal, and force-answers when the hop limit is hit.
137
- * - `std::policy.cliPolicyHandler` provides the interactive
138
- * approve/reject/always menu and persists "always" decisions to
139
- * `~/.agency-agent/policy.json`.
140
- * - `std::ui.repl` provides the terminal UI: a bordered scroll
141
- * output area, status line (cost + label), command palette
142
- * opened with `/`, and history-aware input bar.
143
- *
144
- * This file's responsibilities collapse to:
145
- * 1. Per-turn callback (`_runTurn`) wiring the user message into
146
- * `mainAgent` and printing the reply into the scroll output.
147
- * 2. Per-effect ALWAYS_FIELDS map for the policy handler's
148
- * "approve-always-here" option.
149
- * 3. Wire the two specialists into one `RouterConfig`.
150
- *
151
- * Other features:
152
- * - Doc-as-skills: bundles `docs/site/guide` etc. (copied to
153
- * `dist/lib/agents/docs/` at build time, see makefile) and
154
- * exposes each Markdown file as a skill the research agent can
155
- * read on demand.
156
- * - Typechecking: the code agent can call `typecheck` on any
157
- * source it generates to verify the code before showing it.
158
- * - File I/O tools: `read`, `write`, `edit` for actually creating /
159
- * editing `.agency` files.
160
- */
161
-
162
- // Verbose tool-call tracing. Enabled either by `AGENT_DEBUG=1` (legacy)
163
- // or by passing `--debug` / `--verbose` on the command line (set in main()).
164
- let AGENT_DEBUG: boolean = env("AGENT_DEBUG") == "1"
165
- let VERBOSE: boolean = false
166
-
167
- // Whether the agent is running in interactive (TTY) mode. Set in main()
168
- // before any tool calls happen, so the callbacks below can suppress
169
- // scroll-output writes when stdout is destined for a Unix pipe.
170
- let _isInteractive: boolean = true
171
-
172
- // The `--policy` argument (a built-in name or a policy-file path), or ""
173
- // when the flag is absent. Set in main() before `setupSession` runs;
174
- // consumed there to override the saved policy for this run only.
149
+ // The `--policy` argument (a built-in name or a policy-file path), or "" when
150
+ // absent. CLI-owned: main() sets it, setupSession() reads it.
175
151
  let _policyArg: string = ""
176
152
 
177
- // Live tool-call tracing. Always shown in the interactive REPL; in
178
- // one-shot mode it's suppressed so piped output is just the reply,
179
- // unless the user opts in with `--verbose` / `--debug` (AGENT_DEBUG).
180
- def _showTraces(): boolean {
181
- return _isInteractive || VERBOSE || AGENT_DEBUG
182
- }
183
-
184
- callback("onToolCallStart") as data {
185
- if (_showTraces()) {
186
- pushMessage(color.yellow("⏺ ${data.toolName}(${formatArgs(data.args)})"))
187
- }
188
- }
189
-
190
- callback("onToolCallEnd") as data {
191
- if (_showTraces()) {
192
- if (data.result is success(_result)) {
193
- pushMessage(color.dim.green("${formatToolResponse(_result)}"))
194
- } else if (data.result is failure(_error)) {
195
- pushMessage(color.red(" ⎿ Error: ${_error}"))
196
- } else {
197
- pushMessage(color.dim("${formatToolResponse(data.result)}"))
198
- }
199
- }
200
- }
201
-
202
- callback("onLLMCallStart") as data {
203
- if (AGENT_DEBUG || VERBOSE) {
204
- pushMessage(color.green.dim("💬 [${data.model}] ${data.prompt}"))
205
- }
206
- }
207
-
208
- callback("onLLMCallEnd") as data {
209
- if (AGENT_DEBUG || VERBOSE) {
210
- pushMessage(
211
- color.green.dim("💬 [${data.model}] ${renderLLMCallResponse(data.result)}"),
212
- )
213
- }
214
- }
215
-
216
- // Map a transient LLM retry reason (an `LLMRetryReason` from the runtime
217
- // retry layer) to a short, human-facing label. `connectionLost` is the
218
- // lost-internet / closed-the-laptop case; the rest cover provider hiccups
219
- // and our own per-call timeout.
220
- export def retryReasonLabel(reason: string): string {
221
- if (reason == "connectionLost") {
222
- return "Connection lost"
223
- }
224
- if (reason == "timeout") {
225
- return "Request timed out"
226
- }
227
- if (reason == "streamInterrupted") {
228
- return "Connection interrupted"
229
- }
230
- if (reason == "rateLimit") {
231
- return "Rate limited"
232
- }
233
- if (reason == "overloaded") {
234
- return "Model overloaded"
235
- }
236
- if (reason == "serverError") {
237
- return "Server error"
238
- }
239
- if (reason == "invalidStructuredOutput") {
240
- return "Output failed validation"
241
- }
242
- return reason
243
- }
244
-
245
- // A transient LLM failure (lost connection, timeout, server hiccup) the
246
- // runtime is about to retry. Surface a dim, one-line heads-up so the user
247
- // understands the pause instead of staring at a frozen prompt — this is the
248
- // "lost internet / closed the laptop" experience the abort taxonomy made
249
- // distinguishable. Gated like the other traces so piped one-shot output
250
- // stays clean. `attempt` is the 1-based retry number; `maxRetries` is the
251
- // configured retry budget.
252
- callback("onLLMRetry") as data {
253
- if (_showTraces()) {
254
- pushMessage(
255
- color.dim(
256
- "⟳ ${retryReasonLabel(data.reason)} — retrying (${data.attempt}/${data.maxRetries})…",
257
- ),
258
- )
259
- }
260
- }
261
-
262
- // Turn a terminal (retries-exhausted) LLM failure into a short, actionable
263
- // message. The runtime's exhausted-retry error text embeds the reason in
264
- // parens, e.g. "LLM call failed after 3 attempts (connectionLost): ...". We
265
- // recognize the transport reasons that mean "the network or model dropped"
266
- // and give concrete advice; anything else echoes the raw error so nothing
267
- // is hidden.
268
- export def formatTurnFailure(errText: string): string {
269
- if (errText.includes("(connectionLost)") || errText.includes("(streamInterrupted)")) {
270
- return "⚠ Lost the connection to the model and couldn't recover after retrying.\nCheck your internet connection and try again."
271
- }
272
- if (errText.includes("(timeout)")) {
273
- return "⚠ The model took too long to respond — the request timed out after retrying.\nTry again, perhaps with a smaller request."
274
- }
275
- if (errText.includes("(rateLimit)") || errText.includes("(overloaded)") || errText.includes("(serverError)")) {
276
- return "⚠ The model provider is busy and the request failed after retrying.\nWait a moment and try again."
277
- }
278
- return "⚠ The request failed: ${errText}"
279
- }
280
-
281
- type ToolCallData = {
282
- name: string;
283
- arguments: any
284
- }
285
-
286
- type LLMResponse = {
287
- output?: string;
288
- toolCalls: ToolCallData[];
289
- usage: { inputTokens: number; outputTokens: number; totalTokens: number; cachedInputTokens: number };
290
- cost: { inputCost: number; outputCost: number; cachedInputCost: number; totalCost: number; currency: string };
291
- model: string
292
- }
293
-
294
- def renderLLMCallResponse(data: LLMResponse): string {
295
- let response = []
296
- if (data.output != "" && data.output != null && data.output != undefined) {
297
- response.push(data.output)
298
- }
299
- if (data.toolCalls.length > 0) {
300
- for (toolCall in data.toolCalls) {
301
- response.push(`${toolCall.name}(${formatArgs(toolCall.arguments)})`)
302
- }
303
- }
304
- return response.join("\n")
305
- }
306
-
307
- def loadAgentsMd(dir: string): string {
308
- """
309
- Read `AGENTS.md` from `dir` if it exists and return it wrapped in a
310
- <project_context> block ready to splice into a system prompt. Returns
311
- an empty string if there is no AGENTS.md or it cannot be read. The
312
- read is auto-approved — the user implicitly opted in to scanning the
313
- project directory by running the agent there.
314
- """
315
- if (!exists("AGENTS.md", dir)) {
316
- return ""
317
- }
318
- const result = read("AGENTS.md", dir) with approve
319
- if (isFailure(result)) {
320
- return ""
321
- }
322
- return "\n\n<project_context>\n${result.value}\n</project_context>"
323
- }
324
-
325
- // Per-turn grounding context. Captured at startup and re-used so the
326
- // LLM doesn't have to re-ground each turn. Initialized in `main()`.
327
- let _context: string = ""
328
-
329
- // Project-local slash commands. `cwd()` works at module-init time so
330
- // we anchor at the user's project root (not the agent's source dir).
331
- // `with approve` auto-approves the `glob`/`read` during init — the
332
- // user implicitly opted in by running the agent in this directory.
333
- static const projectCommands = commandsDir("${cwd()}/.claude/commands") with approve
334
-
335
- def builtinPalette(): Record<string, string> {
336
- return {
337
- "/exit": "Exit the agent",
338
- "/clear": "Clear the conversation transcript",
339
- "/clear-history": "Clear the input history (recall + saved file)",
340
- "/cost": "Show cumulative LLM cost and tokens",
341
- "/model": "Switch the model (bare to pick, or slot=model)",
342
- "/models": "List / filter the hosted model catalog",
343
- "/local": "Switch to a local model",
344
- "/search": "Choose the web search backend (hosted / Tavily / Brave / off)",
345
- "/settings": "View and change capability settings for the current model",
346
- "/mcp": "List configured MCP servers and their tools",
347
- "/paste": "Multi-line paste mode (Ctrl+D submits, Ctrl+C cancels)",
348
- "/help": "Show available slash commands"
349
- }
350
- }
351
-
352
- // Built-ins win over file commands so a user `/clear.md` can't shadow
353
- // the built-in `/clear`. Build file entries first, then overlay builtins.
354
- def mergedPalette(): Record<string, string> {
355
- let out: Record<string, string> = {}
356
- for (cmd in projectCommands) {
357
- let label = cmd.description
358
- if (cmd.argHint != "") {
359
- label = "${cmd.description} ${cmd.argHint}"
360
- }
361
- out["/${cmd.name}"] = label
362
- }
363
- const builtins = builtinPalette()
364
- for (key in builtins) {
365
- out[key] = builtins[key]
366
- }
367
- return out
368
- }
369
-
370
- // In-session model selection state. One mutable cell holding the current
371
- // Session (the pin + per-slot overrides chosen via /model this run). switchModel
372
- // is pure over this value — it copies, never mutates — so it stays testable.
373
- export type Session = {
374
- pin: string;
375
- slots: Record<string, string>
376
- }
377
-
378
- let _session: Session = {
379
- pin: "",
380
- slots: {}
381
- }
382
-
383
- /** Apply an in-session model selection. Copies `prior` (never mutates), folds in
384
- the new spec (bare → pin; slot=model → per-slot), resolves, applies, and returns
385
- the new session + assignment + the slots that changed (so the caller can react,
386
- e.g. the cross-provider recall notice). Turn-boundary semantics: takes effect on
387
- the NEXT turn; no in-flight call is mutated. */
388
- export def switchModel(
389
- prior: Session,
390
- spec: string,
391
- ctx: Ctx,
392
- before: Record<string, Resolved>,
393
- ): { session: Session; resolved: Record<string, Resolved>; changes: SlotChange[] } {
394
- // The caller builds ctx from currentProvider(), which returns the
395
- // PROMOTED name on openai sessions. priceDefault and the built-in
396
- // tables key by public provider names, so demote before resolving —
397
- // otherwise a switch that lets any slot fall through to the built-in
398
- // defaults fails with "openai-responses has no built-in defaults".
399
- const ctx2: Ctx = {
400
- provider: demoteProvider(ctx.provider),
401
- price: ctx.price
402
- }
403
- let nextSlots: Record<string, string> = {}
404
- for (key in Object.keys(prior.slots)) {
405
- nextSlots[key] = prior.slots[key]
406
- }
407
- let next: Session = {
408
- pin: prior.pin,
409
- slots: nextSlots
410
- }
411
- const parsed = parseModelFlag(spec)
412
- if (parsed.slot != "" && !SLOTS.includes(parsed.slot)) {
413
- pushMessage(
414
- color.red("Unknown model slot '${parsed.slot}'. Valid slots: ${SLOTS.join(", ")}."),
415
- )
416
- return {
417
- session: prior,
418
- resolved: before,
419
- changes: []
420
- }
421
- }
422
- if (parsed.slot == "embedding" && !embeddingSpecHasProvider(parsed.model)) {
423
- // The embedding slot exists to point AWAY from the chat provider, so
424
- // the provider can never be inferred. Require the explicit form.
425
- pushMessage(
426
- color.red(
427
- "Embedding models need the provider/model form, e.g. embedding=openai/text-embedding-3-small.",
428
- ),
429
- )
430
- return {
431
- session: prior,
432
- resolved: before,
433
- changes: []
434
- }
435
- }
436
- if (parsed.slot == "") {
437
- next.pin = parsed.model
438
- } else {
439
- next.slots[parsed.slot] = parsed.model
440
- }
441
-
442
- // A saved provider (settings.model.provider) means a provider is established,
443
- // so a unified provider/model spec should not be split during resolution.
444
- const settings = getModelSettings(loadSettings())
445
- const providerEstablished = settings.provider != null && settings.provider != ""
446
- const layers = buildLayers(
447
- next.pin,
448
- next.slots,
449
- "",
450
- {},
451
- settings,
452
- knownProviders(),
453
- providerEstablished,
454
- )
455
- const all = resolveAll(layers, ctx2)
456
- if (isFailure(all)) {
457
- pushMessage(color.red("Could not switch model: ${all.error}"))
458
- return {
459
- session: prior,
460
- resolved: before,
461
- changes: []
462
- }
463
- }
464
- const resolved = promoteAll(all.value)
465
- applyResolved(resolved)
466
- return {
467
- session: next,
468
- resolved: resolved,
469
- changes: diffResolved(before, resolved)
470
- }
471
- }
472
-
473
- /** React to one resolved-slot change. Phase 1: a `main`-slot provider change
474
- means the embedding space behind memory changed, so pause memory and warn.
475
- (std::memory has no tier-2-only toggle yet -- full pause; structured recall
476
- returns when a selective toggle lands.) Returns true if it emitted the notice. */
477
- export def reactToSlotChange(change: SlotChange): boolean {
478
- if (change.slot == "main" && change.before.provider != change.after.provider) {
479
- // Skip the pause only when startup actually enabled memory WITH the
480
- // override. A set-but-keyless slot took the fallback path, so memory
481
- // runs on derived embeddings and the provider change still shifts
482
- // the embedding space behind recall.
483
- if (_memoryEmbeddingsPinned) {
484
- return false
485
- }
486
- pushMessage(
487
- color.dim(
488
- "Warning: provider changed - memory is paused until restart (recall would be unreliable).",
489
- ),
490
- )
491
- // `with approve`: the agent is deliberately auto-pausing memory on a
492
- // provider switch, not asking the user — so don't surface an approval prompt.
493
- disableMemory() with approve
494
- return true
495
- }
496
- if (change.slot == "embedding") {
497
- const override = overrideFromResolved(change.after)
498
- if (override != null) {
499
- const missing = missingProviderEnvVar(override.provider)
500
- if (missing != "") {
501
- pushMessage(
502
- color.yellow(
503
- "Warning: the embedding slot needs ${missing}, which is not set. The assignment takes effect at next agent start, and memory falls back to the default embedding behavior until it is exported.",
504
- ),
505
- )
506
- return true
507
- }
508
- // The healthy path must not be silent: enableMemory already ran,
509
- // so the user would otherwise believe embeddings switched now.
510
- pushMessage(
511
- color.dim(
512
- "Embedding slot set: memory embeddings use ${override.provider}/${override.model} at next agent start.",
513
- ),
514
- )
515
- return true
516
- }
517
- }
518
- return false
519
- }
520
-
521
- // ChoiceItem list for the model pickers: the hosted catalog, filtered, each
522
- // labeled with provider + input price for an informed pick.
523
- export def modelChoiceItems(filters: ModelFilters): ChoiceItem[] {
524
- let items: ChoiceItem[] = []
525
- for (model in filterHostedModels(listHostedModels(), filters)) {
526
- const label = "${model.name} (${model.provider}, $${model.inputCost}/1M in)"
527
- items.push({
528
- key: model.name,
529
- label: label
530
- })
531
- }
532
- return items
533
- }
534
-
535
- // Parse a `/models [provider]` command line into filters. Bare `/models` (or a
536
- // trailing-space-only arg) yields no filters; `/models <provider>` narrows to
537
- // one provider. Extracted from the handler so it is unit-testable.
538
- export def parseModelsFilters(cmd: string): ModelFilters {
539
- const prefix = "/models "
540
- if (!cmd.startsWith(prefix)) {
541
- return {}
542
- }
543
- const arg = cmd.substring(prefix.length).trim()
544
- if (arg == "") {
545
- return {}
546
- }
547
- return {
548
- provider: arg
549
- }
550
- }
551
-
552
- /** Human label for a capability source layer. Interprets the source
553
- strings resolveCapabilities emits (capabilities.agency). */
554
- def capabilitySourceLabel(source: string): string {
555
- if (source == "default") {
556
- return "built-in default"
557
- }
558
- if (source == "provider") {
559
- return "provider default: ${getCapabilityProvider()}"
560
- }
561
- if (source == "model") {
562
- return "built-in for ${getCapabilityModelKey()}"
563
- }
564
- if (source == "user-global") {
565
- return "your global override"
566
- }
567
- if (source == "user-provider") {
568
- return "your override for ${getCapabilityProvider()}"
569
- }
570
- return "your override for ${getCapabilityModelKey()}"
571
- }
572
-
573
- /** One "value (source)" cell. The typed Capabilities shape cannot be
574
- indexed by a dynamic key, so this is the renderer's per-field switch. */
575
- def capabilityRow(fieldKey: string): string {
576
- const resolved = getCapabilitiesResolved()
577
- const values = resolved.values
578
- const sources = resolved.sources
579
- if (fieldKey == "prompt") {
580
- return "${values.prompt} (${capabilitySourceLabel(sources.prompt)})"
581
- }
582
- if (fieldKey == "summarize") {
583
- return "${values.summarize} (${capabilitySourceLabel(sources.summarize)})"
584
- }
585
- if (fieldKey == "memory") {
586
- return "${values.memory} (${capabilitySourceLabel(sources.memory)})"
587
- }
588
- let cap = "none"
589
- if (values.maxTokens != null) {
590
- cap = "${values.maxTokens}"
591
- }
592
- return "${cap} (${capabilitySourceLabel(sources.maxTokens)})"
593
- }
594
-
595
- /** Render the current profile with per-field provenance. */
596
- def showCapabilities() {
597
- pushMessage("Capabilities for ${getCapabilityModelKey()} (${getCapabilityProvider()}):")
598
- for (field in CAPABILITY_FIELDS) {
599
- pushMessage(" ${field.label} ${capabilityRow(field.key)}")
600
- }
601
- }
602
-
603
- /** The settings.json key a scope writes under. Global's key is unused. */
604
- def scopeTargetName(scopeKey: string): string {
605
- if (scopeKey == "provider") {
606
- return getCapabilityProvider()
607
- }
608
- return getCapabilityModelKey()
609
- }
610
-
611
- /** Persist one override patch at a scope, then re-resolve. */
612
- def saveCapabilityOverride(scopeKey: string, patch: CapabilityPatch) {
613
- let settings = loadSettings()
614
- settings.capabilities = mergeCapabilityOverride(
615
- getCapabilitySettings(settings),
616
- scopeKey,
617
- scopeTargetName(scopeKey),
618
- patch,
619
- )
620
- saveSettings(settings)
621
- refreshCapabilities(getCapabilityModelKey(), getCapabilityProvider())
622
- }
623
-
624
- /** Remove one field override at a scope, then re-resolve. */
625
- def removeCapabilityOverride(scopeKey: string, fieldKey: string) {
626
- let settings = loadSettings()
627
- settings.capabilities = removeCapabilityField(
628
- getCapabilitySettings(settings),
629
- scopeKey,
630
- scopeTargetName(scopeKey),
631
- fieldKey,
632
- )
633
- saveSettings(settings)
634
- refreshCapabilities(getCapabilityModelKey(), getCapabilityProvider())
635
- }
636
-
637
- /** Ask which scope an override applies to. Returns "" on cancel. */
638
- def pickOverrideScope(): string {
639
- let scopeItems: ChoiceItem[] = []
640
- scopeItems.push({
641
- key: "model",
642
- label: "this model (${getCapabilityModelKey()})"
643
- })
644
- scopeItems.push({
645
- key: "provider",
646
- label: "this provider (${getCapabilityProvider()})"
647
- })
648
- scopeItems.push({
649
- key: "global",
650
- label: "all models"
651
- })
652
- const scopeKey = chooseOption("Scope", "Where should this apply?", scopeItems, allowCancel: true)
653
- if (scopeKey == null) {
654
- return ""
655
- }
656
- return scopeKey
657
- }
658
-
659
- /** Re-apply the resolved cap as the branch default. After a reset the
660
- resolved value falls back to a built-in layer, which is always numeric
661
- for known providers, so live-apply covers removal too. */
662
- def applyLiveMaxTokens() {
663
- const capValue = getCapabilities().maxTokens
664
- if (capValue != null) {
665
- setLlmOptions({ maxTokens: capValue })
666
- }
667
- }
668
153
 
669
- /** Positive-integer parse. parseInt and isNaN appear nowhere in the
670
- repo's .agency code, so this uses a digits check instead. Returns -1
671
- for anything that is not all digits. */
672
- def parsePositiveInt(text: string): number {
673
- // Bound to a const because the parser rejects method calls on string
674
- // LITERALS ("0123456789".includes(...) does not parse; a variable does).
675
- const digits = "0123456789"
676
- const trimmed = text.trim()
677
- if (trimmed == "") {
678
- return -1
679
- }
680
- for (ch in trimmed.split("")) {
681
- if (!digits.includes(ch)) {
682
- return -1
683
- }
684
- }
685
- return Number(trimmed)
686
- }
687
-
688
- /** Interactive edit: field → value → scope → save → live-apply. */
689
- def editCapabilities() {
690
- let fieldItems: ChoiceItem[] = []
691
- for (field in CAPABILITY_FIELDS) {
692
- fieldItems.push({
693
- key: field.key,
694
- label: "${field.label} — ${field.description}"
695
- })
696
- }
697
- const fieldKey = chooseOption(
698
- "Settings",
699
- "Pick a setting to change (empty to exit).",
700
- fieldItems,
701
- allowCancel: true,
702
- )
703
- if (fieldKey == "" || fieldKey == null) {
704
- return
705
- }
706
-
707
- let patch: CapabilityPatch = {}
708
- if (fieldKey == "prompt") {
709
- let promptItems: ChoiceItem[] = []
710
- promptItems.push({
711
- key: "large",
712
- label: "large — full coordinator prompt"
713
- })
714
- promptItems.push({
715
- key: "small",
716
- label: "small — compact prompt for small-context models"
717
- })
718
- const picked = chooseOption("prompt", "System prompt size.", promptItems, allowCancel: true)
719
- if (picked == "" || picked == null) {
720
- return
721
- }
722
- patch = {
723
- prompt: picked
724
- }
725
- }
726
- if (fieldKey == "summarize" || fieldKey == "memory") {
727
- let onOffItems: ChoiceItem[] = []
728
- onOffItems.push({
729
- key: "on",
730
- label: "on"
731
- })
732
- onOffItems.push({
733
- key: "off",
734
- label: "off"
735
- })
736
- const picked = chooseOption(fieldKey, "Enable ${fieldKey}?", onOffItems, allowCancel: true)
737
- if (picked == "" || picked == null) {
738
- return
739
- }
740
- if (fieldKey == "summarize") {
741
- patch = {
742
- summarize: picked == "on"
743
- }
744
- } else {
745
- patch = {
746
- memory: picked == "on"
747
- }
748
- if (picked == "on") {
749
- const status = embeddingKeyStatus(getResolvedSlots())
750
- if (status.state == "key-missing") {
751
- pushMessage(
752
- color.red(
753
- "Cannot enable memory: the embedding slot needs ${status.varName}, which is not set. Export it, or point the embedding slot elsewhere via /model.",
754
- ),
755
- )
756
- return
757
- }
758
- if (status.state == "no-override" && providerLacksEmbeddings(getCapabilityProvider())) {
759
- pushMessage(
760
- color.dim(
761
- "Note: ${getCapabilityProvider()} has no embeddings endpoint, so Tier-2 semantic recall stays off. Point the embedding slot at a provider that has one, e.g. /model embedding=openai/text-embedding-3-small.",
762
- ),
763
- )
764
- }
765
- }
766
- }
767
- }
768
- if (fieldKey == "maxTokens") {
769
- let capItems: ChoiceItem[] = []
770
- capItems.push({
771
- key: "reset",
772
- label: "reset — remove my override, use the default"
773
- })
774
- const picked = chooseOption(
775
- "maxTokens",
776
- "Default output-token cap. Type a number, or pick reset.",
777
- capItems,
778
- allowFreeText: true,
779
- allowCancel: true,
780
- )
781
- if (picked == "" || picked == null) {
782
- return
783
- }
784
- if (picked == "reset") {
785
- const scopeKey = pickOverrideScope()
786
- if (scopeKey == "") {
787
- return
788
- }
789
- removeCapabilityOverride(scopeKey, "maxTokens")
790
- applyLiveMaxTokens()
791
- pushMessage("Override removed.")
792
- showCapabilities()
793
- return
794
- }
795
- const parsed = parsePositiveInt(picked)
796
- if (parsed <= 0) {
797
- pushMessage(color.red("Not a positive number: ${picked}"))
798
- return
799
- }
800
- patch = {
801
- maxTokens: parsed
802
- }
803
- }
804
-
805
- const scopeKey = pickOverrideScope()
806
- if (scopeKey == "") {
807
- return
808
- }
809
- saveCapabilityOverride(scopeKey, patch)
810
-
811
- // Live-apply what can apply now; explain what can't.
812
- if (fieldKey == "memory") {
813
- if (getCapabilities().memory) {
814
- // The ON direction cannot live-apply. enableAgentMemory's
815
- // `with approve` cannot override the outer policy handler that
816
- // startInteractive installed, so the memory-dir fs interrupts
817
- // would surface as policy prompts mid-flow, or get denied and
818
- // half-apply the toggle. The OFF direction stays live below:
819
- // disableMemory raises no fs interrupts and already runs in-REPL
820
- // from reactToSlotChange.
821
- pushMessage(color.dim("Memory turns on at next agent start (enabling mid-session would raise policy prompts)."))
822
- } else {
823
- disableMemory() with approve
824
- }
825
- }
826
- if (fieldKey == "maxTokens") {
827
- applyLiveMaxTokens()
828
- }
829
- if (fieldKey == "prompt") {
830
- pushMessage(color.dim("Prompt change applies on next agent start (this session's system message is already sent)."))
831
- }
832
- pushMessage("Saved.")
833
- showCapabilities()
834
- }
835
-
836
- // Slash-command + user-message dispatcher invoked by `repl()` for
837
- // every Enter keystroke. Return `false` to terminate the loop.
838
- def _runTurn(msg: string): boolean {
839
- // Trim once for built-in matching so `"/help\n"` (piped) or
840
- // `" /clear"` behave the same as `"/clear"`. `expandSlash` is
841
- // whitespace-tolerant in its own right, but it still receives the
842
- // raw `msg` so the LLM sees the exact text the user typed when
843
- // nothing matches.
844
- const trimmed = msg.trim()
845
- if (trimmed == "") {
846
- return true
847
- }
848
- if (trimmed == "/exit" || trimmed == "/quit") {
849
- return false
850
- }
851
- if (trimmed == "/clear") {
852
- clearMessages()
853
- return true
854
- }
855
- if (trimmed == "/clear-history") {
856
- clearHistory()
857
- pushMessage("Input history cleared.")
858
- return true
859
- }
860
- if (trimmed == "/help") {
861
- pushMessage(
862
- "Commands: /exit, /clear, /clear-history, /cost, /model, /models, /local, /search, /settings, /mcp, /paste, /help",
863
- )
864
- return true
865
- }
866
- if (trimmed == "/settings") {
867
- showCapabilities()
868
- editCapabilities()
869
- return true
870
- }
871
- if (trimmed == "/mcp") {
872
- if (!isMcpAvailable()) {
873
- pushMessage(color.yellow("MCP is not installed. Run: npm install @agency-lang/mcp"))
874
- return true
875
- }
876
- const merged = mergeMcpServers(getMcpServers(loadSettings()), readProjectMcpConfig(cwd()))
877
- if (keys(merged).length == 0) {
878
- pushMessage(color.dim("No MCP servers configured. Add an mcpServers block to agency.json or settings.json."))
879
- return true
880
- }
881
- pushMessage(color.bold("MCP servers:"))
882
- for (name in keys(merged)) {
883
- // mcpServerStatus is populated at session start. A server present in the
884
- // config but absent from the status map was never loaded (e.g. /mcp run
885
- // before startup finished) — show it as unknown rather than connected.
886
- let status = mcpServerStatus[name]
887
- if (status == null) {
888
- status = "not loaded"
889
- }
890
- pushMessage(" ${name} — ${status}")
891
- }
892
- pushMessage(color.dim("Loaded ${mcpTools.length} MCP tool(s) this session."))
893
- return true
894
- }
895
- if (trimmed == "/search") {
896
- const opts = availableBackendItems()
897
- const choice = chooseOption(
898
- "Web search backend",
899
- "Pick how this agent searches the web. Current: ${getSearchBackend()}",
900
- opts,
901
- false,
902
- true,
903
- )
904
- if (choice != "" && choice != null && choice != undefined) {
905
- setSearchBackend(choice)
906
- pushMessage("Web search backend set to: ${choice}")
907
- }
908
- return true
909
- }
910
- if (trimmed == "/cost") {
911
- // Derive BOTH the header total and the per-model breakdown from the
912
- // same process-wide accumulator (getModelCosts), so the `Cost:` /
913
- // `Tokens:` lines and the rows below them can never visibly disagree.
914
- // (getCost()/getTokens() read the per-branch accumulator, a different
915
- // scope — adjacent in the output, they could in principle diverge.)
916
- // Rows are sorted by cost descending by getModelCosts(); a subagent
917
- // on a pricier model (e.g. the oracle on opus-4.8) shows up here.
918
- const byModel = getModelCosts()
919
- let totalCost = 0.0
920
- let totalTokens = 0
921
- for (m in byModel) {
922
- totalCost = totalCost + m.cost
923
- totalTokens = totalTokens + m.inputTokens + m.outputTokens
924
- }
925
- pushMessage("Cost: $${totalCost.toFixed(4)}")
926
- pushMessage("Tokens: ${totalTokens}")
927
- if (byModel.length > 0) {
928
- pushMessage("")
929
- pushMessage("By model:")
930
- for (m in byModel) {
931
- pushMessage(
932
- " ${m.model} ↑${m.inputTokens} ↓${m.outputTokens} $${m.cost.toFixed(4)}",
933
- )
934
- }
935
- }
936
- return true
937
- }
938
- if (trimmed == "/model" || trimmed.startsWith("/model ")) {
939
- let spec = ""
940
- if (trimmed != "/model") {
941
- spec = trimmed.substring(7).trim()
942
- }
943
- if (spec == "") {
944
- pushMessage("Current models:")
945
- const current = getResolvedSlots()
946
- for (slot in Object.keys(current)) {
947
- const resolved = current[slot]
948
- if (resolved != null) {
949
- pushMessage(" ${slot}: ${resolved.model} (${resolved.via})")
950
- }
951
- }
952
- const items = modelChoiceItems({})
953
- const choice = chooseOption(
954
- "Model",
955
- "Pick a model, or type one (or slot=model, e.g. reasoning=claude-opus-4-8). Empty to cancel.",
956
- items,
957
- allowFreeText: true,
958
- allowCancel: true,
959
- )
960
- if (choice == "" || choice == null) {
961
- return true
962
- }
963
- spec = choice
964
- }
965
- const ctx: Ctx = {
966
- provider: currentProvider(),
967
- price: "standard"
968
- }
969
- const out = switchModel(_session, spec, ctx, getResolvedSlots())
970
- _session = out.session
971
- for (change in out.changes) {
972
- reactToSlotChange(change)
973
- }
974
- pushMessage("Model set:")
975
- for (slot in Object.keys(out.resolved)) {
976
- const resolved = out.resolved[slot]
977
- if (resolved != null) {
978
- pushMessage(color.dim(" ${slot}: ${resolved.model} (${resolved.via})"))
979
- }
980
- }
981
- return true
982
- }
983
- if (trimmed == "/models" || trimmed.startsWith("/models ")) {
984
- const filters = parseModelsFilters(trimmed)
985
- const models = filterHostedModels(listHostedModels(), filters)
986
- if (models.length == 0) {
987
- pushMessage("No models match.")
988
- return true
989
- }
990
- for (model in models) {
991
- pushMessage(
992
- " ${model.name} (${model.provider}, $${model.inputCost}/1M in, ${model.contextWindow} ctx)",
993
- )
994
- }
995
- return true
996
- }
997
- if (trimmed == "/local") {
998
- if (!localModelsSupported()) {
999
- pushMessage(
1000
- color.yellow(
1001
- "Local models need smoltalk-llama-cpp. Install: ! npm i -g smoltalk-llama-cpp",
1002
- ),
1003
- )
1004
- return true
1005
- }
1006
- let items: ChoiceItem[] = []
1007
- for (modelName in listModelNames()) {
1008
- items.push({
1009
- key: modelName.name,
1010
- label: modelName.name
1011
- })
1012
- }
1013
- const choice = chooseOption(
1014
- "Local model",
1015
- "Pick a local model, or type an hf: URI / .gguf path (downloads on first use):",
1016
- items,
1017
- allowFreeText: true,
1018
- allowCancel: true,
1019
- )
1020
- if (choice == "" || choice == null) {
1021
- return true
1022
- }
1023
- const before = getResolvedSlots()
1024
- configureLocalModel(choice)
1025
- configureSearch(true)
1026
- for (change in diffResolved(before, getResolvedSlots())) {
1027
- reactToSlotChange(change)
1028
- }
1029
- pushMessage("Switched to local model: ${choice}")
1030
- return true
1031
- }
1032
-
1033
- // Hand the message to the agent. `agentReply` does the slash-command
1034
- // expansion and the actual agent work; the REPL just renders the reply.
1035
- // Wrap in `try` so a terminal LLM failure (e.g. the connection dropped and
1036
- // retries were exhausted) renders a friendly heads-up instead of a raw
1037
- // Failure object. Aborts/interrupts are NOT caught here — `try` re-throws
1038
- // them so an Esc-cancel still reaches the policy handler.
1039
- const result = try agentReply(msg)
1040
- if (result is success(reply)) {
1041
- if (reply != "" && reply != null && reply != undefined) {
1042
- pushMessage(highlight("${reply}\n", language: "markdown"))
1043
- } else {
1044
- pushMessage(color.red("No reply generated."))
1045
- }
1046
- } else if (result is failure(f)) {
1047
- pushMessage(color.red(formatTurnFailure("${f.error}")))
1048
- }
1049
- return true
1050
- }
1051
-
1052
- let first = true
1053
-
1054
- // Valid `--agent` targets. Empty / "main" routes through the coordinator;
1055
- // the rest route the starting prompt's first turn directly to that
1056
- // subagent. Used to validate the flag and to dispatch in `agentReplyVia`.
1057
- static const START_AGENTS = ["main", "code", "research", "oracle", "explorer", "review"]
1058
-
1059
- static const MAIN_PROMPT_LARGE = """
1060
- You are the top-level coordinator of an Agency-language assistant. You
1061
- receive every user message and decide how to respond.
1062
-
1063
- You have five subagent tools (each running in its own isolated
1064
- context) and one direct tool:
1065
-
1066
- - `codeAgent(userMsg)` — anything that touches code or the filesystem:
1067
- reading, writing, editing, typechecking, running shell commands,
1068
- and answering Agency syntax / CLI questions. Use this for any task
1069
- that involves inspecting or modifying source code.
1070
- - `researchAgent(userMsg)` — web search, URL fetches, Wikipedia,
1071
- external API lookups, summarizing external content.
1072
- - `reviewAgent(userMsg)` — reviews Agency code for syntax and type
1073
- errors. Call this after `codeAgent` produces non-trivial new or
1074
- modified Agency code, passing the code to be reviewed.
1075
- - `oracleAgent(userMsg)` — a read-only senior reviewer on a stronger
1076
- reasoning model. Read the **Oracle** section below — you are
1077
- expected to use this tool **frequently**.
1078
- - `explorerAgent(userMsg)` — a read-only researcher that produces
1079
- broad, synthesizing answers about the codebase or bundled docs.
1080
- Read the **Explorer** section below.
1081
- - `generateImageFile(prompt, path, size, images)` — generate an image
1082
- from a text prompt (or modify existing images by passing their paths
1083
- in `images`) and save it to `path`. Call it directly whenever the
1084
- user asks you to create, draw, edit, or restyle an image — do NOT
1085
- route image generation to `codeAgent`.
1086
-
1087
- **Answer directly (no tool call) when** the message is conversational,
1088
- a clarifying question, or something you can answer from context alone.
1089
-
1090
- **Delegate when** the message clearly needs one of the subagents'
1091
- capabilities. Pick one based on what the message actually needs —
1092
- don't pre-emptively call multiple subagents.
1093
-
1094
- ## Picking between oracle, explorer, and code agent
1095
-
1096
- These three overlap on "reads the codebase," but they're for
1097
- different jobs. Pick by **the shape of the answer the user wants**:
1098
-
1099
- - **oracle** → sharp verdict on a specific plan, diff, or bug.
1100
- Output: short, decisive ("this plan won't work because X").
1101
- - **explorer** → broad synthesis from reading many files.
1102
- Output: structured overview ("Agency's five main features
1103
- are..."). Use for "summarize", "tour", "what are the main",
1104
- "how does X work across...".
1105
- - **codeAgent** → targeted action: edit, run, typecheck, or
1106
- answer a focused Agency-syntax question. Output: the edit
1107
- itself, or a concise factual reply.
1108
-
1109
- Default: if the user asks a broad/synthesizing question,
1110
- `explorerAgent` beats `codeAgent` every time. The code agent is
1111
- optimized for terse action and will under-read on broad asks.
1112
-
1113
- Subagents return summary text. Surface that result to the user (in
1114
- your own words if you're combining multiple results), formatted as
1115
- Markdown.
1116
-
1117
- ## Oracle
1118
-
1119
- The oracle is the most powerful tool you have. Use it **FREQUENTLY**.
1120
- It is a read-only senior reviewer running on a stronger reasoning
1121
- model than you. It can read the codebase and the Agency docs but
1122
- cannot write, edit, or run anything. Its job is to **think hard so
1123
- you don't have to guess**.
1124
-
1125
- Call the oracle:
1126
-
1127
- - **Before** dispatching `codeAgent` for any non-trivial task — ask
1128
- the oracle to sanity-check the plan, find existing code that
1129
- already solves the problem, or suggest a simpler approach.
1130
- - **After** `codeAgent` produces a non-trivial diff — ask the oracle
1131
- to review the work for correctness, missed edge cases, and
1132
- better alternatives.
1133
- - When `codeAgent` reports it's stuck on a bug after one or two
1134
- attempts — ask the oracle what's actually going on.
1135
- - When the user proposes a plan or approach — ask the oracle
1136
- whether the plan is sound, **before** you act on it. If the
1137
- oracle finds a flaw, surface that to the user *before* taking
1138
- any action.
1139
- - Whenever you're tempted to guess about the codebase ("I think
1140
- there's probably already a helper for X") — ask the oracle to
1141
- look.
1142
-
1143
- **Tell the user when you're consulting the oracle.** Say something
1144
- like "Let me ask the oracle to review this plan before we start"
1145
- or "I'll have the oracle look for an existing implementation." The
1146
- visibility is half the value — the user benefits from knowing a
1147
- second opinion is being sought.
1148
-
1149
- Pass the oracle a self-contained question with full context. It
1150
- does not see your conversation. Include the user's request, the
1151
- plan or diff under review, relevant file paths, and the specific
1152
- question you want answered.
1153
-
1154
- Default bias: when in doubt, **consult the oracle**. The cost of
1155
- asking is small; the cost of executing a flawed plan is large.
1156
-
1157
- ## Explorer
1158
-
1159
- The explorer is your go-to for **broad, synthesizing questions**
1160
- about the codebase or the bundled Agency docs. It is read-only and
1161
- runs on a stronger reasoning model with extended thinking. Its job
1162
- is **coverage** — it reads widely and returns a structured synthesis.
1163
-
1164
- Call the explorer when the user asks:
1165
-
1166
- - "Summarize the Agency docs" / "What are the main features?"
1167
- - "Give me a tour of `lib/X/`" / "What's in this module?"
1168
- - "How does X work across the codebase?"
1169
- - "Walk me through the compilation pipeline"
1170
- - Anything where a good answer requires reading 5+ files and
1171
- organizing the findings by theme.
1172
-
1173
- Do NOT use the explorer for:
1174
- - Specific factual lookups ("what does function X return?") — use
1175
- `codeAgent`.
1176
- - Plan critique or bug diagnosis — use `oracleAgent`.
1177
- - External / web research — use `researchAgent`.
1178
-
1179
- **Tell the user when you're consulting the explorer.** "Let me have
1180
- the explorer go through the docs and put together an overview." Like
1181
- with the oracle, the visibility is part of the value — the user
1182
- benefits from knowing breadth is being applied.
1183
-
1184
- Pass the explorer a self-contained question with explicit scope
1185
- ("all of `docs/site/guide/`", "the `lib/parsers/` module"). It does
1186
- not see your conversation. Be clear about the level of detail
1187
- expected.
1188
-
1189
- ## Style
1190
-
1191
- Never start a response by calling the user's question or idea good,
1192
- great, fascinating, profound, excellent, or perfect. Skip flattery
1193
- and respond directly. Don't pad replies with "happy to help",
1194
- "certainly", or trailing summaries the user can read in the diff.
1195
-
1196
- **Use ASCII diagrams when they clarify.** For control flow, state
1197
- machines, pipelines, module relationships, or any "how do the parts
1198
- fit together" answer, draw a small ASCII diagram in a fenced
1199
- ```text block. Boxes, arrows, and trees beat paragraphs for
1200
- structural explanations:
1201
-
1202
- ```text
1203
- parse → SymbolTable.build → preprocess → TypeScriptBuilder → printTs
1204
- ```
1205
-
1206
- Keep diagrams small. Skip them where prose or code is clearer —
1207
- diagrams earn their space by showing **relationships** or **flow**.
1208
-
1209
- ## Be proactive
1210
-
1211
- When the user asks you to look at, debug, or change a file or some code,
1212
- **delegate to `codeAgent` to do it** — don't ask the user to paste a file
1213
- or describe code a subagent could read. The code agent has `read`, `glob`,
1214
- and `ls` and resolves relative paths against the user's working directory
1215
- automatically, so a bare filename like `foo.agency` is enough. Only ask
1216
- the user for information you genuinely cannot obtain through a subagent.
1217
-
1218
- ## Answer before action
1219
-
1220
- When the user asks a question, asks for an opinion, or asks how to
1221
- plan or approach something, **answer the question first**. Don't
1222
- jump straight into delegating to a subagent or making tool calls
1223
- unless the user has clearly asked for an action ("do X", "fix Y",
1224
- "build Z"). If the user is exploring or thinking out loud, think
1225
- with them — don't sprint to implementation.
1226
- """
1227
-
1228
- // Compact coordinator prompt for small-context models, ~350 tokens
1229
- // instead of ~3,400. Selected when the capability profile says
1230
- // prompt: "small". An 8K-context model loses 40% of its window to the
1231
- // large prompt before the user types anything. The phrase "compact
1232
- // coordinator" is a deliberate marker that verification greps for in
1233
- // statelogs.
1234
- static const MAIN_PROMPT_SMALL = """
1235
- You are the compact coordinator of an Agency-language assistant. Decide
1236
- how to answer each user message.
1237
-
1238
- Tools (each runs in its own context; pass a self-contained message):
1239
- - `codeAgent(userMsg)` — anything touching code or files: read, write,
1240
- edit, run, typecheck. Also Agency syntax and CLI questions.
1241
- - `researchAgent(userMsg)` — web search, URL fetches, external facts.
1242
- - `reviewAgent(userMsg)` — check non-trivial new Agency code for
1243
- syntax and type errors; pass the code to review.
1244
- - `oracleAgent(userMsg)` — deep reasoning on a hard question; include
1245
- all needed context in the message.
1246
- - `explorerAgent(userMsg)` — broad read-only codebase/docs questions.
1247
- - `generateImageFile(prompt, path, size, images)` — create or edit an
1248
- image; do not route image work to codeAgent.
1249
-
1250
- Routing rules:
1251
- - Simple chat, greetings, quick factual answers: reply directly, no
1252
- tools.
1253
- - Anything code- or file-related: codeAgent. Current/external info:
1254
- researchAgent. Broad "summarize/tour/how does X work" questions:
1255
- explorerAgent.
1256
- - Surface tool results to the user concisely; do not re-run a tool the
1257
- user did not ask to re-run.
1258
-
1259
- Style: plain, direct answers in Markdown. No preamble. Keep replies
1260
- short unless the task demands detail.
1261
- """
1262
-
1263
- // Exported for tests: agent-cwd resolution of edit inputs is a spec
1264
- // invariant with no other observable (the deterministic image client
1265
- // ignores its images argument). generateImage accepts path / URL /
1266
- // data-URI strings, so only local paths get agent-cwd resolution —
1267
- // running a URL through applyAgentCwd would mangle it into
1268
- // "<agentCwd>/https:/…".
1269
- export def resolveEditInputs(images: string[]): string[] {
1270
- return map(images) as inputPath {
1271
- if (inputPath.startsWith("http://") || inputPath.startsWith("https://") || inputPath.startsWith("data:")) {
1272
- return inputPath
1273
- }
1274
- return applyAgentCwd(inputPath)
1275
- }
1276
- }
1277
-
1278
- // Direct image generation for the coordinator. Saves to disk and
1279
- // returns the path — never base64, which would flood the LLM context.
1280
- // The write rides the std::writeBinary interrupt gate (writes are not
1281
- // auto-approved by policy) and generation cost accrues to the agent's
1282
- // cost tracking like any llm() call.
1283
- export def generateImageFile(
1284
- prompt: string,
1285
- path: string,
1286
- size: string = "",
1287
- images: string[] = [],
1288
- ): string {
1289
- """
1290
- Generate an image from a text prompt and save it to `path`. To MODIFY
1291
- existing images (edit / variation), pass their paths in `images`.
1292
- Returns the saved path on success. Use this when the user asks to
1293
- create, draw, edit, or restyle an image.
1294
-
1295
- @param prompt - What to generate, or how to modify the input images.
1296
- @param path - Where to save the resulting image (e.g. "diagram.png").
1297
- @param size - Optional size like "1024x1024".
1298
- @param images - Optional input image paths to edit / vary.
1299
- """
1300
- // LLM-supplied paths resolve against the agent cwd, like every other
1301
- // agent file tool.
1302
- const inputs = resolveEditInputs(images)
1303
- const generated = generateImage(prompt, size: size, images: inputs)
1304
- if (isFailure(generated)) {
1305
- return "Image generation failed: ${generated.error}"
1306
- }
1307
- // writeBinary rejects an absolute filename when dir is set, so split
1308
- // path into (dir, name); useAgentCwd resolves a relative dir against
1309
- // the agent cwd (absolute dirs pass through untouched).
1310
- const written = writeBinary(
1311
- basename(path),
1312
- generated.value.base64,
1313
- dirname(path),
1314
- useAgentCwd: true,
1315
- )
1316
- if (isFailure(written)) {
1317
- return "Generated the image, but saving to ${path} failed: ${written.error}"
1318
- }
1319
- // Show the model what it made (generate -> view -> refine). The loop
1320
- // inlines the bytes when it builds the injected user message; the
1321
- // path resolves the same way the write did.
1322
- attachToReply(image(applyAgentCwd(path)))
1323
- return "Saved image to ${path}"
1324
- }
1325
-
1326
- static const mainAgentTools = [
1327
- researchAgent.partial(allowHandoff: false),
1328
- codeAgent.partial(allowHandoff: false),
1329
- reviewAgent.partial(allowHandoff: false),
1330
- oracleAgent.partial(allowHandoff: false),
1331
- explorerAgent.partial(allowHandoff: false),
1332
- generateImageFile,
1333
- ]
1334
-
1335
- // MCP tools are appended to the coordinator's tools. ORDERING CONTRACT:
1336
- // maybeLoadMcp (session start, in main()) must run before mainAgent's first
1337
- // turn, or MCP tools silently vanish.
1338
- let mcpTools: any[] = []
1339
- // Per-server load outcome ("connected" / "unavailable"), for /mcp.
1340
- let mcpServerStatus: Record<string, string> = {}
1341
-
1342
- export def setMcpTools(tools: any[]) {
1343
- mcpTools = tools
1344
- }
1345
-
1346
- def setMcpServerStatus(status: Record<string, string>) {
1347
- mcpServerStatus = status
1348
- }
1349
-
1350
- // MCP OAuth notification. The @agency-lang/mcp package opens the browser itself
1351
- // (macOS-only today); we only print the URL so the user can complete auth.
1352
- def onMcpOAuth(data: any) {
1353
- print(color.yellow("MCP authorization needed — opening browser. If it does not open, visit:\n${data.authUrl}"))
1354
- }
1355
-
1356
- /** Load MCP tools from the project agency.json merged with the global settings
1357
- and hand them to the coordinator. No-op when @agency-lang/mcp is not installed
1358
- or no servers are configured. loadMcpTools warns-and-skips internally on any
1359
- per-server failure, so it always returns an array. */
1360
- def maybeLoadMcp(settings: Settings) {
1361
- if (!isMcpAvailable()) {
1362
- return
1363
- }
1364
- const merged = mergeMcpServers(getMcpServers(settings), readProjectMcpConfig(cwd()))
1365
- if (keys(merged).length == 0) {
1366
- return
1367
- }
1368
- // Always returns a result (per-server failures warn-and-skip internally), so
1369
- // there is no Failure branch. The status map drives /mcp.
1370
- const loaded = loadMcpToolsWithStatus(merged, onMcpOAuth)
1371
- setMcpTools(loaded.tools)
1372
- setMcpServerStatus(loaded.status)
1373
- }
1374
-
1375
- /** Enable memory when the capability profile allows it. When the user
1376
- pointed the embedding slot at a provider, embeddings run there. A
1377
- missing API key degrades to the default embedding behavior with one
1378
- notice. It never blocks startup. */
1379
- // Whether startup actually enabled memory WITH the embedding override.
1380
- // The pause guard in reactToSlotChange consults this instead of
1381
- // re-deriving from the slots: a keyless override took the fallback path,
1382
- // so memory runs on DERIVED embeddings and a main-provider change still
1383
- // shifts the embedding space. Exported mutator so tests can drive the
1384
- // guard directly.
1385
- let _memoryEmbeddingsPinned = false
1386
-
1387
- export def markMemoryEmbeddingsPinned(pinned: boolean) {
1388
- _memoryEmbeddingsPinned = pinned
1389
- }
1390
-
1391
- def maybeEnableMemory() {
1392
- const status = embeddingKeyStatus(getResolvedSlots())
1393
- const plan = memoryEnablePlan(getCapabilities().memory, status)
1394
- markMemoryEmbeddingsPinned(plan == "enable-override")
1395
- if (plan == "skip") {
1396
- return
1397
- }
1398
- if (plan == "enable-override") {
1399
- enableAgentMemory(status.override)
1400
- return
1401
- }
1402
- if (plan == "enable-fallback") {
1403
- print(
1404
- color.dim(
1405
- "Memory: the embedding slot needs ${status.varName}, which is not set. Falling back to the default embedding behavior.",
1406
- ),
1407
- )
1408
- }
1409
- enableAgentMemory()
1410
- }
1411
-
1412
- def mainAgent(prompt: string | (string | Attachment)[]): string {
1413
- const doSummarize = getCapabilities().summarize
1414
- thread(label: "main", summarize: doSummarize, session: "main") {
1415
- setMemoryId("main")
1416
- if (first) {
1417
- // `_context` carries the per-run grounding (date, cwd, AGENTS.md),
1418
- // set by `setupSession`. Appending it to the system prompt is what
1419
- // actually gets that context to the LLM.
1420
- let sysPrompt = MAIN_PROMPT_LARGE
1421
- if (getCapabilities().prompt == "small") {
1422
- sysPrompt = MAIN_PROMPT_SMALL
1423
- }
1424
- systemMessage("${sysPrompt}${_context}")
1425
- first = false
1426
- }
1427
- const result = llm(prompt, {
1428
- memory: true,
1429
- tools: [...mainAgentTools, ...mcpTools]
1430
- })
1431
- }
1432
- return result
1433
- }
1434
-
1435
- // Dispatch one turn. `target` empty (or "main") runs the coordinator
1436
- // `mainAgent`, which routes as usual; any subagent name routes the turn
1437
- // directly to that subagent. All subagents share `(userMsg, allowHandoff)`
1438
- // and the seed turn never hands off (allowHandoff: false). Used by both
1439
- // the one-shot path and the interactive seed turn.
1440
- export def agentReplyVia(target: string, userMsg: string): string {
1441
- const expanded = expandSlash(userMsg, projectCommands)
1442
- if (target == "code") {
1443
- return codeAgent(expanded, false)
1444
- }
1445
- if (target == "research") {
1446
- return researchAgent(expanded, false)
1447
- }
1448
- if (target == "oracle") {
1449
- return oracleAgent(expanded, false)
1450
- }
1451
- if (target == "explorer") {
1452
- return explorerAgent(expanded, false)
1453
- }
1454
- if (target == "review") {
1455
- return reviewAgent(expanded, false)
1456
- }
1457
- // Auto-attach image/PDF files the user referenced (drag-drop or typed
1458
- // path), filtered to what the resolved model accepts. Never silent:
1459
- // every attach and every skip prints a visible line.
1460
- const detected = modalityFilter(detectAttachments(expanded))
1461
- for (skippedFile in detected.skipped) {
1462
- pushMessage(
1463
- color.yellow("📎 skipped ${skippedFile.label} (${skippedFile.reason})"),
1464
- )
1465
- }
1466
- if (detected.attached.length == 0) {
1467
- // Deliberate special case: a text-only turn stays a bare string. A
1468
- // one-element array is API-equivalent, but the stored thread message
1469
- // shape (string vs parts array) — and with it every serialized
1470
- // session and message fixture — would change for EVERY turn.
1471
- return mainAgent(expanded)
1472
- }
1473
- for (item in detected.attached) {
1474
- pushMessage(color.dim("📎 attached ${item.label}"))
1475
- }
1476
- const attachments = map(detected.attached) as item {
1477
- return item.attachment
1478
- }
1479
- const parts: (string | Attachment)[] = [expanded, ...attachments]
1480
- return mainAgent(parts)
1481
- }
1482
-
1483
- // The agent's core turn, decoupled from the terminal: expand any project
1484
- // slash command, then run the prompt through `mainAgent` and return the
1485
- // reply. The REPL (`main` / `_runTurn`) owns input, output, and built-in
1486
- // commands; everything the *agent* does for a user message lives here, so
1487
- // it can be driven and tested without a terminal or user input. See
1488
- // `tests/agentTurn.agency`.
1489
- export def agentReply(userMsg: string): string {
1490
- return agentReplyVia("", userMsg)
1491
- }
1492
-
1493
- def roundedCost(): string {
1494
- return "$${getCost().toFixed(4)}"
1495
- }
1496
-
1497
- def _buildStatus(): { left: string; right: string; context: string } {
1498
- return {
1499
- left: "",
1500
- right: roundedCost(),
1501
- context: ""
1502
- }
1503
- }
1504
-
1505
- def sample(arr: any[]): any {
1506
- return arr[Math.floor(Math.random() * arr.length)]
1507
- }
1508
-
1509
- def printHeader() {
1510
- const fig = sample(figs)
1511
- const data = box(
1512
- title: "Agency",
1513
- padding: 1,
1514
- borderColor: "cyan",
1515
- titleColor: "cyan",
1516
- width: "full",
1517
- ) as b {
1518
- b.row(gap: 1) as r {
1519
- r.column(width: "66%") as left {
1520
- left.text("Welcome to the Agency Agent!", bold: true)
1521
- left.text("Ask me to write code, look up docs, or just chat.")
1522
- left.text("All costs are estimates. Actual costs may be higher.", dim: true)
1523
- left.hline()
1524
- left.text("Getting Started", bold: true, fgColor: "cyan")
1525
- left.text("/help for commands · /exit to quit", dim: true)
1526
- }
1527
- r.vline()
1528
- r.column(width: "30%", align: "center") as right {
1529
- right.raw(fig, align: "center")
1530
- }
1531
- }
1532
- }
1533
- print(render(data, color: true))
1534
- }
1535
-
1536
- // Print `--policy` usage and list the built-in policies (name + one-line
1537
- // description). Shown when `--policy` is passed with no value.
1538
- def printPolicyHelp() {
1539
- print(color.bold("Usage: agency agent --policy <name | path>"))
1540
- print(
1541
- "Select the approval policy for this run: a built-in name below, or a path to a policy JSON file.",
1542
- )
1543
- print("")
1544
- print(color.bold("Built-in policies:"))
1545
- for (p in BUILTIN_POLICIES) {
1546
- print(" ${color.cyan(p.name)}")
1547
- print(" ${p.description}")
1548
- }
1549
- }
1550
-
1551
- def givePolicyChoice() {
1552
- const title = "Welcome to the agency agent. Please pick a policy to start."
1553
- const body = "Don't worry, you can change this later. The policy just controls how the agent asks for your approval when it wants to do something. You can also create your own custom policy file at ${POLICY_PATH} and the agent will use it automatically."
1554
- let items: ChoiceItem[] = [
1555
- {
1556
- key: "minimal",
1557
- label: "minimal default policy, you do most approvals manually"
1558
- },
1559
- {
1560
- key: "recommended",
1561
- label: "recommended default policy, allow reading files and browsing the web, no writes"
1562
- },
1563
- ]
1564
-
1565
- const answer = chooseOption(title, body, items, allowFreeText: true)
1566
- return match(answer) {
1567
- "minimal" => minimalAutoApprovePolicy
1568
- "recommended" => recommendedAutoApprovePolicy
1569
- }
1570
- }
1571
-
1572
- // Shared session setup for both interactive and one-shot modes. Builds
1573
- // the per-run grounding context, loads (or initializes) the policy, and
1574
- // returns the installed CLI policy handler. `interactive` gates the
1575
- // first-run policy-choice prompt: one-shot has no user to answer it, so
1576
- // it falls back to the recommended default (reads/web auto-approved;
1577
- // writes still require approval, which a non-interactive run can't
1578
- // grant — those tasks block, which is the safe behavior).
1579
154
  def setupSession(interactive: boolean): any {
1580
- // Point every path-taking tool at the user's working directory so the
1581
- // agent's relative file/shell commands resolve against where the user
1582
- // launched it. The user (via the agent) can change this later with
1583
- // setAgentCwd.
1584
155
  setAgentCwd(cwd())
1585
156
 
1586
157
  // Grounding: the LLM shouldn't have to ask where it is or what day it
1587
- // is. Project context: inline an AGENTS.md from the workspace root if
1588
- // present so the LLM follows the project's conventions.
158
+ // is. Also load `AGENTS.md` if present.
1589
159
  const projectContext = loadAgentsMd(cwd()) with approve
1590
- _context = "\n\nCurrent date: ${today()}\nCurrent working directory: ${cwd()}${projectContext}"
160
+ const grounding = """
1591
161
 
1592
- // Which file the handler persists against, and an optional in-memory
1593
- // policy to start from. Normally the user's saved policy loaded from
1594
- // POLICY_PATH; a `--policy` override redirects this (see below) so the
1595
- // saved policy is never read or written.
1596
- let policyFile = POLICY_PATH
1597
- let sessionPolicy: any = null
162
+ Current date: ${today()}
163
+ Current working directory: ${cwd()}
164
+ ${projectContext}
165
+ """
166
+ setGroundingContext(grounding)
167
+
168
+ const { policyFile, sessionPolicy } = getPolicyForAgent(_policyArg, interactive)
1598
169
 
1599
- if (_policyArg != "") {
1600
- // `--policy` override: a built-in name or a path to a policy file.
1601
- // The cwd-scoped built-ins pin the launch directory, so we resolve
1602
- // them against `cwd()` (what `setAgentCwd` just stored, and what the
1603
- // write/git/bash interrupts resolve their default paths back to).
1604
- const builtin = builtinPolicy(_policyArg, cwd())
1605
- if (builtin != null) {
1606
- // Hand the policy to the handler in memory (no disk write): a
1607
- // one-off, cwd-scoped override must not clobber the saved policy
1608
- // or leak into a later run from a different directory. Any new
1609
- // interactive "always" decision persists to the session file.
1610
- policyFile = SESSION_POLICY_PATH
1611
- sessionPolicy = builtin
1612
- } else {
1613
- // Not a built-in name — treat it as a policy file path and use it
1614
- // directly (the handler loads/persists it). Validate up front so a
1615
- // typo fails fast instead of silently starting from empty.
1616
- const loaded = parsePolicyFile(_policyArg)
1617
- if (loaded is failure(f)) {
1618
- print(
1619
- color.red(
1620
- "--policy '${_policyArg}' is neither a built-in policy (${builtinPolicyNames().join(", ")}) nor a readable policy file (${f.status}).",
1621
- ),
1622
- )
1623
- process.exit(1)
1624
- }
1625
- policyFile = _policyArg
1626
- }
1627
- } else {
1628
- const policy = parsePolicyFile(POLICY_PATH)
1629
- if (policy is failure(f)) {
1630
- if (f.status == "doesnt-exist") {
1631
- if (interactive) {
1632
- print(color.yellow("No existing policy found at ${POLICY_PATH}."))
1633
- setPolicy(POLICY_PATH, givePolicyChoice())
1634
- } else {
1635
- setPolicy(POLICY_PATH, recommendedAutoApprovePolicy)
1636
- }
1637
- } else {
1638
- print(color.red("Failed to load policy: ${JSON.stringify(f.error)}"))
1639
- process.exit(1)
1640
- }
1641
- } else {
1642
- setPolicy(POLICY_PATH, policy.value)
1643
- }
1644
- }
1645
- // Bind the handler to a local var so `with handler` parses (the
1646
- // `with` clause only accepts an identifier, not a call expression).
1647
170
  return cliPolicyHandler(
1648
171
  file: policyFile,
1649
172
  fields: ALWAYS_FIELDS,
@@ -1651,176 +174,42 @@ def setupSession(interactive: boolean): any {
1651
174
  )
1652
175
  }
1653
176
 
1654
- // One-shot entry: run a single turn through the same `mainAgent` the
1655
- // REPL uses, with the same session setup and policy handler, and return
1656
- // the reply. Used for `agency agent -p "..."`, a positional query, or
1657
- // piped stdin. Slash commands are expanded so `-p /foo bar` works like
1658
- // typing it in the REPL; the loop-only built-ins (`/exit` etc.) are
1659
- // meaningless here and aren't checked.
1660
177
  def oneShotAgent(target: string, prompt: string): string {
1661
- _isInteractive = false
1662
- const handler = setupSession(false)
1663
- let reply: string = ""
178
+ setInteractive(false)
179
+ const handler = setupSession(interactive: false)
1664
180
  handle {
1665
- // `try` converts a terminal LLM failure (retries exhausted on a dropped
1666
- // connection / timeout) into a friendly message; aborts/interrupts still
1667
- // propagate to the handler below.
1668
- const result = try agentReplyVia(target, prompt)
1669
- if (result is success(r)) {
1670
- reply = r
1671
- } else if (result is failure(f)) {
1672
- reply = formatTurnFailure("${f.error}")
181
+ const result = try runTurn(target, prompt)
182
+ return match(result) {
183
+ success(r) => r
184
+ failure(f) => formatTurnFailure("${f.error}")
1673
185
  }
1674
- } with (data) {
1675
- return handler(data)
1676
- }
1677
- return reply
186
+ } with handler
1678
187
  }
1679
188
 
1680
- // Render one seeded turn into the REPL scroll area: echo the auto-run
1681
- // prompt so the user sees what was asked, then push the agent's reply.
1682
- // Mirrors the reply-rendering half of `_runTurn`.
1683
- def _runSeedTurn(target: string, msg: string) {
1684
- pushMessage(color.dim("> ${msg}"))
1685
- const result = try agentReplyVia(target, msg)
1686
- if (result is success(reply)) {
1687
- if (reply != "" && reply != null && reply != undefined) {
1688
- pushMessage(highlight("${reply}\n", language: "markdown"))
1689
- } else {
1690
- pushMessage(color.red("No reply generated."))
1691
- }
1692
- } else if (result is failure(f)) {
1693
- pushMessage(color.red(formatTurnFailure("${f.error}")))
1694
- }
1695
- }
1696
-
1697
- // Start the interactive REPL. When `seedPrompt` is non-empty it is run as
1698
- // the first turn (routed via `seedTarget`) *inside* the handle block so
1699
- // its interrupts reach the policy `handler`; the user is then left at the
1700
- // prompt. `seedPrompt == ""` is the plain REPL with no seed. Subsequent
1701
- // turns always go through `_runTurn` (the coordinator) regardless of
1702
- // `seedTarget` — the target only kicks off the first turn.
1703
- def startInteractive(handler: any, seedTarget: string, seedPrompt: string) {
1704
- handle {
1705
- if (seedPrompt != "") {
1706
- _runSeedTurn(seedTarget, seedPrompt)
1707
- }
1708
- repl(
1709
- status: _buildStatus,
1710
- onSubmit: _runTurn,
1711
- prompt: "> ",
1712
- historyFile: HISTORY_PATH,
1713
- historyMax: 1000,
1714
- paletteCommands: mergedPalette(),
1715
- )
1716
- } with (data) {
1717
- return handler(data)
1718
- }
1719
- print(color.cyan("\nGoodbye!"))
1720
- }
189
+ /* A seeded turn is if the user invokes the Agency agent with
190
+ an initial prompt by using the agency doctor command, for example.
191
+ It means that agent starts with an initial prompt already there to respond to. */
1721
192
 
1722
193
  node main() {
1723
194
  // Parse CLI flags first — `parseArgs` exits on --help / --version /
1724
195
  // usage errors, before any handlers or the TUI are installed.
1725
- const args = parseArgs(
1726
- {
1727
- programName: "agency agent",
1728
- description: "Agency language assistant — interactive REPL by default; one-shot when piped or passed a query / --print.",
1729
- version: getVersion(),
1730
- flags: {
1731
- print: {
1732
- type: "boolean",
1733
- short: "p",
1734
- description: "Run one-shot: print the reply to stdout and exit (no REPL)"
1735
- },
1736
- debug: {
1737
- type: "boolean",
1738
- description: "Log tool returns (toolName, result, timing). Same as AGENT_DEBUG=1"
1739
- },
1740
- verbose: {
1741
- type: "boolean",
1742
- description: "Echo tool-call starts to stdout in non-interactive mode"
1743
- },
1744
- model: {
1745
- type: "string",
1746
- description: "Model for all LLM calls (overrides provider auto-detection)"
1747
- },
1748
- fastmodel: {
1749
- type: "string",
1750
- description: "Model for ordinary work (default: per detected provider)"
1751
- },
1752
- slowmodel: {
1753
- type: "string",
1754
- description: "Model for deep reasoning, e.g. the oracle/explorer subagents"
1755
- },
1756
- provider: {
1757
- type: "string",
1758
- description: "Force the LLM provider. Given alone (openai/anthropic/google/openrouter) it selects that provider's default models and skips env auto-detection; pair it with --model for any other provider (e.g. litellm, openai-compat, or a custom/local model)"
1759
- },
1760
- interactive: {
1761
- type: "boolean",
1762
- short: "i",
1763
- description: "Run the given prompt as the first turn of an interactive session, then hand over the REPL (instead of one-shot)"
1764
- },
1765
- agent: {
1766
- type: "string",
1767
- description: "Route the starting prompt to a named subagent: code, research, oracle, explorer, review (default: coordinator)"
1768
- },
1769
- policy: {
1770
- type: "string",
1771
- optional: true,
1772
- description: "Approval policy for this run: a built-in name (minimal, recommended, with-writes, approve-all) or a path to a policy JSON file. with-writes auto-approves file writes and git changes scoped to the current directory and its children; approve-all approves EVERY interrupt with no scoping (sandbox use only). Overrides the saved policy without persisting it. Pass --policy with no value to list the built-in policies."
1773
- },
1774
- "agent-home": {
1775
- type: "string",
1776
- description: "Directory to use instead of ~/.agency-agent for settings, policy, and history (equivalent to the AGENCY_AGENT_HOME env var; the flag wins when both are set)"
1777
- },
1778
- local: {
1779
- type: "string",
1780
- optional: true,
1781
- description: "Run a local model (downloads if needed): a curated short name, an hf: URI, or a .gguf path. Run without a value for guided setup. Pins all slots to the local model; mutually exclusive with --model/--fastmodel/--slowmodel. Requires: npm i -g smoltalk-llama-cpp"
1782
- },
1783
- "local-model": {
1784
- type: "string",
1785
- optional: true,
1786
- description: "Deprecated alias for --local."
1787
- },
1788
- trace: {
1789
- type: "string",
1790
- optional: true,
1791
- description: "Write an execution trace to this file for debugging (bare --trace writes <runId>.agencytrace in the current directory)"
1792
- },
1793
- "log-file": {
1794
- type: "string",
1795
- description: "Append structured statelog events (one JSON object per line) to this file for debugging"
1796
- },
1797
- "max-tool-call-rounds": {
1798
- type: "number",
1799
- description: "Max LLM tool-call rounds before a tool loop halts (default 10 interactive, 50 in one-shot/-p mode)"
1800
- },
1801
- "max-tool-result-chars": {
1802
- type: "number",
1803
- description: "Max chars of a single tool result fed back to the model (0 disables; default 100000)"
1804
- }
1805
- }
1806
- },
1807
- )
196
+ const args = parseAgentArgs()
1808
197
 
1809
- // NOTE: --trace / --log-file / --agent-home are declared here only for
198
+ // NOTE: --trace / --log / --agent-home are declared here only for
1810
199
  // --help and so parseArgs accepts them. runBundledAgent extracts them from
1811
200
  // the forwarded args and passes them to this process via env vars
1812
201
  // (AGENCY_CONFIG_OVERRIDES for the first two, AGENCY_AGENT_HOME for the
1813
- // last), read before this main() runs — the RuntimeContext consumes the
1814
- // config overrides at construction, and lib/config.agency derives the
1815
- // settings/policy/history paths from the agent home in its static-const
1816
- // initializers. Do not re-handle them here.
202
+ // last).
1817
203
 
1818
204
  if (args.flags.debug) {
1819
- AGENT_DEBUG = true
205
+ setDebug(true)
1820
206
  }
1821
207
  if (args.flags.verbose) {
1822
- VERBOSE = true
208
+ setVerbose(true)
1823
209
  }
210
+
211
+ checkMainPrompts()
212
+
1824
213
  // `--policy` is an optional-value flag: a bare `--policy` (no name or
1825
214
  // path) prints the usage + the built-in policies and exits, rather than
1826
215
  // silently doing nothing.
@@ -1830,100 +219,7 @@ node main() {
1830
219
  }
1831
220
  _policyArg = args.flags.policy ?? ""
1832
221
 
1833
- // Model setup. `--local` (deprecated alias: `--local-model`) is an optional-
1834
- // value flag with three states: absent (null); bare empty-string for guided
1835
- // setup; a value for that local model. `--local` and the hosted flags
1836
- // (--model / --fastmodel / --slowmodel) are mutually exclusive -- local and
1837
- // hosted are different in kind (provider llama-cpp, no embedding endpoint).
1838
- const localVal = args.flags["local"] ?? args.flags["local-model"]
1839
- const modelArg = args.flags.model ?? ""
1840
- const hasModelFlags = modelArg != "" || (args.flags.fastmodel ?? "") != "" || (args.flags.slowmodel ?? "") != ""
1841
- if (localVal != null && hasModelFlags) {
1842
- print(
1843
- color.red("Pass either --model (hosted) or --local (local), not both."),
1844
- )
1845
- process.exit(1)
1846
- }
1847
- if (localVal == "") {
1848
- // Bare --local: guided setup. Non-interactive can't prompt, so keep the
1849
- // print-catalog-and-exit behavior there.
1850
- if (!isTTY()) {
1851
- printLocalCatalog()
1852
- process.exit(0)
1853
- }
1854
- if (!localModelsSupported()) {
1855
- print(color.yellow("Local models need the smoltalk-llama-cpp package."))
1856
- print("Install it, then re-run: ! npm i -g smoltalk-llama-cpp")
1857
- process.exit(1)
1858
- }
1859
- let items: ChoiceItem[] = []
1860
- for (modelName in listModelNames()) {
1861
- items.push({
1862
- key: modelName.name,
1863
- label: modelName.name
1864
- })
1865
- }
1866
- const choice = chooseOption(
1867
- "Local model",
1868
- "Pick a model, or type an hf: URI / .gguf path (downloads on first use):",
1869
- items,
1870
- allowFreeText: true,
1871
- allowCancel: true,
1872
- )
1873
- if (choice == "" || choice == null) {
1874
- process.exit(0)
1875
- }
1876
- configureLocalModel(choice)
1877
- configureSearch(true)
1878
- // fall through into the session on the chosen local model
1879
- } else if (localVal != null) {
1880
- configureLocalModel(localVal)
1881
- configureSearch(true)
1882
- } else {
1883
- // Hosted path. --model accepts `slot=model` (per-slot) or a bare model
1884
- // (global pin); explicit --fastmodel/--slowmodel win over a --model slot=.
1885
- const parsed = parseModelFlag(modelArg)
1886
- let modelGlobal = ""
1887
- let fastFlag = ""
1888
- let slowFlag = ""
1889
- let embeddingFlag = ""
1890
- if (modelArg != "") {
1891
- if (parsed.slot == "") {
1892
- modelGlobal = parsed.model
1893
- } else if (parsed.slot == "main") {
1894
- fastFlag = parsed.model
1895
- } else if (parsed.slot == "reasoning") {
1896
- slowFlag = parsed.model
1897
- } else if (parsed.slot == "embedding") {
1898
- if (!embeddingSpecHasProvider(parsed.model)) {
1899
- print(
1900
- color.red(
1901
- "Embedding models need the provider/model form, e.g. --model embedding=openai/text-embedding-3-small.",
1902
- ),
1903
- )
1904
- process.exit(1)
1905
- }
1906
- embeddingFlag = parsed.model
1907
- } else {
1908
- print(
1909
- color.red(
1910
- "Unknown model slot '${parsed.slot}' in --model. Valid slots: ${SLOTS.join(", ")}.",
1911
- ),
1912
- )
1913
- process.exit(1)
1914
- }
1915
- }
1916
- const fm = args.flags.fastmodel ?? ""
1917
- const sm = args.flags.slowmodel ?? ""
1918
- if (fm != "") {
1919
- fastFlag = fm
1920
- }
1921
- if (sm != "") {
1922
- slowFlag = sm
1923
- }
1924
- configureModels(modelGlobal, fastFlag, slowFlag, embeddingFlag, args.flags.provider ?? "")
1925
- configureSearch(false)
1926
- }
222
+ pickModelsForAgent(args)
1927
223
 
1928
224
  // Persistent knowledge graph, gated on the capability profile. Must run
1929
225
  // before any handler/REPL is installed.
@@ -1939,83 +235,53 @@ node main() {
1939
235
  const positionalQuery = args.positionals.join(" ")
1940
236
  const hasQuery = positionalQuery != ""
1941
237
  const startAgent = args.flags.agent ?? ""
238
+ // Validate the target subagent name up front (empty = coordinator).
239
+ if (startAgent != "" && !START_AGENTS.includes(startAgent)) {
240
+ print(
241
+ color.red(
242
+ "Unknown --agent value: ${startAgent}. Valid: ${START_AGENTS.join(", ")}",
243
+ ),
244
+ )
245
+ process.exit(1)
246
+ }
247
+
1942
248
  const wantInteractive = args.flags.interactive
1943
249
 
1944
250
  // Seeded interactive: run the prompt as the first turn, then hand over the
1945
251
  // REPL (needs a TTY + query, and not --print). Everything else is one-shot.
1946
252
  const seededInteractive = wantInteractive && hasQuery && isTTY() && !args.flags.print
1947
- const runningOneShot = !seededInteractive && (args.flags.print || hasQuery || !isTTY())
253
+ const isOneShot = !seededInteractive && (args.flags.print || hasQuery || !isTTY())
1948
254
 
1949
- // Tool-loop caps. One-shot runs (--print / piped / a positional query) have
1950
- // no REPL to continue an autonomous task, so maxToolCallRounds defaults
1951
- // higher (resolveMaxToolCallRounds); an explicit --max-tool-call-rounds always
1952
- // wins. Set as branch-scoped defaults on the root branch BEFORE any subagent
1953
- // is dispatched, so every (fork-seeded) subagent inherits them. setLlmOptions
1954
- // merges only present keys, so this never clobbers the model defaults above.
1955
- // Separate calls, each gated on its own value: setLlmOptions only skips
1956
- // `undefined`, not `null`, so passing an absent key would clobber the bag.
1957
- const maxRounds = resolveMaxToolCallRounds(args.flags["max-tool-call-rounds"] ?? null, runningOneShot)
255
+ const maxRounds = resolveMaxToolCallRounds(
256
+ args.flags["max-tool-call-rounds"] ?? null,
257
+ isOneShot,
258
+ )
1958
259
  if (maxRounds != null) {
1959
- setLlmOptions({ maxToolCallRounds: maxRounds })
260
+ setLlmOptions({
261
+ maxToolCallRounds: maxRounds
262
+ })
1960
263
  }
1961
264
  const maxResultChars = args.flags["max-tool-result-chars"]
1962
265
  if (maxResultChars != null) {
1963
- setLlmOptions({ maxToolResultChars: maxResultChars })
266
+ setLlmOptions({
267
+ maxToolResultChars: maxResultChars
268
+ })
1964
269
  }
1965
270
 
1966
- // Per-model default output cap from the capability profile. The hosted
1967
- // default of 20000 carries the adaptive-thinking empty-reply fix that
1968
- // used to live here as a TEMPORARY block. Local profiles cap lower.
1969
- // Branch-scoped, so every subagent inherits it. A per-call
1970
- // llm(..., { maxTokens }) still wins, e.g. the summarizer's 256.
1971
271
  const capsMaxTokens = getCapabilities().maxTokens
1972
272
  if (capsMaxTokens != null) {
1973
- setLlmOptions({ maxTokens: capsMaxTokens })
273
+ setLlmOptions({
274
+ maxTokens: capsMaxTokens
275
+ })
1974
276
  }
1975
277
 
1976
278
  // One-shot autonomy: tell the code subagent there is no human to answer
1977
279
  // questions and no next turn, so it must drive to a finished artifact.
1978
280
  // Set before any dispatch so both the pinned `--agent code` path and the
1979
281
  // coordinator (which calls codeAgent as a tool) pick it up.
1980
- setCodeOneShot(runningOneShot)
282
+ setCodeOneShot(isOneShot)
1981
283
 
1982
- // Validate the target subagent name up front (empty = coordinator).
1983
- if (startAgent != "" && !START_AGENTS.includes(startAgent)) {
1984
- print(
1985
- color.red(
1986
- "Unknown --agent value: ${startAgent}. Valid: ${START_AGENTS.join(", ")}",
1987
- ),
1988
- )
1989
- process.exit(1)
1990
- }
1991
-
1992
- // Seeded interactive: run the given prompt as the first turn, then hand
1993
- // the REPL to the user. Requires a seed prompt and a TTY (the REPL reads
1994
- // stdin). `--print` wins if both are passed — its whole job is to print
1995
- // and exit with no REPL. Without a TTY (or with `--print`) we fall
1996
- // through to one-shot below; `--interactive` with no prompt falls through
1997
- // to the plain REPL.
1998
- if (seededInteractive) {
1999
- setTitle("Agency Agent")
2000
- clearScreen()
2001
- printHeader()
2002
- const seededHandler = setupSession(true)
2003
- startInteractive(seededHandler, startAgent, positionalQuery)
2004
- process.exit(0)
2005
- }
2006
-
2007
- // One-shot invocation: run one turn through the same agent the REPL uses
2008
- // and write the reply to stdout. No banner, no REPL. Entered when
2009
- // `--print` / `-p` is passed, a positional query is given, or stdin is
2010
- // piped (no TTY) — so the agent behaves like a Unix filter:
2011
- // `echo "..." | agency agent`. `--interactive` is NOT a one-shot trigger
2012
- // on its own: with a TTY and no prompt it falls through to the plain
2013
- // REPL; without a TTY the `!isTTY()` check below routes it here to
2014
- // degrade gracefully. The prompt comes from the positional when present,
2015
- // otherwise from stdin. (Title/clearScreen are skipped so piped output
2016
- // stays free of escape codes.)
2017
- const forceOneShot = args.flags.print || hasQuery
2018
- if (forceOneShot || !isTTY()) {
284
+ if (isOneShot) {
2019
285
  let prompt = positionalQuery
2020
286
  if (!hasQuery) {
2021
287
  const fromStdin = readStdin()
@@ -2025,17 +291,13 @@ node main() {
2025
291
  prompt = fromStdin
2026
292
  }
2027
293
  print(oneShotAgent(startAgent, prompt))
2028
- process.exit(0)
294
+ const roundedCost = "$${getCost().toFixed(4)}"
295
+ print(color.dim("\nSession cost: ${roundedCost}"))
296
+ } else {
297
+ setTitle("Agency Agent")
298
+ clearScreen()
299
+ print(getHeader())
300
+ const handler = setupSession(interactive: true)
301
+ startInteractive(handler, startAgent, positionalQuery)
2029
302
  }
2030
-
2031
- // Plain interactive REPL (no seed). `startInteractive` owns the runloop;
2032
- // every Enter dispatches into `_runTurn` which calls `mainAgent`.
2033
- // Interrupts raised during a turn propagate to the policy handler
2034
- // installed by the enclosing `handle` block via the AsyncLocalStorage
2035
- // handler stack.
2036
- setTitle("Agency Agent")
2037
- clearScreen()
2038
- printHeader()
2039
- const handler = setupSession(true)
2040
- startInteractive(handler, "", "")
2041
303
  }