hive-agent: stop writing active_model to the harness state file, nothing reads it
This commit is contained in:
parent
78e063e78c
commit
05c193859f
3 changed files with 13 additions and 38 deletions
|
|
@ -118,7 +118,7 @@ Consolidated harness state file written atomically (`.tmp` + rename) by
|
||||||
Shape:
|
Shape:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{ "rate_limited": false, "needs_login": false, "active_model": "…" }
|
{ "rate_limited": false, "needs_login": false }
|
||||||
```
|
```
|
||||||
|
|
||||||
- `rate_limited` — set when the harness detects a 429 from the Claude
|
- `rate_limited` — set when the harness detects a 429 from the Claude
|
||||||
|
|
@ -127,7 +127,6 @@ Shape:
|
||||||
- `needs_login` — set when a turn hits 401 (expired OAuth credentials);
|
- `needs_login` — set when a turn hits 401 (expired OAuth credentials);
|
||||||
cleared by `"online"` status (re-auth completed). Drives the
|
cleared by `"online"` status (re-auth completed). Drives the
|
||||||
`needs_login` flag alongside the `claude_has_session` check.
|
`needs_login` flag alongside the `claude_has_session` check.
|
||||||
- `active_model` — the resolved Claude model.
|
|
||||||
|
|
||||||
The turn loop is the only writer today, but it still goes
|
The turn loop is the only writer today, but it still goes
|
||||||
read-modify-write under a shared in-process lock and merges into the
|
read-modify-write under a shared in-process lock and merges into the
|
||||||
|
|
|
||||||
|
|
@ -393,15 +393,10 @@ impl Bus {
|
||||||
let (tx, _) = broadcast::channel(CHANNEL_CAPACITY);
|
let (tx, _) = broadcast::channel(CHANNEL_CAPACITY);
|
||||||
let (initial_model, model_source) = local_model(configured_model());
|
let (initial_model, model_source) = local_model(configured_model());
|
||||||
let (initial_effort, effort_source) = local_effort(configured_effort());
|
let (initial_effort, effort_source) = local_effort(configured_effort());
|
||||||
// Restore rate_limited (and needs_login) from the consolidated
|
// Restore rate_limited from the consolidated harness state file so
|
||||||
// harness state file so the dashboard shows the correct status
|
// the dashboard shows the correct status on cold load if the harness
|
||||||
// on cold load if the harness crashed while parked.
|
// crashed while parked.
|
||||||
let (was_rate_limited, was_needs_login, _) = read_harness_state();
|
let (was_rate_limited, _) = read_harness_state();
|
||||||
// Write the resolved active model to hyperhive-harness.json on
|
|
||||||
// startup so hive-c0re can surface the model badge without reading
|
|
||||||
// hyperhive-model directly. Written once here; updated on every
|
|
||||||
// apply_model() call and emit_status() call.
|
|
||||||
write_harness_state(was_rate_limited, was_needs_login, Some(&initial_model));
|
|
||||||
Self {
|
Self {
|
||||||
tx: Arc::new(tx),
|
tx: Arc::new(tx),
|
||||||
event_seq: Arc::new(AtomicU64::new(0)),
|
event_seq: Arc::new(AtomicU64::new(0)),
|
||||||
|
|
@ -575,11 +570,6 @@ impl Bus {
|
||||||
pub fn apply_model(&self, value: String, source: Source) {
|
pub fn apply_model(&self, value: String, source: Source) {
|
||||||
self.model.lock().unwrap().clone_from(&value);
|
self.model.lock().unwrap().clone_from(&value);
|
||||||
*self.model_source.lock().unwrap() = source;
|
*self.model_source.lock().unwrap() = source;
|
||||||
// Mirror the resolved model into hyperhive-harness.json so
|
|
||||||
// hive-c0re can surface it on the dashboard badge without reading
|
|
||||||
// the hyperhive-model override file directly.
|
|
||||||
let (rate_limited, needs_login, _) = read_harness_state();
|
|
||||||
write_harness_state(rate_limited, needs_login, Some(&value));
|
|
||||||
self.emit(LiveEvent::ModelChanged { model: value });
|
self.emit(LiveEvent::ModelChanged { model: value });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -905,7 +895,7 @@ impl Bus {
|
||||||
// turns, so the two callers never overlap. Documented rather than
|
// turns, so the two callers never overlap. Documented rather than
|
||||||
// locked because adding a Mutex here would be overkill for the
|
// locked because adding a Mutex here would be overkill for the
|
||||||
// actual call pattern.
|
// actual call pattern.
|
||||||
let (_, current_needs_login, _) = read_harness_state();
|
let (_, current_needs_login) = read_harness_state();
|
||||||
let new_needs_login = if status == "needs_login_idle" {
|
let new_needs_login = if status == "needs_login_idle" {
|
||||||
true
|
true
|
||||||
} else if status == "online" {
|
} else if status == "online" {
|
||||||
|
|
@ -913,8 +903,7 @@ impl Bus {
|
||||||
} else {
|
} else {
|
||||||
current_needs_login
|
current_needs_login
|
||||||
};
|
};
|
||||||
let current_model = self.model.lock().unwrap().clone();
|
write_harness_state(new_rate_limited, new_needs_login);
|
||||||
write_harness_state(new_rate_limited, new_needs_login, Some(¤t_model));
|
|
||||||
self.emit(LiveEvent::StatusChanged { status });
|
self.emit(LiveEvent::StatusChanged { status });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -131,7 +131,7 @@ fn write_harness_json(v: &serde_json::Value) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn read_harness_state() -> (bool, bool, Option<String>) {
|
pub(crate) fn read_harness_state() -> (bool, bool) {
|
||||||
// Try the new consolidated file first.
|
// Try the new consolidated file first.
|
||||||
if let Ok(raw) = std::fs::read_to_string(harness_json_path())
|
if let Ok(raw) = std::fs::read_to_string(harness_json_path())
|
||||||
&& let Ok(v) = serde_json::from_str::<serde_json::Value>(&raw)
|
&& let Ok(v) = serde_json::from_str::<serde_json::Value>(&raw)
|
||||||
|
|
@ -144,38 +144,25 @@ pub(crate) fn read_harness_state() -> (bool, bool, Option<String>) {
|
||||||
.get("needs_login")
|
.get("needs_login")
|
||||||
.and_then(serde_json::Value::as_bool)
|
.and_then(serde_json::Value::as_bool)
|
||||||
.unwrap_or(false);
|
.unwrap_or(false);
|
||||||
let active_model = v
|
return (rate_limited, needs_login);
|
||||||
.get("active_model")
|
|
||||||
.and_then(serde_json::Value::as_str)
|
|
||||||
.filter(|s| !s.is_empty())
|
|
||||||
.map(str::to_owned);
|
|
||||||
return (rate_limited, needs_login, active_model);
|
|
||||||
}
|
}
|
||||||
// Fall back to legacy sentinel files written by older harness builds.
|
// Fall back to legacy sentinel files written by older harness builds.
|
||||||
let state_dir = crate::paths::state_dir();
|
let state_dir = crate::paths::state_dir();
|
||||||
let rate_limited = state_dir.join("hyperhive-rate-limited").exists();
|
let rate_limited = state_dir.join("hyperhive-rate-limited").exists();
|
||||||
let needs_login = state_dir.join("hyperhive-needs-login").exists();
|
let needs_login = state_dir.join("hyperhive-needs-login").exists();
|
||||||
(rate_limited, needs_login, None)
|
(rate_limited, needs_login)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Write the turn-loop's harness state fields via a read-modify-write so
|
/// Write the turn-loop's harness state fields via a read-modify-write so
|
||||||
/// any other writer's fields in the consolidated state file survive.
|
/// any other field in the consolidated state file survives, including an
|
||||||
/// Pass `active_model: Some(s)` to update the resolved model (surfaced in
|
/// `active_model` an older harness left behind (nothing reads it).
|
||||||
/// the dashboard badge); `None` leaves the stored value untouched.
|
pub(crate) fn write_harness_state(rate_limited: bool, needs_login: bool) {
|
||||||
pub(crate) fn write_harness_state(
|
|
||||||
rate_limited: bool,
|
|
||||||
needs_login: bool,
|
|
||||||
active_model: Option<&str>,
|
|
||||||
) {
|
|
||||||
let _guard = HARNESS_JSON_LOCK
|
let _guard = HARNESS_JSON_LOCK
|
||||||
.lock()
|
.lock()
|
||||||
.unwrap_or_else(std::sync::PoisonError::into_inner);
|
.unwrap_or_else(std::sync::PoisonError::into_inner);
|
||||||
let mut v = read_harness_json();
|
let mut v = read_harness_json();
|
||||||
v["rate_limited"] = rate_limited.into();
|
v["rate_limited"] = rate_limited.into();
|
||||||
v["needs_login"] = needs_login.into();
|
v["needs_login"] = needs_login.into();
|
||||||
if let Some(model) = active_model {
|
|
||||||
v["active_model"] = model.into();
|
|
||||||
}
|
|
||||||
write_harness_json(&v);
|
write_harness_json(&v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue