@wrongstack/webui-server 0.289.0 → 0.291.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/index.js +401 -267
- package/dist/index.js.map +3 -3
- package/dist/server/backend-services.d.ts +2 -2
- package/dist/server/backend-services.d.ts.map +1 -1
- package/dist/server/context-meta.d.ts.map +1 -1
- package/dist/server/entry.js +400 -267
- package/dist/server/entry.js.map +3 -3
- package/dist/server/handlers.js.map +2 -2
- package/dist/server/http-server.d.ts.map +1 -1
- package/dist/server/index.d.ts +2 -0
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/kanban-routes.d.ts +15 -0
- package/dist/server/kanban-routes.d.ts.map +1 -1
- package/dist/server/message-dispatcher.d.ts +3 -2
- package/dist/server/message-dispatcher.d.ts.map +1 -1
- package/dist/server/pending-confirms.d.ts +1 -0
- package/dist/server/pending-confirms.d.ts.map +1 -1
- package/dist/server/pre-context-services.d.ts +3 -2
- package/dist/server/pre-context-services.d.ts.map +1 -1
- package/dist/server/pref-helpers.d.ts +18 -1
- package/dist/server/pref-helpers.d.ts.map +1 -1
- package/dist/server/routes.d.ts +2 -2
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/server/server-runtime.d.ts +5 -20
- package/dist/server/server-runtime.d.ts.map +1 -1
- package/dist/server/setup-events.d.ts.map +1 -1
- package/dist/server/terminal-ws-handler.d.ts +2 -1
- package/dist/server/terminal-ws-handler.d.ts.map +1 -1
- package/dist/server/ws-payload-validation.d.ts +24 -23
- package/dist/server/ws-payload-validation.d.ts.map +1 -1
- package/package.json +12 -12
package/dist/server/entry.js
CHANGED
|
@@ -1908,6 +1908,7 @@ async function handleGitDiff(ws, projectRoot, path23) {
|
|
|
1908
1908
|
import * as fs6 from "node:fs/promises";
|
|
1909
1909
|
import * as http from "node:http";
|
|
1910
1910
|
import * as path7 from "node:path";
|
|
1911
|
+
import * as v8 from "node:v8";
|
|
1911
1912
|
|
|
1912
1913
|
// src/server/http-server/api-handlers.ts
|
|
1913
1914
|
async function handleApiSessions(res, globalRoot) {
|
|
@@ -3206,6 +3207,23 @@ function createHttpServer(opts) {
|
|
|
3206
3207
|
}
|
|
3207
3208
|
return;
|
|
3208
3209
|
}
|
|
3210
|
+
if (url.pathname === "/debug/system" && req.method === "GET") {
|
|
3211
|
+
res.writeHead(200, {
|
|
3212
|
+
"Content-Type": "application/json",
|
|
3213
|
+
"Cache-Control": "no-store"
|
|
3214
|
+
});
|
|
3215
|
+
res.end(
|
|
3216
|
+
JSON.stringify({
|
|
3217
|
+
pid: process.pid,
|
|
3218
|
+
memoryUsage: process.memoryUsage(),
|
|
3219
|
+
heapLimit: v8.getHeapStatistics().heap_size_limit,
|
|
3220
|
+
uptime: process.uptime(),
|
|
3221
|
+
cpuUsage: process.cpuUsage(),
|
|
3222
|
+
timestamp: Date.now()
|
|
3223
|
+
})
|
|
3224
|
+
);
|
|
3225
|
+
return;
|
|
3226
|
+
}
|
|
3209
3227
|
let filePath;
|
|
3210
3228
|
if (url.pathname === "/" || url.pathname === "") {
|
|
3211
3229
|
filePath = path7.join(distDir, "index.html");
|
|
@@ -5164,6 +5182,7 @@ var BOOLEAN_PREF_KEYS = /* @__PURE__ */ new Set([
|
|
|
5164
5182
|
"hqRawContent",
|
|
5165
5183
|
"fallbackAuto",
|
|
5166
5184
|
"favoriteModelsOnly",
|
|
5185
|
+
"modelAvailabilitySchedule",
|
|
5167
5186
|
"breakerEnabled",
|
|
5168
5187
|
"debugStream",
|
|
5169
5188
|
// Chimera + auto-review master toggles
|
|
@@ -5308,7 +5327,10 @@ function validatePreferenceValue(key, value) {
|
|
|
5308
5327
|
return `prefs.update payload.${key}.modelRuntime must be an object when provided`;
|
|
5309
5328
|
}
|
|
5310
5329
|
if (isRecord(modelRuntime)) {
|
|
5311
|
-
const runtimeError = validateModelRuntimeValue(
|
|
5330
|
+
const runtimeError = validateModelRuntimeValue(
|
|
5331
|
+
modelRuntime,
|
|
5332
|
+
`prefs.update payload.${key}.modelRuntime`
|
|
5333
|
+
);
|
|
5312
5334
|
if (runtimeError) return runtimeError;
|
|
5313
5335
|
}
|
|
5314
5336
|
if (model === void 0 && fallbackProfile === void 0 && modelRuntime === void 0) {
|
|
@@ -6544,7 +6566,7 @@ function registerShutdownHandlers(res) {
|
|
|
6544
6566
|
import { watch as fsWatch } from "node:fs";
|
|
6545
6567
|
import * as fs11 from "node:fs/promises";
|
|
6546
6568
|
import * as path13 from "node:path";
|
|
6547
|
-
import { getBoard, getKanbanDir } from "@wrongstack/kanban";
|
|
6569
|
+
import { getBoard, getKanbanDir, recordTaskFileActivity } from "@wrongstack/kanban";
|
|
6548
6570
|
|
|
6549
6571
|
// src/server/codemap-telemetry.ts
|
|
6550
6572
|
import * as path12 from "node:path";
|
|
@@ -6940,6 +6962,18 @@ function setupEvents(deps2) {
|
|
|
6940
6962
|
on("file.activity", (e) => {
|
|
6941
6963
|
broadcast2(clients, { type: "codemap.file_event", payload: e });
|
|
6942
6964
|
});
|
|
6965
|
+
on("file.event", (e) => {
|
|
6966
|
+
if (e.scope !== "task" || !e.boardId || !e.taskId) return;
|
|
6967
|
+
void recordTaskFileActivity(context.projectRoot, e.boardId, e.taskId, e).then((recorded) => {
|
|
6968
|
+
if (recorded) {
|
|
6969
|
+
broadcast2(clients, {
|
|
6970
|
+
type: "kanban.task.activity.changed",
|
|
6971
|
+
payload: { boardId: e.boardId, taskId: e.taskId }
|
|
6972
|
+
});
|
|
6973
|
+
}
|
|
6974
|
+
}).catch(() => {
|
|
6975
|
+
});
|
|
6976
|
+
});
|
|
6943
6977
|
on("tool.loop_detected", (e) => {
|
|
6944
6978
|
broadcast2(clients, {
|
|
6945
6979
|
type: "tool.loop_detected",
|
|
@@ -7064,12 +7098,14 @@ function setupEvents(deps2) {
|
|
|
7064
7098
|
input: e.input,
|
|
7065
7099
|
suggestedPattern: e.suggestedPattern,
|
|
7066
7100
|
decisionSource: e.decisionSource,
|
|
7067
|
-
riskTier: e.riskTier
|
|
7101
|
+
riskTier: e.riskTier,
|
|
7102
|
+
boundaryReason: e.boundaryReason
|
|
7068
7103
|
});
|
|
7069
7104
|
pendingConfirms.set(id, {
|
|
7070
7105
|
resolve: e.resolve,
|
|
7071
7106
|
decisionSource: e.decisionSource,
|
|
7072
7107
|
riskTier: e.riskTier,
|
|
7108
|
+
boundaryReason: e.boundaryReason,
|
|
7073
7109
|
payload
|
|
7074
7110
|
});
|
|
7075
7111
|
broadcast2(clients, { type: "tool.confirm_needed", payload });
|
|
@@ -7162,7 +7198,8 @@ function setupEvents(deps2) {
|
|
|
7162
7198
|
oldState: e.oldState,
|
|
7163
7199
|
newState: e.newState,
|
|
7164
7200
|
reason: e.reason,
|
|
7165
|
-
timestamp: e.timestamp
|
|
7201
|
+
timestamp: e.timestamp,
|
|
7202
|
+
stateExpiresAt: e.stateExpiresAt
|
|
7166
7203
|
})
|
|
7167
7204
|
});
|
|
7168
7205
|
});
|
|
@@ -8269,6 +8306,7 @@ function seedContextMeta(config, context) {
|
|
|
8269
8306
|
meta["fallbackProfiles"] = config.fallbackProfiles ?? {};
|
|
8270
8307
|
meta["favoriteModels"] = config.favoriteModels ?? [];
|
|
8271
8308
|
meta["favoriteModelsOnly"] = config.favoriteModelsOnly === true;
|
|
8309
|
+
meta["modelAvailabilitySchedule"] = config.modelAvailabilitySchedule ?? [];
|
|
8272
8310
|
meta["modelMatrix"] = config.modelMatrix ?? {};
|
|
8273
8311
|
meta["fallbackAuto"] = config.fallbackAuto !== false;
|
|
8274
8312
|
if (typeof config.uiLocale === "string" && config.uiLocale) meta["uiLocale"] = config.uiLocale;
|
|
@@ -8351,9 +8389,7 @@ function seedContextMeta(config, context) {
|
|
|
8351
8389
|
} catch {
|
|
8352
8390
|
resolvedChain = [];
|
|
8353
8391
|
}
|
|
8354
|
-
meta["autoReviewFallbackModels"] = resolvedChain.map(
|
|
8355
|
-
(e) => `${e.providerId}/${e.model}`
|
|
8356
|
-
);
|
|
8392
|
+
meta["autoReviewFallbackModels"] = resolvedChain.map((e) => `${e.providerId}/${e.model}`);
|
|
8357
8393
|
}
|
|
8358
8394
|
}
|
|
8359
8395
|
|
|
@@ -9810,7 +9846,7 @@ function setupWebUICodebaseIndexing(deps2) {
|
|
|
9810
9846
|
}
|
|
9811
9847
|
if (idx) {
|
|
9812
9848
|
cancelPendingReindexes();
|
|
9813
|
-
shutdownCodebaseIndexHost();
|
|
9849
|
+
void shutdownCodebaseIndexHost();
|
|
9814
9850
|
}
|
|
9815
9851
|
}
|
|
9816
9852
|
};
|
|
@@ -9977,6 +10013,9 @@ var DEFAULT_COLS = 80;
|
|
|
9977
10013
|
var DEFAULT_ROWS = 24;
|
|
9978
10014
|
var requireFromHere = createRequire4(import.meta.url);
|
|
9979
10015
|
var cachedNodePty;
|
|
10016
|
+
function resolveTerminalShell(platform = process.platform, env = process.env) {
|
|
10017
|
+
return platform === "win32" ? env.COMSPEC || "cmd.exe" : env.SHELL || "/bin/sh";
|
|
10018
|
+
}
|
|
9980
10019
|
var TerminalWebSocketHandler = class {
|
|
9981
10020
|
constructor(getCwd, logger, loadNodePty = defaultLoadNodePty, killProcessTree = defaultKillProcessTree) {
|
|
9982
10021
|
this.getCwd = getCwd;
|
|
@@ -10032,7 +10071,7 @@ var TerminalWebSocketHandler = class {
|
|
|
10032
10071
|
});
|
|
10033
10072
|
return;
|
|
10034
10073
|
}
|
|
10035
|
-
const shell =
|
|
10074
|
+
const shell = resolveTerminalShell();
|
|
10036
10075
|
const nodePty = this.loadNodePty();
|
|
10037
10076
|
if (!nodePty) {
|
|
10038
10077
|
const msg = "Integrated terminal unavailable: optional dependency node-pty is not installed. Install node-pty to enable WebUI terminal sessions.";
|
|
@@ -10352,7 +10391,11 @@ async function createAgentServices(input) {
|
|
|
10352
10391
|
toolExecutor
|
|
10353
10392
|
});
|
|
10354
10393
|
if (config.features.memory && config.features.memoryConsolidation !== false) {
|
|
10355
|
-
|
|
10394
|
+
const consSuperMemory = typeof memoryStore["rememberSuper"] === "function" ? memoryStore : void 0;
|
|
10395
|
+
agent.extensions.register(new SessionMemoryConsolidator({
|
|
10396
|
+
memoryStore,
|
|
10397
|
+
...consSuperMemory ? { superMemory: consSuperMemory } : {}
|
|
10398
|
+
}));
|
|
10356
10399
|
}
|
|
10357
10400
|
console.log("[WebUI] Agent initialized");
|
|
10358
10401
|
const brainCfg = resolveBrainConfigDefaults(config.brain, {
|
|
@@ -10558,6 +10601,7 @@ function isSuperMemoryRetriever(memoryStore) {
|
|
|
10558
10601
|
// src/server/pending-confirms.ts
|
|
10559
10602
|
function resolveYoloEligiblePendingConfirms(pendingConfirms) {
|
|
10560
10603
|
for (const [id, confirm] of pendingConfirms) {
|
|
10604
|
+
if (confirm.boundaryReason) continue;
|
|
10561
10605
|
pendingConfirms.delete(id);
|
|
10562
10606
|
confirm.resolve("yes");
|
|
10563
10607
|
}
|
|
@@ -11037,7 +11081,7 @@ import {
|
|
|
11037
11081
|
createBoard,
|
|
11038
11082
|
duplicateBoard,
|
|
11039
11083
|
exportBoardToTaskGraph,
|
|
11040
|
-
|
|
11084
|
+
createBoardFromText,
|
|
11041
11085
|
getBoard as getBoard2,
|
|
11042
11086
|
getKanbanOrchestrationSnapshot,
|
|
11043
11087
|
getKanbanQueueHealth,
|
|
@@ -11068,6 +11112,32 @@ import {
|
|
|
11068
11112
|
updateTask
|
|
11069
11113
|
} from "@wrongstack/kanban";
|
|
11070
11114
|
import { applySessionKanbanTaskToSource } from "@wrongstack/tools/session-kanban";
|
|
11115
|
+
function paginateKanbanBoards(boards, input) {
|
|
11116
|
+
const pageSize = Math.min(100, Math.max(1, Math.floor(input.pageSize)));
|
|
11117
|
+
const activeSessionIds = new Set(input.activeSessionIds ?? []);
|
|
11118
|
+
const isActive = (board) => board.presence?.some((entry) => entry.active) === true || board.tags?.some(
|
|
11119
|
+
(tag) => tag.startsWith("session:") && activeSessionIds.has(tag.slice(8))
|
|
11120
|
+
) === true;
|
|
11121
|
+
const sorted = [...boards].sort((left, right) => {
|
|
11122
|
+
const activityOrder = Number(isActive(right)) - Number(isActive(left));
|
|
11123
|
+
return activityOrder || right.updatedAt.localeCompare(left.updatedAt);
|
|
11124
|
+
});
|
|
11125
|
+
const activeTotal = sorted.filter(isActive).length;
|
|
11126
|
+
const total = sorted.length;
|
|
11127
|
+
const totalPages = Math.max(1, Math.ceil(total / pageSize));
|
|
11128
|
+
const requestedPage = Number.isFinite(input.page) ? Math.floor(input.page) : 1;
|
|
11129
|
+
const page = Math.min(totalPages, Math.max(1, requestedPage));
|
|
11130
|
+
const start = (page - 1) * pageSize;
|
|
11131
|
+
return {
|
|
11132
|
+
items: sorted.slice(start, start + pageSize),
|
|
11133
|
+
total,
|
|
11134
|
+
page,
|
|
11135
|
+
pageSize,
|
|
11136
|
+
totalPages,
|
|
11137
|
+
activeTotal,
|
|
11138
|
+
orphanedTotal: total - activeTotal
|
|
11139
|
+
};
|
|
11140
|
+
}
|
|
11071
11141
|
async function syncSessionSource(ctx, task, remove = false) {
|
|
11072
11142
|
if (!ctx.context) return;
|
|
11073
11143
|
const update = await applySessionKanbanTaskToSource(ctx.context, task, { remove });
|
|
@@ -11117,9 +11187,26 @@ async function handleKanbanRoute(ws, msg, ctx) {
|
|
|
11117
11187
|
const type = msg.type;
|
|
11118
11188
|
try {
|
|
11119
11189
|
switch (type) {
|
|
11120
|
-
case "kanban.list":
|
|
11121
|
-
|
|
11190
|
+
case "kanban.list": {
|
|
11191
|
+
const boards = await listBoards(ctx.projectRoot);
|
|
11192
|
+
const requestedPage = Number(payload?.page);
|
|
11193
|
+
const requestedPageSize = Number(payload?.pageSize);
|
|
11194
|
+
if (!Number.isFinite(requestedPage) || !Number.isFinite(requestedPageSize)) {
|
|
11195
|
+
ok(ws, type, boards);
|
|
11196
|
+
return true;
|
|
11197
|
+
}
|
|
11198
|
+
const activeSessionIds = Array.isArray(payload?.activeSessionIds) ? payload.activeSessionIds.filter((id) => typeof id === "string") : [];
|
|
11199
|
+
ok(
|
|
11200
|
+
ws,
|
|
11201
|
+
type,
|
|
11202
|
+
paginateKanbanBoards(boards, {
|
|
11203
|
+
page: requestedPage,
|
|
11204
|
+
pageSize: requestedPageSize,
|
|
11205
|
+
activeSessionIds
|
|
11206
|
+
})
|
|
11207
|
+
);
|
|
11122
11208
|
return true;
|
|
11209
|
+
}
|
|
11123
11210
|
case "kanban.get": {
|
|
11124
11211
|
const boardId = payload?.boardId;
|
|
11125
11212
|
if (!boardId) {
|
|
@@ -11185,7 +11272,8 @@ async function handleKanbanRoute(ws, msg, ctx) {
|
|
|
11185
11272
|
...payload?.description ? { description: payload.description } : {},
|
|
11186
11273
|
...payload?.tags ? { tags: payload.tags } : {},
|
|
11187
11274
|
...payload?.columns ? { columns: payload.columns } : {},
|
|
11188
|
-
...has(payload, "lifecycle") ? { lifecycle: payload?.lifecycle } : {}
|
|
11275
|
+
...has(payload, "lifecycle") ? { lifecycle: payload?.lifecycle } : {},
|
|
11276
|
+
...has(payload, "boundary") ? { boundary: payload?.boundary } : {}
|
|
11189
11277
|
})
|
|
11190
11278
|
);
|
|
11191
11279
|
return true;
|
|
@@ -11206,6 +11294,9 @@ async function handleKanbanRoute(ws, msg, ctx) {
|
|
|
11206
11294
|
} : {},
|
|
11207
11295
|
...has(payload, "supervisor") ? {
|
|
11208
11296
|
supervisor: payload?.supervisor ?? null
|
|
11297
|
+
} : {},
|
|
11298
|
+
...has(payload, "boundary") ? {
|
|
11299
|
+
boundary: payload?.boundary ?? null
|
|
11209
11300
|
} : {}
|
|
11210
11301
|
});
|
|
11211
11302
|
board ? ok(ws, type, board) : fail(ws, type, `Board not found: ${boardId}`);
|
|
@@ -11252,7 +11343,7 @@ async function handleKanbanRoute(ws, msg, ctx) {
|
|
|
11252
11343
|
}
|
|
11253
11344
|
const board = await createBoard(
|
|
11254
11345
|
ctx.projectRoot,
|
|
11255
|
-
|
|
11346
|
+
createBoardFromText({
|
|
11256
11347
|
description,
|
|
11257
11348
|
...payload?.title ? { title: payload.title } : {},
|
|
11258
11349
|
...payload?.context ? { context: payload.context } : {}
|
|
@@ -11364,7 +11455,8 @@ async function handleKanbanRoute(ws, msg, ctx) {
|
|
|
11364
11455
|
...payload?.dueDate ? { dueDate: payload.dueDate } : {},
|
|
11365
11456
|
...payload?.priority ? { priority: payload.priority } : {},
|
|
11366
11457
|
...payload?.assignedAgent ? { assignedAgent: payload.assignedAgent } : {},
|
|
11367
|
-
...payload?.labels ? { labels: payload.labels } : {}
|
|
11458
|
+
...payload?.labels ? { labels: payload.labels } : {},
|
|
11459
|
+
...has(payload, "boundary") ? { boundary: payload?.boundary } : {}
|
|
11368
11460
|
},
|
|
11369
11461
|
activityContext(ctx, "webui", payload?.activityNote)
|
|
11370
11462
|
);
|
|
@@ -11445,6 +11537,9 @@ async function handleKanbanRoute(ws, msg, ctx) {
|
|
|
11445
11537
|
} : {},
|
|
11446
11538
|
...has(payload, "costCeilingUsd") ? {
|
|
11447
11539
|
costCeilingUsd: payload?.costCeilingUsd === null || payload?.costCeilingUsd === "" ? null : Number(payload?.costCeilingUsd)
|
|
11540
|
+
} : {},
|
|
11541
|
+
...has(payload, "boundary") ? {
|
|
11542
|
+
boundary: payload?.boundary ?? null
|
|
11448
11543
|
} : {}
|
|
11449
11544
|
},
|
|
11450
11545
|
activityContext(ctx, "webui", payload?.activityNote)
|
|
@@ -12337,7 +12432,7 @@ var chronicleCache = /* @__PURE__ */ new Map();
|
|
|
12337
12432
|
async function chronicleEngine(projectRoot) {
|
|
12338
12433
|
const now = Date.now();
|
|
12339
12434
|
const cached = chronicleCache.get(projectRoot);
|
|
12340
|
-
if (cached && now - cached.loadedAt <
|
|
12435
|
+
if (cached && now - cached.loadedAt < 6e4) return cached.engine;
|
|
12341
12436
|
const paths = resolveWstackPaths2({ projectRoot, userHome: os2.homedir() });
|
|
12342
12437
|
const engine = await ChronicleQueryEngine.fromDirectory(
|
|
12343
12438
|
path19.join(paths.projectDir, "chronicle")
|
|
@@ -12854,7 +12949,7 @@ function createMessageDispatcher(opts) {
|
|
|
12854
12949
|
case "chronicle.query": {
|
|
12855
12950
|
const payload = msg.payload ?? {};
|
|
12856
12951
|
const engine = await chronicleEngine(state.getProjectRoot());
|
|
12857
|
-
send(ws, { type: "chronicle.query_result", payload: engine.query(payload.query ?? {}) });
|
|
12952
|
+
send(ws, { type: "chronicle.query_result", payload: await engine.query(payload.query ?? {}) });
|
|
12858
12953
|
break;
|
|
12859
12954
|
}
|
|
12860
12955
|
case "chronicle.facet": {
|
|
@@ -12884,7 +12979,7 @@ function createMessageDispatcher(opts) {
|
|
|
12884
12979
|
type: "chronicle.facet_result",
|
|
12885
12980
|
payload: {
|
|
12886
12981
|
field: payload.field,
|
|
12887
|
-
values: engine.facet(payload.field, payload.query ?? {}, payload.limit),
|
|
12982
|
+
values: await engine.facet(payload.field, payload.query ?? {}, payload.limit),
|
|
12888
12983
|
diagnostics: engine.diagnostics
|
|
12889
12984
|
}
|
|
12890
12985
|
});
|
|
@@ -12895,7 +12990,7 @@ function createMessageDispatcher(opts) {
|
|
|
12895
12990
|
const engine = await chronicleEngine(state.getProjectRoot());
|
|
12896
12991
|
send(ws, {
|
|
12897
12992
|
type: "chronicle.graph_result",
|
|
12898
|
-
payload: engine.graph(payload.seed ?? {}, payload.hops, payload.maxNodes)
|
|
12993
|
+
payload: await engine.graph(payload.seed ?? {}, payload.hops, payload.maxNodes)
|
|
12899
12994
|
});
|
|
12900
12995
|
break;
|
|
12901
12996
|
}
|
|
@@ -12950,9 +13045,9 @@ function createMessageDispatcher(opts) {
|
|
|
12950
13045
|
}
|
|
12951
13046
|
|
|
12952
13047
|
// src/server/pref-helpers.ts
|
|
12953
|
-
import { atomicWrite as atomicWrite6, FORBIDDEN_PROTO_KEYS as FORBIDDEN_PROTO_KEYS2 } from "@wrongstack/core/utils";
|
|
12954
|
-
import { decryptConfigSecrets as decryptConfigSecrets2, encryptConfigSecrets as encryptConfigSecrets2 } from "@wrongstack/core/security";
|
|
12955
13048
|
import * as fs14 from "node:fs/promises";
|
|
13049
|
+
import { decryptConfigSecrets as decryptConfigSecrets2, encryptConfigSecrets as encryptConfigSecrets2 } from "@wrongstack/core/security";
|
|
13050
|
+
import { atomicWrite as atomicWrite6, FORBIDDEN_PROTO_KEYS as FORBIDDEN_PROTO_KEYS2 } from "@wrongstack/core/utils";
|
|
12956
13051
|
var PREF_KEYS = [
|
|
12957
13052
|
"autonomy",
|
|
12958
13053
|
"autonomyDelayMs",
|
|
@@ -12997,6 +13092,7 @@ var PREF_KEYS = [
|
|
|
12997
13092
|
"fallbackProfiles",
|
|
12998
13093
|
"favoriteModels",
|
|
12999
13094
|
"favoriteModelsOnly",
|
|
13095
|
+
"modelAvailabilitySchedule",
|
|
13000
13096
|
"modelMatrix",
|
|
13001
13097
|
"fallbackAuto",
|
|
13002
13098
|
// Refiner + TUI visual prefs (parity with the CLI's embedded server —
|
|
@@ -13069,256 +13165,264 @@ async function updateGlobalConfig(deps2, holder, mutate, errorLabel) {
|
|
|
13069
13165
|
try {
|
|
13070
13166
|
await next;
|
|
13071
13167
|
} catch (err) {
|
|
13072
|
-
logger.warn(
|
|
13168
|
+
logger.warn(
|
|
13169
|
+
`${errorLabel}: failed to persist to config: ${err instanceof Error ? err.message : String(err)}`
|
|
13170
|
+
);
|
|
13073
13171
|
}
|
|
13074
13172
|
}
|
|
13075
13173
|
async function persistPrefsToConfig(deps2, holder, payload) {
|
|
13076
|
-
return updateGlobalConfig(
|
|
13077
|
-
|
|
13078
|
-
|
|
13079
|
-
|
|
13080
|
-
autonomyCfg
|
|
13081
|
-
autonomyTouched =
|
|
13082
|
-
|
|
13083
|
-
|
|
13084
|
-
|
|
13085
|
-
|
|
13086
|
-
|
|
13087
|
-
|
|
13088
|
-
if (typeof payload["autoProceedMaxIterations"] === "number")
|
|
13089
|
-
setAutonomy("autoProceedMaxIterations", payload["autoProceedMaxIterations"]);
|
|
13090
|
-
if (typeof payload["yolo"] === "boolean") {
|
|
13091
|
-
setAutonomy("yolo", payload["yolo"]);
|
|
13092
|
-
decrypted.yolo = payload["yolo"];
|
|
13093
|
-
}
|
|
13094
|
-
if (typeof payload["chime"] === "boolean") setAutonomy("chime", payload["chime"]);
|
|
13095
|
-
if (typeof payload["confirmExit"] === "boolean")
|
|
13096
|
-
setAutonomy("confirmExit", payload["confirmExit"]);
|
|
13097
|
-
if (typeof payload["streamFleet"] === "boolean")
|
|
13098
|
-
setAutonomy("streamFleet", payload["streamFleet"]);
|
|
13099
|
-
if (typeof payload["enhanceEnabled"] === "boolean")
|
|
13100
|
-
setAutonomy("enhance", payload["enhanceEnabled"]);
|
|
13101
|
-
if (typeof payload["enhanceDelayMs"] === "number")
|
|
13102
|
-
setAutonomy("enhanceDelayMs", payload["enhanceDelayMs"]);
|
|
13103
|
-
if (typeof payload["enhanceLanguage"] === "string")
|
|
13104
|
-
setAutonomy("enhanceLanguage", payload["enhanceLanguage"]);
|
|
13105
|
-
if (typeof payload["refinerProvider"] === "string")
|
|
13106
|
-
setAutonomy("refinerProvider", payload["refinerProvider"]);
|
|
13107
|
-
if (typeof payload["refinerModel"] === "string")
|
|
13108
|
-
setAutonomy("refinerModel", payload["refinerModel"]);
|
|
13109
|
-
if (typeof payload["refinerFallbackProfile"] === "string")
|
|
13110
|
-
setAutonomy("refinerFallbackProfile", payload["refinerFallbackProfile"]);
|
|
13111
|
-
if (typeof payload["thinkingWord"] === "string")
|
|
13112
|
-
setAutonomy("thinkingWord", payload["thinkingWord"]);
|
|
13113
|
-
if (typeof payload["statuslineMode"] === "string")
|
|
13114
|
-
setAutonomy("statuslineMode", payload["statuslineMode"]);
|
|
13115
|
-
if (typeof payload["animationStyle"] === "string")
|
|
13116
|
-
setAutonomy("animationStyle", payload["animationStyle"]);
|
|
13117
|
-
if (typeof payload["showModelReasoning"] === "boolean")
|
|
13118
|
-
setAutonomy("showModelReasoning", payload["showModelReasoning"]);
|
|
13119
|
-
if (autonomyTouched) decrypted.autonomy = autonomyCfg;
|
|
13120
|
-
if (typeof payload["nextPrediction"] === "boolean")
|
|
13121
|
-
decrypted.nextPrediction = payload["nextPrediction"];
|
|
13122
|
-
if (typeof payload["uiLocale"] === "string") decrypted.uiLocale = payload["uiLocale"];
|
|
13123
|
-
if (Array.isArray(payload["fallbackModels"]))
|
|
13124
|
-
decrypted.fallbackModels = payload["fallbackModels"];
|
|
13125
|
-
if (payload["fallbackProfiles"] && typeof payload["fallbackProfiles"] === "object" && !Array.isArray(payload["fallbackProfiles"])) {
|
|
13126
|
-
decrypted.fallbackProfiles = payload["fallbackProfiles"];
|
|
13127
|
-
}
|
|
13128
|
-
if (Array.isArray(payload["favoriteModels"]))
|
|
13129
|
-
decrypted.favoriteModels = payload["favoriteModels"];
|
|
13130
|
-
if (typeof payload["favoriteModelsOnly"] === "boolean")
|
|
13131
|
-
decrypted.favoriteModelsOnly = payload["favoriteModelsOnly"];
|
|
13132
|
-
if (payload["modelMatrix"] && typeof payload["modelMatrix"] === "object" && !Array.isArray(payload["modelMatrix"])) {
|
|
13133
|
-
decrypted.modelMatrix = payload["modelMatrix"];
|
|
13134
|
-
}
|
|
13135
|
-
if (typeof payload["fallbackAuto"] === "boolean")
|
|
13136
|
-
decrypted.fallbackAuto = payload["fallbackAuto"];
|
|
13137
|
-
const FEATURE_MAP = {
|
|
13138
|
-
featureMcp: "mcp",
|
|
13139
|
-
featurePlugins: "plugins",
|
|
13140
|
-
featureMemory: "memory",
|
|
13141
|
-
featureSkills: "skills",
|
|
13142
|
-
featureModelsRegistry: "modelsRegistry"
|
|
13143
|
-
};
|
|
13144
|
-
for (const [prefKey, cfgKey] of Object.entries(FEATURE_MAP)) {
|
|
13145
|
-
if (typeof payload[prefKey] === "boolean") {
|
|
13146
|
-
const feats = decrypted.features ?? {};
|
|
13147
|
-
feats[cfgKey] = payload[prefKey];
|
|
13148
|
-
decrypted.features = feats;
|
|
13149
|
-
}
|
|
13150
|
-
}
|
|
13151
|
-
if (typeof payload["contextAutoCompact"] === "boolean" || typeof payload["contextStrategy"] === "string" || typeof payload["contextMode"] === "string") {
|
|
13152
|
-
const ctxCfg = decrypted.context ?? {};
|
|
13153
|
-
if (typeof payload["contextAutoCompact"] === "boolean")
|
|
13154
|
-
ctxCfg.autoCompact = payload["contextAutoCompact"];
|
|
13155
|
-
if (typeof payload["contextStrategy"] === "string")
|
|
13156
|
-
ctxCfg.strategy = payload["contextStrategy"];
|
|
13157
|
-
if (typeof payload["contextMode"] === "string") ctxCfg.mode = payload["contextMode"];
|
|
13158
|
-
decrypted.context = ctxCfg;
|
|
13159
|
-
}
|
|
13160
|
-
if (typeof payload["tokenSavingTier"] === "string") {
|
|
13161
|
-
const featsCfg = decrypted.features ?? {};
|
|
13162
|
-
featsCfg.tokenSavingMode = payload["tokenSavingTier"];
|
|
13163
|
-
decrypted.features = featsCfg;
|
|
13164
|
-
}
|
|
13165
|
-
if (typeof payload["maxConcurrent"] === "number") {
|
|
13166
|
-
decrypted.maxConcurrent = payload["maxConcurrent"];
|
|
13167
|
-
}
|
|
13168
|
-
if (typeof payload["titleAnimation"] === "boolean") {
|
|
13169
|
-
const autoCfg = decrypted.autonomy ?? {};
|
|
13170
|
-
autoCfg.terminalTitleAnimation = payload["titleAnimation"];
|
|
13171
|
-
decrypted.autonomy = autoCfg;
|
|
13172
|
-
}
|
|
13173
|
-
if (typeof payload["logLevel"] === "string") {
|
|
13174
|
-
const logCfg = decrypted.log ?? {};
|
|
13175
|
-
logCfg.level = payload["logLevel"];
|
|
13176
|
-
decrypted.log = logCfg;
|
|
13177
|
-
}
|
|
13178
|
-
if (typeof payload["auditLevel"] === "string") {
|
|
13179
|
-
const sessionCfg = decrypted.session ?? {};
|
|
13180
|
-
sessionCfg.auditLevel = payload["auditLevel"];
|
|
13181
|
-
decrypted.session = sessionCfg;
|
|
13182
|
-
}
|
|
13183
|
-
if (typeof payload["indexOnStart"] === "boolean") {
|
|
13184
|
-
const indexingCfg = decrypted.indexing ?? {};
|
|
13185
|
-
indexingCfg.onSessionStart = payload["indexOnStart"];
|
|
13186
|
-
decrypted.indexing = indexingCfg;
|
|
13187
|
-
}
|
|
13188
|
-
if (typeof payload["maxIterations"] === "number") {
|
|
13189
|
-
const toolsCfg = decrypted.tools ?? {};
|
|
13190
|
-
toolsCfg.maxIterations = payload["maxIterations"];
|
|
13191
|
-
decrypted.tools = toolsCfg;
|
|
13192
|
-
}
|
|
13193
|
-
const hqTouched = typeof payload["hqEnabled"] === "boolean" || typeof payload["hqUrl"] === "string" || typeof payload["hqToken"] === "string" || typeof payload["hqRawContent"] === "boolean";
|
|
13194
|
-
if (hqTouched) {
|
|
13195
|
-
const hqCfg = decrypted.hq ?? {};
|
|
13196
|
-
if (typeof payload["hqEnabled"] === "boolean") hqCfg.enabled = payload["hqEnabled"];
|
|
13197
|
-
if (typeof payload["hqUrl"] === "string") hqCfg.url = payload["hqUrl"];
|
|
13198
|
-
if (typeof payload["hqToken"] === "string") hqCfg.token = payload["hqToken"];
|
|
13199
|
-
if (typeof payload["hqRawContent"] === "boolean")
|
|
13200
|
-
hqCfg.rawContent = payload["hqRawContent"];
|
|
13201
|
-
decrypted.hq = hqCfg;
|
|
13202
|
-
}
|
|
13203
|
-
const tgTouched = typeof payload["tgSessionEnd"] === "boolean" || typeof payload["tgDelegate"] === "boolean" || typeof payload["tgLongToolMs"] === "number";
|
|
13204
|
-
if (tgTouched) {
|
|
13205
|
-
const ext = decrypted.extensions ?? {};
|
|
13206
|
-
const tg = ext["telegram"] ?? {};
|
|
13207
|
-
if (typeof payload["tgSessionEnd"] === "boolean") {
|
|
13208
|
-
tg["notifyOnSessionEnd"] = payload["tgSessionEnd"];
|
|
13209
|
-
}
|
|
13210
|
-
if (typeof payload["tgDelegate"] === "boolean") {
|
|
13211
|
-
tg["notifyOnDelegate"] = payload["tgDelegate"];
|
|
13212
|
-
}
|
|
13213
|
-
if (typeof payload["tgLongToolMs"] === "number") {
|
|
13214
|
-
tg["longToolThresholdMs"] = payload["tgLongToolMs"];
|
|
13215
|
-
}
|
|
13216
|
-
ext["telegram"] = tg;
|
|
13217
|
-
decrypted.extensions = ext;
|
|
13218
|
-
}
|
|
13219
|
-
const modelRuntimeTouched = typeof payload["reasoningMode"] === "string" || typeof payload["reasoningEffort"] === "string" || typeof payload["reasoningPreserve"] === "boolean" || typeof payload["cacheTtl"] === "string";
|
|
13220
|
-
if (modelRuntimeTouched) {
|
|
13221
|
-
const mr = decrypted.modelRuntime ?? {};
|
|
13222
|
-
const reasoning = mr.reasoning ?? {};
|
|
13223
|
-
if (typeof payload["reasoningMode"] === "string") reasoning.mode = payload["reasoningMode"];
|
|
13224
|
-
if (typeof payload["reasoningEffort"] === "string")
|
|
13225
|
-
reasoning.effort = payload["reasoningEffort"];
|
|
13226
|
-
if (typeof payload["reasoningPreserve"] === "boolean")
|
|
13227
|
-
reasoning.preserve = payload["reasoningPreserve"];
|
|
13228
|
-
mr.reasoning = reasoning;
|
|
13229
|
-
if (typeof payload["cacheTtl"] === "string" && payload["cacheTtl"] !== "default") {
|
|
13230
|
-
mr.cache = { ttl: payload["cacheTtl"] };
|
|
13231
|
-
} else if (payload["cacheTtl"] === "default") {
|
|
13232
|
-
delete mr.cache;
|
|
13233
|
-
}
|
|
13234
|
-
decrypted.modelRuntime = mr;
|
|
13235
|
-
}
|
|
13236
|
-
if (typeof payload["breakerEnabled"] === "boolean" || typeof payload["breakerAutoKillResetMs"] === "number") {
|
|
13237
|
-
const cb = decrypted.circuitBreaker ?? {};
|
|
13238
|
-
if (typeof payload["breakerEnabled"] === "boolean") cb.enabled = payload["breakerEnabled"];
|
|
13239
|
-
if (typeof payload["breakerAutoKillResetMs"] === "number")
|
|
13240
|
-
cb.autoKillResetMs = payload["breakerAutoKillResetMs"];
|
|
13241
|
-
decrypted.circuitBreaker = cb;
|
|
13242
|
-
}
|
|
13243
|
-
if (payload["fsAccess"] === "unrestricted" || payload["fsAccess"] === "project") {
|
|
13244
|
-
const restrict = payload["fsAccess"] === "project";
|
|
13245
|
-
const toolsCfg = decrypted.tools ?? {};
|
|
13246
|
-
toolsCfg.restrictToProjectRoot = restrict;
|
|
13247
|
-
decrypted.tools = toolsCfg;
|
|
13248
|
-
const featsCfg = decrypted.features ?? {};
|
|
13249
|
-
featsCfg.allowOutsideProjectRoot = !restrict;
|
|
13250
|
-
decrypted.features = featsCfg;
|
|
13251
|
-
}
|
|
13252
|
-
if (typeof payload["debugStream"] === "boolean")
|
|
13253
|
-
decrypted.debugStream = payload["debugStream"];
|
|
13254
|
-
if (typeof payload["pluginsEnabled"] === "object" && payload["pluginsEnabled"] !== null) {
|
|
13255
|
-
const ext = decrypted.extensions ?? {};
|
|
13256
|
-
for (const [pluginName, enabled] of Object.entries(
|
|
13257
|
-
payload["pluginsEnabled"]
|
|
13258
|
-
)) {
|
|
13259
|
-
if (FORBIDDEN_PROTO_KEYS2.has(pluginName)) continue;
|
|
13260
|
-
const pExt = ext[pluginName] ?? {};
|
|
13261
|
-
pExt["enabled"] = enabled;
|
|
13262
|
-
ext[pluginName] = pExt;
|
|
13263
|
-
}
|
|
13264
|
-
decrypted.extensions = ext;
|
|
13265
|
-
}
|
|
13266
|
-
const chimeraTouched = typeof payload["chimeraEnabled"] === "boolean" || typeof payload["chimeraProvider"] === "string" || typeof payload["chimeraModel"] === "string" || typeof payload["chimeraMaxFiles"] === "number" || typeof payload["chimeraAutoFix"] === "string";
|
|
13267
|
-
if (chimeraTouched) {
|
|
13268
|
-
const ext = decrypted.extensions ?? {};
|
|
13269
|
-
const chimera = ext["wstack-chimera"] ?? {};
|
|
13270
|
-
if (typeof payload["chimeraEnabled"] === "boolean")
|
|
13271
|
-
chimera["enabled"] = payload["chimeraEnabled"];
|
|
13272
|
-
if (typeof payload["chimeraProvider"] === "string")
|
|
13273
|
-
chimera["provider"] = payload["chimeraProvider"];
|
|
13274
|
-
if (typeof payload["chimeraModel"] === "string")
|
|
13275
|
-
chimera["model"] = payload["chimeraModel"];
|
|
13276
|
-
if (typeof payload["chimeraMaxFiles"] === "number" && payload["chimeraMaxFiles"] >= 1) {
|
|
13277
|
-
chimera["maxFiles"] = payload["chimeraMaxFiles"];
|
|
13278
|
-
}
|
|
13279
|
-
if (typeof payload["chimeraAutoFix"] === "string") {
|
|
13280
|
-
if (payload["chimeraAutoFix"] === "off" || payload["chimeraAutoFix"] === "ask" || payload["chimeraAutoFix"] === "auto") {
|
|
13281
|
-
chimera["autoFix"] = payload["chimeraAutoFix"];
|
|
13282
|
-
}
|
|
13283
|
-
}
|
|
13284
|
-
ext["wstack-chimera"] = chimera;
|
|
13285
|
-
decrypted.extensions = ext;
|
|
13286
|
-
}
|
|
13287
|
-
const autoReviewTouched = typeof payload["autoReviewEnabled"] === "boolean" || typeof payload["autoReviewProvider"] === "string" || typeof payload["autoReviewModel"] === "string" || typeof payload["autoReviewFallbackProfile"] === "string" || Array.isArray(payload["autoReviewFallbackModels"]) || typeof payload["autoReviewDebounceMs"] === "number" || typeof payload["autoReviewMaxFilesPerBatch"] === "number" || typeof payload["autoReviewMaxConcurrentReviews"] === "number" || typeof payload["autoReviewCascadeOn"] === "string";
|
|
13288
|
-
if (autoReviewTouched) {
|
|
13289
|
-
const ext = decrypted.extensions ?? {};
|
|
13290
|
-
const ar = ext["wstack-auto-review"] ?? {};
|
|
13291
|
-
if (typeof payload["autoReviewEnabled"] === "boolean")
|
|
13292
|
-
ar["enabled"] = payload["autoReviewEnabled"];
|
|
13293
|
-
if (typeof payload["autoReviewProvider"] === "string")
|
|
13294
|
-
ar["provider"] = payload["autoReviewProvider"];
|
|
13295
|
-
if (typeof payload["autoReviewModel"] === "string")
|
|
13296
|
-
ar["model"] = payload["autoReviewModel"];
|
|
13297
|
-
if (typeof payload["autoReviewFallbackProfile"] === "string") {
|
|
13298
|
-
if (payload["autoReviewFallbackProfile"] === "") {
|
|
13299
|
-
delete ar["fallbackProfile"];
|
|
13300
|
-
} else {
|
|
13301
|
-
ar["fallbackProfile"] = payload["autoReviewFallbackProfile"];
|
|
13302
|
-
}
|
|
13174
|
+
return updateGlobalConfig(
|
|
13175
|
+
deps2,
|
|
13176
|
+
holder,
|
|
13177
|
+
(decrypted) => {
|
|
13178
|
+
const autonomyCfg = decrypted.autonomy ?? {};
|
|
13179
|
+
let autonomyTouched = false;
|
|
13180
|
+
const setAutonomy = (key, val) => {
|
|
13181
|
+
autonomyCfg[key] = val;
|
|
13182
|
+
autonomyTouched = true;
|
|
13183
|
+
};
|
|
13184
|
+
if (typeof payload["autonomy"] === "string" && ["off", "suggest", "auto"].includes(payload["autonomy"])) {
|
|
13185
|
+
setAutonomy("defaultMode", payload["autonomy"]);
|
|
13303
13186
|
}
|
|
13304
|
-
if (typeof payload["
|
|
13305
|
-
|
|
13187
|
+
if (typeof payload["autonomyDelayMs"] === "number")
|
|
13188
|
+
setAutonomy("autoProceedDelayMs", payload["autonomyDelayMs"]);
|
|
13189
|
+
if (typeof payload["autoProceedMaxIterations"] === "number")
|
|
13190
|
+
setAutonomy("autoProceedMaxIterations", payload["autoProceedMaxIterations"]);
|
|
13191
|
+
if (typeof payload["yolo"] === "boolean") {
|
|
13192
|
+
setAutonomy("yolo", payload["yolo"]);
|
|
13193
|
+
decrypted.yolo = payload["yolo"];
|
|
13194
|
+
}
|
|
13195
|
+
if (typeof payload["chime"] === "boolean") setAutonomy("chime", payload["chime"]);
|
|
13196
|
+
if (typeof payload["confirmExit"] === "boolean")
|
|
13197
|
+
setAutonomy("confirmExit", payload["confirmExit"]);
|
|
13198
|
+
if (typeof payload["streamFleet"] === "boolean")
|
|
13199
|
+
setAutonomy("streamFleet", payload["streamFleet"]);
|
|
13200
|
+
if (typeof payload["enhanceEnabled"] === "boolean")
|
|
13201
|
+
setAutonomy("enhance", payload["enhanceEnabled"]);
|
|
13202
|
+
if (typeof payload["enhanceDelayMs"] === "number")
|
|
13203
|
+
setAutonomy("enhanceDelayMs", payload["enhanceDelayMs"]);
|
|
13204
|
+
if (typeof payload["enhanceLanguage"] === "string")
|
|
13205
|
+
setAutonomy("enhanceLanguage", payload["enhanceLanguage"]);
|
|
13206
|
+
if (typeof payload["refinerProvider"] === "string")
|
|
13207
|
+
setAutonomy("refinerProvider", payload["refinerProvider"]);
|
|
13208
|
+
if (typeof payload["refinerModel"] === "string")
|
|
13209
|
+
setAutonomy("refinerModel", payload["refinerModel"]);
|
|
13210
|
+
if (typeof payload["refinerFallbackProfile"] === "string")
|
|
13211
|
+
setAutonomy("refinerFallbackProfile", payload["refinerFallbackProfile"]);
|
|
13212
|
+
if (typeof payload["thinkingWord"] === "string")
|
|
13213
|
+
setAutonomy("thinkingWord", payload["thinkingWord"]);
|
|
13214
|
+
if (typeof payload["statuslineMode"] === "string")
|
|
13215
|
+
setAutonomy("statuslineMode", payload["statuslineMode"]);
|
|
13216
|
+
if (typeof payload["animationStyle"] === "string")
|
|
13217
|
+
setAutonomy("animationStyle", payload["animationStyle"]);
|
|
13218
|
+
if (typeof payload["showModelReasoning"] === "boolean")
|
|
13219
|
+
setAutonomy("showModelReasoning", payload["showModelReasoning"]);
|
|
13220
|
+
if (autonomyTouched) decrypted.autonomy = autonomyCfg;
|
|
13221
|
+
if (typeof payload["nextPrediction"] === "boolean")
|
|
13222
|
+
decrypted.nextPrediction = payload["nextPrediction"];
|
|
13223
|
+
if (typeof payload["uiLocale"] === "string") decrypted.uiLocale = payload["uiLocale"];
|
|
13224
|
+
if (Array.isArray(payload["fallbackModels"]))
|
|
13225
|
+
decrypted.fallbackModels = payload["fallbackModels"];
|
|
13226
|
+
if (payload["fallbackProfiles"] && typeof payload["fallbackProfiles"] === "object" && !Array.isArray(payload["fallbackProfiles"])) {
|
|
13227
|
+
decrypted.fallbackProfiles = payload["fallbackProfiles"];
|
|
13306
13228
|
}
|
|
13307
|
-
if (
|
|
13308
|
-
|
|
13229
|
+
if (Array.isArray(payload["favoriteModels"]))
|
|
13230
|
+
decrypted.favoriteModels = payload["favoriteModels"];
|
|
13231
|
+
if (typeof payload["favoriteModelsOnly"] === "boolean")
|
|
13232
|
+
decrypted.favoriteModelsOnly = payload["favoriteModelsOnly"];
|
|
13233
|
+
if (Array.isArray(payload["modelAvailabilitySchedule"]))
|
|
13234
|
+
decrypted.modelAvailabilitySchedule = payload["modelAvailabilitySchedule"];
|
|
13235
|
+
if (payload["modelMatrix"] && typeof payload["modelMatrix"] === "object" && !Array.isArray(payload["modelMatrix"])) {
|
|
13236
|
+
decrypted.modelMatrix = payload["modelMatrix"];
|
|
13237
|
+
}
|
|
13238
|
+
if (typeof payload["fallbackAuto"] === "boolean")
|
|
13239
|
+
decrypted.fallbackAuto = payload["fallbackAuto"];
|
|
13240
|
+
const FEATURE_MAP = {
|
|
13241
|
+
featureMcp: "mcp",
|
|
13242
|
+
featurePlugins: "plugins",
|
|
13243
|
+
featureMemory: "memory",
|
|
13244
|
+
featureSkills: "skills",
|
|
13245
|
+
featureModelsRegistry: "modelsRegistry"
|
|
13246
|
+
};
|
|
13247
|
+
for (const [prefKey, cfgKey] of Object.entries(FEATURE_MAP)) {
|
|
13248
|
+
if (typeof payload[prefKey] === "boolean") {
|
|
13249
|
+
const feats = decrypted.features ?? {};
|
|
13250
|
+
feats[cfgKey] = payload[prefKey];
|
|
13251
|
+
decrypted.features = feats;
|
|
13252
|
+
}
|
|
13253
|
+
}
|
|
13254
|
+
if (typeof payload["contextAutoCompact"] === "boolean" || typeof payload["contextStrategy"] === "string" || typeof payload["contextMode"] === "string") {
|
|
13255
|
+
const ctxCfg = decrypted.context ?? {};
|
|
13256
|
+
if (typeof payload["contextAutoCompact"] === "boolean")
|
|
13257
|
+
ctxCfg.autoCompact = payload["contextAutoCompact"];
|
|
13258
|
+
if (typeof payload["contextStrategy"] === "string")
|
|
13259
|
+
ctxCfg.strategy = payload["contextStrategy"];
|
|
13260
|
+
if (typeof payload["contextMode"] === "string") ctxCfg.mode = payload["contextMode"];
|
|
13261
|
+
decrypted.context = ctxCfg;
|
|
13262
|
+
}
|
|
13263
|
+
if (typeof payload["tokenSavingTier"] === "string") {
|
|
13264
|
+
const featsCfg = decrypted.features ?? {};
|
|
13265
|
+
featsCfg.tokenSavingMode = payload["tokenSavingTier"];
|
|
13266
|
+
decrypted.features = featsCfg;
|
|
13267
|
+
}
|
|
13268
|
+
if (typeof payload["maxConcurrent"] === "number") {
|
|
13269
|
+
decrypted.maxConcurrent = payload["maxConcurrent"];
|
|
13270
|
+
}
|
|
13271
|
+
if (typeof payload["titleAnimation"] === "boolean") {
|
|
13272
|
+
const autoCfg = decrypted.autonomy ?? {};
|
|
13273
|
+
autoCfg.terminalTitleAnimation = payload["titleAnimation"];
|
|
13274
|
+
decrypted.autonomy = autoCfg;
|
|
13309
13275
|
}
|
|
13310
|
-
if (typeof payload["
|
|
13311
|
-
|
|
13276
|
+
if (typeof payload["logLevel"] === "string") {
|
|
13277
|
+
const logCfg = decrypted.log ?? {};
|
|
13278
|
+
logCfg.level = payload["logLevel"];
|
|
13279
|
+
decrypted.log = logCfg;
|
|
13280
|
+
}
|
|
13281
|
+
if (typeof payload["auditLevel"] === "string") {
|
|
13282
|
+
const sessionCfg = decrypted.session ?? {};
|
|
13283
|
+
sessionCfg.auditLevel = payload["auditLevel"];
|
|
13284
|
+
decrypted.session = sessionCfg;
|
|
13285
|
+
}
|
|
13286
|
+
if (typeof payload["indexOnStart"] === "boolean") {
|
|
13287
|
+
const indexingCfg = decrypted.indexing ?? {};
|
|
13288
|
+
indexingCfg.onSessionStart = payload["indexOnStart"];
|
|
13289
|
+
decrypted.indexing = indexingCfg;
|
|
13290
|
+
}
|
|
13291
|
+
if (typeof payload["maxIterations"] === "number") {
|
|
13292
|
+
const toolsCfg = decrypted.tools ?? {};
|
|
13293
|
+
toolsCfg.maxIterations = payload["maxIterations"];
|
|
13294
|
+
decrypted.tools = toolsCfg;
|
|
13295
|
+
}
|
|
13296
|
+
const hqTouched = typeof payload["hqEnabled"] === "boolean" || typeof payload["hqUrl"] === "string" || typeof payload["hqToken"] === "string" || typeof payload["hqRawContent"] === "boolean";
|
|
13297
|
+
if (hqTouched) {
|
|
13298
|
+
const hqCfg = decrypted.hq ?? {};
|
|
13299
|
+
if (typeof payload["hqEnabled"] === "boolean") hqCfg.enabled = payload["hqEnabled"];
|
|
13300
|
+
if (typeof payload["hqUrl"] === "string") hqCfg.url = payload["hqUrl"];
|
|
13301
|
+
if (typeof payload["hqToken"] === "string") hqCfg.token = payload["hqToken"];
|
|
13302
|
+
if (typeof payload["hqRawContent"] === "boolean")
|
|
13303
|
+
hqCfg.rawContent = payload["hqRawContent"];
|
|
13304
|
+
decrypted.hq = hqCfg;
|
|
13305
|
+
}
|
|
13306
|
+
const tgTouched = typeof payload["tgSessionEnd"] === "boolean" || typeof payload["tgDelegate"] === "boolean" || typeof payload["tgLongToolMs"] === "number";
|
|
13307
|
+
if (tgTouched) {
|
|
13308
|
+
const ext = decrypted.extensions ?? {};
|
|
13309
|
+
const tg = ext["telegram"] ?? {};
|
|
13310
|
+
if (typeof payload["tgSessionEnd"] === "boolean") {
|
|
13311
|
+
tg["notifyOnSessionEnd"] = payload["tgSessionEnd"];
|
|
13312
|
+
}
|
|
13313
|
+
if (typeof payload["tgDelegate"] === "boolean") {
|
|
13314
|
+
tg["notifyOnDelegate"] = payload["tgDelegate"];
|
|
13315
|
+
}
|
|
13316
|
+
if (typeof payload["tgLongToolMs"] === "number") {
|
|
13317
|
+
tg["longToolThresholdMs"] = payload["tgLongToolMs"];
|
|
13318
|
+
}
|
|
13319
|
+
ext["telegram"] = tg;
|
|
13320
|
+
decrypted.extensions = ext;
|
|
13321
|
+
}
|
|
13322
|
+
const modelRuntimeTouched = typeof payload["reasoningMode"] === "string" || typeof payload["reasoningEffort"] === "string" || typeof payload["reasoningPreserve"] === "boolean" || typeof payload["cacheTtl"] === "string";
|
|
13323
|
+
if (modelRuntimeTouched) {
|
|
13324
|
+
const mr = decrypted.modelRuntime ?? {};
|
|
13325
|
+
const reasoning = mr.reasoning ?? {};
|
|
13326
|
+
if (typeof payload["reasoningMode"] === "string") reasoning.mode = payload["reasoningMode"];
|
|
13327
|
+
if (typeof payload["reasoningEffort"] === "string")
|
|
13328
|
+
reasoning.effort = payload["reasoningEffort"];
|
|
13329
|
+
if (typeof payload["reasoningPreserve"] === "boolean")
|
|
13330
|
+
reasoning.preserve = payload["reasoningPreserve"];
|
|
13331
|
+
mr.reasoning = reasoning;
|
|
13332
|
+
if (typeof payload["cacheTtl"] === "string" && payload["cacheTtl"] !== "default") {
|
|
13333
|
+
mr.cache = { ttl: payload["cacheTtl"] };
|
|
13334
|
+
} else if (payload["cacheTtl"] === "default") {
|
|
13335
|
+
delete mr.cache;
|
|
13336
|
+
}
|
|
13337
|
+
decrypted.modelRuntime = mr;
|
|
13312
13338
|
}
|
|
13313
|
-
if (typeof payload["
|
|
13314
|
-
|
|
13315
|
-
|
|
13339
|
+
if (typeof payload["breakerEnabled"] === "boolean" || typeof payload["breakerAutoKillResetMs"] === "number") {
|
|
13340
|
+
const cb = decrypted.circuitBreaker ?? {};
|
|
13341
|
+
if (typeof payload["breakerEnabled"] === "boolean") cb.enabled = payload["breakerEnabled"];
|
|
13342
|
+
if (typeof payload["breakerAutoKillResetMs"] === "number")
|
|
13343
|
+
cb.autoKillResetMs = payload["breakerAutoKillResetMs"];
|
|
13344
|
+
decrypted.circuitBreaker = cb;
|
|
13345
|
+
}
|
|
13346
|
+
if (payload["fsAccess"] === "unrestricted" || payload["fsAccess"] === "project") {
|
|
13347
|
+
const restrict = payload["fsAccess"] === "project";
|
|
13348
|
+
const toolsCfg = decrypted.tools ?? {};
|
|
13349
|
+
toolsCfg.restrictToProjectRoot = restrict;
|
|
13350
|
+
decrypted.tools = toolsCfg;
|
|
13351
|
+
const featsCfg = decrypted.features ?? {};
|
|
13352
|
+
featsCfg.allowOutsideProjectRoot = !restrict;
|
|
13353
|
+
decrypted.features = featsCfg;
|
|
13354
|
+
}
|
|
13355
|
+
if (typeof payload["debugStream"] === "boolean")
|
|
13356
|
+
decrypted.debugStream = payload["debugStream"];
|
|
13357
|
+
if (typeof payload["pluginsEnabled"] === "object" && payload["pluginsEnabled"] !== null) {
|
|
13358
|
+
const ext = decrypted.extensions ?? {};
|
|
13359
|
+
for (const [pluginName, enabled] of Object.entries(
|
|
13360
|
+
payload["pluginsEnabled"]
|
|
13361
|
+
)) {
|
|
13362
|
+
if (FORBIDDEN_PROTO_KEYS2.has(pluginName)) continue;
|
|
13363
|
+
const pExt = ext[pluginName] ?? {};
|
|
13364
|
+
pExt["enabled"] = enabled;
|
|
13365
|
+
ext[pluginName] = pExt;
|
|
13366
|
+
}
|
|
13367
|
+
decrypted.extensions = ext;
|
|
13368
|
+
}
|
|
13369
|
+
const chimeraTouched = typeof payload["chimeraEnabled"] === "boolean" || typeof payload["chimeraProvider"] === "string" || typeof payload["chimeraModel"] === "string" || typeof payload["chimeraMaxFiles"] === "number" || typeof payload["chimeraAutoFix"] === "string";
|
|
13370
|
+
if (chimeraTouched) {
|
|
13371
|
+
const ext = decrypted.extensions ?? {};
|
|
13372
|
+
const chimera = ext["wstack-chimera"] ?? {};
|
|
13373
|
+
if (typeof payload["chimeraEnabled"] === "boolean")
|
|
13374
|
+
chimera["enabled"] = payload["chimeraEnabled"];
|
|
13375
|
+
if (typeof payload["chimeraProvider"] === "string")
|
|
13376
|
+
chimera["provider"] = payload["chimeraProvider"];
|
|
13377
|
+
if (typeof payload["chimeraModel"] === "string") chimera["model"] = payload["chimeraModel"];
|
|
13378
|
+
if (typeof payload["chimeraMaxFiles"] === "number" && payload["chimeraMaxFiles"] >= 1) {
|
|
13379
|
+
chimera["maxFiles"] = payload["chimeraMaxFiles"];
|
|
13380
|
+
}
|
|
13381
|
+
if (typeof payload["chimeraAutoFix"] === "string") {
|
|
13382
|
+
if (payload["chimeraAutoFix"] === "off" || payload["chimeraAutoFix"] === "ask" || payload["chimeraAutoFix"] === "auto") {
|
|
13383
|
+
chimera["autoFix"] = payload["chimeraAutoFix"];
|
|
13384
|
+
}
|
|
13385
|
+
}
|
|
13386
|
+
ext["wstack-chimera"] = chimera;
|
|
13387
|
+
decrypted.extensions = ext;
|
|
13388
|
+
}
|
|
13389
|
+
const autoReviewTouched = typeof payload["autoReviewEnabled"] === "boolean" || typeof payload["autoReviewProvider"] === "string" || typeof payload["autoReviewModel"] === "string" || typeof payload["autoReviewFallbackProfile"] === "string" || Array.isArray(payload["autoReviewFallbackModels"]) || typeof payload["autoReviewDebounceMs"] === "number" || typeof payload["autoReviewMaxFilesPerBatch"] === "number" || typeof payload["autoReviewMaxConcurrentReviews"] === "number" || typeof payload["autoReviewCascadeOn"] === "string";
|
|
13390
|
+
if (autoReviewTouched) {
|
|
13391
|
+
const ext = decrypted.extensions ?? {};
|
|
13392
|
+
const ar = ext["wstack-auto-review"] ?? {};
|
|
13393
|
+
if (typeof payload["autoReviewEnabled"] === "boolean")
|
|
13394
|
+
ar["enabled"] = payload["autoReviewEnabled"];
|
|
13395
|
+
if (typeof payload["autoReviewProvider"] === "string")
|
|
13396
|
+
ar["provider"] = payload["autoReviewProvider"];
|
|
13397
|
+
if (typeof payload["autoReviewModel"] === "string")
|
|
13398
|
+
ar["model"] = payload["autoReviewModel"];
|
|
13399
|
+
if (typeof payload["autoReviewFallbackProfile"] === "string") {
|
|
13400
|
+
if (payload["autoReviewFallbackProfile"] === "") {
|
|
13401
|
+
delete ar["fallbackProfile"];
|
|
13402
|
+
} else {
|
|
13403
|
+
ar["fallbackProfile"] = payload["autoReviewFallbackProfile"];
|
|
13404
|
+
}
|
|
13405
|
+
}
|
|
13406
|
+
if (typeof payload["autoReviewDebounceMs"] === "number" && payload["autoReviewDebounceMs"] >= 0) {
|
|
13407
|
+
ar["debounceMs"] = payload["autoReviewDebounceMs"];
|
|
13408
|
+
}
|
|
13409
|
+
if (typeof payload["autoReviewMaxFilesPerBatch"] === "number" && payload["autoReviewMaxFilesPerBatch"] >= 1) {
|
|
13410
|
+
ar["maxFilesPerBatch"] = payload["autoReviewMaxFilesPerBatch"];
|
|
13411
|
+
}
|
|
13412
|
+
if (typeof payload["autoReviewMaxConcurrentReviews"] === "number" && payload["autoReviewMaxConcurrentReviews"] >= 1) {
|
|
13413
|
+
ar["maxConcurrentReviews"] = payload["autoReviewMaxConcurrentReviews"];
|
|
13414
|
+
}
|
|
13415
|
+
if (typeof payload["autoReviewCascadeOn"] === "string") {
|
|
13416
|
+
if (payload["autoReviewCascadeOn"] === "off" || payload["autoReviewCascadeOn"] === "critical" || payload["autoReviewCascadeOn"] === "high") {
|
|
13417
|
+
ar["cascadeOn"] = payload["autoReviewCascadeOn"];
|
|
13418
|
+
}
|
|
13316
13419
|
}
|
|
13420
|
+
ext["wstack-auto-review"] = ar;
|
|
13421
|
+
decrypted.extensions = ext;
|
|
13317
13422
|
}
|
|
13318
|
-
|
|
13319
|
-
|
|
13320
|
-
|
|
13321
|
-
}, "prefs");
|
|
13423
|
+
},
|
|
13424
|
+
"prefs"
|
|
13425
|
+
);
|
|
13322
13426
|
}
|
|
13323
13427
|
|
|
13324
13428
|
// src/server/provider-handlers.ts
|
|
@@ -13656,6 +13760,7 @@ import {
|
|
|
13656
13760
|
gatedEnhancerReasoning,
|
|
13657
13761
|
nextEnhanceTimeout,
|
|
13658
13762
|
recentTextTurns,
|
|
13763
|
+
resolveConfiguredRefinerRef,
|
|
13659
13764
|
resolveEnhanceFallbackRef,
|
|
13660
13765
|
resolveProviderModelList
|
|
13661
13766
|
} from "@wrongstack/core";
|
|
@@ -14518,6 +14623,26 @@ function buildRoutes(state, deps2, cb) {
|
|
|
14518
14623
|
});
|
|
14519
14624
|
return;
|
|
14520
14625
|
}
|
|
14626
|
+
} else {
|
|
14627
|
+
const configuredRef = resolveConfiguredRefinerRef({
|
|
14628
|
+
...cfg,
|
|
14629
|
+
provider: providerId,
|
|
14630
|
+
model
|
|
14631
|
+
});
|
|
14632
|
+
if (configuredRef) {
|
|
14633
|
+
const slash = configuredRef.indexOf("/");
|
|
14634
|
+
const configuredProvider = slash > 0 ? configuredRef.slice(0, slash) : providerId;
|
|
14635
|
+
const configuredModel = slash > 0 ? configuredRef.slice(slash + 1) : configuredRef;
|
|
14636
|
+
try {
|
|
14637
|
+
const providerCfg = cfg.providers?.[configuredProvider] ?? {
|
|
14638
|
+
type: configuredProvider
|
|
14639
|
+
};
|
|
14640
|
+
provider = deps2.providerRegistry.has(configuredProvider) ? deps2.providerRegistry.create({ ...providerCfg, type: configuredProvider }) : makeProviderFromConfig2(configuredProvider, providerCfg);
|
|
14641
|
+
providerId = configuredProvider;
|
|
14642
|
+
model = configuredModel;
|
|
14643
|
+
} catch {
|
|
14644
|
+
}
|
|
14645
|
+
}
|
|
14521
14646
|
}
|
|
14522
14647
|
const baseTimeout = 9e4;
|
|
14523
14648
|
const timeoutMs = typeof payload.timeoutMs === "number" && payload.timeoutMs > 0 ? payload.timeoutMs : baseTimeout;
|
|
@@ -14704,19 +14829,27 @@ function buildRoutes(state, deps2, cb) {
|
|
|
14704
14829
|
cfg.favoriteModels = payload["favoriteModels"];
|
|
14705
14830
|
if (typeof payload["favoriteModelsOnly"] === "boolean")
|
|
14706
14831
|
cfg.favoriteModelsOnly = payload["favoriteModelsOnly"];
|
|
14832
|
+
if (Array.isArray(payload["modelAvailabilitySchedule"]))
|
|
14833
|
+
cfg.modelAvailabilitySchedule = payload["modelAvailabilitySchedule"];
|
|
14707
14834
|
if (payload["modelMatrix"] && typeof payload["modelMatrix"] === "object" && !Array.isArray(payload["modelMatrix"])) {
|
|
14708
14835
|
cfg.modelMatrix = payload["modelMatrix"];
|
|
14709
14836
|
}
|
|
14710
14837
|
if (typeof payload["fallbackAuto"] === "boolean") cfg.fallbackAuto = payload["fallbackAuto"];
|
|
14711
14838
|
const routingPatch = {};
|
|
14712
|
-
if (Array.isArray(payload["fallbackModels"]))
|
|
14839
|
+
if (Array.isArray(payload["fallbackModels"]))
|
|
14840
|
+
routingPatch.fallbackModels = payload["fallbackModels"];
|
|
14713
14841
|
if (payload["fallbackProfiles"] && typeof payload["fallbackProfiles"] === "object" && !Array.isArray(payload["fallbackProfiles"]))
|
|
14714
14842
|
routingPatch.fallbackProfiles = payload["fallbackProfiles"];
|
|
14715
|
-
if (Array.isArray(payload["favoriteModels"]))
|
|
14716
|
-
|
|
14843
|
+
if (Array.isArray(payload["favoriteModels"]))
|
|
14844
|
+
routingPatch.favoriteModels = payload["favoriteModels"];
|
|
14845
|
+
if (typeof payload["favoriteModelsOnly"] === "boolean")
|
|
14846
|
+
routingPatch.favoriteModelsOnly = payload["favoriteModelsOnly"];
|
|
14847
|
+
if (Array.isArray(payload["modelAvailabilitySchedule"]))
|
|
14848
|
+
routingPatch.modelAvailabilitySchedule = payload["modelAvailabilitySchedule"];
|
|
14717
14849
|
if (payload["modelMatrix"] && typeof payload["modelMatrix"] === "object" && !Array.isArray(payload["modelMatrix"]))
|
|
14718
14850
|
routingPatch.modelMatrix = payload["modelMatrix"];
|
|
14719
|
-
if (typeof payload["fallbackAuto"] === "boolean")
|
|
14851
|
+
if (typeof payload["fallbackAuto"] === "boolean")
|
|
14852
|
+
routingPatch.fallbackAuto = payload["fallbackAuto"];
|
|
14720
14853
|
if (Object.keys(routingPatch).length > 0)
|
|
14721
14854
|
deps2.configStore.update(routingPatch);
|
|
14722
14855
|
if (typeof payload["contextAutoCompact"] === "boolean") {
|