Files
safe-os-ui/Artifact_SplitScreen_Design.md

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_start arrives: Set workspace.isOpen = true, clear previous content, set isGenerating = true.
  • When workspace_delta arrives: Append text to workspace.content. Do not append this text to the left-panel chat history to avoid redundancy.
  • When workspace_end arrives: Set isGenerating = 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:

  1. The Backend normally streams thought or tool_call events.
  2. Upon entering the specific Skill execution, the backend emits {"type": "workspace_start", "workspace_title": "Update: Project Plan"}.
  3. As the LLM (or a sub-agent) generates the Markdown schema, the backend maps these tokens to workspace_delta events and flushes them to the frontend.
  4. (CRITICAL) Do not send these tokens as message or final chat events. The chat bubble should only say something like: "I have updated the project plan in the workspace area."
  5. Save the final generated Markdown text into the session memory as the Current Artifact for future context injection.

4. Work Flow Summary (For LLM context generation)

  1. User sends prompt: "Plan the new feature".
  2. Agent thinks (type: thought), decides to use Project Planning Skill (type: tool_call).
  3. Agent emits {"type": "workspace_start"}.
  4. Frontend expands right panel (65% width).
  5. Agent streams {"type": "workspace_delta", "content": "..."}.
  6. Frontend live-renders Markdown in the right panel.
  7. Agent finishes, saves artifact to backend session.
  8. User reads right panel, types in left panel: "Change point 2".
  9. Agent receives Left Panel history + Right Panel Artifact Content.
  10. Agent updates document, streaming new workspace_delta. Frontend live-updates the right panel.