use axum::http::HeaderMap;
use nemo_relay::api::llm::LlmRequest;
use serde_json::Value;
use crate::alignment::json_string_at;
use crate::config::header_string;
use crate::model::{AgentKind, ToolEvent};
pub(crate) fn owns_gateway_provider(provider: &str) -> bool {
matches!(provider, "anthropic.messages" | "anthropic.count_tokens")
}
pub(crate) fn session_id_from_headers(headers: &HeaderMap) -> Option<String> {
header_string(headers, "x-claude-code-session-id")
}
pub(crate) fn is_startup_probe(
provider: &str,
model_name: Option<&str>,
request: &LlmRequest,
) -> bool {
if provider != "anthropic.messages" {
return false;
}
let model = model_name
.or_else(|| request.content.get("model").and_then(Value::as_str))
.unwrap_or_default();
if !model.starts_with("claude-") {
return false;
}
if request.content.get("max_tokens").and_then(Value::as_u64) != Some(1) {
return false;
}
let Some(messages) = request.content.get("messages").and_then(Value::as_array) else {
return false;
};
let [message] = messages.as_slice() else {
return false;
};
message.get("role").and_then(Value::as_str) == Some("user")
&& message.get("content").and_then(Value::as_str) == Some("test")
}
pub(crate) fn completed_subagent_from_agent_tool(event: &ToolEvent) -> Option<String> {
if event.agent_kind != AgentKind::ClaudeCode || event.tool_name != "Agent" {
return None;
}
if !is_terminal_agent_tool_result(&event.result) {
return None;
}
json_string_at(
&event.result,
&[
&["agentId"][..],
&["agent_id"][..],
&["subagentId"][..],
&["subagent_id"][..],
],
)
}
fn is_terminal_agent_tool_result(result: &serde_json::Value) -> bool {
let status = json_string_at(result, &[&["status"][..]])
.map(|status| status.trim().to_ascii_lowercase().replace(['-', ' '], "_"));
match status.as_deref() {
Some("async_launched" | "launched" | "started" | "running" | "pending" | "in_progress") => {
false
}
Some(
"completed" | "complete" | "success" | "succeeded" | "failed" | "error" | "errored"
| "cancelled" | "canceled" | "timeout" | "timed_out",
) => true,
Some(_) | None => has_terminal_agent_tool_evidence(result),
}
}
fn has_terminal_agent_tool_evidence(result: &serde_json::Value) -> bool {
[
"content",
"output",
"totalDurationMs",
"totalTokens",
"totalToolUseCount",
"durationMs",
"usage",
]
.into_iter()
.any(|key| result.get(key).is_some_and(|value| !value.is_null()))
}
#[cfg(test)]
#[path = "../../tests/coverage/alignment_claude_code_tests.rs"]
mod tests;