feat(workspace): agent config-watcher for hot-reload of config.yaml without container restart #117
Loading…
Reference in New Issue
Block a user
No description provided.
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
/configsis already bind-mounted into the workspace container, so a config.yaml edit is visible on the agent's filesystem instantly. But the agent process (claude-code subprocess wrapped by the Python adapter) reads its config at startup and never re-checks. Result: every config tweak requires a full container restart viarestartFunc.This is the most-visited dev surface during agent tuning (changing model, idle_prompt, runtime_config, system_prompt) and the restart cost (~5-10s per change + dropped in-flight A2A messages) compounds during iteration. For Reno-Stars, it's also a visible service-blip every time we adjust their team's config.
Proposed approach
Add a config-watcher to the workspace runtime base (Python) using
watchfiles(or stdlibinotify/fseventswrapper) that:<config_path>/config.yaml,<config_path>/system-prompt.md, and<config_path>/plugins/**for filesystem changes.restartFunc(or the existing path remains).Why this matters relative to issue molecule-core#112
#112 (hot-reload SKILL-content-only, plugin-side) addresses the platform's install path — diff classification before deciding to call restartFunc. This issue addresses the runtime path — the agent process learning that something on disk changed and adapting without restart.
They compose: #112 stops the platform from issuing unnecessary restarts; this issue lets the agent benefit (without needing a process restart) when the platform DOES write new content to disk.
Acceptance criteria
workspace/(or per-runtime adapter) that runs a watcher in a background threadMOLECULE_CONFIG_WATCH=1initially (off by default; can flip on after Reno-Stars soak)Out of scope
watchfiles)Risks + mitigations
*.tmp,*.swp,.DS_StoreRefs
workspace-configs-templates/claude-code-default/adapter.py— where the watcher would integrateworkspace/config.pyfor the parse path the watcher would re-invokePhase 1 finding — partial coverage already exists, smaller scope warranted
Investigating before implementing surfaced that the read-at-boundary hot-reload pattern is already in the codebase:
No watchfiles dependency. No background thread. No debounce. Just filesystem-driven re-read on each invocation. This is a strictly cleaner shape than the issue's original watchfiles-based design.
What this means for the issue
self._modelat construction. Extending the pattern to model + idle_prompt + category_routing requires touching the executor's constructor signature.Closing this issue
The original scope assumed we needed watchfiles + a background watcher thread + a custom debounce/classify pipeline. Phase 1 found that the codebase's existing pattern is already simpler and covers the most-visited case (system-prompt). The remaining gap (model field) is a focused follow-up issue (filed as a new issue) — significantly smaller than this one's original scope, no Python deps to add.
Follow-up issue: extend get_system_prompt-style read-at-boundary to
config.modelso model swaps take effect at next message without container restart.Closing this as 'partial coverage exists; remaining gap focused-followup-filed.'