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