diff options
| author | t <t@tjp.lol> | 2026-06-13 23:45:59 -0600 |
|---|---|---|
| committer | t <t@tjp.lol> | 2026-06-15 15:08:32 -0600 |
| commit | 02b4c7a35ac0b714bc045d54fb4bb45d1ce4e490 (patch) | |
| tree | 134196a82dd6fdd55b735be4c0cf38428c85038d /libpanto/src/provider_openai_chat.zig | |
| parent | 71643a5d69ffc40882c9fcde3cc8a3bcf02d7396 (diff) | |
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.
Diffstat (limited to 'libpanto/src/provider_openai_chat.zig')
| -rw-r--r-- | libpanto/src/provider_openai_chat.zig | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/libpanto/src/provider_openai_chat.zig b/libpanto/src/provider_openai_chat.zig index b236a60..3f01e7f 100644 --- a/libpanto/src/provider_openai_chat.zig +++ b/libpanto/src/provider_openai_chat.zig @@ -94,6 +94,7 @@ pub const OpenAIChatRequest = struct { // Build the request body. const body = try json_mod.serializeRequest(self.allocator, self.config, conv, tools); defer self.allocator.free(body); + std.log.debug("openai_chat => {s}", .{body}); // Auth header const auth_value = try std.fmt.allocPrint( @@ -165,11 +166,19 @@ pub const OpenAIChatRequest = struct { if (err_buf.items.len > 16 * 1024) break; } const status: u16 = @intFromEnum(rr.response.head.status); - std.log.err("openai_chat HTTP {d}: {s}", .{ status, err_buf.items }); // Classify the status into a retryable/terminal provider error. // HTTP 400 with a context marker becomes `ContextOverflow` so the // caller can compact and retry rather than hard-fail. const classified = provider_mod.classifyHttpStatus(status, err_buf.items); + // 401/403 is routinely recovered by the turn-runner's forced token + // refresh + reopen; demote it to `.debug` (still in the debug log) + // so a transparent refresh doesn't surface a scary error line. The + // retry layer raises a hard error only if recovery ultimately fails. + if (classified == error.ProviderAuthFailed) { + std.log.debug("openai_chat HTTP {d} (recoverable auth): {s}", .{ status, err_buf.items }); + } else { + std.log.err("openai_chat HTTP {d}: {s}", .{ status, err_buf.items }); + } if (self.diag) |d| { d.status_code = status; d.retry_after_ms = retry_after_ms; @@ -1032,7 +1041,6 @@ test "inbound wire tool name is decoded to dotted form (even split across __)" { try testing.expectEqualStrings("std.read", tu.name); } - test "parallel tool_calls emit one complete start/delta/complete cycle per block" { // Regression test: previously, the OpenAI provider deferred ALL // tool_use onBlockComplete callbacks to finalize, so a four-tool |
