Add missing "nullable" macro to protocol structs that contain optional fields (#5901)
This PR addresses a current hole in the TypeScript code generation for
the API server protocol. Fields that are marked as "Optional<>" in the
Rust code are serialized such that the value is omitted when it is
deserialized — appearing as `undefined`, but the TS type indicates
(incorrectly) that it is always defined but possibly `null`. This can
lead to subtle errors that the TypeScript compiler doesn't catch. The
fix is to include the `#[ts(optional_fields = nullable)]` macro for all
protocol structs that contain one or more `Optional<>` fields.
This PR also includes a new test that validates that all TS protocol
code containing "| null" in its type is marked optional ("?") to catch
cases where `#[ts(optional_fields = nullable)]` is omitted.
This commit is contained in:
@@ -534,3 +534,150 @@ fn generate_index_ts(out_dir: &Path) -> Result<PathBuf> {
|
|||||||
.with_context(|| format!("Failed to write {}", index_path.display()))?;
|
.with_context(|| format!("Failed to write {}", index_path.display()))?;
|
||||||
Ok(index_path)
|
Ok(index_path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use anyhow::Result;
|
||||||
|
use std::collections::BTreeSet;
|
||||||
|
use std::fs;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn generated_ts_omits_undefined_unions_for_optionals() -> Result<()> {
|
||||||
|
let output_dir = std::env::temp_dir().join(format!("codex_ts_types_{}", Uuid::now_v7()));
|
||||||
|
fs::create_dir(&output_dir)?;
|
||||||
|
|
||||||
|
struct TempDirGuard(PathBuf);
|
||||||
|
|
||||||
|
impl Drop for TempDirGuard {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
let _ = fs::remove_dir_all(&self.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let _guard = TempDirGuard(output_dir.clone());
|
||||||
|
|
||||||
|
generate_ts(&output_dir, None)?;
|
||||||
|
|
||||||
|
let mut undefined_offenders = Vec::new();
|
||||||
|
let mut missing_optional_marker = BTreeSet::new();
|
||||||
|
let mut stack = vec![output_dir];
|
||||||
|
while let Some(dir) = stack.pop() {
|
||||||
|
for entry in fs::read_dir(&dir)? {
|
||||||
|
let entry = entry?;
|
||||||
|
let path = entry.path();
|
||||||
|
if path.is_dir() {
|
||||||
|
stack.push(path);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if matches!(path.extension().and_then(|ext| ext.to_str()), Some("ts")) {
|
||||||
|
let contents = fs::read_to_string(&path)?;
|
||||||
|
if contents.contains("| undefined") {
|
||||||
|
undefined_offenders.push(path.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
const SKIP_PREFIXES: &[&str] = &[
|
||||||
|
"const ",
|
||||||
|
"let ",
|
||||||
|
"var ",
|
||||||
|
"export const ",
|
||||||
|
"export let ",
|
||||||
|
"export var ",
|
||||||
|
];
|
||||||
|
|
||||||
|
let mut search_start = 0;
|
||||||
|
while let Some(idx) = contents[search_start..].find("| null") {
|
||||||
|
let abs_idx = search_start + idx;
|
||||||
|
let Some(colon_idx) = contents[..abs_idx].rfind(':') else {
|
||||||
|
search_start = abs_idx + 5;
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
let line_start_idx = contents[..colon_idx]
|
||||||
|
.rfind('\n')
|
||||||
|
.map(|i| i + 1)
|
||||||
|
.unwrap_or(0);
|
||||||
|
|
||||||
|
let mut segment_start_idx = line_start_idx;
|
||||||
|
if let Some(rel_idx) = contents[line_start_idx..colon_idx].rfind(',') {
|
||||||
|
segment_start_idx = segment_start_idx.max(line_start_idx + rel_idx + 1);
|
||||||
|
}
|
||||||
|
if let Some(rel_idx) = contents[line_start_idx..colon_idx].rfind('{') {
|
||||||
|
segment_start_idx = segment_start_idx.max(line_start_idx + rel_idx + 1);
|
||||||
|
}
|
||||||
|
if let Some(rel_idx) = contents[line_start_idx..colon_idx].rfind('}') {
|
||||||
|
segment_start_idx = segment_start_idx.max(line_start_idx + rel_idx + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut field_prefix = contents[segment_start_idx..colon_idx].trim();
|
||||||
|
if field_prefix.is_empty() {
|
||||||
|
search_start = abs_idx + 5;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(comment_idx) = field_prefix.rfind("*/") {
|
||||||
|
field_prefix = field_prefix[comment_idx + 2..].trim_start();
|
||||||
|
}
|
||||||
|
|
||||||
|
if field_prefix.is_empty() {
|
||||||
|
search_start = abs_idx + 5;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if SKIP_PREFIXES
|
||||||
|
.iter()
|
||||||
|
.any(|prefix| field_prefix.starts_with(prefix))
|
||||||
|
{
|
||||||
|
search_start = abs_idx + 5;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if field_prefix.contains('(') {
|
||||||
|
search_start = abs_idx + 5;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if field_prefix.chars().rev().find(|c| !c.is_whitespace()) == Some('?') {
|
||||||
|
search_start = abs_idx + 5;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let line_number =
|
||||||
|
contents[..abs_idx].chars().filter(|c| *c == '\n').count() + 1;
|
||||||
|
let offending_line_end = contents[line_start_idx..]
|
||||||
|
.find('\n')
|
||||||
|
.map(|i| line_start_idx + i)
|
||||||
|
.unwrap_or(contents.len());
|
||||||
|
let offending_snippet = contents[line_start_idx..offending_line_end].trim();
|
||||||
|
|
||||||
|
missing_optional_marker.insert(format!(
|
||||||
|
"{}:{}: {offending_snippet}",
|
||||||
|
path.display(),
|
||||||
|
line_number
|
||||||
|
));
|
||||||
|
|
||||||
|
search_start = abs_idx + 5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert!(
|
||||||
|
undefined_offenders.is_empty(),
|
||||||
|
"Generated TypeScript still includes unions with `undefined` in {undefined_offenders:?}"
|
||||||
|
);
|
||||||
|
|
||||||
|
// If this test fails, it means that a struct field that is `Option<T>` in Rust
|
||||||
|
// is being generated as `T | null` in TypeScript, without the optional marker
|
||||||
|
// (`?`). To fix this, add #[ts(optional_fields = nullable)] to the struct definition.
|
||||||
|
assert!(
|
||||||
|
missing_optional_marker.is_empty(),
|
||||||
|
"Generated TypeScript has nullable fields without an optional marker: {missing_optional_marker:?}"
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ pub enum JSONRPCMessage {
|
|||||||
|
|
||||||
/// A request that expects a response.
|
/// A request that expects a response.
|
||||||
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, TS)]
|
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, TS)]
|
||||||
|
#[ts(optional_fields = nullable)]
|
||||||
pub struct JSONRPCRequest {
|
pub struct JSONRPCRequest {
|
||||||
pub id: RequestId,
|
pub id: RequestId,
|
||||||
pub method: String,
|
pub method: String,
|
||||||
@@ -39,6 +40,7 @@ pub struct JSONRPCRequest {
|
|||||||
|
|
||||||
/// A notification which does not expect a response.
|
/// A notification which does not expect a response.
|
||||||
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, TS)]
|
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, TS)]
|
||||||
|
#[ts(optional_fields = nullable)]
|
||||||
pub struct JSONRPCNotification {
|
pub struct JSONRPCNotification {
|
||||||
pub method: String,
|
pub method: String,
|
||||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
@@ -60,6 +62,7 @@ pub struct JSONRPCError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, TS)]
|
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, TS)]
|
||||||
|
#[ts(optional_fields = nullable)]
|
||||||
pub struct JSONRPCErrorError {
|
pub struct JSONRPCErrorError {
|
||||||
pub code: i64,
|
pub code: i64,
|
||||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
|
|||||||
@@ -248,6 +248,7 @@ pub enum Account {
|
|||||||
#[serde(rename = "chatgpt", rename_all = "camelCase")]
|
#[serde(rename = "chatgpt", rename_all = "camelCase")]
|
||||||
#[ts(rename = "chatgpt", rename_all = "camelCase")]
|
#[ts(rename = "chatgpt", rename_all = "camelCase")]
|
||||||
ChatGpt {
|
ChatGpt {
|
||||||
|
#[ts(optional = nullable)]
|
||||||
email: Option<String>,
|
email: Option<String>,
|
||||||
plan_type: PlanType,
|
plan_type: PlanType,
|
||||||
},
|
},
|
||||||
@@ -266,6 +267,7 @@ pub struct InitializeParams {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default, JsonSchema, TS)]
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default, JsonSchema, TS)]
|
||||||
|
#[ts(optional_fields = nullable)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct ClientInfo {
|
pub struct ClientInfo {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
@@ -281,6 +283,7 @@ pub struct InitializeResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default, JsonSchema, TS)]
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default, JsonSchema, TS)]
|
||||||
|
#[ts(optional_fields = nullable)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct NewConversationParams {
|
pub struct NewConversationParams {
|
||||||
/// Optional override for the model name (e.g. "o3", "o4-mini").
|
/// Optional override for the model name (e.g. "o3", "o4-mini").
|
||||||
@@ -324,6 +327,7 @@ pub struct NewConversationParams {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
||||||
|
#[ts(optional_fields = nullable)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct NewConversationResponse {
|
pub struct NewConversationResponse {
|
||||||
pub conversation_id: ConversationId,
|
pub conversation_id: ConversationId,
|
||||||
@@ -335,6 +339,7 @@ pub struct NewConversationResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, JsonSchema, TS)]
|
#[derive(Serialize, Deserialize, Debug, Clone, JsonSchema, TS)]
|
||||||
|
#[ts(optional_fields = nullable)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct ResumeConversationResponse {
|
pub struct ResumeConversationResponse {
|
||||||
pub conversation_id: ConversationId,
|
pub conversation_id: ConversationId,
|
||||||
@@ -368,6 +373,7 @@ pub struct GetConversationSummaryResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default, JsonSchema, TS)]
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default, JsonSchema, TS)]
|
||||||
|
#[ts(optional_fields = nullable)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct ListConversationsParams {
|
pub struct ListConversationsParams {
|
||||||
/// Optional page size; defaults to a reasonable server-side value.
|
/// Optional page size; defaults to a reasonable server-side value.
|
||||||
@@ -385,6 +391,7 @@ pub struct ListConversationsParams {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
||||||
|
#[ts(optional_fields = nullable)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct ConversationSummary {
|
pub struct ConversationSummary {
|
||||||
pub conversation_id: ConversationId,
|
pub conversation_id: ConversationId,
|
||||||
@@ -398,6 +405,7 @@ pub struct ConversationSummary {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
||||||
|
#[ts(optional_fields = nullable)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct ListConversationsResponse {
|
pub struct ListConversationsResponse {
|
||||||
pub items: Vec<ConversationSummary>,
|
pub items: Vec<ConversationSummary>,
|
||||||
@@ -408,6 +416,7 @@ pub struct ListConversationsResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default, JsonSchema, TS)]
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default, JsonSchema, TS)]
|
||||||
|
#[ts(optional_fields = nullable)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct ListModelsParams {
|
pub struct ListModelsParams {
|
||||||
/// Optional page size; defaults to a reasonable server-side value.
|
/// Optional page size; defaults to a reasonable server-side value.
|
||||||
@@ -439,6 +448,7 @@ pub struct ReasoningEffortOption {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
||||||
|
#[ts(optional_fields = nullable)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct ListModelsResponse {
|
pub struct ListModelsResponse {
|
||||||
pub items: Vec<Model>,
|
pub items: Vec<Model>,
|
||||||
@@ -449,6 +459,7 @@ pub struct ListModelsResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
||||||
|
#[ts(optional_fields = nullable)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct UploadFeedbackParams {
|
pub struct UploadFeedbackParams {
|
||||||
pub classification: String,
|
pub classification: String,
|
||||||
@@ -482,6 +493,7 @@ pub enum LoginAccountParams {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
||||||
|
#[ts(optional_fields = nullable)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct LoginAccountResponse {
|
pub struct LoginAccountResponse {
|
||||||
/// Only set if the login method is ChatGPT.
|
/// Only set if the login method is ChatGPT.
|
||||||
@@ -498,6 +510,7 @@ pub struct LoginAccountResponse {
|
|||||||
pub struct LogoutAccountResponse {}
|
pub struct LogoutAccountResponse {}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
||||||
|
#[ts(optional_fields = nullable)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct ResumeConversationParams {
|
pub struct ResumeConversationParams {
|
||||||
/// Absolute path to the rollout JSONL file, when explicitly resuming a known rollout.
|
/// Absolute path to the rollout JSONL file, when explicitly resuming a known rollout.
|
||||||
@@ -589,6 +602,7 @@ pub struct LogoutChatGptParams {}
|
|||||||
pub struct LogoutChatGptResponse {}
|
pub struct LogoutChatGptResponse {}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
||||||
|
#[ts(optional_fields = nullable)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct GetAuthStatusParams {
|
pub struct GetAuthStatusParams {
|
||||||
/// If true, include the current auth token (if available) in the response.
|
/// If true, include the current auth token (if available) in the response.
|
||||||
@@ -600,6 +614,7 @@ pub struct GetAuthStatusParams {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
||||||
|
#[ts(optional_fields = nullable)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct ExecOneOffCommandParams {
|
pub struct ExecOneOffCommandParams {
|
||||||
/// Command argv to execute.
|
/// Command argv to execute.
|
||||||
@@ -631,6 +646,7 @@ pub struct GetAccountRateLimitsResponse {
|
|||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
|
#[ts(optional_fields = nullable)]
|
||||||
pub struct GetAuthStatusResponse {
|
pub struct GetAuthStatusResponse {
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub auth_method: Option<AuthMode>,
|
pub auth_method: Option<AuthMode>,
|
||||||
@@ -651,6 +667,7 @@ pub struct GetUserAgentResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
||||||
|
#[ts(optional_fields = nullable)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct UserInfoResponse {
|
pub struct UserInfoResponse {
|
||||||
/// Note: `alleged_user_email` is not currently verified. We read it from
|
/// Note: `alleged_user_email` is not currently verified. We read it from
|
||||||
@@ -667,6 +684,7 @@ pub struct GetUserSavedConfigResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
||||||
|
#[ts(optional_fields = nullable)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct SetDefaultModelParams {
|
pub struct SetDefaultModelParams {
|
||||||
/// If set to None, this means `model` should be cleared in config.toml.
|
/// If set to None, this means `model` should be cleared in config.toml.
|
||||||
@@ -686,6 +704,7 @@ pub struct SetDefaultModelResponse {}
|
|||||||
/// client-configurable settings that can be specified in the NewConversation
|
/// client-configurable settings that can be specified in the NewConversation
|
||||||
/// and SendUserTurn requests.
|
/// and SendUserTurn requests.
|
||||||
#[derive(Deserialize, Debug, Clone, PartialEq, Serialize, JsonSchema, TS)]
|
#[derive(Deserialize, Debug, Clone, PartialEq, Serialize, JsonSchema, TS)]
|
||||||
|
#[ts(optional_fields = nullable)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct UserSavedConfig {
|
pub struct UserSavedConfig {
|
||||||
/// Approvals
|
/// Approvals
|
||||||
@@ -724,6 +743,7 @@ pub struct UserSavedConfig {
|
|||||||
|
|
||||||
/// MCP representation of a [`codex_core::config_profile::ConfigProfile`].
|
/// MCP representation of a [`codex_core::config_profile::ConfigProfile`].
|
||||||
#[derive(Deserialize, Debug, Clone, PartialEq, Serialize, JsonSchema, TS)]
|
#[derive(Deserialize, Debug, Clone, PartialEq, Serialize, JsonSchema, TS)]
|
||||||
|
#[ts(optional_fields = nullable)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct Profile {
|
pub struct Profile {
|
||||||
pub model: Option<String>,
|
pub model: Option<String>,
|
||||||
@@ -738,6 +758,7 @@ pub struct Profile {
|
|||||||
}
|
}
|
||||||
/// MCP representation of a [`codex_core::config::ToolsToml`].
|
/// MCP representation of a [`codex_core::config::ToolsToml`].
|
||||||
#[derive(Deserialize, Debug, Clone, PartialEq, Serialize, JsonSchema, TS)]
|
#[derive(Deserialize, Debug, Clone, PartialEq, Serialize, JsonSchema, TS)]
|
||||||
|
#[ts(optional_fields = nullable)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct Tools {
|
pub struct Tools {
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
@@ -748,6 +769,7 @@ pub struct Tools {
|
|||||||
|
|
||||||
/// MCP representation of a [`codex_core::config_types::SandboxWorkspaceWrite`].
|
/// MCP representation of a [`codex_core::config_types::SandboxWorkspaceWrite`].
|
||||||
#[derive(Deserialize, Debug, Clone, PartialEq, Serialize, JsonSchema, TS)]
|
#[derive(Deserialize, Debug, Clone, PartialEq, Serialize, JsonSchema, TS)]
|
||||||
|
#[ts(optional_fields = nullable)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct SandboxSettings {
|
pub struct SandboxSettings {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
@@ -768,6 +790,7 @@ pub struct SendUserMessageParams {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
||||||
|
#[ts(optional_fields = nullable)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct SendUserTurnParams {
|
pub struct SendUserTurnParams {
|
||||||
pub conversation_id: ConversationId,
|
pub conversation_id: ConversationId,
|
||||||
@@ -911,6 +934,7 @@ server_request_definitions! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
||||||
|
#[ts(optional_fields = nullable)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct ApplyPatchApprovalParams {
|
pub struct ApplyPatchApprovalParams {
|
||||||
pub conversation_id: ConversationId,
|
pub conversation_id: ConversationId,
|
||||||
@@ -928,6 +952,7 @@ pub struct ApplyPatchApprovalParams {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
||||||
|
#[ts(optional_fields = nullable)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct ExecCommandApprovalParams {
|
pub struct ExecCommandApprovalParams {
|
||||||
pub conversation_id: ConversationId,
|
pub conversation_id: ConversationId,
|
||||||
@@ -954,6 +979,7 @@ pub struct ApplyPatchApprovalResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
||||||
|
#[ts(optional_fields = nullable)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
#[ts(rename_all = "camelCase")]
|
#[ts(rename_all = "camelCase")]
|
||||||
pub struct FuzzyFileSearchParams {
|
pub struct FuzzyFileSearchParams {
|
||||||
@@ -966,6 +992,7 @@ pub struct FuzzyFileSearchParams {
|
|||||||
|
|
||||||
/// Superset of [`codex_file_search::FileMatch`]
|
/// Superset of [`codex_file_search::FileMatch`]
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
||||||
|
#[ts(optional_fields = nullable)]
|
||||||
pub struct FuzzyFileSearchResult {
|
pub struct FuzzyFileSearchResult {
|
||||||
pub root: String,
|
pub root: String,
|
||||||
pub path: String,
|
pub path: String,
|
||||||
@@ -981,6 +1008,7 @@ pub struct FuzzyFileSearchResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
||||||
|
#[ts(optional_fields = nullable)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct LoginChatGptCompleteNotification {
|
pub struct LoginChatGptCompleteNotification {
|
||||||
#[schemars(with = "String")]
|
#[schemars(with = "String")]
|
||||||
@@ -991,6 +1019,7 @@ pub struct LoginChatGptCompleteNotification {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, JsonSchema, TS)]
|
#[derive(Serialize, Deserialize, Debug, Clone, JsonSchema, TS)]
|
||||||
|
#[ts(optional_fields = nullable)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct SessionConfiguredNotification {
|
pub struct SessionConfiguredNotification {
|
||||||
/// Name left as session_id instead of conversation_id for backwards compatibility.
|
/// Name left as session_id instead of conversation_id for backwards compatibility.
|
||||||
@@ -1019,6 +1048,7 @@ pub struct SessionConfiguredNotification {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
||||||
|
#[ts(optional_fields = nullable)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct AuthStatusChangeNotification {
|
pub struct AuthStatusChangeNotification {
|
||||||
/// Current authentication method; omitted if signed out.
|
/// Current authentication method; omitted if signed out.
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ impl SandboxRiskCategory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, TS)]
|
#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, TS)]
|
||||||
|
#[ts(optional_fields = nullable)]
|
||||||
pub struct ExecApprovalRequestEvent {
|
pub struct ExecApprovalRequestEvent {
|
||||||
/// Identifier for the associated exec call, if available.
|
/// Identifier for the associated exec call, if available.
|
||||||
pub call_id: String,
|
pub call_id: String,
|
||||||
@@ -78,6 +79,7 @@ pub struct ExecApprovalRequestEvent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, TS)]
|
#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, TS)]
|
||||||
|
#[ts(optional_fields = nullable)]
|
||||||
pub struct ApplyPatchApprovalRequestEvent {
|
pub struct ApplyPatchApprovalRequestEvent {
|
||||||
/// Responses API call id for the associated patch apply call, if available.
|
/// Responses API call id for the associated patch apply call, if available.
|
||||||
pub call_id: String,
|
pub call_id: String,
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ use ts_rs::TS;
|
|||||||
pub const PROMPTS_CMD_PREFIX: &str = "prompts";
|
pub const PROMPTS_CMD_PREFIX: &str = "prompts";
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, JsonSchema, TS)]
|
#[derive(Serialize, Deserialize, Debug, Clone, JsonSchema, TS)]
|
||||||
|
#[ts(optional_fields = nullable)]
|
||||||
pub struct CustomPrompt {
|
pub struct CustomPrompt {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub path: PathBuf,
|
pub path: PathBuf,
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ pub enum ContentItem {
|
|||||||
pub enum ResponseItem {
|
pub enum ResponseItem {
|
||||||
Message {
|
Message {
|
||||||
#[serde(skip_serializing)]
|
#[serde(skip_serializing)]
|
||||||
|
#[ts(optional = nullable)]
|
||||||
id: Option<String>,
|
id: Option<String>,
|
||||||
role: String,
|
role: String,
|
||||||
content: Vec<ContentItem>,
|
content: Vec<ContentItem>,
|
||||||
@@ -58,20 +59,25 @@ pub enum ResponseItem {
|
|||||||
id: String,
|
id: String,
|
||||||
summary: Vec<ReasoningItemReasoningSummary>,
|
summary: Vec<ReasoningItemReasoningSummary>,
|
||||||
#[serde(default, skip_serializing_if = "should_serialize_reasoning_content")]
|
#[serde(default, skip_serializing_if = "should_serialize_reasoning_content")]
|
||||||
|
#[ts(optional = nullable)]
|
||||||
content: Option<Vec<ReasoningItemContent>>,
|
content: Option<Vec<ReasoningItemContent>>,
|
||||||
|
#[ts(optional = nullable)]
|
||||||
encrypted_content: Option<String>,
|
encrypted_content: Option<String>,
|
||||||
},
|
},
|
||||||
LocalShellCall {
|
LocalShellCall {
|
||||||
/// Set when using the chat completions API.
|
/// Set when using the chat completions API.
|
||||||
#[serde(skip_serializing)]
|
#[serde(skip_serializing)]
|
||||||
|
#[ts(optional = nullable)]
|
||||||
id: Option<String>,
|
id: Option<String>,
|
||||||
/// Set when using the Responses API.
|
/// Set when using the Responses API.
|
||||||
|
#[ts(optional = nullable)]
|
||||||
call_id: Option<String>,
|
call_id: Option<String>,
|
||||||
status: LocalShellStatus,
|
status: LocalShellStatus,
|
||||||
action: LocalShellAction,
|
action: LocalShellAction,
|
||||||
},
|
},
|
||||||
FunctionCall {
|
FunctionCall {
|
||||||
#[serde(skip_serializing)]
|
#[serde(skip_serializing)]
|
||||||
|
#[ts(optional = nullable)]
|
||||||
id: Option<String>,
|
id: Option<String>,
|
||||||
name: String,
|
name: String,
|
||||||
// The Responses API returns the function call arguments as a *string* that contains
|
// The Responses API returns the function call arguments as a *string* that contains
|
||||||
@@ -92,8 +98,10 @@ pub enum ResponseItem {
|
|||||||
},
|
},
|
||||||
CustomToolCall {
|
CustomToolCall {
|
||||||
#[serde(skip_serializing)]
|
#[serde(skip_serializing)]
|
||||||
|
#[ts(optional = nullable)]
|
||||||
id: Option<String>,
|
id: Option<String>,
|
||||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
|
#[ts(optional = nullable)]
|
||||||
status: Option<String>,
|
status: Option<String>,
|
||||||
|
|
||||||
call_id: String,
|
call_id: String,
|
||||||
@@ -114,8 +122,10 @@ pub enum ResponseItem {
|
|||||||
// }
|
// }
|
||||||
WebSearchCall {
|
WebSearchCall {
|
||||||
#[serde(skip_serializing)]
|
#[serde(skip_serializing)]
|
||||||
|
#[ts(optional = nullable)]
|
||||||
id: Option<String>,
|
id: Option<String>,
|
||||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
|
#[ts(optional = nullable)]
|
||||||
status: Option<String>,
|
status: Option<String>,
|
||||||
action: WebSearchAction,
|
action: WebSearchAction,
|
||||||
},
|
},
|
||||||
@@ -193,6 +203,7 @@ pub enum LocalShellAction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, JsonSchema, TS)]
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, JsonSchema, TS)]
|
||||||
|
#[ts(optional_fields = nullable)]
|
||||||
pub struct LocalShellExecAction {
|
pub struct LocalShellExecAction {
|
||||||
pub command: Vec<String>,
|
pub command: Vec<String>,
|
||||||
pub timeout_ms: Option<u64>,
|
pub timeout_ms: Option<u64>,
|
||||||
@@ -285,6 +296,7 @@ impl From<Vec<UserInput>> for ResponseInputItem {
|
|||||||
/// If the `name` of a `ResponseItem::FunctionCall` is either `container.exec`
|
/// If the `name` of a `ResponseItem::FunctionCall` is either `container.exec`
|
||||||
/// or shell`, the `arguments` field should deserialize to this struct.
|
/// or shell`, the `arguments` field should deserialize to this struct.
|
||||||
#[derive(Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
#[derive(Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
||||||
|
#[ts(optional_fields = nullable)]
|
||||||
pub struct ShellToolCallParams {
|
pub struct ShellToolCallParams {
|
||||||
pub command: Vec<String>,
|
pub command: Vec<String>,
|
||||||
pub workdir: Option<String>,
|
pub workdir: Option<String>,
|
||||||
@@ -317,6 +329,7 @@ pub enum FunctionCallOutputContentItem {
|
|||||||
/// `content_items` with the structured form that the Responses/Chat
|
/// `content_items` with the structured form that the Responses/Chat
|
||||||
/// Completions APIs understand.
|
/// Completions APIs understand.
|
||||||
#[derive(Debug, Default, Clone, PartialEq, JsonSchema, TS)]
|
#[derive(Debug, Default, Clone, PartialEq, JsonSchema, TS)]
|
||||||
|
#[ts(optional_fields = nullable)]
|
||||||
pub struct FunctionCallOutputPayload {
|
pub struct FunctionCallOutputPayload {
|
||||||
pub content: String,
|
pub content: String,
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
|||||||
@@ -18,11 +18,14 @@ pub enum ParsedCommand {
|
|||||||
},
|
},
|
||||||
ListFiles {
|
ListFiles {
|
||||||
cmd: String,
|
cmd: String,
|
||||||
|
#[ts(optional = nullable)]
|
||||||
path: Option<String>,
|
path: Option<String>,
|
||||||
},
|
},
|
||||||
Search {
|
Search {
|
||||||
cmd: String,
|
cmd: String,
|
||||||
|
#[ts(optional = nullable)]
|
||||||
query: Option<String>,
|
query: Option<String>,
|
||||||
|
#[ts(optional = nullable)]
|
||||||
path: Option<String>,
|
path: Option<String>,
|
||||||
},
|
},
|
||||||
Unknown {
|
Unknown {
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ pub struct PlanItemArg {
|
|||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, TS)]
|
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, TS)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
|
#[ts(optional_fields = nullable)]
|
||||||
pub struct UpdatePlanArgs {
|
pub struct UpdatePlanArgs {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub explanation: Option<String>,
|
pub explanation: Option<String>,
|
||||||
|
|||||||
@@ -563,6 +563,7 @@ pub struct ItemCompletedEvent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, TS)]
|
#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, TS)]
|
||||||
|
#[ts(optional_fields = nullable)]
|
||||||
pub struct ExitedReviewModeEvent {
|
pub struct ExitedReviewModeEvent {
|
||||||
pub review_output: Option<ReviewOutputEvent>,
|
pub review_output: Option<ReviewOutputEvent>,
|
||||||
}
|
}
|
||||||
@@ -575,11 +576,13 @@ pub struct ErrorEvent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, TS)]
|
#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, TS)]
|
||||||
|
#[ts(optional_fields = nullable)]
|
||||||
pub struct TaskCompleteEvent {
|
pub struct TaskCompleteEvent {
|
||||||
pub last_agent_message: Option<String>,
|
pub last_agent_message: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, TS)]
|
#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, TS)]
|
||||||
|
#[ts(optional_fields = nullable)]
|
||||||
pub struct TaskStartedEvent {
|
pub struct TaskStartedEvent {
|
||||||
pub model_context_window: Option<i64>,
|
pub model_context_window: Option<i64>,
|
||||||
}
|
}
|
||||||
@@ -599,9 +602,11 @@ pub struct TokenUsage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, TS)]
|
#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, TS)]
|
||||||
|
#[ts(optional_fields = nullable)]
|
||||||
pub struct TokenUsageInfo {
|
pub struct TokenUsageInfo {
|
||||||
pub total_token_usage: TokenUsage,
|
pub total_token_usage: TokenUsage,
|
||||||
pub last_token_usage: TokenUsage,
|
pub last_token_usage: TokenUsage,
|
||||||
|
#[ts(optional = nullable)]
|
||||||
#[ts(type = "number | null")]
|
#[ts(type = "number | null")]
|
||||||
pub model_context_window: Option<i64>,
|
pub model_context_window: Option<i64>,
|
||||||
}
|
}
|
||||||
@@ -662,25 +667,30 @@ impl TokenUsageInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, TS)]
|
#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, TS)]
|
||||||
|
#[ts(optional_fields = nullable)]
|
||||||
pub struct TokenCountEvent {
|
pub struct TokenCountEvent {
|
||||||
pub info: Option<TokenUsageInfo>,
|
pub info: Option<TokenUsageInfo>,
|
||||||
pub rate_limits: Option<RateLimitSnapshot>,
|
pub rate_limits: Option<RateLimitSnapshot>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, TS)]
|
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, TS)]
|
||||||
|
#[ts(optional_fields = nullable)]
|
||||||
pub struct RateLimitSnapshot {
|
pub struct RateLimitSnapshot {
|
||||||
pub primary: Option<RateLimitWindow>,
|
pub primary: Option<RateLimitWindow>,
|
||||||
pub secondary: Option<RateLimitWindow>,
|
pub secondary: Option<RateLimitWindow>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, TS)]
|
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, TS)]
|
||||||
|
#[ts(optional_fields = nullable)]
|
||||||
pub struct RateLimitWindow {
|
pub struct RateLimitWindow {
|
||||||
/// Percentage (0-100) of the window that has been consumed.
|
/// Percentage (0-100) of the window that has been consumed.
|
||||||
pub used_percent: f64,
|
pub used_percent: f64,
|
||||||
/// Rolling window duration, in minutes.
|
/// Rolling window duration, in minutes.
|
||||||
|
#[ts(optional = nullable)]
|
||||||
#[ts(type = "number | null")]
|
#[ts(type = "number | null")]
|
||||||
pub window_minutes: Option<i64>,
|
pub window_minutes: Option<i64>,
|
||||||
/// Unix timestamp (seconds since epoch) when the window resets.
|
/// Unix timestamp (seconds since epoch) when the window resets.
|
||||||
|
#[ts(optional = nullable)]
|
||||||
#[ts(type = "number | null")]
|
#[ts(type = "number | null")]
|
||||||
pub resets_at: Option<i64>,
|
pub resets_at: Option<i64>,
|
||||||
}
|
}
|
||||||
@@ -794,6 +804,7 @@ pub struct AgentMessageEvent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, TS)]
|
#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, TS)]
|
||||||
|
#[ts(optional_fields = nullable)]
|
||||||
pub struct UserMessageEvent {
|
pub struct UserMessageEvent {
|
||||||
pub message: String,
|
pub message: String,
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
@@ -829,6 +840,7 @@ pub struct AgentReasoningDeltaEvent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, TS, PartialEq)]
|
#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, TS, PartialEq)]
|
||||||
|
#[ts(optional_fields = nullable)]
|
||||||
pub struct McpInvocation {
|
pub struct McpInvocation {
|
||||||
/// Name of the MCP server as defined in the config.
|
/// Name of the MCP server as defined in the config.
|
||||||
pub server: String,
|
pub server: String,
|
||||||
@@ -947,6 +959,7 @@ pub enum SessionSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema, TS)]
|
#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema, TS)]
|
||||||
|
#[ts(optional_fields = nullable)]
|
||||||
pub struct SessionMeta {
|
pub struct SessionMeta {
|
||||||
pub id: ConversationId,
|
pub id: ConversationId,
|
||||||
pub timestamp: String,
|
pub timestamp: String,
|
||||||
@@ -975,6 +988,7 @@ impl Default for SessionMeta {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, JsonSchema, TS)]
|
#[derive(Serialize, Deserialize, Debug, Clone, JsonSchema, TS)]
|
||||||
|
#[ts(optional_fields = nullable)]
|
||||||
pub struct SessionMetaLine {
|
pub struct SessionMetaLine {
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
pub meta: SessionMeta,
|
pub meta: SessionMeta,
|
||||||
@@ -1010,6 +1024,7 @@ impl From<CompactedItem> for ResponseItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema, TS)]
|
#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema, TS)]
|
||||||
|
#[ts(optional_fields = nullable)]
|
||||||
pub struct TurnContextItem {
|
pub struct TurnContextItem {
|
||||||
pub cwd: PathBuf,
|
pub cwd: PathBuf,
|
||||||
pub approval_policy: AskForApproval,
|
pub approval_policy: AskForApproval,
|
||||||
@@ -1028,6 +1043,7 @@ pub struct RolloutLine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema, TS)]
|
#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema, TS)]
|
||||||
|
#[ts(optional_fields = nullable)]
|
||||||
pub struct GitInfo {
|
pub struct GitInfo {
|
||||||
/// Current commit hash (SHA)
|
/// Current commit hash (SHA)
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
@@ -1161,6 +1177,7 @@ pub struct BackgroundEventEvent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, TS)]
|
#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, TS)]
|
||||||
|
#[ts(optional_fields = nullable)]
|
||||||
pub struct DeprecationNoticeEvent {
|
pub struct DeprecationNoticeEvent {
|
||||||
/// Concise summary of what is deprecated.
|
/// Concise summary of what is deprecated.
|
||||||
pub summary: String,
|
pub summary: String,
|
||||||
@@ -1170,12 +1187,14 @@ pub struct DeprecationNoticeEvent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, TS)]
|
#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, TS)]
|
||||||
|
#[ts(optional_fields = nullable)]
|
||||||
pub struct UndoStartedEvent {
|
pub struct UndoStartedEvent {
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub message: Option<String>,
|
pub message: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, TS)]
|
#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, TS)]
|
||||||
|
#[ts(optional_fields = nullable)]
|
||||||
pub struct UndoCompletedEvent {
|
pub struct UndoCompletedEvent {
|
||||||
pub success: bool,
|
pub success: bool,
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
@@ -1220,6 +1239,7 @@ pub struct TurnDiffEvent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, TS)]
|
#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, TS)]
|
||||||
|
#[ts(optional_fields = nullable)]
|
||||||
pub struct GetHistoryEntryResponseEvent {
|
pub struct GetHistoryEntryResponseEvent {
|
||||||
pub offset: usize,
|
pub offset: usize,
|
||||||
pub log_id: u64,
|
pub log_id: u64,
|
||||||
@@ -1269,6 +1289,7 @@ pub struct ListCustomPromptsResponseEvent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone, Deserialize, Serialize, JsonSchema, TS)]
|
#[derive(Debug, Default, Clone, Deserialize, Serialize, JsonSchema, TS)]
|
||||||
|
#[ts(optional_fields = nullable)]
|
||||||
pub struct SessionConfiguredEvent {
|
pub struct SessionConfiguredEvent {
|
||||||
/// Name left as session_id instead of conversation_id for backwards compatibility.
|
/// Name left as session_id instead of conversation_id for backwards compatibility.
|
||||||
pub session_id: ConversationId,
|
pub session_id: ConversationId,
|
||||||
@@ -1329,6 +1350,7 @@ pub enum FileChange {
|
|||||||
},
|
},
|
||||||
Update {
|
Update {
|
||||||
unified_diff: String,
|
unified_diff: String,
|
||||||
|
#[ts(optional = nullable)]
|
||||||
move_path: Option<PathBuf>,
|
move_path: Option<PathBuf>,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ type CommitID = String;
|
|||||||
|
|
||||||
/// Details of a ghost commit created from a repository state.
|
/// Details of a ghost commit created from a repository state.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema, TS)]
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema, TS)]
|
||||||
|
#[ts(optional_fields = nullable)]
|
||||||
pub struct GhostCommit {
|
pub struct GhostCommit {
|
||||||
id: CommitID,
|
id: CommitID,
|
||||||
parent: Option<CommitID>,
|
parent: Option<CommitID>,
|
||||||
|
|||||||
Reference in New Issue
Block a user