@intrect/openswarm 0.17.2 → 0.17.4
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/README.md +21 -5
- package/config.example.yaml +18 -0
- package/dist/adapters/agenticLoop.d.ts +2 -0
- package/dist/adapters/agenticLoop.d.ts.map +1 -1
- package/dist/adapters/agenticLoop.js +6 -3
- package/dist/adapters/agenticLoop.js.map +1 -1
- package/dist/adapters/base.d.ts.map +1 -1
- package/dist/adapters/base.js +9 -0
- package/dist/adapters/base.js.map +1 -1
- package/dist/adapters/claude.d.ts.map +1 -1
- package/dist/adapters/claude.js +6 -3
- package/dist/adapters/claude.js.map +1 -1
- package/dist/adapters/codex.d.ts.map +1 -1
- package/dist/adapters/codex.js +3 -2
- package/dist/adapters/codex.js.map +1 -1
- package/dist/adapters/codexResponses.d.ts +2 -1
- package/dist/adapters/codexResponses.d.ts.map +1 -1
- package/dist/adapters/codexResponses.js +34 -30
- package/dist/adapters/codexResponses.js.map +1 -1
- package/dist/adapters/errorClassification.d.ts +11 -0
- package/dist/adapters/errorClassification.d.ts.map +1 -1
- package/dist/adapters/errorClassification.js +21 -0
- package/dist/adapters/errorClassification.js.map +1 -1
- package/dist/adapters/gpt.d.ts.map +1 -1
- package/dist/adapters/gpt.js +1 -0
- package/dist/adapters/gpt.js.map +1 -1
- package/dist/adapters/local.d.ts.map +1 -1
- package/dist/adapters/local.js +1 -0
- package/dist/adapters/local.js.map +1 -1
- package/dist/adapters/openrouter.d.ts.map +1 -1
- package/dist/adapters/openrouter.js +1 -0
- package/dist/adapters/openrouter.js.map +1 -1
- package/dist/adapters/processRegistry.d.ts.map +1 -1
- package/dist/adapters/processRegistry.js +8 -0
- package/dist/adapters/processRegistry.js.map +1 -1
- package/dist/adapters/types.d.ts +2 -0
- package/dist/adapters/types.d.ts.map +1 -1
- package/dist/agents/pairPipeline.d.ts +10 -139
- package/dist/agents/pairPipeline.d.ts.map +1 -1
- package/dist/agents/pairPipeline.js +161 -37
- package/dist/agents/pairPipeline.js.map +1 -1
- package/dist/agents/pairPipelineTypes.d.ts +111 -0
- package/dist/agents/pairPipelineTypes.d.ts.map +1 -0
- package/dist/agents/pairPipelineTypes.js +2 -0
- package/dist/agents/pairPipelineTypes.js.map +1 -0
- package/dist/agents/pipelineGuards.d.ts.map +1 -1
- package/dist/agents/pipelineGuards.js +346 -0
- package/dist/agents/pipelineGuards.js.map +1 -1
- package/dist/agents/pipelineTaskPrefix.d.ts +3 -0
- package/dist/agents/pipelineTaskPrefix.d.ts.map +1 -0
- package/dist/agents/pipelineTaskPrefix.js +16 -0
- package/dist/agents/pipelineTaskPrefix.js.map +1 -0
- package/dist/agents/reflection.d.ts +9 -1
- package/dist/agents/reflection.d.ts.map +1 -1
- package/dist/agents/reflection.js +27 -1
- package/dist/agents/reflection.js.map +1 -1
- package/dist/agents/reviewer.d.ts +6 -0
- package/dist/agents/reviewer.d.ts.map +1 -1
- package/dist/agents/reviewer.js +4 -1
- package/dist/agents/reviewer.js.map +1 -1
- package/dist/agents/stageErrorClassification.d.ts +16 -0
- package/dist/agents/stageErrorClassification.d.ts.map +1 -0
- package/dist/agents/stageErrorClassification.js +38 -0
- package/dist/agents/stageErrorClassification.js.map +1 -0
- package/dist/agents/stageModelResolver.d.ts +8 -0
- package/dist/agents/stageModelResolver.d.ts.map +1 -0
- package/dist/agents/stageModelResolver.js +22 -0
- package/dist/agents/stageModelResolver.js.map +1 -0
- package/dist/agents/worker.d.ts +33 -0
- package/dist/agents/worker.d.ts.map +1 -1
- package/dist/agents/worker.js +59 -4
- package/dist/agents/worker.js.map +1 -1
- package/dist/agents/workerFanout.d.ts +38 -0
- package/dist/agents/workerFanout.d.ts.map +1 -0
- package/dist/agents/workerFanout.js +292 -0
- package/dist/agents/workerFanout.js.map +1 -0
- package/dist/agents/workerFanoutGate.d.ts +48 -0
- package/dist/agents/workerFanoutGate.d.ts.map +1 -0
- package/dist/agents/workerFanoutGate.js +146 -0
- package/dist/agents/workerFanoutGate.js.map +1 -0
- package/dist/agents/workerValidationEvidence.d.ts +5 -0
- package/dist/agents/workerValidationEvidence.d.ts.map +1 -0
- package/dist/agents/workerValidationEvidence.js +75 -0
- package/dist/agents/workerValidationEvidence.js.map +1 -0
- package/dist/automation/autonomousRunner.d.ts +26 -6
- package/dist/automation/autonomousRunner.d.ts.map +1 -1
- package/dist/automation/autonomousRunner.js +243 -45
- package/dist/automation/autonomousRunner.js.map +1 -1
- package/dist/automation/backlogGrooming.d.ts +52 -0
- package/dist/automation/backlogGrooming.d.ts.map +1 -0
- package/dist/automation/backlogGrooming.js +231 -0
- package/dist/automation/backlogGrooming.js.map +1 -0
- package/dist/automation/runnerExecution.d.ts +1 -1
- package/dist/automation/runnerExecution.d.ts.map +1 -1
- package/dist/automation/runnerExecution.js +31 -9
- package/dist/automation/runnerExecution.js.map +1 -1
- package/dist/automation/runnerState.d.ts +9 -0
- package/dist/automation/runnerState.d.ts.map +1 -1
- package/dist/automation/runnerState.js +17 -0
- package/dist/automation/runnerState.js.map +1 -1
- package/dist/automation/runnerTypes.d.ts +3 -1
- package/dist/automation/runnerTypes.d.ts.map +1 -1
- package/dist/automation/taskSource.d.ts +6 -3
- package/dist/automation/taskSource.d.ts.map +1 -1
- package/dist/automation/taskSource.js +5 -0
- package/dist/automation/taskSource.js.map +1 -1
- package/dist/cli/daemon.d.ts +20 -3
- package/dist/cli/daemon.d.ts.map +1 -1
- package/dist/cli/daemon.js +42 -2
- package/dist/cli/daemon.js.map +1 -1
- package/dist/cli/fixBoard.d.ts +14 -0
- package/dist/cli/fixBoard.d.ts.map +1 -0
- package/dist/cli/fixBoard.js +32 -0
- package/dist/cli/fixBoard.js.map +1 -0
- package/dist/cli/fixCommand.d.ts +8 -0
- package/dist/cli/fixCommand.d.ts.map +1 -1
- package/dist/cli/fixCommand.js +47 -8
- package/dist/cli/fixCommand.js.map +1 -1
- package/dist/cli/memoryCommand.d.ts +37 -0
- package/dist/cli/memoryCommand.d.ts.map +1 -0
- package/dist/cli/memoryCommand.js +156 -0
- package/dist/cli/memoryCommand.js.map +1 -0
- package/dist/cli/reviewAudit.d.ts +68 -0
- package/dist/cli/reviewAudit.d.ts.map +1 -1
- package/dist/cli/reviewAudit.js +147 -4
- package/dist/cli/reviewAudit.js.map +1 -1
- package/dist/cli/reviewMaxCommand.d.ts +2 -0
- package/dist/cli/reviewMaxCommand.d.ts.map +1 -1
- package/dist/cli/reviewMaxCommand.js +61 -36
- package/dist/cli/reviewMaxCommand.js.map +1 -1
- package/dist/cli.js +68 -13
- package/dist/cli.js.map +1 -1
- package/dist/core/config.d.ts +413 -0
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +51 -5
- package/dist/core/config.js.map +1 -1
- package/dist/core/eventHub.d.ts +22 -0
- package/dist/core/eventHub.d.ts.map +1 -1
- package/dist/core/eventHub.js +1 -0
- package/dist/core/eventHub.js.map +1 -1
- package/dist/core/providerOverride.d.ts +9 -0
- package/dist/core/providerOverride.d.ts.map +1 -1
- package/dist/core/providerOverride.js +12 -0
- package/dist/core/providerOverride.js.map +1 -1
- package/dist/core/service.d.ts.map +1 -1
- package/dist/core/service.js +8 -2
- package/dist/core/service.js.map +1 -1
- package/dist/core/types.d.ts +61 -1
- package/dist/core/types.d.ts.map +1 -1
- package/dist/linear/linear.d.ts +2 -1
- package/dist/linear/linear.d.ts.map +1 -1
- package/dist/linear/linear.js +16 -6
- package/dist/linear/linear.js.map +1 -1
- package/dist/locale/prompts/en.d.ts.map +1 -1
- package/dist/locale/prompts/en.js +11 -1
- package/dist/locale/prompts/en.js.map +1 -1
- package/dist/locale/prompts/ko.d.ts.map +1 -1
- package/dist/locale/prompts/ko.js +11 -1
- package/dist/locale/prompts/ko.js.map +1 -1
- package/dist/memory/compaction.d.ts +2 -2
- package/dist/memory/compaction.d.ts.map +1 -1
- package/dist/memory/compaction.js +22 -17
- package/dist/memory/compaction.js.map +1 -1
- package/dist/memory/index.d.ts +3 -3
- package/dist/memory/index.js +3 -3
- package/dist/memory/memoryCore.d.ts +15 -27
- package/dist/memory/memoryCore.d.ts.map +1 -1
- package/dist/memory/memoryCore.js +112 -97
- package/dist/memory/memoryCore.js.map +1 -1
- package/dist/memory/memoryFilters.d.ts +8 -0
- package/dist/memory/memoryFilters.d.ts.map +1 -0
- package/dist/memory/memoryFilters.js +26 -0
- package/dist/memory/memoryFilters.js.map +1 -0
- package/dist/memory/memoryOps.d.ts +7 -23
- package/dist/memory/memoryOps.d.ts.map +1 -1
- package/dist/memory/memoryOps.js +49 -109
- package/dist/memory/memoryOps.js.map +1 -1
- package/dist/memory/repoKnowledge.d.ts.map +1 -1
- package/dist/memory/repoKnowledge.js +48 -3
- package/dist/memory/repoKnowledge.js.map +1 -1
- package/dist/orchestration/conflictDetector.d.ts.map +1 -1
- package/dist/orchestration/conflictDetector.js +26 -7
- package/dist/orchestration/conflictDetector.js.map +1 -1
- package/dist/orchestration/decisionEngine.d.ts +1 -0
- package/dist/orchestration/decisionEngine.d.ts.map +1 -1
- package/dist/orchestration/decisionEngine.js.map +1 -1
- package/dist/orchestration/taskScheduler.d.ts +5 -0
- package/dist/orchestration/taskScheduler.d.ts.map +1 -1
- package/dist/orchestration/taskScheduler.js +36 -12
- package/dist/orchestration/taskScheduler.js.map +1 -1
- package/dist/registry/memoryBridge.js +4 -4
- package/dist/registry/memoryBridge.js.map +1 -1
- package/dist/support/chatMemory.js +1 -1
- package/dist/support/chatMemory.js.map +1 -1
- package/dist/support/dashboardHtml.d.ts +1 -1
- package/dist/support/dashboardHtml.d.ts.map +1 -1
- package/dist/support/dashboardHtml.js +12 -0
- package/dist/support/dashboardHtml.js.map +1 -1
- package/dist/support/gitTracker.d.ts +30 -3
- package/dist/support/gitTracker.d.ts.map +1 -1
- package/dist/support/gitTracker.js +108 -29
- package/dist/support/gitTracker.js.map +1 -1
- package/dist/support/repoMetadata.d.ts +10 -0
- package/dist/support/repoMetadata.d.ts.map +1 -1
- package/dist/support/repoMetadata.js +31 -0
- package/dist/support/repoMetadata.js.map +1 -1
- package/dist/support/updateNotifier.d.ts +12 -0
- package/dist/support/updateNotifier.d.ts.map +1 -1
- package/dist/support/updateNotifier.js +71 -0
- package/dist/support/updateNotifier.js.map +1 -1
- package/dist/support/web.d.ts.map +1 -1
- package/dist/support/web.js +5 -3
- package/dist/support/web.js.map +1 -1
- package/dist/support/worktreeManager.d.ts +33 -0
- package/dist/support/worktreeManager.d.ts.map +1 -1
- package/dist/support/worktreeManager.js +172 -2
- package/dist/support/worktreeManager.js.map +1 -1
- package/dist/tui/App.js +1 -1
- package/dist/tui/App.js.map +1 -1
- package/dist/tui/components/AuditBoard.d.ts +3 -2
- package/dist/tui/components/AuditBoard.d.ts.map +1 -1
- package/dist/tui/components/AuditBoard.js +13 -4
- package/dist/tui/components/AuditBoard.js.map +1 -1
- package/dist/tui/components/DataTable.d.ts +3 -1
- package/dist/tui/components/DataTable.d.ts.map +1 -1
- package/dist/tui/components/DataTable.js +22 -5
- package/dist/tui/components/DataTable.js.map +1 -1
- package/dist/tui/components/StageTimeline.d.ts +1 -1
- package/dist/tui/components/StageTimeline.d.ts.map +1 -1
- package/dist/tui/components/StageTimeline.js +5 -2
- package/dist/tui/components/StageTimeline.js.map +1 -1
- package/dist/tui/components/SubagentTree.d.ts +6 -6
- package/dist/tui/components/SubagentTree.d.ts.map +1 -1
- package/dist/tui/components/SubagentTree.js +33 -5
- package/dist/tui/components/SubagentTree.js.map +1 -1
- package/dist/tui/eventCoalescer.d.ts +29 -0
- package/dist/tui/eventCoalescer.d.ts.map +1 -0
- package/dist/tui/eventCoalescer.js +56 -0
- package/dist/tui/eventCoalescer.js.map +1 -0
- package/dist/tui/hooks/usePipelineEvents.d.ts +1 -1
- package/dist/tui/hooks/usePipelineEvents.d.ts.map +1 -1
- package/dist/tui/hooks/usePipelineEvents.js +18 -4
- package/dist/tui/hooks/usePipelineEvents.js.map +1 -1
- package/dist/tui/monitorRows.d.ts +41 -2
- package/dist/tui/monitorRows.d.ts.map +1 -1
- package/dist/tui/monitorRows.js +86 -7
- package/dist/tui/monitorRows.js.map +1 -1
- package/dist/tui/panels/MonitorPanel.d.ts +2 -1
- package/dist/tui/panels/MonitorPanel.d.ts.map +1 -1
- package/dist/tui/panels/MonitorPanel.js +2 -2
- package/dist/tui/panels/MonitorPanel.js.map +1 -1
- package/dist/tui/panels/PipelinePanel.d.ts.map +1 -1
- package/dist/tui/panels/PipelinePanel.js +6 -1
- package/dist/tui/panels/PipelinePanel.js.map +1 -1
- package/dist/tui/pipelineEvents.d.ts +14 -0
- package/dist/tui/pipelineEvents.d.ts.map +1 -1
- package/dist/tui/pipelineEvents.js +89 -1
- package/dist/tui/pipelineEvents.js.map +1 -1
- package/dist/tui/subagentTree.d.ts +26 -3
- package/dist/tui/subagentTree.d.ts.map +1 -1
- package/dist/tui/subagentTree.js +89 -14
- package/dist/tui/subagentTree.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
// ============================================
|
|
2
|
+
// OpenSwarm - Adaptive worker fan-out
|
|
3
|
+
// ============================================
|
|
4
|
+
//
|
|
5
|
+
// Runs candidate workers in isolated temporary git clones and promotes only the
|
|
6
|
+
// selected winner's diff back into the real project path.
|
|
7
|
+
import { execFile } from 'node:child_process';
|
|
8
|
+
import { existsSync } from 'node:fs';
|
|
9
|
+
import { cp, mkdir, mkdtemp, rm, symlink, writeFile } from 'node:fs/promises';
|
|
10
|
+
import { tmpdir } from 'node:os';
|
|
11
|
+
import { dirname, join, resolve } from 'node:path';
|
|
12
|
+
import { promisify } from 'node:util';
|
|
13
|
+
import { runPool } from '../support/concurrencyPool.js';
|
|
14
|
+
import { loadRepoMetadata } from '../support/repoMetadata.js';
|
|
15
|
+
import { resolveSharedPaths } from '../support/worktreeManager.js';
|
|
16
|
+
import { runWorker } from './worker.js';
|
|
17
|
+
import { runGuards } from './pipelineGuards.js';
|
|
18
|
+
const exec = promisify(execFile);
|
|
19
|
+
function safeCandidateId(id, index) {
|
|
20
|
+
const safe = id.toLowerCase().replace(/[^a-z0-9._-]+/g, '-').replace(/^-|-$/g, '').slice(0, 48);
|
|
21
|
+
return safe || `candidate-${index + 1}`;
|
|
22
|
+
}
|
|
23
|
+
async function git(cwd, args, opts) {
|
|
24
|
+
const { stdout } = await exec('git', args, {
|
|
25
|
+
cwd,
|
|
26
|
+
encoding: 'utf8',
|
|
27
|
+
env: opts?.env,
|
|
28
|
+
maxBuffer: 20 * 1024 * 1024,
|
|
29
|
+
});
|
|
30
|
+
return String(stdout);
|
|
31
|
+
}
|
|
32
|
+
// Capture ALL uncommitted work in the project (tracked edits, deletions, and
|
|
33
|
+
// untracked new files) as a binary patch vs HEAD, WITHOUT mutating the project's
|
|
34
|
+
// real index or worktree — everything is staged into a throwaway temporary index
|
|
35
|
+
// selected via GIT_INDEX_FILE. Returns '' when the worktree is clean. This lets
|
|
36
|
+
// fan-out run on a dirty tree (e.g. a self-repair retry that still holds the
|
|
37
|
+
// previous iteration's edits) by seeding that state into each sandbox.
|
|
38
|
+
async function captureBaselinePatch(projectPath) {
|
|
39
|
+
const idxDir = await mkdtemp(join(tmpdir(), 'openswarm-fanout-idx-'));
|
|
40
|
+
const env = { ...process.env, GIT_INDEX_FILE: join(idxDir, 'index') };
|
|
41
|
+
try {
|
|
42
|
+
await git(projectPath, ['add', '-A'], { env });
|
|
43
|
+
return await git(projectPath, ['diff', '--cached', '--binary', 'HEAD'], { env });
|
|
44
|
+
}
|
|
45
|
+
finally {
|
|
46
|
+
await rm(idxDir, { recursive: true, force: true });
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
async function cloneSandbox(projectPath, root, id, sharedPathMode) {
|
|
50
|
+
const sandbox = join(root, id);
|
|
51
|
+
await git(projectPath, ['clone', '--quiet', '--no-hardlinks', '--', projectPath, sandbox]);
|
|
52
|
+
if (sharedPathMode === 'link')
|
|
53
|
+
await linkSharedPaths(projectPath, sandbox);
|
|
54
|
+
if (sharedPathMode === 'copy')
|
|
55
|
+
await copySharedPaths(projectPath, sandbox);
|
|
56
|
+
return sandbox;
|
|
57
|
+
}
|
|
58
|
+
async function linkSharedPaths(projectPath, sandboxPath) {
|
|
59
|
+
let metadata = null;
|
|
60
|
+
try {
|
|
61
|
+
metadata = await loadRepoMetadata(projectPath);
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
metadata = null;
|
|
65
|
+
}
|
|
66
|
+
for (const rel of resolveSharedPaths(projectPath, metadata)) {
|
|
67
|
+
const target = resolve(projectPath, rel);
|
|
68
|
+
const linkPath = resolve(sandboxPath, rel);
|
|
69
|
+
if (existsSync(linkPath))
|
|
70
|
+
continue;
|
|
71
|
+
await mkdir(dirname(linkPath), { recursive: true });
|
|
72
|
+
await symlink(target, linkPath);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
async function copySharedPaths(projectPath, sandboxPath) {
|
|
76
|
+
let metadata = null;
|
|
77
|
+
try {
|
|
78
|
+
metadata = await loadRepoMetadata(projectPath);
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
metadata = null;
|
|
82
|
+
}
|
|
83
|
+
for (const rel of resolveSharedPaths(projectPath, metadata)) {
|
|
84
|
+
const source = resolve(projectPath, rel);
|
|
85
|
+
const target = resolve(sandboxPath, rel);
|
|
86
|
+
if (existsSync(target))
|
|
87
|
+
continue;
|
|
88
|
+
await mkdir(dirname(target), { recursive: true });
|
|
89
|
+
await cp(source, target, {
|
|
90
|
+
recursive: true,
|
|
91
|
+
force: false,
|
|
92
|
+
errorOnExist: false,
|
|
93
|
+
verbatimSymlinks: true,
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
function sharedPathModeFor(linkSharedPaths) {
|
|
98
|
+
if (linkSharedPaths === true)
|
|
99
|
+
return 'link';
|
|
100
|
+
if (linkSharedPaths === false)
|
|
101
|
+
return 'off';
|
|
102
|
+
return 'copy';
|
|
103
|
+
}
|
|
104
|
+
async function changedFiles(projectPath) {
|
|
105
|
+
const out = await git(projectPath, ['status', '--porcelain']).catch(() => '');
|
|
106
|
+
return out
|
|
107
|
+
.split('\n')
|
|
108
|
+
.map((line) => line.trimEnd())
|
|
109
|
+
.filter(Boolean)
|
|
110
|
+
.map((line) => {
|
|
111
|
+
const file = line.slice(3);
|
|
112
|
+
return file.includes(' -> ') ? file.split(' -> ').pop() ?? file : file;
|
|
113
|
+
})
|
|
114
|
+
.filter(Boolean);
|
|
115
|
+
}
|
|
116
|
+
async function diffBinary(projectPath) {
|
|
117
|
+
await git(projectPath, ['add', '-A']);
|
|
118
|
+
return git(projectPath, ['diff', '--cached', '--binary', 'HEAD']);
|
|
119
|
+
}
|
|
120
|
+
async function applyDiff(projectPath, patchRoot, diff) {
|
|
121
|
+
const patchPath = join(patchRoot, 'winner.patch');
|
|
122
|
+
await writeFile(patchPath, diff, 'utf8');
|
|
123
|
+
// Plain worktree apply — NOT --3way. --3way validates the preimage against
|
|
124
|
+
// the INDEX, but on a dirty project (self-repair retry) the index still holds
|
|
125
|
+
// HEAD while the patch preimage is the seeded dirty state → "does not match
|
|
126
|
+
// index" even though the WORKTREE matches the preimage exactly (the sandbox
|
|
127
|
+
// base was cloned+seeded from it). A 3-way fallback couldn't work anyway: the
|
|
128
|
+
// sandbox's baseline blobs don't exist in the project's object database.
|
|
129
|
+
await git(projectPath, ['apply', '--whitespace=nowarn', patchPath]);
|
|
130
|
+
}
|
|
131
|
+
function scoreCandidate(input) {
|
|
132
|
+
const blockingIssues = input.guards?.results.filter((r) => !r.passed && r.blocking).flatMap((r) => r.issues) ?? [];
|
|
133
|
+
const hasDiff = input.filesChanged.length > 0;
|
|
134
|
+
const guardsPass = blockingIssues.length === 0;
|
|
135
|
+
const eligible = input.result.success && hasDiff && guardsPass && !input.error;
|
|
136
|
+
let score = 0;
|
|
137
|
+
if (input.result.success)
|
|
138
|
+
score += 100;
|
|
139
|
+
if (hasDiff)
|
|
140
|
+
score += 25;
|
|
141
|
+
if (guardsPass)
|
|
142
|
+
score += 25;
|
|
143
|
+
if (typeof input.result.confidencePercent === 'number')
|
|
144
|
+
score += Math.max(0, Math.min(100, input.result.confidencePercent)) / 10;
|
|
145
|
+
score -= Math.min(input.filesChanged.length, 20);
|
|
146
|
+
score -= Math.min(Math.round(input.durationMs / 30_000), 20);
|
|
147
|
+
if (input.error)
|
|
148
|
+
score -= 100;
|
|
149
|
+
if (blockingIssues.length > 0)
|
|
150
|
+
score -= 50 + blockingIssues.length * 5;
|
|
151
|
+
return { score, eligible };
|
|
152
|
+
}
|
|
153
|
+
// Seed the project's pre-existing uncommitted state into a freshly-cloned
|
|
154
|
+
// sandbox and commit it, so the candidate continues from the dirty base and the
|
|
155
|
+
// winner's promoted diff is the incremental delta (not base+delta, which would
|
|
156
|
+
// double-apply onto the already-dirty project).
|
|
157
|
+
async function seedBaseline(sandbox, root, id, baseline) {
|
|
158
|
+
if (!baseline.trim())
|
|
159
|
+
return;
|
|
160
|
+
const patchPath = join(root, `${id}-base.patch`);
|
|
161
|
+
await writeFile(patchPath, baseline, 'utf8');
|
|
162
|
+
await git(sandbox, ['apply', '--whitespace=nowarn', patchPath]);
|
|
163
|
+
await rm(patchPath, { force: true });
|
|
164
|
+
await git(sandbox, ['add', '-A']);
|
|
165
|
+
await git(sandbox, [
|
|
166
|
+
'-c', 'user.email=fanout@openswarm.local',
|
|
167
|
+
'-c', 'user.name=OpenSwarm Fanout',
|
|
168
|
+
'commit', '--quiet', '--no-verify', '-m', 'fanout: seed pre-existing worktree state',
|
|
169
|
+
]);
|
|
170
|
+
}
|
|
171
|
+
async function runCandidate(options, candidate, index, root, baseline) {
|
|
172
|
+
const id = safeCandidateId(candidate.id, index);
|
|
173
|
+
const started = Date.now();
|
|
174
|
+
let sandbox = '';
|
|
175
|
+
try {
|
|
176
|
+
sandbox = await cloneSandbox(options.projectPath, root, id, sharedPathModeFor(options.linkSharedPaths));
|
|
177
|
+
await seedBaseline(sandbox, root, id, baseline);
|
|
178
|
+
const result = await runWorker({
|
|
179
|
+
...options.baseWorkerOptions,
|
|
180
|
+
projectPath: sandbox,
|
|
181
|
+
model: candidate.model ?? options.baseWorkerOptions.model,
|
|
182
|
+
adapterName: candidate.adapter ?? options.baseWorkerOptions.adapterName,
|
|
183
|
+
reasoningEffort: candidate.reasoningEffort ?? options.baseWorkerOptions.reasoningEffort,
|
|
184
|
+
maxTurns: candidate.maxTurns ?? options.baseWorkerOptions.maxTurns,
|
|
185
|
+
nudgeMaxOnNoEdit: candidate.nudgeMaxOnNoEdit ?? options.baseWorkerOptions.nudgeMaxOnNoEdit,
|
|
186
|
+
webTools: candidate.webTools ?? options.baseWorkerOptions.webTools,
|
|
187
|
+
memoryTools: candidate.memoryTools ?? options.baseWorkerOptions.memoryTools,
|
|
188
|
+
processContext: options.baseWorkerOptions.processContext
|
|
189
|
+
? { ...options.baseWorkerOptions.processContext, stage: `worker:${id}` }
|
|
190
|
+
: undefined,
|
|
191
|
+
onLog: (line) => options.onLog?.(`[${id}] ${line}`),
|
|
192
|
+
});
|
|
193
|
+
const files = await changedFiles(sandbox);
|
|
194
|
+
const guards = options.guards && files.length > 0
|
|
195
|
+
? await runGuards({ ...result, filesChanged: files }, sandbox, options.guards)
|
|
196
|
+
: undefined;
|
|
197
|
+
const scored = scoreCandidate({ result, filesChanged: files, guards, durationMs: Date.now() - started });
|
|
198
|
+
return {
|
|
199
|
+
id,
|
|
200
|
+
projectPath: sandbox,
|
|
201
|
+
result,
|
|
202
|
+
filesChanged: files,
|
|
203
|
+
guards,
|
|
204
|
+
durationMs: Date.now() - started,
|
|
205
|
+
score: scored.score,
|
|
206
|
+
eligible: scored.eligible,
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
catch (err) {
|
|
210
|
+
const result = {
|
|
211
|
+
success: false,
|
|
212
|
+
summary: `Fan-out candidate ${id} failed`,
|
|
213
|
+
filesChanged: [],
|
|
214
|
+
commands: [],
|
|
215
|
+
output: '',
|
|
216
|
+
error: err instanceof Error ? err.message : String(err),
|
|
217
|
+
};
|
|
218
|
+
const scored = scoreCandidate({ result, filesChanged: [], durationMs: Date.now() - started, error: result.error });
|
|
219
|
+
return {
|
|
220
|
+
id,
|
|
221
|
+
projectPath: sandbox,
|
|
222
|
+
result,
|
|
223
|
+
filesChanged: [],
|
|
224
|
+
durationMs: Date.now() - started,
|
|
225
|
+
score: scored.score,
|
|
226
|
+
eligible: false,
|
|
227
|
+
error: result.error,
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
export async function runWorkerFanout(options) {
|
|
232
|
+
if (options.candidates.length < 2) {
|
|
233
|
+
return { candidates: [], fallbackReason: 'fan-out needs at least two candidates' };
|
|
234
|
+
}
|
|
235
|
+
// A dirty worktree is expected on self-repair retries (the gate scores fan-out
|
|
236
|
+
// mainly on retry signals). Rather than bail, snapshot the uncommitted state
|
|
237
|
+
// and seed it into each sandbox so candidates continue from it and only the
|
|
238
|
+
// incremental winner diff is promoted back. Falls back to '' (clean) on error.
|
|
239
|
+
const baseline = await captureBaselinePatch(options.projectPath).catch(() => '');
|
|
240
|
+
const root = await mkdtemp(join(tmpdir(), 'openswarm-worker-fanout-'));
|
|
241
|
+
try {
|
|
242
|
+
options.onLog?.(`[fanout] launching ${options.candidates.length} candidate worker(s)${baseline.trim() ? ' (seeded from dirty worktree)' : ''}`);
|
|
243
|
+
const settled = await runPool(options.candidates, options.concurrency, (candidate, index) => runCandidate(options, candidate, index, root, baseline), (item) => {
|
|
244
|
+
if (item.value) {
|
|
245
|
+
options.onLog?.(`[fanout] ${item.value.id}: score=${item.value.score.toFixed(1)} eligible=${item.value.eligible} files=${item.value.filesChanged.length}`);
|
|
246
|
+
}
|
|
247
|
+
else if (item.error) {
|
|
248
|
+
options.onLog?.(`[fanout] candidate ${item.index + 1} failed: ${item.error instanceof Error ? item.error.message : String(item.error)}`);
|
|
249
|
+
}
|
|
250
|
+
});
|
|
251
|
+
const candidates = settled
|
|
252
|
+
.map((item) => item.value)
|
|
253
|
+
.filter((item) => Boolean(item));
|
|
254
|
+
const winner = candidates
|
|
255
|
+
.filter((candidate) => candidate.eligible)
|
|
256
|
+
.sort((a, b) => b.score - a.score)[0];
|
|
257
|
+
if (!winner) {
|
|
258
|
+
return { candidates, fallbackReason: 'no eligible fan-out candidate produced a guarded diff' };
|
|
259
|
+
}
|
|
260
|
+
const diff = await diffBinary(winner.projectPath);
|
|
261
|
+
if (!diff.trim()) {
|
|
262
|
+
return { candidates, fallbackReason: 'selected fan-out candidate had no diff to promote' };
|
|
263
|
+
}
|
|
264
|
+
// A promotion failure (e.g. the project drifted while candidates ran) must
|
|
265
|
+
// not sink the whole worker stage — fall back to a single in-place worker,
|
|
266
|
+
// which is what would have run without fan-out.
|
|
267
|
+
try {
|
|
268
|
+
await applyDiff(options.projectPath, root, diff);
|
|
269
|
+
}
|
|
270
|
+
catch (err) {
|
|
271
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
272
|
+
return { candidates, fallbackReason: `winner diff did not apply cleanly: ${msg}` };
|
|
273
|
+
}
|
|
274
|
+
const promotedFiles = await changedFiles(options.projectPath);
|
|
275
|
+
winner.result = {
|
|
276
|
+
...winner.result,
|
|
277
|
+
summary: `[fanout:${winner.id}] ${winner.result.summary}`,
|
|
278
|
+
filesChanged: promotedFiles,
|
|
279
|
+
};
|
|
280
|
+
options.onLog?.(`[fanout] promoted ${winner.id}: ${promotedFiles.length} file(s)`);
|
|
281
|
+
return { winner, candidates };
|
|
282
|
+
}
|
|
283
|
+
finally {
|
|
284
|
+
if (!options.keepSandboxes) {
|
|
285
|
+
await rm(root, { recursive: true, force: true });
|
|
286
|
+
}
|
|
287
|
+
else {
|
|
288
|
+
options.onLog?.(`[fanout] kept sandboxes at ${root}`);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
//# sourceMappingURL=workerFanout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workerFanout.js","sourceRoot":"","sources":["../../src/agents/workerFanout.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { TaskItem } from '../orchestration/decisionEngine.js';
|
|
2
|
+
import type { PipelineGuardsConfig, RoleConfig } from '../core/types.js';
|
|
3
|
+
import type { WorkerResult } from './agentPair.js';
|
|
4
|
+
import type { WorkerOptions } from './worker.js';
|
|
5
|
+
export interface WorkerFanoutGateSignal {
|
|
6
|
+
code: string;
|
|
7
|
+
weight: number;
|
|
8
|
+
reason: string;
|
|
9
|
+
}
|
|
10
|
+
export interface WorkerFanoutGateDecision {
|
|
11
|
+
enabled: boolean;
|
|
12
|
+
shouldFanOut: boolean;
|
|
13
|
+
score: number;
|
|
14
|
+
threshold: number;
|
|
15
|
+
signals: WorkerFanoutGateSignal[];
|
|
16
|
+
}
|
|
17
|
+
export interface FanoutDraftAnalysis {
|
|
18
|
+
relevantFiles: string[];
|
|
19
|
+
sufficient?: boolean;
|
|
20
|
+
}
|
|
21
|
+
export declare function evaluateWorkerFanoutGate(input: {
|
|
22
|
+
task: TaskItem;
|
|
23
|
+
draftAnalysis?: FanoutDraftAnalysis;
|
|
24
|
+
iteration: number;
|
|
25
|
+
feedbackSource?: 'objective' | 'review';
|
|
26
|
+
effort?: 'low' | 'medium' | 'high';
|
|
27
|
+
config?: RoleConfig['fanout'];
|
|
28
|
+
}): WorkerFanoutGateDecision;
|
|
29
|
+
export declare function emitWorkerFanoutGateDecision(input: {
|
|
30
|
+
context: {
|
|
31
|
+
task: TaskItem;
|
|
32
|
+
currentIteration: number;
|
|
33
|
+
taskPrefix: string;
|
|
34
|
+
};
|
|
35
|
+
decision: WorkerFanoutGateDecision;
|
|
36
|
+
verbose?: boolean;
|
|
37
|
+
emit: (event: 'fanout:gate' | 'log', payload: unknown) => void;
|
|
38
|
+
}): void;
|
|
39
|
+
export declare function runWorkerWithOptionalFanout(input: {
|
|
40
|
+
projectPath: string;
|
|
41
|
+
workerOptions: WorkerOptions;
|
|
42
|
+
fanoutDecision?: WorkerFanoutGateDecision;
|
|
43
|
+
fanoutConfig?: RoleConfig['fanout'];
|
|
44
|
+
guards?: Partial<PipelineGuardsConfig>;
|
|
45
|
+
onLog: (line: string) => void;
|
|
46
|
+
runWorker: (options: WorkerOptions) => Promise<WorkerResult>;
|
|
47
|
+
}): Promise<WorkerResult>;
|
|
48
|
+
//# sourceMappingURL=workerFanoutGate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workerFanoutGate.d.ts","sourceRoot":"","sources":["../../src/agents/workerFanoutGate.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oCAAoC,CAAC;AACnE,OAAO,KAAK,EAAE,oBAAoB,EAAE,UAAU,EAA+B,MAAM,kBAAkB,CAAC;AAEtG,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAGjD,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,OAAO,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,sBAAsB,EAAE,CAAC;CACnC;AAED,MAAM,WAAW,mBAAmB;IAClC,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAUD,wBAAgB,wBAAwB,CAAC,KAAK,EAAE;IAC9C,IAAI,EAAE,QAAQ,CAAC;IACf,aAAa,CAAC,EAAE,mBAAmB,CAAC;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,WAAW,GAAG,QAAQ,CAAC;IACxC,MAAM,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IACnC,MAAM,CAAC,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAC;CAC/B,GAAG,wBAAwB,CAsD3B;AAsCD,wBAAgB,4BAA4B,CAAC,KAAK,EAAE;IAClD,OAAO,EAAE;QAAE,IAAI,EAAE,QAAQ,CAAC;QAAC,gBAAgB,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1E,QAAQ,EAAE,wBAAwB,CAAC;IACnC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,EAAE,CAAC,KAAK,EAAE,aAAa,GAAG,KAAK,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;CAChE,GAAG,IAAI,CA0BP;AAED,wBAAsB,2BAA2B,CAAC,KAAK,EAAE;IACvD,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,aAAa,CAAC;IAC7B,cAAc,CAAC,EAAE,wBAAwB,CAAC;IAC1C,YAAY,CAAC,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAC;IACpC,MAAM,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC,CAAC;IACvC,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9B,SAAS,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;CAC9D,GAAG,OAAO,CAAC,YAAY,CAAC,CA4BxB"}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
// ============================================
|
|
2
|
+
// OpenSwarm - Adaptive worker fan-out gate
|
|
3
|
+
// ============================================
|
|
4
|
+
import { broadcastEvent } from '../core/eventHub.js';
|
|
5
|
+
import { runWorkerFanout } from './workerFanout.js';
|
|
6
|
+
const DEFAULT_FANOUT_GATE_MIN_SCORE = 2;
|
|
7
|
+
const CORE_ORCHESTRATION_PATTERN = /\b(pairpipeline|pipeline|autonomousrunner|runnerexecution|worktree|scheduler|adapter|agenticloop|worker|reviewer|tester|auth|mcp|codexresponses|eventhub)\b/i;
|
|
8
|
+
function textMatchesCoreOrchestration(text) {
|
|
9
|
+
return CORE_ORCHESTRATION_PATTERN.test(text.replace(/[^A-Za-z0-9_/.-]+/g, ' '));
|
|
10
|
+
}
|
|
11
|
+
export function evaluateWorkerFanoutGate(input) {
|
|
12
|
+
const enabled = input.config?.enabled ?? true;
|
|
13
|
+
const threshold = input.config?.minScore ?? DEFAULT_FANOUT_GATE_MIN_SCORE;
|
|
14
|
+
if (!enabled) {
|
|
15
|
+
return { enabled: false, shouldFanOut: false, score: 0, threshold, signals: [] };
|
|
16
|
+
}
|
|
17
|
+
const signals = [];
|
|
18
|
+
const add = (code, weight, reason) => {
|
|
19
|
+
signals.push({ code, weight, reason });
|
|
20
|
+
};
|
|
21
|
+
if (input.iteration > 1 && input.feedbackSource === 'objective') {
|
|
22
|
+
add('objective-retry', 2, 'objective guard/test feedback from a previous iteration');
|
|
23
|
+
}
|
|
24
|
+
if (input.iteration > 1 && input.feedbackSource === 'review') {
|
|
25
|
+
add('review-retry', 2, 'reviewer or confidence feedback requested a revision');
|
|
26
|
+
}
|
|
27
|
+
if (input.draftAnalysis?.sufficient === false) {
|
|
28
|
+
add('insufficient-draft', 1, 'draft analysis was insufficient');
|
|
29
|
+
}
|
|
30
|
+
const relevantFiles = input.draftAnalysis?.relevantFiles ?? input.task.fileScope ?? [];
|
|
31
|
+
if (relevantFiles.length >= 4) {
|
|
32
|
+
add('broad-file-scope', 1, `broad file scope (${relevantFiles.length} files)`);
|
|
33
|
+
}
|
|
34
|
+
const scopeText = [
|
|
35
|
+
input.task.title,
|
|
36
|
+
input.task.description ?? '',
|
|
37
|
+
relevantFiles.join(' '),
|
|
38
|
+
].join(' ');
|
|
39
|
+
if (textMatchesCoreOrchestration(scopeText)) {
|
|
40
|
+
add('core-orchestration-scope', 1, 'core orchestration or agent pipeline surface');
|
|
41
|
+
}
|
|
42
|
+
if ((input.task.estimatedMinutes ?? 0) >= 30) {
|
|
43
|
+
add('large-estimate', 1, `estimated ${input.task.estimatedMinutes} minutes`);
|
|
44
|
+
}
|
|
45
|
+
if (input.task.priority === 1 && (input.task.estimatedMinutes ?? 0) >= 15) {
|
|
46
|
+
add('urgent-nontrivial', 1, 'urgent non-trivial task');
|
|
47
|
+
}
|
|
48
|
+
if (input.effort === 'high') {
|
|
49
|
+
add('high-effort-profile', 1, 'matched high-effort job profile');
|
|
50
|
+
}
|
|
51
|
+
const score = signals.reduce((sum, signal) => sum + signal.weight, 0);
|
|
52
|
+
return {
|
|
53
|
+
enabled,
|
|
54
|
+
shouldFanOut: score >= threshold,
|
|
55
|
+
score,
|
|
56
|
+
threshold,
|
|
57
|
+
signals,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
function buildWorkerFanoutCandidates(base, configured) {
|
|
61
|
+
if (configured && configured.length > 0)
|
|
62
|
+
return configured;
|
|
63
|
+
const primary = {
|
|
64
|
+
id: 'primary',
|
|
65
|
+
adapter: base.adapterName,
|
|
66
|
+
model: base.model,
|
|
67
|
+
reasoningEffort: base.reasoningEffort,
|
|
68
|
+
maxTurns: base.maxTurns,
|
|
69
|
+
nudgeMaxOnNoEdit: base.nudgeMaxOnNoEdit,
|
|
70
|
+
webTools: base.webTools,
|
|
71
|
+
memoryTools: base.memoryTools,
|
|
72
|
+
};
|
|
73
|
+
const spark = {
|
|
74
|
+
id: 'spark-diversity',
|
|
75
|
+
adapter: 'codex-responses',
|
|
76
|
+
model: 'gpt-5.3-codex-spark',
|
|
77
|
+
reasoningEffort: 'low',
|
|
78
|
+
maxTurns: Math.min(base.maxTurns ?? 12, 12),
|
|
79
|
+
nudgeMaxOnNoEdit: base.nudgeMaxOnNoEdit,
|
|
80
|
+
webTools: false,
|
|
81
|
+
memoryTools: false,
|
|
82
|
+
};
|
|
83
|
+
const seen = new Set();
|
|
84
|
+
return [primary, spark].filter((candidate) => {
|
|
85
|
+
const key = `${candidate.adapter ?? ''}:${candidate.model ?? ''}`;
|
|
86
|
+
if (seen.has(key))
|
|
87
|
+
return false;
|
|
88
|
+
seen.add(key);
|
|
89
|
+
return true;
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
export function emitWorkerFanoutGateDecision(input) {
|
|
93
|
+
const { context, decision } = input;
|
|
94
|
+
const reasons = decision.signals.map((signal) => signal.reason);
|
|
95
|
+
input.emit('fanout:gate', { context, decision });
|
|
96
|
+
broadcastEvent({
|
|
97
|
+
type: 'pipeline:fanout',
|
|
98
|
+
data: {
|
|
99
|
+
taskId: context.task.id,
|
|
100
|
+
iteration: context.currentIteration,
|
|
101
|
+
enabled: decision.enabled,
|
|
102
|
+
shouldFanOut: decision.shouldFanOut,
|
|
103
|
+
score: decision.score,
|
|
104
|
+
threshold: decision.threshold,
|
|
105
|
+
reasons,
|
|
106
|
+
},
|
|
107
|
+
});
|
|
108
|
+
if (!decision.enabled)
|
|
109
|
+
return;
|
|
110
|
+
if (!decision.shouldFanOut && !input.verbose)
|
|
111
|
+
return;
|
|
112
|
+
const verdict = decision.shouldFanOut ? 'recommend fan-out' : 'single worker';
|
|
113
|
+
const detail = reasons.length > 0 ? `: ${reasons.join('; ')}` : '';
|
|
114
|
+
const line = `[FanoutGate] ${verdict} (${decision.score}/${decision.threshold})${detail}`;
|
|
115
|
+
console.log(`[${context.taskPrefix}] ${line}`);
|
|
116
|
+
input.emit('log', { line });
|
|
117
|
+
broadcastEvent({ type: 'log', data: { taskId: context.task.id, stage: 'worker', line: `[${context.taskPrefix}] ${line}` } });
|
|
118
|
+
}
|
|
119
|
+
export async function runWorkerWithOptionalFanout(input) {
|
|
120
|
+
const { fanoutDecision, fanoutConfig, workerOptions } = input;
|
|
121
|
+
if (fanoutDecision?.shouldFanOut && fanoutConfig?.mode === 'execute') {
|
|
122
|
+
const candidates = buildWorkerFanoutCandidates(workerOptions, fanoutConfig.candidates);
|
|
123
|
+
// Surface execution to stdout too: onLog only reaches broadcastEvent, so
|
|
124
|
+
// without this the daemon log shows the gate's "recommend fan-out" line but
|
|
125
|
+
// no evidence fan-out actually ran (the exact symptom that hid this path).
|
|
126
|
+
console.log(`[fanout] executing ${candidates.length} candidate(s) — gate score ${fanoutDecision.score}/${fanoutDecision.threshold}`);
|
|
127
|
+
const fanoutResult = await runWorkerFanout({
|
|
128
|
+
projectPath: input.projectPath,
|
|
129
|
+
baseWorkerOptions: workerOptions,
|
|
130
|
+
candidates,
|
|
131
|
+
concurrency: fanoutConfig.concurrency ?? Math.min(candidates.length, 3),
|
|
132
|
+
keepSandboxes: fanoutConfig.keepSandboxes,
|
|
133
|
+
linkSharedPaths: fanoutConfig.linkSharedPaths,
|
|
134
|
+
guards: input.guards,
|
|
135
|
+
onLog: input.onLog,
|
|
136
|
+
});
|
|
137
|
+
if (fanoutResult.winner) {
|
|
138
|
+
console.log(`[fanout] promoted winner ${fanoutResult.winner.id} (${fanoutResult.winner.filesChanged.length} file(s))`);
|
|
139
|
+
return fanoutResult.winner.result;
|
|
140
|
+
}
|
|
141
|
+
console.log(`[fanout] fallback to single worker: ${fanoutResult.fallbackReason ?? 'no winner'}`);
|
|
142
|
+
input.onLog(`[fanout] fallback to single worker: ${fanoutResult.fallbackReason ?? 'no winner'}`);
|
|
143
|
+
}
|
|
144
|
+
return input.runWorker(workerOptions);
|
|
145
|
+
}
|
|
146
|
+
//# sourceMappingURL=workerFanoutGate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workerFanoutGate.js","sourceRoot":"","sources":["../../src/agents/workerFanoutGate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { WorkerResult } from './agentPair.js';
|
|
2
|
+
export declare function missingWorkerValidationIssues(result: WorkerResult): string[];
|
|
3
|
+
export declare function testerWouldRunForWorkerResult(result: WorkerResult, hasTester: boolean, skipIfNoCode: boolean): boolean;
|
|
4
|
+
export declare function isTesterCodeFile(file: string): boolean;
|
|
5
|
+
//# sourceMappingURL=workerValidationEvidence.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workerValidationEvidence.d.ts","sourceRoot":"","sources":["../../src/agents/workerValidationEvidence.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAgDnD,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,EAAE,CAe5E;AAED,wBAAgB,6BAA6B,CAC3C,MAAM,EAAE,YAAY,EACpB,SAAS,EAAE,OAAO,EAClB,YAAY,EAAE,OAAO,GACpB,OAAO,CAIT;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEtD"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
const VALIDATION_RELEVANT_FILE_RE = /\.(ts|tsx|mts|cts|js|jsx|mjs|cjs|py|rs|go|java|rb|c|cc|cpp|h|hpp|swift|kt|kts|scala|cs|php|sh|bash|zsh|sql|toml|ya?ml|json)$/i;
|
|
2
|
+
const VALIDATION_RELEVANT_BASENAME_RE = /(^|\/)(Dockerfile(?:\.[^/]+)?|Containerfile(?:\.[^/]+)?|Makefile|GNUmakefile|go\.mod|go\.sum|Cargo\.toml|Cargo\.lock|package(?:-lock)?\.json|pnpm-lock\.ya?ml|yarn\.lock|bun\.lockb?|requirements(?:-[^/]+)?\.txt|pyproject\.toml|poetry\.lock|Pipfile(?:\.lock)?|Gemfile(?:\.lock)?|pom\.xml|build\.gradle(?:\.kts)?|settings\.gradle(?:\.kts)?|flake\.nix|shell\.nix|docker-compose\.ya?ml|compose\.ya?ml)$/i;
|
|
3
|
+
// Only treat README/CHANGELOG/LICENSE/NOTICE as doc-only when they carry a doc
|
|
4
|
+
// extension (or none). A real source module named e.g. `readme.ts` must NOT be
|
|
5
|
+
// misclassified as docs — that would let it skip the validation gate while the
|
|
6
|
+
// tester's isTesterCodeFile() still treats it as code (inconsistent).
|
|
7
|
+
const DOC_ONLY_FILE_RE = /(^|\/)(README|CHANGELOG|LICENSE|NOTICE)(\.(md|mdx|txt|rst|adoc))?$|(^|\/)docs?\/|\.((md|mdx|txt|rst|adoc))$/i;
|
|
8
|
+
// Pure data/asset trees (locale strings, fixtures, snapshots, mocks) have
|
|
9
|
+
// nothing to build or test on their own; exempt them so a data-only edit does
|
|
10
|
+
// not get bounced for "no validation command".
|
|
11
|
+
const DATA_ONLY_DIR_RE = /(^|\/)(locales?|i18n|fixtures?|__fixtures__|__snapshots__|snapshots?|__mocks__|mocks?|testdata|test-data)\//i;
|
|
12
|
+
const VALIDATION_COMMAND_RE = /\b(npm\s+(?:test|run\s+(?:test|build|lint|typecheck|check|ci|verify|validate|smoke))|pnpm\s+(?:test|run\s+(?:test|build|lint|typecheck|check|ci|verify|validate|smoke))|yarn\s+(?:test|run\s+(?:test|build|lint|typecheck|check|ci|verify|validate|smoke))|bun\s+(?:test|run\s+(?:test|build|lint|typecheck|check|ci|verify|validate|smoke))|vitest|jest|mocha|pytest|ruff|mypy|pyright|tsc|eslint|oxlint|cargo\s+(?:check|test|clippy|build)|go\s+(?:test|vet|build)|swift\s+test|gradle\s+(?:test|build|check)|mvn\s+(?:test|verify)|make\b|cmake\b|py_compile|compileall|clippy|fmt\s+--check)\b/i;
|
|
13
|
+
// Anchored at each segment start: a leading inspection verb means that segment
|
|
14
|
+
// ran no validation (e.g. `rg "npm test"` searches for the string, it does not
|
|
15
|
+
// run it), so the segment is skipped rather than the whole command rejected.
|
|
16
|
+
const INSPECTION_ONLY_COMMAND_RE = /^\s*(?:rg|grep|sed|cat|ls|find|pwd|git\s+(?:status|diff|show|log|grep)|jq|head|tail|wc|tree|du|file|which)\b/i;
|
|
17
|
+
const SCRIPT_SMOKE_COMMAND_RE = /^\s*(?:python3?|node|tsx|ts-node|uv\s+run|npx|bunx|bash|sh)\b.*\b(?:scripts?\/|tests?\/|\.py|\.js|\.ts|\.sh|--help|--dry-run|smoke|verify|validate|check|test|build|compile)\b/i;
|
|
18
|
+
const TESTER_CODE_FILE_RE = /\.(ts|tsx|mts|cts|js|jsx|mjs|cjs|py|rs|go|java|rb|c|cpp|h|hpp)$/;
|
|
19
|
+
function validationRelevantFiles(files) {
|
|
20
|
+
return files.filter(file => {
|
|
21
|
+
if (/(^|\/)docs?\//i.test(file))
|
|
22
|
+
return false;
|
|
23
|
+
if (VALIDATION_RELEVANT_BASENAME_RE.test(file))
|
|
24
|
+
return true;
|
|
25
|
+
// Data/asset trees (locale, fixtures, snapshots, mocks) are exempt ONLY for
|
|
26
|
+
// non-code assets. A real source module under such a dir (e.g.
|
|
27
|
+
// src/__mocks__/api.ts, test/fixtures/helper.ts) still needs a check —
|
|
28
|
+
// exempting the whole directory would be a gate bypass.
|
|
29
|
+
if (DATA_ONLY_DIR_RE.test(file) && !TESTER_CODE_FILE_RE.test(file))
|
|
30
|
+
return false;
|
|
31
|
+
return VALIDATION_RELEVANT_FILE_RE.test(file) && !DOC_ONLY_FILE_RE.test(file);
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
function commandLooksLikeValidation(command) {
|
|
35
|
+
// Workers routinely chain inspection then validation in one string
|
|
36
|
+
// (e.g. "git diff && npm test"). Evaluate each shell segment independently so
|
|
37
|
+
// a leading inspection verb does not mask a real validation command in a later
|
|
38
|
+
// segment, while an inspection-only segment (which may merely *mention* a test
|
|
39
|
+
// command as a search string) still counts as no validation.
|
|
40
|
+
const segments = command.split(/&&|\|\||;|\|/).map(s => s.trim()).filter(Boolean);
|
|
41
|
+
const candidates = segments.length > 0 ? segments : [command];
|
|
42
|
+
return candidates.some(seg => {
|
|
43
|
+
if (INSPECTION_ONLY_COMMAND_RE.test(seg))
|
|
44
|
+
return false;
|
|
45
|
+
return VALIDATION_COMMAND_RE.test(seg) || SCRIPT_SMOKE_COMMAND_RE.test(seg);
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
export function missingWorkerValidationIssues(result) {
|
|
49
|
+
const changed = validationRelevantFiles(result.filesChanged ?? []);
|
|
50
|
+
if (changed.length === 0)
|
|
51
|
+
return [];
|
|
52
|
+
const commands = result.commands ?? [];
|
|
53
|
+
if (commands.some(commandLooksLikeValidation))
|
|
54
|
+
return [];
|
|
55
|
+
const sample = changed.slice(0, 6).join(', ');
|
|
56
|
+
const suffix = changed.length > 6 ? `, +${changed.length - 6} more` : '';
|
|
57
|
+
const commandIssue = commands.length === 0
|
|
58
|
+
? 'Worker changed code/config files but reported zero validation commands.'
|
|
59
|
+
: `Worker changed code/config files but only reported non-validation commands: ${commands.slice(0, 3).join('; ')}`;
|
|
60
|
+
return [
|
|
61
|
+
commandIssue,
|
|
62
|
+
`Run at least one relevant smoke/build/test/static check before review, or run the closest available check and report its failure. Files needing validation: ${sample}${suffix}`,
|
|
63
|
+
];
|
|
64
|
+
}
|
|
65
|
+
export function testerWouldRunForWorkerResult(result, hasTester, skipIfNoCode) {
|
|
66
|
+
if (!hasTester)
|
|
67
|
+
return false;
|
|
68
|
+
if (!skipIfNoCode)
|
|
69
|
+
return true;
|
|
70
|
+
return (result.filesChanged ?? []).some(file => TESTER_CODE_FILE_RE.test(file));
|
|
71
|
+
}
|
|
72
|
+
export function isTesterCodeFile(file) {
|
|
73
|
+
return TESTER_CODE_FILE_RE.test(file);
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=workerValidationEvidence.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workerValidationEvidence.js","sourceRoot":"","sources":["../../src/agents/workerValidationEvidence.ts"],"names":[],"mappings":"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"}
|