use std::collections::BTreeMap;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use crate::error::ApiError;
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AgentRequest {
pub prompt: String,
#[serde(default)]
pub urls: Option<Vec<String>>,
#[serde(default)]
pub schema: Option<Value>,
#[serde(default)]
pub effort: Option<AgentEffort>,
#[serde(default, rename = "strictConstrainToURLs")]
pub strict_constrain_to_urls: bool,
#[serde(default)]
pub max_credits: Option<u64>,
#[serde(default)]
pub webhook: Option<Value>,
#[serde(default)]
pub allowed_hosts: Option<Vec<String>>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum AgentEffort {
Low,
Medium,
High,
}
impl AgentEffort {
pub fn as_str(self) -> &'static str {
match self {
Self::Low => "low",
Self::Medium => "medium",
Self::High => "high",
}
}
}
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase", default)]
pub struct AgentOutcome {
pub data: Option<Value>,
pub schema_valid: Option<bool>,
pub finish_reason: String,
pub complete: bool,
pub missing: Vec<String>,
pub message: Option<String>,
pub sources: Vec<AgentSource>,
pub field_sources: BTreeMap<String, FieldSource>,
pub evidence: Vec<AgentEvidence>,
pub steps: Vec<AgentStep>,
pub usage: AgentUsage,
pub budget: AgentBudget,
pub warnings: Vec<String>,
pub error: Option<AgentFailure>,
}
impl AgentOutcome {
pub fn credits(&self) -> u64 {
self.usage.credits()
}
}
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase", default)]
pub struct AgentSource {
pub url: String,
pub title: Option<String>,
pub evidence_ids: Vec<String>,
pub content_hash: Option<String>,
pub fetched_at: Option<String>,
}
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase", default)]
pub struct FieldSource {
pub sources: Vec<String>,
pub evidence_ids: Vec<String>,
pub verified: bool,
}
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase", default)]
pub struct AgentEvidence {
pub id: String,
pub url: String,
pub kind: String,
pub query: Option<String>,
pub text: String,
pub relevance: Option<f32>,
}
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase", default)]
pub struct AgentStep {
pub turn: usize,
pub tool: String,
pub input: Value,
pub result: String,
pub detail: Option<String>,
}
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase", default)]
pub struct AgentUsage {
pub pages: u64,
pub pages_failed: u64,
pub searches: u64,
pub maps: u64,
pub llm_calls: u64,
pub tokens: u64,
pub tokens_estimated: bool,
}
impl AgentUsage {
pub fn credits(&self) -> u64 {
self.pages + self.searches + self.maps
}
}
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase", default)]
pub struct AgentBudget {
pub max_pages: u64,
pub max_llm_calls: u64,
pub max_tokens: u64,
pub max_credits: Option<u64>,
pub input_tokens_per_call: u64,
pub exhausted: Option<String>,
}
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase", default)]
pub struct AgentFailure {
pub code: String,
pub message: String,
}
impl From<&ApiError> for AgentFailure {
fn from(e: &ApiError) -> Self {
Self {
code: e.code.as_str().to_string(),
message: e.message.clone(),
}
}
}