@wrongstack/webui 0.87.0 → 0.89.3

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.
@@ -1,4 +1,5 @@
1
1
  // src/server/index.ts
2
+ import { expectDefined as expectDefined2 } from "@wrongstack/core";
2
3
  import * as fs4 from "fs/promises";
3
4
  import * as path4 from "path";
4
5
 
@@ -163,7 +164,7 @@ import {
163
164
  collabPauseMiddleware,
164
165
  collabInjectMiddleware,
165
166
  estimateRequestTokensCalibrated,
166
- EventBus,
167
+ EventBus as EventBus2,
167
168
  HybridCompactor as HybridCompactor2,
168
169
  ProviderRegistry,
169
170
  TOKENS as TOKENS2,
@@ -171,6 +172,7 @@ import {
171
172
  atomicWrite as atomicWrite3,
172
173
  createDefaultPipelines,
173
174
  DEFAULT_CONTEXT_WINDOW_MODE_ID,
175
+ DEFAULT_SESSION_PRUNE_DAYS,
174
176
  DEFAULT_TOOLS_CONFIG,
175
177
  listContextWindowModes,
176
178
  repairToolUseAdjacency,
@@ -178,7 +180,7 @@ import {
178
180
  } from "@wrongstack/core";
179
181
  import { ToolExecutor } from "@wrongstack/core/execution";
180
182
  import { buildProviderFactoriesFromRegistry, makeProviderFromConfig } from "@wrongstack/providers";
181
- import { builtinToolsPack, forgetTool, rememberTool } from "@wrongstack/tools";
183
+ import { builtinToolsPack, forgetTool, rememberTool, searchMemoryTool, relatedMemoryTool } from "@wrongstack/tools";
182
184
  import { WebSocketServer } from "ws";
183
185
 
184
186
  // ../runtime/src/container.ts
@@ -223,7 +225,7 @@ function createDefaultContainer(opts) {
223
225
  secretScrubber: container.resolve(TOKENS.SecretScrubber)
224
226
  })
225
227
  );
226
- const memoryStore = new DefaultMemoryStore({ paths: wpaths });
228
+ const memoryStore = new DefaultMemoryStore({ paths: wpaths, events: opts.events });
227
229
  container.bind(TOKENS.MemoryStore, () => memoryStore);
228
230
  const skillLoader = new DefaultSkillLoader({ paths: wpaths, bundledDir: opts.bundledSkillsDir });
229
231
  container.bind(TOKENS.SkillLoader, () => skillLoader);
@@ -1692,12 +1694,7 @@ function createProviderConfigIO(configPath) {
1692
1694
  }
1693
1695
 
1694
1696
  // src/server/provider-keys.ts
1695
- function expectDefined(value) {
1696
- if (value === null || value === void 0) {
1697
- throw new Error("Expected value to be defined");
1698
- }
1699
- return value;
1700
- }
1697
+ import { expectDefined } from "@wrongstack/core";
1701
1698
  function normalizeKeys(cfg) {
1702
1699
  if (Array.isArray(cfg.apiKeys) && cfg.apiKeys.length > 0) {
1703
1700
  return cfg.apiKeys.map((k) => ({ ...k }));
@@ -1829,7 +1826,10 @@ function createProviderHandlers(deps) {
1829
1826
  return loadSavedProviders(globalConfigPath, vault);
1830
1827
  }
1831
1828
  async function saveConfigProviders(providers) {
1832
- const next = configWriteLock.then(() => saveProviders(globalConfigPath, vault, providers));
1829
+ const next = configWriteLock.then(() => saveProviders(globalConfigPath, vault, providers)).catch((err) => {
1830
+ const msg = err instanceof Error ? err.message : String(err);
1831
+ console.error(`[ProviderHandlers] saveProviders failed: ${msg}`);
1832
+ });
1833
1833
  configWriteLock = next;
1834
1834
  deps.setConfigWriteLock(next);
1835
1835
  await next;
@@ -2003,12 +2003,6 @@ function estimateContextBreakdown(input) {
2003
2003
  }
2004
2004
 
2005
2005
  // src/server/index.ts
2006
- function expectDefined2(value) {
2007
- if (value === null || value === void 0) {
2008
- throw new Error("Expected value to be defined");
2009
- }
2010
- return value;
2011
- }
2012
2006
  async function startWebUI(opts = {}) {
2013
2007
  const requestedWsPort = opts.wsPort ?? 3457;
2014
2008
  const wsHost = opts.wsHost ?? "127.0.0.1";
@@ -2061,12 +2055,14 @@ async function startWebUI(opts = {}) {
2061
2055
  if (config.features.memory) {
2062
2056
  toolRegistry.register(rememberTool(memoryStore));
2063
2057
  toolRegistry.register(forgetTool(memoryStore));
2058
+ toolRegistry.register(searchMemoryTool(memoryStore));
2059
+ toolRegistry.register(relatedMemoryTool(memoryStore));
2064
2060
  }
2065
2061
  console.log("[WebUI] Tool registry loaded:", toolRegistry.list().length, "tools");
2066
- const events = new EventBus();
2062
+ const events = new EventBus2();
2067
2063
  events.setLogger(logger);
2068
2064
  const sessionStore = new DefaultSessionStore2({ dir: wpaths.projectSessions });
2069
- sessionStore.prune(30).then((count) => {
2065
+ sessionStore.prune(DEFAULT_SESSION_PRUNE_DAYS).then((count) => {
2070
2066
  if (count > 0) logger.info(`Pruned ${count} old session${count === 1 ? "" : "s"}.`);
2071
2067
  }).catch(() => void 0);
2072
2068
  const sessionReader = new DefaultSessionReader({ store: sessionStore });
@@ -2360,7 +2356,10 @@ async function startWebUI(opts = {}) {
2360
2356
  if (typeof rawObj === "object" && rawObj !== null) {
2361
2357
  const obj = rawObj;
2362
2358
  if ("__proto__" in obj || "constructor" in obj || "prototype" in obj) {
2363
- send(ws, { type: "error", payload: { phase: "parse", message: "Invalid message object" } });
2359
+ send(ws, {
2360
+ type: "error",
2361
+ payload: { phase: "parse", message: "Invalid message object" }
2362
+ });
2364
2363
  } else {
2365
2364
  await handleMessage(ws, client, rawObj);
2366
2365
  }
@@ -2961,10 +2960,7 @@ async function startWebUI(opts = {}) {
2961
2960
  break;
2962
2961
  }
2963
2962
  const removed = expectDefined2(context.todos[targetIdx]);
2964
- const next = [
2965
- ...context.todos.slice(0, targetIdx),
2966
- ...context.todos.slice(targetIdx + 1)
2967
- ];
2963
+ const next = [...context.todos.slice(0, targetIdx), ...context.todos.slice(targetIdx + 1)];
2968
2964
  context.state.replaceTodos(next);
2969
2965
  sendResult(ws, true, `Removed: ${removed.content}`);
2970
2966
  broadcast(clients, { type: "todos.updated", payload: { todos: next } });
@@ -2978,12 +2974,26 @@ async function startWebUI(opts = {}) {
2978
2974
  const plan = await loadPlan(planPath);
2979
2975
  send(ws, {
2980
2976
  type: "plan.updated",
2981
- payload: { plan: plan ?? { version: 1, sessionId: session.id, updatedAt: (/* @__PURE__ */ new Date()).toISOString(), items: [] } }
2977
+ payload: {
2978
+ plan: plan ?? {
2979
+ version: 1,
2980
+ sessionId: session.id,
2981
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
2982
+ items: []
2983
+ }
2984
+ }
2982
2985
  });
2983
2986
  } catch {
2984
2987
  send(ws, {
2985
2988
  type: "plan.updated",
2986
- payload: { plan: { version: 1, sessionId: session.id, updatedAt: (/* @__PURE__ */ new Date()).toISOString(), items: [] } }
2989
+ payload: {
2990
+ plan: {
2991
+ version: 1,
2992
+ sessionId: session.id,
2993
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
2994
+ items: []
2995
+ }
2996
+ }
2987
2997
  });
2988
2998
  }
2989
2999
  } else {
@@ -3143,9 +3153,14 @@ async function startWebUI(opts = {}) {
3143
3153
  }
3144
3154
  default:
3145
3155
  if (msg.type.startsWith("autophase.")) {
3146
- await autoPhaseHandler.handleMessage(msg);
3156
+ await autoPhaseHandler.handleMessage(
3157
+ msg
3158
+ );
3147
3159
  } else {
3148
- send(ws, { type: "error", payload: { phase: "handleMessage", message: `Unknown message type: ${msg.type}` } });
3160
+ send(ws, {
3161
+ type: "error",
3162
+ payload: { phase: "handleMessage", message: `Unknown message type: ${msg.type}` }
3163
+ });
3149
3164
  }
3150
3165
  }
3151
3166
  }