@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.
@@ -165,8 +165,8 @@ import {
165
165
  collabPauseMiddleware,
166
166
  collabInjectMiddleware,
167
167
  estimateRequestTokensCalibrated,
168
- EventBus as EventBus2,
169
- HybridCompactor as HybridCompactor2,
168
+ EventBus,
169
+ createStrategyCompactor as createStrategyCompactor2,
170
170
  ProviderRegistry,
171
171
  TOKENS as TOKENS2,
172
172
  ToolRegistry,
@@ -198,7 +198,8 @@ import {
198
198
  DefaultSkillLoader,
199
199
  DefaultSystemPromptBuilder,
200
200
  DefaultTokenCounter,
201
- HybridCompactor,
201
+ createStrategyCompactor,
202
+ buildRecoveryStrategies,
202
203
  TOKENS
203
204
  } from "@wrongstack/core";
204
205
  function createDefaultContainer(opts) {
@@ -209,7 +210,15 @@ function createDefaultContainer(opts) {
209
210
  container.bind(TOKENS.Logger, () => logger);
210
211
  container.bind(TOKENS.SecretScrubber, () => new DefaultSecretScrubber());
211
212
  container.bind(TOKENS.RetryPolicy, () => new DefaultRetryPolicy());
212
- container.bind(TOKENS.ErrorHandler, () => new DefaultErrorHandler());
213
+ container.bind(
214
+ TOKENS.ErrorHandler,
215
+ () => new DefaultErrorHandler(
216
+ buildRecoveryStrategies({
217
+ compactor: container.resolve(TOKENS.Compactor),
218
+ modelsRegistry
219
+ })
220
+ )
221
+ );
213
222
  container.bind(TOKENS.ModelsRegistry, () => modelsRegistry);
214
223
  container.bind(
215
224
  TOKENS.TokenCounter,
@@ -253,10 +262,23 @@ function createDefaultContainer(opts) {
253
262
  );
254
263
  container.bind(
255
264
  TOKENS.Compactor,
256
- () => new HybridCompactor({
257
- preserveK: opts.compactor?.preserveK ?? 20,
258
- eliseThreshold: opts.compactor?.eliseThreshold ?? 0.7
259
- })
265
+ () => (
266
+ // Strategy comes from config.context.strategy: 'hybrid' (default, lossless
267
+ // rules, no LLM), 'intelligent' (LLM summarization), or 'selective'
268
+ // (LLM-driven selection). The LLM strategies resolve their provider from
269
+ // ctx at compact()-time, so binding here (before context.provider exists)
270
+ // is safe. preserveK / eliseThreshold are class-level fallbacks; the active
271
+ // ContextWindowPolicy in ctx.meta normally overrides both at runtime.
272
+ // eliseThreshold is a TOKEN COUNT — a previous value of 0.7 elided
273
+ // essentially every tool_result (anything > 1 token).
274
+ createStrategyCompactor({
275
+ strategy: config.context?.strategy,
276
+ preserveK: opts.compactor?.preserveK ?? 10,
277
+ eliseThreshold: opts.compactor?.eliseThreshold ?? 2e3,
278
+ summarizerModel: config.context?.summarizerModel,
279
+ llmSelector: config.context?.llmSelector
280
+ })
281
+ )
260
282
  );
261
283
  return container;
262
284
  }
@@ -1619,6 +1641,7 @@ function openBrowser(url, platform = process.platform) {
1619
1641
  try {
1620
1642
  import("@wrongstack/tools").then(({ getProcessRegistry }) => {
1621
1643
  getProcessRegistry().register({
1644
+ // biome-ignore lint/style/noNonNullAssertion: pid always present after spawn
1622
1645
  pid: child.pid,
1623
1646
  name: "browser",
1624
1647
  command: `${command} ${args.join(" ")}`,
@@ -2071,7 +2094,7 @@ async function startWebUI(opts = {}) {
2071
2094
  toolRegistry.register(relatedMemoryTool(memoryStore));
2072
2095
  }
2073
2096
  console.log("[WebUI] Tool registry loaded:", toolRegistry.list().length, "tools");
2074
- const events = new EventBus2();
2097
+ const events = new EventBus();
2075
2098
  events.setLogger(logger);
2076
2099
  const sessionStore = new DefaultSessionStore2({ dir: wpaths.projectSessions });
2077
2100
  sessionStore.prune(DEFAULT_SESSION_PRUNE_DAYS).then((count) => {
@@ -2180,9 +2203,12 @@ async function startWebUI(opts = {}) {
2180
2203
  const collabInject = collabInjectMiddleware(collabBus, { logger });
2181
2204
  Object.defineProperty(collabInject, "name", { value: "collab-inject" });
2182
2205
  pipelines.toolCall.prepend(collabInject);
2183
- const compactor = new HybridCompactor2({
2184
- preserveK: config.context?.preserveK ?? 20,
2185
- eliseThreshold: config.context?.eliseThreshold ?? 0.7
2206
+ const compactor = createStrategyCompactor2({
2207
+ strategy: config.context?.strategy,
2208
+ preserveK: config.context?.preserveK ?? 10,
2209
+ eliseThreshold: config.context?.eliseThreshold ?? 2e3,
2210
+ summarizerModel: config.context?.summarizerModel,
2211
+ llmSelector: config.context?.llmSelector
2186
2212
  });
2187
2213
  let autoCompactor;
2188
2214
  if (config.context?.autoCompact !== false) {
@@ -2198,7 +2224,12 @@ async function startWebUI(opts = {}) {
2198
2224
  autoCompactor = new AutoCompactionMiddleware(
2199
2225
  compactor,
2200
2226
  effectiveMaxContext,
2201
- (ctx) => estimateRequestTokensCalibrated(ctx.messages, ctx.systemPrompt, ctx.tools ?? []).total,
2227
+ (ctx) => estimateRequestTokensCalibrated(
2228
+ ctx.messages,
2229
+ ctx.systemPrompt,
2230
+ ctx.tools ?? [],
2231
+ `${ctx.provider?.id ?? "unknown"}/${ctx.model}`
2232
+ ).total,
2202
2233
  {
2203
2234
  warn: initialContextPolicy.thresholds.warn,
2204
2235
  soft: initialContextPolicy.thresholds.soft,