Skip to content

Commit 208310d

Browse files
delexwclaude
andauthored
test(compat): add v0.133.0 regression tests for TurnContextItem field trimming (#88)
Codex v0.133.0 (PR #22709) trimmed unused fields from TurnContextItem session structure. The parser already handled this correctly (all fields extracted via optional .get() chains), and turn.rs already had tests for both pre- and post-v0.133.0 payloads. This commit adds the missing version-specific regression tests to entry.rs and session.rs to document the v0.133.0 change and guard against future regressions: - entry.rs: v0133_turn_context_trimmed_payload_parses_as_turn_context_entry verifies a minimal v0.133.0 turn_context (model only) parses without panic - entry.rs: v0133_all_standard_entry_types_parse_correctly regression guard for all four standard JSONL entry types under v0.133.0 - session.rs: v0133_turn_context_trimmed_fields_session_parses_correctly full session parse with trimmed turn_context verifies model is extracted and missing cwd/effort fields are silently absent Fixes #84 Co-authored-by: Claude <noreply@anthropic.com>
1 parent 0686e09 commit 208310d

2 files changed

Lines changed: 77 additions & 0 deletions

File tree

src-tauri/src/parser/entry.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -607,4 +607,47 @@ mod tests {
607607
assert_eq!(meta.payload["cli_version"], "0.134.0");
608608
assert_eq!(meta.payload["profile"], "default");
609609
}
610+
611+
// Codex v0.133.0 (PR #22709): TurnContextItem fields trimmed.
612+
// turn_context payloads now carry only the fields still used internally; previously
613+
// populated fields like cwd and effort may be absent. The loosely-typed RawEntry
614+
// model must parse both old (extra fields) and new (trimmed) payloads without error.
615+
616+
#[test]
617+
fn v0133_turn_context_trimmed_payload_parses_as_turn_context_entry() {
618+
// v0.133.0 turn_context with minimal payload — only model is present.
619+
let line = r#"{"timestamp":"2026-05-21T10:00:02Z","type":"turn_context","payload":{"model":"gpt-5"}}"#;
620+
let e = RawEntry::parse(line).expect("turn_context with minimal payload must parse");
621+
assert_eq!(e.entry_type, "turn_context");
622+
assert_eq!(e.payload["model"], "gpt-5");
623+
// cwd and effort are absent — must not panic
624+
assert!(e.payload.get("cwd").is_none());
625+
assert!(e.payload.get("effort").is_none());
626+
}
627+
628+
#[test]
629+
fn v0133_all_standard_entry_types_parse_correctly() {
630+
// Regression guard: all standard JSONL entry types must parse under v0.133.0.
631+
// turn_context payload is trimmed — only model is present (PR #22709).
632+
let lines = [
633+
r#"{"timestamp":"2026-05-21T10:00:00Z","type":"session_meta","payload":{"id":"v0133-session","timestamp":"2026-05-21T10:00:00Z","cwd":"/tmp","cli_version":"0.133.0","model_provider":"openai"}}"#,
634+
r#"{"timestamp":"2026-05-21T10:00:01Z","type":"event_msg","payload":{"type":"task_started","turn_id":"turn-1"}}"#,
635+
r#"{"timestamp":"2026-05-21T10:00:02Z","type":"response_item","payload":{"type":"message","role":"assistant","content":"Hello"}}"#,
636+
r#"{"timestamp":"2026-05-21T10:00:03Z","type":"turn_context","payload":{"model":"gpt-5"}}"#,
637+
r#"{"timestamp":"2026-05-21T10:00:04Z","type":"event_msg","payload":{"type":"task_complete","turn_id":"turn-1","completed_at":1748167204.0}}"#,
638+
];
639+
let expected_types = [
640+
"session_meta",
641+
"event_msg",
642+
"response_item",
643+
"turn_context",
644+
"event_msg",
645+
];
646+
for (line, expected) in lines.iter().zip(expected_types.iter()) {
647+
let entry = RawEntry::parse(line).expect("parse failed");
648+
assert_eq!(entry.entry_type, *expected, "wrong type for: {line}");
649+
}
650+
let meta = RawEntry::parse(lines[0]).unwrap();
651+
assert_eq!(meta.payload["cli_version"], "0.133.0");
652+
}
610653
}

src-tauri/src/parser/session.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -911,4 +911,38 @@ mod tests {
911911
assert_eq!(session.turns.len(), 1);
912912
assert!(!session.is_ongoing);
913913
}
914+
915+
// Codex v0.133.0 (PR #22709): TurnContextItem fields trimmed.
916+
// turn_context payloads now carry only the model field; cwd and effort are no longer
917+
// emitted. Sessions from v0.133.0+ must parse correctly with the reduced payload.
918+
919+
#[test]
920+
fn v0133_turn_context_trimmed_fields_session_parses_correctly() {
921+
// v0.133.0 session where turn_context has only model — cwd and effort are absent.
922+
// Verifies the parser extracts model from the trimmed payload and does not panic
923+
// on the missing fields.
924+
let tmp = tempdir().unwrap();
925+
let path = tmp.path().join("rollout-2026-05-21T10-00-00-v0133.jsonl");
926+
std::fs::write(
927+
&path,
928+
[
929+
r#"{"timestamp":"2026-05-21T10:00:00Z","type":"session_meta","payload":{"id":"v0133-turn-ctx","timestamp":"2026-05-21T10:00:00Z","cwd":"/workspace","cli_version":"0.133.0","model_provider":"openai"}}"#,
930+
r#"{"timestamp":"2026-05-21T10:00:01Z","type":"event_msg","payload":{"type":"task_started","turn_id":"turn-1"}}"#,
931+
r#"{"timestamp":"2026-05-21T10:00:02Z","type":"response_item","payload":{"type":"message","role":"assistant","content":"Done"}}"#,
932+
r#"{"timestamp":"2026-05-21T10:00:03Z","type":"turn_context","payload":{"model":"gpt-5"}}"#,
933+
r#"{"timestamp":"2026-05-21T10:00:04Z","type":"event_msg","payload":{"type":"task_complete","turn_id":"turn-1","completed_at":1748167204.0}}"#,
934+
]
935+
.join("\n"),
936+
)
937+
.unwrap();
938+
939+
let session = parse_session(&path).unwrap();
940+
assert_eq!(session.id, "v0133-turn-ctx");
941+
assert_eq!(session.cli_version.as_deref(), Some("0.133.0"));
942+
assert_eq!(session.turns.len(), 1);
943+
assert_eq!(session.turns[0].model.as_deref(), Some("gpt-5"));
944+
// cwd and effort absent in turn_context — must not panic
945+
assert!(session.turns[0].reasoning_effort.is_none());
946+
assert!(!session.is_ongoing);
947+
}
914948
}

0 commit comments

Comments
 (0)