Skip to content

Reliability fixes and server decomposition, merged with main - #1582

Draft
bradhallett wants to merge 113 commits into
milind-soni:mainfrom
bradhallett:droppy-code/2f814b1d
Draft

bradhallett wants to merge 113 commits into
milind-soni:mainfrom
bradhallett:droppy-code/2f814b1d

Conversation

@bradhallett

Copy link
Copy Markdown
Contributor

What this PR does

This branch is a large reliability + maintainability batch on top of current main, delivered as one merge commit. It has two halves.

1. Reliability fixes

2. Decomposition (no behavior change)

server/index.ts (17k+ lines) is decomposed into route modules, wiring modules, start-turn, store/, runtime, and the internal-routes family; store.tsx into model/reducer/overlays/stream-context; ComputerPanel, Sidebar, ChatView, GroupView, composer, RoutineCalendarPage and CursorAvatar into component module families; claude/codex/acp drivers into focused modules; Electron main.mjs into subsystem modules; MCP and agents-proxy tool switches into registries; shared attachment wire and server-endpoint resolvers deduplicated. Every step was verbatim-move + facade, with importer tests kept unchanged.

Merge with current main

The branch merges main (ec62fcf2) and completes the merge by porting the main-side features that the decomposition had orphaned:

  • Incidents wiring: new server/incident-report.ts host, wired in engine-wiring.ts, with the four reportIncident call sites from main (could-not-start in start-turn/phases/dispatch.ts, failed in event-fold/turn-completion.ts, stalled in event-fold.ts, routine-failed in routine-wiring.ts).
  • Teammate resolution: resolveTeammate name-or-id handling restored at the three internal routes (ask-bot, delegations, coordination) with self-check and dedup.
  • Instance icons: PATCH /api/instances/:id/icon restored on top of the shared provider-icon helpers.
  • Message attribution: messageSender moved to request-auth.ts; sender stamped on direct/queued starts and steered appends exactly where main stamps it, and rendered in room-context.ts.
  • Delta-context handoffs: the production Handoffs singleton (new server/delta-handoffs.ts) with full turn-path integration — strict-resume context decisions in start-turn/phases/context.ts (decideContext, session-config hashing, unseen-message rendering), handoffs.begin/dispatching/bindTurn/abandon across the dispatch phases, onEvent in the event fold, steer recording on both steer paths, stoppedByPerson on interrupts, and forget on task delete and results-thread discard. markTaskContextExternallyUpdated keeps a hands-record session when the engine supports strict resume, and boot recovery counts a recovered queued message as handed so a resumed session offers it again.
  • LLM thread titles: generateThreadTitle extracted to server/thread-titles.ts and wired at both title sites (direct turns in start-turn/phases/provider.ts, group turns in group-turn/start.ts), gated on llmThreadTitlesEnabled and never on peer-opened rows.
  • Computer-wait text: bindTurnComputer uses the shared computer-wait.ts chip and give-up wording (holder as bot/task or room), replacing the stale inline strings.
  • Generated-image file 403s: the message file route accepts generated-image attachments as durable capabilities (403s fixed), derives href from the rendered-image target on preview, and allows textless bot messages carrying image attachments.
  • Instance icon projection: describeInstances projects the saved instance icon so the model picker round-trips it.
  • Smaller ports: cache-control: private, no-store on team-computer screenshots, retry-thread.ts import fixes, and two merge-stray syntax errors removed (config/schema.ts, store/tasks.ts).
  • Claude first-turn latency: the --autocompact CLI flag floor (2.1.122) doesn't match what's actually shipped — flag isn't in 2.1.129 #1187 --autocompact feature probe (claude --help, ~140ms) ran inline in the first fresh launch of a process, so a follow-up message sent moments after a turn started lost the steer-vs-launch race and was queued instead of steered; the probe is now warmed from the boot-time instance snapshot beside the --version read, and the paired-person steer attribution test passes 10/10 in isolation.
  • Lazy computer attach (Auto turns serialize on the computer even when they never use screen tools (eager exclusive Local VM claim at dispatch) #1361): ported main's lazy claim semantics into the decomposed start-turn/phases/integrations.ts: a ready Local VM mounts without claiming (the first screen tools/call claims it through the computer-control gate), the VPS desktop no longer binds exclusively at setup, claimAutoLocalVm pins its target and unwinds lease + turn resource on every failure path (dropLease), and each lazy claim restarts the screen poller with the now-live computer capture. The poller handles (screenPollers, startScreenPoller, stopScreenPoller) are threaded through engine/workflow wiring into the start-turn cleanup deps so the restart path is live, not dormant.
  • Instance CLI overrides: ported main's persistableInstanceConfigs config restoration, so saving another engine's CLI no longer freezes inherited url/model/provider defaults into the persisted fleet config.
  • Routine cloud guidance: the missing-Box-key run reason is main's exact guidance sentence (run_on="maus" / self-hosted VPS) instead of a bare run-blocking error.
  • delta-context determinism: the delegate_bot-source soul-edit e2e now waits for the wake turn's CLI launch before editing the soul. The launch record is written at process start, so the dispatch-time soul read is guaranteed done; without this the test raced on machines where the Local VM runtime probe slows turn setup (identical code and test on main — a Docker-equipped developer machine loses the race).
  • Typecheck repair: tsc -p . only covered src/; the server tree is now checked via tsconfig.server.json (server + companion + enterprise), which is how the two syntax errors above were caught.

Verification

  • tsc --noEmit -p tsconfig.server.json — clean
  • tsc --noEmit -p tsconfig.json — clean
  • pnpm lint (oxlint, deny-warnings) — clean
  • Full vitest run suite — 7,482 passed / 46 skipped / 1 todo, 0 failed (586 files passed, 3 skipped). The six files that failed before this round (config, codex-device-auth, routine-cron e2e, delta-context e2e, group-local-vm e2e, vps-routing) are green, including the previously load-flaky codex-device-auth sign-out tests.

Not duplicated here

Still in flight in their own PRs and deliberately not rebased into this branch: #1558, #1559, #1560, #1561, #1562, #1563, #1564, #1523, #1521, #1552, #1526, #1120, #1520, #1518, #1507, #1286.

Deferred (need outside action)

… dead browser-panel-operation module, and the webhooks/routines re-export shims (importers now use shared/ directly; client-only helpers moved to their owners)
…— the server no longer imports renderer code; unify the byte formatters in src/lib/format-bytes.ts and give the paste-policy test its real home
…dule — boxagent/openai-chat/pi/acp-core drop their hand-rolled skeletons; antigravity reuses the ACP connection instead of re-implementing it
… refreshModels consolidated across claude/codex/acp-core, and codex approval config extracted to codex-approvals.ts
…ons from index.ts — /api/events SSE machinery and the routine routes move to server/routes/ behind the workspace-backup-http factory pattern; json/readBody/stderrOf deduplicated into server/http.ts
…ckends — ComputerStatusCommon and the computerStatusProblem ladder, shared probeCuaDesktop, and computerBackendFor(bot); index.ts dispatches through the resolver
…07-line facade — records, context, migrations, messages, groups, bots, and tasks; the public surface is unchanged and both legacy load catches stay verbatim
…e — an ordered OverlayKind list plus an OVERLAY_EXCLUDES table in store.tsx; thirty call sites move to openOverlay/closeOverlay and the testing previews follow
…s into server/routes/internal.ts — 31 path branches move verbatim behind the chain factory pattern; index.ts shrinks 17,135 to 15,505 lines
…and the streaming context move to src/state/overlays.ts and stream-context.tsx behind unchanged re-exports; no consumer changes
…Url and the OPENMAUSBOT_URL/OMB_PORT resolution move to shared/server-endpoint.ts; mcp-server and control-omb drop their private copies, credential guards byte-identical
…l-capability minting moves to server/internal-capabilities.ts and the fold maps plus requestBehavior to server/turn-fold.ts; turn admission stays pending a composition root for the index-local singletons
…ove verbatim to src/components/sidebar/ behind unchanged re-exports; all Sidebar tests pass unmodified (2,367 to 998 lines)
…the 680-line branch chain moves to eleven domain modules under server/drivers/agents-proxy/ with compile-time sync between the tool table and handlers; wire output byte-identical (1,753 to 1,062 lines)
…r/runtime.ts now constructs cfg, registry, store, and the data-dir lease in original order; turn admission and answerRequest/closeOpenApprovals move out of index.ts behind it
…group-view modules and three phone-setup modules behind unchanged re-exports (1,397 to 552 and 1,284 to 43 lines); all importer tests pass unmodified
…enty tools move to seven domain modules under scripts/mcp-server/ with compile-time list/handler sync, mirroring the agents-proxy registry (1,423 to 746 lines)
…ers — seven functions in src/lib/computer-panel-phase.ts replace the scattered setPhase ladders, with 34 new unit tests pinning each family
…behind real imports — createTurnCleanup/createProviderFleet factories replace the extracted functions, roomHandoffHandlers carries the 130-line RoomHandoffs hooks object, and managed-desktop-cleanup.test.ts imports the modules instead of VM-slicing index.ts source (index.ts 15,243 to 14,984 lines)
…— src/state/model.ts carries the domain types and pure helpers, src/state/reducer.ts the AppState/Action union/reducer/initialState, behind a byte-equivalent 58-export facade with zero importer edits (store.tsx 3,344 to 1,444 lines)
… shapes and payload types (wire-types.ts) replace the any-typed handlers and narrow helpers in core.ts (25 to 12 loose-typing sites, zero any in signatures); all 214 acp tests pass unchanged
… body moves verbatim to server/start-turn.ts behind createStartTurn with twelve grouped dep families, wired at the old declaration site with unchanged call sites (index.ts 14,984 to 14,102 lines)
… section modules — selection, status, preview, control, and action families move to src/components/computer-panel/ behind the unchanged facade with zero importer edits (1,683 to 412 lines)
…Error, api, createBotWithRole, persist*, requestConfirmedBotDeletion, and loadSnapshotBoundary move verbatim to src/state/api.ts behind the unchanged facade with no runtime cycle (store.tsx 1,444 to 1,230 lines)
…fold state, the seven ingestion subscribers (registration order preserved), and the RoutineManager/commsBus construction move to server/event-fold.ts and server/routine-wiring.ts behind factories (index.ts 14,102 to 13,087 lines)
…utine schedule/fields schemas move to routine-schemas.ts and the formatting helpers to helpers.ts, registry and compile-time table/handler sync untouched (1,062 to 662 lines)
… — Action union, thread routing, queue receipts, and twelve per-domain case modules split out with byte-identical case bodies and an unchanged export surface (reducer.ts 1,262 to 351 lines)
This was referenced Sep 20, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants