huskies: merge 802
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
//! Agent-mode HTTP context construction and gateway registration.
|
||||
|
||||
use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::broadcast;
|
||||
|
||||
use crate::agents::AgentPool;
|
||||
use crate::io::watcher;
|
||||
use crate::slog;
|
||||
|
||||
/// Register this build agent with a gateway using a one-time join token.
|
||||
///
|
||||
/// POSTs `{ token, label, address }` to `{gateway_url}/gateway/register`. On
|
||||
/// success the gateway stores the agent and it will appear in the gateway UI.
|
||||
pub(super) async fn register_with_gateway(
|
||||
gateway_url: &str,
|
||||
token: &str,
|
||||
label: &str,
|
||||
address: &str,
|
||||
) {
|
||||
let client = reqwest::Client::new();
|
||||
let url = format!("{}/gateway/register", gateway_url.trim_end_matches('/'));
|
||||
let body = serde_json::json!({
|
||||
"token": token,
|
||||
"label": label,
|
||||
"address": address,
|
||||
});
|
||||
match client.post(&url).json(&body).send().await {
|
||||
Ok(resp) if resp.status().is_success() => {
|
||||
slog!("[agent-mode] Registered with gateway at {gateway_url}");
|
||||
}
|
||||
Ok(resp) => {
|
||||
slog!(
|
||||
"[agent-mode] Gateway registration failed: HTTP {}",
|
||||
resp.status()
|
||||
);
|
||||
}
|
||||
Err(e) => {
|
||||
slog!("[agent-mode] Gateway registration error: {e}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Build a minimal [`AppContext`] for the agent-mode HTTP server.
|
||||
///
|
||||
/// The `/crdt-sync` handler receives `Data<&Arc<AppContext>>` but doesn't
|
||||
/// actually use it (the parameter is named `_ctx`). We construct a
|
||||
/// lightweight context with just enough state to satisfy Poem's data
|
||||
/// extractor.
|
||||
pub(super) fn build_agent_app_context(
|
||||
project_root: &Path,
|
||||
port: u16,
|
||||
watcher_tx: broadcast::Sender<watcher::WatcherEvent>,
|
||||
) -> crate::http::context::AppContext {
|
||||
let state = crate::state::SessionState::default();
|
||||
*state.project_root.lock().unwrap() = Some(project_root.to_path_buf());
|
||||
let store_path = project_root.join(".huskies").join("store.json");
|
||||
let store = Arc::new(
|
||||
crate::store::JsonFileStore::from_path(store_path)
|
||||
.unwrap_or_else(|e| panic!("Failed to open store: {e}")),
|
||||
);
|
||||
let (reconciliation_tx, _) = broadcast::channel(64);
|
||||
let (perm_tx, perm_rx) = tokio::sync::mpsc::unbounded_channel();
|
||||
let timer_store = Arc::new(crate::service::timer::TimerStore::load(
|
||||
project_root.join(".huskies").join("timers.json"),
|
||||
));
|
||||
let agents = Arc::new(AgentPool::new(port, watcher_tx.clone()));
|
||||
let services = Arc::new(crate::services::Services {
|
||||
project_root: project_root.to_path_buf(),
|
||||
agents: Arc::clone(&agents),
|
||||
bot_name: "Agent".to_string(),
|
||||
bot_user_id: String::new(),
|
||||
ambient_rooms: Arc::new(std::sync::Mutex::new(std::collections::HashSet::new())),
|
||||
perm_rx: Arc::new(tokio::sync::Mutex::new(perm_rx)),
|
||||
pending_perm_replies: Arc::new(tokio::sync::Mutex::new(std::collections::HashMap::new())),
|
||||
permission_timeout_secs: 120,
|
||||
status: agents.status_broadcaster(),
|
||||
});
|
||||
crate::http::context::AppContext {
|
||||
state: Arc::new(state),
|
||||
store,
|
||||
workflow: Arc::new(std::sync::Mutex::new(
|
||||
crate::workflow::WorkflowState::default(),
|
||||
)),
|
||||
services,
|
||||
watcher_tx,
|
||||
reconciliation_tx,
|
||||
perm_tx,
|
||||
qa_app_process: Arc::new(std::sync::Mutex::new(None)),
|
||||
bot_shutdown: None,
|
||||
matrix_shutdown_tx: None,
|
||||
timer_store,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user