agency-lang 0.0.50 → 0.0.52

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 (71) hide show
  1. package/dist/lib/backends/agencyGenerator.d.ts +10 -4
  2. package/dist/lib/backends/agencyGenerator.js +49 -11
  3. package/dist/lib/backends/baseGenerator.d.ts +11 -1
  4. package/dist/lib/backends/baseGenerator.js +28 -4
  5. package/dist/lib/backends/graphGenerator.d.ts +6 -2
  6. package/dist/lib/backends/graphGenerator.js +27 -7
  7. package/dist/lib/backends/typescriptGenerator/builtins.d.ts +0 -4
  8. package/dist/lib/backends/typescriptGenerator/builtins.js +16 -27
  9. package/dist/lib/backends/typescriptGenerator.d.ts +8 -2
  10. package/dist/lib/backends/typescriptGenerator.js +38 -17
  11. package/dist/lib/config.d.ts +46 -0
  12. package/dist/lib/config.js +25 -0
  13. package/dist/lib/parser.d.ts +2 -1
  14. package/dist/lib/parser.js +13 -13
  15. package/dist/lib/parsers/access.d.ts +4 -1
  16. package/dist/lib/parsers/access.js +19 -2
  17. package/dist/lib/parsers/access.test.js +336 -1
  18. package/dist/lib/parsers/await.d.ts +1 -3
  19. package/dist/lib/parsers/await.js +20 -7
  20. package/dist/lib/parsers/function.d.ts +7 -0
  21. package/dist/lib/parsers/function.js +24 -5
  22. package/dist/lib/parsers/function.test.js +1081 -1
  23. package/dist/lib/parsers/functionCall.d.ts +3 -1
  24. package/dist/lib/parsers/functionCall.js +12 -2
  25. package/dist/lib/parsers/functionCall.test.js +300 -1
  26. package/dist/lib/parsers/literals.test.js +362 -0
  27. package/dist/lib/parsers/matchBlock.js +2 -2
  28. package/dist/lib/parsers/returnStatement.d.ts +1 -1
  29. package/dist/lib/parsers/returnStatement.js +5 -6
  30. package/dist/lib/parsers/tools.js +1 -1
  31. package/dist/lib/preprocessors/typescriptPreprocessor.config.test.js +328 -0
  32. package/dist/lib/preprocessors/typescriptPreprocessor.core.test.js +1127 -0
  33. package/dist/lib/preprocessors/typescriptPreprocessor.d.ts +97 -0
  34. package/dist/lib/preprocessors/typescriptPreprocessor.js +1051 -0
  35. package/dist/lib/preprocessors/typescriptPreprocessor.test.d.ts +1 -0
  36. package/dist/lib/preprocessors/typescriptPreprocessor.test.js +326 -0
  37. package/dist/lib/templates/backends/graphGenerator/goToNode.d.ts +1 -1
  38. package/dist/lib/templates/backends/graphGenerator/goToNode.js +1 -1
  39. package/dist/lib/templates/backends/graphGenerator/graphNode.d.ts +1 -1
  40. package/dist/lib/templates/backends/graphGenerator/graphNode.js +1 -1
  41. package/dist/lib/templates/backends/graphGenerator/imports.d.ts +8 -2
  42. package/dist/lib/templates/backends/graphGenerator/imports.js +220 -38
  43. package/dist/lib/templates/backends/graphGenerator/runNodeFunction.d.ts +1 -1
  44. package/dist/lib/templates/backends/graphGenerator/runNodeFunction.js +4 -3
  45. package/dist/lib/templates/backends/typescriptGenerator/functionDefinition.d.ts +1 -1
  46. package/dist/lib/templates/backends/typescriptGenerator/functionDefinition.js +0 -1
  47. package/dist/lib/templates/backends/typescriptGenerator/messageThread.d.ts +11 -0
  48. package/dist/lib/templates/backends/typescriptGenerator/messageThread.js +22 -0
  49. package/dist/lib/templates/backends/typescriptGenerator/promptFunction.d.ts +2 -1
  50. package/dist/lib/templates/backends/typescriptGenerator/promptFunction.js +74 -94
  51. package/dist/lib/types/access.d.ts +2 -1
  52. package/dist/lib/types/access.js +3 -2
  53. package/dist/lib/types/function.d.ts +1 -0
  54. package/dist/lib/types/literals.d.ts +7 -0
  55. package/dist/lib/types/messageThread.d.ts +8 -0
  56. package/dist/lib/types/messageThread.js +1 -0
  57. package/dist/lib/types/returnStatement.d.ts +1 -2
  58. package/dist/lib/types.d.ts +7 -4
  59. package/dist/lib/types.js +3 -0
  60. package/dist/lib/utils.d.ts +8 -0
  61. package/dist/lib/utils.js +25 -0
  62. package/dist/scripts/agency.js +159 -15
  63. package/package.json +8 -3
  64. package/dist/lib/generate-graph-file.d.ts +0 -2
  65. package/dist/lib/generate-graph-file.js +0 -25
  66. package/dist/lib/generate-ts-file.d.ts +0 -2
  67. package/dist/lib/generate-ts-file.js +0 -26
  68. package/dist/scripts/generateGraph.js +0 -24
  69. package/dist/scripts/generateTypescript.js +0 -24
  70. /package/dist/{scripts/generateGraph.d.ts → lib/preprocessors/typescriptPreprocessor.config.test.d.ts} +0 -0
  71. /package/dist/{scripts/generateTypescript.d.ts → lib/preprocessors/typescriptPreprocessor.core.test.d.ts} +0 -0
@@ -1,22 +1,26 @@
1
1
  import { SpecialVar } from "../types/specialVar.js";
2
2
  import { AgencyComment, AgencyProgram, Assignment, Literal, NewLine, PromptLiteral, TypeAlias, TypeHint, VariableType } from "../types.js";
3
+ import { AwaitStatement } from "../types/await.js";
4
+ import { TimeBlock } from "../types/timeBlock.js";
3
5
  import { AccessExpression, DotFunctionCall, DotProperty, IndexAccess } from "../types/access.js";
4
6
  import { AgencyArray, AgencyObject } from "../types/dataStructures.js";
5
7
  import { FunctionCall, FunctionDefinition } from "../types/function.js";
6
8
  import { GraphNodeDefinition } from "../types/graphNode.js";
9
+ import { IfElse } from "../types/ifElse.js";
7
10
  import { ImportNodeStatement, ImportStatement, ImportToolStatement } from "../types/importStatement.js";
8
11
  import { MatchBlock } from "../types/matchBlock.js";
9
12
  import { ReturnStatement } from "../types/returnStatement.js";
10
13
  import { UsesTool } from "../types/tools.js";
11
14
  import { WhileLoop } from "../types/whileLoop.js";
12
- import { IfElse } from "../types/ifElse.js";
13
15
  import { BaseGenerator } from "./baseGenerator.js";
14
- import { TimeBlock } from "../types/timeBlock.js";
15
- import { AwaitStatement } from "../types/await.js";
16
+ import { AgencyConfig } from "../config.js";
17
+ import { MessageThread } from "../types/messageThread.js";
16
18
  export declare class AgencyGenerator extends BaseGenerator {
17
19
  private indentLevel;
18
20
  private indentSize;
19
- constructor();
21
+ constructor(args?: {
22
+ config?: AgencyConfig;
23
+ });
20
24
  private indent;
21
25
  private increaseIndent;
22
26
  private decreaseIndent;
@@ -40,6 +44,7 @@ export declare class AgencyGenerator extends BaseGenerator {
40
44
  protected processAgencyArray(node: AgencyArray): string;
41
45
  protected processAgencyObject(node: AgencyObject): string;
42
46
  protected processAccessExpression(node: AccessExpression): string;
47
+ protected asyncAwaitPrefix(code: string, async?: boolean): string;
43
48
  protected processDotProperty(node: DotProperty): string;
44
49
  protected processIndexAccess(node: IndexAccess): string;
45
50
  protected processDotFunctionCall(node: DotFunctionCall): string;
@@ -58,5 +63,6 @@ export declare class AgencyGenerator extends BaseGenerator {
58
63
  private indentStr;
59
64
  protected processAwaitStatement(node: AwaitStatement): string;
60
65
  protected processNewLine(_node: NewLine): string;
66
+ protected processMessageThread(node: MessageThread): string;
61
67
  }
62
68
  export declare function generateAgency(program: AgencyProgram): string;
@@ -3,8 +3,8 @@ import { variableTypeToString } from "./typescriptGenerator/typeToString.js";
3
3
  export class AgencyGenerator extends BaseGenerator {
4
4
  indentLevel = 0;
5
5
  indentSize = 2;
6
- constructor() {
7
- super();
6
+ constructor(args = {}) {
7
+ super(args);
8
8
  }
9
9
  indent(level = this.indentLevel) {
10
10
  return " ".repeat(level * this.indentSize);
@@ -89,7 +89,7 @@ export class AgencyGenerator extends BaseGenerator {
89
89
  case "multiLineString":
90
90
  return this.generateMultiLineStringLiteral(literal);
91
91
  case "prompt":
92
- return this.generatePromptLiteral(literal);
92
+ return this.indentStr(this.generatePromptLiteral(literal));
93
93
  default:
94
94
  return "";
95
95
  }
@@ -166,8 +166,15 @@ export class AgencyGenerator extends BaseGenerator {
166
166
  const returnTypeStr = node.returnType
167
167
  ? ": " + variableTypeToString(node.returnType, this.typeAliases)
168
168
  : "";
169
+ let asyncPrefix = "";
170
+ if (node.async === true) {
171
+ asyncPrefix = "async ";
172
+ }
173
+ else if (node.async === false) {
174
+ asyncPrefix = "sync ";
175
+ }
169
176
  // Start function definition
170
- let result = this.indentStr(`def ${functionName}(${params})${returnTypeStr} {\n`);
177
+ let result = this.indentStr(`${asyncPrefix}def ${functionName}(${params})${returnTypeStr} {\n`);
171
178
  // Process body with increased indentation
172
179
  this.increaseIndent();
173
180
  if (node.docString) {
@@ -197,7 +204,13 @@ export class AgencyGenerator extends BaseGenerator {
197
204
  const args = node.arguments.map((arg) => {
198
205
  return this.processNode(arg).trim();
199
206
  });
200
- const asyncPrefix = node.async ? "async " : "";
207
+ let asyncPrefix = "";
208
+ if (node.async === true) {
209
+ asyncPrefix = "async ";
210
+ }
211
+ else if (node.async === false) {
212
+ asyncPrefix = "await ";
213
+ }
201
214
  return `${asyncPrefix}${node.functionName}(${args.join(", ")})`;
202
215
  }
203
216
  // Data structures
@@ -222,29 +235,43 @@ export class AgencyGenerator extends BaseGenerator {
222
235
  }
223
236
  // Access expressions
224
237
  processAccessExpression(node) {
238
+ let code = "";
225
239
  switch (node.expression.type) {
226
240
  case "dotProperty":
227
- return this.processDotProperty(node.expression);
241
+ code = this.processDotProperty(node.expression);
242
+ break;
228
243
  case "indexAccess":
229
- return this.processIndexAccess(node.expression);
244
+ code = this.processIndexAccess(node.expression);
245
+ break;
230
246
  case "dotFunctionCall":
231
- return this.processDotFunctionCall(node.expression);
247
+ code = this.processDotFunctionCall(node.expression);
248
+ break;
232
249
  }
250
+ return this.indentStr(this.asyncAwaitPrefix(code, node.async));
251
+ }
252
+ asyncAwaitPrefix(code, async) {
253
+ if (async === true) {
254
+ return `async ${code}`;
255
+ }
256
+ else if (async === false) {
257
+ return `await ${code}`;
258
+ }
259
+ return code;
233
260
  }
234
261
  processDotProperty(node) {
235
262
  let objectCode = this.processNode(node.object);
236
263
  objectCode = objectCode.trim();
237
- return this.indentStr(`${objectCode}.${node.propertyName}`);
264
+ return `${objectCode}.${node.propertyName}`;
238
265
  }
239
266
  processIndexAccess(node) {
240
267
  const arrayCode = this.processNode(node.array).trim();
241
268
  const indexCode = this.processNode(node.index).trim();
242
- return this.indentStr(`${arrayCode}[${indexCode}]`);
269
+ return `${arrayCode}[${indexCode}]`;
243
270
  }
244
271
  processDotFunctionCall(node) {
245
272
  const objectCode = this.processNode(node.object).trim();
246
273
  const functionCallCode = this.generateFunctionCallExpression(node.functionCall);
247
- return this.indentStr(`${objectCode}.${functionCallCode}`);
274
+ return `${objectCode}.${functionCallCode}`;
248
275
  }
249
276
  // Control flow
250
277
  processMatchBlock(node) {
@@ -370,6 +397,17 @@ export class AgencyGenerator extends BaseGenerator {
370
397
  processNewLine(_node) {
371
398
  return "\n";
372
399
  }
400
+ processMessageThread(node) {
401
+ this.increaseIndent();
402
+ const bodyCodes = [];
403
+ for (const stmt of node.body) {
404
+ bodyCodes.push(this.processNode(stmt));
405
+ }
406
+ this.decreaseIndent();
407
+ const bodyCodeStr = bodyCodes.join("");
408
+ const threadType = node.subthread ? "subthread" : "thread";
409
+ return this.indentStr(`${threadType} {\n${bodyCodeStr}${this.indentStr("}")}`);
410
+ }
373
411
  }
374
412
  export function generateAgency(program) {
375
413
  const generator = new AgencyGenerator();
@@ -12,6 +12,8 @@ import { MatchBlock } from "../types/matchBlock.js";
12
12
  import { ReturnStatement } from "../types/returnStatement.js";
13
13
  import { UsesTool } from "../types/tools.js";
14
14
  import { WhileLoop } from "../types/whileLoop.js";
15
+ import { AgencyConfig } from "../config.js";
16
+ import { MessageThread } from "../types/messageThread.js";
15
17
  type Scope = GlobalScope | FunctionScope | NodeScope;
16
18
  type GlobalScope = {
17
19
  type: "global";
@@ -40,16 +42,24 @@ export declare class BaseGenerator {
40
42
  protected importedTools: ImportToolStatement[];
41
43
  protected functionDefinitions: Record<string, FunctionDefinition>;
42
44
  protected currentScope: Scope[];
45
+ protected program: AgencyProgram | null;
46
+ protected agencyConfig: AgencyConfig;
47
+ constructor({ config }: {
48
+ config?: AgencyConfig;
49
+ });
50
+ configDefaults(): Partial<AgencyConfig>;
43
51
  generate(program: AgencyProgram): {
44
52
  output: string;
45
53
  };
46
54
  addIfNonEmpty(str: string, lines: string[]): void;
55
+ protected preprocessAST(): void;
47
56
  protected generateBuiltins(): string;
48
57
  protected processTypeAlias(node: TypeAlias): string;
49
58
  protected processTypeHint(node: TypeHint): string;
50
59
  protected collectFunctionSignature(node: FunctionDefinition): void;
51
60
  protected processGraphNodeName(node: GraphNodeDefinition): void;
52
61
  protected processNode(node: AgencyNode): string;
62
+ protected processMessageThread(node: MessageThread): string;
53
63
  protected processNewLine(_node: NewLine): string;
54
64
  protected processAwaitStatement(node: AwaitStatement): string;
55
65
  protected processTimeBlock(node: TimeBlock, timingVarName: string): string;
@@ -86,6 +96,6 @@ export declare class BaseGenerator {
86
96
  protected getScopeVar(): string;
87
97
  protected generateScopedVariableName(variableName: string): string;
88
98
  protected isImportedTool(functionName: string): boolean;
89
- protected isInternalFunction(functionName: string): boolean;
99
+ protected isAgencyFunction(functionName: string): boolean;
90
100
  }
91
101
  export {};
@@ -1,3 +1,4 @@
1
+ import { mergeDeep } from "../utils.js";
1
2
  export class BaseGenerator {
2
3
  typeHints = {};
3
4
  graphNodes = [];
@@ -18,7 +19,16 @@ export class BaseGenerator {
18
19
  // TODO also save return types, check if used as a tool, return type cannot be null/void/undefined
19
20
  functionDefinitions = {};
20
21
  currentScope = [{ type: "global" }];
22
+ program = null;
23
+ agencyConfig = {};
24
+ constructor({ config }) {
25
+ this.agencyConfig = mergeDeep(this.configDefaults(), config || {});
26
+ }
27
+ configDefaults() {
28
+ return {};
29
+ }
21
30
  generate(program) {
31
+ this.program = program;
22
32
  // Pass 1: Collect all type aliases
23
33
  for (const node of program.nodes) {
24
34
  if (node.type === "typeAlias") {
@@ -59,6 +69,12 @@ export class BaseGenerator {
59
69
  this.globalScopedVariables.push(node.variableName);
60
70
  }
61
71
  }
72
+ /* For each function, mark whether it is async or not.
73
+ A function has to be run synchronously if
74
+ - it or any of its child functions could throw an interrupt
75
+ - it or any of its child functions performs IO.
76
+ */
77
+ this.preprocessAST();
62
78
  // Pass 7: Process all nodes and generate code
63
79
  for (const node of program.nodes) {
64
80
  const result = this.processNode(node);
@@ -81,6 +97,9 @@ export class BaseGenerator {
81
97
  lines.push(str);
82
98
  }
83
99
  }
100
+ preprocessAST() {
101
+ // subclasses can implement this if their target language has async functions
102
+ }
84
103
  generateBuiltins() {
85
104
  return "";
86
105
  }
@@ -150,14 +169,19 @@ export class BaseGenerator {
150
169
  return this.processIndexAccess(node);
151
170
  case "timeBlock":
152
171
  return this.processTimeBlock(node, `__defaultTimeblockName`);
153
- case "awaitStatement":
154
- return this.processAwaitStatement(node);
155
172
  case "newLine":
156
173
  return this.processNewLine(node);
174
+ case "rawCode":
175
+ return node.value;
176
+ case "messageThread":
177
+ return this.processMessageThread(node);
157
178
  default:
158
179
  throw new Error(`Unhandled Agency node type: ${node.type}`);
159
180
  }
160
181
  }
182
+ processMessageThread(node) {
183
+ return "processMessageThread not implemented";
184
+ }
161
185
  processNewLine(_node) {
162
186
  return "";
163
187
  }
@@ -295,10 +319,10 @@ export class BaseGenerator {
295
319
  .flat()
296
320
  .includes(functionName);
297
321
  }
298
- /* Internal function means the user defined this function in an Agency file,
322
+ /* Agency function means the user defined this function in an Agency file,
299
323
  as opposed to an external function, which was defined in an external TypeScript file
300
324
  and imported into Agency. */
301
- isInternalFunction(functionName) {
325
+ isAgencyFunction(functionName) {
302
326
  return (!!this.functionDefinitions[functionName] ||
303
327
  this.isImportedTool(functionName));
304
328
  }
@@ -2,6 +2,7 @@ import { AgencyProgram, FunctionCall, TypeHintMap, VariableType } from "../types
2
2
  import { GraphNodeDefinition } from "../types/graphNode.js";
3
3
  import { ReturnStatement } from "../types/returnStatement.js";
4
4
  import { TypeScriptGenerator } from "./typescriptGenerator.js";
5
+ import { AgencyConfig } from "../config.js";
5
6
  export declare class GraphGenerator extends TypeScriptGenerator {
6
7
  protected typeHints: TypeHintMap;
7
8
  protected generatedStatements: string[];
@@ -11,7 +12,10 @@ export declare class GraphGenerator extends TypeScriptGenerator {
11
12
  protected adjacentNodes: Record<string, string[]>;
12
13
  protected currentAdjacentNodes: string[];
13
14
  protected isInsideGraphNode: boolean;
14
- constructor();
15
+ constructor(args?: {
16
+ config?: AgencyConfig;
17
+ });
18
+ configDefaults(): Partial<AgencyConfig>;
15
19
  protected processReturnStatement(node: ReturnStatement): string;
16
20
  protected processGraphNodeName(node: GraphNodeDefinition): void;
17
21
  protected processGraphNode(node: GraphNodeDefinition): string;
@@ -23,4 +27,4 @@ export declare class GraphGenerator extends TypeScriptGenerator {
23
27
  private agencyFileToDefaultImportName;
24
28
  protected postprocess(): string;
25
29
  }
26
- export declare function generateGraph(program: AgencyProgram): string;
30
+ export declare function generateGraph(program: AgencyProgram, config?: AgencyConfig): string;
@@ -8,6 +8,7 @@ import * as renderStartNode from "../templates/backends/graphGenerator/startNode
8
8
  import { TypeScriptGenerator } from "./typescriptGenerator.js";
9
9
  import { mapFunctionName } from "./typescriptGenerator/builtins.js";
10
10
  import { variableTypeToString } from "./typescriptGenerator/typeToString.js";
11
+ import { TypescriptPreprocessor } from "../preprocessors/typescriptPreprocessor.js";
11
12
  export class GraphGenerator extends TypeScriptGenerator {
12
13
  typeHints = {};
13
14
  generatedStatements = [];
@@ -17,8 +18,21 @@ export class GraphGenerator extends TypeScriptGenerator {
17
18
  adjacentNodes = {};
18
19
  currentAdjacentNodes = [];
19
20
  isInsideGraphNode = false;
20
- constructor() {
21
- super();
21
+ constructor(args = {}) {
22
+ super(args);
23
+ }
24
+ configDefaults() {
25
+ return {
26
+ log: {
27
+ host: "https://statelog.adit.io",
28
+ projectId: "agency-lang",
29
+ debugMode: false,
30
+ },
31
+ client: {
32
+ logLevel: "warn",
33
+ defaultModel: "gpt-4o-mini",
34
+ },
35
+ };
22
36
  }
23
37
  processReturnStatement(node) {
24
38
  if (!this.isInsideGraphNode) {
@@ -130,9 +144,13 @@ export class GraphGenerator extends TypeScriptGenerator {
130
144
  return "generateLiteral not implemented";
131
145
  } */
132
146
  generateImports() {
133
- let arr = [
147
+ const arr = [
134
148
  renderImports.default({
135
- nodes: JSON.stringify(this.graphNodes.map((n) => n.nodeName)),
149
+ logHost: this.agencyConfig.log?.host || "",
150
+ logProjectId: this.agencyConfig.log?.projectId || "",
151
+ logDebugMode: this.agencyConfig.log?.debugMode || false,
152
+ clientLogLevel: this.agencyConfig.client?.logLevel || "warn",
153
+ clientDefaultModel: this.agencyConfig.client?.defaultModel || "gpt-4o-mini",
136
154
  }),
137
155
  ];
138
156
  arr.push(builtinTools.default({}));
@@ -187,7 +205,9 @@ export class GraphGenerator extends TypeScriptGenerator {
187
205
  return lines.join("\n");
188
206
  }
189
207
  }
190
- export function generateGraph(program) {
191
- const generator = new GraphGenerator();
192
- return generator.generate(program).output;
208
+ export function generateGraph(program, config) {
209
+ const preprocessor = new TypescriptPreprocessor(program, config);
210
+ const preprocessedProgram = preprocessor.preprocess();
211
+ const generator = new GraphGenerator({ config });
212
+ return generator.generate(preprocessedProgram).output;
193
213
  }
@@ -1,7 +1,3 @@
1
- /**
2
- * Maps Agency built-in function names to TypeScript equivalents
3
- */
4
- export declare const BUILTIN_FUNCTIONS: Record<string, string>;
5
1
  /**
6
2
  * Maps an Agency function name to its TypeScript equivalent
7
3
  * Returns the original name if not a built-in
@@ -1,23 +1,7 @@
1
1
  import * as builtinFunctionsInput from "../../templates/backends/typescriptGenerator/builtinFunctions/input.js";
2
2
  import * as builtinFunctionsRead from "../../templates/backends/typescriptGenerator/builtinFunctions/read.js";
3
- import * as builtinFunctionsReadImage from "../../templates/backends/typescriptGenerator/builtinFunctions/readImage.js";
4
3
  import * as builtinFunctionsFetchJSON from "../../templates/backends/typescriptGenerator/builtinFunctions/fetchJSON.js";
5
- import * as builtinFunctionsFetch from "../../templates/backends/typescriptGenerator/builtinFunctions/fetch.js";
6
- import * as builtinFunctionsSleep from "../../templates/backends/typescriptGenerator/builtinFunctions/sleep.js";
7
- /**
8
- * Maps Agency built-in function names to TypeScript equivalents
9
- */
10
- export const BUILTIN_FUNCTIONS = {
11
- print: "console.log",
12
- input: "_builtinInput",
13
- read: "_builtinRead",
14
- readImage: "_builtinReadImage",
15
- write: "fs.writeFileSync",
16
- fetch: "_builtinFetch",
17
- fetchJSON: "_builtinFetchJSON",
18
- fetchJson: "_builtinFetchJSON",
19
- sleep: "_builtinSleep",
20
- };
4
+ import { BUILTIN_FUNCTIONS } from "../../config.js";
21
5
  /**
22
6
  * Maps an Agency function name to its TypeScript equivalent
23
7
  * Returns the original name if not a built-in
@@ -33,26 +17,31 @@ export function generateBuiltinHelpers(functionsUsed) {
33
17
  const readFunc = builtinFunctionsRead.default({});
34
18
  const fetchJSONFunc = builtinFunctionsFetchJSON.default({});
35
19
  const helpers = [];
20
+ // all included by default, since we don't want to have conditional imports in the generated code
21
+ /*
36
22
  if (functionsUsed.has("input")) {
37
- helpers.push(inputFunc);
23
+ helpers.push(inputFunc);
38
24
  }
39
25
  if (functionsUsed.has("read")) {
40
- helpers.push(readFunc);
26
+ helpers.push(readFunc);
41
27
  }
42
28
  if (functionsUsed.has("fetchJSON") || functionsUsed.has("fetchJson")) {
43
- helpers.push(fetchJSONFunc);
29
+ helpers.push(fetchJSONFunc);
44
30
  }
45
31
  if (functionsUsed.has("fetch")) {
46
- const fetchFunc = builtinFunctionsFetch.default({});
47
- helpers.push(fetchFunc);
32
+ const fetchFunc = builtinFunctionsFetch.default({});
33
+ helpers.push(fetchFunc);
48
34
  }
49
35
  if (functionsUsed.has("readImage")) {
50
- const readImageFunc = builtinFunctionsReadImage.default({});
51
- helpers.push(readImageFunc);
52
- }
53
- if (functionsUsed.has("sleep")) {
36
+ const readImageFunc = builtinFunctionsReadImage.default({});
37
+ helpers.push(readImageFunc);
38
+ } */
39
+ /*
40
+ already included by default
41
+ if (functionsUsed.has("sleep")) {
54
42
  const sleepFunc = builtinFunctionsSleep.default({});
55
43
  helpers.push(sleepFunc);
56
- }
44
+ }
45
+ */
57
46
  return helpers.join("\n\n");
58
47
  }
@@ -12,8 +12,13 @@ import { ReturnStatement } from "../types/returnStatement.js";
12
12
  import { UsesTool } from "../types/tools.js";
13
13
  import { WhileLoop } from "../types/whileLoop.js";
14
14
  import { BaseGenerator } from "./baseGenerator.js";
15
+ import { AgencyConfig } from "../config.js";
16
+ import { MessageThread } from "../types/messageThread.js";
15
17
  export declare class TypeScriptGenerator extends BaseGenerator {
16
- constructor();
18
+ protected currentMessageThreadNodeId: string[];
19
+ constructor(args?: {
20
+ config?: AgencyConfig;
21
+ });
17
22
  protected generateBuiltins(): string;
18
23
  protected processTypeAlias(node: TypeAlias): string;
19
24
  protected typeAliasToString(node: TypeAlias): string;
@@ -65,6 +70,7 @@ export declare class TypeScriptGenerator extends BaseGenerator {
65
70
  protected processSpecialVar(node: SpecialVar): string;
66
71
  protected processTimeBlock(node: TimeBlock, timingVarName: string): string;
67
72
  protected processAwaitStatement(node: AwaitStatement): string;
73
+ protected processMessageThread(node: MessageThread, varName?: string): string;
68
74
  protected processBodyAsParts(body: AgencyNode[]): string[];
69
75
  }
70
- export declare function generateTypeScript(program: AgencyProgram): string;
76
+ export declare function generateTypeScript(program: AgencyProgram, config?: AgencyConfig): string;
@@ -6,6 +6,7 @@ import * as renderFunctionDefinition from "../templates/backends/typescriptGener
6
6
  import * as renderInternalFunctionCall from "../templates/backends/typescriptGenerator/internalFunctionCall.js";
7
7
  import * as renderFunctionCallAssignment from "../templates/backends/typescriptGenerator/functionCallAssignment.js";
8
8
  import * as renderImports from "../templates/backends/typescriptGenerator/imports.js";
9
+ import * as renderMessageThread from "../templates/backends/typescriptGenerator/messageThread.js";
9
10
  import * as promptFunction from "../templates/backends/typescriptGenerator/promptFunction.js";
10
11
  import * as renderTool from "../templates/backends/typescriptGenerator/tool.js";
11
12
  import * as renderToolCall from "../templates/backends/typescriptGenerator/toolCall.js";
@@ -14,10 +15,12 @@ import { BaseGenerator } from "./baseGenerator.js";
14
15
  import { generateBuiltinHelpers, mapFunctionName, } from "./typescriptGenerator/builtins.js";
15
16
  import { variableTypeToString } from "./typescriptGenerator/typeToString.js";
16
17
  import { DEFAULT_SCHEMA, mapTypeToZodSchema, } from "./typescriptGenerator/typeToZodSchema.js";
18
+ import { TypescriptPreprocessor } from "../preprocessors/typescriptPreprocessor.js";
17
19
  const DEFAULT_PROMPT_NAME = "__promptVar";
18
20
  export class TypeScriptGenerator extends BaseGenerator {
19
- constructor() {
20
- super();
21
+ currentMessageThreadNodeId = ["0"];
22
+ constructor(args = {}) {
23
+ super(args);
21
24
  }
22
25
  generateBuiltins() {
23
26
  return generateBuiltinHelpers(this.functionsUsed);
@@ -156,6 +159,10 @@ export class TypeScriptGenerator extends BaseGenerator {
156
159
  const code = this.processTimeBlock(value, timingVarName);
157
160
  return code;
158
161
  }
162
+ else if (value.type === "messageThread") {
163
+ const varName = `${this.getScopeVar()}.${variableName}`;
164
+ return this.processMessageThread(value, varName);
165
+ }
159
166
  else {
160
167
  // Direct assignment for other literal types
161
168
  const code = this.processNode(value);
@@ -276,24 +283,18 @@ export class TypeScriptGenerator extends BaseGenerator {
276
283
  if (arg.type === "functionCall") {
277
284
  this.functionsUsed.add(arg.functionName);
278
285
  return this.generateFunctionCallExpression(arg);
279
- /* } else if (arg.type === "accessExpression") {
280
- return this.processAccessExpression(arg);
281
- } else if (arg.type === "indexAccess") {
282
- return this.processIndexAccess(arg);
283
- */
284
286
  }
285
287
  else {
286
- // return this.generateLiteral(arg);
287
288
  return this.processNode(arg);
288
289
  }
289
290
  });
290
291
  let argsString = "";
291
- if (this.isInternalFunction(node.functionName)) {
292
+ if (this.isAgencyFunction(node.functionName)) {
292
293
  argsString = parts.join(", ");
293
294
  const metadata = `{
294
295
  statelogClient,
295
296
  graph: __graph,
296
- messages: __messages,
297
+ messages: __self.messages_${this.currentMessageThreadNodeId.at(-1)}.getMessages(),
297
298
  }`;
298
299
  return renderInternalFunctionCall.default({
299
300
  functionName,
@@ -305,7 +306,8 @@ export class TypeScriptGenerator extends BaseGenerator {
305
306
  else {
306
307
  // must be a builtin function or imported function
307
308
  argsString = parts.join(", ");
308
- return `${functionName}(${argsString})`;
309
+ const awaitStr = node.async ? "await " : "";
310
+ return `${awaitStr}${functionName}(${argsString})`;
309
311
  }
310
312
  }
311
313
  generateLiteral(literal) {
@@ -393,7 +395,6 @@ export class TypeScriptGenerator extends BaseGenerator {
393
395
  value: "string",
394
396
  };
395
397
  const zodSchema = mapTypeToZodSchema(_variableType, this.typeAliases);
396
- //console.log("Generated Zod schema for variable", variableName, "Variable type:", variableType, ":", zodSchema, "aliases:", this.typeAliases, "hints:", this.typeHints);
397
398
  const typeString = variableTypeToString(_variableType, this.typeAliases);
398
399
  // Build prompt construction code
399
400
  const promptCode = this.buildPromptString(prompt.segments, this.typeHints);
@@ -423,7 +424,7 @@ export class TypeScriptGenerator extends BaseGenerator {
423
424
  .join("\n");
424
425
  const clientConfig = prompt.config ? this.processNode(prompt.config) : "{}";
425
426
  const metadataObj = `{
426
- messages: __messages,
427
+ messages: __self.messages_${this.currentMessageThreadNodeId.at(-1)}.getMessages(),
427
428
  }`;
428
429
  this.toolsUsed = []; // reset after use
429
430
  const scopedFunctionArgs = functionArgs.map((arg) => this.generateScopedVariableName(arg));
@@ -440,6 +441,7 @@ export class TypeScriptGenerator extends BaseGenerator {
440
441
  clientConfig,
441
442
  nodeContext: this.getCurrentScope().type === "node",
442
443
  isStreaming: prompt.isStreaming || false,
444
+ isAsync: prompt.async || false,
443
445
  });
444
446
  }
445
447
  processImportStatement(node) {
@@ -490,7 +492,7 @@ export class TypeScriptGenerator extends BaseGenerator {
490
492
  value,
491
493
  });
492
494
  case "messages":
493
- return `__messages = ${value};\n`;
495
+ return `__self.messages_${this.currentMessageThreadNodeId.at(-1)}.setMessages(${value});\n`;
494
496
  default:
495
497
  throw new Error(`Unhandled SpecialVar name: ${node.name}`);
496
498
  }
@@ -511,6 +513,23 @@ export class TypeScriptGenerator extends BaseGenerator {
511
513
  const code = this.processNode(node.expression);
512
514
  return `await ${code}`;
513
515
  }
516
+ processMessageThread(node, varName) {
517
+ this.currentMessageThreadNodeId.push(node.nodeId || "0");
518
+ const bodyCodes = [];
519
+ for (const stmt of node.body) {
520
+ bodyCodes.push(this.processNode(stmt));
521
+ }
522
+ const bodyCodeStr = bodyCodes.join("\n");
523
+ this.currentMessageThreadNodeId.pop();
524
+ return renderMessageThread.default({
525
+ bodyCode: bodyCodeStr,
526
+ hasVar: !!varName,
527
+ varName,
528
+ isSubthread: node.subthread,
529
+ nodeId: node.nodeId || "0",
530
+ parentNodeId: node.parentNodeId || "0",
531
+ });
532
+ }
514
533
  /* This generates the body of a node or function separated into multiple parts.
515
534
  You can think of a part as roughly corresponding to a single statement
516
535
  (although some statements don't need their own parts, such as a newlines or type definitions).
@@ -544,7 +563,9 @@ export class TypeScriptGenerator extends BaseGenerator {
544
563
  return bodyCode;
545
564
  }
546
565
  }
547
- export function generateTypeScript(program) {
548
- const generator = new TypeScriptGenerator();
549
- return generator.generate(program).output;
566
+ export function generateTypeScript(program, config) {
567
+ const preprocessor = new TypescriptPreprocessor(program, config);
568
+ const preprocessedProgram = preprocessor.preprocess();
569
+ const generator = new TypeScriptGenerator({ config });
570
+ return generator.generate(preprocessedProgram).output;
550
571
  }
@@ -1,2 +1,48 @@
1
1
  import { AgencyNode } from "./types.js";
2
2
  export declare const TYPES_THAT_DONT_TRIGGER_NEW_PART: AgencyNode["type"][];
3
+ /**
4
+ * Maps Agency built-in function names to TypeScript equivalents
5
+ */
6
+ export declare const BUILTIN_FUNCTIONS: Record<string, string>;
7
+ export declare const BUILTIN_FUNCTIONS_TO_ASYNC: Record<string, boolean>;
8
+ /**
9
+ * Configuration options for the Agency compiler
10
+ */
11
+ export interface AgencyConfig {
12
+ verbose?: boolean;
13
+ outDir?: string;
14
+ /**
15
+ * Array of AST node types to exclude from code generation
16
+ * Example: ["comment", "typeHint"]
17
+ */
18
+ excludeNodeTypes?: string[];
19
+ /**
20
+ * Array of built-in function names to exclude from code generation
21
+ * Example: ["fetch", "write"]
22
+ */
23
+ excludeBuiltinFunctions?: string[];
24
+ /**
25
+ * Array of domains allowed for fetch operations
26
+ * If specified, only these domains can be fetched
27
+ * Example: ["api.example.com", "data.mysite.com"]
28
+ */
29
+ allowedFetchDomains?: string[];
30
+ /**
31
+ * Array of domains disallowed for fetch operations
32
+ * These domains will throw an error if fetch is attempted
33
+ * If both allowed and disallowed are set, takes the intersection
34
+ * (only allowed domains, minus disallowed ones)
35
+ * Example: ["malicious.com", "blocked.site.com"]
36
+ */
37
+ disallowedFetchDomains?: string[];
38
+ /** Statelog config */
39
+ log?: Partial<{
40
+ host: string;
41
+ projectId: string;
42
+ debugMode: boolean;
43
+ }>;
44
+ client?: Partial<{
45
+ logLevel: "error" | "warn" | "info" | "debug";
46
+ defaultModel: string;
47
+ }>;
48
+ }