Ditto Collaboration + v5 Agent Chat Handoff

Shared by

Updated May 22, 2026

Ditto Collaboration + v5 Agent Chat Handoff

Date: 2026-05-22

Goal

Turn prototype orgs/projects/friends features into a polished collaboration UX, with a new v5 websocket chat system, durable async server-side agent queues, main-agent resource permissions, and frontend simulator coverage.

Branches

  • Backend repo: /Users/peyton/code/ditto/backend
  • Backend branch: codex/add-agents-table
  • Frontend repo: /Users/peyton/code/ditto/ditto-app
  • Frontend branch: codex/backend-1013-collaboration-ui

Latest Pushed Commits

Backend:

  • 7db98231 Process v5 agent chat queues natively
  • 376e8e44 Include roles in agent chat events
  • 25013d6b Resume agent chat queues in background
  • e5ba57d6 Process agent chat queues on the server
  • 69049682 Add multiplexed agent chat websocket

Frontend:

  • abda8e07 Mirror agent chat roles in simulator
  • a1e3040f Parse agent chat message roles
  • 14087cb8 Keep agent websocket subscriptions live
  • 9f9bffea Stop client-side agent queue draining
  • 3b812cb2 Use session-level agent chat websocket

What Is Implemented

Backend v5 now has a session-level websocket endpoint at GET /api/v5/agents/chat/ws. The client sends control messages such as subscribe_thread and unsubscribe_thread with agentID and threadID, allowing one websocket connection to multiplex multiple live agent threads.

Agent chat queues are server-side and durable in Postgres. Users can enqueue messages via v5 REST/websocket APIs, and queued work is processed by a backend worker instead of by browser state. Queue sweep resumes persisted work after process restart. The backend has RunAgentChatQueueSweep, RunAgentChatQueueOnce, and kick-on-enqueue behavior.

A native v5 queue processor is now registered by NewService when Postgres and session cache are available. It uses v5 thread context and OpenRouter directly, not chat v2. It appends completed assistant messages through the new SQLC AppendAgentChatMessage query. This is the first production-draining path for v5 queued work.

Message events now include role, so clients can distinguish user and assistant rows. The frontend API schema and simulator mirror that contract.

Main Agent resource permission actions are implemented and tested for project create/update, org create/update, agent create/update, and resource grant/revoke. Permission requests without expiresAt wait indefinitely until approved or denied. Terminal message status updates cancel pending approvals consistently.

Frontend now uses one session-level websocket and keeps live subscriptions for all known sidebar agent command threads, plus the selected agent. Switching agent views no longer disconnects other live streams. The client no longer drains queued work through chat v2; it only enqueues and observes server-side queue state.

Simulator coverage was extended so the frontend can exercise v5 agent chat, roles, queue summaries, permissions, approval decisions, and resource action flows without a real backend.

Validation Already Run

Backend:

  • go test ./pkg/api/v5
  • go test ./pkg/database/...
  • targeted Postgres-backed native processor tests:
    • TestNativeAgentChatQueueProcessorAppendsAssistantMessage
    • TestNewServiceRegistersNativeAgentChatQueueProcessor

Frontend:

  • bunx vitest run src/api/agentChat.test.ts src/components/CollaborationSurface.test.ts src/components/SendMessage.test.tsx
  • bun run typecheck
  • bun run check

Repo hygiene:

  • git diff --check passed in backend and frontend.
  • Backend worktree is clean except pre-existing untracked .codex/.
  • Frontend worktree is clean.
  • Both mega branches were pushed successfully after credits were reloaded.

Known Remaining Gaps / Next Work

The v5 processor is native and production-wired, but it is still a first-pass LLM worker. It generates assistant responses and persists them, but deeper agentic tool orchestration for resource edits should be evolved so the processor can request permissions itself from structured model intent instead of relying on explicit permission endpoints or existing manual flows.

The websocket broker is process-local. Durable history makes reconnect/replay work, but multi-instance live fanout would need shared pub/sub if deployed across multiple backend instances.

The frontend collaboration surface is much improved, but a true Notion/Slack/Linear-polish pass should still include browser-visible QA across desktop/mobile, tighter loading/error states, and visual refinement of the agent command center and approval cards.

The simulator now mirrors roles and queue state better, but it should next simulate assistant-message append after server-side queue completion so frontend tests can cover the exact two-row user/assistant lifecycle end to end.

Suggested Next Slice

  1. Add structured v5 agent tool/action output parsing in the native queue processor.
  2. Let the processor create permission_request events itself for main-agent resource changes.
  3. Add websocket replay/fanout tests for assistant messages arriving while a thread is inactive but subscribed.
  4. Add frontend simulator tests for server-completed assistant rows and sidebar queue count clearing.
  5. Browser QA the collaboration UI in simulator mode once the above is in place.