Skip to main content

openai_core/resources/
chat.rs

1//! Chat namespace implementations, builders, and tool-runner helpers.
2
3use std::collections::BTreeMap;
4#[cfg(feature = "structured-output")]
5use std::marker::PhantomData;
6use std::time::Duration;
7
8use bytes::Bytes;
9use http::Method;
10#[cfg(feature = "structured-output")]
11use schemars::JsonSchema;
12#[cfg(feature = "tool-runner")]
13use serde::Deserialize;
14use serde::Serialize;
15use serde_json::Value;
16use tokio_util::sync::CancellationToken;
17
18use crate::Client;
19use crate::config::RequestOptions;
20use crate::error::{Error, Result};
21use crate::generated::endpoints;
22#[cfg(feature = "structured-output")]
23use crate::helpers::{ParsedChatCompletion, parse_json_payload};
24#[cfg(feature = "tool-runner")]
25use crate::helpers::{ToolDefinition, ToolRegistry};
26use crate::json_payload::JsonPayload;
27use crate::response_meta::ApiResponse;
28#[cfg(feature = "tool-runner")]
29use crate::stream::ChatCompletionRuntimeEvent;
30use crate::stream::{
31    AssistantEventStream, AssistantStream, ChatCompletionEventStream, ChatCompletionStream,
32};
33use crate::transport::{RequestSpec, merge_json_body};
34#[cfg(feature = "tool-runner")]
35use futures_util::StreamExt;
36
37#[cfg(feature = "tool-runner")]
38use super::ChatCompletionToolCall;
39#[cfg(feature = "tool-runner")]
40use super::CompletionUsage;
41use super::{
42    ChatCompletion, ChatCompletionCreateParams, ChatCompletionMessage,
43    ChatCompletionMessagesResource, ChatCompletionStoreContentPart, ChatCompletionsResource,
44    ChatResource, ChatToolChoice, ChatToolDefinition, DeleteResponse, JsonRequestBuilder,
45    ListRequestBuilder, encode_path_segment, value_from,
46};
47
48/// 表示已存储 chat completion 下的消息对象。
49#[derive(Debug, Clone, Serialize, serde::Deserialize, Default)]
50pub struct ChatCompletionStoreMessage {
51    /// 消息 ID。
52    pub id: String,
53    /// 角色。
54    #[serde(default)]
55    pub role: String,
56    /// 文本内容。
57    #[serde(skip_serializing_if = "Option::is_none")]
58    pub content: Option<String>,
59    /// content parts。
60    #[serde(default, skip_serializing_if = "Vec::is_empty")]
61    pub content_parts: Vec<ChatCompletionStoreContentPart>,
62    /// 工具调用。
63    #[serde(default, skip_serializing_if = "Vec::is_empty")]
64    pub tool_calls: Vec<super::ChatCompletionToolCall>,
65    /// 额外字段。
66    #[serde(flatten)]
67    pub extra: BTreeMap<String, Value>,
68}
69
70impl ChatResource {
71    /// 返回聊天补全资源。
72    pub fn completions(&self) -> ChatCompletionsResource {
73        ChatCompletionsResource::new(self.client.clone())
74    }
75}
76
77impl ChatCompletionsResource {
78    /// 创建聊天补全请求构建器。
79    pub fn create(&self) -> ChatCompletionCreateRequestBuilder {
80        ChatCompletionCreateRequestBuilder::new(self.client.clone())
81    }
82
83    /// 创建聊天补全流式请求构建器。
84    pub fn stream(&self) -> ChatCompletionStreamRequestBuilder {
85        ChatCompletionStreamRequestBuilder::new(self.client.clone())
86    }
87
88    /// 创建结构化解析请求构建器。
89    #[cfg(feature = "structured-output")]
90    #[cfg_attr(docsrs, doc(cfg(feature = "structured-output")))]
91    pub fn parse<T>(&self) -> ChatCompletionParseRequestBuilder<T> {
92        ChatCompletionParseRequestBuilder::new(self.client.clone())
93    }
94
95    /// 创建工具运行构建器。
96    #[cfg(feature = "tool-runner")]
97    #[cfg_attr(docsrs, doc(cfg(feature = "tool-runner")))]
98    pub fn run_tools(&self) -> ChatCompletionRunToolsRequestBuilder {
99        ChatCompletionRunToolsRequestBuilder::new(self.client.clone())
100    }
101
102    /// 根据 ID 获取聊天补全对象。
103    pub fn retrieve(&self, id: impl Into<String>) -> JsonRequestBuilder<ChatCompletion> {
104        JsonRequestBuilder::new(
105            self.client.clone(),
106            "chat.completions.retrieve",
107            Method::GET,
108            format!("/chat/completions/{}", encode_path_segment(id.into())),
109        )
110    }
111
112    /// 更新聊天补全对象。
113    pub fn update(&self, id: impl Into<String>) -> JsonRequestBuilder<ChatCompletion> {
114        JsonRequestBuilder::new(
115            self.client.clone(),
116            "chat.completions.update",
117            Method::POST,
118            format!("/chat/completions/{}", encode_path_segment(id.into())),
119        )
120    }
121
122    /// 列出聊天补全对象。
123    pub fn list(&self) -> ListRequestBuilder<ChatCompletion> {
124        ListRequestBuilder::new(
125            self.client.clone(),
126            "chat.completions.list",
127            "/chat/completions",
128        )
129    }
130
131    /// 删除聊天补全对象。
132    pub fn delete(&self, id: impl Into<String>) -> JsonRequestBuilder<DeleteResponse> {
133        JsonRequestBuilder::new(
134            self.client.clone(),
135            "chat.completions.delete",
136            Method::DELETE,
137            format!("/chat/completions/{}", encode_path_segment(id.into())),
138        )
139    }
140
141    /// 返回聊天补全消息子资源。
142    pub fn messages(&self) -> ChatCompletionMessagesResource {
143        ChatCompletionMessagesResource::new(self.client.clone())
144    }
145}
146
147impl ChatCompletionMessagesResource {
148    /// 列出某个聊天补全下的消息。
149    pub fn list(
150        &self,
151        completion_id: impl Into<String>,
152    ) -> ListRequestBuilder<ChatCompletionStoreMessage> {
153        let endpoint = endpoints::chat::CHAT_COMPLETIONS_MESSAGES_LIST;
154        ListRequestBuilder::new(
155            self.client.clone(),
156            endpoint.id,
157            endpoint.render(&[("completion_id", &encode_path_segment(completion_id.into()))]),
158        )
159    }
160}
161
162/// 表示聊天补全创建构建器。
163#[derive(Debug, Clone, Default)]
164pub struct ChatCompletionCreateRequestBuilder {
165    client: Option<Client>,
166    pub(crate) params: ChatCompletionCreateParams,
167    options: RequestOptions,
168    extra_body: BTreeMap<String, Value>,
169    provider_options: BTreeMap<String, Value>,
170}
171
172impl ChatCompletionCreateRequestBuilder {
173    pub(crate) fn new(client: Client) -> Self {
174        Self {
175            client: Some(client),
176            ..Self::default()
177        }
178    }
179
180    /// 设置模型。
181    pub fn model(mut self, model: impl Into<String>) -> Self {
182        self.params.model = Some(model.into());
183        self
184    }
185
186    /// 直接设置消息列表。
187    pub fn messages(mut self, messages: Vec<ChatCompletionMessage>) -> Self {
188        self.params.messages = messages;
189        self
190    }
191
192    /// 追加一条 system 消息。
193    pub fn message_system(mut self, content: impl Into<String>) -> Self {
194        self.params
195            .messages
196            .push(ChatCompletionMessage::system(content));
197        self
198    }
199
200    /// 追加一条 user 消息。
201    pub fn message_user(mut self, content: impl Into<String>) -> Self {
202        self.params
203            .messages
204            .push(ChatCompletionMessage::user(content));
205        self
206    }
207
208    /// 追加一条 assistant 消息。
209    pub fn message_assistant(mut self, content: impl Into<String>) -> Self {
210        self.params
211            .messages
212            .push(ChatCompletionMessage::assistant(content));
213        self
214    }
215
216    /// 设置温度。
217    pub fn temperature(mut self, temperature: f32) -> Self {
218        self.params.temperature = Some(temperature);
219        self
220    }
221
222    /// 设置候选数量。
223    pub fn n(mut self, n: u32) -> Self {
224        self.params.n = Some(n);
225        self
226    }
227
228    /// 设置最大 token 数。
229    pub fn max_tokens(mut self, max_tokens: u32) -> Self {
230        self.params.max_tokens = Some(max_tokens);
231        self
232    }
233
234    /// 追加工具定义。
235    pub fn tool(mut self, tool: ChatToolDefinition) -> Self {
236        self.params.tools.push(tool);
237        self
238    }
239
240    /// 设置工具选择策略。
241    pub fn tool_choice(mut self, tool_choice: impl Into<ChatToolChoice>) -> Self {
242        self.params.tool_choice = Some(tool_choice.into());
243        self
244    }
245
246    /// 设置附加请求头。
247    pub fn extra_header(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
248        self.options.insert_header(key, value);
249        self
250    }
251
252    /// 设置附加查询参数。
253    pub fn extra_query(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
254        self.options.insert_query(key, value);
255        self
256    }
257
258    /// 在请求体根对象中追加字段。
259    pub fn extra_body(mut self, key: impl Into<String>, value: impl Into<JsonPayload>) -> Self {
260        self.extra_body.insert(key.into(), value.into().into_raw());
261        self
262    }
263
264    /// 在 provider 对应的 `provider_options` 节点下追加字段。
265    pub fn provider_option(
266        mut self,
267        key: impl Into<String>,
268        value: impl Into<JsonPayload>,
269    ) -> Self {
270        self.provider_options
271            .insert(key.into(), value.into().into_raw());
272        self
273    }
274
275    /// 覆盖超时时间。
276    pub fn timeout(mut self, timeout: Duration) -> Self {
277        self.options.timeout = Some(timeout);
278        self
279    }
280
281    /// 设置取消令牌。
282    pub fn cancellation_token(mut self, token: CancellationToken) -> Self {
283        self.options.cancellation_token = Some(token);
284        self
285    }
286
287    pub(crate) fn build_spec(mut self, stream: bool) -> Result<(Client, RequestSpec)> {
288        let client = self
289            .client
290            .take()
291            .ok_or_else(|| Error::InvalidConfig("聊天补全构建器缺少客户端".into()))?;
292        if self.params.model.as_deref().unwrap_or_default().is_empty() {
293            return Err(Error::MissingRequiredField { field: "model" });
294        }
295        if self.params.messages.is_empty() {
296            return Err(Error::MissingRequiredField { field: "messages" });
297        }
298        self.params.stream = Some(stream);
299        let provider_key = client.provider().kind().as_key();
300        let body = merge_json_body(
301            Some(value_from(&self.params)?),
302            &self.extra_body,
303            provider_key,
304            &self.provider_options,
305        );
306        let mut spec = RequestSpec::new(
307            if stream {
308                "chat.completions.stream"
309            } else {
310                "chat.completions.create"
311            },
312            Method::POST,
313            "/chat/completions",
314        );
315        spec.body = Some(body);
316        spec.options = self.options;
317        Ok((client, spec))
318    }
319
320    /// 发送普通聊天补全请求。
321    ///
322    /// # Errors
323    ///
324    /// 当参数校验失败、请求失败或反序列化失败时返回错误。
325    pub async fn send(self) -> Result<ChatCompletion> {
326        Ok(self.send_with_meta().await?.data)
327    }
328
329    /// 发送普通聊天补全请求并保留元信息。
330    ///
331    /// # Errors
332    ///
333    /// 当参数校验失败、请求失败或反序列化失败时返回错误。
334    pub async fn send_with_meta(self) -> Result<ApiResponse<ChatCompletion>> {
335        let (client, spec) = self.build_spec(false)?;
336        client.execute_json(spec).await
337    }
338
339    /// 发送普通聊天补全请求并返回原始 HTTP 响应。
340    ///
341    /// # Errors
342    ///
343    /// 当参数校验失败或请求失败时返回错误。
344    pub async fn send_raw(self) -> Result<http::Response<Bytes>> {
345        let (client, spec) = self.build_spec(false)?;
346        client.execute_raw_http(spec).await
347    }
348}
349
350/// 表示聊天补全流式请求构建器。
351#[derive(Debug, Clone)]
352pub struct ChatCompletionStreamRequestBuilder {
353    inner: ChatCompletionCreateRequestBuilder,
354}
355
356/// 表示 Assistants/Beta Threads 流式请求构建器。
357#[derive(Debug, Clone)]
358pub struct AssistantStreamRequestBuilder {
359    inner: JsonRequestBuilder<Value>,
360}
361
362impl ChatCompletionStreamRequestBuilder {
363    pub(crate) fn new(client: Client) -> Self {
364        Self {
365            inner: ChatCompletionCreateRequestBuilder::new(client),
366        }
367    }
368
369    /// 设置模型。
370    pub fn model(mut self, model: impl Into<String>) -> Self {
371        self.inner = self.inner.model(model);
372        self
373    }
374
375    /// 设置消息列表。
376    pub fn messages(mut self, messages: Vec<ChatCompletionMessage>) -> Self {
377        self.inner = self.inner.messages(messages);
378        self
379    }
380
381    /// 追加一条 system 消息。
382    pub fn message_system(mut self, content: impl Into<String>) -> Self {
383        self.inner = self.inner.message_system(content);
384        self
385    }
386
387    /// 追加一条 user 消息。
388    pub fn message_user(mut self, content: impl Into<String>) -> Self {
389        self.inner = self.inner.message_user(content);
390        self
391    }
392
393    /// 追加一条 assistant 消息。
394    pub fn message_assistant(mut self, content: impl Into<String>) -> Self {
395        self.inner = self.inner.message_assistant(content);
396        self
397    }
398
399    /// 设置温度。
400    pub fn temperature(mut self, temperature: f32) -> Self {
401        self.inner = self.inner.temperature(temperature);
402        self
403    }
404
405    /// 设置候选数量。
406    pub fn n(mut self, n: u32) -> Self {
407        self.inner = self.inner.n(n);
408        self
409    }
410
411    /// 设置最大 token 数。
412    pub fn max_tokens(mut self, max_tokens: u32) -> Self {
413        self.inner = self.inner.max_tokens(max_tokens);
414        self
415    }
416
417    /// 添加额外字段。
418    pub fn extra_body(mut self, key: impl Into<String>, value: impl Into<JsonPayload>) -> Self {
419        self.inner = self.inner.extra_body(key, value);
420        self
421    }
422
423    /// 添加 provider 选项。
424    pub fn provider_option(
425        mut self,
426        key: impl Into<String>,
427        value: impl Into<JsonPayload>,
428    ) -> Self {
429        self.inner = self.inner.provider_option(key, value);
430        self
431    }
432
433    /// 发送流式聊天补全请求。
434    ///
435    /// # Errors
436    ///
437    /// 当参数校验失败、请求失败或流初始化失败时返回错误。
438    pub async fn send(self) -> Result<ChatCompletionStream> {
439        let (client, spec) = self.inner.build_spec(true)?;
440        Ok(ChatCompletionStream::new(client.execute_sse(spec).await?))
441    }
442
443    /// 发送流式聊天补全请求,并返回带高层语义事件的运行时流。
444    ///
445    /// # Errors
446    ///
447    /// 当参数校验失败、请求失败或流初始化失败时返回错误。
448    pub async fn send_events(self) -> Result<ChatCompletionEventStream> {
449        Ok(self.send().await?.events())
450    }
451}
452
453impl AssistantStreamRequestBuilder {
454    pub(crate) fn new(
455        client: Client,
456        endpoint_id: &'static str,
457        method: Method,
458        path: impl Into<String>,
459    ) -> Self {
460        Self {
461            inner: JsonRequestBuilder::new(client, endpoint_id, method, path),
462        }
463    }
464
465    /// 设置整个请求体为一个 `serde_json::Value`。
466    pub fn body_value(mut self, body: impl Into<JsonPayload>) -> Self {
467        self.inner = self.inner.body_value(body);
468        self
469    }
470
471    /// 使用任意可序列化对象设置请求体。
472    ///
473    /// # Errors
474    ///
475    /// 当序列化失败时返回错误。
476    pub fn json_body<U>(mut self, body: &U) -> Result<Self>
477    where
478        U: Serialize,
479    {
480        self.inner = self.inner.json_body(body)?;
481        Ok(self)
482    }
483
484    /// 添加一个额外请求头。
485    pub fn extra_header(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
486        self.inner = self.inner.extra_header(key, value);
487        self
488    }
489
490    /// 删除一个默认请求头。
491    pub fn remove_header(mut self, key: impl Into<String>) -> Self {
492        self.inner = self.inner.remove_header(key);
493        self
494    }
495
496    /// 添加一个额外查询参数。
497    pub fn extra_query(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
498        self.inner = self.inner.extra_query(key, value);
499        self
500    }
501
502    /// 在 JSON 根对象中追加字段。
503    pub fn extra_body(mut self, key: impl Into<String>, value: impl Into<JsonPayload>) -> Self {
504        self.inner = self.inner.extra_body(key, value);
505        self
506    }
507
508    /// 在 provider 对应的 `provider_options` 下追加字段。
509    pub fn provider_option(
510        mut self,
511        key: impl Into<String>,
512        value: impl Into<JsonPayload>,
513    ) -> Self {
514        self.inner = self.inner.provider_option(key, value);
515        self
516    }
517
518    /// 覆盖请求超时时间。
519    pub fn timeout(mut self, timeout: Duration) -> Self {
520        self.inner = self.inner.timeout(timeout);
521        self
522    }
523
524    /// 覆盖最大重试次数。
525    pub fn max_retries(mut self, max_retries: u32) -> Self {
526        self.inner = self.inner.max_retries(max_retries);
527        self
528    }
529
530    /// 设置取消令牌。
531    pub fn cancellation_token(mut self, token: CancellationToken) -> Self {
532        self.inner = self.inner.cancellation_token(token);
533        self
534    }
535
536    /// 发送流式 Assistants 请求。
537    ///
538    /// # Errors
539    ///
540    /// 当请求失败或流初始化失败时返回错误。
541    pub async fn send(self) -> Result<AssistantStream> {
542        let client = self.inner.client.clone();
543        let stream = client.execute_raw_sse(self.inner.into_spec()).await?;
544        Ok(AssistantStream::new(stream))
545    }
546
547    /// 发送流式 Assistants 请求,并返回带高层派生事件的运行时流。
548    ///
549    /// # Errors
550    ///
551    /// 当请求失败或流初始化失败时返回错误。
552    pub async fn send_events(self) -> Result<AssistantEventStream> {
553        Ok(self.send().await?.events())
554    }
555}
556
557/// 表示聊天补全结构化解析构建器。
558#[cfg(feature = "structured-output")]
559#[derive(Debug, Clone)]
560pub struct ChatCompletionParseRequestBuilder<T> {
561    inner: ChatCompletionCreateRequestBuilder,
562    _marker: PhantomData<T>,
563}
564
565#[cfg(feature = "structured-output")]
566impl<T> ChatCompletionParseRequestBuilder<T> {
567    pub(crate) fn new(client: Client) -> Self {
568        Self {
569            inner: ChatCompletionCreateRequestBuilder::new(client),
570            _marker: PhantomData,
571        }
572    }
573
574    /// 设置模型。
575    pub fn model(mut self, model: impl Into<String>) -> Self {
576        self.inner = self.inner.model(model);
577        self
578    }
579
580    /// 设置消息列表。
581    pub fn messages(mut self, messages: Vec<ChatCompletionMessage>) -> Self {
582        self.inner = self.inner.messages(messages);
583        self
584    }
585
586    /// 追加一条 user 消息。
587    pub fn message_user(mut self, content: impl Into<String>) -> Self {
588        self.inner = self.inner.message_user(content);
589        self
590    }
591
592    /// 追加一个额外请求体字段。
593    pub fn extra_body(mut self, key: impl Into<String>, value: impl Into<JsonPayload>) -> Self {
594        self.inner = self.inner.extra_body(key, value);
595        self
596    }
597}
598
599#[cfg(feature = "structured-output")]
600impl<T> ChatCompletionParseRequestBuilder<T>
601where
602    T: JsonSchema + serde::de::DeserializeOwned,
603{
604    /// 发送请求并把首条 assistant 文本解析成结构化对象。
605    ///
606    /// # Errors
607    ///
608    /// 当模型返回内容为空或 JSON 解析失败时返回错误。
609    pub async fn send(self) -> Result<ParsedChatCompletion<T>> {
610        let response = self.inner.send().await?;
611        response.ensure_not_truncated()?;
612        let choice = response
613            .choices
614            .first()
615            .ok_or_else(|| Error::InvalidConfig("聊天补全返回中缺少 choice".into()))?;
616        let parsed = if let Some(content) = choice.message.content.as_deref() {
617            parse_json_payload(content)?
618        } else if let Some(parsed_arguments) = choice.message.parse_tool_arguments()? {
619            parsed_arguments
620        } else {
621            return Err(Error::InvalidConfig(
622                "聊天补全返回中既没有 assistant 文本,也没有可解析的工具参数".into(),
623            ));
624        };
625        Ok(ParsedChatCompletion { response, parsed })
626    }
627}
628
629/// 表示工具运行构建器。
630#[cfg(feature = "tool-runner")]
631#[derive(Debug, Clone)]
632pub struct ChatCompletionRunToolsRequestBuilder {
633    inner: ChatCompletionCreateRequestBuilder,
634    registry: ToolRegistry,
635    max_rounds: usize,
636}
637
638#[cfg(feature = "tool-runner")]
639impl ChatCompletionRunToolsRequestBuilder {
640    pub(crate) fn new(client: Client) -> Self {
641        Self {
642            inner: ChatCompletionCreateRequestBuilder::new(client),
643            registry: ToolRegistry::new(),
644            max_rounds: 8,
645        }
646    }
647
648    /// 设置模型。
649    pub fn model(mut self, model: impl Into<String>) -> Self {
650        self.inner = self.inner.model(model);
651        self
652    }
653
654    /// 设置消息列表。
655    pub fn messages(mut self, messages: Vec<ChatCompletionMessage>) -> Self {
656        self.inner = self.inner.messages(messages);
657        self
658    }
659
660    /// 追加一条 user 消息。
661    pub fn message_user(mut self, content: impl Into<String>) -> Self {
662        self.inner = self.inner.message_user(content);
663        self
664    }
665
666    /// 注册一个工具。
667    pub fn register_tool(mut self, tool: ToolDefinition) -> Self {
668        self.registry.register(tool);
669        self
670    }
671
672    /// 设置最大工具轮次。
673    pub fn max_rounds(mut self, max_rounds: usize) -> Self {
674        self.max_rounds = max_rounds;
675        self
676    }
677
678    /// 发送请求并返回工具调用运行 trace。
679    ///
680    /// # Errors
681    ///
682    /// 当工具不存在、工具执行失败或请求失败时返回错误。
683    pub async fn into_runner(self) -> Result<ChatCompletionRunner> {
684        let execution = self.execute(false).await?;
685        Ok(ChatCompletionRunner::from_execution(execution))
686    }
687
688    /// 使用流式请求执行工具调用,并返回包含流式事件的运行 trace。
689    ///
690    /// # Errors
691    ///
692    /// 当工具不存在、工具执行失败、流式请求失败或结束原因不可解析时返回错误。
693    pub async fn into_streaming_runner(self) -> Result<ChatCompletionStreamingRunner> {
694        let execution = self.execute(true).await?;
695        Ok(ChatCompletionStreamingRunner::from_execution(execution))
696    }
697
698    /// 发送请求并自动处理工具调用。
699    ///
700    /// # Errors
701    ///
702    /// 当工具不存在、工具执行失败或请求失败时返回错误。
703    pub async fn send(self) -> Result<ChatCompletion> {
704        self.into_runner()
705            .await?
706            .final_chat_completion()
707            .cloned()
708            .ok_or_else(|| Error::InvalidConfig("工具运行未返回最终聊天补全结果".into()))
709    }
710
711    /// 使用流式请求执行工具调用轮次,并返回最终聊天补全结果。
712    ///
713    /// # Errors
714    ///
715    /// 当工具不存在、工具执行失败、流式请求失败或结束原因不可解析时返回错误。
716    pub async fn send_streaming(self) -> Result<ChatCompletion> {
717        self.into_streaming_runner()
718            .await?
719            .final_chat_completion()
720            .cloned()
721            .ok_or_else(|| Error::InvalidConfig("工具运行未返回最终聊天补全结果".into()))
722    }
723
724    async fn execute(self, stream: bool) -> Result<ChatCompletionRunExecution> {
725        let mut inner = self.inner;
726        if inner.params.tools.is_empty() {
727            inner.params.tools = self
728                .registry
729                .all()
730                .map(ChatToolDefinition::from_tool)
731                .collect();
732        }
733
734        let mut messages = inner.params.messages.clone();
735        let mut execution = ChatCompletionRunExecution {
736            messages: messages.clone(),
737            ..ChatCompletionRunExecution::default()
738        };
739        for _ in 0..self.max_rounds {
740            let request = ChatCompletionCreateRequestBuilder {
741                params: ChatCompletionCreateParams {
742                    messages: messages.clone(),
743                    ..inner.params.clone()
744                },
745                ..inner.clone()
746            };
747            let response = if stream {
748                let (client, spec) = request.build_spec(true)?;
749                let mut event_stream =
750                    ChatCompletionStream::new(client.execute_sse(spec).await?).events();
751                while let Some(event) = event_stream.next().await {
752                    execution.stream_events.push(event?);
753                }
754                let response = event_stream
755                    .snapshot()
756                    .ok_or_else(|| Error::InvalidConfig("流式聊天补全未返回最终结果".into()))?;
757                response.ensure_not_truncated()?;
758                response
759            } else {
760                request.send().await?
761            };
762            execution.chat_completions.push(response.clone());
763            let Some(choice) = response.choices.first() else {
764                return Ok(execution);
765            };
766            response.ensure_not_truncated()?;
767            execution.messages.push(choice.message.clone());
768            if choice.message.tool_calls.is_empty() {
769                return Ok(execution);
770            }
771
772            messages.push(choice.message.clone());
773
774            for tool_call in &choice.message.tool_calls {
775                let tool = self.registry.get(&tool_call.function.name).ok_or_else(|| {
776                    Error::InvalidConfig(format!("未注册工具: {}", tool_call.function.name))
777                })?;
778                let arguments = if tool_call.function.arguments.trim().is_empty() {
779                    Value::Object(Default::default())
780                } else {
781                    serde_json::from_str(&tool_call.function.arguments)
782                        .unwrap_or_else(|_| Value::String(tool_call.function.arguments.clone()))
783                };
784                let output = tool.invoke(arguments).await?;
785                let content = if output.is_string() {
786                    output.as_str().unwrap_or_default().to_owned()
787                } else {
788                    output.to_string()
789                };
790                let tool_message =
791                    ChatCompletionMessage::tool(tool_call.id.clone(), content.clone());
792                messages.push(tool_message.clone());
793                execution.messages.push(tool_message);
794                execution.tool_results.push(ChatCompletionToolResult {
795                    tool_call: tool_call.clone(),
796                    output: content,
797                });
798            }
799        }
800
801        Err(Error::InvalidConfig("工具调用轮次已超过上限".into()))
802    }
803}
804
805/// 表示一次工具调用返回的结果。
806#[cfg(feature = "tool-runner")]
807#[derive(Debug, Clone, Serialize, Deserialize)]
808pub struct ChatCompletionToolResult {
809    /// 对应的工具调用。
810    pub tool_call: ChatCompletionToolCall,
811    /// 工具执行输出文本。
812    pub output: String,
813}
814
815#[cfg(feature = "tool-runner")]
816#[derive(Debug, Clone, Default)]
817struct ChatCompletionRunExecution {
818    messages: Vec<ChatCompletionMessage>,
819    chat_completions: Vec<ChatCompletion>,
820    tool_results: Vec<ChatCompletionToolResult>,
821    stream_events: Vec<ChatCompletionRuntimeEvent>,
822}
823
824/// 表示非流式工具调用运行 trace。
825#[cfg(feature = "tool-runner")]
826#[derive(Debug, Clone, Default)]
827pub struct ChatCompletionRunner {
828    messages: Vec<ChatCompletionMessage>,
829    chat_completions: Vec<ChatCompletion>,
830    tool_results: Vec<ChatCompletionToolResult>,
831}
832
833#[cfg(feature = "tool-runner")]
834impl ChatCompletionRunner {
835    fn from_execution(execution: ChatCompletionRunExecution) -> Self {
836        Self {
837            messages: execution.messages,
838            chat_completions: execution.chat_completions,
839            tool_results: execution.tool_results,
840        }
841    }
842
843    /// 返回运行过程中累积的全部消息。
844    pub fn messages(&self) -> &[ChatCompletionMessage] {
845        &self.messages
846    }
847
848    /// 返回运行过程中累积的全部聊天补全。
849    pub fn all_chat_completions(&self) -> &[ChatCompletion] {
850        &self.chat_completions
851    }
852
853    /// 返回运行过程中累积的全部工具调用结果。
854    pub fn tool_results(&self) -> &[ChatCompletionToolResult] {
855        &self.tool_results
856    }
857
858    /// 返回最终聊天补全结果。
859    pub fn final_chat_completion(&self) -> Option<&ChatCompletion> {
860        self.chat_completions.last()
861    }
862
863    /// 返回最终 assistant 消息。
864    pub fn final_message(&self) -> Option<&ChatCompletionMessage> {
865        self.messages
866            .iter()
867            .rev()
868            .find(|message| message.role == "assistant")
869    }
870
871    /// 返回最终 assistant 文本。
872    pub fn final_content(&self) -> Option<&str> {
873        self.final_message()
874            .and_then(|message| message.content.as_deref())
875    }
876
877    /// 返回最终工具调用。
878    pub fn final_function_tool_call(&self) -> Option<&ChatCompletionToolCall> {
879        self.tool_results.last().map(|result| &result.tool_call)
880    }
881
882    /// 返回最终工具调用结果。
883    pub fn final_function_tool_call_result(&self) -> Option<&str> {
884        self.tool_results
885            .last()
886            .map(|result| result.output.as_str())
887    }
888
889    /// 汇总所有补全响应中的 usage 字段。
890    pub fn total_usage(&self) -> Option<CompletionUsage> {
891        let mut completion_tokens = 0u64;
892        let mut prompt_tokens = 0u64;
893        let mut total_tokens = 0u64;
894        let mut found = false;
895        for completion in &self.chat_completions {
896            let Some(usage) = completion.usage.as_ref() else {
897                continue;
898            };
899            completion_tokens += usage.completion_tokens;
900            prompt_tokens += usage.prompt_tokens;
901            total_tokens += usage.total_tokens;
902            found = true;
903        }
904
905        found.then(|| CompletionUsage {
906            completion_tokens,
907            prompt_tokens,
908            total_tokens,
909            ..CompletionUsage::default()
910        })
911    }
912}
913
914/// 表示流式工具调用运行 trace。
915#[cfg(feature = "tool-runner")]
916#[derive(Debug, Clone, Default)]
917pub struct ChatCompletionStreamingRunner {
918    runner: ChatCompletionRunner,
919    stream_events: Vec<ChatCompletionRuntimeEvent>,
920}
921
922#[cfg(feature = "tool-runner")]
923impl ChatCompletionStreamingRunner {
924    fn from_execution(execution: ChatCompletionRunExecution) -> Self {
925        Self {
926            runner: ChatCompletionRunner::from_execution(ChatCompletionRunExecution {
927                messages: execution.messages,
928                chat_completions: execution.chat_completions,
929                tool_results: execution.tool_results,
930                stream_events: Vec::new(),
931            }),
932            stream_events: execution.stream_events,
933        }
934    }
935
936    /// 返回流式运行过程中产生的全部高层事件。
937    pub fn events(&self) -> &[ChatCompletionRuntimeEvent] {
938        &self.stream_events
939    }
940
941    /// 返回运行过程中累积的全部消息。
942    pub fn messages(&self) -> &[ChatCompletionMessage] {
943        self.runner.messages()
944    }
945
946    /// 返回运行过程中累积的全部聊天补全。
947    pub fn all_chat_completions(&self) -> &[ChatCompletion] {
948        self.runner.all_chat_completions()
949    }
950
951    /// 返回运行过程中累积的全部工具调用结果。
952    pub fn tool_results(&self) -> &[ChatCompletionToolResult] {
953        self.runner.tool_results()
954    }
955
956    /// 返回最终聊天补全结果。
957    pub fn final_chat_completion(&self) -> Option<&ChatCompletion> {
958        self.runner.final_chat_completion()
959    }
960
961    /// 返回最终 assistant 消息。
962    pub fn final_message(&self) -> Option<&ChatCompletionMessage> {
963        self.runner.final_message()
964    }
965
966    /// 返回最终 assistant 文本。
967    pub fn final_content(&self) -> Option<&str> {
968        self.runner.final_content()
969    }
970
971    /// 返回最终工具调用。
972    pub fn final_function_tool_call(&self) -> Option<&ChatCompletionToolCall> {
973        self.runner.final_function_tool_call()
974    }
975
976    /// 返回最终工具调用结果。
977    pub fn final_function_tool_call_result(&self) -> Option<&str> {
978        self.runner.final_function_tool_call_result()
979    }
980
981    /// 汇总所有补全响应中的 usage 字段。
982    pub fn total_usage(&self) -> Option<CompletionUsage> {
983        self.runner.total_usage()
984    }
985}