attocode 0.2.1 → 0.2.3
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/CHANGELOG.md +191 -1
- package/README.md +7 -0
- package/dist/src/adapters.d.ts +6 -1
- package/dist/src/adapters.d.ts.map +1 -1
- package/dist/src/adapters.js +8 -1
- package/dist/src/adapters.js.map +1 -1
- package/dist/src/agent.d.ts +41 -4
- package/dist/src/agent.d.ts.map +1 -1
- package/dist/src/agent.js +846 -75
- package/dist/src/agent.js.map +1 -1
- package/dist/src/cli.d.ts.map +1 -1
- package/dist/src/cli.js +23 -2
- package/dist/src/cli.js.map +1 -1
- package/dist/src/core/protocol/types.d.ts +8 -8
- package/dist/src/defaults.d.ts +7 -2
- package/dist/src/defaults.d.ts.map +1 -1
- package/dist/src/defaults.js +38 -2
- package/dist/src/defaults.js.map +1 -1
- package/dist/src/integrations/agent-registry.d.ts +13 -0
- package/dist/src/integrations/agent-registry.d.ts.map +1 -1
- package/dist/src/integrations/agent-registry.js.map +1 -1
- package/dist/src/integrations/async-subagent.d.ts +135 -0
- package/dist/src/integrations/async-subagent.d.ts.map +1 -0
- package/dist/src/integrations/async-subagent.js +213 -0
- package/dist/src/integrations/async-subagent.js.map +1 -0
- package/dist/src/integrations/auto-checkpoint.d.ts +98 -0
- package/dist/src/integrations/auto-checkpoint.d.ts.map +1 -0
- package/dist/src/integrations/auto-checkpoint.js +252 -0
- package/dist/src/integrations/auto-checkpoint.js.map +1 -0
- package/dist/src/integrations/auto-compaction.d.ts.map +1 -1
- package/dist/src/integrations/auto-compaction.js +5 -1
- package/dist/src/integrations/auto-compaction.js.map +1 -1
- package/dist/src/integrations/bash-policy.d.ts +33 -0
- package/dist/src/integrations/bash-policy.d.ts.map +1 -0
- package/dist/src/integrations/bash-policy.js +142 -0
- package/dist/src/integrations/bash-policy.js.map +1 -0
- package/dist/src/integrations/codebase-context.d.ts +5 -0
- package/dist/src/integrations/codebase-context.d.ts.map +1 -1
- package/dist/src/integrations/codebase-context.js +33 -0
- package/dist/src/integrations/codebase-context.js.map +1 -1
- package/dist/src/integrations/complexity-classifier.d.ts +86 -0
- package/dist/src/integrations/complexity-classifier.d.ts.map +1 -0
- package/dist/src/integrations/complexity-classifier.js +233 -0
- package/dist/src/integrations/complexity-classifier.js.map +1 -0
- package/dist/src/integrations/delegation-protocol.d.ts +86 -0
- package/dist/src/integrations/delegation-protocol.d.ts.map +1 -0
- package/dist/src/integrations/delegation-protocol.js +127 -0
- package/dist/src/integrations/delegation-protocol.js.map +1 -0
- package/dist/src/integrations/dynamic-budget.d.ts +81 -0
- package/dist/src/integrations/dynamic-budget.d.ts.map +1 -0
- package/dist/src/integrations/dynamic-budget.js +151 -0
- package/dist/src/integrations/dynamic-budget.js.map +1 -0
- package/dist/src/integrations/economics.d.ts +86 -1
- package/dist/src/integrations/economics.d.ts.map +1 -1
- package/dist/src/integrations/economics.js +306 -11
- package/dist/src/integrations/economics.js.map +1 -1
- package/dist/src/integrations/environment-facts.d.ts +52 -0
- package/dist/src/integrations/environment-facts.d.ts.map +1 -0
- package/dist/src/integrations/environment-facts.js +84 -0
- package/dist/src/integrations/environment-facts.js.map +1 -0
- package/dist/src/integrations/hierarchical-config.d.ts.map +1 -1
- package/dist/src/integrations/hierarchical-config.js +17 -0
- package/dist/src/integrations/hierarchical-config.js.map +1 -1
- package/dist/src/integrations/index.d.ts +19 -2
- package/dist/src/integrations/index.d.ts.map +1 -1
- package/dist/src/integrations/index.js +34 -2
- package/dist/src/integrations/index.js.map +1 -1
- package/dist/src/integrations/injection-budget.d.ts +71 -0
- package/dist/src/integrations/injection-budget.d.ts.map +1 -0
- package/dist/src/integrations/injection-budget.js +136 -0
- package/dist/src/integrations/injection-budget.js.map +1 -0
- package/dist/src/integrations/mcp-client.d.ts.map +1 -1
- package/dist/src/integrations/mcp-client.js +14 -0
- package/dist/src/integrations/mcp-client.js.map +1 -1
- package/dist/src/integrations/mcp-custom-tools.d.ts +102 -0
- package/dist/src/integrations/mcp-custom-tools.d.ts.map +1 -0
- package/dist/src/integrations/mcp-custom-tools.js +232 -0
- package/dist/src/integrations/mcp-custom-tools.js.map +1 -0
- package/dist/src/integrations/mcp-tool-validator.d.ts +60 -0
- package/dist/src/integrations/mcp-tool-validator.d.ts.map +1 -0
- package/dist/src/integrations/mcp-tool-validator.js +141 -0
- package/dist/src/integrations/mcp-tool-validator.js.map +1 -0
- package/dist/src/integrations/policy-engine.d.ts +55 -0
- package/dist/src/integrations/policy-engine.d.ts.map +1 -0
- package/dist/src/integrations/policy-engine.js +247 -0
- package/dist/src/integrations/policy-engine.js.map +1 -0
- package/dist/src/integrations/safety.d.ts +5 -4
- package/dist/src/integrations/safety.d.ts.map +1 -1
- package/dist/src/integrations/safety.js +32 -7
- package/dist/src/integrations/safety.js.map +1 -1
- package/dist/src/integrations/sandbox/basic.d.ts +7 -0
- package/dist/src/integrations/sandbox/basic.d.ts.map +1 -1
- package/dist/src/integrations/sandbox/basic.js +27 -2
- package/dist/src/integrations/sandbox/basic.js.map +1 -1
- package/dist/src/integrations/sandbox/index.d.ts +6 -0
- package/dist/src/integrations/sandbox/index.d.ts.map +1 -1
- package/dist/src/integrations/sandbox/index.js +3 -0
- package/dist/src/integrations/sandbox/index.js.map +1 -1
- package/dist/src/integrations/sandbox/landlock.d.ts.map +1 -1
- package/dist/src/integrations/sandbox/landlock.js +3 -0
- package/dist/src/integrations/sandbox/landlock.js.map +1 -1
- package/dist/src/integrations/self-improvement.d.ts +90 -0
- package/dist/src/integrations/self-improvement.d.ts.map +1 -0
- package/dist/src/integrations/self-improvement.js +229 -0
- package/dist/src/integrations/self-improvement.js.map +1 -0
- package/dist/src/integrations/smart-decomposer.d.ts +22 -1
- package/dist/src/integrations/smart-decomposer.d.ts.map +1 -1
- package/dist/src/integrations/smart-decomposer.js +127 -28
- package/dist/src/integrations/smart-decomposer.js.map +1 -1
- package/dist/src/integrations/subagent-output-store.d.ts +91 -0
- package/dist/src/integrations/subagent-output-store.d.ts.map +1 -0
- package/dist/src/integrations/subagent-output-store.js +257 -0
- package/dist/src/integrations/subagent-output-store.js.map +1 -0
- package/dist/src/integrations/swarm/index.d.ts +2 -2
- package/dist/src/integrations/swarm/index.d.ts.map +1 -1
- package/dist/src/integrations/swarm/index.js +1 -1
- package/dist/src/integrations/swarm/index.js.map +1 -1
- package/dist/src/integrations/swarm/model-selector.d.ts +16 -0
- package/dist/src/integrations/swarm/model-selector.d.ts.map +1 -1
- package/dist/src/integrations/swarm/model-selector.js +123 -10
- package/dist/src/integrations/swarm/model-selector.js.map +1 -1
- package/dist/src/integrations/swarm/swarm-budget.d.ts +4 -0
- package/dist/src/integrations/swarm/swarm-budget.d.ts.map +1 -1
- package/dist/src/integrations/swarm/swarm-budget.js +6 -0
- package/dist/src/integrations/swarm/swarm-budget.js.map +1 -1
- package/dist/src/integrations/swarm/swarm-config-loader.d.ts +10 -1
- package/dist/src/integrations/swarm/swarm-config-loader.d.ts.map +1 -1
- package/dist/src/integrations/swarm/swarm-config-loader.js +226 -13
- package/dist/src/integrations/swarm/swarm-config-loader.js.map +1 -1
- package/dist/src/integrations/swarm/swarm-event-bridge.d.ts +12 -1
- package/dist/src/integrations/swarm/swarm-event-bridge.d.ts.map +1 -1
- package/dist/src/integrations/swarm/swarm-event-bridge.js +178 -9
- package/dist/src/integrations/swarm/swarm-event-bridge.js.map +1 -1
- package/dist/src/integrations/swarm/swarm-events.d.ts +66 -1
- package/dist/src/integrations/swarm/swarm-events.d.ts.map +1 -1
- package/dist/src/integrations/swarm/swarm-events.js +26 -5
- package/dist/src/integrations/swarm/swarm-events.js.map +1 -1
- package/dist/src/integrations/swarm/swarm-orchestrator.d.ts +127 -0
- package/dist/src/integrations/swarm/swarm-orchestrator.d.ts.map +1 -1
- package/dist/src/integrations/swarm/swarm-orchestrator.js +1842 -47
- package/dist/src/integrations/swarm/swarm-orchestrator.js.map +1 -1
- package/dist/src/integrations/swarm/swarm-quality-gate.d.ts +91 -3
- package/dist/src/integrations/swarm/swarm-quality-gate.d.ts.map +1 -1
- package/dist/src/integrations/swarm/swarm-quality-gate.js +395 -19
- package/dist/src/integrations/swarm/swarm-quality-gate.js.map +1 -1
- package/dist/src/integrations/swarm/task-queue.d.ts +55 -1
- package/dist/src/integrations/swarm/task-queue.d.ts.map +1 -1
- package/dist/src/integrations/swarm/task-queue.js +389 -16
- package/dist/src/integrations/swarm/task-queue.js.map +1 -1
- package/dist/src/integrations/swarm/types.d.ts +247 -11
- package/dist/src/integrations/swarm/types.d.ts.map +1 -1
- package/dist/src/integrations/swarm/types.js +67 -9
- package/dist/src/integrations/swarm/types.js.map +1 -1
- package/dist/src/integrations/swarm/worker-pool.d.ts +18 -5
- package/dist/src/integrations/swarm/worker-pool.d.ts.map +1 -1
- package/dist/src/integrations/swarm/worker-pool.js +236 -34
- package/dist/src/integrations/swarm/worker-pool.js.map +1 -1
- package/dist/src/integrations/thinking-strategy.d.ts +52 -0
- package/dist/src/integrations/thinking-strategy.d.ts.map +1 -0
- package/dist/src/integrations/thinking-strategy.js +129 -0
- package/dist/src/integrations/thinking-strategy.js.map +1 -0
- package/dist/src/integrations/tool-recommendation.d.ts +61 -0
- package/dist/src/integrations/tool-recommendation.d.ts.map +1 -0
- package/dist/src/integrations/tool-recommendation.js +268 -0
- package/dist/src/integrations/tool-recommendation.js.map +1 -0
- package/dist/src/integrations/verification-gate.d.ts +80 -0
- package/dist/src/integrations/verification-gate.d.ts.map +1 -0
- package/dist/src/integrations/verification-gate.js +146 -0
- package/dist/src/integrations/verification-gate.js.map +1 -0
- package/dist/src/integrations/work-log.d.ts +87 -0
- package/dist/src/integrations/work-log.d.ts.map +1 -0
- package/dist/src/integrations/work-log.js +275 -0
- package/dist/src/integrations/work-log.js.map +1 -0
- package/dist/src/main.js +31 -5
- package/dist/src/main.js.map +1 -1
- package/dist/src/modes/repl.d.ts.map +1 -1
- package/dist/src/modes/repl.js +10 -4
- package/dist/src/modes/repl.js.map +1 -1
- package/dist/src/modes/tui.d.ts.map +1 -1
- package/dist/src/modes/tui.js +5 -0
- package/dist/src/modes/tui.js.map +1 -1
- package/dist/src/modes.d.ts +6 -0
- package/dist/src/modes.d.ts.map +1 -1
- package/dist/src/modes.js +69 -21
- package/dist/src/modes.js.map +1 -1
- package/dist/src/tools/agent.d.ts.map +1 -1
- package/dist/src/tools/agent.js +11 -2
- package/dist/src/tools/agent.js.map +1 -1
- package/dist/src/tools/bash.d.ts +9 -3
- package/dist/src/tools/bash.d.ts.map +1 -1
- package/dist/src/tools/bash.js +12 -0
- package/dist/src/tools/bash.js.map +1 -1
- package/dist/src/tools/coercion.d.ts +6 -0
- package/dist/src/tools/coercion.d.ts.map +1 -1
- package/dist/src/tools/coercion.js +13 -0
- package/dist/src/tools/coercion.js.map +1 -1
- package/dist/src/tools/file.d.ts +2 -2
- package/dist/src/tools/file.js +2 -2
- package/dist/src/tools/file.js.map +1 -1
- package/dist/src/tools/permission.d.ts.map +1 -1
- package/dist/src/tools/permission.js +4 -111
- package/dist/src/tools/permission.js.map +1 -1
- package/dist/src/tools/standard.d.ts +17 -1
- package/dist/src/tools/standard.d.ts.map +1 -1
- package/dist/src/tools/standard.js +64 -11
- package/dist/src/tools/standard.js.map +1 -1
- package/dist/src/tracing/trace-collector.d.ts +167 -0
- package/dist/src/tracing/trace-collector.d.ts.map +1 -1
- package/dist/src/tracing/trace-collector.js +137 -0
- package/dist/src/tracing/trace-collector.js.map +1 -1
- package/dist/src/tracing/types.d.ts +105 -1
- package/dist/src/tracing/types.d.ts.map +1 -1
- package/dist/src/tracing/types.js.map +1 -1
- package/dist/src/tui/app.d.ts.map +1 -1
- package/dist/src/tui/app.js +34 -5
- package/dist/src/tui/app.js.map +1 -1
- package/dist/src/types.d.ts +89 -0
- package/dist/src/types.d.ts.map +1 -1
- package/package.json +6 -2
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Verification Gate - Opt-in Completion Verification
|
|
3
|
+
*
|
|
4
|
+
* Prevents premature completion by checking if required verification
|
|
5
|
+
* steps (like running tests) have been performed before allowing
|
|
6
|
+
* the agent to stop.
|
|
7
|
+
*
|
|
8
|
+
* Configuration:
|
|
9
|
+
* - TUI mode: off by default
|
|
10
|
+
* - Eval mode: auto-configured from FAIL_TO_PASS tests
|
|
11
|
+
* - Swarm mode: set by orchestrator per worker
|
|
12
|
+
*/
|
|
13
|
+
// =============================================================================
|
|
14
|
+
// VERIFICATION GATE
|
|
15
|
+
// =============================================================================
|
|
16
|
+
export class VerificationGate {
|
|
17
|
+
criteria;
|
|
18
|
+
state;
|
|
19
|
+
constructor(criteria) {
|
|
20
|
+
this.criteria = {
|
|
21
|
+
requiredTests: criteria.requiredTests,
|
|
22
|
+
requireFileChanges: criteria.requireFileChanges ?? false,
|
|
23
|
+
maxAttempts: criteria.maxAttempts ?? 2,
|
|
24
|
+
};
|
|
25
|
+
this.state = {
|
|
26
|
+
testsRun: new Set(),
|
|
27
|
+
anyTestPassed: false,
|
|
28
|
+
hasFileChanges: false,
|
|
29
|
+
nudgeCount: 0,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Record that a bash command was executed.
|
|
34
|
+
* Detects test execution from command patterns and output.
|
|
35
|
+
*/
|
|
36
|
+
recordBashExecution(command, output, exitCode) {
|
|
37
|
+
// Detect pytest/test runs
|
|
38
|
+
const isTestRun = /pytest|python\s+-m\s+pytest/.test(command);
|
|
39
|
+
if (isTestRun) {
|
|
40
|
+
this.state.testsRun.add(command);
|
|
41
|
+
if (exitCode === 0) {
|
|
42
|
+
this.state.anyTestPassed = true;
|
|
43
|
+
}
|
|
44
|
+
// Check if specific required tests were run
|
|
45
|
+
if (this.criteria.requiredTests) {
|
|
46
|
+
for (const req of this.criteria.requiredTests) {
|
|
47
|
+
if (command.includes(req) || output.includes(req)) {
|
|
48
|
+
this.state.testsRun.add(req);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Record that a file was modified.
|
|
56
|
+
*/
|
|
57
|
+
recordFileChange() {
|
|
58
|
+
this.state.hasFileChanges = true;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Check if the agent can complete.
|
|
62
|
+
* Returns satisfied=true if criteria are met, or a nudge message if not.
|
|
63
|
+
*/
|
|
64
|
+
check() {
|
|
65
|
+
const missing = [];
|
|
66
|
+
// Check file changes
|
|
67
|
+
if (this.criteria.requireFileChanges && !this.state.hasFileChanges) {
|
|
68
|
+
missing.push('No file changes made');
|
|
69
|
+
}
|
|
70
|
+
// Check required tests
|
|
71
|
+
if (this.criteria.requiredTests && this.criteria.requiredTests.length > 0) {
|
|
72
|
+
if (this.state.testsRun.size === 0) {
|
|
73
|
+
missing.push('Required tests have not been run');
|
|
74
|
+
}
|
|
75
|
+
else if (!this.state.anyTestPassed) {
|
|
76
|
+
missing.push('Tests ran but none passed');
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
// All criteria met
|
|
80
|
+
if (missing.length === 0) {
|
|
81
|
+
return { satisfied: true, forceAllow: false, missing: [] };
|
|
82
|
+
}
|
|
83
|
+
// Max nudges exceeded - allow anyway
|
|
84
|
+
if (this.state.nudgeCount >= (this.criteria.maxAttempts ?? 2)) {
|
|
85
|
+
return { satisfied: false, forceAllow: true, missing };
|
|
86
|
+
}
|
|
87
|
+
// Generate nudge
|
|
88
|
+
this.state.nudgeCount++;
|
|
89
|
+
const nudge = this.buildNudge(missing);
|
|
90
|
+
return { satisfied: false, forceAllow: false, nudge, missing };
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Get the current verification state.
|
|
94
|
+
*/
|
|
95
|
+
getState() {
|
|
96
|
+
return {
|
|
97
|
+
testsRun: this.state.testsRun.size,
|
|
98
|
+
anyTestPassed: this.state.anyTestPassed,
|
|
99
|
+
hasFileChanges: this.state.hasFileChanges,
|
|
100
|
+
nudgeCount: this.state.nudgeCount,
|
|
101
|
+
maxAttempts: this.criteria.maxAttempts ?? 2,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Reset the gate state (for reuse).
|
|
106
|
+
*/
|
|
107
|
+
reset() {
|
|
108
|
+
this.state = {
|
|
109
|
+
testsRun: new Set(),
|
|
110
|
+
anyTestPassed: false,
|
|
111
|
+
hasFileChanges: false,
|
|
112
|
+
nudgeCount: 0,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
// ---------------------------------------------------------------------------
|
|
116
|
+
// PRIVATE
|
|
117
|
+
// ---------------------------------------------------------------------------
|
|
118
|
+
buildNudge(missing) {
|
|
119
|
+
const parts = ['[System] Verification incomplete:'];
|
|
120
|
+
for (const m of missing) {
|
|
121
|
+
parts.push(`- ${m}`);
|
|
122
|
+
}
|
|
123
|
+
if (this.criteria.requiredTests && this.criteria.requiredTests.length > 0) {
|
|
124
|
+
const testCmd = `python -m pytest ${this.criteria.requiredTests.join(' ')} -xvs`;
|
|
125
|
+
parts.push(`\nRun the required tests now: \`${testCmd}\``);
|
|
126
|
+
}
|
|
127
|
+
parts.push('Do NOT finish until verification is complete.');
|
|
128
|
+
return parts.join('\n');
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
// =============================================================================
|
|
132
|
+
// FACTORY
|
|
133
|
+
// =============================================================================
|
|
134
|
+
/**
|
|
135
|
+
* Create a verification gate from criteria.
|
|
136
|
+
* Returns null if no criteria provided (gate disabled).
|
|
137
|
+
*/
|
|
138
|
+
export function createVerificationGate(criteria) {
|
|
139
|
+
if (!criteria)
|
|
140
|
+
return null;
|
|
141
|
+
// Only create if there's something to verify
|
|
142
|
+
if (!criteria.requiredTests?.length && !criteria.requireFileChanges)
|
|
143
|
+
return null;
|
|
144
|
+
return new VerificationGate(criteria);
|
|
145
|
+
}
|
|
146
|
+
//# sourceMappingURL=verification-gate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verification-gate.js","sourceRoot":"","sources":["../../../src/integrations/verification-gate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Work Log - Compaction-Resilient Structured Summary
|
|
3
|
+
*
|
|
4
|
+
* Maintains a persistent structured summary of agent work that survives
|
|
5
|
+
* context compaction. Auto-populated from tool execution results.
|
|
6
|
+
*
|
|
7
|
+
* When context is compacted, the work log is injected as a system message
|
|
8
|
+
* so the agent doesn't "forget" what it has already done (preventing
|
|
9
|
+
* re-reading files, re-searching, etc.).
|
|
10
|
+
*/
|
|
11
|
+
export interface WorkLogEntry {
|
|
12
|
+
timestamp: number;
|
|
13
|
+
type: 'file_read' | 'file_edit' | 'search' | 'test_run' | 'command' | 'approach';
|
|
14
|
+
summary: string;
|
|
15
|
+
}
|
|
16
|
+
export interface TestResult {
|
|
17
|
+
test: string;
|
|
18
|
+
passed: boolean;
|
|
19
|
+
error?: string;
|
|
20
|
+
}
|
|
21
|
+
export interface ApproachEntry {
|
|
22
|
+
approach: string;
|
|
23
|
+
outcome: 'success' | 'failure' | 'partial';
|
|
24
|
+
detail?: string;
|
|
25
|
+
}
|
|
26
|
+
export interface WorkLogConfig {
|
|
27
|
+
/** Maximum number of entries per category before oldest are dropped */
|
|
28
|
+
maxEntriesPerCategory?: number;
|
|
29
|
+
/** Maximum token count for compact output */
|
|
30
|
+
maxCompactTokens?: number;
|
|
31
|
+
}
|
|
32
|
+
export declare class WorkLog {
|
|
33
|
+
private currentHypothesis;
|
|
34
|
+
private filesRead;
|
|
35
|
+
private filesModified;
|
|
36
|
+
private testResults;
|
|
37
|
+
private approachesTried;
|
|
38
|
+
private commands;
|
|
39
|
+
private config;
|
|
40
|
+
constructor(config?: WorkLogConfig);
|
|
41
|
+
/**
|
|
42
|
+
* Record a tool execution result into the work log.
|
|
43
|
+
* Called automatically after each tool call in agent.ts.
|
|
44
|
+
*/
|
|
45
|
+
recordToolExecution(toolName: string, args: Record<string, unknown>, result?: unknown): void;
|
|
46
|
+
/**
|
|
47
|
+
* Record an approach the agent tried and its outcome.
|
|
48
|
+
*/
|
|
49
|
+
recordApproach(approach: string, outcome: ApproachEntry['outcome'], detail?: string): void;
|
|
50
|
+
/**
|
|
51
|
+
* Set the current working hypothesis.
|
|
52
|
+
*/
|
|
53
|
+
setHypothesis(hypothesis: string): void;
|
|
54
|
+
/**
|
|
55
|
+
* Generate a compact string representation (~500 tokens) for injection
|
|
56
|
+
* after context compaction.
|
|
57
|
+
*/
|
|
58
|
+
toCompactString(): string;
|
|
59
|
+
/**
|
|
60
|
+
* Produce a truncated compact string that fits within the character budget.
|
|
61
|
+
* Keeps fewer entries per category to stay within limits.
|
|
62
|
+
*/
|
|
63
|
+
private toCompactStringTruncated;
|
|
64
|
+
/**
|
|
65
|
+
* Check if the work log has any content worth injecting.
|
|
66
|
+
*/
|
|
67
|
+
hasContent(): boolean;
|
|
68
|
+
/**
|
|
69
|
+
* Get basic stats about the work log.
|
|
70
|
+
*/
|
|
71
|
+
getStats(): {
|
|
72
|
+
filesRead: number;
|
|
73
|
+
filesModified: number;
|
|
74
|
+
testResults: number;
|
|
75
|
+
approaches: number;
|
|
76
|
+
commands: number;
|
|
77
|
+
};
|
|
78
|
+
/**
|
|
79
|
+
* Reset the work log.
|
|
80
|
+
*/
|
|
81
|
+
reset(): void;
|
|
82
|
+
private summarizeFileContent;
|
|
83
|
+
private parseTestResults;
|
|
84
|
+
private trimMap;
|
|
85
|
+
}
|
|
86
|
+
export declare function createWorkLog(config?: WorkLogConfig): WorkLog;
|
|
87
|
+
//# sourceMappingURL=work-log.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"work-log.d.ts","sourceRoot":"","sources":["../../../src/integrations/work-log.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAMH,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,WAAW,GAAG,WAAW,GAAG,QAAQ,GAAG,UAAU,GAAG,SAAS,GAAG,UAAU,CAAC;IACjF,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;IAC3C,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,uEAAuE;IACvE,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,6CAA6C;IAC7C,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAMD,qBAAa,OAAO;IAClB,OAAO,CAAC,iBAAiB,CAAc;IACvC,OAAO,CAAC,SAAS,CAAkC;IACnD,OAAO,CAAC,aAAa,CAAkC;IACvD,OAAO,CAAC,WAAW,CAAoB;IACvC,OAAO,CAAC,eAAe,CAAuB;IAC9C,OAAO,CAAC,QAAQ,CAAgB;IAChC,OAAO,CAAC,MAAM,CAA0B;gBAE5B,MAAM,GAAE,aAAkB;IAOtC;;;OAGG;IACH,mBAAmB,CACjB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,MAAM,CAAC,EAAE,OAAO,GACf,IAAI;IAyDP;;OAEG;IACH,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI;IAO1F;;OAEG;IACH,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAIvC;;;OAGG;IACH,eAAe,IAAI,MAAM;IAiEzB;;;OAGG;IACH,OAAO,CAAC,wBAAwB;IAyDhC;;OAEG;IACH,UAAU,IAAI,OAAO;IAOrB;;OAEG;IACH,QAAQ,IAAI;QACV,SAAS,EAAE,MAAM,CAAC;QAClB,aAAa,EAAE,MAAM,CAAC;QACtB,WAAW,EAAE,MAAM,CAAC;QACpB,UAAU,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE,MAAM,CAAC;KAClB;IAUD;;OAEG;IACH,KAAK,IAAI,IAAI;IAab,OAAO,CAAC,oBAAoB;IAM5B,OAAO,CAAC,gBAAgB;IAwBxB,OAAO,CAAC,OAAO;CAQhB;AAMD,wBAAgB,aAAa,CAAC,MAAM,CAAC,EAAE,aAAa,GAAG,OAAO,CAE7D"}
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Work Log - Compaction-Resilient Structured Summary
|
|
3
|
+
*
|
|
4
|
+
* Maintains a persistent structured summary of agent work that survives
|
|
5
|
+
* context compaction. Auto-populated from tool execution results.
|
|
6
|
+
*
|
|
7
|
+
* When context is compacted, the work log is injected as a system message
|
|
8
|
+
* so the agent doesn't "forget" what it has already done (preventing
|
|
9
|
+
* re-reading files, re-searching, etc.).
|
|
10
|
+
*/
|
|
11
|
+
// =============================================================================
|
|
12
|
+
// WORK LOG
|
|
13
|
+
// =============================================================================
|
|
14
|
+
export class WorkLog {
|
|
15
|
+
currentHypothesis = '';
|
|
16
|
+
filesRead = new Map(); // path → 1-line summary
|
|
17
|
+
filesModified = new Map(); // path → what changed
|
|
18
|
+
testResults = [];
|
|
19
|
+
approachesTried = [];
|
|
20
|
+
commands = [];
|
|
21
|
+
config;
|
|
22
|
+
constructor(config = {}) {
|
|
23
|
+
this.config = {
|
|
24
|
+
maxEntriesPerCategory: config.maxEntriesPerCategory ?? 30,
|
|
25
|
+
maxCompactTokens: config.maxCompactTokens ?? 1500,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Record a tool execution result into the work log.
|
|
30
|
+
* Called automatically after each tool call in agent.ts.
|
|
31
|
+
*/
|
|
32
|
+
recordToolExecution(toolName, args, result) {
|
|
33
|
+
const resultStr = typeof result === 'string' ? result : '';
|
|
34
|
+
switch (toolName) {
|
|
35
|
+
case 'read_file': {
|
|
36
|
+
const filePath = String(args.path || args.file_path || '');
|
|
37
|
+
if (filePath && !this.filesRead.has(filePath)) {
|
|
38
|
+
// Extract a brief summary from the first few lines of content
|
|
39
|
+
const summary = this.summarizeFileContent(resultStr);
|
|
40
|
+
this.filesRead.set(filePath, summary);
|
|
41
|
+
this.trimMap(this.filesRead, this.config.maxEntriesPerCategory);
|
|
42
|
+
}
|
|
43
|
+
break;
|
|
44
|
+
}
|
|
45
|
+
case 'write_file':
|
|
46
|
+
case 'edit_file': {
|
|
47
|
+
const filePath = String(args.path || args.file_path || '');
|
|
48
|
+
if (filePath) {
|
|
49
|
+
const desc = toolName === 'write_file'
|
|
50
|
+
? 'created/overwritten'
|
|
51
|
+
: `edited: ${String(args.old_text || '').slice(0, 50)}...`;
|
|
52
|
+
this.filesModified.set(filePath, desc);
|
|
53
|
+
this.trimMap(this.filesModified, this.config.maxEntriesPerCategory);
|
|
54
|
+
}
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
case 'bash': {
|
|
58
|
+
const cmd = String(args.command || '');
|
|
59
|
+
if (cmd) {
|
|
60
|
+
this.commands.push(cmd.slice(0, 200));
|
|
61
|
+
if (this.commands.length > this.config.maxEntriesPerCategory) {
|
|
62
|
+
this.commands.shift();
|
|
63
|
+
}
|
|
64
|
+
// Detect test results from bash output
|
|
65
|
+
this.parseTestResults(cmd, resultStr);
|
|
66
|
+
}
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
69
|
+
case 'grep':
|
|
70
|
+
case 'glob':
|
|
71
|
+
case 'search':
|
|
72
|
+
case 'search_files':
|
|
73
|
+
case 'find_files': {
|
|
74
|
+
const pattern = String(args.pattern || args.query || '');
|
|
75
|
+
if (pattern) {
|
|
76
|
+
const key = `search:${pattern}`;
|
|
77
|
+
this.filesRead.set(key, `Searched for: ${pattern}`);
|
|
78
|
+
}
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Record an approach the agent tried and its outcome.
|
|
85
|
+
*/
|
|
86
|
+
recordApproach(approach, outcome, detail) {
|
|
87
|
+
this.approachesTried.push({ approach, outcome, detail });
|
|
88
|
+
if (this.approachesTried.length > this.config.maxEntriesPerCategory) {
|
|
89
|
+
this.approachesTried.shift();
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Set the current working hypothesis.
|
|
94
|
+
*/
|
|
95
|
+
setHypothesis(hypothesis) {
|
|
96
|
+
this.currentHypothesis = hypothesis;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Generate a compact string representation (~500 tokens) for injection
|
|
100
|
+
* after context compaction.
|
|
101
|
+
*/
|
|
102
|
+
toCompactString() {
|
|
103
|
+
const sections = [];
|
|
104
|
+
sections.push('[WORK LOG - What you have already done in this session]');
|
|
105
|
+
if (this.currentHypothesis) {
|
|
106
|
+
sections.push(`Hypothesis: ${this.currentHypothesis}`);
|
|
107
|
+
}
|
|
108
|
+
// Files read
|
|
109
|
+
if (this.filesRead.size > 0) {
|
|
110
|
+
const fileEntries = Array.from(this.filesRead.entries())
|
|
111
|
+
.filter(([k]) => !k.startsWith('search:'))
|
|
112
|
+
.slice(-15)
|
|
113
|
+
.map(([path, summary]) => ` ${path}: ${summary}`)
|
|
114
|
+
.join('\n');
|
|
115
|
+
if (fileEntries) {
|
|
116
|
+
sections.push(`Files read (${this.filesRead.size} total):\n${fileEntries}`);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
// Files modified
|
|
120
|
+
if (this.filesModified.size > 0) {
|
|
121
|
+
const modEntries = Array.from(this.filesModified.entries())
|
|
122
|
+
.map(([path, desc]) => ` ${path}: ${desc}`)
|
|
123
|
+
.join('\n');
|
|
124
|
+
sections.push(`Files modified:\n${modEntries}`);
|
|
125
|
+
}
|
|
126
|
+
// Test results (most recent)
|
|
127
|
+
if (this.testResults.length > 0) {
|
|
128
|
+
const recentTests = this.testResults.slice(-5);
|
|
129
|
+
const testLines = recentTests.map(t => ` ${t.passed ? 'PASS' : 'FAIL'}: ${t.test}${t.error ? ` (${t.error.slice(0, 80)})` : ''}`).join('\n');
|
|
130
|
+
sections.push(`Test results:\n${testLines}`);
|
|
131
|
+
}
|
|
132
|
+
// Approaches tried
|
|
133
|
+
if (this.approachesTried.length > 0) {
|
|
134
|
+
const approachLines = this.approachesTried.map(a => ` [${a.outcome}] ${a.approach}${a.detail ? `: ${a.detail}` : ''}`).join('\n');
|
|
135
|
+
sections.push(`Approaches tried:\n${approachLines}`);
|
|
136
|
+
}
|
|
137
|
+
// Recent commands
|
|
138
|
+
if (this.commands.length > 0) {
|
|
139
|
+
const recentCmds = this.commands.slice(-5).map(c => ` $ ${c}`).join('\n');
|
|
140
|
+
sections.push(`Recent commands:\n${recentCmds}`);
|
|
141
|
+
}
|
|
142
|
+
sections.push('[END WORK LOG - Do NOT re-read files listed above. Continue from where you left off.]');
|
|
143
|
+
const result = sections.join('\n\n');
|
|
144
|
+
// Enforce maxCompactTokens (~4 chars per token)
|
|
145
|
+
const maxChars = this.config.maxCompactTokens * 4;
|
|
146
|
+
if (result.length > maxChars) {
|
|
147
|
+
return this.toCompactStringTruncated(maxChars);
|
|
148
|
+
}
|
|
149
|
+
return result;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Produce a truncated compact string that fits within the character budget.
|
|
153
|
+
* Keeps fewer entries per category to stay within limits.
|
|
154
|
+
*/
|
|
155
|
+
toCompactStringTruncated(maxChars) {
|
|
156
|
+
const sections = [];
|
|
157
|
+
sections.push('[WORK LOG - What you have already done in this session]');
|
|
158
|
+
if (this.currentHypothesis) {
|
|
159
|
+
sections.push(`Hypothesis: ${this.currentHypothesis}`);
|
|
160
|
+
}
|
|
161
|
+
// Files modified (always included — most important)
|
|
162
|
+
if (this.filesModified.size > 0) {
|
|
163
|
+
const modEntries = Array.from(this.filesModified.entries())
|
|
164
|
+
.slice(-5)
|
|
165
|
+
.map(([path, desc]) => ` ${path}: ${desc}`)
|
|
166
|
+
.join('\n');
|
|
167
|
+
sections.push(`Files modified:\n${modEntries}`);
|
|
168
|
+
}
|
|
169
|
+
// Files read (top 5 most recent)
|
|
170
|
+
if (this.filesRead.size > 0) {
|
|
171
|
+
const fileEntries = Array.from(this.filesRead.entries())
|
|
172
|
+
.filter(([k]) => !k.startsWith('search:'))
|
|
173
|
+
.slice(-10)
|
|
174
|
+
.map(([path, summary]) => ` ${path}: ${summary}`)
|
|
175
|
+
.join('\n');
|
|
176
|
+
if (fileEntries) {
|
|
177
|
+
sections.push(`Files read (${this.filesRead.size} total, showing last 10):\n${fileEntries}`);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
// Test results (last 3)
|
|
181
|
+
if (this.testResults.length > 0) {
|
|
182
|
+
const recentTests = this.testResults.slice(-5);
|
|
183
|
+
const testLines = recentTests.map(t => ` ${t.passed ? 'PASS' : 'FAIL'}: ${t.test}${t.error ? ` (${t.error.slice(0, 80)})` : ''}`).join('\n');
|
|
184
|
+
sections.push(`Test results:\n${testLines}`);
|
|
185
|
+
}
|
|
186
|
+
// Recent commands (last 3)
|
|
187
|
+
if (this.commands.length > 0) {
|
|
188
|
+
const recentCmds = this.commands.slice(-3).map(c => ` $ ${c}`).join('\n');
|
|
189
|
+
sections.push(`Recent commands:\n${recentCmds}`);
|
|
190
|
+
}
|
|
191
|
+
sections.push('[END WORK LOG - Do NOT re-read files listed above. Continue from where you left off.]');
|
|
192
|
+
let result = sections.join('\n\n');
|
|
193
|
+
// Hard truncation as last resort
|
|
194
|
+
if (result.length > maxChars) {
|
|
195
|
+
result = result.slice(0, maxChars - 30) + '\n\n[... WORK LOG TRUNCATED ...]';
|
|
196
|
+
}
|
|
197
|
+
return result;
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Check if the work log has any content worth injecting.
|
|
201
|
+
*/
|
|
202
|
+
hasContent() {
|
|
203
|
+
return this.filesRead.size > 0
|
|
204
|
+
|| this.filesModified.size > 0
|
|
205
|
+
|| this.testResults.length > 0
|
|
206
|
+
|| this.commands.length > 0;
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Get basic stats about the work log.
|
|
210
|
+
*/
|
|
211
|
+
getStats() {
|
|
212
|
+
return {
|
|
213
|
+
filesRead: this.filesRead.size,
|
|
214
|
+
filesModified: this.filesModified.size,
|
|
215
|
+
testResults: this.testResults.length,
|
|
216
|
+
approaches: this.approachesTried.length,
|
|
217
|
+
commands: this.commands.length,
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Reset the work log.
|
|
222
|
+
*/
|
|
223
|
+
reset() {
|
|
224
|
+
this.currentHypothesis = '';
|
|
225
|
+
this.filesRead.clear();
|
|
226
|
+
this.filesModified.clear();
|
|
227
|
+
this.testResults = [];
|
|
228
|
+
this.approachesTried = [];
|
|
229
|
+
this.commands = [];
|
|
230
|
+
}
|
|
231
|
+
// ---------------------------------------------------------------------------
|
|
232
|
+
// PRIVATE HELPERS
|
|
233
|
+
// ---------------------------------------------------------------------------
|
|
234
|
+
summarizeFileContent(content) {
|
|
235
|
+
if (!content)
|
|
236
|
+
return '(read)';
|
|
237
|
+
const firstLine = content.split('\n').find(l => l.trim().length > 0) || '';
|
|
238
|
+
return firstLine.slice(0, 80) || '(read)';
|
|
239
|
+
}
|
|
240
|
+
parseTestResults(command, output) {
|
|
241
|
+
const isTestCommand = /pytest|python\s+-m\s+pytest|npm\s+test|jest/.test(command);
|
|
242
|
+
if (!isTestCommand || !output)
|
|
243
|
+
return;
|
|
244
|
+
// Parse pytest-style output: "PASSED" or "FAILED" in output
|
|
245
|
+
const passMatch = output.match(/(\d+)\s+passed/);
|
|
246
|
+
const failMatch = output.match(/(\d+)\s+failed/);
|
|
247
|
+
if (passMatch || failMatch) {
|
|
248
|
+
const passed = passMatch ? parseInt(passMatch[1], 10) : 0;
|
|
249
|
+
const failed = failMatch ? parseInt(failMatch[1], 10) : 0;
|
|
250
|
+
this.testResults.push({
|
|
251
|
+
test: command.slice(0, 100),
|
|
252
|
+
passed: failed === 0 && passed > 0,
|
|
253
|
+
error: failed > 0 ? `${failed} failed, ${passed} passed` : undefined,
|
|
254
|
+
});
|
|
255
|
+
if (this.testResults.length > this.config.maxEntriesPerCategory) {
|
|
256
|
+
this.testResults.shift();
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
trimMap(map, maxSize) {
|
|
261
|
+
if (map.size > maxSize) {
|
|
262
|
+
const keysToRemove = Array.from(map.keys()).slice(0, map.size - maxSize);
|
|
263
|
+
for (const key of keysToRemove) {
|
|
264
|
+
map.delete(key);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
// =============================================================================
|
|
270
|
+
// FACTORY
|
|
271
|
+
// =============================================================================
|
|
272
|
+
export function createWorkLog(config) {
|
|
273
|
+
return new WorkLog(config);
|
|
274
|
+
}
|
|
275
|
+
//# sourceMappingURL=work-log.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"work-log.js","sourceRoot":"","sources":["../../../src/integrations/work-log.ts"],"names":[],"mappings":"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"}
|
package/dist/src/main.js
CHANGED
|
@@ -59,7 +59,7 @@ import { readFileSync } from 'node:fs';
|
|
|
59
59
|
* Build a SwarmConfig from CLI args.
|
|
60
60
|
* V3: Supports YAML configs with merge order: DEFAULT < yaml < CLI.
|
|
61
61
|
*/
|
|
62
|
-
async function buildSwarmConfig(swarmArg, orchestratorModel, resumeSessionId, paidOnly) {
|
|
62
|
+
async function buildSwarmConfig(swarmArg, orchestratorModel, resumeSessionId, paidOnly, orchestratorModelExplicit) {
|
|
63
63
|
let yamlConfig = null;
|
|
64
64
|
if (typeof swarmArg === 'string') {
|
|
65
65
|
// Explicit config file path
|
|
@@ -86,11 +86,33 @@ async function buildSwarmConfig(swarmArg, orchestratorModel, resumeSessionId, pa
|
|
|
86
86
|
yamlConfig = yamlToSwarmConfig(rawYaml, orchestratorModel);
|
|
87
87
|
}
|
|
88
88
|
}
|
|
89
|
+
// Resolve 'latest' session ID before merge
|
|
90
|
+
let resolvedResumeId = resumeSessionId;
|
|
91
|
+
if (resolvedResumeId === 'latest') {
|
|
92
|
+
try {
|
|
93
|
+
const { SwarmStateStore } = await import('./integrations/swarm/swarm-state-store.js');
|
|
94
|
+
const stateDir = '.agent/swarm-state';
|
|
95
|
+
const sessions = SwarmStateStore.listSessions(stateDir);
|
|
96
|
+
if (sessions.length > 0) {
|
|
97
|
+
resolvedResumeId = sessions[0].sessionId;
|
|
98
|
+
console.log(`[Swarm] Resuming latest session: ${resolvedResumeId}`);
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
console.warn('[Swarm] No previous sessions found to resume — starting fresh');
|
|
102
|
+
resolvedResumeId = undefined;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
console.warn('[Swarm] Could not list sessions — starting fresh');
|
|
107
|
+
resolvedResumeId = undefined;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
89
110
|
// Merge: DEFAULT < yaml < CLI
|
|
90
111
|
const config = mergeSwarmConfigs(DEFAULT_SWARM_CONFIG, yamlConfig, {
|
|
91
112
|
paidOnly,
|
|
92
113
|
orchestratorModel,
|
|
93
|
-
|
|
114
|
+
orchestratorModelExplicit,
|
|
115
|
+
resumeSessionId: resolvedResumeId,
|
|
94
116
|
});
|
|
95
117
|
// V3: Pre-flight key check for rate limit awareness
|
|
96
118
|
const apiKey = process.env.OPENROUTER_API_KEY;
|
|
@@ -275,13 +297,17 @@ async function main() {
|
|
|
275
297
|
const tools = convertToolsFromRegistry(registry);
|
|
276
298
|
const adaptedProvider = new ProviderAdapter(provider, resolvedModel);
|
|
277
299
|
// Build swarm config if --swarm flag is set
|
|
278
|
-
const swarmConfig = args.swarm ? await buildSwarmConfig(args.swarm, resolvedModel, args.swarmResume, args.paidOnly) : undefined;
|
|
300
|
+
const swarmConfig = args.swarm ? await buildSwarmConfig(args.swarm, resolvedModel, args.swarmResume, args.paidOnly, !!args.model) : undefined;
|
|
279
301
|
const agent = createProductionAgent({
|
|
280
302
|
provider: adaptedProvider,
|
|
281
303
|
tools,
|
|
282
304
|
model: resolvedModel,
|
|
283
305
|
maxIterations: args.maxIterations,
|
|
284
306
|
humanInLoop: false, // Disable for non-interactive
|
|
307
|
+
codebaseContext: {
|
|
308
|
+
enabled: true,
|
|
309
|
+
root: process.cwd(),
|
|
310
|
+
},
|
|
285
311
|
swarm: swarmConfig || false,
|
|
286
312
|
observability: args.trace ? {
|
|
287
313
|
enabled: true,
|
|
@@ -318,7 +344,7 @@ async function main() {
|
|
|
318
344
|
model: resolvedModel,
|
|
319
345
|
trace: args.trace,
|
|
320
346
|
theme: args.theme,
|
|
321
|
-
swarm: args.swarm ? await buildSwarmConfig(args.swarm, resolvedModel, args.swarmResume, args.paidOnly) : undefined,
|
|
347
|
+
swarm: args.swarm ? await buildSwarmConfig(args.swarm, resolvedModel, args.swarmResume, args.paidOnly, !!args.model) : undefined,
|
|
322
348
|
});
|
|
323
349
|
}
|
|
324
350
|
else {
|
|
@@ -327,7 +353,7 @@ async function main() {
|
|
|
327
353
|
maxIterations: args.maxIterations,
|
|
328
354
|
model: resolvedModel,
|
|
329
355
|
trace: args.trace,
|
|
330
|
-
swarm: args.swarm ? await buildSwarmConfig(args.swarm, resolvedModel, args.swarmResume, args.paidOnly) : undefined,
|
|
356
|
+
swarm: args.swarm ? await buildSwarmConfig(args.swarm, resolvedModel, args.swarmResume, args.paidOnly, !!args.model) : undefined,
|
|
331
357
|
});
|
|
332
358
|
}
|
|
333
359
|
}
|