chore: fix all 702 clippy warnings across codebase - auto-fix 475 via cargo clippy --fix - fix remaining 227 manually: uninlined_format_args, redundant_closure, match_same_arms, underscore_binding, format_push_string, items_after_statements, needless_pass_by_value, clone_on_copy, case_sensitive_extension, single_match/let-else, write_with_newline, and other clippy lints
75 lines
2.9 KiB
Rust
75 lines
2.9 KiB
Rust
//! Outbound request DTOs for the OpenAI/Anthropic-compatible chat completions API.
|
|
//!
|
|
//! Flow: `harness`/`runtime` builds a `ChatRequest` from conversation state and
|
|
//! the active tool set → serializes to JSON via `serde` → sends to the
|
|
//! provider's `/chat/completions`-style endpoint (streaming or not).
|
|
//!
|
|
//! Why: fields mirror the wire format exactly (including `#[serde(rename)]`
|
|
//! for reserved words like `type`) so no manual (de)serialization glue is
|
|
//! needed; optional fields use `skip_serializing_if` so unset knobs are
|
|
//! omitted rather than sent as `null`, matching provider expectations.
|
|
|
|
use serde::{Deserialize, Serialize};
|
|
use serde_json::Value;
|
|
|
|
/// Outbound chat completion request body sent to an OpenAI/Anthropic-compatible provider.
|
|
///
|
|
/// Flow: constructed from the current message history plus optional
|
|
/// generation knobs (temperature, `max_tokens`, tools, etc.) and serialized
|
|
/// directly into the HTTP request body.
|
|
///
|
|
/// Return: not a function, but the value that becomes the JSON request
|
|
/// payload for a completion call.
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct ChatRequest {
|
|
pub model: String,
|
|
pub messages: Vec<super::super::chat::message::ChatMessage>,
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
pub max_tokens: Option<u32>,
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
pub temperature: Option<f32>,
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
pub tools: Option<Vec<ToolDef>>,
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
pub stream: Option<bool>,
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
pub top_p: Option<f32>,
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
pub stop: Option<Vec<String>>,
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
pub stream_options: Option<StreamOptions>,
|
|
}
|
|
|
|
/// Streaming options for the request; `include_usage` asks the provider to
|
|
/// emit a final usage chunk in the SSE stream.
|
|
///
|
|
/// Why: usage tokens are otherwise unavailable in a streamed response since
|
|
/// they're normally only attached to the final non-streamed completion.
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct StreamOptions {
|
|
pub include_usage: bool,
|
|
}
|
|
|
|
/// Wire format for a single tool definition sent to the provider.
|
|
///
|
|
/// Flow: built from the harness's registered `Tool` impls (see `all_tools()`)
|
|
/// and attached to `ChatRequest.tools` so the model knows which functions it
|
|
/// may call.
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct ToolDef {
|
|
#[serde(rename = "type")]
|
|
pub type_: String,
|
|
pub function: ToolFunctionDef,
|
|
}
|
|
|
|
/// Name, description, and JSON schema parameters for a tool definition.
|
|
///
|
|
/// Why: `parameters` is a raw `serde_json::Value` rather than a typed struct
|
|
/// because each tool defines its own arbitrary JSON schema.
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct ToolFunctionDef {
|
|
pub name: String,
|
|
pub description: String,
|
|
pub parameters: Value,
|
|
}
|