1use std::collections::HashMap;
2
3use serde::{Deserialize, Serialize};
4
5use crate::chat::{ChatResponse, ChatTool};
6use crate::client::Client;
7use crate::error::Result;
8
9#[derive(Debug, Clone, Serialize, Deserialize, Default)]
11pub struct ContextConfig {
12 #[serde(skip_serializing_if = "Option::is_none")]
14 pub max_tokens: Option<i64>,
15
16 #[serde(skip_serializing_if = "Option::is_none")]
18 pub auto_compact: Option<bool>,
19}
20
21#[derive(Debug, Clone, Serialize, Deserialize, Default)]
23pub struct ToolResult {
24 pub tool_call_id: String,
26
27 pub content: String,
29
30 #[serde(skip_serializing_if = "Option::is_none")]
32 pub is_error: Option<bool>,
33}
34
35#[derive(Debug, Clone, Serialize, Default)]
37pub struct SessionChatRequest {
38 #[serde(skip_serializing_if = "Option::is_none")]
40 pub session_id: Option<String>,
41
42 #[serde(skip_serializing_if = "Option::is_none")]
44 pub model: Option<String>,
45
46 pub message: String,
48
49 #[serde(skip_serializing_if = "Option::is_none")]
51 pub tools: Option<Vec<ChatTool>>,
52
53 #[serde(skip_serializing_if = "Option::is_none")]
55 pub tool_results: Option<Vec<ToolResult>>,
56
57 #[serde(skip_serializing_if = "Option::is_none")]
59 pub stream: Option<bool>,
60
61 #[serde(skip_serializing_if = "Option::is_none")]
63 pub system_prompt: Option<String>,
64
65 #[serde(skip_serializing_if = "Option::is_none")]
67 pub context_config: Option<ContextConfig>,
68
69 #[serde(skip_serializing_if = "Option::is_none")]
71 pub provider_options: Option<HashMap<String, serde_json::Value>>,
72}
73
74#[derive(Debug, Clone, Deserialize)]
76pub struct SessionContext {
77 pub turn_count: i64,
79
80 pub estimated_tokens: i64,
82
83 #[serde(default)]
85 pub compacted: bool,
86
87 #[serde(default)]
89 pub compaction_note: Option<String>,
90}
91
92#[derive(Debug, Clone, Deserialize)]
94pub struct SessionChatResponse {
95 pub session_id: String,
97
98 pub response: ChatResponse,
100
101 pub context: SessionContext,
103}
104
105impl Client {
106 pub async fn chat_session(&self, req: &SessionChatRequest) -> Result<SessionChatResponse> {
111 let (resp, _meta) = self
112 .post_json::<SessionChatRequest, SessionChatResponse>("/qai/v1/chat/session", req)
113 .await?;
114 Ok(resp)
115 }
116}