alith_interface/llms/api/openai/completion/
res.rs1use crate::requests::completion::tool::ToolCall;
2use crate::requests::completion::*;
3use serde::{Deserialize, Serialize};
4
5impl CompletionResponse {
6 pub fn new_from_openai(
7 req: &CompletionRequest,
8 res: OpenAICompletionResponse,
9 ) -> Result<Self, CompletionError> {
10 let choice = if res.choices.is_empty() {
11 return Err(CompletionError::ResponseContentEmpty);
12 } else {
13 &res.choices[0]
14 };
15 let finish_reason = match choice.finish_reason {
16 Some(FinishReason::Stop) => CompletionFinishReason::Eos,
17 Some(FinishReason::Length) => CompletionFinishReason::StopLimit,
18 Some(FinishReason::ToolCalls) => CompletionFinishReason::ToolsCall,
19 Some(FinishReason::ContentFilter) => {
20 return Err(CompletionError::StopReasonUnsupported(
21 "FinishReason::ContentFilter is not supported".to_owned(),
22 ));
23 }
24 Some(FinishReason::FunctionCall) => {
25 return Err(CompletionError::StopReasonUnsupported(
26 "FinishReason::FunctionCall is not supported".to_owned(),
27 ));
28 }
29 None => CompletionFinishReason::Eos,
30 };
31 Ok(Self {
32 id: res.id.to_owned(),
33 index: None,
34 content: choice.message.content.as_ref().cloned().unwrap_or_default(),
35 finish_reason,
36 completion_probabilities: None,
37 truncated: false,
38 generation_settings: GenerationSettings::new_from_openai(req, &res),
39 timing_usage: TimingUsage::new_from_generic(req.start_time),
40 token_usage: TokenUsage::new_from_generic(&res),
41 tool_calls: choice.message.tool_calls.clone(),
42 })
43 }
44}
45
46#[derive(Debug, Deserialize, Clone, PartialEq, Serialize)]
48pub struct OpenAICompletionResponse {
49 pub id: String,
51 pub choices: Vec<ChatChoice>,
53 pub created: u32,
55 pub model: String,
57 pub usage: Option<CompletionUsage>,
58}
59
60#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
61pub struct ChatChoice {
62 pub index: u32,
64 pub message: ChatCompletionResponseMessage,
65 pub finish_reason: Option<FinishReason>,
70 pub logprobs: Option<ChatChoiceLogprobs>,
72}
73
74#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
76pub struct CompletionUsage {
77 pub prompt_tokens: u32,
79 pub completion_tokens: u32,
81 pub total_tokens: u32,
83}
84
85#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
87pub struct ChatCompletionResponseMessage {
88 pub content: Option<String>,
90 pub role: Role,
92 #[serde(skip_serializing_if = "Option::is_none")]
94 pub tool_calls: Option<Vec<ToolCall>>,
95}
96
97#[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq)]
98#[serde(rename_all = "snake_case")]
99pub enum FinishReason {
100 Stop,
101 Length,
102 ToolCalls,
103 ContentFilter,
104 FunctionCall,
105}
106
107#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
108pub struct ChatChoiceLogprobs {
109 pub content: Option<Vec<ChatCompletionTokenLogprob>>,
111}
112
113#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
114pub struct ChatCompletionTokenLogprob {
115 pub token: String,
117 pub logprob: f32,
119 pub bytes: Option<Vec<u8>>,
121 pub top_logprobs: Vec<TopLogprobs>,
123}
124
125#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
126pub struct TopLogprobs {
127 pub token: String,
129 pub logprob: f32,
131 pub bytes: Option<Vec<u8>>,
133}
134
135#[derive(Debug, Serialize, Deserialize, Clone, Copy, Default, PartialEq)]
136#[serde(rename_all = "lowercase")]
137pub enum Role {
138 System,
139 #[default]
140 User,
141 Assistant,
142 Tool,
143 Function,
144}