minovative-mind-cli 2.11.5 → 2.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +27 -1
- package/dist/commands/chat.js +3 -1
- package/dist/commands/eval.d.ts +22 -0
- package/dist/commands/eval.js +141 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/services/agent/slashCommands.js +4 -2
- package/dist/services/agent/toolLoop.d.ts +4 -0
- package/dist/services/agent/toolLoop.js +61 -10
- package/dist/services/agent-tools.d.ts +5 -5
- package/dist/services/agent-tools.js +150 -11
- package/dist/services/contextAgent.d.ts +1 -0
- package/dist/services/contextAgent.js +29 -6
- package/dist/services/ideOptimization.d.ts +15 -0
- package/dist/services/ideOptimization.js +169 -0
- package/dist/services/metrics.d.ts +10 -0
- package/dist/services/metrics.js +24 -0
- package/dist/services/orchestration/messageBus.d.ts +81 -41
- package/dist/services/orchestration/messageBus.js +242 -98
- package/dist/services/orchestration/orchestrator.d.ts +6 -6
- package/dist/services/orchestration/orchestrator.js +32 -21
- package/dist/services/orchestration/scopedTools.d.ts +7 -1
- package/dist/services/orchestration/scopedTools.js +45 -9
- package/dist/services/orchestration/subAgent.d.ts +19 -17
- package/dist/services/orchestration/subAgent.js +98 -81
- package/dist/services/swebench/gitDiffExtractor.d.ts +57 -0
- package/dist/services/swebench/gitDiffExtractor.js +209 -0
- package/dist/services/swebench/index.d.ts +4 -0
- package/dist/services/swebench/index.js +4 -0
- package/dist/services/swebench/instanceLoader.d.ts +21 -0
- package/dist/services/swebench/instanceLoader.js +171 -0
- package/dist/services/swebench/sweBenchRunnerService.d.ts +38 -0
- package/dist/services/swebench/sweBenchRunnerService.js +618 -0
- package/dist/services/swebench/types.d.ts +167 -0
- package/dist/services/swebench/types.js +7 -0
- package/dist/services/verificationService.js +3 -0
- package/dist/utils/fuzzyMatch.d.ts +51 -21
- package/dist/utils/fuzzyMatch.js +37 -122
- package/dist/utils/projectStorage.js +10 -5
- package/dist/utils/systemPrompts.d.ts +1 -1
- package/dist/utils/systemPrompts.js +10 -4
- package/oclif.manifest.json +137 -1
- package/package.json +1 -1
|
@@ -41,7 +41,7 @@ export function getScopedToolDeclarations() {
|
|
|
41
41
|
},
|
|
42
42
|
content: {
|
|
43
43
|
type: 'STRING',
|
|
44
|
-
description: 'The semantic intent or message content',
|
|
44
|
+
description: 'The semantic intent or message content (concise summary, max 500 chars)',
|
|
45
45
|
},
|
|
46
46
|
affectedFiles: {
|
|
47
47
|
type: 'ARRAY',
|
|
@@ -58,10 +58,23 @@ export function getScopedToolDeclarations() {
|
|
|
58
58
|
},
|
|
59
59
|
{
|
|
60
60
|
name: 'read_messages',
|
|
61
|
-
description: 'Fetch
|
|
61
|
+
description: 'Fetch intelligent updates from other agents on the bus. Can filter by file, agent ID, or signal type.',
|
|
62
62
|
parameters: {
|
|
63
63
|
type: 'OBJECT',
|
|
64
|
-
properties: {
|
|
64
|
+
properties: {
|
|
65
|
+
file: {
|
|
66
|
+
type: 'STRING',
|
|
67
|
+
description: 'Optional: Filter updates touching a specific file path (e.g., "src/services/auth.ts")',
|
|
68
|
+
},
|
|
69
|
+
fromAgent: {
|
|
70
|
+
type: 'STRING',
|
|
71
|
+
description: 'Optional: Filter updates from a specific collaborator agent ID',
|
|
72
|
+
},
|
|
73
|
+
type: {
|
|
74
|
+
type: 'STRING',
|
|
75
|
+
description: 'Optional: Filter by signal type ("completion", "warning", "discovery", "request")',
|
|
76
|
+
},
|
|
77
|
+
},
|
|
65
78
|
},
|
|
66
79
|
},
|
|
67
80
|
];
|
|
@@ -80,8 +93,9 @@ export function getScopedToolDeclarations() {
|
|
|
80
93
|
* @param locks - Shared file lock registry instance
|
|
81
94
|
* @param onProgress - Callback to notify parent of sub-agent progress
|
|
82
95
|
* @param options - Optional sub-path auto-focus and override configuration
|
|
96
|
+
* @param taskScope - Optional task scope metadata (targetFiles, dependsOn)
|
|
83
97
|
*/
|
|
84
|
-
export async function executeScopedTool(name, args, workspaceRoot, agentId, bus, locks, onProgress, options) {
|
|
98
|
+
export async function executeScopedTool(name, args, workspaceRoot, agentId, bus, locks, onProgress, options, taskScope) {
|
|
85
99
|
// Update heartbeat so the orchestrator knows we are making progress
|
|
86
100
|
onProgress();
|
|
87
101
|
const timestamp = Date.now();
|
|
@@ -89,23 +103,27 @@ export async function executeScopedTool(name, args, workspaceRoot, agentId, bus,
|
|
|
89
103
|
let targetDesc = 'workspace';
|
|
90
104
|
let status = 'success';
|
|
91
105
|
let result = null;
|
|
92
|
-
let resultSummary
|
|
106
|
+
let resultSummary;
|
|
93
107
|
try {
|
|
94
108
|
// ─── Orchestration-Specific Tools ────────────────────────────────
|
|
95
109
|
if (name === 'post_message') {
|
|
96
110
|
const type = args.type;
|
|
111
|
+
let content = String(args.content || '');
|
|
112
|
+
if (content.length > 500) {
|
|
113
|
+
content = content.substring(0, 500) + '... (truncated)';
|
|
114
|
+
}
|
|
97
115
|
const signal = {
|
|
98
116
|
type,
|
|
99
117
|
timestamp,
|
|
100
118
|
fromAgent: agentId,
|
|
101
|
-
content
|
|
119
|
+
content,
|
|
102
120
|
};
|
|
103
121
|
if (type === 'discovery')
|
|
104
122
|
signal.affectedFiles = args.affectedFiles || [];
|
|
105
123
|
if (type === 'request')
|
|
106
124
|
signal.toAgent = args.toAgent || 'all';
|
|
107
125
|
if (type === 'completion')
|
|
108
|
-
signal.summary =
|
|
126
|
+
signal.summary = content; // map completion summary
|
|
109
127
|
const accepted = bus.postSignal(signal);
|
|
110
128
|
if (!accepted) {
|
|
111
129
|
return { error: `Message bus rejected signal. You have hit the max signal cap (${MessageBus.MAX_SIGNALS_PER_AGENT}). Stop sending signals.` };
|
|
@@ -113,7 +131,18 @@ export async function executeScopedTool(name, args, workspaceRoot, agentId, bus,
|
|
|
113
131
|
return { success: true, message: 'Message posted to bus.' };
|
|
114
132
|
}
|
|
115
133
|
if (name === 'read_messages') {
|
|
116
|
-
const unread = bus.
|
|
134
|
+
const unread = bus.queryBus({
|
|
135
|
+
agentId,
|
|
136
|
+
file: args.file,
|
|
137
|
+
fromAgent: args.fromAgent,
|
|
138
|
+
type: args.type,
|
|
139
|
+
onlyMutations: true,
|
|
140
|
+
targetFiles: taskScope?.targetFiles,
|
|
141
|
+
dependsOn: taskScope?.dependsOn,
|
|
142
|
+
});
|
|
143
|
+
if (unread.activities.length === 0 && unread.signals.length === 0) {
|
|
144
|
+
return { status: 'No new peer messages or workspace mutations.' };
|
|
145
|
+
}
|
|
117
146
|
return {
|
|
118
147
|
activityLogs: MessageBus.formatActivityEntries(unread.activities),
|
|
119
148
|
semanticSignals: MessageBus.formatSignals(unread.signals),
|
|
@@ -157,9 +186,16 @@ export async function executeScopedTool(name, args, workspaceRoot, agentId, bus,
|
|
|
157
186
|
// If we got a file lock and had context from a previous writer, we should
|
|
158
187
|
// inject that diff info back into the agent's tool return payload so it
|
|
159
188
|
// knows someone else changed the file while it was queued.
|
|
160
|
-
if (diffContext && typeof result === 'object') {
|
|
189
|
+
if (diffContext && typeof result === 'object' && result !== null) {
|
|
161
190
|
result._orchestrationWarning = `NOTICE: Another agent modified this file while you were waiting. Diff context: ${diffContext}`;
|
|
162
191
|
}
|
|
192
|
+
// In-band relevance-gated urgent signals (warnings, targeted requests, or upstream completions)
|
|
193
|
+
if (typeof result === 'object' && result !== null && typeof bus?.peekUrgentSignals === 'function') {
|
|
194
|
+
const urgentSignals = bus.peekUrgentSignals(agentId, taskScope);
|
|
195
|
+
if (urgentSignals && urgentSignals.length > 0) {
|
|
196
|
+
result._orchestrationNotice = MessageBus.formatSignals(urgentSignals);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
163
199
|
}
|
|
164
200
|
finally {
|
|
165
201
|
// Release the lock if we grabbed one
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @
|
|
2
|
+
* @file Sub-Agent Runner for Orchestration.
|
|
3
3
|
*
|
|
4
4
|
* Implements the lifecycle, health monitoring, and tool-loop execution for a single
|
|
5
5
|
* parallelized sub-agent.
|
|
6
6
|
*/
|
|
7
7
|
import { MessageBus } from './messageBus.js';
|
|
8
8
|
import { FileLockRegistry } from './fileLockRegistry.js';
|
|
9
|
+
import { TaskScope } from './scopedTools.js';
|
|
9
10
|
/**
|
|
10
11
|
* Scopes workspace file blocks within a context string by replacing full implementation
|
|
11
12
|
* bodies with compact AST declaration outlines (types, classes, function signatures),
|
|
@@ -53,31 +54,20 @@ export declare class SubAgentRunner {
|
|
|
53
54
|
private readonly globalContext;
|
|
54
55
|
private readonly onProgress?;
|
|
55
56
|
private readonly onTool?;
|
|
57
|
+
private readonly taskScope?;
|
|
58
|
+
/** Max time without a tool call or response before the agent is considered stalled */
|
|
59
|
+
static readonly STALL_TIMEOUT_MS = 300000;
|
|
56
60
|
private chat;
|
|
57
|
-
private lastHeartbeat;
|
|
58
61
|
private creditsUsed;
|
|
59
62
|
private inputTokens;
|
|
63
|
+
private lastHeartbeat;
|
|
60
64
|
private outputTokens;
|
|
61
|
-
/** Max time without a tool call or response before the agent is considered stalled */
|
|
62
|
-
static readonly STALL_TIMEOUT_MS = 300000;
|
|
63
|
-
constructor(taskId: string, intent: string, workspaceRoot: string, bus: MessageBus, locks: FileLockRegistry, globalContext: string, onProgress?: ((msg: string) => void) | undefined, onTool?: ((msg: string) => void) | undefined);
|
|
64
|
-
/**
|
|
65
|
-
* Constructs the base system instruction for this specific agent,
|
|
66
|
-
* injecting scoped AST outlines for referenced workspace files to eliminate
|
|
67
|
-
* multi-megabyte context bloat during parallel sub-agent execution.
|
|
68
|
-
*/
|
|
69
|
-
private buildSystemInstruction;
|
|
70
65
|
/**
|
|
71
66
|
* Updates the heartbeat. Passed to `executeScopedTool` to ensure the agent
|
|
72
67
|
* isn't marked as stalled while performing long-running commands.
|
|
73
68
|
*/
|
|
74
69
|
private pingHeartbeat;
|
|
75
|
-
|
|
76
|
-
* Executes the sub-agent with a health monitor harness.
|
|
77
|
-
* Runs the tool loop until the model stops returning function calls,
|
|
78
|
-
* an error occurs, or the stall timeout is hit.
|
|
79
|
-
*/
|
|
80
|
-
execute(signal: AbortSignal): Promise<SubAgentResult>;
|
|
70
|
+
constructor(taskId: string, intent: string, workspaceRoot: string, bus: MessageBus, locks: FileLockRegistry, globalContext: string, onProgress?: ((msg: string) => void) | undefined, onTool?: ((msg: string) => void) | undefined, taskScope?: TaskScope | undefined);
|
|
81
71
|
/**
|
|
82
72
|
* Compacts older tool responses in the chat session history into concise references
|
|
83
73
|
* (e.g. `[Read X lines from file.ts - tool execution completed]`), drastically reducing
|
|
@@ -87,6 +77,18 @@ export declare class SubAgentRunner {
|
|
|
87
77
|
* @param turnsToKeep Number of recent turns to preserve in full (default: 1).
|
|
88
78
|
*/
|
|
89
79
|
compactOlderToolResponses(turnsToKeep?: number): void;
|
|
80
|
+
/**
|
|
81
|
+
* Executes the sub-agent with a health monitor harness.
|
|
82
|
+
* Runs the tool loop until the model stops returning function calls,
|
|
83
|
+
* an error occurs, or the stall timeout is hit.
|
|
84
|
+
*/
|
|
85
|
+
execute(signal: AbortSignal): Promise<SubAgentResult>;
|
|
86
|
+
/**
|
|
87
|
+
* Constructs the base system instruction for this specific agent,
|
|
88
|
+
* injecting scoped AST outlines for referenced workspace files to eliminate
|
|
89
|
+
* multi-megabyte context bloat during parallel sub-agent execution.
|
|
90
|
+
*/
|
|
91
|
+
private buildSystemInstruction;
|
|
90
92
|
/**
|
|
91
93
|
* Accumulates token usage from the chat session.
|
|
92
94
|
*/
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @
|
|
2
|
+
* @file Sub-Agent Runner for Orchestration.
|
|
3
3
|
*
|
|
4
4
|
* Implements the lifecycle, health monitoring, and tool-loop execution for a single
|
|
5
5
|
* parallelized sub-agent.
|
|
@@ -64,6 +64,12 @@ function findMatchingFunctionCall(modelEntry, toolName, partIndex) {
|
|
|
64
64
|
* @returns Compacted tool execution reference string.
|
|
65
65
|
*/
|
|
66
66
|
export function createCompactToolReference(toolName, output, args) {
|
|
67
|
+
if (toolName === 'read_messages') {
|
|
68
|
+
return '[read_messages - peer activity reviewed]';
|
|
69
|
+
}
|
|
70
|
+
if (toolName === 'post_message') {
|
|
71
|
+
return '[post_message - coordination signal posted]';
|
|
72
|
+
}
|
|
67
73
|
if (typeof output !== 'string') {
|
|
68
74
|
return `[${toolName} tool execution completed]`;
|
|
69
75
|
}
|
|
@@ -126,14 +132,25 @@ export class SubAgentRunner {
|
|
|
126
132
|
globalContext;
|
|
127
133
|
onProgress;
|
|
128
134
|
onTool;
|
|
135
|
+
taskScope;
|
|
136
|
+
/** Max time without a tool call or response before the agent is considered stalled */
|
|
137
|
+
static STALL_TIMEOUT_MS = 300_000;
|
|
129
138
|
chat;
|
|
130
|
-
lastHeartbeat = Date.now();
|
|
131
139
|
creditsUsed = 0;
|
|
132
140
|
inputTokens = 0;
|
|
141
|
+
lastHeartbeat = Date.now();
|
|
133
142
|
outputTokens = 0;
|
|
134
|
-
/**
|
|
135
|
-
|
|
136
|
-
|
|
143
|
+
/**
|
|
144
|
+
* Updates the heartbeat. Passed to `executeScopedTool` to ensure the agent
|
|
145
|
+
* isn't marked as stalled while performing long-running commands.
|
|
146
|
+
*/
|
|
147
|
+
pingHeartbeat = (msg) => {
|
|
148
|
+
this.lastHeartbeat = Date.now();
|
|
149
|
+
if (msg && this.onProgress) {
|
|
150
|
+
this.onProgress(msg);
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
constructor(taskId, intent, workspaceRoot, bus, locks, globalContext, onProgress, onTool, taskScope) {
|
|
137
154
|
this.taskId = taskId;
|
|
138
155
|
this.intent = intent;
|
|
139
156
|
this.workspaceRoot = workspaceRoot;
|
|
@@ -142,6 +159,7 @@ export class SubAgentRunner {
|
|
|
142
159
|
this.globalContext = globalContext;
|
|
143
160
|
this.onProgress = onProgress;
|
|
144
161
|
this.onTool = onTool;
|
|
162
|
+
this.taskScope = taskScope;
|
|
145
163
|
let model = getGlobalActiveModel();
|
|
146
164
|
if (model === GEMINI_MODELS.AUTO)
|
|
147
165
|
model = GEMINI_MODELS.FLASH;
|
|
@@ -154,44 +172,56 @@ export class SubAgentRunner {
|
|
|
154
172
|
});
|
|
155
173
|
}
|
|
156
174
|
/**
|
|
157
|
-
*
|
|
158
|
-
*
|
|
159
|
-
*
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
return (`<identity>\n` +
|
|
164
|
-
`You are an autonomous Senior software developer sub-agent executing a specific portion of a larger task.\n` +
|
|
165
|
-
`</identity>\n\n` +
|
|
166
|
-
`<task_info>\n` +
|
|
167
|
-
`Your task ID is: ${this.taskId}\n` +
|
|
168
|
-
`Your objective: ${this.intent}\n` +
|
|
169
|
-
`</task_info>\n\n` +
|
|
170
|
-
`<reference_context>\n` +
|
|
171
|
-
`DO NOT IMPLEMENT THIS FULL REQUEST. THIS IS JUST FOR CONTEXT.\n\n` +
|
|
172
|
-
`${scopedContext}\n` +
|
|
173
|
-
`</reference_context>\n\n` +
|
|
174
|
-
`<critical_guidelines>\n` +
|
|
175
|
-
`1. You are ONE worker in a team. Focus EXCLUSIVELY on your specific objective: "${this.intent}".\n` +
|
|
176
|
-
`2. DO NOT attempt to fulfill the entire original user request in the reference context. Other agents handle other tasks.\n` +
|
|
177
|
-
`3. EXECUTION WORKFLOW:\n` +
|
|
178
|
-
` - Step 1 (Investigate): Use 'grep_search', 'read_file', or 'list_directory' to inspect the codebase as needed.\n` +
|
|
179
|
-
` - Step 2 (Execute): Use 'modify_file' or 'write_file' to implement the required changes.\n` +
|
|
180
|
-
` - Step 3 (Verify): Use 'run_debug_script', 'run_fuzz_probe', 'check_heap_delta', 'check_behavioral_drift', or 'run_command' to test your changes if necessary.\n` +
|
|
181
|
-
` - Step 4 (Conclude): Once your specific objective is fully met, stop calling tools and return a text summary of your changes.\n` +
|
|
182
|
-
`4. Coordinate: Use 'read_messages' to check for updates from other agents. Use 'post_message' if you discover breaking changes affecting others.\n` +
|
|
183
|
-
`</critical_guidelines>`);
|
|
184
|
-
}
|
|
185
|
-
/**
|
|
186
|
-
* Updates the heartbeat. Passed to `executeScopedTool` to ensure the agent
|
|
187
|
-
* isn't marked as stalled while performing long-running commands.
|
|
175
|
+
* Compacts older tool responses in the chat session history into concise references
|
|
176
|
+
* (e.g. `[Read X lines from file.ts - tool execution completed]`), drastically reducing
|
|
177
|
+
* context window bloat across multi-turn sub-agent executions while preserving
|
|
178
|
+
* Gemini's functionCall <-> functionResponse protocol.
|
|
179
|
+
*
|
|
180
|
+
* @param turnsToKeep Number of recent turns to preserve in full (default: 1).
|
|
188
181
|
*/
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
182
|
+
compactOlderToolResponses(turnsToKeep = 1) {
|
|
183
|
+
const rawHistory = this.chat.getRawHistory();
|
|
184
|
+
// 1 turn = 1 user Content + 1 model Content pair (2 entries)
|
|
185
|
+
const cutoffIndex = Math.max(0, rawHistory.length - turnsToKeep * 2);
|
|
186
|
+
if (cutoffIndex <= 0)
|
|
187
|
+
return;
|
|
188
|
+
for (let i = 0; i < cutoffIndex; i++) {
|
|
189
|
+
const entry = rawHistory[i];
|
|
190
|
+
if (entry && entry.role === 'user' && Array.isArray(entry.parts)) {
|
|
191
|
+
const prevModelEntry = i > 0 ? rawHistory[i - 1] : undefined;
|
|
192
|
+
let funcRespIdx = 0;
|
|
193
|
+
for (const part of entry.parts) {
|
|
194
|
+
if (part && typeof part === 'object' && 'functionResponse' in part && part.functionResponse) {
|
|
195
|
+
const funcResp = part.functionResponse;
|
|
196
|
+
const toolName = funcResp.name || 'tool';
|
|
197
|
+
const matchingCall = findMatchingFunctionCall(prevModelEntry, toolName, funcRespIdx);
|
|
198
|
+
const args = matchingCall?.args;
|
|
199
|
+
if (funcResp.response && typeof funcResp.response === 'object') {
|
|
200
|
+
const respObj = funcResp.response;
|
|
201
|
+
if (toolName === 'read_messages') {
|
|
202
|
+
funcResp.response = { output: '[read_messages - peer activity reviewed]' };
|
|
203
|
+
}
|
|
204
|
+
else if (toolName === 'post_message') {
|
|
205
|
+
funcResp.response = { output: '[post_message - coordination signal posted]' };
|
|
206
|
+
}
|
|
207
|
+
else if (typeof respObj.output === 'string') {
|
|
208
|
+
respObj.output = createCompactToolReference(toolName, respObj.output, args);
|
|
209
|
+
}
|
|
210
|
+
else if (typeof respObj.result === 'string') {
|
|
211
|
+
respObj.result = createCompactToolReference(toolName, respObj.result, args);
|
|
212
|
+
}
|
|
213
|
+
else if (typeof respObj.output === 'object' && respObj.output !== null) {
|
|
214
|
+
respObj.output = createCompactToolReference(toolName, respObj.output, args);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
funcRespIdx++;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
193
221
|
}
|
|
194
|
-
|
|
222
|
+
// Also trigger proxy chat session pruning to collapse any remaining long fields
|
|
223
|
+
this.chat.pruneToolOutputHistory();
|
|
224
|
+
}
|
|
195
225
|
/**
|
|
196
226
|
* Executes the sub-agent with a health monitor harness.
|
|
197
227
|
* Runs the tool loop until the model stops returning function calls,
|
|
@@ -243,7 +273,7 @@ export class SubAgentRunner {
|
|
|
243
273
|
debugLog(`SubAgent [${this.taskId}]: Executing tool ${call.name}`);
|
|
244
274
|
let responseData;
|
|
245
275
|
try {
|
|
246
|
-
responseData = await executeScopedTool(call.name, call.args, this.workspaceRoot, this.taskId, this.bus, this.locks, this.pingHeartbeat);
|
|
276
|
+
responseData = await executeScopedTool(call.name, call.args, this.workspaceRoot, this.taskId, this.bus, this.locks, this.pingHeartbeat, undefined, this.taskScope);
|
|
247
277
|
}
|
|
248
278
|
catch (err) {
|
|
249
279
|
responseData = { error: err.message || String(err) };
|
|
@@ -309,46 +339,33 @@ export class SubAgentRunner {
|
|
|
309
339
|
});
|
|
310
340
|
}
|
|
311
341
|
/**
|
|
312
|
-
*
|
|
313
|
-
*
|
|
314
|
-
* context
|
|
315
|
-
* Gemini's functionCall <-> functionResponse protocol.
|
|
316
|
-
*
|
|
317
|
-
* @param turnsToKeep Number of recent turns to preserve in full (default: 1).
|
|
342
|
+
* Constructs the base system instruction for this specific agent,
|
|
343
|
+
* injecting scoped AST outlines for referenced workspace files to eliminate
|
|
344
|
+
* multi-megabyte context bloat during parallel sub-agent execution.
|
|
318
345
|
*/
|
|
319
|
-
|
|
320
|
-
const
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
respObj.result = createCompactToolReference(toolName, respObj.result, args);
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
funcRespIdx++;
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
// Also trigger proxy chat session pruning to collapse any remaining long fields
|
|
351
|
-
this.chat.pruneToolOutputHistory();
|
|
346
|
+
buildSystemInstruction() {
|
|
347
|
+
const scopedContext = scopeContext(this.globalContext);
|
|
348
|
+
return (`<identity>\n` +
|
|
349
|
+
`You are an autonomous Senior software developer sub-agent executing a specific portion of a larger task.\n` +
|
|
350
|
+
`</identity>\n\n` +
|
|
351
|
+
`<task_info>\n` +
|
|
352
|
+
`Your task ID is: ${this.taskId}\n` +
|
|
353
|
+
`Your objective: ${this.intent}\n` +
|
|
354
|
+
`</task_info>\n\n` +
|
|
355
|
+
`<reference_context>\n` +
|
|
356
|
+
`DO NOT IMPLEMENT THIS FULL REQUEST. THIS IS JUST FOR CONTEXT.\n\n` +
|
|
357
|
+
`${scopedContext}\n` +
|
|
358
|
+
`</reference_context>\n\n` +
|
|
359
|
+
`<critical_guidelines>\n` +
|
|
360
|
+
`1. You are ONE worker in a team. Focus EXCLUSIVELY on your specific objective: "${this.intent}".\n` +
|
|
361
|
+
`2. DO NOT attempt to fulfill the entire original user request in the reference context. Other agents handle other tasks.\n` +
|
|
362
|
+
`3. EXECUTION WORKFLOW:\n` +
|
|
363
|
+
` - Step 1 (Investigate): Use 'grep_search', 'read_file', or 'list_directory' to inspect the codebase as needed.\n` +
|
|
364
|
+
` - Step 2 (Execute): Use 'modify_file' or 'write_file' to implement the required changes.\n` +
|
|
365
|
+
` - Step 3 (Verify): Use 'run_debug_script', 'run_fuzz_probe', 'check_heap_delta', 'check_behavioral_drift', or 'run_command' to test your changes if necessary.\n` +
|
|
366
|
+
` - Step 4 (Conclude): Once your specific objective is fully met, stop calling tools and return a text summary of your changes.\n` +
|
|
367
|
+
`4. Coordinate: Use 'read_messages' to check for updates from other agents. Use 'post_message' if you discover breaking changes affecting others.\n` +
|
|
368
|
+
`</critical_guidelines>`);
|
|
352
369
|
}
|
|
353
370
|
/**
|
|
354
371
|
* Accumulates token usage from the chat session.
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
export interface DiffExtractionOptions {
|
|
2
|
+
baseCommit?: string;
|
|
3
|
+
includeUntracked?: boolean;
|
|
4
|
+
maxBuffer?: number;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Checks whether the target directory contains a valid git repository.
|
|
8
|
+
*/
|
|
9
|
+
export declare function isGitRepository(workspaceDir: string): Promise<boolean>;
|
|
10
|
+
/**
|
|
11
|
+
* Gets the current HEAD commit hash of the git repository.
|
|
12
|
+
*/
|
|
13
|
+
export declare function getHeadCommit(workspaceDir: string): Promise<string>;
|
|
14
|
+
/**
|
|
15
|
+
* Resets the workspace git repository to a clean state matching baseCommit or HEAD.
|
|
16
|
+
*/
|
|
17
|
+
export declare function resetWorkspaceRepo(workspaceDir: string, baseCommit?: string): Promise<void>;
|
|
18
|
+
/**
|
|
19
|
+
* Extracts a unified git patch representing all modifications made by the model.
|
|
20
|
+
* Produces standard SWE-bench format (patch starting with `diff --git` or empty string).
|
|
21
|
+
*/
|
|
22
|
+
export declare function extractGitPatch(workspaceDir: string, options?: string | DiffExtractionOptions): Promise<string>;
|
|
23
|
+
/**
|
|
24
|
+
* Normalizes git unified diff patch text:
|
|
25
|
+
* - Trims superfluous leading/trailing whitespace
|
|
26
|
+
* - Ensures empty diff returns exact empty string ""
|
|
27
|
+
* - Preserves trailing newline if content exists
|
|
28
|
+
*/
|
|
29
|
+
export declare function normalizePatch(patch: string): string;
|
|
30
|
+
/**
|
|
31
|
+
* Validates whether a patch conforms to standard unified diff structure.
|
|
32
|
+
*/
|
|
33
|
+
export declare function validatePatchFormat(patch: string): {
|
|
34
|
+
valid: boolean;
|
|
35
|
+
issues?: string[];
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Checks out a specific base commit in the repository.
|
|
39
|
+
*/
|
|
40
|
+
export declare function checkoutBaseCommit(workspaceDir: string, baseCommit: string, options?: {
|
|
41
|
+
fetchIfMissing?: boolean;
|
|
42
|
+
}): Promise<{
|
|
43
|
+
success: boolean;
|
|
44
|
+
error?: string;
|
|
45
|
+
}>;
|
|
46
|
+
/**
|
|
47
|
+
* Clones a repository if it doesn't already exist or ensures it is checked out.
|
|
48
|
+
*/
|
|
49
|
+
export declare function cloneOrEnsureRepo(repo: string, targetDir: string, options?: {
|
|
50
|
+
cloneUrl?: string;
|
|
51
|
+
baseCommit?: string;
|
|
52
|
+
shallow?: boolean;
|
|
53
|
+
}): Promise<{
|
|
54
|
+
success: boolean;
|
|
55
|
+
repoDir: string;
|
|
56
|
+
error?: string;
|
|
57
|
+
}>;
|