@wrongstack/webui 0.3.3 → 0.3.7
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/assets/index-B-u6omip.css +1 -0
- package/dist/assets/{index-CJmc6zwr.js → index-Do84Z2Fv.js} +33 -33
- package/dist/index.css +3 -0
- package/dist/index.css.map +1 -1
- package/dist/index.html +2 -2
- package/dist/index.js +54 -16
- package/dist/index.js.map +1 -1
- package/dist/server/entry.js +54 -19
- package/dist/server/entry.js.map +1 -1
- package/dist/server/index.js +54 -19
- package/dist/server/index.js.map +1 -1
- package/package.json +5 -5
- package/dist/assets/index-TCwASaz8.css +0 -1
package/dist/server/entry.js
CHANGED
|
@@ -26,8 +26,7 @@ import {
|
|
|
26
26
|
resolveContextWindowPolicy
|
|
27
27
|
} from "@wrongstack/core";
|
|
28
28
|
import { buildProviderFactoriesFromRegistry, makeProviderFromConfig } from "@wrongstack/providers";
|
|
29
|
-
import { forgetTool, rememberTool } from "@wrongstack/tools";
|
|
30
|
-
import { builtinToolsPack } from "@wrongstack/tools/pack";
|
|
29
|
+
import { builtinToolsPack, forgetTool, rememberTool } from "@wrongstack/tools";
|
|
31
30
|
import { WebSocket, WebSocketServer } from "ws";
|
|
32
31
|
import { randomBytes } from "crypto";
|
|
33
32
|
import { createDefaultContainer } from "@wrongstack/runtime";
|
|
@@ -83,6 +82,7 @@ async function startWebUI(opts = {}) {
|
|
|
83
82
|
const boot = await bootConfig();
|
|
84
83
|
const { config: baseConfig, vault, globalConfigPath, projectRoot, wpaths, logger } = boot;
|
|
85
84
|
let config = baseConfig;
|
|
85
|
+
let configWriteLock = Promise.resolve();
|
|
86
86
|
console.log("[WebUI] Config loaded:", config.provider, "/", config.model);
|
|
87
87
|
const modelsRegistry = new DefaultModelsRegistry({
|
|
88
88
|
cacheFile: wpaths.modelsCache,
|
|
@@ -291,6 +291,7 @@ async function startWebUI(opts = {}) {
|
|
|
291
291
|
console.log(
|
|
292
292
|
`[WebUI] WebSocket server running on ws://${wsHost2}:${wsPort2}` + (wssSecondary ? ` (and ws://[::1]:${wsPort2})` : "")
|
|
293
293
|
);
|
|
294
|
+
const pendingConfirms = /* @__PURE__ */ new Map();
|
|
294
295
|
function setupEvents() {
|
|
295
296
|
events.on("iteration.started", (e) => {
|
|
296
297
|
broadcast({
|
|
@@ -362,6 +363,19 @@ async function startWebUI(opts = {}) {
|
|
|
362
363
|
}
|
|
363
364
|
});
|
|
364
365
|
});
|
|
366
|
+
events.on("tool.confirm_needed", (e) => {
|
|
367
|
+
const id = e.toolUseId ?? `confirm_${Date.now()}`;
|
|
368
|
+
pendingConfirms.set(id, e.resolve);
|
|
369
|
+
broadcast({
|
|
370
|
+
type: "tool.confirm_needed",
|
|
371
|
+
payload: {
|
|
372
|
+
id,
|
|
373
|
+
toolName: e.tool?.name ?? "unknown",
|
|
374
|
+
input: e.input,
|
|
375
|
+
suggestedPattern: e.suggestedPattern
|
|
376
|
+
}
|
|
377
|
+
});
|
|
378
|
+
});
|
|
365
379
|
events.on("error", (e) => {
|
|
366
380
|
broadcast({
|
|
367
381
|
type: "error",
|
|
@@ -403,6 +417,12 @@ async function startWebUI(opts = {}) {
|
|
|
403
417
|
ws.on("close", () => {
|
|
404
418
|
clients.delete(ws);
|
|
405
419
|
console.log("[WebUI] Client disconnected, total:", clients.size);
|
|
420
|
+
if (pendingConfirms.size > 0) {
|
|
421
|
+
for (const [id, resolve] of pendingConfirms) {
|
|
422
|
+
resolve("no");
|
|
423
|
+
pendingConfirms.delete(id);
|
|
424
|
+
}
|
|
425
|
+
}
|
|
406
426
|
});
|
|
407
427
|
ws.on("error", (err) => {
|
|
408
428
|
console.warn("[WebUI] Client socket error:", err.message);
|
|
@@ -477,6 +497,15 @@ async function startWebUI(opts = {}) {
|
|
|
477
497
|
}
|
|
478
498
|
break;
|
|
479
499
|
}
|
|
500
|
+
case "tool.confirm_result": {
|
|
501
|
+
const { id, decision } = msg.payload;
|
|
502
|
+
const resolve = pendingConfirms.get(id);
|
|
503
|
+
if (resolve) {
|
|
504
|
+
pendingConfirms.delete(id);
|
|
505
|
+
resolve(decision);
|
|
506
|
+
}
|
|
507
|
+
break;
|
|
508
|
+
}
|
|
480
509
|
case "abort":
|
|
481
510
|
runLock?.abort();
|
|
482
511
|
broadcast({ type: "error", payload: { phase: "abort", message: "User aborted" } });
|
|
@@ -710,11 +739,14 @@ async function startWebUI(opts = {}) {
|
|
|
710
739
|
const newProv = providerRegistry.has(newProvider) ? providerRegistry.create({ ...providerCfg, type: newProvider }) : makeProviderFromConfig(newProvider, providerCfg);
|
|
711
740
|
context.provider = newProv;
|
|
712
741
|
try {
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
742
|
+
configWriteLock = configWriteLock.then(async () => {
|
|
743
|
+
const raw = await fs2.readFile(globalConfigPath, "utf8");
|
|
744
|
+
const parsed = JSON.parse(raw);
|
|
745
|
+
parsed.provider = newProvider;
|
|
746
|
+
parsed.model = newModel;
|
|
747
|
+
await atomicWrite(globalConfigPath, JSON.stringify(parsed, null, 2));
|
|
748
|
+
});
|
|
749
|
+
await configWriteLock;
|
|
718
750
|
} catch (err) {
|
|
719
751
|
console.warn("[WebUI] Failed to save config:", err);
|
|
720
752
|
}
|
|
@@ -761,11 +793,11 @@ async function startWebUI(opts = {}) {
|
|
|
761
793
|
await handleProviderRemove(ws, providerId);
|
|
762
794
|
break;
|
|
763
795
|
}
|
|
764
|
-
case "providers.
|
|
796
|
+
case "providers.list": {
|
|
765
797
|
try {
|
|
766
798
|
const providers = await loadSavedProviders();
|
|
767
799
|
send(ws, {
|
|
768
|
-
type: "providers.
|
|
800
|
+
type: "providers.list",
|
|
769
801
|
payload: {
|
|
770
802
|
providers: Object.entries(providers).map(([id, cfg]) => ({
|
|
771
803
|
id,
|
|
@@ -781,7 +813,7 @@ async function startWebUI(opts = {}) {
|
|
|
781
813
|
}
|
|
782
814
|
});
|
|
783
815
|
} catch {
|
|
784
|
-
send(ws, { type: "providers.
|
|
816
|
+
send(ws, { type: "providers.list", payload: { providers: [] } });
|
|
785
817
|
}
|
|
786
818
|
break;
|
|
787
819
|
}
|
|
@@ -1157,15 +1189,18 @@ async function startWebUI(opts = {}) {
|
|
|
1157
1189
|
}
|
|
1158
1190
|
}
|
|
1159
1191
|
async function saveProviders(providers) {
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1192
|
+
configWriteLock = configWriteLock.then(async () => {
|
|
1193
|
+
let parsed;
|
|
1194
|
+
try {
|
|
1195
|
+
const raw = await fs2.readFile(globalConfigPath, "utf8");
|
|
1196
|
+
parsed = JSON.parse(raw);
|
|
1197
|
+
} catch {
|
|
1198
|
+
parsed = {};
|
|
1199
|
+
}
|
|
1200
|
+
parsed["providers"] = providers;
|
|
1201
|
+
await atomicWrite(globalConfigPath, JSON.stringify(parsed, null, 2), { mode: 384 });
|
|
1202
|
+
});
|
|
1203
|
+
await configWriteLock;
|
|
1169
1204
|
}
|
|
1170
1205
|
function normalizeKeys(cfg) {
|
|
1171
1206
|
if (Array.isArray(cfg.apiKeys) && cfg.apiKeys.length > 0) {
|