agency-lang 0.1.2 → 0.2.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 (405) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1 -1
  3. package/dist/lib/agents/judge.js +12 -5
  4. package/dist/lib/agents/policy/agent.agency +29 -21
  5. package/dist/lib/agents/review/agent.js +12 -5
  6. package/dist/lib/backends/agencyGenerator.d.ts +10 -0
  7. package/dist/lib/backends/agencyGenerator.js +79 -22
  8. package/dist/lib/backends/agencyGenerator.test.js +85 -0
  9. package/dist/lib/backends/typescriptBuilder.d.ts +64 -0
  10. package/dist/lib/backends/typescriptBuilder.integration.test.js +5 -46
  11. package/dist/lib/backends/typescriptBuilder.js +294 -11
  12. package/dist/lib/backends/typescriptGenerator/typeToString.d.ts +1 -1
  13. package/dist/lib/backends/typescriptGenerator/typeToString.js +11 -8
  14. package/dist/lib/backends/typescriptGenerator.integration.test.js +6 -52
  15. package/dist/lib/cli/commands.d.ts +6 -1
  16. package/dist/lib/cli/commands.js +76 -7
  17. package/dist/lib/cli/coverage.d.ts +21 -2
  18. package/dist/lib/cli/coverage.js +51 -2
  19. package/dist/lib/cli/doc.js +29 -6
  20. package/dist/lib/cli/doc.test.js +38 -0
  21. package/dist/lib/cli/installLocation.d.ts +3 -0
  22. package/dist/lib/cli/installLocation.js +40 -0
  23. package/dist/lib/cli/installLocation.test.js +32 -0
  24. package/dist/lib/cli/logsView.d.ts +3 -0
  25. package/dist/lib/cli/logsView.js +96 -0
  26. package/dist/lib/cli/pack.d.ts +10 -0
  27. package/dist/lib/cli/pack.js +205 -0
  28. package/dist/lib/cli/pack.test.d.ts +1 -0
  29. package/dist/lib/cli/pack.test.js +131 -0
  30. package/dist/lib/cli/policy.js +31 -7
  31. package/dist/lib/cli/run.spawn.test.d.ts +1 -0
  32. package/dist/lib/cli/run.spawn.test.js +53 -0
  33. package/dist/lib/cli/runBundledAgent.js +10 -4
  34. package/dist/lib/cli/runShim/register.mjs +5 -0
  35. package/dist/lib/cli/runShim/resolver.mjs +59 -0
  36. package/dist/lib/cli/runShim/resolver.test.d.ts +1 -0
  37. package/dist/lib/cli/runShim/resolver.test.js +69 -0
  38. package/dist/lib/cli/schedule/backends/github.d.ts +18 -0
  39. package/dist/lib/cli/schedule/backends/github.js +113 -0
  40. package/dist/lib/cli/schedule/backends/github.snapshot.test.d.ts +1 -0
  41. package/dist/lib/cli/schedule/backends/github.snapshot.test.js +50 -0
  42. package/dist/lib/cli/schedule/backends/github.test.d.ts +1 -0
  43. package/dist/lib/cli/schedule/backends/github.test.js +165 -0
  44. package/dist/lib/cli/schedule/backends/index.d.ts +3 -1
  45. package/dist/lib/cli/schedule/backends/index.js +4 -0
  46. package/dist/lib/cli/schedule/backends/index.test.d.ts +1 -0
  47. package/dist/lib/cli/schedule/backends/index.test.js +9 -0
  48. package/dist/lib/cli/schedule/backends/pinnedActions.d.ts +5 -0
  49. package/dist/lib/cli/schedule/backends/pinnedActions.js +16 -0
  50. package/dist/lib/cli/schedule/index.d.ts +11 -0
  51. package/dist/lib/cli/schedule/index.github.test.d.ts +1 -0
  52. package/dist/lib/cli/schedule/index.github.test.js +123 -0
  53. package/dist/lib/cli/schedule/index.js +56 -5
  54. package/dist/lib/cli/schedule/registry.d.ts +7 -0
  55. package/dist/lib/cli/test.js +8 -0
  56. package/dist/lib/codegenBuiltins/contextInjected.d.ts +56 -0
  57. package/dist/lib/codegenBuiltins/contextInjected.js +78 -0
  58. package/dist/lib/codegenBuiltins/contextInjected.test.d.ts +1 -0
  59. package/dist/lib/codegenBuiltins/contextInjected.test.js +57 -0
  60. package/dist/lib/compilationUnit.d.ts +8 -0
  61. package/dist/lib/compilationUnit.js +14 -0
  62. package/dist/lib/compiler/compile.js +1 -1
  63. package/dist/lib/compiler/compile.test.js +1 -1
  64. package/dist/lib/config.d.ts +180 -14
  65. package/dist/lib/config.js +59 -4
  66. package/dist/lib/config.test.js +67 -0
  67. package/dist/lib/constants.d.ts +20 -0
  68. package/dist/lib/constants.js +20 -0
  69. package/dist/lib/debugger/driver.js +12 -15
  70. package/dist/lib/debugger/driver.test.js +31 -13
  71. package/dist/lib/debugger/thread.test.js +3 -3
  72. package/dist/lib/debugger/trace.test.js +24 -38
  73. package/dist/lib/debugger/ui.js +33 -3
  74. package/dist/lib/formatter.js +3 -1
  75. package/dist/lib/importPaths.d.ts +7 -1
  76. package/dist/lib/importPaths.js +43 -12
  77. package/dist/lib/ir/prettyPrint.js +9 -1
  78. package/dist/lib/ir/prettyPrint.test.js +21 -0
  79. package/dist/lib/logsViewer/clipboard.d.ts +6 -0
  80. package/dist/lib/logsViewer/clipboard.js +61 -0
  81. package/dist/lib/logsViewer/clipboard.test.d.ts +1 -0
  82. package/dist/lib/logsViewer/clipboard.test.js +60 -0
  83. package/dist/lib/logsViewer/conversation.d.ts +20 -0
  84. package/dist/lib/logsViewer/conversation.js +91 -0
  85. package/dist/lib/logsViewer/conversation.test.d.ts +1 -0
  86. package/dist/lib/logsViewer/conversation.test.js +59 -0
  87. package/dist/lib/logsViewer/follow.d.ts +9 -0
  88. package/dist/lib/logsViewer/follow.js +53 -0
  89. package/dist/lib/logsViewer/follow.test.d.ts +1 -0
  90. package/dist/lib/logsViewer/follow.test.js +70 -0
  91. package/dist/lib/logsViewer/help.d.ts +9 -0
  92. package/dist/lib/logsViewer/help.js +60 -0
  93. package/dist/lib/logsViewer/input.d.ts +15 -0
  94. package/dist/lib/logsViewer/input.js +187 -0
  95. package/dist/lib/logsViewer/input.test.d.ts +1 -0
  96. package/dist/lib/logsViewer/input.test.js +163 -0
  97. package/dist/lib/logsViewer/jsonView/build.d.ts +3 -0
  98. package/dist/lib/logsViewer/jsonView/build.js +70 -0
  99. package/dist/lib/logsViewer/jsonView/build.test.d.ts +1 -0
  100. package/dist/lib/logsViewer/jsonView/build.test.js +113 -0
  101. package/dist/lib/logsViewer/jsonView/input.d.ts +12 -0
  102. package/dist/lib/logsViewer/jsonView/input.js +111 -0
  103. package/dist/lib/logsViewer/jsonView/input.test.d.ts +1 -0
  104. package/dist/lib/logsViewer/jsonView/input.test.js +76 -0
  105. package/dist/lib/logsViewer/jsonView/render.d.ts +18 -0
  106. package/dist/lib/logsViewer/jsonView/render.js +221 -0
  107. package/dist/lib/logsViewer/jsonView/render.test.d.ts +1 -0
  108. package/dist/lib/logsViewer/jsonView/render.test.js +93 -0
  109. package/dist/lib/logsViewer/jsonView/types.d.ts +22 -0
  110. package/dist/lib/logsViewer/jsonView/types.js +3 -0
  111. package/dist/lib/logsViewer/parse.d.ts +11 -0
  112. package/dist/lib/logsViewer/parse.js +61 -0
  113. package/dist/lib/logsViewer/parse.test.d.ts +1 -0
  114. package/dist/lib/logsViewer/parse.test.js +67 -0
  115. package/dist/lib/logsViewer/render.d.ts +20 -0
  116. package/dist/lib/logsViewer/render.js +243 -0
  117. package/dist/lib/logsViewer/render.test.d.ts +1 -0
  118. package/dist/lib/logsViewer/render.test.js +184 -0
  119. package/dist/lib/logsViewer/run.d.ts +16 -0
  120. package/dist/lib/logsViewer/run.js +293 -0
  121. package/dist/lib/logsViewer/run.test.d.ts +1 -0
  122. package/dist/lib/logsViewer/run.test.js +158 -0
  123. package/dist/lib/logsViewer/search.d.ts +8 -0
  124. package/dist/lib/logsViewer/search.js +119 -0
  125. package/dist/lib/logsViewer/search.test.d.ts +1 -0
  126. package/dist/lib/logsViewer/search.test.js +180 -0
  127. package/dist/lib/logsViewer/summary.d.ts +7 -0
  128. package/dist/lib/logsViewer/summary.js +153 -0
  129. package/dist/lib/logsViewer/summary.test.d.ts +1 -0
  130. package/dist/lib/logsViewer/summary.test.js +155 -0
  131. package/dist/lib/logsViewer/thresholds.d.ts +9 -0
  132. package/dist/lib/logsViewer/thresholds.js +22 -0
  133. package/dist/lib/logsViewer/thresholds.test.d.ts +1 -0
  134. package/dist/lib/logsViewer/thresholds.test.js +26 -0
  135. package/dist/lib/logsViewer/tree.d.ts +2 -0
  136. package/dist/lib/logsViewer/tree.js +247 -0
  137. package/dist/lib/logsViewer/tree.test.d.ts +1 -0
  138. package/dist/lib/logsViewer/tree.test.js +277 -0
  139. package/dist/lib/logsViewer/types.d.ts +40 -0
  140. package/dist/lib/logsViewer/types.js +1 -0
  141. package/dist/lib/lowering/patternLowering.d.ts +18 -0
  142. package/dist/lib/lowering/patternLowering.js +631 -0
  143. package/dist/lib/lowering/patternLowering.test.d.ts +8 -0
  144. package/dist/lib/lowering/patternLowering.test.js +383 -0
  145. package/dist/lib/lsp/builtinHover.d.ts +20 -0
  146. package/dist/lib/lsp/builtinHover.js +85 -0
  147. package/dist/lib/lsp/diagnostics.js +53 -0
  148. package/dist/lib/lsp/diagnostics.test.js +34 -0
  149. package/dist/lib/lsp/hover.js +41 -0
  150. package/dist/lib/lsp/hover.test.js +43 -0
  151. package/dist/lib/parser.d.ts +1 -1
  152. package/dist/lib/parser.js +27 -2
  153. package/dist/lib/parsers/blockArgument.test.js +7 -2
  154. package/dist/lib/parsers/expression.test.js +58 -0
  155. package/dist/lib/parsers/literals.test.js +33 -2
  156. package/dist/lib/parsers/parsers.d.ts +16 -0
  157. package/dist/lib/parsers/parsers.js +241 -17
  158. package/dist/lib/parsers/pattern.test.d.ts +1 -0
  159. package/dist/lib/parsers/pattern.test.js +672 -0
  160. package/dist/lib/parsers/typeHints.test.js +35 -0
  161. package/dist/lib/parsers/withModifier.test.js +10 -0
  162. package/dist/lib/preprocessors/typescriptPreprocessor.core.test.js +0 -551
  163. package/dist/lib/preprocessors/typescriptPreprocessor.d.ts +0 -8
  164. package/dist/lib/preprocessors/typescriptPreprocessor.integration.test.js +6 -50
  165. package/dist/lib/preprocessors/typescriptPreprocessor.js +0 -192
  166. package/dist/lib/runtime/agencyFunction.d.ts +5 -0
  167. package/dist/lib/runtime/agencyFunction.js +35 -0
  168. package/dist/lib/runtime/call.js +10 -0
  169. package/dist/lib/runtime/call.test.js +14 -0
  170. package/dist/lib/runtime/deterministicClient.d.ts +2 -1
  171. package/dist/lib/runtime/deterministicClient.js +12 -0
  172. package/dist/lib/runtime/interrupts.d.ts +1 -0
  173. package/dist/lib/runtime/interrupts.js +179 -76
  174. package/dist/lib/runtime/llmClient.d.ts +19 -0
  175. package/dist/lib/runtime/llmClient.js +9 -0
  176. package/dist/lib/runtime/memory/cacheEntry.d.ts +113 -0
  177. package/dist/lib/runtime/memory/cacheEntry.js +153 -0
  178. package/dist/lib/runtime/memory/cacheEntry.test.d.ts +1 -0
  179. package/dist/lib/runtime/memory/cacheEntry.test.js +136 -0
  180. package/dist/lib/runtime/memory/compaction.d.ts +21 -0
  181. package/dist/lib/runtime/memory/compaction.js +46 -0
  182. package/dist/lib/runtime/memory/compaction.test.d.ts +1 -0
  183. package/dist/lib/runtime/memory/compaction.test.js +87 -0
  184. package/dist/lib/runtime/memory/embeddings.d.ts +18 -0
  185. package/dist/lib/runtime/memory/embeddings.js +59 -0
  186. package/dist/lib/runtime/memory/embeddings.test.d.ts +1 -0
  187. package/dist/lib/runtime/memory/embeddings.test.js +65 -0
  188. package/dist/lib/runtime/memory/extraction.d.ts +43 -0
  189. package/dist/lib/runtime/memory/extraction.js +88 -0
  190. package/dist/lib/runtime/memory/extraction.test.d.ts +1 -0
  191. package/dist/lib/runtime/memory/extraction.test.js +85 -0
  192. package/dist/lib/runtime/memory/graph.d.ts +24 -0
  193. package/dist/lib/runtime/memory/graph.js +126 -0
  194. package/dist/lib/runtime/memory/graph.test.d.ts +1 -0
  195. package/dist/lib/runtime/memory/graph.test.js +106 -0
  196. package/dist/lib/runtime/memory/index.d.ts +9 -0
  197. package/dist/lib/runtime/memory/index.js +6 -0
  198. package/dist/lib/runtime/memory/manager.d.ts +217 -0
  199. package/dist/lib/runtime/memory/manager.js +1012 -0
  200. package/dist/lib/runtime/memory/manager.test.d.ts +1 -0
  201. package/dist/lib/runtime/memory/manager.test.js +446 -0
  202. package/dist/lib/runtime/memory/retrieval.d.ts +8 -0
  203. package/dist/lib/runtime/memory/retrieval.js +106 -0
  204. package/dist/lib/runtime/memory/retrieval.test.d.ts +1 -0
  205. package/dist/lib/runtime/memory/retrieval.test.js +118 -0
  206. package/dist/lib/runtime/memory/store.d.ts +21 -0
  207. package/dist/lib/runtime/memory/store.js +105 -0
  208. package/dist/lib/runtime/memory/store.test.d.ts +1 -0
  209. package/dist/lib/runtime/memory/store.test.js +111 -0
  210. package/dist/lib/runtime/memory/types.d.ts +129 -0
  211. package/dist/lib/runtime/memory/types.js +69 -0
  212. package/dist/lib/runtime/node.js +69 -4
  213. package/dist/lib/runtime/prompt.js +231 -97
  214. package/dist/lib/runtime/revivers/functionRefReviver.js +19 -9
  215. package/dist/lib/runtime/rewind.js +9 -1
  216. package/dist/lib/runtime/runner.d.ts +11 -0
  217. package/dist/lib/runtime/runner.js +183 -39
  218. package/dist/lib/runtime/simpleOpenAIClient.d.ts +2 -1
  219. package/dist/lib/runtime/simpleOpenAIClient.js +32 -0
  220. package/dist/lib/runtime/state/context.d.ts +21 -0
  221. package/dist/lib/runtime/state/context.js +63 -0
  222. package/dist/lib/runtime/state/threadStore.d.ts +4 -1
  223. package/dist/lib/runtime/state/threadStore.js +22 -1
  224. package/dist/lib/runtime/trace/contentAddressableStore.d.ts +10 -0
  225. package/dist/lib/runtime/trace/contentAddressableStore.js +13 -0
  226. package/dist/lib/runtime/trace/contentAddressableStore.test.js +19 -0
  227. package/dist/lib/runtime/trace/sinks.js +13 -1
  228. package/dist/lib/runtime/trace/traceWriter.d.ts +41 -1
  229. package/dist/lib/runtime/trace/traceWriter.js +96 -11
  230. package/dist/lib/runtime/trace/traceWriter.test.js +145 -1
  231. package/dist/lib/runtime/trace/types.d.ts +22 -0
  232. package/dist/lib/simplemachine/graph.d.ts +2 -0
  233. package/dist/lib/simplemachine/graph.js +28 -19
  234. package/dist/lib/simplemachine/types.d.ts +2 -0
  235. package/dist/lib/statelogClient.d.ts +224 -2
  236. package/dist/lib/statelogClient.js +390 -10
  237. package/dist/lib/statelogClient.test.d.ts +1 -0
  238. package/dist/lib/statelogClient.test.js +697 -0
  239. package/dist/lib/stdlib/agency.js +1 -1
  240. package/dist/lib/stdlib/builtins.d.ts +1 -0
  241. package/dist/lib/stdlib/builtins.js +3 -0
  242. package/dist/lib/stdlib/memory.d.ts +24 -0
  243. package/dist/lib/stdlib/memory.js +56 -0
  244. package/dist/lib/stdlib/syntax.js +19 -16
  245. package/dist/lib/symbolTable.js +5 -0
  246. package/dist/lib/templates/backends/agency/template.d.ts +1 -1
  247. package/dist/lib/templates/backends/agency/template.js +1 -1
  248. package/dist/lib/templates/backends/typescriptGenerator/forkBlockSetup.d.ts +2 -1
  249. package/dist/lib/templates/backends/typescriptGenerator/forkBlockSetup.js +14 -1
  250. package/dist/lib/templates/backends/typescriptGenerator/imports.d.ts +2 -1
  251. package/dist/lib/templates/backends/typescriptGenerator/imports.js +11 -1
  252. package/dist/lib/templates/cli/schedule/githubWorkflow.d.ts +14 -0
  253. package/dist/lib/templates/cli/schedule/githubWorkflow.js +30 -0
  254. package/dist/lib/templates/prompts/memory/compaction.d.ts +6 -0
  255. package/dist/lib/templates/prompts/memory/compaction.js +15 -0
  256. package/dist/lib/templates/prompts/memory/extraction.d.ts +7 -0
  257. package/dist/lib/templates/prompts/memory/extraction.js +20 -0
  258. package/dist/lib/templates/prompts/memory/forget.d.ts +7 -0
  259. package/dist/lib/templates/prompts/memory/forget.js +21 -0
  260. package/dist/lib/templates/prompts/memory/mergeSummary.d.ts +7 -0
  261. package/dist/lib/templates/prompts/memory/mergeSummary.js +18 -0
  262. package/dist/lib/templates/prompts/memory/retrieval.d.ts +7 -0
  263. package/dist/lib/templates/prompts/memory/retrieval.js +25 -0
  264. package/dist/lib/tui/builders.d.ts +3 -1
  265. package/dist/lib/tui/builders.js +28 -28
  266. package/dist/lib/tui/builders.test.d.ts +1 -0
  267. package/dist/lib/tui/builders.test.js +38 -0
  268. package/dist/lib/tui/colors.d.ts +16 -0
  269. package/dist/lib/tui/colors.js +20 -0
  270. package/dist/lib/tui/elements.d.ts +12 -4
  271. package/dist/lib/tui/frame.d.ts +6 -0
  272. package/dist/lib/tui/frame.js +9 -1
  273. package/dist/lib/tui/index.d.ts +3 -0
  274. package/dist/lib/tui/index.js +3 -0
  275. package/dist/lib/tui/input/format.d.ts +3 -0
  276. package/dist/lib/tui/input/format.js +37 -0
  277. package/dist/lib/tui/input/format.test.d.ts +1 -0
  278. package/dist/lib/tui/input/format.test.js +26 -0
  279. package/dist/lib/tui/input/scripted.d.ts +5 -0
  280. package/dist/lib/tui/input/scripted.js +13 -2
  281. package/dist/lib/tui/input/terminal.d.ts +5 -0
  282. package/dist/lib/tui/input/terminal.js +72 -3
  283. package/dist/lib/tui/layout.js +16 -30
  284. package/dist/lib/tui/output/recorder.d.ts +3 -1
  285. package/dist/lib/tui/output/recorder.js +31 -1
  286. package/dist/lib/tui/output/terminal.d.ts +2 -1
  287. package/dist/lib/tui/output/terminal.js +19 -3
  288. package/dist/lib/tui/render/ansi.js +39 -10
  289. package/dist/lib/tui/render/html.js +28 -14
  290. package/dist/lib/tui/render/renderer.js +25 -10
  291. package/dist/lib/tui/screen.d.ts +7 -0
  292. package/dist/lib/tui/screen.js +10 -0
  293. package/dist/lib/tui/scroll.d.ts +2 -0
  294. package/dist/lib/tui/scroll.js +26 -0
  295. package/dist/lib/tui/scroll.test.d.ts +1 -0
  296. package/dist/lib/tui/scroll.test.js +30 -0
  297. package/dist/lib/tui/scrollList.d.ts +28 -0
  298. package/dist/lib/tui/scrollList.js +29 -0
  299. package/dist/lib/tui/scrollList.test.d.ts +1 -0
  300. package/dist/lib/tui/scrollList.test.js +78 -0
  301. package/dist/lib/tui/styleParser.js +172 -18
  302. package/dist/lib/tui/utils.d.ts +12 -1
  303. package/dist/lib/tui/utils.js +15 -0
  304. package/dist/lib/typeChecker/assignability.js +30 -0
  305. package/dist/lib/typeChecker/assignability.test.js +22 -0
  306. package/dist/lib/typeChecker/blockBody.test.js +3 -1
  307. package/dist/lib/typeChecker/builtinSignatures.test.d.ts +1 -0
  308. package/dist/lib/typeChecker/builtinSignatures.test.js +51 -0
  309. package/dist/lib/typeChecker/builtins.d.ts +8 -5
  310. package/dist/lib/typeChecker/builtins.js +35 -25
  311. package/dist/lib/typeChecker/checker.js +149 -38
  312. package/dist/lib/typeChecker/constReassignment.test.d.ts +1 -0
  313. package/dist/lib/typeChecker/constReassignment.test.js +88 -0
  314. package/dist/lib/typeChecker/fixtureTypeCheck.integration.test.d.ts +1 -0
  315. package/dist/lib/typeChecker/fixtureTypeCheck.integration.test.js +72 -0
  316. package/dist/lib/typeChecker/index.d.ts +1 -0
  317. package/dist/lib/typeChecker/index.js +30 -22
  318. package/dist/lib/typeChecker/interruptAnalysis.js +16 -12
  319. package/dist/lib/typeChecker/interruptWarnings.test.js +53 -0
  320. package/dist/lib/typeChecker/jsGlobalsSig.test.d.ts +1 -0
  321. package/dist/lib/typeChecker/jsGlobalsSig.test.js +100 -0
  322. package/dist/lib/typeChecker/primitiveMembers.d.ts +80 -0
  323. package/dist/lib/typeChecker/primitiveMembers.js +183 -0
  324. package/dist/lib/typeChecker/primitiveMembers.test.d.ts +1 -0
  325. package/dist/lib/typeChecker/primitiveMembers.test.js +56 -0
  326. package/dist/lib/typeChecker/primitiveMembersIntegration.test.d.ts +1 -0
  327. package/dist/lib/typeChecker/primitiveMembersIntegration.test.js +171 -0
  328. package/dist/lib/typeChecker/reservedNameDeclaration.test.d.ts +1 -0
  329. package/dist/lib/typeChecker/reservedNameDeclaration.test.js +57 -0
  330. package/dist/lib/typeChecker/resolveCall.d.ts +160 -0
  331. package/dist/lib/typeChecker/resolveCall.js +292 -0
  332. package/dist/lib/typeChecker/resolveCall.test.d.ts +1 -0
  333. package/dist/lib/typeChecker/resolveCall.test.js +115 -0
  334. package/dist/lib/typeChecker/resolveVariable.d.ts +77 -0
  335. package/dist/lib/typeChecker/resolveVariable.js +37 -0
  336. package/dist/lib/typeChecker/schemaType.test.d.ts +1 -0
  337. package/dist/lib/typeChecker/schemaType.test.js +79 -0
  338. package/dist/lib/typeChecker/scope.d.ts +14 -1
  339. package/dist/lib/typeChecker/scope.js +28 -2
  340. package/dist/lib/typeChecker/scope.test.js +16 -0
  341. package/dist/lib/typeChecker/scopes.js +121 -3
  342. package/dist/lib/typeChecker/shadowing.d.ts +11 -0
  343. package/dist/lib/typeChecker/shadowing.js +19 -0
  344. package/dist/lib/typeChecker/suppression.test.js +3 -1
  345. package/dist/lib/typeChecker/synthesizer.js +284 -7
  346. package/dist/lib/typeChecker/typeWalker.js +2 -0
  347. package/dist/lib/typeChecker/types.d.ts +2 -0
  348. package/dist/lib/typeChecker/undefinedFunctionDiagnostic.d.ts +15 -0
  349. package/dist/lib/typeChecker/undefinedFunctionDiagnostic.js +138 -0
  350. package/dist/lib/typeChecker/undefinedFunctionDiagnostic.test.d.ts +1 -0
  351. package/dist/lib/typeChecker/undefinedFunctionDiagnostic.test.js +273 -0
  352. package/dist/lib/typeChecker/undefinedVariableDiagnostic.d.ts +29 -0
  353. package/dist/lib/typeChecker/undefinedVariableDiagnostic.js +129 -0
  354. package/dist/lib/typeChecker/undefinedVariableDiagnostic.test.d.ts +1 -0
  355. package/dist/lib/typeChecker/undefinedVariableDiagnostic.test.js +80 -0
  356. package/dist/lib/typeChecker.test.js +65 -63
  357. package/dist/lib/types/forLoop.d.ts +2 -1
  358. package/dist/lib/types/matchBlock.d.ts +4 -2
  359. package/dist/lib/types/pattern.d.ts +35 -0
  360. package/dist/lib/types/pattern.js +1 -0
  361. package/dist/lib/types/typeHints.d.ts +12 -1
  362. package/dist/lib/types.d.ts +5 -2
  363. package/dist/lib/types.js +1 -0
  364. package/dist/lib/utils/agentUtils.d.ts +1 -1
  365. package/dist/lib/utils/agentUtils.js +3 -75
  366. package/dist/lib/utils/formatType.js +2 -0
  367. package/dist/lib/utils/mapBodies.d.ts +20 -0
  368. package/dist/lib/utils/mapBodies.js +48 -0
  369. package/dist/lib/utils/termcolors.d.ts +7 -1
  370. package/dist/lib/utils/termcolors.js +44 -0
  371. package/dist/scripts/agency.js +83 -6
  372. package/dist/tests/fixtureDiscovery.d.ts +25 -0
  373. package/dist/tests/fixtureDiscovery.js +60 -0
  374. package/package.json +4 -5
  375. package/stdlib/agency.js +12 -5
  376. package/stdlib/agent.js +12 -5
  377. package/stdlib/array.js +12 -5
  378. package/stdlib/browser.js +12 -5
  379. package/stdlib/calendar.js +12 -5
  380. package/stdlib/clipboard.js +12 -5
  381. package/stdlib/date.js +12 -5
  382. package/stdlib/email.js +12 -5
  383. package/stdlib/fs.js +12 -5
  384. package/stdlib/http.js +12 -5
  385. package/stdlib/imessage.js +12 -5
  386. package/stdlib/index.agency +8 -1
  387. package/stdlib/index.js +122 -6
  388. package/stdlib/keyring.js +12 -5
  389. package/stdlib/math.js +12 -5
  390. package/stdlib/memory.agency +92 -0
  391. package/stdlib/memory.js +690 -0
  392. package/stdlib/oauth.js +12 -5
  393. package/stdlib/object.js +12 -5
  394. package/stdlib/path.js +12 -5
  395. package/stdlib/policy.js +12 -5
  396. package/stdlib/shell.js +12 -5
  397. package/stdlib/sms.js +12 -5
  398. package/stdlib/speech.js +12 -5
  399. package/stdlib/strategy.js +12 -5
  400. package/stdlib/system.js +12 -5
  401. package/stdlib/ui.js +12 -5
  402. package/stdlib/weather.js +12 -5
  403. package/stdlib/wikipedia.js +12 -5
  404. package/dist/lib/preprocessors/typescriptPreprocessor.test.js +0 -283
  405. /package/dist/lib/{preprocessors/typescriptPreprocessor.test.d.ts → cli/installLocation.test.d.ts} +0 -0
@@ -4,49 +4,8 @@ import { TypeScriptBuilder } from "./typescriptBuilder.js";
4
4
  import { TypescriptPreprocessor } from "../preprocessors/typescriptPreprocessor.js";
5
5
  import { buildCompilationUnit } from "../compilationUnit.js";
6
6
  import { printTs } from "../ir/prettyPrint.js";
7
- import fs from "fs";
7
+ import { discoverFixturePairs } from "../../tests/fixtureDiscovery.js";
8
8
  import path from "path";
9
- function discoverFixtures(fixtureDir) {
10
- const fixtures = [];
11
- function scanDirectory(dir, relativePath = "") {
12
- const entries = fs.readdirSync(dir, { withFileTypes: true });
13
- for (const entry of entries) {
14
- const fullPath = path.join(dir, entry.name);
15
- const relPath = relativePath
16
- ? `${relativePath}/${entry.name}`
17
- : entry.name;
18
- if (entry.isDirectory()) {
19
- scanDirectory(fullPath, relPath);
20
- }
21
- else if (entry.isFile() && entry.name.endsWith(".agency")) {
22
- const baseName = entry.name.replace(".agency", "");
23
- const mtsPath = path.join(dir, `${baseName}.mjs`);
24
- if (fs.existsSync(mtsPath)) {
25
- const nameWithoutExt = relativePath
26
- ? `${relativePath}/${baseName}`
27
- : baseName;
28
- try {
29
- fixtures.push({
30
- name: nameWithoutExt,
31
- agencyPath: fullPath,
32
- mtsPath: mtsPath,
33
- agencyContent: fs.readFileSync(fullPath, "utf-8"),
34
- expectedTS: fs.readFileSync(mtsPath, "utf-8"),
35
- });
36
- }
37
- catch (error) {
38
- console.error(`Cannot read fixture ${fullPath}: ${error instanceof Error ? error.message : String(error)}`);
39
- }
40
- }
41
- else {
42
- console.warn(`Warning: No corresponding .mjs file for ${fullPath}`);
43
- }
44
- }
45
- }
46
- }
47
- scanDirectory(fixtureDir);
48
- return fixtures.sort((a, b) => a.name.localeCompare(b.name));
49
- }
50
9
  function normalizeWhitespace(code) {
51
10
  return (code
52
11
  .replace(/\r\n/g, "\n")
@@ -71,7 +30,7 @@ export function generateWithBuilder(agencySource, moduleId = "test.agency") {
71
30
  }
72
31
  const FIXTURES_DIR = path.resolve(__dirname, "../../tests/typescriptBuilder");
73
32
  describe("TypeScript Builder Integration Tests", () => {
74
- const fixtures = discoverFixtures(FIXTURES_DIR);
33
+ const fixtures = discoverFixturePairs(FIXTURES_DIR, ".mjs");
75
34
  if (fixtures.length === 0) {
76
35
  it("should find test fixtures (add .agency + .mjs pairs to tests/typescriptBuilder/)", () => {
77
36
  // No fixtures yet — this is expected initially.
@@ -80,16 +39,16 @@ describe("TypeScript Builder Integration Tests", () => {
80
39
  });
81
40
  return;
82
41
  }
83
- describe.each(fixtures)("Fixture: $name", ({ name, agencyPath, agencyContent, expectedTS }) => {
42
+ describe.each(fixtures)("Fixture: $name", ({ name, filePath, agencyContent, companionContent }) => {
84
43
  it("should generate correct TypeScript output", () => {
85
44
  let generatedTS;
86
45
  try {
87
46
  generatedTS = generateWithBuilder(agencyContent, name + ".agency");
88
47
  }
89
48
  catch (error) {
90
- throw new Error(`Failed to generate TypeScript for fixture: ${name}\nFile: ${agencyPath}\nError: ${error instanceof Error ? error.message : String(error)}`);
49
+ throw new Error(`Failed to generate TypeScript for fixture: ${name}\nFile: ${filePath}\nError: ${error instanceof Error ? error.message : String(error)}`);
91
50
  }
92
- expect(normalizeWhitespace(generatedTS)).toBe(normalizeWhitespace(expectedTS));
51
+ expect(normalizeWhitespace(generatedTS)).toBe(normalizeWhitespace(companionContent));
93
52
  });
94
53
  });
95
54
  });
@@ -3,6 +3,7 @@ import { formatTypeHintTs } from "../utils/formatType.js";
3
3
  import { BUILTIN_FUNCTIONS, BUILTIN_TOOLS, BUILTIN_VARIABLES, TYPES_THAT_DONT_TRIGGER_NEW_PART, } from "../config.js";
4
4
  import { expressionToString } from "../utils/node.js";
5
5
  import { toCompiledImportPath } from "../importPaths.js";
6
+ import { CONTEXT_INJECTED_BUILTINS, isContextInjectedBuiltin, } from "../codegenBuiltins/contextInjected.js";
6
7
  import * as renderImports from "../templates/backends/typescriptGenerator/imports.js";
7
8
  import * as renderInterruptAssignment from "../templates/backends/typescriptGenerator/interruptAssignment.js";
8
9
  import * as renderInterruptReturn from "../templates/backends/typescriptGenerator/interruptReturn.js";
@@ -13,11 +14,11 @@ import * as renderResultCheckpointSetup from "../templates/backends/typescriptGe
13
14
  import * as renderFunctionCatchFailure from "../templates/backends/typescriptGenerator/functionCatchFailure.js";
14
15
  import * as renderClassDefinition from "../templates/backends/typescriptGenerator/classDefinition.js";
15
16
  import { PRECEDENCE, } from "../types/binop.js";
16
- import { walkNodesArray } from "../utils/node.js";
17
+ import { walkNodes, walkNodesArray } from "../utils/node.js";
17
18
  import { getImportedNames, } from "../types/importStatement.js";
18
19
  import { isClassKeyword } from "../types/classDefinition.js";
19
20
  import { moduleIdToOrigin } from "../runtime/origin.js";
20
- import { escape, mergeDeep } from "../utils.js";
21
+ import { mergeDeep } from "../utils.js";
21
22
  import { generateBuiltinHelpers, mapFunctionName, } from "./typescriptGenerator/builtins.js";
22
23
  import { DEFAULT_SCHEMA, mapTypeToValidationSchema, } from "./typescriptGenerator/typeToZodSchema.js";
23
24
  import { $, ts } from "../ir/builders.js";
@@ -25,6 +26,19 @@ import { printTs } from "../ir/prettyPrint.js";
25
26
  import { scopeKey } from "../compilationUnit.js";
26
27
  import { SourceMapBuilder } from "./sourceMap.js";
27
28
  const DEFAULT_PROMPT_NAME = "__promptVar";
29
+ /** Maps Agency compound-assignment operators to their underlying binary
30
+ * operator. Used to lower `foo <op>= rhs` into a get/set pair when `foo`
31
+ * is a global, since globals can't appear on the LHS of an assignment.
32
+ * Covers every compound operator the parser recognizes. */
33
+ const COMPOUND_ASSIGN_TO_BINARY = {
34
+ "+=": "+",
35
+ "-=": "-",
36
+ "*=": "*",
37
+ "/=": "/",
38
+ "??=": "??",
39
+ "||=": "||",
40
+ "&&=": "&&",
41
+ };
28
42
  /** Runner IR node kinds that already manage their own step counter/path and
29
43
  * must NOT be wrapped inside a runnerStep by processBodyAsParts. */
30
44
  const COMPOUND_RUNNER_KINDS = new Set([
@@ -38,6 +52,13 @@ export class TypeScriptBuilder {
38
52
  // Output assembly
39
53
  generatedStatements = [];
40
54
  generatedTypeAliases = [];
55
+ /**
56
+ * TypeAlias AST nodes whose declaration has been hoisted to the
57
+ * containing function/node's outer scope (so it's visible to every
58
+ * runner.step closure). When processNode sees one of these inside a
59
+ * body, it returns ts.empty() to avoid a redeclaration.
60
+ */
61
+ hoistedTypeAliasNodes = new Set();
41
62
  // Import tracking
42
63
  importStatements = [];
43
64
  toolRegistrations = [];
@@ -57,6 +78,11 @@ export class TypeScriptBuilder {
57
78
  insideGlobalInit = false;
58
79
  _isInSafeFunction = false;
59
80
  _blockCounter = 0;
81
+ /** Nesting depth of fork/race block bodies currently being generated.
82
+ * Used to detect when a fork is nested inside another fork's block, so
83
+ * the inner block can carry forward the outer block's args (otherwise
84
+ * the inner __bstack only contains the inner iteration variable). */
85
+ _forkBlockDepth = 0;
60
86
  /** Stack of loop subKeys for generating break/continue cleanup code.
61
87
  * Pushed when entering a stepped loop, popped when leaving. */
62
88
  _loopContextStack = [];
@@ -99,6 +125,11 @@ export class TypeScriptBuilder {
99
125
  configDefaults() {
100
126
  return {
101
127
  maxToolCallRounds: 10,
128
+ // Top-level threshold for runtime subsystem loggers (memory,
129
+ // etc.). Distinct from `client.logLevel` which is the
130
+ // smoltalk-internal one. "info" matches the existing
131
+ // no-debug-by-default behavior — users opt in via agency.json.
132
+ logLevel: "info",
102
133
  log: {
103
134
  host: "https://statelog.adit.io",
104
135
  },
@@ -582,6 +613,8 @@ export class TypeScriptBuilder {
582
613
  processNode(node) {
583
614
  switch (node.type) {
584
615
  case "typeAlias":
616
+ if (this.hoistedTypeAliasNodes.has(node))
617
+ return ts.empty();
585
618
  return this.processTypeAlias(node);
586
619
  case "assignment":
587
620
  return this.processAssignment(node);
@@ -686,6 +719,55 @@ export class TypeScriptBuilder {
686
719
  ]);
687
720
  }
688
721
  // ------- Type system (side effects only) -------
722
+ /**
723
+ * Walk a function/node body and collect every typeAlias declaration
724
+ * that belongs to this body's scope. Used to hoist body-local type
725
+ * aliases up to the enclosing function/node's outer scope so the
726
+ * generated zod schemas are visible to every runner.step closure.
727
+ *
728
+ * Delegates body recursion to `walkNodes` so any new body-bearing
729
+ * AST node (thread, parallelBlock, seqBlock, …) is automatically
730
+ * handled. Aliases nested inside a function/graphNode/class method
731
+ * are skipped — those defs hoist their own aliases when their bodies
732
+ * are built.
733
+ */
734
+ collectBodyTypeAliases(body) {
735
+ const collected = [];
736
+ for (const { node, ancestors } of walkNodes(body)) {
737
+ if (node.type !== "typeAlias")
738
+ continue;
739
+ const inNestedDef = ancestors.some((a) => a.type === "function" ||
740
+ a.type === "graphNode" ||
741
+ a.type === "classDefinition");
742
+ if (inNestedDef)
743
+ continue;
744
+ collected.push(node);
745
+ }
746
+ return collected;
747
+ }
748
+ /**
749
+ * Hoist body-local type aliases. Returns the generated TS declarations
750
+ * (to be inserted at the top of the enclosing function/node body) and
751
+ * marks each AST node so processNode skips its in-body emission.
752
+ *
753
+ * Coalesces duplicates by alias name: if the same name appears in
754
+ * multiple branches/blocks, only the first declaration is emitted to
755
+ * avoid redeclaration errors at the function scope. (The Agency
756
+ * typechecker is responsible for diagnosing genuine name collisions.)
757
+ */
758
+ hoistBodyTypeAliases(body) {
759
+ const aliases = this.collectBodyTypeAliases(body);
760
+ const out = [];
761
+ const seen = new Set();
762
+ for (const alias of aliases) {
763
+ this.hoistedTypeAliasNodes.add(alias);
764
+ if (seen.has(alias.aliasName))
765
+ continue;
766
+ seen.add(alias.aliasName);
767
+ out.push(this.processTypeAlias(alias));
768
+ }
769
+ return out;
770
+ }
689
771
  processTypeAlias(node) {
690
772
  const exportPrefix = node.exported ? "export " : "";
691
773
  const zodSchema = mapTypeToValidationSchema(node.aliasedType, this.getVisibleTypeAliases());
@@ -748,17 +830,21 @@ export class TypeScriptBuilder {
748
830
  const parts = [];
749
831
  for (const segment of segments) {
750
832
  if (segment.type === "text") {
751
- const escaped = escape(segment.value);
833
+ // Pass raw text — the templateLit printer (prettyPrint.ts) handles
834
+ // all template-literal escaping (\, `, ${). Escaping here would
835
+ // cause the printer to escape our escapes, producing broken output
836
+ // (e.g. a literal `\\\`` instead of `\``).
837
+ const text = segment.value;
752
838
  if (parts.length > 0 && parts[parts.length - 1].expr) {
753
839
  // Previous part had an expr; start a new part for this text
754
- parts.push({ text: escaped });
840
+ parts.push({ text });
755
841
  }
756
842
  else if (parts.length > 0) {
757
843
  // Previous part is text-only, append to it
758
- parts[parts.length - 1].text += escaped;
844
+ parts[parts.length - 1].text += text;
759
845
  }
760
846
  else {
761
- parts.push({ text: escaped });
847
+ parts.push({ text });
762
848
  }
763
849
  }
764
850
  else {
@@ -783,6 +869,16 @@ export class TypeScriptBuilder {
783
869
  if (node.base.type === "functionCall" && node.chain.length > 0) {
784
870
  result = ts.raw(`(${this.str(ts.await(result))})`);
785
871
  }
872
+ else if (node.chain.length > 0 &&
873
+ node.base.type !== "functionCall" &&
874
+ node.base.type !== "variableName" &&
875
+ node.base.type !== "valueAccess") {
876
+ // For any non-trivial base (binOp, tryExpression, newExpression,
877
+ // unary, object/array literals, etc.) wrap in parens before
878
+ // applying the chain so `.foo` / `[i]` / `.method()` bind to the
879
+ // whole base expression.
880
+ result = ts.raw(`(${this.str(result)})`);
881
+ }
786
882
  for (const element of node.chain) {
787
883
  switch (element.kind) {
788
884
  case "property":
@@ -848,6 +944,32 @@ export class TypeScriptBuilder {
848
944
  if (node.operator === "typeof" || node.operator === "void") {
849
945
  return ts.unaryOp(node.operator, this.processNode(node.right));
850
946
  }
947
+ // Compound assignment to a global variable: globals are accessed via
948
+ // `__ctx.globals.get(...)`, which is not a valid assignment target,
949
+ // so `foo <op>= rhs` would emit invalid JS. Lower it to an IIFE so
950
+ // the expression still evaluates to the new value (matching JS
951
+ // semantics for `let x = foo += 1`, `return foo += 1`, etc.):
952
+ //
953
+ // ((__v) => (__ctx.globals.set(file, name, __v), __v))(
954
+ // __ctx.globals.get(file, name) <op> rhs
955
+ // )
956
+ const compoundOp = COMPOUND_ASSIGN_TO_BINARY[node.operator];
957
+ if (compoundOp !== undefined &&
958
+ node.left.type === "variableName" &&
959
+ node.left.scope === "global") {
960
+ const name = node.left.value;
961
+ const getNode = ts.scopedVar(name, "global", this.moduleId);
962
+ const rightNode = this.processNode(node.right);
963
+ const newValueExpr = ts.binOp(getNode, compoundOp, rightNode, {
964
+ parenRight: true,
965
+ });
966
+ const setCall = ts.globalSet(this.moduleId, name, ts.id("__v"));
967
+ // Arrow-fn IIFE: `((__v) => (set(...), __v))(newValueExpr)`. The
968
+ // outer parens around the arrow are required — without them JS
969
+ // parses `(__v) => (...)(args)` as an arrow whose body invokes
970
+ // `__v(args)`, never running the IIFE.
971
+ return ts.raw(`((__v) => (${this.str(setCall)}, __v))(${this.str(newValueExpr)})`);
972
+ }
851
973
  const leftNode = this.processNode(node.left);
852
974
  const rightNode = this.processNode(node.right);
853
975
  // Agency uses strict equality/inequality: == → ===, != → !==
@@ -958,6 +1080,8 @@ export class TypeScriptBuilder {
958
1080
  this._sourceMapBuilder.enterScope(this.moduleId, methodScopeName);
959
1081
  const prevSafe = this._isInSafeFunction;
960
1082
  this._isInSafeFunction = !!method.safe;
1083
+ // Hoist body-local type aliases to the method's outer scope.
1084
+ const hoistedAliases = this.hoistBodyTypeAliases(method.body);
961
1085
  const bodyCode = this.processBodyAsParts(method.body);
962
1086
  this._isInSafeFunction = prevSafe;
963
1087
  this.endScope();
@@ -966,6 +1090,7 @@ export class TypeScriptBuilder {
966
1090
  functionName: methodScopeName,
967
1091
  parameters: method.parameters,
968
1092
  bodyCode,
1093
+ hoistedAliases,
969
1094
  });
970
1095
  // Build as an async method with __state as last param
971
1096
  const params = method.parameters.map((p) => this.formatParam(p)).join(", ");
@@ -1319,6 +1444,7 @@ export class TypeScriptBuilder {
1319
1444
  */
1320
1445
  buildFunctionBody(opts) {
1321
1446
  const { functionName, parameters, bodyCode, skipHooks } = opts;
1447
+ const hoistedAliases = opts.hoistedAliases ?? [];
1322
1448
  const args = parameters.map((p) => p.name);
1323
1449
  // Build args object for hook data
1324
1450
  const argsObj = {};
@@ -1385,6 +1511,7 @@ export class TypeScriptBuilder {
1385
1511
  // Try/catch wrapping the body, with finally to always pop the state stack
1386
1512
  setupStmts.push(ts.tryCatch(ts.statements([
1387
1513
  ...validationGuards,
1514
+ ...hoistedAliases,
1388
1515
  ...bodyCode,
1389
1516
  ts.raw("if (runner.halted) { if (isFailure(runner.haltResult)) { runner.haltResult.retryable = runner.haltResult.retryable && __self.__retryable; } return runner.haltResult; }"),
1390
1517
  ]), ts.raw(renderFunctionCatchFailure.default({
@@ -1412,6 +1539,9 @@ export class TypeScriptBuilder {
1412
1539
  const { functionName, parameters } = node;
1413
1540
  const prevSafe = this._isInSafeFunction;
1414
1541
  this._isInSafeFunction = !!node.safe;
1542
+ // Hoist body-local type aliases to the function's outer scope so
1543
+ // every runner.step closure can reference the generated zod schemas.
1544
+ const hoistedAliases = this.hoistBodyTypeAliases(node.body);
1415
1545
  const bodyCode = this.processBodyAsParts(node.body);
1416
1546
  this._isInSafeFunction = prevSafe;
1417
1547
  this.endScope();
@@ -1433,7 +1563,7 @@ export class TypeScriptBuilder {
1433
1563
  defaultValue: ts.id("undefined"),
1434
1564
  });
1435
1565
  const implName = `__${functionName}_impl`;
1436
- const setupStmts = this.buildFunctionBody({ functionName, parameters, bodyCode, skipHooks: node.callback });
1566
+ const setupStmts = this.buildFunctionBody({ functionName, parameters, bodyCode, skipHooks: node.callback, hoistedAliases });
1437
1567
  const funcDecl = ts.functionDecl(implName, fnParams, ts.statements(setupStmts), {
1438
1568
  async: true,
1439
1569
  });
@@ -1593,6 +1723,9 @@ export class TypeScriptBuilder {
1593
1723
  const data = argNodes.length > 0 ? argNodes[0] : ts.id("undefined");
1594
1724
  return ts.callHook("onEmit", data);
1595
1725
  }
1726
+ if (node.functionName === "__objectRest") {
1727
+ return ts.raw(this.buildObjectRestIIFE(node));
1728
+ }
1596
1729
  if (node.functionName === "llm") {
1597
1730
  // Standalone llm() call (not assigned to variable)
1598
1731
  return this.processLlmCall(DEFAULT_PROMPT_NAME, this.getScopeReturnType(), node, "local");
@@ -1627,6 +1760,16 @@ export class TypeScriptBuilder {
1627
1760
  .call([ts.smoltalkSystemMessage(argNodes)])
1628
1761
  .done();
1629
1762
  }
1763
+ // Context-injected builtins: codegen rewrites the call to prepend
1764
+ // `__ctx` as the first positional argument. The actual emit is a
1765
+ // plain direct call (`f(__ctx, ...args)`), like the __-prefixed
1766
+ // branch below — but the registry lookup has to happen FIRST so
1767
+ // we know to inject ctx. See lib/codegenBuiltins/contextInjected.ts.
1768
+ if (isContextInjectedBuiltin(node.functionName)) {
1769
+ return this.emitDirectFunctionCall(node, functionName, shouldAwait, [
1770
+ ts.id("__ctx"),
1771
+ ]);
1772
+ }
1630
1773
  // __-prefixed helpers and DIRECT_CALL_FUNCTIONS: emit plain direct call
1631
1774
  if (functionName.startsWith("__") ||
1632
1775
  TypeScriptBuilder.DIRECT_CALL_FUNCTIONS.has(functionName)) {
@@ -1652,8 +1795,17 @@ export class TypeScriptBuilder {
1652
1795
  const callExpr = ts.call(ts.id("__call"), [callee, descriptor, configObj]);
1653
1796
  return shouldAwait ? ts.await(callExpr) : callExpr;
1654
1797
  }
1655
- emitDirectFunctionCall(node, functionName, shouldAwait) {
1656
- const argNodes = node.arguments.map((a) => this.processCallArg(a));
1798
+ /**
1799
+ * Emit a plain direct function call: `f(arg1, arg2, blockArg?)`.
1800
+ * Context-injected builtins reuse this with `prependArgs =
1801
+ * [__ctx]`; the registry lookup at the call site is what marks the
1802
+ * intent, no separate method needed.
1803
+ */
1804
+ emitDirectFunctionCall(node, functionName, shouldAwait, prependArgs = []) {
1805
+ const argNodes = [
1806
+ ...prependArgs,
1807
+ ...node.arguments.map((a) => this.processCallArg(a)),
1808
+ ];
1657
1809
  if (node.block) {
1658
1810
  argNodes.push(this.processBlockArgument(node));
1659
1811
  }
@@ -1713,11 +1865,18 @@ export class TypeScriptBuilder {
1713
1865
  : ts.arr([]);
1714
1866
  const blockName = `__block_${this._blockCounter++}`;
1715
1867
  const parentScopeName = this.currentScopeName();
1868
+ // Track that we're now generating code inside a fork-block body so
1869
+ // any nested fork can carry parent block args forward. Capture the
1870
+ // depth value the inner fork will see, then increment for the body
1871
+ // walk and restore after.
1872
+ const isNestedInForkBlock = this._forkBlockDepth > 0;
1873
+ this._forkBlockDepth++;
1716
1874
  this.startScope({ type: "block", blockName });
1717
1875
  this._sourceMapBuilder.enterScope(this.moduleId, blockName);
1718
1876
  const bodyParts = this.processBodyAsParts(block.body);
1719
1877
  this._sourceMapBuilder.enterScope(this.moduleId, parentScopeName);
1720
1878
  this.endScope();
1879
+ this._forkBlockDepth--;
1721
1880
  const bodyStr = bodyParts.map((n) => printTs(n, 1)).join("\n");
1722
1881
  const blockSetupCode = renderForkBlockSetup.default({
1723
1882
  paramName,
@@ -1725,6 +1884,7 @@ export class TypeScriptBuilder {
1725
1884
  moduleId: JSON.stringify(this.moduleId),
1726
1885
  scopeName: JSON.stringify(blockName),
1727
1886
  body: bodyStr,
1887
+ isNested: isNestedInForkBlock,
1728
1888
  });
1729
1889
  const blockFn = ts.arrowFn([
1730
1890
  { name: "__forkItem" },
@@ -1782,6 +1942,9 @@ export class TypeScriptBuilder {
1782
1942
  throw new Error(`Call to graph node '${stmt.functionName}' inside graph node '${nodeName}' must use goto or return, eg: goto ${stmt.functionName}(...)`);
1783
1943
  }
1784
1944
  }
1945
+ // Hoist body-local type aliases to the outer arrow body so every
1946
+ // runner.step closure can reference the generated zod schemas.
1947
+ const hoistedAliases = this.hoistBodyTypeAliases(body);
1785
1948
  const bodyCode = this.processBodyAsParts(body);
1786
1949
  this.adjacentNodes[nodeName] = [...this.currentAdjacentNodes];
1787
1950
  this.isInsideGraphNode = false;
@@ -1804,6 +1967,7 @@ export class TypeScriptBuilder {
1804
1967
  ts.callHook("onNodeStart", { nodeName: ts.str(nodeName) }),
1805
1968
  // Create runner for step execution (nodeContext enables { messages, data } wrapping for debug halts)
1806
1969
  ts.raw(`const runner = new Runner(__ctx, __stack, { nodeContext: true, state: __stack, moduleId: ${JSON.stringify(this.moduleId)}, scopeName: ${JSON.stringify(nodeName)} });`),
1970
+ ...hoistedAliases,
1807
1971
  ];
1808
1972
  // Param assignments (only when not resuming)
1809
1973
  if (parameters.length > 0) {
@@ -2192,6 +2356,39 @@ export class TypeScriptBuilder {
2192
2356
  }
2193
2357
  return ts.forOf(node.itemVar, this.processNode(node.iterable), processBody(node.body));
2194
2358
  }
2359
+ /**
2360
+ * Compile the synthetic `__objectRest(source, ["a", "b", ...])` call emitted
2361
+ * by the pattern lowering pass for `let { a, b, ...rest } = obj` into a
2362
+ * native-JS IIFE. No runtime helper required.
2363
+ *
2364
+ * __objectRest(source, ["a", "b"])
2365
+ * → (({ a: __k0, b: __k1, ...__r }) => __r)(<resolved source>)
2366
+ *
2367
+ * For `let { ...rest } = obj` (no excluded keys), emits
2368
+ * (({ ...__r }) => __r)(<resolved source>)
2369
+ */
2370
+ buildObjectRestIIFE(node) {
2371
+ const [sourceArg, keysArg] = node.arguments;
2372
+ const sourceJs = this.str(this.processNode(sourceArg));
2373
+ const keys = [];
2374
+ if (keysArg && "type" in keysArg && keysArg.type === "agencyArray") {
2375
+ for (const item of keysArg.items) {
2376
+ if ("type" in item && item.type === "string") {
2377
+ const value = item.segments[0];
2378
+ if (value?.type === "text" && value.value.length > 0) {
2379
+ keys.push(value.value);
2380
+ }
2381
+ }
2382
+ }
2383
+ }
2384
+ const destructured = keys.map((k, i) => `${k}: __k${i}`).join(", ");
2385
+ // Empty destructured (no excluded keys) collapses the leading comma so
2386
+ // we never emit invalid `(({ , ...__r }) => ...)`.
2387
+ const params = destructured.length > 0
2388
+ ? `{ ${destructured}, ...__r }`
2389
+ : `{ ...__r }`;
2390
+ return `((${params}) => __r)(${sourceJs})`;
2391
+ }
2195
2392
  processNodeInGlobalInit(node) {
2196
2393
  this.insideGlobalInit = true;
2197
2394
  try {
@@ -2532,14 +2729,41 @@ export class TypeScriptBuilder {
2532
2729
  }
2533
2730
  generateImports() {
2534
2731
  const cfg = this.agencyConfig;
2535
- const statelogConfig = ts.obj({
2732
+ const statelogFields = {
2536
2733
  host: ts.str(cfg.log?.host || ""),
2537
2734
  apiKey: cfg.log?.apiKey
2538
2735
  ? ts.str(cfg.log.apiKey)
2539
2736
  : ts.binOp(ts.env("STATELOG_API_KEY"), "||", ts.str("")),
2540
2737
  projectId: ts.str(cfg.log?.projectId || ""),
2541
2738
  debugMode: ts.bool(cfg.log?.debugMode || false),
2542
- });
2739
+ observability: ts.bool(cfg.observability || false),
2740
+ };
2741
+ if (cfg.log?.logFile) {
2742
+ statelogFields.logFile = ts.str(cfg.log.logFile);
2743
+ }
2744
+ if (cfg.log?.requestTimeoutMs !== undefined) {
2745
+ statelogFields.requestTimeoutMs = ts.raw(String(cfg.log.requestTimeoutMs));
2746
+ }
2747
+ if (cfg.log?.metadata) {
2748
+ const metaFields = {};
2749
+ if (cfg.log.metadata.tags) {
2750
+ metaFields.tags = ts.raw(JSON.stringify(cfg.log.metadata.tags));
2751
+ }
2752
+ if (cfg.log.metadata.environment) {
2753
+ metaFields.environment = ts.str(cfg.log.metadata.environment);
2754
+ }
2755
+ if (cfg.log.metadata.userId) {
2756
+ metaFields.userId = ts.str(cfg.log.metadata.userId);
2757
+ }
2758
+ if (cfg.log.metadata.agentVersion) {
2759
+ metaFields.agentVersion = ts.str(cfg.log.metadata.agentVersion);
2760
+ }
2761
+ if (cfg.log.metadata.custom) {
2762
+ metaFields.custom = ts.raw(JSON.stringify(cfg.log.metadata.custom));
2763
+ }
2764
+ statelogFields.metadata = ts.obj(metaFields);
2765
+ }
2766
+ const statelogConfig = ts.obj(statelogFields);
2543
2767
  const smoltalkDefaults = ts.obj({
2544
2768
  openAiApiKey: cfg.client?.openAiApiKey
2545
2769
  ? ts.str(cfg.client.openAiApiKey)
@@ -2564,6 +2788,13 @@ export class TypeScriptBuilder {
2564
2788
  if (this.agencyConfig.verbose) {
2565
2789
  runtimeCtxArgs.verbose = ts.raw("true");
2566
2790
  }
2791
+ // Always render the top-level logLevel; `configDefaults()` guarantees
2792
+ // a value, so this never emits a runtime default-fallback path. The
2793
+ // RuntimeContext uses this to construct ad-hoc loggers in subsystems
2794
+ // (e.g. memory) on demand.
2795
+ if (this.agencyConfig.logLevel) {
2796
+ runtimeCtxArgs.logLevel = ts.str(this.agencyConfig.logLevel);
2797
+ }
2567
2798
  if (this.agencyConfig.checkpoints?.maxRestores !== undefined) {
2568
2799
  runtimeCtxArgs.maxRestores = ts.raw(String(this.agencyConfig.checkpoints.maxRestores));
2569
2800
  }
@@ -2577,6 +2808,35 @@ export class TypeScriptBuilder {
2577
2808
  traceConfigFields.traceFile = ts.str(this.agencyConfig.traceFile);
2578
2809
  }
2579
2810
  runtimeCtxArgs.traceConfig = ts.obj(traceConfigFields);
2811
+ if (this.agencyConfig.memory) {
2812
+ const mem = this.agencyConfig.memory;
2813
+ const memoryFields = {
2814
+ dir: ts.str(mem.dir),
2815
+ };
2816
+ if (mem.model)
2817
+ memoryFields.model = ts.str(mem.model);
2818
+ if (mem.autoExtract?.interval !== undefined) {
2819
+ memoryFields.autoExtract = ts.obj({
2820
+ interval: ts.raw(String(mem.autoExtract.interval)),
2821
+ });
2822
+ }
2823
+ if (mem.compaction) {
2824
+ const compFields = {};
2825
+ if (mem.compaction.trigger) {
2826
+ compFields.trigger = ts.str(mem.compaction.trigger);
2827
+ }
2828
+ if (mem.compaction.threshold !== undefined) {
2829
+ compFields.threshold = ts.raw(String(mem.compaction.threshold));
2830
+ }
2831
+ memoryFields.compaction = ts.obj(compFields);
2832
+ }
2833
+ if (mem.embeddings?.model) {
2834
+ memoryFields.embeddings = ts.obj({
2835
+ model: ts.str(mem.embeddings.model),
2836
+ });
2837
+ }
2838
+ runtimeCtxArgs.memory = ts.obj(memoryFields);
2839
+ }
2580
2840
  const runtimeCtxStatements = [
2581
2841
  ts.constDecl("__globalCtx", ts.new(ts.id("RuntimeContext"), [ts.obj(runtimeCtxArgs)])),
2582
2842
  ts.constDecl("graph", $(ts.runtime.globalCtx).prop("graph").done()),
@@ -2584,8 +2844,31 @@ export class TypeScriptBuilder {
2584
2844
  let runtimeCtx = ts.statements(runtimeCtxStatements);
2585
2845
  return renderImports.default({
2586
2846
  runtimeContextCode: printTs(runtimeCtx),
2847
+ contextInjectedImports: this.generateContextInjectedImports(),
2587
2848
  });
2588
2849
  }
2850
+ /**
2851
+ * Emit the import statements that bring every context-injected
2852
+ * builtin into scope in the generated TS. The set is fixed by
2853
+ * `CONTEXT_INJECTED_BUILTINS` at codegen time, so we always import
2854
+ * the full list — esbuild tree-shakes anything the call site
2855
+ * didn't use. Imports are grouped by each entry's `from` field, so
2856
+ * adding a builtin sourced from a different module is a registry
2857
+ * change only.
2858
+ */
2859
+ generateContextInjectedImports() {
2860
+ const byFrom = {};
2861
+ for (const entry of Object.values(CONTEXT_INJECTED_BUILTINS)) {
2862
+ (byFrom[entry.from] ??= []).push(entry.name);
2863
+ }
2864
+ return Object.keys(byFrom)
2865
+ .sort()
2866
+ .map((from) => {
2867
+ const names = byFrom[from].sort();
2868
+ return `import {\n ${names.join(",\n ")},\n} from ${JSON.stringify(from)};`;
2869
+ })
2870
+ .join("\n");
2871
+ }
2589
2872
  preprocess() {
2590
2873
  const nodes = [];
2591
2874
  this.compilationUnit.importedNodes.forEach((importNode) => {
@@ -2,4 +2,4 @@ import { VariableType } from "../../types.js";
2
2
  /**
3
3
  * Converts a VariableType to a string representation for naming/logging
4
4
  */
5
- export declare function variableTypeToString(variableType: VariableType, typeAliases: Record<string, VariableType>): string;
5
+ export declare function variableTypeToString(variableType: VariableType, typeAliases: Record<string, VariableType>, forFormatting?: boolean): string;
@@ -2,16 +2,19 @@ const MAX_LENGTH = 50;
2
2
  /**
3
3
  * Converts a VariableType to a string representation for naming/logging
4
4
  */
5
- export function variableTypeToString(variableType, typeAliases) {
5
+ export function variableTypeToString(variableType, typeAliases, forFormatting = false) {
6
6
  if (variableType.type === "primitiveType") {
7
7
  if (variableType.value === "object") {
8
+ if (forFormatting) {
9
+ return "object";
10
+ }
8
11
  return "Record<string, any>";
9
12
  }
10
13
  return variableType.value;
11
14
  }
12
15
  else if (variableType.type === "arrayType") {
13
16
  // Recursively build array type string
14
- return `${variableTypeToString(variableType.elementType, typeAliases)}[]`;
17
+ return `${variableTypeToString(variableType.elementType, typeAliases, forFormatting)}[]`;
15
18
  }
16
19
  else if (variableType.type === "stringLiteralType") {
17
20
  return `"${variableType.value}"`;
@@ -24,7 +27,7 @@ export function variableTypeToString(variableType, typeAliases) {
24
27
  }
25
28
  else if (variableType.type === "unionType") {
26
29
  const str = variableType.types
27
- .map((t) => variableTypeToString(t, typeAliases))
30
+ .map((t) => variableTypeToString(t, typeAliases, forFormatting))
28
31
  .join(" | ");
29
32
  if (str.length > MAX_LENGTH) {
30
33
  const arr = str.split(" | ");
@@ -34,7 +37,7 @@ export function variableTypeToString(variableType, typeAliases) {
34
37
  }
35
38
  else if (variableType.type === "objectType") {
36
39
  const props = variableType.properties
37
- .map((prop) => `${prop.key}: ${variableTypeToString(prop.value, typeAliases)}`)
40
+ .map((prop) => `${prop.key}: ${variableTypeToString(prop.value, typeAliases, forFormatting)}`)
38
41
  .join("; ");
39
42
  return `{ ${props} }`;
40
43
  }
@@ -43,14 +46,14 @@ export function variableTypeToString(variableType, typeAliases) {
43
46
  }
44
47
  else if (variableType.type === "blockType") {
45
48
  const params = variableType.params
46
- .map((p) => variableTypeToString(p.typeAnnotation, typeAliases))
49
+ .map((p) => variableTypeToString(p.typeAnnotation, typeAliases, forFormatting))
47
50
  .join(", ");
48
- const ret = variableTypeToString(variableType.returnType, typeAliases);
51
+ const ret = variableTypeToString(variableType.returnType, typeAliases, forFormatting);
49
52
  return `(${params}) => ${ret}`;
50
53
  }
51
54
  else if (variableType.type === "resultType") {
52
- const s = variableTypeToString(variableType.successType, typeAliases);
53
- const f = variableTypeToString(variableType.failureType, typeAliases);
55
+ const s = variableTypeToString(variableType.successType, typeAliases, forFormatting);
56
+ const f = variableTypeToString(variableType.failureType, typeAliases, forFormatting);
54
57
  if (s === "any" && f === "any")
55
58
  return "Result";
56
59
  if (f === "string")