hive-c0re: render the new agent option paths into generated agent flakes
meta.rs writes each agent's flake, and it still named the pre-move `hyperhive.*` paths — so every agent rebuild would print a rename deprecation warning about a line no human wrote and no operator could fix. A warning nobody can act on trains everyone to ignore the ones that matter, which is the whole value of the alias shims. Repoints the FORWARDED_VAR_OPTIONS table and every other emitted option assignment (otel.*, docs.source, claudeCodePath, github.enable, user.name, claudeMemoryMaxBytes) to `services.hyperhive.agent.*`, with the test expectations that pin the rendered text. The flake input named `hyperhive` (`hyperhive.url`, `hyperhive.inputs.nixpkgs.follows`, `hyperhive.nixosConfigurations.*`), hive-tier `services.hyperhive.*` paths, and the `@hyperhive.local` git identity share the word and are untouched. Also repoints the same option paths where they appear in comments, rustdoc and runtime message strings across the other crates — a refusal message naming `hyperhive.allowedRecipients` sends an operator to a path that will stop existing. Prose under docs/ is deliberately not in this commit. Refs #4473
This commit is contained in:
parent
3662eda440
commit
6ea81aae65
30 changed files with 138 additions and 121 deletions
|
|
@ -385,7 +385,7 @@ impl Bus {
|
|||
}
|
||||
};
|
||||
let (tx, _) = broadcast::channel(CHANNEL_CAPACITY);
|
||||
// Priority: HIVE_DEFAULT_MODEL (from hyperhive.model in agent.nix) >
|
||||
// Priority: HIVE_DEFAULT_MODEL (from services.hyperhive.agent.model in agent.nix) >
|
||||
// persisted runtime override > compiled-in DEFAULT_MODEL.
|
||||
// The nix config always wins on rebuild; the persisted file is kept
|
||||
// for within-session tracking only (see persist_model / set_model).
|
||||
|
|
|
|||
|
|
@ -189,7 +189,7 @@ pub(crate) fn write_api_key_mode(enabled: bool) {
|
|||
pub const DEFAULT_MODEL: &str = "haiku";
|
||||
|
||||
/// Return the model declared in `HIVE_DEFAULT_MODEL` (set from
|
||||
/// `hyperhive.model` in `agent.nix`), or `None` if the env var is absent /
|
||||
/// `services.hyperhive.agent.model` in `agent.nix`), or `None` if the env var is absent /
|
||||
/// empty. When `Some`, this takes precedence over any persisted runtime
|
||||
/// override so that nix config changes always take effect on rebuild.
|
||||
#[must_use]
|
||||
|
|
@ -216,7 +216,7 @@ pub fn is_valid_effort(level: &str) -> bool {
|
|||
}
|
||||
|
||||
/// Return the effort level declared in `HIVE_DEFAULT_EFFORT` (set from
|
||||
/// `hyperhive.effortLevel` in `agent.nix`), or `None` if absent / empty.
|
||||
/// `services.hyperhive.agent.effortLevel` in `agent.nix`), or `None` if absent / empty.
|
||||
/// Mirrors [`configured_model`]'s env shape. Unlike model, the persisted
|
||||
/// runtime override takes precedence over this baseline (see `Bus::new`):
|
||||
/// the operator's effort pick sticks across harness restart, with the nix
|
||||
|
|
|
|||
|
|
@ -119,7 +119,7 @@ impl LoginState {
|
|||
|
||||
/// Whether this agent is configured to authenticate to its backend with an
|
||||
/// API key rather than a Claude OAuth session — set by
|
||||
/// `hyperhive.useApiKey` via the `HIVE_USE_API_KEY` env var
|
||||
/// `services.hyperhive.agent.useApiKey` via the `HIVE_USE_API_KEY` env var
|
||||
/// (`nix/agent-modules/agent-service.nix`). Read fresh on every call rather
|
||||
/// than cached: it's an env var, not a value worth a `OnceLock` for.
|
||||
#[must_use]
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
//! Claude launch-config layer: resolves the agent's tool-group / capability
|
||||
//! set into the `--allowedTools` / `--tools` argument strings and renders the
|
||||
//! `--mcp-config` blob claude reads at spawn (built-in hyperhive server +
|
||||
//! any `hyperhive.extraMcpServers`). Pure config-string generation consumed by
|
||||
//! any `services.hyperhive.agent.extraMcpServers`). Pure config-string generation consumed by
|
||||
//! [`crate::turn`] when it builds the claude command. It never touches the
|
||||
//! running MCP server (a separate binary) — the `send` allow-list check that
|
||||
//! server enforces lives alongside it in the `hive-agent-mcp` crate.
|
||||
|
|
@ -12,7 +12,7 @@ pub const SERVER_NAME: &str = "hyperhive";
|
|||
|
||||
/// Default loopback port the built-in hyperhive MCP surface is served on
|
||||
/// (streamable HTTP, via the persistent `hive-mcp-http` daemon). Overridable
|
||||
/// via `hyperhive.mcp.httpPort`; **must match that option's default** in
|
||||
/// via `services.hyperhive.agent.mcp.httpPort`; **must match that option's default** in
|
||||
/// `nix/agent-modules/mcp.nix`. Safe as a single fixed value across all
|
||||
/// agents because each container runs in its own private network namespace,
|
||||
/// so `127.0.0.1:<port>` is per-container-private (no cross-agent collision).
|
||||
|
|
@ -65,7 +65,7 @@ fn allowed_capability_tools() -> Vec<String> {
|
|||
|
||||
/// Tool group an extra (out-of-process) MCP server is gated behind, if any.
|
||||
///
|
||||
/// Most `hyperhive.extraMcpServers` entries are ungated — available whenever
|
||||
/// Most `services.hyperhive.agent.extraMcpServers` entries are ungated — available whenever
|
||||
/// the operator declares them. The `bash` server is the exception: raw shell
|
||||
/// execution is a privilege, so it is only exposed when the agent holds the
|
||||
/// `Execution` tool group. Unlike the in-process hyperhive tools (gated at
|
||||
|
|
@ -135,7 +135,7 @@ pub fn allowed_mcp_tools(groups: &[hive_sh4re::permissions::ToolGroup]) -> Vec<S
|
|||
.filter(|t| seen.insert(*t))
|
||||
.map(|t| format!("mcp__{SERVER_NAME}__{t}"))
|
||||
.collect();
|
||||
// Extra MCP servers declared via `hyperhive.extraMcpServers` in
|
||||
// Extra MCP servers declared via `services.hyperhive.agent.extraMcpServers` in
|
||||
// the agent's NixOS config. Each entry maps its `allowedTools`
|
||||
// pattern list to `mcp__<server>__<pattern>` so claude can call
|
||||
// them without per-tool operator approval. `["*"]` (the default)
|
||||
|
|
@ -177,7 +177,7 @@ pub fn allowed_tools_arg() -> String {
|
|||
/// The built-in `hyperhive` surface is an HTTP entry pointing at the
|
||||
/// persistent `hive-mcp-http` daemon (see [`DEFAULT_MCP_HTTP_PORT`]); there
|
||||
/// is no per-turn stdio child for it. Merges in any extra MCP servers
|
||||
/// declared via `hyperhive.extraMcpServers` — each one is either a
|
||||
/// declared via `services.hyperhive.agent.extraMcpServers` — each one is either a
|
||||
/// per-turn stdio bridge or another persistent HTTP entry, per its own
|
||||
/// `type`.
|
||||
#[must_use]
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
//! Boot-time `claude plugin install` driver. Reads the list declared
|
||||
//! via the `hyperhive.claudePlugins` NixOS option (rendered to
|
||||
//! via the `services.hyperhive.agent.claudePlugins` NixOS option (rendered to
|
||||
//! `/etc/hyperhive/claude-plugins.json` by the harness module) and
|
||||
//! shells out `claude plugin install <spec>` for each entry. Runs once
|
||||
//! per harness boot before the turn loop; `claude plugin install`
|
||||
|
|
@ -62,7 +62,7 @@ async fn add_marketplaces() {
|
|||
}
|
||||
}
|
||||
|
||||
/// Read the `hyperhive.claudePluginsAutoUpdate` flag written by the NixOS
|
||||
/// Read the `services.hyperhive.agent.claudePluginsAutoUpdate` flag written by the NixOS
|
||||
/// module. Defaults to `false` when the file is absent or unparseable.
|
||||
async fn auto_update_enabled() -> bool {
|
||||
match tokio::fs::read_to_string(AUTO_UPDATE_PATH).await {
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ pub fn render(
|
|||
.replace("{operator_pronouns}", operator_pronouns)
|
||||
.replace("{hive_identity}", &hive_identity)
|
||||
.replace("{swarm_identity}", &swarm_identity);
|
||||
// When the reference docs are mounted in-container (`hyperhive.docs.enable`
|
||||
// When the reference docs are mounted in-container (`services.hyperhive.agent.docs.enable`
|
||||
// wires `HIVE_DOCS_DIR` + `claude --add-dir`), append a single pointer
|
||||
// sentence so the agent knows they exist. Additive: it doesn't replace the
|
||||
// agent's own memory/project instructions. Absent env → no change.
|
||||
|
|
@ -129,7 +129,7 @@ pub async fn write_system_prompt(_socket: &Path, label: &str) -> Result<PathBuf>
|
|||
// verbatim (single-hive deployments see no diff).
|
||||
let hive_name = crate::identity::hive_name();
|
||||
let swarm_name = crate::identity::swarm_name();
|
||||
// `hyperhive.docs.enable` sets HIVE_DOCS_DIR (and the harness passes it to
|
||||
// `services.hyperhive.agent.docs.enable` sets HIVE_DOCS_DIR (and the harness passes it to
|
||||
// claude via `--add-dir`); when present, render() appends a pointer line.
|
||||
let docs_dir = std::env::var("HIVE_DOCS_DIR")
|
||||
.ok()
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@ impl TurnFiles {
|
|||
/// Drop the MCP config blob claude reads from `--mcp-config <path>`.
|
||||
/// The built-in hyperhive surface is served over HTTP by the persistent
|
||||
/// `hive-mcp-http` daemon, so no per-turn stdio child is spawned; extra
|
||||
/// servers declared via `hyperhive.extraMcpServers` are still stdio bridges.
|
||||
/// servers declared via `services.hyperhive.agent.extraMcpServers` are still stdio bridges.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
|
|
@ -576,7 +576,7 @@ fn session_store() -> hive_claude::SessionStore {
|
|||
/// tool allow-lists and the optional docs `--add-dir`.
|
||||
fn claude_config(bus: &Bus, files: &TurnFiles) -> Config {
|
||||
let mut add_dirs = Vec::new();
|
||||
// hyperhive.docs.enable wires HIVE_DOCS_DIR to the in-container reference
|
||||
// services.hyperhive.agent.docs.enable wires HIVE_DOCS_DIR to the in-container reference
|
||||
// docs; expose it as an additional readable directory when set.
|
||||
if let Some(docs_dir) = std::env::var_os("HIVE_DOCS_DIR")
|
||||
&& !docs_dir.is_empty()
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ pub async fn serve(
|
|||
.map(PathBuf::from)
|
||||
.context(
|
||||
"HIVE_STATIC_DIR env var not set — point it at the merged \
|
||||
per-agent dist (see hyperhive.frontend.mergedDist in nix)",
|
||||
per-agent dist (see services.hyperhive.agent.frontend.mergedDist in nix)",
|
||||
)?;
|
||||
if !static_dir.is_dir() {
|
||||
anyhow::bail!(
|
||||
|
|
@ -130,7 +130,7 @@ pub async fn serve(
|
|||
.route("/api/stats", get(stats::api_stats))
|
||||
.route("/screen/ws", get(screen::screen_ws))
|
||||
.route("/icon", get(screen::serve_icon));
|
||||
// Mount any `hyperhive.extraWebProxies` under `/extra/<name>/` before the
|
||||
// Mount any `services.hyperhive.agent.extraWebProxies` under `/extra/<name>/` before the
|
||||
// static fallback so declared proxies win over `ServeDir`.
|
||||
let app = proxy::mount_extra_proxies(app)
|
||||
// Anything else (`/`, `/stats`, `/screen`, `/static/*`)
|
||||
|
|
@ -139,7 +139,7 @@ pub async fn serve(
|
|||
// (so `/stats` → `dist/stats.html`, `/screen` → `dist/
|
||||
// screen.html`). Per-agent `extraFiles` additions are
|
||||
// already layered into this same directory (see
|
||||
// hyperhive.frontend.mergedDist in nix).
|
||||
// services.hyperhive.agent.frontend.mergedDist in nix).
|
||||
.fallback_service(ServeDir::new(&static_dir))
|
||||
.with_state(state);
|
||||
// `HIVE_WEB_SOCKET` opt-in: when set + non-empty, bind a
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
//! Extra web proxies (`HIVE_EXTRA_WEB_PROXIES` / `hyperhive.extraWebProxies`).
|
||||
//! Extra web proxies (`HIVE_EXTRA_WEB_PROXIES` / `services.hyperhive.agent.extraWebProxies`).
|
||||
//!
|
||||
//! Each declared entry mounts a transparent reverse-proxy at `/extra/<name>/`
|
||||
//! in the per-agent web UI, forwarding every request (method, headers, body)
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ use tokio::io::{AsyncReadExt, AsyncWriteExt};
|
|||
use super::AppState;
|
||||
|
||||
/// This agent's icon. Serves the operator-configured SVG from
|
||||
/// `/etc/hyperhive/icon.svg` (set via the `hyperhive.icon` agent.nix
|
||||
/// `/etc/hyperhive/icon.svg` (set via the `services.hyperhive.agent.icon` agent.nix
|
||||
/// option) when present, otherwise **404** — there is no bundled
|
||||
/// server-side default any more (that was `hive_sh4re::assets::
|
||||
/// branding_svg`, now removed). Consumers fall back client-side: the
|
||||
|
|
|
|||
|
|
@ -255,7 +255,7 @@ enum AgentLinkKind {
|
|||
/// `http://<host>:3000<url>`.
|
||||
Forge,
|
||||
/// `url` is already a fully-qualified absolute URL — use as-is.
|
||||
/// Agent-declared `hyperhive.dashboardLinks` extras arrive here.
|
||||
/// Agent-declared `services.hyperhive.agent.dashboardLinks` extras arrive here.
|
||||
External,
|
||||
}
|
||||
|
||||
|
|
@ -366,7 +366,7 @@ fn agent_links(label: &str, gui_enabled: bool) -> Vec<AgentLink> {
|
|||
});
|
||||
}
|
||||
|
||||
// Agent-declared extras (`hyperhive.dashboardLinks` → the
|
||||
// Agent-declared extras (`services.hyperhive.agent.dashboardLinks` → the
|
||||
// `hive-dashboard-links` NixOS oneshot writes them to
|
||||
// `{state_dir}/hyperhive-dashboard-links.json`). Shape on disk
|
||||
// is `{label, icon, url}` with absolute URLs — those become
|
||||
|
|
|
|||
Loading…
Reference in a new issue