-
Notifications
You must be signed in to change notification settings - Fork 6.8k
[app-server] feat: export.rs supports a v2 namespace, initial v2 notifications #6212
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
fd76e2d to
4e55cd9
Compare
4e55cd9 to
30f8525
Compare
💡 Codex Reviewcodex/codex-rs/app-server-protocol/src/export.rs Lines 149 to 206 in 4e55cd9
The bundling loop now reads every generated JSON schema and inserts any embedded definitions directly into the root map when ℹ️ About Codex in GitHubCodex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
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". |
f7a80fa to
d6160c3
Compare
2868a5a to
4506790
Compare
4506790 to
5f793a1
Compare
| pub enum ServerNotification { | ||
| server_notification_definitions! { | ||
| /// NEW NOTIFICATIONS | ||
| #[serde(rename = "thread/started")] |
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.
Chat claims the following is possible to eliminate the duplication:
macro_rules! notif_variant {
($name:ident, $wire:literal, $ty:path) => {
#[serde(rename = $wire)]
#[ts(rename = $wire)]
#[strum(serialize = $wire)]
$name($ty),
};
}
server_notification_definitions! {
/// NEW NOTIFICATIONS
notif_variant!(ThreadStarted, "thread/started", v2::ThreadStartedNotification);
notif_variant!(TurnStarted, "turn/started", v2::TurnStartedNotification);
notif_variant!(TurnCompleted, "turn/completed", v2::TurnCompletedNotification);
}
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.
Maybe if $wire is "", then return only $name($ty)?
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.
Reading more, it seems you need a proc macro so you can do this:
#[multi_rename("thread/started")]
ThreadStarted(v2::ThreadStartedNotification),via something like this:
use proc_macro::TokenStream;
use quote::quote;
use syn::{parse_macro_input, AttributeArgs, ItemEnum, NestedMeta, Lit};
#[proc_macro_attribute]
pub fn notify_variants(attr: TokenStream, item: TokenStream) -> TokenStream {
// no attributes expected on the enum itself — disregard `attr`
let mut input = parse_macro_input!(item as ItemEnum);
for variant in &mut input.variants {
let name = variant.ident.to_string();
// Insert the 3 repeated attributes:
variant.attrs.push(syn::parse_quote!(#[serde(rename = #name)]));
variant.attrs.push(syn::parse_quote!(#[ts(rename = #name)]));
variant.attrs.push(syn::parse_quote!(#[strum(serialize = #name)]));
}
TokenStream::from(quote! { #input })
}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 came up with something cool!
server_notification_definitions! {
/// NEW NOTIFICATIONS
ThreadStarted => "thread/started" (v2::ThreadStartedNotification),
TurnStarted => "turn/started" (v2::TurnStartedNotification),
TurnCompleted => "turn/completed" (v2::TurnCompletedNotification),
ItemStarted => "item/started" (v2::ItemStartedNotification),
ItemCompleted => "item/completed" (v2::ItemCompletedNotification),
AgentMessageDelta => "item/agentMessage/delta" (v2::AgentMessageDeltaNotification),
CommandExecutionOutputDelta => "item/commandExecution/outputDelta" (v2::CommandExecutionOutputDeltaNotification),
McpToolCallProgress => "item/mcpToolCall/progress" (v2::McpToolCallProgressNotification),
AccountUpdated => "account/updated" (v2::AccountUpdatedNotification),
AccountRateLimitsUpdated => "account/rateLimits/updated" (v2::AccountRateLimitsUpdatedNotification),
/// DEPRECATED NOTIFICATIONS below
AuthStatusChange(v1::AuthStatusChangeNotification),
LoginChatGptComplete(v1::LoginChatGptCompleteNotification),
SessionConfigured(v1::SessionConfiguredNotification),
}
was able to do update the original macro to support this. what do you think?
|
|
||
| /// DEPRECATED NOTIFICATIONS below | ||
| /// Authentication status changed | ||
| AuthStatusChange(v1::AuthStatusChangeNotification), |
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.
Is this why we have to do the triple #[] thing on the other variants? Should this be a separate enum?
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 exactly, the same enum has v1 and v2 variants
Typescript and JSON schema exports
While working on Thread/Turn/Items type definitions, I realize we will run into name conflicts between v1 and v2 APIs (e.g.
RateLimitWindowwhich won't be reusable since v1 usesRateLimitWindowfromprotocol/which uses snake_case, but we want to expose camelCase everywhere, so we'll define a V2 version of that struct that serializes as camelCase).To set us up for a clean and isolated v2 API, generate types into a
v2/namespace for both typescript and JSON schema.out_dir/v2/*.ts, and root index.ts now re-exports them viaexport * as v2 from "./v2";.#/definitions/v2/*rather than the root.The location for the original types (v1 and types pulled from
protocol/and other core crates) haven't changed and are still at the root. This is for backwards compatibility: no breaking changes to existing usages of v1 APIs and types.Notifications
While working on export.rs, I: