agency-lang 0.0.87 → 0.0.88

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 (233) hide show
  1. package/README.md +17 -24
  2. package/dist/lib/backends/agencyGenerator.d.ts +8 -2
  3. package/dist/lib/backends/agencyGenerator.js +86 -18
  4. package/dist/lib/backends/agencyGenerator.test.js +85 -0
  5. package/dist/lib/backends/typescriptBuilder.d.ts +57 -2
  6. package/dist/lib/backends/typescriptBuilder.js +586 -216
  7. package/dist/lib/backends/typescriptGenerator/typeToString.js +7 -0
  8. package/dist/lib/backends/typescriptGenerator/typeToZodSchema.js +3 -0
  9. package/dist/lib/cli/bundle.d.ts +1 -0
  10. package/dist/lib/cli/bundle.js +45 -5
  11. package/dist/lib/cli/bundle.test.js +82 -1
  12. package/dist/lib/cli/commands.d.ts +0 -1
  13. package/dist/lib/cli/commands.js +4 -21
  14. package/dist/lib/cli/optimize.d.ts +30 -0
  15. package/dist/lib/cli/optimize.js +204 -0
  16. package/dist/lib/cli/optimize.test.js +246 -0
  17. package/dist/lib/cli/optimizerIO.d.ts +28 -0
  18. package/dist/lib/cli/optimizerIO.js +84 -0
  19. package/dist/lib/cli/test.js +4 -4
  20. package/dist/lib/cli/testOptimizerIO.d.ts +29 -0
  21. package/dist/lib/cli/testOptimizerIO.js +31 -0
  22. package/dist/lib/cli/util.js +10 -2
  23. package/dist/lib/config.d.ts +0 -4
  24. package/dist/lib/debugger/driver.js +1 -1
  25. package/dist/lib/debugger/driver.test.js +4 -4
  26. package/dist/lib/index.d.ts +1 -1
  27. package/dist/lib/index.js +1 -1
  28. package/dist/lib/ir/builders.d.ts +11 -3
  29. package/dist/lib/ir/builders.js +16 -3
  30. package/dist/lib/ir/prettyPrint.js +31 -14
  31. package/dist/lib/ir/prettyPrint.test.js +8 -0
  32. package/dist/lib/ir/tsIR.d.ts +15 -1
  33. package/dist/lib/parser.js +2 -19
  34. package/dist/lib/parsers/access.test.js +1 -1
  35. package/dist/lib/parsers/assignment.test.js +1 -1
  36. package/dist/lib/parsers/binop.test.js +2 -2
  37. package/dist/lib/parsers/blockArgument.test.js +2 -2
  38. package/dist/lib/parsers/body.test.js +1 -1
  39. package/dist/lib/parsers/comment.test.js +1 -1
  40. package/dist/lib/parsers/dataStructures.test.js +1 -1
  41. package/dist/lib/parsers/debuggerStatement.test.js +1 -1
  42. package/dist/lib/parsers/expression.test.js +72 -1
  43. package/dist/lib/parsers/forLoop.test.js +1 -1
  44. package/dist/lib/parsers/function.test.js +1 -1
  45. package/dist/lib/parsers/functionCall.test.js +2 -2
  46. package/dist/lib/parsers/handleBlock.test.js +1 -1
  47. package/dist/lib/parsers/ifElse.test.js +1 -1
  48. package/dist/lib/parsers/importStatement.test.js +1 -1
  49. package/dist/lib/parsers/keyword.test.js +1 -1
  50. package/dist/lib/parsers/literals.test.js +1 -1
  51. package/dist/lib/parsers/matchBlock.test.js +1 -1
  52. package/dist/lib/parsers/multiLineComment.test.js +1 -1
  53. package/dist/lib/parsers/parserUtils.test.js +1 -1
  54. package/dist/lib/parsers/parsers.d.ts +136 -0
  55. package/dist/lib/parsers/parsers.js +916 -0
  56. package/dist/lib/parsers/returnStatement.test.js +1 -1
  57. package/dist/lib/parsers/skill.test.js +1 -1
  58. package/dist/lib/parsers/tag.test.js +63 -0
  59. package/dist/lib/parsers/tagIntegration.test.js +168 -0
  60. package/dist/lib/parsers/tools.test.js +1 -1
  61. package/dist/lib/parsers/typeHints.test.js +78 -1
  62. package/dist/lib/parsers/whileLoop.test.js +1 -1
  63. package/dist/lib/parsers/withModifier.test.d.ts +1 -0
  64. package/dist/lib/parsers/withModifier.test.js +63 -0
  65. package/dist/lib/preprocessors/typescriptPreprocessor.d.ts +4 -0
  66. package/dist/lib/preprocessors/typescriptPreprocessor.js +126 -14
  67. package/dist/lib/programInfo.d.ts +2 -1
  68. package/dist/lib/programInfo.js +4 -0
  69. package/dist/lib/runtime/__tests__/node.test.d.ts +1 -0
  70. package/dist/lib/runtime/__tests__/node.test.js +38 -0
  71. package/dist/lib/runtime/classReviver.d.ts +15 -0
  72. package/dist/lib/runtime/classReviver.js +26 -0
  73. package/dist/lib/runtime/errors.d.ts +5 -7
  74. package/dist/lib/runtime/errors.js +0 -12
  75. package/dist/lib/runtime/hooks.d.ts +0 -2
  76. package/dist/lib/runtime/index.d.ts +4 -3
  77. package/dist/lib/runtime/index.js +3 -2
  78. package/dist/lib/runtime/interrupts.d.ts +1 -0
  79. package/dist/lib/runtime/interrupts.js +5 -65
  80. package/dist/lib/runtime/node.d.ts +1 -1
  81. package/dist/lib/runtime/node.js +30 -18
  82. package/dist/lib/runtime/prompt.js +19 -18
  83. package/dist/lib/runtime/result.d.ts +30 -0
  84. package/dist/lib/runtime/result.js +60 -0
  85. package/dist/lib/runtime/result.test.d.ts +1 -0
  86. package/dist/lib/runtime/result.test.js +132 -0
  87. package/dist/lib/runtime/rewind.js +0 -21
  88. package/dist/lib/runtime/runner.d.ts +20 -1
  89. package/dist/lib/runtime/runner.js +114 -1
  90. package/dist/lib/runtime/state/checkpointStore.d.ts +2 -0
  91. package/dist/lib/runtime/state/checkpointStore.js +3 -1
  92. package/dist/lib/runtime/state/context.d.ts +9 -4
  93. package/dist/lib/runtime/state/context.js +27 -20
  94. package/dist/lib/runtime/state/threadStore.d.ts +2 -0
  95. package/dist/lib/runtime/state/threadStore.js +10 -0
  96. package/dist/lib/runtime/streaming.d.ts +1 -1
  97. package/dist/lib/runtime/types.d.ts +1 -1
  98. package/dist/lib/runtime/utils.d.ts +1 -1
  99. package/dist/lib/symbolTable.d.ts +1 -1
  100. package/dist/lib/symbolTable.js +5 -2
  101. package/dist/lib/templates/backends/agency/template.d.ts +1 -1
  102. package/dist/lib/templates/backends/agency/template.js +1 -1
  103. package/dist/lib/templates/backends/typescriptGenerator/builtinFunctions/input.d.ts +1 -1
  104. package/dist/lib/templates/backends/typescriptGenerator/builtinFunctions/input.js +2 -2
  105. package/dist/lib/templates/backends/typescriptGenerator/classDefinition.d.ts +19 -0
  106. package/dist/lib/templates/backends/typescriptGenerator/classDefinition.js +48 -0
  107. package/dist/lib/templates/backends/typescriptGenerator/classMethod.d.ts +14 -0
  108. package/dist/lib/templates/backends/typescriptGenerator/classMethod.js +37 -0
  109. package/dist/lib/templates/backends/typescriptGenerator/forkBlockSetup.d.ts +9 -0
  110. package/dist/lib/templates/backends/typescriptGenerator/forkBlockSetup.js +18 -0
  111. package/dist/lib/templates/backends/typescriptGenerator/functionCatchFailure.d.ts +6 -0
  112. package/dist/lib/templates/backends/typescriptGenerator/functionCatchFailure.js +21 -0
  113. package/dist/lib/templates/backends/typescriptGenerator/imports.d.ts +1 -1
  114. package/dist/lib/templates/backends/typescriptGenerator/imports.js +5 -5
  115. package/dist/lib/templates/backends/typescriptGenerator/interruptAssignment.d.ts +1 -1
  116. package/dist/lib/templates/backends/typescriptGenerator/interruptAssignment.js +4 -4
  117. package/dist/lib/templates/backends/typescriptGenerator/interruptReturn.d.ts +1 -1
  118. package/dist/lib/templates/backends/typescriptGenerator/interruptReturn.js +4 -4
  119. package/dist/lib/templates/backends/typescriptGenerator/resultCheckpointSetup.d.ts +8 -0
  120. package/dist/lib/templates/backends/typescriptGenerator/resultCheckpointSetup.js +18 -0
  121. package/dist/lib/templates/backends/typescriptGenerator/runnerIfElse.d.ts +12 -0
  122. package/dist/lib/templates/backends/typescriptGenerator/runnerIfElse.js +20 -0
  123. package/dist/lib/typeChecker/assignability.d.ts +4 -0
  124. package/dist/lib/typeChecker/assignability.js +120 -0
  125. package/dist/lib/typeChecker/builtins.d.ts +2 -0
  126. package/dist/lib/typeChecker/builtins.js +53 -0
  127. package/dist/lib/typeChecker/checker.d.ts +4 -0
  128. package/dist/lib/typeChecker/checker.js +107 -0
  129. package/dist/lib/typeChecker/index.d.ts +26 -0
  130. package/dist/lib/typeChecker/index.js +104 -0
  131. package/dist/lib/typeChecker/inference.d.ts +5 -0
  132. package/dist/lib/typeChecker/inference.js +67 -0
  133. package/dist/lib/typeChecker/scopes.d.ts +9 -0
  134. package/dist/lib/typeChecker/scopes.js +150 -0
  135. package/dist/lib/typeChecker/synthesizer.d.ts +15 -0
  136. package/dist/lib/typeChecker/synthesizer.js +193 -0
  137. package/dist/lib/typeChecker/types.d.ts +35 -0
  138. package/dist/lib/typeChecker/types.js +1 -0
  139. package/dist/lib/typeChecker/utils.d.ts +14 -0
  140. package/dist/lib/typeChecker/utils.js +38 -0
  141. package/dist/lib/typeChecker/validate.d.ts +3 -0
  142. package/dist/lib/typeChecker/validate.js +24 -0
  143. package/dist/lib/typeChecker.test.js +1 -1
  144. package/dist/lib/types/binop.d.ts +1 -1
  145. package/dist/lib/types/binop.js +4 -0
  146. package/dist/lib/types/classDefinition.d.ts +29 -0
  147. package/dist/lib/types/classDefinition.js +4 -0
  148. package/dist/lib/types/function.d.ts +3 -0
  149. package/dist/lib/types/graphNode.d.ts +2 -0
  150. package/dist/lib/types/placeholder.d.ts +4 -0
  151. package/dist/lib/types/placeholder.js +1 -0
  152. package/dist/lib/types/tag.d.ts +6 -0
  153. package/dist/lib/types/tag.js +1 -0
  154. package/dist/lib/types/tryExpression.d.ts +7 -0
  155. package/dist/lib/types/tryExpression.js +1 -0
  156. package/dist/lib/types/typeHints.d.ts +6 -1
  157. package/dist/lib/types/withModifier.d.ts +7 -0
  158. package/dist/lib/types/withModifier.js +1 -0
  159. package/dist/lib/types.d.ts +13 -4
  160. package/dist/lib/types.js +4 -1
  161. package/dist/lib/utils/node.js +31 -6
  162. package/dist/scripts/agency.js +95 -78
  163. package/package.json +6 -5
  164. package/stdlib/_builtins.js +24 -0
  165. package/stdlib/consensus.agency +9 -0
  166. package/stdlib/firstValid.agency +15 -0
  167. package/stdlib/index.agency +203 -8
  168. package/stdlib/index.js +3233 -1190
  169. package/stdlib/lib/wikipedia.js +47 -0
  170. package/stdlib/retry.agency +29 -0
  171. package/stdlib/sample.agency +8 -0
  172. package/stdlib/wikipedia.agency +41 -0
  173. package/dist/lib/ir/audit.d.ts +0 -22
  174. package/dist/lib/ir/audit.js +0 -57
  175. package/dist/lib/ir/audit.test.js +0 -82
  176. package/dist/lib/parsers/access.d.ts +0 -7
  177. package/dist/lib/parsers/access.js +0 -68
  178. package/dist/lib/parsers/binop.d.ts +0 -3
  179. package/dist/lib/parsers/binop.js +0 -19
  180. package/dist/lib/parsers/blockArgument.d.ts +0 -3
  181. package/dist/lib/parsers/blockArgument.js +0 -28
  182. package/dist/lib/parsers/comment.d.ts +0 -3
  183. package/dist/lib/parsers/comment.js +0 -6
  184. package/dist/lib/parsers/dataStructures.d.ts +0 -6
  185. package/dist/lib/parsers/dataStructures.js +0 -13
  186. package/dist/lib/parsers/debuggerStatement.d.ts +0 -3
  187. package/dist/lib/parsers/debuggerStatement.js +0 -12
  188. package/dist/lib/parsers/expression.d.ts +0 -3
  189. package/dist/lib/parsers/expression.js +0 -121
  190. package/dist/lib/parsers/forLoop.d.ts +0 -1
  191. package/dist/lib/parsers/forLoop.js +0 -3
  192. package/dist/lib/parsers/function.d.ts +0 -27
  193. package/dist/lib/parsers/function.js +0 -159
  194. package/dist/lib/parsers/functionCall.d.ts +0 -4
  195. package/dist/lib/parsers/functionCall.js +0 -13
  196. package/dist/lib/parsers/importStatement.d.ts +0 -5
  197. package/dist/lib/parsers/importStatement.js +0 -45
  198. package/dist/lib/parsers/keyword.d.ts +0 -3
  199. package/dist/lib/parsers/keyword.js +0 -12
  200. package/dist/lib/parsers/literals.d.ts +0 -16
  201. package/dist/lib/parsers/literals.js +0 -103
  202. package/dist/lib/parsers/loc.d.ts +0 -9
  203. package/dist/lib/parsers/loc.js +0 -30
  204. package/dist/lib/parsers/matchBlock.d.ts +0 -9
  205. package/dist/lib/parsers/matchBlock.js +0 -24
  206. package/dist/lib/parsers/multiLineComment.d.ts +0 -3
  207. package/dist/lib/parsers/multiLineComment.js +0 -7
  208. package/dist/lib/parsers/newline.d.ts +0 -3
  209. package/dist/lib/parsers/newline.js +0 -2
  210. package/dist/lib/parsers/parserUtils.d.ts +0 -3
  211. package/dist/lib/parsers/parserUtils.js +0 -5
  212. package/dist/lib/parsers/returnStatement.d.ts +0 -3
  213. package/dist/lib/parsers/returnStatement.js +0 -6
  214. package/dist/lib/parsers/skill.d.ts +0 -5
  215. package/dist/lib/parsers/skill.js +0 -37
  216. package/dist/lib/parsers/specialVar.d.ts +0 -4
  217. package/dist/lib/parsers/specialVar.js +0 -7
  218. package/dist/lib/parsers/specialVar.test.js +0 -240
  219. package/dist/lib/parsers/tools.d.ts +0 -3
  220. package/dist/lib/parsers/tools.js +0 -3
  221. package/dist/lib/parsers/typeHints.d.ts +0 -22
  222. package/dist/lib/parsers/typeHints.js +0 -118
  223. package/dist/lib/parsers/utils.d.ts +0 -8
  224. package/dist/lib/parsers/utils.js +0 -8
  225. package/dist/lib/runtime/audit.d.ts +0 -79
  226. package/dist/lib/typeChecker.d.ts +0 -65
  227. package/dist/lib/typeChecker.js +0 -800
  228. package/dist/lib/types/specialVar.d.ts +0 -9
  229. package/dist/lib/types/specialVar.js +0 -1
  230. package/stdlib/math.js +0 -389
  231. /package/dist/lib/{ir/audit.test.d.ts → cli/optimize.test.d.ts} +0 -0
  232. /package/dist/lib/parsers/{specialVar.test.d.ts → tag.test.d.ts} +0 -0
  233. /package/dist/lib/{runtime/audit.js → parsers/tagIntegration.test.d.ts} +0 -0
package/README.md CHANGED
@@ -1,38 +1,31 @@
1
- # Agency
2
- Agent Definition Language
1
+ # Getting Started
3
2
 
4
- ```ts
5
- node main() {
6
- result = llm("Say hello to world")
7
- return result
8
- }
9
- ```
3
+ Agency is a language for building agents that compiles to TypeScript.
10
4
 
11
- ## Usage
12
-
13
- Add agency to a project:
5
+ ## Installation
14
6
 
15
7
  ```bash
16
- pnpm add agency-lang zod
8
+ npm install agency-lang zod
17
9
  ```
18
10
 
19
- You can then start using the agency script on your files:
20
-
21
- ```bash
22
- # to compile
23
- agency compile infile.agency outfile.ts
11
+ ## Quick Start
24
12
 
25
- # to compile and run
26
- agency run infile.agency
13
+ Create a file called `hello.agency`:
27
14
 
28
- # or simply
29
- agency infile.agency
15
+ ```ts
16
+ node main() {
17
+ const greeting = llm("Say hello to the world!");
18
+ print(greeting);
19
+ }
30
20
  ```
31
21
 
32
- ## troubleshooting
33
- ### Weird undefined error
22
+ Compile and run it:
23
+
24
+ ```bash
25
+ pnpm run agency hello.agency
26
+ ```
34
27
 
35
- A couple of times, I have tried to import a parser, and even though it exists, when I import it, the value that is `undefined`. This is due to a circular dependency issue. If I move that parser to its own file and then import it, it works.
28
+ Now read [the docs](https://agency-lang.com) to learn more about the language and how to use it!
36
29
 
37
30
  ## License
38
31
  [FSL](https://fsl.software).
@@ -1,4 +1,3 @@
1
- import { SpecialVar } from "../types/specialVar.js";
2
1
  import { AgencyComment, AgencyMultiLineComment, AgencyNode, AgencyProgram, Assignment, DebuggerStatement, Literal, NewLine, Scope, TypeAlias, VariableType } from "../types.js";
3
2
  import { AccessChainElement, ValueAccess } from "../types/access.js";
4
3
  import { AgencyArray, AgencyObject } from "../types/dataStructures.js";
@@ -17,6 +16,8 @@ import { Skill } from "../types/skill.js";
17
16
  import { BinOpArgument, BinOpExpression, Operator } from "../types/binop.js";
18
17
  import { Keyword } from "../types/keyword.js";
19
18
  import { HandleBlock } from "../types/handleBlock.js";
19
+ import { Tag } from "../types/tag.js";
20
+ import { ClassDefinition, NewExpression } from "../types/classDefinition.js";
20
21
  export declare class AgencyGenerator {
21
22
  protected graphNodes: GraphNodeDefinition[];
22
23
  protected generatedStatements: string[];
@@ -87,15 +88,20 @@ export declare class AgencyGenerator {
87
88
  protected processImportToolStatement(node: ImportToolStatement): string;
88
89
  protected visibilityToString(vis: Visibility): string;
89
90
  protected processGraphNode(node: GraphNodeDefinition): string;
91
+ protected processClassDefinition(node: ClassDefinition): string;
92
+ protected processNewExpression(node: NewExpression): string;
90
93
  protected processTool(node: FunctionDefinition): string;
91
94
  protected processUsesTool(node: UsesTool): string;
92
- protected processSpecialVar(node: SpecialVar): string;
93
95
  protected processNewLine(_node: NewLine): string;
94
96
  protected processMessageThread(node: MessageThread): string;
95
97
  protected processHandleBlock(node: HandleBlock): string;
96
98
  protected processSkill(node: Skill): string;
97
99
  protected processBinOpExpression(node: BinOpExpression): string;
98
100
  protected processAccessChainElement(node: AccessChainElement): string;
101
+ protected formatTag(tag: Tag): string;
102
+ protected formatAttachedTags(node: {
103
+ tags?: Tag[];
104
+ }): string;
99
105
  protected processKeyword(node: Keyword): string;
100
106
  }
101
107
  export declare function generateAgency(program: AgencyProgram): string;
@@ -62,7 +62,7 @@ export class AgencyGenerator {
62
62
  "graphNode", "function", "typeAlias",
63
63
  ]);
64
64
  const NO_SPACE_TYPES = new Set([
65
- "comment", "multiLineComment"
65
+ "comment", "multiLineComment", "tag"
66
66
  ]);
67
67
  // Pass 5: Process all nodes and generate code
68
68
  const stmtPairs = [];
@@ -171,8 +171,6 @@ export class AgencyGenerator {
171
171
  return this.processWhileLoop(node);
172
172
  case "ifElse":
173
173
  return this.processIfElse(node);
174
- case "specialVar":
175
- return this.processSpecialVar(node);
176
174
  case "newLine":
177
175
  return this.processNewLine(node);
178
176
  case "rawCode":
@@ -181,12 +179,24 @@ export class AgencyGenerator {
181
179
  return this.processMessageThread(node);
182
180
  case "handleBlock":
183
181
  return this.processHandleBlock(node);
182
+ case "withModifier":
183
+ return `${this.processNode(node.statement)} with ${node.handlerName}`;
184
184
  case "skill":
185
185
  return this.processSkill(node);
186
186
  case "binOpExpression":
187
187
  return this.processBinOpExpression(node);
188
188
  case "keyword":
189
189
  return this.processKeyword(node);
190
+ case "tag":
191
+ return this.formatTag(node);
192
+ case "placeholder":
193
+ return "?";
194
+ case "tryExpression":
195
+ return `try ${this.processNode(node.call)}`;
196
+ case "classDefinition":
197
+ return this.processClassDefinition(node);
198
+ case "newExpression":
199
+ return this.processNewExpression(node);
190
200
  default:
191
201
  throw new Error(`Unhandled Agency node type: ${node.type}`);
192
202
  }
@@ -280,6 +290,7 @@ export class AgencyGenerator {
280
290
  }
281
291
  // Assignment and literals
282
292
  processAssignment(node) {
293
+ const tags = this.formatAttachedTags(node);
283
294
  const chainStr = node.accessChain
284
295
  ?.map((ce) => this.processAccessChainElement(ce))
285
296
  .join("") ?? "";
@@ -289,7 +300,7 @@ export class AgencyGenerator {
289
300
  const sharedPrefix = node.shared ? "shared " : "";
290
301
  const declPrefix = node.declKind ? `${node.declKind} ` : "";
291
302
  let valueCode = this.processNode(node.value).trim();
292
- return this.indentStr(`${sharedPrefix}${declPrefix}${varName} = ${valueCode}`);
303
+ return tags + this.indentStr(`${sharedPrefix}${declPrefix}${varName} = ${valueCode}`);
293
304
  }
294
305
  generateLiteral(literal) {
295
306
  switch (literal.type) {
@@ -340,6 +351,7 @@ export class AgencyGenerator {
340
351
  }
341
352
  // Function methods
342
353
  processFunctionDefinition(node) {
354
+ const tags = this.formatAttachedTags(node);
343
355
  const { functionName, body, parameters } = node;
344
356
  const params = parameters
345
357
  .map((p) => {
@@ -376,11 +388,12 @@ export class AgencyGenerator {
376
388
  result += bodyCode;
377
389
  this.decreaseIndent();
378
390
  result += this.indentStr(`}`);
379
- return result;
391
+ return tags + result;
380
392
  }
381
393
  processFunctionCall(node) {
394
+ const tags = this.formatAttachedTags(node);
382
395
  const expr = this.generateFunctionCallExpression(node, "topLevelStatement");
383
- return this.indentStr(`${expr}`);
396
+ return tags + this.indentStr(`${expr}`);
384
397
  }
385
398
  generateFunctionCallExpression(node, context) {
386
399
  const args = node.arguments.map((arg) => {
@@ -602,6 +615,7 @@ export class AgencyGenerator {
602
615
  }
603
616
  }
604
617
  processGraphNode(node) {
618
+ const tags = this.formatAttachedTags(node);
605
619
  const { nodeName, body, parameters } = node;
606
620
  const params = parameters
607
621
  .map((p) => p.typeHint
@@ -622,17 +636,48 @@ export class AgencyGenerator {
622
636
  result += bodyCode;
623
637
  this.decreaseIndent();
624
638
  result += this.indentStr(`}`);
639
+ return tags + result;
640
+ }
641
+ processClassDefinition(node) {
642
+ const extendsStr = node.parentClass ? ` extends ${node.parentClass}` : "";
643
+ let result = this.indentStr(`class ${node.className}${extendsStr} {\n`);
644
+ this.increaseIndent();
645
+ // Fields
646
+ for (const field of node.fields) {
647
+ result += this.indentStr(`${field.name}: ${variableTypeToString(field.typeHint, this.typeAliases)}\n`);
648
+ }
649
+ // Methods (constructor is auto-generated, not formatted)
650
+ for (const method of node.methods) {
651
+ const params = method.parameters
652
+ .map((p) => p.typeHint
653
+ ? `${p.name}: ${variableTypeToString(p.typeHint, this.typeAliases)}`
654
+ : p.name)
655
+ .join(", ");
656
+ const returnTypeStr = `: ${variableTypeToString(method.returnType, this.typeAliases)}`;
657
+ result += "\n" + this.indentStr(`${method.name}(${params})${returnTypeStr} {\n`);
658
+ this.increaseIndent();
659
+ const methodLines = [];
660
+ for (const stmt of method.body) {
661
+ methodLines.push(this.processNode(stmt));
662
+ }
663
+ result += methodLines.filter(s => s !== "").join("\n").trimEnd() + "\n";
664
+ this.decreaseIndent();
665
+ result += this.indentStr(`}\n`);
666
+ }
667
+ this.decreaseIndent();
668
+ result += this.indentStr(`}`);
625
669
  return result;
626
670
  }
671
+ processNewExpression(node) {
672
+ const args = node.arguments.map((a) => expressionToString(a)).join(", ");
673
+ return `new ${node.className}(${args})`;
674
+ }
627
675
  processTool(node) {
628
676
  return "";
629
677
  }
630
678
  processUsesTool(node) {
631
679
  return this.indentStr(`uses ${node.toolNames.join(", ")}`);
632
680
  }
633
- processSpecialVar(node) {
634
- return this.indentStr(`@${node.name} = ${this.processNode(node.value).trim()}`);
635
- }
636
681
  processNewLine(_node) {
637
682
  return "";
638
683
  }
@@ -678,15 +723,21 @@ export class AgencyGenerator {
678
723
  return this.indentStr(`skill "${node.filepath}"`);
679
724
  }
680
725
  processBinOpExpression(node) {
681
- const left = this.processNode(node.left).trim();
682
- const right = this.processNode(node.right).trim();
683
- const wrappedLeft = this.needsParensLeft(node.left, node.operator)
684
- ? `(${left})`
685
- : left;
686
- const wrappedRight = this.needsParensRight(node.right, node.operator)
687
- ? `(${right})`
688
- : right;
689
- return this.indentStr(`${wrappedLeft} ${node.operator} ${wrappedRight}`);
726
+ // Collect a chain of the same operator (e.g. a |> b |> c)
727
+ const op = node.operator;
728
+ const parts = [];
729
+ let current = node;
730
+ while (current.type === "binOpExpression" && current.operator === op) {
731
+ parts.push(this.processNode(current.right).trim());
732
+ current = current.left;
733
+ }
734
+ parts.push(this.processNode(current).trim());
735
+ parts.reverse();
736
+ const oneLine = parts.join(` ${op} `);
737
+ if (oneLine.length <= 60) {
738
+ return oneLine;
739
+ }
740
+ return parts[0] + "\n" + parts.slice(1).map((p) => this.indentStr(`${op} ${p}`)).join("\n");
690
741
  }
691
742
  processAccessChainElement(node) {
692
743
  switch (node.kind) {
@@ -700,6 +751,23 @@ export class AgencyGenerator {
700
751
  throw new Error(`Unknown access chain element kind: ${node.kind}`);
701
752
  }
702
753
  }
754
+ formatTag(tag) {
755
+ if (tag.arguments.length === 0) {
756
+ return this.indentStr(`@${tag.name}`);
757
+ }
758
+ const args = tag.arguments.map((arg) => {
759
+ if (/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(arg)) {
760
+ return arg;
761
+ }
762
+ return JSON.stringify(arg);
763
+ });
764
+ return this.indentStr(`@${tag.name}(${args.join(", ")})`);
765
+ }
766
+ formatAttachedTags(node) {
767
+ if (!node.tags?.length)
768
+ return "";
769
+ return node.tags.map((tag) => this.formatTag(tag)).join("\n") + "\n";
770
+ }
703
771
  processKeyword(node) {
704
772
  return this.indentStr(`${node.value}`);
705
773
  }
@@ -155,3 +155,88 @@ describe("AgencyGenerator - Function Parameter Type Hints", () => {
155
155
  });
156
156
  });
157
157
  });
158
+ describe("AgencyGenerator - Class Definitions", () => {
159
+ function formatAgency(input) {
160
+ const parseResult = parseAgency(input, {}, false);
161
+ expect(parseResult.success).toBe(true);
162
+ if (!parseResult.success)
163
+ return "";
164
+ const generator = new AgencyGenerator();
165
+ return generator.generate(parseResult.result).output.trim();
166
+ }
167
+ it("should format a class with fields and a method", () => {
168
+ const input = `class Counter {
169
+ value: number
170
+
171
+ get(): number {
172
+ return this.value
173
+ }
174
+ }`;
175
+ const output = formatAgency(input);
176
+ expect(output).toContain("class Counter {");
177
+ expect(output).toContain(" value: number");
178
+ expect(output).toContain(" get(): number {");
179
+ expect(output).toContain(" return this.value");
180
+ expect(output).toContain(" }");
181
+ expect(output).toContain("}");
182
+ });
183
+ it("should format method bodies with proper line breaks", () => {
184
+ const input = `class Foo {
185
+ x: number
186
+
187
+ doStuff(): number {
188
+ let a = this.x
189
+ let b = a + 1
190
+ return b
191
+ }
192
+ }`;
193
+ const output = formatAgency(input);
194
+ // Each statement in the method body should be on its own line
195
+ expect(output).toContain(" let a = this.x\n");
196
+ expect(output).toContain(" let b = a + 1\n");
197
+ expect(output).toContain(" return b\n");
198
+ });
199
+ it("should reject user-defined constructors", () => {
200
+ const input = `class User {
201
+ name: string
202
+ constructor(name: string) {
203
+ this.name = name
204
+ }
205
+ }`;
206
+ const parseResult = parseAgency(input, {}, false);
207
+ expect(parseResult.success).toBe(false);
208
+ });
209
+ it("should format a class with inheritance", () => {
210
+ const input = `class Dog extends Animal {
211
+ breed: string
212
+
213
+ speak(): string {
214
+ return this.name
215
+ }
216
+ }`;
217
+ const output = formatAgency(input);
218
+ expect(output).toContain("class Dog extends Animal {");
219
+ expect(output).toContain(" breed: string");
220
+ });
221
+ it("should format a method with parameters", () => {
222
+ const input = `class Calc {
223
+ value: number
224
+
225
+ add(n: number): number {
226
+ this.value = this.value + n
227
+ return this.value
228
+ }
229
+ }`;
230
+ const output = formatAgency(input);
231
+ expect(output).toContain(" add(n: number): number {");
232
+ expect(output).toContain(" this.value = this.value + n\n");
233
+ expect(output).toContain(" return this.value\n");
234
+ });
235
+ it("should format new expressions", () => {
236
+ const input = `node main() {
237
+ let c = new Counter(0)
238
+ }`;
239
+ const output = formatAgency(input);
240
+ expect(output).toContain("new Counter(0)");
241
+ });
242
+ });
@@ -13,8 +13,8 @@ export declare class TypeScriptBuilder {
13
13
  private currentAdjacentNodes;
14
14
  private isInsideGraphNode;
15
15
  private loopVars;
16
- private insideMessageThread;
17
16
  private insideHandlerBody;
17
+ private insideGlobalInit;
18
18
  private _blockCounter;
19
19
  /** Stack of loop subKeys for generating break/continue cleanup code.
20
20
  * Pushed when entering a stepped loop, popped when leaving. */
@@ -86,6 +86,27 @@ export declare class TypeScriptBuilder {
86
86
  private generateStringLiteralNode;
87
87
  private processValueAccess;
88
88
  private processBinOpExpression;
89
+ private processCatchExpression;
90
+ private processPipeExpression;
91
+ private processTryExpression;
92
+ private processNewExpression;
93
+ /**
94
+ * Check if a method name matches any method defined on any known Agency class.
95
+ * Used to decide whether to inject __state into method calls.
96
+ */
97
+ private isKnownClassMethod;
98
+ /**
99
+ * Build the __state config object for method calls on Agency class instances.
100
+ */
101
+ private buildMethodCallConfig;
102
+ /**
103
+ * Collect all fields for a class, walking the inheritance chain.
104
+ * Returns parent fields first, then own fields.
105
+ */
106
+ private collectAllClassFields;
107
+ private formatParam;
108
+ private buildMethodCode;
109
+ private processClassDefinition;
89
110
  private processIfElseWithSteps;
90
111
  private processForLoopWithSteps;
91
112
  private processWhileLoopWithSteps;
@@ -101,12 +122,24 @@ export declare class TypeScriptBuilder {
101
122
  * The tool() function is defined in imports.mustache and closes over __toolRegistry.
102
123
  */
103
124
  private generateToolRegistry;
125
+ /**
126
+ * For Result-returning functions: emit a pinned checkpoint at function entry
127
+ * and a preamble that applies arg overrides on restore (for result.retry()).
128
+ */
129
+ private buildResultCheckpointSetup;
130
+ /**
131
+ * Build the body statements for an Agency function or class method.
132
+ * Includes setup, runner, result checkpoint, try/catch/finally, hooks.
133
+ * Shared between processFunctionDefinition and class method compilation.
134
+ */
135
+ private buildFunctionBody;
104
136
  private processFunctionDefinition;
105
137
  private processStatement;
106
138
  private buildInterruptReturn;
107
139
  private processFunctionCallAsStatement;
108
140
  private processFunctionCall;
109
141
  private generateFunctionCallExpression;
142
+ private processForkCall;
110
143
  private generateNodeCallExpression;
111
144
  private processGraphNode;
112
145
  private processReturnStatement;
@@ -121,14 +154,36 @@ export declare class TypeScriptBuilder {
121
154
  private processLlmCall;
122
155
  private processSentinel;
123
156
  private processDebuggerStatement;
124
- private processSpecialVar;
125
157
  private processMessageThread;
126
158
  private processBlockPlain;
159
+ private processNodeInGlobalInit;
160
+ private buildBuiltinHandlerArrow;
127
161
  private processHandleBlockWithSteps;
162
+ private processWithModifier;
128
163
  /** In debugger mode, insert debuggerStatement nodes before each
129
164
  * step-triggering statement so that debugStep() is called at every
130
165
  * substep boundary, not just top-level steps. */
131
166
  private insertDebugSteps;
167
+ private _pipeCounter;
168
+ /**
169
+ * Walk a left-recursive |> tree and return [initial, stage1, stage2, ...].
170
+ * Returns null if the expression is not a pipe assignment.
171
+ */
172
+ private getPipeChainStages;
173
+ /** Build: await __pipeBind(leftIR, async (__pipeArg) => stage(__pipeArg)) */
174
+ private buildPipeBind;
175
+ /**
176
+ * Expand a pipe chain assignment into multiple IR parts, one per stage.
177
+ * Each part becomes its own runner step so interrupts don't replay earlier stages.
178
+ */
179
+ private expandPipeChain;
180
+ private buildPipeLambda;
181
+ /**
182
+ * Process a valueAccess up to but not including the last chain element.
183
+ * Used by pipe to get the receiver for a method call.
184
+ */
185
+ private processValueAccessPartial;
186
+ private buildPipeStateArgs;
132
187
  private processBodyAsParts;
133
188
  private generateBuiltins;
134
189
  private generateImports;