Skip to content

fix: preserve model/provider/temperature across Hand respawn#699

Open
Fail-Safe wants to merge 3 commits intoRightNow-AI:mainfrom
Fail-Safe:fix/hand-model-preservation
Open

fix: preserve model/provider/temperature across Hand respawn#699
Fail-Safe wants to merge 3 commits intoRightNow-AI:mainfrom
Fail-Safe:fix/hand-model-preservation

Conversation

@Fail-Safe
Copy link
Contributor

Problem

Every time a Hand agent was respawned (daemon restart, crash recovery, or manual reactivation), activate_hand() rebuilt the AgentManifest entirely from the compile-time-embedded HAND.toml, silently discarding any changes made via the agents API. This caused a persistent revert loop:

  1. Patch researcher-hand via API (model, provider, tool filters) ✅
  2. Daemon restart → activate_hand() rebuilds from HAND.toml → changes gone ❌
  3. Patch again ✅
  4. Crash recovery → same wipe ❌

Changes

Commit 1 — preserve API-patched tool filters across Hand respawn

activate_hand() now reads the existing agent's tool_allowlist and tool_blocklist from the registry before rebuilding the manifest, and reapplies them after. Only applied when non-empty — an empty list means "no override set", not "block all".

Commit 2 — preserve model/provider/temperature + temperature API

Extends the same pattern to model config fields. A single registry scan captures the existing agent's provider, model, and temperature before rebuild. After computing hand_provider/hand_model from HAND.toml, any difference from the live values indicates an API patch — those values are reapplied after the manifest build.

system_prompt is intentionally excluded: it is assembled dynamically from HAND.toml + settings context and must stay live.

Also adds:

  • registry::update_temperature() for hot-patching sampling temperature
  • temperature exposed in GET /api/agents and GET /api/agents/{id} responses
  • temperature field in PATCH /api/agents/{id}/config with 0.0–2.0 validation
  • Temperature input in the dashboard agent config tab

What survives respawn after this PR

Field Before After
tool_allowlist
tool_blocklist
provider
model
temperature
system_prompt ❌ intentional

Test plan

  • Patch a Hand's model/provider via PUT /api/agents/{id}/model, restart daemon — agent should come back with the patched model
  • Patch tool filters via PUT /api/agents/{id}/tools, restart — filters should be preserved
  • Patch temperature via PATCH /api/agents/{id}/config with {"temperature": 0.5}, restart — temperature should be preserved
  • Verify a Hand that was never patched still inherits default_model from config correctly (override path should be None)
  • cargo test --workspace passes

🤖 Generated with Claude Code

Fail-Safe and others added 3 commits March 17, 2026 14:20
When a Hand agent is respawned (on daemon restart or reactivation),
activate_hand() rebuilds the manifest entirely from HAND.toml, silently
discarding any tool_allowlist/tool_blocklist changes made via the API.
The API returned {"status":"ok"} for these updates, creating a broken
contract: changes appeared to succeed but were lost on the next restart.

Fix: capture the existing agent's tool filters before killing it at
respawn time, and reapply them to the freshly-built manifest. Empty
filters are treated as "no override" (not "block all") so hands with no
API-set filters continue to get the full tool list from HAND.toml.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Extends the API-patch preservation introduced in 81eb7cb to cover model
config fields. Previously, provider, model, and temperature changes made
via the agents API were lost every time a Hand was respawned (daemon
restart, crash recovery, or manual reactivation) because activate_hand()
rebuilt the AgentManifest entirely from the compile-time-embedded HAND.toml.

Changes:
- kernel.rs: single registry scan now captures both tool filters and model
  config before rebuild; existing_model_override carries provider/model/
  temperature and is reapplied after the manifest is built, only when the
  live values differ from what HAND.toml would produce.  system_prompt is
  intentionally excluded — it is assembled dynamically from HAND.toml plus
  settings context and must stay live.
- registry.rs: add update_temperature() for hot-patching sampling temp.
- routes.rs: expose temperature in list/get responses; add temperature field
  to PatchAgentConfigRequest and implement it in patch_agent_config with
  0.0–2.0 validation.
- index_body.html + agents.js: temperature input in the agent config tab.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant