refactor(#2464): rename hive-ag3nt crate to hive-agent, collapse lib into main
This commit is contained in:
parent
7b54e7aa50
commit
3f1643c594
57 changed files with 101 additions and 130 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
|
@ -1460,7 +1460,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c"
|
checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hive-ag3nt"
|
name = "hive-agent"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
[workspace]
|
[workspace]
|
||||||
resolver = "3"
|
resolver = "3"
|
||||||
members = [
|
members = [
|
||||||
"hive-ag3nt",
|
"hive-agent",
|
||||||
"hive-agent-mcp",
|
"hive-agent-mcp",
|
||||||
"hive-agent-wake",
|
"hive-agent-wake",
|
||||||
"hive-bash-mcp",
|
"hive-bash-mcp",
|
||||||
|
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
//! Shared in-container harness code for the sibling `hive-agent` /
|
|
||||||
//! `hive-agent-mcp` / `hive-agent-wake` binaries, which serve every
|
|
||||||
//! agent role (the manager is just an agent role, not a separate set
|
|
||||||
//! of binaries).
|
|
||||||
|
|
||||||
pub mod client;
|
|
||||||
pub mod events;
|
|
||||||
pub mod forge_notify;
|
|
||||||
pub mod harness_state;
|
|
||||||
pub mod identity;
|
|
||||||
pub mod login;
|
|
||||||
pub mod login_session;
|
|
||||||
pub mod mcp_config;
|
|
||||||
pub mod paths;
|
|
||||||
pub mod plugins;
|
|
||||||
pub mod prompt;
|
|
||||||
pub mod serve_common;
|
|
||||||
pub mod stats;
|
|
||||||
pub mod turn;
|
|
||||||
pub mod turn_stats;
|
|
||||||
pub mod vacuum;
|
|
||||||
pub mod web_ui;
|
|
||||||
|
|
||||||
/// Default socket path inside the container — bind-mounted by `hive-c0re`.
|
|
||||||
pub const DEFAULT_SOCKET: &str = "/run/hive/mcp.sock";
|
|
||||||
|
|
||||||
/// Default web UI port — used when `HIVE_PORT` env is unset.
|
|
||||||
pub const DEFAULT_WEB_PORT: u16 = 8042;
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
//!
|
//!
|
||||||
//! Standalone bin crate: the MCP surface (`mcp/`) plus its small support
|
//! Standalone bin crate: the MCP surface (`mcp/`) plus its small support
|
||||||
//! modules (socket client, send allow-list, loose-end scanner, path
|
//! modules (socket client, send allow-list, loose-end scanner, path
|
||||||
//! resolver) live here rather than in the `hive-ag3nt` harness lib, so the
|
//! resolver) live here rather than in the `hive-agent` harness lib, so the
|
||||||
//! server binary doesn't link the whole turn loop.
|
//! server binary doesn't link the whole turn loop.
|
||||||
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
//!
|
//!
|
||||||
//! Standalone bin crate: it dials the per-agent MCP socket directly and
|
//! Standalone bin crate: it dials the per-agent MCP socket directly and
|
||||||
//! carries its own copy of the retrying request client (below), so it
|
//! carries its own copy of the retrying request client (below), so it
|
||||||
//! does not link the whole `hive-ag3nt` harness lib — a helper author
|
//! does not link the whole `hive-agent` harness lib — a helper author
|
||||||
//! wiring up an `extraMcpServers` binary only needs this one small crate.
|
//! wiring up an `extraMcpServers` binary only needs this one small crate.
|
||||||
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
@ -66,7 +66,7 @@ async fn main() -> Result<()> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Self-contained retrying unix-socket JSON request client. A trimmed
|
/// Self-contained retrying unix-socket JSON request client. A trimmed
|
||||||
/// copy of `hive_ag3nt::client` (no `request_retried` variant — the wake
|
/// copy of `hive_agent::client` (no `request_retried` variant — the wake
|
||||||
/// CLI never needs the retry-count) so this bin does not link the harness
|
/// CLI never needs the retry-count) so this bin does not link the harness
|
||||||
/// lib. Keeping the retry matters: the socket can be briefly absent while
|
/// lib. Keeping the retry matters: the socket can be briefly absent while
|
||||||
/// hive-c0re restarts under an operator redeploy, and a helper firing a
|
/// hive-c0re restarts under an operator redeploy, and a helper firing a
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
[package]
|
[package]
|
||||||
name = "hive-ag3nt"
|
name = "hive-agent"
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
version.workspace = true
|
version.workspace = true
|
||||||
|
|
||||||
|
|
@ -34,8 +34,8 @@ tracing-subscriber.workspace = true
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
tempfile = "3"
|
tempfile = "3"
|
||||||
|
|
||||||
# Three sibling harness binaries for all agents (auto-discovered from
|
# Single harness serve-loop binary: `hive-agent` (from `src/main.rs`).
|
||||||
# `src/bin/`): `hive-agent` (serve loop), `hive-agent-mcp` (MCP
|
# The sibling MCP server + external wake CLI are their own bin crates
|
||||||
# server), `hive-agent-wake` (wake CLI). Privilege boundary is
|
# now (`hive-agent-mcp`, `hive-agent-wake`). Privilege boundary is
|
||||||
# enforced server-side at the socket (tool groups / manager surface).
|
# enforced server-side at the socket (tool groups / manager surface).
|
||||||
# See `docs/turn-loop.md::Harness binary shape`.
|
# See `docs/turn-loop.md::Harness binary shape`.
|
||||||
|
|
@ -184,11 +184,6 @@ impl EventStore {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn recent(&self, limit: usize) -> rusqlite::Result<Vec<StoredEvent>> {
|
|
||||||
let (events, _, _) = self.page(None, limit)?;
|
|
||||||
Ok(events)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Fetch up to `limit` events with id < `before_id` (or the most recent
|
/// Fetch up to `limit` events with id < `before_id` (or the most recent
|
||||||
/// `limit` events when `before_id` is `None`). Returns
|
/// `limit` events when `before_id` is `None`). Returns
|
||||||
/// `(events_oldest_first, min_row_id, has_more)`.
|
/// `(events_oldest_first, min_row_id, has_more)`.
|
||||||
|
|
@ -818,17 +813,6 @@ impl Bus {
|
||||||
self.tx.subscribe()
|
self.tx.subscribe()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Most recent events, oldest first, capped at `HISTORY_CAPACITY`.
|
|
||||||
/// Drives the terminal pre-fill when the operator opens the agent
|
|
||||||
/// page; without a store (db open failed) this is empty.
|
|
||||||
#[must_use]
|
|
||||||
pub fn history(&self) -> Vec<StoredEvent> {
|
|
||||||
let Some(store) = &self.store else {
|
|
||||||
return Vec::new();
|
|
||||||
};
|
|
||||||
store.recent(HISTORY_CAPACITY).unwrap_or_default()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Paginated history: up to `limit` events before `before_id`
|
/// Paginated history: up to `limit` events before `before_id`
|
||||||
/// (or the most recent `limit` when `before_id` is `None`).
|
/// (or the most recent `limit` when `before_id` is `None`).
|
||||||
/// Returns `(events_oldest_first, min_row_id, has_more)`.
|
/// Returns `(events_oldest_first, min_row_id, has_more)`.
|
||||||
|
|
@ -48,25 +48,6 @@ pub fn swarm_name() -> Option<String> {
|
||||||
non_empty_env("HYPERHIVE_SWARM_NAME")
|
non_empty_env("HYPERHIVE_SWARM_NAME")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// One peer hive in the same swarm. Parsed from `HYPERHIVE_PEERS`.
|
|
||||||
#[derive(Debug, Clone, serde::Deserialize)]
|
|
||||||
pub struct PeerHive {
|
|
||||||
pub domain: String,
|
|
||||||
pub cert_fingerprint: Option<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Peer hives in the same swarm, parsed from `HYPERHIVE_PEERS` env var
|
|
||||||
/// (JSON array of `{domain, cert_fingerprint}` objects, emitted by the
|
|
||||||
/// c0re NixOS module from `services.hyperhive.swarm.peers`). Returns
|
|
||||||
/// empty vec on single-hive deploys (env var absent).
|
|
||||||
#[must_use]
|
|
||||||
pub fn peers() -> Vec<PeerHive> {
|
|
||||||
env::var("HYPERHIVE_PEERS")
|
|
||||||
.ok()
|
|
||||||
.and_then(|s| serde_json::from_str(&s).ok())
|
|
||||||
.unwrap_or_default()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Hive-qualified agent identity. When the hive domain is configured, returns
|
/// Hive-qualified agent identity. When the hive domain is configured, returns
|
||||||
/// `${label}@${domain}` (e.g. `iris@darkest.space`); when not, returns just
|
/// `${label}@${domain}` (e.g. `iris@darkest.space`); when not, returns just
|
||||||
/// the short label so callers can render a single string regardless of
|
/// the short label so callers can render a single string regardless of
|
||||||
|
|
@ -5,17 +5,43 @@
|
||||||
//! loop points claude at) and `hive-agent-wake` (external wake CLI).
|
//! loop points claude at) and `hive-agent-wake` (external wake CLI).
|
||||||
//! Architecture lives in
|
//! Architecture lives in
|
||||||
//! [`docs/turn-loop.md::Harness binary shape`](../../../docs/turn-loop.md).
|
//! [`docs/turn-loop.md::Harness binary shape`](../../../docs/turn-loop.md).
|
||||||
|
//!
|
||||||
|
//! Single bin crate: the module tree below (formerly this crate's `lib.rs`,
|
||||||
|
//! before lib + bin were collapsed into one) plus the serve loop.
|
||||||
|
|
||||||
|
mod client;
|
||||||
|
mod events;
|
||||||
|
mod forge_notify;
|
||||||
|
mod harness_state;
|
||||||
|
mod identity;
|
||||||
|
mod login;
|
||||||
|
mod login_session;
|
||||||
|
mod mcp_config;
|
||||||
|
mod paths;
|
||||||
|
mod plugins;
|
||||||
|
mod prompt;
|
||||||
|
mod serve_common;
|
||||||
|
mod stats;
|
||||||
|
mod turn;
|
||||||
|
mod turn_stats;
|
||||||
|
mod vacuum;
|
||||||
|
mod web_ui;
|
||||||
|
|
||||||
|
/// Default socket path inside the container — bind-mounted by `hive-c0re`.
|
||||||
|
const DEFAULT_SOCKET: &str = "/run/hive/mcp.sock";
|
||||||
|
|
||||||
|
/// Default web UI port — used when `HIVE_PORT` env is unset.
|
||||||
|
const DEFAULT_WEB_PORT: u16 = 8042;
|
||||||
|
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
|
use crate::events::{Bus, LiveEvent, TurnState};
|
||||||
|
use crate::login::LoginState;
|
||||||
|
use crate::turn_stats::TurnStats;
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use hive_ag3nt::events::{Bus, LiveEvent, TurnState};
|
|
||||||
use hive_ag3nt::login::{self, LoginState};
|
|
||||||
use hive_ag3nt::turn_stats::TurnStats;
|
|
||||||
use hive_ag3nt::{DEFAULT_SOCKET, DEFAULT_WEB_PORT, client, plugins, serve_common, turn, web_ui};
|
|
||||||
use hive_sh4re::{AgentRequest, AgentResponse, HelperEvent, SYSTEM_SENDER};
|
use hive_sh4re::{AgentRequest, AgentResponse, HelperEvent, SYSTEM_SENDER};
|
||||||
|
|
||||||
#[derive(Parser)]
|
#[derive(Parser)]
|
||||||
|
|
@ -72,7 +98,7 @@ fn log_system_event(bus: &Bus, from: &str, body: &str) {
|
||||||
/// Falls back to `<unknown>` when `HIVE_LABEL` is missing so a
|
/// Falls back to `<unknown>` when `HIVE_LABEL` is missing so a
|
||||||
/// misconfigured harness still produces a parseable line.
|
/// misconfigured harness still produces a parseable line.
|
||||||
fn format_turn_failure(err: &anyhow::Error) -> String {
|
fn format_turn_failure(err: &anyhow::Error) -> String {
|
||||||
let who = hive_ag3nt::identity::qualified_label();
|
let who = crate::identity::qualified_label();
|
||||||
let who = if who.is_empty() {
|
let who = if who.is_empty() {
|
||||||
"<unknown>".to_owned()
|
"<unknown>".to_owned()
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -87,7 +113,7 @@ fn format_turn_failure(err: &anyhow::Error) -> String {
|
||||||
/// the role-specific `Wake` request — the sentinel itself is wire-
|
/// the role-specific `Wake` request — the sentinel itself is wire-
|
||||||
/// agnostic so this helper lives outside both surfaces.
|
/// agnostic so this helper lives outside both surfaces.
|
||||||
fn consume_continue_sentinel() -> bool {
|
fn consume_continue_sentinel() -> bool {
|
||||||
let sentinel = hive_ag3nt::paths::state_dir().join("hyperhive-continue");
|
let sentinel = crate::paths::state_dir().join("hyperhive-continue");
|
||||||
if !sentinel.exists() {
|
if !sentinel.exists() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -374,11 +400,11 @@ async fn serve_main<S: Surface>(socket: &Path, poll_ms: u64) -> Result<()> {
|
||||||
for failure in plugins::install_configured().await {
|
for failure in plugins::install_configured().await {
|
||||||
S::send_to_parent(socket, failure).await;
|
S::send_to_parent(socket, failure).await;
|
||||||
}
|
}
|
||||||
tokio::spawn(hive_ag3nt::forge_notify::run(socket.to_path_buf()));
|
tokio::spawn(crate::forge_notify::run(socket.to_path_buf()));
|
||||||
// Agent-side cleanup of this agent's own harness artifacts (completed
|
// Agent-side cleanup of this agent's own harness artifacts (completed
|
||||||
// bash-task files + verbose event rows). Runs here, not host-side in
|
// bash-task files + verbose event rows). Runs here, not host-side in
|
||||||
// hive-c0re, because the files are agent-owned — see `vacuum` module docs.
|
// hive-c0re, because the files are agent-owned — see `vacuum` module docs.
|
||||||
tokio::spawn(hive_ag3nt::vacuum::run());
|
tokio::spawn(crate::vacuum::run());
|
||||||
// Log web_ui::serve's error instead of dropping it. A bare
|
// Log web_ui::serve's error instead of dropping it. A bare
|
||||||
// `tokio::spawn(web_ui::serve(...))` discards the JoinHandle, so
|
// `tokio::spawn(web_ui::serve(...))` discards the JoinHandle, so
|
||||||
// any Err (e.g. EACCES from `bind_unix` when HIVE_WEB_SOCKET points
|
// any Err (e.g. EACCES from `bind_unix` when HIVE_WEB_SOCKET points
|
||||||
|
|
@ -171,7 +171,7 @@ mod tests {
|
||||||
// no file open at compile, so this still doesn't pull
|
// no file open at compile, so this still doesn't pull
|
||||||
// `prompts/` into the build hash.
|
// `prompts/` into the build hash.
|
||||||
// The combined effect is that the flake's `cleanSrc` no longer
|
// The combined effect is that the flake's `cleanSrc` no longer
|
||||||
// unions `./hive-ag3nt/prompts` — tweaks to system.md don't bust
|
// unions `./hive-agent/prompts` — tweaks to system.md don't bust
|
||||||
// the cargo cache anymore.
|
// the cargo cache anymore.
|
||||||
static PRODUCTION_TEMPLATE: LazyLock<String> = LazyLock::new(|| {
|
static PRODUCTION_TEMPLATE: LazyLock<String> = LazyLock::new(|| {
|
||||||
let path = match std::env::var("HIVE_ASSETS_DIR") {
|
let path = match std::env::var("HIVE_ASSETS_DIR") {
|
||||||
|
|
@ -185,11 +185,19 @@ pub struct KeyCount {
|
||||||
pub count: u64,
|
pub count: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Field names drop the `_ms` unit suffix (satisfies `clippy::struct_field_names`
|
||||||
|
// once this crate is a bin — pub structs lose the lib API-name exemption), but
|
||||||
|
// the serialized keys keep `_ms` via `serde(rename)` so the `/api/stats` JSON
|
||||||
|
// contract the agent web UI reads (`frontend/packages/agent/src/stats.js`) is
|
||||||
|
// unchanged.
|
||||||
#[derive(Debug, Default, Serialize)]
|
#[derive(Debug, Default, Serialize)]
|
||||||
pub struct DurationSummary {
|
pub struct DurationSummary {
|
||||||
pub avg_ms: f64,
|
#[serde(rename = "avg_ms")]
|
||||||
pub p50_ms: f64,
|
pub avg: f64,
|
||||||
pub p95_ms: f64,
|
#[serde(rename = "p50_ms")]
|
||||||
|
pub p50: f64,
|
||||||
|
#[serde(rename = "p95_ms")]
|
||||||
|
pub p95: f64,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
|
|
@ -531,9 +539,9 @@ fn summarize_durations(all: &mut [i64]) -> DurationSummary {
|
||||||
)]
|
)]
|
||||||
let len_f = all.len() as f64;
|
let len_f = all.len() as f64;
|
||||||
DurationSummary {
|
DurationSummary {
|
||||||
avg_ms: sum_f / len_f,
|
avg: sum_f / len_f,
|
||||||
p50_ms: percentile(all, 50),
|
p50: percentile(all, 50),
|
||||||
p95_ms: percentile(all, 95),
|
p95: percentile(all, 95),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -686,9 +694,9 @@ mod tests {
|
||||||
assert_eq!(model_totals.get("opus").copied(), Some(2));
|
assert_eq!(model_totals.get("opus").copied(), Some(2));
|
||||||
assert_eq!(model_totals.get("sonnet").copied(), Some(1));
|
assert_eq!(model_totals.get("sonnet").copied(), Some(1));
|
||||||
// Durations: [5000, 10000, 20000] → avg ≈ 11666.67, p50 = 10000, p95 ~ 20000
|
// Durations: [5000, 10000, 20000] → avg ≈ 11666.67, p50 = 10000, p95 ~ 20000
|
||||||
assert!((s.duration_summary.avg_ms - 11_666.666_666_666_666).abs() < 1.0);
|
assert!((s.duration_summary.avg - 11_666.666_666_666_666).abs() < 1.0);
|
||||||
assert!((s.duration_summary.p50_ms - 10_000.0).abs() < 1.0);
|
assert!((s.duration_summary.p50 - 10_000.0).abs() < 1.0);
|
||||||
assert!((s.duration_summary.p95_ms - 20_000.0).abs() < 1.0);
|
assert!((s.duration_summary.p95 - 20_000.0).abs() < 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
@ -48,7 +48,7 @@ async fn round_trip(req: DaemonRequest) -> Result<DaemonResponse> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Format a `TaskFile` JSON value as a human-readable status string.
|
/// Format a `TaskFile` JSON value as a human-readable status string.
|
||||||
/// Mirrors `format_bash_status` in the old hive-ag3nt, adapted to work
|
/// Mirrors `format_bash_status` in the old hive-agent, adapted to work
|
||||||
/// from the daemon's JSON payload.
|
/// from the daemon's JSON payload.
|
||||||
fn format_task(id: &str, task: &serde_json::Value) -> String {
|
fn format_task(id: &str, task: &serde_json::Value) -> String {
|
||||||
let status = task["status"].as_str().unwrap_or("unknown");
|
let status = task["status"].as_str().unwrap_or("unknown");
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
// `TaskFile` + `TaskStatus` are the bash-task on-disk schema. They live in
|
// `TaskFile` + `TaskStatus` are the bash-task on-disk schema. They live in
|
||||||
// `hive-sh4re` (the shared wire-types crate) so the agent web UI in
|
// `hive-sh4re` (the shared wire-types crate) so the agent web UI in
|
||||||
// `hive-ag3nt` can deserialize the same canonical type when reading the
|
// `hive-agent` can deserialize the same canonical type when reading the
|
||||||
// tasks dir for its running-tasks panel — no parallel copy to drift. Both
|
// tasks dir for its running-tasks panel — no parallel copy to drift. Both
|
||||||
// are re-exported here so existing `crate::protocol::{TaskFile, TaskStatus}`
|
// are re-exported here so existing `crate::protocol::{TaskFile, TaskStatus}`
|
||||||
// imports across this crate keep compiling unchanged.
|
// imports across this crate keep compiling unchanged.
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ pub fn check_size(label: &str, body: &str) -> Result<(), String> {
|
||||||
/// payload. Cap at 200 chars to fit the chip plus a little
|
/// payload. Cap at 200 chars to fit the chip plus a little
|
||||||
/// descriptive padding without forcing the operator to read a
|
/// descriptive padding without forcing the operator to read a
|
||||||
/// scrolling chunk.
|
/// scrolling chunk.
|
||||||
/// NOTE: `hive-ag3nt/src/mcp.rs::write_status_file` mirrors this constant
|
/// NOTE: `hive-agent/src/mcp.rs::write_status_file` mirrors this constant
|
||||||
/// client-side so invalid text is caught before the file is written.
|
/// client-side so invalid text is caught before the file is written.
|
||||||
/// Keep in sync if this value changes.
|
/// Keep in sync if this value changes.
|
||||||
pub const STATUS_MAX_CHARS: usize = 200;
|
pub const STATUS_MAX_CHARS: usize = 200;
|
||||||
|
|
|
||||||
|
|
@ -1178,7 +1178,7 @@ fn choom(name: &str, resume_session: Option<&str>) -> Result<()> {
|
||||||
// right `$HOME/.claude`.
|
// right `$HOME/.claude`.
|
||||||
let target = format!("{name}@{container}");
|
let target = format!("{name}@{container}");
|
||||||
let claude = "/run/current-system/sw/bin/claude";
|
let claude = "/run/current-system/sw/bin/claude";
|
||||||
// Bind-mounted state dir; matches `hive-ag3nt::paths::state_dir()`.
|
// Bind-mounted state dir; matches `hive-agent::paths::state_dir()`.
|
||||||
let state_dir = format!("/agents/{name}/state");
|
let state_dir = format!("/agents/{name}/state");
|
||||||
// Per-turn config the harness writes; matches `paths::config_dir()`.
|
// Per-turn config the harness writes; matches `paths::config_dir()`.
|
||||||
let cfg = "/run/hive-config";
|
let cfg = "/run/hive-config";
|
||||||
|
|
|
||||||
|
|
@ -109,7 +109,7 @@ pub async fn build_all(coord: &Coordinator) -> Vec<ContainerView> {
|
||||||
out
|
out
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Host-side mirror of `hive_ag3nt::login::has_session`. Returns true
|
/// Host-side mirror of `hive_agent::login::has_session`. Returns true
|
||||||
/// if the agent's bound `~/.claude/` dir on disk contains any regular
|
/// if the agent's bound `~/.claude/` dir on disk contains any regular
|
||||||
/// file. Reads each `build_all()` so a login driven from the agent's
|
/// file. Reads each `build_all()` so a login driven from the agent's
|
||||||
/// own web UI reflects on the next snapshot.
|
/// own web UI reflects on the next snapshot.
|
||||||
|
|
@ -225,7 +225,7 @@ fn read_active_model(name: &str) -> Option<String> {
|
||||||
/// Host-side hive + swarm display names, read from the c0re service's
|
/// Host-side hive + swarm display names, read from the c0re service's
|
||||||
/// own process env. The `hive-c0re.nix` module sets these from
|
/// own process env. The `hive-c0re.nix` module sets these from
|
||||||
/// `services.hyperhive.{hiveName, swarmName}`. The agent-side
|
/// `services.hyperhive.{hiveName, swarmName}`. The agent-side
|
||||||
/// `hive-ag3nt::identity::{hive_name, swarm_name}` accessors read the
|
/// `hive-agent::identity::{hive_name, swarm_name}` accessors read the
|
||||||
/// same env vars after they're forwarded into each sub-agent's
|
/// same env vars after they're forwarded into each sub-agent's
|
||||||
/// harness service environment by `meta::render_flake`; surfacing
|
/// harness service environment by `meta::render_flake`; surfacing
|
||||||
/// them here from c0re's own env keeps the manager + agent
|
/// them here from c0re's own env keeps the manager + agent
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ use crate::lifecycle;
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
pub(super) struct JournalQuery {
|
pub(super) struct JournalQuery {
|
||||||
/// Optional systemd unit filter — e.g. `hive-ag3nt.service`. When
|
/// Optional systemd unit filter — e.g. `hive-agent.service`. When
|
||||||
/// omitted, returns the full machine journal.
|
/// omitted, returns the full machine journal.
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
unit: Option<String>,
|
unit: Option<String>,
|
||||||
|
|
@ -57,8 +57,8 @@ pub(super) async fn get_journal(
|
||||||
let lines = q.lines.unwrap_or(500).min(5000);
|
let lines = q.lines.unwrap_or(500).min(5000);
|
||||||
let unit = match q.unit.as_deref().filter(|s| !s.is_empty()) {
|
let unit = match q.unit.as_deref().filter(|s| !s.is_empty()) {
|
||||||
Some(u) => {
|
Some(u) => {
|
||||||
// accept hive-ag3nt[.service] — anything else refused.
|
// accept hive-agent[.service] — anything else refused.
|
||||||
let allowed = ["hive-ag3nt.service"];
|
let allowed = ["hive-agent.service"];
|
||||||
let unit = if u.ends_with(".service") {
|
let unit = if u.ends_with(".service") {
|
||||||
u.to_owned()
|
u.to_owned()
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -495,7 +495,7 @@ async fn cmd_serve(
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// Per-agent events.sqlite + bash-tasks file cleanup now runs
|
// Per-agent events.sqlite + bash-tasks file cleanup now runs
|
||||||
// agent-side in the harness (`hive_ag3nt::vacuum`): the files are
|
// agent-side in the harness (`hive_agent::vacuum`): the files are
|
||||||
// agent-owned, so host-side deletes hit PermissionDenied / readonly-db
|
// agent-owned, so host-side deletes hit PermissionDenied / readonly-db
|
||||||
// under privsep. See issue tracker "perms borked".
|
// under privsep. See issue tracker "perms borked".
|
||||||
// (turn-stats.sqlite has no vacuum — it's one tiny row per turn,
|
// (turn-stats.sqlite has no vacuum — it's one tiny row per turn,
|
||||||
|
|
|
||||||
|
|
@ -959,7 +959,7 @@ where
|
||||||
then hyperhive.nixosConfigurations.ruth
|
then hyperhive.nixosConfigurations.ruth
|
||||||
else hyperhive.nixosConfigurations.agent-base;
|
else hyperhive.nixosConfigurations.agent-base;
|
||||||
input = inputs."agent-${name}";
|
input = inputs."agent-${name}";
|
||||||
service = "hive-ag3nt";
|
service = "hive-agent";
|
||||||
parentEnv = if parent == null then {} else { HIVE_PARENT = parent; };
|
parentEnv = if parent == null then {} else { HIVE_PARENT = parent; };
|
||||||
toolGroupsEnv = if toolGroups == null then {} else { HIVE_TOOL_GROUPS = toolGroups; };
|
toolGroupsEnv = if toolGroups == null then {} else { HIVE_TOOL_GROUPS = toolGroups; };
|
||||||
capabilitiesEnv = if capabilities == null then {} else { HIVE_CAPABILITIES = capabilities; };
|
capabilitiesEnv = if capabilities == null then {} else { HIVE_CAPABILITIES = capabilities; };
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
//! swarm totals + a per-agent rollup + model mix + a *labelled*
|
//! swarm totals + a per-agent rollup + model mix + a *labelled*
|
||||||
//! cost estimate.
|
//! cost estimate.
|
||||||
//!
|
//!
|
||||||
//! Why re-read the rows here instead of reusing `hive-ag3nt`'s
|
//! Why re-read the rows here instead of reusing `hive-agent`'s
|
||||||
//! `stats.rs`: that module lives in a different crate (the agent
|
//! `stats.rs`: that module lives in a different crate (the agent
|
||||||
//! harness) which hive-c0re can't import. The stable contract is the
|
//! harness) which hive-c0re can't import. The stable contract is the
|
||||||
//! turn-stats *schema*, so we run a focused query against it. If we
|
//! turn-stats *schema*, so we run a focused query against it. If we
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
//! Wake-signal writer: notifies the hyperhive harness when an incoming
|
//! Wake-signal writer: notifies the hyperhive harness when an incoming
|
||||||
//! matrix event arrives so claude drives a new turn.
|
//! matrix event arrives so claude drives a new turn.
|
||||||
//!
|
//!
|
||||||
//! Same wire shape as `hive-ag3nt::forge_notify`'s wake: a single JSON
|
//! Same wire shape as `hive-agent::forge_notify`'s wake: a single JSON
|
||||||
//! line written to the hyperhive control socket (`/run/hive/mcp.sock`
|
//! line written to the hyperhive control socket (`/run/hive/mcp.sock`
|
||||||
//! by default) carrying an `AgentRequest::Wake { from, body }`.
|
//! by default) carrying an `AgentRequest::Wake { from, body }`.
|
||||||
//! The agent harness's `agent_server` parses it and treats it as a
|
//! The agent harness's `agent_server` parses it and treats it as a
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,7 @@ pub fn config_org_avatar_png() -> PathBuf {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// `$HIVE_ASSETS_DIR/prompts/system.md` — the claude system prompt
|
/// `$HIVE_ASSETS_DIR/prompts/system.md` — the claude system prompt
|
||||||
/// template. `hive-ag3nt::prompt::render` filters the role markers
|
/// template. `hive-agent::prompt::render` filters the role markers
|
||||||
/// inside it per agent / manager flavor.
|
/// inside it per agent / manager flavor.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn prompt_template() -> PathBuf {
|
pub fn prompt_template() -> PathBuf {
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ pub mod wire_time;
|
||||||
/// above the cap silently clamps. 5 keeps individual turns small — a big
|
/// above the cap silently clamps. 5 keeps individual turns small — a big
|
||||||
/// backlog is drained over several recv calls instead of one giant pop.
|
/// backlog is drained over several recv calls instead of one giant pop.
|
||||||
/// Lives here so both the enforcing side (hive-c0re's `socket_server`) and
|
/// Lives here so both the enforcing side (hive-c0re's `socket_server`) and
|
||||||
/// the hinting side (hive-ag3nt's wake prompt + tool docs) reference one
|
/// the hinting side (hive-agent's wake prompt + tool docs) reference one
|
||||||
/// constant instead of a scattered magic value.
|
/// constant instead of a scattered magic value.
|
||||||
pub const RECV_BATCH_MAX: u32 = 5;
|
pub const RECV_BATCH_MAX: u32 = 5;
|
||||||
|
|
||||||
|
|
@ -294,7 +294,7 @@ pub enum CancelLooseEndKind {
|
||||||
///
|
///
|
||||||
/// Canonical home for the bash-task persisted schema: `hive-bash-mcp`
|
/// Canonical home for the bash-task persisted schema: `hive-bash-mcp`
|
||||||
/// (the daemon that writes the files) re-exports these from its
|
/// (the daemon that writes the files) re-exports these from its
|
||||||
/// `protocol` module, and `hive-ag3nt` (the agent web UI that reads
|
/// `protocol` module, and `hive-agent` (the agent web UI that reads
|
||||||
/// them back for the running-tasks panel) deserializes the same type, so
|
/// them back for the running-tasks panel) deserializes the same type, so
|
||||||
/// the on-disk shape can't drift between writer and reader.
|
/// the on-disk shape can't drift between writer and reader.
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
# The hive-ag3nt harness service itself, plus the per-agent knobs it
|
# The hive-agent harness service itself, plus the per-agent knobs it
|
||||||
# reads from its environment: model selection, effort level,
|
# reads from its environment: model selection, effort level,
|
||||||
# compaction watermark, and the extra reverse-proxies of the per-agent
|
# compaction watermark, and the extra reverse-proxies of the per-agent
|
||||||
# web UI.
|
# web UI.
|
||||||
|
|
@ -176,7 +176,7 @@ in
|
||||||
# docs/agent-hierarchy.md::Harness systemd unit shape. PATH /bin
|
# docs/agent-hierarchy.md::Harness systemd unit shape. PATH /bin
|
||||||
# auto-append behaviour: docs/gotchas.md::systemd.services.*.path
|
# auto-append behaviour: docs/gotchas.md::systemd.services.*.path
|
||||||
# appends /bin to every entry.
|
# appends /bin to every entry.
|
||||||
systemd.services.hive-ag3nt =
|
systemd.services.hive-agent =
|
||||||
let
|
let
|
||||||
binary = "hive-agent";
|
binary = "hive-agent";
|
||||||
in
|
in
|
||||||
|
|
|
||||||
|
|
@ -299,7 +299,7 @@ in
|
||||||
{
|
{
|
||||||
description = "Inject the OTEL auth header into the agent's claude user settings";
|
description = "Inject the OTEL auth header into the agent's claude user settings";
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
before = [ "hive-ag3nt.service" ];
|
before = [ "hive-agent.service" ];
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
Type = "oneshot";
|
Type = "oneshot";
|
||||||
RemainAfterExit = true;
|
RemainAfterExit = true;
|
||||||
|
|
@ -341,7 +341,7 @@ in
|
||||||
systemd.services.hive-claude-onboarding = {
|
systemd.services.hive-claude-onboarding = {
|
||||||
description = "Seed claude onboarding + project-trust so choom skips the walkthrough";
|
description = "Seed claude onboarding + project-trust so choom skips the walkthrough";
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
before = [ "hive-ag3nt.service" ];
|
before = [ "hive-agent.service" ];
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
Type = "oneshot";
|
Type = "oneshot";
|
||||||
RemainAfterExit = true;
|
RemainAfterExit = true;
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
via `claude --add-dir`, so the markdown is readable at
|
via `claude --add-dir`, so the markdown is readable at
|
||||||
`$HIVE_DOCS_DIR/`, and appends a single pointer sentence to the agent's
|
`$HIVE_DOCS_DIR/`, and appends a single pointer sentence to the agent's
|
||||||
system prompt so it knows the docs exist (see
|
system prompt so it knows the docs exist (see
|
||||||
`hive-ag3nt::prompt::render`). Default-on for the root/manager agent
|
`hive-agent::prompt::render`). Default-on for the root/manager agent
|
||||||
(see `../templates/ruth.nix`), off elsewhere; any agent can flip it from its
|
(see `../templates/ruth.nix`), off elsewhere; any agent can flip it from its
|
||||||
`agent.nix`.
|
`agent.nix`.
|
||||||
'';
|
'';
|
||||||
|
|
@ -40,10 +40,10 @@
|
||||||
# The harness reads HIVE_DOCS_DIR and passes it to claude as
|
# The harness reads HIVE_DOCS_DIR and passes it to claude as
|
||||||
# `--add-dir` so the docs are readable, and appends a single
|
# `--add-dir` so the docs are readable, and appends a single
|
||||||
# pointer sentence to the system prompt
|
# pointer sentence to the system prompt
|
||||||
# (hive-ag3nt::prompt::render) telling the agent the docs exist.
|
# (hive-agent::prompt::render) telling the agent the docs exist.
|
||||||
# Source is `hyperhive.docs.source` (the narrow `hyperhive-docs`
|
# Source is `hyperhive.docs.source` (the narrow `hyperhive-docs`
|
||||||
# meta-flake input, or `pkgs.hyperhive-docs` for standalone
|
# meta-flake input, or `pkgs.hyperhive-docs` for standalone
|
||||||
# builds). See hive-ag3nt::turn.
|
# builds). See hive-agent::turn.
|
||||||
HIVE_DOCS_DIR = "${config.hyperhive.docs.source}";
|
HIVE_DOCS_DIR = "${config.hyperhive.docs.source}";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -212,14 +212,14 @@ in
|
||||||
# per-turn MCP registration race). It dials the control socket
|
# per-turn MCP registration race). It dials the control socket
|
||||||
# (`/run/hive/mcp.sock`, the harness binaries' default) fresh on every
|
# (`/run/hive/mcp.sock`, the harness binaries' default) fresh on every
|
||||||
# tool call, so a host-side hive-c0re restart is transparent.
|
# tool call, so a host-side hive-c0re restart is transparent.
|
||||||
# `before = hive-ag3nt` so the URL is already listening by the time
|
# `before = hive-agent` so the URL is already listening by the time
|
||||||
# the harness renders the first turn's config; the harness/claude also
|
# the harness renders the first turn's config; the harness/claude also
|
||||||
# reconnect on their own, so ordering is a latency nicety not a hard
|
# reconnect on their own, so ordering is a latency nicety not a hard
|
||||||
# correctness dep.
|
# correctness dep.
|
||||||
systemd.services.hive-mcp-http = {
|
systemd.services.hive-mcp-http = {
|
||||||
description = "persistent streamable-http MCP daemon for the hyperhive surface";
|
description = "persistent streamable-http MCP daemon for the hyperhive surface";
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
before = [ "hive-ag3nt.service" ];
|
before = [ "hive-agent.service" ];
|
||||||
environment.RUST_LOG = "info";
|
environment.RUST_LOG = "info";
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
ExecStart = "${config.hyperhive.packages.hive-agent-mcp}/bin/hive-agent-mcp --http 127.0.0.1:${toString config.hyperhive.mcp.httpPort}";
|
ExecStart = "${config.hyperhive.packages.hive-agent-mcp}/bin/hive-agent-mcp --http 127.0.0.1:${toString config.hyperhive.mcp.httpPort}";
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
after = [ "local-fs.target" ];
|
after = [ "local-fs.target" ];
|
||||||
# Ordered before every network consumer that does DNS on first
|
# Ordered before every network consumer that does DNS on first
|
||||||
# boot. `hive-ag3nt` (the harness) is the load-bearing one: its
|
# boot. `hive-agent` (the harness) is the load-bearing one: its
|
||||||
# first-turn api.anthropic.com lookup must not race the resolv.conf
|
# first-turn api.anthropic.com lookup must not race the resolv.conf
|
||||||
# rewrite (it only declares `after network.target`, so without this
|
# rewrite (it only declares `after network.target`, so without this
|
||||||
# edge the harness can start before we've fixed resolv.conf and the
|
# edge the harness can start before we've fixed resolv.conf and the
|
||||||
|
|
@ -52,7 +52,7 @@
|
||||||
before = [
|
before = [
|
||||||
"network-online.target"
|
"network-online.target"
|
||||||
"tea-login.service"
|
"tea-login.service"
|
||||||
"hive-ag3nt.service"
|
"hive-agent.service"
|
||||||
"hive-matrix-daemon.service"
|
"hive-matrix-daemon.service"
|
||||||
];
|
];
|
||||||
unitConfig.ConditionPathExists = "/etc/hyperhive-bridge-dns";
|
unitConfig.ConditionPathExists = "/etc/hyperhive-bridge-dns";
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
# GUI processes run as the agent's own non-root user — the same user
|
# GUI processes run as the agent's own non-root user — the same user
|
||||||
# hive-ag3nt runs as (declared + home-chowned by harness-base.nix) — so
|
# hive-agent runs as (declared + home-chowned by harness-base.nix) — so
|
||||||
# weston, the wayland client, and the agent share one user session.
|
# weston, the wayland client, and the agent share one user session.
|
||||||
# `hyperhive.user.name` is set per-agent by the meta-flake renderer.
|
# `hyperhive.user.name` is set per-agent by the meta-flake renderer.
|
||||||
userName = config.hyperhive.user.name;
|
userName = config.hyperhive.user.name;
|
||||||
|
|
|
||||||
|
|
@ -39,11 +39,11 @@ in
|
||||||
};
|
};
|
||||||
|
|
||||||
# `cargo test --workspace` lifted out of the package builds so the
|
# `cargo test --workspace` lifted out of the package builds so the
|
||||||
# `hyperhive-assets` dep (which `hive-ag3nt::prompt::tests`
|
# `hyperhive-assets` dep (which `hive-agent::prompt::tests`
|
||||||
# needs via `HIVE_ASSETS_DIR` to assert against the actual
|
# needs via `HIVE_ASSETS_DIR` to assert against the actual
|
||||||
# production prompt template) is scoped to this one check
|
# production prompt template) is scoped to this one check
|
||||||
# instead of bleeding into the binary derivations' input
|
# instead of bleeding into the binary derivations' input
|
||||||
# hash. Net: editing `hive-ag3nt/prompts/system.md` still
|
# hash. Net: editing `hive-agent/prompts/system.md` still
|
||||||
# rebuilds this test check (correct — the tests assert
|
# rebuilds this test check (correct — the tests assert
|
||||||
# against its wording), but `packages.default` and the
|
# against its wording), but `packages.default` and the
|
||||||
# per-container toplevels stay fully cached.
|
# per-container toplevels stay fully cached.
|
||||||
|
|
|
||||||
|
|
@ -142,7 +142,7 @@ in
|
||||||
}
|
}
|
||||||
// lib.optionalAttrs (config.services.hyperhive.swarm.peers != { }) {
|
// lib.optionalAttrs (config.services.hyperhive.swarm.peers != { }) {
|
||||||
# Peer hives serialised as a JSON array of {domain, cert_fingerprint,
|
# Peer hives serialised as a JSON array of {domain, cert_fingerprint,
|
||||||
# wireguard_address?} objects. Consumed by hive-ag3nt::identity::peers()
|
# wireguard_address?} objects. Consumed by hive-agent::identity::peers()
|
||||||
# + the dashboard's peer_hives StateSnapshot field (P33RS tab). Domain
|
# + the dashboard's peer_hives StateSnapshot field (P33RS tab). Domain
|
||||||
# is the attrset key; cert_fingerprint is null for CA-trusted peers;
|
# is the attrset key; cert_fingerprint is null for CA-trusted peers;
|
||||||
# wireguard_address is omitted when not part of the mesh.
|
# wireguard_address is omitted when not part of the mesh.
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@
|
||||||
first boot and drives the gateway/forge/agent URLs, with no safe
|
first boot and drives the gateway/forge/agent URLs, with no safe
|
||||||
default; changing it later is destructive). Exposed to agents as
|
default; changing it later is destructive). Exposed to agents as
|
||||||
`HYPERHIVE_HIVE_DOMAIN`; consumed by
|
`HYPERHIVE_HIVE_DOMAIN`; consumed by
|
||||||
`hive-ag3nt::identity::hive_domain()` for `<name>@<domain>`
|
`hive-agent::identity::hive_domain()` for `<name>@<domain>`
|
||||||
qualified labels.
|
qualified labels.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -19,16 +19,16 @@
|
||||||
stdenv.mkDerivation {
|
stdenv.mkDerivation {
|
||||||
pname = "hyperhive-assets";
|
pname = "hyperhive-assets";
|
||||||
version = "0.1.0";
|
version = "0.1.0";
|
||||||
# Narrow `srcs` (branding/ + hive-ag3nt/prompts/) is what decouples
|
# Narrow `srcs` (branding/ + hive-agent/prompts/) is what decouples
|
||||||
# this derivation's input hash from the rest of the tree.
|
# this derivation's input hash from the rest of the tree.
|
||||||
srcs = [
|
srcs = [
|
||||||
../../branding
|
../../branding
|
||||||
../../hive-ag3nt/prompts
|
../../hive-agent/prompts
|
||||||
];
|
];
|
||||||
unpackPhase = ''
|
unpackPhase = ''
|
||||||
runHook preUnpack
|
runHook preUnpack
|
||||||
cp -r ${../../branding} branding
|
cp -r ${../../branding} branding
|
||||||
cp -r ${../../hive-ag3nt/prompts} prompts
|
cp -r ${../../hive-agent/prompts} prompts
|
||||||
chmod -R u+w branding prompts
|
chmod -R u+w branding prompts
|
||||||
runHook postUnpack
|
runHook postUnpack
|
||||||
'';
|
'';
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ let
|
||||||
#
|
#
|
||||||
# Tests are kept in the separate `checks.cargo-test` derivation
|
# Tests are kept in the separate `checks.cargo-test` derivation
|
||||||
# (carries the hyperhive-assets build input for the prompt-template
|
# (carries the hyperhive-assets build input for the prompt-template
|
||||||
# assertions in hive-ag3nt::prompt::tests). Keeping them out of this
|
# assertions in hive-agent::prompt::tests). Keeping them out of this
|
||||||
# derivation means a prompt edit doesn't bust the cargo cache.
|
# derivation means a prompt edit doesn't bust the cargo cache.
|
||||||
workspaceBuild = craneLib.buildPackage {
|
workspaceBuild = craneLib.buildPackage {
|
||||||
src = cleanSrc;
|
src = cleanSrc;
|
||||||
|
|
@ -160,7 +160,7 @@ in
|
||||||
# `preBuildAgentTemplates` option on the hive-c0re module —
|
# `preBuildAgentTemplates` option on the hive-c0re module —
|
||||||
# see nix/host-modules/hive-c0re.nix). Speeds up the first agent
|
# see nix/host-modules/hive-c0re.nix). Speeds up the first agent
|
||||||
# spawn dramatically because the heavy lifting (nixpkgs +
|
# spawn dramatically because the heavy lifting (nixpkgs +
|
||||||
# claude-code + hive-ag3nt binary) is already in the store
|
# claude-code + hive-agent binary) is already in the store
|
||||||
# when the meta evaluator goes to build the container.
|
# when the meta evaluator goes to build the container.
|
||||||
#
|
#
|
||||||
# nixosConfigurations are pinned to x86_64-linux (nixos-
|
# nixosConfigurations are pinned to x86_64-linux (nixos-
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
# $out/share/icons/hicolor/<N>x<N>/apps/hyperhive.png (N = 16,32,48,64,128,256)
|
# $out/share/icons/hicolor/<N>x<N>/apps/hyperhive.png (N = 16,32,48,64,128,256)
|
||||||
# $out/share/pixmaps/hyperhive.png (48px fallback)
|
# $out/share/pixmaps/hyperhive.png (48px fallback)
|
||||||
# $out/share/applications/hive-c0re.desktop
|
# $out/share/applications/hive-c0re.desktop
|
||||||
# $out/share/applications/hive-ag3nt.desktop
|
# $out/share/applications/hive-agent.desktop
|
||||||
stdenv.mkDerivation {
|
stdenv.mkDerivation {
|
||||||
pname = "hive-xdg-icons";
|
pname = "hive-xdg-icons";
|
||||||
version = "0.1.0";
|
version = "0.1.0";
|
||||||
|
|
@ -62,11 +62,11 @@ stdenv.mkDerivation {
|
||||||
NoDisplay=true
|
NoDisplay=true
|
||||||
StartupNotify=false
|
StartupNotify=false
|
||||||
EOF
|
EOF
|
||||||
cat > "$out/share/applications/hive-ag3nt.desktop" <<EOF
|
cat > "$out/share/applications/hive-agent.desktop" <<EOF
|
||||||
[Desktop Entry]
|
[Desktop Entry]
|
||||||
Type=Application
|
Type=Application
|
||||||
Name=hyperhive agent
|
Name=hyperhive agent
|
||||||
GenericName=hive-ag3nt
|
GenericName=hive-agent
|
||||||
Comment=hyperhive per-agent harness (claude turn loop + MCP server)
|
Comment=hyperhive per-agent harness (claude turn loop + MCP server)
|
||||||
Exec=hive serve
|
Exec=hive serve
|
||||||
Icon=hyperhive
|
Icon=hyperhive
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue