Skip to content
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
This repository was archived by the owner on Nov 4, 2026. It is now read-only.

Unify console AI chat surfaces — one conversation, docked (ADR-0057) #2409

Closed

Description

@os-zhuang

Implements objectui ADR-0057 — Console AI chat is one system, docked (retire the FAB).

Today the console renders AI chat through 3 parallel shells over one backend (ConsoleFloatingChatbot FAB / AiChatPage full-page / StudioAiCopilot left panel), and the shells fork the conversation — the same app's build chat can exist as two disjoint threads (an empty "Build with AI" copilot next to an active full-page build conversation). This epic collapses them into one chat system:

surface = view · conversation = model · product (ask / build) = the binding axis.

This is not a merge of ask and build — cloud ADR-0063 already fixed that (two products, bound by surface, no roster). This is console-layer consolidation only.

Phases (each reversible; one ADR-0054 browser proof per phase)

  • P1 — one conversation context + one gate (no visible change)
    • ChatSessionProvider owns agent resolution / conversation binding / list / streaming / pending / reconcile; all 3 shells read it
    • Key conversations on (user, app, product) — drop the studio: scope prefix
    • Delete isAiEnabled / discovery.services.ai; useAiSurface everywhere
    • ✔ same thread visible in full-page ↔ Studio copilot for one app
  • P2 — declarative surface→agent resolver (B)
    • resolveSurfaceAgent(surface, ctx) + SURFACE_DEFAULT table; all call sites migrated
    • Fold the ConsoleLayout aiStudio-downgrade special case into the resolver
    • ✔ unit table for ADR-0063 (Studio→build, console/app→ask, downgrade, app.defaultAgent bounded to ask/build)
  • P3 — docked rail + Studio right-side reflow; retire the FAB
    • ChatDock: shared panel as a collapsible/resizable right rail; FAB → launcher / ⌘I
    • Studio → [left: nav] [center: canvas + properties] [right: chat]
    • /ai = maximized dock, same thread; runtime SDUI bubble unchanged
    • ✔ chat location identical across console pages; expand/collapse preserves thread
    • depends on: objectstack-ai/cloud#816 (render behavior by declared capability, optional)
  • P4 — ask→build explicit handoff
    • build-shaped request in ask → "Open in Builder →" carrying context via assistantBus
    • ✔ Builder opens with context; no authoring on the ask surface
    • depends on: objectstack-ai/cloud#817 (handoff context contract)

Cloud dependencies (separate, non-blocking)

  • objectstack-ai/cloud#816 — agent catalog returns capabilities (B+)
  • objectstack-ai/cloud#817 — ask→build handoff context contract

Open questions (see ADR-0057)

Dock side under Studio (chat vs properties on the right) · FAB hard-retire vs collapsed-affordance · handoff explicit vs seamless · app.defaultAgent rejection post-ADR-0063 · focus-mode deep-link.

Activity

  1. os-zhuang commented on Jul 13, 2026

    @os-zhuang
    ContributorAuthor

    Design doc / decision: #2411 (ADR-0057).

  2. os-zhuang commented on Jul 13, 2026

    @os-zhuang
    ContributorAuthor

    Agent-executable work order: #2412 — the self-contained implementation spec (repo workflow, exact file paths, per-phase design + acceptance, verification, invariants). Hand #2412 to the implementing agent; this epic stays the high-level roll-up.

  3. os-zhuang commented on Jul 13, 2026

    @os-zhuang
    ContributorAuthor

    P4 progress update (2026-07-13) — ask→build handoff is functionally complete:

    Remaining for this epic: P3 (docked right rail + FAB retirement + Studio right-side reflow) — untouched; the ADR's open questions 1–2 (dock side under Studio, FAB retirement path) should be settled before starting it. Also pending: cloud#816 (capabilities) to eliminate the remaining isBuildAgent name checks (7 files), and flipping the ADR's Status line once P1/P2/P4 are considered accepted.

  4. os-zhuang commented on Jul 13, 2026

    @os-zhuang
    ContributorAuthor

    P3 implementation plan — docked right rail, FAB as collapsed affordance, Studio reflow

    Per the decisions locked 2026-07-13 (recorded in the ADR): chat docks right (Studio properties fold into a center tab) and the FAB survives as the dock's collapsed affordance. Three reversible sub-phases, each its own PR with an ADR-0054 browser proof.

    P3a — ChatDock shell (additive; no entry-point changes)

    New: packages/app-shell/src/layout/ChatDock.tsx + hooks/useChatDockState.ts

    • Right-side rail in ConsoleLayout (flex row beside main): collapsible, default collapsed, drag-resizable (min 360px / max 50vw, width persisted to localStorage), full-screen sheet under the md breakpoint.
    • Renders the existing ChatPane body (already exported from AiChatPage) over the P1 conversation key — the dock is a VIEW; no new conversation state.
    • Gate: useAiSurface (catalog empty → no dock, OSS unchanged). Keyboard toggle ⌘I.
    • Feature flag features.chatDock (default off in prod) = the rollback lever for the whole phase.
    • Proof: dock opens on any console page; collapse/expand preserves the thread id; OSS build shows nothing.

    P3b — FAB → collapsed affordance; overlay retires

    Touched: layout/ConsoleChatbotFab.tsx, layout/ConsoleFloatingChatbot.tsx, assistant/assistantBus.ts

    • FAB click toggles the dock (no more floating overlay in the console); FloatingChatbot the component stays for the runtime SDUI bubble (audience idiom, per ADR §4).
    • assistantBus open/context/review signals re-point to the dock.
    • Sub-task (flagged risk): the FAB still keys its conversation per-agent (scope: activeAgent, ConsoleFloatingChatbot.tsx:961) — migrate to the P1 chatConversationScope key with a one-time fallback read of the legacy scope, so existing FAB threads don't vanish for users.
    • Proof: FAB opens the dock showing the SAME thread as /ai/ask; reconcile-on-error + HITL cards function inside the dock; no overlay remains.

    P3c — /ai = maximized dock; Studio right-side reflow

    Touched: console/ai/AiChatPage.tsx (becomes a thin route wrapper: sidebar + maximized dock body), views/studio-design/StudioAiCopilot.tsx (leaves the left w-96 border-r slot), views/studio-design/StudioDesignSurface.tsx (grid → [left: nav/tree] [center: canvas + properties tabs] [right: dock])

    • Deep links /ai/:agent/:conversationId (share links, ADR-0013) open the dock maximized on that thread — routing unchanged.
    • Live Canvas (ADR-0037) renders beside the chat in maximized mode, unchanged in the rail (canvas needs width → auto-maximize on canvas open, tuck on close; reuse the existing onCanvasOpenChange seam).
    • Proof: one app's build thread is IDENTICAL across dock / /ai/build / Studio copilot (P1 key, the ADR's headline fix); Studio properties reachable via center tab; canvas opens beside chat.

    Sequencing & estimates

    P3a (~1d) → P3b (~1d, scope migration is the risk) → P3c (~2d, Studio reflow is the risk). Flag stays until P3c proves out, then the flag + dead overlay code are removed in a cleanup PR.

    Pre-existing seams this leans on (verified in-repo today)

    • ChatPane already exported and reused by Studio (P1); chatConversationScope keying (P1); resolveSurfaceAgent (P2); useAiSurface gate; agentHasCapability (cloud#816, just landed) so the dock renders debug/canvas/resume behavior by declared capability from day one.
  5. added a commit that references this issue on Jul 13, 2026
  6. os-zhuang commented on Jul 13, 2026

    @os-zhuang
    ContributorAuthor

    New: Amendment A1 proposal (build conversations bind a package, lazily) — PR #2457; consolidated live-testing UX findings — #2458. A1.a is designed to fold into P3a's dock header.

  7. os-zhuang commented on Jul 13, 2026

    @os-zhuang
    ContributorAuthor

    P3a shipped (in review): the ChatDock shell — additive, default-off (features.chatDock) — #2464. AppShell.rightRail (reflow, not overlay) + a collapsible/resizable rail reusing ChatPane over the P1 ask conversation + ⌘⇧I toggle. Live-verified (flag forced on): launcher→rail with ask chat + content reflow + collapse. Next: P3b (FAB → dock launcher), P3c (/ai = maximized dock + Studio right-side reflow). Amendment A1.a (binding chip) already lives in the dock-ready header.

  8. os-zhuang commented on Jul 13, 2026

    @os-zhuang
    ContributorAuthor

    P3b shipped (in review): #2465 — the FAB now opens the ChatDock (when features.chatDock on) instead of the floating overlay; P3a's edge launcher is superseded. Live-verified: FAB→dock, no floating overlay mounted, content reflows. P3 status: P3a ✅ (#2464) · P3b ✅ (#2465) · P3c next (/ai = maximized dock + Studio right-side reflow — the 3-pane surgery; own PR). Amendment A1.b (bind-on-create conversation re-key) also queued as its own pass (mutates live conversation keying; likely needs a backend scope-rekey).

  9. os-zhuang commented on Jul 13, 2026

    @os-zhuang
    ContributorAuthor

    P3c is up: #2467 — the final P3 slice (/ai = the ChatDock maximized; Studio copilot → the shared right dock with the Interfaces properties folding into center tabs; Live-Canvas auto-maximize in the rail). All behind the default-off features.chatDock flag, with an ADR-0054 browser proof on the local rig covering (a) rail ⇄ /ai same-thread round-trip, (b) the Studio [nav] [canvas+properties tabs] [chat] grid incl. dock collapse/launcher/maximize, and (c) flag-off pixel-parity.

    With P3a (#2464) + P3b (#2465) + P3c merged, every P3 deliverable in the plan above is implemented. Remaining before this epic can close:

    1. Roll the flag out (server-side features.chatDock: true) and let it soak;
    2. The cleanup PR the plan calls for once P3c proves out: remove the flag + the now-dead console floating-overlay path (the runtime SDUI bubble stays, per ADR §4);
    3. Flip the ADR Status line from "shipped behind flag" to done at that point.

    Proposal: keep this epic open to track (1)–(3), or close it now and track the cleanup as its own issue — maintainer's call.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions