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.
- package/dist/lib/backends/agencyGenerator.d.ts +10 -4
- package/dist/lib/backends/agencyGenerator.js +49 -11
- package/dist/lib/backends/baseGenerator.d.ts +11 -1
- package/dist/lib/backends/baseGenerator.js +28 -4
- package/dist/lib/backends/graphGenerator.d.ts +6 -2
- package/dist/lib/backends/graphGenerator.js +27 -7
- package/dist/lib/backends/typescriptGenerator/builtins.d.ts +0 -4
- package/dist/lib/backends/typescriptGenerator/builtins.js +16 -27
- package/dist/lib/backends/typescriptGenerator.d.ts +8 -2
- package/dist/lib/backends/typescriptGenerator.js +38 -17
- package/dist/lib/config.d.ts +46 -0
- package/dist/lib/config.js +25 -0
- package/dist/lib/parser.d.ts +2 -1
- package/dist/lib/parser.js +13 -13
- package/dist/lib/parsers/access.d.ts +4 -1
- package/dist/lib/parsers/access.js +19 -2
- package/dist/lib/parsers/access.test.js +336 -1
- package/dist/lib/parsers/await.d.ts +1 -3
- package/dist/lib/parsers/await.js +20 -7
- package/dist/lib/parsers/function.d.ts +7 -0
- package/dist/lib/parsers/function.js +24 -5
- package/dist/lib/parsers/function.test.js +1081 -1
- package/dist/lib/parsers/functionCall.d.ts +3 -1
- package/dist/lib/parsers/functionCall.js +12 -2
- package/dist/lib/parsers/functionCall.test.js +300 -1
- package/dist/lib/parsers/literals.test.js +362 -0
- package/dist/lib/parsers/matchBlock.js +2 -2
- package/dist/lib/parsers/returnStatement.d.ts +1 -1
- package/dist/lib/parsers/returnStatement.js +5 -6
- package/dist/lib/parsers/tools.js +1 -1
- package/dist/lib/preprocessors/typescriptPreprocessor.config.test.js +328 -0
- package/dist/lib/preprocessors/typescriptPreprocessor.core.test.js +1127 -0
- package/dist/lib/preprocessors/typescriptPreprocessor.d.ts +97 -0
- package/dist/lib/preprocessors/typescriptPreprocessor.js +1051 -0
- package/dist/lib/preprocessors/typescriptPreprocessor.test.d.ts +1 -0
- package/dist/lib/preprocessors/typescriptPreprocessor.test.js +326 -0
- package/dist/lib/templates/backends/graphGenerator/goToNode.d.ts +1 -1
- package/dist/lib/templates/backends/graphGenerator/goToNode.js +1 -1
- package/dist/lib/templates/backends/graphGenerator/graphNode.d.ts +1 -1
- package/dist/lib/templates/backends/graphGenerator/graphNode.js +1 -1
- package/dist/lib/templates/backends/graphGenerator/imports.d.ts +8 -2
- package/dist/lib/templates/backends/graphGenerator/imports.js +220 -38
- package/dist/lib/templates/backends/graphGenerator/runNodeFunction.d.ts +1 -1
- package/dist/lib/templates/backends/graphGenerator/runNodeFunction.js +4 -3
- package/dist/lib/templates/backends/typescriptGenerator/functionDefinition.d.ts +1 -1
- package/dist/lib/templates/backends/typescriptGenerator/functionDefinition.js +0 -1
- package/dist/lib/templates/backends/typescriptGenerator/messageThread.d.ts +11 -0
- package/dist/lib/templates/backends/typescriptGenerator/messageThread.js +22 -0
- package/dist/lib/templates/backends/typescriptGenerator/promptFunction.d.ts +2 -1
- package/dist/lib/templates/backends/typescriptGenerator/promptFunction.js +74 -94
- package/dist/lib/types/access.d.ts +2 -1
- package/dist/lib/types/access.js +3 -2
- package/dist/lib/types/function.d.ts +1 -0
- package/dist/lib/types/literals.d.ts +7 -0
- package/dist/lib/types/messageThread.d.ts +8 -0
- package/dist/lib/types/messageThread.js +1 -0
- package/dist/lib/types/returnStatement.d.ts +1 -2
- package/dist/lib/types.d.ts +7 -4
- package/dist/lib/types.js +3 -0
- package/dist/lib/utils.d.ts +8 -0
- package/dist/lib/utils.js +25 -0
- package/dist/scripts/agency.js +159 -15
- package/package.json +8 -3
- package/dist/lib/generate-graph-file.d.ts +0 -2
- package/dist/lib/generate-graph-file.js +0 -25
- package/dist/lib/generate-ts-file.d.ts +0 -2
- package/dist/lib/generate-ts-file.js +0 -26
- package/dist/scripts/generateGraph.js +0 -24
- package/dist/scripts/generateTypescript.js +0 -24
- /package/dist/{scripts/generateGraph.d.ts → lib/preprocessors/typescriptPreprocessor.config.test.d.ts} +0 -0
- /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 {
|
|
15
|
-
import {
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
241
|
+
code = this.processDotProperty(node.expression);
|
|
242
|
+
break;
|
|
228
243
|
case "indexAccess":
|
|
229
|
-
|
|
244
|
+
code = this.processIndexAccess(node.expression);
|
|
245
|
+
break;
|
|
230
246
|
case "dotFunctionCall":
|
|
231
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
/*
|
|
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
|
-
|
|
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
|
-
|
|
147
|
+
const arr = [
|
|
134
148
|
renderImports.default({
|
|
135
|
-
|
|
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
|
|
192
|
-
|
|
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,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
|
|
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
|
-
|
|
23
|
+
helpers.push(inputFunc);
|
|
38
24
|
}
|
|
39
25
|
if (functionsUsed.has("read")) {
|
|
40
|
-
|
|
26
|
+
helpers.push(readFunc);
|
|
41
27
|
}
|
|
42
28
|
if (functionsUsed.has("fetchJSON") || functionsUsed.has("fetchJson")) {
|
|
43
|
-
|
|
29
|
+
helpers.push(fetchJSONFunc);
|
|
44
30
|
}
|
|
45
31
|
if (functionsUsed.has("fetch")) {
|
|
46
|
-
|
|
47
|
-
|
|
32
|
+
const fetchFunc = builtinFunctionsFetch.default({});
|
|
33
|
+
helpers.push(fetchFunc);
|
|
48
34
|
}
|
|
49
35
|
if (functionsUsed.has("readImage")) {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
}
|
|
53
|
-
|
|
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
|
-
|
|
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
|
-
|
|
20
|
-
|
|
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.
|
|
292
|
+
if (this.isAgencyFunction(node.functionName)) {
|
|
292
293
|
argsString = parts.join(", ");
|
|
293
294
|
const metadata = `{
|
|
294
295
|
statelogClient,
|
|
295
296
|
graph: __graph,
|
|
296
|
-
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
|
-
|
|
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:
|
|
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 `
|
|
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
|
|
549
|
-
|
|
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
|
}
|
package/dist/lib/config.d.ts
CHANGED
|
@@ -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
|
+
}
|