@mikode13/harness 11.0.1 → 11.2.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 +186 -16
- package/dist/agent/domain/agent.d.ts +41 -3
- package/dist/agent/domain/agent.js.map +1 -1
- package/dist/agent/domain/approval.d.ts +20 -0
- package/dist/agent/domain/approval.js.map +1 -1
- package/dist/agent/domain/inbox.d.ts +42 -0
- package/dist/agent/domain/inbox.js +81 -0
- package/dist/agent/domain/inbox.js.map +1 -0
- package/dist/agent/domain/oneRunAtATime.d.ts +17 -0
- package/dist/agent/domain/oneRunAtATime.js +32 -0
- package/dist/agent/domain/oneRunAtATime.js.map +1 -0
- package/dist/agent/domain/runContext.d.ts +9 -0
- package/dist/agent/domain/runContext.js +5 -0
- package/dist/agent/domain/runContext.js.map +1 -1
- package/dist/agent/domain/session.d.ts +15 -0
- package/dist/agent/domain/session.js +80 -0
- package/dist/agent/domain/session.js.map +1 -0
- package/dist/engines/claude/infrastructure/model/claudeAgent.d.ts +6 -2
- package/dist/engines/claude/infrastructure/model/claudeAgent.js +20 -5
- package/dist/engines/claude/infrastructure/model/claudeAgent.js.map +1 -1
- package/dist/engines/codex/infrastructure/model/codexAgent.d.ts +5 -1
- package/dist/engines/codex/infrastructure/model/codexAgent.js +13 -2
- package/dist/engines/codex/infrastructure/model/codexAgent.js.map +1 -1
- package/dist/engines/domain/model/backgroundAgents.d.ts +5 -2
- package/dist/engines/domain/model/backgroundAgents.js +11 -3
- package/dist/engines/domain/model/backgroundAgents.js.map +1 -1
- package/dist/engines/domain/model/compactor.d.ts +40 -0
- package/dist/engines/domain/model/compactor.js +5 -0
- package/dist/engines/domain/model/compactor.js.map +1 -0
- package/dist/engines/domain/model/llmAgent.d.ts +53 -2
- package/dist/engines/domain/model/llmAgent.js +419 -24
- package/dist/engines/domain/model/llmAgent.js.map +1 -1
- package/dist/engines/domain/model/recentCompaction.d.ts +39 -0
- package/dist/engines/domain/model/recentCompaction.js +119 -0
- package/dist/engines/domain/model/recentCompaction.js.map +1 -0
- package/dist/engines/domain/model/stepContext.js +3 -0
- package/dist/engines/domain/model/stepContext.js.map +1 -1
- package/dist/engines/domain/model/triagedCompaction.d.ts +27 -0
- package/dist/engines/domain/model/triagedCompaction.js +60 -0
- package/dist/engines/domain/model/triagedCompaction.js.map +1 -0
- package/dist/factory/infrastructure/agentLLMFactory.d.ts +56 -15
- package/dist/factory/infrastructure/agentLLMFactory.js +144 -25
- package/dist/factory/infrastructure/agentLLMFactory.js.map +1 -1
- package/dist/index.d.ts +6 -2
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/llm/domain/contextTriage.d.ts +26 -0
- package/dist/llm/domain/contextTriage.js +3 -0
- package/dist/llm/domain/contextTriage.js.map +1 -0
- package/dist/llm/domain/llm.d.ts +18 -1
- package/dist/llm/domain/llm.js.map +1 -1
- package/dist/llm/domain/message.d.ts +18 -1
- package/dist/llm/domain/message.js +20 -0
- package/dist/llm/domain/message.js.map +1 -1
- package/dist/llm/infrastructure/claudeLLMClient.d.ts +4 -5
- package/dist/llm/infrastructure/claudeLLMClient.js +39 -13
- package/dist/llm/infrastructure/claudeLLMClient.js.map +1 -1
- package/dist/llm/infrastructure/jevContextTriage.d.ts +18 -0
- package/dist/llm/infrastructure/jevContextTriage.js +92 -0
- package/dist/llm/infrastructure/jevContextTriage.js.map +1 -0
- package/dist/llm/infrastructure/openAILLMClient.d.ts +4 -5
- package/dist/llm/infrastructure/openAILLMClient.js +20 -9
- package/dist/llm/infrastructure/openAILLMClient.js.map +1 -1
- package/dist/orchestration/domain/model/orchestratorAgent.d.ts +9 -1
- package/dist/orchestration/domain/model/orchestratorAgent.js +20 -3
- package/dist/orchestration/domain/model/orchestratorAgent.js.map +1 -1
- package/dist/recovery/domain/history.d.ts +10 -3
- package/dist/recovery/domain/history.js +1 -0
- package/dist/recovery/domain/history.js.map +1 -1
- package/dist/recovery/domain/recoveryStore.d.ts +14 -2
- package/dist/recovery/domain/recoveryStore.js.map +1 -1
- package/dist/recovery/infrastructure/fileRecoveryStore.d.ts +21 -2
- package/dist/recovery/infrastructure/fileRecoveryStore.js +58 -6
- package/dist/recovery/infrastructure/fileRecoveryStore.js.map +1 -1
- package/dist/recovery/infrastructure/folderClaims.d.ts +27 -0
- package/dist/recovery/infrastructure/folderClaims.js +124 -0
- package/dist/recovery/infrastructure/folderClaims.js.map +1 -0
- package/dist/shared/domain/session.d.ts +12 -0
- package/dist/shared/domain/session.js +2 -0
- package/dist/shared/domain/session.js.map +1 -0
- package/dist/tools/domain/preparedCall.d.ts +5 -2
- package/dist/tools/domain/preparedCall.js +7 -1
- package/dist/tools/domain/preparedCall.js.map +1 -1
- package/dist/tools/domain/readRegistry.d.ts +11 -0
- package/dist/tools/domain/readRegistry.js.map +1 -1
- package/dist/tools/infrastructure/agentAsTool.d.ts +6 -0
- package/dist/tools/infrastructure/agentAsTool.js +9 -0
- package/dist/tools/infrastructure/agentAsTool.js.map +1 -1
- package/dist/tools/infrastructure/commandTool.js +6 -1
- package/dist/tools/infrastructure/commandTool.js.map +1 -1
- package/dist/tools/infrastructure/exploreTool.js +2 -0
- package/dist/tools/infrastructure/exploreTool.js.map +1 -1
- package/dist/tools/infrastructure/fileTools.d.ts +2 -0
- package/dist/tools/infrastructure/fileTools.js +10 -1
- package/dist/tools/infrastructure/fileTools.js.map +1 -1
- package/dist/tools/infrastructure/removeWorktreeTool.d.ts +23 -0
- package/dist/tools/infrastructure/removeWorktreeTool.js +178 -0
- package/dist/tools/infrastructure/removeWorktreeTool.js.map +1 -0
- package/dist/tools/infrastructure/subagents.d.ts +3 -1
- package/dist/tools/infrastructure/subagents.js +2 -1
- package/dist/tools/infrastructure/subagents.js.map +1 -1
- package/dist/tools/infrastructure/trackedEdits.js +1 -0
- package/dist/tools/infrastructure/trackedEdits.js.map +1 -1
- package/dist/tools/infrastructure/workspaceWrites.d.ts +17 -1
- package/dist/tools/infrastructure/workspaceWrites.js +48 -17
- package/dist/tools/infrastructure/workspaceWrites.js.map +1 -1
- package/dist/tools/infrastructure/worktrees.d.ts +49 -0
- package/dist/tools/infrastructure/worktrees.js +154 -0
- package/dist/tools/infrastructure/worktrees.js.map +1 -0
- package/dist/tools/infrastructure/writeCeiling.d.ts +16 -0
- package/dist/tools/infrastructure/writeCeiling.js +49 -0
- package/dist/tools/infrastructure/writeCeiling.js.map +1 -0
- package/dist/tools/infrastructure/writeSession.d.ts +5 -1
- package/dist/tools/infrastructure/writeSession.js +7 -3
- package/dist/tools/infrastructure/writeSession.js.map +1 -1
- package/dist/workflow/domain/workflow.d.ts +3 -0
- package/dist/workflow/domain/workflow.js.map +1 -1
- package/dist/workflow/domain/workflowRunner.js +8 -2
- package/dist/workflow/domain/workflowRunner.js.map +1 -1
- package/package.json +2 -1
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { resolve } from 'node:path';
|
|
2
|
+
import { recentKeptSteps } from '#src/engines/domain/model/compactor';
|
|
2
3
|
import { LLMAgent } from '#src/engines/domain/model/llmAgent';
|
|
4
|
+
import { JevContextTriage } from '#src/llm/infrastructure/jevContextTriage';
|
|
3
5
|
import { ClaudeLLMClient, claudeLLMModels, claudeLLMReasoningEfforts, } from '#src/llm/infrastructure/claudeLLMClient';
|
|
4
6
|
import { OpenAILLMClient, openAIModels, openAIReasoningEfforts, } from '#src/llm/infrastructure/openAILLMClient';
|
|
5
7
|
import { executorInstructions, executorInstructionsWithoutCommands, OrchestratorAgent, plannerInstructions, reviewerInstructions, reviewerInstructionsWithoutCommands, } from '#src/orchestration/domain/model/orchestratorAgent';
|
|
@@ -12,6 +14,8 @@ import { commandsFor, validateCommands, validateFormatter, } from '#src/tools/do
|
|
|
12
14
|
import { commandToolFor, fileToolsFor, openStore, openWorkspace, stateDirectoryOf, } from '#src/tools/infrastructure/fileTools';
|
|
13
15
|
import { createExploreTool } from '#src/tools/infrastructure/exploreTool';
|
|
14
16
|
import { createShowChangesTool } from '#src/tools/infrastructure/showChangesTool';
|
|
17
|
+
import { createRemoveWorktreeTool } from '#src/tools/infrastructure/removeWorktreeTool';
|
|
18
|
+
import { listWorktrees } from '#src/tools/infrastructure/worktrees';
|
|
15
19
|
import { createTrackedReadFile, createTrackedReadFiles, } from '#src/tools/infrastructure/trackedReadFile';
|
|
16
20
|
import { createWorkspaceTools } from '#src/tools/infrastructure/workspaceTools';
|
|
17
21
|
import { isAgentProvider, orchestratorRolesFor } from "./agentFactory.js";
|
|
@@ -34,13 +38,14 @@ export function isLLMModelOf(provider, value) {
|
|
|
34
38
|
export function isLLMReasoningEffortOf(provider, value) {
|
|
35
39
|
return isOneOf(llmReasoningEfforts[provider], value);
|
|
36
40
|
}
|
|
41
|
+
const compactionModes = ['provider', 'recent', 'jev'];
|
|
37
42
|
// The executor reads, edits and checks, so it needs more calls than the roles that only read.
|
|
38
43
|
const defaultRoleSteps = {
|
|
39
44
|
planner: 65,
|
|
40
45
|
executor: 80,
|
|
41
46
|
reviewer: 65,
|
|
42
47
|
};
|
|
43
|
-
//
|
|
48
|
+
// Each role compacts at its model's threshold unless told otherwise.
|
|
44
49
|
const defaultRoleCompaction = {
|
|
45
50
|
planner: undefined,
|
|
46
51
|
executor: undefined,
|
|
@@ -74,24 +79,68 @@ const defaultLLMAgentModels = {
|
|
|
74
79
|
anthropic: 'sonnet',
|
|
75
80
|
openai: 'gpt-5.6-luna',
|
|
76
81
|
};
|
|
82
|
+
// The tokens of context at which each model compacts by default, the small ones sooner. The
|
|
83
|
+
// margins are wide on purpose: compacting at 64k cleared file reads the executor then read again.
|
|
84
|
+
const compactionThresholds = {
|
|
85
|
+
opus: 450_000,
|
|
86
|
+
fable: 450_000,
|
|
87
|
+
sonnet: 450_000,
|
|
88
|
+
haiku: 125_000,
|
|
89
|
+
'gpt-6-astra': 450_000,
|
|
90
|
+
'gpt-5.6-sol': 450_000,
|
|
91
|
+
'gpt-5.6-terra': 450_000,
|
|
92
|
+
'gpt-5.6-luna': 125_000,
|
|
93
|
+
};
|
|
94
|
+
/**
|
|
95
|
+
* The compactor `mode` names for an agent on `model`: at `compactAt`, at the model's threshold
|
|
96
|
+
* without it, or off with `false`, when only a context that no longer fits is compacted.
|
|
97
|
+
*
|
|
98
|
+
* @throws {InvalidAgentConfigError} for a mode that does not exist, from untyped input.
|
|
99
|
+
*/
|
|
100
|
+
function compactorFor(model, compactAt, mode = 'provider') {
|
|
101
|
+
// Checked whatever it is, as untyped input can hold anything here.
|
|
102
|
+
if (typeof mode !== 'string' || !isOneOf(compactionModes, mode)) {
|
|
103
|
+
throw new InvalidAgentConfigError(`compaction must be one of: ${compactionModes.join(', ')}; got ${String(mode)}`);
|
|
104
|
+
}
|
|
105
|
+
// A model with no threshold was already refused by its client.
|
|
106
|
+
const at = compactAt === false
|
|
107
|
+
? undefined
|
|
108
|
+
: (compactAt ?? compactionThresholds[model]);
|
|
109
|
+
switch (mode) {
|
|
110
|
+
case 'provider':
|
|
111
|
+
return { by: 'provider', at };
|
|
112
|
+
case 'recent':
|
|
113
|
+
return { by: 'harness', at, keptSteps: recentKeptSteps };
|
|
114
|
+
case 'jev':
|
|
115
|
+
return { by: 'harness', at, keptSteps: recentKeptSteps, triage: new JevContextTriage() };
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
function defaultModelOf(provider) {
|
|
119
|
+
switch (provider) {
|
|
120
|
+
case 'anthropic':
|
|
121
|
+
case 'openai':
|
|
122
|
+
return defaultLLMAgentModels[provider];
|
|
123
|
+
default:
|
|
124
|
+
// Reachable from untyped input.
|
|
125
|
+
throw unknownProvider(provider);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
77
128
|
function unknownProvider(provider) {
|
|
78
129
|
return new InvalidAgentConfigError(`"${String(provider)}" is not an agent provider; expected one of: ${agentProviders.join(', ')}`);
|
|
79
130
|
}
|
|
80
|
-
function llmClientFor(provider, { model, reasoningEffort,
|
|
131
|
+
function llmClientFor(provider, { model, reasoningEffort, systemPrompt, logger, }) {
|
|
81
132
|
switch (provider) {
|
|
82
133
|
case 'anthropic':
|
|
83
134
|
return new ClaudeLLMClient({
|
|
84
|
-
model
|
|
135
|
+
model,
|
|
85
136
|
reasoningEffort,
|
|
86
|
-
compactAt,
|
|
87
137
|
systemPrompt,
|
|
88
138
|
logger,
|
|
89
139
|
});
|
|
90
140
|
case 'openai':
|
|
91
141
|
return new OpenAILLMClient({
|
|
92
|
-
model
|
|
142
|
+
model,
|
|
93
143
|
reasoningEffort,
|
|
94
|
-
compactAt,
|
|
95
144
|
systemPrompt,
|
|
96
145
|
logger,
|
|
97
146
|
});
|
|
@@ -157,11 +206,11 @@ function withGuidance(systemPrompt, guidance) {
|
|
|
157
206
|
return guidance === '' ? systemPrompt : `${systemPrompt}\n\n${guidance}`;
|
|
158
207
|
}
|
|
159
208
|
/** An `LLMAgent` on `provider`, wrapped in the harness's retry policy. */
|
|
160
|
-
function buildLLMAgent(provider, { model, reasoningEffort, systemPrompt, tools, history, summarizer, maxSteps, compactAt, autoApprove, logger, onTranscript, }) {
|
|
209
|
+
function buildLLMAgent(provider, { model, reasoningEffort, systemPrompt, tools, history, summarizer, maxSteps, compactAt, compaction, autoApprove, logger, onTranscript, writeRoots, }) {
|
|
210
|
+
const chosen = model ?? defaultModelOf(provider);
|
|
161
211
|
const llmClient = llmClientFor(provider, {
|
|
162
|
-
model,
|
|
212
|
+
model: chosen,
|
|
163
213
|
reasoningEffort,
|
|
164
|
-
compactAt,
|
|
165
214
|
systemPrompt,
|
|
166
215
|
logger,
|
|
167
216
|
});
|
|
@@ -176,6 +225,8 @@ function buildLLMAgent(provider, { model, reasoningEffort, systemPrompt, tools,
|
|
|
176
225
|
...(summarizer ? { summarizer } : {}),
|
|
177
226
|
...(maxSteps === undefined ? {} : { maxSteps }),
|
|
178
227
|
...(onTranscript ? { onTranscript } : {}),
|
|
228
|
+
...(writeRoots ? { writeRoots } : {}),
|
|
229
|
+
compactor: compactorFor(chosen, compactAt, compaction),
|
|
179
230
|
}),
|
|
180
231
|
logger,
|
|
181
232
|
noteFailures: false,
|
|
@@ -188,12 +239,17 @@ function buildLLMAgent(provider, { model, reasoningEffort, systemPrompt, tools,
|
|
|
188
239
|
* `destructive` one runs only when the run's `approve` allows it, or with `autoApprove`.
|
|
189
240
|
*
|
|
190
241
|
* @throws {InvalidAgentConfigError} for an unknown provider, a model or reasoning effort its
|
|
191
|
-
* client does not support,
|
|
242
|
+
* client does not support, two tools that share a name, or a workspace given with no tools.
|
|
192
243
|
* @throws {UnrecoverableError} when the client cannot be set up, for example because
|
|
193
244
|
* `OPENAI_API_KEY` is missing. The Anthropic SDK resolves credentials lazily, so a missing
|
|
194
245
|
* `ANTHROPIC_API_KEY` fails the first run instead, with an `UnrecoverableError`.
|
|
195
246
|
*/
|
|
196
|
-
export function createLLMAgent(provider, { model, reasoningEffort, systemPrompt, tools = [], workspace, summarizeUndone = true, maxSteps, compactAt, autoApprove, logger = new Logger(), onTranscript, }) {
|
|
247
|
+
export function createLLMAgent(provider, { model, reasoningEffort, systemPrompt, tools = [], workspace, summarizeUndone = true, maxSteps, compactAt, compaction, autoApprove, logger = new Logger(), onTranscript, }) {
|
|
248
|
+
// Told where to work with nothing to work with, the model would only pretend: it writes its
|
|
249
|
+
// tool calls as text, and the run returns them as its answer.
|
|
250
|
+
if (workspace && tools.length === 0) {
|
|
251
|
+
throw new InvalidAgentConfigError('An agent given a workspace needs tools to work on it: pass those of createFileTools in `tools`');
|
|
252
|
+
}
|
|
197
253
|
return buildLLMAgent(provider, {
|
|
198
254
|
model,
|
|
199
255
|
reasoningEffort,
|
|
@@ -206,11 +262,17 @@ export function createLLMAgent(provider, { model, reasoningEffort, systemPrompt,
|
|
|
206
262
|
...(workspace && summarizeUndone ? { summarizer: summarizerFor(provider, logger) } : {}),
|
|
207
263
|
maxSteps,
|
|
208
264
|
compactAt,
|
|
265
|
+
compaction,
|
|
209
266
|
autoApprove,
|
|
210
267
|
logger,
|
|
211
268
|
onTranscript,
|
|
269
|
+
// An agent it delegates to writes only where its workspace lets it.
|
|
270
|
+
...(workspace ? { writeRoots: writeRootsOf(workspace.roots) } : {}),
|
|
212
271
|
});
|
|
213
272
|
}
|
|
273
|
+
function writeRootsOf(roots) {
|
|
274
|
+
return roots.filter(({ access }) => access === 'write').map(({ path }) => path);
|
|
275
|
+
}
|
|
214
276
|
/**
|
|
215
277
|
* The file tools for an agent from `createLLMAgent` on `provider`, over `workspace`, in the
|
|
216
278
|
* provider's own format:
|
|
@@ -238,12 +300,18 @@ export function createLLMAgent(provider, { model, reasoningEffort, systemPrompt,
|
|
|
238
300
|
* in the history. When it fails, the file stays as the edit wrote it, and the model is told
|
|
239
301
|
* why. Not supported on Windows yet.
|
|
240
302
|
*
|
|
303
|
+
* With `removeWorktree`, they include `removeWorktree`, which removes a git worktree of the
|
|
304
|
+
* repository the first root is in, when the user asks: its folder and every file in it, never
|
|
305
|
+
* its branch. Each call asks the approver, whose request's `worktree` says what is lost:
|
|
306
|
+
* changes no commit has, and the commits only a detached HEAD holds. It refuses the main folder
|
|
307
|
+
* and a worktree the agent works in. See `createWorktree`.
|
|
308
|
+
*
|
|
241
309
|
* @throws {InvalidAgentConfigError} for an unknown provider, a workspace with no root, or an
|
|
242
310
|
* invalid command or formatter, including one whose `cwd` is not in a `write` root, or any on
|
|
243
|
-
* Windows.
|
|
311
|
+
* Windows, or `removeWorktree` with a first root in no git repository.
|
|
244
312
|
* @throws {UnrecoverableError} when no program can read the first root.
|
|
245
313
|
*/
|
|
246
|
-
export async function createFileTools(provider, workspace, { logger = new Logger(), commands, formatter, } = {}) {
|
|
314
|
+
export async function createFileTools(provider, workspace, { logger = new Logger(), commands, formatter, removeWorktree = false, } = {}) {
|
|
247
315
|
// Reachable from untyped input.
|
|
248
316
|
if (!isAgentProvider(provider))
|
|
249
317
|
throw unknownProvider(provider);
|
|
@@ -252,16 +320,52 @@ export async function createFileTools(provider, workspace, { logger = new Logger
|
|
|
252
320
|
if (formatter !== undefined)
|
|
253
321
|
validateFormatter(formatter);
|
|
254
322
|
const opened = await openWorkspace(workspace, logger, formatter ? { formatter } : {});
|
|
255
|
-
return (await executorTools(provider, opened, commands));
|
|
323
|
+
return (await executorTools(provider, opened, commands, removeWorktree));
|
|
256
324
|
}
|
|
257
|
-
/** The executor's file tools,
|
|
258
|
-
async function executorTools(provider, workspace, commands) {
|
|
325
|
+
/** The executor's file tools, `runCommand` when there are commands, and `removeWorktree`. */
|
|
326
|
+
async function executorTools(provider, workspace, commands, removeWorktree) {
|
|
259
327
|
const tools = fileToolsFor(provider, workspace);
|
|
328
|
+
if (removeWorktree)
|
|
329
|
+
tools.push(await removeWorktreeToolFor(workspace));
|
|
260
330
|
// Every command may belong to other roles, leaving none for this one.
|
|
261
331
|
if (commands === undefined || Object.keys(commands).length === 0)
|
|
262
332
|
return tools;
|
|
263
333
|
return [...tools, await commandToolFor(workspace, commands)];
|
|
264
334
|
}
|
|
335
|
+
/** `removeWorktree` over the repository of the first root, which must be in one. */
|
|
336
|
+
async function removeWorktreeToolFor({ base, roots, stateDirectory, }) {
|
|
337
|
+
// Checked now: a tool that could never work is a setup error, not a first-call one.
|
|
338
|
+
await listWorktrees(base).catch((error) => {
|
|
339
|
+
throw new InvalidAgentConfigError(`removeWorktree needs a first root in a git repository, and git 2.36 or later; with ${base}, ${error instanceof Error ? error.message : String(error)}`);
|
|
340
|
+
});
|
|
341
|
+
return createRemoveWorktreeTool({ base, roots, stateDirectory });
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* Each role's agents from `agentAsTool`, as the harness's tools.
|
|
345
|
+
*
|
|
346
|
+
* @throws {InvalidAgentConfigError} for a role that does not exist, or a role's agents that are
|
|
347
|
+
* not a list.
|
|
348
|
+
*/
|
|
349
|
+
function roleAgents(agents) {
|
|
350
|
+
// Untyped input, such as the CLI's configuration file, can hold anything here.
|
|
351
|
+
if (typeof agents !== 'object' || agents === null || Array.isArray(agents)) {
|
|
352
|
+
throw new InvalidAgentConfigError('agents must be an object of agentAsTool tools per role, such as { executor: [committer] }');
|
|
353
|
+
}
|
|
354
|
+
const byRole = { planner: [], executor: [], reviewer: [] };
|
|
355
|
+
for (const [role, tools] of Object.entries(agents)) {
|
|
356
|
+
if (!Object.hasOwn(byRole, role)) {
|
|
357
|
+
throw new InvalidAgentConfigError(`agents names "${role}", which is not a role; expected one of: ${Object.keys(byRole).join(', ')}`);
|
|
358
|
+
}
|
|
359
|
+
if (tools === undefined)
|
|
360
|
+
continue;
|
|
361
|
+
if (!Array.isArray(tools)) {
|
|
362
|
+
throw new InvalidAgentConfigError(`agents.${role} must be a list of agentAsTool tools`);
|
|
363
|
+
}
|
|
364
|
+
// A delegation tool is a harness tool under its public name.
|
|
365
|
+
byRole[role] = tools;
|
|
366
|
+
}
|
|
367
|
+
return byRole;
|
|
368
|
+
}
|
|
265
369
|
/** What an explorer finds and reads with: no edits, no changes, no commands. */
|
|
266
370
|
function explorerTools({ read, policy }) {
|
|
267
371
|
const finding = createWorkspaceTools(read).filter(tool => tool.name !== 'readFile' && tool.name !== 'readFiles');
|
|
@@ -332,22 +436,30 @@ const repositoryGuidance = {
|
|
|
332
436
|
* @throws {UnrecoverableError} when a role cannot be set up, for example because
|
|
333
437
|
* `OPENAI_API_KEY` is missing, or when no program can read the repository.
|
|
334
438
|
*/
|
|
335
|
-
export async function createLLMOrchestrator({ provider, autoApprove, systemPrompts = {}, workspace = { roots: [{ path: process.cwd(), access: 'read' }] }, maxSteps, compactAt, commands, formatter, summarizeUndone = true, logger = new Logger(), onTranscript, } = {}) {
|
|
439
|
+
export async function createLLMOrchestrator({ provider, autoApprove, systemPrompts = {}, workspace = { roots: [{ path: process.cwd(), access: 'read' }] }, maxSteps, compactAt, compaction: compactionMode, commands, formatter, summarizeUndone = true, logger = new Logger(), onTranscript, removeWorktree = false, agents = {}, } = {}) {
|
|
336
440
|
const roles = orchestratorRolesFor(provider);
|
|
441
|
+
const agentsOf = roleAgents(agents);
|
|
337
442
|
const steps = perRole('maxSteps', maxSteps, defaultRoleSteps, {
|
|
338
443
|
unit: 'steps',
|
|
339
444
|
example: '{ "executor": 120 }',
|
|
340
445
|
});
|
|
341
|
-
const compaction =
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
446
|
+
const compaction = compactAt === false
|
|
447
|
+
? { planner: false, executor: false, reviewer: false }
|
|
448
|
+
: perRole('compactAt', compactAt, defaultRoleCompaction, {
|
|
449
|
+
unit: 'tokens',
|
|
450
|
+
example: '{ "executor": 200000 }',
|
|
451
|
+
});
|
|
345
452
|
if (formatter !== undefined)
|
|
346
453
|
validateFormatter(formatter);
|
|
347
454
|
const opened = await openWorkspace(workspace, logger, formatter ? { formatter } : {});
|
|
348
455
|
const guidance = workspaceGuidance(workspace.roots);
|
|
349
456
|
const summarizer = summarizeUndone ? summarizerFor(roles.planner.provider, logger) : undefined;
|
|
350
|
-
const shared = {
|
|
457
|
+
const shared = {
|
|
458
|
+
history: opened.store,
|
|
459
|
+
...(summarizer ? { summarizer } : {}),
|
|
460
|
+
compaction: compactionMode,
|
|
461
|
+
logger,
|
|
462
|
+
};
|
|
351
463
|
// A caller's own prompt replaces our instructions and guidance, not the workspace: the model
|
|
352
464
|
// needs the roots to name a file, as `createLLMAgent` gives them.
|
|
353
465
|
const prompt = (role, own, instructions) => own === undefined
|
|
@@ -365,6 +477,7 @@ export async function createLLMOrchestrator({ provider, autoApprove, systemPromp
|
|
|
365
477
|
systemPrompt: withGuidance(explorerInstructions, guidance),
|
|
366
478
|
tools: explorerToolset,
|
|
367
479
|
maxSteps: explorerSteps,
|
|
480
|
+
compaction: compactionMode,
|
|
368
481
|
logger,
|
|
369
482
|
onTranscript: transcriptsOf('explorer'),
|
|
370
483
|
});
|
|
@@ -372,14 +485,19 @@ export async function createLLMOrchestrator({ provider, autoApprove, systemPromp
|
|
|
372
485
|
model,
|
|
373
486
|
reasoningEffort,
|
|
374
487
|
systemPrompt,
|
|
375
|
-
tools:
|
|
488
|
+
tools: [
|
|
489
|
+
...(await readingTools(opened, role, commands, explorer(provider))),
|
|
490
|
+
...agentsOf[role],
|
|
491
|
+
],
|
|
376
492
|
maxSteps: steps[role],
|
|
377
493
|
compactAt: compaction[role],
|
|
378
494
|
onTranscript: transcriptsOf(role),
|
|
495
|
+
// It only reads, so the agents it calls only read too.
|
|
496
|
+
writeRoots: [],
|
|
379
497
|
...shared,
|
|
380
498
|
});
|
|
381
499
|
const { executor } = roles;
|
|
382
|
-
const executorToolset = await executorTools(executor.provider, opened, commands && commandsFor(commands, 'executor'));
|
|
500
|
+
const executorToolset = await executorTools(executor.provider, opened, commands && commandsFor(commands, 'executor'), removeWorktree);
|
|
383
501
|
// The executor and the reviewer are told whether the tests were run, which only an executor
|
|
384
502
|
// with a command can do.
|
|
385
503
|
const executorRuns = executorToolset.some(tool => tool.name === 'runCommand');
|
|
@@ -389,11 +507,12 @@ export async function createLLMOrchestrator({ provider, autoApprove, systemPromp
|
|
|
389
507
|
model: executor.model,
|
|
390
508
|
reasoningEffort: executor.reasoningEffort,
|
|
391
509
|
systemPrompt: prompt('executor', systemPrompts.executor, executorRuns ? executorInstructions : executorInstructionsWithoutCommands),
|
|
392
|
-
tools: executorToolset,
|
|
510
|
+
tools: [...executorToolset, ...agentsOf.executor],
|
|
393
511
|
maxSteps: steps.executor,
|
|
394
512
|
compactAt: compaction.executor,
|
|
395
513
|
autoApprove,
|
|
396
514
|
onTranscript: transcriptsOf('executor'),
|
|
515
|
+
writeRoots: writeRootsOf(workspace.roots),
|
|
397
516
|
...shared,
|
|
398
517
|
}),
|
|
399
518
|
reviewerAgent: await reader(roles.reviewer, 'reviewer', prompt('reviewer', systemPrompts.reviewer, executorRuns ? reviewerInstructions : reviewerInstructionsWithoutCommands)),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agentLLMFactory.js","sourceRoot":"","sources":["../../../src/factory/infrastructure/agentLLMFactory.ts"],"names":[],"mappings":"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","sourcesContent":["import { resolve } from 'node:path';\nimport type { Agent } from '#src/agent/domain/agent';\nimport type { Transcript, TranscriptCallback } from '#src/agent/domain/transcript';\nimport type { HistoryReader } from '#src/engines/domain/model/historyFollower';\nimport { LLMAgent } from '#src/engines/domain/model/llmAgent';\nimport type { LLMClient } from '#src/llm/domain/llm';\nimport {\n\tClaudeLLMClient,\n\tclaudeLLMModels,\n\tclaudeLLMReasoningEfforts,\n} from '#src/llm/infrastructure/claudeLLMClient';\nimport {\n\tOpenAILLMClient,\n\topenAIModels,\n\topenAIReasoningEfforts,\n} from '#src/llm/infrastructure/openAILLMClient';\nimport {\n\texecutorInstructions,\n\texecutorInstructionsWithoutCommands,\n\tOrchestratorAgent,\n\tplannerInstructions,\n\treviewerInstructions,\n\treviewerInstructionsWithoutCommands,\n} from '#src/orchestration/domain/model/orchestratorAgent';\nimport { ReviewerDecisionValidator } from '#src/orchestration/infrastructure/model/reviewerDecisionValidator';\nimport type { RecoveryStore } from '#src/recovery/domain/recoveryStore';\nimport { RetryingAgent } from '#src/retry/domain/model/retryingAgent';\nimport { InvalidAgentConfigError } from '#src/shared/domain/errors';\nimport { isOneOf } from '#src/shared/domain/isOneOf';\nimport type { ILogger } from '#src/shared/domain/logger';\nimport { Logger } from '#src/shared/infrastructure/logger';\nimport type { WorkspaceRoot } from '#src/tools/domain/accessPolicy';\nimport {\n\ttype CommandRole,\n\ttype Commands,\n\tcommandsFor,\n\ttype Formatter,\n\tvalidateCommands,\n\tvalidateFormatter,\n} from '#src/tools/domain/commands';\nimport type { AgentTool } from '#src/tools/domain/preparedCall';\nimport type { Tool } from '#src/tools/domain/tool';\nimport {\n\tcommandToolFor,\n\ttype FileTool,\n\tfileToolsFor,\n\ttype OpenedWorkspace,\n\topenStore,\n\topenWorkspace,\n\tstateDirectoryOf,\n\ttype WorkspaceOptions,\n} from '#src/tools/infrastructure/fileTools';\nimport type { DelegationTool } from '#src/tools/infrastructure/agentAsTool';\nimport { createExploreTool } from '#src/tools/infrastructure/exploreTool';\nimport { createShowChangesTool } from '#src/tools/infrastructure/showChangesTool';\nimport {\n\tcreateTrackedReadFile,\n\tcreateTrackedReadFiles,\n} from '#src/tools/infrastructure/trackedReadFile';\nimport { createWorkspaceTools } from '#src/tools/infrastructure/workspaceTools';\nimport { isAgentProvider, orchestratorRolesFor, type Role } from './agentFactory.ts';\nimport {\n\tagentProviders,\n\ttype AgentModel,\n\ttype AgentProvider,\n\ttype CreateOrchestratorOptions,\n\ttype ReasoningEffort,\n} from './types.ts';\n\n/** The models each provider's model API accepts. */\nexport const llmModels = {\n\tanthropic: claudeLLMModels,\n\topenai: openAIModels,\n} as const satisfies Readonly<Record<AgentProvider, readonly AgentModel[]>>;\n\n/** The reasoning efforts each provider's model API accepts. */\nexport const llmReasoningEfforts = {\n\tanthropic: claudeLLMReasoningEfforts,\n\topenai: openAIReasoningEfforts,\n} as const satisfies Readonly<Record<AgentProvider, readonly ReasoningEffort[]>>;\n\n/** Narrows a model to one accepted by the selected provider's model API. */\nexport function isLLMModelOf<Provider extends AgentProvider>(\n\tprovider: Provider,\n\tvalue: string,\n): value is (typeof llmModels)[Provider][number] {\n\treturn isOneOf(llmModels[provider], value);\n}\n\n/** Narrows a reasoning effort to one accepted by the selected provider's model API. */\nexport function isLLMReasoningEffortOf<Provider extends AgentProvider>(\n\tprovider: Provider,\n\tvalue: string,\n): value is (typeof llmReasoningEfforts)[Provider][number] {\n\treturn isOneOf(llmReasoningEfforts[provider], value);\n}\n\nexport interface CreateLLMAgentOptions {\n\t/**\n\t * Defaults to `'sonnet'` on Anthropic and `'gpt-5.6-luna'` on OpenAI. The provider's client\n\t * rejects a model it does not support.\n\t */\n\tmodel?: AgentModel;\n\t/** Defaults to `'high'`. The provider's client rejects an effort it does not support. */\n\treasoningEffort?: ReasoningEffort;\n\t/** Sent as the model's instructions on every call. */\n\tsystemPrompt: string;\n\t/**\n\t * The tools the model may call: the consumer's own, those of `createFileTools`, and agents\n\t * offered with `agentAsTool`. Defaults to none.\n\t */\n\ttools?: (Tool | FileTool | DelegationTool)[];\n\t/**\n\t * The folders the agent works on, the same as given to `createFileTools`. With it, the agent\n\t * follows the workspace's history: after the user undoes runs, its next run starts from the\n\t * conversation as it was, and is told what was undone. The system prompt is followed by the\n\t * roots and how to name a file in them.\n\t */\n\tworkspace?: WorkspaceOptions;\n\t/**\n\t * With `workspace`, a summary of what was undone, from the provider's cheap model, in place\n\t * of the undone prompts. That is Claude Haiku 5.5 or `gpt-5.6-luna`, at high effort, and the\n\t * call is billed with the run's tokens. Defaults to `true`.\n\t */\n\tsummarizeUndone?: boolean;\n\t/**\n\t * How many calls to the model one run may make before it fails. Defaults to 65, with no upper\n\t * bound. A run that asks for exactly the same tool calls 5 times in a row fails before that.\n\t */\n\tmaxSteps?: number;\n\t/**\n\t * The input tokens at which the provider compacts the conversation on its side: it replaces\n\t * every turn before that call with its own summary, which only its model reads back. The\n\t * conversation keeps every original turn. Without it, the conversation is never compacted.\n\t * At least 50,000 on Anthropic.\n\t */\n\tcompactAt?: number;\n\t/**\n\t * Runs every tool call without asking, `destructive` ones included, for CI where no one can\n\t * answer. Without it, a `destructive` call goes to the run's `approve`, or is denied.\n\t */\n\tautoApprove?: boolean;\n\t/** Defaults to warnings on stderr. */\n\tlogger?: ILogger;\n\t/**\n\t * Receives what the model saw in each run once the run ended, completed, failed or\n\t * cancelled, for debugging. See `Transcript`. Without it, nothing is kept.\n\t */\n\tonTranscript?: TranscriptCallback;\n}\n\n/** A limit per role of `createLLMOrchestrator`; a role left out keeps its default. */\nexport type RoleSteps = Partial<Record<OrchestratorRole, number>>;\n\n/** A number of tokens per role of `createLLMOrchestrator`; a role left out keeps its default. */\nexport type RoleTokens = Partial<Record<OrchestratorRole, number>>;\n\n// The same three roles a command can be given to.\ntype OrchestratorRole = CommandRole;\n\n// The executor reads, edits and checks, so it needs more calls than the roles that only read.\nconst defaultRoleSteps: Record<OrchestratorRole, number> = {\n\tplanner: 65,\n\texecutor: 80,\n\treviewer: 65,\n};\n\n// No role compacts unless asked to.\nconst defaultRoleCompaction: Record<OrchestratorRole, number | undefined> = {\n\tplanner: undefined,\n\texecutor: undefined,\n\treviewer: undefined,\n};\n\n/**\n * Each role's value of the option `name`, from one number for all of them or a number per role.\n * Each number is checked by whatever takes it.\n *\n * @throws {InvalidAgentConfigError} for a value that is neither, and for a role that does not\n * exist, which is a typo that would otherwise leave that role on its default without a word.\n */\nfunction perRole<T extends number | undefined>(\n\tname: string,\n\tvalue: unknown,\n\tdefaults: Record<OrchestratorRole, T>,\n\t{ unit, example }: { unit: string; example: string },\n): Record<OrchestratorRole, T | number> {\n\tif (value === undefined) return defaults;\n\tif (typeof value === 'number') return { planner: value, executor: value, reviewer: value };\n\t// Untyped input, such as the CLI's configuration file, can hold `null` or a list here.\n\tif (typeof value !== 'object' || value === null || Array.isArray(value)) {\n\t\tthrow new InvalidAgentConfigError(\n\t\t\t`${name} must be a number or an object of ${unit} per role, such as ${example}`,\n\t\t);\n\t}\n\tconst unknown = Object.keys(value).filter(role => !(role in defaults));\n\tif (unknown.length > 0) {\n\t\tthrow new InvalidAgentConfigError(\n\t\t\t`${name} names roles that do not exist: ${unknown.join(', ')}; expected planner, executor or reviewer`,\n\t\t);\n\t}\n\t// A role given as `undefined`, which untyped input can do, keeps its default.\n\tconst given = Object.entries(value as Record<string, unknown>).filter(\n\t\t([, each]) => each !== undefined,\n\t);\n\treturn { ...defaults, ...Object.fromEntries(given) };\n}\n\nexport interface CreateLLMOrchestratorOptions extends CreateOrchestratorOptions {\n\t/**\n\t * The folders the agents work on. The executor changes files only in a `write` root, every\n\t * change recorded in the workspace's history. Defaults to the current working directory,\n\t * read only.\n\t */\n\tworkspace?: WorkspaceOptions;\n\t/**\n\t * How many calls to the model one run of each role may make: one number for every role, or a\n\t * number per role. Defaults to 80 for the executor and 65 for the planner and the reviewer,\n\t * with no upper bound. A run that asks for exactly the same tool calls 5 times in a row fails\n\t * before its limit.\n\t */\n\tmaxSteps?: number | RoleSteps;\n\t/**\n\t * The input tokens at which each role's provider compacts its conversation, as\n\t * `CreateLLMAgentOptions.compactAt`: one number for every role, or a number per role. Without\n\t * it, no role compacts.\n\t */\n\tcompactAt?: number | RoleTokens;\n\t/**\n\t * Commands the roles may run, such as the project's tests, through `runCommand`. Each goes to\n\t * the roles its `roles` names, the executor by default. See `createFileTools`. Each needs a\n\t * `write` root to run in.\n\t */\n\tcommands?: Commands;\n\t/**\n\t * A program the executor's edits run on each file they create or change, such as the\n\t * project's formatter. See `createFileTools`. It needs a `write` root to run in.\n\t */\n\tformatter?: Formatter;\n\t/**\n\t * A summary of what the user undid, from the planner's provider's cheap model, for every\n\t * role. See `CreateLLMAgentOptions.summarizeUndone`. Defaults to `true`.\n\t */\n\tsummarizeUndone?: boolean;\n\t/**\n\t * Receives what the model saw in each run of each role and each explorer, once the run\n\t * ended, for debugging. Each transcript names its role. See `Transcript`.\n\t */\n\tonTranscript?: TranscriptCallback;\n}\n\nconst defaultLLMAgentModels = {\n\tanthropic: 'sonnet',\n\topenai: 'gpt-5.6-luna',\n} as const satisfies Record<AgentProvider, AgentModel>;\n\nfunction unknownProvider(provider: never): InvalidAgentConfigError {\n\treturn new InvalidAgentConfigError(\n\t\t`\"${String(provider)}\" is not an agent provider; expected one of: ${agentProviders.join(', ')}`,\n\t);\n}\n\nfunction llmClientFor(\n\tprovider: AgentProvider,\n\t{\n\t\tmodel,\n\t\treasoningEffort,\n\t\tcompactAt,\n\t\tsystemPrompt,\n\t\tlogger,\n\t}: {\n\t\tmodel?: AgentModel;\n\t\treasoningEffort?: ReasoningEffort;\n\t\tcompactAt?: number | undefined;\n\t\tsystemPrompt: string;\n\t\tlogger: ILogger;\n\t},\n): LLMClient {\n\tswitch (provider) {\n\t\tcase 'anthropic':\n\t\t\treturn new ClaudeLLMClient({\n\t\t\t\tmodel: model ?? defaultLLMAgentModels.anthropic,\n\t\t\t\treasoningEffort,\n\t\t\t\tcompactAt,\n\t\t\t\tsystemPrompt,\n\t\t\t\tlogger,\n\t\t\t});\n\t\tcase 'openai':\n\t\t\treturn new OpenAILLMClient({\n\t\t\t\tmodel: model ?? defaultLLMAgentModels.openai,\n\t\t\t\treasoningEffort,\n\t\t\t\tcompactAt,\n\t\t\t\tsystemPrompt,\n\t\t\t\tlogger,\n\t\t\t});\n\t\tdefault:\n\t\t\t// Reachable from untyped input.\n\t\t\tthrow unknownProvider(provider);\n\t}\n}\n\n/** The provider's cheap model, for the summary of what was undone. */\nfunction summarizerFor(provider: AgentProvider, logger: ILogger): LLMClient {\n\treturn provider === 'anthropic'\n\t\t? new ClaudeLLMClient({ model: 'haiku', reasoningEffort: 'high', systemPrompt: '', logger })\n\t\t: new OpenAILLMClient({\n\t\t\t\tmodel: 'gpt-5.6-luna',\n\t\t\t\treasoningEffort: 'high',\n\t\t\t\tsystemPrompt: '',\n\t\t\t\tlogger,\n\t\t\t});\n}\n\n/**\n * The workspace's history, opened on first use, so a factory that builds an agent stays\n * synchronous. Every agent and every file tool of one workspace reads the same files on disk.\n */\nfunction historyOf(workspace: WorkspaceOptions, logger: ILogger): HistoryReader {\n\t// Checked now: an agent with no root to follow is a setup error, not a first-run one.\n\tif (workspace.roots.length === 0) {\n\t\tthrow new InvalidAgentConfigError('A workspace needs at least one root');\n\t}\n\tlet store: Promise<RecoveryStore> | undefined;\n\tconst open = () => {\n\t\tstore ??= stateDirectoryOf(workspace)\n\t\t\t.then(directory => openStore(workspace, directory, logger))\n\t\t\t.catch((error: unknown) => {\n\t\t\t\t// Not kept: the next run tries again, as one whose disk was full for a moment.\n\t\t\t\tstore = undefined;\n\t\t\t\tthrow error;\n\t\t\t});\n\t\treturn store;\n\t};\n\treturn {\n\t\tlistRuns: async () => (await open()).listRuns(),\n\t\tlistRevisions: async () => (await open()).listRevisions(),\n\t\treadRun: async runId => (await open()).readRun(runId),\n\t};\n}\n\n/**\n * What the model is told about the workspace after its instructions: the roots, which it may\n * change, and how to name a file. A host path in an error sends the model looking for it, so\n * the real root is given here once.\n */\nfunction workspaceGuidance(roots: WorkspaceRoot[]): string {\n\tconst [first, ...others] = roots.map(root => ({ ...root, path: resolve(root.path) }));\n\tif (!first) return '';\n\tconst described = [first, ...others].map(\n\t\t({ path, access }) => `- ${path}${access === 'write' ? '' : ' (read only)'}`,\n\t);\n\treturn [\n\t\t'The workspace:',\n\t\t...described,\n\t\t`Name a file by its path relative to ${first.path}, such as src/index.ts, and a file in another folder of the workspace by its full path. Read a file before you change it.`,\n\t].join('\\n');\n}\n\nfunction withGuidance(systemPrompt: string, guidance: string): string {\n\treturn guidance === '' ? systemPrompt : `${systemPrompt}\\n\\n${guidance}`;\n}\n\n/** An `LLMAgent` on `provider`, wrapped in the harness's retry policy. */\nfunction buildLLMAgent(\n\tprovider: AgentProvider,\n\t{\n\t\tmodel,\n\t\treasoningEffort,\n\t\tsystemPrompt,\n\t\ttools,\n\t\thistory,\n\t\tsummarizer,\n\t\tmaxSteps,\n\t\tcompactAt,\n\t\tautoApprove,\n\t\tlogger,\n\t\tonTranscript,\n\t}: {\n\t\tmodel?: AgentModel;\n\t\treasoningEffort?: ReasoningEffort;\n\t\tsystemPrompt: string;\n\t\ttools: AgentTool[];\n\t\thistory?: HistoryReader;\n\t\tsummarizer?: LLMClient;\n\t\tmaxSteps?: number;\n\t\tcompactAt?: number | undefined;\n\t\tautoApprove?: boolean;\n\t\tlogger: ILogger;\n\t\tonTranscript?: TranscriptCallback | undefined;\n\t},\n): Agent {\n\tconst llmClient = llmClientFor(provider, {\n\t\tmodel,\n\t\treasoningEffort,\n\t\tcompactAt,\n\t\tsystemPrompt,\n\t\tlogger,\n\t});\n\t// LLMAgent records nothing from a failed call, so the original prompt is the whole story.\n\treturn new RetryingAgent({\n\t\tinner: new LLMAgent({\n\t\t\tllmClient,\n\t\t\ttools,\n\t\t\tautoApprove,\n\t\t\tlogger,\n\t\t\t...(history ? { history } : {}),\n\t\t\t...(summarizer ? { summarizer } : {}),\n\t\t\t...(maxSteps === undefined ? {} : { maxSteps }),\n\t\t\t...(onTranscript ? { onTranscript } : {}),\n\t\t}),\n\t\tlogger,\n\t\tnoteFailures: false,\n\t});\n}\n\n/**\n * Builds an agent whose conversation MiKode owns, on a provider's model API, already wrapped in\n * the harness's retry policy. It needs the provider's API key and bills per token, where\n * `createAgent` uses the Agent SDK's login. Each tool judges the risk of each call; a\n * `destructive` one runs only when the run's `approve` allows it, or with `autoApprove`.\n *\n * @throws {InvalidAgentConfigError} for an unknown provider, a model or reasoning effort its\n * client does not support, or two tools that share a name.\n * @throws {UnrecoverableError} when the client cannot be set up, for example because\n * `OPENAI_API_KEY` is missing. The Anthropic SDK resolves credentials lazily, so a missing\n * `ANTHROPIC_API_KEY` fails the first run instead, with an `UnrecoverableError`.\n */\nexport function createLLMAgent(\n\tprovider: AgentProvider,\n\t{\n\t\tmodel,\n\t\treasoningEffort,\n\t\tsystemPrompt,\n\t\ttools = [],\n\t\tworkspace,\n\t\tsummarizeUndone = true,\n\t\tmaxSteps,\n\t\tcompactAt,\n\t\tautoApprove,\n\t\tlogger = new Logger(),\n\t\tonTranscript,\n\t}: CreateLLMAgentOptions,\n): Agent {\n\treturn buildLLMAgent(provider, {\n\t\tmodel,\n\t\treasoningEffort,\n\t\tsystemPrompt: workspace\n\t\t\t? withGuidance(systemPrompt, workspaceGuidance(workspace.roots))\n\t\t\t: systemPrompt,\n\t\t// A file tool or a delegation tool is a harness tool under its public name.\n\t\ttools: tools as AgentTool[],\n\t\t...(workspace ? { history: historyOf(workspace, logger) } : {}),\n\t\t...(workspace && summarizeUndone ? { summarizer: summarizerFor(provider, logger) } : {}),\n\t\tmaxSteps,\n\t\tcompactAt,\n\t\tautoApprove,\n\t\tlogger,\n\t\tonTranscript,\n\t});\n}\n\n/**\n * The file tools for an agent from `createLLMAgent` on `provider`, over `workspace`, in the\n * provider's own format:\n *\n * - OpenAI: `listFiles`, `searchText`, `readFile`, `readFiles` and its native `apply_patch`;\n * - Anthropic: `listFiles`, `searchText`, its native text editor, whose `view` reads, and\n * `delete_file`.\n *\n * Every one goes through the workspace's access policy: a path outside the roots, a secret,\n * a file `.gitignore` excludes or the harness protects is refused. A change is made only in a\n * `write` root, only from a version the agent read, and is recorded in the workspace's history,\n * so it can be undone. Without a `write` root the tools only read. Give the agent the same\n * `workspace`, so it follows what the history undoes.\n *\n * With `commands`, they include `runCommand`, which runs one of them by name, with only the\n * parameters it declares and never through a shell. Each run asks the approver, showing the\n * program exactly as it will run, and gets a small environment without the provider keys. The\n * files of the `write` roots are captured before it and compared after, so what it changed is\n * in the history too. It is trusted execution, not a sandbox: a command can reach whatever\n * this user can. Not supported on Windows yet.\n *\n * With `formatter`, every file an edit creates or changes is formatted right after, its path\n * the formatter's last argument. The edit shows the lines the formatter rewrote, and the model\n * reads a file it rewrote again before editing it. Like a command it runs without a shell, in a small environment, and what it changes in that file is\n * in the history. When it fails, the file stays as the edit wrote it, and the model is told\n * why. Not supported on Windows yet.\n *\n * @throws {InvalidAgentConfigError} for an unknown provider, a workspace with no root, or an\n * invalid command or formatter, including one whose `cwd` is not in a `write` root, or any on\n * Windows.\n * @throws {UnrecoverableError} when no program can read the first root.\n */\nexport async function createFileTools(\n\tprovider: AgentProvider,\n\tworkspace: WorkspaceOptions,\n\t{\n\t\tlogger = new Logger(),\n\t\tcommands,\n\t\tformatter,\n\t}: { logger?: ILogger; commands?: Commands; formatter?: Formatter } = {},\n): Promise<FileTool[]> {\n\t// Reachable from untyped input.\n\tif (!isAgentProvider(provider)) throw unknownProvider(provider);\n\tif (commands !== undefined) validateCommands(commands);\n\tif (formatter !== undefined) validateFormatter(formatter);\n\tconst opened = await openWorkspace(workspace, logger, formatter ? { formatter } : {});\n\treturn (await executorTools(provider, opened, commands)) as unknown as FileTool[];\n}\n\n/** The executor's file tools, and `runCommand` when there are commands. */\nasync function executorTools(\n\tprovider: AgentProvider,\n\tworkspace: OpenedWorkspace,\n\tcommands: Commands | undefined,\n): Promise<AgentTool[]> {\n\tconst tools = fileToolsFor(provider, workspace);\n\t// Every command may belong to other roles, leaving none for this one.\n\tif (commands === undefined || Object.keys(commands).length === 0) return tools;\n\treturn [...tools, await commandToolFor(workspace, commands)];\n}\n\n/** What an explorer finds and reads with: no edits, no changes, no commands. */\nfunction explorerTools({ read, policy }: OpenedWorkspace): AgentTool[] {\n\tconst finding = createWorkspaceTools(read).filter(\n\t\ttool => tool.name !== 'readFile' && tool.name !== 'readFiles',\n\t);\n\treturn [...finding, createTrackedReadFile(policy), createTrackedReadFiles(policy)];\n}\n\n/**\n * What the planner and the reviewer read with: no edits, the current task's changes, `explore`\n * with `explorer`, and the commands given to their role.\n */\nasync function readingTools(\n\tworkspace: OpenedWorkspace,\n\trole: CommandRole,\n\tcommands: Commands | undefined,\n\texplorer: () => Agent,\n): Promise<AgentTool[]> {\n\tconst { policy, store } = workspace;\n\tconst tools = [\n\t\t...explorerTools(workspace),\n\t\tcreateShowChangesTool({ store, policy }),\n\t\tcreateExploreTool(explorer),\n\t];\n\tconst own = commands && commandsFor(commands, role);\n\tif (!own || Object.keys(own).length === 0) return tools;\n\treturn [...tools, await commandToolFor(workspace, own)];\n}\n\nconst batching =\n\t'When you know you need several files, or several searches, ask for all of them in one answer rather than one at a time: each answer is a step, and steps are limited.';\n\n// For the roles that have `readFiles`, which the executor on Claude does not.\nconst batchingReads =\n\t'When you know you need several files, or several ranges, read them in one readFiles call, and ask for several searches in one answer, rather than one at a time: each answer is a step, and steps are limited.';\n\n// The explorers find and the role reads, as a reader asks a librarian where a book is and then\n// reads it: their reports are where to look, not a summary to work from.\nconst exploring =\n\t'To find where something is in the repository, ask explorers instead of searching yourself: send `explore` the independent questions you have in one call. They work in the background while you go on, and each one answers, once it finishes, with the files and line ranges that hold what you asked. Then read those ranges yourself, all of them in one readFiles call.';\n\n// Each provider's cheaper model, which only finds and reads.\nconst explorerRoles = {\n\tanthropic: { model: 'haiku', reasoningEffort: 'medium' },\n\topenai: { model: 'gpt-5.6-luna', reasoningEffort: 'medium' },\n} as const satisfies Record<AgentProvider, { model: AgentModel; reasoningEffort: ReasoningEffort }>;\n\nconst explorerSteps = 30;\n\nconst explorerInstructions = `You find things in a repository for another agent, which is planning or reviewing a change and asked you one question, as a reader asks a librarian where a book is. Find where the answer is with listFiles, searchText, readFile and readFiles, reading only what you need to be sure. Answer with where it is: each file and the line ranges that matter, and in a sentence what each range holds and why it answers the question. The other agent reads those ranges itself, so do not copy code beyond a line that marks a place. Say what you looked for and could not find. Do not propose changes or a plan. ${batchingReads}`;\n\n// How each role finds its way, sent after the workspace's roots, so it stays short. Only the\n// planner learns the repository; the executor and the reviewer work from its plan, so a plan\n// that leaves them guessing is the planner's to fix, not theirs to make up for.\nconst repositoryGuidance: Record<CommandRole, string> = {\n\tplanner: `Start with AGENTS.md, which says where the architecture and the decisions are, and read only the parts your task needs. Name in the plan every file to change and what to change in it, so the executor needs nothing else. ${exploring} ${batchingReads}`,\n\texecutor: `Work from the plan: read the files it names, and only what you need to change them. Do not study the repository's architecture or decisions; the plan already applied them. ${batching}`,\n\treviewer: `Work from the plan and the changes: read what they touch, and only what you need to judge them. ${exploring} ${batchingReads}`,\n};\n\n/**\n * Builds the planner → executor → reviewer workflow with every role on the model APIs, each\n * holding its role's instructions, or `systemPrompts`, as its system prompt, followed by the\n * workspace's roots.\n *\n * - The planner and the reviewer read: `listFiles`, `searchText`, `readFile`, `readFiles`, `showChanges`,\n * the current task's changes as far as each may read them, and `explore`, which sends up to 4\n * read-only explorers at once on the role's provider's cheaper model, each a new agent that\n * starts from its question and works in the background while the role goes on.\n * - The executor gets its provider's file tools (see `createFileTools`), and changes files only\n * in a `write` root; `autoApprove` reaches only it.\n * - Each role has its own step limit: `maxSteps`, 80 for the executor and 65 for the others by\n * default.\n * - Each role gets `runCommand` with the `commands` whose `roles` name it, the executor by\n * default. A command asks the approver in any role, and its files are captured around it.\n * - When the executor has a command, it is told to finish only once the tests and checks pass,\n * or to say which fail, and the reviewer takes from its response whether they pass. Without\n * one, both are told the tests were not run, and the reviewer judges from the code whether\n * they would pass.\n *\n * One run of the orchestrator is one run of the workspace's history, every round and retry\n * included, and its `AgentResponse` names it. Every role follows what the user undoes.\n * Asynchronous because opening the workspace is.\n *\n * @throws {InvalidAgentConfigError} for an unknown provider, or a workspace with no root.\n * @throws {UnrecoverableError} when a role cannot be set up, for example because\n * `OPENAI_API_KEY` is missing, or when no program can read the repository.\n */\nexport async function createLLMOrchestrator({\n\tprovider,\n\tautoApprove,\n\tsystemPrompts = {},\n\tworkspace = { roots: [{ path: process.cwd(), access: 'read' }] },\n\tmaxSteps,\n\tcompactAt,\n\tcommands,\n\tformatter,\n\tsummarizeUndone = true,\n\tlogger = new Logger(),\n\tonTranscript,\n}: CreateLLMOrchestratorOptions = {}): Promise<Agent> {\n\tconst roles = orchestratorRolesFor(provider);\n\tconst steps = perRole('maxSteps', maxSteps, defaultRoleSteps, {\n\t\tunit: 'steps',\n\t\texample: '{ \"executor\": 120 }',\n\t});\n\tconst compaction = perRole('compactAt', compactAt, defaultRoleCompaction, {\n\t\tunit: 'tokens',\n\t\texample: '{ \"executor\": 200000 }',\n\t});\n\tif (formatter !== undefined) validateFormatter(formatter);\n\tconst opened = await openWorkspace(workspace, logger, formatter ? { formatter } : {});\n\tconst guidance = workspaceGuidance(workspace.roots);\n\tconst summarizer = summarizeUndone ? summarizerFor(roles.planner.provider, logger) : undefined;\n\tconst shared = { history: opened.store, ...(summarizer ? { summarizer } : {}), logger };\n\t// A caller's own prompt replaces our instructions and guidance, not the workspace: the model\n\t// needs the roots to name a file, as `createLLMAgent` gives them.\n\tconst prompt = (role: CommandRole, own: string | undefined, instructions: string) =>\n\t\town === undefined\n\t\t\t? withGuidance(instructions, `${guidance}\\n${repositoryGuidance[role]}`)\n\t\t\t: withGuidance(own, guidance);\n\t// Each transcript names the agent it is of.\n\tconst transcriptsOf = (agent: Transcript['agent']) =>\n\t\tonTranscript && ((transcript: Transcript) => onTranscript({ ...transcript, agent }));\n\t// Every command, checked once, before any role takes its share.\n\tif (commands !== undefined) validateCommands(commands);\n\t// A new explorer for each question, on the role's provider: it starts from the question alone.\n\tconst explorerToolset = explorerTools(opened);\n\tconst explorer = (provider: AgentProvider) => () =>\n\t\tbuildLLMAgent(provider, {\n\t\t\t...explorerRoles[provider],\n\t\t\tsystemPrompt: withGuidance(explorerInstructions, guidance),\n\t\t\ttools: explorerToolset,\n\t\t\tmaxSteps: explorerSteps,\n\t\t\tlogger,\n\t\t\tonTranscript: transcriptsOf('explorer'),\n\t\t});\n\tconst reader = async (\n\t\t{ provider, model, reasoningEffort }: Role,\n\t\trole: CommandRole,\n\t\tsystemPrompt: string,\n\t) =>\n\t\tbuildLLMAgent(provider, {\n\t\t\tmodel,\n\t\t\treasoningEffort,\n\t\t\tsystemPrompt,\n\t\t\ttools: await readingTools(opened, role, commands, explorer(provider)),\n\t\t\tmaxSteps: steps[role],\n\t\t\tcompactAt: compaction[role],\n\t\t\tonTranscript: transcriptsOf(role),\n\t\t\t...shared,\n\t\t});\n\tconst { executor } = roles;\n\tconst executorToolset = await executorTools(\n\t\texecutor.provider,\n\t\topened,\n\t\tcommands && commandsFor(commands, 'executor'),\n\t);\n\t// The executor and the reviewer are told whether the tests were run, which only an executor\n\t// with a command can do.\n\tconst executorRuns = executorToolset.some(tool => tool.name === 'runCommand');\n\n\treturn new OrchestratorAgent({\n\t\tplannerAgent: await reader(\n\t\t\troles.planner,\n\t\t\t'planner',\n\t\t\tprompt('planner', systemPrompts.planner, plannerInstructions),\n\t\t),\n\t\texecutorAgent: buildLLMAgent(executor.provider, {\n\t\t\tmodel: executor.model,\n\t\t\treasoningEffort: executor.reasoningEffort,\n\t\t\tsystemPrompt: prompt(\n\t\t\t\t'executor',\n\t\t\t\tsystemPrompts.executor,\n\t\t\t\texecutorRuns ? executorInstructions : executorInstructionsWithoutCommands,\n\t\t\t),\n\t\t\ttools: executorToolset,\n\t\t\tmaxSteps: steps.executor,\n\t\t\tcompactAt: compaction.executor,\n\t\t\tautoApprove,\n\t\t\tonTranscript: transcriptsOf('executor'),\n\t\t\t...shared,\n\t\t}),\n\t\treviewerAgent: await reader(\n\t\t\troles.reviewer,\n\t\t\t'reviewer',\n\t\t\tprompt(\n\t\t\t\t'reviewer',\n\t\t\t\tsystemPrompts.reviewer,\n\t\t\t\texecutorRuns ? reviewerInstructions : reviewerInstructionsWithoutCommands,\n\t\t\t),\n\t\t),\n\t\treviewerDecisionValidator: new ReviewerDecisionValidator(),\n\t\tlogger,\n\t});\n}\n"]}
|
|
1
|
+
{"version":3,"file":"agentLLMFactory.js","sourceRoot":"","sources":["../../../src/factory/infrastructure/agentLLMFactory.ts"],"names":[],"mappings":"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","sourcesContent":["import { resolve } from 'node:path';\nimport type { Agent } from '#src/agent/domain/agent';\nimport type { Transcript, TranscriptCallback } from '#src/agent/domain/transcript';\nimport type { HistoryReader } from '#src/engines/domain/model/historyFollower';\nimport { type Compactor, recentKeptSteps } from '#src/engines/domain/model/compactor';\nimport { LLMAgent } from '#src/engines/domain/model/llmAgent';\nimport { JevContextTriage } from '#src/llm/infrastructure/jevContextTriage';\nimport type { LLMClient } from '#src/llm/domain/llm';\nimport {\n\tClaudeLLMClient,\n\ttype ClaudeLLMModel,\n\tclaudeLLMModels,\n\tclaudeLLMReasoningEfforts,\n} from '#src/llm/infrastructure/claudeLLMClient';\nimport {\n\tOpenAILLMClient,\n\ttype OpenAIModel,\n\topenAIModels,\n\topenAIReasoningEfforts,\n} from '#src/llm/infrastructure/openAILLMClient';\nimport {\n\texecutorInstructions,\n\texecutorInstructionsWithoutCommands,\n\tOrchestratorAgent,\n\tplannerInstructions,\n\treviewerInstructions,\n\treviewerInstructionsWithoutCommands,\n} from '#src/orchestration/domain/model/orchestratorAgent';\nimport { ReviewerDecisionValidator } from '#src/orchestration/infrastructure/model/reviewerDecisionValidator';\nimport type { RecoveryStore } from '#src/recovery/domain/recoveryStore';\nimport { RetryingAgent } from '#src/retry/domain/model/retryingAgent';\nimport { InvalidAgentConfigError } from '#src/shared/domain/errors';\nimport { isOneOf } from '#src/shared/domain/isOneOf';\nimport type { ILogger } from '#src/shared/domain/logger';\nimport { Logger } from '#src/shared/infrastructure/logger';\nimport type { WorkspaceRoot } from '#src/tools/domain/accessPolicy';\nimport {\n\ttype CommandRole,\n\ttype Commands,\n\tcommandsFor,\n\ttype Formatter,\n\tvalidateCommands,\n\tvalidateFormatter,\n} from '#src/tools/domain/commands';\nimport type { AgentTool } from '#src/tools/domain/preparedCall';\nimport type { Tool } from '#src/tools/domain/tool';\nimport {\n\tcommandToolFor,\n\ttype FileTool,\n\tfileToolsFor,\n\ttype OpenedWorkspace,\n\topenStore,\n\topenWorkspace,\n\tstateDirectoryOf,\n\ttype WorkspaceOptions,\n} from '#src/tools/infrastructure/fileTools';\nimport type { DelegationTool } from '#src/tools/infrastructure/agentAsTool';\nimport { createExploreTool } from '#src/tools/infrastructure/exploreTool';\nimport { createShowChangesTool } from '#src/tools/infrastructure/showChangesTool';\nimport { createRemoveWorktreeTool } from '#src/tools/infrastructure/removeWorktreeTool';\nimport { listWorktrees } from '#src/tools/infrastructure/worktrees';\nimport {\n\tcreateTrackedReadFile,\n\tcreateTrackedReadFiles,\n} from '#src/tools/infrastructure/trackedReadFile';\nimport { createWorkspaceTools } from '#src/tools/infrastructure/workspaceTools';\nimport { isAgentProvider, orchestratorRolesFor, type Role } from './agentFactory.ts';\nimport {\n\tagentProviders,\n\ttype AgentModel,\n\ttype AgentProvider,\n\ttype CreateOrchestratorOptions,\n\ttype ReasoningEffort,\n} from './types.ts';\n\n/** The models each provider's model API accepts. */\nexport const llmModels = {\n\tanthropic: claudeLLMModels,\n\topenai: openAIModels,\n} as const satisfies Readonly<Record<AgentProvider, readonly AgentModel[]>>;\n\n/** The reasoning efforts each provider's model API accepts. */\nexport const llmReasoningEfforts = {\n\tanthropic: claudeLLMReasoningEfforts,\n\topenai: openAIReasoningEfforts,\n} as const satisfies Readonly<Record<AgentProvider, readonly ReasoningEffort[]>>;\n\n/** Narrows a model to one accepted by the selected provider's model API. */\nexport function isLLMModelOf<Provider extends AgentProvider>(\n\tprovider: Provider,\n\tvalue: string,\n): value is (typeof llmModels)[Provider][number] {\n\treturn isOneOf(llmModels[provider], value);\n}\n\n/** Narrows a reasoning effort to one accepted by the selected provider's model API. */\nexport function isLLMReasoningEffortOf<Provider extends AgentProvider>(\n\tprovider: Provider,\n\tvalue: string,\n): value is (typeof llmReasoningEfforts)[Provider][number] {\n\treturn isOneOf(llmReasoningEfforts[provider], value);\n}\n\nexport interface CreateLLMAgentOptions {\n\t/**\n\t * Defaults to `'sonnet'` on Anthropic and `'gpt-5.6-luna'` on OpenAI. The provider's client\n\t * rejects a model it does not support.\n\t */\n\tmodel?: AgentModel;\n\t/** Defaults to `'high'`. The provider's client rejects an effort it does not support. */\n\treasoningEffort?: ReasoningEffort;\n\t/** Sent as the model's instructions on every call. */\n\tsystemPrompt: string;\n\t/**\n\t * The tools the model may call: the consumer's own, those of `createFileTools`, and agents\n\t * offered with `agentAsTool`. Defaults to none.\n\t */\n\ttools?: (Tool | FileTool | DelegationTool)[];\n\t/**\n\t * The folders the agent works on, the same as given to `createFileTools`. With it, the agent\n\t * follows the workspace's history: after the user undoes runs, its next run starts from the\n\t * conversation as it was, and is told what was undone. The system prompt is followed by the\n\t * roots and how to name a file in them. It gives no tools: pass those of `createFileTools`\n\t * in `tools`, and an agent given a workspace and no tools is refused.\n\t */\n\tworkspace?: WorkspaceOptions;\n\t/**\n\t * With `workspace`, a summary of what was undone, from the provider's cheap model, in place\n\t * of the undone prompts. That is Claude Haiku 5.5 or `gpt-5.6-luna`, at high effort, and the\n\t * call is billed with the run's tokens. Defaults to `true`.\n\t */\n\tsummarizeUndone?: boolean;\n\t/**\n\t * How many calls to the model one run may make before it fails. Defaults to 65, with no upper\n\t * bound. A run that asks for exactly the same tool calls 5 times in a row fails before that.\n\t */\n\tmaxSteps?: number;\n\t/**\n\t * The tokens of context at which the provider compacts it on its side: it replaces every turn\n\t * before that call with its own summary, which only its model reads back. The conversation\n\t * keeps every original turn. Defaults to the model's threshold: 450,000 for Claude Opus,\n\t * Fable and Sonnet and GPT astra, sol and terra, and 125,000 for Claude Haiku and GPT luna.\n\t * `false` turns compaction off. Either way, a context that no longer fits the model is\n\t * compacted once, and the call tried again. At least 50,000 on Anthropic.\n\t */\n\tcompactAt?: number | false;\n\t/**\n\t * Who compacts the context once it passes `compactAt`. `provider`, the default, has the\n\t * model's provider compact it on its side. `recent` has the agent's own model summarize it\n\t * before the next call, from its provider's cache, and keeps the run's prompt and the run's\n\t * last 10 answers, each with its tool results, word for word after the summary, without\n\t * their signed reasoning. Earlier runs are always summarized. `jev` summarizes the same way,\n\t * but TypeSafe's Jev chooses what is kept: the run's prompt, the model's last answer with its\n\t * tool results, and each earlier tool result Jev judges the agent still needs word for word,\n\t * with its call. Jev is sent the run's prompt, the model's last answer and each of those tool\n\t * results, so what the tools read leaves for TypeSafe. It reads the key from `TYPESAFE_API_KEY`; without it, or when Jev fails, the\n\t * `recent` choice is made instead, and logged.\n\t */\n\tcompaction?: CompactionMode;\n\t/**\n\t * Runs every tool call without asking, `destructive` ones included, for CI where no one can\n\t * answer. Without it, a `destructive` call goes to the run's `approve`, or is denied.\n\t */\n\tautoApprove?: boolean;\n\t/** Defaults to warnings on stderr. */\n\tlogger?: ILogger;\n\t/**\n\t * Receives what the model saw in each run once the run ended, completed, failed or\n\t * cancelled, for debugging. See `Transcript`. Without it, nothing is kept.\n\t */\n\tonTranscript?: TranscriptCallback;\n}\n\n/** Who compacts an agent's context; see `CreateLLMAgentOptions.compaction`. */\nexport type CompactionMode = 'provider' | 'recent' | 'jev';\n\nconst compactionModes = ['provider', 'recent', 'jev'] as const satisfies readonly CompactionMode[];\n\n/** A limit per role of `createLLMOrchestrator`; a role left out keeps its default. */\nexport type RoleSteps = Partial<Record<OrchestratorRole, number>>;\n\n/** A number of tokens per role of `createLLMOrchestrator`; a role left out keeps its default. */\nexport type RoleTokens = Partial<Record<OrchestratorRole, number>>;\n\n/** The consumer's agents, from `agentAsTool`, that each role of `createLLMOrchestrator` may call. */\nexport type RoleAgents = Partial<Record<OrchestratorRole, DelegationTool[]>>;\n\n// The same three roles a command can be given to.\ntype OrchestratorRole = CommandRole;\n\n// The executor reads, edits and checks, so it needs more calls than the roles that only read.\nconst defaultRoleSteps: Record<OrchestratorRole, number> = {\n\tplanner: 65,\n\texecutor: 80,\n\treviewer: 65,\n};\n\n// Each role compacts at its model's threshold unless told otherwise.\nconst defaultRoleCompaction: Record<OrchestratorRole, number | undefined> = {\n\tplanner: undefined,\n\texecutor: undefined,\n\treviewer: undefined,\n};\n\n/**\n * Each role's value of the option `name`, from one number for all of them or a number per role.\n * Each number is checked by whatever takes it.\n *\n * @throws {InvalidAgentConfigError} for a value that is neither, and for a role that does not\n * exist, which is a typo that would otherwise leave that role on its default without a word.\n */\nfunction perRole<T extends number | undefined>(\n\tname: string,\n\tvalue: unknown,\n\tdefaults: Record<OrchestratorRole, T>,\n\t{ unit, example }: { unit: string; example: string },\n): Record<OrchestratorRole, T | number> {\n\tif (value === undefined) return defaults;\n\tif (typeof value === 'number') return { planner: value, executor: value, reviewer: value };\n\t// Untyped input, such as the CLI's configuration file, can hold `null` or a list here.\n\tif (typeof value !== 'object' || value === null || Array.isArray(value)) {\n\t\tthrow new InvalidAgentConfigError(\n\t\t\t`${name} must be a number or an object of ${unit} per role, such as ${example}`,\n\t\t);\n\t}\n\tconst unknown = Object.keys(value).filter(role => !(role in defaults));\n\tif (unknown.length > 0) {\n\t\tthrow new InvalidAgentConfigError(\n\t\t\t`${name} names roles that do not exist: ${unknown.join(', ')}; expected planner, executor or reviewer`,\n\t\t);\n\t}\n\t// A role given as `undefined`, which untyped input can do, keeps its default.\n\tconst given = Object.entries(value as Record<string, unknown>).filter(\n\t\t([, each]) => each !== undefined,\n\t);\n\treturn { ...defaults, ...Object.fromEntries(given) };\n}\n\nexport interface CreateLLMOrchestratorOptions extends CreateOrchestratorOptions {\n\t/**\n\t * The folders the agents work on. The executor changes files only in a `write` root, every\n\t * change recorded in the workspace's history. Defaults to the current working directory,\n\t * read only.\n\t */\n\tworkspace?: WorkspaceOptions;\n\t/**\n\t * How many calls to the model one run of each role may make: one number for every role, or a\n\t * number per role. Defaults to 80 for the executor and 65 for the planner and the reviewer,\n\t * with no upper bound. A run that asks for exactly the same tool calls 5 times in a row fails\n\t * before its limit.\n\t */\n\tmaxSteps?: number | RoleSteps;\n\t/**\n\t * The tokens of context at which each role's provider compacts it, as\n\t * `CreateLLMAgentOptions.compactAt`: one number for every role, or a number per role. A role\n\t * left out compacts at its model's threshold, as do the explorers. `false` turns compaction\n\t * off for every role.\n\t */\n\tcompactAt?: number | false | RoleTokens;\n\t/** Who compacts every agent's context, as `CreateLLMAgentOptions.compaction`. */\n\tcompaction?: CompactionMode;\n\t/**\n\t * Commands the roles may run, such as the project's tests, through `runCommand`. Each goes to\n\t * the roles its `roles` names, the executor by default. See `createFileTools`. Each needs a\n\t * `write` root to run in.\n\t */\n\tcommands?: Commands;\n\t/**\n\t * A program the executor's edits run on each file they create or change, such as the\n\t * project's formatter. See `createFileTools`. It needs a `write` root to run in.\n\t */\n\tformatter?: Formatter;\n\t/**\n\t * A summary of what the user undid, from the planner's provider's cheap model, for every\n\t * role. See `CreateLLMAgentOptions.summarizeUndone`. Defaults to `true`.\n\t */\n\tsummarizeUndone?: boolean;\n\t/**\n\t * Receives what the model saw in each run of each role and each explorer, once the run\n\t * ended, for debugging. Each transcript names its role. See `Transcript`.\n\t */\n\tonTranscript?: TranscriptCallback;\n\t/**\n\t * Gives the executor `removeWorktree`, which removes a worktree of the repository the first\n\t * root is in when the user asks. See `createFileTools`.\n\t */\n\tremoveWorktree?: boolean;\n\t/**\n\t * The consumer's agents, from `agentAsTool`, that each role may hand a task to, beside its own\n\t * tools: the planner and the reviewer keep their explorers. An agent never writes more than\n\t * the role that calls it, so only the executor's may write, within the `write` roots.\n\t */\n\tagents?: RoleAgents;\n}\n\nconst defaultLLMAgentModels = {\n\tanthropic: 'sonnet',\n\topenai: 'gpt-5.6-luna',\n} as const satisfies Record<AgentProvider, AgentModel>;\n\n// The tokens of context at which each model compacts by default, the small ones sooner. The\n// margins are wide on purpose: compacting at 64k cleared file reads the executor then read again.\nconst compactionThresholds: Record<ClaudeLLMModel | OpenAIModel, number> = {\n\topus: 450_000,\n\tfable: 450_000,\n\tsonnet: 450_000,\n\thaiku: 125_000,\n\t'gpt-6-astra': 450_000,\n\t'gpt-5.6-sol': 450_000,\n\t'gpt-5.6-terra': 450_000,\n\t'gpt-5.6-luna': 125_000,\n};\n\n/**\n * The compactor `mode` names for an agent on `model`: at `compactAt`, at the model's threshold\n * without it, or off with `false`, when only a context that no longer fits is compacted.\n *\n * @throws {InvalidAgentConfigError} for a mode that does not exist, from untyped input.\n */\nfunction compactorFor(\n\tmodel: AgentModel,\n\tcompactAt: number | false | undefined,\n\tmode: CompactionMode = 'provider',\n): Compactor {\n\t// Checked whatever it is, as untyped input can hold anything here.\n\tif (typeof mode !== 'string' || !isOneOf(compactionModes, mode)) {\n\t\tthrow new InvalidAgentConfigError(\n\t\t\t`compaction must be one of: ${compactionModes.join(', ')}; got ${String(mode)}`,\n\t\t);\n\t}\n\t// A model with no threshold was already refused by its client.\n\tconst at =\n\t\tcompactAt === false\n\t\t\t? undefined\n\t\t\t: (compactAt ?? (compactionThresholds as Partial<Record<string, number>>)[model]);\n\tswitch (mode) {\n\t\tcase 'provider':\n\t\t\treturn { by: 'provider', at };\n\t\tcase 'recent':\n\t\t\treturn { by: 'harness', at, keptSteps: recentKeptSteps };\n\t\tcase 'jev':\n\t\t\treturn { by: 'harness', at, keptSteps: recentKeptSteps, triage: new JevContextTriage() };\n\t}\n}\n\nfunction defaultModelOf(provider: AgentProvider): AgentModel {\n\tswitch (provider) {\n\t\tcase 'anthropic':\n\t\tcase 'openai':\n\t\t\treturn defaultLLMAgentModels[provider];\n\t\tdefault:\n\t\t\t// Reachable from untyped input.\n\t\t\tthrow unknownProvider(provider);\n\t}\n}\n\nfunction unknownProvider(provider: never): InvalidAgentConfigError {\n\treturn new InvalidAgentConfigError(\n\t\t`\"${String(provider)}\" is not an agent provider; expected one of: ${agentProviders.join(', ')}`,\n\t);\n}\n\nfunction llmClientFor(\n\tprovider: AgentProvider,\n\t{\n\t\tmodel,\n\t\treasoningEffort,\n\t\tsystemPrompt,\n\t\tlogger,\n\t}: {\n\t\tmodel: AgentModel;\n\t\treasoningEffort?: ReasoningEffort;\n\t\tsystemPrompt: string;\n\t\tlogger: ILogger;\n\t},\n): LLMClient {\n\tswitch (provider) {\n\t\tcase 'anthropic':\n\t\t\treturn new ClaudeLLMClient({\n\t\t\t\tmodel,\n\t\t\t\treasoningEffort,\n\t\t\t\tsystemPrompt,\n\t\t\t\tlogger,\n\t\t\t});\n\t\tcase 'openai':\n\t\t\treturn new OpenAILLMClient({\n\t\t\t\tmodel,\n\t\t\t\treasoningEffort,\n\t\t\t\tsystemPrompt,\n\t\t\t\tlogger,\n\t\t\t});\n\t\tdefault:\n\t\t\t// Reachable from untyped input.\n\t\t\tthrow unknownProvider(provider);\n\t}\n}\n\n/** The provider's cheap model, for the summary of what was undone. */\nfunction summarizerFor(provider: AgentProvider, logger: ILogger): LLMClient {\n\treturn provider === 'anthropic'\n\t\t? new ClaudeLLMClient({ model: 'haiku', reasoningEffort: 'high', systemPrompt: '', logger })\n\t\t: new OpenAILLMClient({\n\t\t\t\tmodel: 'gpt-5.6-luna',\n\t\t\t\treasoningEffort: 'high',\n\t\t\t\tsystemPrompt: '',\n\t\t\t\tlogger,\n\t\t\t});\n}\n\n/**\n * The workspace's history, opened on first use, so a factory that builds an agent stays\n * synchronous. Every agent and every file tool of one workspace reads the same files on disk.\n */\nfunction historyOf(workspace: WorkspaceOptions, logger: ILogger): HistoryReader {\n\t// Checked now: an agent with no root to follow is a setup error, not a first-run one.\n\tif (workspace.roots.length === 0) {\n\t\tthrow new InvalidAgentConfigError('A workspace needs at least one root');\n\t}\n\tlet store: Promise<RecoveryStore> | undefined;\n\tconst open = () => {\n\t\tstore ??= stateDirectoryOf(workspace)\n\t\t\t.then(directory => openStore(workspace, directory, logger))\n\t\t\t.catch((error: unknown) => {\n\t\t\t\t// Not kept: the next run tries again, as one whose disk was full for a moment.\n\t\t\t\tstore = undefined;\n\t\t\t\tthrow error;\n\t\t\t});\n\t\treturn store;\n\t};\n\treturn {\n\t\tlistRuns: async () => (await open()).listRuns(),\n\t\tlistRevisions: async () => (await open()).listRevisions(),\n\t\treadRun: async runId => (await open()).readRun(runId),\n\t};\n}\n\n/**\n * What the model is told about the workspace after its instructions: the roots, which it may\n * change, and how to name a file. A host path in an error sends the model looking for it, so\n * the real root is given here once.\n */\nfunction workspaceGuidance(roots: WorkspaceRoot[]): string {\n\tconst [first, ...others] = roots.map(root => ({ ...root, path: resolve(root.path) }));\n\tif (!first) return '';\n\tconst described = [first, ...others].map(\n\t\t({ path, access }) => `- ${path}${access === 'write' ? '' : ' (read only)'}`,\n\t);\n\treturn [\n\t\t'The workspace:',\n\t\t...described,\n\t\t`Name a file by its path relative to ${first.path}, such as src/index.ts, and a file in another folder of the workspace by its full path. Read a file before you change it.`,\n\t].join('\\n');\n}\n\nfunction withGuidance(systemPrompt: string, guidance: string): string {\n\treturn guidance === '' ? systemPrompt : `${systemPrompt}\\n\\n${guidance}`;\n}\n\n/** An `LLMAgent` on `provider`, wrapped in the harness's retry policy. */\nfunction buildLLMAgent(\n\tprovider: AgentProvider,\n\t{\n\t\tmodel,\n\t\treasoningEffort,\n\t\tsystemPrompt,\n\t\ttools,\n\t\thistory,\n\t\tsummarizer,\n\t\tmaxSteps,\n\t\tcompactAt,\n\t\tcompaction,\n\t\tautoApprove,\n\t\tlogger,\n\t\tonTranscript,\n\t\twriteRoots,\n\t}: {\n\t\tmodel?: AgentModel;\n\t\treasoningEffort?: ReasoningEffort;\n\t\tsystemPrompt: string;\n\t\ttools: AgentTool[];\n\t\thistory?: HistoryReader;\n\t\tsummarizer?: LLMClient;\n\t\tmaxSteps?: number;\n\t\t/** See `CreateLLMAgentOptions.compactAt`. */\n\t\tcompactAt?: number | false | undefined;\n\t\tcompaction?: CompactionMode | undefined;\n\t\tautoApprove?: boolean;\n\t\tlogger: ILogger;\n\t\tonTranscript?: TranscriptCallback | undefined;\n\t\t/** See `LLMAgent`: where an agent it delegates to may write. */\n\t\twriteRoots?: readonly string[];\n\t},\n): Agent {\n\tconst chosen = model ?? defaultModelOf(provider);\n\tconst llmClient = llmClientFor(provider, {\n\t\tmodel: chosen,\n\t\treasoningEffort,\n\t\tsystemPrompt,\n\t\tlogger,\n\t});\n\t// LLMAgent records nothing from a failed call, so the original prompt is the whole story.\n\treturn new RetryingAgent({\n\t\tinner: new LLMAgent({\n\t\t\tllmClient,\n\t\t\ttools,\n\t\t\tautoApprove,\n\t\t\tlogger,\n\t\t\t...(history ? { history } : {}),\n\t\t\t...(summarizer ? { summarizer } : {}),\n\t\t\t...(maxSteps === undefined ? {} : { maxSteps }),\n\t\t\t...(onTranscript ? { onTranscript } : {}),\n\t\t\t...(writeRoots ? { writeRoots } : {}),\n\t\t\tcompactor: compactorFor(chosen, compactAt, compaction),\n\t\t}),\n\t\tlogger,\n\t\tnoteFailures: false,\n\t});\n}\n\n/**\n * Builds an agent whose conversation MiKode owns, on a provider's model API, already wrapped in\n * the harness's retry policy. It needs the provider's API key and bills per token, where\n * `createAgent` uses the Agent SDK's login. Each tool judges the risk of each call; a\n * `destructive` one runs only when the run's `approve` allows it, or with `autoApprove`.\n *\n * @throws {InvalidAgentConfigError} for an unknown provider, a model or reasoning effort its\n * client does not support, two tools that share a name, or a workspace given with no tools.\n * @throws {UnrecoverableError} when the client cannot be set up, for example because\n * `OPENAI_API_KEY` is missing. The Anthropic SDK resolves credentials lazily, so a missing\n * `ANTHROPIC_API_KEY` fails the first run instead, with an `UnrecoverableError`.\n */\nexport function createLLMAgent(\n\tprovider: AgentProvider,\n\t{\n\t\tmodel,\n\t\treasoningEffort,\n\t\tsystemPrompt,\n\t\ttools = [],\n\t\tworkspace,\n\t\tsummarizeUndone = true,\n\t\tmaxSteps,\n\t\tcompactAt,\n\t\tcompaction,\n\t\tautoApprove,\n\t\tlogger = new Logger(),\n\t\tonTranscript,\n\t}: CreateLLMAgentOptions,\n): Agent {\n\t// Told where to work with nothing to work with, the model would only pretend: it writes its\n\t// tool calls as text, and the run returns them as its answer.\n\tif (workspace && tools.length === 0) {\n\t\tthrow new InvalidAgentConfigError(\n\t\t\t'An agent given a workspace needs tools to work on it: pass those of createFileTools in `tools`',\n\t\t);\n\t}\n\treturn buildLLMAgent(provider, {\n\t\tmodel,\n\t\treasoningEffort,\n\t\tsystemPrompt: workspace\n\t\t\t? withGuidance(systemPrompt, workspaceGuidance(workspace.roots))\n\t\t\t: systemPrompt,\n\t\t// A file tool or a delegation tool is a harness tool under its public name.\n\t\ttools: tools as AgentTool[],\n\t\t...(workspace ? { history: historyOf(workspace, logger) } : {}),\n\t\t...(workspace && summarizeUndone ? { summarizer: summarizerFor(provider, logger) } : {}),\n\t\tmaxSteps,\n\t\tcompactAt,\n\t\tcompaction,\n\t\tautoApprove,\n\t\tlogger,\n\t\tonTranscript,\n\t\t// An agent it delegates to writes only where its workspace lets it.\n\t\t...(workspace ? { writeRoots: writeRootsOf(workspace.roots) } : {}),\n\t});\n}\n\nfunction writeRootsOf(roots: readonly WorkspaceRoot[]): string[] {\n\treturn roots.filter(({ access }) => access === 'write').map(({ path }) => path);\n}\n\n/**\n * The file tools for an agent from `createLLMAgent` on `provider`, over `workspace`, in the\n * provider's own format:\n *\n * - OpenAI: `listFiles`, `searchText`, `readFile`, `readFiles` and its native `apply_patch`;\n * - Anthropic: `listFiles`, `searchText`, its native text editor, whose `view` reads, and\n * `delete_file`.\n *\n * Every one goes through the workspace's access policy: a path outside the roots, a secret,\n * a file `.gitignore` excludes or the harness protects is refused. A change is made only in a\n * `write` root, only from a version the agent read, and is recorded in the workspace's history,\n * so it can be undone. Without a `write` root the tools only read. Give the agent the same\n * `workspace`, so it follows what the history undoes.\n *\n * With `commands`, they include `runCommand`, which runs one of them by name, with only the\n * parameters it declares and never through a shell. Each run asks the approver, showing the\n * program exactly as it will run, and gets a small environment without the provider keys. The\n * files of the `write` roots are captured before it and compared after, so what it changed is\n * in the history too. It is trusted execution, not a sandbox: a command can reach whatever\n * this user can. Not supported on Windows yet.\n *\n * With `formatter`, every file an edit creates or changes is formatted right after, its path\n * the formatter's last argument. The edit shows the lines the formatter rewrote, and the model\n * reads a file it rewrote again before editing it. Like a command it runs without a shell, in a small environment, and what it changes in that file is\n * in the history. When it fails, the file stays as the edit wrote it, and the model is told\n * why. Not supported on Windows yet.\n *\n * With `removeWorktree`, they include `removeWorktree`, which removes a git worktree of the\n * repository the first root is in, when the user asks: its folder and every file in it, never\n * its branch. Each call asks the approver, whose request's `worktree` says what is lost:\n * changes no commit has, and the commits only a detached HEAD holds. It refuses the main folder\n * and a worktree the agent works in. See `createWorktree`.\n *\n * @throws {InvalidAgentConfigError} for an unknown provider, a workspace with no root, or an\n * invalid command or formatter, including one whose `cwd` is not in a `write` root, or any on\n * Windows, or `removeWorktree` with a first root in no git repository.\n * @throws {UnrecoverableError} when no program can read the first root.\n */\nexport async function createFileTools(\n\tprovider: AgentProvider,\n\tworkspace: WorkspaceOptions,\n\t{\n\t\tlogger = new Logger(),\n\t\tcommands,\n\t\tformatter,\n\t\tremoveWorktree = false,\n\t}: {\n\t\tlogger?: ILogger;\n\t\tcommands?: Commands;\n\t\tformatter?: Formatter;\n\t\tremoveWorktree?: boolean;\n\t} = {},\n): Promise<FileTool[]> {\n\t// Reachable from untyped input.\n\tif (!isAgentProvider(provider)) throw unknownProvider(provider);\n\tif (commands !== undefined) validateCommands(commands);\n\tif (formatter !== undefined) validateFormatter(formatter);\n\tconst opened = await openWorkspace(workspace, logger, formatter ? { formatter } : {});\n\treturn (await executorTools(provider, opened, commands, removeWorktree)) as unknown as FileTool[];\n}\n\n/** The executor's file tools, `runCommand` when there are commands, and `removeWorktree`. */\nasync function executorTools(\n\tprovider: AgentProvider,\n\tworkspace: OpenedWorkspace,\n\tcommands: Commands | undefined,\n\tremoveWorktree: boolean,\n): Promise<AgentTool[]> {\n\tconst tools = fileToolsFor(provider, workspace);\n\tif (removeWorktree) tools.push(await removeWorktreeToolFor(workspace));\n\t// Every command may belong to other roles, leaving none for this one.\n\tif (commands === undefined || Object.keys(commands).length === 0) return tools;\n\treturn [...tools, await commandToolFor(workspace, commands)];\n}\n\n/** `removeWorktree` over the repository of the first root, which must be in one. */\nasync function removeWorktreeToolFor({\n\tbase,\n\troots,\n\tstateDirectory,\n}: OpenedWorkspace): Promise<AgentTool> {\n\t// Checked now: a tool that could never work is a setup error, not a first-call one.\n\tawait listWorktrees(base).catch((error: unknown) => {\n\t\tthrow new InvalidAgentConfigError(\n\t\t\t`removeWorktree needs a first root in a git repository, and git 2.36 or later; with ${base}, ${error instanceof Error ? error.message : String(error)}`,\n\t\t);\n\t});\n\treturn createRemoveWorktreeTool({ base, roots, stateDirectory });\n}\n\n/**\n * Each role's agents from `agentAsTool`, as the harness's tools.\n *\n * @throws {InvalidAgentConfigError} for a role that does not exist, or a role's agents that are\n * not a list.\n */\nfunction roleAgents(agents: unknown): Record<OrchestratorRole, AgentTool[]> {\n\t// Untyped input, such as the CLI's configuration file, can hold anything here.\n\tif (typeof agents !== 'object' || agents === null || Array.isArray(agents)) {\n\t\tthrow new InvalidAgentConfigError(\n\t\t\t'agents must be an object of agentAsTool tools per role, such as { executor: [committer] }',\n\t\t);\n\t}\n\tconst byRole: Record<OrchestratorRole, AgentTool[]> = { planner: [], executor: [], reviewer: [] };\n\tfor (const [role, tools] of Object.entries(agents)) {\n\t\tif (!Object.hasOwn(byRole, role)) {\n\t\t\tthrow new InvalidAgentConfigError(\n\t\t\t\t`agents names \"${role}\", which is not a role; expected one of: ${Object.keys(byRole).join(', ')}`,\n\t\t\t);\n\t\t}\n\t\tif (tools === undefined) continue;\n\t\tif (!Array.isArray(tools)) {\n\t\t\tthrow new InvalidAgentConfigError(`agents.${role} must be a list of agentAsTool tools`);\n\t\t}\n\t\t// A delegation tool is a harness tool under its public name.\n\t\tbyRole[role as OrchestratorRole] = tools as AgentTool[];\n\t}\n\treturn byRole;\n}\n\n/** What an explorer finds and reads with: no edits, no changes, no commands. */\nfunction explorerTools({ read, policy }: OpenedWorkspace): AgentTool[] {\n\tconst finding = createWorkspaceTools(read).filter(\n\t\ttool => tool.name !== 'readFile' && tool.name !== 'readFiles',\n\t);\n\treturn [...finding, createTrackedReadFile(policy), createTrackedReadFiles(policy)];\n}\n\n/**\n * What the planner and the reviewer read with: no edits, the current task's changes, `explore`\n * with `explorer`, and the commands given to their role.\n */\nasync function readingTools(\n\tworkspace: OpenedWorkspace,\n\trole: CommandRole,\n\tcommands: Commands | undefined,\n\texplorer: () => Agent,\n): Promise<AgentTool[]> {\n\tconst { policy, store } = workspace;\n\tconst tools = [\n\t\t...explorerTools(workspace),\n\t\tcreateShowChangesTool({ store, policy }),\n\t\tcreateExploreTool(explorer),\n\t];\n\tconst own = commands && commandsFor(commands, role);\n\tif (!own || Object.keys(own).length === 0) return tools;\n\treturn [...tools, await commandToolFor(workspace, own)];\n}\n\nconst batching =\n\t'When you know you need several files, or several searches, ask for all of them in one answer rather than one at a time: each answer is a step, and steps are limited.';\n\n// For the roles that have `readFiles`, which the executor on Claude does not.\nconst batchingReads =\n\t'When you know you need several files, or several ranges, read them in one readFiles call, and ask for several searches in one answer, rather than one at a time: each answer is a step, and steps are limited.';\n\n// The explorers find and the role reads, as a reader asks a librarian where a book is and then\n// reads it: their reports are where to look, not a summary to work from.\nconst exploring =\n\t'To find where something is in the repository, ask explorers instead of searching yourself: send `explore` the independent questions you have in one call. They work in the background while you go on, and each one answers, once it finishes, with the files and line ranges that hold what you asked. Then read those ranges yourself, all of them in one readFiles call.';\n\n// Each provider's cheaper model, which only finds and reads.\nconst explorerRoles = {\n\tanthropic: { model: 'haiku', reasoningEffort: 'medium' },\n\topenai: { model: 'gpt-5.6-luna', reasoningEffort: 'medium' },\n} as const satisfies Record<AgentProvider, { model: AgentModel; reasoningEffort: ReasoningEffort }>;\n\nconst explorerSteps = 30;\n\nconst explorerInstructions = `You find things in a repository for another agent, which is planning or reviewing a change and asked you one question, as a reader asks a librarian where a book is. Find where the answer is with listFiles, searchText, readFile and readFiles, reading only what you need to be sure. Answer with where it is: each file and the line ranges that matter, and in a sentence what each range holds and why it answers the question. The other agent reads those ranges itself, so do not copy code beyond a line that marks a place. Say what you looked for and could not find. Do not propose changes or a plan. ${batchingReads}`;\n\n// How each role finds its way, sent after the workspace's roots, so it stays short. Only the\n// planner learns the repository; the executor and the reviewer work from its plan, so a plan\n// that leaves them guessing is the planner's to fix, not theirs to make up for.\nconst repositoryGuidance: Record<CommandRole, string> = {\n\tplanner: `Start with AGENTS.md, which says where the architecture and the decisions are, and read only the parts your task needs. Name in the plan every file to change and what to change in it, so the executor needs nothing else. ${exploring} ${batchingReads}`,\n\texecutor: `Work from the plan: read the files it names, and only what you need to change them. Do not study the repository's architecture or decisions; the plan already applied them. ${batching}`,\n\treviewer: `Work from the plan and the changes: read what they touch, and only what you need to judge them. ${exploring} ${batchingReads}`,\n};\n\n/**\n * Builds the planner → executor → reviewer workflow with every role on the model APIs, each\n * holding its role's instructions, or `systemPrompts`, as its system prompt, followed by the\n * workspace's roots.\n *\n * - The planner and the reviewer read: `listFiles`, `searchText`, `readFile`, `readFiles`, `showChanges`,\n * the current task's changes as far as each may read them, and `explore`, which sends up to 4\n * read-only explorers at once on the role's provider's cheaper model, each a new agent that\n * starts from its question and works in the background while the role goes on.\n * - The executor gets its provider's file tools (see `createFileTools`), and changes files only\n * in a `write` root; `autoApprove` reaches only it.\n * - Each role has its own step limit: `maxSteps`, 80 for the executor and 65 for the others by\n * default.\n * - Each role gets `runCommand` with the `commands` whose `roles` name it, the executor by\n * default. A command asks the approver in any role, and its files are captured around it.\n * - When the executor has a command, it is told to finish only once the tests and checks pass,\n * or to say which fail, and the reviewer takes from its response whether they pass. Without\n * one, both are told the tests were not run, and the reviewer judges from the code whether\n * they would pass.\n *\n * One run of the orchestrator is one run of the workspace's history, every round and retry\n * included, and its `AgentResponse` names it. Every role follows what the user undoes.\n * Asynchronous because opening the workspace is.\n *\n * @throws {InvalidAgentConfigError} for an unknown provider, or a workspace with no root.\n * @throws {UnrecoverableError} when a role cannot be set up, for example because\n * `OPENAI_API_KEY` is missing, or when no program can read the repository.\n */\nexport async function createLLMOrchestrator({\n\tprovider,\n\tautoApprove,\n\tsystemPrompts = {},\n\tworkspace = { roots: [{ path: process.cwd(), access: 'read' }] },\n\tmaxSteps,\n\tcompactAt,\n\tcompaction: compactionMode,\n\tcommands,\n\tformatter,\n\tsummarizeUndone = true,\n\tlogger = new Logger(),\n\tonTranscript,\n\tremoveWorktree = false,\n\tagents = {},\n}: CreateLLMOrchestratorOptions = {}): Promise<Agent> {\n\tconst roles = orchestratorRolesFor(provider);\n\tconst agentsOf = roleAgents(agents);\n\tconst steps = perRole('maxSteps', maxSteps, defaultRoleSteps, {\n\t\tunit: 'steps',\n\t\texample: '{ \"executor\": 120 }',\n\t});\n\tconst compaction: Record<OrchestratorRole, number | false | undefined> =\n\t\tcompactAt === false\n\t\t\t? { planner: false, executor: false, reviewer: false }\n\t\t\t: perRole('compactAt', compactAt, defaultRoleCompaction, {\n\t\t\t\t\tunit: 'tokens',\n\t\t\t\t\texample: '{ \"executor\": 200000 }',\n\t\t\t\t});\n\tif (formatter !== undefined) validateFormatter(formatter);\n\tconst opened = await openWorkspace(workspace, logger, formatter ? { formatter } : {});\n\tconst guidance = workspaceGuidance(workspace.roots);\n\tconst summarizer = summarizeUndone ? summarizerFor(roles.planner.provider, logger) : undefined;\n\tconst shared = {\n\t\thistory: opened.store,\n\t\t...(summarizer ? { summarizer } : {}),\n\t\tcompaction: compactionMode,\n\t\tlogger,\n\t};\n\t// A caller's own prompt replaces our instructions and guidance, not the workspace: the model\n\t// needs the roots to name a file, as `createLLMAgent` gives them.\n\tconst prompt = (role: CommandRole, own: string | undefined, instructions: string) =>\n\t\town === undefined\n\t\t\t? withGuidance(instructions, `${guidance}\\n${repositoryGuidance[role]}`)\n\t\t\t: withGuidance(own, guidance);\n\t// Each transcript names the agent it is of.\n\tconst transcriptsOf = (agent: Transcript['agent']) =>\n\t\tonTranscript && ((transcript: Transcript) => onTranscript({ ...transcript, agent }));\n\t// Every command, checked once, before any role takes its share.\n\tif (commands !== undefined) validateCommands(commands);\n\t// A new explorer for each question, on the role's provider: it starts from the question alone.\n\tconst explorerToolset = explorerTools(opened);\n\tconst explorer = (provider: AgentProvider) => () =>\n\t\tbuildLLMAgent(provider, {\n\t\t\t...explorerRoles[provider],\n\t\t\tsystemPrompt: withGuidance(explorerInstructions, guidance),\n\t\t\ttools: explorerToolset,\n\t\t\tmaxSteps: explorerSteps,\n\t\t\tcompaction: compactionMode,\n\t\t\tlogger,\n\t\t\tonTranscript: transcriptsOf('explorer'),\n\t\t});\n\tconst reader = async (\n\t\t{ provider, model, reasoningEffort }: Role,\n\t\trole: CommandRole,\n\t\tsystemPrompt: string,\n\t) =>\n\t\tbuildLLMAgent(provider, {\n\t\t\tmodel,\n\t\t\treasoningEffort,\n\t\t\tsystemPrompt,\n\t\t\ttools: [\n\t\t\t\t...(await readingTools(opened, role, commands, explorer(provider))),\n\t\t\t\t...agentsOf[role],\n\t\t\t],\n\t\t\tmaxSteps: steps[role],\n\t\t\tcompactAt: compaction[role],\n\t\t\tonTranscript: transcriptsOf(role),\n\t\t\t// It only reads, so the agents it calls only read too.\n\t\t\twriteRoots: [],\n\t\t\t...shared,\n\t\t});\n\tconst { executor } = roles;\n\tconst executorToolset = await executorTools(\n\t\texecutor.provider,\n\t\topened,\n\t\tcommands && commandsFor(commands, 'executor'),\n\t\tremoveWorktree,\n\t);\n\t// The executor and the reviewer are told whether the tests were run, which only an executor\n\t// with a command can do.\n\tconst executorRuns = executorToolset.some(tool => tool.name === 'runCommand');\n\n\treturn new OrchestratorAgent({\n\t\tplannerAgent: await reader(\n\t\t\troles.planner,\n\t\t\t'planner',\n\t\t\tprompt('planner', systemPrompts.planner, plannerInstructions),\n\t\t),\n\t\texecutorAgent: buildLLMAgent(executor.provider, {\n\t\t\tmodel: executor.model,\n\t\t\treasoningEffort: executor.reasoningEffort,\n\t\t\tsystemPrompt: prompt(\n\t\t\t\t'executor',\n\t\t\t\tsystemPrompts.executor,\n\t\t\t\texecutorRuns ? executorInstructions : executorInstructionsWithoutCommands,\n\t\t\t),\n\t\t\ttools: [...executorToolset, ...agentsOf.executor],\n\t\t\tmaxSteps: steps.executor,\n\t\t\tcompactAt: compaction.executor,\n\t\t\tautoApprove,\n\t\t\tonTranscript: transcriptsOf('executor'),\n\t\t\twriteRoots: writeRootsOf(workspace.roots),\n\t\t\t...shared,\n\t\t}),\n\t\treviewerAgent: await reader(\n\t\t\troles.reviewer,\n\t\t\t'reviewer',\n\t\t\tprompt(\n\t\t\t\t'reviewer',\n\t\t\t\tsystemPrompts.reviewer,\n\t\t\t\texecutorRuns ? reviewerInstructions : reviewerInstructionsWithoutCommands,\n\t\t\t),\n\t\t),\n\t\treviewerDecisionValidator: new ReviewerDecisionValidator(),\n\t\tlogger,\n\t});\n}\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export type { ILogger } from './shared/domain/logger.ts';
|
|
2
2
|
export { createAgent, createOrchestrator, agentModels, agentReasoningEfforts, isAgentProvider, isModelOf, isReasoningEffortOf, type CreateAgentOptions, } from './factory/infrastructure/agentFactory.ts';
|
|
3
|
-
export { createFileTools, createLLMAgent, createLLMOrchestrator, isLLMModelOf, isLLMReasoningEffortOf, llmModels, llmReasoningEfforts, type CreateLLMAgentOptions, type CreateLLMOrchestratorOptions, type RoleSteps, type RoleTokens, } from './factory/infrastructure/agentLLMFactory.ts';
|
|
3
|
+
export { createFileTools, createLLMAgent, createLLMOrchestrator, isLLMModelOf, isLLMReasoningEffortOf, llmModels, llmReasoningEfforts, type CreateLLMAgentOptions, type CreateLLMOrchestratorOptions, type RoleSteps, type RoleTokens, type RoleAgents, type CompactionMode, } from './factory/infrastructure/agentLLMFactory.ts';
|
|
4
4
|
export type { FileTool, WorkspaceOptions } from './tools/infrastructure/fileTools.ts';
|
|
5
5
|
export { agentAsTool, type AgentAsToolOptions, type DelegationTool, } from './tools/infrastructure/agentAsTool.ts';
|
|
6
6
|
export type { WorkspaceRoot } from './tools/domain/accessPolicy.ts';
|
|
@@ -9,10 +9,13 @@ export type { SecretRules } from './tools/infrastructure/rootsAccessPolicy.ts';
|
|
|
9
9
|
export { agentProviders, type AgentModel, type AgentProvider, type CreateOrchestratorOptions, type ReasoningEffort, } from './factory/infrastructure/types.ts';
|
|
10
10
|
export { type Agent, type AgentResponse, type Callback, type ProgressAgent, type ProgressEvent, type StepContext, type RunOptions, } from './agent/domain/agent.ts';
|
|
11
11
|
export type { Transcript, TranscriptCallback } from './agent/domain/transcript.ts';
|
|
12
|
+
export { Inbox } from './agent/domain/inbox.ts';
|
|
13
|
+
export { RunInProgressError } from './agent/domain/oneRunAtATime.ts';
|
|
12
14
|
export { InvalidAgentConfigError, RecoverableError, UnrecoverableError, } from './shared/domain/errors.ts';
|
|
13
15
|
export { isAbortError } from './shared/domain/isAbortError.ts';
|
|
16
|
+
export type { Session } from './shared/domain/session.ts';
|
|
14
17
|
export type { Tokens } from './shared/domain/tokens.ts';
|
|
15
|
-
export { rememberApprovals, type ApprovalDecision, type ApprovalRequest, type Approver, type CommandLine, type RememberableDecision, type ToolRisk, } from './agent/domain/approval.ts';
|
|
18
|
+
export { rememberApprovals, type ApprovalDecision, type ApprovalRequest, type Approver, type CommandLine, type RememberableDecision, type ToolRisk, type WorktreeRemoval, } from './agent/domain/approval.ts';
|
|
16
19
|
export type { Asker, QuestionOption, UserQuestion } from './agent/domain/question.ts';
|
|
17
20
|
export type { JSONSchema, ToolDefinition } from './llm/domain/tool.ts';
|
|
18
21
|
export type { Tool, ToolSummarizer } from './tools/domain/tool.ts';
|
|
@@ -21,6 +24,7 @@ export { defineTool } from './tools/infrastructure/defineTool.ts';
|
|
|
21
24
|
export { createWorkspace } from './tools/infrastructure/createWorkspace.ts';
|
|
22
25
|
export { createWorkspaceTools } from './tools/infrastructure/workspaceTools.ts';
|
|
23
26
|
export { createHistory } from './recovery/infrastructure/createHistory.ts';
|
|
27
|
+
export { createWorktree } from './tools/infrastructure/worktrees.ts';
|
|
24
28
|
export type { History, HistoryRun, Move } from './recovery/domain/history.ts';
|
|
25
29
|
export { historyStart, NothingToMoveError, WorkspaceBusyError, WorkspaceMovedError, type MoveOptions, type RunStatus, } from './recovery/domain/recoveryStore.ts';
|
|
26
30
|
export { HistoryExpiredError, UnknownRunError } from './recovery/domain/runTree.ts';
|
package/dist/index.js
CHANGED
|
@@ -3,6 +3,8 @@ export { createFileTools, createLLMAgent, createLLMOrchestrator, isLLMModelOf, i
|
|
|
3
3
|
export { agentAsTool, } from "./tools/infrastructure/agentAsTool.js";
|
|
4
4
|
export { agentProviders, } from "./factory/infrastructure/types.js";
|
|
5
5
|
export {} from "./agent/domain/agent.js";
|
|
6
|
+
export { Inbox } from "./agent/domain/inbox.js";
|
|
7
|
+
export { RunInProgressError } from "./agent/domain/oneRunAtATime.js";
|
|
6
8
|
export { InvalidAgentConfigError, RecoverableError, UnrecoverableError, } from "./shared/domain/errors.js";
|
|
7
9
|
export { isAbortError } from "./shared/domain/isAbortError.js";
|
|
8
10
|
export { rememberApprovals, } from "./agent/domain/approval.js";
|
|
@@ -10,6 +12,7 @@ export { defineTool } from "./tools/infrastructure/defineTool.js";
|
|
|
10
12
|
export { createWorkspace } from "./tools/infrastructure/createWorkspace.js";
|
|
11
13
|
export { createWorkspaceTools } from "./tools/infrastructure/workspaceTools.js";
|
|
12
14
|
export { createHistory } from "./recovery/infrastructure/createHistory.js";
|
|
15
|
+
export { createWorktree } from "./tools/infrastructure/worktrees.js";
|
|
13
16
|
export { historyStart, NothingToMoveError, WorkspaceBusyError, WorkspaceMovedError, } from "./recovery/domain/recoveryStore.js";
|
|
14
17
|
export { HistoryExpiredError, UnknownRunError } from "./recovery/domain/runTree.js";
|
|
15
18
|
export { createWorkflow } from "./factory/infrastructure/workflowFactory.js";
|