agency-lang 0.0.16 → 0.0.18
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.js +13 -6
- package/dist/lib/backends/baseGenerator.d.ts +2 -1
- package/dist/lib/backends/baseGenerator.js +9 -1
- package/dist/lib/backends/graphGenerator.js +20 -10
- package/dist/lib/backends/typescriptGenerator.js +13 -6
- package/dist/lib/parsers/function.d.ts +2 -1
- package/dist/lib/parsers/function.js +4 -3
- package/dist/lib/parsers/function.test.js +865 -9
- package/dist/lib/parsers/literals.d.ts +2 -1
- package/dist/lib/parsers/literals.js +5 -4
- package/dist/lib/parsers/literals.test.js +182 -9
- 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/runNodeFunction.d.ts +2 -1
- package/dist/lib/templates/backends/graphGenerator/runNodeFunction.js +1 -1
- package/dist/lib/templates/backends/typescriptGenerator/functionDefinition.d.ts +2 -1
- package/dist/lib/templates/backends/typescriptGenerator/functionDefinition.js +1 -1
- package/dist/lib/types/function.d.ts +1 -1
- package/dist/lib/types/graphNode.d.ts +2 -1
- package/dist/lib/types/literals.d.ts +5 -1
- package/package.json +2 -2
|
@@ -66,12 +66,13 @@ export class AgencyGenerator extends BaseGenerator {
|
|
|
66
66
|
return literal.value;
|
|
67
67
|
case "string":
|
|
68
68
|
// Escape backslashes and quotes
|
|
69
|
-
const escaped = literal.value
|
|
70
|
-
.replace(/\\/g, "\\\\")
|
|
71
|
-
.replace(/"/g, '\\"');
|
|
69
|
+
const escaped = literal.value;
|
|
72
70
|
return `"${escaped}"`;
|
|
73
71
|
case "variableName":
|
|
74
72
|
return literal.value;
|
|
73
|
+
case "multiLineString":
|
|
74
|
+
const escapedMultiLine = literal.value;
|
|
75
|
+
return `"""${escapedMultiLine}"""`;
|
|
75
76
|
case "prompt":
|
|
76
77
|
return this.generatePromptLiteral(literal);
|
|
77
78
|
default:
|
|
@@ -111,8 +112,11 @@ export class AgencyGenerator extends BaseGenerator {
|
|
|
111
112
|
}
|
|
112
113
|
})
|
|
113
114
|
.join(", ");
|
|
115
|
+
const returnTypeStr = node.returnType
|
|
116
|
+
? ": " + variableTypeToString(node.returnType, this.typeAliases)
|
|
117
|
+
: "";
|
|
114
118
|
// Start function definition
|
|
115
|
-
let result = this.indentStr(`def ${functionName}(${params}) {\n`);
|
|
119
|
+
let result = this.indentStr(`def ${functionName}(${params})${returnTypeStr} {\n`);
|
|
116
120
|
// Process body with increased indentation
|
|
117
121
|
this.increaseIndent();
|
|
118
122
|
if (node.docString) {
|
|
@@ -233,7 +237,10 @@ export class AgencyGenerator extends BaseGenerator {
|
|
|
233
237
|
// Graph nodes use similar syntax to functions
|
|
234
238
|
const { nodeName, body, parameters } = node;
|
|
235
239
|
const params = parameters.join(", ");
|
|
236
|
-
|
|
240
|
+
const returnTypeStr = node.returnType
|
|
241
|
+
? ": " + variableTypeToString(node.returnType, this.typeAliases)
|
|
242
|
+
: "";
|
|
243
|
+
let result = this.indentStr(`node ${nodeName}(${params})${returnTypeStr} {\n`);
|
|
237
244
|
this.increaseIndent();
|
|
238
245
|
this.functionScopedVariables = [...parameters];
|
|
239
246
|
const lines = [];
|
|
@@ -244,7 +251,7 @@ export class AgencyGenerator extends BaseGenerator {
|
|
|
244
251
|
result += bodyCode;
|
|
245
252
|
this.functionScopedVariables = [];
|
|
246
253
|
this.decreaseIndent();
|
|
247
|
-
result += this.indentStr(`}\n`);
|
|
254
|
+
result += this.indentStr(`}\n\n`);
|
|
248
255
|
return result;
|
|
249
256
|
}
|
|
250
257
|
processTool(node) {
|
|
@@ -11,10 +11,11 @@ import { UsesTool } from "../types/tools.js";
|
|
|
11
11
|
import { WhileLoop } from "../types/whileLoop.js";
|
|
12
12
|
export declare class BaseGenerator {
|
|
13
13
|
protected typeHints: TypeHintMap;
|
|
14
|
-
protected graphNodes:
|
|
14
|
+
protected graphNodes: GraphNodeDefinition[];
|
|
15
15
|
protected generatedStatements: string[];
|
|
16
16
|
protected generatedTypeAliases: string[];
|
|
17
17
|
protected functionScopedVariables: string[];
|
|
18
|
+
protected globalScopedVariables: string[];
|
|
18
19
|
protected toolsUsed: string[];
|
|
19
20
|
protected typeAliases: Record<string, VariableType>;
|
|
20
21
|
protected functionsUsed: Set<string>;
|
|
@@ -4,6 +4,7 @@ export class BaseGenerator {
|
|
|
4
4
|
generatedStatements = [];
|
|
5
5
|
generatedTypeAliases = [];
|
|
6
6
|
functionScopedVariables = [];
|
|
7
|
+
globalScopedVariables = [];
|
|
7
8
|
// collect tools for a prompt
|
|
8
9
|
toolsUsed = [];
|
|
9
10
|
typeAliases = {};
|
|
@@ -39,7 +40,13 @@ export class BaseGenerator {
|
|
|
39
40
|
this.collectFunctionSignature(node);
|
|
40
41
|
}
|
|
41
42
|
}
|
|
42
|
-
// Pass 5:
|
|
43
|
+
// Pass 5: Collect global scoped variables
|
|
44
|
+
for (const node of program.nodes) {
|
|
45
|
+
if (node.type === "assignment") {
|
|
46
|
+
this.globalScopedVariables.push(node.variableName);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
// Pass 6: Process all nodes and generate code
|
|
43
50
|
for (const node of program.nodes) {
|
|
44
51
|
const result = this.processNode(node);
|
|
45
52
|
this.generatedStatements.push(result);
|
|
@@ -91,6 +98,7 @@ export class BaseGenerator {
|
|
|
91
98
|
case "matchBlock":
|
|
92
99
|
return this.processMatchBlock(node);
|
|
93
100
|
case "number":
|
|
101
|
+
case "multiLineString":
|
|
94
102
|
case "string":
|
|
95
103
|
case "variableName":
|
|
96
104
|
case "prompt":
|
|
@@ -7,6 +7,7 @@ import * as renderStartNode from "../templates/backends/graphGenerator/startNode
|
|
|
7
7
|
import * as renderRunNodeFunction from "../templates/backends/graphGenerator/runNodeFunction.js";
|
|
8
8
|
import { TypeScriptGenerator } from "./typescriptGenerator.js";
|
|
9
9
|
import { mapFunctionName } from "./typescriptGenerator/builtins.js";
|
|
10
|
+
import { variableTypeToString } from "./typescriptGenerator/typeToString.js";
|
|
10
11
|
export class GraphGenerator extends TypeScriptGenerator {
|
|
11
12
|
typeHints = {};
|
|
12
13
|
generatedStatements = [];
|
|
@@ -203,7 +204,7 @@ export class GraphGenerator extends TypeScriptGenerator {
|
|
|
203
204
|
else {
|
|
204
205
|
const returnCode = this.processNode(node.value);
|
|
205
206
|
if (node.value.type === "functionCall" &&
|
|
206
|
-
this.graphNodes.includes(node.value.functionName)) {
|
|
207
|
+
this.graphNodes.map((n) => n.nodeName).includes(node.value.functionName)) {
|
|
207
208
|
// we're going to return a goToNode call, so just return that directly
|
|
208
209
|
return `return ${returnCode}\n`;
|
|
209
210
|
}
|
|
@@ -211,7 +212,7 @@ export class GraphGenerator extends TypeScriptGenerator {
|
|
|
211
212
|
}
|
|
212
213
|
}
|
|
213
214
|
processGraphNodeName(node) {
|
|
214
|
-
this.graphNodes.push(node
|
|
215
|
+
this.graphNodes.push(node);
|
|
215
216
|
}
|
|
216
217
|
processGraphNode(node) {
|
|
217
218
|
const { nodeName, body, parameters } = node;
|
|
@@ -234,13 +235,16 @@ export class GraphGenerator extends TypeScriptGenerator {
|
|
|
234
235
|
this.isInsideGraphNode = false;
|
|
235
236
|
return graphNode.default({
|
|
236
237
|
name: nodeName,
|
|
238
|
+
/* returnType: node.returnType
|
|
239
|
+
? variableTypeToString(node.returnType, this.typeAliases)
|
|
240
|
+
: "any", */
|
|
237
241
|
body: bodyCode.join("\n"),
|
|
238
242
|
hasParam: parameters.length > 0,
|
|
239
243
|
paramName: parameters[0] || "input",
|
|
240
244
|
});
|
|
241
245
|
}
|
|
242
246
|
processFunctionCall(node) {
|
|
243
|
-
if (this.graphNodes.includes(node.functionName)) {
|
|
247
|
+
if (this.graphNodes.map((n) => n.nodeName).includes(node.functionName)) {
|
|
244
248
|
this.currentAdjacentNodes.push(node.functionName);
|
|
245
249
|
this.functionsUsed.add(node.functionName);
|
|
246
250
|
const functionCallCode = this.generateNodeCallExpression(node);
|
|
@@ -258,10 +262,11 @@ export class GraphGenerator extends TypeScriptGenerator {
|
|
|
258
262
|
this.functionsUsed.add(arg.functionName);
|
|
259
263
|
return this.generateFunctionCallExpression(arg);
|
|
260
264
|
/* } else if (arg.type === "accessExpression") {
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
+
return this.processAccessExpression(arg);
|
|
266
|
+
} else if (arg.type === "indexAccess") {
|
|
267
|
+
return this.processIndexAccess(arg);
|
|
268
|
+
*/
|
|
269
|
+
}
|
|
265
270
|
else {
|
|
266
271
|
return this.processNode(arg);
|
|
267
272
|
// return this.generateLiteral(arg);
|
|
@@ -279,7 +284,9 @@ export class GraphGenerator extends TypeScriptGenerator {
|
|
|
279
284
|
} */
|
|
280
285
|
generateImports() {
|
|
281
286
|
let arr = [
|
|
282
|
-
renderImports.default({
|
|
287
|
+
renderImports.default({
|
|
288
|
+
nodes: JSON.stringify(this.graphNodes.map((n) => n.nodeName)),
|
|
289
|
+
}),
|
|
283
290
|
];
|
|
284
291
|
arr.push(builtinTools.default({}));
|
|
285
292
|
return arr.join("\n");
|
|
@@ -299,14 +306,17 @@ export class GraphGenerator extends TypeScriptGenerator {
|
|
|
299
306
|
toNodes: JSON.stringify(adjacent),
|
|
300
307
|
}));
|
|
301
308
|
});
|
|
302
|
-
if (this.graphNodes.includes("main")) {
|
|
309
|
+
if (this.graphNodes.map((n) => n.nodeName).includes("main")) {
|
|
303
310
|
lines.push(renderStartNode.default({
|
|
304
311
|
startNode: "main",
|
|
305
312
|
}));
|
|
306
313
|
}
|
|
307
314
|
for (const node of this.graphNodes) {
|
|
308
315
|
lines.push(renderRunNodeFunction.default({
|
|
309
|
-
nodeName: node,
|
|
316
|
+
nodeName: node.nodeName,
|
|
317
|
+
returnType: node.returnType
|
|
318
|
+
? variableTypeToString(node.returnType, this.typeAliases)
|
|
319
|
+
: "any",
|
|
310
320
|
}));
|
|
311
321
|
}
|
|
312
322
|
lines.push("export default graph;");
|
|
@@ -135,7 +135,8 @@ export class TypeScriptGenerator extends BaseGenerator {
|
|
|
135
135
|
.filter((s) => s.type === "interpolation")
|
|
136
136
|
.map((s) => s.variableName);
|
|
137
137
|
for (const varName of interpolatedVars) {
|
|
138
|
-
if (!this.functionScopedVariables.includes(varName)
|
|
138
|
+
if (!this.functionScopedVariables.includes(varName) &&
|
|
139
|
+
!this.globalScopedVariables.includes(varName)) {
|
|
139
140
|
throw new Error(`Variable '${varName}' used in prompt interpolation but not defined. ` +
|
|
140
141
|
`Referenced in assignment to '${variableName}'.`);
|
|
141
142
|
}
|
|
@@ -152,7 +153,7 @@ export class TypeScriptGenerator extends BaseGenerator {
|
|
|
152
153
|
}
|
|
153
154
|
processTool(node) {
|
|
154
155
|
const { functionName, body, parameters } = node;
|
|
155
|
-
if (this.graphNodes.includes(functionName)) {
|
|
156
|
+
if (this.graphNodes.map((n) => n.nodeName).includes(functionName)) {
|
|
156
157
|
throw new Error(`There is already a node named '${functionName}'. Functions can't have the same name as an existing node.`);
|
|
157
158
|
}
|
|
158
159
|
const properties = {};
|
|
@@ -193,6 +194,9 @@ export class TypeScriptGenerator extends BaseGenerator {
|
|
|
193
194
|
return renderFunctionDefinition.default({
|
|
194
195
|
functionName,
|
|
195
196
|
args: "{" + args + "}",
|
|
197
|
+
returnType: node.returnType
|
|
198
|
+
? variableTypeToString(node.returnType, this.typeAliases)
|
|
199
|
+
: "any",
|
|
196
200
|
functionBody: bodyCode.join("\n"),
|
|
197
201
|
});
|
|
198
202
|
}
|
|
@@ -220,10 +224,11 @@ export class TypeScriptGenerator extends BaseGenerator {
|
|
|
220
224
|
this.functionsUsed.add(arg.functionName);
|
|
221
225
|
return this.generateFunctionCallExpression(arg);
|
|
222
226
|
/* } else if (arg.type === "accessExpression") {
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
+
return this.processAccessExpression(arg);
|
|
228
|
+
} else if (arg.type === "indexAccess") {
|
|
229
|
+
return this.processIndexAccess(arg);
|
|
230
|
+
*/
|
|
231
|
+
}
|
|
227
232
|
else {
|
|
228
233
|
// return this.generateLiteral(arg);
|
|
229
234
|
return this.processNode(arg);
|
|
@@ -252,6 +257,8 @@ export class TypeScriptGenerator extends BaseGenerator {
|
|
|
252
257
|
return literal.value;
|
|
253
258
|
case "string":
|
|
254
259
|
return `"${escape(literal.value)}"`;
|
|
260
|
+
case "multiLineString":
|
|
261
|
+
return `\`${escape(literal.value)}\``;
|
|
255
262
|
case "variableName":
|
|
256
263
|
return literal.value;
|
|
257
264
|
case "prompt":
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AgencyNode, DocString, FunctionDefinition, FunctionParameter } from "../types.js";
|
|
1
|
+
import { AgencyNode, DocString, FunctionDefinition, FunctionParameter, VariableType } from "../types.js";
|
|
2
2
|
import { Parser } from "tarsec";
|
|
3
3
|
import { GraphNodeDefinition } from "../types/graphNode.js";
|
|
4
4
|
import { WhileLoop } from "../types/whileLoop.js";
|
|
@@ -7,5 +7,6 @@ export declare const bodyParser: Parser<AgencyNode[]>;
|
|
|
7
7
|
export declare const whileLoopParser: Parser<WhileLoop>;
|
|
8
8
|
export declare const functionParameterParserWithTypeHint: Parser<FunctionParameter>;
|
|
9
9
|
export declare const functionParameterParser: Parser<FunctionParameter>;
|
|
10
|
+
export declare const functionReturnTypeParser: Parser<VariableType>;
|
|
10
11
|
export declare const functionParser: Parser<FunctionDefinition>;
|
|
11
12
|
export declare const graphNodeParser: Parser<GraphNodeDefinition>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { capture, char, debug, many1, many1Till, many1WithJoin, map, or, sepBy, seqC, set, space, spaces, str, succeed, trace, } from "tarsec";
|
|
1
|
+
import { capture, captureCaptures, char, debug, many1, many1Till, many1WithJoin, map, optional, or, sepBy, seqC, set, space, spaces, str, succeed, trace, } from "tarsec";
|
|
2
2
|
import { accessExpressionParser, indexAccessParser } from "./access.js";
|
|
3
3
|
import { assignmentParser } from "./assignment.js";
|
|
4
4
|
import { commentParser } from "./comment.js";
|
|
@@ -21,5 +21,6 @@ export const bodyParser = trace("functionBodyParser", (input) => {
|
|
|
21
21
|
export const whileLoopParser = trace("whileLoopParser", seqC(set("type", "whileLoop"), str("while"), optionalSpaces, char("("), optionalSpaces, capture(or(indexAccessParser, functionCallParser, accessExpressionParser, literalParser), "condition"), optionalSpaces, char(")"), optionalSpaces, char("{"), spaces, capture(bodyParser, "body"), optionalSpaces, char("}")));
|
|
22
22
|
export const functionParameterParserWithTypeHint = trace("functionParameterParserWithTypeHint", seqC(set("type", "functionParameter"), capture(many1WithJoin(varNameChar), "name"), optionalSpaces, char(":"), optionalSpaces, capture(variableTypeParser, "typeHint")));
|
|
23
23
|
export const functionParameterParser = trace("functionParameterParser", seqC(set("type", "functionParameter"), capture(many1WithJoin(varNameChar), "name")));
|
|
24
|
-
export const
|
|
25
|
-
export const
|
|
24
|
+
export const functionReturnTypeParser = trace("functionReturnTypeParser", seqC(char(":"), optionalSpaces, captureCaptures(variableTypeParser)));
|
|
25
|
+
export const functionParser = trace("functionParser", seqC(set("type", "function"), str("def"), many1(space), capture(many1Till(char("(")), "functionName"), char("("), optionalSpaces, capture(sepBy(comma, or(functionParameterParserWithTypeHint, functionParameterParser)), "parameters"), optionalSpaces, char(")"), optionalSpaces, capture(optional(functionReturnTypeParser), "returnType"), optionalSpaces, char("{"), optionalSpaces, capture(or(docStringParser, succeed(undefined)), "docString"), optionalSpaces, capture(bodyParser, "body"), optionalSpaces, char("}"), optionalSemicolon));
|
|
26
|
+
export const graphNodeParser = trace("graphNodeParser", seqC(set("type", "graphNode"), str("node"), many1(space), capture(many1Till(char("(")), "nodeName"), char("("), optionalSpaces, capture(or(sepBy(comma, many1WithJoin(varNameChar)), succeed([])), "parameters"), optionalSpaces, char(")"), optionalSpaces, capture(optional(functionReturnTypeParser), "returnType"), optionalSpaces, char("{"), optionalSpaces, capture(bodyParser, "body"), optionalSpaces, char("}"), optionalSemicolon));
|