use rskit_tool::ToolSchema;
use serde::{Deserialize, Serialize};
pub use rskit_ai::chat::{
AssistantMessage, Message, SystemMessage, ToolResultMessage, UserMessage, assistant, system,
tool_result_msg, user,
};
pub use rskit_ai::{
ContentPart, FinishReason, ToolResultBlock, ToolUseBlock, Usage, text_content, text_of,
};
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ToolDefinition {
pub name: String,
pub description: String,
pub input_schema: ToolSchema,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub output_schema: Option<ToolSchema>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ToolChoice {
pub mode: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub function: Option<String>,
}
impl ToolChoice {
#[must_use]
pub fn auto() -> Self {
Self {
mode: "auto".to_string(),
function: None,
}
}
#[must_use]
pub fn none() -> Self {
Self {
mode: "none".to_string(),
function: None,
}
}
#[must_use]
pub fn required() -> Self {
Self {
mode: "required".to_string(),
function: None,
}
}
#[must_use]
pub fn specific(name: &str) -> Self {
Self {
mode: "specific".to_string(),
function: Some(name.to_string()),
}
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct CompletionRequest {
pub model: String,
pub messages: Vec<Message>,
pub max_tokens: Option<u32>,
pub temperature: Option<f32>,
pub stream: bool,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub tools: Option<Vec<ToolDefinition>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub tool_choice: Option<ToolChoice>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct CompletionResponse {
pub message: AssistantMessage,
pub model: String,
pub usage: Usage,
pub stop_reason: Option<FinishReason>,
}
impl CompletionResponse {
#[must_use]
pub fn has_tool_calls(&self) -> bool {
self.message.has_tool_calls()
}
#[must_use]
pub fn text(&self) -> String {
self.message.text()
}
}