agency-lang 0.0.102 → 0.0.104

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 (91) hide show
  1. package/dist/lib/agents/agency-agent/agent.agency +4 -5
  2. package/dist/lib/backends/agencyGenerator.d.ts +1 -6
  3. package/dist/lib/backends/agencyGenerator.js +2 -28
  4. package/dist/lib/backends/typescriptBuilder.d.ts +32 -12
  5. package/dist/lib/backends/typescriptBuilder.integration.test.js +11 -9
  6. package/dist/lib/backends/typescriptBuilder.js +329 -306
  7. package/dist/lib/cli/util.js +1 -2
  8. package/dist/lib/config.js +0 -2
  9. package/dist/lib/debugger/driver.js +1 -1
  10. package/dist/lib/importPaths.js +1 -8
  11. package/dist/lib/importPaths.test.js +3 -13
  12. package/dist/lib/ir/builders.d.ts +4 -1
  13. package/dist/lib/ir/builders.js +3 -0
  14. package/dist/lib/ir/prettyPrint.js +14 -0
  15. package/dist/lib/ir/prettyPrint.test.js +3 -0
  16. package/dist/lib/ir/tsIR.d.ts +12 -2
  17. package/dist/lib/parser.js +2 -2
  18. package/dist/lib/parsers/importStatement.test.js +15 -257
  19. package/dist/lib/parsers/parsers.d.ts +1 -4
  20. package/dist/lib/parsers/parsers.js +3 -25
  21. package/dist/lib/preprocessors/importResolver.js +12 -47
  22. package/dist/lib/preprocessors/importResolver.test.js +35 -42
  23. package/dist/lib/preprocessors/typescriptPreprocessor.core.test.js +0 -230
  24. package/dist/lib/preprocessors/typescriptPreprocessor.d.ts +0 -4
  25. package/dist/lib/preprocessors/typescriptPreprocessor.js +51 -56
  26. package/dist/lib/programInfo.d.ts +1 -2
  27. package/dist/lib/programInfo.js +5 -24
  28. package/dist/lib/programInfo.test.js +1 -6
  29. package/dist/lib/runtime/agencyFunction.d.ts +44 -0
  30. package/dist/lib/runtime/agencyFunction.js +101 -0
  31. package/dist/lib/runtime/agencyFunction.test.js +146 -0
  32. package/dist/lib/runtime/builtins.d.ts +0 -14
  33. package/dist/lib/runtime/builtins.js +0 -5
  34. package/dist/lib/runtime/hooks.d.ts +1 -1
  35. package/dist/lib/runtime/index.d.ts +4 -3
  36. package/dist/lib/runtime/index.js +3 -1
  37. package/dist/lib/runtime/mcp/mcp.integration.test.js +5 -5
  38. package/dist/lib/runtime/mcp/mcpConnection.test.js +1 -1
  39. package/dist/lib/runtime/mcp/mcpManager.test.js +1 -1
  40. package/dist/lib/runtime/mcp/toolAdapter.d.ts +2 -2
  41. package/dist/lib/runtime/mcp/toolAdapter.js +22 -17
  42. package/dist/lib/runtime/mcp/toolAdapter.test.js +12 -12
  43. package/dist/lib/runtime/prompt.d.ts +0 -6
  44. package/dist/lib/runtime/prompt.js +27 -29
  45. package/dist/lib/runtime/revivers/functionRefReviver.d.ts +12 -0
  46. package/dist/lib/runtime/revivers/functionRefReviver.js +36 -0
  47. package/dist/lib/runtime/revivers/functionRefReviver.test.d.ts +1 -0
  48. package/dist/lib/runtime/revivers/functionRefReviver.test.js +150 -0
  49. package/dist/lib/runtime/revivers/index.d.ts +2 -0
  50. package/dist/lib/runtime/revivers/index.js +14 -2
  51. package/dist/lib/runtime/state/context.js +7 -1
  52. package/dist/lib/symbolTable.js +0 -3
  53. package/dist/lib/templates/backends/typescriptGenerator/builtinToolRegistration.d.ts +9 -0
  54. package/dist/lib/templates/backends/typescriptGenerator/builtinToolRegistration.js +15 -0
  55. package/dist/lib/templates/backends/typescriptGenerator/forkBlockSetup.d.ts +2 -1
  56. package/dist/lib/templates/backends/typescriptGenerator/forkBlockSetup.js +1 -0
  57. package/dist/lib/templates/backends/typescriptGenerator/imports.d.ts +1 -1
  58. package/dist/lib/templates/backends/typescriptGenerator/imports.js +17 -8
  59. package/dist/lib/templates/ir/agencyFunctionWrap.d.ts +9 -0
  60. package/dist/lib/templates/ir/agencyFunctionWrap.js +9 -0
  61. package/dist/lib/types/function.d.ts +2 -3
  62. package/dist/lib/types/importStatement.d.ts +1 -0
  63. package/dist/lib/types.d.ts +3 -5
  64. package/dist/lib/types.js +0 -1
  65. package/dist/lib/utils/node.js +1 -6
  66. package/dist/lib/version.d.ts +1 -1
  67. package/dist/lib/version.js +1 -1
  68. package/package.json +3 -2
  69. package/stdlib/_builtins.js +134 -0
  70. package/stdlib/_math.js +9 -0
  71. package/stdlib/agent.js +85 -214
  72. package/stdlib/array.js +376 -407
  73. package/stdlib/clipboard.js +68 -196
  74. package/stdlib/fs.js +190 -287
  75. package/stdlib/http.js +90 -196
  76. package/stdlib/index.js +316 -304
  77. package/stdlib/math.agency +7 -0
  78. package/stdlib/math.js +232 -215
  79. package/stdlib/object.js +184 -260
  80. package/stdlib/path.js +170 -287
  81. package/stdlib/shell.js +214 -296
  82. package/stdlib/speech.js +98 -200
  83. package/stdlib/strategy.js +194 -260
  84. package/stdlib/system.js +149 -254
  85. package/stdlib/ui.js +271 -399
  86. package/stdlib/weather.js +97 -215
  87. package/stdlib/wikipedia.js +97 -215
  88. package/dist/lib/debugger/hotReload.d.ts +0 -11
  89. package/dist/lib/debugger/hotReload.js +0 -73
  90. package/dist/lib/parsers/tools.test.js +0 -281
  91. /package/dist/lib/{parsers/tools.test.d.ts → runtime/agencyFunction.test.d.ts} +0 -0
@@ -1,6 +1,6 @@
1
- import tool { addTask, listTasks, markTaskDone } from "./subagents/task.agency"
2
- import tool { writeToPlan, readPlan } from "./subagents/plan.agency"
3
- import tool { writeCode, appendCode, readCode } from "./subagents/code.agency"
1
+ import { addTask, listTasks, markTaskDone } from "./subagents/task.agency"
2
+ import { writeToPlan, readPlan } from "./subagents/plan.agency"
3
+ import { writeCode, appendCode, readCode } from "./subagents/code.agency"
4
4
  import { syntaxHighlight } from "../../utils/agentUtils.js"
5
5
  // todo allow this
6
6
  // import { Plan } from "./subagents/plan.agency"
@@ -130,8 +130,7 @@ node plan(mode, existingCode, existingFilename: string | null) {
130
130
  type: "start"
131
131
  }
132
132
  while (nextAction.type != "done") {
133
- uses writeToPlan, readPlan, print
134
- nextAction: NextAction = llm("${userMsg}", config)
133
+ nextAction: NextAction = llm("${userMsg}", { ...config, tools: [writeToPlan, readPlan, print] })
135
134
  if (nextAction.type == "askUser") {
136
135
  userMsg = input("${nextAction.question} ")
137
136
  }
@@ -4,10 +4,9 @@ import { AgencyArray, AgencyObject } from "../types/dataStructures.js";
4
4
  import { FunctionCall, FunctionDefinition } from "../types/function.js";
5
5
  import { GraphNodeDefinition, Visibility } from "../types/graphNode.js";
6
6
  import { IfElse } from "../types/ifElse.js";
7
- import { ImportNameType, ImportNodeStatement, ImportStatement, ImportToolStatement } from "../types/importStatement.js";
7
+ import { ImportNameType, ImportNodeStatement, ImportStatement } from "../types/importStatement.js";
8
8
  import { MatchBlock } from "../types/matchBlock.js";
9
9
  import { ReturnStatement } from "../types/returnStatement.js";
10
- import { UsesTool } from "../types/tools.js";
11
10
  import { ForLoop } from "../types/forLoop.js";
12
11
  import { WhileLoop } from "../types/whileLoop.js";
13
12
  import { AgencyConfig } from "../config.js";
@@ -26,7 +25,6 @@ export declare class AgencyGenerator {
26
25
  protected functionsUsed: Set<string>;
27
26
  protected importStatements: string[];
28
27
  protected importedNodes: ImportNodeStatement[];
29
- protected importedTools: ImportToolStatement[];
30
28
  protected functionDefinitions: Record<string, FunctionDefinition>;
31
29
  protected currentScope: Scope[];
32
30
  protected program: AgencyProgram | null;
@@ -54,7 +52,6 @@ export declare class AgencyGenerator {
54
52
  protected startScope(scope: Scope): void;
55
53
  protected endScope(): void;
56
54
  protected getCurrentScope(): Scope;
57
- protected isImportedTool(functionName: string): boolean;
58
55
  protected isAgencyFunction(functionName: string, context: "valueAccess" | "functionArg" | "topLevelStatement"): boolean;
59
56
  private indent;
60
57
  private increaseIndent;
@@ -88,13 +85,11 @@ export declare class AgencyGenerator {
88
85
  protected processImportStatement(node: ImportStatement): string;
89
86
  protected processImportNameType(node: ImportNameType): string;
90
87
  protected processImportNodeStatement(node: ImportNodeStatement): string;
91
- protected processImportToolStatement(node: ImportToolStatement): string;
92
88
  protected visibilityToString(vis: Visibility): string;
93
89
  protected processGraphNode(node: GraphNodeDefinition): string;
94
90
  protected processClassDefinition(node: ClassDefinition): string;
95
91
  protected processNewExpression(node: NewExpression): string;
96
92
  protected processTool(node: FunctionDefinition): string;
97
- protected processUsesTool(node: UsesTool): string;
98
93
  protected processNewLine(_node: NewLine): string;
99
94
  protected processMessageThread(node: MessageThread): string;
100
95
  protected processHandleBlock(node: HandleBlock): string;
@@ -1,4 +1,3 @@
1
- import { getImportedToolNames, } from "../types/importStatement.js";
2
1
  import { variableTypeToString } from "./typescriptGenerator/typeToString.js";
3
2
  import { mergeDeep } from "../utils.js";
4
3
  import { PRECEDENCE, } from "../types/binop.js";
@@ -11,7 +10,6 @@ export class AgencyGenerator {
11
10
  functionsUsed = new Set();
12
11
  importStatements = [];
13
12
  importedNodes = [];
14
- importedTools = [];
15
13
  functionDefinitions = {};
16
14
  currentScope = [{ type: "global" }];
17
15
  program = null;
@@ -41,14 +39,11 @@ export class AgencyGenerator {
41
39
  this.processGraphNodeName(node);
42
40
  }
43
41
  }
44
- // Pass 3: Collect all node and tool imports
42
+ // Pass 3: Collect all node imports
45
43
  for (const node of program.nodes) {
46
44
  if (node.type === "importNodeStatement") {
47
45
  this.importedNodes.push(node);
48
46
  }
49
- else if (node.type === "importToolStatement") {
50
- this.importedTools.push(node);
51
- }
52
47
  }
53
48
  // Pass 4: Generate code for tools
54
49
  for (const node of program.nodes) {
@@ -152,17 +147,12 @@ export class AgencyGenerator {
152
147
  return this.processAgencyObject(node);
153
148
  case "graphNode":
154
149
  return this.processGraphNode(node);
155
- case "usesTool":
156
- return this.processUsesTool(node);
157
150
  case "importStatement":
158
151
  this.importStatements.push(this.processImportStatement(node));
159
152
  return "";
160
153
  case "importNodeStatement":
161
154
  this.importStatements.push(this.processImportNodeStatement(node));
162
155
  return "";
163
- case "importToolStatement":
164
- this.importStatements.push(this.processImportToolStatement(node));
165
- return "";
166
156
  case "forLoop":
167
157
  return this.processForLoop(node);
168
158
  case "whileLoop":
@@ -226,17 +216,11 @@ export class AgencyGenerator {
226
216
  getCurrentScope() {
227
217
  return this.currentScope[this.currentScope.length - 1];
228
218
  }
229
- isImportedTool(functionName) {
230
- return this.importedTools
231
- .flatMap(getImportedToolNames)
232
- .includes(functionName);
233
- }
234
219
  isAgencyFunction(functionName, context) {
235
220
  if (context === "valueAccess") {
236
221
  return false;
237
222
  }
238
- return (!!this.functionDefinitions[functionName] ||
239
- this.isImportedTool(functionName));
223
+ return !!this.functionDefinitions[functionName];
240
224
  }
241
225
  // Indent helpers
242
226
  indent(level = this.indentLevel) {
@@ -648,13 +632,6 @@ export class AgencyGenerator {
648
632
  processImportNodeStatement(node) {
649
633
  return `import node { ${node.importedNodes.join(", ")} } from "${node.agencyFile}"`;
650
634
  }
651
- processImportToolStatement(node) {
652
- const toolNames = node.importedTools.flatMap((n) => n.importedNames.map((name) => {
653
- const alias = n.aliases[name];
654
- return alias ? `${name} as ${alias}` : name;
655
- }));
656
- return `import tool { ${toolNames.join(", ")} } from "${node.agencyFile}"`;
657
- }
658
635
  visibilityToString(vis) {
659
636
  switch (vis) {
660
637
  case "public":
@@ -748,9 +725,6 @@ export class AgencyGenerator {
748
725
  processTool(node) {
749
726
  return "";
750
727
  }
751
- processUsesTool(node) {
752
- return this.indentStr(`uses ${node.toolNames.join(", ")}`);
753
- }
754
728
  processNewLine(_node) {
755
729
  return "";
756
730
  }
@@ -6,6 +6,7 @@ export declare class TypeScriptBuilder {
6
6
  private generatedStatements;
7
7
  private generatedTypeAliases;
8
8
  private importStatements;
9
+ private toolRegistrations;
9
10
  private functionsUsed;
10
11
  private currentScope;
11
12
  private agencyConfig;
@@ -65,9 +66,17 @@ export declare class TypeScriptBuilder {
65
66
  private checkpointOpts;
66
67
  private getVisibleTypeAliases;
67
68
  private forkBranchSetup;
68
- private isImportedTool;
69
- private static RUNTIME_STATEFUL_FUNCTIONS;
69
+ private static TEMPLATE_FUNCTIONS;
70
+ /**
71
+ * Returns true if the function should be called via .invoke() (AgencyFunction).
72
+ * The default is true — everything goes through .invoke() UNLESS it's a known
73
+ * non-Agency function (TS import, internal __ prefixed helper, or template function).
74
+ */
70
75
  private isAgencyFunction;
76
+ private _plainTsImportNames;
77
+ private _agencyImportNames;
78
+ private isPlainTsImport;
79
+ private _buildImportNameSets;
71
80
  private isGraphNode;
72
81
  private isImpureImportedFunction;
73
82
  private containsImpureCall;
@@ -98,8 +107,6 @@ export declare class TypeScriptBuilder {
98
107
  * 1. Pad omitted optional args (those with defaults) with null
99
108
  * 2. Wrap extra args into an array for variadic params
100
109
  */
101
- private getCalleeParams;
102
- private adjustCallArgs;
103
110
  private processNode;
104
111
  private processKeyword;
105
112
  private processTypeAlias;
@@ -139,13 +146,20 @@ export declare class TypeScriptBuilder {
139
146
  private processMatchBlockWithSteps;
140
147
  private processImportStatement;
141
148
  private processImportNodeStatement;
142
- private processImportToolStatement;
143
- private processUsesTool;
144
- private processTool;
145
- private buildToolRegistryEntry;
146
149
  /**
147
- * Generate __toolRegistry mapping function names to their tool definitions and handlers.
148
- * The tool() function is defined in imports.mustache and closes over __toolRegistry.
150
+ * Process a block argument into a wrapped AgencyFunction TsNode.
151
+ * Shared by generateFunctionCallExpression and buildCallDescriptor.
152
+ */
153
+ private processBlockArgument;
154
+ /**
155
+ * Build a tool definition TsNode for an Agency function.
156
+ * Returns ts.id("null") if the function has no parameters (no schema needed for tools).
157
+ */
158
+ private buildToolDefinition;
159
+ /**
160
+ * Generate __toolRegistry as an empty object. AgencyFunction.create() calls
161
+ * register local functions into it. Imported and builtin tools are registered
162
+ * here directly. The reviver is bound at the end.
149
163
  */
150
164
  private generateToolRegistry;
151
165
  /**
@@ -165,6 +179,13 @@ export declare class TypeScriptBuilder {
165
179
  private processFunctionCallAsStatement;
166
180
  private processFunctionCall;
167
181
  private generateFunctionCallExpression;
182
+ private emitAgencyFunctionCall;
183
+ private emitDirectFunctionCall;
184
+ /**
185
+ * Build a CallType descriptor TsNode for an Agency function call.
186
+ * Determines whether to emit positional or named call type based on arguments.
187
+ */
188
+ private buildCallDescriptor;
168
189
  private processForkCall;
169
190
  private generateNodeCallExpression;
170
191
  private processGraphNode;
@@ -185,7 +206,7 @@ export declare class TypeScriptBuilder {
185
206
  private processMessageThread;
186
207
  private processBlockPlain;
187
208
  private processNodeInGlobalInit;
188
- private buildBuiltinHandlerArrow;
209
+ private buildHandlerArrow;
189
210
  private processHandleBlockWithSteps;
190
211
  private processWithModifier;
191
212
  /** In debugger mode, insert debuggerStatement nodes before each
@@ -211,7 +232,6 @@ export declare class TypeScriptBuilder {
211
232
  * Used by pipe to get the receiver for a method call.
212
233
  */
213
234
  private processValueAccessPartial;
214
- private buildPipeStateArgs;
215
235
  private processBodyAsParts;
216
236
  private generateBuiltins;
217
237
  private generateImports;
@@ -94,21 +94,23 @@ describe("TypeScript Builder Integration Tests", () => {
94
94
  });
95
95
  });
96
96
  describe("Named argument validation", () => {
97
- it("should throw when skipping a required argument", () => {
97
+ // Named arg validation is now done at runtime by AgencyFunction.invoke(),
98
+ // not at compile time. These tests verify the builder compiles successfully.
99
+ it("should compile when skipping a required argument (validated at runtime)", () => {
98
100
  expect(() => generateWithBuilder(`
99
101
  def greet(name: string, greeting: string = "Hello") {
100
102
  print(name)
101
103
  }
102
104
  greet(greeting: "Hi")
103
- `)).toThrow("Missing required argument 'name' in call to 'greet'");
105
+ `)).not.toThrow();
104
106
  });
105
- it("should throw on unknown named argument", () => {
107
+ it("should compile with unknown named argument (validated at runtime)", () => {
106
108
  expect(() => generateWithBuilder(`
107
109
  def foo(a: string) {
108
110
  print(a)
109
111
  }
110
112
  foo(a: "hi", extra: "oops")
111
- `)).toThrow("Unknown named argument 'extra' in call to 'foo'");
113
+ `)).not.toThrow();
112
114
  });
113
115
  it("should accept correct named arguments", () => {
114
116
  expect(() => generateWithBuilder(`
@@ -126,21 +128,21 @@ def greet(name: string, greeting: string = "Hello") {
126
128
  greet(greeting: "Hi", name: "world")
127
129
  `)).not.toThrow();
128
130
  });
129
- it("should throw on positional after named", () => {
131
+ it("should compile with positional after named (validated at runtime)", () => {
130
132
  expect(() => generateWithBuilder(`
131
133
  def greet(name: string, greeting: string = "Hello") {
132
134
  print(name)
133
135
  }
134
136
  greet(name: "world", "Hi")
135
- `)).toThrow("Positional argument cannot follow a named argument");
137
+ `)).not.toThrow();
136
138
  });
137
- it("should throw on duplicate named argument", () => {
139
+ it("should compile with duplicate named argument (validated at runtime)", () => {
138
140
  expect(() => generateWithBuilder(`
139
141
  def greet(name: string, greeting: string = "Hello") {
140
142
  print(name)
141
143
  }
142
144
  greet(name: "world", name: "other")
143
- `)).toThrow("Duplicate named argument 'name' in call to 'greet'");
145
+ `)).not.toThrow();
144
146
  });
145
147
  it("should accept named args with block parameters", () => {
146
148
  expect(() => generateWithBuilder(`
@@ -203,7 +205,7 @@ ${safeKeyword}def ${funcName}(id: string, shouldSave: boolean, items: string[]):
203
205
  }
204
206
  `;
205
207
  const output = generateWithBuilder(code);
206
- const funcMatch = output.match(new RegExp(`async function ${funcName}\\([\\s\\S]*?finally`));
208
+ const funcMatch = output.match(new RegExp(`async function __${funcName}_impl\\([\\s\\S]*?finally`));
207
209
  expect(funcMatch).toBeTruthy();
208
210
  if (emitsRetryableFalse) {
209
211
  expect(funcMatch[0]).toContain("__retryable = false");