From 02b4c7a35ac0b714bc045d54fb4bb45d1ce4e490 Mon Sep 17 00:00:00 2001 From: t Date: Sat, 13 Jun 2026 23:45:59 -0600 Subject: Add Codex Responses support and session debugging Teach provider config and auth resolution about the Codex Responses dialect, including user-facing `style = "openai_responses"` with `dialect = "codex"`. Serialize and parse Responses traffic with provider-specific reasoning replay, assistant phase metadata, and robust function-call assembly keyed by `output_index` so streamed tool inputs survive proxy quirks and empty terminal payloads. Also persist thinking origins and message metadata across sessions, add the Anthropic interleaved-thinking header switch, write per-session debug logs, and improve the TUI and scripts for inspecting tool output and session costs. --- src/main.zig | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'src/main.zig') diff --git a/src/main.zig b/src/main.zig index 58502ad..8ac5e8b 100644 --- a/src/main.zig +++ b/src/main.zig @@ -16,6 +16,12 @@ const glob = @import("glob.zig"); const system_prompt = @import("system_prompt.zig"); const command = @import("command.zig"); const command_compaction = @import("compaction.zig"); +const debug_log = @import("debug_log.zig"); + +/// Route the process-wide log stream. In Debug builds this redirects every +/// `std.log` call to a per-session file (keeping the TUI clean); other builds +/// keep the stderr default. See `debug_log.zig`. +pub const std_options: std.Options = .{ .logFn = debug_log.logFn }; // TUI foundation layer (Phase 1, sub-phase 1). Not yet wired into the REPL; // referenced here so `zig build test` type-checks and exercises them. @@ -60,6 +66,7 @@ test { _ = system_prompt; _ = command; _ = command_compaction; + _ = debug_log; _ = tui_terminal; _ = tui_key; _ = tui_input; @@ -255,7 +262,9 @@ pub fn main(init: std.process.Init) !void { // per-cwd `session_dir` (the CLI owns the cwd→dir grouping; the store // is cwd-agnostic). Must outlive the agent, which appends through a // `Session` handle minted/resolved below. - const session_metadata = try std.fmt.allocPrint(alloc, "{{\"cwd\":{s}}}", .{try std.json.Stringify.valueAlloc(alloc, cwd, .{})}); + const cwd_json = try std.json.Stringify.valueAlloc(alloc, cwd, .{}); + defer alloc.free(cwd_json); + const session_metadata = try std.fmt.allocPrint(alloc, "{{\"cwd\":{s}}}", .{cwd_json}); defer alloc.free(session_metadata); var session_store_impl = try panto.FileSystemJSONLStore.initWithMetadata(alloc, io, session_dir, session_metadata); defer session_store_impl.deinit(); @@ -277,6 +286,12 @@ pub fn main(init: std.process.Init) !void { // `session.info` is adopted by the agent below (`Agent.init` can't fail) // and freed in the agent's `deinit`; no separate cleanup here. + // Arm the per-session debug log now that we know the session id. In Debug + // builds this opens `$PANTO_HOME/debug/.log` and redirects all + // `std.log` output there; no-op in release. Best-effort — failures leave + // logging disabled rather than aborting startup. + debug_log.init(alloc, io, init.environ_map, session.info.id); + const is_resume = cli_flags.resume_kind != .none and session.info.message_count > 0; // On resume, reconstruct the conversation from the store. (The -- cgit v1.3