Watch
0
0
Fork
You've already forked hyperhive
0

move the review classifier, agent login and inference types into swarm-wire

This commit is contained in:
atlas 2026-10-18 08:58:13 +02:00 • committed by mara
commit 6ea13c02e3
44 changed files with 344 additions and 332 deletions

View file

@ -104,22 +104,21 @@ swarm-controller-api = { workspace = true, features = ["schema"] }
# config the crate spells.
# `agent-term`: likewise every agent's terminal stream, plus the consumer it
# replays that stream through.
# `schema`: the review classifier try-out API serves the shapes the queue
# carries.
swarm-queue-client = { workspace = true, features = [
"kv",
"agent-permissions",
"subagent-term",
"agent-term",
"schema",
] }
# `matrix_account.rs` writes the credential this daemon's route accepts. Same
# crate the hive reads it back with, which is the point: the path, the field
# name and the object's shape are agreements between the two ends, and a
# second spelling here would be a store this hive could not read.
swarm-secret-client.workspace = true
# The builder and claude login subjects, requests and replies it sends.
swarm-wire.workspace = true
# The builder, claude login and review classifier subjects, requests and
# replies it sends. `schema`: the review classifier try-out API serves the
# same shapes, so they derive `ToSchema`.
swarm-wire = { workspace = true, features = ["schema"] }
# The appservice calls `matrix_account::agent_token` mints agents' accounts
# with — shared with `swarm-matrix-ctl`, which pins the same device id.
swarm-matrix-client.workspace = true

View file

@ -12,7 +12,7 @@ use std::sync::{Arc, Mutex, PoisonError};
use std::time::Duration;
use futures_util::StreamExt as _;
use swarm_queue_client::agent_login::Login;
use swarm_wire::agent_login::Login;
/// The latest login flag each agent reported, by agent.
#[derive(Debug, Default)]

View file

@ -195,7 +195,7 @@ pub(crate) struct ArchetypeView {
/// As `PUT /api/agents/{name}/inference` takes them.
#[serde(skip_serializing_if = "Option::is_none")]
#[schema(value_type = Option<Object>)]
inference: Option<swarm_queue_client::agent_inference::AgentInference>,
inference: Option<swarm_wire::agent_inference::AgentInference>,
}
/// One archetype a source declared and this daemon refused.

View file

@ -41,8 +41,8 @@ use std::sync::{Arc, OnceLock};
use utoipa::ToSchema;
use crate::webhook::DeliveryKind;
use swarm_queue_client::review_classifier::Commit;
use swarm_secret_client::stored_secret::StoredSecret;
use swarm_wire::review_classifier::Commit;
pub mod agent_token;
mod api;

View file

@ -3,7 +3,7 @@
//! running on.
//!
//! Each agent's settings are one value under its own key of `agent-inference`
//! (`swarm_queue_client::agent_inference`), which this daemon alone writes.
//! (`swarm_wire::agent_inference`), which this daemon alone writes.
//! The agent reads its key and applies each set field over its local value;
//! an unset field leaves the local value in force.
//!
@ -23,7 +23,8 @@ use axum::http::StatusCode;
use futures_util::StreamExt as _;
use problem_details::ProblemDetails;
use serde::{Deserialize, Serialize};
use swarm_queue_client::agent_inference::{self, AgentInference, Effective, Effort, Source};
use swarm_queue_client::agent_inference;
use swarm_wire::agent_inference::{AgentInference, Effective, Effort, Source};
use utoipa::ToSchema;
use crate::routes::{AppState, error_problem, wanted_error_status};

View file

@ -31,7 +31,7 @@ use axum::extract::{Path, Query, State};
use axum::http::{HeaderMap, StatusCode};
use problem_details::ProblemDetails;
use serde::{Deserialize, Serialize};
use swarm_queue_client::review_classifier::{
use swarm_wire::review_classifier::{
Classification, MAX_CLASSIFICATIONS, Overall, RUN_DEADLINE, Reply, Row, SUBJECT, TryOut,
};
use utoipa::{IntoParams, ToSchema};
@ -763,7 +763,7 @@ pub(crate) mod tests {
use axum::body::Body;
use axum::http::{Request, StatusCode};
use forgejo_api::{ApiErrorKind, ForgejoError};
use swarm_queue_client::review_classifier::{Overall, Polarity, Reply, Row, Verdict};
use swarm_wire::review_classifier::{Overall, Polarity, Reply, Row, Verdict};
use tower::ServiceExt as _;
use super::*;
@ -988,13 +988,13 @@ pub(crate) mod tests {
#[tokio::test]
async fn a_try_out_runs_on_the_stored_runtime_model_and_effort() {
use swarm_queue_client::agent_inference::Effort;
use swarm_queue_client::review_classifier::Runtime;
use swarm_wire::agent_inference::Effort;
use swarm_wire::review_classifier::Runtime;
let acp = swarm_queue_client::review_classifier::Acp {
let acp = swarm_wire::review_classifier::Acp {
base_url: "https://llm.example/v1".to_owned(),
model: "qwen".to_owned(),
prices: swarm_queue_client::review_classifier::Prices {
prices: swarm_wire::review_classifier::Prices {
input: 1.0,
output: 2.0,
cache_read: None,
@ -1167,7 +1167,7 @@ pub(crate) mod tests {
let mut requests = classifier
.queue_subscribe(
SUBJECT,
swarm_queue_client::review_classifier::QUEUE_GROUP.to_owned(),
swarm_wire::review_classifier::QUEUE_GROUP.to_owned(),
)
.await
.expect("subscribe");

View file

@ -26,7 +26,7 @@ use axum::http::{HeaderMap, StatusCode};
use forgejo_api::{ApiErrorKind, ForgejoError};
use problem_details::ProblemDetails;
use serde::{Deserialize, Serialize};
use swarm_queue_client::review_classifier::{Classification, Polarity};
use swarm_wire::review_classifier::{Classification, Polarity};
use utoipa::ToSchema;
use super::{FileSource, RULES_PATHS, check_classifications, operator, parse_rules, split_repo};
@ -509,7 +509,7 @@ mod tests {
use axum::body::Body;
use axum::http::{Request, StatusCode};
use swarm_queue_client::review_classifier::{Overall, Reply};
use swarm_wire::review_classifier::{Overall, Reply};
use tower::ServiceExt as _;
use super::super::tests::Fake;

View file

@ -26,7 +26,7 @@ use std::time::Duration;
use forgejo_api::ForgejoError;
use serde::Deserialize;
use swarm_queue_client::review_classifier::{Overall, Reply, Row, TryOut, Verdict};
use swarm_wire::review_classifier::{Overall, Reply, Row, TryOut, Verdict};
use tokio::sync::Notify;
use tokio::task::JoinHandle;
@ -983,7 +983,7 @@ mod tests {
use std::time::Duration;
use axum::http::StatusCode;
use swarm_queue_client::review_classifier::Polarity;
use swarm_wire::review_classifier::Polarity;
use super::*;
use crate::review_classifier::runs::tests::FakeDoc;
@ -2113,7 +2113,7 @@ mod tests {
#[tokio::test]
async fn a_review_runs_on_the_stored_runtime_model_and_effort() {
use swarm_queue_client::agent_inference::Effort;
use swarm_wire::agent_inference::Effort;
let mut fake = Fake::new(
Reply::Done {
@ -2122,10 +2122,10 @@ mod tests {
},
vec![rules_json()],
);
let acp = swarm_queue_client::review_classifier::Acp {
let acp = swarm_wire::review_classifier::Acp {
base_url: "https://llm.example/v1".to_owned(),
model: "qwen".to_owned(),
prices: swarm_queue_client::review_classifier::Prices {
prices: swarm_wire::review_classifier::Prices {
input: 1.0,
output: 2.0,
cache_read: None,
@ -2149,7 +2149,7 @@ mod tests {
);
assert_eq!(
sent[0].runtime,
swarm_queue_client::review_classifier::Runtime::Acp(acp)
swarm_wire::review_classifier::Runtime::Acp(acp)
);
}

View file

@ -20,7 +20,7 @@ use axum::extract::State;
use axum::http::StatusCode;
use problem_details::ProblemDetails;
use serde::{Deserialize, Serialize};
use swarm_queue_client::review_classifier::{Overall, Reply, Row};
use swarm_wire::review_classifier::{Overall, Reply, Row};
use utoipa::ToSchema;
use crate::routes::{AppState, error_problem};
@ -386,7 +386,7 @@ pub(crate) mod tests {
use axum::body::Body;
use axum::http::Request;
use swarm_queue_client::review_classifier::{Polarity, Verdict};
use swarm_wire::review_classifier::{Polarity, Verdict};
use tower::ServiceExt as _;
use tracing_subscriber::layer::SubscriberExt as _;

View file

@ -20,8 +20,8 @@ use axum::extract::rejection::JsonRejection;
use axum::http::{HeaderMap, StatusCode};
use problem_details::ProblemDetails;
use serde::{Deserialize, Serialize};
use swarm_queue_client::agent_inference::Effort;
use swarm_queue_client::review_classifier::{Acp, Runtime};
use swarm_wire::agent_inference::Effort;
use swarm_wire::review_classifier::{Acp, Runtime};
use utoipa::ToSchema;
use crate::routes::{AppState, error_problem, wanted_error_status};
@ -79,7 +79,7 @@ pub(crate) enum RuntimeKind {
impl Default for Settings {
fn default() -> Self {
Self {
model: swarm_queue_client::review_classifier::DEFAULT_MODEL.to_owned(),
model: swarm_wire::review_classifier::DEFAULT_MODEL.to_owned(),
effort: None,
max_concurrent_reviews: 2,
runtime: RuntimeKind::ApiKey,
@ -404,7 +404,7 @@ mod tests {
Acp {
base_url: "https://llm.example/v1".to_owned(),
model: "Qwen/Qwen3-35B".to_owned(),
prices: swarm_queue_client::review_classifier::Prices {
prices: swarm_wire::review_classifier::Prices {
input: 0.5,
output: 2.0,
cache_read: Some(0.05),

View file

@ -712,7 +712,7 @@ pub(crate) async fn create_agent(
/// The settings a `POST /api/agents` body gives, as they are stored.
struct CreateSettings {
limits: Option<swarm_queue_client::agent_limits::AgentCaps>,
inference: Option<swarm_queue_client::agent_inference::AgentInference>,
inference: Option<swarm_wire::agent_inference::AgentInference>,
permissions: Option<swarm_queue_client::agent_permissions::AgentPermissions>,
archetype: Option<swarm_queue_client::agent_archetype::ArchetypeRef>,
agents_md: Option<String>,
@ -795,7 +795,7 @@ impl StoredSettings {
client: &async_nats::Client,
agent: &str,
limits: Option<&swarm_queue_client::agent_limits::AgentCaps>,
inference: Option<&swarm_queue_client::agent_inference::AgentInference>,
inference: Option<&swarm_wire::agent_inference::AgentInference>,
permissions: Option<&swarm_queue_client::agent_permissions::AgentPermissions>,
archetype: Option<&swarm_queue_client::agent_archetype::ArchetypeRef>,
agents_md: Option<&str>,
@ -1446,7 +1446,7 @@ mod tests {
let client = nats.client().await;
async_nats::jetstream::new(client.clone())
.create_key_value(async_nats::jetstream::kv::Config {
bucket: swarm_queue_client::agent_inference::BUCKET.to_owned(),
bucket: swarm_wire::agent_inference::BUCKET.to_owned(),
history: 1,
max_value_size: 1,
..Default::default()
@ -1505,7 +1505,7 @@ mod tests {
let client = nats.client().await;
async_nats::jetstream::new(client.clone())
.create_key_value(async_nats::jetstream::kv::Config {
bucket: swarm_queue_client::agent_inference::BUCKET.to_owned(),
bucket: swarm_wire::agent_inference::BUCKET.to_owned(),
history: 1,
max_value_size: 1,
..Default::default()