@wrongstack/cli 0.298.3 → 0.300.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{acp-S4LZQB66.js → acp-IDNS2YVE.js} +3 -3
- package/dist/{auth-G5YKKSRH.js → auth-6T6ZOT2R.js} +5 -5
- package/dist/auth-menu/loopback-server.d.ts +41 -55
- package/dist/auth-menu/openai-codex-oauth.d.ts +36 -123
- package/dist/auto-discover-providers-DRW4OZHG.js +8 -0
- package/dist/boot/dispatch-webui.d.ts +3 -0
- package/dist/{chunk-PEKUKUCH.js → chunk-3MWUZMOL.js} +19 -12
- package/dist/{chunk-TGDHN4LM.js → chunk-4GVH7V3S.js} +4 -24
- package/dist/{chunk-4U3DMA2Y.js → chunk-4WJKVQJY.js} +15 -20
- package/dist/{chunk-C5GH4YBL.js → chunk-GYDQABMA.js} +271 -182
- package/dist/{chunk-4HH3YGG4.js → chunk-MRLYDHQ7.js} +8 -5
- package/dist/{chunk-66T43Q4Y.js → chunk-N7ULWBO5.js} +4 -3
- package/dist/{chunk-ZNZJ34RF.js → chunk-PEMN4T5O.js} +2 -2
- package/dist/chunk-PYTFS4MC.js +238 -0
- package/dist/{chunk-L5CE52XW.js → chunk-V76R7DC5.js} +25 -19
- package/dist/{cli-main-ZDZMCVLM.js → cli-main-7B3G2YSG.js} +943 -160
- package/dist/{execution-BY556FCF.js → execution-SHGM7BVC.js} +76 -8
- package/dist/fleet/budget-source.d.ts +18 -0
- package/dist/fleet/host-status.d.ts +31 -0
- package/dist/fleet/host-types.d.ts +8 -0
- package/dist/fleet/host.d.ts +5 -0
- package/dist/{hq-WO6CLUSI.js → hq-DVDD4XPV.js} +22 -3
- package/dist/hq-server/auth-state.d.ts +29 -1
- package/dist/hq-server/auth.d.ts +16 -0
- package/dist/hq-server/client-address.d.ts +56 -0
- package/dist/hq-server/login-attempt-store.d.ts +30 -10
- package/dist/hq-server/routes/auth-handlers.d.ts +66 -26
- package/dist/hq-server/routes.d.ts +13 -0
- package/dist/hq-server/types.d.ts +10 -0
- package/dist/{hq-server-6TSAORAC.js → hq-server-DQHLNHDL.js} +2 -2
- package/dist/hq-server.d.ts +19 -0
- package/dist/index.js +20 -20
- package/dist/{modeldiag-HENYJ4N7.js → modeldiag-YOQZHBQV.js} +2 -2
- package/dist/{plugin-usage-VTL7ZTVC.js → plugin-usage-EOG4ET4S.js} +2 -2
- package/dist/{plugins-ETY6W3DC.js → plugins-56CMWMPR.js} +3 -3
- package/dist/{providers-models-GDELBHZK.js → providers-models-K6RT7ABI.js} +34 -9
- package/dist/slash-commands/command-context.d.ts +19 -0
- package/dist/slash-commands/intake.d.ts +4 -0
- package/dist/slash-commands/memory-triage.d.ts +47 -0
- package/dist/webui-server/setup-events.d.ts +17 -0
- package/dist/webui-server/terminal-log-view.d.ts +29 -12
- package/dist/{webui-server-PCLSXX6L.js → webui-server-G3EKFXLL.js} +109 -38
- package/dist/webui-server-options.d.ts +16 -0
- package/dist/wiring/brain-and-orchestration.d.ts +3 -0
- package/dist/wiring/director-setup.d.ts +4 -0
- package/dist/wiring/fallback-gate.d.ts +31 -0
- package/dist/wiring/fleet-command-handlers.d.ts +1 -1
- package/dist/wiring/plugins.d.ts +2 -8
- package/dist/wiring/provider-utility-tools.d.ts +26 -1
- package/package.json +23 -22
- package/dist/chunk-GO3TJICK.js +0 -489
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import {
|
|
2
|
+
setupPlugins
|
|
3
|
+
} from "./chunk-4WJKVQJY.js";
|
|
1
4
|
import {
|
|
2
5
|
runProjectPicker
|
|
3
6
|
} from "./chunk-5N34EWJR.js";
|
|
@@ -37,13 +40,10 @@ import {
|
|
|
37
40
|
matchTaskNode,
|
|
38
41
|
sddState
|
|
39
42
|
} from "./chunk-XTIXVJXP.js";
|
|
40
|
-
import {
|
|
41
|
-
setupPlugins
|
|
42
|
-
} from "./chunk-4U3DMA2Y.js";
|
|
43
43
|
import {
|
|
44
44
|
PLUGIN_AUDIT_ENTRIES,
|
|
45
45
|
runPluginManagementCommand
|
|
46
|
-
} from "./chunk-
|
|
46
|
+
} from "./chunk-3MWUZMOL.js";
|
|
47
47
|
import {
|
|
48
48
|
configureSimpleUiRuntimeContext,
|
|
49
49
|
detectProjectFacts,
|
|
@@ -70,7 +70,7 @@ import {
|
|
|
70
70
|
loadCachedAcpRegistry,
|
|
71
71
|
refreshAcpRegistry,
|
|
72
72
|
setupProvider
|
|
73
|
-
} from "./chunk-
|
|
73
|
+
} from "./chunk-MRLYDHQ7.js";
|
|
74
74
|
import {
|
|
75
75
|
addCustomProvider,
|
|
76
76
|
addKeyForCatalogProvider,
|
|
@@ -80,17 +80,18 @@ import {
|
|
|
80
80
|
runClaudeOAuthLogin,
|
|
81
81
|
runCopilotOAuthLogin,
|
|
82
82
|
validateFamily
|
|
83
|
-
} from "./chunk-
|
|
83
|
+
} from "./chunk-V76R7DC5.js";
|
|
84
84
|
import {
|
|
85
85
|
LOCAL_LLM_PRESETS,
|
|
86
86
|
parseSpawnFlags
|
|
87
|
-
} from "./chunk-
|
|
87
|
+
} from "./chunk-PEMN4T5O.js";
|
|
88
88
|
import {
|
|
89
|
-
buildPickableProviders
|
|
90
|
-
|
|
89
|
+
buildPickableProviders,
|
|
90
|
+
visibleModelIds
|
|
91
|
+
} from "./chunk-N7ULWBO5.js";
|
|
91
92
|
import {
|
|
92
93
|
runCodexOAuthLogin
|
|
93
|
-
} from "./chunk-
|
|
94
|
+
} from "./chunk-PYTFS4MC.js";
|
|
94
95
|
import {
|
|
95
96
|
activeLabel,
|
|
96
97
|
loadConfigProviders,
|
|
@@ -2555,7 +2556,8 @@ function wireSessionEvents(deps) {
|
|
|
2555
2556
|
attempt: e.attempt,
|
|
2556
2557
|
delayMs: e.delayMs,
|
|
2557
2558
|
status: e.status,
|
|
2558
|
-
description: e.description
|
|
2559
|
+
description: e.description,
|
|
2560
|
+
...e.errorBody ? { errorBody: e.errorBody } : {}
|
|
2559
2561
|
});
|
|
2560
2562
|
}
|
|
2561
2563
|
);
|
|
@@ -2568,7 +2570,8 @@ function wireSessionEvents(deps) {
|
|
|
2568
2570
|
providerId: e.providerId,
|
|
2569
2571
|
status: e.status,
|
|
2570
2572
|
description: e.description,
|
|
2571
|
-
retryable: e.retryable ?? false
|
|
2573
|
+
retryable: e.retryable ?? false,
|
|
2574
|
+
...e.errorBody ? { errorBody: e.errorBody } : {}
|
|
2572
2575
|
});
|
|
2573
2576
|
}
|
|
2574
2577
|
);
|
|
@@ -3023,7 +3026,7 @@ import {
|
|
|
3023
3026
|
} from "@wrongstack/acp";
|
|
3024
3027
|
import { ToolValidationError } from "@wrongstack/core/types";
|
|
3025
3028
|
function buildAcpSubagentRunner(subagentId) {
|
|
3026
|
-
let cmd = Object.
|
|
3029
|
+
let cmd = Object.hasOwn(ACP_AGENT_COMMANDS, subagentId) ? ACP_AGENT_COMMANDS[subagentId] : void 0;
|
|
3027
3030
|
if (!cmd) {
|
|
3028
3031
|
const desc = findAgentDescriptor(subagentId);
|
|
3029
3032
|
if (desc) {
|
|
@@ -3261,6 +3264,10 @@ function registerDirectorStatsBridge(input) {
|
|
|
3261
3264
|
...u.toolCalls !== void 0 ? { toolCalls: u.toolCalls } : {}
|
|
3262
3265
|
};
|
|
3263
3266
|
});
|
|
3267
|
+
const budgetSnap = director.fleetManager?.budgetSnapshot?.();
|
|
3268
|
+
const maxSpawns = budgetSnap?.maxSpawns ?? director.maxSpawns;
|
|
3269
|
+
const usedSpawns = budgetSnap?.usedSpawns ?? director.spawnCount;
|
|
3270
|
+
const remainingSpawns = budgetSnap?.remainingSpawns ?? Math.max(0, (Number.isFinite(maxSpawns) ? maxSpawns : Number.POSITIVE_INFINITY) - usedSpawns);
|
|
3264
3271
|
events.emit("coordinator.stats", {
|
|
3265
3272
|
sessionId,
|
|
3266
3273
|
total: payload.total,
|
|
@@ -3271,6 +3278,11 @@ function registerDirectorStatsBridge(input) {
|
|
|
3271
3278
|
pending: payload.pending,
|
|
3272
3279
|
completed: payload.completed,
|
|
3273
3280
|
...usage?.total?.cost !== void 0 ? { totalCostUsd: usage.total.cost } : {},
|
|
3281
|
+
maxSpawns,
|
|
3282
|
+
usedSpawns,
|
|
3283
|
+
remainingSpawns,
|
|
3284
|
+
...budgetSnap?.checkpointMaxSpawns !== void 0 ? { checkpointMaxSpawns: budgetSnap.checkpointMaxSpawns } : {},
|
|
3285
|
+
...budgetSnap?.ceilingMismatch ? { ceilingMismatch: true } : {},
|
|
3274
3286
|
subagentStatuses
|
|
3275
3287
|
});
|
|
3276
3288
|
});
|
|
@@ -4364,7 +4376,47 @@ function buildFleetHostStatus(input) {
|
|
|
4364
4376
|
const completedCount = completed.length;
|
|
4365
4377
|
const liveCount = live.filter((s) => s.status === "running" || s.status === "idle").length;
|
|
4366
4378
|
const summary = !input.coordinatorStatus && !input.completedResults ? "No subagents have been spawned." : liveCount > 0 ? `${pending.length} pending, ${liveCount} active, ${completedCount} completed.` : `${pending.length} pending, ${completedCount} completed.`;
|
|
4367
|
-
return {
|
|
4379
|
+
return {
|
|
4380
|
+
pending,
|
|
4381
|
+
completed,
|
|
4382
|
+
live,
|
|
4383
|
+
summary,
|
|
4384
|
+
...input.budget ? { budget: input.budget } : {}
|
|
4385
|
+
};
|
|
4386
|
+
}
|
|
4387
|
+
function formatFleetBudgetLines(budget, colorize) {
|
|
4388
|
+
const bold = colorize?.bold ?? ((s) => s);
|
|
4389
|
+
const dim = colorize?.dim ?? ((s) => s);
|
|
4390
|
+
const amber = colorize?.amber ?? ((s) => s);
|
|
4391
|
+
const fmtNum = (n) => Number.isFinite(n) ? String(n) : "\u221E";
|
|
4392
|
+
const sourceSuffix = budget.effectiveSource ? ` ${dim(`(source: ${budget.effectiveSource})`)}` : "";
|
|
4393
|
+
const lines = [
|
|
4394
|
+
bold("Budget"),
|
|
4395
|
+
` maxConcurrent: ${budget.maxConcurrent} \xB7 activeAgents: ${budget.activeAgents}`,
|
|
4396
|
+
` maxSpawns: ${fmtNum(budget.maxSpawns)} \xB7 usedSpawns: ${budget.usedSpawns} \xB7 remainingSpawns: ${fmtNum(budget.remainingSpawns)}${sourceSuffix}`
|
|
4397
|
+
];
|
|
4398
|
+
if (budget.maxTokens !== void 0 && Number.isFinite(budget.maxTokens) && budget.maxTokens < Number.POSITIVE_INFINITY) {
|
|
4399
|
+
lines.push(
|
|
4400
|
+
` tokens: ${budget.usedTokens ?? 0} / ${fmtNum(budget.maxTokens)} remaining ${fmtNum(budget.remainingTokens ?? 0)}`
|
|
4401
|
+
);
|
|
4402
|
+
}
|
|
4403
|
+
if (budget.maxCostUsd !== void 0 && Number.isFinite(budget.maxCostUsd) && budget.maxCostUsd < Number.POSITIVE_INFINITY) {
|
|
4404
|
+
const used = budget.usedCostUsd ?? 0;
|
|
4405
|
+
const rem = budget.remainingCostUsd ?? 0;
|
|
4406
|
+
lines.push(
|
|
4407
|
+
` costUsd: ${used.toFixed(4)} / ${budget.maxCostUsd.toFixed(4)} remaining ${rem.toFixed(4)}`
|
|
4408
|
+
);
|
|
4409
|
+
}
|
|
4410
|
+
if (budget.ceilingMismatch && budget.checkpointMaxSpawns !== void 0) {
|
|
4411
|
+
lines.push(
|
|
4412
|
+
amber(
|
|
4413
|
+
` \u26A0 checkpoint maxSpawns was ${budget.checkpointMaxSpawns}; live ceiling is ${fmtNum(budget.maxSpawns)}`
|
|
4414
|
+
)
|
|
4415
|
+
);
|
|
4416
|
+
} else if (budget.checkpointMaxSpawns !== void 0) {
|
|
4417
|
+
lines.push(dim(` checkpointMaxSpawns: ${budget.checkpointMaxSpawns}`));
|
|
4418
|
+
}
|
|
4419
|
+
return lines;
|
|
4368
4420
|
}
|
|
4369
4421
|
function aggregateFleetUsage(completed) {
|
|
4370
4422
|
const bySubagent = /* @__PURE__ */ new Map();
|
|
@@ -5072,9 +5124,44 @@ var MultiAgentHost = class {
|
|
|
5072
5124
|
coordinatorStatus: this.director ? this.getCoordinator().getStatus() : null,
|
|
5073
5125
|
fleetStatus: this.fleetManager?.getFleetStatus() ?? null,
|
|
5074
5126
|
completedResults: this.director ? this.director.completedResults() : null,
|
|
5075
|
-
shadowTaskIds: this.shadowTaskIds
|
|
5127
|
+
shadowTaskIds: this.shadowTaskIds,
|
|
5128
|
+
budget: this.budgetView()
|
|
5076
5129
|
});
|
|
5077
5130
|
}
|
|
5131
|
+
/**
|
|
5132
|
+
* Read-only concurrency + lifetime spawn budget for `/fleet status` and
|
|
5133
|
+
* resume diagnostics. Safe when no director/fleet is active yet.
|
|
5134
|
+
*/
|
|
5135
|
+
budgetView() {
|
|
5136
|
+
const snap = this.fleetManager?.budgetSnapshot?.();
|
|
5137
|
+
const maxSpawns = snap?.maxSpawns ?? this.opts.maxSpawns ?? this.director?.maxSpawns ?? Number.POSITIVE_INFINITY;
|
|
5138
|
+
const usedSpawns = snap?.usedSpawns ?? this.director?.spawnCount ?? 0;
|
|
5139
|
+
const remainingSpawns = snap?.remainingSpawns ?? Math.max(0, (Number.isFinite(maxSpawns) ? maxSpawns : Number.POSITIVE_INFINITY) - usedSpawns);
|
|
5140
|
+
const live = this.director ? this.getCoordinator().getStatus().subagents.filter((s) => s.status === "running" || s.status === "idle").length : 0;
|
|
5141
|
+
const maxConcurrentSource = this.opts.budgetSources?.maxConcurrent ?? "default";
|
|
5142
|
+
const maxSpawnsSource = this.opts.budgetSources?.maxSpawns ?? "default";
|
|
5143
|
+
const effectiveSource = `maxConcurrent=${maxConcurrentSource}, maxSpawns=${maxSpawnsSource}`;
|
|
5144
|
+
return {
|
|
5145
|
+
maxConcurrent: this.getMaxConcurrent(),
|
|
5146
|
+
activeAgents: live,
|
|
5147
|
+
maxSpawns,
|
|
5148
|
+
usedSpawns,
|
|
5149
|
+
remainingSpawns,
|
|
5150
|
+
maxConcurrentSource,
|
|
5151
|
+
maxSpawnsSource,
|
|
5152
|
+
effectiveSource,
|
|
5153
|
+
...snap ? {
|
|
5154
|
+
maxTokens: snap.maxTokens,
|
|
5155
|
+
usedTokens: snap.usedTokens,
|
|
5156
|
+
remainingTokens: snap.remainingTokens,
|
|
5157
|
+
maxCostUsd: snap.maxCostUsd,
|
|
5158
|
+
usedCostUsd: snap.usedCostUsd,
|
|
5159
|
+
remainingCostUsd: snap.remainingCostUsd,
|
|
5160
|
+
...snap.checkpointMaxSpawns !== void 0 ? { checkpointMaxSpawns: snap.checkpointMaxSpawns } : {},
|
|
5161
|
+
...snap.ceilingMismatch ? { ceilingMismatch: true } : {}
|
|
5162
|
+
} : {}
|
|
5163
|
+
};
|
|
5164
|
+
}
|
|
5078
5165
|
usage() {
|
|
5079
5166
|
const completed = this.director ? this.director.completedResults().filter((r) => !this.shadowTaskIds.has(r.taskId)) : [];
|
|
5080
5167
|
return aggregateFleetUsage(completed);
|
|
@@ -5174,7 +5261,10 @@ function resolveProviderCfg(config, providerId) {
|
|
|
5174
5261
|
function buildProviderForId(args, providerId) {
|
|
5175
5262
|
const { cfg, factoryType } = resolveProviderCfg(args.config, providerId);
|
|
5176
5263
|
const useRegistry = !!args.config.features.modelsRegistry && args.providerRegistry.has(factoryType);
|
|
5177
|
-
return useRegistry ? args.providerRegistry.create(cfg, factoryType) : makeProviderFromConfig2(
|
|
5264
|
+
return useRegistry ? args.providerRegistry.create(cfg, factoryType) : makeProviderFromConfig2(
|
|
5265
|
+
providerId,
|
|
5266
|
+
factoryType === "ai-gateway" ? { ...cfg, type: factoryType } : cfg
|
|
5267
|
+
);
|
|
5178
5268
|
}
|
|
5179
5269
|
|
|
5180
5270
|
// src/wiring/brain-and-orchestration.ts
|
|
@@ -5413,8 +5503,12 @@ function setupBrainAndOrchestration(deps) {
|
|
|
5413
5503
|
maxCostUsd: config.fleet.budget.maxCostUsd
|
|
5414
5504
|
}
|
|
5415
5505
|
} : {},
|
|
5416
|
-
maxSpawns: config.fleet?.budget?.maxSpawns,
|
|
5506
|
+
maxSpawns: deps.maxSpawns ?? config.fleet?.budget?.maxSpawns,
|
|
5417
5507
|
maxConcurrent,
|
|
5508
|
+
budgetSources: {
|
|
5509
|
+
maxConcurrent: deps.maxConcurrentSource ?? "default",
|
|
5510
|
+
maxSpawns: deps.maxSpawnsSource ?? "default"
|
|
5511
|
+
},
|
|
5418
5512
|
getLeaderMaxContext: () => effectiveMaxContextRef.current,
|
|
5419
5513
|
brain,
|
|
5420
5514
|
agentMonitor,
|
|
@@ -5931,13 +6025,78 @@ import * as path10 from "node:path";
|
|
|
5931
6025
|
import { expectDefined as expectDefined2 } from "@wrongstack/core/utils";
|
|
5932
6026
|
import { createAgentMonitorService } from "@wrongstack/core/coordination";
|
|
5933
6027
|
import { sessionScopedPath as sessionScopedPath2 } from "@wrongstack/core/utils";
|
|
6028
|
+
|
|
6029
|
+
// src/fleet/budget-source.ts
|
|
6030
|
+
import { DEFAULT_MAX_FLEET_SPAWNS as DEFAULT_MAX_FLEET_SPAWNS3 } from "@wrongstack/core/coordination";
|
|
6031
|
+
function positiveInt(raw) {
|
|
6032
|
+
if (typeof raw === "number" && Number.isFinite(raw) && raw > 0) return Math.floor(raw);
|
|
6033
|
+
if (typeof raw === "string" && raw.trim() !== "") {
|
|
6034
|
+
const n = Number.parseInt(raw, 10);
|
|
6035
|
+
if (Number.isFinite(n) && n > 0) return n;
|
|
6036
|
+
}
|
|
6037
|
+
return void 0;
|
|
6038
|
+
}
|
|
6039
|
+
function resolveFleetBudgetSources(input) {
|
|
6040
|
+
const flags = input.flags ?? {};
|
|
6041
|
+
const env = input.env ?? process.env;
|
|
6042
|
+
const config = input.config;
|
|
6043
|
+
const defaultMaxConcurrent = input.defaultMaxConcurrent ?? 4;
|
|
6044
|
+
const defaultMaxSpawns = input.defaultMaxSpawns ?? DEFAULT_MAX_FLEET_SPAWNS3;
|
|
6045
|
+
const maxConcurrentFlag = positiveInt(flags["max-concurrent"]);
|
|
6046
|
+
const maxConcurrentEnv = positiveInt(env["WRONGSTACK_MAX_CONCURRENT"]);
|
|
6047
|
+
const maxConcurrentProfile = positiveInt(config?.maxConcurrent);
|
|
6048
|
+
let maxConcurrent;
|
|
6049
|
+
let maxConcurrentSource;
|
|
6050
|
+
if (maxConcurrentFlag !== void 0) {
|
|
6051
|
+
maxConcurrent = maxConcurrentFlag;
|
|
6052
|
+
maxConcurrentSource = "cli-flag";
|
|
6053
|
+
} else if (maxConcurrentEnv !== void 0) {
|
|
6054
|
+
maxConcurrent = maxConcurrentEnv;
|
|
6055
|
+
maxConcurrentSource = "env";
|
|
6056
|
+
} else if (maxConcurrentProfile !== void 0) {
|
|
6057
|
+
maxConcurrent = maxConcurrentProfile;
|
|
6058
|
+
maxConcurrentSource = "profile";
|
|
6059
|
+
} else {
|
|
6060
|
+
maxConcurrent = defaultMaxConcurrent;
|
|
6061
|
+
maxConcurrentSource = "default";
|
|
6062
|
+
}
|
|
6063
|
+
const maxSpawnsFlag = positiveInt(flags["max-spawns"]);
|
|
6064
|
+
const maxSpawnsEnv = positiveInt(env["WRONGSTACK_MAX_SPAWNS"]);
|
|
6065
|
+
const maxSpawnsProfile = positiveInt(config?.fleet?.budget?.maxSpawns);
|
|
6066
|
+
let maxSpawns;
|
|
6067
|
+
let maxSpawnsSource;
|
|
6068
|
+
if (maxSpawnsFlag !== void 0) {
|
|
6069
|
+
maxSpawns = maxSpawnsFlag;
|
|
6070
|
+
maxSpawnsSource = "cli-flag";
|
|
6071
|
+
} else if (maxSpawnsEnv !== void 0) {
|
|
6072
|
+
maxSpawns = maxSpawnsEnv;
|
|
6073
|
+
maxSpawnsSource = "env";
|
|
6074
|
+
} else if (maxSpawnsProfile !== void 0) {
|
|
6075
|
+
maxSpawns = maxSpawnsProfile;
|
|
6076
|
+
maxSpawnsSource = "profile";
|
|
6077
|
+
} else {
|
|
6078
|
+
maxSpawns = defaultMaxSpawns;
|
|
6079
|
+
maxSpawnsSource = "default";
|
|
6080
|
+
}
|
|
6081
|
+
return {
|
|
6082
|
+
maxConcurrent,
|
|
6083
|
+
maxConcurrentSource,
|
|
6084
|
+
maxSpawns,
|
|
6085
|
+
maxSpawnsSource
|
|
6086
|
+
};
|
|
6087
|
+
}
|
|
6088
|
+
|
|
6089
|
+
// src/wiring/director-setup.ts
|
|
5934
6090
|
function setupDirectorAndAutonomy(deps) {
|
|
5935
6091
|
const { flags, config, wpaths, session, events, autonomyModeRef } = deps;
|
|
5936
6092
|
const directorMode = true;
|
|
5937
|
-
const
|
|
5938
|
-
|
|
5939
|
-
|
|
5940
|
-
|
|
6093
|
+
const {
|
|
6094
|
+
maxConcurrent: resolvedMaxConcurrent,
|
|
6095
|
+
maxConcurrentSource,
|
|
6096
|
+
maxSpawns,
|
|
6097
|
+
maxSpawnsSource
|
|
6098
|
+
} = resolveFleetBudgetSources({ flags, config });
|
|
6099
|
+
const maxConcurrent = maxConcurrentSource === "default" ? void 0 : resolvedMaxConcurrent;
|
|
5941
6100
|
const autonomyMode = (() => {
|
|
5942
6101
|
const v = flags["autonomy"];
|
|
5943
6102
|
if (v === "auto" || v === "suggest" || v === "eternal" || v === "eternal-parallel") return v;
|
|
@@ -5984,6 +6143,9 @@ function setupDirectorAndAutonomy(deps) {
|
|
|
5984
6143
|
director: null,
|
|
5985
6144
|
directorMode,
|
|
5986
6145
|
maxConcurrent,
|
|
6146
|
+
maxSpawns,
|
|
6147
|
+
maxConcurrentSource,
|
|
6148
|
+
maxSpawnsSource,
|
|
5987
6149
|
autonomyMode,
|
|
5988
6150
|
nextPredictEnabled,
|
|
5989
6151
|
currentSuggestions,
|
|
@@ -6103,6 +6265,7 @@ ${color6.dim("\u2500".repeat(40))}` : "";
|
|
|
6103
6265
|
onAgents: (subagentId) => formatAgents(input, subagentId),
|
|
6104
6266
|
onFleet: (action, target) => handleFleetAction(input, action, target),
|
|
6105
6267
|
onFleetStatus: () => input.getDirector()?.status() ?? null,
|
|
6268
|
+
onFleetBudget: () => input.multiAgentHost.budgetView(),
|
|
6106
6269
|
onFleetUsage: () => input.getDirector()?.snapshot() ?? null,
|
|
6107
6270
|
onFleetKill: () => killFleet2(input.getDirector()),
|
|
6108
6271
|
onFleetTerminate: async (subagentId) => {
|
|
@@ -6221,6 +6384,15 @@ async function handleFleetAction(input, action, target) {
|
|
|
6221
6384
|
function formatFleetStatus(host) {
|
|
6222
6385
|
const status = host.status();
|
|
6223
6386
|
const lines = [color6.bold("Fleet status"), ` ${status.summary}`];
|
|
6387
|
+
const budget = status.budget ?? host.budgetView();
|
|
6388
|
+
lines.push(
|
|
6389
|
+
"",
|
|
6390
|
+
...formatFleetBudgetLines(budget, {
|
|
6391
|
+
bold: color6.bold,
|
|
6392
|
+
dim: color6.dim,
|
|
6393
|
+
amber: color6.amber
|
|
6394
|
+
})
|
|
6395
|
+
);
|
|
6224
6396
|
const icons = { running: "\u25CF", idle: "\u25CB", stopped: "\u2298" };
|
|
6225
6397
|
const active2 = status.live.filter((agent) => agent.status === "running" || agent.status === "idle");
|
|
6226
6398
|
if (active2.length > 0) {
|
|
@@ -6760,6 +6932,7 @@ function setupHqTelemetry(deps) {
|
|
|
6760
6932
|
// src/wiring/lifecycle-plugins.ts
|
|
6761
6933
|
import * as path15 from "node:path";
|
|
6762
6934
|
import { getSharedProjectMailbox as getSharedProjectMailbox8 } from "@wrongstack/core/coordination";
|
|
6935
|
+
import { CouncilOrchestrator, OneShotOrchestrator as OneShotOrchestrator2 } from "@wrongstack/core/execution";
|
|
6763
6936
|
import { countShellHooks, HookRegistry, HookRunner, shellHooksEqual } from "@wrongstack/core/hooks";
|
|
6764
6937
|
import { allServers } from "@wrongstack/core/infrastructure";
|
|
6765
6938
|
import { TOKENS as TOKENS8 } from "@wrongstack/core/kernel";
|
|
@@ -7348,6 +7521,130 @@ function createAgent(params) {
|
|
|
7348
7521
|
});
|
|
7349
7522
|
}
|
|
7350
7523
|
|
|
7524
|
+
// src/wiring/provider-utility-tools.ts
|
|
7525
|
+
import { createContextManagerTool as createContextManagerTool2 } from "@wrongstack/core/infrastructure";
|
|
7526
|
+
import { createCouncilTool, createOneShotLLMTool } from "@wrongstack/core/tools";
|
|
7527
|
+
import {
|
|
7528
|
+
createCouncilPersonaRegistry,
|
|
7529
|
+
createCouncilProfileRegistry,
|
|
7530
|
+
OneShotOrchestrator
|
|
7531
|
+
} from "@wrongstack/core/execution";
|
|
7532
|
+
import { ModelRouter } from "@wrongstack/core/models";
|
|
7533
|
+
async function adoptResumedProvider(input) {
|
|
7534
|
+
if (!input.resumedProvider && !input.resumedModel) return;
|
|
7535
|
+
const config = input.getConfig();
|
|
7536
|
+
const provider = input.resumedProvider?.trim() || config.provider;
|
|
7537
|
+
const model = input.resumedModel?.trim() || config.model;
|
|
7538
|
+
if (provider === config.provider && model === config.model) return;
|
|
7539
|
+
const error = await input.switchProviderAndModel(provider, model);
|
|
7540
|
+
if (error) {
|
|
7541
|
+
const current = input.getConfig();
|
|
7542
|
+
input.logger.warn(
|
|
7543
|
+
`Resume: could not switch to the session's model ${provider}/${model} (${error}); continuing with ${current.provider}/${current.model}.`
|
|
7544
|
+
);
|
|
7545
|
+
}
|
|
7546
|
+
}
|
|
7547
|
+
function createLiveModelRouter(getConfig) {
|
|
7548
|
+
return {
|
|
7549
|
+
pickForTask(role, description) {
|
|
7550
|
+
const config = getConfig();
|
|
7551
|
+
const router = new ModelRouter({
|
|
7552
|
+
...config.modelMatrix ? { matrix: config.modelMatrix } : {},
|
|
7553
|
+
config: {
|
|
7554
|
+
provider: config.provider,
|
|
7555
|
+
model: config.model,
|
|
7556
|
+
...config.providers ? { providers: config.providers } : {}
|
|
7557
|
+
}
|
|
7558
|
+
});
|
|
7559
|
+
return router.pickForTask(role, description);
|
|
7560
|
+
}
|
|
7561
|
+
};
|
|
7562
|
+
}
|
|
7563
|
+
function buildCouncilRegistries(cfg) {
|
|
7564
|
+
const base = {
|
|
7565
|
+
...cfg?.defaultProfile ? { defaultProfile: cfg.defaultProfile } : {},
|
|
7566
|
+
...cfg?.maxConcurrency !== void 0 ? { maxConcurrency: cfg.maxConcurrency } : {}
|
|
7567
|
+
};
|
|
7568
|
+
if (!cfg?.personas?.length && !cfg?.profiles?.length) return base;
|
|
7569
|
+
try {
|
|
7570
|
+
const personas = createCouncilPersonaRegistry(cfg.personas ?? []);
|
|
7571
|
+
const profiles = createCouncilProfileRegistry(
|
|
7572
|
+
cfg.profiles ?? [],
|
|
7573
|
+
personas
|
|
7574
|
+
);
|
|
7575
|
+
return { ...base, personas, profiles };
|
|
7576
|
+
} catch (error) {
|
|
7577
|
+
console.warn(
|
|
7578
|
+
`Council tool: ignoring tools.council personas/profiles \u2014 ${error instanceof Error ? error.message : String(error)}. Falling back to the built-in lenses and panels.`
|
|
7579
|
+
);
|
|
7580
|
+
return base;
|
|
7581
|
+
}
|
|
7582
|
+
}
|
|
7583
|
+
function registerProviderUtilityTools(input) {
|
|
7584
|
+
const config = input.getConfig();
|
|
7585
|
+
const llmTool = createOneShotLLMTool({
|
|
7586
|
+
buildProvider: input.buildProvider,
|
|
7587
|
+
getConfig: input.getConfig,
|
|
7588
|
+
fallbackProfileManager: input.fallbackProfileManager,
|
|
7589
|
+
defaultProvider: config.provider,
|
|
7590
|
+
defaultModel: config.model
|
|
7591
|
+
});
|
|
7592
|
+
registerOrOverride(input.toolRegistry, "llm", llmTool);
|
|
7593
|
+
const councilOrchestrator = new OneShotOrchestrator({
|
|
7594
|
+
buildProvider: input.buildProvider,
|
|
7595
|
+
getConfig: input.getConfig,
|
|
7596
|
+
fallbackProfileManager: input.fallbackProfileManager,
|
|
7597
|
+
statusTracker: input.statusTracker,
|
|
7598
|
+
// Council profiles route each seat by ROLE ('planner', 'critic',
|
|
7599
|
+
// 'analyst', 'security-reviewer'…) rather than pinning models. Without a
|
|
7600
|
+
// router those hints were inert: every seat fell through to the session
|
|
7601
|
+
// provider/model, so a three-seat panel asked one model three times and
|
|
7602
|
+
// reported a distinctness warning on every single call.
|
|
7603
|
+
modelRouter: createLiveModelRouter(input.getConfig)
|
|
7604
|
+
});
|
|
7605
|
+
registerOrOverride(
|
|
7606
|
+
input.toolRegistry,
|
|
7607
|
+
"council",
|
|
7608
|
+
createCouncilTool({
|
|
7609
|
+
caller: councilOrchestrator,
|
|
7610
|
+
fallbackProfileManager: input.fallbackProfileManager,
|
|
7611
|
+
...buildCouncilRegistries(config.tools?.council)
|
|
7612
|
+
})
|
|
7613
|
+
);
|
|
7614
|
+
try {
|
|
7615
|
+
const summarizer = new OneShotOrchestrator({
|
|
7616
|
+
buildProvider: input.buildProvider,
|
|
7617
|
+
getConfig: input.getConfig,
|
|
7618
|
+
fallbackProfileManager: input.fallbackProfileManager,
|
|
7619
|
+
statusTracker: input.statusTracker
|
|
7620
|
+
});
|
|
7621
|
+
input.toolRegistry.override(
|
|
7622
|
+
"context_manager",
|
|
7623
|
+
createContextManagerTool2({
|
|
7624
|
+
compactor: input.compactor,
|
|
7625
|
+
summarizer: async (messages) => {
|
|
7626
|
+
const result = await summarizer.call({
|
|
7627
|
+
system: "Summarize concisely. Keep decisions and key facts.",
|
|
7628
|
+
messages,
|
|
7629
|
+
model: "deepseek-chat",
|
|
7630
|
+
maxTokens: 1024,
|
|
7631
|
+
timeoutMs: 3e4
|
|
7632
|
+
});
|
|
7633
|
+
return result.text || "(summary unavailable)";
|
|
7634
|
+
}
|
|
7635
|
+
})
|
|
7636
|
+
);
|
|
7637
|
+
} catch {
|
|
7638
|
+
}
|
|
7639
|
+
}
|
|
7640
|
+
function registerOrOverride(registry, name, tool) {
|
|
7641
|
+
try {
|
|
7642
|
+
registry.register(tool);
|
|
7643
|
+
} catch {
|
|
7644
|
+
registry.override(name, tool);
|
|
7645
|
+
}
|
|
7646
|
+
}
|
|
7647
|
+
|
|
7351
7648
|
// src/wiring/lifecycle-plugins.ts
|
|
7352
7649
|
async function setupLifecycleAndPlugins(deps) {
|
|
7353
7650
|
const {
|
|
@@ -7516,11 +7813,9 @@ async function setupLifecycleAndPlugins(deps) {
|
|
|
7516
7813
|
for (const cfg of Object.values(config.mcpServers ?? {})) {
|
|
7517
7814
|
const preset = presets[cfg.name];
|
|
7518
7815
|
const merged = preset ? { ...preset, ...cfg } : cfg;
|
|
7519
|
-
|
|
7520
|
-
await mcpRegistry.start(merged);
|
|
7521
|
-
} catch (err) {
|
|
7816
|
+
void mcpRegistry.start(merged).catch((err) => {
|
|
7522
7817
|
logger.warn(`MCP server "${cfg.name}" failed to start`, err);
|
|
7523
|
-
}
|
|
7818
|
+
});
|
|
7524
7819
|
}
|
|
7525
7820
|
}
|
|
7526
7821
|
registerMcpObservability(healthRegistry, metricsSink, mcpRegistry);
|
|
@@ -7532,6 +7827,23 @@ async function setupLifecycleAndPlugins(deps) {
|
|
|
7532
7827
|
() => hqPublisherRef.current
|
|
7533
7828
|
);
|
|
7534
7829
|
const notifier = new NotifierImpl();
|
|
7830
|
+
const getLiveConfig = () => configStore.get();
|
|
7831
|
+
const fallbackProfileManager = container.resolve(TOKENS8.FallbackProfileManager);
|
|
7832
|
+
const statusTracker = container.resolve(TOKENS8.ProviderModelStatusTracker);
|
|
7833
|
+
const buildUtilityProvider = (providerId) => buildProviderForIdRuntimeFn({ config: getLiveConfig(), providerRegistry }, providerId);
|
|
7834
|
+
const pluginOneShot = new OneShotOrchestrator2({
|
|
7835
|
+
buildProvider: buildUtilityProvider,
|
|
7836
|
+
getConfig: getLiveConfig,
|
|
7837
|
+
fallbackProfileManager,
|
|
7838
|
+
statusTracker,
|
|
7839
|
+
modelRouter: createLiveModelRouter(getLiveConfig),
|
|
7840
|
+
logger
|
|
7841
|
+
});
|
|
7842
|
+
const pluginCouncil = new CouncilOrchestrator({
|
|
7843
|
+
caller: pluginOneShot,
|
|
7844
|
+
fallbackProfileManager,
|
|
7845
|
+
...buildCouncilRegistries(getLiveConfig().tools?.council)
|
|
7846
|
+
});
|
|
7535
7847
|
const pluginHost = await setupPlugins({
|
|
7536
7848
|
config,
|
|
7537
7849
|
container,
|
|
@@ -7572,7 +7884,9 @@ async function setupLifecycleAndPlugins(deps) {
|
|
|
7572
7884
|
model: config.model,
|
|
7573
7885
|
getProvider: () => context.provider,
|
|
7574
7886
|
getModel: () => context.model,
|
|
7575
|
-
createProvider: (name) => buildProviderForIdRuntimeFn({ config: configStore.get(), providerRegistry }, name)
|
|
7887
|
+
createProvider: (name) => buildProviderForIdRuntimeFn({ config: configStore.get(), providerRegistry }, name),
|
|
7888
|
+
oneShot: (input) => pluginOneShot.call(input),
|
|
7889
|
+
council: (question) => pluginCouncil.ask(question)
|
|
7576
7890
|
}
|
|
7577
7891
|
});
|
|
7578
7892
|
return {
|
|
@@ -7672,6 +7986,61 @@ import {
|
|
|
7672
7986
|
} from "@wrongstack/core/storage";
|
|
7673
7987
|
import { withCatalogCapabilities as withCatalogCapabilities2 } from "@wrongstack/providers";
|
|
7674
7988
|
import { getSageService } from "@wrongstack/sage";
|
|
7989
|
+
|
|
7990
|
+
// src/wiring/fallback-gate.ts
|
|
7991
|
+
function createFallbackGate(_events) {
|
|
7992
|
+
const gateFn = (params) => {
|
|
7993
|
+
const { events: bus, sessionId, from, status, candidates, autoSwitchSeconds, requestId } = params;
|
|
7994
|
+
return runGate(bus, { sessionId, from, status, candidates, autoSwitchSeconds, requestId });
|
|
7995
|
+
};
|
|
7996
|
+
return gateFn;
|
|
7997
|
+
}
|
|
7998
|
+
function runGate(events, gateParams) {
|
|
7999
|
+
const { sessionId, from, status, candidates, autoSwitchSeconds, requestId } = gateParams;
|
|
8000
|
+
if (events.listenerCount("provider.fallback_pending") === 0) {
|
|
8001
|
+
return Promise.resolve(null);
|
|
8002
|
+
}
|
|
8003
|
+
return new Promise((resolve8) => {
|
|
8004
|
+
let settled = false;
|
|
8005
|
+
let timer;
|
|
8006
|
+
let deadline;
|
|
8007
|
+
const cleanup = () => {
|
|
8008
|
+
if (timer) clearTimeout(timer);
|
|
8009
|
+
if (deadline) clearTimeout(deadline);
|
|
8010
|
+
events.off("provider.fallback_choice", handler);
|
|
8011
|
+
};
|
|
8012
|
+
const finish = (result) => {
|
|
8013
|
+
if (settled) return;
|
|
8014
|
+
settled = true;
|
|
8015
|
+
cleanup();
|
|
8016
|
+
resolve8(result);
|
|
8017
|
+
};
|
|
8018
|
+
const handler = (payload) => {
|
|
8019
|
+
const p = payload;
|
|
8020
|
+
if (p?.requestId !== requestId) return;
|
|
8021
|
+
if (p.autoSwitch === true) {
|
|
8022
|
+
finish(null);
|
|
8023
|
+
return;
|
|
8024
|
+
}
|
|
8025
|
+
if (typeof p.providerId === "string" && typeof p.model === "string") {
|
|
8026
|
+
finish({ providerId: p.providerId, model: p.model });
|
|
8027
|
+
}
|
|
8028
|
+
};
|
|
8029
|
+
events.on("provider.fallback_choice", handler);
|
|
8030
|
+
deadline = setTimeout(() => finish(null), Math.round(autoSwitchSeconds * 1500));
|
|
8031
|
+
events.emit("provider.fallback_pending", {
|
|
8032
|
+
...sessionId ? { sessionId } : {},
|
|
8033
|
+
from,
|
|
8034
|
+
status,
|
|
8035
|
+
candidates,
|
|
8036
|
+
autoSwitchSeconds,
|
|
8037
|
+
requestId,
|
|
8038
|
+
timestamp: Date.now()
|
|
8039
|
+
});
|
|
8040
|
+
});
|
|
8041
|
+
}
|
|
8042
|
+
|
|
8043
|
+
// src/wiring/provider-runtime-setup.ts
|
|
7675
8044
|
function serializeProviderRuntimeSnapshot(snapshot) {
|
|
7676
8045
|
return JSON.stringify(snapshot);
|
|
7677
8046
|
}
|
|
@@ -7736,6 +8105,12 @@ function setupProviderRuntime(deps) {
|
|
|
7736
8105
|
events,
|
|
7737
8106
|
logger,
|
|
7738
8107
|
statusTracker,
|
|
8108
|
+
// Fallback gate — shows a modal with countdown + manual pick in every
|
|
8109
|
+
// UI surface (TUI/WebUI/SimpleUI) before switching models. The gate
|
|
8110
|
+
// emits provider.fallback_pending and waits for provider.fallback_choice
|
|
8111
|
+
// or the auto-switch countdown.
|
|
8112
|
+
fallbackGate: createFallbackGate(events),
|
|
8113
|
+
fallbackGateSeconds: 7,
|
|
7739
8114
|
...cfg.fallbackStickiness?.primaryProbeInterval !== void 0 ? { primaryCooldownMs: cfg.fallbackStickiness.primaryProbeInterval } : {},
|
|
7740
8115
|
...cfg.fallbackStickiness?.stickyFallbackTurns !== void 0 ? { stickyFallbackTurns: cfg.fallbackStickiness.stickyFallbackTurns } : {}
|
|
7741
8116
|
})
|
|
@@ -7977,79 +8352,6 @@ function warnUnlessMissing(logger, operation, error) {
|
|
|
7977
8352
|
}
|
|
7978
8353
|
}
|
|
7979
8354
|
|
|
7980
|
-
// src/wiring/provider-utility-tools.ts
|
|
7981
|
-
import { createContextManagerTool as createContextManagerTool2 } from "@wrongstack/core/infrastructure";
|
|
7982
|
-
import { createCouncilTool, createOneShotLLMTool } from "@wrongstack/core/tools";
|
|
7983
|
-
import { OneShotOrchestrator } from "@wrongstack/core/execution";
|
|
7984
|
-
async function adoptResumedProvider(input) {
|
|
7985
|
-
if (!input.resumedProvider && !input.resumedModel) return;
|
|
7986
|
-
const config = input.getConfig();
|
|
7987
|
-
const provider = input.resumedProvider?.trim() || config.provider;
|
|
7988
|
-
const model = input.resumedModel?.trim() || config.model;
|
|
7989
|
-
if (provider === config.provider && model === config.model) return;
|
|
7990
|
-
const error = await input.switchProviderAndModel(provider, model);
|
|
7991
|
-
if (error) {
|
|
7992
|
-
const current = input.getConfig();
|
|
7993
|
-
input.logger.warn(
|
|
7994
|
-
`Resume: could not switch to the session's model ${provider}/${model} (${error}); continuing with ${current.provider}/${current.model}.`
|
|
7995
|
-
);
|
|
7996
|
-
}
|
|
7997
|
-
}
|
|
7998
|
-
function registerProviderUtilityTools(input) {
|
|
7999
|
-
const config = input.getConfig();
|
|
8000
|
-
const llmTool = createOneShotLLMTool({
|
|
8001
|
-
buildProvider: input.buildProvider,
|
|
8002
|
-
getConfig: input.getConfig,
|
|
8003
|
-
fallbackProfileManager: input.fallbackProfileManager,
|
|
8004
|
-
defaultProvider: config.provider,
|
|
8005
|
-
defaultModel: config.model
|
|
8006
|
-
});
|
|
8007
|
-
registerOrOverride(input.toolRegistry, "llm", llmTool);
|
|
8008
|
-
const councilOrchestrator = new OneShotOrchestrator({
|
|
8009
|
-
buildProvider: input.buildProvider,
|
|
8010
|
-
getConfig: input.getConfig,
|
|
8011
|
-
fallbackProfileManager: input.fallbackProfileManager,
|
|
8012
|
-
statusTracker: input.statusTracker
|
|
8013
|
-
});
|
|
8014
|
-
registerOrOverride(
|
|
8015
|
-
input.toolRegistry,
|
|
8016
|
-
"council",
|
|
8017
|
-
createCouncilTool({ caller: councilOrchestrator, fallbackProfileManager: input.fallbackProfileManager })
|
|
8018
|
-
);
|
|
8019
|
-
try {
|
|
8020
|
-
const summarizer = new OneShotOrchestrator({
|
|
8021
|
-
buildProvider: input.buildProvider,
|
|
8022
|
-
getConfig: input.getConfig,
|
|
8023
|
-
fallbackProfileManager: input.fallbackProfileManager,
|
|
8024
|
-
statusTracker: input.statusTracker
|
|
8025
|
-
});
|
|
8026
|
-
input.toolRegistry.override(
|
|
8027
|
-
"context_manager",
|
|
8028
|
-
createContextManagerTool2({
|
|
8029
|
-
compactor: input.compactor,
|
|
8030
|
-
summarizer: async (messages) => {
|
|
8031
|
-
const result = await summarizer.call({
|
|
8032
|
-
system: "Summarize concisely. Keep decisions and key facts.",
|
|
8033
|
-
messages,
|
|
8034
|
-
model: "deepseek-chat",
|
|
8035
|
-
maxTokens: 1024,
|
|
8036
|
-
timeoutMs: 3e4
|
|
8037
|
-
});
|
|
8038
|
-
return result.text || "(summary unavailable)";
|
|
8039
|
-
}
|
|
8040
|
-
})
|
|
8041
|
-
);
|
|
8042
|
-
} catch {
|
|
8043
|
-
}
|
|
8044
|
-
}
|
|
8045
|
-
function registerOrOverride(registry, name, tool) {
|
|
8046
|
-
try {
|
|
8047
|
-
registry.register(tool);
|
|
8048
|
-
} catch {
|
|
8049
|
-
registry.override(name, tool);
|
|
8050
|
-
}
|
|
8051
|
-
}
|
|
8052
|
-
|
|
8053
8355
|
// src/wiring/runtime-controller-deps.ts
|
|
8054
8356
|
import { resolveConfiguredRefinerRef, resolveEnhanceFallbackRef } from "@wrongstack/core/execution";
|
|
8055
8357
|
function createRuntimeControllerDeps(input) {
|
|
@@ -9004,8 +9306,9 @@ async function setupSession(params) {
|
|
|
9004
9306
|
const tCounts = {};
|
|
9005
9307
|
for (const t of dirState.tasks) tCounts[t.status] = (tCounts[t.status] ?? 0) + 1;
|
|
9006
9308
|
const summary = Object.entries(tCounts).map(([k, v]) => `${v} ${k}`).join(", ");
|
|
9309
|
+
const spawnPart = typeof dirState.maxSpawns === "number" && Number.isFinite(dirState.maxSpawns) ? `, spawns ${dirState.spawnCount}/${dirState.maxSpawns} (checkpoint ceiling; live profile may differ)` : `, spawns used ${dirState.spawnCount}`;
|
|
9007
9310
|
renderer.writeInfo(
|
|
9008
|
-
`Prior fleet state: ${dirState.subagents.length} subagent${dirState.subagents.length === 1 ? "" : "s"}, tasks ${summary || "(none)"}.`
|
|
9311
|
+
`Prior fleet state: ${dirState.subagents.length} subagent${dirState.subagents.length === 1 ? "" : "s"}, tasks ${summary || "(none)"}${spawnPart}.`
|
|
9009
9312
|
);
|
|
9010
9313
|
}
|
|
9011
9314
|
} catch {
|
|
@@ -10533,11 +10836,18 @@ ${color13.dim("YOLO enabled; tool calls run without approval unless an explicit
|
|
|
10533
10836
|
// src/slash-commands/brain.ts
|
|
10534
10837
|
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
10535
10838
|
import { readFile as readFile7 } from "node:fs/promises";
|
|
10839
|
+
import { BUILTIN_COUNCIL_PERSONA_IDS, BUILTIN_COUNCIL_PERSONAS } from "@wrongstack/core/execution";
|
|
10536
10840
|
import { color as color14 } from "@wrongstack/core/utils";
|
|
10537
10841
|
import { parseModelRef } from "@wrongstack/core/agent";
|
|
10538
10842
|
var RISK_LEVELS = /* @__PURE__ */ new Set(["off", "low", "medium", "high", "all"]);
|
|
10539
10843
|
var COUNCIL_RISKS = /* @__PURE__ */ new Set(["medium", "high", "critical"]);
|
|
10540
|
-
var
|
|
10844
|
+
var COUNCIL_DISTINCTNESS = /* @__PURE__ */ new Set(["none", "model", "provider"]);
|
|
10845
|
+
var COUNCIL_NUMERIC_OPS = {
|
|
10846
|
+
timeout: "perCallTimeoutMs",
|
|
10847
|
+
concurrency: "maxConcurrency",
|
|
10848
|
+
judgetokens: "judgeMaxTokens"
|
|
10849
|
+
};
|
|
10850
|
+
var PERSONA_SHORTHANDS = new Set(BUILTIN_COUNCIL_PERSONA_IDS);
|
|
10541
10851
|
var HEURISTIC_FIELDS = {
|
|
10542
10852
|
lowrisk: "lowRiskAutoAnswer",
|
|
10543
10853
|
blocked: "blockedResolved",
|
|
@@ -10613,8 +10923,11 @@ function buildBrainCommand(opts) {
|
|
|
10613
10923
|
" /brain human-timeout <ms|off> Interactive escalation wait before terminal policy",
|
|
10614
10924
|
" /brain council on|off Enable/disable the multi-LLM council",
|
|
10615
10925
|
" /brain council minrisk <medium|high|critical>",
|
|
10616
|
-
" /brain council voters <seat> [<seat> ...] seat = <ref>[
|
|
10926
|
+
" /brain council voters <seat> [<seat> ...] seat = <ref>[:<persona>][:veto][:w=N]",
|
|
10927
|
+
" /brain council personas List the built-in decision lenses",
|
|
10617
10928
|
" /brain council judge <ref|auto> | quorum <0..1> | approval <0..1>",
|
|
10929
|
+
" /brain council distinctness <none|model|provider> warn on a non-diverse panel",
|
|
10930
|
+
" /brain council timeout|concurrency|judgetokens <n|default>",
|
|
10618
10931
|
" /brain ledger [n] Show the last n rows (default 15) of the persistent decision ledger",
|
|
10619
10932
|
" /brain ledger on|off | autodeny <n>",
|
|
10620
10933
|
" /brain stats Per-tier decision counts: how often the Brain actually calls a model",
|
|
@@ -10835,12 +11148,24 @@ function buildBrainCommand(opts) {
|
|
|
10835
11148
|
if (op === "voters") {
|
|
10836
11149
|
const seats = rest.slice(1).map(parseSeat);
|
|
10837
11150
|
if (seats.length === 0 || seats.some((s) => s === null)) {
|
|
10838
|
-
const msg3 =
|
|
11151
|
+
const msg3 = `Usage: /brain council voters <ref[:<persona>][:veto][:w=N]> [...] \u2014 personas: ${BUILTIN_COUNCIL_PERSONA_IDS.join(", ")} (see /brain council personas)`;
|
|
10839
11152
|
opts.renderer.writeWarning(msg3);
|
|
10840
11153
|
return { message: msg3 };
|
|
10841
11154
|
}
|
|
10842
11155
|
return applyPatch({ council: { voters: seats } }, councilSummary);
|
|
10843
11156
|
}
|
|
11157
|
+
if (op === "personas") {
|
|
11158
|
+
const lines = [
|
|
11159
|
+
"Council decision lenses (built-in):",
|
|
11160
|
+
...BUILTIN_COUNCIL_PERSONAS.map(
|
|
11161
|
+
(p) => ` ${color14.cyan(p.id.padEnd(15))} ${p.description}${p.defaultVeto ? color14.dim(" [veto by default]") : ""}`
|
|
11162
|
+
),
|
|
11163
|
+
color14.dim("Any other string is used verbatim as a custom lens instruction.")
|
|
11164
|
+
];
|
|
11165
|
+
const msg3 = lines.join("\n");
|
|
11166
|
+
opts.renderer.write(msg3);
|
|
11167
|
+
return { message: msg3 };
|
|
11168
|
+
}
|
|
10844
11169
|
if (op === "judge") {
|
|
10845
11170
|
const ref = rest[1];
|
|
10846
11171
|
if (!ref) {
|
|
@@ -10857,7 +11182,33 @@ function buildBrainCommand(opts) {
|
|
|
10857
11182
|
(s) => `Brain council ${op} set to ${color14.cyan(String(op === "quorum" ? s.council.quorum ?? 0.5 : s.council.approval ?? 0.5))}`
|
|
10858
11183
|
);
|
|
10859
11184
|
}
|
|
10860
|
-
|
|
11185
|
+
if (op === "distinctness") {
|
|
11186
|
+
const mode = (rest[1] ?? "").toLowerCase();
|
|
11187
|
+
if (!COUNCIL_DISTINCTNESS.has(mode)) {
|
|
11188
|
+
const msg3 = "Usage: /brain council distinctness <none|model|provider>";
|
|
11189
|
+
opts.renderer.writeWarning(msg3);
|
|
11190
|
+
return { message: msg3 };
|
|
11191
|
+
}
|
|
11192
|
+
return applyPatch(
|
|
11193
|
+
{ council: { distinctness: mode } },
|
|
11194
|
+
(s) => `Brain council distinctness set to ${color14.cyan(s.council.distinctness)}${mode === "none" ? color14.dim(" \u2014 a non-diverse panel will no longer be reported") : ""}`
|
|
11195
|
+
);
|
|
11196
|
+
}
|
|
11197
|
+
if (COUNCIL_NUMERIC_OPS[op]) {
|
|
11198
|
+
const field = COUNCIL_NUMERIC_OPS[op];
|
|
11199
|
+
const raw = rest[1];
|
|
11200
|
+
if (!raw) {
|
|
11201
|
+
const msg3 = `Usage: /brain council ${op} <positive integer | default>`;
|
|
11202
|
+
opts.renderer.writeWarning(msg3);
|
|
11203
|
+
return { message: msg3 };
|
|
11204
|
+
}
|
|
11205
|
+
const value = raw.toLowerCase() === "default" ? null : Number(raw);
|
|
11206
|
+
return applyPatch({ council: { [field]: value } }, (s) => {
|
|
11207
|
+
const applied = s.council[field];
|
|
11208
|
+
return `Brain council ${op} set to ${color14.cyan(applied === void 0 ? "default" : String(applied))}`;
|
|
11209
|
+
});
|
|
11210
|
+
}
|
|
11211
|
+
const msg2 = `Unknown council subcommand: ${op}. Use on, off, minrisk, voters, personas, judge, quorum, approval, distinctness, timeout, concurrency, or judgetokens.`;
|
|
10861
11212
|
opts.renderer.writeWarning(msg2);
|
|
10862
11213
|
return { message: msg2 };
|
|
10863
11214
|
}
|
|
@@ -11996,6 +12347,7 @@ function cacheMechanismLabel(providerId, cacheControl) {
|
|
|
11996
12347
|
if (id.includes("google") || id.includes("gemini")) {
|
|
11997
12348
|
return "implicit (auto) + explicit cachedContents (opt-in)";
|
|
11998
12349
|
}
|
|
12350
|
+
if (id.includes("gateway")) return "automatic (Gateway-managed, per routed upstream)";
|
|
11999
12351
|
if (cacheControl === "auto") return "automatic + prompt_cache_key routing";
|
|
12000
12352
|
return "none / provider-managed";
|
|
12001
12353
|
}
|
|
@@ -12998,6 +13350,58 @@ function diagnoseConfig(cfg, plugins = []) {
|
|
|
12998
13350
|
}
|
|
12999
13351
|
}
|
|
13000
13352
|
}
|
|
13353
|
+
if ("fleet" in fixed) {
|
|
13354
|
+
if (!isPlainObject(fixed["fleet"])) {
|
|
13355
|
+
findings.push({
|
|
13356
|
+
path: "fleet",
|
|
13357
|
+
problem: `expected object, got ${JSON.stringify(fixed["fleet"])}`,
|
|
13358
|
+
severity: "error",
|
|
13359
|
+
fix: "removed (built-in defaults apply)"
|
|
13360
|
+
});
|
|
13361
|
+
delete fixed["fleet"];
|
|
13362
|
+
} else {
|
|
13363
|
+
const fleet = fixed["fleet"];
|
|
13364
|
+
if ("budget" in fleet) {
|
|
13365
|
+
if (!isPlainObject(fleet["budget"])) {
|
|
13366
|
+
findings.push({
|
|
13367
|
+
path: "fleet.budget",
|
|
13368
|
+
problem: `expected object, got ${JSON.stringify(fleet["budget"])}`,
|
|
13369
|
+
severity: "error",
|
|
13370
|
+
fix: "removed (built-in defaults apply)"
|
|
13371
|
+
});
|
|
13372
|
+
delete fleet["budget"];
|
|
13373
|
+
} else {
|
|
13374
|
+
const budget = fleet["budget"];
|
|
13375
|
+
for (const key of ["maxSpawns", "maxTokens", "maxCostUsd"]) {
|
|
13376
|
+
if (!(key in budget)) continue;
|
|
13377
|
+
const v = budget[key];
|
|
13378
|
+
const n = coerceNumber(v);
|
|
13379
|
+
if (n === void 0) {
|
|
13380
|
+
delete budget[key];
|
|
13381
|
+
findings.push({
|
|
13382
|
+
path: `fleet.budget.${key}`,
|
|
13383
|
+
problem: `expected a non-negative number, got ${JSON.stringify(v)}`,
|
|
13384
|
+
severity: "error",
|
|
13385
|
+
fix: "removed (built-in default applies)"
|
|
13386
|
+
});
|
|
13387
|
+
} else {
|
|
13388
|
+
const clamped = Math.max(0, n);
|
|
13389
|
+
const next = key === "maxCostUsd" ? clamped : Math.floor(clamped);
|
|
13390
|
+
if (next !== v) {
|
|
13391
|
+
budget[key] = next;
|
|
13392
|
+
findings.push({
|
|
13393
|
+
path: `fleet.budget.${key}`,
|
|
13394
|
+
problem: `expected a non-negative ${key === "maxCostUsd" ? "number" : "integer"}, got ${JSON.stringify(v)}`,
|
|
13395
|
+
severity: "error",
|
|
13396
|
+
fix: `set to ${next}`
|
|
13397
|
+
});
|
|
13398
|
+
}
|
|
13399
|
+
}
|
|
13400
|
+
}
|
|
13401
|
+
}
|
|
13402
|
+
}
|
|
13403
|
+
}
|
|
13404
|
+
}
|
|
13001
13405
|
for (const key of ["provider", "model"]) {
|
|
13002
13406
|
if (key in fixed && typeof fixed[key] !== "string") {
|
|
13003
13407
|
findings.push({
|
|
@@ -13281,7 +13685,7 @@ function buildDoctorCommand(opts) {
|
|
|
13281
13685
|
].join("\n");
|
|
13282
13686
|
async function loadPluginSchemas() {
|
|
13283
13687
|
try {
|
|
13284
|
-
const { BUILTIN_PLUGIN_FACTORIES } = await import("./plugins-
|
|
13688
|
+
const { BUILTIN_PLUGIN_FACTORIES } = await import("./plugins-56CMWMPR.js");
|
|
13285
13689
|
const settled = await Promise.allSettled(BUILTIN_PLUGIN_FACTORIES.map((f) => f()));
|
|
13286
13690
|
const loaded = [];
|
|
13287
13691
|
for (const s of settled) {
|
|
@@ -15198,6 +15602,17 @@ async function handleStatus(opts, cmd) {
|
|
|
15198
15602
|
lines.push(` ${id} ${name} ${statusColor} ${ext}${task}`);
|
|
15199
15603
|
}
|
|
15200
15604
|
}
|
|
15605
|
+
const budget = opts.onFleetBudget?.();
|
|
15606
|
+
if (budget) {
|
|
15607
|
+
lines.push(
|
|
15608
|
+
"",
|
|
15609
|
+
...formatFleetBudgetLines(budget, {
|
|
15610
|
+
bold: color26.bold,
|
|
15611
|
+
dim: color26.dim,
|
|
15612
|
+
amber: color26.amber
|
|
15613
|
+
})
|
|
15614
|
+
);
|
|
15615
|
+
}
|
|
15201
15616
|
const msg2 = lines.join("\n");
|
|
15202
15617
|
opts.renderer.write(msg2);
|
|
15203
15618
|
return { message: msg2 };
|
|
@@ -16320,6 +16735,78 @@ async function fileExists(filePath) {
|
|
|
16320
16735
|
}
|
|
16321
16736
|
}
|
|
16322
16737
|
|
|
16738
|
+
// src/slash-commands/intake.ts
|
|
16739
|
+
import {
|
|
16740
|
+
AllowAllIntakeAuthorizer,
|
|
16741
|
+
RequirementIntakeService,
|
|
16742
|
+
RequirementIntakeStore
|
|
16743
|
+
} from "@wrongstack/requirement-intake";
|
|
16744
|
+
import { ensureProjectIdentity, resolveWstackPaths as resolveWstackPaths2 } from "@wrongstack/core/utils";
|
|
16745
|
+
var INTAKE_ACTOR = { id: "cli-operator", type: "user" };
|
|
16746
|
+
function lastUserPrompt(opts) {
|
|
16747
|
+
const ctx = opts.context;
|
|
16748
|
+
if (!ctx) return "";
|
|
16749
|
+
for (let index = ctx.messages.length - 1; index >= 0; index -= 1) {
|
|
16750
|
+
const message = ctx.messages[index];
|
|
16751
|
+
if (message?.role === "user" && typeof message.content === "string") {
|
|
16752
|
+
const trimmed = message.content.trim();
|
|
16753
|
+
if (trimmed.length > 0) return trimmed;
|
|
16754
|
+
}
|
|
16755
|
+
}
|
|
16756
|
+
return "";
|
|
16757
|
+
}
|
|
16758
|
+
function buildIntakeCommand(opts) {
|
|
16759
|
+
return {
|
|
16760
|
+
name: "intake",
|
|
16761
|
+
category: "Run",
|
|
16762
|
+
description: "Create and submit a requirement intake record from the current prompt (or given text)",
|
|
16763
|
+
argsHint: "[request text]",
|
|
16764
|
+
help: [
|
|
16765
|
+
"/intake [text] Create + submit a requirement intake record.",
|
|
16766
|
+
" No text \u2192 uses the most recent prompt in this session.",
|
|
16767
|
+
"",
|
|
16768
|
+
"The exact text is preserved verbatim as the record's original request;",
|
|
16769
|
+
"the record is stored under the project state dir and is ready for",
|
|
16770
|
+
"downstream modules (SDD interview kickoff, planning)."
|
|
16771
|
+
].join("\n"),
|
|
16772
|
+
async run(args) {
|
|
16773
|
+
const text = args.trim() || lastUserPrompt(opts);
|
|
16774
|
+
if (!text) {
|
|
16775
|
+
return {
|
|
16776
|
+
message: "Nothing to intake \u2014 give the request as text or submit a prompt first.\nUsage: /intake <request text>"
|
|
16777
|
+
};
|
|
16778
|
+
}
|
|
16779
|
+
const identity = await ensureProjectIdentity(opts.projectRoot);
|
|
16780
|
+
const projectId = identity.identity.projectId;
|
|
16781
|
+
const baseDir = opts.paths?.projectRequirementIntakes ?? resolveWstackPaths2({ projectRoot: opts.projectRoot }).projectRequirementIntakes;
|
|
16782
|
+
const service = new RequirementIntakeService({
|
|
16783
|
+
store: new RequirementIntakeStore({ baseDir }),
|
|
16784
|
+
authorizer: new AllowAllIntakeAuthorizer()
|
|
16785
|
+
});
|
|
16786
|
+
const ctx = { ...INTAKE_ACTOR, projectId };
|
|
16787
|
+
const { record, created, idempotent } = await service.createIntake(
|
|
16788
|
+
{ projectId, originalRequest: text, requestedBy: ctx.id },
|
|
16789
|
+
ctx
|
|
16790
|
+
);
|
|
16791
|
+
const { record: submitted } = await service.submitIntake(record.id, ctx);
|
|
16792
|
+
return {
|
|
16793
|
+
message: [
|
|
16794
|
+
idempotent ? "\u26A0 Already recorded \u2014 resubmitted the existing record:" : "\u{1F4E5} Requirement intake recorded:",
|
|
16795
|
+
` id: ${submitted.id}`,
|
|
16796
|
+
` title: ${submitted.title}`,
|
|
16797
|
+
` type: ${submitted.requestType}`,
|
|
16798
|
+
` status: ${submitted.status} (${created ? "new" : "existing"})`,
|
|
16799
|
+
` stored: ${baseDir}`,
|
|
16800
|
+
"",
|
|
16801
|
+
"Use /sdd to turn this into a specification. Records live under the",
|
|
16802
|
+
"project state dir (see `stored` above) and are consumed by the",
|
|
16803
|
+
"WebUI requirement-intake API."
|
|
16804
|
+
].join("\n")
|
|
16805
|
+
};
|
|
16806
|
+
}
|
|
16807
|
+
};
|
|
16808
|
+
}
|
|
16809
|
+
|
|
16323
16810
|
// src/slash-commands/kanban.ts
|
|
16324
16811
|
import {
|
|
16325
16812
|
addCheckToTask,
|
|
@@ -18300,7 +18787,7 @@ function errorMessage(err) {
|
|
|
18300
18787
|
}
|
|
18301
18788
|
|
|
18302
18789
|
// src/slash-commands/memory.ts
|
|
18303
|
-
import { toErrorMessage as
|
|
18790
|
+
import { toErrorMessage as toErrorMessage18 } from "@wrongstack/core/utils";
|
|
18304
18791
|
import { getSageSurface as getSageSurface2 } from "@wrongstack/sage";
|
|
18305
18792
|
|
|
18306
18793
|
// src/slash-commands/memory-compact.ts
|
|
@@ -18564,6 +19051,240 @@ function parseCompactEntries(raw) {
|
|
|
18564
19051
|
return entries;
|
|
18565
19052
|
}
|
|
18566
19053
|
|
|
19054
|
+
// src/slash-commands/memory-triage.ts
|
|
19055
|
+
import { toErrorMessage as toErrorMessage17 } from "@wrongstack/core/utils";
|
|
19056
|
+
import { runTriage, formatTriageReport } from "@wrongstack/sage";
|
|
19057
|
+
var DEFAULT_MAX_PHASE3 = 1e3;
|
|
19058
|
+
var DEFAULT_MAX_PHASE4_PAIRS = 50;
|
|
19059
|
+
async function runTriageCommand(opts, args) {
|
|
19060
|
+
const Sage = getSage(opts);
|
|
19061
|
+
if (!Sage) return { message: "No SAGE surface available." };
|
|
19062
|
+
let dryRun = true;
|
|
19063
|
+
let limit;
|
|
19064
|
+
let maxPhase3 = DEFAULT_MAX_PHASE3;
|
|
19065
|
+
let maxPhase4Pairs = DEFAULT_MAX_PHASE4_PAIRS;
|
|
19066
|
+
const flagErrors = [];
|
|
19067
|
+
for (let i = 0; i < args.length; i++) {
|
|
19068
|
+
const token = args[i];
|
|
19069
|
+
if (!token) continue;
|
|
19070
|
+
if (!token.startsWith("--")) continue;
|
|
19071
|
+
const name = token.slice(2).toLowerCase();
|
|
19072
|
+
const next = args[i + 1];
|
|
19073
|
+
switch (name) {
|
|
19074
|
+
case "dry-run":
|
|
19075
|
+
dryRun = true;
|
|
19076
|
+
break;
|
|
19077
|
+
case "apply":
|
|
19078
|
+
dryRun = false;
|
|
19079
|
+
break;
|
|
19080
|
+
case "limit": {
|
|
19081
|
+
if (next === void 0 || next.startsWith("--")) {
|
|
19082
|
+
flagErrors.push("--limit needs a value.");
|
|
19083
|
+
continue;
|
|
19084
|
+
}
|
|
19085
|
+
const parsed = Number.parseInt(next, 10);
|
|
19086
|
+
if (!Number.isFinite(parsed) || parsed < 1) {
|
|
19087
|
+
flagErrors.push(`--limit must be a positive integer (got "${next}").`);
|
|
19088
|
+
continue;
|
|
19089
|
+
}
|
|
19090
|
+
limit = Math.min(500, Math.max(1, parsed));
|
|
19091
|
+
i++;
|
|
19092
|
+
break;
|
|
19093
|
+
}
|
|
19094
|
+
case "max-phase3": {
|
|
19095
|
+
if (next === void 0 || next.startsWith("--")) {
|
|
19096
|
+
flagErrors.push("--max-phase3 needs a value.");
|
|
19097
|
+
continue;
|
|
19098
|
+
}
|
|
19099
|
+
const parsed = Number.parseInt(next, 10);
|
|
19100
|
+
if (!Number.isFinite(parsed) || parsed < 1) {
|
|
19101
|
+
flagErrors.push(`--max-phase3 must be a positive integer (got "${next}").`);
|
|
19102
|
+
continue;
|
|
19103
|
+
}
|
|
19104
|
+
maxPhase3 = parsed;
|
|
19105
|
+
i++;
|
|
19106
|
+
break;
|
|
19107
|
+
}
|
|
19108
|
+
case "max-phase4-pairs": {
|
|
19109
|
+
if (next === void 0 || next.startsWith("--")) {
|
|
19110
|
+
flagErrors.push("--max-phase4-pairs needs a value.");
|
|
19111
|
+
continue;
|
|
19112
|
+
}
|
|
19113
|
+
const parsed = Number.parseInt(next, 10);
|
|
19114
|
+
if (!Number.isFinite(parsed) || parsed < 1) {
|
|
19115
|
+
flagErrors.push(`--max-phase4-pairs must be a positive integer (got "${next}").`);
|
|
19116
|
+
continue;
|
|
19117
|
+
}
|
|
19118
|
+
maxPhase4Pairs = parsed;
|
|
19119
|
+
i++;
|
|
19120
|
+
break;
|
|
19121
|
+
}
|
|
19122
|
+
default:
|
|
19123
|
+
flagErrors.push(`Unknown flag "--${name}".`);
|
|
19124
|
+
}
|
|
19125
|
+
}
|
|
19126
|
+
if (flagErrors.length > 0) {
|
|
19127
|
+
return {
|
|
19128
|
+
message: `Cannot triage:
|
|
19129
|
+
- ${flagErrors.join("\n- ")}
|
|
19130
|
+
|
|
19131
|
+
Usage: /memory triage [--dry-run|--apply] [--limit N] [--max-phase3 N] [--max-phase4-pairs N]`
|
|
19132
|
+
};
|
|
19133
|
+
}
|
|
19134
|
+
const memories = await loadActiveMemories(Sage, limit);
|
|
19135
|
+
if (memories.length === 0) {
|
|
19136
|
+
return { message: "No active memories to triage." };
|
|
19137
|
+
}
|
|
19138
|
+
const provider = opts.llmProvider;
|
|
19139
|
+
const model = opts.llmModel ?? "";
|
|
19140
|
+
const callLlm = provider?.complete ? async (system, userPrompt) => {
|
|
19141
|
+
const signal = AbortSignal.timeout(3e4);
|
|
19142
|
+
const response = await provider.complete(
|
|
19143
|
+
{
|
|
19144
|
+
model,
|
|
19145
|
+
system: [{ type: "text", text: system }],
|
|
19146
|
+
messages: [{ role: "user", content: userPrompt }],
|
|
19147
|
+
maxTokens: 60,
|
|
19148
|
+
temperature: 0.1
|
|
19149
|
+
},
|
|
19150
|
+
{ signal }
|
|
19151
|
+
);
|
|
19152
|
+
return response.content.filter((b) => b.type === "text").map((b) => b.text).join("").trim();
|
|
19153
|
+
} : async () => "3";
|
|
19154
|
+
let report;
|
|
19155
|
+
try {
|
|
19156
|
+
report = await runTriage(memories, callLlm, {
|
|
19157
|
+
dryRun,
|
|
19158
|
+
maxPhase3Calls: maxPhase3,
|
|
19159
|
+
maxPhase4Pairs,
|
|
19160
|
+
verbose: false
|
|
19161
|
+
});
|
|
19162
|
+
} catch (err) {
|
|
19163
|
+
return { message: `Triage failed: ${toErrorMessage17(err)}` };
|
|
19164
|
+
}
|
|
19165
|
+
if (!dryRun) {
|
|
19166
|
+
const applyReport = await applyDispatch(Sage, report);
|
|
19167
|
+
return {
|
|
19168
|
+
message: formatTriageReport(report) + "\n\n" + applyReport
|
|
19169
|
+
};
|
|
19170
|
+
}
|
|
19171
|
+
return { message: formatTriageReport(report) };
|
|
19172
|
+
}
|
|
19173
|
+
function getSage(opts) {
|
|
19174
|
+
if (!opts.memoryStore) return null;
|
|
19175
|
+
try {
|
|
19176
|
+
const { getSageSurface: getSageSurface3 } = __require("@wrongstack/sage");
|
|
19177
|
+
return getSageSurface3(opts.memoryStore);
|
|
19178
|
+
} catch {
|
|
19179
|
+
return null;
|
|
19180
|
+
}
|
|
19181
|
+
}
|
|
19182
|
+
async function loadActiveMemories(Sage, limit) {
|
|
19183
|
+
const all = [];
|
|
19184
|
+
let cursor;
|
|
19185
|
+
while (true) {
|
|
19186
|
+
const pageSize = limit ? Math.min(500, limit - all.length) : 500;
|
|
19187
|
+
if (pageSize <= 0) break;
|
|
19188
|
+
const page = await Sage.listSagePage({
|
|
19189
|
+
statuses: ["active", "stale"],
|
|
19190
|
+
limit: pageSize,
|
|
19191
|
+
cursor
|
|
19192
|
+
});
|
|
19193
|
+
all.push(...page.memories);
|
|
19194
|
+
if (limit && all.length >= limit) break;
|
|
19195
|
+
if (!page.nextCursor) break;
|
|
19196
|
+
cursor = page.nextCursor;
|
|
19197
|
+
}
|
|
19198
|
+
return limit ? all.slice(0, limit) : all;
|
|
19199
|
+
}
|
|
19200
|
+
async function applyDispatch(Sage, report) {
|
|
19201
|
+
const lines = ["## Apply Results", ""];
|
|
19202
|
+
let autoOk = 0;
|
|
19203
|
+
let autoFail = 0;
|
|
19204
|
+
for (const action of report.dispatch.autoApply) {
|
|
19205
|
+
const patch = {};
|
|
19206
|
+
for (const update of action.updates) {
|
|
19207
|
+
if (update.field === "status") {
|
|
19208
|
+
patch.status = update.value;
|
|
19209
|
+
} else if (update.field === "confidence") {
|
|
19210
|
+
patch.confidence = update.value;
|
|
19211
|
+
} else if (update.field === "importance") {
|
|
19212
|
+
patch.importance = update.value;
|
|
19213
|
+
}
|
|
19214
|
+
}
|
|
19215
|
+
try {
|
|
19216
|
+
await Sage.updateSage(action.memoryId, patch);
|
|
19217
|
+
autoOk++;
|
|
19218
|
+
} catch (err) {
|
|
19219
|
+
autoFail++;
|
|
19220
|
+
lines.push(` \u2717 Failed to update ${action.memoryId}: ${toErrorMessage17(err)}`);
|
|
19221
|
+
}
|
|
19222
|
+
}
|
|
19223
|
+
lines.push(`**Auto-apply:** ${autoOk} succeeded, ${autoFail} failed`);
|
|
19224
|
+
lines.push("");
|
|
19225
|
+
let mergeOk = 0;
|
|
19226
|
+
let mergeFail = 0;
|
|
19227
|
+
for (const merge of report.merges.merges) {
|
|
19228
|
+
try {
|
|
19229
|
+
await Sage.updateSage(merge.supersededId, { status: "superseded" });
|
|
19230
|
+
await Sage.updateSage(merge.keeperId, { supersedes: [merge.supersededId] });
|
|
19231
|
+
mergeOk++;
|
|
19232
|
+
} catch (err) {
|
|
19233
|
+
mergeFail++;
|
|
19234
|
+
lines.push(` \u2717 Failed to merge ${merge.supersededId} \u2192 ${merge.keeperId}: ${toErrorMessage17(err)}`);
|
|
19235
|
+
}
|
|
19236
|
+
}
|
|
19237
|
+
lines.push(`**Merges:** ${mergeOk} succeeded, ${mergeFail} failed`);
|
|
19238
|
+
lines.push("");
|
|
19239
|
+
const proposalResult = await fileProposals(Sage, report.dispatch.proposals);
|
|
19240
|
+
if (proposalResult.total > 0) {
|
|
19241
|
+
lines.push(
|
|
19242
|
+
`**Proposals:** ${proposalResult.filed} of ${proposalResult.total} filed via memory_candidates (use \`/memory candidates\` to accept/reject).`
|
|
19243
|
+
);
|
|
19244
|
+
}
|
|
19245
|
+
for (const failure of proposalResult.failures) {
|
|
19246
|
+
lines.push(` \u2717 Failed to file proposal for ${failure.memoryId}: ${failure.error}`);
|
|
19247
|
+
}
|
|
19248
|
+
return lines.join("\n");
|
|
19249
|
+
}
|
|
19250
|
+
async function fileProposals(Sage, proposals) {
|
|
19251
|
+
const inputs = [];
|
|
19252
|
+
const failures = [];
|
|
19253
|
+
let filed = 0;
|
|
19254
|
+
for (const proposal of proposals) {
|
|
19255
|
+
const input = {
|
|
19256
|
+
text: proposal.memoryText,
|
|
19257
|
+
targetMemoryId: proposal.memoryId,
|
|
19258
|
+
reviewReason: proposal.reason,
|
|
19259
|
+
suggestedAction: proposal.suggestedAction,
|
|
19260
|
+
kind: "memory_review",
|
|
19261
|
+
scope: "project",
|
|
19262
|
+
importance: 0.5,
|
|
19263
|
+
confidence: 0.9,
|
|
19264
|
+
tags: ["triage"],
|
|
19265
|
+
anchors: [],
|
|
19266
|
+
sources: [{ type: "project_instruction" }]
|
|
19267
|
+
};
|
|
19268
|
+
inputs.push(input);
|
|
19269
|
+
try {
|
|
19270
|
+
await Sage.createCandidate(input);
|
|
19271
|
+
filed++;
|
|
19272
|
+
} catch (err) {
|
|
19273
|
+
failures.push({
|
|
19274
|
+
memoryId: proposal.memoryId,
|
|
19275
|
+
error: toErrorMessage17(err)
|
|
19276
|
+
});
|
|
19277
|
+
}
|
|
19278
|
+
}
|
|
19279
|
+
return {
|
|
19280
|
+
filed,
|
|
19281
|
+
failed: failures.length,
|
|
19282
|
+
total: proposals.length,
|
|
19283
|
+
failures,
|
|
19284
|
+
inputs
|
|
19285
|
+
};
|
|
19286
|
+
}
|
|
19287
|
+
|
|
18567
19288
|
// src/slash-commands/memory-formatters.ts
|
|
18568
19289
|
function previewText(text, maxLen) {
|
|
18569
19290
|
if (text.length <= maxLen) return text;
|
|
@@ -18918,7 +19639,7 @@ function buildMemoryCommand(opts) {
|
|
|
18918
19639
|
return {
|
|
18919
19640
|
name: "memory",
|
|
18920
19641
|
category: "Inspect",
|
|
18921
|
-
description: "Inspect or edit persistent memory: /memory [show|search|file|path|for-file|graph|gather|remember|update|delete|forget|hygiene|verify|candidates|audit|import-legacy|clear|compact|compact-log|stats|audience]",
|
|
19642
|
+
description: "Inspect or edit persistent memory: /memory [show|search|file|path|for-file|graph|gather|remember|update|delete|forget|hygiene|verify|candidates|triage|audit|import-legacy|clear|compact|compact-log|stats|audience]",
|
|
18922
19643
|
async run(args) {
|
|
18923
19644
|
const store = opts.memoryStore;
|
|
18924
19645
|
if (!store) return { message: "No memory store configured." };
|
|
@@ -18981,7 +19702,7 @@ function buildMemoryCommand(opts) {
|
|
|
18981
19702
|
message: `Remembered \`${memory.id}\` [${memory.kind}] ${memory.text}${tags}`
|
|
18982
19703
|
};
|
|
18983
19704
|
} catch (err) {
|
|
18984
|
-
return { message: `Could not remember: ${
|
|
19705
|
+
return { message: `Could not remember: ${toErrorMessage18(err)}` };
|
|
18985
19706
|
}
|
|
18986
19707
|
}
|
|
18987
19708
|
case "update":
|
|
@@ -19019,7 +19740,7 @@ function buildMemoryCommand(opts) {
|
|
|
19019
19740
|
message: `Updated \`${memory.id}\` [${memory.kind}|${memory.status}] ${memory.text}`
|
|
19020
19741
|
};
|
|
19021
19742
|
} catch (err) {
|
|
19022
|
-
return { message: `Could not update: ${
|
|
19743
|
+
return { message: `Could not update: ${toErrorMessage18(err)}` };
|
|
19023
19744
|
}
|
|
19024
19745
|
}
|
|
19025
19746
|
case "delete":
|
|
@@ -19034,7 +19755,7 @@ function buildMemoryCommand(opts) {
|
|
|
19034
19755
|
await Sage.deleteSage(id, reason, { force: true });
|
|
19035
19756
|
return { message: `Deleted \`${id}\`.` };
|
|
19036
19757
|
} catch (err) {
|
|
19037
|
-
return { message: `Could not delete: ${
|
|
19758
|
+
return { message: `Could not delete: ${toErrorMessage18(err)}` };
|
|
19038
19759
|
}
|
|
19039
19760
|
}
|
|
19040
19761
|
case "forget":
|
|
@@ -19253,7 +19974,7 @@ function buildMemoryCommand(opts) {
|
|
|
19253
19974
|
}
|
|
19254
19975
|
return { message: lines.join("\n") };
|
|
19255
19976
|
} catch (err) {
|
|
19256
|
-
return { message: `gather failed: ${
|
|
19977
|
+
return { message: `gather failed: ${toErrorMessage18(err)}` };
|
|
19257
19978
|
}
|
|
19258
19979
|
}
|
|
19259
19980
|
case "verify": {
|
|
@@ -19289,6 +20010,10 @@ function buildMemoryCommand(opts) {
|
|
|
19289
20010
|
message: formatCandidates(await Sage.listCandidates(action === "all"))
|
|
19290
20011
|
};
|
|
19291
20012
|
}
|
|
20013
|
+
case "triage": {
|
|
20014
|
+
if (!Sage) return requiresSage("triage");
|
|
20015
|
+
return runTriageCommand(opts, rest);
|
|
20016
|
+
}
|
|
19292
20017
|
case "audit": {
|
|
19293
20018
|
if (!Sage?.readAudit) return requiresSage("audit");
|
|
19294
20019
|
return { message: formatAudit(await Sage.readAudit(50)) };
|
|
@@ -19344,7 +20069,7 @@ function buildMemoryCommand(opts) {
|
|
|
19344
20069
|
File size reduced. Audit-logged as \`memory.log_compacted\`.`
|
|
19345
20070
|
};
|
|
19346
20071
|
} catch (err) {
|
|
19347
|
-
return { message: `Compaction failed: ${
|
|
20072
|
+
return { message: `Compaction failed: ${toErrorMessage18(err)}` };
|
|
19348
20073
|
}
|
|
19349
20074
|
}
|
|
19350
20075
|
case "stats": {
|
|
@@ -19404,6 +20129,7 @@ File size reduced. Audit-logged as \`memory.log_compacted\`.`
|
|
|
19404
20129
|
"hygiene",
|
|
19405
20130
|
"verify",
|
|
19406
20131
|
"candidates",
|
|
20132
|
+
"triage",
|
|
19407
20133
|
"audit",
|
|
19408
20134
|
"import-legacy",
|
|
19409
20135
|
"clear",
|
|
@@ -19571,7 +20297,7 @@ async function runAudienceMemory(store, rest) {
|
|
|
19571
20297
|
message: `Remembered \`${memory.id}\` for ${formatAudienceSelector(memory.audience)}: ${memory.text}`
|
|
19572
20298
|
};
|
|
19573
20299
|
} catch (err) {
|
|
19574
|
-
return { message: `Could not remember: ${
|
|
20300
|
+
return { message: `Could not remember: ${toErrorMessage18(err)}` };
|
|
19575
20301
|
}
|
|
19576
20302
|
}
|
|
19577
20303
|
if (sub === "clear") {
|
|
@@ -19583,7 +20309,7 @@ async function runAudienceMemory(store, rest) {
|
|
|
19583
20309
|
message: `Cleared audience scope from \`${id}\` \u2014 it is now general project memory.`
|
|
19584
20310
|
};
|
|
19585
20311
|
} catch (err) {
|
|
19586
|
-
return { message: `Could not clear audience: ${
|
|
20312
|
+
return { message: `Could not clear audience: ${toErrorMessage18(err)}` };
|
|
19587
20313
|
}
|
|
19588
20314
|
}
|
|
19589
20315
|
if (sub === "search" || sub === "find") {
|
|
@@ -20212,7 +20938,7 @@ function buildModelCapsCommand(opts) {
|
|
|
20212
20938
|
|
|
20213
20939
|
// src/slash-commands/models.ts
|
|
20214
20940
|
import * as fs15 from "node:fs/promises";
|
|
20215
|
-
import { toErrorMessage as
|
|
20941
|
+
import { toErrorMessage as toErrorMessage19 } from "@wrongstack/core/utils";
|
|
20216
20942
|
import { atomicWrite as atomicWrite7, color as color37 } from "@wrongstack/core/utils";
|
|
20217
20943
|
import { ConfigError as ConfigError4, ToolValidationError as ToolValidationError4 } from "@wrongstack/core/types";
|
|
20218
20944
|
import { decryptConfigSecrets as decryptConfigSecrets3, encryptConfigSecrets as encryptConfigSecrets3, noOpVault as noOpVault4 } from "@wrongstack/core/security";
|
|
@@ -20447,7 +21173,7 @@ function buildModelsCommand(opts) {
|
|
|
20447
21173
|
};
|
|
20448
21174
|
} catch (err) {
|
|
20449
21175
|
return {
|
|
20450
|
-
message: `${color37.red("models error")}: ${
|
|
21176
|
+
message: `${color37.red("models error")}: ${toErrorMessage19(err)}`
|
|
20451
21177
|
};
|
|
20452
21178
|
}
|
|
20453
21179
|
}
|
|
@@ -21296,7 +22022,7 @@ function buildPruneCommand(opts) {
|
|
|
21296
22022
|
// src/slash-commands/refiner.ts
|
|
21297
22023
|
import { color as color42 } from "@wrongstack/core/utils";
|
|
21298
22024
|
import { noOpVault as noOpVault5 } from "@wrongstack/core/security";
|
|
21299
|
-
import { toErrorMessage as
|
|
22025
|
+
import { toErrorMessage as toErrorMessage20 } from "@wrongstack/core/utils";
|
|
21300
22026
|
function buildRefinerCommand(opts) {
|
|
21301
22027
|
const help = [
|
|
21302
22028
|
"Usage:",
|
|
@@ -21394,7 +22120,7 @@ function buildRefinerCommand(opts) {
|
|
|
21394
22120
|
};
|
|
21395
22121
|
} catch (err) {
|
|
21396
22122
|
return {
|
|
21397
|
-
message: `${color42.red("refiner error")}: ${
|
|
22123
|
+
message: `${color42.red("refiner error")}: ${toErrorMessage20(err)}`
|
|
21398
22124
|
};
|
|
21399
22125
|
}
|
|
21400
22126
|
}
|
|
@@ -21416,7 +22142,7 @@ function buildRefinerCommand(opts) {
|
|
|
21416
22142
|
};
|
|
21417
22143
|
} catch (err) {
|
|
21418
22144
|
return {
|
|
21419
|
-
message: `${color42.red("refiner error")}: ${
|
|
22145
|
+
message: `${color42.red("refiner error")}: ${toErrorMessage20(err)}`
|
|
21420
22146
|
};
|
|
21421
22147
|
}
|
|
21422
22148
|
}
|
|
@@ -22594,7 +23320,7 @@ ${sddHelp()}`
|
|
|
22594
23320
|
// src/slash-commands/session.ts
|
|
22595
23321
|
import { color as color43, isPidAlive } from "@wrongstack/core/utils";
|
|
22596
23322
|
import { SessionRecovery } from "@wrongstack/core/storage";
|
|
22597
|
-
import { toErrorMessage as
|
|
23323
|
+
import { toErrorMessage as toErrorMessage21 } from "@wrongstack/core/utils";
|
|
22598
23324
|
function statusIcon2(status) {
|
|
22599
23325
|
switch (status) {
|
|
22600
23326
|
case "active":
|
|
@@ -22712,7 +23438,7 @@ function buildLoadCommand(opts) {
|
|
|
22712
23438
|
message: name ? color43.green(`Renamed ${targetId} \u2192 "${name}"`) : color43.green(`Cleared name on ${targetId} (title: "${summary.title}")`)
|
|
22713
23439
|
};
|
|
22714
23440
|
} catch (err) {
|
|
22715
|
-
return { message: color43.red(`Rename failed: ${
|
|
23441
|
+
return { message: color43.red(`Rename failed: ${toErrorMessage21(err)}`) };
|
|
22716
23442
|
}
|
|
22717
23443
|
}
|
|
22718
23444
|
if (first === "delete") {
|
|
@@ -22738,7 +23464,7 @@ function buildLoadCommand(opts) {
|
|
|
22738
23464
|
await opts.sessionStore.delete(targetId);
|
|
22739
23465
|
return { message: color43.green(`Deleted session ${targetId}`) };
|
|
22740
23466
|
} catch (err) {
|
|
22741
|
-
return { message: color43.red(`Delete failed: ${
|
|
23467
|
+
return { message: color43.red(`Delete failed: ${toErrorMessage21(err)}`) };
|
|
22742
23468
|
}
|
|
22743
23469
|
}
|
|
22744
23470
|
const showIncomplete = parts.includes("--incomplete") || parts.includes("-i");
|
|
@@ -23076,7 +23802,7 @@ async function killSession(sessionId, confirm) {
|
|
|
23076
23802
|
} catch (err) {
|
|
23077
23803
|
return {
|
|
23078
23804
|
message: color43.red(
|
|
23079
|
-
`Failed to kill session: ${
|
|
23805
|
+
`Failed to kill session: ${toErrorMessage21(err)}`
|
|
23080
23806
|
)
|
|
23081
23807
|
};
|
|
23082
23808
|
}
|
|
@@ -23084,7 +23810,7 @@ async function killSession(sessionId, confirm) {
|
|
|
23084
23810
|
|
|
23085
23811
|
// src/slash-commands/setmodel.ts
|
|
23086
23812
|
import * as fs16 from "node:fs/promises";
|
|
23087
|
-
import { toErrorMessage as
|
|
23813
|
+
import { toErrorMessage as toErrorMessage22 } from "@wrongstack/core/utils";
|
|
23088
23814
|
import { AGENT_CATALOG as AGENT_CATALOG2, AGENTS_BY_PHASE as AGENTS_BY_PHASE3 } from "@wrongstack/core/agent-catalog";
|
|
23089
23815
|
import { atomicWrite as atomicWrite9, color as color44, expectDefined as expectDefined8 } from "@wrongstack/core/utils";
|
|
23090
23816
|
import { ConfigError as ConfigError5 } from "@wrongstack/core/types";
|
|
@@ -23092,6 +23818,26 @@ import { fallbackProfileChain } from "@wrongstack/core/agent";
|
|
|
23092
23818
|
import { decryptConfigSecrets as decryptConfigSecrets4, encryptConfigSecrets as encryptConfigSecrets4, noOpVault as noOpVault6 } from "@wrongstack/core/security";
|
|
23093
23819
|
import { MATRIX_PHASE_KEYS, matrixKeyKind, phaseForRole, resolveModelMatrix, resolveModelTargetFromEntry } from "@wrongstack/core/coordination";
|
|
23094
23820
|
import { parseModelRef as parseModelRef3 } from "@wrongstack/core/agent";
|
|
23821
|
+
import { catalogProviderIdFor } from "@wrongstack/providers";
|
|
23822
|
+
async function resolveCatalogModelIds(registry, config, providerIds) {
|
|
23823
|
+
const out = /* @__PURE__ */ new Map();
|
|
23824
|
+
if (!registry) return out;
|
|
23825
|
+
await Promise.all(
|
|
23826
|
+
providerIds.map(async (id) => {
|
|
23827
|
+
try {
|
|
23828
|
+
const catalogId = catalogProviderIdFor(id, config.providers?.[id]?.type);
|
|
23829
|
+
const provider = await registry.getProvider(catalogId);
|
|
23830
|
+
if (provider) out.set(id, provider.models.map((m) => m.id));
|
|
23831
|
+
} catch {
|
|
23832
|
+
}
|
|
23833
|
+
})
|
|
23834
|
+
);
|
|
23835
|
+
return out;
|
|
23836
|
+
}
|
|
23837
|
+
function summarizeModelIds(ids, limit = 8) {
|
|
23838
|
+
if (ids.length <= limit) return ids.join(", ");
|
|
23839
|
+
return `${ids.slice(0, limit).join(", ")} ${color44.dim(`\u2026 +${ids.length - limit} more`)}`;
|
|
23840
|
+
}
|
|
23095
23841
|
function providerHasKey(entry) {
|
|
23096
23842
|
if (!entry) return false;
|
|
23097
23843
|
if (typeof entry.apiKey === "string" && entry.apiKey.length > 0) return true;
|
|
@@ -23293,9 +24039,10 @@ function buildSetModelCommand(opts) {
|
|
|
23293
24039
|
);
|
|
23294
24040
|
const matrix = config.modelMatrix ?? {};
|
|
23295
24041
|
if (sub === "list") {
|
|
24042
|
+
const catalogModels = await resolveCatalogModelIds(opts.modelsRegistry, config, keyed);
|
|
23296
24043
|
const provLines = keyed.map((id) => {
|
|
23297
|
-
const models = config.
|
|
23298
|
-
const ms = models.length ? models
|
|
24044
|
+
const models = visibleModelIds(id, config, catalogModels.get(id) ?? []);
|
|
24045
|
+
const ms = models.length ? summarizeModelIds(models) : color44.dim("(any model id accepted)");
|
|
23299
24046
|
return ` ${color44.cyan(id.padEnd(16))} ${ms}`;
|
|
23300
24047
|
});
|
|
23301
24048
|
const roles = Object.keys(AGENT_CATALOG2).sort();
|
|
@@ -23371,6 +24118,11 @@ function buildSetModelCommand(opts) {
|
|
|
23371
24118
|
if (sub === "doctor") {
|
|
23372
24119
|
const issues = [];
|
|
23373
24120
|
const warnings = [];
|
|
24121
|
+
const doctorCatalogModels = await resolveCatalogModelIds(
|
|
24122
|
+
opts.modelsRegistry,
|
|
24123
|
+
config,
|
|
24124
|
+
keyed
|
|
24125
|
+
);
|
|
23374
24126
|
for (const [key, entry] of Object.entries(matrix)) {
|
|
23375
24127
|
const kind = matrixKeyKind(key);
|
|
23376
24128
|
if (kind === "unknown") {
|
|
@@ -23393,9 +24145,14 @@ function buildSetModelCommand(opts) {
|
|
|
23393
24145
|
const effectiveProvider = entry.provider ?? config.provider;
|
|
23394
24146
|
const provCfg = config.providers?.[effectiveProvider];
|
|
23395
24147
|
if (entry.model && provCfg?.models && provCfg.models.length > 0) {
|
|
23396
|
-
|
|
24148
|
+
const reachable = visibleModelIds(
|
|
24149
|
+
effectiveProvider,
|
|
24150
|
+
config,
|
|
24151
|
+
doctorCatalogModels.get(effectiveProvider) ?? []
|
|
24152
|
+
);
|
|
24153
|
+
if (!reachable.includes(entry.model)) {
|
|
23397
24154
|
warnings.push(
|
|
23398
|
-
`${color44.amber("\u26A0")} ${color44.amber(key)}: model "${entry.model}" not in ${effectiveProvider}'s model list (${
|
|
24155
|
+
`${color44.amber("\u26A0")} ${color44.amber(key)}: model "${entry.model}" not in ${effectiveProvider}'s model list (${summarizeModelIds(reachable)})`
|
|
23399
24156
|
);
|
|
23400
24157
|
}
|
|
23401
24158
|
}
|
|
@@ -23617,7 +24374,7 @@ function buildSetModelCommand(opts) {
|
|
|
23617
24374
|
};
|
|
23618
24375
|
} catch (err) {
|
|
23619
24376
|
return {
|
|
23620
|
-
message: `${color44.red("setmodel error")}: ${
|
|
24377
|
+
message: `${color44.red("setmodel error")}: ${toErrorMessage22(err)}`
|
|
23621
24378
|
};
|
|
23622
24379
|
}
|
|
23623
24380
|
}
|
|
@@ -23630,7 +24387,7 @@ import { access as access4 } from "node:fs/promises";
|
|
|
23630
24387
|
import * as path25 from "node:path";
|
|
23631
24388
|
import { color as color45 } from "@wrongstack/core/utils";
|
|
23632
24389
|
import { parseNextSteps } from "@wrongstack/tools/next-steps";
|
|
23633
|
-
import { toErrorMessage as
|
|
24390
|
+
import { toErrorMessage as toErrorMessage23 } from "@wrongstack/core/utils";
|
|
23634
24391
|
function readGitStatus(projectRoot, includeBranch) {
|
|
23635
24392
|
const args = ["status", "--short"];
|
|
23636
24393
|
if (includeBranch) args.push("--branch");
|
|
@@ -23754,7 +24511,7 @@ function buildSuggestCommand(opts) {
|
|
|
23754
24511
|
suggestCache = { suggestions, at: Date.now() };
|
|
23755
24512
|
return { message: formatSuggestions(suggestions) };
|
|
23756
24513
|
} catch (err) {
|
|
23757
|
-
const msg = `Suggestion generation failed: ${
|
|
24514
|
+
const msg = `Suggestion generation failed: ${toErrorMessage23(err)}`;
|
|
23758
24515
|
opts.renderer.writeWarning(msg);
|
|
23759
24516
|
return { message: msg };
|
|
23760
24517
|
}
|
|
@@ -24341,7 +25098,7 @@ import * as path26 from "node:path";
|
|
|
24341
25098
|
import {
|
|
24342
25099
|
color as color47,
|
|
24343
25100
|
ensureProjectGitignore,
|
|
24344
|
-
ensureProjectIdentity,
|
|
25101
|
+
ensureProjectIdentity as ensureProjectIdentity2,
|
|
24345
25102
|
projectIdentityPath,
|
|
24346
25103
|
readProjectIdentity,
|
|
24347
25104
|
rekeyProjectIdentity
|
|
@@ -24477,7 +25234,7 @@ ${color47.dim(filePath)}`
|
|
|
24477
25234
|
} : { message: `No committed project identity. Run ${color47.cyan("/project init")}.` };
|
|
24478
25235
|
}
|
|
24479
25236
|
if (action === "init") {
|
|
24480
|
-
const result2 = await
|
|
25237
|
+
const result2 = await ensureProjectIdentity2(root);
|
|
24481
25238
|
await ensureProjectGitignore(root);
|
|
24482
25239
|
return {
|
|
24483
25240
|
message: result2.created ? `${color47.green("Created")} ${filePath}
|
|
@@ -25068,7 +25825,7 @@ function buildSecurityCommand(opts) {
|
|
|
25068
25825
|
// src/slash-commands/settings.ts
|
|
25069
25826
|
import { noOpVault as noOpVault9 } from "@wrongstack/core/security";
|
|
25070
25827
|
import { resolveFleetChatVerbosity as resolveFleetChatVerbosity2 } from "@wrongstack/core/types";
|
|
25071
|
-
import { color as color48, toErrorMessage as
|
|
25828
|
+
import { color as color48, toErrorMessage as toErrorMessage24 } from "@wrongstack/core/utils";
|
|
25072
25829
|
import { getProcessRegistry } from "@wrongstack/tools";
|
|
25073
25830
|
|
|
25074
25831
|
// src/utils/delay-format.ts
|
|
@@ -25983,7 +26740,7 @@ function buildSettingsCommand(opts) {
|
|
|
25983
26740
|
};
|
|
25984
26741
|
} catch (err) {
|
|
25985
26742
|
return {
|
|
25986
|
-
message: `${color48.red("Settings error")}: ${
|
|
26743
|
+
message: `${color48.red("Settings error")}: ${toErrorMessage24(err)}`
|
|
25987
26744
|
};
|
|
25988
26745
|
}
|
|
25989
26746
|
}
|
|
@@ -26273,7 +27030,7 @@ function parseFlags2(args) {
|
|
|
26273
27030
|
}
|
|
26274
27031
|
|
|
26275
27032
|
// src/slash-commands/spawn-agents.ts
|
|
26276
|
-
import { toErrorMessage as
|
|
27033
|
+
import { toErrorMessage as toErrorMessage25 } from "@wrongstack/core/utils";
|
|
26277
27034
|
function buildSpawnCommand(opts) {
|
|
26278
27035
|
return {
|
|
26279
27036
|
name: "spawn",
|
|
@@ -26310,7 +27067,7 @@ function buildSpawnCommand(opts) {
|
|
|
26310
27067
|
const summary = Object.keys(parsed).length > 0 ? await opts.onSpawn(description, parsed) : await opts.onSpawn(description);
|
|
26311
27068
|
return { message: summary };
|
|
26312
27069
|
} catch (err) {
|
|
26313
|
-
return { message: `Spawn failed: ${
|
|
27070
|
+
return { message: `Spawn failed: ${toErrorMessage25(err)}` };
|
|
26314
27071
|
}
|
|
26315
27072
|
}
|
|
26316
27073
|
};
|
|
@@ -26918,7 +27675,7 @@ ${formatTaskProgress(file.tasks)}`;
|
|
|
26918
27675
|
import * as fs18 from "node:fs/promises";
|
|
26919
27676
|
import * as path28 from "node:path";
|
|
26920
27677
|
import { color as color51 } from "@wrongstack/core/utils";
|
|
26921
|
-
import { toErrorMessage as
|
|
27678
|
+
import { toErrorMessage as toErrorMessage26 } from "@wrongstack/core/utils";
|
|
26922
27679
|
async function discoverPackageFiles(projectRoot) {
|
|
26923
27680
|
const files = [];
|
|
26924
27681
|
const rootPkg = path28.join(projectRoot, "package.json");
|
|
@@ -27126,7 +27883,7 @@ function buildTechStackCommand(opts) {
|
|
|
27126
27883
|
message: `TechStack remediation finished: ${applied} applied, ${failed} failed, ${skipped} skipped.`
|
|
27127
27884
|
};
|
|
27128
27885
|
} catch (err) {
|
|
27129
|
-
const msg = `TechStack remediation failed: ${
|
|
27886
|
+
const msg = `TechStack remediation failed: ${toErrorMessage26(err)}`;
|
|
27130
27887
|
opts.renderer.writeWarning(msg);
|
|
27131
27888
|
return { message: msg };
|
|
27132
27889
|
} finally {
|
|
@@ -27145,7 +27902,7 @@ function buildTechStackCommand(opts) {
|
|
|
27145
27902
|
message: `TechStack inventory complete: ${snapshot.workspaces.length} workspaces, ${snapshot.dependencies.length} dependencies (fingerprint: ${snapshot.fingerprint})`
|
|
27146
27903
|
};
|
|
27147
27904
|
} catch (err) {
|
|
27148
|
-
const msg = `TechStack inventory failed: ${
|
|
27905
|
+
const msg = `TechStack inventory failed: ${toErrorMessage26(err)}`;
|
|
27149
27906
|
opts.renderer.writeWarning(msg);
|
|
27150
27907
|
return { message: msg };
|
|
27151
27908
|
}
|
|
@@ -27160,7 +27917,7 @@ function buildTechStackCommand(opts) {
|
|
|
27160
27917
|
);
|
|
27161
27918
|
}
|
|
27162
27919
|
} catch (err) {
|
|
27163
|
-
discoveryNote = color51.red(`Could not scan for package files: ${
|
|
27920
|
+
discoveryNote = color51.red(`Could not scan for package files: ${toErrorMessage26(err)}`);
|
|
27164
27921
|
}
|
|
27165
27922
|
const task = buildTechStackTask({
|
|
27166
27923
|
projectRoot: opts.projectRoot,
|
|
@@ -27200,7 +27957,7 @@ function buildTechStackCommand(opts) {
|
|
|
27200
27957
|
});
|
|
27201
27958
|
return { message: summary };
|
|
27202
27959
|
} catch (err) {
|
|
27203
|
-
const msg = `Tech stack scan failed: ${
|
|
27960
|
+
const msg = `Tech stack scan failed: ${toErrorMessage26(err)}`;
|
|
27204
27961
|
opts.renderer.writeWarning(msg);
|
|
27205
27962
|
return { message: msg };
|
|
27206
27963
|
}
|
|
@@ -27210,7 +27967,7 @@ function buildTechStackCommand(opts) {
|
|
|
27210
27967
|
|
|
27211
27968
|
// src/slash-commands/telegram-settings.ts
|
|
27212
27969
|
import { color as color53 } from "@wrongstack/core/utils";
|
|
27213
|
-
import { toErrorMessage as
|
|
27970
|
+
import { toErrorMessage as toErrorMessage27 } from "@wrongstack/core/utils";
|
|
27214
27971
|
|
|
27215
27972
|
// src/slash-commands/telegram-setup.ts
|
|
27216
27973
|
import { color as color52 } from "@wrongstack/core/utils";
|
|
@@ -27708,7 +28465,7 @@ function buildTelegramSettingsCommand(opts) {
|
|
|
27708
28465
|
};
|
|
27709
28466
|
} catch (err) {
|
|
27710
28467
|
return {
|
|
27711
|
-
message: `${color53.red("Settings error")}: ${
|
|
28468
|
+
message: `${color53.red("Settings error")}: ${toErrorMessage27(err)}`
|
|
27712
28469
|
};
|
|
27713
28470
|
}
|
|
27714
28471
|
}
|
|
@@ -27817,7 +28574,7 @@ function buildTodosCommand(opts) {
|
|
|
27817
28574
|
// src/slash-commands/tool.ts
|
|
27818
28575
|
import { color as color54, getToolDescriptionMode as getToolDescriptionMode2, getToolResultRenderMode, normalizeToolDescriptionMode, normalizeToolResultRenderMode, setToolResultRenderMode } from "@wrongstack/core/utils";
|
|
27819
28576
|
import { noOpVault as noOpVault10 } from "@wrongstack/core/security";
|
|
27820
|
-
import { toErrorMessage as
|
|
28577
|
+
import { toErrorMessage as toErrorMessage28 } from "@wrongstack/core/utils";
|
|
27821
28578
|
function fit(text, width) {
|
|
27822
28579
|
if (text.length <= width) return text.padEnd(width);
|
|
27823
28580
|
return `${text.slice(0, Math.max(0, width - 3))}...`;
|
|
@@ -28051,7 +28808,7 @@ function buildToolCommand(opts) {
|
|
|
28051
28808
|
try {
|
|
28052
28809
|
return { message: await cmdEnableAll() };
|
|
28053
28810
|
} catch (err) {
|
|
28054
|
-
return { message: `${color54.red("Error")}: ${
|
|
28811
|
+
return { message: `${color54.red("Error")}: ${toErrorMessage28(err)}` };
|
|
28055
28812
|
}
|
|
28056
28813
|
}
|
|
28057
28814
|
const name = parts[0] ?? "";
|
|
@@ -28065,7 +28822,7 @@ function buildToolCommand(opts) {
|
|
|
28065
28822
|
for (const t of targets) results.push(await cmdDisable(t));
|
|
28066
28823
|
return { message: results.join("\n") };
|
|
28067
28824
|
} catch (err) {
|
|
28068
|
-
return { message: `${color54.red("Error")}: ${
|
|
28825
|
+
return { message: `${color54.red("Error")}: ${toErrorMessage28(err)}` };
|
|
28069
28826
|
}
|
|
28070
28827
|
}
|
|
28071
28828
|
if (sub === "enable") {
|
|
@@ -28077,7 +28834,7 @@ function buildToolCommand(opts) {
|
|
|
28077
28834
|
for (const t of targets) results.push(await cmdEnable(t));
|
|
28078
28835
|
return { message: results.join("\n") };
|
|
28079
28836
|
} catch (err) {
|
|
28080
|
-
return { message: `${color54.red("Error")}: ${
|
|
28837
|
+
return { message: `${color54.red("Error")}: ${toErrorMessage28(err)}` };
|
|
28081
28838
|
}
|
|
28082
28839
|
}
|
|
28083
28840
|
const action = parts[1]?.toLowerCase();
|
|
@@ -28090,7 +28847,7 @@ function buildToolCommand(opts) {
|
|
|
28090
28847
|
try {
|
|
28091
28848
|
return { message: action === "disable" ? await cmdDisable(name) : await cmdEnable(name) };
|
|
28092
28849
|
} catch (err) {
|
|
28093
|
-
return { message: `${color54.red("Error")}: ${
|
|
28850
|
+
return { message: `${color54.red("Error")}: ${toErrorMessage28(err)}` };
|
|
28094
28851
|
}
|
|
28095
28852
|
}
|
|
28096
28853
|
if (!opts.toolRegistry.get(name) && !opts.toolRegistry.isDisabled(name)) {
|
|
@@ -28130,7 +28887,7 @@ function buildToolCommand(opts) {
|
|
|
28130
28887
|
};
|
|
28131
28888
|
} catch (err) {
|
|
28132
28889
|
return {
|
|
28133
|
-
message: `${color54.red("Could not save tool setting")}: ${
|
|
28890
|
+
message: `${color54.red("Could not save tool setting")}: ${toErrorMessage28(err)}`
|
|
28134
28891
|
};
|
|
28135
28892
|
}
|
|
28136
28893
|
}
|
|
@@ -28150,7 +28907,7 @@ function buildToolCommand(opts) {
|
|
|
28150
28907
|
};
|
|
28151
28908
|
} catch (err) {
|
|
28152
28909
|
return {
|
|
28153
|
-
message: `${color54.red("Could not save tool setting")}: ${
|
|
28910
|
+
message: `${color54.red("Could not save tool setting")}: ${toErrorMessage28(err)}`
|
|
28154
28911
|
};
|
|
28155
28912
|
}
|
|
28156
28913
|
}
|
|
@@ -29047,7 +29804,7 @@ function summaryLine(findings, fixable, handoffs, power) {
|
|
|
29047
29804
|
import * as fs20 from "node:fs/promises";
|
|
29048
29805
|
import * as path30 from "node:path";
|
|
29049
29806
|
import { color as color57 } from "@wrongstack/core/utils";
|
|
29050
|
-
import { toErrorMessage as
|
|
29807
|
+
import { toErrorMessage as toErrorMessage29 } from "@wrongstack/core/utils";
|
|
29051
29808
|
function buildWorkingDirCommand(_opts) {
|
|
29052
29809
|
return {
|
|
29053
29810
|
name: "working_dir",
|
|
@@ -29104,7 +29861,7 @@ function buildWorkingDirCommand(_opts) {
|
|
|
29104
29861
|
ctx.setWorkingDir(resolved);
|
|
29105
29862
|
} catch (err) {
|
|
29106
29863
|
return {
|
|
29107
|
-
message: color57.red(
|
|
29864
|
+
message: color57.red(toErrorMessage29(err))
|
|
29108
29865
|
};
|
|
29109
29866
|
}
|
|
29110
29867
|
const prevRel = path30.relative(ctx.projectRoot, previous) || ".";
|
|
@@ -29250,6 +30007,7 @@ function buildBuiltinSlashCommands(opts) {
|
|
|
29250
30007
|
buildDesktopCommand(),
|
|
29251
30008
|
buildWebuiCommand(),
|
|
29252
30009
|
buildInitCommand(opts),
|
|
30010
|
+
buildIntakeCommand(opts),
|
|
29253
30011
|
buildClearCommand(opts),
|
|
29254
30012
|
buildInterruptCommand(opts),
|
|
29255
30013
|
buildKanbanCommand(opts),
|
|
@@ -29673,6 +30431,9 @@ async function runInteractive(cliCtx) {
|
|
|
29673
30431
|
let {
|
|
29674
30432
|
director,
|
|
29675
30433
|
maxConcurrent,
|
|
30434
|
+
maxSpawns,
|
|
30435
|
+
maxConcurrentSource,
|
|
30436
|
+
maxSpawnsSource,
|
|
29676
30437
|
autonomyMode,
|
|
29677
30438
|
nextPredictEnabled,
|
|
29678
30439
|
currentSuggestions,
|
|
@@ -29725,6 +30486,9 @@ async function runInteractive(cliCtx) {
|
|
|
29725
30486
|
stateCheckpointPath,
|
|
29726
30487
|
fleetRootForPromotion,
|
|
29727
30488
|
maxConcurrent,
|
|
30489
|
+
maxSpawns,
|
|
30490
|
+
maxConcurrentSource,
|
|
30491
|
+
maxSpawnsSource,
|
|
29728
30492
|
effectiveMaxContextRef,
|
|
29729
30493
|
mcpRegistry,
|
|
29730
30494
|
sessResult,
|
|
@@ -29765,11 +30529,30 @@ async function runInteractive(cliCtx) {
|
|
|
29765
30529
|
for (const tool of director.tools(FLEET_ROSTER5)) {
|
|
29766
30530
|
toolRegistry.register(tool);
|
|
29767
30531
|
}
|
|
29768
|
-
|
|
29769
|
-
|
|
29770
|
-
|
|
29771
|
-
|
|
29772
|
-
|
|
30532
|
+
const browserSurface = flags.webui === true || flags.simpleui === true;
|
|
30533
|
+
if (browserSurface) {
|
|
30534
|
+
renderer.writeInfo(
|
|
30535
|
+
`Director mode enabled (${Object.keys(FLEET_ROSTER5).length} roles) \u2192 ${fleetRoot}`
|
|
30536
|
+
);
|
|
30537
|
+
} else {
|
|
30538
|
+
renderer.writeInfo(`Director mode enabled. Roster: ${Object.keys(FLEET_ROSTER5).join(", ")}`);
|
|
30539
|
+
renderer.writeInfo(` fleet root \u2192 ${fleetRoot}`);
|
|
30540
|
+
renderer.writeInfo(` manifest \u2192 ${manifestPath}`);
|
|
30541
|
+
renderer.writeInfo(` scratchpad \u2192 ${sharedScratchpadPath}`);
|
|
30542
|
+
renderer.writeInfo(` subagents \u2192 ${subagentSessionsRoot}`);
|
|
30543
|
+
}
|
|
30544
|
+
if (priorFleetState) {
|
|
30545
|
+
const budget = multiAgentHost.budgetView();
|
|
30546
|
+
const fmt = (n) => Number.isFinite(n) ? String(n) : "\u221E";
|
|
30547
|
+
renderer.writeInfo(
|
|
30548
|
+
` fleet budget \u2192 ${budget.usedSpawns}/${fmt(budget.maxSpawns)} spawns used (${fmt(budget.remainingSpawns)} remaining; maxConcurrent ${budget.maxConcurrent})`
|
|
30549
|
+
);
|
|
30550
|
+
if (budget.ceilingMismatch && budget.checkpointMaxSpawns !== void 0) {
|
|
30551
|
+
renderer.writeInfo(
|
|
30552
|
+
` \u26A0 checkpoint maxSpawns was ${budget.checkpointMaxSpawns}; live ceiling is ${fmt(budget.maxSpawns)}`
|
|
30553
|
+
);
|
|
30554
|
+
}
|
|
30555
|
+
}
|
|
29773
30556
|
} else {
|
|
29774
30557
|
renderer.writeInfo(`Running without Director \u2014 fleet orchestration tools disabled.`);
|
|
29775
30558
|
}
|
|
@@ -29993,7 +30776,7 @@ async function runInteractive(cliCtx) {
|
|
|
29993
30776
|
onEvent: evOn
|
|
29994
30777
|
});
|
|
29995
30778
|
const savedProviderCfg = config.providers?.[config.provider];
|
|
29996
|
-
const { execute } = await import("./execution-
|
|
30779
|
+
const { execute } = await import("./execution-SHGM7BVC.js");
|
|
29997
30780
|
const stopHeapWatchdog = startSharedHeapWatchdog({
|
|
29998
30781
|
collectStats: () => {
|
|
29999
30782
|
const hqQueue = hqPublisherRef.current?.getQueueStats();
|
|
@@ -30225,4 +31008,4 @@ export {
|
|
|
30225
31008
|
CLI_VERSION,
|
|
30226
31009
|
runInteractive
|
|
30227
31010
|
};
|
|
30228
|
-
//# sourceMappingURL=cli-main-
|
|
31011
|
+
//# sourceMappingURL=cli-main-7B3G2YSG.js.map
|