6.3 KiB
Vibe Coding Design Docs: Workspace/Artifact Split-Screen Pattern
1. Context & Objective
The goal is to implement a UI/UX pattern similar to Claude Artifacts or Gemini Deep Research. When a specific complex task is triggered (e.g., "Project Planning Skill"), the single-column chat interface should smoothly transition into a split-screen layout:
- Left Panel (35%): Conversational context, CoT (Chain of Thought) traces, tool calls, and user input.
- Right Panel (65%): A dedicated "Workspace" or "Artifact" rendering area to display long-form content (Markdown, code, diagrams) generated by the Agent's skills.
Crucially, this system must support Reflexion/Iterative generation. The user can comment on the generated artifact in the left panel, and the agent should update the artifact in the right panel based on the feedback.
2. Frontend Implementation Guide (React + Vite + Tailwind)
2.1 State Management (State & Types)
Extend the existing frontend state to track the workspace status and content.
// 1. Extend the StreamEvent type to support UI control and artifact streaming
type StreamEvent = {
type:
| "thought"
| "tool_call"
| "tool_result"
| "message" // Standard chat message
| "error"
| "workspace_start" // Trigger right panel open
| "workspace_delta" // Streaming text for the right panel
| "workspace_end"; // Streaming completed
content: string;
step?: number;
tool_name?: string;
workspace_title?: string; // Optional title for the artifact
};
// 2. Add Workspace State (Can be added to useReducer or a separate useState)
type WorkspaceState = {
isOpen: boolean;
title: string;
content: string;
isGenerating: boolean;
};
2.2 SSE Parsing Logic
Modify the onEvent handler inside streamChat to intercept workspace_* events.
- When
workspace_startarrives: Setworkspace.isOpen = true, clear previous content, setisGenerating = true. - When
workspace_deltaarrives: Append text toworkspace.content. Do not append this text to the left-panel chat history to avoid redundancy. - When
workspace_endarrives: SetisGenerating = false.
2.3 Layout & UI Re-architecture
Refactor the root <div> of PlanningAgent.tsx to handle dynamic flex layouts. Use Tailwind's transition utilities for smooth scaling.
<div className="flex h-full w-full overflow-hidden bg-surface">
{/* Left Panel: Chat & Controls */}
<div
className={`flex flex-col h-full transition-all duration-300 ease-in-out ${
workspace.isOpen ? 'w-[35%] border-r border-border min-w-[350px]' : 'w-full max-w-5xl mx-auto'
}`}
>
{/* Existing Message List & Input Area */}
</div>
{/* Right Panel: Workspace / Deep Research Output */}
{workspace.isOpen && (
<div className="w-[65%] h-full flex flex-col bg-surface-muted transition-opacity duration-300 animate-fade-in">
{/* Header */}
<div className="h-14 border-b border-border flex items-center px-6 justify-between bg-white">
<h3 className="font-semibold text-txt flex items-center gap-2">
<IconDocument /> {workspace.title || 'Project Planning Document'}
</h3>
{workspace.isGenerating && (
<span className="text-sm text-magenta animate-pulse flex items-center gap-1">
<Spinner /> Generating...
</span>
)}
</div>
{/* Markdown Content Area */}
<div className="flex-1 overflow-y-auto p-8 prose prose-slate max-w-none">
<ReactMarkdown remarkPlugins={[remarkGfm]} rehypePlugins={[rehypeRaw]}>
{workspace.content}
</ReactMarkdown>
</div>
</div>
)}
</div>
3. Backend Implementation Guide (Agent / ReAct Loop)
The backend agent requires structural changes to understand the "Artifact" concept, emit correct SSE events, and maintain the artifact in its memory for iterative edits.
3.1 Tool / Skill Definition
When defining the Project Planning Skill for the LLM, clearly state its output behavior so the LLM knows when to use it.
- Tool Description:
use_planning_workspace: "Invoke this tool to generate, structure, or update a major project planning document. The output will be rendered in a dedicated UI workspace."
3.2 Context Injection (Memory for Reflexion)
To allow the user to say "extend the testing phase to 2 weeks", the LLM must know what is currently in the right panel.
- Before sending the prompt to the LLM, query the database/session for the current Artifact state.
- Prompt Assembly:
[System Prompt / ReAct Instructions] ... [Current Workspace Artifact (if exists)] <workspace> # Project Plan 1. Dev Phase: 1 week 2. Testing Phase: 1 week </workspace> [Chat History] User: extend the testing phase to 2 weeks.
3.3 Streaming Control (Hijacking the Stream)
Within the ReAct execution loop, when the Agent decides to execute the Project Planning Skill:
- The Backend normally streams
thoughtortool_callevents. - Upon entering the specific Skill execution, the backend emits
{"type": "workspace_start", "workspace_title": "Update: Project Plan"}. - As the LLM (or a sub-agent) generates the Markdown schema, the backend maps these tokens to
workspace_deltaevents and flushes them to the frontend. - (CRITICAL) Do not send these tokens as
messageorfinalchat events. The chat bubble should only say something like: "I have updated the project plan in the workspace area." - Save the final generated Markdown text into the session memory as the
Current Artifactfor future context injection.
4. Work Flow Summary (For LLM context generation)
Usersends prompt: "Plan the new feature".Agentthinks (type: thought), decides to useProject Planning Skill(type: tool_call).Agentemits{"type": "workspace_start"}.Frontendexpands right panel (65% width).Agentstreams{"type": "workspace_delta", "content": "..."}.Frontendlive-renders Markdown in the right panel.Agentfinishes, saves artifact to backend session.Userreads right panel, types in left panel: "Change point 2".Agentreceives Left Panel history + Right Panel Artifact Content.Agentupdates document, streaming newworkspace_delta. Frontend live-updates the right panel.