use super::*;
#[tokio::test]
async fn get_turn_context_returns_context_data() {
let state = test_state();
let sid = roboticus_db::sessions::create_new(&state.db, "agent-d", None).unwrap();
roboticus_db::sessions::create_turn_with_id(
&state.db,
"turn-ctx-1",
&sid,
Some("gpt-4"),
Some(300),
Some(150),
Some(0.03),
)
.unwrap();
roboticus_db::sessions::upsert_context_snapshot(
&state.db,
roboticus_db::sessions::UpsertContextSnapshotInput {
turn_id: "turn-ctx-1",
complexity_level: "L2",
token_budget: 16000,
system_prompt_tokens: Some(1200),
memory_tokens: Some(700),
history_tokens: Some(900),
history_depth: Some(6),
memory_tiers_json: None,
retrieved_memories_json: None,
model: Some("gpt-4"),
},
)
.unwrap();
let app = build_router(state);
let resp = app
.oneshot(
Request::builder()
.uri("/api/turns/turn-ctx-1/context")
.body(Body::empty())
.unwrap(),
)
.await
.unwrap();
assert_eq!(resp.status(), StatusCode::OK);
let body = json_body(resp).await;
assert_eq!(body["turn_id"], "turn-ctx-1");
assert_eq!(body["model"], "gpt-4");
assert_eq!(body["tokens_in"], 300);
assert_eq!(body["tokens_out"], 150);
assert_eq!(body["token_budget"], 16000);
assert_eq!(body["system_prompt_tokens"], 1200);
assert_eq!(body["memory_tokens"], 700);
assert_eq!(body["history_tokens"], 900);
assert_eq!(body["history_depth"], 6);
assert_eq!(body["complexity_level"], "L2");
assert_eq!(body["snapshot"], true);
assert_eq!(body["tool_call_count"], 0);
assert_eq!(body["tool_failure_count"], 0);
}
#[tokio::test]
async fn get_turn_context_nonexistent_returns_404() {
let app = build_router(test_state());
let resp = app
.oneshot(
Request::builder()
.uri("/api/turns/nonexistent/context")
.body(Body::empty())
.unwrap(),
)
.await
.unwrap();
assert_eq!(resp.status(), StatusCode::NOT_FOUND);
}
#[tokio::test]
async fn capabilities_resync_matches_tool_registry_names() {
struct ParityTool;
#[async_trait]
impl roboticus_agent::tools::Tool for ParityTool {
fn name(&self) -> &str {
"parity_probe"
}
fn description(&self) -> &str {
"test-only parity tool"
}
fn risk_level(&self) -> roboticus_core::RiskLevel {
roboticus_core::RiskLevel::Safe
}
fn parameters_schema(&self) -> serde_json::Value {
serde_json::json!({"type":"object"})
}
async fn execute(
&self,
_params: serde_json::Value,
_ctx: &roboticus_agent::tools::ToolContext,
) -> std::result::Result<
roboticus_agent::tools::ToolResult,
roboticus_agent::tools::ToolError,
> {
Ok(roboticus_agent::tools::ToolResult {
output: "ok".to_string(),
metadata: None,
})
}
}
let mut state = test_state();
let mut registry = ToolRegistry::new();
registry.register(Box::new(ParityTool));
state.tools = Arc::new(registry);
state.resync_capabilities_from_tools().await;
let mut tool_names: Vec<String> = state
.tools
.list()
.iter()
.map(|t| t.name().to_string())
.collect();
let mut capability_names = state.capabilities.list_names().await;
tool_names.sort();
capability_names.sort();
assert_eq!(tool_names, capability_names);
}