Skip to main content

6. UI surfaces

So far the agent has been a chat-only thing. In this step you give it a workspace pane: a side panel the client mounts while the agent writes real files with the filesystem module. Digitorn apps such as LaTeX, Univer, and Craft use the same shape.

Two pieces:

  • The filesystem module exposes file tools (read, write, edit, glob, grep, delete, ...).
  • The ui.workspace block tells the client how to render the pane (renderer mode, entry file, position, width).

Optional: enable preview (inspect, snapshot) when the pane is an interactive HTML / app surface the agent should inspect.

The Go workspace module is different: it is the Git / revision toolkit (baseline, changes, diff, approve, ...), not a virtual in-memory filesystem.

Prerequisites

Same daemon and credential as the previous tutorials.

The YAML

Save this as workspace-bot.yaml:

app.yaml
app:
app_id: workspace-bot
name: Workspace Bot
version: "1.0"

runtime:
mode: conversation
workdir_mode: auto
max_turns: 6
timeout: 90

agents:
- id: main
role: assistant
brain:
provider: deepseek
model: deepseek-chat
backend: openai_compat
credential:
ref: deepseek_main
scope: per_user
provider: deepseek
config:
api_key: "{{env.DEEPSEEK_API_KEY}}"
base_url: https://api.deepseek.com/v1
temperature: 0
max_tokens: 512
system_prompt: |
You write files with filesystem.write / edit. After every
file you write, reply with one short confirmation line
naming the file you wrote.

tools:
modules:
filesystem:
config:
workspace: "."
preview: {}
capabilities:
default_policy: block
grant:
- module: filesystem
actions: [write, read, edit, glob, grep, delete]
- module: preview
actions: [inspect, snapshot]

ui:
workspace:
render_mode: code
entry_file: README.md
title: Workspace Bot
position: right
width_pct: 60
greeting: "Ask me to scaffold a project; I'll write files into the workspace pane."

Three things changed vs the previous tutorials.

The capability block is deny-by-default with explicit grants. This is the canonical production shape: name only the actions the agent actually needs. Auto-policy is fine for tutorials but you want something tighter for live apps.

The ui.workspace block tells the client to mount the pane on the right at 60 % width with the code renderer (other choices: html for live previews, slides, markdown, latex, builder, auto).

Deploy and chat

bash
digitorn install workspace-bot.yaml
digitorn chat workspace-bot

When you chat in the daemon's UI, the workspace pane appears on the right and the agent's writes stream live into it.

Live transcript

Sample shape (exact wording depends on the model):

text
> Create README.md that says hello

Wrote README.md.

The pane shows README.md with the new content.

Widgets (optional)

Workspace files are one surface; widgets are another. Where the workspace is "files the agent writes", widgets are interactive UI trees the client renders from the app manifest / session state.

The simplest example - a status card:

yaml
ui:
widgets:
inline:
status_card:
tree:
type: card
children:
- { type: text, text: "Status: {{state.status}}" }
- { type: text, text: "Last update: {{state.last_seen}}" }

{{state.X}} placeholders resolve client-side from session widget state. There is no preview.set_state / preview.get_state tool in the Go daemon today; preview tools are inspect and snapshot. Do not invent a widget.set_state catalog tool unless your client documents a separate API.

When to use which

  • ui.workspace + filesystem - the agent produces files (code, docs, slides, static sites).
  • Widgets - interactive forms / panels when your client supports them.
  • preview - inspect / snapshot a live preview surface.
  • workspace module - Git baseline / approve / reject flows, not file I/O.

Next: 7. Deploying - hardening, credentials vault, and the production checklist.