-
Notifications
You must be signed in to change notification settings - Fork 5.9k
codex-rs: make tool calls prettier #1211
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
aef101c
to
c824ac4
Compare
tui-markdown = "0.3.3" | ||
tui-textarea = "0.7.0" | ||
uuid = "1" | ||
unicode-segmentation = "1.12.0" |
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.
nit: alpha sort?
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.
Done.
("approval", format!("{:?}", config.approval_policy)), | ||
("sandbox", format!("{:?}", config.sandbox_policy)), | ||
]; | ||
if config.model_provider.wire_api == WireApi::Responses |
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.
bad rebase maybe? did you mean to remove this?
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.
Oops, sorry for not catching this. Yes, I messed this up when moving from this repo to my own fork 🙇
codex-rs/tui/src/history_cell.rs
Outdated
// try to parse the text as json | ||
let json = serde_json::from_str::<serde_json::Value>(text); | ||
if let Ok(json) = json { | ||
let json_pretty = serde_json::to_string_pretty(&json).unwrap_or_else(|_| json.to_string()); |
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.
Hmm, I guess PrettyFormatter
isn't configurable to support what you're trying to do here?
https://docs.rs/serde_json/1.0.140/serde_json/ser/struct.PrettyFormatter.html
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 don't believe so, it looks like only indentation is configurable in PrettyFormatter
– no matter what it will always split JSON onto multiple newlines, i.e.
{
"foo": "bar"
}
Instead of {"foo": "bar"}
.
I think there's a tradeoff here between readability and compactness. serde_json
pretty-printing looks good but it leaves a lot of horizontal space unused; not much info can be shown in 5 lines if every field and bracket gets its own line.
codex-rs/tui/src/history_cell.rs
Outdated
pub(crate) fn new_completed_mcp_tool_call( | ||
fq_tool_name: String, | ||
invocation: String, | ||
terminal_width: u16, |
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 num_cols
is a more appropriate name? Because the terminal is technically a bit wider because of borders and whatnot, right?
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.
Yes, good point
codex-rs/tui/src/history_cell.rs
Outdated
} | ||
|
||
/// Truncate a tool result to fit within the given width. If the text is valid JSON, we format it in a compact way before truncating | ||
fn format_and_truncate_tool_result(text: &str, width: u16) -> String { |
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.
Could you please add a couple of unit tests for these functions? Or maybe move them into a helper file (truncate.rs
?) since this file is getting a bit long...
|
||
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)] | ||
#[serde(untagged)] | ||
#[allow(clippy::large_enum_variant)] |
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.
After enabling the preserve_order
feature on serde_json
, this Clippy lint started going off:
warning: large size difference between variants
--> mcp-types/src/lib.rs:1147:1
|
1147 | / pub enum ServerResult {
1148 | | Result(Result),
| | -------------- the second-largest variant contains at least 72 bytes
1149 | | InitializeResult(InitializeResult),
| | ---------------------------------- the largest variant contains at least 320 bytes
1150 | | ListResourcesResult(ListResourcesResult),
... |
1157 | | CompleteResult(CompleteResult),
1158 | | }
| |_^ the entire enum is at least 320 bytes
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#large_enum_variant
= note: `#[warn(clippy::large_enum_variant)]` on by default
help: consider boxing the large fields to reduce the total size of the enum
|
1149 - InitializeResult(InitializeResult),
1149 + InitializeResult(Box<InitializeResult>),
|
I don't think this is especially performance-sensitive code, boxing InitializeResults feels like a premature optimization to me.
530905b
to
6f67caf
Compare
@bolinfest Thank you for the detailed review and sorry for missing a few obvious things! I've addressed your comments, including moving the truncation+formatting logic out to With tests in place I made some improvements to the JSON formatting (preserving original order of fields, more opinionated compact formatting). It's a little complex but I think with the comments+tests in place it's worthwhile. |
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.
This looks great and thanks for the thorough tests! I'll merge once CI is green.
'\n' | '\r' if !in_string => { | ||
// Skip newlines when not in a string | ||
} | ||
' ' | '\t' if !in_string => { |
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.
to_string_pretty()
should never include a literal \r
or \n
, should it?
This PR overhauls how active tool calls and completed tool calls are displayed:
CallToolResult
was serialized to JSON and pretty-printed. Now, we extract each individualCallToolResultContent
and print thoseCallToolResult
struct to users, without formatting the actual tool call results nicelyBefore:
After:
Future Work
CallToolResultContent
first_visible_line
scrolling works