summaryrefslogtreecommitdiff
path: root/libpanto/src/anthropic_messages_json.zig
diff options
context:
space:
mode:
authort <t@tjp.lol>2026-06-02 10:50:05 -0600
committert <t@tjp.lol>2026-06-02 11:11:29 -0600
commit16ea45b6854232541fb45f7d2e5b767118cccf43 (patch)
tree1bf37d766e4b9de2b646c1475497ae7e9d5699c7 /libpanto/src/anthropic_messages_json.zig
parent9c64a7d4462a11674e2dea481b037b5f5d9c62fc (diff)
tool call resiliency
Diffstat (limited to 'libpanto/src/anthropic_messages_json.zig')
-rw-r--r--libpanto/src/anthropic_messages_json.zig22
1 files changed, 21 insertions, 1 deletions
diff --git a/libpanto/src/anthropic_messages_json.zig b/libpanto/src/anthropic_messages_json.zig
index f8bfc2e..d382de8 100644
--- a/libpanto/src/anthropic_messages_json.zig
+++ b/libpanto/src/anthropic_messages_json.zig
@@ -111,6 +111,26 @@ fn writeRawJson(s: *std.json.Stringify, raw: []const u8) !void {
try s.write(parsed.value);
}
+fn writeToolUseInput(s: *std.json.Stringify, raw: []const u8) !void {
+ var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
+ defer arena.deinit();
+ const parsed = std.json.parseFromSlice(std.json.Value, arena.allocator(), raw, .{}) catch {
+ try s.beginObject();
+ try s.objectField("_invalid_input");
+ try s.write(raw);
+ try s.endObject();
+ return;
+ };
+ if (parsed.value != .object) {
+ try s.beginObject();
+ try s.objectField("_invalid_input");
+ try s.write(raw);
+ try s.endObject();
+ return;
+ }
+ try s.write(parsed.value);
+}
+
/// Build the top-level Anthropic `system` string. Applies the shared
/// append/replace derivation (see `conversation.effectiveSystemBlocks`),
/// strips trailing newlines from each surviving block, and joins them with
@@ -200,7 +220,7 @@ fn writeBlock(s: *std.json.Stringify, block: conversation.ContentBlock) !void {
try s.beginObject();
try s.endObject();
} else {
- try writeRawJson(s, input_bytes);
+ try writeToolUseInput(s, input_bytes);
}
try s.endObject();
},