diff options
| author | t <t@tjp.lol> | 2026-06-02 15:00:44 -0600 |
|---|---|---|
| committer | t <t@tjp.lol> | 2026-06-02 16:37:32 -0600 |
| commit | 8b88b886346460b1ab29edb03ad85bc3bb565a45 (patch) | |
| tree | 13b9ab56061a722641389b5fc8ac1113d09b66e5 /libpanto/src/provider.zig | |
| parent | 7268c0b8e8bcf4b325581fabe7476a394f167738 (diff) | |
compaction
Diffstat (limited to 'libpanto/src/provider.zig')
| -rw-r--r-- | libpanto/src/provider.zig | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/libpanto/src/provider.zig b/libpanto/src/provider.zig index 1a8ee4e..6ccbefe 100644 --- a/libpanto/src/provider.zig +++ b/libpanto/src/provider.zig @@ -14,6 +14,28 @@ pub const ContentBlockType = enum { ToolResult, }; +/// Heuristic detector for provider context-overflow rejections, applied to +/// an HTTP 400 error response body. Both OpenAI-compatible and Anthropic +/// APIs reject oversized requests on the input side with HTTP 400 and a +/// recognizable message; matching it lets the agent compact and retry +/// instead of surfacing a hard error. +/// +/// Markers (case-sensitive substrings, as the wire emits them): +/// - OpenAI: `context_length_exceeded`, `maximum context length` +/// - Anthropic: `prompt is too long` +pub fn isContextOverflowBody(body: []const u8) bool { + const markers = [_][]const u8{ + "context_length_exceeded", + "maximum context length", + "prompt is too long", + "context window", + }; + for (markers) |m| { + if (std.mem.indexOf(u8, body, m) != null) return true; + } + return false; +} + /// Vtable for receiving streaming events from a Provider. /// /// The lifecycle callbacks (`onMessageStart` ... `onMessageComplete`) return @@ -143,3 +165,12 @@ pub const StreamFn = *const fn ( conv: *conversation.Conversation, receiver: *Receiver, ) anyerror!void; + +test "isContextOverflowBody - matches known markers, rejects others" { + const t2 = std.testing; + try t2.expect(isContextOverflowBody("{\"error\":{\"code\":\"context_length_exceeded\"}}")); + try t2.expect(isContextOverflowBody("This model's maximum context length is 8192 tokens")); + try t2.expect(isContextOverflowBody("prompt is too long: 250000 tokens > 200000 maximum")); + try t2.expect(!isContextOverflowBody("{\"error\":{\"code\":\"invalid_api_key\"}}")); + try t2.expect(!isContextOverflowBody("rate limit exceeded")); +} |
