agency-lang 0.0.106 → 0.0.107

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 (155) hide show
  1. package/dist/lib/backends/agencyGenerator.d.ts +4 -0
  2. package/dist/lib/backends/agencyGenerator.js +30 -6
  3. package/dist/lib/backends/typescriptBuilder.d.ts +4 -0
  4. package/dist/lib/backends/typescriptBuilder.js +70 -19
  5. package/dist/lib/backends/typescriptGenerator/builtins.js +3 -0
  6. package/dist/lib/backends/typescriptGenerator/typeToZodSchema.js +1 -4
  7. package/dist/lib/backends/typescriptGenerator/typeToZodSchema.test.d.ts +1 -0
  8. package/dist/lib/backends/typescriptGenerator/typeToZodSchema.test.js +84 -0
  9. package/dist/lib/cli/commands.d.ts +2 -2
  10. package/dist/lib/cli/commands.js +36 -72
  11. package/dist/lib/cli/doc.js +12 -6
  12. package/dist/lib/cli/doc.test.js +2 -2
  13. package/dist/lib/config.d.ts +14 -0
  14. package/dist/lib/config.js +93 -14
  15. package/dist/lib/debugger/hotReload.d.ts +11 -0
  16. package/dist/lib/debugger/hotReload.js +73 -0
  17. package/dist/lib/formatter.d.ts +6 -0
  18. package/dist/lib/formatter.js +12 -0
  19. package/dist/lib/formatter.test.d.ts +1 -0
  20. package/dist/lib/formatter.test.js +10 -0
  21. package/dist/lib/importPaths.js +5 -2
  22. package/dist/lib/ir/builders.d.ts +1 -1
  23. package/dist/lib/ir/builders.js +2 -1
  24. package/dist/lib/lsp/completion.d.ts +3 -0
  25. package/dist/lib/lsp/completion.js +31 -0
  26. package/dist/lib/lsp/completion.test.d.ts +1 -0
  27. package/dist/lib/lsp/completion.test.js +50 -0
  28. package/dist/lib/lsp/definition.d.ts +4 -0
  29. package/dist/lib/lsp/definition.js +25 -0
  30. package/dist/lib/lsp/definition.test.d.ts +1 -0
  31. package/dist/lib/lsp/definition.test.js +61 -0
  32. package/dist/lib/lsp/diagnostics.d.ts +15 -0
  33. package/dist/lib/lsp/diagnostics.js +70 -0
  34. package/dist/lib/lsp/diagnostics.test.d.ts +1 -0
  35. package/dist/lib/lsp/diagnostics.test.js +35 -0
  36. package/dist/lib/lsp/documentSymbol.d.ts +3 -0
  37. package/dist/lib/lsp/documentSymbol.js +48 -0
  38. package/dist/lib/lsp/documentSymbol.test.d.ts +1 -0
  39. package/dist/lib/lsp/documentSymbol.test.js +42 -0
  40. package/dist/lib/lsp/formatting.d.ts +4 -0
  41. package/dist/lib/lsp/formatting.js +14 -0
  42. package/dist/lib/lsp/formatting.test.d.ts +1 -0
  43. package/dist/lib/lsp/formatting.test.js +30 -0
  44. package/dist/lib/lsp/hover.d.ts +4 -0
  45. package/dist/lib/lsp/hover.js +12 -0
  46. package/dist/lib/lsp/hover.test.d.ts +1 -0
  47. package/dist/lib/lsp/hover.test.js +69 -0
  48. package/dist/lib/lsp/index.d.ts +1 -0
  49. package/dist/lib/lsp/index.js +1 -0
  50. package/dist/lib/lsp/locations.d.ts +3 -0
  51. package/dist/lib/lsp/locations.js +12 -0
  52. package/dist/lib/lsp/projectRoot.test.d.ts +1 -0
  53. package/dist/lib/lsp/projectRoot.test.js +46 -0
  54. package/dist/lib/lsp/semantics.d.ts +19 -0
  55. package/dist/lib/lsp/semantics.js +183 -0
  56. package/dist/lib/lsp/server.d.ts +1 -0
  57. package/dist/lib/lsp/server.js +135 -0
  58. package/dist/lib/lsp/setup.d.ts +9 -0
  59. package/dist/lib/lsp/setup.js +88 -0
  60. package/dist/lib/lsp/setup.test.d.ts +1 -0
  61. package/dist/lib/lsp/setup.test.js +56 -0
  62. package/dist/lib/lsp/uri.d.ts +2 -0
  63. package/dist/lib/lsp/uri.js +7 -0
  64. package/dist/lib/lsp/uri.test.d.ts +1 -0
  65. package/dist/lib/lsp/uri.test.js +11 -0
  66. package/dist/lib/lsp/workspace.d.ts +8 -0
  67. package/dist/lib/lsp/workspace.js +14 -0
  68. package/dist/lib/mcp/server.d.ts +20 -0
  69. package/dist/lib/mcp/server.js +191 -0
  70. package/dist/lib/mcp/server.test.d.ts +1 -0
  71. package/dist/lib/mcp/server.test.js +131 -0
  72. package/dist/lib/mcp/setup.d.ts +8 -0
  73. package/dist/lib/mcp/setup.js +42 -0
  74. package/dist/lib/mcp/setup.test.d.ts +1 -0
  75. package/dist/lib/mcp/setup.test.js +45 -0
  76. package/dist/lib/mcp/tools.d.ts +53 -0
  77. package/dist/lib/mcp/tools.js +175 -0
  78. package/dist/lib/parser.d.ts +18 -1
  79. package/dist/lib/parser.js +14 -4
  80. package/dist/lib/parser.test.js +20 -0
  81. package/dist/lib/parsers/blockArgument.test.js +155 -1
  82. package/dist/lib/parsers/gotoStatement.test.d.ts +1 -0
  83. package/dist/lib/parsers/gotoStatement.test.js +51 -0
  84. package/dist/lib/parsers/parsers.d.ts +3 -0
  85. package/dist/lib/parsers/parsers.js +62 -5
  86. package/dist/lib/preprocessors/importResolver.js +7 -3
  87. package/dist/lib/runtime/builtins.d.ts +0 -9
  88. package/dist/lib/runtime/builtins.js +0 -9
  89. package/dist/lib/runtime/call.d.ts +1 -1
  90. package/dist/lib/runtime/call.js +4 -1
  91. package/dist/lib/runtime/hooks.d.ts +1 -0
  92. package/dist/lib/runtime/hooks.js +12 -4
  93. package/dist/lib/runtime/index.d.ts +4 -1
  94. package/dist/lib/runtime/index.js +3 -1
  95. package/dist/lib/runtime/llmClient.d.ts +45 -0
  96. package/dist/lib/runtime/llmClient.js +18 -0
  97. package/dist/lib/runtime/prompt.js +12 -4
  98. package/dist/lib/runtime/simpleOpenAIClient.d.ts +16 -0
  99. package/dist/lib/runtime/simpleOpenAIClient.js +115 -0
  100. package/dist/lib/runtime/simpleOpenAIClient.test.d.ts +1 -0
  101. package/dist/lib/runtime/simpleOpenAIClient.test.js +24 -0
  102. package/dist/lib/runtime/state/context.d.ts +6 -0
  103. package/dist/lib/runtime/state/context.js +9 -0
  104. package/dist/lib/symbolTable.d.ts +3 -0
  105. package/dist/lib/symbolTable.js +14 -3
  106. package/dist/lib/symbolTable.test.js +20 -2
  107. package/dist/lib/templates/backends/agency/template.d.ts +1 -1
  108. package/dist/lib/templates/backends/agency/template.js +1 -1
  109. package/dist/lib/templates/backends/typescriptGenerator/builtinFunctions/setLLMClient.d.ts +4 -0
  110. package/dist/lib/templates/backends/typescriptGenerator/builtinFunctions/setLLMClient.js +12 -0
  111. package/dist/lib/templates/backends/typescriptGenerator/imports.d.ts +1 -1
  112. package/dist/lib/templates/backends/typescriptGenerator/imports.js +1 -2
  113. package/dist/lib/typeChecker/builtins.js +2 -1
  114. package/dist/lib/typeChecker/checker.js +5 -2
  115. package/dist/lib/typeChecker/index.js +1 -1
  116. package/dist/lib/typeChecker/scopes.js +5 -1
  117. package/dist/lib/typeChecker/types.d.ts +3 -0
  118. package/dist/lib/typeChecker/utils.js +1 -0
  119. package/dist/lib/typeChecker/validate.d.ts +2 -1
  120. package/dist/lib/typeChecker/validate.js +2 -1
  121. package/dist/lib/types/access.d.ts +4 -1
  122. package/dist/lib/types/blockArgument.d.ts +1 -0
  123. package/dist/lib/types/function.d.ts +1 -1
  124. package/dist/lib/types/function.js +1 -0
  125. package/dist/lib/types/gotoStatement.d.ts +6 -0
  126. package/dist/lib/types/gotoStatement.js +1 -0
  127. package/dist/lib/types.d.ts +3 -1
  128. package/dist/lib/types.js +1 -0
  129. package/dist/lib/utils/node.js +6 -0
  130. package/dist/lib/version.d.ts +1 -1
  131. package/dist/lib/version.js +1 -1
  132. package/dist/scripts/agency.d.ts +8 -0
  133. package/dist/scripts/agency.js +466 -387
  134. package/dist/scripts/agency.test.d.ts +1 -0
  135. package/dist/scripts/agency.test.js +47 -0
  136. package/package.json +4 -1
  137. package/stdlib/agent.js +7 -2
  138. package/stdlib/array.js +5 -1
  139. package/stdlib/clipboard.js +5 -1
  140. package/stdlib/fs.js +10 -2
  141. package/stdlib/http.js +5 -1
  142. package/stdlib/index.agency +7 -0
  143. package/stdlib/index.js +108 -1
  144. package/stdlib/math.js +5 -1
  145. package/stdlib/object.js +5 -1
  146. package/stdlib/path.js +5 -1
  147. package/stdlib/shell.js +9 -1
  148. package/stdlib/speech.js +5 -1
  149. package/stdlib/strategy.js +5 -1
  150. package/stdlib/system.js +5 -1
  151. package/stdlib/ui.js +5 -1
  152. package/stdlib/weather.js +6 -1
  153. package/stdlib/wikipedia.js +8 -1
  154. package/stdlib/_builtins.js +0 -134
  155. package/stdlib/_math.js +0 -9
@@ -1,5 +1,6 @@
1
1
  import { AgencyComment, AgencyMultiLineComment, AgencyNode, AgencyProgram, Assignment, DebuggerStatement, Literal, NewLine, Scope, TypeAlias, VariableType } from "../types.js";
2
2
  import { AccessChainElement, ValueAccess } from "../types/access.js";
3
+ import { BlockArgument } from "../types/blockArgument.js";
3
4
  import { AgencyArray, AgencyObject } from "../types/dataStructures.js";
4
5
  import { FunctionCall, FunctionDefinition } from "../types/function.js";
5
6
  import { GraphNodeDefinition, Visibility } from "../types/graphNode.js";
@@ -7,6 +8,7 @@ import { IfElse } from "../types/ifElse.js";
7
8
  import { ImportNameType, ImportNodeStatement, ImportStatement } from "../types/importStatement.js";
8
9
  import { MatchBlock } from "../types/matchBlock.js";
9
10
  import { ReturnStatement } from "../types/returnStatement.js";
11
+ import { GotoStatement } from "../types/gotoStatement.js";
10
12
  import { ForLoop } from "../types/forLoop.js";
11
13
  import { WhileLoop } from "../types/whileLoop.js";
12
14
  import { AgencyConfig } from "../config.js";
@@ -66,6 +68,7 @@ export declare class AgencyGenerator {
66
68
  private generateMultiLineStringLiteral;
67
69
  protected processFunctionDefinition(node: FunctionDefinition): string;
68
70
  protected processFunctionCall(node: FunctionCall): string;
71
+ protected renderArgList(args: FunctionCall["arguments"], block?: BlockArgument): string;
69
72
  protected generateFunctionCallExpression(node: FunctionCall, context: "valueAccess" | "functionArg" | "topLevelStatement"): string;
70
73
  protected processAgencyArray(node: AgencyArray): string;
71
74
  protected processAgencyObject(node: AgencyObject): string;
@@ -76,6 +79,7 @@ export declare class AgencyGenerator {
76
79
  protected processWhileLoop(node: WhileLoop): string;
77
80
  protected processIfElse(node: IfElse): string;
78
81
  protected processReturnStatement(node: ReturnStatement): string;
82
+ protected processGotoStatement(node: GotoStatement): string;
79
83
  protected processDebuggerStatement(node: DebuggerStatement): string;
80
84
  protected processComment(node: AgencyComment): string;
81
85
  protected processMultiLineComment(node: AgencyMultiLineComment): string;
@@ -139,6 +139,8 @@ export class AgencyGenerator {
139
139
  return this.generateLiteral(node);
140
140
  case "returnStatement":
141
141
  return this.processReturnStatement(node);
142
+ case "gotoStatement":
143
+ return this.processGotoStatement(node);
142
144
  case "debuggerStatement":
143
145
  return this.processDebuggerStatement(node);
144
146
  case "agencyArray":
@@ -396,8 +398,9 @@ export class AgencyGenerator {
396
398
  const expr = this.generateFunctionCallExpression(node, "topLevelStatement");
397
399
  return tags + this.indentStr(`${expr}`);
398
400
  }
399
- generateFunctionCallExpression(node, context) {
400
- const args = node.arguments.map((arg) => {
401
+ // Render arguments (and optional inline block) into a parenthesized string: (arg1, arg2, \x -> expr)
402
+ renderArgList(args, block) {
403
+ const rendered = args.map((arg) => {
401
404
  if (arg.type === "namedArgument") {
402
405
  return `${arg.name}: ${this.processNode(arg.value).trim()}`;
403
406
  }
@@ -406,6 +409,21 @@ export class AgencyGenerator {
406
409
  }
407
410
  return this.processNode(arg).trim();
408
411
  });
412
+ if (block?.inline) {
413
+ const returnStmt = block.body[0];
414
+ const exprStr = this.processNode(returnStmt.value).trim();
415
+ let params = "";
416
+ if (block.params.length === 1) {
417
+ params = block.params[0].name;
418
+ }
419
+ else if (block.params.length > 1) {
420
+ params = `(${block.params.map((p) => p.name).join(", ")})`;
421
+ }
422
+ rendered.push(`\\${params} -> ${exprStr}`);
423
+ }
424
+ return `(${rendered.join(", ")})`;
425
+ }
426
+ generateFunctionCallExpression(node, context) {
409
427
  let asyncPrefix = "";
410
428
  if (node.async === true) {
411
429
  asyncPrefix = "async ";
@@ -413,9 +431,9 @@ export class AgencyGenerator {
413
431
  else if (node.async === false) {
414
432
  asyncPrefix = "await ";
415
433
  }
416
- let result = `${asyncPrefix}${node.functionName}(${args.join(", ")})`;
417
- if (node.block) {
418
- const block = node.block;
434
+ const block = node.block;
435
+ let result = `${asyncPrefix}${node.functionName}${this.renderArgList(node.arguments, block?.inline ? block : undefined)}`;
436
+ if (block && !block.inline) {
419
437
  let asClause = "as ";
420
438
  if (block.params.length === 1) {
421
439
  asClause = `as ${block.params[0].name} `;
@@ -587,6 +605,10 @@ export class AgencyGenerator {
587
605
  const valueCode = this.processNode(node.value).trim();
588
606
  return this.indentStr(`return ${valueCode}`);
589
607
  }
608
+ processGotoStatement(node) {
609
+ const callCode = this.processNode(node.nodeCall).trim();
610
+ return this.indentStr(`goto ${callCode}`);
611
+ }
590
612
  processDebuggerStatement(node) {
591
613
  return this.indentStr(node.label ? `debugger(${JSON.stringify(node.label)})` : "debugger()");
592
614
  }
@@ -719,7 +741,7 @@ export class AgencyGenerator {
719
741
  return result;
720
742
  }
721
743
  processNewExpression(node) {
722
- const args = node.arguments.map((a) => expressionToString(a)).join(", ");
744
+ const args = node.arguments.map((a) => this.processNode(a)).join(", ");
723
745
  return `new ${node.className}(${args})`;
724
746
  }
725
747
  processTool(node) {
@@ -818,6 +840,8 @@ export class AgencyGenerator {
818
840
  }
819
841
  case "methodCall":
820
842
  return `${dot}${this.generateFunctionCallExpression(node.functionCall, "valueAccess")}`;
843
+ case "call":
844
+ return `${node.optional ? "?." : ""}${this.renderArgList(node.arguments, node.block)}`;
821
845
  default:
822
846
  throw new Error(`Unknown access chain element kind: ${node.kind}`);
823
847
  }
@@ -76,6 +76,8 @@ export declare class TypeScriptBuilder {
76
76
  private _agencyImportNames;
77
77
  private _buildImportNameSets;
78
78
  private isGraphNode;
79
+ private static TOP_LEVEL_DECLARATION_TYPES;
80
+ private isTopLevelDeclaration;
79
81
  private isImpureImportedFunction;
80
82
  private containsImpureCall;
81
83
  private getScopeReturnType;
@@ -114,6 +116,7 @@ export declare class TypeScriptBuilder {
114
116
  private generateLiteral;
115
117
  private generateStringLiteralNode;
116
118
  private processValueAccess;
119
+ private awaitChainCall;
117
120
  private processBinOpExpression;
118
121
  private processRegexMatchExpression;
119
122
  private processCatchExpression;
@@ -191,6 +194,7 @@ export declare class TypeScriptBuilder {
191
194
  private processGraphNode;
192
195
  /** If the enclosing function/node has returnTypeValidated, wrap value in __validateType */
193
196
  private maybeWrapReturnValidation;
197
+ private processGotoStatement;
194
198
  private processReturnStatement;
195
199
  private processAssignment;
196
200
  private _processAssignmentInner;
@@ -18,7 +18,7 @@ import { getImportedNames, } from "../types/importStatement.js";
18
18
  import { isClassKeyword } from "../types/classDefinition.js";
19
19
  import { escape, mergeDeep } from "../utils.js";
20
20
  import { generateBuiltinHelpers, mapFunctionName, } from "./typescriptGenerator/builtins.js";
21
- import { DEFAULT_SCHEMA, mapTypeToZodSchema, mapTypeToValidationSchema, } from "./typescriptGenerator/typeToZodSchema.js";
21
+ import { DEFAULT_SCHEMA, mapTypeToValidationSchema, } from "./typescriptGenerator/typeToZodSchema.js";
22
22
  import { $, ts } from "../ir/builders.js";
23
23
  import { printTs } from "../ir/prettyPrint.js";
24
24
  import { getVisibleTypes, scopeKey } from "../programInfo.js";
@@ -207,7 +207,7 @@ export class TypeScriptBuilder {
207
207
  "approve", "reject", "propagate",
208
208
  "success", "failure",
209
209
  "isInterrupt", "isDebugger", "isRejected", "isApproved",
210
- "isSuccess", "isFailure", "mcp"
210
+ "isSuccess", "isFailure", "mcp", "setLLMClient"
211
211
  ]);
212
212
  /**
213
213
  * Returns true if a function call should have interrupt-checking boilerplate.
@@ -247,6 +247,18 @@ export class TypeScriptBuilder {
247
247
  .flat()
248
248
  .includes(functionName));
249
249
  }
250
+ static TOP_LEVEL_DECLARATION_TYPES = new Set([
251
+ "graphNode", "function", "typeAlias", "classDefinition",
252
+ "importStatement", "importNodeStatement",
253
+ "comment", "multiLineComment", "newLine",
254
+ ]);
255
+ isTopLevelDeclaration(node) {
256
+ if (TypeScriptBuilder.TOP_LEVEL_DECLARATION_TYPES.has(node.type))
257
+ return true;
258
+ if (node.type === "assignment" && node.scope === "shared")
259
+ return true;
260
+ return false;
261
+ }
250
262
  isImpureImportedFunction(functionName) {
251
263
  if (!this._plainTsImportNames) {
252
264
  this._buildImportNameSets();
@@ -353,10 +365,16 @@ export class TypeScriptBuilder {
353
365
  const handler = this.buildHandlerArrow(node.handlerName);
354
366
  globalInitStatements.push(ts.withHandler(handler, setNode));
355
367
  }
356
- else {
368
+ else if (this.isTopLevelDeclaration(node)) {
357
369
  const result = this.processNode(node);
358
370
  this.generatedStatements.push(result);
359
371
  }
372
+ else {
373
+ // Top-level statements (function calls, etc.) go into __initializeGlobals
374
+ // so they can access the execution context and global variables.
375
+ const result = this.processNodeInGlobalInit(node);
376
+ globalInitStatements.push(result);
377
+ }
360
378
  }
361
379
  // Assemble output
362
380
  const sections = [];
@@ -536,6 +554,8 @@ export class TypeScriptBuilder {
536
554
  return this.generateLiteral(node);
537
555
  case "returnStatement":
538
556
  return this.processReturnStatement(node);
557
+ case "gotoStatement":
558
+ return this.processGotoStatement(node);
539
559
  case "agencyArray":
540
560
  return this.processAgencyArray(node);
541
561
  case "agencyObject":
@@ -611,7 +631,11 @@ export class TypeScriptBuilder {
611
631
  // ------- Type system (side effects only) -------
612
632
  processTypeAlias(node) {
613
633
  const exportPrefix = node.exported ? "export " : "";
614
- return ts.raw(`${exportPrefix}type ${node.aliasName} = ${formatTypeHint(node.aliasedType)};`);
634
+ const zodSchema = mapTypeToValidationSchema(node.aliasedType, this.getVisibleTypeAliases());
635
+ return ts.statements([
636
+ ts.raw(`${exportPrefix}const ${node.aliasName} = ${zodSchema};`),
637
+ ts.raw(`${exportPrefix}type ${node.aliasName} = z.infer<typeof ${node.aliasName}>;`),
638
+ ]);
615
639
  }
616
640
  // ------- Proper IR node methods -------
617
641
  processComment(node) {
@@ -724,26 +748,31 @@ export class TypeScriptBuilder {
724
748
  break;
725
749
  }
726
750
  case "methodCall": {
727
- const isLastInChain = element === node.chain[node.chain.length - 1];
728
751
  const fnCall = element.functionCall;
729
- // Build descriptor from the method call's arguments
730
752
  const descriptor = this.buildCallDescriptor(fnCall);
731
753
  const configObj = this.buildStateConfig();
732
- const propArg = ts.str(fnCall.functionName);
733
- const callArgs = [result, propArg, descriptor, configObj];
734
- if (element.optional) {
754
+ const callArgs = [result, ts.str(fnCall.functionName), descriptor, configObj];
755
+ if (element.optional)
735
756
  callArgs.push(ts.bool(true));
736
- }
737
- const callExpr = ts.call(ts.id("__callMethod"), callArgs);
738
- result = isLastInChain
739
- ? ts.await(callExpr)
740
- : ts.raw(`(${this.str(ts.await(callExpr))})`);
757
+ result = this.awaitChainCall(ts.call(ts.id("__callMethod"), callArgs), element === node.chain[node.chain.length - 1]);
758
+ break;
759
+ }
760
+ case "call": {
761
+ const descriptor = this.buildCallDescriptor(element);
762
+ const configObj = this.buildStateConfig();
763
+ const callArgs = [result, descriptor, configObj];
764
+ if (element.optional)
765
+ callArgs.push(ts.bool(true));
766
+ result = this.awaitChainCall(ts.call(ts.id("__call"), callArgs), element === node.chain[node.chain.length - 1]);
741
767
  break;
742
768
  }
743
769
  }
744
770
  }
745
771
  return result;
746
772
  }
773
+ awaitChainCall(callExpr, isLast) {
774
+ return isLast ? ts.await(callExpr) : ts.raw(`(${this.str(ts.await(callExpr))})`);
775
+ }
747
776
  processBinOpExpression(node) {
748
777
  if (node.operator === "|>") {
749
778
  return this.processPipeExpression(node);
@@ -1085,8 +1114,8 @@ export class TypeScriptBuilder {
1085
1114
  */
1086
1115
  processBlockArgument(node) {
1087
1116
  const block = node.block;
1088
- const fnDef = this.programInfo.functionDefinitions[node.functionName];
1089
- const imported = this.programInfo.importedFunctions[node.functionName];
1117
+ const fnDef = node.functionName ? this.programInfo.functionDefinitions[node.functionName] : undefined;
1118
+ const imported = node.functionName ? this.programInfo.importedFunctions[node.functionName] : undefined;
1090
1119
  const paramList = fnDef?.parameters ?? imported?.parameters;
1091
1120
  const blockType = paramList
1092
1121
  ?.map((p) => p.typeHint)
@@ -1133,7 +1162,7 @@ export class TypeScriptBuilder {
1133
1162
  type: "primitiveType",
1134
1163
  value: "string",
1135
1164
  };
1136
- let tsType = mapTypeToZodSchema(typeHint, this.getVisibleTypeAliases());
1165
+ let tsType = mapTypeToValidationSchema(typeHint, this.getVisibleTypeAliases());
1137
1166
  if (param.defaultValue) {
1138
1167
  const defaultStr = expressionToString(param.defaultValue);
1139
1168
  tsType += `.nullable().describe(${JSON.stringify("Default: " + defaultStr)})`;
@@ -1375,6 +1404,9 @@ export class TypeScriptBuilder {
1375
1404
  if (node.functionName === "interrupt") {
1376
1405
  return this.buildInterruptReturn(node.arguments);
1377
1406
  }
1407
+ if (node.functionName === "_emit") {
1408
+ return this.processFunctionCall(node);
1409
+ }
1378
1410
  const callNode = this.processFunctionCall(node);
1379
1411
  const scope = this.getCurrentScope();
1380
1412
  if (this.shouldHandleInterrupts(node.functionName) &&
@@ -1442,6 +1474,11 @@ export class TypeScriptBuilder {
1442
1474
  const arg = argNodes.length > 0 ? argNodes[0] : ts.str("");
1443
1475
  return ts.throw(`new Error(${this.str(arg)})`);
1444
1476
  }
1477
+ if (node.functionName === "_emit") {
1478
+ const argNodes = node.arguments.map((arg) => this.processCallArg(arg));
1479
+ const data = argNodes.length > 0 ? argNodes[0] : ts.id("undefined");
1480
+ return ts.callHook("onEmit", data);
1481
+ }
1445
1482
  if (node.functionName === "llm") {
1446
1483
  // Standalone llm() call (not assigned to variable)
1447
1484
  return this.processLlmCall(DEFAULT_PROMPT_NAME, this.getScopeReturnType(), node, "local");
@@ -1627,7 +1664,7 @@ export class TypeScriptBuilder {
1627
1664
  this.isInsideGraphNode = true;
1628
1665
  for (const stmt of body) {
1629
1666
  if (stmt.type === "functionCall" && this.isGraphNode(stmt.functionName)) {
1630
- throw new Error(`Call to graph node '${stmt.functionName}' inside graph node '${nodeName}' was not returned. All calls to graph nodes must be returned, eg (return ${stmt.functionName}(...)).`);
1667
+ throw new Error(`Call to graph node '${stmt.functionName}' inside graph node '${nodeName}' must use goto or return, eg: goto ${stmt.functionName}(...)`);
1631
1668
  }
1632
1669
  }
1633
1670
  const bodyCode = this.processBodyAsParts(body);
@@ -1700,6 +1737,17 @@ export class TypeScriptBuilder {
1700
1737
  const zodSchema = mapTypeToValidationSchema(returnType, this.getVisibleTypeAliases());
1701
1738
  return ts.validateType(valueNode, ts.raw(zodSchema));
1702
1739
  }
1740
+ processGotoStatement(node) {
1741
+ if (!this.isInsideGraphNode) {
1742
+ throw new Error(`goto can only be used inside a node body`);
1743
+ }
1744
+ if (!this.isGraphNode(node.nodeCall.functionName)) {
1745
+ throw new Error(`goto target '${node.nodeCall.functionName}' is not a node`);
1746
+ }
1747
+ this.currentAdjacentNodes.push(node.nodeCall.functionName);
1748
+ this.functionsUsed.add(node.nodeCall.functionName);
1749
+ return this.generateNodeCallExpression(node.nodeCall);
1750
+ }
1703
1751
  processReturnStatement(node) {
1704
1752
  // Bare return (no value)
1705
1753
  if (!node.value) {
@@ -1881,7 +1929,7 @@ export class TypeScriptBuilder {
1881
1929
  type: "primitiveType",
1882
1930
  value: "string",
1883
1931
  };
1884
- const zodSchema = mapTypeToZodSchema(_variableType, this.getVisibleTypeAliases());
1932
+ const zodSchema = mapTypeToValidationSchema(_variableType, this.getVisibleTypeAliases());
1885
1933
  // Extract prompt from first argument, using processNode to get scoped variable references
1886
1934
  const promptArg = node.arguments[0];
1887
1935
  const promptNode = promptArg
@@ -2373,6 +2421,9 @@ export class TypeScriptBuilder {
2373
2421
  smoltalkDefaults,
2374
2422
  dirname: ts.id("__dirname"),
2375
2423
  };
2424
+ if (this.agencyConfig.verbose) {
2425
+ runtimeCtxArgs.verbose = ts.raw("true");
2426
+ }
2376
2427
  if (this.agencyConfig.checkpoints?.maxRestores !== undefined) {
2377
2428
  runtimeCtxArgs.maxRestores = ts.raw(String(this.agencyConfig.checkpoints.maxRestores));
2378
2429
  }
@@ -2,6 +2,7 @@ import * as builtinFunctionsInput from "../../templates/backends/typescriptGener
2
2
  import * as builtinFunctionsRead from "../../templates/backends/typescriptGenerator/builtinFunctions/read.js";
3
3
  import * as builtinFunctionsFetchJSON from "../../templates/backends/typescriptGenerator/builtinFunctions/fetchJSON.js";
4
4
  import * as builtinFunctionsMcp from "../../templates/backends/typescriptGenerator/builtinFunctions/mcp.js";
5
+ import * as builtinFunctionsSetLLMClient from "../../templates/backends/typescriptGenerator/builtinFunctions/setLLMClient.js";
5
6
  import { BUILTIN_FUNCTIONS } from "../../config.js";
6
7
  /**
7
8
  * Maps an Agency function name to its TypeScript equivalent
@@ -49,5 +50,7 @@ export function generateBuiltinHelpers(functionsUsed) {
49
50
  */
50
51
  const mcpFunc = builtinFunctionsMcp.default({});
51
52
  helpers.push(mcpFunc);
53
+ const setLLMClientFunc = builtinFunctionsSetLLMClient.default({});
54
+ helpers.push(setLLMClientFunc);
52
55
  return helpers.join("\n\n");
53
56
  }
@@ -65,10 +65,7 @@ function mapTypeToSchema(variableType, typeAliases, resultHandler) {
65
65
  return resultHandler(variableType, typeAliases);
66
66
  }
67
67
  else if (variableType.type === "typeAliasVariable") {
68
- if (!typeAliases || !typeAliases[variableType.aliasName]) {
69
- throw new Error(`Type alias '${variableType.aliasName}' not found in provided type aliases: ${JSON.stringify(typeAliases)}`);
70
- }
71
- return recurse(typeAliases[variableType.aliasName]);
68
+ return variableType.aliasName;
72
69
  }
73
70
  return "z.string()";
74
71
  }
@@ -0,0 +1,84 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { mapTypeToZodSchema, mapTypeToValidationSchema } from "./typeToZodSchema.js";
3
+ describe("mapTypeToZodSchema", () => {
4
+ it("should return the alias name directly for typeAliasVariable", () => {
5
+ const variableType = {
6
+ type: "typeAliasVariable",
7
+ aliasName: "MathResult",
8
+ };
9
+ const typeAliases = {
10
+ MathResult: {
11
+ type: "objectType",
12
+ properties: [{ key: "answer", value: { type: "primitiveType", value: "number" } }],
13
+ },
14
+ };
15
+ const result = mapTypeToZodSchema(variableType, typeAliases);
16
+ expect(result).toBe("MathResult");
17
+ });
18
+ it("should return the alias name in nested contexts", () => {
19
+ const variableType = {
20
+ type: "objectType",
21
+ properties: [
22
+ { key: "result", value: { type: "typeAliasVariable", aliasName: "Coords" } },
23
+ ],
24
+ };
25
+ const typeAliases = {
26
+ Coords: {
27
+ type: "objectType",
28
+ properties: [
29
+ { key: "x", value: { type: "primitiveType", value: "number" } },
30
+ { key: "y", value: { type: "primitiveType", value: "number" } },
31
+ ],
32
+ },
33
+ };
34
+ const result = mapTypeToZodSchema(variableType, typeAliases);
35
+ expect(result).toBe(`z.object({ "result": Coords })`);
36
+ });
37
+ it("should return the alias name inside an array type", () => {
38
+ const variableType = {
39
+ type: "arrayType",
40
+ elementType: { type: "typeAliasVariable", aliasName: "Item" },
41
+ };
42
+ const typeAliases = {
43
+ Item: {
44
+ type: "objectType",
45
+ properties: [{ key: "name", value: { type: "primitiveType", value: "string" } }],
46
+ },
47
+ };
48
+ const result = mapTypeToZodSchema(variableType, typeAliases);
49
+ expect(result).toBe("z.array(Item)");
50
+ });
51
+ it("should return the alias name inside a union type", () => {
52
+ const variableType = {
53
+ type: "unionType",
54
+ types: [
55
+ { type: "typeAliasVariable", aliasName: "Foo" },
56
+ { type: "primitiveType", value: "number" },
57
+ ],
58
+ };
59
+ const typeAliases = {
60
+ Foo: { type: "primitiveType", value: "string" },
61
+ };
62
+ const result = mapTypeToZodSchema(variableType, typeAliases);
63
+ expect(result).toBe("z.union([Foo, z.number()])");
64
+ });
65
+ });
66
+ describe("mapTypeToValidationSchema", () => {
67
+ it("should return the alias name directly for typeAliasVariable", () => {
68
+ const variableType = {
69
+ type: "typeAliasVariable",
70
+ aliasName: "Category",
71
+ };
72
+ const typeAliases = {
73
+ Category: {
74
+ type: "unionType",
75
+ types: [
76
+ { type: "stringLiteralType", value: "bug" },
77
+ { type: "stringLiteralType", value: "feature" },
78
+ ],
79
+ },
80
+ };
81
+ const result = mapTypeToValidationSchema(variableType, typeAliases);
82
+ expect(result).toBe("Category");
83
+ });
84
+ });
@@ -12,6 +12,6 @@ export declare function compile(config: AgencyConfig, inputFile: string, _output
12
12
  symbolTable?: SymbolTable;
13
13
  importStrategy?: ImportStrategy;
14
14
  }): string | null;
15
+ export declare function format(contents: string, config?: AgencyConfig): Promise<string>;
16
+ export declare function formatFile(inputFile: string, inPlace?: boolean, config?: AgencyConfig): Promise<void>;
15
17
  export declare function run(config: AgencyConfig, inputFile: string, outputFile?: string, resumeFile?: string): void;
16
- export declare function format(contents: string, config: AgencyConfig): Promise<string>;
17
- export declare function formatFile(inputPath: string, inPlace: boolean, config: AgencyConfig): void;