llm-orchestrator 1.2.7 → 1.2.8
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/.claude-plugin/plugin.json +1 -1
- package/README.md +2 -2
- package/lib/flow-gate.mjs +16 -4
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "llm-orchestrator",
|
|
3
3
|
"description": "Write /task once — it plans the work, shards it across parallel subagents, gates every phase and verifies before claiming done. Claude Code, Codex, OpenCode, Kilo.",
|
|
4
|
-
"version": "1.2.
|
|
4
|
+
"version": "1.2.8",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Bogdan-Gabriel Torcescu",
|
|
7
7
|
"url": "https://www.linkedin.com/in/bogdantorcescu/"
|
package/README.md
CHANGED
|
@@ -365,8 +365,8 @@ more instructions:
|
|
|
365
365
|
it, runs opened without a PlanShard count, runs that planned several shards but started no
|
|
366
366
|
subagents, and runs still open.
|
|
367
367
|
- Trivial is the narrow exception — a one-line change such as a typo or a version bump. A run
|
|
368
|
-
declared trivial that then edits a second file, touches tests,
|
|
369
|
-
(an investigation is not trivial) gets one reminder to reopen it as
|
|
368
|
+
declared trivial that then edits a second file, touches tests, queries a live source twice, or keeps
|
|
369
|
+
working past eight calls (an investigation is not trivial) gets one reminder to reopen it as
|
|
370
370
|
a typed run, and counts as `trivial_overreach` in the audit. Trivial runs close at the end of the
|
|
371
371
|
turn (`Stop` hook), so single-prompt sessions still reach the history. Typed runs stay open across
|
|
372
372
|
turns and close when the session ends (`SessionEnd`), so an unclosed run is never lost.
|
package/lib/flow-gate.mjs
CHANGED
|
@@ -52,6 +52,11 @@ export function overreachWorkNudgeFor(cli = 'llm-orchestrator', calls = 9) {
|
|
|
52
52
|
return `This task was declared trivial, but it has now made ${calls} work calls — trivial is a one-line change, not an investigation. Reopen it as a typed run (\`${cli} run start --type <TYPE> --shards <n>\`) so it is classified, planned and verified like one.`;
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
+
/** A run declared trivial that is querying live sources. */
|
|
56
|
+
export function overreachLiveNudgeFor(cli = 'llm-orchestrator', live = 2) {
|
|
57
|
+
return `This task was declared trivial, but it has now queried live sources ${live} times — an investigation over production evidence is not trivial. Reopen it as a typed run (\`${cli} run start --type INCIDENT|INVESTIGATION --shards <n>\`), where independent live sources are shards for collectors.`;
|
|
58
|
+
}
|
|
59
|
+
|
|
55
60
|
// Edit-shaped tools, per harness. Only a short hash of each path is kept.
|
|
56
61
|
const EDIT_TOOLS = new Set(['edit', 'write', 'multiedit', 'notebookedit', 'str_replace_based_edit_tool', 'apply_patch', 'patch']);
|
|
57
62
|
const TEST_PATH = /(^|\/)(test|tests|__tests__|spec|specs)\/|[._-](test|spec)\.[a-z0-9]+$|(^|\/)test_[^/]+\.py$|_spec\.rb$/i;
|
|
@@ -122,6 +127,8 @@ export const INLINE_REASON = /^stateful:\s*\S/;
|
|
|
122
127
|
|
|
123
128
|
// A: a trivial run is a one-line change, not an investigation.
|
|
124
129
|
export const TRIVIAL_WORK_LIMIT = 8;
|
|
130
|
+
// Querying a live source more than once is an investigation, however few calls it takes.
|
|
131
|
+
export const TRIVIAL_LIVE_LIMIT = 2;
|
|
125
132
|
|
|
126
133
|
// C: sources whose reads cost real time and live remotely — the reads that pay to fan out.
|
|
127
134
|
const LIVE_SOURCE = /(^|[\s;&|(])(rtk\s+)?(ssh|scp|psql|mysql|mongosh|mongo|redis-cli|kubectl|docker\s+(exec|logs)|aws|gcloud|az|curl|wget|http|httpie)(\s|$)/;
|
|
@@ -428,20 +435,24 @@ export function decide(previous, event, now) {
|
|
|
428
435
|
if (session.run) {
|
|
429
436
|
const current = session.run;
|
|
430
437
|
current.main_work_calls = (current.main_work_calls ?? 0) + 1;
|
|
438
|
+
// Live reads count on every run, trivial ones included — they are what fan-out is for.
|
|
439
|
+
if (event.live) current.live_calls = (current.live_calls ?? 0) + 1;
|
|
431
440
|
if (current.trivial) {
|
|
432
441
|
current.edited_files = [...new Set([...(current.edited_files ?? []), ...event.edits.map((entry) => entry.hash)])];
|
|
433
442
|
current.touched_tests = Boolean(current.touched_tests) || event.edits.some((entry) => entry.test);
|
|
434
443
|
const grewByEdits = current.edited_files.length >= 2 || current.touched_tests;
|
|
435
444
|
const grewByWork = current.main_work_calls > TRIVIAL_WORK_LIMIT;
|
|
436
|
-
|
|
445
|
+
const grewByLive = (current.live_calls ?? 0) >= TRIVIAL_LIVE_LIMIT;
|
|
446
|
+
if (!current.overreach_nudged && (grewByEdits || grewByWork || grewByLive)) {
|
|
437
447
|
current.overreach_nudged = true;
|
|
438
448
|
output = grewByEdits
|
|
439
449
|
? { additionalContext: overreachNudgeFor(undefined, current.edited_files.length), kind: 'overreach', files: current.edited_files.length }
|
|
440
|
-
:
|
|
450
|
+
: grewByLive
|
|
451
|
+
? { additionalContext: overreachLiveNudgeFor(undefined, current.live_calls), kind: 'overreach', live: current.live_calls }
|
|
452
|
+
: { additionalContext: overreachWorkNudgeFor(undefined, current.main_work_calls), kind: 'overreach', calls: current.main_work_calls };
|
|
441
453
|
}
|
|
442
454
|
return { session, output, history };
|
|
443
455
|
}
|
|
444
|
-
if (event.live) current.live_calls = (current.live_calls ?? 0) + 1;
|
|
445
456
|
const evidence = EVIDENCE_TYPES.has(current.task_type);
|
|
446
457
|
const step = (evidence ? EVIDENCE_CALLS_PER_SHARD : DISPATCH_CALLS_PER_SHARD) * (current.planned_shards ?? 0);
|
|
447
458
|
const nudges = current.dispatch_nudges ?? (current.dispatch_nudged ? 1 : 0);
|
|
@@ -593,7 +604,8 @@ export async function handleHook({ payload, project, now = Date.now(), cli = 'll
|
|
|
593
604
|
// decide() speaks in the default CLI spelling; the hook swaps in the runnable path.
|
|
594
605
|
const text = result.output.kind === 'dispatch' ? dispatchNudgeFor(cli, result.output.planned, result.output.taskType)
|
|
595
606
|
: result.output.kind === 'dispatch_followup' ? dispatchFollowupFor(cli, result.output.planned, result.output.taskType)
|
|
596
|
-
: result.output.kind === 'overreach' ? (result.output.
|
|
607
|
+
: result.output.kind === 'overreach' ? (result.output.live ? overreachLiveNudgeFor(cli, result.output.live)
|
|
608
|
+
: result.output.calls ? overreachWorkNudgeFor(cli, result.output.calls) : overreachNudgeFor(cli, result.output.files))
|
|
597
609
|
: nudgeFor(cli);
|
|
598
610
|
return { hookSpecificOutput: { hookEventName: 'PreToolUse', additionalContext: text } };
|
|
599
611
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "llm-orchestrator",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.8",
|
|
4
4
|
"description": "Write /task once — it plans the work, shards it across parallel subagents, gates every phase and verifies before claiming done. Claude Code, Codex, OpenCode, Kilo.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|