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
filesystemmodule exposes file tools (read,write,edit,glob,grep,delete, ...). - The
ui.workspaceblock 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:
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
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):
> 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:
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.workspacemodule - Git baseline / approve / reject flows, not file I/O.
Next: 7. Deploying - hardening, credentials vault, and the production checklist.