2025-11-03 22:01:33 -08:00
|
|
|
use crate::protocol::common::AuthMode;
|
2025-10-30 16:56:55 -07:00
|
|
|
use codex_protocol::ConversationId;
|
|
|
|
|
use codex_protocol::account::PlanType;
|
|
|
|
|
use codex_protocol::config_types::ReasoningEffort;
|
2025-11-04 17:02:39 -08:00
|
|
|
use codex_protocol::protocol::RateLimitSnapshot as CoreRateLimitSnapshot;
|
|
|
|
|
use codex_protocol::protocol::RateLimitWindow as CoreRateLimitWindow;
|
|
|
|
|
use mcp_types::ContentBlock as McpContentBlock;
|
2025-10-30 16:56:55 -07:00
|
|
|
use schemars::JsonSchema;
|
|
|
|
|
use serde::Deserialize;
|
|
|
|
|
use serde::Serialize;
|
2025-11-04 17:02:39 -08:00
|
|
|
use serde_json::Value as JsonValue;
|
|
|
|
|
use std::path::PathBuf;
|
2025-10-30 16:56:55 -07:00
|
|
|
use ts_rs::TS;
|
|
|
|
|
use uuid::Uuid;
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(tag = "type", rename_all = "camelCase")]
|
|
|
|
|
#[ts(tag = "type")]
|
2025-11-04 17:02:39 -08:00
|
|
|
#[ts(export_to = "v2/")]
|
2025-10-30 16:56:55 -07:00
|
|
|
pub enum Account {
|
|
|
|
|
#[serde(rename = "apiKey", rename_all = "camelCase")]
|
|
|
|
|
#[ts(rename = "apiKey", rename_all = "camelCase")]
|
|
|
|
|
ApiKey { api_key: String },
|
|
|
|
|
|
|
|
|
|
#[serde(rename = "chatgpt", rename_all = "camelCase")]
|
|
|
|
|
#[ts(rename = "chatgpt", rename_all = "camelCase")]
|
|
|
|
|
ChatGpt {
|
|
|
|
|
email: Option<String>,
|
|
|
|
|
plan_type: PlanType,
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(tag = "type")]
|
|
|
|
|
#[ts(tag = "type")]
|
2025-11-04 17:02:39 -08:00
|
|
|
#[ts(export_to = "v2/")]
|
2025-10-30 16:56:55 -07:00
|
|
|
pub enum LoginAccountParams {
|
|
|
|
|
#[serde(rename = "apiKey")]
|
|
|
|
|
#[ts(rename = "apiKey")]
|
|
|
|
|
ApiKey {
|
|
|
|
|
#[serde(rename = "apiKey")]
|
|
|
|
|
#[ts(rename = "apiKey")]
|
|
|
|
|
api_key: String,
|
|
|
|
|
},
|
|
|
|
|
#[serde(rename = "chatgpt")]
|
|
|
|
|
#[ts(rename = "chatgpt")]
|
|
|
|
|
ChatGpt,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
2025-11-04 17:02:39 -08:00
|
|
|
#[ts(export_to = "v2/")]
|
2025-10-30 16:56:55 -07:00
|
|
|
pub struct LoginAccountResponse {
|
|
|
|
|
/// Only set if the login method is ChatGPT.
|
|
|
|
|
#[schemars(with = "String")]
|
|
|
|
|
pub login_id: Option<Uuid>,
|
|
|
|
|
|
|
|
|
|
/// URL the client should open in a browser to initiate the OAuth flow.
|
|
|
|
|
/// Only set if the login method is ChatGPT.
|
|
|
|
|
pub auth_url: Option<String>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
2025-11-04 17:02:39 -08:00
|
|
|
#[ts(export_to = "v2/")]
|
2025-10-30 16:56:55 -07:00
|
|
|
pub struct LogoutAccountResponse {}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
2025-11-04 17:02:39 -08:00
|
|
|
#[ts(export_to = "v2/")]
|
2025-10-30 16:56:55 -07:00
|
|
|
pub struct GetAccountRateLimitsResponse {
|
|
|
|
|
pub rate_limits: RateLimitSnapshot,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
2025-11-04 17:02:39 -08:00
|
|
|
#[ts(export_to = "v2/")]
|
2025-10-30 16:56:55 -07:00
|
|
|
pub struct GetAccountResponse {
|
|
|
|
|
pub account: Account,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
2025-11-04 17:02:39 -08:00
|
|
|
#[ts(export_to = "v2/")]
|
2025-10-30 16:56:55 -07:00
|
|
|
pub struct ListModelsParams {
|
|
|
|
|
/// Optional page size; defaults to a reasonable server-side value.
|
|
|
|
|
pub page_size: Option<usize>,
|
|
|
|
|
/// Opaque pagination cursor returned by a previous call.
|
|
|
|
|
pub cursor: Option<String>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
2025-11-04 17:02:39 -08:00
|
|
|
#[ts(export_to = "v2/")]
|
2025-10-30 16:56:55 -07:00
|
|
|
pub struct Model {
|
|
|
|
|
pub id: String,
|
|
|
|
|
pub model: String,
|
|
|
|
|
pub display_name: String,
|
|
|
|
|
pub description: String,
|
|
|
|
|
pub supported_reasoning_efforts: Vec<ReasoningEffortOption>,
|
|
|
|
|
pub default_reasoning_effort: ReasoningEffort,
|
|
|
|
|
// Only one model should be marked as default.
|
|
|
|
|
pub is_default: bool,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
2025-11-04 17:02:39 -08:00
|
|
|
#[ts(export_to = "v2/")]
|
2025-10-30 16:56:55 -07:00
|
|
|
pub struct ReasoningEffortOption {
|
|
|
|
|
pub reasoning_effort: ReasoningEffort,
|
|
|
|
|
pub description: String,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
2025-11-04 17:02:39 -08:00
|
|
|
#[ts(export_to = "v2/")]
|
2025-10-30 16:56:55 -07:00
|
|
|
pub struct ListModelsResponse {
|
|
|
|
|
pub items: Vec<Model>,
|
|
|
|
|
/// Opaque cursor to pass to the next call to continue after the last item.
|
|
|
|
|
/// if None, there are no more items to return.
|
|
|
|
|
pub next_cursor: Option<String>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
2025-11-04 17:02:39 -08:00
|
|
|
#[ts(export_to = "v2/")]
|
2025-10-30 16:56:55 -07:00
|
|
|
pub struct UploadFeedbackParams {
|
|
|
|
|
pub classification: String,
|
|
|
|
|
pub reason: Option<String>,
|
|
|
|
|
pub conversation_id: Option<ConversationId>,
|
|
|
|
|
pub include_logs: bool,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
2025-11-04 17:02:39 -08:00
|
|
|
#[ts(export_to = "v2/")]
|
2025-10-30 16:56:55 -07:00
|
|
|
pub struct UploadFeedbackResponse {
|
|
|
|
|
pub thread_id: String,
|
|
|
|
|
}
|
2025-11-03 22:01:33 -08:00
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
2025-11-04 17:02:39 -08:00
|
|
|
#[ts(export_to = "v2/")]
|
2025-11-03 22:01:33 -08:00
|
|
|
pub struct AccountUpdatedNotification {
|
|
|
|
|
pub auth_method: Option<AuthMode>,
|
|
|
|
|
}
|
2025-11-04 17:02:39 -08:00
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
#[ts(export_to = "v2/")]
|
|
|
|
|
pub struct Thread {
|
|
|
|
|
pub id: String,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
#[ts(export_to = "v2/")]
|
|
|
|
|
pub struct Turn {
|
|
|
|
|
pub id: String,
|
|
|
|
|
pub items: Vec<ThreadItem>,
|
|
|
|
|
pub status: TurnStatus,
|
|
|
|
|
pub error: Option<TurnError>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
#[ts(export_to = "v2/")]
|
|
|
|
|
pub enum TurnStatus {
|
|
|
|
|
Completed,
|
|
|
|
|
Interrupted,
|
|
|
|
|
Failed,
|
|
|
|
|
InProgress,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
#[ts(export_to = "v2/")]
|
|
|
|
|
pub struct TurnError {
|
|
|
|
|
pub message: String,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(tag = "type", rename_all = "camelCase")]
|
|
|
|
|
#[ts(export_to = "v2/")]
|
|
|
|
|
pub enum UserInput {
|
|
|
|
|
Text { text: String },
|
|
|
|
|
Image { url: String },
|
|
|
|
|
LocalImage { path: PathBuf },
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(tag = "type", rename_all = "camelCase")]
|
|
|
|
|
#[ts(export_to = "v2/")]
|
|
|
|
|
pub enum ThreadItem {
|
|
|
|
|
UserMessage {
|
|
|
|
|
id: String,
|
|
|
|
|
content: Vec<UserInput>,
|
|
|
|
|
},
|
|
|
|
|
AgentMessage {
|
|
|
|
|
id: String,
|
|
|
|
|
text: String,
|
|
|
|
|
},
|
|
|
|
|
Reasoning {
|
|
|
|
|
id: String,
|
|
|
|
|
text: String,
|
|
|
|
|
},
|
|
|
|
|
CommandExecution {
|
|
|
|
|
id: String,
|
|
|
|
|
command: String,
|
|
|
|
|
aggregated_output: String,
|
|
|
|
|
exit_code: Option<i32>,
|
|
|
|
|
status: CommandExecutionStatus,
|
|
|
|
|
duration_ms: Option<i64>,
|
|
|
|
|
},
|
|
|
|
|
FileChange {
|
|
|
|
|
id: String,
|
|
|
|
|
changes: Vec<FileUpdateChange>,
|
|
|
|
|
status: PatchApplyStatus,
|
|
|
|
|
},
|
|
|
|
|
McpToolCall {
|
|
|
|
|
id: String,
|
|
|
|
|
server: String,
|
|
|
|
|
tool: String,
|
|
|
|
|
status: McpToolCallStatus,
|
|
|
|
|
arguments: JsonValue,
|
|
|
|
|
result: Option<McpToolCallResult>,
|
|
|
|
|
error: Option<McpToolCallError>,
|
|
|
|
|
},
|
|
|
|
|
WebSearch {
|
|
|
|
|
id: String,
|
|
|
|
|
query: String,
|
|
|
|
|
},
|
|
|
|
|
TodoList {
|
|
|
|
|
id: String,
|
|
|
|
|
items: Vec<TodoItem>,
|
|
|
|
|
},
|
|
|
|
|
ImageView {
|
|
|
|
|
id: String,
|
|
|
|
|
path: String,
|
|
|
|
|
},
|
|
|
|
|
CodeReview {
|
|
|
|
|
id: String,
|
|
|
|
|
review: String,
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
#[ts(export_to = "v2/")]
|
|
|
|
|
pub enum CommandExecutionStatus {
|
|
|
|
|
InProgress,
|
|
|
|
|
Completed,
|
|
|
|
|
Failed,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
#[ts(export_to = "v2/")]
|
|
|
|
|
pub struct FileUpdateChange {
|
|
|
|
|
pub path: String,
|
|
|
|
|
pub kind: PatchChangeKind,
|
|
|
|
|
pub diff: String,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
#[ts(export_to = "v2/")]
|
|
|
|
|
pub enum PatchChangeKind {
|
|
|
|
|
Add,
|
|
|
|
|
Delete,
|
|
|
|
|
Update,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
#[ts(export_to = "v2/")]
|
|
|
|
|
pub enum PatchApplyStatus {
|
|
|
|
|
Completed,
|
|
|
|
|
Failed,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
#[ts(export_to = "v2/")]
|
|
|
|
|
pub enum McpToolCallStatus {
|
|
|
|
|
InProgress,
|
|
|
|
|
Completed,
|
|
|
|
|
Failed,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
#[ts(export_to = "v2/")]
|
|
|
|
|
pub struct McpToolCallResult {
|
|
|
|
|
pub content: Vec<McpContentBlock>,
|
|
|
|
|
pub structured_content: JsonValue,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
#[ts(export_to = "v2/")]
|
|
|
|
|
pub struct McpToolCallError {
|
|
|
|
|
pub message: String,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
#[ts(export_to = "v2/")]
|
|
|
|
|
pub struct TodoItem {
|
|
|
|
|
pub id: String,
|
|
|
|
|
pub text: String,
|
|
|
|
|
pub completed: bool,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// === Server Notifications ===
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
#[ts(export_to = "v2/")]
|
|
|
|
|
pub struct ThreadStartedNotification {
|
|
|
|
|
pub thread: Thread,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
#[ts(export_to = "v2/")]
|
|
|
|
|
pub struct TurnStartedNotification {
|
|
|
|
|
pub turn: Turn,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
#[ts(export_to = "v2/")]
|
|
|
|
|
pub struct Usage {
|
|
|
|
|
pub input_tokens: i32,
|
|
|
|
|
pub cached_input_tokens: i32,
|
|
|
|
|
pub output_tokens: i32,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
#[ts(export_to = "v2/")]
|
|
|
|
|
pub struct TurnCompletedNotification {
|
|
|
|
|
pub turn: Turn,
|
|
|
|
|
pub usage: Usage,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
#[ts(export_to = "v2/")]
|
|
|
|
|
pub struct ItemStartedNotification {
|
|
|
|
|
pub item: ThreadItem,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
#[ts(export_to = "v2/")]
|
|
|
|
|
pub struct ItemCompletedNotification {
|
|
|
|
|
pub item: ThreadItem,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
#[ts(export_to = "v2/")]
|
|
|
|
|
pub struct AgentMessageDeltaNotification {
|
|
|
|
|
pub item_id: String,
|
|
|
|
|
pub delta: String,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
#[ts(export_to = "v2/")]
|
|
|
|
|
pub struct CommandExecutionOutputDeltaNotification {
|
|
|
|
|
pub item_id: String,
|
|
|
|
|
pub delta: String,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
#[ts(export_to = "v2/")]
|
|
|
|
|
pub struct McpToolCallProgressNotification {
|
|
|
|
|
pub item_id: String,
|
|
|
|
|
pub message: String,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
#[ts(export_to = "v2/")]
|
|
|
|
|
pub struct AccountRateLimitsUpdatedNotification {
|
|
|
|
|
pub rate_limits: RateLimitSnapshot,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
#[ts(export_to = "v2/")]
|
|
|
|
|
pub struct RateLimitSnapshot {
|
|
|
|
|
pub primary: Option<RateLimitWindow>,
|
|
|
|
|
pub secondary: Option<RateLimitWindow>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl From<CoreRateLimitSnapshot> for RateLimitSnapshot {
|
|
|
|
|
fn from(value: CoreRateLimitSnapshot) -> Self {
|
|
|
|
|
Self {
|
|
|
|
|
primary: value.primary.map(RateLimitWindow::from),
|
|
|
|
|
secondary: value.secondary.map(RateLimitWindow::from),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
#[ts(export_to = "v2/")]
|
|
|
|
|
pub struct RateLimitWindow {
|
|
|
|
|
pub used_percent: i32,
|
|
|
|
|
pub window_duration_mins: Option<i64>,
|
|
|
|
|
pub resets_at: Option<i64>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl From<CoreRateLimitWindow> for RateLimitWindow {
|
|
|
|
|
fn from(value: CoreRateLimitWindow) -> Self {
|
|
|
|
|
Self {
|
|
|
|
|
used_percent: value.used_percent.round() as i32,
|
|
|
|
|
window_duration_mins: value.window_minutes,
|
|
|
|
|
resets_at: value.resets_at,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|