Watch
0
0
Fork
You've already forked hyperhive
0

swarm-controller: start a review try-out on a PR and read its result

POST /api/review-classifier/try-out validates the run (owner/name repo,
a PR number, one to ten classifications with distinct names, thresholds
up to 100), reads the PR's head commit, commits and diff with the
controller's forge token, sends one request to the review classifier on
the queue and answers 202 with an id. GET .../try-out/{id} reports the
run as running, done (rows and overall verdict) or failed (the error).
Results live in memory for an hour after the reply; there is no run
store. POST then GET because a run can outlast the gateway's 60-second
proxy read timeout. Both routes are utoipa-annotated, so they show on
/api/docs/.
This commit is contained in:
atlas 2026-10-12 03:29:54 +02:00 • committed by mara
commit d70ed41537
9 changed files with 824 additions and 3 deletions

View file

@ -59,6 +59,7 @@ mod matrix_account;
mod otel_http_client;
mod queue_identity;
mod read_policy;
mod review_classifier;
mod schedules;
mod status;
mod store;
@ -735,6 +736,7 @@ fn socket_path() -> PathBuf {
(name = "repos", description = "forge repo browsing (swarm-ui's issue-report page)"),
(name = "forge", description = "forge site admins (`swarmctl forge make-admin`)"),
(name = "schedules", description = "scheduled prompts (`swarmctl schedule`)"),
(name = "review-classifier", description = "trying review classifications against a PR (swarm-ui's try-out page)"),
)
)]
struct ApiDoc;
@ -857,6 +859,9 @@ struct AppState {
create_gate: Arc<tokio::sync::Mutex<()>>,
/// The store the linked-account routes read and write.
accounts: linked_accounts::Accounts,
/// The review classifier try-outs started here, until their results
/// expire.
try_outs: review_classifier::TryOuts,
}
/// Env var the controller's NixOS module sets from
@ -3208,6 +3213,7 @@ async fn main() -> Result<()> {
forge: forge_client,
create_gate: Arc::default(),
accounts: linked_accounts::Accounts::Live,
try_outs: review_classifier::TryOuts::default(),
};
let app = build_app(state);
@ -3273,6 +3279,8 @@ fn build_app(state: AppState) -> axum::Router {
.routes(routes!(issue_report::get_repos))
.routes(routes!(issue_report::get_issue_report_all))
.routes(routes!(issue_report::get_issue_report))
.routes(routes!(review_classifier::post_try_out))
.routes(routes!(review_classifier::get_try_out))
.routes(routes!(webhook::post_webhook_forge))
.split_for_parts();
// Just the JSON, not the UI — Swagger UI itself is nginx-hosted from
@ -3361,7 +3369,7 @@ mod tests {
>,
>;
fn state_with_roster() -> (super::AppState, SharedSched) {
pub(crate) fn state_with_roster() -> (super::AppState, SharedSched) {
let sched =
std::sync::Arc::new(std::sync::Mutex::new(hive_jobq::scheduler::Scheduler::new(
hive_jobq::Graph::new(),
@ -3392,6 +3400,7 @@ mod tests {
forge: std::sync::Arc::default(),
create_gate: std::sync::Arc::default(),
accounts: super::linked_accounts::Accounts::Fake(std::sync::Arc::default()),
try_outs: super::review_classifier::TryOuts::default(),
};
(state, sched)
}