gpfsagent/README.md
Laurence Horrocks-Barlow 8840ba74f7 Initial commit: agentic chat app for IBM Storage Scale REST API v3
Adds a Python package that wraps the Storage Scale /scalemgmt/v3 management
API behind a Claude-driven tool-use loop. Ships a Rich-styled terminal REPL
and a Streamlit web UI sharing the same Agent/Dispatcher/GPFSClient stack.

Guardrails are env-driven (.env): read-only by default; writes and DELETE
gated by GPFS_ALLOW_WRITES / GPFS_ALLOW_DESTRUCTIVE; optional path
allow/deny regex; mutating calls require operator confirmation. Free-text
GPFS_INSTRUCTIONS (or GPFS_INSTRUCTIONS_FILE) appended to the system prompt.

The system prompt also includes a curated v3 endpoint reference compiled
from IBM Storage Scale 5.2.3 / 6.0.0 documentation so the agent doesn't
have to guess endpoint shapes for common operations.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 01:36:59 +01:00

89 lines
3.4 KiB
Markdown

# gpfs-agent
Agentic chat front-end for the IBM Spectrum Scale (GPFS) REST API, driven by
Claude with tool-use. Read-only by default; writes and destructive operations
are gated behind explicit env flags. Ships with both a terminal REPL and a
pure-Python web UI (Streamlit).
## Quick start
```powershell
cd D:\Projects\gpfs-agent
python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -r requirements.txt
Copy-Item .env.example .env
# edit .env: ANTHROPIC_API_KEY, GPFS_API_BASE, GPFS_USERNAME, GPFS_PASSWORD
```
### Web UI
```powershell
streamlit run gpfs_agent\web.py
```
Opens http://localhost:8501 with a chat panel, a sidebar showing the mode and
system prompt, a tool-call log, and (when writes are enabled in `.env`) a
session-scoped "Auto-approve mutations" toggle.
### Terminal REPL
```powershell
python -m gpfs_agent
```
Commands inside the REPL: `/reset`, `/system`, `/quit`.
## How the guardrails work
Everything is configured in `.env`:
| Variable | Effect |
| -------------------------- | ---------------------------------------------------------------------- |
| `GPFS_ALLOW_WRITES` | When `false` (default) the model is given a tool that only accepts `GET`. |
| `GPFS_ALLOW_DESTRUCTIVE` | When `false` (default) `DELETE` is stripped even if writes are on. |
| `GPFS_CONFIRM_MUTATIONS` | When `true` (default) every `POST/PUT/DELETE` is gated by a confirm step. |
| `GPFS_PATH_ALLOW` / `_DENY`| Optional regexes applied to the request path. |
| `GPFS_INSTRUCTIONS` | Free-text instructions appended to the system prompt. |
| `GPFS_INSTRUCTIONS_FILE` | Path to a file with longer instructions; merged with `GPFS_INSTRUCTIONS`. |
Guardrails are enforced in three layers:
1. **Tool schema** — the `method` enum given to the model is built from
`cfg.allowed_methods`, so it cannot ask for `DELETE` when disabled.
2. **Dispatcher**`tools.py` re-checks method and allow/deny regex and
triggers the confirm hook before any mutating HTTP call.
3. **System prompt**`agent.py` injects natural-language guardrails so the
model behaves sensibly even when a guardrail is loose.
### Mutation confirmation
- **REPL**: prints the planned call and waits for `y` at the terminal.
- **Web UI**: mutations are denied unless the sidebar checkbox
*"Auto-approve mutations this session"* is on. The checkbox only appears
when `GPFS_ALLOW_WRITES=true`.
## Project layout
```
gpfs_agent/
├── __init__.py
├── __main__.py # python -m gpfs_agent (REPL)
├── agent.py # Anthropic tool-use loop
├── cli.py # Rich REPL
├── config.py # .env loading & validation
├── gpfs_client.py # httpx wrapper around the GPFS REST API
├── tools.py # Tool schemas + guarded dispatcher
└── web.py # Streamlit chat app
```
## Notes on the GPFS REST API
- `GPFS_API_BASE` should include the version prefix, e.g.
`https://gui:443/scalemgmt/v3`. Shipping Spectrum Scale builds currently
serve `/v2`; set whichever your cluster exposes.
- Auth is HTTP Basic against the Spectrum Scale GUI user. Use an account
scoped to the operations you intend to allow.
- For self-signed lab gear, set `GPFS_VERIFY_TLS=false` or point
`GPFS_CA_BUNDLE` at a PEM file.