agency-lang 0.0.48 → 0.0.50
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 +0 -1
- package/dist/lib/backends/agencyGenerator.js +16 -23
- package/dist/lib/backends/baseGenerator.d.ts +12 -1
- package/dist/lib/backends/baseGenerator.js +4 -4
- package/dist/lib/backends/graphGenerator.js +1 -1
- package/dist/lib/backends/typescriptGenerator.d.ts +1 -0
- package/dist/lib/backends/typescriptGenerator.js +41 -52
- package/dist/lib/parser.js +2 -2
- package/dist/lib/parsers/await.js +3 -3
- package/dist/lib/parsers/function.d.ts +2 -0
- package/dist/lib/parsers/function.js +9 -4
- package/dist/lib/parsers/functionCall.d.ts +4 -1
- package/dist/lib/parsers/functionCall.js +58 -2
- package/dist/lib/parsers/functionCall.test.js +363 -1
- package/dist/lib/parsers/literals.d.ts +1 -0
- package/dist/lib/parsers/literals.js +43 -13
- package/dist/lib/parsers/matchBlock.js +2 -2
- package/dist/lib/parsers/returnStatement.js +2 -2
- package/dist/lib/parsers/tools.js +3 -3
- package/dist/lib/parsers/tools.test.js +125 -19
- package/dist/lib/parsers/utils.d.ts +1 -0
- package/dist/lib/parsers/utils.js +1 -0
- package/dist/lib/templates/backends/graphGenerator/goToNode.d.ts +1 -1
- package/dist/lib/templates/backends/graphGenerator/goToNode.js +1 -0
- package/dist/lib/templates/backends/graphGenerator/graphNode.d.ts +1 -1
- package/dist/lib/templates/backends/graphGenerator/graphNode.js +5 -1
- package/dist/lib/templates/backends/graphGenerator/imports.d.ts +1 -1
- package/dist/lib/templates/backends/graphGenerator/imports.js +21 -6
- package/dist/lib/templates/backends/graphGenerator/runNodeFunction.d.ts +1 -1
- package/dist/lib/templates/backends/graphGenerator/runNodeFunction.js +3 -2
- package/dist/lib/templates/backends/typescriptGenerator/builtinFunctions/time.d.ts +2 -1
- package/dist/lib/templates/backends/typescriptGenerator/builtinFunctions/time.js +7 -3
- package/dist/lib/templates/backends/typescriptGenerator/functionCallAssignment.d.ts +2 -1
- package/dist/lib/templates/backends/typescriptGenerator/functionCallAssignment.js +4 -2
- package/dist/lib/templates/backends/typescriptGenerator/functionDefinition.d.ts +1 -1
- package/dist/lib/templates/backends/typescriptGenerator/functionDefinition.js +1 -1
- package/dist/lib/templates/backends/typescriptGenerator/internalFunctionCall.d.ts +2 -1
- package/dist/lib/templates/backends/typescriptGenerator/internalFunctionCall.js +1 -1
- package/dist/lib/templates/backends/typescriptGenerator/promptFunction.d.ts +2 -1
- package/dist/lib/templates/backends/typescriptGenerator/promptFunction.js +106 -1
- package/dist/lib/types/function.d.ts +1 -0
- package/dist/lib/types/literals.d.ts +1 -0
- package/dist/lib/types/specialVar.d.ts +1 -1
- package/dist/lib/types/specialVar.js +1 -1
- package/dist/lib/types/timeBlock.d.ts +1 -0
- package/dist/lib/types/tools.d.ts +1 -1
- package/package.json +4 -3
|
@@ -31,7 +31,6 @@ export declare class AgencyGenerator extends BaseGenerator {
|
|
|
31
31
|
protected processTimeBlock(node: TimeBlock): string;
|
|
32
32
|
protected generateLiteral(literal: Literal): string;
|
|
33
33
|
private generatePromptLiteral;
|
|
34
|
-
private renderObjectLiteral;
|
|
35
34
|
private generateStringLiteral;
|
|
36
35
|
private generateMultiLineStringLiteral;
|
|
37
36
|
protected processPromptLiteral(variableName: string, variableType: VariableType | undefined, node: PromptLiteral): string;
|
|
@@ -75,7 +75,8 @@ export class AgencyGenerator extends BaseGenerator {
|
|
|
75
75
|
}
|
|
76
76
|
this.decreaseIndent();
|
|
77
77
|
const bodyCodeStr = bodyCodes.join("");
|
|
78
|
-
|
|
78
|
+
const timeBlockName = node.printTime ? "printTime" : "time";
|
|
79
|
+
return this.indentStr(`${timeBlockName} {\n${bodyCodeStr}${this.indentStr("}")}`);
|
|
79
80
|
}
|
|
80
81
|
generateLiteral(literal) {
|
|
81
82
|
switch (literal.type) {
|
|
@@ -94,7 +95,11 @@ export class AgencyGenerator extends BaseGenerator {
|
|
|
94
95
|
}
|
|
95
96
|
}
|
|
96
97
|
generatePromptLiteral(node) {
|
|
97
|
-
let result =
|
|
98
|
+
let result = "";
|
|
99
|
+
if (node.isStreaming) {
|
|
100
|
+
result += "stream ";
|
|
101
|
+
}
|
|
102
|
+
result += 'llm("';
|
|
98
103
|
for (const segment of node.segments) {
|
|
99
104
|
if (segment.type === "text") {
|
|
100
105
|
result += segment.value;
|
|
@@ -104,27 +109,14 @@ export class AgencyGenerator extends BaseGenerator {
|
|
|
104
109
|
}
|
|
105
110
|
}
|
|
106
111
|
if (node.config) {
|
|
107
|
-
|
|
112
|
+
const objCode = this.processAgencyObject(node.config);
|
|
113
|
+
result += `", ${objCode})`;
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
result += `")`;
|
|
108
117
|
}
|
|
109
|
-
result += `")`;
|
|
110
118
|
return result;
|
|
111
119
|
}
|
|
112
|
-
renderObjectLiteral(obj) {
|
|
113
|
-
const entries = Object.entries(obj).map(([key, value]) => {
|
|
114
|
-
let valueStr;
|
|
115
|
-
if (typeof value === "string") {
|
|
116
|
-
valueStr = `"${value}"`;
|
|
117
|
-
}
|
|
118
|
-
else if (typeof value === "object") {
|
|
119
|
-
valueStr = this.renderObjectLiteral(value);
|
|
120
|
-
}
|
|
121
|
-
else {
|
|
122
|
-
valueStr = String(value);
|
|
123
|
-
}
|
|
124
|
-
return `${key}: ${valueStr}`;
|
|
125
|
-
});
|
|
126
|
-
return `{ ${entries.join(", ")} }`;
|
|
127
|
-
}
|
|
128
120
|
generateStringLiteral(node) {
|
|
129
121
|
let result = '"';
|
|
130
122
|
for (const segment of node.segments) {
|
|
@@ -205,7 +197,8 @@ export class AgencyGenerator extends BaseGenerator {
|
|
|
205
197
|
const args = node.arguments.map((arg) => {
|
|
206
198
|
return this.processNode(arg).trim();
|
|
207
199
|
});
|
|
208
|
-
|
|
200
|
+
const asyncPrefix = node.async ? "async " : "";
|
|
201
|
+
return `${asyncPrefix}${node.functionName}(${args.join(", ")})`;
|
|
209
202
|
}
|
|
210
203
|
// Data structures
|
|
211
204
|
processAgencyArray(node) {
|
|
@@ -361,8 +354,8 @@ export class AgencyGenerator extends BaseGenerator {
|
|
|
361
354
|
}
|
|
362
355
|
processUsesTool(node) {
|
|
363
356
|
// Track tool usage but don't generate code
|
|
364
|
-
this.toolsUsed.push(node.
|
|
365
|
-
return this.indentStr(
|
|
357
|
+
this.toolsUsed.push(...node.toolNames);
|
|
358
|
+
return this.indentStr(`uses ${node.toolNames.join(", ")}`);
|
|
366
359
|
}
|
|
367
360
|
processSpecialVar(node) {
|
|
368
361
|
return this.indentStr(`@${node.name} = ${this.processNode(node.value).trim()}`);
|
|
@@ -12,7 +12,18 @@ 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
|
-
type Scope =
|
|
15
|
+
type Scope = GlobalScope | FunctionScope | NodeScope;
|
|
16
|
+
type GlobalScope = {
|
|
17
|
+
type: "global";
|
|
18
|
+
};
|
|
19
|
+
type FunctionScope = {
|
|
20
|
+
type: "function";
|
|
21
|
+
functionName: string;
|
|
22
|
+
};
|
|
23
|
+
type NodeScope = {
|
|
24
|
+
type: "node";
|
|
25
|
+
nodeName: string;
|
|
26
|
+
};
|
|
16
27
|
export declare class BaseGenerator {
|
|
17
28
|
protected typeHints: TypeHintMap;
|
|
18
29
|
protected graphNodes: GraphNodeDefinition[];
|
|
@@ -17,7 +17,7 @@ export class BaseGenerator {
|
|
|
17
17
|
// collect function signatures so we can implement named args
|
|
18
18
|
// TODO also save return types, check if used as a tool, return type cannot be null/void/undefined
|
|
19
19
|
functionDefinitions = {};
|
|
20
|
-
currentScope = ["global"];
|
|
20
|
+
currentScope = [{ type: "global" }];
|
|
21
21
|
generate(program) {
|
|
22
22
|
// Pass 1: Collect all type aliases
|
|
23
23
|
for (const node of program.nodes) {
|
|
@@ -149,7 +149,7 @@ export class BaseGenerator {
|
|
|
149
149
|
case "indexAccess":
|
|
150
150
|
return this.processIndexAccess(node);
|
|
151
151
|
case "timeBlock":
|
|
152
|
-
|
|
152
|
+
return this.processTimeBlock(node, `__defaultTimeblockName`);
|
|
153
153
|
case "awaitStatement":
|
|
154
154
|
return this.processAwaitStatement(node);
|
|
155
155
|
case "newLine":
|
|
@@ -268,8 +268,8 @@ export class BaseGenerator {
|
|
|
268
268
|
should be assigned on local or global scope. There's a related function `generateScopedVariableName`,
|
|
269
269
|
which is used when retrieving the value of a variable. */
|
|
270
270
|
getScopeVar() {
|
|
271
|
-
const currentScope = this.
|
|
272
|
-
switch (currentScope) {
|
|
271
|
+
const currentScope = this.getCurrentScope();
|
|
272
|
+
switch (currentScope.type) {
|
|
273
273
|
case "global":
|
|
274
274
|
return "__stateStack.globals";
|
|
275
275
|
case "function":
|
|
@@ -39,7 +39,7 @@ export class GraphGenerator extends TypeScriptGenerator {
|
|
|
39
39
|
this.graphNodes.push(node);
|
|
40
40
|
}
|
|
41
41
|
processGraphNode(node) {
|
|
42
|
-
this.startScope("node");
|
|
42
|
+
this.startScope({ type: "node", nodeName: node.nodeName });
|
|
43
43
|
const { nodeName, body, parameters } = node;
|
|
44
44
|
/* if (parameters.length > 1) {
|
|
45
45
|
throw new Error(
|
|
@@ -44,6 +44,7 @@ export declare class TypeScriptGenerator extends BaseGenerator {
|
|
|
44
44
|
*/
|
|
45
45
|
protected generateFunctionCallExpression(node: FunctionCall): string;
|
|
46
46
|
protected generateLiteral(literal: Literal): string;
|
|
47
|
+
protected getScopeReturnType(): VariableType | undefined;
|
|
47
48
|
protected generateImports(): string;
|
|
48
49
|
buildPromptString(segments: PromptSegment[], typeHints: TypeHintMap): string;
|
|
49
50
|
generateStringLiteral(segments: PromptSegment[]): string;
|
|
@@ -14,6 +14,7 @@ import { BaseGenerator } from "./baseGenerator.js";
|
|
|
14
14
|
import { generateBuiltinHelpers, mapFunctionName, } from "./typescriptGenerator/builtins.js";
|
|
15
15
|
import { variableTypeToString } from "./typescriptGenerator/typeToString.js";
|
|
16
16
|
import { DEFAULT_SCHEMA, mapTypeToZodSchema, } from "./typescriptGenerator/typeToZodSchema.js";
|
|
17
|
+
const DEFAULT_PROMPT_NAME = "__promptVar";
|
|
17
18
|
export class TypeScriptGenerator extends BaseGenerator {
|
|
18
19
|
constructor() {
|
|
19
20
|
super();
|
|
@@ -69,6 +70,9 @@ export class TypeScriptGenerator extends BaseGenerator {
|
|
|
69
70
|
interrupt. */
|
|
70
71
|
return `__stack.step++;\nreturn ${returnCode}\n`;
|
|
71
72
|
}
|
|
73
|
+
else if (node.value.type === "prompt") {
|
|
74
|
+
return `${returnCode}\n__stateStack.pop();\nreturn __self.${DEFAULT_PROMPT_NAME};\n`;
|
|
75
|
+
}
|
|
72
76
|
/* Pop the state off the stack, we won't be coming back.
|
|
73
77
|
Doesn't matter if we update the step or not, since we won't be coming back here. */
|
|
74
78
|
return `__stateStack.pop();\nreturn ${returnCode}\n`;
|
|
@@ -124,7 +128,7 @@ export class TypeScriptGenerator extends BaseGenerator {
|
|
|
124
128
|
processAssignment(node) {
|
|
125
129
|
const { variableName, typeHint, value } = node;
|
|
126
130
|
const _currentScope = this.getCurrentScope();
|
|
127
|
-
if (_currentScope === "global") {
|
|
131
|
+
if (_currentScope.type === "global") {
|
|
128
132
|
this.globalScopedVariables.push(variableName);
|
|
129
133
|
}
|
|
130
134
|
else {
|
|
@@ -137,43 +141,14 @@ export class TypeScriptGenerator extends BaseGenerator {
|
|
|
137
141
|
return this.processPromptLiteral(variableName, typeHint, value);
|
|
138
142
|
}
|
|
139
143
|
else if (value.type === "functionCall") {
|
|
140
|
-
if (value.functionName === "llm") {
|
|
141
|
-
const args = value.arguments;
|
|
142
|
-
if (args.length === 0) {
|
|
143
|
-
throw new Error(`llm function call must have at least one argument for the prompt.`);
|
|
144
|
-
}
|
|
145
|
-
const promptArg = args[0];
|
|
146
|
-
const promptArgIsPrompt = promptArg.type === "prompt" ||
|
|
147
|
-
promptArg.type === "string" ||
|
|
148
|
-
promptArg.type === "multiLineString" ||
|
|
149
|
-
promptArg.type === "variableName"; // if variable name, assume its a string
|
|
150
|
-
if (!promptArgIsPrompt) {
|
|
151
|
-
throw new Error(`First argument to llm function must be a prompt literal.`);
|
|
152
|
-
}
|
|
153
|
-
const promptConfig = args[1];
|
|
154
|
-
if (promptConfig && promptConfig.type !== "agencyObject") {
|
|
155
|
-
throw new Error(`Second argument to llm function must be an object literal for configuration.`);
|
|
156
|
-
}
|
|
157
|
-
return this.processPromptLiteral(variableName, typeHint, {
|
|
158
|
-
type: "prompt",
|
|
159
|
-
segments: promptArg.type === "variableName"
|
|
160
|
-
? [
|
|
161
|
-
{
|
|
162
|
-
type: "interpolation",
|
|
163
|
-
variableName: promptArg.value,
|
|
164
|
-
},
|
|
165
|
-
]
|
|
166
|
-
: promptArg.segments,
|
|
167
|
-
config: promptConfig,
|
|
168
|
-
});
|
|
169
|
-
}
|
|
170
144
|
// Direct assignment for other literal types
|
|
171
145
|
const code = this.processNode(value);
|
|
172
146
|
return renderFunctionCallAssignment.default({
|
|
173
147
|
variableName: `${this.getScopeVar()}.${variableName}`,
|
|
174
148
|
typeAnnotation,
|
|
175
149
|
functionCode: code.trim(),
|
|
176
|
-
nodeContext: this.getCurrentScope() === "node",
|
|
150
|
+
nodeContext: this.getCurrentScope().type === "node",
|
|
151
|
+
globalScope: this.getCurrentScope().type === "global",
|
|
177
152
|
});
|
|
178
153
|
}
|
|
179
154
|
else if (value.type === "timeBlock") {
|
|
@@ -214,13 +189,7 @@ export class TypeScriptGenerator extends BaseGenerator {
|
|
|
214
189
|
functionArgs: interpolatedVars,
|
|
215
190
|
prompt: node,
|
|
216
191
|
});
|
|
217
|
-
|
|
218
|
-
//const argsStr = [...interpolatedVars, "__messages"].join(", ");
|
|
219
|
-
// Generate the function call
|
|
220
|
-
return functionCode; /* (
|
|
221
|
-
`${functionCode}\nconst __self.${variableName} = await _${variableName}(${argsStr});` +
|
|
222
|
-
"\n"
|
|
223
|
-
); */
|
|
192
|
+
return functionCode;
|
|
224
193
|
}
|
|
225
194
|
processTool(node) {
|
|
226
195
|
const { functionName, body, parameters } = node;
|
|
@@ -247,18 +216,19 @@ export class TypeScriptGenerator extends BaseGenerator {
|
|
|
247
216
|
});
|
|
248
217
|
}
|
|
249
218
|
processUsesTool(node) {
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
219
|
+
node.toolNames.forEach((toolName) => {
|
|
220
|
+
if (!this.functionDefinitions[toolName]) {
|
|
221
|
+
throw new Error(`Tool '${toolName}' is being used but no function definition found for it. Make sure to define a function for this tool.`);
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
this.toolsUsed.push(...node.toolNames);
|
|
255
225
|
return "";
|
|
256
226
|
}
|
|
257
227
|
/**
|
|
258
228
|
* Process a function definition node
|
|
259
229
|
*/
|
|
260
230
|
processFunctionDefinition(node) {
|
|
261
|
-
this.startScope("function");
|
|
231
|
+
this.startScope({ type: "function", functionName: node.functionName });
|
|
262
232
|
const { functionName, body, parameters } = node;
|
|
263
233
|
const args = parameters.map((p) => p.name);
|
|
264
234
|
this.functionScopedVariables = [...parameters.map((p) => p.name)];
|
|
@@ -329,6 +299,7 @@ export class TypeScriptGenerator extends BaseGenerator {
|
|
|
329
299
|
functionName,
|
|
330
300
|
argsString,
|
|
331
301
|
metadata,
|
|
302
|
+
awaitPrefix: node.async ? "" : "await ",
|
|
332
303
|
});
|
|
333
304
|
}
|
|
334
305
|
else {
|
|
@@ -348,12 +319,26 @@ export class TypeScriptGenerator extends BaseGenerator {
|
|
|
348
319
|
case "variableName":
|
|
349
320
|
return this.generateScopedVariableName(literal.value);
|
|
350
321
|
case "prompt":
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
322
|
+
return this.processPromptLiteral(DEFAULT_PROMPT_NAME, this.getScopeReturnType(), literal);
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
getScopeReturnType() {
|
|
326
|
+
const currentScope = this.getCurrentScope();
|
|
327
|
+
switch (currentScope.type) {
|
|
328
|
+
case "global":
|
|
329
|
+
return undefined;
|
|
330
|
+
case "function":
|
|
331
|
+
const funcDef = this.functionDefinitions[currentScope.functionName];
|
|
332
|
+
if (funcDef && funcDef.returnType) {
|
|
333
|
+
return funcDef.returnType;
|
|
334
|
+
}
|
|
335
|
+
return undefined;
|
|
336
|
+
case "node":
|
|
337
|
+
const graphNode = this.graphNodes.find((n) => n.nodeName === currentScope.nodeName);
|
|
338
|
+
if (graphNode && graphNode.returnType) {
|
|
339
|
+
return graphNode.returnType;
|
|
340
|
+
}
|
|
341
|
+
return undefined;
|
|
357
342
|
}
|
|
358
343
|
}
|
|
359
344
|
generateImports() {
|
|
@@ -453,7 +438,8 @@ export class TypeScriptGenerator extends BaseGenerator {
|
|
|
453
438
|
tools,
|
|
454
439
|
functionCalls,
|
|
455
440
|
clientConfig,
|
|
456
|
-
nodeContext: this.getCurrentScope() === "node",
|
|
441
|
+
nodeContext: this.getCurrentScope().type === "node",
|
|
442
|
+
isStreaming: prompt.isStreaming || false,
|
|
457
443
|
});
|
|
458
444
|
}
|
|
459
445
|
processImportStatement(node) {
|
|
@@ -503,6 +489,8 @@ export class TypeScriptGenerator extends BaseGenerator {
|
|
|
503
489
|
name: "model",
|
|
504
490
|
value,
|
|
505
491
|
});
|
|
492
|
+
case "messages":
|
|
493
|
+
return `__messages = ${value};\n`;
|
|
506
494
|
default:
|
|
507
495
|
throw new Error(`Unhandled SpecialVar name: ${node.name}`);
|
|
508
496
|
}
|
|
@@ -516,6 +504,7 @@ export class TypeScriptGenerator extends BaseGenerator {
|
|
|
516
504
|
return renderTime.default({
|
|
517
505
|
timingVarName,
|
|
518
506
|
bodyCodeStr,
|
|
507
|
+
printTime: node.printTime || false,
|
|
519
508
|
});
|
|
520
509
|
}
|
|
521
510
|
processAwaitStatement(node) {
|
package/dist/lib/parser.js
CHANGED
|
@@ -3,7 +3,7 @@ import { anyChar, between, capture, eof, many, or, search, seqC, set, str, succe
|
|
|
3
3
|
import { accessExpressionParser } from "./parsers/access.js";
|
|
4
4
|
import { commentParser } from "./parsers/comment.js";
|
|
5
5
|
import { assignmentParser, functionParser, graphNodeParser, ifParser, timeBlockParser, whileLoopParser, } from "./parsers/function.js";
|
|
6
|
-
import { functionCallParser } from "./parsers/functionCall.js";
|
|
6
|
+
import { functionCallParser, llmPromptFunctionCallParser, streamingPromptLiteralParser, } from "./parsers/functionCall.js";
|
|
7
7
|
import { importNodeStatmentParser, importStatmentParser, importToolStatmentParser, } from "./parsers/importStatement.js";
|
|
8
8
|
import { matchBlockParser } from "./parsers/matchBlock.js";
|
|
9
9
|
import { returnStatementParser } from "./parsers/returnStatement.js";
|
|
@@ -13,7 +13,7 @@ import { specialVarParser } from "./parsers/specialVar.js";
|
|
|
13
13
|
import { awaitParser } from "./parsers/await.js";
|
|
14
14
|
import { newLineParser } from "./parsers/newline.js";
|
|
15
15
|
export const agencyNode = (input) => {
|
|
16
|
-
const parser = many(trace("agencyParser", or(usesToolParser, importNodeStatmentParser, importToolStatmentParser, importStatmentParser, graphNodeParser, typeAliasParser, ifParser, whileLoopParser, typeHintParser, matchBlockParser, timeBlockParser, awaitParser, functionParser, returnStatementParser, specialVarParser, accessExpressionParser, assignmentParser, functionCallParser, commentParser, newLineParser)));
|
|
16
|
+
const parser = many(trace("agencyParser", or(usesToolParser, importNodeStatmentParser, importToolStatmentParser, importStatmentParser, graphNodeParser, typeAliasParser, ifParser, whileLoopParser, typeHintParser, matchBlockParser, timeBlockParser, awaitParser, streamingPromptLiteralParser, functionParser, returnStatementParser, specialVarParser, accessExpressionParser, assignmentParser, llmPromptFunctionCallParser, functionCallParser, commentParser, newLineParser)));
|
|
17
17
|
return parser(input);
|
|
18
18
|
};
|
|
19
19
|
export const agencyParser = seqC(set("type", "agencyProgram"), capture(agencyNode, "nodes"), eof);
|
|
@@ -8,11 +8,11 @@ export const usesToolParser: Parser<UsesTool> = seqC(
|
|
|
8
8
|
capture(many1WithJoin(varNameChar), "toolName")
|
|
9
9
|
);
|
|
10
10
|
*/
|
|
11
|
-
import { capture, or, seqC, set, spaces, str } from "tarsec";
|
|
11
|
+
import { capture, or, seqC, set, spaces, str, } from "tarsec";
|
|
12
12
|
import { accessExpressionParser } from "./access.js";
|
|
13
|
-
import { functionCallParser } from "./functionCall.js";
|
|
13
|
+
import { functionCallParser, llmPromptFunctionCallParser, } from "./functionCall.js";
|
|
14
14
|
import { literalParser } from "./literals.js";
|
|
15
15
|
export const awaitParser = (input) => {
|
|
16
|
-
const parser = seqC(set("type", "awaitStatement"), str("await"), spaces, capture(or(accessExpressionParser, functionCallParser, literalParser), "expression"));
|
|
16
|
+
const parser = seqC(set("type", "awaitStatement"), str("await"), spaces, capture(or(accessExpressionParser, llmPromptFunctionCallParser, functionCallParser, literalParser), "expression"));
|
|
17
17
|
return parser(input);
|
|
18
18
|
};
|
|
@@ -7,6 +7,8 @@ import { IfElse } from "../types/ifElse.js";
|
|
|
7
7
|
export declare const assignmentParser: Parser<Assignment>;
|
|
8
8
|
export declare const docStringParser: Parser<DocString>;
|
|
9
9
|
export declare const bodyParser: (input: string) => ParserResult<AgencyNode[]>;
|
|
10
|
+
export declare const _timeBlockParser: Parser<TimeBlock>;
|
|
11
|
+
export declare const printTimeBlockParser: Parser<TimeBlock>;
|
|
10
12
|
export declare const timeBlockParser: Parser<TimeBlock>;
|
|
11
13
|
export declare const ifParser: Parser<IfElse>;
|
|
12
14
|
export declare const whileLoopParser: Parser<WhileLoop>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { capture, captureCaptures, char, debug, many, 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 { commentParser } from "./comment.js";
|
|
4
|
-
import { functionCallParser } from "./functionCall.js";
|
|
4
|
+
import { asyncFunctionCallParser, functionCallParser, llmPromptFunctionCallParser, streamingPromptLiteralParser, } from "./functionCall.js";
|
|
5
5
|
import { literalParser, promptParser } from "./literals.js";
|
|
6
6
|
import { matchBlockParser } from "./matchBlock.js";
|
|
7
7
|
import { optionalSemicolon } from "./parserUtils.js";
|
|
@@ -14,16 +14,21 @@ import { agencyArrayParser, agencyObjectParser } from "./dataStructures.js";
|
|
|
14
14
|
import { awaitParser } from "./await.js";
|
|
15
15
|
import { newLineParser } from "./newline.js";
|
|
16
16
|
export const assignmentParser = (input) => {
|
|
17
|
-
const parser = trace("assignmentParser", seqC(set("type", "assignment"), optionalSpaces, capture(many1WithJoin(varNameChar), "variableName"), optionalSpaces, optional(captureCaptures(seqC(char(":"), optionalSpaces, capture(variableTypeParser, "typeHint")))), optionalSpaces, char("="), optionalSpaces, capture(or(timeBlockParser, awaitParser, promptParser, functionCallParser, indexAccessParser, accessExpressionParser, agencyArrayParser, agencyObjectParser, literalParser), "value"), optionalSemicolon));
|
|
17
|
+
const parser = trace("assignmentParser", seqC(set("type", "assignment"), optionalSpaces, capture(many1WithJoin(varNameChar), "variableName"), optionalSpaces, optional(captureCaptures(seqC(char(":"), optionalSpaces, capture(variableTypeParser, "typeHint")))), optionalSpaces, char("="), optionalSpaces, capture(or(timeBlockParser, awaitParser, asyncFunctionCallParser, promptParser, streamingPromptLiteralParser, llmPromptFunctionCallParser, functionCallParser, indexAccessParser, accessExpressionParser, agencyArrayParser, agencyObjectParser, literalParser), "value"), optionalSemicolon));
|
|
18
18
|
return parser(input);
|
|
19
19
|
};
|
|
20
20
|
const trim = (s) => s.trim();
|
|
21
21
|
export const docStringParser = trace("docStringParser", seqC(set("type", "docString"), str('"""'), capture(map(many1Till(str('"""')), trim), "value"), str('"""')));
|
|
22
22
|
export const bodyParser = (input) => {
|
|
23
|
-
const parser = trace("functionBodyParser", many(or(usesToolParser, debug(typeAliasParser, "error in typeAliasParser"), debug(typeHintParser, "error in typeHintParser"), specialVarParser, returnStatementParser, whileLoopParser, matchBlockParser, awaitParser, ifParser, functionParser, accessExpressionParser, assignmentParser, functionCallParser, literalParser, commentParser, newLineParser)));
|
|
23
|
+
const parser = trace("functionBodyParser", many(or(usesToolParser, debug(typeAliasParser, "error in typeAliasParser"), debug(typeHintParser, "error in typeHintParser"), specialVarParser, returnStatementParser, whileLoopParser, matchBlockParser, awaitParser, asyncFunctionCallParser, streamingPromptLiteralParser, ifParser, timeBlockParser, functionParser, accessExpressionParser, assignmentParser, llmPromptFunctionCallParser, functionCallParser, literalParser, commentParser, newLineParser)));
|
|
24
24
|
return parser(input);
|
|
25
25
|
};
|
|
26
|
-
export const
|
|
26
|
+
export const _timeBlockParser = trace("timeBlockParser", seqC(set("type", "timeBlock"), str("time"), optionalSpaces, char("{"), spaces, capture(bodyParser, "body"), optionalSpacesOrNewline, char("}")));
|
|
27
|
+
export const printTimeBlockParser = trace("timeBlockParser", map(seqC(set("type", "timeBlock"), str("printTime"), optionalSpaces, char("{"), spaces, capture(bodyParser, "body"), optionalSpacesOrNewline, char("}")), (result) => ({
|
|
28
|
+
...result,
|
|
29
|
+
printTime: true,
|
|
30
|
+
})));
|
|
31
|
+
export const timeBlockParser = or(printTimeBlockParser, _timeBlockParser);
|
|
27
32
|
/* const elseClauseParser: Parser<AgencyNode[]> = seqC(
|
|
28
33
|
str("else"),
|
|
29
34
|
optionalSpaces,
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
-
import { FunctionCall } from "../types.js";
|
|
1
|
+
import { FunctionCall, PromptLiteral } from "../types.js";
|
|
2
2
|
import { Parser } from "tarsec";
|
|
3
3
|
export declare const functionCallParser: Parser<FunctionCall>;
|
|
4
|
+
export declare const asyncFunctionCallParser: Parser<FunctionCall>;
|
|
5
|
+
export declare const llmPromptFunctionCallParser: Parser<PromptLiteral>;
|
|
6
|
+
export declare const streamingPromptLiteralParser: Parser<PromptLiteral>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { capture, char, many1WithJoin, or, sepBy, seqC, set, } from "tarsec";
|
|
1
|
+
import { capture, char, failure, many1WithJoin, or, sepBy, seqC, set, spaces, str, success, } from "tarsec";
|
|
2
2
|
import { accessExpressionParser, indexAccessParser } from "./access.js";
|
|
3
|
-
import { literalParser } from "./literals.js";
|
|
3
|
+
import { literalParser, promptParser } from "./literals.js";
|
|
4
4
|
import { optionalSemicolon } from "./parserUtils.js";
|
|
5
5
|
import { comma, optionalSpaces, varNameChar } from "./utils.js";
|
|
6
6
|
import { agencyArrayParser, agencyObjectParser } from "./dataStructures.js";
|
|
@@ -8,3 +8,59 @@ export const functionCallParser = (input) => {
|
|
|
8
8
|
const parser = seqC(set("type", "functionCall"), capture(many1WithJoin(varNameChar), "functionName"), char("("), optionalSpaces, capture(sepBy(comma, or(agencyArrayParser, agencyObjectParser, indexAccessParser, functionCallParser, accessExpressionParser, literalParser)), "arguments"), optionalSpaces, char(")"), optionalSemicolon);
|
|
9
9
|
return parser(input);
|
|
10
10
|
};
|
|
11
|
+
export const asyncFunctionCallParser = (input) => {
|
|
12
|
+
const parser = seqC(str("async"), spaces, capture(functionCallParser, "functionCall"));
|
|
13
|
+
const result = parser(input);
|
|
14
|
+
if (!result.success) {
|
|
15
|
+
return result;
|
|
16
|
+
}
|
|
17
|
+
const { functionCall } = result.result;
|
|
18
|
+
return success({ ...functionCall, async: true }, result.rest);
|
|
19
|
+
};
|
|
20
|
+
export const llmPromptFunctionCallParser = (input) => {
|
|
21
|
+
const parser = functionCallParser;
|
|
22
|
+
const result = parser(input);
|
|
23
|
+
if (!result.success) {
|
|
24
|
+
return result;
|
|
25
|
+
}
|
|
26
|
+
const { functionName, arguments: args } = result.result;
|
|
27
|
+
if (functionName !== "llm") {
|
|
28
|
+
return failure(`Expected function name "llm", got "${functionName}"`, input);
|
|
29
|
+
}
|
|
30
|
+
if (args.length === 0) {
|
|
31
|
+
throw new Error(`llm function call must have at least one argument for the prompt.`);
|
|
32
|
+
}
|
|
33
|
+
const promptArg = args[0];
|
|
34
|
+
const promptArgIsPrompt = promptArg.type === "prompt" ||
|
|
35
|
+
promptArg.type === "string" ||
|
|
36
|
+
promptArg.type === "multiLineString" ||
|
|
37
|
+
promptArg.type === "variableName"; // if variable name, assume its a string
|
|
38
|
+
if (!promptArgIsPrompt) {
|
|
39
|
+
throw new Error(`First argument to llm function must be a prompt literal.`);
|
|
40
|
+
}
|
|
41
|
+
const promptConfig = args[1];
|
|
42
|
+
if (promptConfig && promptConfig.type !== "agencyObject") {
|
|
43
|
+
throw new Error(`Second argument to llm function must be an object literal for configuration.`);
|
|
44
|
+
}
|
|
45
|
+
return success({
|
|
46
|
+
type: "prompt",
|
|
47
|
+
segments: promptArg.type === "variableName"
|
|
48
|
+
? [
|
|
49
|
+
{
|
|
50
|
+
type: "interpolation",
|
|
51
|
+
variableName: promptArg.value,
|
|
52
|
+
},
|
|
53
|
+
]
|
|
54
|
+
: promptArg.segments,
|
|
55
|
+
config: promptConfig,
|
|
56
|
+
}, result.rest);
|
|
57
|
+
};
|
|
58
|
+
export const streamingPromptLiteralParser = (input) => {
|
|
59
|
+
const parser = seqC(or(str("streaming"), str("stream")), spaces, capture(or(promptParser, llmPromptFunctionCallParser), "prompt"));
|
|
60
|
+
const result = parser(input);
|
|
61
|
+
if (!result.success) {
|
|
62
|
+
return result;
|
|
63
|
+
}
|
|
64
|
+
const { prompt } = result.result;
|
|
65
|
+
return success({ ...prompt, isStreaming: true }, result.rest);
|
|
66
|
+
};
|