feat(core,tui): log ChatGPT claims and polish run cells

This commit is contained in:
James Peter
2025-09-16 17:16:13 +10:00
parent 85159d1f81
commit 8efe47236b
3 changed files with 89 additions and 15 deletions
+7 -1
View File
@@ -1,7 +1,9 @@
use base64::Engine;
use serde::Deserialize;
use serde::Serialize;
use serde_json::Value;
use thiserror::Error;
use tracing::Level;
#[derive(Deserialize, Serialize, Clone, Debug, PartialEq, Default)]
@@ -111,7 +113,11 @@ pub fn parse_id_token(id_token: &str) -> Result<IdTokenInfo, IdTokenInfoError> {
};
let payload_bytes = base64::engine::general_purpose::URL_SAFE_NO_PAD.decode(payload_b64)?;
let claims: IdClaims = serde_json::from_slice(&payload_bytes)?;
let raw_claims: Value = serde_json::from_slice(&payload_bytes)?;
if tracing::enabled!(Level::INFO) {
tracing::info!(id_token_claims = %raw_claims, "decoded ChatGPT id_token claims");
}
let claims: IdClaims = serde_json::from_value(raw_claims)?;
Ok(IdTokenInfo {
email: claims.email,
+67 -14
View File
@@ -742,18 +742,14 @@ impl HistoryCell for ExploreAggregationCell {
if self.entries.is_empty() {
return vec![Line::styled(
"Exploring",
Style::default()
.fg(crate::colors::text())
.add_modifier(Modifier::BOLD),
Style::default().fg(crate::colors::text()),
)];
}
let mut lines: Vec<Line<'static>> = Vec::new();
lines.push(Line::styled(
"Exploring",
Style::default()
.fg(crate::colors::text())
.add_modifier(Modifier::BOLD),
Style::default().fg(crate::colors::text()),
));
for (idx, entry) in self.entries.iter().enumerate() {
@@ -800,9 +796,7 @@ impl HistoryCell for ExploreAggregationCell {
.unwrap_or(0)
}
fn gutter_symbol(&self) -> Option<&'static str> {
Some("☰")
}
fn gutter_symbol(&self) -> Option<&'static str> { None }
}
// ==================== PlainHistoryCell ====================
@@ -2455,6 +2449,17 @@ fn exec_render_parts_generic(
}
if output.is_some() {
if let Some(first) = highlighted_cmd.first_mut() {
first.spans.insert(
0,
Span::styled(
"Ran ",
Style::default()
.fg(crate::colors::text_bright())
.add_modifier(Modifier::BOLD),
),
);
}
for line in highlighted_cmd.iter_mut() {
for span in line.spans.iter_mut() {
span.style = span.style.fg(crate::colors::text_bright());
@@ -2579,6 +2584,7 @@ fn exec_render_parts_parsed(
let show_stdout = matches!(action, ExecAction::Run);
let out = output_lines(output, !show_stdout, false);
let mut any_content_emitted = false;
let mut added_inline_ran = false;
// Determine allowed label(s) for this cell's primary action
let expected_label: Option<&'static str> = match action {
ExecAction::Read => Some("Read"),
@@ -2834,14 +2840,42 @@ fn exec_render_parts_parsed(
let mut hl =
crate::syntax_highlight::highlight_code_block(line_text, Some("bash"));
if let Some(mut first) = hl.pop() {
// `highlight_code_block` returns exactly one line for single-line input.
// Append the highlighted spans inline after the prefix.
spans.extend(first.spans.drain(..));
if output.is_some() && !added_inline_ran {
spans.push(Span::styled(
"Ran ",
Style::default()
.fg(crate::colors::text_bright())
.add_modifier(Modifier::BOLD),
));
added_inline_ran = true;
}
if output.is_some() {
for s in first.spans.drain(..) {
spans.push(Span::styled(
s.content.to_string(),
Style::default().fg(crate::colors::text_bright()),
));
}
} else {
spans.extend(first.spans.drain(..));
}
} else {
// Fallback: plain text if highlighting yields nothing.
if output.is_some() && !added_inline_ran {
spans.push(Span::styled(
"Ran ",
Style::default()
.fg(crate::colors::text_bright())
.add_modifier(Modifier::BOLD),
));
added_inline_ran = true;
}
spans.push(Span::styled(
line_text.to_string(),
Style::default().fg(crate::colors::text()),
Style::default().fg(if output.is_some() {
crate::colors::text_bright()
} else {
crate::colors::text()
}),
));
}
}
@@ -5469,6 +5503,7 @@ fn new_parsed_command(
// We'll emit only content lines here; the header above already communicates the action.
// Use a single leading "└ " for the very first content line, then indent subsequent ones.
let mut any_content_emitted = false;
let mut added_inline_ran = false;
// Restrict displayed entries to the primary action for this cell.
// For the generic "run" header, allow Run/Test/Lint/Format entries.
@@ -5734,6 +5769,15 @@ fn new_parsed_command(
let mut hl =
crate::syntax_highlight::highlight_code_block(line_text, Some("bash"));
if let Some(mut first) = hl.pop() {
if output.is_some() && !added_inline_ran {
spans.push(Span::styled(
"Ran ",
Style::default()
.fg(crate::colors::text_bright())
.add_modifier(Modifier::BOLD),
));
added_inline_ran = true;
}
if output.is_some() {
for s in first.spans.drain(..) {
spans.push(Span::styled(
@@ -5745,6 +5789,15 @@ fn new_parsed_command(
spans.extend(first.spans.drain(..));
}
} else {
if output.is_some() && !added_inline_ran {
spans.push(Span::styled(
"Ran ",
Style::default()
.fg(crate::colors::text_bright())
.add_modifier(Modifier::BOLD),
));
added_inline_ran = true;
}
spans.push(Span::styled(
line_text.to_string(),
Style::default().fg(if output.is_some() {
+15
View File
@@ -18,6 +18,9 @@ use ratatui::widgets::Wrap;
use codex_login::AuthMode;
use codex_core::config::GPT_5_CODEX_MEDIUM_MODEL;
use codex_core::model_family::{derive_default_model_family, find_family_for_model};
use crate::LoginStatus;
use crate::app::ChatWidgetArgs;
use crate::app_event::AppEvent;
@@ -382,6 +385,18 @@ impl AuthModeWidget {
self.login_status = LoginStatus::AuthMode(AuthMode::ChatGPT);
if let Ok(mut args) = self.chat_widget_args.lock() {
args.config.using_chatgpt_auth = true;
if args
.config
.model
.eq_ignore_ascii_case("gpt-5")
{
let new_model = GPT_5_CODEX_MEDIUM_MODEL.to_string();
args.config.model = new_model.clone();
let family = find_family_for_model(&new_model)
.unwrap_or_else(|| derive_default_model_family(&new_model));
args.config.model_family = family;
}
}
}
}