The workspace of a conversation: where file and command tools act.
It is configuration, stored in the conversation's pi.agent document:
"workspace" => %{"kind" => "local"} # default
"workspace" => %{"kind" => "shared", "root" => "/mnt/shared/ws"}
"workspace" => %{"kind" => "scratch"} # also "base", "lifetime"
"workspace" => %{"kind" => "none"}| Kind | Where | Survives node loss | Capabilities |
|---|---|---|---|
local | The disk of the node, as before (cwd and the permission policy decide). | No | fs, exec, net |
shared | A directory on storage that every node mounts. Paths are confined to root. Writes take a cross-node lock. | Yes | fs, exec, net |
scratch | A temporary directory on the node that runs the task, confined, removed when the task ends. "lifetime" => "conversation" keeps it until the sweep (scratch_ttl_hours, default 24). "base" or config :super_pi, scratch_dir sets the parent directory. | No | fs, exec, net |
none | No filesystem or commands. The agent has the artifact tools, MCP tools and the web. | n/a | net |
Network
net is on in every kind. "network" => false in the workspace map removes it, so a deployment
can run an agent that reads a repository and cannot make outgoing calls: web, MCP and every other
tool that declares a net_read or net_write effect is then not offered and is refused if called.
This differs from Permissions (network: "deny"): the workspace decides whether the model is
shown a network tool, the policy decides whether one call is allowed.
Capability of a tool
A tool states its effects (SuperPi.Tools.effects/2) and the effects give the capability:
fs_write needs fs, exec needs exec, net_read and net_write need net, read and
state_write need nothing. The built-in file and shell tools are matched by name, because read
is also the effect of tools that read Super-Pi state. Artifact tools need artifacts. A tool that
states no effects needs fs, exec and net, so an unknown tool is not offered where any of
them is missing.
Artifact tools (SuperPi.Artifacts) are offered with shared, scratch and none, and with
local when the workspace sets "artifacts" => true. A tool whose capability the workspace
does not have is not offered and is refused if called. The tools never fall back to the local
disk: a shared workspace without a root is an error.
Confinement of shared and scratch follows symlinks, so a link inside the workspace cannot
lead out of it. It applies to file tools. A shell command runs with the root as its working
directory but is not sandboxed by this module; use an OS-level sandbox for untrusted commands.
Summary
Functions
Resolves a workspace from its configuration map.
First capability a tool needs, or nil. Kept for callers that ask about one capability.
Removes the scratch directory of a finished task.
Absolute path for path inside a confined workspace. A relative path is joined to base (the
root, or a cd inside it). Raises throw({:workspace_error, message}) for a path outside the root.
The tool list to offer a conversation: tools the workspace cannot serve are removed and the artifact tools are added when the workspace has them. Safe to call on every request.
Capabilities a tool needs, all of them: a list of :fs, :exec, :net or :artifacts.
agent_cfg supplies the tool's declared effects (SuperPi.Tools.effects/2). See the module doc.
Resolves the workspace for a tool call. ctx has :conversation_id and, in a turn, :active_task_id.
True when the workspace can serve the tool.
Removes scratch directories that nothing needs: the directory of a task that is no longer
running, and any directory idle longer than scratch_ttl_hours (default 24). Returns the number
of directories removed.
Types
Functions
Resolves a workspace from its configuration map.
First capability a tool needs, or nil. Kept for callers that ask about one capability.
Removes the scratch directory of a finished task.
Absolute path for path inside a confined workspace. A relative path is joined to base (the
root, or a cd inside it). Raises throw({:workspace_error, message}) for a path outside the root.
The tool list to offer a conversation: tools the workspace cannot serve are removed and the artifact tools are added when the workspace has them. Safe to call on every request.
Capabilities a tool needs, all of them: a list of :fs, :exec, :net or :artifacts.
agent_cfg supplies the tool's declared effects (SuperPi.Tools.effects/2). See the module doc.
Resolves the workspace for a tool call. ctx has :conversation_id and, in a turn, :active_task_id.
True when the workspace can serve the tool.
Removes scratch directories that nothing needs: the directory of a task that is no longer
running, and any directory idle longer than scratch_ttl_hours (default 24). Returns the number
of directories removed.