agency-lang 0.0.21 → 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.
- package/dist/lib/backends/agencyGenerator.d.ts +10 -2
- package/dist/lib/backends/agencyGenerator.js +86 -19
- package/dist/lib/backends/agencyGenerator.test.js +0 -48
- package/dist/lib/backends/baseGenerator.d.ts +11 -4
- package/dist/lib/backends/baseGenerator.js +35 -11
- package/dist/lib/backends/graphGenerator.js +19 -186
- package/dist/lib/backends/typescriptGenerator/builtins.js +6 -0
- package/dist/lib/backends/typescriptGenerator.d.ts +11 -3
- package/dist/lib/backends/typescriptGenerator.js +98 -26
- package/dist/lib/backends/utils.d.ts +1 -1
- package/dist/lib/parser.js +5 -5
- package/dist/lib/parser.test.js +15 -38
- package/dist/lib/parsers/access.test.js +14 -3
- package/dist/lib/parsers/assignment.test.js +159 -4
- package/dist/lib/parsers/await.d.ts +3 -0
- package/dist/lib/parsers/await.js +18 -0
- package/dist/lib/parsers/body.test.js +10 -1
- package/dist/lib/parsers/dataStructures.js +2 -2
- package/dist/lib/parsers/dataStructures.test.js +11 -11
- package/dist/lib/parsers/function.d.ts +8 -3
- package/dist/lib/parsers/function.js +64 -12
- package/dist/lib/parsers/function.test.js +284 -52
- package/dist/lib/parsers/functionCall.test.js +6 -6
- package/dist/lib/parsers/ifElse.test.d.ts +1 -0
- package/dist/lib/parsers/ifElse.test.js +376 -0
- package/dist/lib/parsers/importStatement.js +2 -2
- package/dist/lib/parsers/literals.d.ts +1 -0
- package/dist/lib/parsers/literals.js +6 -2
- package/dist/lib/parsers/literals.test.js +110 -21
- package/dist/lib/parsers/matchBlock.js +7 -4
- package/dist/lib/parsers/matchBlock.test.js +16 -16
- package/dist/lib/parsers/newline.d.ts +3 -0
- package/dist/lib/parsers/newline.js +2 -0
- package/dist/lib/parsers/parserUtils.d.ts +3 -1
- package/dist/lib/parsers/parserUtils.js +4 -1
- package/dist/lib/parsers/returnStatement.js +2 -1
- package/dist/lib/parsers/returnStatement.test.js +2 -2
- package/dist/lib/parsers/specialVar.test.js +7 -7
- package/dist/lib/parsers/typeHints.d.ts +1 -1
- package/dist/lib/parsers/typeHints.js +4 -4
- package/dist/lib/parsers/typeHints.test.js +0 -8
- package/dist/lib/parsers/utils.d.ts +1 -0
- package/dist/lib/parsers/utils.js +2 -1
- package/dist/lib/parsers/whileLoop.test.js +46 -1
- package/dist/lib/templates/backends/graphGenerator/goToNode.d.ts +2 -1
- package/dist/lib/templates/backends/graphGenerator/goToNode.js +11 -1
- package/dist/lib/templates/backends/graphGenerator/graphNode.d.ts +2 -2
- package/dist/lib/templates/backends/graphGenerator/graphNode.js +2 -1
- package/dist/lib/templates/backends/graphGenerator/imports.d.ts +1 -1
- package/dist/lib/templates/backends/graphGenerator/imports.js +14 -1
- package/dist/lib/templates/backends/typescriptGenerator/builtinFunctions/sleep.d.ts +4 -0
- package/dist/lib/templates/backends/typescriptGenerator/builtinFunctions/sleep.js +13 -0
- package/dist/lib/templates/backends/typescriptGenerator/builtinFunctions/time.d.ts +7 -0
- package/dist/lib/templates/backends/typescriptGenerator/builtinFunctions/time.js +12 -0
- package/dist/lib/templates/backends/typescriptGenerator/functionDefinition.d.ts +1 -1
- package/dist/lib/templates/backends/typescriptGenerator/functionDefinition.js +1 -0
- package/dist/lib/templates/backends/typescriptGenerator/promptFunction.d.ts +1 -1
- package/dist/lib/templates/backends/typescriptGenerator/promptFunction.js +3 -2
- package/dist/lib/templates/backends/typescriptGenerator/tool.d.ts +1 -1
- package/dist/lib/templates/backends/typescriptGenerator/tool.js +1 -1
- package/dist/lib/templates/backends/typescriptGenerator/toolCall.d.ts +1 -1
- package/dist/lib/templates/backends/typescriptGenerator/toolCall.js +2 -2
- package/dist/lib/types/await.d.ts +7 -0
- package/dist/lib/types/await.js +1 -0
- package/dist/lib/types/graphNode.d.ts +2 -1
- package/dist/lib/types/ifElse.d.ts +7 -0
- package/dist/lib/types/ifElse.js +1 -0
- package/dist/lib/types/literals.d.ts +1 -1
- package/dist/lib/types/returnStatement.d.ts +2 -1
- package/dist/lib/types/timeBlock.d.ts +5 -0
- package/dist/lib/types/timeBlock.js +1 -0
- package/dist/lib/types.d.ts +16 -8
- package/dist/lib/types.js +1 -0
- package/dist/lib/utils.d.ts +1 -0
- package/dist/lib/utils.js +3 -0
- package/package.json +3 -2
- package/dist/lib/parsers/assignment.d.ts +0 -3
- package/dist/lib/parsers/assignment.js +0 -8
- package/dist/lib/templates/backends/graphGenerator/node.d.ts +0 -7
- package/dist/lib/templates/backends/graphGenerator/node.js +0 -18
- package/dist/lib/templates/backends/graphGenerator/promptNode.d.ts +0 -8
- 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
|
|
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
|
-
|
|
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
|
-
|
|
227
|
-
this.functionScopedVariables.push(
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
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.
|
|
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
|
|
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
|
|
343
|
+
const _variableType = variableType ||
|
|
344
|
+
this.typeHints[variableName] || {
|
|
306
345
|
type: "primitiveType",
|
|
307
346
|
value: "string",
|
|
308
347
|
};
|
|
309
|
-
const zodSchema = mapTypeToZodSchema(
|
|
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(
|
|
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
|
|
315
|
-
|
|
316
|
-
|
|
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 {
|
|
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;
|
package/dist/lib/parser.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { typeAliasParser, typeHintParser } from "./parsers/typeHints.js";
|
|
2
|
-
import { anyChar, between, capture, eof, or, search,
|
|
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 =
|
|
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({
|