@wrongstack/webui 0.109.1 → 0.141.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.
@@ -164,8 +164,8 @@ import {
164
164
  collabPauseMiddleware,
165
165
  collabInjectMiddleware,
166
166
  estimateRequestTokensCalibrated,
167
- EventBus as EventBus2,
168
- HybridCompactor as HybridCompactor2,
167
+ EventBus,
168
+ createStrategyCompactor as createStrategyCompactor2,
169
169
  ProviderRegistry,
170
170
  TOKENS as TOKENS2,
171
171
  ToolRegistry,
@@ -197,7 +197,8 @@ import {
197
197
  DefaultSkillLoader,
198
198
  DefaultSystemPromptBuilder,
199
199
  DefaultTokenCounter,
200
- HybridCompactor,
200
+ createStrategyCompactor,
201
+ buildRecoveryStrategies,
201
202
  TOKENS
202
203
  } from "@wrongstack/core";
203
204
  function createDefaultContainer(opts) {
@@ -208,7 +209,15 @@ function createDefaultContainer(opts) {
208
209
  container.bind(TOKENS.Logger, () => logger);
209
210
  container.bind(TOKENS.SecretScrubber, () => new DefaultSecretScrubber());
210
211
  container.bind(TOKENS.RetryPolicy, () => new DefaultRetryPolicy());
211
- container.bind(TOKENS.ErrorHandler, () => new DefaultErrorHandler());
212
+ container.bind(
213
+ TOKENS.ErrorHandler,
214
+ () => new DefaultErrorHandler(
215
+ buildRecoveryStrategies({
216
+ compactor: container.resolve(TOKENS.Compactor),
217
+ modelsRegistry
218
+ })
219
+ )
220
+ );
212
221
  container.bind(TOKENS.ModelsRegistry, () => modelsRegistry);
213
222
  container.bind(
214
223
  TOKENS.TokenCounter,
@@ -252,10 +261,23 @@ function createDefaultContainer(opts) {
252
261
  );
253
262
  container.bind(
254
263
  TOKENS.Compactor,
255
- () => new HybridCompactor({
256
- preserveK: opts.compactor?.preserveK ?? 20,
257
- eliseThreshold: opts.compactor?.eliseThreshold ?? 0.7
258
- })
264
+ () => (
265
+ // Strategy comes from config.context.strategy: 'hybrid' (default, lossless
266
+ // rules, no LLM), 'intelligent' (LLM summarization), or 'selective'
267
+ // (LLM-driven selection). The LLM strategies resolve their provider from
268
+ // ctx at compact()-time, so binding here (before context.provider exists)
269
+ // is safe. preserveK / eliseThreshold are class-level fallbacks; the active
270
+ // ContextWindowPolicy in ctx.meta normally overrides both at runtime.
271
+ // eliseThreshold is a TOKEN COUNT — a previous value of 0.7 elided
272
+ // essentially every tool_result (anything > 1 token).
273
+ createStrategyCompactor({
274
+ strategy: config.context?.strategy,
275
+ preserveK: opts.compactor?.preserveK ?? 10,
276
+ eliseThreshold: opts.compactor?.eliseThreshold ?? 2e3,
277
+ summarizerModel: config.context?.summarizerModel,
278
+ llmSelector: config.context?.llmSelector
279
+ })
280
+ )
259
281
  );
260
282
  return container;
261
283
  }
@@ -1618,6 +1640,7 @@ function openBrowser(url, platform = process.platform) {
1618
1640
  try {
1619
1641
  import("@wrongstack/tools").then(({ getProcessRegistry }) => {
1620
1642
  getProcessRegistry().register({
1643
+ // biome-ignore lint/style/noNonNullAssertion: pid always present after spawn
1621
1644
  pid: child.pid,
1622
1645
  name: "browser",
1623
1646
  command: `${command} ${args.join(" ")}`,
@@ -2078,7 +2101,7 @@ async function startWebUI(opts = {}) {
2078
2101
  toolRegistry.register(relatedMemoryTool(memoryStore));
2079
2102
  }
2080
2103
  console.log("[WebUI] Tool registry loaded:", toolRegistry.list().length, "tools");
2081
- const events = new EventBus2();
2104
+ const events = new EventBus();
2082
2105
  events.setLogger(logger);
2083
2106
  const sessionStore = new DefaultSessionStore2({ dir: wpaths.projectSessions });
2084
2107
  sessionStore.prune(DEFAULT_SESSION_PRUNE_DAYS).then((count) => {
@@ -2187,9 +2210,12 @@ async function startWebUI(opts = {}) {
2187
2210
  const collabInject = collabInjectMiddleware(collabBus, { logger });
2188
2211
  Object.defineProperty(collabInject, "name", { value: "collab-inject" });
2189
2212
  pipelines.toolCall.prepend(collabInject);
2190
- const compactor = new HybridCompactor2({
2191
- preserveK: config.context?.preserveK ?? 20,
2192
- eliseThreshold: config.context?.eliseThreshold ?? 0.7
2213
+ const compactor = createStrategyCompactor2({
2214
+ strategy: config.context?.strategy,
2215
+ preserveK: config.context?.preserveK ?? 10,
2216
+ eliseThreshold: config.context?.eliseThreshold ?? 2e3,
2217
+ summarizerModel: config.context?.summarizerModel,
2218
+ llmSelector: config.context?.llmSelector
2193
2219
  });
2194
2220
  let autoCompactor;
2195
2221
  if (config.context?.autoCompact !== false) {
@@ -2205,7 +2231,12 @@ async function startWebUI(opts = {}) {
2205
2231
  autoCompactor = new AutoCompactionMiddleware(
2206
2232
  compactor,
2207
2233
  effectiveMaxContext,
2208
- (ctx) => estimateRequestTokensCalibrated(ctx.messages, ctx.systemPrompt, ctx.tools ?? []).total,
2234
+ (ctx) => estimateRequestTokensCalibrated(
2235
+ ctx.messages,
2236
+ ctx.systemPrompt,
2237
+ ctx.tools ?? [],
2238
+ `${ctx.provider?.id ?? "unknown"}/${ctx.model}`
2239
+ ).total,
2209
2240
  {
2210
2241
  warn: initialContextPolicy.thresholds.warn,
2211
2242
  soft: initialContextPolicy.thresholds.soft,