@kimbho/kimbho-cli 0.1.26 → 0.1.30
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/dist/index.cjs +1135 -153
- package/dist/index.cjs.map +3 -3
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -12718,7 +12718,7 @@ function createCompletionRuntimeCommand(program2) {
|
|
|
12718
12718
|
// package.json
|
|
12719
12719
|
var package_default = {
|
|
12720
12720
|
name: "@kimbho/kimbho-cli",
|
|
12721
|
-
version: "0.1.
|
|
12721
|
+
version: "0.1.30",
|
|
12722
12722
|
description: "Kimbho CLI is a terminal-native coding agent for planning, execution, and verification.",
|
|
12723
12723
|
type: "module",
|
|
12724
12724
|
engines: {
|
|
@@ -13080,11 +13080,11 @@ var AGENT_CATALOG = {
|
|
|
13080
13080
|
"Design-system mismatch",
|
|
13081
13081
|
"Frontend contract drift"
|
|
13082
13082
|
],
|
|
13083
|
-
maxConcurrentTasks:
|
|
13083
|
+
maxConcurrentTasks: 3,
|
|
13084
13084
|
policy: {
|
|
13085
13085
|
sandboxMode: "workspace-write",
|
|
13086
13086
|
canSpawnSubagents: true,
|
|
13087
|
-
maxSubagentDepth:
|
|
13087
|
+
maxSubagentDepth: 2
|
|
13088
13088
|
}
|
|
13089
13089
|
},
|
|
13090
13090
|
"backend-specialist": {
|
|
@@ -13110,11 +13110,11 @@ var AGENT_CATALOG = {
|
|
|
13110
13110
|
"Schema drift",
|
|
13111
13111
|
"Unclear domain contract"
|
|
13112
13112
|
],
|
|
13113
|
-
maxConcurrentTasks:
|
|
13113
|
+
maxConcurrentTasks: 3,
|
|
13114
13114
|
policy: {
|
|
13115
13115
|
sandboxMode: "workspace-write",
|
|
13116
13116
|
canSpawnSubagents: true,
|
|
13117
|
-
maxSubagentDepth:
|
|
13117
|
+
maxSubagentDepth: 2
|
|
13118
13118
|
}
|
|
13119
13119
|
},
|
|
13120
13120
|
"database-specialist": {
|
|
@@ -13140,7 +13140,7 @@ var AGENT_CATALOG = {
|
|
|
13140
13140
|
"Data-destructive migration",
|
|
13141
13141
|
"Unclear persistence requirements"
|
|
13142
13142
|
],
|
|
13143
|
-
maxConcurrentTasks:
|
|
13143
|
+
maxConcurrentTasks: 2,
|
|
13144
13144
|
policy: {
|
|
13145
13145
|
sandboxMode: "workspace-write",
|
|
13146
13146
|
requireApprovalPatterns: [
|
|
@@ -13149,7 +13149,7 @@ var AGENT_CATALOG = {
|
|
|
13149
13149
|
"\\bdrop\\s+database\\b"
|
|
13150
13150
|
],
|
|
13151
13151
|
canSpawnSubagents: true,
|
|
13152
|
-
maxSubagentDepth:
|
|
13152
|
+
maxSubagentDepth: 2
|
|
13153
13153
|
}
|
|
13154
13154
|
},
|
|
13155
13155
|
"infra-specialist": {
|
|
@@ -13180,7 +13180,7 @@ var AGENT_CATALOG = {
|
|
|
13180
13180
|
"Dependency installation",
|
|
13181
13181
|
"External environment changes"
|
|
13182
13182
|
],
|
|
13183
|
-
maxConcurrentTasks:
|
|
13183
|
+
maxConcurrentTasks: 2,
|
|
13184
13184
|
policy: {
|
|
13185
13185
|
sandboxMode: "workspace-write",
|
|
13186
13186
|
requireApprovalPatterns: [
|
|
@@ -13192,7 +13192,7 @@ var AGENT_CATALOG = {
|
|
|
13192
13192
|
"\\bapt(-get)?\\s+install\\b"
|
|
13193
13193
|
],
|
|
13194
13194
|
canSpawnSubagents: true,
|
|
13195
|
-
maxSubagentDepth:
|
|
13195
|
+
maxSubagentDepth: 2
|
|
13196
13196
|
}
|
|
13197
13197
|
},
|
|
13198
13198
|
"test-debugger": {
|
|
@@ -17627,6 +17627,44 @@ var RepoStrategySchema = external_exports.object({
|
|
|
17627
17627
|
]),
|
|
17628
17628
|
reasoning: external_exports.string().min(1)
|
|
17629
17629
|
});
|
|
17630
|
+
var TaskExecutionPhaseSchema = external_exports.enum([
|
|
17631
|
+
"survey",
|
|
17632
|
+
"plan-edit",
|
|
17633
|
+
"implement",
|
|
17634
|
+
"verify",
|
|
17635
|
+
"repair",
|
|
17636
|
+
"finalize",
|
|
17637
|
+
"escalate"
|
|
17638
|
+
]);
|
|
17639
|
+
var TaskVerifierStateSchema = external_exports.object({
|
|
17640
|
+
availableCommands: external_exports.array(external_exports.string().min(1)).default([]),
|
|
17641
|
+
preferredCommands: external_exports.array(external_exports.string().min(1)).default([]),
|
|
17642
|
+
attemptedCommands: external_exports.array(external_exports.string().min(1)).default([]),
|
|
17643
|
+
disabledCommands: external_exports.array(external_exports.string().min(1)).default([]),
|
|
17644
|
+
successfulCommands: external_exports.array(external_exports.string().min(1)).default([]),
|
|
17645
|
+
currentCommand: external_exports.string().min(1).optional(),
|
|
17646
|
+
latestFailureSummary: external_exports.string().min(1).optional(),
|
|
17647
|
+
latestFailureCommand: external_exports.string().min(1).optional(),
|
|
17648
|
+
latestSuccessfulCommand: external_exports.string().min(1).optional(),
|
|
17649
|
+
requiresInteractiveSetup: external_exports.boolean().default(false)
|
|
17650
|
+
});
|
|
17651
|
+
var TaskWorldModelSchema = external_exports.object({
|
|
17652
|
+
phase: TaskExecutionPhaseSchema.default("survey"),
|
|
17653
|
+
targetFiles: external_exports.array(external_exports.string().min(1)).default([]),
|
|
17654
|
+
inspectedFiles: external_exports.array(external_exports.string().min(1)).default([]),
|
|
17655
|
+
changedFiles: external_exports.array(external_exports.string().min(1)).default([]),
|
|
17656
|
+
hypotheses: external_exports.array(external_exports.string().min(1)).default([]),
|
|
17657
|
+
blockers: external_exports.array(external_exports.string().min(1)).default([]),
|
|
17658
|
+
proofPending: external_exports.array(external_exports.string().min(1)).default([]),
|
|
17659
|
+
proofSatisfied: external_exports.array(external_exports.string().min(1)).default([]),
|
|
17660
|
+
recentActions: external_exports.array(external_exports.string().min(1)).default([]),
|
|
17661
|
+
recentCommands: external_exports.array(external_exports.string().min(1)).default([]),
|
|
17662
|
+
nextFocus: external_exports.string().min(1).optional(),
|
|
17663
|
+
sourceEditCount: external_exports.number().int().nonnegative().default(0),
|
|
17664
|
+
validationLoopCount: external_exports.number().int().nonnegative().default(0),
|
|
17665
|
+
verifier: TaskVerifierStateSchema.default({}),
|
|
17666
|
+
lastUpdatedAt: external_exports.string().datetime().optional()
|
|
17667
|
+
});
|
|
17630
17668
|
var PlanTaskSchema = external_exports.object({
|
|
17631
17669
|
id: external_exports.string().min(1),
|
|
17632
17670
|
title: external_exports.string().min(1),
|
|
@@ -17662,7 +17700,8 @@ var PlanTaskSchema = external_exports.object({
|
|
|
17662
17700
|
teamId: external_exports.string().min(1).optional(),
|
|
17663
17701
|
teamMemberIds: external_exports.array(external_exports.string()).optional(),
|
|
17664
17702
|
subagentLabel: external_exports.string().min(1).optional(),
|
|
17665
|
-
subagentInstructions: external_exports.string().min(1).optional()
|
|
17703
|
+
subagentInstructions: external_exports.string().min(1).optional(),
|
|
17704
|
+
executionState: TaskWorldModelSchema.optional()
|
|
17666
17705
|
});
|
|
17667
17706
|
var PlanMilestoneSchema = external_exports.object({
|
|
17668
17707
|
id: external_exports.string().min(1),
|
|
@@ -18150,6 +18189,103 @@ var LegacyKimbhoConfigSchema = external_exports.object({
|
|
|
18150
18189
|
"next-prisma-postgres"
|
|
18151
18190
|
])
|
|
18152
18191
|
});
|
|
18192
|
+
function uniqueModelIds(models) {
|
|
18193
|
+
return Array.from(new Set(models.map((model) => model?.trim()).filter((model) => Boolean(model))));
|
|
18194
|
+
}
|
|
18195
|
+
function providerCandidateModels(provider) {
|
|
18196
|
+
if (!provider) {
|
|
18197
|
+
return [];
|
|
18198
|
+
}
|
|
18199
|
+
return uniqueModelIds([
|
|
18200
|
+
provider.defaultModel,
|
|
18201
|
+
...provider.models
|
|
18202
|
+
]);
|
|
18203
|
+
}
|
|
18204
|
+
function estimateModelScale(model) {
|
|
18205
|
+
const matches = Array.from(model.matchAll(/(\d+(?:\.\d+)?)b/gi));
|
|
18206
|
+
if (matches.length === 0) {
|
|
18207
|
+
return 0;
|
|
18208
|
+
}
|
|
18209
|
+
return Math.max(...matches.map((match) => Number.parseFloat(match[1] ?? "0")).filter((value) => Number.isFinite(value)));
|
|
18210
|
+
}
|
|
18211
|
+
function scoreModelForRole(model, role) {
|
|
18212
|
+
const normalized = model.toLowerCase();
|
|
18213
|
+
const scale = estimateModelScale(normalized);
|
|
18214
|
+
let score = 0;
|
|
18215
|
+
if (/gpt-5(?!.*mini)(?!.*nano)/i.test(normalized) || /\bgpt5\b/i.test(normalized)) {
|
|
18216
|
+
score += 160;
|
|
18217
|
+
}
|
|
18218
|
+
if (/\bo3\b|\bo4\b|o4-mini-high/i.test(normalized)) {
|
|
18219
|
+
score += 145;
|
|
18220
|
+
}
|
|
18221
|
+
if (/opus|sonnet|claude-4|claude-3\.7/i.test(normalized)) {
|
|
18222
|
+
score += /opus|claude-4/i.test(normalized) ? 150 : 132;
|
|
18223
|
+
}
|
|
18224
|
+
if (/gpt-4\.1|gpt-4o|deepseek-r1|deepseek-v3|qwq/i.test(normalized)) {
|
|
18225
|
+
score += 122;
|
|
18226
|
+
}
|
|
18227
|
+
if (/qwen.*(?:32b|35b|72b|110b|235b)|llama.*(?:70b|90b|405b)|mixtral/i.test(normalized)) {
|
|
18228
|
+
score += 110;
|
|
18229
|
+
}
|
|
18230
|
+
if (/reason|thinking|r1|o[34]/i.test(normalized)) {
|
|
18231
|
+
score += 20;
|
|
18232
|
+
}
|
|
18233
|
+
if (scale > 0) {
|
|
18234
|
+
score += Math.min(scale, 120) * 0.8;
|
|
18235
|
+
}
|
|
18236
|
+
if (/mini|nano|flash|haiku|small|fast|instant|lite/i.test(normalized)) {
|
|
18237
|
+
score -= 55;
|
|
18238
|
+
}
|
|
18239
|
+
if (/\b(?:3|7|8|9|14)b\b/i.test(normalized)) {
|
|
18240
|
+
score -= 35;
|
|
18241
|
+
}
|
|
18242
|
+
if (/preview|experimental|beta/i.test(normalized)) {
|
|
18243
|
+
score -= 6;
|
|
18244
|
+
}
|
|
18245
|
+
if (role === "fast") {
|
|
18246
|
+
let fastBias = 0;
|
|
18247
|
+
if (/mini|nano|flash|haiku|small|fast|instant|lite/i.test(normalized)) {
|
|
18248
|
+
fastBias += 95;
|
|
18249
|
+
}
|
|
18250
|
+
if (/sonnet|gpt-4o-mini|gpt-5-mini|claude.*haiku/i.test(normalized)) {
|
|
18251
|
+
fastBias += 60;
|
|
18252
|
+
}
|
|
18253
|
+
if (scale >= 32) {
|
|
18254
|
+
fastBias -= 40;
|
|
18255
|
+
} else if (scale > 0 && scale <= 16) {
|
|
18256
|
+
fastBias += 24;
|
|
18257
|
+
}
|
|
18258
|
+
return fastBias + score * 0.2;
|
|
18259
|
+
}
|
|
18260
|
+
if (role === "reviewer") {
|
|
18261
|
+
if (/reason|thinking|r1|\bo3\b|\bo4\b|opus/i.test(normalized)) {
|
|
18262
|
+
score += 24;
|
|
18263
|
+
}
|
|
18264
|
+
if (/mini|flash|haiku/i.test(normalized)) {
|
|
18265
|
+
score -= 10;
|
|
18266
|
+
}
|
|
18267
|
+
}
|
|
18268
|
+
if (role === "planner") {
|
|
18269
|
+
if (/reason|thinking|r1|\bo3\b|\bo4\b|sonnet|opus/i.test(normalized)) {
|
|
18270
|
+
score += 18;
|
|
18271
|
+
}
|
|
18272
|
+
}
|
|
18273
|
+
if (role === "coder") {
|
|
18274
|
+
if (/sonnet|gpt-5|gpt-4\.1|deepseek|qwen|llama/i.test(normalized)) {
|
|
18275
|
+
score += 16;
|
|
18276
|
+
}
|
|
18277
|
+
}
|
|
18278
|
+
return score;
|
|
18279
|
+
}
|
|
18280
|
+
function pickPreferredProviderModel(provider, role) {
|
|
18281
|
+
const candidates = providerCandidateModels(provider);
|
|
18282
|
+
if (candidates.length === 0) {
|
|
18283
|
+
return null;
|
|
18284
|
+
}
|
|
18285
|
+
return [
|
|
18286
|
+
...candidates
|
|
18287
|
+
].sort((left, right) => scoreModelForRole(right, role) - scoreModelForRole(left, role))[0] ?? null;
|
|
18288
|
+
}
|
|
18153
18289
|
function createBrainCatalog(providerId, defaultModel, fastModel) {
|
|
18154
18290
|
return {
|
|
18155
18291
|
planner: {
|
|
@@ -18229,12 +18365,13 @@ function normalizeConfigInput(raw) {
|
|
|
18229
18365
|
const legacy = LegacyKimbhoConfigSchema.safeParse(raw);
|
|
18230
18366
|
if (legacy.success) {
|
|
18231
18367
|
const provider = mapLegacyProviderToDefinition(legacy.data.provider);
|
|
18232
|
-
const defaultModel = provider.defaultModel ?? "gpt-5";
|
|
18368
|
+
const defaultModel = pickPreferredProviderModel(provider, "planner") ?? provider.defaultModel ?? "gpt-5";
|
|
18369
|
+
const fastModel = pickPreferredProviderModel(provider, "fast") ?? defaultModel;
|
|
18233
18370
|
return {
|
|
18234
18371
|
providers: [
|
|
18235
18372
|
provider
|
|
18236
18373
|
],
|
|
18237
|
-
brains: createBrainCatalog(provider.id, defaultModel,
|
|
18374
|
+
brains: createBrainCatalog(provider.id, defaultModel, fastModel),
|
|
18238
18375
|
approvalMode: legacy.data.approvalMode,
|
|
18239
18376
|
sandboxMode: legacy.data.sandboxMode,
|
|
18240
18377
|
stackPresets: legacy.data.stackPresets,
|
|
@@ -18285,8 +18422,8 @@ function createDefaultConfig(options = {}) {
|
|
|
18285
18422
|
baseUrl: "https://api.openai.com/v1",
|
|
18286
18423
|
defaultModel: "gpt-5"
|
|
18287
18424
|
});
|
|
18288
|
-
const defaultModel = options.defaultModel ?? provider.defaultModel;
|
|
18289
|
-
const fastModel = options.fastModel ?? defaultModel;
|
|
18425
|
+
const defaultModel = options.defaultModel ?? pickPreferredProviderModel(provider, "planner") ?? provider.defaultModel;
|
|
18426
|
+
const fastModel = options.fastModel ?? pickPreferredProviderModel(provider, "fast") ?? defaultModel;
|
|
18290
18427
|
return KimbhoConfigSchema.parse({
|
|
18291
18428
|
providers: [
|
|
18292
18429
|
provider
|
|
@@ -18765,7 +18902,10 @@ function resolveBrainSettings(config2, role) {
|
|
|
18765
18902
|
function resolveBrainModel(config2, role) {
|
|
18766
18903
|
const settings = resolveBrainSettings(config2, role);
|
|
18767
18904
|
const provider = findProviderById(config2, settings.providerId);
|
|
18768
|
-
|
|
18905
|
+
if (settings.model) {
|
|
18906
|
+
return settings.model;
|
|
18907
|
+
}
|
|
18908
|
+
return pickPreferredProviderModel(provider, role) ?? provider?.defaultModel ?? null;
|
|
18769
18909
|
}
|
|
18770
18910
|
|
|
18771
18911
|
// ../core/dist/session/store.js
|
|
@@ -32988,6 +33128,9 @@ function combinePositiveLimit(...values) {
|
|
|
32988
33128
|
}
|
|
32989
33129
|
return Math.min(...filtered);
|
|
32990
33130
|
}
|
|
33131
|
+
function uniqueStrings2(values) {
|
|
33132
|
+
return Array.from(new Set(values.map((value) => value.trim()).filter((value) => value.length > 0)));
|
|
33133
|
+
}
|
|
32991
33134
|
function truncateForModel(value) {
|
|
32992
33135
|
if (!value) {
|
|
32993
33136
|
return value;
|
|
@@ -33077,6 +33220,18 @@ function isReadOnlyShellCommand2(command) {
|
|
|
33077
33220
|
"git diff"
|
|
33078
33221
|
].some((prefix) => normalized === prefix || normalized.startsWith(prefix));
|
|
33079
33222
|
}
|
|
33223
|
+
function isShellFileInspectionCommand(command) {
|
|
33224
|
+
const normalized = command.trim().toLowerCase();
|
|
33225
|
+
return [
|
|
33226
|
+
"cat ",
|
|
33227
|
+
"head ",
|
|
33228
|
+
"tail ",
|
|
33229
|
+
"wc ",
|
|
33230
|
+
"sed ",
|
|
33231
|
+
"more ",
|
|
33232
|
+
"less "
|
|
33233
|
+
].some((prefix) => normalized === prefix || normalized.startsWith(prefix));
|
|
33234
|
+
}
|
|
33080
33235
|
function isVerificationCommand(command) {
|
|
33081
33236
|
const normalized = command.trim().toLowerCase();
|
|
33082
33237
|
return [
|
|
@@ -33121,6 +33276,310 @@ function isVerificationAction(action) {
|
|
|
33121
33276
|
const command = typeof action.input.command === "string" ? action.input.command : "";
|
|
33122
33277
|
return command.length > 0 && isVerificationCommand(command);
|
|
33123
33278
|
}
|
|
33279
|
+
function isRuntimeValidationAction(action) {
|
|
33280
|
+
if (action.type !== "tool") {
|
|
33281
|
+
return false;
|
|
33282
|
+
}
|
|
33283
|
+
if (isVerificationAction(action)) {
|
|
33284
|
+
return true;
|
|
33285
|
+
}
|
|
33286
|
+
return [
|
|
33287
|
+
"process.start",
|
|
33288
|
+
"process.logs",
|
|
33289
|
+
"process.stop",
|
|
33290
|
+
"browser.open",
|
|
33291
|
+
"browser.inspect",
|
|
33292
|
+
"browser.click",
|
|
33293
|
+
"browser.fill",
|
|
33294
|
+
"browser.close",
|
|
33295
|
+
"http.fetch"
|
|
33296
|
+
].includes(action.tool);
|
|
33297
|
+
}
|
|
33298
|
+
function isShellFileInspectionAction(action) {
|
|
33299
|
+
if (action.type !== "tool" || action.tool !== "shell.exec") {
|
|
33300
|
+
return false;
|
|
33301
|
+
}
|
|
33302
|
+
const command = typeof action.input.command === "string" ? action.input.command : "";
|
|
33303
|
+
return isShellFileInspectionCommand(command);
|
|
33304
|
+
}
|
|
33305
|
+
function isRepoInspectionAction(action) {
|
|
33306
|
+
if (action.type !== "tool") {
|
|
33307
|
+
return false;
|
|
33308
|
+
}
|
|
33309
|
+
return [
|
|
33310
|
+
"file.read",
|
|
33311
|
+
"file.search",
|
|
33312
|
+
"file.list",
|
|
33313
|
+
"repo.index",
|
|
33314
|
+
"repo.query",
|
|
33315
|
+
"git.diff"
|
|
33316
|
+
].includes(action.tool);
|
|
33317
|
+
}
|
|
33318
|
+
function normalizeWorkspacePath(cwd, value) {
|
|
33319
|
+
const normalized = value.replace(/\\/g, "/").trim();
|
|
33320
|
+
if (normalized.length === 0) {
|
|
33321
|
+
return normalized;
|
|
33322
|
+
}
|
|
33323
|
+
if (!import_node_path14.default.isAbsolute(normalized)) {
|
|
33324
|
+
return normalized.replace(/^\.\//, "");
|
|
33325
|
+
}
|
|
33326
|
+
const relative = import_node_path14.default.relative(cwd, normalized).replace(/\\/g, "/");
|
|
33327
|
+
return relative.length > 0 && !relative.startsWith("..") ? relative : normalized;
|
|
33328
|
+
}
|
|
33329
|
+
async function detectVerificationCommands(cwd) {
|
|
33330
|
+
const commands = [];
|
|
33331
|
+
const packagePath = import_node_path14.default.join(cwd, "package.json");
|
|
33332
|
+
try {
|
|
33333
|
+
await (0, import_promises14.access)(packagePath);
|
|
33334
|
+
const raw = await (0, import_promises14.readFile)(packagePath, "utf8");
|
|
33335
|
+
const parsed = JSON.parse(raw);
|
|
33336
|
+
const scripts = parsed.scripts ?? {};
|
|
33337
|
+
const packageManager = parsed.packageManager?.startsWith("pnpm") ? "pnpm" : parsed.packageManager?.startsWith("yarn") ? "yarn" : parsed.packageManager?.startsWith("bun") ? "bun" : "npm";
|
|
33338
|
+
const renderRun = (script) => {
|
|
33339
|
+
if (packageManager === "yarn") {
|
|
33340
|
+
return `yarn ${script}`;
|
|
33341
|
+
}
|
|
33342
|
+
return `${packageManager} run ${script}`;
|
|
33343
|
+
};
|
|
33344
|
+
if (scripts.typecheck) {
|
|
33345
|
+
commands.push(renderRun("typecheck"));
|
|
33346
|
+
}
|
|
33347
|
+
if (scripts.build) {
|
|
33348
|
+
commands.push(renderRun("build"));
|
|
33349
|
+
}
|
|
33350
|
+
if (scripts.test) {
|
|
33351
|
+
commands.push(renderRun("test"));
|
|
33352
|
+
}
|
|
33353
|
+
if (scripts.lint) {
|
|
33354
|
+
commands.push(renderRun("lint"));
|
|
33355
|
+
}
|
|
33356
|
+
} catch {
|
|
33357
|
+
}
|
|
33358
|
+
if (commands.length === 0) {
|
|
33359
|
+
try {
|
|
33360
|
+
await (0, import_promises14.access)(import_node_path14.default.join(cwd, "tsconfig.json"));
|
|
33361
|
+
commands.push("npx tsc --noEmit");
|
|
33362
|
+
} catch {
|
|
33363
|
+
}
|
|
33364
|
+
}
|
|
33365
|
+
const unique = uniqueStrings2(commands);
|
|
33366
|
+
const preferred = [
|
|
33367
|
+
...unique.filter((command) => /typecheck|build|test/i.test(command)),
|
|
33368
|
+
...unique.filter((command) => /lint/i.test(command) && !/typecheck|build|test/i.test(command))
|
|
33369
|
+
];
|
|
33370
|
+
return {
|
|
33371
|
+
availableCommands: unique,
|
|
33372
|
+
preferredCommands: uniqueStrings2(preferred)
|
|
33373
|
+
};
|
|
33374
|
+
}
|
|
33375
|
+
function createInitialWorldModel(task, request, verifier) {
|
|
33376
|
+
const phase = task.type === "verification" ? "verify" : task.type === "integration" || task.type === "documentation" ? "finalize" : request.workspaceState === "existing" ? "survey" : "implement";
|
|
33377
|
+
return {
|
|
33378
|
+
phase,
|
|
33379
|
+
targetFiles: uniqueStrings2(task.filesLikelyTouched.map((filePath) => normalizeWorkspacePath(request.cwd, filePath))),
|
|
33380
|
+
inspectedFiles: [],
|
|
33381
|
+
changedFiles: [],
|
|
33382
|
+
hypotheses: uniqueStrings2([
|
|
33383
|
+
`Satisfy task acceptance criteria for ${task.id}.`,
|
|
33384
|
+
task.description
|
|
33385
|
+
]),
|
|
33386
|
+
blockers: [],
|
|
33387
|
+
proofPending: uniqueStrings2(task.acceptanceCriteria),
|
|
33388
|
+
proofSatisfied: [],
|
|
33389
|
+
recentActions: [],
|
|
33390
|
+
recentCommands: [],
|
|
33391
|
+
nextFocus: phase === "verify" ? "Run the preferred verification path and capture proof." : "Inspect the likely source files and determine the minimal safe change.",
|
|
33392
|
+
sourceEditCount: 0,
|
|
33393
|
+
validationLoopCount: 0,
|
|
33394
|
+
verifier: {
|
|
33395
|
+
availableCommands: verifier.availableCommands,
|
|
33396
|
+
preferredCommands: verifier.preferredCommands,
|
|
33397
|
+
attemptedCommands: [],
|
|
33398
|
+
disabledCommands: [],
|
|
33399
|
+
successfulCommands: [],
|
|
33400
|
+
requiresInteractiveSetup: false
|
|
33401
|
+
},
|
|
33402
|
+
lastUpdatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
33403
|
+
};
|
|
33404
|
+
}
|
|
33405
|
+
function summarizeWorldModel(worldModel) {
|
|
33406
|
+
return [
|
|
33407
|
+
`phase: ${worldModel.phase}`,
|
|
33408
|
+
`next focus: ${worldModel.nextFocus ?? "(unset)"}`,
|
|
33409
|
+
`target files: ${worldModel.targetFiles.join(", ") || "(none)"}`,
|
|
33410
|
+
`inspected files: ${worldModel.inspectedFiles.join(", ") || "(none)"}`,
|
|
33411
|
+
`changed files: ${worldModel.changedFiles.join(", ") || "(none)"}`,
|
|
33412
|
+
`hypotheses: ${worldModel.hypotheses.join(" | ") || "(none)"}`,
|
|
33413
|
+
`blockers: ${worldModel.blockers.join(" | ") || "(none)"}`,
|
|
33414
|
+
`proof pending: ${worldModel.proofPending.join(" | ") || "(none)"}`,
|
|
33415
|
+
`proof satisfied: ${worldModel.proofSatisfied.join(" | ") || "(none)"}`,
|
|
33416
|
+
`verifier preferred commands: ${worldModel.verifier.preferredCommands.join(", ") || "(none)"}`,
|
|
33417
|
+
`verifier disabled commands: ${worldModel.verifier.disabledCommands.join(", ") || "(none)"}`,
|
|
33418
|
+
`latest verifier failure: ${worldModel.verifier.latestFailureSummary ?? "(none)"}`,
|
|
33419
|
+
`recent actions: ${worldModel.recentActions.join(" | ") || "(none)"}`
|
|
33420
|
+
].join("\n");
|
|
33421
|
+
}
|
|
33422
|
+
function recordWorldModelAction(worldModel, label, command) {
|
|
33423
|
+
return {
|
|
33424
|
+
...worldModel,
|
|
33425
|
+
recentActions: uniqueStrings2([
|
|
33426
|
+
...worldModel.recentActions.slice(-5),
|
|
33427
|
+
label
|
|
33428
|
+
]).slice(-6),
|
|
33429
|
+
recentCommands: command ? uniqueStrings2([
|
|
33430
|
+
...worldModel.recentCommands.slice(-5),
|
|
33431
|
+
command
|
|
33432
|
+
]).slice(-6) : worldModel.recentCommands,
|
|
33433
|
+
lastUpdatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
33434
|
+
};
|
|
33435
|
+
}
|
|
33436
|
+
function scoreVerificationCommand(command, worldModel) {
|
|
33437
|
+
const normalized = command.trim().toLowerCase();
|
|
33438
|
+
let score = 0;
|
|
33439
|
+
if (worldModel.phase === "repair" && worldModel.verifier.latestFailureCommand && normalized === worldModel.verifier.latestFailureCommand.trim().toLowerCase()) {
|
|
33440
|
+
score += 80;
|
|
33441
|
+
}
|
|
33442
|
+
if (/typecheck|tsc --noemit|tsc\b/i.test(normalized)) {
|
|
33443
|
+
score += worldModel.proofPending.some((item) => /typescript|compile|type/i.test(item)) ? 70 : 32;
|
|
33444
|
+
}
|
|
33445
|
+
if (/build/i.test(normalized)) {
|
|
33446
|
+
score += worldModel.proofPending.some((item) => /build|compile|render|page|layout|responsive/i.test(item)) ? 68 : 34;
|
|
33447
|
+
}
|
|
33448
|
+
if (/test|vitest|jest/i.test(normalized)) {
|
|
33449
|
+
score += worldModel.proofPending.some((item) => /test|behavior|logic|regression/i.test(item)) ? 74 : 38;
|
|
33450
|
+
}
|
|
33451
|
+
if (/lint|eslint/i.test(normalized)) {
|
|
33452
|
+
score += worldModel.proofPending.some((item) => /lint|style|quality/i.test(item)) ? 54 : 18;
|
|
33453
|
+
}
|
|
33454
|
+
if (/dev|serve|start/i.test(normalized)) {
|
|
33455
|
+
score -= 18;
|
|
33456
|
+
}
|
|
33457
|
+
if (worldModel.verifier.successfulCommands.includes(command)) {
|
|
33458
|
+
score -= 12;
|
|
33459
|
+
}
|
|
33460
|
+
if (worldModel.verifier.disabledCommands.includes(command)) {
|
|
33461
|
+
score -= 1e3;
|
|
33462
|
+
}
|
|
33463
|
+
return score;
|
|
33464
|
+
}
|
|
33465
|
+
function determineNextVerificationCommand(worldModel) {
|
|
33466
|
+
const candidates = uniqueStrings2([
|
|
33467
|
+
...worldModel.phase === "repair" && worldModel.verifier.latestFailureCommand ? [
|
|
33468
|
+
worldModel.verifier.latestFailureCommand
|
|
33469
|
+
] : [],
|
|
33470
|
+
...worldModel.verifier.preferredCommands,
|
|
33471
|
+
...worldModel.verifier.availableCommands
|
|
33472
|
+
]).filter((command) => !worldModel.verifier.disabledCommands.includes(command));
|
|
33473
|
+
if (candidates.length === 0) {
|
|
33474
|
+
return null;
|
|
33475
|
+
}
|
|
33476
|
+
return [
|
|
33477
|
+
...candidates
|
|
33478
|
+
].sort((left, right) => scoreVerificationCommand(right, worldModel) - scoreVerificationCommand(left, worldModel))[0] ?? null;
|
|
33479
|
+
}
|
|
33480
|
+
function updateProofStateForVerification(worldModel, command, success2) {
|
|
33481
|
+
if (!command || !success2) {
|
|
33482
|
+
return {
|
|
33483
|
+
proofPending: worldModel.proofPending,
|
|
33484
|
+
proofSatisfied: worldModel.proofSatisfied
|
|
33485
|
+
};
|
|
33486
|
+
}
|
|
33487
|
+
const normalized = command.toLowerCase();
|
|
33488
|
+
const satisfiedLabels = [];
|
|
33489
|
+
let proofPending = [
|
|
33490
|
+
...worldModel.proofPending
|
|
33491
|
+
];
|
|
33492
|
+
const satisfyMatching = (pattern, fallback) => {
|
|
33493
|
+
const matching = proofPending.filter((item) => pattern.test(item));
|
|
33494
|
+
if (matching.length > 0) {
|
|
33495
|
+
satisfiedLabels.push(...matching);
|
|
33496
|
+
proofPending = proofPending.filter((item) => !pattern.test(item));
|
|
33497
|
+
return;
|
|
33498
|
+
}
|
|
33499
|
+
satisfiedLabels.push(fallback);
|
|
33500
|
+
};
|
|
33501
|
+
if (/typecheck|tsc --noemit|tsc\b/.test(normalized)) {
|
|
33502
|
+
satisfyMatching(/typescript|compile|type/i, `Type safety verified via ${command}`);
|
|
33503
|
+
}
|
|
33504
|
+
if (/build/.test(normalized)) {
|
|
33505
|
+
satisfyMatching(/build|compile|render|page|layout|responsive/i, `Build/render verification passed via ${command}`);
|
|
33506
|
+
}
|
|
33507
|
+
if (/test|vitest|jest/.test(normalized)) {
|
|
33508
|
+
satisfyMatching(/test|behavior|logic|regression/i, `Behavior verified via ${command}`);
|
|
33509
|
+
}
|
|
33510
|
+
if (/lint|eslint/.test(normalized)) {
|
|
33511
|
+
satisfyMatching(/lint|style|quality/i, `Code quality verified via ${command}`);
|
|
33512
|
+
}
|
|
33513
|
+
if (satisfiedLabels.length === 0) {
|
|
33514
|
+
satisfiedLabels.push(`Verified via ${command}`);
|
|
33515
|
+
}
|
|
33516
|
+
return {
|
|
33517
|
+
proofPending: uniqueStrings2(proofPending),
|
|
33518
|
+
proofSatisfied: uniqueStrings2([
|
|
33519
|
+
...worldModel.proofSatisfied,
|
|
33520
|
+
...satisfiedLabels
|
|
33521
|
+
])
|
|
33522
|
+
};
|
|
33523
|
+
}
|
|
33524
|
+
function derivePhaseGuidance(worldModel) {
|
|
33525
|
+
switch (worldModel.phase) {
|
|
33526
|
+
case "survey":
|
|
33527
|
+
return [
|
|
33528
|
+
"Survey likely source files and constraints before making a change.",
|
|
33529
|
+
"Do not spend more than one baseline validation action before a real source edit lands."
|
|
33530
|
+
];
|
|
33531
|
+
case "plan-edit":
|
|
33532
|
+
case "implement":
|
|
33533
|
+
return [
|
|
33534
|
+
"Make the concrete source change now.",
|
|
33535
|
+
"Use file.patch or file.write against the likely target files before further runtime validation."
|
|
33536
|
+
];
|
|
33537
|
+
case "verify":
|
|
33538
|
+
return [
|
|
33539
|
+
`Use the strategic verifier next: ${determineNextVerificationCommand(worldModel) ?? "(choose the best non-interactive verifier)"}.`,
|
|
33540
|
+
"Capture proof for the changed behavior before finishing."
|
|
33541
|
+
];
|
|
33542
|
+
case "repair":
|
|
33543
|
+
return [
|
|
33544
|
+
`Repair the latest failing verifier before rerunning it: ${worldModel.verifier.latestFailureSummary ?? "(missing failure summary)"}.`,
|
|
33545
|
+
"Inspect failure output, edit the relevant source, then rerun the strategic verifier."
|
|
33546
|
+
];
|
|
33547
|
+
case "finalize":
|
|
33548
|
+
return [
|
|
33549
|
+
"Only finish once the key proof is captured and no blocker remains.",
|
|
33550
|
+
"Use git.diff or one final verifier if you still need confirmation."
|
|
33551
|
+
];
|
|
33552
|
+
case "escalate":
|
|
33553
|
+
return [
|
|
33554
|
+
"Summarize blockers precisely so the supervisor can reassign or replan."
|
|
33555
|
+
];
|
|
33556
|
+
}
|
|
33557
|
+
}
|
|
33558
|
+
function deriveSupervisorHints(status, task, worldModel) {
|
|
33559
|
+
const delegatedTask = Boolean(task.parentTaskId);
|
|
33560
|
+
if (status === "completed" && delegatedTask) {
|
|
33561
|
+
return {
|
|
33562
|
+
shouldMergeDelegatedWork: true,
|
|
33563
|
+
shouldReprioritize: true,
|
|
33564
|
+
reason: `Delegated task ${task.id} completed; parent flow may be ready to merge or reprioritize.`
|
|
33565
|
+
};
|
|
33566
|
+
}
|
|
33567
|
+
if (status === "blocked" || status === "handoff" || worldModel.phase === "escalate") {
|
|
33568
|
+
return {
|
|
33569
|
+
shouldReplan: true,
|
|
33570
|
+
shouldReprioritize: delegatedTask,
|
|
33571
|
+
reason: worldModel.blockers[0] ?? `Task ${task.id} needs supervisor intervention.`
|
|
33572
|
+
};
|
|
33573
|
+
}
|
|
33574
|
+
if (delegatedTask && worldModel.phase === "repair") {
|
|
33575
|
+
return {
|
|
33576
|
+
shouldReplan: true,
|
|
33577
|
+
shouldReprioritize: true,
|
|
33578
|
+
reason: `Delegated task ${task.id} is in repair mode and may need reassignment or dependency changes.`
|
|
33579
|
+
};
|
|
33580
|
+
}
|
|
33581
|
+
return void 0;
|
|
33582
|
+
}
|
|
33124
33583
|
function extractShellCommand(action) {
|
|
33125
33584
|
if (action.type !== "tool" || action.tool !== "shell.exec") {
|
|
33126
33585
|
return "";
|
|
@@ -33139,7 +33598,7 @@ function isInteractiveVerificationSetupFailure(action, result) {
|
|
|
33139
33598
|
].join("\n").toLowerCase();
|
|
33140
33599
|
return combined.includes("interactive eslint setup required") || combined.includes("command requires interactive input before it can continue") || command.includes("lint") && combined.includes("how would you like to configure eslint");
|
|
33141
33600
|
}
|
|
33142
|
-
function buildSystemPrompt(agent, task, request, allowedTools, plan, extraInstructions) {
|
|
33601
|
+
function buildSystemPrompt(agent, task, request, allowedTools, worldModel, plan, extraInstructions) {
|
|
33143
33602
|
const toolShape = allowedTools.join("|");
|
|
33144
33603
|
const dependencyTasks = plan ? flattenPlanTasks(plan).filter((candidate) => task.dependsOn.includes(candidate.id)) : [];
|
|
33145
33604
|
const completedTasks = plan ? flattenPlanTasks(plan).filter((candidate) => candidate.status === "completed" && candidate.id !== task.id) : [];
|
|
@@ -33153,6 +33612,7 @@ function buildSystemPrompt(agent, task, request, allowedTools, plan, extraInstru
|
|
|
33153
33612
|
`Goal: ${request.goal}`,
|
|
33154
33613
|
`Current task: ${task.id} - ${task.title}`,
|
|
33155
33614
|
`Task description: ${task.description}`,
|
|
33615
|
+
`Execution phase: ${worldModel.phase}`,
|
|
33156
33616
|
`Acceptance criteria:`,
|
|
33157
33617
|
...task.acceptanceCriteria.map((item) => `- ${item}`),
|
|
33158
33618
|
`Likely files: ${task.filesLikelyTouched.join(", ") || "(not specified)"}`,
|
|
@@ -33162,6 +33622,8 @@ function buildSystemPrompt(agent, task, request, allowedTools, plan, extraInstru
|
|
|
33162
33622
|
`Completed tasks in this run: ${completedTasks.length > 0 ? completedTasks.slice(-4).map((candidate) => `${candidate.id}:${candidate.title}`).join(", ") : "(none yet)"}`,
|
|
33163
33623
|
`Downstream tasks depending on this task: ${downstreamTasks.length > 0 ? downstreamTasks.slice(0, 4).map((candidate) => `${candidate.id}:${candidate.title}`).join(", ") : "(none)"}`,
|
|
33164
33624
|
`Allowed tools: ${allowedTools.join(", ")}`,
|
|
33625
|
+
`Task world-model:`,
|
|
33626
|
+
summarizeWorldModel(worldModel),
|
|
33165
33627
|
`Respond with exactly one JSON object and no markdown.`,
|
|
33166
33628
|
`Tool action shape: {"type":"tool","tool":"${toolShape}","input":{...},"reason":"why this step matters"}`,
|
|
33167
33629
|
`Finish shape: {"type":"finish","summary":"what was completed and verified"}`,
|
|
@@ -33170,6 +33632,7 @@ function buildSystemPrompt(agent, task, request, allowedTools, plan, extraInstru
|
|
|
33170
33632
|
`- Use one action per response.`,
|
|
33171
33633
|
`- Use file.list, file.search, repo.index, and repo.query to explore the workspace before editing.`,
|
|
33172
33634
|
`- Prefer file.read before editing existing files.`,
|
|
33635
|
+
`- For repo file inspection, prefer file.read, file.search, file.list, repo.query, and git.diff instead of shell.exec cat/head/tail/wc/sed.`,
|
|
33173
33636
|
`- Use scaffold.generate when the task is clearly greenfield and a known preset fits better than improvising every file by hand.`,
|
|
33174
33637
|
`- Use file.patch for existing files when possible; use file.write for new files or full replacements.`,
|
|
33175
33638
|
`- Use git.diff to inspect the current patch after changes when helpful.`,
|
|
@@ -33184,6 +33647,7 @@ function buildSystemPrompt(agent, task, request, allowedTools, plan, extraInstru
|
|
|
33184
33647
|
`- If a verification command asks for interactive setup or operator input, do not rerun it unchanged. Choose a different non-interactive verifier, or configure that verifier only if the task explicitly requires it.`,
|
|
33185
33648
|
`- Do not claim success unless the task acceptance criteria are satisfied.`,
|
|
33186
33649
|
`- If the task is underspecified, make a pragmatic implementation choice and continue.`,
|
|
33650
|
+
...derivePhaseGuidance(worldModel).map((rule) => `- ${rule}`),
|
|
33187
33651
|
...task.subagentInstructions ? [
|
|
33188
33652
|
`Delegation instructions:`,
|
|
33189
33653
|
task.subagentInstructions
|
|
@@ -33341,17 +33805,6 @@ function inferFallbackActionFromResponse(raw, task, request, allowedTools) {
|
|
|
33341
33805
|
};
|
|
33342
33806
|
}
|
|
33343
33807
|
}
|
|
33344
|
-
if (allowedTools.includes("scaffold.generate") && looksLikeStaticLandingGoal(request.goal) && task.filesLikelyTouched.some((filePath) => filePath === "src/app/page.tsx" || filePath === "src/app/layout.tsx" || filePath === "src/pages/index.tsx" || filePath === "index.html" || filePath === "styles.css")) {
|
|
33345
|
-
return {
|
|
33346
|
-
type: "tool",
|
|
33347
|
-
tool: "scaffold.generate",
|
|
33348
|
-
input: {
|
|
33349
|
-
goal: request.goal,
|
|
33350
|
-
preset: "static-landing"
|
|
33351
|
-
},
|
|
33352
|
-
reason: "Use the deterministic static-site adapter because the model stayed out of structured mode."
|
|
33353
|
-
};
|
|
33354
|
-
}
|
|
33355
33808
|
if (!allowedTools.includes("file.write")) {
|
|
33356
33809
|
return null;
|
|
33357
33810
|
}
|
|
@@ -33484,6 +33937,8 @@ var AutonomousTaskExecutor = class {
|
|
|
33484
33937
|
const brain = await this.resolver.resolve(effectiveBrainRole);
|
|
33485
33938
|
const allowedTools = resolvedExecutionPolicy.allowedTools;
|
|
33486
33939
|
const actionSchema = createAgentActionSchema(allowedTools);
|
|
33940
|
+
const verificationCommands = await detectVerificationCommands(request.cwd);
|
|
33941
|
+
let worldModel = task.executionState ?? createInitialWorldModel(task, request, verificationCommands);
|
|
33487
33942
|
const messages = [
|
|
33488
33943
|
{
|
|
33489
33944
|
role: "user",
|
|
@@ -33510,11 +33965,13 @@ var AutonomousTaskExecutor = class {
|
|
|
33510
33965
|
}
|
|
33511
33966
|
};
|
|
33512
33967
|
let changedWorkspace = false;
|
|
33968
|
+
let appliedSourceEdit = false;
|
|
33513
33969
|
let verifiedAfterLatestChange = false;
|
|
33514
33970
|
let repairRequiredBeforeVerification = false;
|
|
33515
33971
|
let repairAppliedSinceFailure = false;
|
|
33516
33972
|
let verificationFailures = 0;
|
|
33517
33973
|
let lastVerificationFailure = null;
|
|
33974
|
+
let preEditValidationActions = 0;
|
|
33518
33975
|
let preservedMessageCount = messages.length;
|
|
33519
33976
|
let compactedTranscriptEntries = 0;
|
|
33520
33977
|
let compactionSummary = null;
|
|
@@ -33525,6 +33982,26 @@ var AutonomousTaskExecutor = class {
|
|
|
33525
33982
|
inputTokens: 0,
|
|
33526
33983
|
outputTokens: 0
|
|
33527
33984
|
};
|
|
33985
|
+
const snapshotWorldModel = () => ({
|
|
33986
|
+
...worldModel,
|
|
33987
|
+
lastUpdatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
33988
|
+
});
|
|
33989
|
+
const makeOutcome = (status, summary, extra = {}) => {
|
|
33990
|
+
const currentWorldModel = snapshotWorldModel();
|
|
33991
|
+
const supervisorHints = deriveSupervisorHints(status, task, currentWorldModel);
|
|
33992
|
+
return {
|
|
33993
|
+
status,
|
|
33994
|
+
summary,
|
|
33995
|
+
toolResults,
|
|
33996
|
+
artifacts: Array.from(artifacts),
|
|
33997
|
+
usage: usageTotals,
|
|
33998
|
+
worldModel: currentWorldModel,
|
|
33999
|
+
...supervisorHints ? {
|
|
34000
|
+
supervisorHints
|
|
34001
|
+
} : {},
|
|
34002
|
+
...extra
|
|
34003
|
+
};
|
|
34004
|
+
};
|
|
33528
34005
|
const createToolExecutionContext = (step, approvalReason, operatorApproved = false) => ({
|
|
33529
34006
|
cwd: request.cwd,
|
|
33530
34007
|
...options.signal ? {
|
|
@@ -33598,13 +34075,17 @@ var AutonomousTaskExecutor = class {
|
|
|
33598
34075
|
});
|
|
33599
34076
|
const transcriptPath2 = await writeTranscriptArtifact(request.cwd, sessionId, task.id, transcript);
|
|
33600
34077
|
artifacts.add(transcriptPath2);
|
|
33601
|
-
|
|
33602
|
-
|
|
33603
|
-
|
|
33604
|
-
|
|
33605
|
-
|
|
33606
|
-
|
|
34078
|
+
worldModel = {
|
|
34079
|
+
...worldModel,
|
|
34080
|
+
phase: "escalate",
|
|
34081
|
+
blockers: uniqueStrings2([
|
|
34082
|
+
...worldModel.blockers,
|
|
34083
|
+
summary
|
|
34084
|
+
]),
|
|
34085
|
+
nextFocus: "Supervisor should replan or reassign this task because a budget was exhausted.",
|
|
34086
|
+
lastUpdatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
33607
34087
|
};
|
|
34088
|
+
return makeOutcome("blocked", summary);
|
|
33608
34089
|
};
|
|
33609
34090
|
await emitProgress({
|
|
33610
34091
|
type: "task-note",
|
|
@@ -33633,24 +34114,32 @@ var AutonomousTaskExecutor = class {
|
|
|
33633
34114
|
});
|
|
33634
34115
|
const transcriptPath2 = await writeTranscriptArtifact(request.cwd, sessionId, task.id, transcript);
|
|
33635
34116
|
artifacts.add(transcriptPath2);
|
|
33636
|
-
|
|
33637
|
-
|
|
33638
|
-
|
|
33639
|
-
|
|
33640
|
-
|
|
33641
|
-
|
|
34117
|
+
worldModel = {
|
|
34118
|
+
...worldModel,
|
|
34119
|
+
phase: "escalate",
|
|
34120
|
+
blockers: uniqueStrings2([
|
|
34121
|
+
...worldModel.blockers,
|
|
34122
|
+
summary
|
|
34123
|
+
]),
|
|
34124
|
+
nextFocus: "Supervisor should inspect why this task has no executable tools.",
|
|
34125
|
+
lastUpdatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
33642
34126
|
};
|
|
34127
|
+
return makeOutcome("blocked", summary);
|
|
33643
34128
|
}
|
|
33644
34129
|
if (resolvedApproval?.decision === "deny") {
|
|
33645
34130
|
const transcriptPath2 = await writeTranscriptArtifact(request.cwd, sessionId, task.id, transcript);
|
|
33646
34131
|
artifacts.add(transcriptPath2);
|
|
33647
|
-
|
|
33648
|
-
|
|
33649
|
-
|
|
33650
|
-
|
|
33651
|
-
|
|
33652
|
-
|
|
34132
|
+
worldModel = {
|
|
34133
|
+
...worldModel,
|
|
34134
|
+
phase: "escalate",
|
|
34135
|
+
blockers: uniqueStrings2([
|
|
34136
|
+
...worldModel.blockers,
|
|
34137
|
+
`Operator denied ${resolvedApproval.approval.toolId}.`
|
|
34138
|
+
]),
|
|
34139
|
+
nextFocus: "Choose a safer path or wait for supervisor replanning after the denied action.",
|
|
34140
|
+
lastUpdatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
33653
34141
|
};
|
|
34142
|
+
return makeOutcome("blocked", `Operator denied approval for ${resolvedApproval.approval.toolId} in ${task.id}.`);
|
|
33654
34143
|
}
|
|
33655
34144
|
if (request.workspaceState === "existing") {
|
|
33656
34145
|
const preflightResults = [];
|
|
@@ -33692,6 +34181,18 @@ var AutonomousTaskExecutor = class {
|
|
|
33692
34181
|
for (const artifact of result.artifacts) {
|
|
33693
34182
|
artifacts.add(artifact);
|
|
33694
34183
|
}
|
|
34184
|
+
if (toolId === "file.read" && result.success && typeof input.path === "string") {
|
|
34185
|
+
worldModel = {
|
|
34186
|
+
...worldModel,
|
|
34187
|
+
inspectedFiles: uniqueStrings2([
|
|
34188
|
+
...worldModel.inspectedFiles,
|
|
34189
|
+
normalizeWorkspacePath(request.cwd, input.path)
|
|
34190
|
+
]),
|
|
34191
|
+
phase: worldModel.phase === "survey" ? "plan-edit" : worldModel.phase,
|
|
34192
|
+
nextFocus: worldModel.phase === "survey" ? "Make the concrete source change in the inspected target files." : worldModel.nextFocus,
|
|
34193
|
+
lastUpdatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
34194
|
+
};
|
|
34195
|
+
}
|
|
33695
34196
|
transcript.push({
|
|
33696
34197
|
step: 0,
|
|
33697
34198
|
response: JSON.stringify({
|
|
@@ -33791,6 +34292,14 @@ ${truncateForModel(customAgentMemory)}`);
|
|
|
33791
34292
|
].join("\n\n")
|
|
33792
34293
|
});
|
|
33793
34294
|
}
|
|
34295
|
+
if (request.workspaceState === "existing" && (task.type === "scaffold" || task.type === "implementation") && worldModel.phase === "survey") {
|
|
34296
|
+
worldModel = {
|
|
34297
|
+
...worldModel,
|
|
34298
|
+
phase: "plan-edit",
|
|
34299
|
+
nextFocus: "Edit the likely source files before using more verification or browser/runtime checks.",
|
|
34300
|
+
lastUpdatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
34301
|
+
};
|
|
34302
|
+
}
|
|
33794
34303
|
}
|
|
33795
34304
|
preservedMessageCount = messages.length;
|
|
33796
34305
|
const runToolAction = async (parsedAction, step, operatorApproved = false) => {
|
|
@@ -33852,7 +34361,10 @@ ${truncateForModel(customAgentMemory)}`);
|
|
|
33852
34361
|
const applyToolResult = async (parsedAction, result, step, transcriptEntry) => {
|
|
33853
34362
|
const mutatingAction = isMutatingAction(parsedAction);
|
|
33854
34363
|
const verificationAction = isVerificationAction(parsedAction);
|
|
34364
|
+
const runtimeValidationAction = isRuntimeValidationAction(parsedAction);
|
|
34365
|
+
const shellCommand = extractShellCommand(parsedAction);
|
|
33855
34366
|
const interactiveVerificationSetupFailure = verificationAction && !result.success && isInteractiveVerificationSetupFailure(parsedAction, result);
|
|
34367
|
+
worldModel = recordWorldModelAction(worldModel, parsedAction.type === "tool" ? `${parsedAction.tool}${shellCommand ? ` ${shellCommand}` : ""}` : parsedAction.type === "finish" ? "finish" : "block", shellCommand || void 0);
|
|
33856
34368
|
if (mutatingAction && result.success) {
|
|
33857
34369
|
changedWorkspace = true;
|
|
33858
34370
|
verifiedAfterLatestChange = false;
|
|
@@ -33860,22 +34372,121 @@ ${truncateForModel(customAgentMemory)}`);
|
|
|
33860
34372
|
repairAppliedSinceFailure = true;
|
|
33861
34373
|
}
|
|
33862
34374
|
}
|
|
34375
|
+
if (parsedAction.tool === "file.write" || parsedAction.tool === "file.patch") {
|
|
34376
|
+
if (result.success) {
|
|
34377
|
+
appliedSourceEdit = true;
|
|
34378
|
+
preEditValidationActions = 0;
|
|
34379
|
+
worldModel = {
|
|
34380
|
+
...worldModel,
|
|
34381
|
+
phase: "verify",
|
|
34382
|
+
changedFiles: uniqueStrings2([
|
|
34383
|
+
...worldModel.changedFiles,
|
|
34384
|
+
...result.artifacts.map((artifact) => normalizeWorkspacePath(request.cwd, artifact)),
|
|
34385
|
+
...typeof parsedAction.input.path === "string" ? [
|
|
34386
|
+
normalizeWorkspacePath(request.cwd, parsedAction.input.path)
|
|
34387
|
+
] : []
|
|
34388
|
+
]),
|
|
34389
|
+
blockers: [],
|
|
34390
|
+
sourceEditCount: worldModel.sourceEditCount + 1,
|
|
34391
|
+
nextFocus: `Run the strategic verifier next: ${determineNextVerificationCommand(worldModel) ?? "choose the best non-interactive verifier"}.`,
|
|
34392
|
+
lastUpdatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
34393
|
+
};
|
|
34394
|
+
}
|
|
34395
|
+
}
|
|
34396
|
+
if (!appliedSourceEdit && runtimeValidationAction) {
|
|
34397
|
+
preEditValidationActions += 1;
|
|
34398
|
+
worldModel = {
|
|
34399
|
+
...worldModel,
|
|
34400
|
+
validationLoopCount: worldModel.validationLoopCount + 1,
|
|
34401
|
+
nextFocus: "Make a source edit before spending more time on runtime validation.",
|
|
34402
|
+
lastUpdatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
34403
|
+
};
|
|
34404
|
+
}
|
|
34405
|
+
if (parsedAction.tool === "file.read" && result.success && typeof parsedAction.input.path === "string") {
|
|
34406
|
+
worldModel = {
|
|
34407
|
+
...worldModel,
|
|
34408
|
+
inspectedFiles: uniqueStrings2([
|
|
34409
|
+
...worldModel.inspectedFiles,
|
|
34410
|
+
normalizeWorkspacePath(request.cwd, parsedAction.input.path)
|
|
34411
|
+
]),
|
|
34412
|
+
phase: worldModel.phase === "survey" ? "plan-edit" : worldModel.phase,
|
|
34413
|
+
nextFocus: worldModel.phase === "survey" ? "Use the inspected files to make the concrete implementation change." : worldModel.nextFocus,
|
|
34414
|
+
lastUpdatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
34415
|
+
};
|
|
34416
|
+
}
|
|
33863
34417
|
if (verificationAction) {
|
|
33864
34418
|
verifiedAfterLatestChange = result.success;
|
|
34419
|
+
const attemptedCommand = shellCommand || (parsedAction.tool === "tests.run" ? "tests.run" : "");
|
|
34420
|
+
const proofUpdate = updateProofStateForVerification(worldModel, attemptedCommand || void 0, result.success);
|
|
34421
|
+
const verifier = {
|
|
34422
|
+
...worldModel.verifier,
|
|
34423
|
+
attemptedCommands: attemptedCommand ? uniqueStrings2([
|
|
34424
|
+
...worldModel.verifier.attemptedCommands,
|
|
34425
|
+
attemptedCommand
|
|
34426
|
+
]) : worldModel.verifier.attemptedCommands,
|
|
34427
|
+
currentCommand: attemptedCommand || worldModel.verifier.currentCommand,
|
|
34428
|
+
latestFailureSummary: result.success ? void 0 : result.summary,
|
|
34429
|
+
latestFailureCommand: result.success ? void 0 : attemptedCommand || void 0,
|
|
34430
|
+
latestSuccessfulCommand: result.success ? attemptedCommand || worldModel.verifier.latestSuccessfulCommand : worldModel.verifier.latestSuccessfulCommand,
|
|
34431
|
+
successfulCommands: result.success && attemptedCommand ? uniqueStrings2([
|
|
34432
|
+
...worldModel.verifier.successfulCommands,
|
|
34433
|
+
attemptedCommand
|
|
34434
|
+
]) : worldModel.verifier.successfulCommands,
|
|
34435
|
+
disabledCommands: interactiveVerificationSetupFailure && attemptedCommand ? uniqueStrings2([
|
|
34436
|
+
...worldModel.verifier.disabledCommands,
|
|
34437
|
+
attemptedCommand
|
|
34438
|
+
]) : worldModel.verifier.disabledCommands,
|
|
34439
|
+
requiresInteractiveSetup: interactiveVerificationSetupFailure
|
|
34440
|
+
};
|
|
34441
|
+
worldModel = {
|
|
34442
|
+
...worldModel,
|
|
34443
|
+
verifier,
|
|
34444
|
+
lastUpdatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
34445
|
+
};
|
|
33865
34446
|
if (result.success) {
|
|
33866
34447
|
verificationFailures = 0;
|
|
33867
34448
|
repairRequiredBeforeVerification = false;
|
|
33868
34449
|
repairAppliedSinceFailure = false;
|
|
33869
34450
|
lastVerificationFailure = null;
|
|
34451
|
+
worldModel = {
|
|
34452
|
+
...worldModel,
|
|
34453
|
+
phase: "finalize",
|
|
34454
|
+
validationLoopCount: 0,
|
|
34455
|
+
proofPending: proofUpdate.proofPending,
|
|
34456
|
+
proofSatisfied: proofUpdate.proofSatisfied,
|
|
34457
|
+
nextFocus: "Review the diff and finish if the task acceptance criteria are satisfied.",
|
|
34458
|
+
blockers: [],
|
|
34459
|
+
lastUpdatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
34460
|
+
};
|
|
33870
34461
|
} else if (interactiveVerificationSetupFailure) {
|
|
33871
34462
|
repairRequiredBeforeVerification = false;
|
|
33872
34463
|
repairAppliedSinceFailure = false;
|
|
33873
34464
|
lastVerificationFailure = result;
|
|
34465
|
+
worldModel = {
|
|
34466
|
+
...worldModel,
|
|
34467
|
+
phase: appliedSourceEdit ? "verify" : "implement",
|
|
34468
|
+
blockers: uniqueStrings2([
|
|
34469
|
+
...worldModel.blockers.filter((blocker) => !blocker.includes("interactive")),
|
|
34470
|
+
result.summary
|
|
34471
|
+
]),
|
|
34472
|
+
nextFocus: "Choose a different non-interactive verifier or configure the verifier only if the task truly requires it.",
|
|
34473
|
+
lastUpdatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
34474
|
+
};
|
|
33874
34475
|
} else {
|
|
33875
34476
|
verificationFailures += 1;
|
|
33876
34477
|
repairRequiredBeforeVerification = true;
|
|
33877
34478
|
repairAppliedSinceFailure = false;
|
|
33878
34479
|
lastVerificationFailure = result;
|
|
34480
|
+
worldModel = {
|
|
34481
|
+
...worldModel,
|
|
34482
|
+
phase: "repair",
|
|
34483
|
+
blockers: uniqueStrings2([
|
|
34484
|
+
...worldModel.blockers,
|
|
34485
|
+
result.summary
|
|
34486
|
+
]),
|
|
34487
|
+
nextFocus: "Repair the latest failing verifier output before running verification again.",
|
|
34488
|
+
lastUpdatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
34489
|
+
};
|
|
33879
34490
|
}
|
|
33880
34491
|
}
|
|
33881
34492
|
transcriptEntry.toolResult = result;
|
|
@@ -33936,21 +34547,21 @@ ${truncateForModel(customAgentMemory)}`);
|
|
|
33936
34547
|
const transcriptPath2 = await writeTranscriptArtifact(request.cwd, sessionId, task.id, transcript);
|
|
33937
34548
|
artifacts.add(transcriptPath2);
|
|
33938
34549
|
if (task.agentRole !== "test-debugger") {
|
|
33939
|
-
|
|
33940
|
-
|
|
33941
|
-
|
|
33942
|
-
|
|
33943
|
-
|
|
33944
|
-
usage: usageTotals
|
|
34550
|
+
worldModel = {
|
|
34551
|
+
...worldModel,
|
|
34552
|
+
phase: "escalate",
|
|
34553
|
+
nextFocus: "Escalate to test-debugger with the latest failing verifier context.",
|
|
34554
|
+
lastUpdatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
33945
34555
|
};
|
|
34556
|
+
return makeOutcome("handoff", `Verification failed ${verificationFailures} time${verificationFailures === 1 ? "" : "s"} for ${task.id}; handing off to test-debugger.`);
|
|
33946
34557
|
}
|
|
33947
|
-
|
|
33948
|
-
|
|
33949
|
-
|
|
33950
|
-
|
|
33951
|
-
|
|
33952
|
-
usage: usageTotals
|
|
34558
|
+
worldModel = {
|
|
34559
|
+
...worldModel,
|
|
34560
|
+
phase: "escalate",
|
|
34561
|
+
nextFocus: "Debugger repair budget is exhausted; supervisor must replan or accept the blocker.",
|
|
34562
|
+
lastUpdatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
33953
34563
|
};
|
|
34564
|
+
return makeOutcome("blocked", `Verification failed ${verificationFailures} time${verificationFailures === 1 ? "" : "s"} for ${task.id}; repair budget exhausted.`);
|
|
33954
34565
|
}
|
|
33955
34566
|
}
|
|
33956
34567
|
messages.push({
|
|
@@ -33994,14 +34605,9 @@ ${truncateForModel(customAgentMemory)}`);
|
|
|
33994
34605
|
if (execution.approvalRequest) {
|
|
33995
34606
|
const transcriptPath2 = await writeTranscriptArtifact(request.cwd, sessionId, task.id, transcript.concat(transcriptEntry));
|
|
33996
34607
|
artifacts.add(transcriptPath2);
|
|
33997
|
-
return {
|
|
33998
|
-
|
|
33999
|
-
|
|
34000
|
-
toolResults,
|
|
34001
|
-
artifacts: Array.from(artifacts),
|
|
34002
|
-
approvalRequest: execution.approvalRequest,
|
|
34003
|
-
usage: usageTotals
|
|
34004
|
-
};
|
|
34608
|
+
return makeOutcome("awaiting-approval", execution.approvalRequest.reason, {
|
|
34609
|
+
approvalRequest: execution.approvalRequest
|
|
34610
|
+
});
|
|
34005
34611
|
}
|
|
34006
34612
|
if (!execution.result) {
|
|
34007
34613
|
throw new Error("Approved action did not produce a tool result.");
|
|
@@ -34018,13 +34624,12 @@ ${truncateForModel(customAgentMemory)}`);
|
|
|
34018
34624
|
} catch (error2) {
|
|
34019
34625
|
const transcriptPath2 = await writeTranscriptArtifact(request.cwd, sessionId, task.id, transcript);
|
|
34020
34626
|
artifacts.add(transcriptPath2);
|
|
34021
|
-
|
|
34022
|
-
|
|
34023
|
-
|
|
34024
|
-
|
|
34025
|
-
artifacts: Array.from(artifacts),
|
|
34026
|
-
usage: usageTotals
|
|
34627
|
+
worldModel = {
|
|
34628
|
+
...worldModel,
|
|
34629
|
+
nextFocus: "Resume from the current execution state without redoing completed inspection or verification.",
|
|
34630
|
+
lastUpdatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
34027
34631
|
};
|
|
34632
|
+
return makeOutcome("paused", `Execution interrupted by operator during ${task.id}.`);
|
|
34028
34633
|
}
|
|
34029
34634
|
await compactExecutionContextIfNeeded(step);
|
|
34030
34635
|
if (typeof maxModelCalls === "number" && usageTotals.modelCalls >= maxModelCalls) {
|
|
@@ -34047,7 +34652,7 @@ ${truncateForModel(customAgentMemory)}`);
|
|
|
34047
34652
|
try {
|
|
34048
34653
|
response = await brain.client.generateText({
|
|
34049
34654
|
model: brain.model,
|
|
34050
|
-
systemPrompt: buildSystemPrompt(effectiveAgent, task, request, allowedTools, options.plan, task.agentPromptPreamble ?? customOverlay?.promptPreamble),
|
|
34655
|
+
systemPrompt: buildSystemPrompt(effectiveAgent, task, request, allowedTools, snapshotWorldModel(), options.plan, task.agentPromptPreamble ?? customOverlay?.promptPreamble),
|
|
34051
34656
|
messages,
|
|
34052
34657
|
responseFormat: "json_object",
|
|
34053
34658
|
...typeof brain.settings.temperature === "number" ? {
|
|
@@ -34065,24 +34670,27 @@ ${truncateForModel(customAgentMemory)}`);
|
|
|
34065
34670
|
});
|
|
34066
34671
|
const transcriptPath2 = await writeTranscriptArtifact(request.cwd, sessionId, task.id, transcript);
|
|
34067
34672
|
artifacts.add(transcriptPath2);
|
|
34068
|
-
|
|
34069
|
-
|
|
34070
|
-
|
|
34071
|
-
|
|
34072
|
-
|
|
34073
|
-
|
|
34673
|
+
worldModel = {
|
|
34674
|
+
...worldModel,
|
|
34675
|
+
phase: "escalate",
|
|
34676
|
+
blockers: uniqueStrings2([
|
|
34677
|
+
...worldModel.blockers,
|
|
34678
|
+
error2 instanceof Error ? error2.message : String(error2)
|
|
34679
|
+
]),
|
|
34680
|
+
nextFocus: "Supervisor should inspect the model failure or switch to a healthier provider/model.",
|
|
34681
|
+
lastUpdatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
34074
34682
|
};
|
|
34683
|
+
return makeOutcome("blocked", `Model request failed before ${task.id} could choose a safe action: ${error2 instanceof Error ? error2.message : String(error2)}`);
|
|
34075
34684
|
}
|
|
34076
34685
|
if (options.signal?.aborted) {
|
|
34077
34686
|
const transcriptPath2 = await writeTranscriptArtifact(request.cwd, sessionId, task.id, transcript);
|
|
34078
34687
|
artifacts.add(transcriptPath2);
|
|
34079
|
-
|
|
34080
|
-
|
|
34081
|
-
|
|
34082
|
-
|
|
34083
|
-
artifacts: Array.from(artifacts),
|
|
34084
|
-
usage: usageTotals
|
|
34688
|
+
worldModel = {
|
|
34689
|
+
...worldModel,
|
|
34690
|
+
nextFocus: "Resume from the current execution state without redoing completed inspection or verification.",
|
|
34691
|
+
lastUpdatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
34085
34692
|
};
|
|
34693
|
+
return makeOutcome("paused", `Execution interrupted by operator during ${task.id}.`);
|
|
34086
34694
|
}
|
|
34087
34695
|
responseText = response.text;
|
|
34088
34696
|
usageTotals.modelCalls += 1;
|
|
@@ -34145,13 +34753,17 @@ ${truncateForModel(customAgentMemory)}`);
|
|
|
34145
34753
|
step,
|
|
34146
34754
|
message: "Model stayed out of structured mode after multiple retries."
|
|
34147
34755
|
});
|
|
34148
|
-
|
|
34149
|
-
|
|
34150
|
-
|
|
34151
|
-
|
|
34152
|
-
|
|
34153
|
-
|
|
34756
|
+
worldModel = {
|
|
34757
|
+
...worldModel,
|
|
34758
|
+
phase: "escalate",
|
|
34759
|
+
blockers: uniqueStrings2([
|
|
34760
|
+
...worldModel.blockers,
|
|
34761
|
+
parseSummary
|
|
34762
|
+
]),
|
|
34763
|
+
nextFocus: "Supervisor should inspect the unstructured model output and replan or switch models.",
|
|
34764
|
+
lastUpdatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
34154
34765
|
};
|
|
34766
|
+
return makeOutcome("blocked", `${parseSummary} The task stopped before a safe tool action could be chosen.`);
|
|
34155
34767
|
}
|
|
34156
34768
|
await emitProgress({
|
|
34157
34769
|
type: "task-note",
|
|
@@ -34185,10 +34797,53 @@ ${truncateForModel(customAgentMemory)}`);
|
|
|
34185
34797
|
response: responseText,
|
|
34186
34798
|
parsedAction
|
|
34187
34799
|
};
|
|
34800
|
+
const strategicVerifier = determineNextVerificationCommand(worldModel);
|
|
34188
34801
|
messages.push({
|
|
34189
34802
|
role: "assistant",
|
|
34190
34803
|
content: JSON.stringify(parsedAction)
|
|
34191
34804
|
});
|
|
34805
|
+
if (worldModel.phase === "survey" && parsedAction.type === "tool" && !isRepoInspectionAction(parsedAction)) {
|
|
34806
|
+
transcriptEntry.runtimeNote = "Rejected phase-inconsistent action because survey phase still requires repo inspection.";
|
|
34807
|
+
transcript.push(transcriptEntry);
|
|
34808
|
+
await emitProgress({
|
|
34809
|
+
type: "task-note",
|
|
34810
|
+
sessionId,
|
|
34811
|
+
taskId: task.id,
|
|
34812
|
+
agentRole: task.agentRole,
|
|
34813
|
+
step,
|
|
34814
|
+
message: "Survey phase requires file/repo inspection before implementation or verification."
|
|
34815
|
+
});
|
|
34816
|
+
messages.push({
|
|
34817
|
+
role: "user",
|
|
34818
|
+
content: [
|
|
34819
|
+
"The current execution phase is survey.",
|
|
34820
|
+
"Inspect likely source files and repository context first with file.read, file.search, file.list, repo.index, repo.query, or git.diff.",
|
|
34821
|
+
"Do not jump to runtime validation or edits before you understand the target files."
|
|
34822
|
+
].join("\n")
|
|
34823
|
+
});
|
|
34824
|
+
continue;
|
|
34825
|
+
}
|
|
34826
|
+
if (worldModel.phase === "verify" && parsedAction.type === "tool" && !isVerificationAction(parsedAction) && !isRepoInspectionAction(parsedAction)) {
|
|
34827
|
+
transcriptEntry.runtimeNote = "Rejected phase-inconsistent action because verify phase requires proof or diff review.";
|
|
34828
|
+
transcript.push(transcriptEntry);
|
|
34829
|
+
await emitProgress({
|
|
34830
|
+
type: "task-note",
|
|
34831
|
+
sessionId,
|
|
34832
|
+
taskId: task.id,
|
|
34833
|
+
agentRole: task.agentRole,
|
|
34834
|
+
step,
|
|
34835
|
+
message: strategicVerifier ? `Verify phase requires proof. Run ${strategicVerifier} or inspect the diff.` : "Verify phase requires proof. Use a non-interactive verifier or inspect the diff."
|
|
34836
|
+
});
|
|
34837
|
+
messages.push({
|
|
34838
|
+
role: "user",
|
|
34839
|
+
content: [
|
|
34840
|
+
"The current execution phase is verify.",
|
|
34841
|
+
strategicVerifier ? `Run the strategic verifier next: ${strategicVerifier}.` : "Run the best non-interactive verifier next.",
|
|
34842
|
+
"Only use diff/inspection actions here if you still need proof context before finishing."
|
|
34843
|
+
].join("\n")
|
|
34844
|
+
});
|
|
34845
|
+
continue;
|
|
34846
|
+
}
|
|
34192
34847
|
if (parsedAction.type === "finish") {
|
|
34193
34848
|
if (changedWorkspace && !verifiedAfterLatestChange) {
|
|
34194
34849
|
transcriptEntry.runtimeNote = "Finish rejected because code changed without a successful verification step.";
|
|
@@ -34205,31 +34860,77 @@ ${truncateForModel(customAgentMemory)}`);
|
|
|
34205
34860
|
role: "user",
|
|
34206
34861
|
content: [
|
|
34207
34862
|
"You tried to finish after making code changes without a successful verification step.",
|
|
34208
|
-
"Run tests.run or a build/lint/test shell command, inspect failures, and only finish after verification passes."
|
|
34863
|
+
strategicVerifier ? `Run the strategic verifier next: ${strategicVerifier}.` : "Run tests.run or a build/lint/test shell command, inspect failures, and only finish after verification passes."
|
|
34864
|
+
].join("\n")
|
|
34865
|
+
});
|
|
34866
|
+
continue;
|
|
34867
|
+
}
|
|
34868
|
+
if (worldModel.phase !== "finalize") {
|
|
34869
|
+
transcriptEntry.runtimeNote = `Finish rejected because the task is still in ${worldModel.phase} phase.`;
|
|
34870
|
+
transcript.push(transcriptEntry);
|
|
34871
|
+
await emitProgress({
|
|
34872
|
+
type: "task-note",
|
|
34873
|
+
sessionId,
|
|
34874
|
+
taskId: task.id,
|
|
34875
|
+
agentRole: task.agentRole,
|
|
34876
|
+
step,
|
|
34877
|
+
message: `Finish rejected because the task is still in ${worldModel.phase} phase.`
|
|
34878
|
+
});
|
|
34879
|
+
messages.push({
|
|
34880
|
+
role: "user",
|
|
34881
|
+
content: [
|
|
34882
|
+
`The task is still in ${worldModel.phase} phase.`,
|
|
34883
|
+
...derivePhaseGuidance(worldModel),
|
|
34884
|
+
"Do the next strategic action instead of finishing early."
|
|
34885
|
+
].join("\n")
|
|
34886
|
+
});
|
|
34887
|
+
continue;
|
|
34888
|
+
}
|
|
34889
|
+
if (worldModel.proofPending.length > 0 && worldModel.proofSatisfied.length === 0) {
|
|
34890
|
+
transcriptEntry.runtimeNote = "Finish rejected because the task still has pending proof and no satisfied verifier evidence.";
|
|
34891
|
+
transcript.push(transcriptEntry);
|
|
34892
|
+
await emitProgress({
|
|
34893
|
+
type: "task-note",
|
|
34894
|
+
sessionId,
|
|
34895
|
+
taskId: task.id,
|
|
34896
|
+
agentRole: task.agentRole,
|
|
34897
|
+
step,
|
|
34898
|
+
message: "Finish rejected because the task still has pending proof requirements."
|
|
34899
|
+
});
|
|
34900
|
+
messages.push({
|
|
34901
|
+
role: "user",
|
|
34902
|
+
content: [
|
|
34903
|
+
"You still owe proof for this task before finishing.",
|
|
34904
|
+
`Pending proof: ${worldModel.proofPending.join(" | ")}`,
|
|
34905
|
+
strategicVerifier ? `Run the strategic verifier next: ${strategicVerifier}.` : "Run the best non-interactive verifier, then finish only after the proof is captured."
|
|
34209
34906
|
].join("\n")
|
|
34210
34907
|
});
|
|
34211
34908
|
continue;
|
|
34212
34909
|
}
|
|
34213
34910
|
const transcriptPath2 = await writeTranscriptArtifact(request.cwd, sessionId, task.id, transcript.concat(transcriptEntry));
|
|
34214
34911
|
artifacts.add(transcriptPath2);
|
|
34215
|
-
|
|
34216
|
-
|
|
34217
|
-
|
|
34218
|
-
|
|
34219
|
-
|
|
34220
|
-
usage: usageTotals
|
|
34912
|
+
worldModel = {
|
|
34913
|
+
...worldModel,
|
|
34914
|
+
phase: "finalize",
|
|
34915
|
+
nextFocus: "Task completed.",
|
|
34916
|
+
lastUpdatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
34221
34917
|
};
|
|
34918
|
+
return makeOutcome("completed", parsedAction.summary);
|
|
34222
34919
|
}
|
|
34223
34920
|
if (parsedAction.type === "block") {
|
|
34224
34921
|
const transcriptPath2 = await writeTranscriptArtifact(request.cwd, sessionId, task.id, transcript.concat(transcriptEntry));
|
|
34225
34922
|
artifacts.add(transcriptPath2);
|
|
34226
|
-
|
|
34227
|
-
|
|
34228
|
-
|
|
34229
|
-
|
|
34230
|
-
|
|
34231
|
-
|
|
34923
|
+
worldModel = {
|
|
34924
|
+
...worldModel,
|
|
34925
|
+
phase: "escalate",
|
|
34926
|
+
blockers: uniqueStrings2([
|
|
34927
|
+
...worldModel.blockers,
|
|
34928
|
+
parsedAction.reason
|
|
34929
|
+
]),
|
|
34930
|
+
nextFocus: "Supervisor should inspect the reported blocker and adjust the task graph.",
|
|
34931
|
+
lastUpdatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
34232
34932
|
};
|
|
34933
|
+
return makeOutcome("blocked", parsedAction.reason);
|
|
34233
34934
|
}
|
|
34234
34935
|
if (!allowedTools.includes(parsedAction.tool)) {
|
|
34235
34936
|
transcriptEntry.runtimeNote = `Rejected disallowed tool "${parsedAction.tool}" for ${agent.role}.`;
|
|
@@ -34274,6 +34975,67 @@ ${truncateForModel(customAgentMemory)}`);
|
|
|
34274
34975
|
});
|
|
34275
34976
|
continue;
|
|
34276
34977
|
}
|
|
34978
|
+
if (isVerificationAction(parsedAction) && strategicVerifier && extractShellCommand(parsedAction) && extractShellCommand(parsedAction) !== strategicVerifier) {
|
|
34979
|
+
transcriptEntry.runtimeNote = "Verification command rejected because it does not match the current strategic verifier.";
|
|
34980
|
+
transcript.push(transcriptEntry);
|
|
34981
|
+
await emitProgress({
|
|
34982
|
+
type: "task-note",
|
|
34983
|
+
sessionId,
|
|
34984
|
+
taskId: task.id,
|
|
34985
|
+
agentRole: task.agentRole,
|
|
34986
|
+
step,
|
|
34987
|
+
message: `Verification should follow the strategic order. Prefer ${strategicVerifier} next.`
|
|
34988
|
+
});
|
|
34989
|
+
messages.push({
|
|
34990
|
+
role: "user",
|
|
34991
|
+
content: [
|
|
34992
|
+
"Use the strategic verification path instead of picking a random verifier.",
|
|
34993
|
+
`Preferred next verifier: ${strategicVerifier}`
|
|
34994
|
+
].join("\n")
|
|
34995
|
+
});
|
|
34996
|
+
continue;
|
|
34997
|
+
}
|
|
34998
|
+
if (allowedTools.includes("file.read") && isShellFileInspectionAction(parsedAction)) {
|
|
34999
|
+
transcriptEntry.runtimeNote = "Rejected shell-based file inspection because file.read is available.";
|
|
35000
|
+
transcript.push(transcriptEntry);
|
|
35001
|
+
await emitProgress({
|
|
35002
|
+
type: "task-note",
|
|
35003
|
+
sessionId,
|
|
35004
|
+
taskId: task.id,
|
|
35005
|
+
agentRole: task.agentRole,
|
|
35006
|
+
step,
|
|
35007
|
+
message: "Use file.read or repo/file tools instead of cat/head/wc/sed shell commands for source inspection."
|
|
35008
|
+
});
|
|
35009
|
+
messages.push({
|
|
35010
|
+
role: "user",
|
|
35011
|
+
content: [
|
|
35012
|
+
"Do not use shell.exec for simple repo file inspection when file.read is available.",
|
|
35013
|
+
"Use file.read, file.search, file.list, repo.query, or git.diff instead."
|
|
35014
|
+
].join("\n")
|
|
35015
|
+
});
|
|
35016
|
+
continue;
|
|
35017
|
+
}
|
|
35018
|
+
if (request.workspaceState === "existing" && (task.type === "scaffold" || task.type === "implementation") && !appliedSourceEdit && isRuntimeValidationAction(parsedAction) && preEditValidationActions >= 1) {
|
|
35019
|
+
transcriptEntry.runtimeNote = "Rejected repeated validation/runtime loop before any source edit.";
|
|
35020
|
+
transcript.push(transcriptEntry);
|
|
35021
|
+
await emitProgress({
|
|
35022
|
+
type: "task-note",
|
|
35023
|
+
sessionId,
|
|
35024
|
+
taskId: task.id,
|
|
35025
|
+
agentRole: task.agentRole,
|
|
35026
|
+
step,
|
|
35027
|
+
message: "Repeated build/dev/browser verification was stopped because no source edit has landed yet."
|
|
35028
|
+
});
|
|
35029
|
+
messages.push({
|
|
35030
|
+
role: "user",
|
|
35031
|
+
content: [
|
|
35032
|
+
"You already used one baseline verification/runtime check before making a source edit.",
|
|
35033
|
+
"Do not keep rerunning build, lint, dev server, browser, or HTTP checks unchanged.",
|
|
35034
|
+
"Inspect likely source files, make a concrete edit with file.patch or file.write, and then validate again."
|
|
35035
|
+
].join("\n")
|
|
35036
|
+
});
|
|
35037
|
+
continue;
|
|
35038
|
+
}
|
|
34277
35039
|
const execution = await runToolAction(parsedAction, step);
|
|
34278
35040
|
if (execution.budgetExceeded) {
|
|
34279
35041
|
transcriptEntry.runtimeNote = execution.budgetExceeded;
|
|
@@ -34284,14 +35046,9 @@ ${truncateForModel(customAgentMemory)}`);
|
|
|
34284
35046
|
transcriptEntry.runtimeNote = execution.approvalRequest.reason;
|
|
34285
35047
|
const transcriptPath2 = await writeTranscriptArtifact(request.cwd, sessionId, task.id, transcript.concat(transcriptEntry));
|
|
34286
35048
|
artifacts.add(transcriptPath2);
|
|
34287
|
-
return {
|
|
34288
|
-
|
|
34289
|
-
|
|
34290
|
-
toolResults,
|
|
34291
|
-
artifacts: Array.from(artifacts),
|
|
34292
|
-
approvalRequest: execution.approvalRequest,
|
|
34293
|
-
usage: usageTotals
|
|
34294
|
-
};
|
|
35049
|
+
return makeOutcome("awaiting-approval", execution.approvalRequest.reason, {
|
|
35050
|
+
approvalRequest: execution.approvalRequest
|
|
35051
|
+
});
|
|
34295
35052
|
}
|
|
34296
35053
|
if (!execution.result) {
|
|
34297
35054
|
throw new Error(`Tool ${parsedAction.tool} did not return a result.`);
|
|
@@ -34311,21 +35068,21 @@ ${truncateForModel(customAgentMemory)}`);
|
|
|
34311
35068
|
message: task.agentRole !== "test-debugger" ? `Step budget exhausted after ${maxSteps} steps; handing task to test-debugger.` : `Step budget exhausted after ${maxSteps} steps; debugger escalation exhausted.`
|
|
34312
35069
|
});
|
|
34313
35070
|
if (task.agentRole !== "test-debugger") {
|
|
34314
|
-
|
|
34315
|
-
|
|
34316
|
-
|
|
34317
|
-
|
|
34318
|
-
|
|
34319
|
-
usage: usageTotals
|
|
35071
|
+
worldModel = {
|
|
35072
|
+
...worldModel,
|
|
35073
|
+
phase: "escalate",
|
|
35074
|
+
nextFocus: "Hand off the task to test-debugger with the current world-model and transcript.",
|
|
35075
|
+
lastUpdatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
34320
35076
|
};
|
|
35077
|
+
return makeOutcome("handoff", `Autonomous executor reached the step limit (${maxSteps}) for ${task.id}; handing off to test-debugger.`);
|
|
34321
35078
|
}
|
|
34322
|
-
|
|
34323
|
-
|
|
34324
|
-
|
|
34325
|
-
|
|
34326
|
-
|
|
34327
|
-
usage: usageTotals
|
|
35079
|
+
worldModel = {
|
|
35080
|
+
...worldModel,
|
|
35081
|
+
phase: "escalate",
|
|
35082
|
+
nextFocus: "Debugger escalation is exhausted; supervisor must replan or accept the blocker.",
|
|
35083
|
+
lastUpdatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
34328
35084
|
};
|
|
35085
|
+
return makeOutcome("blocked", `Autonomous executor reached the step limit (${maxSteps}) for ${task.id}; debugger escalation exhausted.`);
|
|
34329
35086
|
}
|
|
34330
35087
|
};
|
|
34331
35088
|
|
|
@@ -35036,6 +35793,26 @@ function buildSummary(shape, goal) {
|
|
|
35036
35793
|
}
|
|
35037
35794
|
return `Deliver "${goal}" through structured analysis, implementation, and verification milestones.`;
|
|
35038
35795
|
}
|
|
35796
|
+
function buildPlanningSeedSummary(goal) {
|
|
35797
|
+
return `Create the best executable task graph for "${goal}" with dynamically chosen milestones, task count, and verification.`;
|
|
35798
|
+
}
|
|
35799
|
+
function planningSeedMilestone() {
|
|
35800
|
+
return {
|
|
35801
|
+
id: "m1-planning-seed",
|
|
35802
|
+
title: "Planning Seed",
|
|
35803
|
+
objective: "Schema-valid placeholder context for the planner model. Replace this seed with a real executable plan.",
|
|
35804
|
+
tasks: [
|
|
35805
|
+
buildTask("seed-plan-task", "Replace this planning seed with the real task graph", "This placeholder exists only so the planner model receives a schema-valid example. The final plan should replace it with concrete milestones and executable tasks tailored to the goal.", "planner", "documentation", [], [
|
|
35806
|
+
"The final plan removes the placeholder task.",
|
|
35807
|
+
"The final plan contains executable tasks with explicit dependencies and verification."
|
|
35808
|
+
], [
|
|
35809
|
+
"Executable task graph"
|
|
35810
|
+
], [
|
|
35811
|
+
"."
|
|
35812
|
+
], "low")
|
|
35813
|
+
]
|
|
35814
|
+
};
|
|
35815
|
+
}
|
|
35039
35816
|
function createPlan(input) {
|
|
35040
35817
|
const request = PlanRequestSchema.parse({
|
|
35041
35818
|
...input,
|
|
@@ -35065,6 +35842,33 @@ function createPlan(input) {
|
|
|
35065
35842
|
]
|
|
35066
35843
|
});
|
|
35067
35844
|
}
|
|
35845
|
+
function createPlanningSeed(input) {
|
|
35846
|
+
const request = PlanRequestSchema.parse({
|
|
35847
|
+
...input,
|
|
35848
|
+
goal: normalizeGoal(input.goal)
|
|
35849
|
+
});
|
|
35850
|
+
const shape = inferProjectShape(request.goal);
|
|
35851
|
+
return KimbhoPlanSchema.parse({
|
|
35852
|
+
goal: request.goal,
|
|
35853
|
+
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
35854
|
+
summary: buildPlanningSeedSummary(request.goal),
|
|
35855
|
+
repoStrategy: {
|
|
35856
|
+
mode: request.workspaceState === "empty" ? "greenfield" : "existing-repo",
|
|
35857
|
+
reasoning: request.workspaceState === "empty" ? "No meaningful workspace contents were detected, so the planner can choose an opinionated greenfield graph." : "Existing workspace state should be analyzed and preserved while the planner chooses the execution graph."
|
|
35858
|
+
},
|
|
35859
|
+
assumptions: deriveAssumptions(shape, request),
|
|
35860
|
+
openQuestions: deriveOpenQuestions(shape),
|
|
35861
|
+
milestones: [
|
|
35862
|
+
planningSeedMilestone()
|
|
35863
|
+
],
|
|
35864
|
+
verificationChecklist: deriveVerificationChecklist(shape),
|
|
35865
|
+
executionNotes: [
|
|
35866
|
+
"Replace the placeholder seed milestone with the real execution graph.",
|
|
35867
|
+
"Choose milestone count, task count, and dependencies dynamically from the goal.",
|
|
35868
|
+
"Keep deterministic fallback available only if model planning fails."
|
|
35869
|
+
]
|
|
35870
|
+
});
|
|
35871
|
+
}
|
|
35068
35872
|
|
|
35069
35873
|
// ../planner/dist/model-planner.js
|
|
35070
35874
|
var DEFAULT_PLANNER_TEMPERATURE = 0.1;
|
|
@@ -35148,8 +35952,8 @@ function buildPlannerSystemPrompt() {
|
|
|
35148
35952
|
"You are Kimbho's planner brain.",
|
|
35149
35953
|
"Return one JSON object only. Do not use markdown fences or prose outside the JSON.",
|
|
35150
35954
|
"The JSON must satisfy the KimbhoPlan schema used by Kimbho's runtime.",
|
|
35151
|
-
"
|
|
35152
|
-
"Keep task ids
|
|
35955
|
+
"For initial planning, choose the milestone count, task count, and task graph shape that best fits the request instead of mirroring the fallback plan.",
|
|
35956
|
+
"Keep task ids machine-friendly and stable within the returned plan.",
|
|
35153
35957
|
"Use only these agent roles:",
|
|
35154
35958
|
"- session-orchestrator",
|
|
35155
35959
|
"- repo-analyst",
|
|
@@ -35180,8 +35984,9 @@ ${request.constraints.map((constraint) => `- ${constraint}`).join("\n")}` : "",
|
|
|
35180
35984
|
"Seed plan JSON:",
|
|
35181
35985
|
JSON.stringify(seedPlan, null, 2),
|
|
35182
35986
|
"Instructions:",
|
|
35183
|
-
"-
|
|
35184
|
-
"-
|
|
35987
|
+
"- Use the seed plan only as a fallback reference, not as a task-count template.",
|
|
35988
|
+
"- Produce the best executable plan for this goal, choosing milestone count and task count dynamically.",
|
|
35989
|
+
"- You may replace the seed task ids for the initial plan if a different graph is materially better.",
|
|
35185
35990
|
"- Keep the plan concise, practical, and tool-executable."
|
|
35186
35991
|
].filter(Boolean).join("\n\n");
|
|
35187
35992
|
}
|
|
@@ -35205,7 +36010,7 @@ ${request.constraints.map((constraint) => `- ${constraint}`).join("\n")}` : "",
|
|
|
35205
36010
|
"- Adjust milestone wording, task descriptions, acceptance criteria, files, and dependencies only when the repo evidence justifies it."
|
|
35206
36011
|
].filter(Boolean).join("\n\n");
|
|
35207
36012
|
}
|
|
35208
|
-
async function generatePlannerPlan(request, seedPlan, invocation, userPrompt, preserveStatusesFrom) {
|
|
36013
|
+
async function generatePlannerPlan(request, seedPlan, fallbackPlan, invocation, userPrompt, preserveStatusesFrom, requireStableTaskIds = true) {
|
|
35209
36014
|
try {
|
|
35210
36015
|
const response = await invocation.generate({
|
|
35211
36016
|
systemPrompt: buildPlannerSystemPrompt(),
|
|
@@ -35215,7 +36020,7 @@ async function generatePlannerPlan(request, seedPlan, invocation, userPrompt, pr
|
|
|
35215
36020
|
});
|
|
35216
36021
|
const parsed = extractJsonObjectish(response.text, "planner response");
|
|
35217
36022
|
const candidatePlan = KimbhoPlanSchema.parse(parsed);
|
|
35218
|
-
const normalized = normalizeCandidatePlan(request,
|
|
36023
|
+
const normalized = normalizeCandidatePlan(request, fallbackPlan, candidatePlan, requireStableTaskIds, preserveStatusesFrom);
|
|
35219
36024
|
return {
|
|
35220
36025
|
plan: normalized,
|
|
35221
36026
|
source: "model",
|
|
@@ -35229,7 +36034,7 @@ async function generatePlannerPlan(request, seedPlan, invocation, userPrompt, pr
|
|
|
35229
36034
|
};
|
|
35230
36035
|
} catch (error2) {
|
|
35231
36036
|
return {
|
|
35232
|
-
plan: preserveStatusesFrom ? preserveTaskStatuses(preserveStatusesFrom,
|
|
36037
|
+
plan: preserveStatusesFrom ? preserveTaskStatuses(preserveStatusesFrom, fallbackPlan) : fallbackPlan,
|
|
35233
36038
|
source: "fallback",
|
|
35234
36039
|
warning: summarizeStructuredOutputError("Planner", error2),
|
|
35235
36040
|
...invocation.modelLabel ? {
|
|
@@ -35239,18 +36044,19 @@ async function generatePlannerPlan(request, seedPlan, invocation, userPrompt, pr
|
|
|
35239
36044
|
}
|
|
35240
36045
|
}
|
|
35241
36046
|
async function createPlanWithModel(request, invocation) {
|
|
35242
|
-
const
|
|
35243
|
-
|
|
36047
|
+
const fallbackPlan = createPlan(request);
|
|
36048
|
+
const seedPlan = createPlanningSeed(request);
|
|
36049
|
+
return generatePlannerPlan(request, seedPlan, fallbackPlan, invocation, buildInitialPlannerPrompt(request, seedPlan), void 0, false);
|
|
35244
36050
|
}
|
|
35245
36051
|
async function revisePlanWithModel(request, currentPlan, repoSummary, invocation) {
|
|
35246
|
-
return generatePlannerPlan(request, currentPlan, invocation, buildReplanPrompt(request, currentPlan, repoSummary), currentPlan);
|
|
36052
|
+
return generatePlannerPlan(request, currentPlan, currentPlan, invocation, buildReplanPrompt(request, currentPlan, repoSummary), currentPlan);
|
|
35247
36053
|
}
|
|
35248
36054
|
|
|
35249
36055
|
// ../planner/dist/task-expander.js
|
|
35250
36056
|
var DEFAULT_EXPANDER_TEMPERATURE = 0.1;
|
|
35251
36057
|
var DEFAULT_EXPANDER_MAX_TOKENS = 1600;
|
|
35252
36058
|
var MAX_EXPANSION_CONTEXT_CHARS = 6e3;
|
|
35253
|
-
var MAX_EXPANDED_SUBTASKS =
|
|
36059
|
+
var MAX_EXPANDED_SUBTASKS = 6;
|
|
35254
36060
|
var ExpansionCandidateTaskSchema = external_exports.object({
|
|
35255
36061
|
id: external_exports.string().min(1).optional(),
|
|
35256
36062
|
title: external_exports.string().min(1),
|
|
@@ -35310,7 +36116,7 @@ function createEntrySubtask(task, suffix, title, description) {
|
|
|
35310
36116
|
};
|
|
35311
36117
|
}
|
|
35312
36118
|
function fallbackExpandedTasks(task) {
|
|
35313
|
-
if ((task.swarmDepth ?? 0) >=
|
|
36119
|
+
if ((task.swarmDepth ?? 0) >= 2) {
|
|
35314
36120
|
return null;
|
|
35315
36121
|
}
|
|
35316
36122
|
if (task.agentRole === "frontend-specialist" && task.type === "implementation") {
|
|
@@ -35326,10 +36132,24 @@ function fallbackExpandedTasks(task) {
|
|
|
35326
36132
|
]
|
|
35327
36133
|
},
|
|
35328
36134
|
{
|
|
35329
|
-
...createEntrySubtask(task, "
|
|
36135
|
+
...createEntrySubtask(task, "interaction", `Design ${task.title.toLowerCase()} interaction and motion`, `Define animation, scroll behavior, and interaction states once the content structure is clear.`),
|
|
35330
36136
|
dependsOn: [
|
|
35331
36137
|
`${task.id}-content`
|
|
35332
36138
|
],
|
|
36139
|
+
acceptanceCriteria: [
|
|
36140
|
+
"Interaction patterns and motion direction are explicit.",
|
|
36141
|
+
"Primary calls to action and navigation states feel intentional."
|
|
36142
|
+
],
|
|
36143
|
+
outputs: [
|
|
36144
|
+
"Interaction and motion direction"
|
|
36145
|
+
]
|
|
36146
|
+
},
|
|
36147
|
+
{
|
|
36148
|
+
...createEntrySubtask(task, "polish", `Polish ${task.title.toLowerCase()} visuals and responsiveness`, `Refine styling, responsiveness, and interaction details after the content structure is in place.`),
|
|
36149
|
+
dependsOn: [
|
|
36150
|
+
`${task.id}-content`,
|
|
36151
|
+
`${task.id}-interaction`
|
|
36152
|
+
],
|
|
35333
36153
|
acceptanceCriteria: [
|
|
35334
36154
|
...task.acceptanceCriteria,
|
|
35335
36155
|
"Responsive behavior and visual polish are verified."
|
|
@@ -35532,9 +36352,10 @@ function buildExpansionPrompt(request, plan, task, repoSummary) {
|
|
|
35532
36352
|
"Repo context:",
|
|
35533
36353
|
truncate2(repoSummary),
|
|
35534
36354
|
"Instructions:",
|
|
35535
|
-
|
|
36355
|
+
`- Replace the target task with 2-${MAX_EXPANDED_SUBTASKS} narrower subtasks.`,
|
|
35536
36356
|
"- Preserve the target task's overall intent, but make execution more parallel-friendly when safe.",
|
|
35537
36357
|
"- Keep dependencies explicit and machine-valid.",
|
|
36358
|
+
"- Prefer at least 3 subtasks for broad frontend or product-surface work when the task can be split safely.",
|
|
35538
36359
|
"- Prefer roles like frontend-specialist, backend-specialist, database-specialist, infra-specialist, reviewer, and test-debugger when they fit."
|
|
35539
36360
|
].join("\n\n");
|
|
35540
36361
|
}
|
|
@@ -35551,7 +36372,7 @@ ${task.acceptanceCriteria.map((criterion) => `- ${criterion}`).join("\n") || "-
|
|
|
35551
36372
|
].filter(Boolean).join("\n\n");
|
|
35552
36373
|
}
|
|
35553
36374
|
function shouldExpandTask(task) {
|
|
35554
|
-
if ((task.swarmDepth ?? 0) >=
|
|
36375
|
+
if ((task.swarmDepth ?? 0) >= 2) {
|
|
35555
36376
|
return false;
|
|
35556
36377
|
}
|
|
35557
36378
|
if (task.type !== "implementation") {
|
|
@@ -36625,6 +37446,15 @@ function updateTaskStatus(plan, taskId, status) {
|
|
|
36625
37446
|
milestones
|
|
36626
37447
|
};
|
|
36627
37448
|
}
|
|
37449
|
+
function updateTaskExecutionState(plan, taskId, executionState) {
|
|
37450
|
+
if (!executionState) {
|
|
37451
|
+
return plan;
|
|
37452
|
+
}
|
|
37453
|
+
return replaceTask(plan, taskId, (task) => ({
|
|
37454
|
+
...task,
|
|
37455
|
+
executionState
|
|
37456
|
+
}));
|
|
37457
|
+
}
|
|
36628
37458
|
function replaceTask(plan, taskId, mapper) {
|
|
36629
37459
|
const milestones = plan.milestones.map((milestone) => ({
|
|
36630
37460
|
...milestone,
|
|
@@ -36673,9 +37503,6 @@ function shouldDelegateTask(task, request) {
|
|
|
36673
37503
|
if (!canSpawnSubagents) {
|
|
36674
37504
|
return false;
|
|
36675
37505
|
}
|
|
36676
|
-
if ((looksLikeVisualAdjustmentGoal(request.goal) || looksLikePageExpansionGoal(request.goal)) && isStaticSiteTask(task, request)) {
|
|
36677
|
-
return false;
|
|
36678
|
-
}
|
|
36679
37506
|
return (task.swarmDepth ?? 0) < maxSubagentDepth && task.type === "implementation" && ![
|
|
36680
37507
|
"repo-analyst",
|
|
36681
37508
|
"planner",
|
|
@@ -36714,6 +37541,20 @@ function createDefaultDelegationPlan(task, request) {
|
|
|
36714
37541
|
"Structured page/content update"
|
|
36715
37542
|
]
|
|
36716
37543
|
},
|
|
37544
|
+
{
|
|
37545
|
+
id: "interaction-designer",
|
|
37546
|
+
label: "interaction-designer",
|
|
37547
|
+
agentRole: "frontend-specialist",
|
|
37548
|
+
description: "Own motion design, interaction states, scroll behavior, and narrative pacing.",
|
|
37549
|
+
instructions: "Focus on animation, interaction states, scroll rhythm, and motion hierarchy. Keep motion purposeful and aligned with the requested design direction.",
|
|
37550
|
+
acceptanceCriteria: [
|
|
37551
|
+
"Interaction patterns and motion choices are explicit.",
|
|
37552
|
+
"The page has a coherent motion system without distracting from the content."
|
|
37553
|
+
],
|
|
37554
|
+
outputs: [
|
|
37555
|
+
"Interaction and motion design update"
|
|
37556
|
+
]
|
|
37557
|
+
},
|
|
36717
37558
|
{
|
|
36718
37559
|
id: "visual-polisher",
|
|
36719
37560
|
label: "visual-polisher",
|
|
@@ -37048,6 +37889,44 @@ ${result.stderr.slice(0, 1e3)}`);
|
|
|
37048
37889
|
return lines.join("\n");
|
|
37049
37890
|
}).join("\n\n");
|
|
37050
37891
|
}
|
|
37892
|
+
function renderTaskWorldModelContext(task, outcome) {
|
|
37893
|
+
const worldModel = outcome.worldModel;
|
|
37894
|
+
if (!worldModel) {
|
|
37895
|
+
return [
|
|
37896
|
+
`task: ${task.id}`,
|
|
37897
|
+
`status: ${outcome.status}`,
|
|
37898
|
+
`summary: ${outcome.summary}`
|
|
37899
|
+
].join("\n");
|
|
37900
|
+
}
|
|
37901
|
+
return [
|
|
37902
|
+
`task: ${task.id}`,
|
|
37903
|
+
`status: ${outcome.status}`,
|
|
37904
|
+
`summary: ${outcome.summary}`,
|
|
37905
|
+
`phase: ${worldModel.phase}`,
|
|
37906
|
+
`next focus: ${worldModel.nextFocus ?? "(unset)"}`,
|
|
37907
|
+
`target files: ${worldModel.targetFiles.join(", ") || "(none)"}`,
|
|
37908
|
+
`inspected files: ${worldModel.inspectedFiles.join(", ") || "(none)"}`,
|
|
37909
|
+
`changed files: ${worldModel.changedFiles.join(", ") || "(none)"}`,
|
|
37910
|
+
`blockers: ${worldModel.blockers.join(" | ") || "(none)"}`,
|
|
37911
|
+
`proof pending: ${worldModel.proofPending.join(" | ") || "(none)"}`,
|
|
37912
|
+
`proof satisfied: ${worldModel.proofSatisfied.join(" | ") || "(none)"}`,
|
|
37913
|
+
`recent actions: ${worldModel.recentActions.join(" | ") || "(none)"}`,
|
|
37914
|
+
`preferred verifiers: ${worldModel.verifier.preferredCommands.join(", ") || "(none)"}`,
|
|
37915
|
+
`latest verifier failure: ${worldModel.verifier.latestFailureSummary ?? "(none)"}`
|
|
37916
|
+
].join("\n");
|
|
37917
|
+
}
|
|
37918
|
+
function shouldRevisePlanAfterTaskOutcome(task, outcome) {
|
|
37919
|
+
if (task.agentRole === "repo-analyst" || task.agentRole === "planner") {
|
|
37920
|
+
return false;
|
|
37921
|
+
}
|
|
37922
|
+
if (outcome.supervisorHints?.shouldReplan || outcome.supervisorHints?.shouldReprioritize || outcome.supervisorHints?.shouldMergeDelegatedWork) {
|
|
37923
|
+
return true;
|
|
37924
|
+
}
|
|
37925
|
+
if (outcome.status === "blocked" || outcome.status === "handoff") {
|
|
37926
|
+
return true;
|
|
37927
|
+
}
|
|
37928
|
+
return Boolean(task.parentTaskId && outcome.worldModel && (outcome.worldModel.phase === "repair" || outcome.worldModel.phase === "finalize" || outcome.worldModel.blockers.length > 0));
|
|
37929
|
+
}
|
|
37051
37930
|
function latestRepoAnalysisContext(events) {
|
|
37052
37931
|
const event = [
|
|
37053
37932
|
...events
|
|
@@ -37323,8 +38202,8 @@ var ExecutionOrchestrator = class {
|
|
|
37323
38202
|
let pendingApprovals = [
|
|
37324
38203
|
...session.pendingApprovals
|
|
37325
38204
|
];
|
|
37326
|
-
const maxAutoTasks = options.maxAutoTasks ??
|
|
37327
|
-
const maxParallelTasks = Math.max(1, options.maxParallelTasks ??
|
|
38205
|
+
const maxAutoTasks = options.maxAutoTasks ?? 4;
|
|
38206
|
+
const maxParallelTasks = Math.max(1, options.maxParallelTasks ?? 4);
|
|
37328
38207
|
let executedTasks = 0;
|
|
37329
38208
|
for (const approval of session.pendingApprovals) {
|
|
37330
38209
|
const decision = decisionByApprovalId.get(approval.id);
|
|
@@ -37485,7 +38364,13 @@ var ExecutionOrchestrator = class {
|
|
|
37485
38364
|
let sawApprovalRequest = false;
|
|
37486
38365
|
for (const batchResult of batchResults) {
|
|
37487
38366
|
const { task: autoTask, outcome } = batchResult;
|
|
37488
|
-
workingPlan =
|
|
38367
|
+
workingPlan = updateTaskExecutionState(workingPlan, autoTask.id, outcome.worldModel);
|
|
38368
|
+
workingPlan = outcome.status === "handoff" ? replaceTask(workingPlan, autoTask.id, () => ({
|
|
38369
|
+
...outcome.handoffTask ?? createDebuggerHandoffTask(autoTask, outcome, this.toolsForAgent("test-debugger").map((tool) => tool.id)),
|
|
38370
|
+
...outcome.worldModel ? {
|
|
38371
|
+
executionState: outcome.worldModel
|
|
38372
|
+
} : {}
|
|
38373
|
+
})) : updateTaskStatus(workingPlan, autoTask.id, outcome.status === "completed" ? "completed" : outcome.status === "blocked" ? "blocked" : "pending");
|
|
37489
38374
|
if (autoTask.agentRole === "repo-analyst" && outcome.status === "completed") {
|
|
37490
38375
|
const replanned = await this.maybeRevisePlanAfterRepoAnalysis(session.id, session.request, workingPlan, outcome, emitProgress);
|
|
37491
38376
|
workingPlan = replanned.plan;
|
|
@@ -37498,6 +38383,16 @@ var ExecutionOrchestrator = class {
|
|
|
37498
38383
|
});
|
|
37499
38384
|
}
|
|
37500
38385
|
}
|
|
38386
|
+
const adapted = await this.maybeRevisePlanAfterTaskOutcome(session.id, session.request, workingPlan, autoTask, outcome, emitProgress);
|
|
38387
|
+
workingPlan = adapted.plan;
|
|
38388
|
+
if (adapted.note) {
|
|
38389
|
+
notes = maybeAppendNote(notes, adapted.note);
|
|
38390
|
+
await emitProgress({
|
|
38391
|
+
type: "task-note",
|
|
38392
|
+
sessionId: session.id,
|
|
38393
|
+
message: adapted.note
|
|
38394
|
+
});
|
|
38395
|
+
}
|
|
37501
38396
|
notes = maybeAppendNote(notes, outcome.summary);
|
|
37502
38397
|
if (outcome.status === "awaiting-approval" && outcome.approvalRequest) {
|
|
37503
38398
|
pendingApprovals.push(outcome.approvalRequest);
|
|
@@ -37640,7 +38535,8 @@ var ExecutionOrchestrator = class {
|
|
|
37640
38535
|
}
|
|
37641
38536
|
const profile = AGENT_CATALOG[task.agentRole];
|
|
37642
38537
|
const currentRoleCount = roleCounts.get(task.agentRole) ?? 0;
|
|
37643
|
-
|
|
38538
|
+
const effectiveConcurrency = Math.max(profile.maxConcurrentTasks, task.agentRole === "frontend-specialist" || task.agentRole === "backend-specialist" ? 3 : profile.maxConcurrentTasks);
|
|
38539
|
+
if (currentRoleCount >= effectiveConcurrency) {
|
|
37644
38540
|
continue;
|
|
37645
38541
|
}
|
|
37646
38542
|
selected.push(task);
|
|
@@ -37660,9 +38556,6 @@ var ExecutionOrchestrator = class {
|
|
|
37660
38556
|
if (task.agentRole === "planner") {
|
|
37661
38557
|
return this.executePlannerTask(sessionId, task, request, plan, emitProgress);
|
|
37662
38558
|
}
|
|
37663
|
-
if (request.workspaceState === "existing" && isStaticSiteTask(task, request) && (task.type === "scaffold" || task.type === "implementation")) {
|
|
37664
|
-
return this.executeDeterministicStaticSiteTask(sessionId, task, request, resolvedApproval, options, emitProgress);
|
|
37665
|
-
}
|
|
37666
38559
|
if (request.workspaceState === "existing" && looksLikeStaticLandingGoal(request.goal) && task.type === "verification") {
|
|
37667
38560
|
return this.executeDeterministicVerificationTask(sessionId, task, request, emitProgress, options.signal);
|
|
37668
38561
|
}
|
|
@@ -38079,6 +38972,12 @@ var ExecutionOrchestrator = class {
|
|
|
38079
38972
|
...outcome.usage ? {
|
|
38080
38973
|
usage: outcome.usage
|
|
38081
38974
|
} : {},
|
|
38975
|
+
...outcome.worldModel ? {
|
|
38976
|
+
worldModel: outcome.worldModel
|
|
38977
|
+
} : {},
|
|
38978
|
+
...outcome.supervisorHints ? {
|
|
38979
|
+
supervisorHints: outcome.supervisorHints
|
|
38980
|
+
} : {},
|
|
38082
38981
|
...integrated.integrationFailed && integrated.conflict && task.agentRole !== "integrator" ? {
|
|
38083
38982
|
handoffTask: createIntegratorHandoffTask(task, outcome, this.toolsForAgent("integrator").map((tool) => tool.id), integrated.conflict)
|
|
38084
38983
|
} : {}
|
|
@@ -38259,6 +39158,89 @@ var ExecutionOrchestrator = class {
|
|
|
38259
39158
|
};
|
|
38260
39159
|
}
|
|
38261
39160
|
}
|
|
39161
|
+
async maybeRevisePlanAfterTaskOutcome(sessionId, request, plan, task, outcome, emitProgress) {
|
|
39162
|
+
if (!shouldRevisePlanAfterTaskOutcome(task, outcome)) {
|
|
39163
|
+
return {
|
|
39164
|
+
plan
|
|
39165
|
+
};
|
|
39166
|
+
}
|
|
39167
|
+
const config2 = await loadConfig(request.cwd);
|
|
39168
|
+
if (!config2) {
|
|
39169
|
+
return {
|
|
39170
|
+
plan
|
|
39171
|
+
};
|
|
39172
|
+
}
|
|
39173
|
+
const revisionContext = [
|
|
39174
|
+
"Task outcome context:",
|
|
39175
|
+
renderTaskWorldModelContext(task, outcome),
|
|
39176
|
+
"",
|
|
39177
|
+
"Supervisor hints:",
|
|
39178
|
+
outcome.supervisorHints ? [
|
|
39179
|
+
`- should replan: ${outcome.supervisorHints.shouldReplan ? "yes" : "no"}`,
|
|
39180
|
+
`- should reprioritize: ${outcome.supervisorHints.shouldReprioritize ? "yes" : "no"}`,
|
|
39181
|
+
`- should merge delegated work: ${outcome.supervisorHints.shouldMergeDelegatedWork ? "yes" : "no"}`,
|
|
39182
|
+
`- reason: ${outcome.supervisorHints.reason ?? "(none)"}`
|
|
39183
|
+
].join("\n") : "- none",
|
|
39184
|
+
"",
|
|
39185
|
+
"Tool evidence:",
|
|
39186
|
+
renderPlannerReplanContext(outcome.toolResults),
|
|
39187
|
+
"",
|
|
39188
|
+
"Planner instructions:",
|
|
39189
|
+
"- Reassign, merge, reorder, or split follow-up tasks if the task outcome suggests the current graph is suboptimal.",
|
|
39190
|
+
"- Preserve completed work, but feel free to adapt pending task order, dependencies, agent roles, or milestone shape.",
|
|
39191
|
+
"- Prefer making parallel work possible when blockers or delegated-worker outcomes reveal an opportunity."
|
|
39192
|
+
].join("\n");
|
|
39193
|
+
try {
|
|
39194
|
+
const brain = await new BrainResolver(config2, createDefaultBrainProviderRegistry(request.cwd)).resolve("planner");
|
|
39195
|
+
const result = await revisePlanWithModel(request, plan, revisionContext, {
|
|
39196
|
+
modelLabel: `${brain.provider.id}/${brain.model}`,
|
|
39197
|
+
...typeof brain.settings.temperature === "number" ? {
|
|
39198
|
+
temperature: brain.settings.temperature
|
|
39199
|
+
} : {},
|
|
39200
|
+
...typeof brain.settings.maxTokens === "number" ? {
|
|
39201
|
+
maxTokens: brain.settings.maxTokens
|
|
39202
|
+
} : {},
|
|
39203
|
+
generate: async (input) => brain.client.generateText({
|
|
39204
|
+
model: brain.model,
|
|
39205
|
+
systemPrompt: [
|
|
39206
|
+
brain.settings.promptPreamble,
|
|
39207
|
+
input.systemPrompt
|
|
39208
|
+
].filter(Boolean).join("\n\n"),
|
|
39209
|
+
userPrompt: input.userPrompt,
|
|
39210
|
+
responseFormat: "json_object",
|
|
39211
|
+
...typeof input.temperature === "number" ? {
|
|
39212
|
+
temperature: input.temperature
|
|
39213
|
+
} : {},
|
|
39214
|
+
...typeof input.maxTokens === "number" ? {
|
|
39215
|
+
maxTokens: input.maxTokens
|
|
39216
|
+
} : {}
|
|
39217
|
+
})
|
|
39218
|
+
});
|
|
39219
|
+
if (result.source === "model") {
|
|
39220
|
+
return {
|
|
39221
|
+
plan: result.plan,
|
|
39222
|
+
note: `Planner brain adapted the active task graph after ${task.id} via ${brain.provider.id}/${brain.model}.`
|
|
39223
|
+
};
|
|
39224
|
+
}
|
|
39225
|
+
return {
|
|
39226
|
+
plan,
|
|
39227
|
+
...result.warning ? {
|
|
39228
|
+
note: `${result.warning} Keeping the current task graph.`
|
|
39229
|
+
} : {}
|
|
39230
|
+
};
|
|
39231
|
+
} catch (error2) {
|
|
39232
|
+
if (emitProgress) {
|
|
39233
|
+
await emitProgress({
|
|
39234
|
+
type: "task-note",
|
|
39235
|
+
sessionId,
|
|
39236
|
+
message: `Planner task adaptation skipped: ${error2 instanceof Error ? error2.message : String(error2)}`
|
|
39237
|
+
});
|
|
39238
|
+
}
|
|
39239
|
+
return {
|
|
39240
|
+
plan
|
|
39241
|
+
};
|
|
39242
|
+
}
|
|
39243
|
+
}
|
|
38262
39244
|
async maybeExpandReadyTaskGraph(sessionId, request, plan, events, emitProgress) {
|
|
38263
39245
|
const envelope = this.buildEnvelope(request, plan, sessionId);
|
|
38264
39246
|
const candidate = envelope.readyTasks.find((task) => shouldDelegateTask(task, request));
|
|
@@ -39693,7 +40675,7 @@ async function executePromptByIntent(cwd, input, options = {}) {
|
|
|
39693
40675
|
}
|
|
39694
40676
|
return executeRunPrompt(cwd, input, options.outputFormat ?? "json", {
|
|
39695
40677
|
ephemeral: options.ephemeral ?? false,
|
|
39696
|
-
maxAutoTasks: options.maxAutoTasks ??
|
|
40678
|
+
maxAutoTasks: options.maxAutoTasks ?? 4,
|
|
39697
40679
|
maxAgentSteps: options.maxAgentSteps ?? 8,
|
|
39698
40680
|
maxRepairAttempts: options.maxRepairAttempts ?? 2,
|
|
39699
40681
|
...options.sessionId ? {
|
|
@@ -39714,7 +40696,7 @@ function createExecCommand() {
|
|
|
39714
40696
|
], []).option("--image <pathOrUrl>", "Attach an image to the prompt", (value, previous = []) => [
|
|
39715
40697
|
...previous,
|
|
39716
40698
|
value
|
|
39717
|
-
], []).option("--max-auto-tasks <count>", "Maximum ready tasks to auto-execute", parseCount,
|
|
40699
|
+
], []).option("--max-auto-tasks <count>", "Maximum ready tasks to auto-execute", parseCount, 4).option("--max-agent-steps <count>", "Maximum tool/model steps per autonomous task", parseCount, 8).option("--max-repair-attempts <count>", "Maximum failed verification cycles per autonomous task", parseCount, 2).action(async (rawPrompt, options) => {
|
|
39718
40700
|
const cwd = import_node_process5.default.cwd();
|
|
39719
40701
|
const format = options.json ? "json" : options.outputFormat;
|
|
39720
40702
|
const agentSelection = await resolveAgentSelection(cwd, {
|
|
@@ -42190,7 +43172,7 @@ async function resolveSourceSession(cwd, sessionId, last = false, search) {
|
|
|
42190
43172
|
return loadSessionById(sessionId, cwd);
|
|
42191
43173
|
}
|
|
42192
43174
|
function createForkCommand() {
|
|
42193
|
-
return new Command("fork").description("Fork a saved session into a new session snapshot.").argument("[sessionId]", "Optional session id; defaults to the latest session").option("--last", "Fork the most recent session", false).option("--list", "List recent sessions and exit", false).option("--search <query>", "Filter sessions by id, goal, cwd, or labels").option("--json", "Print the forked snapshot as JSON", false).option("--execute", "Continue auto-executing the forked session", false).option("--max-auto-tasks <count>", "Maximum ready tasks to auto-execute", parseCount3,
|
|
43175
|
+
return new Command("fork").description("Fork a saved session into a new session snapshot.").argument("[sessionId]", "Optional session id; defaults to the latest session").option("--last", "Fork the most recent session", false).option("--list", "List recent sessions and exit", false).option("--search <query>", "Filter sessions by id, goal, cwd, or labels").option("--json", "Print the forked snapshot as JSON", false).option("--execute", "Continue auto-executing the forked session", false).option("--max-auto-tasks <count>", "Maximum ready tasks to auto-execute", parseCount3, 4).option("--max-agent-steps <count>", "Maximum tool/model steps per autonomous task", parseCount3, 8).option("--max-repair-attempts <count>", "Maximum failed verification cycles per autonomous task", parseCount3, 2).action(async (sessionId, options) => {
|
|
42194
43176
|
const cwd = import_node_process12.default.cwd();
|
|
42195
43177
|
if (options.list) {
|
|
42196
43178
|
const sessions = options.search ? await searchSessions(options.search, cwd) : await listSessions(cwd);
|
|
@@ -43360,7 +44342,7 @@ function parseCount4(value) {
|
|
|
43360
44342
|
return parsed;
|
|
43361
44343
|
}
|
|
43362
44344
|
function createResumeCommand() {
|
|
43363
|
-
return new Command("resume").alias("continue").description("Resume the latest saved Kimbho session snapshot.").argument("[sessionId]", "Optional session id; defaults to the latest session").option("--json", "Print the latest session as JSON", false).option("--last", "Resume the most recent session", false).option("--list", "List recent sessions and exit", false).option("--search <query>", "Filter sessions by id, goal, cwd, or labels").option("--execute", "Continue auto-executing the ready-task frontier", false).option("--approve <approvalId>", "Approve a pending action before continuing").option("--deny <approvalId>", "Deny a pending action before continuing").option("--max-auto-tasks <count>", "Maximum ready tasks to auto-execute", parseCount4,
|
|
44345
|
+
return new Command("resume").alias("continue").description("Resume the latest saved Kimbho session snapshot.").argument("[sessionId]", "Optional session id; defaults to the latest session").option("--json", "Print the latest session as JSON", false).option("--last", "Resume the most recent session", false).option("--list", "List recent sessions and exit", false).option("--search <query>", "Filter sessions by id, goal, cwd, or labels").option("--execute", "Continue auto-executing the ready-task frontier", false).option("--approve <approvalId>", "Approve a pending action before continuing").option("--deny <approvalId>", "Deny a pending action before continuing").option("--max-auto-tasks <count>", "Maximum ready tasks to auto-execute", parseCount4, 4).option("--max-agent-steps <count>", "Maximum tool/model steps per autonomous task", parseCount4, 8).option("--max-repair-attempts <count>", "Maximum failed verification cycles per autonomous task", parseCount4, 2).action(async (sessionId, options) => {
|
|
43364
44346
|
const cwd = import_node_process23.default.cwd();
|
|
43365
44347
|
const firstSearchMatch = options.search ? (await searchSessions(options.search, cwd, 1)).at(0) ?? null : null;
|
|
43366
44348
|
if (options.list) {
|
|
@@ -43439,7 +44421,7 @@ function createRunCommand() {
|
|
|
43439
44421
|
"Explicit execution constraint; can be provided multiple times",
|
|
43440
44422
|
(value, previous = []) => [...previous, value],
|
|
43441
44423
|
[]
|
|
43442
|
-
).option("--json", "Print the session snapshot as JSON", false).option("--snapshot-only", "Create the session without auto-executing ready tasks", false).option("--agent <id>", "Prefer one custom or plugin agent id for this session").option("--agents <jsonOrPath>", "Inline agent definitions as JSON or a path to a JSON file").option("--session-id <id>", "Use an explicit session id").option("--ephemeral", "Do not persist plans or sessions for this invocation", false).option("--max-auto-tasks <count>", "Maximum ready tasks to auto-execute", parseCount5,
|
|
44424
|
+
).option("--json", "Print the session snapshot as JSON", false).option("--snapshot-only", "Create the session without auto-executing ready tasks", false).option("--agent <id>", "Prefer one custom or plugin agent id for this session").option("--agents <jsonOrPath>", "Inline agent definitions as JSON or a path to a JSON file").option("--session-id <id>", "Use an explicit session id").option("--ephemeral", "Do not persist plans or sessions for this invocation", false).option("--max-auto-tasks <count>", "Maximum ready tasks to auto-execute", parseCount5, 4).option("--max-agent-steps <count>", "Maximum tool/model steps per autonomous task", parseCount5, 8).option("--max-repair-attempts <count>", "Maximum failed verification cycles per autonomous task", parseCount5, 2).action(async (goal, options) => {
|
|
43443
44425
|
const cwd = import_node_process24.default.cwd();
|
|
43444
44426
|
const orchestrator = new ExecutionOrchestrator();
|
|
43445
44427
|
const agentSelection = await resolveAgentSelection(cwd, {
|