agency-lang 0.19.3 → 0.20.0

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 (51) hide show
  1. package/dist/lib/agentTarget.d.ts +3 -0
  2. package/dist/lib/agentTarget.js +7 -4
  3. package/dist/lib/agents/agency-agent/agent.js +9 -2
  4. package/dist/lib/agents/agency-agent/brains/coordinator/prompts/codeSample.js +9 -2
  5. package/dist/lib/agents/eval/goalJudge.js +9 -2
  6. package/dist/lib/agents/eval/judge.js +31 -2
  7. package/dist/lib/agents/eval/judgePairwise.js +31 -2
  8. package/dist/lib/agents/eval/rubricJudge.js +9 -2
  9. package/dist/lib/agents/optimize/gepaReflect.js +31 -2
  10. package/dist/lib/agents/optimize/mutatePrompt.js +31 -2
  11. package/dist/lib/agents/policy/agent.js +9 -2
  12. package/dist/lib/agents/review/agent.js +9 -2
  13. package/dist/lib/backends/typescriptBuilder.js +22 -21
  14. package/dist/lib/cli/childEnv.d.ts +2 -0
  15. package/dist/lib/cli/childEnv.js +10 -5
  16. package/dist/lib/cli/commands.d.ts +3 -1
  17. package/dist/lib/cli/commands.js +4 -2
  18. package/dist/lib/cli/localServe.d.ts +34 -12
  19. package/dist/lib/cli/localServe.js +173 -45
  20. package/dist/lib/cli/mlxServer.d.ts +5 -3
  21. package/dist/lib/cli/mlxServer.js +24 -9
  22. package/dist/lib/cli/mlxSpeechRules.py +261 -0
  23. package/dist/lib/cli/mlxSpeechServer.py +328 -0
  24. package/dist/lib/cli/serveLog.d.ts +17 -2
  25. package/dist/lib/cli/serveLog.js +23 -4
  26. package/dist/lib/constants.d.ts +6 -0
  27. package/dist/lib/constants.js +6 -0
  28. package/dist/lib/runtime/cliEntry.d.ts +4 -1
  29. package/dist/lib/runtime/cliEntry.js +14 -2
  30. package/dist/lib/stdlib/localModels.d.ts +6 -0
  31. package/dist/lib/stdlib/localModels.js +50 -9
  32. package/dist/lib/stdlib/modelCatalog.d.ts +5 -1
  33. package/dist/lib/stdlib/modelCatalog.js +32 -0
  34. package/dist/lib/stdlib/speech.d.ts +12 -0
  35. package/dist/lib/stdlib/speech.js +175 -31
  36. package/dist/lib/stdlib/speechPieces.d.ts +10 -0
  37. package/dist/lib/stdlib/speechPieces.js +44 -0
  38. package/dist/lib/stdlib/wavFile.d.ts +5 -0
  39. package/dist/lib/stdlib/wavFile.js +61 -0
  40. package/dist/scripts/agency.js +11 -6
  41. package/package.json +2 -2
  42. package/stdlib/agents/agency/coding.js +31 -2
  43. package/stdlib/agents/agency/review.js +31 -2
  44. package/stdlib/agents/researcher.js +31 -2
  45. package/stdlib/agents/typescript/review.js +31 -2
  46. package/stdlib/agents/writing/review.js +31 -2
  47. package/stdlib/agents/writing/rewrite.js +31 -2
  48. package/stdlib/docs/cli/local.md +41 -10
  49. package/stdlib/docs/stdlib/speech.md +70 -8
  50. package/stdlib/speech.agency +49 -0
  51. package/stdlib/speech.js +265 -3
@@ -3,6 +3,9 @@
3
3
  * entry point: `path`, `path:node`, or a directory (meaning its main.agency).
4
4
  * Consumed by the eval commands, the optimizer, and `agency test`.
5
5
  */
6
+ /** Split `path:node` on its last colon, but only when the text after it is a
7
+ * node name, so a path with a colon in it (`C:\agents\a.agency`) stays whole.
8
+ * `nodeName` is "" when the target names no node. */
6
9
  export declare function parseTarget(target: string): {
7
10
  filename: string;
8
11
  nodeName: string;
@@ -2,19 +2,22 @@ import * as fs from "fs";
2
2
  import * as path from "path";
3
3
  import { MISSING_INPUT_PLACEHOLDER_ERROR, INPUT_PLACEHOLDER, OLD_TASK_PLACEHOLDER, OLD_TASK_PLACEHOLDER_ERROR, tokenizeCommand, } from "./eval/run/commandLine.js";
4
4
  import { parseAgency } from "./parser.js";
5
+ import { LEGAL_IDENTIFIER } from "./parsers/parsers.js";
5
6
  /**
6
7
  * How an agent target string is parsed and resolved. A target names an agent
7
8
  * entry point: `path`, `path:node`, or a directory (meaning its main.agency).
8
9
  * Consumed by the eval commands, the optimizer, and `agency test`.
9
10
  */
11
+ /** Split `path:node` on its last colon, but only when the text after it is a
12
+ * node name, so a path with a colon in it (`C:\agents\a.agency`) stays whole.
13
+ * `nodeName` is "" when the target names no node. */
10
14
  export function parseTarget(target) {
11
15
  const colonIndex = target.lastIndexOf(":");
12
- if (colonIndex === -1) {
16
+ const nodeName = colonIndex === -1 ? "" : target.slice(colonIndex + 1);
17
+ if (!LEGAL_IDENTIFIER.test(nodeName)) {
13
18
  return { filename: target, nodeName: "" };
14
19
  }
15
- const filename = target.slice(0, colonIndex);
16
- const nodeName = target.slice(colonIndex + 1);
17
- return { filename, nodeName };
20
+ return { filename: target.slice(0, colonIndex), nodeName };
18
21
  }
19
22
  /** Resolve a target into the agent file, node (default "main"), and the
20
23
  * display label run results carry. */
@@ -185,7 +185,7 @@ function registerTools(tools) {
185
185
  }
186
186
  }
187
187
  }
188
- __registerModuleFingerprint("dist/lib/agents/agency-agent/agent.agency", "999bad9373c6463c93b8af1dd3b5296e396908808edf7c699b0b7bfae769c2d5", import.meta.url);
188
+ __registerModuleFingerprint("dist/lib/agents/agency-agent/agent.agency", "477c53c4122d493535511b176cc23dae7217561c563807d499143e18d4fa8547", import.meta.url);
189
189
  __registerTool(print);
190
190
  __registerTool(printJSON);
191
191
  __registerTool(input);
@@ -1676,7 +1676,14 @@ if (__process.argv[1] === fileURLToPath(import.meta.url)) {
1676
1676
  data: {}
1677
1677
  };
1678
1678
  const __result = await runCliEntry({
1679
- runMain: () => main(initialState),
1679
+ nodeNames: ["main"],
1680
+ startNode: (nodeName) => runNode({
1681
+ ctx: __globalCtx,
1682
+ nodeName,
1683
+ data: initialState.data,
1684
+ messages: initialState.messages,
1685
+ initializeGlobals: __initializeGlobals
1686
+ }),
1680
1687
  resume: __resumeFromCheckpoint
1681
1688
  });
1682
1689
  await resolveCliInterrupts(__result, respondToInterrupts);
@@ -154,7 +154,7 @@ function registerTools(tools) {
154
154
  }
155
155
  }
156
156
  }
157
- __registerModuleFingerprint("dist/lib/agents/agency-agent/brains/coordinator/prompts/codeSample.agency", "b6542c14a6ea0e41a06b5887656726eb1e101b01cf6326b68bcac6e174b0fb03", import.meta.url);
157
+ __registerModuleFingerprint("dist/lib/agents/agency-agent/brains/coordinator/prompts/codeSample.agency", "54ac8e91969c7a431868443b870aa391a653a3d47c4d9330f0664006f13dd789", import.meta.url);
158
158
  __registerTool(print);
159
159
  __registerTool(printJSON);
160
160
  __registerTool(input);
@@ -818,7 +818,14 @@ if (__process.argv[1] === fileURLToPath(import.meta.url)) {
818
818
  data: {}
819
819
  };
820
820
  const __result = await runCliEntry({
821
- runMain: () => main(initialState),
821
+ nodeNames: ["main", "categorize", "scrapeRecipe", "createIngredients", "createMeals"],
822
+ startNode: (nodeName) => runNode({
823
+ ctx: __globalCtx,
824
+ nodeName,
825
+ data: initialState.data,
826
+ messages: initialState.messages,
827
+ initializeGlobals: __initializeGlobals
828
+ }),
822
829
  resume: __resumeFromCheckpoint
823
830
  });
824
831
  await resolveCliInterrupts(__result, respondToInterrupts);
@@ -150,7 +150,7 @@ function registerTools(tools) {
150
150
  }
151
151
  }
152
152
  }
153
- __registerModuleFingerprint("dist/lib/agents/eval/goalJudge.agency", "4219fc3a089489bb68c8cf08fd2dcb81aeba5dfdef1d0961b42571fa13298776", import.meta.url);
153
+ __registerModuleFingerprint("dist/lib/agents/eval/goalJudge.agency", "07ab1b0abd5c51e9ea1ae92777c7996a6534377c20ffb6bff823655241a30312", import.meta.url);
154
154
  __registerTool(print);
155
155
  __registerTool(printJSON);
156
156
  __registerTool(input);
@@ -342,7 +342,14 @@ if (__process.argv[1] === fileURLToPath(import.meta.url)) {
342
342
  data: {}
343
343
  };
344
344
  const __result = await runCliEntry({
345
- runMain: () => main(void 0, void 0, void 0, initialState),
345
+ nodeNames: ["main"],
346
+ startNode: (nodeName) => runNode({
347
+ ctx: __globalCtx,
348
+ nodeName,
349
+ data: initialState.data,
350
+ messages: initialState.messages,
351
+ initializeGlobals: __initializeGlobals
352
+ }),
346
353
  resume: __resumeFromCheckpoint
347
354
  });
348
355
  await resolveCliInterrupts(__result, respondToInterrupts);
@@ -7,6 +7,7 @@ import { nanoid } from "agency-lang";
7
7
  import path from "path";
8
8
  import {
9
9
  RuntimeContext,
10
+ ThreadStore,
10
11
  Runner,
11
12
  setupNode,
12
13
  claimFrameForScope,
@@ -20,6 +21,8 @@ import {
20
21
  interrupt,
21
22
  isInterrupt,
22
23
  hasInterrupts,
24
+ resolveCliInterrupts,
25
+ reportBudgetExceededAndExit,
23
26
  isDebugger,
24
27
  isPaused,
25
28
  respondToInterrupts as _respondToInterrupts,
@@ -43,7 +46,8 @@ import {
43
46
  functionRefReviver as __functionRefReviver,
44
47
  DeterministicClient as __DeterministicClient,
45
48
  installFetchMock as __installFetchMock,
46
- createLogger as __createLogger
49
+ createLogger as __createLogger,
50
+ runCliEntry
47
51
  } from "agency-lang/runtime";
48
52
  const __filename = fileURLToPath(import.meta.url);
49
53
  const __dirname = path.dirname(__filename);
@@ -146,7 +150,7 @@ function registerTools(tools) {
146
150
  }
147
151
  }
148
152
  }
149
- __registerModuleFingerprint("dist/lib/agents/eval/judge.agency", "a137ed1282e91493d391244bd661564878330b974336562c484b26ce135b687b", import.meta.url);
153
+ __registerModuleFingerprint("dist/lib/agents/eval/judge.agency", "a32d8be051f27940441bda4ec03be6fcea27f03f790674e257c13d11a4ddd2ae", import.meta.url);
150
154
  __registerTool(print);
151
155
  __registerTool(printJSON);
152
156
  __registerTool(input);
@@ -322,6 +326,31 @@ async function judge(actualOutput, expectedOutput, judgePrompt, { messages: __in
322
326
  });
323
327
  }
324
328
  const __judgeNodeParams = ["actualOutput", "expectedOutput", "judgePrompt"];
329
+ if (__process.argv[1] === fileURLToPath(import.meta.url)) {
330
+ try {
331
+ const initialState = {
332
+ messages: new ThreadStore(),
333
+ data: {}
334
+ };
335
+ const __result = await runCliEntry({
336
+ nodeNames: ["judge"],
337
+ startNode: (nodeName) => runNode({
338
+ ctx: __globalCtx,
339
+ nodeName,
340
+ data: initialState.data,
341
+ messages: initialState.messages,
342
+ initializeGlobals: __initializeGlobals
343
+ }),
344
+ resume: __resumeFromCheckpoint
345
+ });
346
+ await resolveCliInterrupts(__result, respondToInterrupts);
347
+ } catch (__error) {
348
+ reportBudgetExceededAndExit(__error);
349
+ console.error(`
350
+ Agent crashed: ${__error.message}`);
351
+ throw __error;
352
+ }
353
+ }
325
354
  var stdin_default = graph;
326
355
  const __sourceMap = { "dist/lib/agents/eval/judge.agency:judge": { "1": { "line": 8, "col": 2 }, "2": { "line": 18, "col": 2 } } };
327
356
  export {
@@ -7,6 +7,7 @@ import { nanoid } from "agency-lang";
7
7
  import path from "path";
8
8
  import {
9
9
  RuntimeContext,
10
+ ThreadStore,
10
11
  Runner,
11
12
  setupNode,
12
13
  claimFrameForScope,
@@ -20,6 +21,8 @@ import {
20
21
  interrupt,
21
22
  isInterrupt,
22
23
  hasInterrupts,
24
+ resolveCliInterrupts,
25
+ reportBudgetExceededAndExit,
23
26
  isDebugger,
24
27
  isPaused,
25
28
  respondToInterrupts as _respondToInterrupts,
@@ -43,7 +46,8 @@ import {
43
46
  functionRefReviver as __functionRefReviver,
44
47
  DeterministicClient as __DeterministicClient,
45
48
  installFetchMock as __installFetchMock,
46
- createLogger as __createLogger
49
+ createLogger as __createLogger,
50
+ runCliEntry
47
51
  } from "agency-lang/runtime";
48
52
  const __filename = fileURLToPath(import.meta.url);
49
53
  const __dirname = path.dirname(__filename);
@@ -146,7 +150,7 @@ function registerTools(tools) {
146
150
  }
147
151
  }
148
152
  }
149
- __registerModuleFingerprint("dist/lib/agents/eval/judgePairwise.agency", "7a6ddc2bfc878cf2a5ff5233f8a461c4b9c62af9eebaea8968637ca377742350", import.meta.url);
153
+ __registerModuleFingerprint("dist/lib/agents/eval/judgePairwise.agency", "86e1cfb0ee10433bc937c8caf288f1212ca5e9d0018aafec3d2853aa43af6d69", import.meta.url);
150
154
  __registerTool(print);
151
155
  __registerTool(printJSON);
152
156
  __registerTool(input);
@@ -342,6 +346,31 @@ async function judgePairwise(goal, responseA, responseB, { messages: __invocatio
342
346
  });
343
347
  }
344
348
  const __judgePairwiseNodeParams = ["goal", "responseA", "responseB"];
349
+ if (__process.argv[1] === fileURLToPath(import.meta.url)) {
350
+ try {
351
+ const initialState = {
352
+ messages: new ThreadStore(),
353
+ data: {}
354
+ };
355
+ const __result = await runCliEntry({
356
+ nodeNames: ["judgePairwise"],
357
+ startNode: (nodeName) => runNode({
358
+ ctx: __globalCtx,
359
+ nodeName,
360
+ data: initialState.data,
361
+ messages: initialState.messages,
362
+ initializeGlobals: __initializeGlobals
363
+ }),
364
+ resume: __resumeFromCheckpoint
365
+ });
366
+ await resolveCliInterrupts(__result, respondToInterrupts);
367
+ } catch (__error) {
368
+ reportBudgetExceededAndExit(__error);
369
+ console.error(`
370
+ Agent crashed: ${__error.message}`);
371
+ throw __error;
372
+ }
373
+ }
345
374
  var stdin_default = graph;
346
375
  const __sourceMap = { "dist/lib/agents/eval/judgePairwise.agency:judgePairwise": { "1": { "line": 11, "col": 2 }, "2": { "line": 37, "col": 2 }, "3": { "line": 39, "col": 2 } } };
347
376
  export {
@@ -150,7 +150,7 @@ function registerTools(tools) {
150
150
  }
151
151
  }
152
152
  }
153
- __registerModuleFingerprint("dist/lib/agents/eval/rubricJudge.agency", "15f077f083f41b3bee11dbe69f7b41b1a7aaae4bd0440731472e84246cbe770f", import.meta.url);
153
+ __registerModuleFingerprint("dist/lib/agents/eval/rubricJudge.agency", "da6496cbfe73c0aebf577575b504bc9fb4d694e27512dbe202467b7ac8cc8ec2", import.meta.url);
154
154
  __registerTool(print);
155
155
  __registerTool(printJSON);
156
156
  __registerTool(input);
@@ -346,7 +346,14 @@ if (__process.argv[1] === fileURLToPath(import.meta.url)) {
346
346
  data: {}
347
347
  };
348
348
  const __result = await runCliEntry({
349
- runMain: () => main(void 0, void 0, void 0, initialState),
349
+ nodeNames: ["main"],
350
+ startNode: (nodeName) => runNode({
351
+ ctx: __globalCtx,
352
+ nodeName,
353
+ data: initialState.data,
354
+ messages: initialState.messages,
355
+ initializeGlobals: __initializeGlobals
356
+ }),
350
357
  resume: __resumeFromCheckpoint
351
358
  });
352
359
  await resolveCliInterrupts(__result, respondToInterrupts);
@@ -7,6 +7,7 @@ import { nanoid } from "agency-lang";
7
7
  import path from "path";
8
8
  import {
9
9
  RuntimeContext,
10
+ ThreadStore,
10
11
  Runner,
11
12
  setupNode,
12
13
  claimFrameForScope,
@@ -20,6 +21,8 @@ import {
20
21
  interrupt,
21
22
  isInterrupt,
22
23
  hasInterrupts,
24
+ resolveCliInterrupts,
25
+ reportBudgetExceededAndExit,
23
26
  isDebugger,
24
27
  isPaused,
25
28
  respondToInterrupts as _respondToInterrupts,
@@ -43,7 +46,8 @@ import {
43
46
  functionRefReviver as __functionRefReviver,
44
47
  DeterministicClient as __DeterministicClient,
45
48
  installFetchMock as __installFetchMock,
46
- createLogger as __createLogger
49
+ createLogger as __createLogger,
50
+ runCliEntry
47
51
  } from "agency-lang/runtime";
48
52
  const __filename = fileURLToPath(import.meta.url);
49
53
  const __dirname = path.dirname(__filename);
@@ -146,7 +150,7 @@ function registerTools(tools) {
146
150
  }
147
151
  }
148
152
  }
149
- __registerModuleFingerprint("dist/lib/agents/optimize/gepaReflect.agency", "03d74acb529c3bff2e2fc8382e731aa316d5f618495c93d9bda9cac964abe687", import.meta.url);
153
+ __registerModuleFingerprint("dist/lib/agents/optimize/gepaReflect.agency", "fe03cc0db80dc505434026e7434bad81f7ea754ee429b89717121d0f78a57130", import.meta.url);
150
154
  __registerTool(print);
151
155
  __registerTool(printJSON);
152
156
  __registerTool(input);
@@ -361,6 +365,31 @@ async function gepaReflect(targets, goals, feedback, history, { messages: __invo
361
365
  });
362
366
  }
363
367
  const __gepaReflectNodeParams = ["targets", "goals", "feedback", "history"];
368
+ if (__process.argv[1] === fileURLToPath(import.meta.url)) {
369
+ try {
370
+ const initialState = {
371
+ messages: new ThreadStore(),
372
+ data: {}
373
+ };
374
+ const __result = await runCliEntry({
375
+ nodeNames: ["gepaReflect"],
376
+ startNode: (nodeName) => runNode({
377
+ ctx: __globalCtx,
378
+ nodeName,
379
+ data: initialState.data,
380
+ messages: initialState.messages,
381
+ initializeGlobals: __initializeGlobals
382
+ }),
383
+ resume: __resumeFromCheckpoint
384
+ });
385
+ await resolveCliInterrupts(__result, respondToInterrupts);
386
+ } catch (__error) {
387
+ reportBudgetExceededAndExit(__error);
388
+ console.error(`
389
+ Agent crashed: ${__error.message}`);
390
+ throw __error;
391
+ }
392
+ }
364
393
  var stdin_default = graph;
365
394
  const __sourceMap = { "dist/lib/agents/optimize/gepaReflect.agency:gepaReflect": { "1": { "line": 19, "col": 2 }, "2": { "line": 61, "col": 2 }, "3": { "line": 62, "col": 2 } } };
366
395
  export {
@@ -7,6 +7,7 @@ import { nanoid } from "agency-lang";
7
7
  import path from "path";
8
8
  import {
9
9
  RuntimeContext,
10
+ ThreadStore,
10
11
  Runner,
11
12
  setupNode,
12
13
  claimFrameForScope,
@@ -20,6 +21,8 @@ import {
20
21
  interrupt,
21
22
  isInterrupt,
22
23
  hasInterrupts,
24
+ resolveCliInterrupts,
25
+ reportBudgetExceededAndExit,
23
26
  isDebugger,
24
27
  isPaused,
25
28
  respondToInterrupts as _respondToInterrupts,
@@ -43,7 +46,8 @@ import {
43
46
  functionRefReviver as __functionRefReviver,
44
47
  DeterministicClient as __DeterministicClient,
45
48
  installFetchMock as __installFetchMock,
46
- createLogger as __createLogger
49
+ createLogger as __createLogger,
50
+ runCliEntry
47
51
  } from "agency-lang/runtime";
48
52
  const __filename = fileURLToPath(import.meta.url);
49
53
  const __dirname = path.dirname(__filename);
@@ -146,7 +150,7 @@ function registerTools(tools) {
146
150
  }
147
151
  }
148
152
  }
149
- __registerModuleFingerprint("dist/lib/agents/optimize/mutatePrompt.agency", "73a91138ec4e25f3bb79b9a1843675dcd5a3790f2c2c95512d0377a8e9829517", import.meta.url);
153
+ __registerModuleFingerprint("dist/lib/agents/optimize/mutatePrompt.agency", "aafb22db4a7e374680c56907854744b8adb41c32478291d5f684ea2aa5392b38", import.meta.url);
150
154
  __registerTool(print);
151
155
  __registerTool(printJSON);
152
156
  __registerTool(input);
@@ -344,6 +348,31 @@ async function mutatePrompt(targets, goals, feedback, history, diagnostics = ``,
344
348
  });
345
349
  }
346
350
  const __mutatePromptNodeParams = ["targets", "goals", "feedback", "history", "diagnostics"];
351
+ if (__process.argv[1] === fileURLToPath(import.meta.url)) {
352
+ try {
353
+ const initialState = {
354
+ messages: new ThreadStore(),
355
+ data: {}
356
+ };
357
+ const __result = await runCliEntry({
358
+ nodeNames: ["mutatePrompt"],
359
+ startNode: (nodeName) => runNode({
360
+ ctx: __globalCtx,
361
+ nodeName,
362
+ data: initialState.data,
363
+ messages: initialState.messages,
364
+ initializeGlobals: __initializeGlobals
365
+ }),
366
+ resume: __resumeFromCheckpoint
367
+ });
368
+ await resolveCliInterrupts(__result, respondToInterrupts);
369
+ } catch (__error) {
370
+ reportBudgetExceededAndExit(__error);
371
+ console.error(`
372
+ Agent crashed: ${__error.message}`);
373
+ throw __error;
374
+ }
375
+ }
347
376
  var stdin_default = graph;
348
377
  const __sourceMap = { "dist/lib/agents/optimize/mutatePrompt.agency:mutatePrompt": { "1": { "line": 20, "col": 2 }, "2": { "line": 43, "col": 2 }, "3": { "line": 44, "col": 2 } } };
349
378
  export {
@@ -172,7 +172,7 @@ function registerTools(tools) {
172
172
  }
173
173
  }
174
174
  }
175
- __registerModuleFingerprint("dist/lib/agents/policy/agent.agency", "06bda8a109c760046eb71a1c6493a5f5b7a6538dacde97e92385a9371369d077", import.meta.url);
175
+ __registerModuleFingerprint("dist/lib/agents/policy/agent.agency", "5913a37e61b1c33ab421267741ec0796de8edbb4f3683bbaa484b42d8b78def0", import.meta.url);
176
176
  __registerTool(print);
177
177
  __registerTool(printJSON);
178
178
  __registerTool(input);
@@ -2069,7 +2069,14 @@ if (__process.argv[1] === fileURLToPath(import.meta.url)) {
2069
2069
  data: {}
2070
2070
  };
2071
2071
  const __result = await runCliEntry({
2072
- runMain: () => main(initialState),
2072
+ nodeNames: ["main"],
2073
+ startNode: (nodeName) => runNode({
2074
+ ctx: __globalCtx,
2075
+ nodeName,
2076
+ data: initialState.data,
2077
+ messages: initialState.messages,
2078
+ initializeGlobals: __initializeGlobals
2079
+ }),
2073
2080
  resume: __resumeFromCheckpoint
2074
2081
  });
2075
2082
  await resolveCliInterrupts(__result, respondToInterrupts);
@@ -160,7 +160,7 @@ function registerTools(tools) {
160
160
  }
161
161
  }
162
162
  }
163
- __registerModuleFingerprint("dist/lib/agents/review/agent.agency", "e9761740791d5dccde1e6273fd8d6d7acd55cb1c00146b7234501ece0d13ebe5", import.meta.url);
163
+ __registerModuleFingerprint("dist/lib/agents/review/agent.agency", "d0387b58eb07bdfb06a7b7c1137ec4bad67d91282d9c1396323697ca959fdb7b", import.meta.url);
164
164
  __registerTool(print);
165
165
  __registerTool(printJSON);
166
166
  __registerTool(input);
@@ -837,7 +837,14 @@ if (__process.argv[1] === fileURLToPath(import.meta.url)) {
837
837
  data: {}
838
838
  };
839
839
  const __result = await runCliEntry({
840
- runMain: () => main(initialState),
840
+ nodeNames: ["main", "end"],
841
+ startNode: (nodeName) => runNode({
842
+ ctx: __globalCtx,
843
+ nodeName,
844
+ data: initialState.data,
845
+ messages: initialState.messages,
846
+ initializeGlobals: __initializeGlobals
847
+ }),
841
848
  resume: __resumeFromCheckpoint
842
849
  });
843
850
  await resolveCliInterrupts(__result, respondToInterrupts);
@@ -3710,26 +3710,26 @@ export class TypeScriptBuilder {
3710
3710
  }));
3711
3711
  result.push(ts.export(ts.varDecl("const", `__${declaredName(node.nodeName)}NodeParams`, ts.arr(args.map((arg) => ts.str(arg.name))))));
3712
3712
  }
3713
- if (this.compilationUnit.graphNodes.some((n) => n.nodeName === "main")) {
3714
- // The direct-run call reserves one slot per declared parameter and puts
3715
- // initialState after them, in main's hidden OPTIONS argument.
3713
+ if (this.compilationUnit.graphNodes.length > 0) {
3714
+ // The direct-run block starts a node by name through runNode, the same
3715
+ // call every exported node wrapper makes, so `agency run file.agency:node`
3716
+ // can pick any node in this file. runCliEntry starts `main` unless the
3717
+ // CLI names another. The names are this file's own: the graph also holds
3718
+ // every node merged in from imports, which are not entry points.
3716
3719
  //
3717
- // The reservation is what matters: initialState used to be the FIRST
3718
- // argument, which was harmless while mains took no parameters (it landed
3719
- // in the options slot) and wrong once they did (#739) — the state object
3720
- // arrived as the first parameter's value. `undefined` in each slot keeps
3721
- // it where it belongs, and JavaScript treats an explicit `undefined` and
3722
- // an omitted argument alike, so parameter defaults still apply.
3723
- //
3724
- // The slots are filled with `undefined` rather than argv because a
3725
- // program's command line belongs to the program. `agency run` forwards
3726
- // trailing arguments to the child process, where `std::args` reads them;
3727
- // the compiler does not read them on the entry node's behalf.
3728
- const mainParamCount = this.compilationUnit.graphNodes.find((n) => n.nodeName === "main")?.parameters.length ?? 0;
3729
- const mainCallArgs = [
3730
- ...Array.from({ length: mainParamCount }, () => ts.id("undefined")),
3731
- ts.id("initialState"),
3732
- ];
3720
+ // The node's parameters get no values: a program's command line belongs
3721
+ // to the program. `agency run` forwards trailing arguments to the child
3722
+ // process, where `std::args` reads them.
3723
+ const nodeNames = ts.arr(this.compilationUnit.graphNodes.map((node) => ts.str(declaredName(node.nodeName))));
3724
+ const startNode = ts.arrowFn([{ name: "nodeName", typeAnnotation: "string" }], ts.call(ts.id("runNode"), [
3725
+ ts.obj({
3726
+ ctx: ts.id("__globalCtx"),
3727
+ nodeName: ts.id("nodeName"),
3728
+ data: $(ts.id("initialState")).prop("data").done(),
3729
+ messages: $(ts.id("initialState")).prop("messages").done(),
3730
+ initializeGlobals: ts.id("__initializeGlobals"),
3731
+ }),
3732
+ ]));
3733
3733
  result.push(ts.if(ts.binOp($(ts.id("__process")).prop("argv").index(ts.num(1)).done(), "===", ts.call(ts.id("fileURLToPath"), [$(ts.id("import")).prop("meta").prop("url").done()])), ts.statements([
3734
3734
  ts.tryCatch(ts.statements([
3735
3735
  ts.varDecl("const", "initialState", ts.obj({
@@ -3738,11 +3738,12 @@ export class TypeScriptBuilder {
3738
3738
  })),
3739
3739
  ts.varDecl("const", "__result", ts.await(ts.call(ts.id("runCliEntry"), [
3740
3740
  ts.obj({
3741
- runMain: ts.arrowFn([], ts.call(ts.id("main"), mainCallArgs)),
3741
+ nodeNames,
3742
+ startNode,
3742
3743
  resume: ts.id("__resumeFromCheckpoint"),
3743
3744
  }),
3744
3745
  ]))),
3745
- // Running `main` directly from the CLI: interrupts that no
3746
+ // Running a node directly from the CLI: interrupts that no
3746
3747
  // handler settled have surfaced to the user. resolveCliInterrupts
3747
3748
  // is that user endpoint — under a run policy it decides each one
3748
3749
  // (prompting with --interactive, rejecting otherwise) and resumes
@@ -10,5 +10,7 @@ export type RootCarriers = {
10
10
  maxTime?: string;
11
11
  };
12
12
  resume?: ResumeCarrier;
13
+ /** The node to start, from `agency run file.agency:node`. Unset means `main`. */
14
+ entryNode?: string;
13
15
  };
14
16
  export declare function withRootCarriers(env: NodeJS.ProcessEnv, carriers: RootCarriers): NodeJS.ProcessEnv;
@@ -1,10 +1,11 @@
1
1
  /**
2
- * The root policy and budget a CLI command carries to the Agency program it
3
- * spawns, as env vars the runtime reads (`installRunPolicyHandler`,
4
- * `rootBudget`). Always cleared first: a child's behavior comes from this
5
- * invocation's flags, never from a parent shell or an outer run.
2
+ * The root policy, budget, resume request, and entry node a CLI command
3
+ * carries to the Agency program it spawns, as env vars the runtime reads
4
+ * (`installRunPolicyHandler`, `rootBudget`, `runCliEntry`). Always cleared
5
+ * first: a child's behavior comes from this invocation's flags, never from a
6
+ * parent shell or an outer run.
6
7
  */
7
- import { AGENCY_MAX_COST, AGENCY_MAX_TIME, AGENCY_RUN_POLICY, AGENCY_RUN_POLICY_INTERACTIVE, AGENCY_RUN_POLICY_INTERACTIVE_ON, AGENCY_RESUME_FILE, AGENCY_RESUME_FORCE, AGENCY_RESUME_OVERRIDES, } from "../constants.js";
8
+ import { AGENCY_ENTRY_NODE, AGENCY_MAX_COST, AGENCY_MAX_TIME, AGENCY_RUN_POLICY, AGENCY_RUN_POLICY_INTERACTIVE, AGENCY_RUN_POLICY_INTERACTIVE_ON, AGENCY_RESUME_FILE, AGENCY_RESUME_FORCE, AGENCY_RESUME_OVERRIDES, } from "../constants.js";
8
9
  export function withRootCarriers(env, carriers) {
9
10
  const out = { ...env };
10
11
  delete out[AGENCY_RUN_POLICY];
@@ -14,6 +15,10 @@ export function withRootCarriers(env, carriers) {
14
15
  delete out[AGENCY_RESUME_FILE];
15
16
  delete out[AGENCY_RESUME_OVERRIDES];
16
17
  delete out[AGENCY_RESUME_FORCE];
18
+ delete out[AGENCY_ENTRY_NODE];
19
+ if (carriers.entryNode !== undefined) {
20
+ out[AGENCY_ENTRY_NODE] = carriers.entryNode;
21
+ }
17
22
  if (carriers.policy !== undefined) {
18
23
  out[AGENCY_RUN_POLICY] = carriers.policy.policyJson;
19
24
  if (carriers.policy.interactive)
@@ -67,7 +67,9 @@ capture?: {
67
67
  runDir: string;
68
68
  }, compileMode?: {
69
69
  agencyOnly: boolean;
70
- }): void;
70
+ },
71
+ /** The node to start, from `agency run file.agency:node`. Unset means `main`. */
72
+ entryNode?: string): void;
71
73
  /**
72
74
  * The config overrides `agency run` hands its child. Inherited overrides are
73
75
  * kept (an eval harness hands this process its statelog path the same way),
@@ -229,7 +229,9 @@ export function run(config, inputFile, outputFile, resume, runPolicy, budget,
229
229
  nodeArgs = [],
230
230
  /** `--capture-workdir <dir>`: after the run, write its statelog, code and a
231
231
  * snapshot of the working directory as the run directory `<dir>/<traceId>/`. */
232
- capture, compileMode = { agencyOnly: false }) {
232
+ capture, compileMode = { agencyOnly: false },
233
+ /** The node to start, from `agency run file.agency:node`. Unset means `main`. */
234
+ entryNode) {
233
235
  let output;
234
236
  if (compileMode.agencyOnly) {
235
237
  const compiled = compileAgencyOnly(inputFile);
@@ -253,7 +255,7 @@ capture, compileMode = { agencyOnly: false }) {
253
255
  }
254
256
  console.log(`Running ${output}...`);
255
257
  console.log("---");
256
- const env = withRootCarriers(process.env, { policy: runPolicy, budget, resume });
258
+ const env = withRootCarriers(process.env, { policy: runPolicy, budget, resume, entryNode });
257
259
  const captured = capture === undefined ? undefined : prepareCapture(capture.runDir);
258
260
  env[CONFIG_OVERRIDES_ENV] = serializeConfigOverrides(runChildOverrides({
259
261
  inherited: readConfigOverrides(env),