diff --git a/docs/cordis-catalog/services.md b/docs/cordis-catalog/services.md index c91f1578b2..6e09a5e3ab 100644 --- a/docs/cordis-catalog/services.md +++ b/docs/cordis-catalog/services.md @@ -79,8 +79,8 @@ Implementations MUST honor: - **Blocking**: no compaction begins while another is in progress for the same session. The recommended mechanism is the log-recorded lock — append `compact/start` before the slow work and `compact/end` after (even on failure) — so the lock is visible to replay and crash recovery. ```ts cordis-catalog -abstract compactIfNeeded( agent: CompactAgentContext, turn: number, step: number, fullSystemPrompt: string, signal: AbortSignal, ): Promise -abstract compactRegion( session: Session, start: number, end: number, agent: CompactAgentContext, turn: number, step: number, signal?: AbortSignal, ): Promise +abstract compactIfNeeded( agent: CompactAgentContext, fullSystemPrompt: string, signal: AbortSignal, ): Promise +abstract compactRegion( session: Session, start: number, end: number, agent: CompactAgentContext, signal?: AbortSignal, ): Promise ``` Source: [`packages/compact/compact/src/index.ts:63`](../../packages/compact/compact/src/index.ts) diff --git a/docs/core-data-structures/compaction.md b/docs/core-data-structures/compaction.md index 05d1ce6c2e..5023d14e93 100644 --- a/docs/core-data-structures/compaction.md +++ b/docs/core-data-structures/compaction.md @@ -50,6 +50,6 @@ interface CompactionResult { ## The service -`CompactService` (`ctx.compact`, abstract — defined in [`packages/compact/compact/src/index.ts`](../../packages/compact/compact/src/index.ts)) declares two abstract methods: `compactIfNeeded(agent, turn, step, fullSystemPrompt, signal)` checks token pressure and compacts an older range if the history is too large (returning `null` when nothing needs it), and `compactRegion(session, start, end, agent, turn, step, signal?)` forcibly summarizes surface nodes `[start, end]` into a single replacement node. `compactIfNeeded`'s parameters are all required — the loop's `agent/pre-step` checkpoint supplies the agent, lifecycle context, assembled `fullSystemPrompt`, and turn `signal`. A backend summarizing via `ctx.llm.stream()` must forward `signal` into the call's `GenerateOptions.signal`, so an abort or dispose tears down the in-flight summarization. The entire strategy — token estimation, retention policy, event sequencing, summarization — is a HOW decision owned by the implementation. +`CompactService` (`ctx.compact`, abstract — defined in [`packages/compact/compact/src/index.ts`](../../packages/compact/compact/src/index.ts)) declares two abstract methods: `compactIfNeeded(agent, fullSystemPrompt, signal)` checks token pressure and compacts an older range if the history is too large (returning `null` when nothing needs it), and `compactRegion(session, start, end, agent, signal?)` forcibly summarizes surface nodes `[start, end]` into a single replacement node. `compactIfNeeded`'s parameters are all required — the loop's `agent/pre-step` checkpoint supplies the agent, the assembled `fullSystemPrompt`, and the turn `signal`. A backend summarizing via `ctx.llm.stream()` must forward `signal` into the call's `GenerateOptions.signal`, so an abort or dispose tears down the in-flight summarization. The entire strategy — token estimation, retention policy, event sequencing, summarization — is a HOW decision owned by the implementation. Auto-compaction runs on the serial `agent/pre-step` loop seam (fired once per step, after `turn/start` and BEFORE the step opens and its request history is derived), not the `agent/request` waterfall: compaction mutates the session surface in place — with its log-only `compact/*` records landing cleanly outside any step — and the loop derives the request from the already-compacted surface. Retention is turn-agnostic — the only structural guard is tool-pairing balance (a compacted region's edges are balanced cuts on the surface, so it never splits a step's tool-calls from their results), so a single runaway turn that alone exceeds the window compacts its own early closed steps rather than being retained verbatim. The backend that ships this (`dsh-compact-basic`) documents the retention walk, summary shrink validation, bounded re-compaction, and the crash/recoverable failure taxonomy. diff --git a/docs/event-producer-consumer.md b/docs/event-producer-consumer.md index 18c2b9faf0..25b8b8b66a 100644 --- a/docs/event-producer-consumer.md +++ b/docs/event-producer-consumer.md @@ -13,7 +13,7 @@ This matrix shows which packages dispatch each harness-owned event and which pac | `agent/pre-step` | `serial` | [`packages/core/agent/src/types.ts:333`](../packages/core/agent/src/types.ts) | [`agent-loop`](../packages/core/agent-loop) (`serial`) | [`compact-basic`](../packages/compact/compact-basic) | | `agent/prompt-submit` | `waterfall` | [`packages/core/agent/src/types.ts:346`](../packages/core/agent/src/types.ts) | [`agent-loop`](../packages/core/agent-loop) (`waterfall`) | [`hooks-claude`](../packages/hooks/hooks-claude), [`hooks-codex`](../packages/hooks/hooks-codex) | | `agent/queued` | `emit` | [`packages/core/agent/src/types.ts:273`](../packages/core/agent/src/types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emit`) | - | -| `agent/request` | `waterfall` | [`packages/core/agent/src/types.ts:359`](../packages/core/agent/src/types.ts) | [`agent-loop`](../packages/core/agent-loop) (`waterfall`), [`compact-basic`](../packages/compact/compact-basic) (`waterfall`) | - | +| `agent/request` | `waterfall` | [`packages/core/agent/src/types.ts:359`](../packages/core/agent/src/types.ts) | [`agent-loop`](../packages/core/agent-loop) (`waterfall`) | - | | `agent/session-start` | `emit` | [`packages/core/agent/src/types.ts:288`](../packages/core/agent/src/types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emit`) | [`hooks-claude`](../packages/hooks/hooks-claude), [`hooks-codex`](../packages/hooks/hooks-codex) | | `agent/status` | `emit` | [`packages/core/agent/src/types.ts:264`](../packages/core/agent/src/types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emit`) | [`acp`](../packages/ui/acp), [`invariants`](../packages/support/invariants), [`stdio-agent`](../packages/ui/stdio-agent) | | `agent/step-result` | `waterfall` | [`packages/core/agent/src/types.ts:369`](../packages/core/agent/src/types.ts) | [`agent-loop`](../packages/core/agent-loop) (`waterfall`) | - | diff --git a/packages/compact/compact-basic/README.md b/packages/compact/compact-basic/README.md index 81163973fc..65baeb4451 100644 --- a/packages/compact/compact-basic/README.md +++ b/packages/compact/compact-basic/README.md @@ -11,7 +11,7 @@ The abstract contract states only WHAT compaction does; this backend owns every - **Token estimation** — `estimateContentTokens()`: chars divided by the `charsPerToken` config (default 4) with per-block structural overhead (`text`/`reasoning` = `ceil(len/charsPerToken) + 4`, `tool-call` from name + arguments, `tool-result` recursive, unknown blocks via JSON length). - **Retention policy** — `compactIfNeeded()` walks the surface nodes tail→head summing per-node token estimates, and retains the smallest tail-run of WHOLE units (a closed step, or a single no-step node such as a pre-step `user/message` or inter-step `steering/message`) whose total reaches `retainTokens`; everything older is compacted. Retention is **turn-agnostic** — turn boundaries play no role, so a single runaway turn that alone exceeds the window compacts its OWN early closed steps rather than being retained verbatim (the failure mode that motivated dropping turn-protection: a tool-heavy turn must stay compactable or the harness dies exactly when compaction is needed). The only structural guard is **tool-pairing balance**: the compacted region's edges are balanced cuts on the surface (no unanswered tool-call crosses either edge), so it never splits a step's `assistant/message` tool-calls from their `tool/result`s. When the only compactable content left is an un-splittable open tail step, it declines (returns `null`) and retries once an older step closes. **Single-unit overflow is out of scope, by design**: if one retained unit (a single closed step, or a large pasted `user/message`) ALONE exceeds the budget, compaction cannot help and the call may go out over-budget — bounding an individual unit's size is a separate concern. `compactRegion()` enforces tool-pairing balance strictly, throwing on a boundary that would split a step. `dsh-session` exports `isToolPairingBalanced` for the check. - **Dynamic convergence** — no static summary-length config pretends to bound what the model will write. If framing/estimator/system overhead leaves the compacted surface above threshold, `compactIfNeeded()` re-compacts the head checkpoint up to `compactionRetries` extra times; if it still cannot get below threshold, it throws. A summary whose estimated stored size is not smaller than the shadowed content fails closed before it mutates the surface. -- **Summarization** — `summarize()`: a `GenerateOptions` request assembled via `BlockAssembler` with a fixed system prompt that asks for a structured checkpoint (Primary Request and Intent · Key Technical Concepts · Files and Code · Errors and Fixes · Pending Tasks · Current Work · Next Step · Critical Context), every section mandatory, exact paths/commands/identifiers preserved. The request runs through the `agent/request` waterfall before `ctx.llm.stream()`, so router agents that choose the concrete model there also route compaction summaries. `maxTokens` is the provider-side generation cap; only text blocks from the model's reply are kept before the checkpoint is stored (reasoning is dropped so private chain-of-thought never leaks into the durable summary, and a stray `tool-call` is dropped so the synthesized `user/message` summary cannot land an orphaned call with no matching `tool-result`). The compacted region is flattened to a plain-text transcript first: text and reasoning contribute their text, and every non-text block (tool-call, tool-result, plugin-added types) contributes a type-tagged placeholder (`[tool-call: name(args)]`, `[tool-result: …]`, …) so the summarizer is told what existed rather than silently dropping it. +- **Summarization** — `summarize()`: a `GenerateOptions` request assembled via `BlockAssembler` with a fixed system prompt that asks for a structured checkpoint (Primary Request and Intent · Key Technical Concepts · Files and Code · Errors and Fixes · Pending Tasks · Current Work · Next Step · Critical Context), every section mandatory, exact paths/commands/identifiers preserved. The request is a direct one-shot `ctx.llm.stream()` call — NOT a loop step, so it does not run `agent/request` (that seam shapes the loop's conversation requests); the model comes from `summarizationModel` falling back to the agent's own, and per-call routing happens at `llm/stream` like any other direct call. `maxTokens` is the provider-side generation cap; only text blocks from the model's reply are kept before the checkpoint is stored (reasoning is dropped so private chain-of-thought never leaks into the durable summary, and a stray `tool-call` is dropped so the synthesized `user/message` summary cannot land an orphaned call with no matching `tool-result`). The compacted region is flattened to a plain-text transcript first: text and reasoning contribute their text, and every non-text block (tool-call, tool-result, plugin-added types) contributes a type-tagged placeholder (`[tool-call: name(args)]`, `[tool-result: …]`, …) so the summarizer is told what existed rather than silently dropping it. - **Checkpoint framing** — the raw summary is not landed directly. `compactRegion()` wraps it in a checkpoint preamble (so a resuming model reads it as a checkpoint, not a fresh user request, and builds on the captured context rather than restating it) plus `` tags. Because region compaction can be invoked manually, a surface may hold several checkpoints, so the framing does not claim everything after it is recent or verbatim. The tags make a prior checkpoint detectable in the transcript on the next compaction cycle: the summarization prompt then instructs the model to merge it in place (preserve still-true facts, drop stale ones) rather than re-summarize it verbatim — a cheap incremental merge that needs no extra log/event machinery. The unframed summary stays on the `compact/summary` provenance event. - **Surface mutation** — `compactRegion()` appends the `compact/start` → `compact/summary` → `compact/end` log records and the single `user/message` replace node carrying the framed summary (see the interface README). - **Auto-compaction** — an `agent/pre-step` listener delegates to `compactIfNeeded()` before every step (not just a turn's first — a tool-heavy turn grows the surface mid-turn, so a runaway turn still compacts, and per-step firing is the only moment to rescue it before overflow). `agent/pre-step` is a serial (awaited, in-order) surface-mutation checkpoint that fires after `turn/start` and BEFORE the step opens (`step/start`) and its request history is derived, so compaction mutates the surface — with its log-only `compact/*` records landing cleanly outside any step — and the loop derives once from the result: no double-derive, and the listener cannot see (or need to rewrite) an already-assembled `messages` array. The listener owns no threshold logic of its own (the single token-pressure check lives in `compactIfNeeded()`); because Cordis `serial` bails early on non-void return values, the listener returns `void` and does not use the dispatcher's bail channel as a veto surface. diff --git a/packages/compact/compact-basic/src/index.ts b/packages/compact/compact-basic/src/index.ts index 2bc7b65a80..d4a993471e 100644 --- a/packages/compact/compact-basic/src/index.ts +++ b/packages/compact/compact-basic/src/index.ts @@ -182,9 +182,9 @@ export class BasicCompactService extends CompactService { // log-only `compact/*` records and the replacement node cleanly outside a // step, so a crash mid-compaction leaves an inert orphan the turn-repair // closes — never a half-open step. - ctx.on('agent/pre-step', async (agent: Agent, turn: number, step: number, fullSystemPrompt: string, signal: AbortSignal) => { + ctx.on('agent/pre-step', async (agent: Agent, _turn: number, _step: number, fullSystemPrompt: string, signal: AbortSignal) => { try { - const result = await this.compactIfNeeded(agent, turn, step, fullSystemPrompt, signal) + const result = await this.compactIfNeeded(agent, fullSystemPrompt, signal) if (result) { const after = this.estimateTokens(agent.session.deriveMessages(), fullSystemPrompt) ctx.logger.info( @@ -271,9 +271,13 @@ export class BasicCompactService extends CompactService { } /** - * Summarize conversation text into content blocks via `agent/request` plus - * `ctx.llm.stream()` assembled through a `BlockAssembler` (the single - * model-call surface). + * Summarize conversation text into content blocks via `ctx.llm.stream()` + * assembled through a `BlockAssembler`. A direct one-shot model call, NOT a + * loop step: it does not run the `agent/request` waterfall (that seam shapes + * the loop's conversation requests); per-call + * interception happens at `llm/stream` like any other direct call. The model + * comes from `BasicCompactConfig.summarizationModel`, falling back to the + * agent's own model. * Override in a subclass for a template or remote summarizer. * * Honors the adapter failure contract: an adapter may report a model failure @@ -284,7 +288,7 @@ export class BasicCompactService extends CompactService { * Forwards `signal` into `GenerateOptions.signal` so an abort/dispose tears * down the in-flight summarization rather than orphaning the model call. */ - async summarize(text: string, agent: Agent, turn: number, step: number, signal?: AbortSignal): Promise { + async summarize(text: string, agent: Agent, signal?: AbortSignal): Promise { const assembler = new BlockAssembler() const options: GenerateOptions = { model: this.config.summarizationModel || agent.options.model || '', @@ -299,11 +303,10 @@ export class BasicCompactService extends CompactService { // exactOptionalPropertyTypes: only set `signal` when present — assigning // `undefined` to an optional `signal?: AbortSignal` is a type error. if (signal) options.signal = signal - const request = await this.ctx.waterfall('agent/request', agent, turn, step, options, () => Promise.resolve(options)) - if (!request.model) { - throw new Error('no model available for summarization: set BasicCompactConfig.summarizationModel, AgentOptions.model, or supply one via the agent/request waterfall') + if (!options.model) { + throw new Error('no model available for summarization: set BasicCompactConfig.summarizationModel or AgentOptions.model') } - for await (const chunk of this.ctx.llm.stream(request)) { + for await (const chunk of this.ctx.llm.stream(options)) { assembler.push(chunk) } @@ -348,8 +351,6 @@ export class BasicCompactService extends CompactService { */ override async compactIfNeeded( agent: Agent, - turn: number, - step: number, fullSystemPrompt: string, signal: AbortSignal, ): Promise { @@ -368,7 +369,7 @@ export class BasicCompactService extends CompactService { break } - result = await this.compactRegion(session, range.start, range.end, agent, turn, step, signal) + result = await this.compactRegion(session, range.start, range.end, agent, signal) } const totalTokens = this.estimateTokens(session.deriveMessages(), fullSystemPrompt) @@ -385,8 +386,6 @@ export class BasicCompactService extends CompactService { start: number, end: number, agent: Agent, - turn: number, - step: number, signal?: AbortSignal, ): Promise { // Resolve the range by surface POSITION, not numeric seq interval. A prior @@ -450,7 +449,7 @@ export class BasicCompactService extends CompactService { try { // --- Extract text and summarize --- const text = this._extractText(session, shadowedSeqs) - const summary = await this.summarize(text, agent, turn, step, signal) + const summary = await this.summarize(text, agent, signal) // Estimate token count of the shadowed content for provenance. let shadowedTokenCount = 0 diff --git a/packages/compact/compact-basic/tests/compact-basic.spec.ts b/packages/compact/compact-basic/tests/compact-basic.spec.ts index 80c35d4b06..d00b093493 100644 --- a/packages/compact/compact-basic/tests/compact-basic.spec.ts +++ b/packages/compact/compact-basic/tests/compact-basic.spec.ts @@ -980,7 +980,7 @@ function compactIfNeeded( model: string, signal: AbortSignal, ) { - return svc.compactIfNeeded(stubAgent(session, model), 1, 1, fullSystemPrompt, signal) + return svc.compactIfNeeded(stubAgent(session, model), fullSystemPrompt, signal) } function compactRegion( @@ -991,11 +991,11 @@ function compactRegion( model: string, signal?: AbortSignal, ) { - return svc.compactRegion(session, start, end, stubAgent(session, model), 1, 1, signal) + return svc.compactRegion(session, start, end, stubAgent(session, model), signal) } function summarize(svc: BasicCompactService, text: string, model: string) { - return svc.summarize(text, stubAgent(new Session(SessionId('summary')), model), 1, 1) + return svc.summarize(text, stubAgent(new Session(SessionId('summary')), model)) } describe('BasicCompactService.summarize (real ctx.llm.stream)', () => { @@ -1231,15 +1231,20 @@ describe('BasicCompactService auto-compaction (agent/pre-step listener)', () => expect(session.events.some(e => e.type === 'compact/start')).toBe(false) }) - it('routes summarization through agent/request so router agents can choose the model', async () => { + it('summarization is interceptable at llm/stream (model routing for direct calls)', async () => { const { ctx, adapter } = await ctxWithModel('ROUTED SUMMARY', 'routed-model') - ctx.on('agent/request', async (_agent, _turn, _step, options, next) => { + // The summarize call is a direct one-shot model call, not a loop step: it + // does not run agent/request (that seam shapes the loop's conversation + // requests). llm/stream is its interception surface, and a hand-built + // request is not frozen, so mutate-then-next model routing works — the + // adapter resolves AFTER the waterfall, so the rewrite picks the adapter. + ctx.on('llm/stream', (options, next) => { options.model = 'routed-model' return next() }) void new BasicCompactService(ctx, cfg({ contextWindow: 200, thresholdRatio: 0.5, retainTokens: 20 })) const session = multiTurnSession(5, 1) - const agent = stubAgent(session) + const agent = stubAgent(session, 'agent-model') await ctx.serial('agent/pre-step', agent, 1, 1, '', SIGNAL) diff --git a/packages/compact/compact/README.md b/packages/compact/compact/README.md index b49070c3b5..51184337dd 100644 --- a/packages/compact/compact/README.md +++ b/packages/compact/compact/README.md @@ -18,8 +18,8 @@ Both methods are **abstract** — the backend owns the entire strategy (token es | Member | Semantics | |---|---| -| `compactIfNeeded(agent, turn, step, fullSystemPrompt, signal)` | Estimate the surface-derived history size; if over the backend's threshold, compact an older range via `compactRegion`, keeping recent context intact. Returns the `CompactionResult`, or `null` if nothing needed compacting. All parameters required — the loop's `agent/pre-step` checkpoint supplies the agent, lifecycle context, assembled `fullSystemPrompt`, and turn `signal`; router-aware summarizers can use the agent lifecycle context to route their own model call through `agent/request`. | -| `compactRegion(session, start, end, agent, turn, step, signal?)` | Forcibly summarize surface nodes `[start, end]` (inclusive seqs) into a single replacement node. **Throws** if a compaction is already in progress, if `start`/`end` aren't surface nodes, or if `start` is positioned after `end` on the surface. The range is a SURFACE-POSITION span, not a numeric seq interval — after a prior replace lands a fresh high-seq summary node at the shadowed range's position, surface order no longer tracks seq order. | +| `compactIfNeeded(agent, fullSystemPrompt, signal)` | Estimate the surface-derived history size; if over the backend's threshold, compact an older range via `compactRegion`, keeping recent context intact. Returns the `CompactionResult`, or `null` if nothing needed compacting. All parameters required — the loop's `agent/pre-step` checkpoint supplies the agent, assembled `fullSystemPrompt`, and turn `signal`. A backend's summarization request is a direct `ctx.llm.stream()` call (not a loop step), so per-call interception happens at `llm/stream`. | +| `compactRegion(session, start, end, agent, signal?)` | Forcibly summarize surface nodes `[start, end]` (inclusive seqs) into a single replacement node. **Throws** if a compaction is already in progress, if `start`/`end` aren't surface nodes, or if `start` is positioned after `end` on the surface. The range is a SURFACE-POSITION span, not a numeric seq interval — after a prior replace lands a fresh high-seq summary node at the shadowed range's position, surface order no longer tracks seq order. | `compactIfNeeded` takes a required `signal`; `compactRegion`'s is optional. A backend that summarizes via `ctx.llm.stream()` **must** forward it into the call's `GenerateOptions.signal`, so an abort or fiber dispose tears down the in-flight summarization instead of leaving an orphaned model call running past the cancellation. The session being compacted comes from the agent context; the turn that the `compact/*` events belong to is recoverable from the log (the currently-open turn), so the backend stamps it from the log rather than trusting a caller-supplied value. diff --git a/packages/compact/compact/src/index.ts b/packages/compact/compact/src/index.ts index 37c94920f3..cc190ccd87 100644 --- a/packages/compact/compact/src/index.ts +++ b/packages/compact/compact/src/index.ts @@ -91,8 +91,6 @@ export abstract class CompactService extends Service { * over-budget. Bounding an individual unit's size is a separate concern. * * @param agent - agent context owning the session surface and model options. - * @param turn - turn number of the pre-step checkpoint. - * @param step - step number about to start. * @param fullSystemPrompt - assembled system prompt, counted toward the estimate. * @param signal - cancellation signal. A backend summarizing via * `ctx.llm.stream()` MUST forward this into the call's `GenerateOptions.signal` @@ -102,8 +100,6 @@ export abstract class CompactService extends Service { */ abstract compactIfNeeded( agent: CompactAgentContext, - turn: number, - step: number, fullSystemPrompt: string, signal: AbortSignal, ): Promise @@ -129,8 +125,6 @@ export abstract class CompactService extends Service { * @param start - inclusive seq of the first surface node to compact. * @param end - inclusive seq of the last surface node to compact. * @param agent - agent context used by router-aware summarizers. - * @param turn - lifecycle turn forwarded to request-routing seams. - * @param step - lifecycle step forwarded to request-routing seams. * @param signal - optional cancellation signal. A backend that summarizes via * `ctx.llm.stream()` MUST forward this into the call's `GenerateOptions.signal` * so an abort/dispose tears down the in-flight summarization rather than @@ -148,8 +142,6 @@ export abstract class CompactService extends Service { start: number, end: number, agent: CompactAgentContext, - turn: number, - step: number, signal?: AbortSignal, ): Promise } diff --git a/packages/compact/compact/tests/compact.spec.ts b/packages/compact/compact/tests/compact.spec.ts index 5b9e033fcc..8729ad7ab8 100644 --- a/packages/compact/compact/tests/compact.spec.ts +++ b/packages/compact/compact/tests/compact.spec.ts @@ -17,8 +17,6 @@ class StubCompactService extends CompactService { override async compactIfNeeded( _agent: CompactAgentContext, - _turn: number, - _step: number, _fullSystemPrompt: string, signal: AbortSignal, ): Promise { @@ -31,8 +29,6 @@ class StubCompactService extends CompactService { start: number, end: number, _agent: CompactAgentContext, - _turn: number, - _step: number, signal?: AbortSignal, ): Promise { this.lastSignal = signal @@ -81,7 +77,7 @@ describe('CompactService seam', () => { const ctx = new Context() const svc = new StubCompactService(ctx) const session = new Session(SessionId('s')) - expect(await svc.compactIfNeeded(stubAgent(session), 1, 1, '', new AbortController().signal)).toBeNull() + expect(await svc.compactIfNeeded(stubAgent(session), '', new AbortController().signal)).toBeNull() }) it('compact/* events merge into SessionEventMap and are log-only', async () => { @@ -89,7 +85,7 @@ describe('CompactService seam', () => { const svc = new StubCompactService(ctx) const session = new Session(SessionId('s')) - const result = await svc.compactRegion(session, 0, 0, stubAgent(session, 'm'), 1, 1) + const result = await svc.compactRegion(session, 0, 0, stubAgent(session, 'm')) const startEvent = session.events.find(e => e.type === 'compact/start') expect(startEvent).toBeDefined() @@ -107,10 +103,10 @@ describe('CompactService seam', () => { const session = new Session(SessionId('s')) const controller = new AbortController() - await svc.compactRegion(session, 0, 0, stubAgent(session, 'm'), 1, 1, controller.signal) + await svc.compactRegion(session, 0, 0, stubAgent(session, 'm'), controller.signal) expect(svc.lastSignal).toBe(controller.signal) - await svc.compactIfNeeded(stubAgent(session), 1, 1, '', controller.signal) + await svc.compactIfNeeded(stubAgent(session), '', controller.signal) expect(svc.lastSignal).toBe(controller.signal) }) })