Skip to main content

codex_app_server_sdk/events/
mod.rs

1use serde_json::Value;
2
3use crate::error::ClientError;
4use crate::protocol::notifications as n;
5use crate::protocol::server_requests as sr;
6use crate::protocol::shared::RequestId;
7
8#[derive(Debug, Clone)]
9pub enum ServerEvent {
10    Notification(ServerNotification),
11    ServerRequest(ServerRequestEvent),
12    TransportClosed,
13}
14
15#[derive(Debug, Clone)]
16pub enum ServerNotification {
17    Error(n::ErrorNotification),
18    ThreadStarted(n::ThreadStartedNotification),
19    ThreadArchived(n::ThreadLifecycleNotification),
20    ThreadUnarchived(n::ThreadLifecycleNotification),
21    ThreadClosed(n::ThreadLifecycleNotification),
22    ThreadNameUpdated(n::ThreadNameUpdatedNotification),
23    ThreadStatusChanged(n::ThreadStatusChangedNotification),
24    ThreadTokenUsageUpdated(n::ThreadTokenUsageUpdatedNotification),
25    TurnStarted(n::TurnStartedNotification),
26    TurnCompleted(n::TurnCompletedNotification),
27    TurnDiffUpdated(n::TurnDiffUpdatedNotification),
28    TurnPlanUpdated(n::TurnPlanUpdatedNotification),
29    ItemStarted(n::ItemLifecycleNotification),
30    ItemCompleted(n::ItemLifecycleNotification),
31    RawResponseItemCompleted(n::RawResponseItemCompletedNotification),
32    ItemAgentMessageDelta(n::DeltaNotification),
33    ItemPlanDelta(n::DeltaNotification),
34    ItemCommandExecutionOutputDelta(n::DeltaNotification),
35    ItemCommandExecutionTerminalInteraction(n::DeltaNotification),
36    ItemFileChangeOutputDelta(n::DeltaNotification),
37    ItemMcpToolCallProgress(n::DeltaNotification),
38    ItemReasoningSummaryTextDelta(n::DeltaNotification),
39    ItemReasoningSummaryPartAdded(n::DeltaNotification),
40    ItemReasoningTextDelta(n::DeltaNotification),
41    McpServerOauthLoginCompleted(n::McpServerOauthLoginCompletedNotification),
42    AccountUpdated(n::AccountUpdatedNotification),
43    AccountRateLimitsUpdated(n::AccountRateLimitsUpdatedNotification),
44    AppListUpdated(n::AppListUpdatedNotification),
45    ContextCompacted(n::DeltaNotification),
46    DeprecationNotice(n::DeprecationNoticeNotification),
47    ConfigWarning(n::ConfigWarningNotification),
48    WindowsWorldWritableWarning(n::WindowsWorldWritableWarningNotification),
49    WindowsSandboxSetupCompleted(n::WindowsSandboxSetupCompletedNotification),
50    AccountLoginCompleted(n::AccountLoginCompletedNotification),
51    AuthStatusChange(n::AuthStatusChangeNotification),
52    LoginChatGptComplete(n::LoginChatGptCompleteNotification),
53    SessionConfigured(n::SessionConfiguredNotification),
54    FuzzyFileSearchSessionUpdated(n::FuzzyFileSearchSessionUpdatedNotification),
55    FuzzyFileSearchSessionCompleted(n::FuzzyFileSearchSessionCompletedNotification),
56    ServerRequestResolved(n::ServerRequestResolvedNotification),
57    Unknown { method: String, params: Value },
58}
59
60#[derive(Debug, Clone)]
61pub enum ServerRequestEvent {
62    ChatgptAuthTokensRefresh {
63        id: RequestId,
64        params: sr::ChatgptAuthTokensRefreshParams,
65    },
66    ApplyPatchApproval {
67        id: RequestId,
68        params: sr::ApplyPatchApprovalParams,
69    },
70    ExecCommandApproval {
71        id: RequestId,
72        params: sr::ExecCommandApprovalParams,
73    },
74    CommandExecutionRequestApproval {
75        id: RequestId,
76        params: sr::CommandExecutionRequestApprovalParams,
77    },
78    FileChangeRequestApproval {
79        id: RequestId,
80        params: sr::FileChangeRequestApprovalParams,
81    },
82    ToolRequestUserInput {
83        id: RequestId,
84        params: sr::ToolRequestUserInputParams,
85    },
86    DynamicToolCall {
87        id: RequestId,
88        params: sr::DynamicToolCallParams,
89    },
90    Unknown {
91        id: RequestId,
92        method: String,
93        params: Value,
94    },
95}
96
97fn decode<T: serde::de::DeserializeOwned>(params: Value) -> Result<T, ClientError> {
98    serde_json::from_value(params).map_err(ClientError::Serialization)
99}
100
101pub fn parse_notification(
102    method: String,
103    params: Value,
104) -> Result<ServerNotification, ClientError> {
105    let event = match method.as_str() {
106        "error" => ServerNotification::Error(decode(params)?),
107        "thread/started" => ServerNotification::ThreadStarted(decode(params)?),
108        "thread/archived" => ServerNotification::ThreadArchived(decode(params)?),
109        "thread/unarchived" => ServerNotification::ThreadUnarchived(decode(params)?),
110        "thread/closed" => ServerNotification::ThreadClosed(decode(params)?),
111        "thread/name/updated" => ServerNotification::ThreadNameUpdated(decode(params)?),
112        "thread/status/changed" => ServerNotification::ThreadStatusChanged(decode(params)?),
113        "thread/tokenUsage/updated" => ServerNotification::ThreadTokenUsageUpdated(decode(params)?),
114        "turn/started" => ServerNotification::TurnStarted(decode(params)?),
115        "turn/completed" => ServerNotification::TurnCompleted(decode(params)?),
116        "turn/diff/updated" => ServerNotification::TurnDiffUpdated(decode(params)?),
117        "turn/plan/updated" => ServerNotification::TurnPlanUpdated(decode(params)?),
118        "item/started" => ServerNotification::ItemStarted(decode(params)?),
119        "item/completed" => ServerNotification::ItemCompleted(decode(params)?),
120        "rawResponseItem/completed" => {
121            ServerNotification::RawResponseItemCompleted(decode(params)?)
122        }
123        "item/agentMessage/delta" => ServerNotification::ItemAgentMessageDelta(decode(params)?),
124        "item/plan/delta" => ServerNotification::ItemPlanDelta(decode(params)?),
125        "item/commandExecution/outputDelta" => {
126            ServerNotification::ItemCommandExecutionOutputDelta(decode(params)?)
127        }
128        "item/commandExecution/terminalInteraction" => {
129            ServerNotification::ItemCommandExecutionTerminalInteraction(decode(params)?)
130        }
131        "item/fileChange/outputDelta" => {
132            ServerNotification::ItemFileChangeOutputDelta(decode(params)?)
133        }
134        "item/mcpToolCall/progress" => ServerNotification::ItemMcpToolCallProgress(decode(params)?),
135        "item/reasoning/summaryTextDelta" => {
136            ServerNotification::ItemReasoningSummaryTextDelta(decode(params)?)
137        }
138        "item/reasoning/summaryPartAdded" => {
139            ServerNotification::ItemReasoningSummaryPartAdded(decode(params)?)
140        }
141        "item/reasoning/textDelta" => ServerNotification::ItemReasoningTextDelta(decode(params)?),
142        "mcpServer/oauthLogin/completed" => {
143            ServerNotification::McpServerOauthLoginCompleted(decode(params)?)
144        }
145        "account/updated" => ServerNotification::AccountUpdated(decode(params)?),
146        "account/rateLimits/updated" => {
147            ServerNotification::AccountRateLimitsUpdated(decode(params)?)
148        }
149        "app/list/updated" => ServerNotification::AppListUpdated(decode(params)?),
150        "thread/compacted" => ServerNotification::ContextCompacted(decode(params)?),
151        "deprecationNotice" => ServerNotification::DeprecationNotice(decode(params)?),
152        "configWarning" => ServerNotification::ConfigWarning(decode(params)?),
153        "windows/worldWritableWarning" => {
154            ServerNotification::WindowsWorldWritableWarning(decode(params)?)
155        }
156        "windowsSandbox/setupCompleted" => {
157            ServerNotification::WindowsSandboxSetupCompleted(decode(params)?)
158        }
159        "account/login/completed" => ServerNotification::AccountLoginCompleted(decode(params)?),
160        "authStatusChange" => ServerNotification::AuthStatusChange(decode(params)?),
161        "loginChatGptComplete" => ServerNotification::LoginChatGptComplete(decode(params)?),
162        "sessionConfigured" => ServerNotification::SessionConfigured(decode(params)?),
163        "fuzzyFileSearch/sessionUpdated" => {
164            ServerNotification::FuzzyFileSearchSessionUpdated(decode(params)?)
165        }
166        "fuzzyFileSearch/sessionCompleted" => {
167            ServerNotification::FuzzyFileSearchSessionCompleted(decode(params)?)
168        }
169        "serverRequest/resolved" => ServerNotification::ServerRequestResolved(decode(params)?),
170        _ => ServerNotification::Unknown { method, params },
171    };
172    Ok(event)
173}
174
175pub fn parse_server_request(
176    id: RequestId,
177    method: String,
178    params: Value,
179) -> Result<ServerRequestEvent, ClientError> {
180    let req = match method.as_str() {
181        "account/chatgptAuthTokens/refresh" => ServerRequestEvent::ChatgptAuthTokensRefresh {
182            id,
183            params: decode(params)?,
184        },
185        "applyPatchApproval" => ServerRequestEvent::ApplyPatchApproval {
186            id,
187            params: decode(params)?,
188        },
189        "execCommandApproval" => ServerRequestEvent::ExecCommandApproval {
190            id,
191            params: decode(params)?,
192        },
193        "item/commandExecution/requestApproval" => {
194            ServerRequestEvent::CommandExecutionRequestApproval {
195                id,
196                params: decode(params)?,
197            }
198        }
199        "item/fileChange/requestApproval" => ServerRequestEvent::FileChangeRequestApproval {
200            id,
201            params: decode(params)?,
202        },
203        "item/tool/requestUserInput" => ServerRequestEvent::ToolRequestUserInput {
204            id,
205            params: decode(params)?,
206        },
207        "item/tool/call" => ServerRequestEvent::DynamicToolCall {
208            id,
209            params: decode(params)?,
210        },
211        _ => ServerRequestEvent::Unknown { id, method, params },
212    };
213    Ok(req)
214}