Early bird: 30% off Dashral ProSee pricing

Dashral

Agent workspacePro

A chat with an AI agent beside what it's making, a document, a table or code, in versions: ask for a change and the new version writes itself line by line, see what changed, or bring an older one back. On motion.

Installation

When to use

  • An agent that makes something people keep working on: a brief, a report, a table of numbers, a piece of code.
  • Products where people ask for changes in words and want to compare versions or go back to one.

When not to use

  • Questions with a quick answer and nothing to keep: AI assistant.
  • Editing the document by hand: pair the panel with your own editor instead of this view.

Usage

Agent workspace with your own data: every prop has the sample as its default, so pass only what you have.

example.tsx
"use client"

import { AgentWorkspace } from "@/components/dashral/blocks/agent-workspace"

export default function Workspace() {
  return (
    <AgentWorkspace
      title="Release notes"
      messages={[]}
      versions={[]}
      suggestions={["Draft this week's release notes"]}
      onSend={async (prompt, run, current) => {
        // Stream your model here: run.reply goes into the chat, run.write into a new version.
        run.reply("Writing it now.")
        for (const line of ["# Release notes", "", `- ${prompt}`]) {
          if (run.signal.aborted) return
          run.write(line + "\n")
          await new Promise((resolve) => setTimeout(resolve, 120))
        }
        run.label(current ? "Updated" : "First draft")
      }}
      onRestore={(version) => console.log("restored", version.id)}
    />
  )
}

API reference

AgentWorkspace

A conversation with an AI agent beside what it's making: a document, a table or code, in versions. Ask for a change and the answer streams into the chat while the new version writes itself into the panel. Pick a version to read it, turn on Changes to see what's added and removed since the one before, and Restore to bring an older one back as the newest. Each answer that made a version links to it. The panel closes to give the chat the room, and on a phone it covers the chat.

PropTypeDefault
titlestring

The thing being made, at the top of the panel: "Launch brief".

"Launch brief"
messagesWorkspaceMessage[]

The conversation so far.

sample
versionsWorkspaceVersion[]

Its versions, oldest first.

sample
suggestionsPromptSuggestion[]

Ideas for what to ask next, under the chat while it's quiet.

sample
onSend(prompt: string, run: WorkspaceRun, current: WorkspaceVersion | undefined) => Promise<void> | void

Your model answering: stream into run (the chat with reply, a new version with write or replace). While its promise is pending the composer shows stop; a thrown Error shows on the answer. current is the version shown.

—
renderContent(content: Extract<WorkspaceContent, { kind: "custom" }>, state: { writing: boolean }) => React.ReactNode

Draws a custom content (a chart, an image, a page preview…): return it, or nothing for the default note. While the agent is still making it, writing is true.

—
onRestore(version: WorkspaceVersion) => Promise<void> | void

A version brought back: it comes again as the newest one.

—
classNamestring—

StreamWords

Text as it streams in: each new word arrives from a soft blur the moment it comes, as TextReveal's blur variant has its words arrive, without waiting for the rest. Words already there stay still. With reduced motion, plain text.

PropTypeDefault
textstring

Required.

—

WorkspaceView

A version's content: a document, code, a table or your own, with what changed marked when asked.

PropTypeDefault
versionWorkspaceVersion

Required.

—
previousWorkspaceVersion

The version before it: with changes, what's added and removed since.

—
changesbooleanfalse
writingboolean

Still being written: its lines grow in, with a caret at the end.

false
renderContentAgentWorkspaceProps["renderContent"]

Draws a custom content; see AgentWorkspace's renderContent.

—

type WorkspaceContent

= | { kind: "document"; text: string } | { kind: "code"; language: string; text: string } /** * Anything else, drawn by your `renderContent`: a chart, an image, a page preview, a form. `type` says which; `text` * is what Copy copies and what Changes compares (left out, Copy copies `data` as JSON and Changes is off). */ | { kind: "custom"; type: string; data: unknown; text?: string } | { kind: "table"; columns: string[]; rows: string[][] }

type WorkspaceVersion

PropTypeDefault
idstring—
labelstring

What changed, in a few words: "Shorter intro".

—
timestring

When, as shown: "2 min ago".

—
contentWorkspaceContent—

type WorkspaceMessage

PropTypeDefault
idstring—
from"user" | "assistant"—
textstring—
versionstring

The version this answer made: a card in the chat that opens it.

—
errorstring

Why the answer didn't come.

—

type WorkspaceRun

What your model streams into, for one answer.

PropTypeDefault
reply(text: string) => void

Adds text to the agent's answer in the chat.

—
write(text: string) => void

Adds text to a new version of the document or code, which starts with the first call.

—
replace(content: WorkspaceContent) => void

Sets the new version's whole content, e.g. a table.

—
label(text: string) => void

The new version's few words: what changed.

—
signalAbortSignal

Aborted when the person presses stop: stop streaming. What came so far is kept.

—

type DiffLine

PropTypeDefault
textstring—
change"same" | "added" | "removed"—
indexnumber—