huskies: merge 921
This commit is contained in:
@@ -547,8 +547,9 @@ fn handle_agents_list_tool(id: Option<Value>) -> JsonRpcResponse {
|
||||
)
|
||||
}
|
||||
|
||||
/// Handle the `pipeline.get` read-RPC — returns the same shape as the old
|
||||
/// `GET /api/gateway/pipeline` endpoint: `{ "active": "...", "projects": {...} }`.
|
||||
/// Handle the `pipeline.get` read-RPC — returns per-project item lists in the
|
||||
/// shape expected by the gateway web UI:
|
||||
/// `{ "active": "...", "projects": { "name": { "active": [...], "backlog_count": N } } }`.
|
||||
async fn handle_pipeline_get(state: &GatewayState, id: Option<Value>) -> JsonRpcResponse {
|
||||
let project_urls: BTreeMap<String, String> = state
|
||||
.projects
|
||||
@@ -558,8 +559,7 @@ async fn handle_pipeline_get(state: &GatewayState, id: Option<Value>) -> JsonRpc
|
||||
.map(|(n, e)| (n.clone(), e.url.clone()))
|
||||
.collect();
|
||||
|
||||
let results =
|
||||
gateway::io::fetch_all_project_pipeline_statuses(&project_urls, &state.client).await;
|
||||
let results = gateway::io::fetch_all_project_pipeline_items(&project_urls, &state.client).await;
|
||||
let active = state.active_project.read().await.clone();
|
||||
|
||||
JsonRpcResponse::success(id, json!({ "active": active, "projects": results }))
|
||||
|
||||
@@ -215,6 +215,82 @@ pub async fn fetch_all_project_pipeline_statuses(
|
||||
join_all(futures).await.into_iter().collect()
|
||||
}
|
||||
|
||||
/// Fetch pipeline items for a single project URL.
|
||||
///
|
||||
/// Returns `{ "active": [...], "backlog_count": N }` preserving individual
|
||||
/// story items so the gateway UI can render them. On error returns
|
||||
/// `{ "error": "..." }`. This is distinct from
|
||||
/// `fetch_one_project_pipeline_status` which discards items and returns
|
||||
/// aggregated counts.
|
||||
pub async fn fetch_one_project_pipeline_items(url: &str, client: &Client) -> Value {
|
||||
let mcp_url = format!("{}/mcp", url.trim_end_matches('/'));
|
||||
let rpc_body = json!({
|
||||
"jsonrpc": "2.0",
|
||||
"id": 1,
|
||||
"method": "tools/call",
|
||||
"params": {
|
||||
"name": "get_pipeline_status",
|
||||
"arguments": {}
|
||||
}
|
||||
});
|
||||
|
||||
match client.post(&mcp_url).json(&rpc_body).send().await {
|
||||
Ok(resp) => match resp.json::<Value>().await {
|
||||
Ok(upstream) => {
|
||||
if let Some(text) = upstream
|
||||
.get("result")
|
||||
.and_then(|r| r.get("content"))
|
||||
.and_then(|c| c.get(0))
|
||||
.and_then(|c| c.get("text"))
|
||||
.and_then(|t| t.as_str())
|
||||
{
|
||||
match serde_json::from_str::<Value>(text) {
|
||||
Ok(pipeline) => {
|
||||
let active = pipeline.get("active").cloned().unwrap_or(json!([]));
|
||||
let backlog_count = pipeline
|
||||
.get("backlog_count")
|
||||
.and_then(|n| n.as_u64())
|
||||
.unwrap_or(0);
|
||||
json!({ "active": active, "backlog_count": backlog_count })
|
||||
}
|
||||
Err(_) => json!({ "error": "invalid pipeline JSON" }),
|
||||
}
|
||||
} else {
|
||||
json!({ "error": "unexpected response shape" })
|
||||
}
|
||||
}
|
||||
Err(e) => json!({ "error": format!("invalid response: {e}") }),
|
||||
},
|
||||
Err(e) => json!({ "error": format!("unreachable: {e}") }),
|
||||
}
|
||||
}
|
||||
|
||||
/// Fetch pipeline items from every registered project URL in parallel.
|
||||
///
|
||||
/// Returns per-project `{ "active": [...], "backlog_count": N }` objects
|
||||
/// suitable for the gateway web UI.
|
||||
pub async fn fetch_all_project_pipeline_items(
|
||||
project_urls: &BTreeMap<String, String>,
|
||||
client: &Client,
|
||||
) -> BTreeMap<String, Value> {
|
||||
use futures::future::join_all;
|
||||
|
||||
let futures: Vec<_> = project_urls
|
||||
.iter()
|
||||
.map(|(name, url)| {
|
||||
let name = name.clone();
|
||||
let url = url.clone();
|
||||
let client = client.clone();
|
||||
async move {
|
||||
let result = fetch_one_project_pipeline_items(&url, &client).await;
|
||||
(name, result)
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
join_all(futures).await.into_iter().collect()
|
||||
}
|
||||
|
||||
/// Fetch the pipeline status from a single project for the `gateway_status` tool.
|
||||
pub async fn fetch_pipeline_status_for_project(
|
||||
client: &Client,
|
||||
|
||||
Reference in New Issue
Block a user