From ef4647f1d324cff43bb444ef4df6c253faed0d52 Mon Sep 17 00:00:00 2001 From: t Date: Fri, 12 Jun 2026 14:49:51 -0600 Subject: improve errors: retries, surfacing provider errors to the user --- libpanto/src/provider.zig | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'libpanto/src/provider.zig') diff --git a/libpanto/src/provider.zig b/libpanto/src/provider.zig index 8ea74f3..e83012d 100644 --- a/libpanto/src/provider.zig +++ b/libpanto/src/provider.zig @@ -102,6 +102,7 @@ pub fn isRetryableProviderError(err: anyerror) bool { error.ProviderServerError, error.ProviderTransport, error.ProviderStreamMalformed, + error.ProviderOverloaded, => true, else => false, }; @@ -217,6 +218,12 @@ pub const ProviderStream = struct { produce: *const fn (*anyopaque, *EventQueue) anyerror!ProduceStatus, /// Free the response and any owned state. deinit: *const fn (*anyopaque) void, + /// Optional: after a failed `produce`, return the provider's + /// diagnostic message for the failure (e.g. an Anthropic + /// `overloaded_error` message), borrowed for the lifetime of the + /// response. Null when the provider has nothing to add beyond the + /// classified error name. + last_error: ?*const fn (*anyopaque) ?[]const u8 = null, }; /// Pump the response, appending decoded events to `out`. Errors are @@ -228,6 +235,13 @@ pub const ProviderStream = struct { pub fn deinit(self: ProviderStream) void { self.vtable.deinit(self.ptr); } + + /// The provider's diagnostic message for the most recent `produce` + /// failure, if any. Borrowed for the lifetime of the response. + pub fn lastError(self: ProviderStream) ?[]const u8 { + const f = self.vtable.last_error orelse return null; + return f(self.ptr); + } }; /// Open one streaming provider turn against the active config snapshot, -- cgit v1.3