Skip to main content

llmsdk_provider/language_model/
result.rs

1//! Results returned by `do_generate` / `do_stream`.
2//!
3//! Mirrors `-generate-result.ts`, `-stream-result.ts`, `-response-metadata.ts`.
4// Rust guideline compliant 2026-02-21
5
6use std::collections::HashMap;
7
8use serde::{Deserialize, Serialize};
9
10use crate::error::Result;
11use crate::shared::{Headers, ProviderMetadata, RequestInfo, Warning};
12
13use super::BoxStream;
14use super::content::Content;
15use super::finish_reason::FinishReason;
16use super::stream_part::StreamPart;
17use super::usage::Usage;
18
19/// Result of [`super::LanguageModel::do_generate`].
20#[derive(Debug, Clone)]
21pub struct GenerateResult {
22    /// Ordered model output.
23    pub content: Vec<Content>,
24    /// Why the model stopped.
25    pub finish_reason: FinishReason,
26    /// Token usage.
27    pub usage: Usage,
28    /// Provider-specific metadata.
29    pub provider_metadata: Option<ProviderMetadata>,
30    /// Request info (telemetry).
31    pub request: Option<RequestInfo>,
32    /// Response info (telemetry).
33    pub response: Option<GenerateResponse>,
34    /// Warnings, e.g. unsupported settings.
35    pub warnings: Vec<Warning>,
36}
37
38/// Response-side info attached to [`GenerateResult`].
39#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
40pub struct GenerateResponse {
41    /// Inline response metadata.
42    #[serde(flatten)]
43    pub metadata: ResponseMetadata,
44    /// Response HTTP body for debugging.
45    #[serde(default, skip_serializing_if = "Option::is_none")]
46    pub body: Option<crate::json::JsonValue>,
47}
48
49/// Response metadata reported by a provider mid-stream or post-call.
50#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
51pub struct ResponseMetadata {
52    /// Provider-reported response id.
53    #[serde(default, skip_serializing_if = "Option::is_none")]
54    pub id: Option<String>,
55    /// Provider-reported timestamp (ISO-8601).
56    #[serde(default, skip_serializing_if = "Option::is_none")]
57    pub timestamp: Option<String>,
58    /// Provider-reported model id.
59    #[serde(default, rename = "modelId", skip_serializing_if = "Option::is_none")]
60    pub model_id: Option<String>,
61    /// Response headers.
62    #[serde(default, skip_serializing_if = "Option::is_none")]
63    pub headers: Option<Headers>,
64}
65
66/// Result of [`super::LanguageModel::do_stream`].
67///
68/// Owns the stream of [`StreamPart`]s. Each item is a `Result` so the
69/// transport can surface partial failures; in-stream provider errors are
70/// delivered as [`StreamPart::Error`] (still `Ok`).
71#[expect(
72    missing_debug_implementations,
73    reason = "BoxStream is not Debug; trait obj has no useful repr"
74)]
75pub struct StreamResult {
76    /// Yielded parts.
77    pub stream: BoxStream<Result<StreamPart>>,
78    /// Request info (telemetry).
79    pub request: Option<RequestInfo>,
80    /// Response headers captured at stream start.
81    pub response: Option<StreamResponse>,
82}
83
84/// Headers / metadata available when the stream opens.
85#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
86pub struct StreamResponse {
87    /// Response headers.
88    #[serde(default, skip_serializing_if = "Option::is_none")]
89    pub headers: Option<Headers>,
90}
91
92/// Native-URL support map returned by [`super::LanguageModel::supported_urls`].
93///
94/// Keys are media-type globs (e.g. `"*/*"`, `"image/*"`, `"application/pdf"`).
95/// Values are regex pattern strings — kept as plain `String` so that
96/// downstream crates pick their preferred regex engine.
97pub type SupportedUrls = HashMap<String, Vec<UrlPattern>>;
98
99/// One supported-URL regex pattern entry.
100#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
101pub struct UrlPattern(pub String);
102
103impl UrlPattern {
104    /// Wrap an existing pattern string.
105    pub fn new(pattern: impl Into<String>) -> Self {
106        Self(pattern.into())
107    }
108
109    /// Borrow the pattern.
110    #[must_use]
111    pub fn as_str(&self) -> &str {
112        &self.0
113    }
114}