Skip to content

Conversation

@owenlin0
Copy link
Contributor

@owenlin0 owenlin0 commented Dec 2, 2025

The problem with using serde(flatten) on Turn status is that it conditionally serializes the error field, which is not the pattern we want in API v2 where all fields on an object should always be returned.

#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export_to = "v2/")]
pub struct Turn {
    pub id: String,
    /// Only populated on a `thread/resume` response.
    /// For all other responses and notifications returning a Turn,
    /// the items field will be an empty list.
    pub items: Vec<ThreadItem>,
    #[serde(flatten)]
    pub status: TurnStatus,
}

#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
#[serde(tag = "status", rename_all = "camelCase")]
#[ts(tag = "status", export_to = "v2/")]
pub enum TurnStatus {
    Completed,
    Interrupted,
    Failed { error: TurnError },
    InProgress,
}

serializes to:

{
  "id": "turn-123",
  "items": [],
  "status": "completed"
}

{
  "id": "turn-123",
  "items": [],
  "status": "failed",
  "error": {
    "message": "Tool timeout",
    "codexErrorInfo": null
  }
}

Instead we want:

{
  "id": "turn-123",
  "items": [],
  "status": "completed",
  "error": null
}

{
  "id": "turn-123",
  "items": [],
  "status": "failed",
  "error": {
    "message": "Tool timeout",
    "codexErrorInfo": null
  }
}

@owenlin0 owenlin0 marked this pull request as ready for review December 2, 2025 19:35
Copy link
Contributor

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines 875 to 878
/// For all other responses and notifications returning a Turn,
/// the items field will be an empty list.
pub items: Vec<ThreadItem>,
#[serde(flatten)]
pub status: TurnStatus,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Keep Turn.status flat when serializing

The Turn struct now stores status as a normal field while TurnStatus is still internally tagged with status; without the previous #[serde(flatten)], any v2 Turn serialization will nest a second status key (e.g., { "status": { "status": "completed" }, "error": null }) instead of the expected top-level string shown in the commit description. That breaks the v2 API schema for every Turn response/notification, changing status from a string to an object and likely invalidating clients deserializing existing payloads.

Useful? React with 👍 / 👎.

}

#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
#[serde(tag = "status", rename_all = "camelCase")]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think codex' review is valid. you want to remove the tag in this line & below.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

codex the implementer has failed me

@owenlin0 owenlin0 enabled auto-merge (squash) December 2, 2025 20:42
@bolinfest
Copy link
Collaborator

the pattern we want in API v2 where all fields on an object should always be returned

Hmm, is this a good choice for error, though? In a JSON-RPC style response, result and error are generally mutually exclusive:

https://www.jsonrpc.org/specification#response_object

@owenlin0
Copy link
Contributor Author

owenlin0 commented Dec 2, 2025

Hmm, is this a good choice for error, though? In a JSON-RPC style response, result and error are generally mutually exclusive:

@bolinfest This is a fine contract for RPC calls, but this Turn object gets serialized out in notifications (and RPC calls like thread/resume), and the client has to have nasty code like const errorObj = "error" in turn ? turn.error : null; so it's a bit of a different scenario

@owenlin0 owenlin0 merged commit 77c4571 into main Dec 2, 2025
26 checks passed
@owenlin0 owenlin0 deleted the owen/remove_serde_flatten branch December 2, 2025 21:39
@github-actions github-actions bot locked and limited conversation to collaborators Dec 2, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants