agency-lang 0.0.77 → 0.0.78

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/dist/lib/backends/agencyGenerator.js +16 -11
  2. package/dist/lib/backends/typescriptGenerator/typeToZodSchema.js +12 -0
  3. package/dist/lib/backends/typescriptGenerator.js +15 -1
  4. package/dist/lib/cli/commands.js +11 -10
  5. package/dist/lib/cli/test.js +9 -0
  6. package/dist/lib/config.d.ts +0 -4
  7. package/dist/lib/parsers/typeHints.js +33 -2
  8. package/dist/lib/runtime/index.d.ts +2 -0
  9. package/dist/lib/templates/backends/typescriptGenerator/builtinFunctions/fetch.d.ts +1 -1
  10. package/dist/lib/templates/backends/typescriptGenerator/builtinFunctions/fetch.js +1 -1
  11. package/dist/lib/templates/backends/typescriptGenerator/builtinFunctions/fetchJSON.d.ts +1 -1
  12. package/dist/lib/templates/backends/typescriptGenerator/builtinFunctions/fetchJSON.js +1 -1
  13. package/dist/lib/templates/backends/typescriptGenerator/builtinFunctions/input.d.ts +1 -1
  14. package/dist/lib/templates/backends/typescriptGenerator/builtinFunctions/input.js +1 -1
  15. package/dist/lib/templates/backends/typescriptGenerator/builtinFunctions/read.d.ts +1 -1
  16. package/dist/lib/templates/backends/typescriptGenerator/builtinFunctions/read.js +1 -1
  17. package/dist/lib/templates/backends/typescriptGenerator/builtinFunctions/readImage.d.ts +1 -1
  18. package/dist/lib/templates/backends/typescriptGenerator/builtinFunctions/readImage.js +1 -1
  19. package/dist/lib/templates/backends/typescriptGenerator/builtinFunctions/sleep.d.ts +1 -1
  20. package/dist/lib/templates/backends/typescriptGenerator/builtinFunctions/sleep.js +1 -1
  21. package/dist/lib/templates/backends/typescriptGenerator/builtinFunctions/time.d.ts +1 -1
  22. package/dist/lib/templates/backends/typescriptGenerator/builtinFunctions/time.js +3 -3
  23. package/dist/lib/templates/backends/typescriptGenerator/functionDefinition.d.ts +1 -1
  24. package/dist/lib/templates/backends/typescriptGenerator/functionDefinition.js +1 -1
  25. package/dist/lib/templates/backends/typescriptGenerator/graphNode.d.ts +1 -1
  26. package/dist/lib/templates/backends/typescriptGenerator/graphNode.js +1 -1
  27. package/dist/lib/templates/backends/typescriptGenerator/imports.d.ts +1 -1
  28. package/dist/lib/templates/backends/typescriptGenerator/imports.js +11 -10
  29. package/dist/lib/templates/backends/typescriptGenerator/promptFunction.d.ts +1 -1
  30. package/dist/lib/templates/backends/typescriptGenerator/promptFunction.js +1 -1
  31. package/dist/lib/templates/backends/typescriptGenerator/runNodeFunction.d.ts +2 -1
  32. package/dist/lib/templates/backends/typescriptGenerator/runNodeFunction.js +2 -2
  33. package/dist/lib/templates/backends/typescriptGenerator/startNode.d.ts +1 -1
  34. package/dist/lib/templates/backends/typescriptGenerator/startNode.js +1 -1
  35. package/package.json +2 -1
  36. package/dist/lib/backends/declarationGenerator.d.ts +0 -42
  37. package/dist/lib/backends/declarationGenerator.js +0 -233
  38. package/dist/lib/backends/declarationGenerator.test.d.ts +0 -1
  39. package/dist/lib/backends/declarationGenerator.test.js +0 -287
@@ -31,17 +31,22 @@ export class AgencyGenerator extends BaseGenerator {
31
31
  }
32
32
  aliasedTypeToString(aliasedType) {
33
33
  if (aliasedType.type === "objectType") {
34
- const props = aliasedType.properties
35
- .map((prop) => {
36
- let str = `${this.indent(this.indentLevel + 1)}`;
37
- str += `${prop.key}: ${this.aliasedTypeToString(prop.value)}`;
38
- if (prop.description) {
39
- str += ` # ${prop.description}`;
40
- }
41
- return str;
42
- })
43
- .join(";\n");
44
- return `{\n${props}\n}`;
34
+ this.increaseIndent();
35
+ let result = "{\n" +
36
+ aliasedType.properties
37
+ .map((prop) => {
38
+ let str = "";
39
+ str += this.indentStr(`${prop.key}: ${this.aliasedTypeToString(prop.value)}`);
40
+ if (prop.description) {
41
+ str += ` # ${prop.description}`;
42
+ }
43
+ return str;
44
+ })
45
+ .join(";\n") +
46
+ "\n";
47
+ this.decreaseIndent();
48
+ result += this.indentStr("}");
49
+ return result;
45
50
  }
46
51
  return variableTypeToString(aliasedType, this.typeAliases);
47
52
  }
@@ -4,6 +4,13 @@ export const DEFAULT_SCHEMA = "z.string()";
4
4
  * Maps Agency types to Zod schema strings
5
5
  */
6
6
  export function mapTypeToZodSchema(variableType, typeAliases) {
7
+ /* console.log(
8
+ color.yellow(
9
+ `Variable type is`,
10
+ JSON.stringify(variableType),
11
+ ),
12
+ );
13
+ */
7
14
  if (variableType.type === "primitiveType") {
8
15
  switch (variableType.value.toLowerCase()) {
9
16
  case "number":
@@ -12,6 +19,11 @@ export function mapTypeToZodSchema(variableType, typeAliases) {
12
19
  return DEFAULT_SCHEMA;
13
20
  case "boolean":
14
21
  return "z.boolean()";
22
+ case "null":
23
+ return "z.null()";
24
+ case "undefined":
25
+ // Undefined cannot be represented in JSON Schema
26
+ return "z.null()";
15
27
  default:
16
28
  // Default to string for unknown types
17
29
  return DEFAULT_SCHEMA;
@@ -1,4 +1,5 @@
1
1
  import { BUILTIN_FUNCTIONS, BUILTIN_TOOLS, TYPES_THAT_DONT_TRIGGER_NEW_PART, } from "../config.js";
2
+ import { formatTypeHint } from "../cli/util.js";
2
3
  import * as renderSpecialVar from "../templates/backends/typescriptGenerator/specialVar.js";
3
4
  import * as renderTime from "../templates/backends/typescriptGenerator/builtinFunctions/time.js";
4
5
  // builtinTools now handled by runtime library
@@ -325,9 +326,15 @@ export class TypeScriptGenerator extends BaseGenerator {
325
326
  this.startScope({ type: "function", functionName: node.functionName });
326
327
  const { functionName, body, parameters } = node;
327
328
  const args = parameters.map((p) => p.name);
329
+ const typedArgs = parameters.map((p) => {
330
+ if (p.typeHint) {
331
+ return `${p.name}: ${formatTypeHint(p.typeHint)}`;
332
+ }
333
+ return `${p.name}: any`;
334
+ });
328
335
  const bodyCode = this.processBodyAsParts(body);
329
336
  this.endScope();
330
- const paramList = args.length > 0 ? args.join(", ") + ", " : "";
337
+ const paramList = typedArgs.length > 0 ? typedArgs.join(", ") + ", " : "";
331
338
  const paramAssignments = args
332
339
  .map((arg) => `__stack.args["${arg}"] = ${arg};`)
333
340
  .join("\n ");
@@ -887,10 +894,17 @@ export class TypeScriptGenerator extends BaseGenerator {
887
894
  for (const node of this.graphNodes) {
888
895
  const args = node.parameters;
889
896
  const argsStr = args.map((arg) => arg.name).join(", ");
897
+ const typedArgsStr = args.map((arg) => {
898
+ if (arg.typeHint) {
899
+ return `${arg.name}: ${formatTypeHint(arg.typeHint)}`;
900
+ }
901
+ return `${arg.name}: any`;
902
+ }).join(", ");
890
903
  lines.push(renderRunNodeFunction.default({
891
904
  nodeName: node.nodeName,
892
905
  hasArgs: args.length > 0,
893
906
  argsStr,
907
+ typedArgsStr,
894
908
  }));
895
909
  // Export node parameter names so imported nodes can build correct data objects
896
910
  const paramNames = args.map((arg) => `"${arg.name}"`).join(", ");
@@ -1,6 +1,6 @@
1
1
  import { generateAgency } from "../backends/agencyGenerator.js";
2
- import { generateDeclarations } from "../backends/declarationGenerator.js";
3
2
  import { generateTypeScript } from "../index.js";
3
+ import { transformSync } from "esbuild";
4
4
  import { TypescriptPreprocessor } from "../preprocessors/typescriptPreprocessor.js";
5
5
  import { typeCheck, formatErrors } from "../typeChecker.js";
6
6
  import { renderMermaidAscii } from "beautiful-mermaid";
@@ -149,17 +149,18 @@ export function compile(config, inputFile, _outputFile, options) {
149
149
  node.modulePath = node.modulePath.replace(".agency", ext);
150
150
  }
151
151
  });
152
- let generatedCode = generateTypeScript(parsedProgram, config);
152
+ const generatedCode = generateTypeScript(parsedProgram, config);
153
153
  if (options?.ts) {
154
- generatedCode = "//@ts-nocheck\n" + generatedCode;
154
+ // TypeScript output — write as-is with proper types
155
+ fs.writeFileSync(outputFile, generatedCode, "utf-8");
155
156
  }
156
- fs.writeFileSync(outputFile, generatedCode, "utf-8");
157
- // Generate .d.ts declarations if enabled
158
- if (config.declarations) {
159
- const declarations = generateDeclarations(parsedProgram, config);
160
- const dtsFile = outputFile.replace(/\.(js|ts)$/, ".d.ts");
161
- fs.writeFileSync(dtsFile, declarations, "utf-8");
162
- console.log(`${inputFile} ${dtsFile}`);
157
+ else {
158
+ // JavaScript output strip types with esbuild
159
+ const result = transformSync(generatedCode, {
160
+ loader: "ts",
161
+ format: "esm",
162
+ });
163
+ fs.writeFileSync(outputFile, result.code, "utf-8");
163
164
  }
164
165
  console.log(`${inputFile} → ${outputFile}`);
165
166
  return outputFile;
@@ -38,6 +38,13 @@ function writeTestCase(agencyFilename, nodeName, input, expectedOutput, evaluati
38
38
  const onCancel = () => {
39
39
  process.exit(0);
40
40
  };
41
+ function exitIfSignal(e) {
42
+ if (e instanceof Error &&
43
+ "signal" in e &&
44
+ (e.signal === "SIGINT" || e.signal === "SIGTERM")) {
45
+ process.exit(1);
46
+ }
47
+ }
41
48
  export async function fixtures(config, target) {
42
49
  let { filename, nodeName } = target
43
50
  ? parseTarget(target)
@@ -306,6 +313,7 @@ export async function test(config, testFile) {
306
313
  break;
307
314
  }
308
315
  catch (e) {
316
+ exitIfSignal(e);
309
317
  console.log(color.red(` ✗ Test error: ${e}`));
310
318
  testPassed = false;
311
319
  }
@@ -390,6 +398,7 @@ export async function testTs(config, inputPaths) {
390
398
  });
391
399
  }
392
400
  catch (e) {
401
+ exitIfSignal(e);
393
402
  console.log(color.red(` ✗ Test script execution failed: ${e}`));
394
403
  failures.push(dir);
395
404
  continue;
@@ -79,10 +79,6 @@ export interface AgencyConfig {
79
79
  * If true, type errors are fatal during compilation (implies typeCheck: true).
80
80
  */
81
81
  typeCheckStrict?: boolean;
82
- /**
83
- * If true, generate .d.ts declaration files alongside .js output.
84
- */
85
- declarations?: boolean;
86
82
  /**
87
83
  * If true, validate that import paths resolve within the project directory.
88
84
  * Prevents path traversal attacks via imports like `../../etc/passwd`.
@@ -31,8 +31,39 @@ export const numberLiteralTypeParser = trace("numberLiteralTypeParser", seqC(set
31
31
  export const booleanLiteralTypeParser = trace("booleanLiteralTypeParser", seqC(set("type", "booleanLiteralType"), capture(or(str("true"), str("false")), "value")));
32
32
  export const objectPropertyDelimiter = seqR(optionalSpaces, oneOf(",;"), optionalSpacesOrNewline);
33
33
  export const objectPropertyParser = trace("objectPropertyParser", (input) => {
34
- const parser = seqC(capture(many1WithJoin(varNameChar), "key"), optionalSpaces, char(":"), optionalSpaces, capture(variableTypeParser, "value"));
35
- return parser(input);
34
+ const parser = seqC(capture(many1WithJoin(varNameChar), "key"), optionalSpaces, capture(optional(char("?")), "isOptional"), char(":"), optionalSpaces, capture(variableTypeParser, "value"));
35
+ const result = parser(input);
36
+ if (!result.success) {
37
+ return result;
38
+ }
39
+ const { key, isOptional, value } = result.result;
40
+ if (!isOptional) {
41
+ return success({
42
+ key,
43
+ value,
44
+ }, result.rest);
45
+ }
46
+ if (value.type === "unionType") {
47
+ // If it's already a union, just add undefined to the list of types
48
+ return success({
49
+ key,
50
+ value: {
51
+ type: "unionType",
52
+ types: [
53
+ ...value.types,
54
+ { type: "primitiveType", value: "undefined" },
55
+ ],
56
+ },
57
+ }, result.rest);
58
+ }
59
+ // If it's not a union, create a new union with the original type and undefined
60
+ return success({
61
+ key,
62
+ value: {
63
+ type: "unionType",
64
+ types: [value, { type: "primitiveType", value: "undefined" }],
65
+ },
66
+ }, result.rest);
36
67
  });
37
68
  export const objectPropertyDescriptionParser = trace("objectPropertyDescriptionParser", seqC(char("#"), optionalSpaces, capture(many1Till(oneOf(",;\n")), "description")));
38
69
  export const objectPropertyWithDescriptionParser = trace("objectPropertyWithDescriptionParser", seqC(captureCaptures(objectPropertyParser), spaces, captureCaptures(objectPropertyDescriptionParser)));
@@ -1,3 +1,5 @@
1
+ export type { GraphState, InternalFunctionState } from "./types.js";
2
+ export type { Interrupt } from "./interrupts.js";
1
3
  export { RuntimeContext } from "./state/context.js";
2
4
  export { StateStack } from "./state/stateStack.js";
3
5
  export { MessageThread } from "./state/messageThread.js";
@@ -1,4 +1,4 @@
1
- export declare const template = "async function _builtinFetch(url, args = {}) {\n const result = await fetch(url, args);\n try {\n const text = await result.text();\n return text;\n } catch (e) {\n throw new Error(`Failed to get text from ${url}: ${e}`);\n }\n}";
1
+ export declare const template = "async function _builtinFetch(url: string, args: RequestInit = {}): Promise<string> {\n const result = await fetch(url, args);\n try {\n const text = await result.text();\n return text;\n } catch (e) {\n throw new Error(`Failed to get text from ${url}: ${e}`);\n }\n}";
2
2
  export type TemplateType = {};
3
3
  declare const render: (args: TemplateType) => string;
4
4
  export default render;
@@ -2,7 +2,7 @@
2
2
  // Source: lib/templates/backends/typescriptGenerator/builtinFunctions/fetch.mustache
3
3
  // Any manual changes will be lost.
4
4
  import { apply } from "typestache";
5
- export const template = `async function _builtinFetch(url, args = {}) {
5
+ export const template = `async function _builtinFetch(url: string, args: RequestInit = {}): Promise<string> {
6
6
  const result = await fetch(url, args);
7
7
  try {
8
8
  const text = await result.text();
@@ -1,4 +1,4 @@
1
- export declare const template = "async function _builtinFetchJSON(url, args = {}) {\n const result = await fetch(url, args);\n try {\n const json = await result.json();\n return json;\n } catch (e) {\n throw new Error(`Failed to parse JSON from ${url}: ${e}`);\n }\n}";
1
+ export declare const template = "async function _builtinFetchJSON(url: string, args: RequestInit = {}): Promise<any> {\n const result = await fetch(url, args);\n try {\n const json = await result.json();\n return json;\n } catch (e) {\n throw new Error(`Failed to parse JSON from ${url}: ${e}`);\n }\n}";
2
2
  export type TemplateType = {};
3
3
  declare const render: (args: TemplateType) => string;
4
4
  export default render;
@@ -2,7 +2,7 @@
2
2
  // Source: lib/templates/backends/typescriptGenerator/builtinFunctions/fetchJSON.mustache
3
3
  // Any manual changes will be lost.
4
4
  import { apply } from "typestache";
5
- export const template = `async function _builtinFetchJSON(url, args = {}) {
5
+ export const template = `async function _builtinFetchJSON(url: string, args: RequestInit = {}): Promise<any> {
6
6
  const result = await fetch(url, args);
7
7
  try {
8
8
  const json = await result.json();
@@ -1,4 +1,4 @@
1
- export declare const template = "function _builtinInput(prompt) {\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout\n });\n\n return new Promise((resolve) => {\n rl.question(prompt, (answer) => {\n rl.close();\n resolve(answer);\n });\n });\n}";
1
+ export declare const template = "function _builtinInput(prompt: string): Promise<string> {\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout\n });\n\n return new Promise((resolve) => {\n rl.question(prompt, (answer) => {\n rl.close();\n resolve(answer);\n });\n });\n}";
2
2
  export type TemplateType = {};
3
3
  declare const render: (args: TemplateType) => string;
4
4
  export default render;
@@ -2,7 +2,7 @@
2
2
  // Source: lib/templates/backends/typescriptGenerator/builtinFunctions/input.mustache
3
3
  // Any manual changes will be lost.
4
4
  import { apply } from "typestache";
5
- export const template = `function _builtinInput(prompt) {
5
+ export const template = `function _builtinInput(prompt: string): Promise<string> {
6
6
  const rl = readline.createInterface({
7
7
  input: process.stdin,
8
8
  output: process.stdout
@@ -1,4 +1,4 @@
1
- export declare const template = "function _builtinRead(filename) {\n const data = fs.readFileSync(filename);\n const contents = data.toString('utf8');\n return contents;\n}";
1
+ export declare const template = "function _builtinRead(filename: string): string {\n const data = fs.readFileSync(filename);\n const contents = data.toString('utf8');\n return contents;\n}";
2
2
  export type TemplateType = {};
3
3
  declare const render: (args: TemplateType) => string;
4
4
  export default render;
@@ -2,7 +2,7 @@
2
2
  // Source: lib/templates/backends/typescriptGenerator/builtinFunctions/read.mustache
3
3
  // Any manual changes will be lost.
4
4
  import { apply } from "typestache";
5
- export const template = `function _builtinRead(filename) {
5
+ export const template = `function _builtinRead(filename: string): string {
6
6
  const data = fs.readFileSync(filename);
7
7
  const contents = data.toString('utf8');
8
8
  return contents;
@@ -1,4 +1,4 @@
1
- export declare const template = "/*\n * @param filePath The absolute or relative path to the image file.\n * @returns The Base64 string, or null if an error occurs.\n */\nfunction _builtinReadImage(filePath) {\n const data = fs.readFileSync(filePath); // Synchronous file reading\n const base64String = data.toString('base64');\n return base64String;\n}";
1
+ export declare const template = "/*\n * @param filePath The absolute or relative path to the image file.\n * @returns The Base64 string, or null if an error occurs.\n */\nfunction _builtinReadImage(filePath: string): string {\n const data = fs.readFileSync(filePath); // Synchronous file reading\n const base64String = data.toString('base64');\n return base64String;\n}";
2
2
  export type TemplateType = {};
3
3
  declare const render: (args: TemplateType) => string;
4
4
  export default render;
@@ -6,7 +6,7 @@ export const template = `/*
6
6
  * @param filePath The absolute or relative path to the image file.
7
7
  * @returns The Base64 string, or null if an error occurs.
8
8
  */
9
- function _builtinReadImage(filePath) {
9
+ function _builtinReadImage(filePath: string): string {
10
10
  const data = fs.readFileSync(filePath); // Synchronous file reading
11
11
  const base64String = data.toString('base64');
12
12
  return base64String;
@@ -1,4 +1,4 @@
1
- export declare const template = "function _builtinSleep(seconds) {\n return new Promise((resolve) => {\n setTimeout(resolve, seconds * 1000);\n });\n}";
1
+ export declare const template = "function _builtinSleep(seconds: number): Promise<void> {\n return new Promise((resolve) => {\n setTimeout(resolve, seconds * 1000);\n });\n}";
2
2
  export type TemplateType = {};
3
3
  declare const render: (args: TemplateType) => string;
4
4
  export default render;
@@ -2,7 +2,7 @@
2
2
  // Source: lib/templates/backends/typescriptGenerator/builtinFunctions/sleep.mustache
3
3
  // Any manual changes will be lost.
4
4
  import { apply } from "typestache";
5
- export const template = `function _builtinSleep(seconds) {
5
+ export const template = `function _builtinSleep(seconds: number): Promise<void> {
6
6
  return new Promise((resolve) => {
7
7
  setTimeout(resolve, seconds * 1000);
8
8
  });
@@ -1,4 +1,4 @@
1
- export declare const template = "let {{{timingVarName:string}}}_startTime = performance.now();\n{{{bodyCodeStr:string}}}\nlet {{{timingVarName}}}_endTime = performance.now();\nlet {{{timingVarName}}} = {{{timingVarName}}}_endTime - {{{timingVarName}}}_startTime;\n\n{{#printTime}}\nconsole.log(\"Time taken:\", {{{timingVarName}}}, \"ms\");\n{{/printTime}}";
1
+ export declare const template = "let {{{timingVarName:string}}}_startTime: number = performance.now();\n{{{bodyCodeStr:string}}}\nlet {{{timingVarName}}}_endTime: number = performance.now();\nlet {{{timingVarName}}}: number = {{{timingVarName}}}_endTime - {{{timingVarName}}}_startTime;\n\n{{#printTime}}\nconsole.log(\"Time taken:\", {{{timingVarName}}}, \"ms\");\n{{/printTime}}";
2
2
  export type TemplateType = {
3
3
  timingVarName: string;
4
4
  bodyCodeStr: string;
@@ -2,10 +2,10 @@
2
2
  // Source: lib/templates/backends/typescriptGenerator/builtinFunctions/time.mustache
3
3
  // Any manual changes will be lost.
4
4
  import { apply } from "typestache";
5
- export const template = `let {{{timingVarName:string}}}_startTime = performance.now();
5
+ export const template = `let {{{timingVarName:string}}}_startTime: number = performance.now();
6
6
  {{{bodyCodeStr:string}}}
7
- let {{{timingVarName}}}_endTime = performance.now();
8
- let {{{timingVarName}}} = {{{timingVarName}}}_endTime - {{{timingVarName}}}_startTime;
7
+ let {{{timingVarName}}}_endTime: number = performance.now();
8
+ let {{{timingVarName}}}: number = {{{timingVarName}}}_endTime - {{{timingVarName}}}_startTime;
9
9
 
10
10
  {{#printTime}}
11
11
  console.log("Time taken:", {{{timingVarName}}}, "ms");
@@ -1,4 +1,4 @@
1
- export declare const template = "\nexport async function {{{functionName:string}}}({{{paramList:string}}}__state=undefined) {\n const { stack: __stack, step: __step, self: __self, threads: __threads } =\n setupFunction({ state: __state });\n\n // __state will be undefined if this function is\n // being called as a tool by an llm\n const __ctx = __state?.ctx || __globalCtx;\n const statelogClient = __ctx.statelogClient;\n const __graph = __ctx.graph;\n const __funcStartTime = performance.now();\n await callHook({ callbacks: __ctx.callbacks, name: \"onFunctionStart\", data: { functionName: \"{{{functionName}}}\", args: {{{argsObject:string}}}, isBuiltin: false } });\n\n // put all args on the state stack\n {{{paramAssignments:string}}}\n\n {{{functionBody}}}\n\n await callHook({ callbacks: __ctx.callbacks, name: \"onFunctionEnd\", data: { functionName: \"{{{functionName}}}\", timeTaken: performance.now() - __funcStartTime } });\n}\n";
1
+ export declare const template = "\nexport async function {{{functionName:string}}}({{{paramList:string}}}__state: InternalFunctionState | undefined = undefined) {\n const { stack: __stack, step: __step, self: __self, threads: __threads } =\n setupFunction({ state: __state });\n\n // __state will be undefined if this function is\n // being called as a tool by an llm\n const __ctx = __state?.ctx || __globalCtx;\n const statelogClient = __ctx.statelogClient;\n const __graph = __ctx.graph;\n const __funcStartTime = performance.now();\n await callHook({ callbacks: __ctx.callbacks, name: \"onFunctionStart\", data: { functionName: \"{{{functionName}}}\", args: {{{argsObject:string}}}, isBuiltin: false } });\n\n // put all args on the state stack\n {{{paramAssignments:string}}}\n\n {{{functionBody}}}\n\n await callHook({ callbacks: __ctx.callbacks, name: \"onFunctionEnd\", data: { functionName: \"{{{functionName}}}\", timeTaken: performance.now() - __funcStartTime } });\n}\n";
2
2
  export type TemplateType = {
3
3
  functionName: string;
4
4
  paramList: string;
@@ -3,7 +3,7 @@
3
3
  // Any manual changes will be lost.
4
4
  import { apply } from "typestache";
5
5
  export const template = `
6
- export async function {{{functionName:string}}}({{{paramList:string}}}__state=undefined) {
6
+ export async function {{{functionName:string}}}({{{paramList:string}}}__state: InternalFunctionState | undefined = undefined) {
7
7
  const { stack: __stack, step: __step, self: __self, threads: __threads } =
8
8
  setupFunction({ state: __state });
9
9
 
@@ -1,4 +1,4 @@
1
- export declare const template = "\ngraph.node(\"{{{name}}}\", async (__state) => {\n const { stack: __stack, step: __step, self: __self, threads: __threads } =\n setupNode({ state: __state });\n const __ctx = __state.ctx;\n const statelogClient = __ctx.statelogClient;\n const __graph = __ctx.graph;\n await callHook({ callbacks: __ctx.callbacks, name: \"onNodeStart\", data: { nodeName: \"{{{name}}}\" } });\n\n if (__state.isResume) {\n __globalCtx.stateStack.globals = __state.ctx.stateStack.globals;\n }\n\n {{#hasParam}}\n if (!__state.isResume) {\n {{{paramAssignments}}}\n }\n {{/hasParam}}\n {{{body}}}\n\n await callHook({ callbacks: __ctx.callbacks, name: \"onNodeEnd\", data: { nodeName: \"{{{name}}}\", data: undefined } });\n return { messages: __threads, data: undefined };\n});\n";
1
+ export declare const template = "\ngraph.node(\"{{{name}}}\", async (__state: GraphState) => {\n const { stack: __stack, step: __step, self: __self, threads: __threads } =\n setupNode({ state: __state });\n const __ctx = __state.ctx;\n const statelogClient = __ctx.statelogClient;\n const __graph = __ctx.graph;\n await callHook({ callbacks: __ctx.callbacks, name: \"onNodeStart\", data: { nodeName: \"{{{name}}}\" } });\n\n if (__state.isResume) {\n __globalCtx.stateStack.globals = __state.ctx.stateStack.globals;\n }\n\n {{#hasParam}}\n if (!__state.isResume) {\n {{{paramAssignments}}}\n }\n {{/hasParam}}\n {{{body}}}\n\n await callHook({ callbacks: __ctx.callbacks, name: \"onNodeEnd\", data: { nodeName: \"{{{name}}}\", data: undefined } });\n return { messages: __threads, data: undefined };\n});\n";
2
2
  export type TemplateType = {
3
3
  name: string | boolean | number;
4
4
  hasParam: boolean;
@@ -3,7 +3,7 @@
3
3
  // Any manual changes will be lost.
4
4
  import { apply } from "typestache";
5
5
  export const template = `
6
- graph.node("{{{name}}}", async (__state) => {
6
+ graph.node("{{{name}}}", async (__state: GraphState) => {
7
7
  const { stack: __stack, step: __step, self: __self, threads: __threads } =
8
8
  setupNode({ state: __state });
9
9
  const __ctx = __state.ctx;
@@ -1,4 +1,4 @@
1
- export declare const template = "import { fileURLToPath } from \"url\";\nimport process from \"process\";\nimport { readFileSync, writeFileSync } from \"fs\";\nimport { z } from \"zod\";\nimport { goToNode, color, nanoid, registerProvider, registerTextModel } from \"agency-lang\";\nimport * as smoltalk from \"agency-lang\";\nimport path from \"path\";\nimport {\n RuntimeContext, MessageThread, ThreadStore,\n setupNode, setupFunction, runNode, runPrompt, callHook,\n interrupt, isInterrupt,\n respondToInterrupt as _respondToInterrupt,\n approveInterrupt as _approveInterrupt,\n rejectInterrupt as _rejectInterrupt,\n resolveInterrupt as _resolveInterrupt,\n modifyInterrupt as _modifyInterrupt,\n resumeFromState as _resumeFromState,\n deepClone as __deepClone,\n not, eq, neq, lt, lte, gt, gte, and, or,\n head, tail, empty,\n builtinFetch as _builtinFetch,\n builtinFetchJSON as _builtinFetchJSON,\n builtinInput as _builtinInput,\n builtinRead as _builtinReadRaw,\n builtinWrite as _builtinWriteRaw,\n builtinReadImage as _builtinReadImageRaw,\n builtinSleep as _builtinSleep,\n builtinRound as _builtinRound,\n printJSON as _printJSON,\n print as _print,\n readSkill as _readSkillRaw,\n readSkillTool as __readSkillTool,\n readSkillToolParams as __readSkillToolParams,\n printTool as __printTool,\n printToolParams as __printToolParams,\n printJSONTool as __printJSONTool,\n printJSONToolParams as __printJSONToolParams,\n inputTool as __inputTool,\n inputToolParams as __inputToolParams,\n readTool as __readTool,\n readToolParams as __readToolParams,\n readImageTool as __readImageTool,\n readImageToolParams as __readImageToolParams,\n writeTool as __writeTool,\n writeToolParams as __writeToolParams,\n fetchTool as __fetchTool,\n fetchToolParams as __fetchToolParams,\n fetchJSONTool as __fetchJSONTool,\n fetchJSONToolParams as __fetchJSONToolParams,\n fetchJsonTool as __fetchJsonTool,\n fetchJsonToolParams as __fetchJsonToolParams,\n sleepTool as __sleepTool,\n sleepToolParams as __sleepToolParams,\n roundTool as __roundTool,\n roundToolParams as __roundToolParams,\n} from \"agency-lang/runtime\";\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\nconst __cwd = process.cwd();\n\nconst __globalCtx = new RuntimeContext({\n statelogConfig: {\n host: \"{{{logHost:string}}}\",\n {{#hasApiKey}}\n apiKey: \"{{{logApiKey?:string}}}\",\n {{/hasApiKey}}\n {{^hasApiKey}}\n apiKey: process.env.STATELOG_API_KEY || \"\",\n {{/hasApiKey}}\n projectId: \"{{{logProjectId:string}}}\",\n debugMode: {{{logDebugMode:boolean}}},\n },\n smoltalkDefaults: {\n {{#hasOpenAiApiKey}}\n openAiApiKey: \"{{{clientOpenAiApiKey?:string}}}\",\n {{/hasOpenAiApiKey}}\n {{^hasOpenAiApiKey}}\n openAiApiKey: process.env.OPENAI_API_KEY || \"\",\n {{/hasOpenAiApiKey}}\n {{#hasGoogleApiKey}}\n googleApiKey: \"{{{clientGoogleApiKey?:string}}}\",\n {{/hasGoogleApiKey}}\n {{^hasGoogleApiKey}}\n googleApiKey: process.env.GEMINI_API_KEY || \"\",\n {{/hasGoogleApiKey}}\n model: \"{{{clientDefaultModel:string}}}\",\n logLevel: \"{{{clientLogLevel:string}}}\",\n statelog: { \n host: \"{{{clientStatelogHost:string}}}\",\n projectId: \"{{{clientStatelogProjectId:string}}}\",\n apiKey: process.env.STATELOG_SMOLTALK_API_KEY || \"\",\n traceId: nanoid()\n }\n },\n dirname: __dirname,\n});\nconst graph = __globalCtx.graph;\n\n// Path-dependent builtin wrappers\nfunction _builtinRead(filename) {\n return _builtinReadRaw({ filename, dirname: __dirname });\n}\nfunction _builtinWrite(filename, content) {\n return _builtinWriteRaw({ filename, content, dirname: __dirname });\n}\nfunction _builtinReadImage(filename) {\n return _builtinReadImageRaw({ filename, dirname: __dirname });\n}\nexport function readSkill({filepath}) {\n return _readSkillRaw({ filepath, dirname: __dirname });\n}\n\n// Interrupt re-exports bound to this module's context\nexport { interrupt, isInterrupt };\nexport const respondToInterrupt = (i, r, m) => _respondToInterrupt({ ctx: __globalCtx, interrupt: i, interruptResponse: r, metadata: m });\nexport const approveInterrupt = (i, m) => _approveInterrupt({ ctx: __globalCtx, interrupt: i, metadata: m });\nexport const rejectInterrupt = (i, m) => _rejectInterrupt({ ctx: __globalCtx, interrupt: i, metadata: m });\nexport const modifyInterrupt = (i, a, m) => _modifyInterrupt({ ctx: __globalCtx, interrupt: i, newArguments: a, metadata: m });\nexport const resolveInterrupt = (i, v, m) => _resolveInterrupt({ ctx: __globalCtx, interrupt: i, value: v, metadata: m });";
1
+ export declare const template = "import { fileURLToPath } from \"url\";\nimport process from \"process\";\nimport { readFileSync, writeFileSync } from \"fs\";\nimport { z } from \"zod\";\nimport { goToNode, color, nanoid, registerProvider, registerTextModel } from \"agency-lang\";\nimport * as smoltalk from \"agency-lang\";\nimport path from \"path\";\nimport type { GraphState, InternalFunctionState, Interrupt } from \"agency-lang/runtime\";\nimport {\n RuntimeContext, MessageThread, ThreadStore,\n setupNode, setupFunction, runNode, runPrompt, callHook,\n interrupt, isInterrupt,\n respondToInterrupt as _respondToInterrupt,\n approveInterrupt as _approveInterrupt,\n rejectInterrupt as _rejectInterrupt,\n resolveInterrupt as _resolveInterrupt,\n modifyInterrupt as _modifyInterrupt,\n resumeFromState as _resumeFromState,\n deepClone as __deepClone,\n not, eq, neq, lt, lte, gt, gte, and, or,\n head, tail, empty,\n builtinFetch as _builtinFetch,\n builtinFetchJSON as _builtinFetchJSON,\n builtinInput as _builtinInput,\n builtinRead as _builtinReadRaw,\n builtinWrite as _builtinWriteRaw,\n builtinReadImage as _builtinReadImageRaw,\n builtinSleep as _builtinSleep,\n builtinRound as _builtinRound,\n printJSON as _printJSON,\n print as _print,\n readSkill as _readSkillRaw,\n readSkillTool as __readSkillTool,\n readSkillToolParams as __readSkillToolParams,\n printTool as __printTool,\n printToolParams as __printToolParams,\n printJSONTool as __printJSONTool,\n printJSONToolParams as __printJSONToolParams,\n inputTool as __inputTool,\n inputToolParams as __inputToolParams,\n readTool as __readTool,\n readToolParams as __readToolParams,\n readImageTool as __readImageTool,\n readImageToolParams as __readImageToolParams,\n writeTool as __writeTool,\n writeToolParams as __writeToolParams,\n fetchTool as __fetchTool,\n fetchToolParams as __fetchToolParams,\n fetchJSONTool as __fetchJSONTool,\n fetchJSONToolParams as __fetchJSONToolParams,\n fetchJsonTool as __fetchJsonTool,\n fetchJsonToolParams as __fetchJsonToolParams,\n sleepTool as __sleepTool,\n sleepToolParams as __sleepToolParams,\n roundTool as __roundTool,\n roundToolParams as __roundToolParams,\n} from \"agency-lang/runtime\";\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\nconst __cwd = process.cwd();\n\nconst __globalCtx = new RuntimeContext({\n statelogConfig: {\n host: \"{{{logHost:string}}}\",\n {{#hasApiKey}}\n apiKey: \"{{{logApiKey?:string}}}\",\n {{/hasApiKey}}\n {{^hasApiKey}}\n apiKey: process.env.STATELOG_API_KEY || \"\",\n {{/hasApiKey}}\n projectId: \"{{{logProjectId:string}}}\",\n debugMode: {{{logDebugMode:boolean}}},\n },\n smoltalkDefaults: {\n {{#hasOpenAiApiKey}}\n openAiApiKey: \"{{{clientOpenAiApiKey?:string}}}\",\n {{/hasOpenAiApiKey}}\n {{^hasOpenAiApiKey}}\n openAiApiKey: process.env.OPENAI_API_KEY || \"\",\n {{/hasOpenAiApiKey}}\n {{#hasGoogleApiKey}}\n googleApiKey: \"{{{clientGoogleApiKey?:string}}}\",\n {{/hasGoogleApiKey}}\n {{^hasGoogleApiKey}}\n googleApiKey: process.env.GEMINI_API_KEY || \"\",\n {{/hasGoogleApiKey}}\n model: \"{{{clientDefaultModel:string}}}\",\n logLevel: \"{{{clientLogLevel:string}}}\",\n statelog: { \n host: \"{{{clientStatelogHost:string}}}\",\n projectId: \"{{{clientStatelogProjectId:string}}}\",\n apiKey: process.env.STATELOG_SMOLTALK_API_KEY || \"\",\n traceId: nanoid()\n }\n },\n dirname: __dirname,\n});\nconst graph = __globalCtx.graph;\n\n// Path-dependent builtin wrappers\nfunction _builtinRead(filename: string): string {\n return _builtinReadRaw({ filename, dirname: __dirname });\n}\nfunction _builtinWrite(filename: string, content: string): void {\n _builtinWriteRaw({ filename, content, dirname: __dirname });\n}\nfunction _builtinReadImage(filename: string): string {\n return _builtinReadImageRaw({ filename, dirname: __dirname });\n}\nexport function readSkill({filepath}: {filepath: string}): string {\n return _readSkillRaw({ filepath, dirname: __dirname });\n}\n\n// Interrupt re-exports bound to this module's context\nexport { interrupt, isInterrupt };\nexport const respondToInterrupt = (i: Interrupt, r: any, m?: any) => _respondToInterrupt({ ctx: __globalCtx, interrupt: i, interruptResponse: r, metadata: m });\nexport const approveInterrupt = (i: Interrupt, m?: any) => _approveInterrupt({ ctx: __globalCtx, interrupt: i, metadata: m });\nexport const rejectInterrupt = (i: Interrupt, m?: any) => _rejectInterrupt({ ctx: __globalCtx, interrupt: i, metadata: m });\nexport const modifyInterrupt = (i: Interrupt, a: any, m?: any) => _modifyInterrupt({ ctx: __globalCtx, interrupt: i, newArguments: a, metadata: m });\nexport const resolveInterrupt = (i: Interrupt, v: any, m?: any) => _resolveInterrupt({ ctx: __globalCtx, interrupt: i, value: v, metadata: m });";
2
2
  export type TemplateType = {
3
3
  logHost: string;
4
4
  hasApiKey: boolean;
@@ -9,6 +9,7 @@ import { z } from "zod";
9
9
  import { goToNode, color, nanoid, registerProvider, registerTextModel } from "agency-lang";
10
10
  import * as smoltalk from "agency-lang";
11
11
  import path from "path";
12
+ import type { GraphState, InternalFunctionState, Interrupt } from "agency-lang/runtime";
12
13
  import {
13
14
  RuntimeContext, MessageThread, ThreadStore,
14
15
  setupNode, setupFunction, runNode, runPrompt, callHook,
@@ -102,26 +103,26 @@ const __globalCtx = new RuntimeContext({
102
103
  const graph = __globalCtx.graph;
103
104
 
104
105
  // Path-dependent builtin wrappers
105
- function _builtinRead(filename) {
106
+ function _builtinRead(filename: string): string {
106
107
  return _builtinReadRaw({ filename, dirname: __dirname });
107
108
  }
108
- function _builtinWrite(filename, content) {
109
- return _builtinWriteRaw({ filename, content, dirname: __dirname });
109
+ function _builtinWrite(filename: string, content: string): void {
110
+ _builtinWriteRaw({ filename, content, dirname: __dirname });
110
111
  }
111
- function _builtinReadImage(filename) {
112
+ function _builtinReadImage(filename: string): string {
112
113
  return _builtinReadImageRaw({ filename, dirname: __dirname });
113
114
  }
114
- export function readSkill({filepath}) {
115
+ export function readSkill({filepath}: {filepath: string}): string {
115
116
  return _readSkillRaw({ filepath, dirname: __dirname });
116
117
  }
117
118
 
118
119
  // Interrupt re-exports bound to this module's context
119
120
  export { interrupt, isInterrupt };
120
- export const respondToInterrupt = (i, r, m) => _respondToInterrupt({ ctx: __globalCtx, interrupt: i, interruptResponse: r, metadata: m });
121
- export const approveInterrupt = (i, m) => _approveInterrupt({ ctx: __globalCtx, interrupt: i, metadata: m });
122
- export const rejectInterrupt = (i, m) => _rejectInterrupt({ ctx: __globalCtx, interrupt: i, metadata: m });
123
- export const modifyInterrupt = (i, a, m) => _modifyInterrupt({ ctx: __globalCtx, interrupt: i, newArguments: a, metadata: m });
124
- export const resolveInterrupt = (i, v, m) => _resolveInterrupt({ ctx: __globalCtx, interrupt: i, value: v, metadata: m });`;
121
+ export const respondToInterrupt = (i: Interrupt, r: any, m?: any) => _respondToInterrupt({ ctx: __globalCtx, interrupt: i, interruptResponse: r, metadata: m });
122
+ export const approveInterrupt = (i: Interrupt, m?: any) => _approveInterrupt({ ctx: __globalCtx, interrupt: i, metadata: m });
123
+ export const rejectInterrupt = (i: Interrupt, m?: any) => _rejectInterrupt({ ctx: __globalCtx, interrupt: i, metadata: m });
124
+ export const modifyInterrupt = (i: Interrupt, a: any, m?: any) => _modifyInterrupt({ ctx: __globalCtx, interrupt: i, newArguments: a, metadata: m });
125
+ export const resolveInterrupt = (i: Interrupt, v: any, m?: any) => _resolveInterrupt({ ctx: __globalCtx, interrupt: i, value: v, metadata: m });`;
125
126
  const render = (args) => {
126
127
  return apply(template, args);
127
128
  };
@@ -1,4 +1,4 @@
1
- export declare const template = "\nasync function _{{{variableName:string}}}({{{argsStr:string}}}) {\n return runPrompt({\n ctx: __ctx,\n prompt: {{{promptCode:string}}},\n messages: __metadata?.messages || new MessageThread(),\n {{#hasResponseFormat}}\n responseFormat: z.object({\n response: {{{zodSchema:string}}}\n }),\n {{/hasResponseFormat}}\n tools: {{{tools}}},\n toolHandlers: [{{{toolHandlers:string}}}],\n clientConfig: {{{clientConfig:string}}},\n stream: {{{isStreaming:boolean}}},\n maxToolCallRounds: {{{maxToolCallRounds:number}}},\n interruptData: __state?.interruptData\n });\n}\n\n{{#isAsync}}\n__self.{{{variableName:string}}} = _{{{variableName:string}}}({{{funcCallParams:string}}});\n{{/isAsync}}\n\n{{^isAsync}}\n__self.{{{variableName:string}}} = await _{{{variableName:string}}}({{{funcCallParams:string}}});\n\n// return early from node if this is an interrupt\nif (isInterrupt(__self.{{{variableName:string}}})) {\n {{#nodeContext}}\n return { messages: __threads, data: __self.{{{variableName:string}}} };\n {{/nodeContext}}\n {{^nodeContext}}\n return __self.{{{variableName:string}}};\n {{/nodeContext}}\n}\n{{/isAsync}}";
1
+ export declare const template = "\nasync function _{{{variableName:string}}}({{{argsStr:string}}}): Promise<any> {\n return runPrompt({\n ctx: __ctx,\n prompt: {{{promptCode:string}}},\n messages: __metadata?.messages || new MessageThread(),\n {{#hasResponseFormat}}\n responseFormat: z.object({\n response: {{{zodSchema:string}}}\n }),\n {{/hasResponseFormat}}\n tools: {{{tools}}},\n toolHandlers: [{{{toolHandlers:string}}}],\n clientConfig: {{{clientConfig:string}}},\n stream: {{{isStreaming:boolean}}},\n maxToolCallRounds: {{{maxToolCallRounds:number}}},\n interruptData: __state?.interruptData\n });\n}\n\n{{#isAsync}}\n__self.{{{variableName:string}}} = _{{{variableName:string}}}({{{funcCallParams:string}}});\n{{/isAsync}}\n\n{{^isAsync}}\n__self.{{{variableName:string}}} = await _{{{variableName:string}}}({{{funcCallParams:string}}});\n\n// return early from node if this is an interrupt\nif (isInterrupt(__self.{{{variableName:string}}})) {\n {{#nodeContext}}\n return { messages: __threads, data: __self.{{{variableName:string}}} };\n {{/nodeContext}}\n {{^nodeContext}}\n return __self.{{{variableName:string}}};\n {{/nodeContext}}\n}\n{{/isAsync}}";
2
2
  export type TemplateType = {
3
3
  variableName: string;
4
4
  argsStr: string;
@@ -3,7 +3,7 @@
3
3
  // Any manual changes will be lost.
4
4
  import { apply } from "typestache";
5
5
  export const template = `
6
- async function _{{{variableName:string}}}({{{argsStr:string}}}) {
6
+ async function _{{{variableName:string}}}({{{argsStr:string}}}): Promise<any> {
7
7
  return runPrompt({
8
8
  ctx: __ctx,
9
9
  prompt: {{{promptCode:string}}},
@@ -1,7 +1,8 @@
1
- export declare const template = "{{#hasArgs}}\nexport async function {{{nodeName:string}}}({{{argsStr:string}}}, { messages, callbacks } = {}) {\n{{/hasArgs}}\n{{^hasArgs}}\nexport async function {{{nodeName:string}}}({ messages, callbacks } = {}) {\n{{/hasArgs}}\n return runNode({\n ctx: __globalCtx,\n nodeName: \"{{{nodeName:string}}}\",\n data: { {{{argsStr:string}}} },\n messages,\n callbacks,\n });\n}\n";
1
+ export declare const template = "{{#hasArgs}}\nexport async function {{{nodeName:string}}}({{{typedArgsStr:string}}}, { messages, callbacks }: { messages?: any; callbacks?: any } = {}) {\n{{/hasArgs}}\n{{^hasArgs}}\nexport async function {{{nodeName:string}}}({ messages, callbacks }: { messages?: any; callbacks?: any } = {}) {\n{{/hasArgs}}\n return runNode({\n ctx: __globalCtx,\n nodeName: \"{{{nodeName:string}}}\",\n data: { {{{argsStr:string}}} },\n messages,\n callbacks,\n });\n}\n";
2
2
  export type TemplateType = {
3
3
  hasArgs: boolean;
4
4
  nodeName: string;
5
+ typedArgsStr: string;
5
6
  argsStr: string;
6
7
  };
7
8
  declare const render: (args: TemplateType) => string;
@@ -3,10 +3,10 @@
3
3
  // Any manual changes will be lost.
4
4
  import { apply } from "typestache";
5
5
  export const template = `{{#hasArgs}}
6
- export async function {{{nodeName:string}}}({{{argsStr:string}}}, { messages, callbacks } = {}) {
6
+ export async function {{{nodeName:string}}}({{{typedArgsStr:string}}}, { messages, callbacks }: { messages?: any; callbacks?: any } = {}) {
7
7
  {{/hasArgs}}
8
8
  {{^hasArgs}}
9
- export async function {{{nodeName:string}}}({ messages, callbacks } = {}) {
9
+ export async function {{{nodeName:string}}}({ messages, callbacks }: { messages?: any; callbacks?: any } = {}) {
10
10
  {{/hasArgs}}
11
11
  return runNode({
12
12
  ctx: __globalCtx,
@@ -1,4 +1,4 @@
1
- export declare const template = "if (process.argv[1] === fileURLToPath(import.meta.url)) {\n try {\n const initialState = { messages: new ThreadStore(), data: {} };\n await main(initialState);\n } catch (__error) {\n console.error(`\nAgent crashed: ${__error.message}`);\n throw __error;\n }\n}\n";
1
+ export declare const template = "if (process.argv[1] === fileURLToPath(import.meta.url)) {\n try {\n const initialState = { messages: new ThreadStore(), data: {} };\n await main(initialState);\n } catch (__error: any) {\n console.error(`\nAgent crashed: ${__error.message}`);\n throw __error;\n }\n}\n";
2
2
  export type TemplateType = {};
3
3
  declare const render: (args: TemplateType) => string;
4
4
  export default render;
@@ -6,7 +6,7 @@ export const template = `if (process.argv[1] === fileURLToPath(import.meta.url))
6
6
  try {
7
7
  const initialState = { messages: new ThreadStore(), data: {} };
8
8
  await main(initialState);
9
- } catch (__error) {
9
+ } catch (__error: any) {
10
10
  console.error(\`\nAgent crashed: \${__error.message}\`);
11
11
  throw __error;
12
12
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agency-lang",
3
- "version": "0.0.77",
3
+ "version": "0.0.78",
4
4
  "description": "The Agency language",
5
5
  "main": "lib/index.js",
6
6
  "scripts": {
@@ -63,6 +63,7 @@
63
63
  "cli-highlight": "^2.1.11",
64
64
  "commander": "^14.0.3",
65
65
  "egonlog": "^0.0.2",
66
+ "esbuild": "^0.27.4",
66
67
  "nanoid": "^5.1.6",
67
68
  "ora": "^9.3.0",
68
69
  "prompts": "^2.4.2",
@@ -1,42 +0,0 @@
1
- import { AgencyConfig } from "../config.js";
2
- import { AgencyProgram } from "../types.js";
3
- /**
4
- * Generates .d.ts declaration files from Agency AST.
5
- *
6
- * Produces TypeScript declarations for:
7
- * - Type aliases
8
- * - `def` functions (tool-style: args array + metadata)
9
- * - `node` graph nodes (wrapper-style: named params + options)
10
- * - Tool definition exports (__nameTool, __nameToolParams)
11
- * - The default graph export
12
- * - Import re-exports
13
- */
14
- export declare class DeclarationGenerator {
15
- private program;
16
- private config;
17
- private typeAliases;
18
- private lines;
19
- constructor(program: AgencyProgram, config?: AgencyConfig);
20
- generate(): string;
21
- private collectTypeAliases;
22
- private emit;
23
- private typeToString;
24
- private emitHeader;
25
- private emitImports;
26
- private emitImportStatement;
27
- private emitImportNodeStatement;
28
- private emitImportToolStatement;
29
- private emitRuntimeImports;
30
- private emitTypeAliases;
31
- private emitReturnObjectType;
32
- private emitFunctions;
33
- private emitFunction;
34
- private emitGraphNodes;
35
- private emitGraphNode;
36
- private emitToolDefinitions;
37
- private emitDefaultExport;
38
- }
39
- /**
40
- * Generate a .d.ts declaration string from an Agency AST.
41
- */
42
- export declare function generateDeclarations(program: AgencyProgram, config?: AgencyConfig): string;
@@ -1,233 +0,0 @@
1
- import { variableTypeToString } from "./typescriptGenerator/typeToString.js";
2
- /**
3
- * Generates .d.ts declaration files from Agency AST.
4
- *
5
- * Produces TypeScript declarations for:
6
- * - Type aliases
7
- * - `def` functions (tool-style: args array + metadata)
8
- * - `node` graph nodes (wrapper-style: named params + options)
9
- * - Tool definition exports (__nameTool, __nameToolParams)
10
- * - The default graph export
11
- * - Import re-exports
12
- */
13
- export class DeclarationGenerator {
14
- program;
15
- config;
16
- typeAliases = {};
17
- lines = [];
18
- constructor(program, config = {}) {
19
- this.program = program;
20
- this.config = config;
21
- }
22
- generate() {
23
- this.lines = [];
24
- this.collectTypeAliases();
25
- this.emitHeader();
26
- this.emitImports();
27
- this.emitRuntimeImports();
28
- this.emitTypeAliases();
29
- this.emitReturnObjectType();
30
- this.emitFunctions();
31
- this.emitGraphNodes();
32
- this.emitToolDefinitions();
33
- this.emitDefaultExport();
34
- return this.lines.join("\n") + "\n";
35
- }
36
- collectTypeAliases() {
37
- for (const node of this.program.nodes) {
38
- if (node.type === "typeAlias") {
39
- this.typeAliases[node.aliasName] = node.aliasedType;
40
- }
41
- }
42
- }
43
- emit(line = "") {
44
- this.lines.push(line);
45
- }
46
- typeToString(vt) {
47
- return variableTypeToString(vt, this.typeAliases);
48
- }
49
- // --- Header ---
50
- emitHeader() {
51
- this.emit("// Auto-generated by Agency compiler");
52
- this.emit("// Do not edit manually");
53
- this.emit("");
54
- }
55
- // --- Imports ---
56
- emitImports() {
57
- let hasImports = false;
58
- for (const node of this.program.nodes) {
59
- if (node.type === "importStatement") {
60
- this.emitImportStatement(node);
61
- hasImports = true;
62
- }
63
- else if (node.type === "importNodeStatement") {
64
- this.emitImportNodeStatement(node);
65
- hasImports = true;
66
- }
67
- else if (node.type === "importToolStatement") {
68
- this.emitImportToolStatement(node);
69
- hasImports = true;
70
- }
71
- }
72
- if (hasImports) {
73
- this.emit("");
74
- }
75
- }
76
- emitImportStatement(node) {
77
- // Re-emit the import with .js extension (already transformed by compile pipeline)
78
- const parts = [];
79
- for (const name of node.importedNames) {
80
- if (name.type === "defaultImport") {
81
- parts.push(name.importedNames);
82
- }
83
- else if (name.type === "namedImport") {
84
- parts.push(`{ ${name.importedNames.join(", ")} }`);
85
- }
86
- else if (name.type === "namespaceImport") {
87
- parts.push(`* as ${name.importedNames}`);
88
- }
89
- }
90
- const modulePath = node.modulePath.replace(/\.agency$/, ".js");
91
- this.emit(`import ${parts.join(", ")} from "${modulePath}";`);
92
- }
93
- emitImportNodeStatement(node) {
94
- const modulePath = node.agencyFile.replace(/\.agency$/, ".js");
95
- this.emit(`import { ${node.importedNodes.join(", ")} } from "${modulePath}";`);
96
- }
97
- emitImportToolStatement(node) {
98
- const modulePath = node.agencyFile.replace(/\.agency$/, ".js");
99
- const toolExports = node.importedTools
100
- .map((t) => `__${t}Tool, __${t}ToolParams`)
101
- .join(", ");
102
- this.emit(`import { ${toolExports} } from "${modulePath}";`);
103
- }
104
- // --- Runtime Imports ---
105
- emitRuntimeImports() {
106
- const hasNodes = this.program.nodes.some((n) => n.type === "graphNode");
107
- if (!hasNodes)
108
- return;
109
- this.emit('import type { AgencyCallbacks } from "agency-lang/runtime";');
110
- this.emit("");
111
- }
112
- // --- Type Aliases ---
113
- emitTypeAliases() {
114
- const aliases = this.program.nodes.filter((n) => n.type === "typeAlias");
115
- if (aliases.length === 0)
116
- return;
117
- for (const alias of aliases) {
118
- this.emit(`export type ${alias.aliasName} = ${this.typeToString(alias.aliasedType)};`);
119
- }
120
- this.emit("");
121
- }
122
- // --- ReturnObject type ---
123
- emitReturnObjectType() {
124
- const hasNodes = this.program.nodes.some((n) => n.type === "graphNode");
125
- if (!hasNodes)
126
- return;
127
- this.emit("export interface TokenStats {");
128
- this.emit(" usage: {");
129
- this.emit(" inputTokens: number;");
130
- this.emit(" outputTokens: number;");
131
- this.emit(" cachedInputTokens: number;");
132
- this.emit(" totalTokens: number;");
133
- this.emit(" };");
134
- this.emit(" cost: {");
135
- this.emit(" inputCost: number;");
136
- this.emit(" outputCost: number;");
137
- this.emit(" totalCost: number;");
138
- this.emit(' currency: "USD";');
139
- this.emit(" };");
140
- this.emit("}");
141
- this.emit("");
142
- this.emit("export interface ReturnObject<T = any> {");
143
- this.emit(" messages: any;");
144
- this.emit(" data: T;");
145
- this.emit(" tokens: TokenStats;");
146
- this.emit("}");
147
- this.emit("");
148
- this.emit("export interface NodeOptions {");
149
- this.emit(" messages?: any[];");
150
- this.emit(" callbacks?: AgencyCallbacks;");
151
- this.emit("}");
152
- this.emit("");
153
- }
154
- // --- `def` functions ---
155
- emitFunctions() {
156
- const functions = this.program.nodes.filter((n) => n.type === "function");
157
- if (functions.length === 0)
158
- return;
159
- for (const fn of functions) {
160
- this.emitFunction(fn);
161
- }
162
- this.emit("");
163
- }
164
- emitFunction(fn) {
165
- const params = fn.parameters.map((p) => {
166
- const type = p.typeHint ? this.typeToString(p.typeHint) : "any";
167
- return `${p.name}: ${type}`;
168
- });
169
- params.push("__metadata?: Record<string, any>");
170
- const returnType = fn.returnType
171
- ? this.typeToString(fn.returnType)
172
- : "any";
173
- if (fn.docString) {
174
- this.emit(`/** ${fn.docString.value.trim()} */`);
175
- }
176
- this.emit(`export function ${fn.functionName}(${params.join(", ")}): Promise<${returnType}>;`);
177
- }
178
- // --- Graph nodes ---
179
- emitGraphNodes() {
180
- const nodes = this.program.nodes.filter((n) => n.type === "graphNode");
181
- if (nodes.length === 0)
182
- return;
183
- for (const node of nodes) {
184
- this.emitGraphNode(node);
185
- }
186
- this.emit("");
187
- }
188
- emitGraphNode(node) {
189
- // Graph nodes get a public wrapper: export async function name(param1, param2, { messages, callbacks } = {})
190
- // Returns ReturnObject<T>
191
- const params = node.parameters.map((p) => {
192
- const type = p.typeHint ? this.typeToString(p.typeHint) : "any";
193
- return `${p.name}: ${type}`;
194
- });
195
- params.push("options?: NodeOptions");
196
- const dataType = node.returnType
197
- ? this.typeToString(node.returnType)
198
- : "undefined";
199
- this.emit(`export function ${node.nodeName}(${params.join(", ")}): Promise<ReturnObject<${dataType}>>;`);
200
- }
201
- // --- Tool definitions ---
202
- emitToolDefinitions() {
203
- const functions = this.program.nodes.filter((n) => n.type === "function");
204
- if (functions.length === 0)
205
- return;
206
- for (const fn of functions) {
207
- const paramNames = fn.parameters.map((p) => `"${p.name}"`);
208
- this.emit("");
209
- this.emit(`export const __${fn.functionName}Tool: {`);
210
- this.emit(` name: "${fn.functionName}";`);
211
- this.emit(" description: string;");
212
- this.emit(" schema: import('zod').ZodType;");
213
- this.emit("};");
214
- this.emit(`export const __${fn.functionName}ToolParams: [${paramNames.join(", ")}];`);
215
- }
216
- this.emit("");
217
- }
218
- // --- Default export ---
219
- emitDefaultExport() {
220
- const hasNodes = this.program.nodes.some((n) => n.type === "graphNode");
221
- if (!hasNodes)
222
- return;
223
- this.emit("declare const graph: any;");
224
- this.emit("export default graph;");
225
- }
226
- }
227
- /**
228
- * Generate a .d.ts declaration string from an Agency AST.
229
- */
230
- export function generateDeclarations(program, config = {}) {
231
- const generator = new DeclarationGenerator(program, config);
232
- return generator.generate();
233
- }
@@ -1 +0,0 @@
1
- export {};
@@ -1,287 +0,0 @@
1
- import { describe, it, expect } from "vitest";
2
- import { generateDeclarations } from "./declarationGenerator.js";
3
- describe("DeclarationGenerator", () => {
4
- it("should generate declarations for a def function", () => {
5
- const program = {
6
- type: "agencyProgram",
7
- nodes: [
8
- {
9
- type: "function",
10
- functionName: "add",
11
- parameters: [
12
- {
13
- type: "functionParameter",
14
- name: "x",
15
- typeHint: { type: "primitiveType", value: "number" },
16
- },
17
- {
18
- type: "functionParameter",
19
- name: "y",
20
- typeHint: { type: "primitiveType", value: "number" },
21
- },
22
- ],
23
- body: [],
24
- returnType: { type: "primitiveType", value: "number" },
25
- },
26
- ],
27
- };
28
- const result = generateDeclarations(program);
29
- expect(result).toContain("export function add(x: number, y: number, __metadata?: Record<string, any>): Promise<number>;");
30
- expect(result).toContain('export const __addTool:');
31
- expect(result).toContain('export const __addToolParams: ["x", "y"];');
32
- });
33
- it("should generate declarations for a graph node", () => {
34
- const program = {
35
- type: "agencyProgram",
36
- nodes: [
37
- {
38
- type: "graphNode",
39
- nodeName: "greet",
40
- parameters: [
41
- {
42
- type: "functionParameter",
43
- name: "name",
44
- typeHint: { type: "primitiveType", value: "string" },
45
- },
46
- ],
47
- body: [],
48
- returnType: { type: "primitiveType", value: "string" },
49
- },
50
- ],
51
- };
52
- const result = generateDeclarations(program);
53
- expect(result).toContain("export function greet(name: string, options?: NodeOptions): Promise<ReturnObject<string>>;");
54
- expect(result).toContain("export interface ReturnObject<T = any>");
55
- expect(result).toContain("export interface NodeOptions");
56
- expect(result).toContain(" callbacks?: AgencyCallbacks;");
57
- expect(result).toContain("export interface TokenStats");
58
- expect(result).toContain('import type { AgencyCallbacks } from "agency-lang/runtime";');
59
- expect(result).toContain("export default graph;");
60
- });
61
- it("should generate declarations for type aliases", () => {
62
- const program = {
63
- type: "agencyProgram",
64
- nodes: [
65
- {
66
- type: "typeAlias",
67
- aliasName: "UserId",
68
- aliasedType: { type: "primitiveType", value: "string" },
69
- },
70
- {
71
- type: "typeAlias",
72
- aliasName: "Status",
73
- aliasedType: {
74
- type: "unionType",
75
- types: [
76
- { type: "stringLiteralType", value: "active" },
77
- { type: "stringLiteralType", value: "inactive" },
78
- ],
79
- },
80
- },
81
- ],
82
- };
83
- const result = generateDeclarations(program);
84
- expect(result).toContain("export type UserId = string;");
85
- expect(result).toContain('export type Status = "active" | "inactive";');
86
- });
87
- it("should handle functions without type hints", () => {
88
- const program = {
89
- type: "agencyProgram",
90
- nodes: [
91
- {
92
- type: "function",
93
- functionName: "doStuff",
94
- parameters: [
95
- { type: "functionParameter", name: "input" },
96
- ],
97
- body: [],
98
- },
99
- ],
100
- };
101
- const result = generateDeclarations(program);
102
- expect(result).toContain("export function doStuff(input: any, __metadata?: Record<string, any>): Promise<any>;");
103
- });
104
- it("should handle graph nodes without return type", () => {
105
- const program = {
106
- type: "agencyProgram",
107
- nodes: [
108
- {
109
- type: "graphNode",
110
- nodeName: "main",
111
- parameters: [],
112
- body: [],
113
- },
114
- ],
115
- };
116
- const result = generateDeclarations(program);
117
- expect(result).toContain("export function main(options?: NodeOptions): Promise<ReturnObject<undefined>>;");
118
- });
119
- it("should handle complex parameter types", () => {
120
- const program = {
121
- type: "agencyProgram",
122
- nodes: [
123
- {
124
- type: "function",
125
- functionName: "process",
126
- parameters: [
127
- {
128
- type: "functionParameter",
129
- name: "items",
130
- typeHint: {
131
- type: "arrayType",
132
- elementType: { type: "primitiveType", value: "number" },
133
- },
134
- },
135
- {
136
- type: "functionParameter",
137
- name: "mode",
138
- typeHint: {
139
- type: "unionType",
140
- types: [
141
- { type: "stringLiteralType", value: "fast" },
142
- { type: "stringLiteralType", value: "slow" },
143
- ],
144
- },
145
- },
146
- ],
147
- body: [],
148
- returnType: {
149
- type: "objectType",
150
- properties: [
151
- {
152
- key: "count",
153
- value: { type: "primitiveType", value: "number" },
154
- },
155
- {
156
- key: "result",
157
- value: { type: "primitiveType", value: "string" },
158
- },
159
- ],
160
- },
161
- },
162
- ],
163
- };
164
- const result = generateDeclarations(program);
165
- expect(result).toContain('export function process(items: number[], mode: "fast" | "slow", __metadata?: Record<string, any>): Promise<{ count: number; result: string }>;');
166
- });
167
- it("should include docstrings as JSDoc", () => {
168
- const program = {
169
- type: "agencyProgram",
170
- nodes: [
171
- {
172
- type: "function",
173
- functionName: "greet",
174
- parameters: [
175
- {
176
- type: "functionParameter",
177
- name: "name",
178
- typeHint: { type: "primitiveType", value: "string" },
179
- },
180
- ],
181
- body: [],
182
- docString: { type: "docString", value: "Greets a person by name" },
183
- },
184
- ],
185
- };
186
- const result = generateDeclarations(program);
187
- expect(result).toContain("/** Greets a person by name */");
188
- });
189
- it("should handle imports", () => {
190
- const program = {
191
- type: "agencyProgram",
192
- nodes: [
193
- {
194
- type: "importStatement",
195
- importedNames: [
196
- { type: "namedImport", importedNames: ["foo", "bar"] },
197
- ],
198
- modulePath: "./utils.js",
199
- },
200
- {
201
- type: "importNodeStatement",
202
- importedNodes: ["analyzeData"],
203
- agencyFile: "./analyzer.agency",
204
- },
205
- {
206
- type: "importToolStatement",
207
- importedTools: ["search"],
208
- agencyFile: "./tools.agency",
209
- },
210
- ],
211
- };
212
- const result = generateDeclarations(program);
213
- expect(result).toContain('import { foo, bar } from "./utils.js";');
214
- expect(result).toContain('import { analyzeData } from "./analyzer.js";');
215
- expect(result).toContain('import { __searchTool, __searchToolParams } from "./tools.js";');
216
- });
217
- it("should not emit ReturnObject/NodeOptions/default export when there are no graph nodes", () => {
218
- const program = {
219
- type: "agencyProgram",
220
- nodes: [
221
- {
222
- type: "function",
223
- functionName: "add",
224
- parameters: [],
225
- body: [],
226
- returnType: { type: "primitiveType", value: "number" },
227
- },
228
- ],
229
- };
230
- const result = generateDeclarations(program);
231
- expect(result).not.toContain("ReturnObject");
232
- expect(result).not.toContain("NodeOptions");
233
- expect(result).not.toContain("AgencyCallbacks");
234
- expect(result).not.toContain("export default");
235
- });
236
- it("should handle a full program with multiple features", () => {
237
- const program = {
238
- type: "agencyProgram",
239
- nodes: [
240
- {
241
- type: "typeAlias",
242
- aliasName: "Name",
243
- aliasedType: { type: "primitiveType", value: "string" },
244
- },
245
- {
246
- type: "function",
247
- functionName: "formatName",
248
- parameters: [
249
- {
250
- type: "functionParameter",
251
- name: "name",
252
- typeHint: { type: "typeAliasVariable", aliasName: "Name" },
253
- },
254
- ],
255
- body: [],
256
- returnType: { type: "primitiveType", value: "string" },
257
- docString: { type: "docString", value: "Formats a name" },
258
- },
259
- {
260
- type: "graphNode",
261
- nodeName: "main",
262
- parameters: [
263
- {
264
- type: "functionParameter",
265
- name: "input",
266
- typeHint: { type: "primitiveType", value: "string" },
267
- },
268
- ],
269
- body: [],
270
- returnType: { type: "primitiveType", value: "string" },
271
- },
272
- ],
273
- };
274
- const result = generateDeclarations(program);
275
- // Has type alias
276
- expect(result).toContain("export type Name = string;");
277
- // Has function with docstring
278
- expect(result).toContain("/** Formats a name */");
279
- expect(result).toContain("export function formatName(name: Name, __metadata?: Record<string, any>): Promise<string>;");
280
- // Has node
281
- expect(result).toContain("export function main(input: string, options?: NodeOptions): Promise<ReturnObject<string>>;");
282
- // Has tool definition
283
- expect(result).toContain("export const __formatNameTool:");
284
- // Has default export
285
- expect(result).toContain("export default graph;");
286
- });
287
- });