agency-lang 0.0.20 → 0.0.22

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 (82) hide show
  1. package/dist/lib/backends/agencyGenerator.d.ts +10 -2
  2. package/dist/lib/backends/agencyGenerator.js +86 -19
  3. package/dist/lib/backends/agencyGenerator.test.js +0 -48
  4. package/dist/lib/backends/baseGenerator.d.ts +11 -4
  5. package/dist/lib/backends/baseGenerator.js +35 -11
  6. package/dist/lib/backends/graphGenerator.js +19 -186
  7. package/dist/lib/backends/typescriptGenerator/builtins.js +6 -0
  8. package/dist/lib/backends/typescriptGenerator.d.ts +11 -3
  9. package/dist/lib/backends/typescriptGenerator.js +98 -26
  10. package/dist/lib/backends/utils.d.ts +1 -1
  11. package/dist/lib/parser.js +5 -5
  12. package/dist/lib/parser.test.js +15 -38
  13. package/dist/lib/parsers/access.test.js +14 -3
  14. package/dist/lib/parsers/assignment.test.js +159 -4
  15. package/dist/lib/parsers/await.d.ts +3 -0
  16. package/dist/lib/parsers/await.js +18 -0
  17. package/dist/lib/parsers/body.test.js +10 -1
  18. package/dist/lib/parsers/dataStructures.js +2 -2
  19. package/dist/lib/parsers/dataStructures.test.js +11 -11
  20. package/dist/lib/parsers/function.d.ts +8 -3
  21. package/dist/lib/parsers/function.js +64 -12
  22. package/dist/lib/parsers/function.test.js +284 -52
  23. package/dist/lib/parsers/functionCall.test.js +6 -6
  24. package/dist/lib/parsers/ifElse.test.d.ts +1 -0
  25. package/dist/lib/parsers/ifElse.test.js +376 -0
  26. package/dist/lib/parsers/importStatement.js +2 -2
  27. package/dist/lib/parsers/literals.d.ts +1 -0
  28. package/dist/lib/parsers/literals.js +6 -2
  29. package/dist/lib/parsers/literals.test.js +110 -21
  30. package/dist/lib/parsers/matchBlock.js +7 -4
  31. package/dist/lib/parsers/matchBlock.test.js +16 -16
  32. package/dist/lib/parsers/newline.d.ts +3 -0
  33. package/dist/lib/parsers/newline.js +2 -0
  34. package/dist/lib/parsers/parserUtils.d.ts +3 -1
  35. package/dist/lib/parsers/parserUtils.js +4 -1
  36. package/dist/lib/parsers/returnStatement.js +2 -1
  37. package/dist/lib/parsers/returnStatement.test.js +2 -2
  38. package/dist/lib/parsers/specialVar.test.js +7 -7
  39. package/dist/lib/parsers/typeHints.d.ts +1 -1
  40. package/dist/lib/parsers/typeHints.js +6 -6
  41. package/dist/lib/parsers/typeHints.test.js +0 -8
  42. package/dist/lib/parsers/utils.d.ts +1 -0
  43. package/dist/lib/parsers/utils.js +2 -1
  44. package/dist/lib/parsers/whileLoop.test.js +46 -1
  45. package/dist/lib/templates/backends/graphGenerator/goToNode.d.ts +2 -1
  46. package/dist/lib/templates/backends/graphGenerator/goToNode.js +11 -1
  47. package/dist/lib/templates/backends/graphGenerator/graphNode.d.ts +2 -2
  48. package/dist/lib/templates/backends/graphGenerator/graphNode.js +2 -1
  49. package/dist/lib/templates/backends/graphGenerator/imports.d.ts +1 -1
  50. package/dist/lib/templates/backends/graphGenerator/imports.js +14 -1
  51. package/dist/lib/templates/backends/typescriptGenerator/builtinFunctions/sleep.d.ts +4 -0
  52. package/dist/lib/templates/backends/typescriptGenerator/builtinFunctions/sleep.js +13 -0
  53. package/dist/lib/templates/backends/typescriptGenerator/builtinFunctions/time.d.ts +7 -0
  54. package/dist/lib/templates/backends/typescriptGenerator/builtinFunctions/time.js +12 -0
  55. package/dist/lib/templates/backends/typescriptGenerator/functionDefinition.d.ts +1 -1
  56. package/dist/lib/templates/backends/typescriptGenerator/functionDefinition.js +1 -0
  57. package/dist/lib/templates/backends/typescriptGenerator/promptFunction.d.ts +1 -1
  58. package/dist/lib/templates/backends/typescriptGenerator/promptFunction.js +3 -2
  59. package/dist/lib/templates/backends/typescriptGenerator/tool.d.ts +1 -1
  60. package/dist/lib/templates/backends/typescriptGenerator/tool.js +1 -1
  61. package/dist/lib/templates/backends/typescriptGenerator/toolCall.d.ts +1 -1
  62. package/dist/lib/templates/backends/typescriptGenerator/toolCall.js +2 -2
  63. package/dist/lib/types/await.d.ts +7 -0
  64. package/dist/lib/types/await.js +1 -0
  65. package/dist/lib/types/graphNode.d.ts +2 -1
  66. package/dist/lib/types/ifElse.d.ts +7 -0
  67. package/dist/lib/types/ifElse.js +1 -0
  68. package/dist/lib/types/literals.d.ts +1 -1
  69. package/dist/lib/types/returnStatement.d.ts +2 -1
  70. package/dist/lib/types/timeBlock.d.ts +5 -0
  71. package/dist/lib/types/timeBlock.js +1 -0
  72. package/dist/lib/types.d.ts +16 -8
  73. package/dist/lib/types.js +1 -0
  74. package/dist/lib/utils.d.ts +1 -0
  75. package/dist/lib/utils.js +3 -0
  76. package/package.json +3 -2
  77. package/dist/lib/parsers/assignment.d.ts +0 -3
  78. package/dist/lib/parsers/assignment.js +0 -8
  79. package/dist/lib/templates/backends/graphGenerator/node.d.ts +0 -7
  80. package/dist/lib/templates/backends/graphGenerator/node.js +0 -18
  81. package/dist/lib/templates/backends/graphGenerator/promptNode.d.ts +0 -8
  82. package/dist/lib/templates/backends/graphGenerator/promptNode.js +0 -16
@@ -1,7 +1,7 @@
1
1
  import * as builtinTools from "../templates/backends/graphGenerator/builtinTools.js";
2
2
  import * as renderConditionalEdge from "../templates/backends/graphGenerator/conditionalEdge.js";
3
3
  import * as goToNode from "../templates/backends/graphGenerator/goToNode.js";
4
- import * as graphNode from "../templates/backends/graphGenerator/graphNode.js";
4
+ import * as renderGraphNode from "../templates/backends/graphGenerator/graphNode.js";
5
5
  import * as renderImports from "../templates/backends/graphGenerator/imports.js";
6
6
  import * as renderStartNode from "../templates/backends/graphGenerator/startNode.js";
7
7
  import * as renderRunNodeFunction from "../templates/backends/graphGenerator/runNodeFunction.js";
@@ -20,183 +20,6 @@ export class GraphGenerator extends TypeScriptGenerator {
20
20
  constructor() {
21
21
  super();
22
22
  }
23
- /*
24
- protected generateBuiltins(): string {
25
- return "";
26
- }
27
-
28
- protected processTypeAlias(node: TypeAlias): void {
29
- // subclasses implement this
30
- }
31
-
32
- protected processTypeHint(node: TypeHint): void {
33
- // subclasses implement this
34
- }
35
-
36
- protected processNode(node: AgencyNode): string {
37
- switch (node.type) {
38
- case "typeHint":
39
- case "typeAlias":
40
- return "";
41
- case "assignment":
42
- return this.processAssignment(node);
43
- case "function":
44
- return this.processFunctionDefinition(node);
45
- case "functionCall":
46
- return this.processFunctionCall(node);
47
- case "accessExpression":
48
- return this.processAccessExpression(node);
49
- case "comment":
50
- return this.processComment(node);
51
- case "matchBlock":
52
- return this.processMatchBlock(node);
53
- case "number":
54
- case "string":
55
- case "variableName":
56
- case "prompt":
57
- // Standalone literals at top level
58
- return this.generateLiteral(node);
59
- case "returnStatement":
60
- return this.processReturnStatement(node);
61
- case "agencyArray":
62
- return this.processAgencyArray(node);
63
- case "agencyObject":
64
- return this.processAgencyObject(node);
65
- }
66
- }
67
-
68
- protected processAgencyObject(node: AgencyObject): string {
69
- return "<processAgencyObject not implemented>";
70
- }
71
-
72
- protected processAgencyArray(node: AgencyArray): string {
73
- return "<processAgencyArray not implemented>";
74
- }
75
-
76
- protected processComment(node: AgencyComment): string {
77
- return "processComment not implemented";
78
- }
79
-
80
-
81
-
82
- protected processAccessExpression(node: AccessExpression): string {
83
- switch (node.expression.type) {
84
- case "dotProperty":
85
- return this.processDotProperty(node.expression);
86
- case "indexAccess":
87
- return this.processIndexAccess(node.expression);
88
- case "dotFunctionCall":
89
- return this.processDotFunctionCall(node.expression);
90
- }
91
- }
92
-
93
- protected processMatchBlock(node: MatchBlock): string {
94
- return "processMatchBlock not implemented";
95
- }
96
-
97
- protected processDotProperty(node: DotProperty): string {
98
- return "processDotProperty not implemented";
99
- }
100
-
101
- protected processDotFunctionCall(node: DotFunctionCall): string {
102
- return "processDotFunctionCall not implemented";
103
- }
104
-
105
- protected processIndexAccess(node: IndexAccess): string {
106
- return "processIndexAccess not implemented";
107
- } */
108
- /* protected processAssignment(node: Assignment): string {
109
- switch (node.value.type) {
110
- case "prompt":
111
- return this.processPromptLiteral(node.variableName, node.value);
112
- default:
113
- return this.createNode(
114
- node.variableName,
115
- this.processNode(wrapInReturn(node.value))
116
- );
117
- }
118
- }
119
-
120
- protected createNode(name: string, body: string): string {
121
- this.graphNodes.push(name);
122
- return renderNode.default({
123
- name,
124
- body,
125
- });
126
- }
127
-
128
- protected processPromptLiteral(
129
- variableName: string,
130
- node: PromptLiteral
131
- ): string {
132
- this.graphNodes.push(variableName);
133
-
134
- // Validate all interpolated variables are in scope
135
- const interpolatedVars = node.segments
136
- .filter((s) => s.type === "interpolation")
137
- .map((s) => (s as InterpolationSegment).variableName);
138
-
139
- for (const varName of interpolatedVars) {
140
- if (!this.graphNodes.includes(varName)) {
141
- throw new Error(
142
- `Variable '${varName}' used in prompt interpolation but not defined. ` +
143
- `Referenced in assignment to '${variableName}'.`
144
- );
145
- }
146
- }
147
-
148
- const promptFunction = this.generatePromptFunction({
149
- variableName,
150
- functionArgs: interpolatedVars,
151
- prompt: node,
152
- });
153
- const argsStr = interpolatedVars.join(", ");
154
-
155
- return promptNode.default({
156
- name: variableName,
157
- promptFunction,
158
- argsStr,
159
- });
160
- }
161
-
162
- generatePromptFunction({
163
- variableName,
164
- functionArgs = [],
165
- prompt,
166
- }: {
167
- variableName: string;
168
- functionArgs: string[];
169
- prompt: PromptLiteral;
170
- }): string {
171
- // Generate async function for prompt-based assignment
172
- const variableType = this.typeHints[variableName] || {
173
- type: "primitiveType" as const,
174
- value: "string",
175
- };
176
-
177
- const zodSchema = mapTypeToZodSchema(variableType, this.typeAliases);
178
- const typeString = variableTypeToString(variableType, this.typeAliases);
179
-
180
- // Build prompt construction code
181
- const promptCode = this.buildPromptString(prompt.segments, this.typeHints);
182
- const argsStr = functionArgs
183
- .map(
184
- (arg) =>
185
- `${arg}: ${variableTypeToString(
186
- this.typeHints[arg] || { type: "primitiveType", value: "string" },
187
- this.typeAliases
188
- )}`
189
- )
190
- .join(", ");
191
- return promptFunction.default({
192
- variableName,
193
- argsStr,
194
- typeString,
195
- promptCode,
196
- zodSchema,
197
- });
198
- }
199
- */
200
23
  processReturnStatement(node) {
201
24
  if (!this.isInsideGraphNode) {
202
25
  return super.processReturnStatement(node);
@@ -216,15 +39,17 @@ export class GraphGenerator extends TypeScriptGenerator {
216
39
  }
217
40
  processGraphNode(node) {
218
41
  const { nodeName, body, parameters } = node;
219
- if (parameters.length > 1) {
220
- throw new Error(`Graph node '${nodeName}' has more than one parameter. Only one parameter is supported for now.`);
221
- }
42
+ /* if (parameters.length > 1) {
43
+ throw new Error(
44
+ `Graph node '${nodeName}' has more than one parameter. Only one parameter is supported for now.`,
45
+ );
46
+ } */
222
47
  this.adjacentNodes[nodeName] = [];
223
48
  this.currentAdjacentNodes = [];
224
49
  this.functionScopedVariables = [];
225
50
  this.isInsideGraphNode = true;
226
- if (parameters.length > 0) {
227
- this.functionScopedVariables.push(parameters[0]);
51
+ for (const param of parameters) {
52
+ this.functionScopedVariables.push(param.name);
228
53
  }
229
54
  const bodyCode = [];
230
55
  for (const stmt of body) {
@@ -233,14 +58,15 @@ export class GraphGenerator extends TypeScriptGenerator {
233
58
  this.functionScopedVariables = [];
234
59
  this.adjacentNodes[nodeName] = [...this.currentAdjacentNodes];
235
60
  this.isInsideGraphNode = false;
236
- return graphNode.default({
61
+ const paramNames = "{" + parameters.map((p) => p.name).join(", ") + "}";
62
+ return renderGraphNode.default({
237
63
  name: nodeName,
238
64
  /* returnType: node.returnType
239
65
  ? variableTypeToString(node.returnType, this.typeAliases)
240
66
  : "any", */
241
67
  body: bodyCode.join("\n"),
242
68
  hasParam: parameters.length > 0,
243
- paramName: parameters[0] || "input",
69
+ paramNames,
244
70
  });
245
71
  }
246
72
  processFunctionCall(node) {
@@ -272,9 +98,16 @@ export class GraphGenerator extends TypeScriptGenerator {
272
98
  // return this.generateLiteral(arg);
273
99
  }
274
100
  });
275
- const argsString = parts.join(", ");
101
+ const argNames = this.graphNodes
102
+ .find((n) => n.nodeName === node.functionName)
103
+ ?.parameters.map((p) => p.name) || [];
104
+ const pairedArgs = argNames.map((name, index) => {
105
+ return `${name}: ${parts[index]}`;
106
+ });
107
+ const argsString = "{" + pairedArgs.join(", ") + "}";
276
108
  return goToNode.default({
277
109
  nodeName: functionName,
110
+ hasData: parts.length > 0,
278
111
  data: argsString,
279
112
  });
280
113
  } /*
@@ -3,6 +3,7 @@ import * as builtinFunctionsRead from "../../templates/backends/typescriptGenera
3
3
  import * as builtinFunctionsReadImage from "../../templates/backends/typescriptGenerator/builtinFunctions/readImage.js";
4
4
  import * as builtinFunctionsFetchJSON from "../../templates/backends/typescriptGenerator/builtinFunctions/fetchJSON.js";
5
5
  import * as builtinFunctionsFetch from "../../templates/backends/typescriptGenerator/builtinFunctions/fetch.js";
6
+ import * as builtinFunctionsSleep from "../../templates/backends/typescriptGenerator/builtinFunctions/sleep.js";
6
7
  /**
7
8
  * Maps Agency built-in function names to TypeScript equivalents
8
9
  */
@@ -15,6 +16,7 @@ export const BUILTIN_FUNCTIONS = {
15
16
  fetch: "_builtinFetch",
16
17
  fetchJSON: "_builtinFetchJSON",
17
18
  fetchJson: "_builtinFetchJSON",
19
+ sleep: "_builtinSleep",
18
20
  };
19
21
  /**
20
22
  * Maps an Agency function name to its TypeScript equivalent
@@ -48,5 +50,9 @@ export function generateBuiltinHelpers(functionsUsed) {
48
50
  const readImageFunc = builtinFunctionsReadImage.default({});
49
51
  helpers.push(readImageFunc);
50
52
  }
53
+ if (functionsUsed.has("sleep")) {
54
+ const sleepFunc = builtinFunctionsSleep.default({});
55
+ helpers.push(sleepFunc);
56
+ }
51
57
  return helpers.join("\n\n");
52
58
  }
@@ -1,4 +1,4 @@
1
- import { AgencyComment, AgencyProgram, Assignment, Literal, PromptLiteral, PromptSegment, TypeAlias, TypeHint, TypeHintMap } from "../types.js";
1
+ import { AgencyComment, AgencyProgram, Assignment, Literal, PromptLiteral, PromptSegment, TypeAlias, TypeHint, TypeHintMap, VariableType } from "../types.js";
2
2
  import { SpecialVar } from "../types/specialVar.js";
3
3
  import { AccessExpression, DotFunctionCall, DotProperty, IndexAccess } from "../types/access.js";
4
4
  import { AgencyArray, AgencyObject } from "../types/dataStructures.js";
@@ -8,7 +8,10 @@ import { MatchBlock } from "../types/matchBlock.js";
8
8
  import { ReturnStatement } from "../types/returnStatement.js";
9
9
  import { UsesTool } from "../types/tools.js";
10
10
  import { WhileLoop } from "../types/whileLoop.js";
11
+ import { IfElse } from "../types/ifElse.js";
11
12
  import { BaseGenerator } from "./baseGenerator.js";
13
+ import { TimeBlock } from "../types/timeBlock.js";
14
+ import { AwaitStatement } from "../types/await.js";
12
15
  export declare class TypeScriptGenerator extends BaseGenerator {
13
16
  constructor();
14
17
  protected generateBuiltins(): string;
@@ -25,7 +28,7 @@ export declare class TypeScriptGenerator extends BaseGenerator {
25
28
  protected processDotFunctionCall(node: DotFunctionCall): string;
26
29
  protected processIndexAccess(node: IndexAccess): string;
27
30
  protected processAssignment(node: Assignment): string;
28
- protected processPromptLiteral(variableName: string, node: PromptLiteral): string;
31
+ protected processPromptLiteral(variableName: string, variableType: VariableType | undefined, node: PromptLiteral): string;
29
32
  protected processTool(node: FunctionDefinition): string;
30
33
  protected processUsesTool(node: UsesTool): string;
31
34
  /**
@@ -43,16 +46,21 @@ export declare class TypeScriptGenerator extends BaseGenerator {
43
46
  protected generateLiteral(literal: Literal): string;
44
47
  protected generateImports(): string;
45
48
  buildPromptString(segments: PromptSegment[], typeHints: TypeHintMap): string;
49
+ generateStringLiteral(segments: PromptSegment[]): string;
46
50
  /**
47
51
  * Generates an async for prompt-based assignments
48
52
  */
49
- generatePromptFunction({ variableName, functionArgs, prompt, }: {
53
+ generatePromptFunction({ variableName, variableType, functionArgs, prompt, }: {
50
54
  variableName: string;
55
+ variableType: VariableType | undefined;
51
56
  functionArgs: string[];
52
57
  prompt: PromptLiteral;
53
58
  }): string;
54
59
  protected processImportStatement(node: ImportStatement): string;
55
60
  protected processWhileLoop(node: WhileLoop): string;
61
+ protected processIfElse(node: IfElse): string;
56
62
  protected processSpecialVar(node: SpecialVar): string;
63
+ protected processTimeBlock(node: TimeBlock, timingVarName: string): string;
64
+ protected processAwaitStatement(node: AwaitStatement): string;
57
65
  }
58
66
  export declare function generateTypeScript(program: AgencyProgram): string;
@@ -4,8 +4,9 @@ import * as renderFunctionDefinition from "../templates/backends/typescriptGener
4
4
  import * as renderImports from "../templates/backends/typescriptGenerator/imports.js";
5
5
  import * as promptFunction from "../templates/backends/typescriptGenerator/promptFunction.js";
6
6
  import * as renderTool from "../templates/backends/typescriptGenerator/tool.js";
7
+ import * as renderTime from "../templates/backends/typescriptGenerator/builtinFunctions/time.js";
7
8
  import * as renderToolCall from "../templates/backends/typescriptGenerator/toolCall.js";
8
- import { escape, zip } from "../utils.js";
9
+ import { escape, uniq, zip } from "../utils.js";
9
10
  import { BaseGenerator } from "./baseGenerator.js";
10
11
  import { generateBuiltinHelpers, mapFunctionName, } from "./typescriptGenerator/builtins.js";
11
12
  import { variableTypeToString } from "./typescriptGenerator/typeToString.js";
@@ -108,46 +109,59 @@ export class TypeScriptGenerator extends BaseGenerator {
108
109
  return accessCode;
109
110
  }
110
111
  processAssignment(node) {
111
- const { variableName, value } = node;
112
+ const { variableName, typeHint, value } = node;
112
113
  // Track this variable as in scope
113
114
  this.functionScopedVariables.push(variableName);
115
+ const typeAnnotation = typeHint
116
+ ? `: ${variableTypeToString(typeHint, this.typeAliases)}`
117
+ : "";
114
118
  if (value.type === "prompt") {
115
- return this.processPromptLiteral(variableName, value);
119
+ return this.processPromptLiteral(variableName, typeHint, value);
116
120
  }
117
121
  else if (value.type === "functionCall") {
118
122
  // Direct assignment for other literal types
119
123
  const code = this.processNode(value);
120
- return `const ${variableName} = await ${code.trim()};` + "\n";
124
+ return (`const ${variableName}${typeAnnotation} = await ${code.trim()};` + "\n");
125
+ }
126
+ else if (value.type === "timeBlock") {
127
+ const timingVarName = variableName;
128
+ const code = this.processTimeBlock(value, timingVarName);
129
+ return code;
121
130
  }
122
131
  else {
123
132
  // Direct assignment for other literal types
124
133
  const code = this.processNode(value);
125
- return `const ${variableName} = ${code.trim()};` + "\n";
134
+ return `const ${variableName}${typeAnnotation} = ${code.trim()};` + "\n";
126
135
  }
127
136
  }
128
137
  /*
129
138
  protected processAgencyArray(node: AgencyArray): string {
130
139
  const itemCodes = node.items.map((item) => {
131
140
  if (item.type === "functionCall") { */
132
- processPromptLiteral(variableName, node) {
141
+ processPromptLiteral(variableName, variableType, node) {
133
142
  // Validate all interpolated variables are in scope
134
- const interpolatedVars = node.segments
143
+ const interpolatedVars = uniq(node.segments
135
144
  .filter((s) => s.type === "interpolation")
136
- .map((s) => s.variableName);
137
- for (const varName of interpolatedVars) {
138
- if (!this.functionScopedVariables.includes(varName) &&
139
- !this.globalScopedVariables.includes(varName)) {
140
- throw new Error(`Variable '${varName}' used in prompt interpolation but not defined. ` +
141
- `Referenced in assignment to '${variableName}'.`);
142
- }
143
- }
145
+ .map((s) => s.variableName));
146
+ /* for (const varName of interpolatedVars) {
147
+ if (
148
+ !this.functionScopedVariables.includes(varName) &&
149
+ !this.globalScopedVariables.includes(varName)
150
+ ) {
151
+ throw new Error(
152
+ `Variable '${varName}' used in prompt interpolation but not defined. ` +
153
+ `Referenced in assignment to '${variableName}'.`,
154
+ );
155
+ }
156
+ } */
144
157
  const functionCode = this.generatePromptFunction({
145
158
  variableName,
159
+ variableType,
146
160
  functionArgs: interpolatedVars,
147
161
  prompt: node,
148
162
  });
149
163
  this.generatedStatements.push(functionCode);
150
- const argsStr = interpolatedVars.join(", ");
164
+ const argsStr = [...interpolatedVars, "__messages"].join(", ");
151
165
  // Generate the function call
152
166
  return `const ${variableName} = await _${variableName}(${argsStr});` + "\n";
153
167
  }
@@ -176,6 +190,10 @@ export class TypeScriptGenerator extends BaseGenerator {
176
190
  });
177
191
  }
178
192
  processUsesTool(node) {
193
+ const functionDef = this.functionDefinitions[node.toolName];
194
+ if (functionDef && functionDef.returnType == null) {
195
+ throw new Error(`Function '${node.toolName}' is being used as a tool but has no return type. Tools must have a return type.`);
196
+ }
179
197
  this.toolsUsed.push(node.toolName);
180
198
  return "";
181
199
  }
@@ -211,6 +229,12 @@ export class TypeScriptGenerator extends BaseGenerator {
211
229
  }
212
230
  */ this.functionsUsed.add(node.functionName);
213
231
  const functionCallCode = this.generateFunctionCallExpression(node);
232
+ // Check if this is a built-in function that needs await
233
+ const mappedName = mapFunctionName(node.functionName);
234
+ const isBuiltinFunction = mappedName !== node.functionName;
235
+ if (isBuiltinFunction) {
236
+ return `await ${functionCallCode}`;
237
+ }
214
238
  return functionCallCode;
215
239
  }
216
240
  /**
@@ -235,7 +259,7 @@ export class TypeScriptGenerator extends BaseGenerator {
235
259
  }
236
260
  });
237
261
  let argsString = "";
238
- const paramNames = this.functionSignatures[node.functionName];
262
+ const paramNames = this.functionDefinitions[node.functionName]?.parameters.map((p) => p.name) || null;
239
263
  if (paramNames) {
240
264
  const partsWithNames = zip(paramNames, parts).map(([paramName, part]) => {
241
265
  return `${paramName}: ${part}`;
@@ -256,7 +280,7 @@ export class TypeScriptGenerator extends BaseGenerator {
256
280
  case "number":
257
281
  return literal.value;
258
282
  case "string":
259
- return `"${escape(literal.value)}"`;
283
+ return this.generateStringLiteral(literal.segments);
260
284
  case "multiLineString":
261
285
  return `\`${escape(literal.value)}\``;
262
286
  case "variableName":
@@ -284,7 +308,7 @@ export class TypeScriptGenerator extends BaseGenerator {
284
308
  }
285
309
  else {
286
310
  // Interpolation segment
287
- const varName = segment.variableName;
311
+ const varName = segment.variableName.replace(".", "_");
288
312
  const varType = typeHints[varName];
289
313
  // Serialize complex types to JSON
290
314
  if (varType && varType.type === "arrayType") {
@@ -297,23 +321,38 @@ export class TypeScriptGenerator extends BaseGenerator {
297
321
  }
298
322
  return "`" + promptParts.join("") + "`";
299
323
  }
324
+ generateStringLiteral(segments) {
325
+ const stringParts = [];
326
+ for (const segment of segments) {
327
+ if (segment.type === "text") {
328
+ const escaped = escape(segment.value);
329
+ stringParts.push(escaped);
330
+ }
331
+ else {
332
+ // Interpolation segment
333
+ stringParts.push(`\${${segment.variableName}}`);
334
+ }
335
+ }
336
+ return "`" + stringParts.join("") + "`";
337
+ }
300
338
  /**
301
339
  * Generates an async for prompt-based assignments
302
340
  */
303
- generatePromptFunction({ variableName, functionArgs = [], prompt, }) {
341
+ generatePromptFunction({ variableName, variableType, functionArgs = [], prompt, }) {
304
342
  // Generate async function for prompt-based assignment
305
- const variableType = this.typeHints[variableName] || {
343
+ const _variableType = variableType ||
344
+ this.typeHints[variableName] || {
306
345
  type: "primitiveType",
307
346
  value: "string",
308
347
  };
309
- const zodSchema = mapTypeToZodSchema(variableType, this.typeAliases);
348
+ const zodSchema = mapTypeToZodSchema(_variableType, this.typeAliases);
310
349
  //console.log("Generated Zod schema for variable", variableName, "Variable type:", variableType, ":", zodSchema, "aliases:", this.typeAliases, "hints:", this.typeHints);
311
- const typeString = variableTypeToString(variableType, this.typeAliases);
350
+ const typeString = variableTypeToString(_variableType, this.typeAliases);
312
351
  // Build prompt construction code
313
352
  const promptCode = this.buildPromptString(prompt.segments, this.typeHints);
314
- const argsStr = functionArgs
315
- .map((arg) => `${arg}: ${variableTypeToString(this.typeHints[arg] || { type: "primitiveType", value: "string" }, this.typeAliases)}`)
316
- .join(", ");
353
+ const parts = functionArgs.map((arg) => `${arg.replace(".", "_")}: ${variableTypeToString(this.typeHints[arg] || { type: "primitiveType", value: "string" }, this.typeAliases)}`);
354
+ parts.push("__messages: Message[] = []");
355
+ const argsStr = parts.join(", ");
317
356
  const _tools = this.toolsUsed
318
357
  .map((toolName) => `${toolName}Tool`)
319
358
  .join(", ");
@@ -349,6 +388,24 @@ export class TypeScriptGenerator extends BaseGenerator {
349
388
  const bodyCodeStr = bodyCodes.join("\n");
350
389
  return `while (${conditionCode}) {\n${bodyCodeStr}\n}\n`;
351
390
  }
391
+ processIfElse(node) {
392
+ const conditionCode = this.processNode(node.condition);
393
+ const thenBodyCodes = [];
394
+ for (const stmt of node.thenBody) {
395
+ thenBodyCodes.push(this.processNode(stmt));
396
+ }
397
+ const thenBodyStr = thenBodyCodes.join("\n");
398
+ let result = `if (${conditionCode}) {\n${thenBodyStr}\n}`;
399
+ if (node.elseBody && node.elseBody.length > 0) {
400
+ const elseBodyCodes = [];
401
+ for (const stmt of node.elseBody) {
402
+ elseBodyCodes.push(this.processNode(stmt));
403
+ }
404
+ const elseBodyStr = elseBodyCodes.join("\n");
405
+ result += ` else {\n${elseBodyStr}\n}`;
406
+ }
407
+ return result + "\n";
408
+ }
352
409
  processSpecialVar(node) {
353
410
  const value = this.processNode(node.value);
354
411
  switch (node.name) {
@@ -361,6 +418,21 @@ export class TypeScriptGenerator extends BaseGenerator {
361
418
  throw new Error(`Unhandled SpecialVar name: ${node.name}`);
362
419
  }
363
420
  }
421
+ processTimeBlock(node, timingVarName) {
422
+ const bodyCodes = [];
423
+ for (const stmt of node.body) {
424
+ bodyCodes.push(this.processNode(stmt));
425
+ }
426
+ const bodyCodeStr = bodyCodes.join("\n");
427
+ return renderTime.default({
428
+ timingVarName,
429
+ bodyCodeStr,
430
+ });
431
+ }
432
+ processAwaitStatement(node) {
433
+ const code = this.processNode(node.expression);
434
+ return `await ${code}`;
435
+ }
364
436
  }
365
437
  export function generateTypeScript(program) {
366
438
  const generator = new TypeScriptGenerator();
@@ -1,4 +1,4 @@
1
1
  import { AccessExpression, FunctionCall, Literal } from "../types.js";
2
- import { AgencyObject, AgencyArray } from "../types/dataStructures.js";
2
+ import { AgencyArray, AgencyObject } from "../types/dataStructures.js";
3
3
  import { ReturnStatement } from "../types/returnStatement.js";
4
4
  export declare const wrapInReturn: (node: AccessExpression | FunctionCall | Literal | AgencyObject | AgencyArray) => ReturnStatement;
@@ -1,9 +1,8 @@
1
1
  import { typeAliasParser, typeHintParser } from "./parsers/typeHints.js";
2
- import { anyChar, between, capture, eof, or, search, sepBy, seqC, set, spaces, str, success, trace, } from "tarsec";
2
+ import { anyChar, between, capture, eof, many, or, search, seqC, set, str, success, trace, } from "tarsec";
3
3
  import { accessExpressionParser } from "./parsers/access.js";
4
- import { assignmentParser } from "./parsers/assignment.js";
5
4
  import { commentParser } from "./parsers/comment.js";
6
- import { functionParser, graphNodeParser, whileLoopParser, } from "./parsers/function.js";
5
+ import { assignmentParser, functionParser, graphNodeParser, ifParser, timeBlockParser, whileLoopParser, } from "./parsers/function.js";
7
6
  import { functionCallParser } from "./parsers/functionCall.js";
8
7
  import { importStatmentParser } from "./parsers/importStatement.js";
9
8
  import { matchBlockParser } from "./parsers/matchBlock.js";
@@ -11,8 +10,10 @@ import { returnStatementParser } from "./parsers/returnStatement.js";
11
10
  import { usesToolParser } from "./parsers/tools.js";
12
11
  import { EgonLog } from "egonlog";
13
12
  import { specialVarParser } from "./parsers/specialVar.js";
13
+ import { awaitParser } from "./parsers/await.js";
14
+ import { newLineParser } from "./parsers/newline.js";
14
15
  export const agencyNode = (input) => {
15
- const parser = sepBy(spaces, trace("agencyParser", or(usesToolParser, importStatmentParser, graphNodeParser, typeAliasParser, whileLoopParser, typeHintParser, matchBlockParser, functionParser, returnStatementParser, specialVarParser, accessExpressionParser, assignmentParser, functionCallParser, commentParser)));
16
+ const parser = many(trace("agencyParser", or(usesToolParser, importStatmentParser, graphNodeParser, typeAliasParser, ifParser, whileLoopParser, typeHintParser, matchBlockParser, timeBlockParser, awaitParser, functionParser, returnStatementParser, specialVarParser, accessExpressionParser, assignmentParser, functionCallParser, commentParser, newLineParser)));
16
17
  return parser(input);
17
18
  };
18
19
  export const agencyParser = seqC(set("type", "agencyProgram"), capture(agencyNode, "nodes"), eof);
@@ -33,7 +34,6 @@ export function parseAgency(input, verbose = false) {
33
34
  .map((line) => {
34
35
  return line.trim();
35
36
  })
36
- .filter((l) => l.length > 0)
37
37
  .join("\n");
38
38
  if (normalized.trim().length === 0) {
39
39
  return success({