pub use crate::runtime::tool_call::{ToolResult, ToolStatus};
use crate::thread::ToolCall;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum StopReason {
EndTurn,
MaxTokens,
ToolUse,
StopSequence,
}
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct TokenUsage {
#[serde(skip_serializing_if = "Option::is_none")]
pub prompt_tokens: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub completion_tokens: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub total_tokens: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub cache_read_tokens: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub cache_creation_tokens: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub thinking_tokens: Option<i32>,
}
#[derive(Debug, Clone)]
pub struct StreamResult {
pub text: String,
pub tool_calls: Vec<ToolCall>,
pub usage: Option<TokenUsage>,
pub stop_reason: Option<StopReason>,
}
impl StreamResult {
pub fn needs_tools(&self) -> bool {
!self.tool_calls.is_empty()
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct InferenceError {
#[serde(rename = "type")]
pub error_type: String,
pub message: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub error_class: Option<String>,
}
#[derive(Debug, Clone)]
pub struct LLMResponse {
pub outcome: Result<StreamResult, InferenceError>,
}
impl LLMResponse {
pub fn success(result: StreamResult) -> Self {
Self {
outcome: Ok(result),
}
}
pub fn error(error: InferenceError) -> Self {
Self {
outcome: Err(error),
}
}
}