pub struct CompletionRequest {
pub model: Option<String>,
pub preamble: Option<String>,
pub chat_history: Vec<Message>,
pub documents: Vec<Document>,
pub tools: Vec<ToolDefinition>,
pub temperature: Option<f64>,
pub max_tokens: Option<u64>,
pub tool_choice: Option<ToolChoice>,
pub additional_params: Option<Value>,
pub output_schema: Option<Schema>,
pub record_telemetry_content: bool,
}Expand description
Struct representing a general completion request that can be sent to a completion model provider.
Fields§
§model: Option<String>Optional model override for this request.
preamble: Option<String>Legacy preamble field preserved for backwards compatibility.
New code should prefer a leading Message::System
in chat_history as the canonical representation of system instructions.
chat_history: Vec<Message>The chat history to be sent to the completion model provider. The very last message is the prompt.
This used to be a non-empty container, so “there is always at least one”
was a type guarantee. It is a Vec now and the field is public, so the
guarantee is a rule instead: it is checked by
CompletionRequest::validate_message_content at the request boundary.
documents: Vec<Document>The documents to be sent to the completion model provider
tools: Vec<ToolDefinition>The tools to be sent to the completion model provider
temperature: Option<f64>The temperature to be sent to the completion model provider
max_tokens: Option<u64>The max tokens to be sent to the completion model provider
tool_choice: Option<ToolChoice>Whether tools are required to be used by the model provider or not before providing a response.
additional_params: Option<Value>Additional provider-specific parameters to be sent to the completion model provider
output_schema: Option<Schema>Optional JSON Schema for structured output. When set, providers that support native structured outputs will constrain the model’s response to match this schema.
record_telemetry_content: boolWhether to record sensitive request, response, and tool content on GenAI telemetry spans.
Defaults to false. Enabling this can expose prompts, retrieved context,
tool results, model responses, and other sensitive or high-cardinality data
through OpenTelemetry span attributes, which can increase observability
backend storage and query costs. Only enable it when the caller has
explicitly opted in to content telemetry.
Higher-level agent drivers use this flag for portable input, output, and tool-content telemetry. Direct provider calls only forward the policy; the exact content fields available there are provider- and surface-dependent, especially for streaming responses that are consumed after the provider returns.
This is local observability policy and is never serialized into provider request payloads.
Implementations§
Source§impl CompletionRequest
impl CompletionRequest
Sourcepub fn validate_message_content(&self) -> Result<(), CompletionError>
pub fn validate_message_content(&self) -> Result<(), CompletionError>
Reject a request with no messages, or a message that carries no content.
Removing the non-empty container removed two guarantees at once, and this is where both are restated:
chat_historywas non-empty by construction. As aVecit is not, and the field is public, soCompletionRequest { chat_history: vec![], .. }is constructible and would reach a provider asmessages: []— a remote 400 in place of a local error that names the problem.- Message content was likewise non-empty by construction, and every wire rejects an empty content block.
The rule also covers the block list inside a tool result. A user
message carrying one UserContent::ToolResult is itself non-empty, but
ToolResult::content was non-empty by construction under the removed
container and is request-direction data just like the message content
around it — so its check is relocated here rather than dropped. Only a
tool result with zero blocks is rejected; a tool that legitimately
returned an empty string produces one block and still sends.
This is the request direction only, and the asymmetry is deliberate.
Empty assistant content is a real provider outcome on the response path
— a tool-call-only turn, a content-filtered turn, a truncated stream — and
the agent layer drops such a turn rather than sending it, so it never
reaches here. The response direction is guarded per-wire instead, by
crate::message::require_non_empty, because “this provider returned
nothing where its protocol promises content” is a judgement only the
provider’s own conversion can make.
System content is deliberately not checked. It is a String and always
has been, so the removed container never constrained it; rejecting an
empty one would be a new restriction rather than a relocated enforcement
point, and would break a history carrying a conditionally built preamble
that resolved to "".
Where this runs. CompletionRequestBuilder::send and
CompletionRequestBuilder::stream call it, which covers both agent
surfaces too — the blocking and streaming turn drivers both issue their
request through the builder. Handing a request straight to a
CompletionModel bypasses it; call this yourself there.
Sourcepub fn output_schema_name(&self) -> Option<String>
pub fn output_schema_name(&self) -> Option<String>
Extracts a name from the output schema’s "title" field, falling back to "response_schema".
Useful for providers that require a name alongside the JSON Schema (e.g., OpenAI).
Sourcepub fn normalized_documents(&self) -> Option<Message>
pub fn normalized_documents(&self) -> Option<Message>
Returns documents normalized into a message (if any).
Most providers do not accept documents directly as input, so it needs to convert into a
Message so that it can be incorporated into chat_history.
Trait Implementations§
Source§impl Clone for CompletionRequest
impl Clone for CompletionRequest
Source§fn clone(&self) -> CompletionRequest
fn clone(&self) -> CompletionRequest
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for CompletionRequest
impl Debug for CompletionRequest
Source§impl<'de> Deserialize<'de> for CompletionRequest
impl<'de> Deserialize<'de> for CompletionRequest
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Auto Trait Implementations§
impl Freeze for CompletionRequest
impl RefUnwindSafe for CompletionRequest
impl Send for CompletionRequest
impl Sync for CompletionRequest
impl Unpin for CompletionRequest
impl UnsafeUnpin for CompletionRequest
impl UnwindSafe for CompletionRequest
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more