use chrono::DateTime;
use chrono::Utc;
use serde::Deserialize;
use serde::Serialize;
use super::content::Content;
use super::finish_reason::FinishReason;
use super::stream_part::StreamPart;
use super::usage::Usage;
use crate::dynamic::BoxStream;
use crate::json::JsonValue;
use crate::shared::Headers;
use crate::shared::ModelId;
use crate::shared::ProviderMetadata;
use crate::shared::Warning;
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
pub struct RequestMetadata {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub body: Option<JsonValue>,
}
impl RequestMetadata {
#[must_use]
pub fn with_body(body: JsonValue) -> Self {
Self { body: Some(body) }
}
}
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
pub struct ResponseMetadata {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub id: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub timestamp: Option<DateTime<Utc>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub model_id: Option<ModelId>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub headers: Option<Headers>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub body: Option<JsonValue>,
}
impl ResponseMetadata {
#[must_use]
pub fn with_headers(headers: Headers) -> Self {
Self {
headers: Some(headers),
..Self::default()
}
}
#[must_use]
pub fn new(timestamp: DateTime<Utc>, model_id: impl Into<ModelId>) -> Self {
Self {
timestamp: Some(timestamp),
model_id: Some(model_id.into()),
..Self::default()
}
}
pub fn merge(&mut self, other: ResponseMetadata) {
if other.id.is_some() {
self.id = other.id;
}
if other.timestamp.is_some() {
self.timestamp = other.timestamp;
}
if other.model_id.is_some() {
self.model_id = other.model_id;
}
if other.headers.is_some() {
self.headers = other.headers;
}
if other.body.is_some() {
self.body = other.body;
}
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct GenerateResult {
pub content: Vec<Content>,
pub finish_reason: FinishReason,
#[serde(default)]
pub usage: Usage,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub provider_metadata: Option<ProviderMetadata>,
#[serde(default)]
pub request: RequestMetadata,
#[serde(default)]
pub response: ResponseMetadata,
#[serde(default)]
pub warnings: Vec<Warning>,
}
impl GenerateResult {
#[must_use]
pub fn new(content: Vec<Content>, finish_reason: FinishReason) -> Self {
Self {
content,
finish_reason,
usage: Usage::default(),
provider_metadata: None,
request: RequestMetadata::default(),
response: ResponseMetadata::default(),
warnings: Vec::new(),
}
}
#[must_use]
pub fn text(&self) -> String {
self.content.iter().filter_map(Content::as_text).collect()
}
}
pub struct StreamResult {
pub stream: BoxStream<'static, StreamPart>,
pub request: RequestMetadata,
pub response: ResponseMetadata,
}
impl StreamResult {
#[must_use]
pub fn new(stream: BoxStream<'static, StreamPart>) -> Self {
Self {
stream,
request: RequestMetadata::default(),
response: ResponseMetadata::default(),
}
}
}
impl std::fmt::Debug for StreamResult {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("StreamResult")
.field("stream", &"<stream>")
.field("request", &self.request)
.field("response", &self.response)
.finish()
}
}