fix(manifest-reload): re-read source TOML on daemon restart so manifest edits take effect without respawning#225
Open
capt-marbles wants to merge 1 commit intoRightNow-AI:mainfrom
Conversation
…st edits take effect without respawning Fixes RightNow-AI#219. When a daemon restarts, the restore loop exclusively reads agent manifests from the SQLite blob — edits to the on-disk TOML (e.g. in ~/.openfang/hands/) were silently ignored, requiring a full delete-and-respawn to pick up changes. Root cause: `AgentEntry` had no record of where its manifest came from, so the restore loop had no path to re-read. The `load_all_agents` query only pulled the msgpack blob. **Changes:** `crates/openfang-types/src/agent.rs` - Add `source_toml_path: Option<PathBuf>` to `AgentEntry` with `#[serde(default)]` for zero-cost backwards compatibility with existing DB rows. `crates/openfang-memory/src/structured.rs` - Add `source_toml_path TEXT DEFAULT NULL` column migration in `save_agent` (same inline-ALTER pattern already used for `session_id`). - Read and populate the column in both `load_agent` and `load_all_agents`. `crates/openfang-kernel/src/kernel.rs` - Restore loop: if `source_toml_path` is set and the file exists, re-parse the TOML and use it as the manifest. On success, the refreshed manifest is written back to the DB so unchanged files incur no extra I/O on subsequent restarts. Parse or read errors fall back to the DB blob with a WARN log — a bad edit never prevents an agent from starting. - `activate_hand`: after spawning the agent, write the manifest to `~/.openfang/hands/{name}/agent.toml` (skipped if the file already exists to preserve user edits), then record the path in the `AgentEntry` via a `load_agent` + `save_agent` round-trip. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #219.
Problem
Editing
~/.openfang/hands/{name}/agent.tomland restarting the daemon has no effect — the agent comes back with the old manifest. The only workaround is to delete the agent and respawn it from scratch, losing conversation history, session state, and schedule linkage.Verified broken in v0.3.2: changed
modelfield fromclaude-sonnet-4-20250514toclaude-haiku-4-5-20251001in a hands agent.toml, killed daemon, restarted — API still returnedclaude-sonnet-4-20250514.Root Cause
The restore loop in
kernel.rsreads manifests exclusively from the SQLite blob:AgentEntryhad nosource_toml_pathfield, so even if the code wanted to check disk, it had no path to read.load_all_agentsinstructured.rsread the msgpack blob from themanifestcolumn and returned it directly, no file I/O.Fix
Three files, one concept: record where each manifest came from, and re-read it on restart.
crates/openfang-types/src/agent.rsAdd
source_toml_path: Option<PathBuf>toAgentEntry:#[serde(default)]ensures existing DB rows (no column) deserialise toNone— no migration required for the msgpack blob.crates/openfang-memory/src/structured.rssave_agent: inlineALTER TABLE agents ADD COLUMN source_toml_path TEXT DEFAULT NULL(same pattern assession_id). Include the column in theINSERT ... ON CONFLICT UPDATE.load_agentandload_all_agents: read the column (col index 7), pass through toAgentEntry. Falls back gracefully on older DBs that don't have the column yet.crates/openfang-kernel/src/kernel.rsRestore loop — after loading from DB, re-read from disk if a source path is recorded:
Parse or read errors fall back to the DB blob with a
WARNlog — a typo in a TOML file never prevents an agent from starting.activate_hand— after spawning the agent, write the manifest to~/.openfang/hands/{name}/agent.toml(only if the file doesn't already exist, to preserve user edits), then record the path:Behaviour after this fix
agent.tomlto hands dirTests
All 279 existing tests pass. Build is clean.