-
Notifications
You must be signed in to change notification settings - Fork 6.8k
[app-server] feat: v2 Thread APIs #6214
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
77d059e to
48d30c8
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codex Review
codex/codex-rs/app-server-protocol/src/protocol/common.rs
Lines 414 to 424 in 943a97c
| pub enum ServerNotification { | |
| /// NEW NOTIFICATIONS | |
| #[serde(rename = "account/updated")] | |
| #[ts(rename = "account/updated")] | |
| #[strum(serialize = "account/updated")] | |
| AccountUpdated(v2::AccountUpdatedNotification), | |
| #[serde(rename = "account/rateLimits/updated")] | |
| #[ts(rename = "account/rateLimits/updated")] | |
| #[strum(serialize = "account/rateLimits/updated")] | |
| AccountRateLimitsUpdated(RateLimitSnapshot), |
The notification enum still declares AccountRateLimitsUpdated(RateLimitSnapshot) yet the commit introduces a new AccountRateLimitsUpdatedNotification type (and tests expect a nested rateLimits object). The send-site continues to pass a raw RateLimitSnapshot, so the emitted JSON lacks the new wrapper and cannot match the updated schema/serialization test. Either the enum variant needs to carry AccountRateLimitsUpdatedNotification or the send logic must wrap the snapshot before serialization; as written the API and implementation are inconsistent and will not build alongside the new test.
ℹ️ 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".
| #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default, JsonSchema, TS)] | ||
| #[serde(rename_all = "camelCase")] | ||
| #[ts(export_to = "v2/")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider defining a custom attribute macro (in a proc-macro crate) so you can make this one line instead of three.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah making sure everything has these annotations is a bit tedious, might do as a followup
| #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] | ||
| #[serde(rename_all = "camelCase")] | ||
| #[ts(export_to = "v2/")] | ||
| pub struct Thread { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we expand this to evolve to contain the history and other metadata?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah will follow up with some additional fields that are useful here. We're pretty inconsistent with the old API.
I'm thinking model_provider, rollout_path, preview might be useful. And created_at and updated_at timestamp would be quite nice I think. https://linear.app/openai/issue/CLI-1377/expose-useful-fields-on-thread
| // Auto-attach a conversation listener when starting a thread. | ||
| // Use the same behavior as the v1 API with experimental_raw_events=false. | ||
| if let Err(err) = self | ||
| .attach_conversation_listener(new_conv.conversation_id, false) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We auto-add the listener now, but when do we remove it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i asked codex about the VSCE codebase and it looks like it never calls RemoveConversationListener 😅
however, I think it'd be worth doing on thread/archive at least (will follow up)
79b6356 to
32716d7
Compare
32716d7 to
ee62e19
Compare
ee62e19 to
3445d53
Compare
| pub struct ListModelsResponse { | ||
| pub items: Vec<Model>, | ||
| pub struct ModelListResponse { | ||
| pub data: Vec<Model>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we name this models instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the convention that the OpenAI APIs have where list APIs have a consistent top-level shape:
{
data: <list of results>,
next_cursor: string | null,
}
it's nice since no matter which List API you call, the results are always in data
| Some(s) => serde_json::from_str::<RolloutCursor>(&format!("\"{s}\"")).ok(), | ||
| None => None, | ||
| }; | ||
| let cursor_obj: Option<RolloutCursor> = cursor.as_ref().and_then(|s| parse_cursor(s)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm surprised clippy didn't tell you to do:
| let cursor_obj: Option<RolloutCursor> = cursor.as_ref().and_then(|s| parse_cursor(s)); | |
| let cursor_obj: Option<RolloutCursor> = cursor.as_ref().and_then(parse_cursor); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
interesting, seems like that should work but getting this error:
type mismatch in function arguments
expected function signature `fn(&std::string::String) -> _`
found function signature `fn(&str) -> _`rustc[Click for full compiler diagnostic](rust-analyzer-diagnostics-view:/diagnostic%20message%20[0]?0#file:///Users/owen/repos/codex/codex-rs/app-server/src/codex_message_processor.rs)
047b89b to
3f5b1c8
Compare
3f5b1c8 to
5e45b6c
Compare
Implements:
along with their integration tests. These are relatively light wrappers around the existing core logic, and changes to core logic are minimal.
However, an improvement made for developer ergonomics:
thread/startandthread/resumeautomatically attaches a conversation listener internally, so clients don't have to make a separateAddConversationListenercall like they do today.For consistency, also updated
model/listandfeedback/upload(naming conventions, list API params).