summaryrefslogtreecommitdiff
path: root/libpanto/src/provider_openai_chat.zig
diff options
context:
space:
mode:
Diffstat (limited to 'libpanto/src/provider_openai_chat.zig')
-rw-r--r--libpanto/src/provider_openai_chat.zig12
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