Skip to content

v1.110.4

Choose a tag to compare

@MarkEhr MarkEhr released this 29 May 16:57
· 14 commits to master since this release

What's New

Added

  • `waitForIdle` option on `POST /api/agents/:id/collapse-context` — accepts `{"waitForIdle": true}` in the body. When the target agent is busy, the `/compact` is held in an in-process queue and dispatched the first time the agent transitions to `idle`. Solves the auto-collapse case: an agent invoking the endpoint against ITSELF from inside its own turn is by definition `working`, so the default behavior returned `409 busy`; with `waitForIdle: true` the response is `200 + {status: "queued"}` and the collapse fires automatically once the current turn finishes. Coalesced — N `waitForIdle` calls for the same agent drain into a single `/compact`. Per-agent isolation: each pending entry drains only when its own agent goes idle. Drain errors are logged and the entry is cleared (no infinite retry loop).
  • `runtimeService.collapseAgentContext(agentId, opts)` accepts `{waitForIdle?: boolean}` — REST route, WS handler, and the new factory share the same path. New `CollapseContextResult` variant: `{status: "queued"}`.

Changed

  • Collapse-context logic factored into a testable module (`services/collapse-context.ts`) — a factory `createCollapseContextService(deps)` owns the pending-collapse Set and the lazy `agentService.subscribe` listener. Runtime-service wires the real deps; tests use a fake event bus to exercise queue/drain/coalesce in isolation.
  • `Send Message to Agent` skill — new "Auto-collapse from inside your OWN turn (`waitForIdle`)" section with the exact curl example; status-code list now documents `200 + status:"queued"`.

Technical Details

  • 13 new vitest specs in `collapse-context.test.ts` cover sync paths (not-found / idle dispatch / busy / error), queue lifecycle (enqueue, drain on idle, no drain on other agents/statuses), coalescence (multiple waitForIdle → single drain), per-agent isolation, idle target + waitForIdle still fires immediately, not-found + waitForIdle doesn't contaminate the queue, and drain swallows sendCommand errors without leaking pending state.
  • Live smoke validation: `POST /api/agents/nonexistent/collapse-context` with `{"waitForIdle":true}` → HTTP 404 + `{status:"not-found"}` (no queue side effect).
  • Gates: lint clean, tsc clean, vitest 672/672 with `env -u TIDE_IDLE_RESPAWN_MS`.

Migration

No breaking changes. Existing `POST /api/agents/:id/collapse-context` callers continue to receive the same `409 busy` response when the target is mid-turn. Opt into the queue per-call by passing `{"waitForIdle": true}` in the body.