Hot-Reload
ra watches your config file and all files it references — system prompts, middleware scripts, custom tools, context resolvers — and reloads them automatically between agent loops. Edit a file, send the next message, and the agent picks up your changes. No restart needed.
How it works
Before each agent loop (each REPL input or HTTP request), ra checks the mtime of every tracked file. If any file has been modified since the last check, ra:
- Reloads the config — re-reads and re-merges
ra.config.yamlwith defaults, env vars, and CLI args - Rebuilds the provider — if the provider name or credentials changed
- Rebuilds tools — re-imports custom tool files, re-registers builtins
- Rebuilds middleware — re-imports middleware scripts, re-wires system hooks
- Rebuilds skills — re-scans skill directories
- Rebuilds context — re-discovers context files if patterns changed
Long-lived state is preserved: storage, MCP server connections, memory and scratchpad stores, and observability pipelines are never disrupted.
What's tracked
| File type | Example | Detected how |
|---|---|---|
| Config file | ra.config.yaml | Always tracked |
| System prompt | ./prompt.txt | Tracked when systemPrompt points to a file |
| Middleware scripts | ./middleware/budget.ts | File path entries in agent.middleware |
| Custom tools | ./tools/search.ts | Entries in agent.tools.custom |
| Context resolvers | ./resolvers/jira.ts | agent.context.resolvers[].path |
Inline middleware expressions ((ctx) => { ... }) and shell: entries are not tracked — only file paths.
Configuration
Hot-reload is enabled by default. To disable it:
agent:
hotReload: falseWhen disabled, config is loaded once at startup and never re-checked. This saves a few stat() calls per request if your config never changes at runtime.
Example: live system prompt editing
# ra.config.yaml
agent:
systemPrompt: ./prompts/system.md# Terminal 1: start the agent
ra
# Terminal 2: edit the prompt while the agent is running
echo "You are a pirate. Respond only in pirate speak." > prompts/system.mdThe next message you send in Terminal 1 uses the new prompt — no restart.
Example: iterating on a custom tool
agent:
tools:
custom:
- ./tools/deploy.tsEdit tools/deploy.ts in your editor. The next time the agent calls the tool, it runs the updated code.
Example: tweaking middleware
agent:
middleware:
afterToolExecution:
- ./middleware/audit.tsModify audit.ts to change what gets logged. Changes take effect on the next agent loop.
Concurrency
For HTTP servers handling concurrent requests, reloads are serialized — if two requests arrive simultaneously and both detect a file change, only one reload runs. The second request waits for the first reload to finish and reuses its result.
Caveats
- MCP connections are not restarted. Adding or removing
app.mcpServersentries requires a restart. Existing MCP tools are preserved across reloads. - App-level settings (
app.interface,app.http.port,app.dataDir) are bound at startup. Changing them in the config has no effect until restart. - Module cache is cleared on reload. When a
.tsor.jsfile is re-imported, the previous module is evicted from the cache. This means module-level state (counters, caches) resets on each reload.