linger-openai-sdk 0.1.1

Rust-native async SDK for OpenAI APIs with typed requests, streaming, uploads, retries, and pluggable transports.
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
use crate::LingerError;
use crate::RequestId;
use serde::{Deserialize, Serialize};
use serde_json::Value;

/// EN: ChatKit session returned by the ChatKit beta API.
/// 中文:ChatKit beta API 返回的 ChatKit session。
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
#[non_exhaustive]
pub struct ChatKitSession {
    /// EN: Identifier for the ChatKit session.
    /// 中文:ChatKit session 标识符。
    pub id: String,
    /// EN: API object type, normally `chatkit.session`.
    /// 中文:API 对象类型,通常为 `chatkit.session`。
    pub object: String,
    /// EN: Unix timestamp for when the session expires.
    /// 中文:session 过期时间的 Unix 时间戳。
    pub expires_at: u64,
    /// EN: Ephemeral client secret that authenticates session requests.
    /// 中文:用于认证 session 请求的临时 client secret。
    pub client_secret: String,
    /// EN: Workflow metadata for the session.
    /// 中文:session 的 workflow 元数据。
    pub workflow: ChatKitWorkflow,
    /// EN: User identifier associated with the session.
    /// 中文:与 session 关联的用户标识符。
    pub user: String,
    /// EN: Resolved rate limit values.
    /// 中文:解析后的速率限制值。
    pub rate_limits: ChatKitSessionRateLimits,
    /// EN: Convenience copy of the per-minute request limit.
    /// 中文:每分钟请求限制的便捷副本。
    pub max_requests_per_1_minute: u64,
    /// EN: Current lifecycle state of the session.
    /// 中文:session 当前生命周期状态。
    pub status: String,
    /// EN: Resolved ChatKit feature configuration.
    /// 中文:解析后的 ChatKit 功能配置。
    pub chatkit_configuration: Value,
    /// EN: OpenAI request id from response headers.
    /// 中文:响应头中的 OpenAI 请求 ID。
    #[serde(skip)]
    request_id: Option<RequestId>,
}

impl ChatKitSession {
    pub(crate) fn with_request_id(mut self, request_id: Option<RequestId>) -> Self {
        self.request_id = request_id;
        self
    }

    /// EN: Returns the OpenAI request id, when present.
    /// 中文:返回 OpenAI 请求 ID,如存在。
    pub fn request_id(&self) -> Option<&RequestId> {
        self.request_id.as_ref()
    }
}

/// EN: ChatKit thread returned by the ChatKit beta API.
/// 中文:ChatKit beta API 返回的 ChatKit thread。
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
#[non_exhaustive]
pub struct ChatKitThread {
    /// EN: Identifier for the ChatKit thread.
    /// 中文:ChatKit thread 标识符。
    pub id: String,
    /// EN: API object type, normally `chatkit.thread`.
    /// 中文:API 对象类型,通常为 `chatkit.thread`。
    pub object: String,
    /// EN: Unix timestamp for when the thread was created.
    /// 中文:thread 创建时间的 Unix 时间戳。
    pub created_at: u64,
    /// EN: Optional human-readable thread title.
    /// 中文:可选的人类可读 thread 标题。
    pub title: Option<String>,
    /// EN: Current status object for the thread.
    /// 中文:thread 当前状态对象。
    pub status: Value,
    /// EN: End-user identifier that owns the thread.
    /// 中文:拥有该 thread 的最终用户标识符。
    pub user: String,
    /// EN: OpenAI request id from response headers.
    /// 中文:响应头中的 OpenAI 请求 ID。
    #[serde(skip)]
    request_id: Option<RequestId>,
}

impl ChatKitThread {
    pub(crate) fn with_request_id(mut self, request_id: Option<RequestId>) -> Self {
        self.request_id = request_id;
        self
    }

    /// EN: Returns the OpenAI request id, when present.
    /// 中文:返回 OpenAI 请求 ID,如存在。
    pub fn request_id(&self) -> Option<&RequestId> {
        self.request_id.as_ref()
    }
}

/// EN: Deletion result returned by the ChatKit Threads API.
/// 中文:ChatKit Threads API 返回的删除结果。
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
#[non_exhaustive]
pub struct ChatKitThreadDeletion {
    /// EN: Deleted ChatKit thread id.
    /// 中文:已删除的 ChatKit thread ID。
    pub id: String,
    /// EN: API object type, normally `chatkit.thread.deleted`.
    /// 中文:API 对象类型,通常为 `chatkit.thread.deleted`。
    pub object: String,
    /// EN: Whether the ChatKit thread was deleted.
    /// 中文:ChatKit thread 是否已删除。
    pub deleted: bool,
    /// EN: OpenAI request id from response headers.
    /// 中文:响应头中的 OpenAI 请求 ID。
    #[serde(skip)]
    request_id: Option<RequestId>,
}

impl ChatKitThreadDeletion {
    pub(crate) fn with_request_id(mut self, request_id: Option<RequestId>) -> Self {
        self.request_id = request_id;
        self
    }

    /// EN: Returns the OpenAI request id, when present.
    /// 中文:返回 OpenAI 请求 ID,如存在。
    pub fn request_id(&self) -> Option<&RequestId> {
        self.request_id.as_ref()
    }
}

/// EN: Page of ChatKit threads returned by `GET /v1/chatkit/threads`.
/// 中文:`GET /v1/chatkit/threads` 返回的 ChatKit thread 分页。
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
#[non_exhaustive]
pub struct ChatKitThreadPage {
    /// EN: API object type, normally `list`.
    /// 中文:API 对象类型,通常为 `list`。
    pub object: String,
    /// EN: ChatKit threads in this page.
    /// 中文:当前分页中的 ChatKit threads。
    pub data: Vec<ChatKitThread>,
    /// EN: First thread id in this page, when present.
    /// 中文:当前分页中的第一个 thread ID,如存在。
    pub first_id: Option<String>,
    /// EN: Last thread id in this page, when present.
    /// 中文:当前分页中的最后一个 thread ID,如存在。
    pub last_id: Option<String>,
    /// EN: Whether more threads are available.
    /// 中文:是否还有更多 threads 可用。
    pub has_more: bool,
    /// EN: OpenAI request id from response headers.
    /// 中文:响应头中的 OpenAI 请求 ID。
    #[serde(skip)]
    request_id: Option<RequestId>,
}

impl ChatKitThreadPage {
    pub(crate) fn with_request_id(mut self, request_id: Option<RequestId>) -> Self {
        self.request_id = request_id;
        self
    }

    /// EN: Returns the OpenAI request id, when present.
    /// 中文:返回 OpenAI 请求 ID,如存在。
    pub fn request_id(&self) -> Option<&RequestId> {
        self.request_id.as_ref()
    }
}

/// EN: Page of ChatKit thread items returned by `GET /v1/chatkit/threads/{thread_id}/items`.
/// 中文:`GET /v1/chatkit/threads/{thread_id}/items` 返回的 ChatKit thread item 分页。
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
#[non_exhaustive]
pub struct ChatKitThreadItemPage {
    /// EN: API object type, normally `list`.
    /// 中文:API 对象类型,通常为 `list`。
    pub object: String,
    /// EN: Raw ChatKit thread items in this page.
    /// 中文:当前分页中的原始 ChatKit thread items。
    pub data: Vec<Value>,
    /// EN: First item id in this page, when present.
    /// 中文:当前分页中的第一个 item ID,如存在。
    pub first_id: Option<String>,
    /// EN: Last item id in this page, when present.
    /// 中文:当前分页中的最后一个 item ID,如存在。
    pub last_id: Option<String>,
    /// EN: Whether more items are available.
    /// 中文:是否还有更多 items 可用。
    pub has_more: bool,
    /// EN: OpenAI request id from response headers.
    /// 中文:响应头中的 OpenAI 请求 ID。
    #[serde(skip)]
    request_id: Option<RequestId>,
}

impl ChatKitThreadItemPage {
    pub(crate) fn with_request_id(mut self, request_id: Option<RequestId>) -> Self {
        self.request_id = request_id;
        self
    }

    /// EN: Returns the OpenAI request id, when present.
    /// 中文:返回 OpenAI 请求 ID,如存在。
    pub fn request_id(&self) -> Option<&RequestId> {
        self.request_id.as_ref()
    }
}

/// EN: Workflow metadata on a ChatKit session.
/// 中文:ChatKit session 上的 workflow 元数据。
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
#[non_exhaustive]
pub struct ChatKitWorkflow {
    /// EN: Workflow identifier.
    /// 中文:workflow 标识符。
    pub id: String,
    /// EN: Workflow version, when returned.
    /// 中文:返回的 workflow 版本。
    pub version: Option<String>,
}

/// EN: Rate limit values on a ChatKit session.
/// 中文:ChatKit session 上的速率限制值。
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
#[non_exhaustive]
pub struct ChatKitSessionRateLimits {
    /// EN: Maximum requests per one minute.
    /// 中文:每一分钟最大请求数。
    pub max_requests_per_1_minute: u64,
}

/// EN: Request body for `POST /v1/chatkit/sessions`.
/// 中文:`POST /v1/chatkit/sessions` 的请求体。
#[derive(Clone, Debug, Serialize, PartialEq)]
#[non_exhaustive]
pub struct CreateChatKitSessionRequest {
    /// EN: Workflow that powers the session.
    /// 中文:驱动 session 的 workflow。
    pub workflow: ChatKitWorkflowParam,
    /// EN: End-user identifier for the session.
    /// 中文:session 的最终用户标识符。
    pub user: String,
    /// EN: Optional session expiration override.
    /// 中文:可选的 session 过期时间覆盖。
    #[serde(skip_serializing_if = "Option::is_none")]
    pub expires_after: Option<ChatKitSessionExpiration>,
    /// EN: Optional request rate limit overrides.
    /// 中文:可选的请求速率限制覆盖。
    #[serde(skip_serializing_if = "Option::is_none")]
    pub rate_limits: Option<ChatKitSessionRateLimitOverrides>,
    /// EN: Optional ChatKit runtime configuration overrides.
    /// 中文:可选的 ChatKit 运行时配置覆盖。
    #[serde(skip_serializing_if = "Option::is_none")]
    pub chatkit_configuration: Option<Value>,
}

impl CreateChatKitSessionRequest {
    /// EN: Returns a builder for ChatKit session create requests.
    /// 中文:返回 ChatKit session 创建请求构建器。
    pub fn builder() -> CreateChatKitSessionRequestBuilder {
        CreateChatKitSessionRequestBuilder::default()
    }
}

/// EN: Builder for `CreateChatKitSessionRequest`.
/// 中文:`CreateChatKitSessionRequest` 的构建器。
#[derive(Clone, Debug, Default)]
pub struct CreateChatKitSessionRequestBuilder {
    workflow: Option<ChatKitWorkflowParam>,
    user: Option<String>,
    expires_after: Option<ChatKitSessionExpiration>,
    rate_limits: Option<ChatKitSessionRateLimitOverrides>,
    chatkit_configuration: Option<Value>,
}

impl CreateChatKitSessionRequestBuilder {
    /// EN: Sets the workflow that powers the session.
    /// 中文:设置驱动 session 的 workflow。
    pub fn workflow(mut self, workflow: ChatKitWorkflowParam) -> Self {
        self.workflow = Some(workflow);
        self
    }

    /// EN: Sets the end-user identifier.
    /// 中文:设置最终用户标识符。
    pub fn user(mut self, user: impl Into<String>) -> Self {
        self.user = Some(user.into());
        self
    }

    /// EN: Sets the session expiration override.
    /// 中文:设置 session 过期时间覆盖。
    pub fn expires_after(mut self, expires_after: ChatKitSessionExpiration) -> Self {
        self.expires_after = Some(expires_after);
        self
    }

    /// EN: Sets the request rate limit overrides.
    /// 中文:设置请求速率限制覆盖。
    pub fn rate_limits(mut self, rate_limits: ChatKitSessionRateLimitOverrides) -> Self {
        self.rate_limits = Some(rate_limits);
        self
    }

    /// EN: Sets ChatKit runtime configuration overrides.
    /// 中文:设置 ChatKit 运行时配置覆盖。
    pub fn chatkit_configuration(mut self, chatkit_configuration: Value) -> Self {
        self.chatkit_configuration = Some(chatkit_configuration);
        self
    }

    /// EN: Builds a validated ChatKit session create request.
    /// 中文:构建经过校验的 ChatKit session 创建请求。
    pub fn build(self) -> Result<CreateChatKitSessionRequest, LingerError> {
        let workflow = self
            .workflow
            .ok_or_else(|| LingerError::invalid_config("workflow is required"))?;
        let user = self
            .user
            .ok_or_else(|| LingerError::invalid_config("user is required"))?;
        if user.trim().is_empty() {
            return Err(LingerError::invalid_config("user must not be empty"));
        }
        Ok(CreateChatKitSessionRequest {
            workflow,
            user,
            expires_after: self.expires_after,
            rate_limits: self.rate_limits,
            chatkit_configuration: self.chatkit_configuration,
        })
    }
}

/// EN: Workflow reference and overrides for a ChatKit session.
/// 中文:ChatKit session 的 workflow 引用和覆盖。
#[derive(Clone, Debug, Serialize, PartialEq)]
#[non_exhaustive]
pub struct ChatKitWorkflowParam {
    /// EN: Workflow identifier.
    /// 中文:workflow 标识符。
    pub id: String,
    /// EN: Specific workflow version to run.
    /// 中文:要运行的特定 workflow 版本。
    #[serde(skip_serializing_if = "Option::is_none")]
    pub version: Option<String>,
    /// EN: State variables forwarded to the workflow.
    /// 中文:转发给 workflow 的状态变量。
    #[serde(skip_serializing_if = "Option::is_none")]
    pub state_variables: Option<Value>,
    /// EN: Optional tracing overrides.
    /// 中文:可选 tracing 覆盖。
    #[serde(skip_serializing_if = "Option::is_none")]
    pub tracing: Option<Value>,
}

impl ChatKitWorkflowParam {
    /// EN: Creates a workflow reference with the required id.
    /// 中文:使用必需的 id 创建 workflow 引用。
    pub fn new(id: impl Into<String>) -> Self {
        Self {
            id: id.into(),
            version: None,
            state_variables: None,
            tracing: None,
        }
    }

    /// EN: Sets the workflow version.
    /// 中文:设置 workflow 版本。
    pub fn version(mut self, version: impl Into<String>) -> Self {
        self.version = Some(version.into());
        self
    }

    /// EN: Sets state variables forwarded to the workflow.
    /// 中文:设置转发给 workflow 的状态变量。
    pub fn state_variables(mut self, state_variables: Value) -> Self {
        self.state_variables = Some(state_variables);
        self
    }

    /// EN: Sets tracing overrides.
    /// 中文:设置 tracing 覆盖。
    pub fn tracing(mut self, tracing: Value) -> Self {
        self.tracing = Some(tracing);
        self
    }
}

/// EN: ChatKit session expiration override.
/// 中文:ChatKit session 过期时间覆盖。
#[derive(Clone, Debug, Serialize, PartialEq, Eq)]
#[non_exhaustive]
pub struct ChatKitSessionExpiration {
    /// EN: Base timestamp used to calculate expiration.
    /// 中文:用于计算过期时间的基准时间戳。
    pub anchor: String,
    /// EN: Number of seconds after the anchor when the session expires.
    /// 中文:基准时间戳之后 session 过期的秒数。
    pub seconds: u64,
}

impl ChatKitSessionExpiration {
    /// EN: Creates an expiration override anchored at `created_at`.
    /// 中文:创建以 `created_at` 为基准的过期时间覆盖。
    pub fn created_at(seconds: u64) -> Self {
        Self {
            anchor: "created_at".to_string(),
            seconds,
        }
    }
}

/// EN: ChatKit session rate limit overrides.
/// 中文:ChatKit session 速率限制覆盖。
#[derive(Clone, Debug, Default, Serialize, PartialEq, Eq)]
#[non_exhaustive]
pub struct ChatKitSessionRateLimitOverrides {
    /// EN: Maximum requests per one minute.
    /// 中文:每一分钟最大请求数。
    #[serde(skip_serializing_if = "Option::is_none")]
    pub max_requests_per_1_minute: Option<u64>,
}

impl ChatKitSessionRateLimitOverrides {
    /// EN: Creates empty rate limit overrides.
    /// 中文:创建空的速率限制覆盖。
    pub fn new() -> Self {
        Self::default()
    }

    /// EN: Sets the maximum requests per one minute.
    /// 中文:设置每一分钟最大请求数。
    pub fn max_requests_per_1_minute(mut self, max_requests_per_1_minute: u64) -> Self {
        self.max_requests_per_1_minute = Some(max_requests_per_1_minute);
        self
    }
}