Agent tools
| Tool | Contract |
|---|---|
workflow_design_save | {ok, path?, nodes?} or {ok: false, error} |
workflow_design_load | {ok, graph?} or {ok: false, error} |
workflow_design_validate | {ok, errors} |
workflow_design_run | A run result, or {ok: false, errors?/error} |
workflow_design_respond | A run result or {ok: false, error} |
{
"ok": true,
"run_id": "d7b493cae249",
"status": "done | awaiting_approval | awaiting_agent | failed",
"pending": null,
"outputs": {},
"skipped": [],
"deliveries": [],
"error": null
} Every store, plan and persistence failure is translated into a JSON body, never raised into the dispatcher. A slash command must never crash a turn.
The /workflow command
| Command | Purpose |
|---|---|
/workflow | Help and usage |
/workflow list | Saved designs |
/workflow new <name> | Open a blank designer |
/workflow open <name> | Print the saved graph and the canvas hint |
/workflow save <name> <json> | Validate and save pasted JSON |
/workflow validate <name> | Check a saved design |
/workflow run <name> | Run now |
/workflow run retry <run_id> | Retry a failed run from its failed step |
/workflow approve <run> <gate> <answer> | Answer a gate |
Dashboard API
The FastAPI router mounts at /api/plugins/visual-workflow and is a thin layer over the same store, converter, runner and delivery code the chat tools use, so the GUI and chat cannot drift. A design problem returns HTTP 200 with a body describing it; HTTP errors are reserved for requests the client got structurally wrong (400), missing designs or runs (404), a run not waiting on that node (409), and a missing agent backend (502 / 503).
| Method | Path | Purpose |
|---|---|---|
| GET | /models | Host model catalog; refresh=1 drops the cache |
| GET | /profiles | Host profiles (bots) |
| GET | /channels | Delivery targets from the channel directory |
| GET | /designs | Saved design names |
| GET | /designs/templates | Built-in designs from examples/ |
| GET | /designs/{name} | One saved graph |
| POST | /designs/{name} | Validate and save {graph} |
| POST | /designs/{name}/validate | Validate a saved design or a draft |
| POST | /designs/{name}/run | Run now until done or paused |
| GET | /schedules | Cron jobs this plugin created |
| POST | /designs/{name}/schedule | Create or update the job |
| POST | /schedules/{job_id}/{action} | pause, resume, run or remove |
| GET | /runs | Recent runs, newest first (limit, default 20) |
| GET | /runs/{run_id} | One run in result shape |
| POST | /runs/{run_id}/respond | Answer a gate or supply agent output |
| POST | /runs/{run_id}/retry | Retry a failed run |
POST /runs/{run_id}/respond also accepts agent_generate: true with no answer on a parked agent step: the server performs the step through the spawn seam and resumes the run. A failure leaves the run parked, so pasting an answer is still possible.
Files on disk
| Path | Contents |
|---|---|
$HERMES_HOME/workflow-designs/<name>.json | Saved designer graphs |
$HERMES_HOME/workflow-runs/<run_id>.json | Run state, written after every step |
widgets/designer.html | Standalone dependency-free canvas |
examples/*.designer.json | Four starting templates, all validated by tests |
Both stores write atomically through a same-directory temp file plus os.replace, so a poller never observes a half-written run.
What it touches
The catalog record, in the plugin’s own words: no telemetry, no sockets, no credentials, and two directories on disk.
- Network
- None directly. Agent steps and message sends go through host-owned seams (subagent lifecycle, the plugin LLM facade, host send), so the plugin opens no sockets and calls no third-party service. There is no telemetry.
- Reads and writes
- Designs under
~/.hermes/workflow-designs/and run state under~/.hermes/workflow-runs/. Run history is plain JSON, so deleting a file forgets the run. Nothing is written outside those two directories, plus the host-owned cron jobs it is asked to create. - Processes
- Nothing runs on a timer and there are no background threads. Recurring runs are real Hermes cron jobs created only on request; a cron run opens a fresh session and answers its own agent steps, never a human approval gate.
- Credentials
- None. The plugin declares no
requires_env, holds no secrets, and reads no credential files. - Platforms
- Tested on Linux, macOS and Windows: the CI matrix runs the full suite and both host manifest gates on all three on every push and pull request.
Released under Apache-2.0: the repository ships LICENSE and changelog.md, and the release history starts at 1.0.0.