Skip to main content

infinity_provider_protocol/
completion.rs

1//! Completion request, response streaming, and error types.
2
3use std::pin::Pin;
4
5use futures_util::Stream;
6use serde::{Deserialize, Serialize};
7
8use crate::message::{Message, Reasoning, ToolCall};
9
10/// A request to stream one completion from a model.
11///
12/// This is the entire API surface providers must support; anything
13/// provider-specific (thinking configuration, beta flags, ...) travels in
14/// `additional_params` or is applied by the provider itself.
15#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
16pub struct CompletionRequest {
17    /// The system prompt.
18    pub preamble: Option<String>,
19    /// The conversation so far, ending with the content to complete.
20    pub chat_history: Vec<Message>,
21    /// Definitions of the tools available to the model.
22    pub tools: Vec<ToolDefinition>,
23    /// Maximum number of output tokens. `None` uses the provider's default.
24    pub max_tokens: Option<u64>,
25    /// Extra provider-specific request parameters, merged into the request
26    /// by the provider.
27    pub additional_params: Option<serde_json::Value>,
28}
29
30/// Definition of one tool the model may call.
31#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
32pub struct ToolDefinition {
33    pub name: String,
34    pub description: String,
35    /// JSON schema of the tool's arguments.
36    pub parameters: serde_json::Value,
37}
38
39/// Token usage reported by a provider for one completion.
40#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
41pub struct Usage {
42    /// The number of input ("prompt") tokens used in a given request.
43    #[serde(default)]
44    pub input_tokens: u64,
45    /// The number of output ("completion") tokens used in a given request.
46    #[serde(default)]
47    pub output_tokens: u64,
48    /// Stored separately as some providers only report one number.
49    #[serde(default)]
50    pub total_tokens: u64,
51    /// The number of cached input tokens (from prompt caching). 0 if not
52    /// reported by the provider.
53    #[serde(default)]
54    pub cached_input_tokens: u64,
55}
56
57/// Error invoking a completion model.
58#[derive(Debug, thiserror::Error)]
59pub enum CompletionError {
60    /// Error building the completion request.
61    #[error("RequestError: {0}")]
62    RequestError(#[from] Box<dyn std::error::Error + Send + Sync + 'static>),
63
64    /// Error parsing the completion response.
65    #[error("ResponseError: {0}")]
66    ResponseError(String),
67
68    /// Error returned by the completion model provider.
69    #[error("ProviderError: {0}")]
70    ProviderError(String),
71
72    /// JSON (de)serialization error.
73    #[error("JsonError: {0}")]
74    JsonError(#[from] serde_json::Error),
75}
76
77/// One streamed item of a completion response.
78///
79/// Deltas stream incremental UI-facing content; the non-delta variants
80/// (`ToolCall`, `Reasoning`) carry the complete block to be recorded in
81/// history. A well-formed stream ends with `Final` (though providers may
82/// terminate without one, e.g. on network errors).
83#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
84pub enum StreamChunk {
85    /// A chunk of assistant text.
86    Text(String),
87    /// A complete tool call (all arguments accumulated).
88    ToolCall(ToolCall),
89    /// An incremental piece of an in-progress tool call.
90    ToolCallDelta {
91        /// Provider-supplied tool call id.
92        id: String,
93        content: ToolCallDeltaContent,
94    },
95    /// A complete reasoning block.
96    Reasoning(Reasoning),
97    /// A chunk of reasoning text.
98    ReasoningDelta { id: Option<String>, text: String },
99    /// The final chunk, carrying the completion's token usage (if the
100    /// provider reports it).
101    Final(FinalResponse),
102}
103
104/// The content of a [`StreamChunk::ToolCallDelta`].
105#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
106pub enum ToolCallDeltaContent {
107    /// The name of the tool being called (start of the call).
108    Name(String),
109    /// A fragment of the call's JSON arguments.
110    Delta(String),
111}
112
113/// Payload of [`StreamChunk::Final`].
114#[derive(Clone, Copy, Debug, Default, PartialEq, Serialize, Deserialize)]
115pub struct FinalResponse {
116    pub usage: Option<Usage>,
117}
118
119/// The streaming response returned by a model invocation.
120pub type ModelStream = Pin<Box<dyn Stream<Item = Result<StreamChunk, CompletionError>> + Send>>;