spec_ai_core/agent/
output.rs1use crate::agent::model::TokenUsage;
4use crate::tools::ToolResult;
5use crate::types::MessageRole;
6use serde::{Deserialize, Serialize};
7use serde_json::Value;
8
9#[derive(Debug, Clone, Serialize, Deserialize)]
11pub struct AgentOutput {
12 pub response: String,
14 pub response_message_id: Option<i64>,
16 pub token_usage: Option<TokenUsage>,
18 pub tool_invocations: Vec<ToolInvocation>,
20 pub finish_reason: Option<String>,
22 pub recall_stats: Option<MemoryRecallStats>,
24 pub run_id: String,
26 pub next_action: Option<String>,
28 #[serde(skip_serializing_if = "Option::is_none")]
30 pub reasoning: Option<String>,
31 #[serde(skip_serializing_if = "Option::is_none")]
33 pub reasoning_summary: Option<String>,
34 #[serde(skip_serializing_if = "Option::is_none")]
36 pub graph_debug: Option<GraphDebugInfo>,
37}
38
39#[derive(Debug, Clone, Serialize, Deserialize)]
41pub struct GraphDebugNode {
42 pub id: i64,
43 pub node_type: String,
44 pub label: String,
45}
46
47#[derive(Debug, Clone, Serialize, Deserialize)]
49pub struct GraphDebugInfo {
50 pub enabled: bool,
51 pub graph_memory_enabled: bool,
52 pub auto_graph_enabled: bool,
53 pub graph_steering_enabled: bool,
54 pub node_count: usize,
55 pub edge_count: usize,
56 pub recent_nodes: Vec<GraphDebugNode>,
57}
58
59#[derive(Debug, Clone, Serialize, Deserialize)]
61pub struct ToolInvocation {
62 pub name: String,
63 pub arguments: Value,
64 pub success: bool,
65 #[serde(skip_serializing_if = "Option::is_none")]
66 pub output: Option<String>,
67 #[serde(skip_serializing_if = "Option::is_none")]
68 pub error: Option<String>,
69}
70
71impl ToolInvocation {
72 pub fn from_result(name: &str, arguments: Value, result: &ToolResult) -> Self {
73 let output = if result.output.trim().is_empty() {
74 None
75 } else {
76 Some(result.output.clone())
77 };
78
79 Self {
80 name: name.to_string(),
81 arguments,
82 success: result.success,
83 output,
84 error: result.error.clone(),
85 }
86 }
87}
88
89#[derive(Debug, Clone, Serialize, Deserialize)]
91pub struct MemoryRecallStats {
92 pub strategy: MemoryRecallStrategy,
93 pub matches: Vec<MemoryRecallMatch>,
94}
95
96#[derive(Debug, Clone, Serialize, Deserialize)]
98pub enum MemoryRecallStrategy {
99 Semantic { requested: usize, returned: usize },
100 RecentContext { limit: usize },
101}
102
103#[derive(Debug, Clone, Serialize, Deserialize)]
105pub struct MemoryRecallMatch {
106 pub message_id: Option<i64>,
107 pub score: f32,
108 pub role: MessageRole,
109 pub preview: String,
110}