mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-09-06 08:18:58 +00:00
Fix MCP run search submitted ordering
This commit is contained in:
parent
17a870b4d1
commit
afa982176f
2 changed files with 69 additions and 3 deletions
|
|
@ -12,11 +12,12 @@ use std::io::{BufRead as _, Write as _};
|
|||
use std::path::{Path, PathBuf};
|
||||
use std::process::Stdio;
|
||||
|
||||
use chrono::{Duration as ChronoDuration, Utc};
|
||||
use chrono::{DateTime, Duration as ChronoDuration, Utc};
|
||||
use fabro_client::{AuthEntry, AuthStore, DevTokenEntry, OAuthEntry, StoredSubject};
|
||||
use fabro_mcp::client::McpClient;
|
||||
use fabro_mcp::config::{McpServerSettings, McpTransport};
|
||||
use fabro_test::{fabro_json_snapshot, fabro_snapshot, test_context};
|
||||
use fabro_types::RunId;
|
||||
use httpmock::Method::{GET, POST};
|
||||
use httpmock::MockServer;
|
||||
|
||||
|
|
@ -872,6 +873,64 @@ async fn mcp_search_orders_by_started_timestamp_before_created_timestamp() {
|
|||
.expect("MCP client should shut down");
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn mcp_search_orders_submitted_runs_by_created_timestamp_not_run_id_timestamp() {
|
||||
let context = test_context!();
|
||||
let server = MockServer::start();
|
||||
let target_url = format!("{}/api/v1", server.base_url());
|
||||
let target: fabro_client::ServerTarget = target_url.parse().unwrap();
|
||||
seed_dev_token_auth(&context.home_dir, &target, TEST_DEV_TOKEN);
|
||||
let newer_created_id = run_id_with_timestamp("2026-04-05T12:00:00Z", 1);
|
||||
let older_created_id = run_id_with_timestamp("2026-04-05T12:40:00Z", 1);
|
||||
let mut newer_created = remote_run_summary_json(
|
||||
&newer_created_id,
|
||||
"Simple",
|
||||
"simple",
|
||||
"Created later",
|
||||
&serde_json::json!({ "kind": "submitted" }),
|
||||
"2026-04-05T12:30:00Z",
|
||||
);
|
||||
newer_created["timestamps"]["started_at"] = serde_json::Value::Null;
|
||||
let mut older_created = remote_run_summary_json(
|
||||
&older_created_id,
|
||||
"Simple",
|
||||
"simple",
|
||||
"Created earlier",
|
||||
&serde_json::json!({ "kind": "submitted" }),
|
||||
"2026-04-05T12:10:00Z",
|
||||
);
|
||||
older_created["timestamps"]["started_at"] = serde_json::Value::Null;
|
||||
let list_runs = server.mock(|when, then| {
|
||||
when.method(GET)
|
||||
.path("/api/v1/runs")
|
||||
.query_param("include_archived", "true")
|
||||
.query_param("page[limit]", "100")
|
||||
.query_param("page[offset]", "0");
|
||||
then.status(200)
|
||||
.header("Content-Type", "application/json")
|
||||
.json_body(serde_json::json!({
|
||||
"data": [newer_created, older_created],
|
||||
"meta": { "has_more": false }
|
||||
}));
|
||||
});
|
||||
|
||||
let client = spawn_mcp_client(&context, &["--server", &target_url]).await;
|
||||
let result = call_tool_json(
|
||||
&client,
|
||||
"fabro_run_search",
|
||||
serde_json::json!({ "run_ids": [newer_created_id, older_created_id], "first": 2 }),
|
||||
)
|
||||
.await;
|
||||
|
||||
assert_eq!(result["runs"][0]["run_id"], newer_created_id);
|
||||
assert_eq!(result["runs"][1]["run_id"], older_created_id);
|
||||
list_runs.assert();
|
||||
client
|
||||
.shutdown()
|
||||
.await
|
||||
.expect("MCP client should shut down");
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn mcp_lifecycle_tools_manage_real_run() {
|
||||
let context = test_context!();
|
||||
|
|
@ -2054,3 +2113,10 @@ fn normalize_gather(mut value: serde_json::Value) -> serde_json::Value {
|
|||
}
|
||||
value
|
||||
}
|
||||
|
||||
fn run_id_with_timestamp(timestamp: &str, sequence: u128) -> String {
|
||||
let timestamp = DateTime::parse_from_rfc3339(timestamp)
|
||||
.expect("test timestamp should parse")
|
||||
.with_timezone(&Utc);
|
||||
RunId::with_timestamp(timestamp, sequence).to_string()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -402,8 +402,8 @@ pub(crate) async fn search_runs(
|
|||
.await
|
||||
.map_err(|err| ToolError::from_anyhow(&err))?;
|
||||
runs.sort_by(|a, b| {
|
||||
let a_sort_time = a.timestamps.started_at.unwrap_or_else(|| a.id.created_at());
|
||||
let b_sort_time = b.timestamps.started_at.unwrap_or_else(|| b.id.created_at());
|
||||
let a_sort_time = a.timestamps.started_at.unwrap_or(a.timestamps.created_at);
|
||||
let b_sort_time = b.timestamps.started_at.unwrap_or(b.timestamps.created_at);
|
||||
b_sort_time.cmp(&a_sort_time).then_with(|| b.id.cmp(&a.id))
|
||||
});
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue