Skip to main content

codei_llm/
lib.rs

1//! LLM provider abstraction for CodeI.
2
3mod error;
4mod factory;
5mod message;
6mod provider;
7mod stream;
8mod tool;
9mod tool_format;
10
11pub use error::LlmError;
12pub use factory::{create_provider, create_provider_by_name};
13pub use message::{Message, Role, ToolCall};
14pub use provider::LlmProvider;
15pub use stream::{collect_response, ChatStream, StreamEvent, Usage};
16pub use tool::ToolDefinition;
17pub use tool_format::ToolFormat;
18
19use serde::{Deserialize, Serialize};
20
21/// Request sent to an LLM provider.
22#[derive(Debug, Clone)]
23pub struct ChatRequest {
24    pub model: String,
25    pub messages: Vec<Message>,
26    pub tools: Option<Vec<ToolDefinition>>,
27    pub temperature: Option<f32>,
28    pub max_tokens: Option<u32>,
29}
30
31/// Aggregated assistant response after consuming a stream.
32#[derive(Debug, Clone, Default)]
33pub struct AssistantResponse {
34    pub content: String,
35    pub tool_calls: Vec<ToolCall>,
36    pub usage: Option<Usage>,
37}
38
39/// OpenAI-compatible streaming chunk (internal).
40#[derive(Debug, Deserialize)]
41pub(crate) struct ChatCompletionChunk {
42    pub choices: Vec<StreamChoice>,
43    pub usage: Option<OpenAiUsage>,
44}
45
46#[derive(Debug, Deserialize)]
47pub(crate) struct StreamChoice {
48    pub delta: StreamDelta,
49    #[allow(dead_code)]
50    pub finish_reason: Option<String>,
51}
52
53#[derive(Debug, Deserialize, Default)]
54pub(crate) struct StreamDelta {
55    pub content: Option<String>,
56    pub tool_calls: Option<Vec<StreamToolCallDelta>>,
57    pub function_call: Option<StreamFunctionDelta>,
58}
59
60#[derive(Debug, Deserialize)]
61pub(crate) struct StreamToolCallDelta {
62    #[serde(default)]
63    pub index: u32,
64    pub id: Option<String>,
65    pub function: Option<StreamFunctionDelta>,
66    /// Some OpenAI-compatible servers (e.g. certain vLLM builds) flatten these fields.
67    pub name: Option<String>,
68    pub arguments: Option<String>,
69}
70
71#[derive(Debug, Deserialize)]
72pub(crate) struct StreamFunctionDelta {
73    pub name: Option<String>,
74    pub arguments: Option<String>,
75}
76
77impl StreamToolCallDelta {
78    pub(crate) fn id(&self) -> Option<String> {
79        self.id.clone()
80    }
81
82    pub(crate) fn name(&self) -> Option<String> {
83        self.function
84            .as_ref()
85            .and_then(|f| f.name.clone())
86            .or_else(|| self.name.clone())
87    }
88
89    pub(crate) fn arguments(&self) -> Option<String> {
90        self.function
91            .as_ref()
92            .and_then(|f| f.arguments.clone())
93            .or_else(|| self.arguments.clone())
94    }
95}
96
97#[derive(Debug, Deserialize, Serialize)]
98pub(crate) struct OpenAiUsage {
99    pub prompt_tokens: u32,
100    pub completion_tokens: u32,
101}