@forwardimpact/libeval 0.1.42 → 0.1.43
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/fit-eval.js +2 -1
- package/package.json +1 -1
- package/src/commands/facilitate.js +14 -6
- package/src/commands/supervise.js +1 -1
- package/src/facilitator.js +1 -1
- package/src/supervisor.js +17 -5
package/bin/fit-eval.js
CHANGED
|
@@ -100,7 +100,8 @@ const definition = {
|
|
|
100
100
|
},
|
|
101
101
|
"max-turns": {
|
|
102
102
|
type: "string",
|
|
103
|
-
description:
|
|
103
|
+
description:
|
|
104
|
+
"Max agentic turns per runner invocation (default: 200, 0 = unlimited)",
|
|
104
105
|
},
|
|
105
106
|
output: {
|
|
106
107
|
type: "string",
|
package/package.json
CHANGED
|
@@ -10,19 +10,21 @@ import { createTeeWriter } from "../tee-writer.js";
|
|
|
10
10
|
* @param {string} cwd - Shared working directory for all agents
|
|
11
11
|
* @returns {Array<{name: string, role: string, cwd: string, agentProfile: string}>}
|
|
12
12
|
*/
|
|
13
|
-
function parseAgentProfiles(raw, cwd) {
|
|
13
|
+
function parseAgentProfiles(raw, cwd, maxTurns) {
|
|
14
14
|
return raw.split(",").map((entry) => {
|
|
15
15
|
const name = entry.trim();
|
|
16
|
-
return { name, role: name, cwd, agentProfile: name };
|
|
16
|
+
return { name, role: name, cwd, agentProfile: name, maxTurns };
|
|
17
17
|
});
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
|
-
* Parse and validate facilitate command options.
|
|
21
|
+
* Parse and validate facilitate command options. Exported for test
|
|
22
|
+
* coverage of the `--max-turns` → per-agent threading contract; not part
|
|
23
|
+
* of the package's public API.
|
|
22
24
|
* @param {object} values - Parsed option values
|
|
23
25
|
* @returns {object} Parsed options
|
|
24
26
|
*/
|
|
25
|
-
function parseFacilitateOptions(values) {
|
|
27
|
+
export function parseFacilitateOptions(values) {
|
|
26
28
|
const taskFile = values["task-file"];
|
|
27
29
|
const taskText = values["task-text"];
|
|
28
30
|
if (taskFile && taskText)
|
|
@@ -36,9 +38,15 @@ function parseFacilitateOptions(values) {
|
|
|
36
38
|
const profilesRaw = values["agent-profiles"];
|
|
37
39
|
if (!profilesRaw) throw new Error("--agent-profiles is required");
|
|
38
40
|
const agentCwd = resolve(values["agent-cwd"] ?? ".");
|
|
39
|
-
const agentConfigs = parseAgentProfiles(profilesRaw, agentCwd);
|
|
40
41
|
|
|
41
42
|
const maxTurnsRaw = values["max-turns"] ?? "20";
|
|
43
|
+
const maxTurns = maxTurnsRaw === "0" ? 0 : parseInt(maxTurnsRaw, 10);
|
|
44
|
+
|
|
45
|
+
// Thread --max-turns into each participant: without this, every facilitated
|
|
46
|
+
// agent silently falls back to the 50-turn default in facilitator.js even
|
|
47
|
+
// when the caller raises the budget. Observed in run 26078312414 where
|
|
48
|
+
// staff-engineer terminated at 51 turns despite --max-turns=200.
|
|
49
|
+
const agentConfigs = parseAgentProfiles(profilesRaw, agentCwd, maxTurns);
|
|
42
50
|
|
|
43
51
|
return {
|
|
44
52
|
taskContent,
|
|
@@ -47,7 +55,7 @@ function parseFacilitateOptions(values) {
|
|
|
47
55
|
facilitatorCwd: resolve(values["facilitator-cwd"] ?? "."),
|
|
48
56
|
agentModel: values["agent-model"] ?? "claude-opus-4-7[1m]",
|
|
49
57
|
facilitatorModel: values["facilitator-model"] ?? "claude-opus-4-7[1m]",
|
|
50
|
-
maxTurns
|
|
58
|
+
maxTurns,
|
|
51
59
|
outputPath: values.output,
|
|
52
60
|
facilitatorProfile: values["facilitator-profile"] ?? undefined,
|
|
53
61
|
};
|
|
@@ -35,7 +35,7 @@ function parseSuperviseOptions(values) {
|
|
|
35
35
|
agentModel: values["agent-model"] ?? "claude-opus-4-7[1m]",
|
|
36
36
|
supervisorModel: values["supervisor-model"] ?? "claude-opus-4-7[1m]",
|
|
37
37
|
maxTurns: (() => {
|
|
38
|
-
const raw = values["max-turns"] ?? "
|
|
38
|
+
const raw = values["max-turns"] ?? "200";
|
|
39
39
|
return raw === "0" ? 0 : parseInt(raw, 10);
|
|
40
40
|
})(),
|
|
41
41
|
outputPath: values.output,
|
package/src/facilitator.js
CHANGED
|
@@ -393,7 +393,7 @@ const devNull = new Writable({
|
|
|
393
393
|
* @param {string} [deps.model] - Default model for all participants.
|
|
394
394
|
* @param {string} [deps.agentModel] - Agent model override (falls back to `model`).
|
|
395
395
|
* @param {string} [deps.facilitatorModel] - Facilitator model override (falls back to `model`).
|
|
396
|
-
* @param {number} [deps.maxTurns]
|
|
396
|
+
* @param {number} [deps.maxTurns] - Facilitator's own per-invocation turn budget (default 20). Each participating agent's budget is taken from `config.maxTurns` on its entry in `agentConfigs` (default 50 when unset). The CLI command (`commands/facilitate.js`) threads `--max-turns` into both this parameter and every agent config so a single CLI value bounds all participants uniformly.
|
|
397
397
|
* @param {string[]} [deps.facilitatorAllowedTools] - Tools the facilitator may use; defaults to a read/write file-edit set.
|
|
398
398
|
* @param {string[]} [deps.facilitatorDisallowedTools] - Additional tools to block on the facilitator; merged with the sub-agent spawn defaults (Agent/Task/TaskOutput/TaskStop).
|
|
399
399
|
* @param {string} [deps.facilitatorProfile] - Facilitator profile name; resolved into the main-thread system prompt via `composeProfilePrompt`.
|
package/src/supervisor.js
CHANGED
|
@@ -50,10 +50,17 @@ export const AGENT_SYSTEM_PROMPT =
|
|
|
50
50
|
* Maximum number of mid-turn interventions allowed within a single agent turn.
|
|
51
51
|
* Bounded so a looping supervisor exhausts its quota fast (observability) but
|
|
52
52
|
* leaves headroom for legitimate "intervene, observe, intervene again" patterns.
|
|
53
|
-
* The outer
|
|
53
|
+
* The outer exchange budget still bounds overall runtime.
|
|
54
54
|
*/
|
|
55
55
|
const MAX_INTERVENTIONS_PER_TURN = 5;
|
|
56
56
|
|
|
57
|
+
/**
|
|
58
|
+
* Default cap on supervisor↔agent exchanges in a single run. Not exposed via
|
|
59
|
+
* CLI — `--max-turns` governs the per-runner invocation budget instead. When
|
|
60
|
+
* a `--max-exchanges` flag is added this becomes the default for that flag.
|
|
61
|
+
*/
|
|
62
|
+
const DEFAULT_MAX_EXCHANGES = 100;
|
|
63
|
+
|
|
57
64
|
/** Orchestrate a relay loop between a supervisor LLM and an agent LLM with mid-turn review. */
|
|
58
65
|
export class Supervisor {
|
|
59
66
|
/**
|
|
@@ -485,7 +492,7 @@ const devNull = new Writable({
|
|
|
485
492
|
* @param {string} [deps.model] - Default model for both runners.
|
|
486
493
|
* @param {string} [deps.agentModel] - Agent model override (falls back to `model`).
|
|
487
494
|
* @param {string} [deps.supervisorModel] - Supervisor model override (falls back to `model`).
|
|
488
|
-
* @param {number} [deps.maxTurns]
|
|
495
|
+
* @param {number} [deps.maxTurns] - Per-runner invocation budget for both the supervisor and the agent (default 200; 0 = unlimited). Outer supervisor↔agent exchanges are bounded separately by `DEFAULT_MAX_EXCHANGES` (passes through to unlimited when `maxTurns === 0`).
|
|
489
496
|
* @param {string[]} [deps.allowedTools]
|
|
490
497
|
* @param {string[]} [deps.supervisorAllowedTools]
|
|
491
498
|
* @param {string[]} [deps.supervisorDisallowedTools]
|
|
@@ -544,8 +551,13 @@ export function createSupervisor({
|
|
|
544
551
|
|
|
545
552
|
const onLine = (line) => supervisor.emitLine(line);
|
|
546
553
|
|
|
547
|
-
|
|
548
|
-
|
|
554
|
+
// `maxTurns` is the per-runner invocation budget — matches `run` and
|
|
555
|
+
// `facilitate` semantics. The outer supervisor↔agent exchange loop is
|
|
556
|
+
// bounded separately by `DEFAULT_MAX_EXCHANGES`; when --max-exchanges is
|
|
557
|
+
// added it will become a parameter. `maxTurns === 0` propagates through
|
|
558
|
+
// to mean unlimited on both axes.
|
|
559
|
+
const perInvocationTurns = maxTurns ?? 200;
|
|
560
|
+
const exchangeBudget = maxTurns === 0 ? 0 : DEFAULT_MAX_EXCHANGES;
|
|
549
561
|
|
|
550
562
|
const agentRunner = createAgentRunner({
|
|
551
563
|
cwd: agentCwd,
|
|
@@ -595,7 +607,7 @@ export function createSupervisor({
|
|
|
595
607
|
agentRunner,
|
|
596
608
|
supervisorRunner,
|
|
597
609
|
output,
|
|
598
|
-
maxTurns,
|
|
610
|
+
maxTurns: exchangeBudget,
|
|
599
611
|
ctx,
|
|
600
612
|
messageBus,
|
|
601
613
|
taskAmend,
|