1use std::collections::BTreeMap;
4
5use serde::{Deserialize, Serialize};
6use serde_json::Value;
7
8use crate::error::ApiError;
9
10#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
12#[serde(rename_all = "camelCase")]
13pub struct AgentRequest {
14 pub prompt: String,
15 #[serde(default)]
16 pub urls: Option<Vec<String>>,
17 #[serde(default)]
18 pub schema: Option<Value>,
19 #[serde(default)]
20 pub effort: Option<AgentEffort>,
21 #[serde(default, rename = "strictConstrainToURLs")]
23 pub strict_constrain_to_urls: bool,
24 #[serde(default)]
26 pub max_credits: Option<u64>,
27 #[serde(default)]
28 pub webhook: Option<Value>,
29 #[serde(default)]
31 pub allowed_hosts: Option<Vec<String>>,
32}
33
34#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
36#[serde(rename_all = "lowercase")]
37pub enum AgentEffort {
38 Low,
39 Medium,
40 High,
41}
42
43impl AgentEffort {
44 pub fn as_str(self) -> &'static str {
45 match self {
46 Self::Low => "low",
47 Self::Medium => "medium",
48 Self::High => "high",
49 }
50 }
51}
52
53#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
55#[serde(rename_all = "camelCase", default)]
56pub struct AgentOutcome {
57 pub data: Option<Value>,
59 pub schema_valid: Option<bool>,
61 pub finish_reason: String,
64 pub complete: bool,
66 pub missing: Vec<String>,
68 pub message: Option<String>,
69 pub sources: Vec<AgentSource>,
70 pub field_sources: BTreeMap<String, FieldSource>,
72 pub evidence: Vec<AgentEvidence>,
73 pub steps: Vec<AgentStep>,
74 pub usage: AgentUsage,
75 pub budget: AgentBudget,
76 pub warnings: Vec<String>,
77 pub error: Option<AgentFailure>,
78}
79
80impl AgentOutcome {
81 pub fn credits(&self) -> u64 {
83 self.usage.credits()
84 }
85}
86
87#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
88#[serde(rename_all = "camelCase", default)]
89pub struct AgentSource {
90 pub url: String,
91 pub title: Option<String>,
92 pub evidence_ids: Vec<String>,
93 pub content_hash: Option<String>,
94 pub fetched_at: Option<String>,
95}
96
97#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
99#[serde(rename_all = "camelCase", default)]
100pub struct FieldSource {
101 pub sources: Vec<String>,
102 pub evidence_ids: Vec<String>,
103 pub verified: bool,
104}
105
106#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
108#[serde(rename_all = "camelCase", default)]
109pub struct AgentEvidence {
110 pub id: String,
111 pub url: String,
112 pub kind: String,
114 pub query: Option<String>,
115 pub text: String,
116 pub relevance: Option<f32>,
117}
118
119#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
120#[serde(rename_all = "camelCase", default)]
121pub struct AgentStep {
122 pub turn: usize,
123 pub tool: String,
125 pub input: Value,
126 pub result: String,
128 pub detail: Option<String>,
129}
130
131#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
132#[serde(rename_all = "camelCase", default)]
133pub struct AgentUsage {
134 pub pages: u64,
135 pub pages_failed: u64,
136 pub searches: u64,
137 pub maps: u64,
138 pub llm_calls: u64,
139 pub tokens: u64,
140 pub tokens_estimated: bool,
142}
143
144impl AgentUsage {
145 pub fn credits(&self) -> u64 {
146 self.pages + self.searches + self.maps
147 }
148}
149
150#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
151#[serde(rename_all = "camelCase", default)]
152pub struct AgentBudget {
153 pub max_pages: u64,
154 pub max_llm_calls: u64,
155 pub max_tokens: u64,
156 pub max_credits: Option<u64>,
157 pub input_tokens_per_call: u64,
159 pub exhausted: Option<String>,
161}
162
163#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
165#[serde(rename_all = "camelCase", default)]
166pub struct AgentFailure {
167 pub code: String,
168 pub message: String,
169}
170
171impl From<&ApiError> for AgentFailure {
172 fn from(e: &ApiError) -> Self {
173 Self {
174 code: e.code.as_str().to_string(),
175 message: e.message.clone(),
176 }
177 }
178}