summaryrefslogtreecommitdiff
path: root/libpanto/src/provider_anthropic_messages.zig
diff options
context:
space:
mode:
authorT <t@tjp.lol>2026-05-27 06:25:52 -0600
committerT <t@tjp.lol>2026-05-27 07:02:47 -0600
commiteddebe4e8131b7d2112b067fed07e7493d8b1984 (patch)
tree21cc58822aa4e99d55d082444c2347c15101bfe1 /libpanto/src/provider_anthropic_messages.zig
parent1f0915edbe0213e8bc134922f10933468d35a172 (diff)
Stream OpenAI tool_use as discrete blocks; drop BlockMeta
Close each tool_use on next-index delta (and at finalize) so receivers see one start/delta/complete trio per tool, matching Anthropic. Log+drop fragments for already-closed indices. Remove BlockMeta from the Receiver interface: tool id/name can't be reliably known at onBlockStart under OpenAI's streaming model. Receivers get identity from the assembled ContentBlock at onBlockComplete. CLI renders 'tool: {args} : (name)' accordingly.
Diffstat (limited to 'libpanto/src/provider_anthropic_messages.zig')
-rw-r--r--libpanto/src/provider_anthropic_messages.zig21
1 files changed, 8 insertions, 13 deletions
diff --git a/libpanto/src/provider_anthropic_messages.zig b/libpanto/src/provider_anthropic_messages.zig
index 7511ce8..03c1d90 100644
--- a/libpanto/src/provider_anthropic_messages.zig
+++ b/libpanto/src/provider_anthropic_messages.zig
@@ -257,7 +257,8 @@ const StreamState = struct {
receiver: *provider_mod.Receiver,
wire_index: usize,
kind: BlockKind,
- tool_meta: ?provider_mod.BlockMeta,
+ tool_id: ?[]const u8,
+ tool_name: ?[]const u8,
) !void {
// Defensive: if a prior block didn't get an explicit stop, drop it.
if (self.active != null) {
@@ -267,12 +268,11 @@ const StreamState = struct {
.wire_index = wire_index,
.kind = kind,
};
- // For tool_use blocks, capture the identity fields from the meta.
+ // For tool_use blocks, capture the identity fields. Anthropic
+ // delivers both whole on content_block_start.
if (kind == .tool_use) {
- if (tool_meta) |m| {
- if (m.tool_id) |id| ab.tool_id = try self.allocator.dupe(u8, id);
- if (m.tool_name) |n| ab.tool_name = try self.allocator.dupe(u8, n);
- }
+ if (tool_id) |id| ab.tool_id = try self.allocator.dupe(u8, id);
+ if (tool_name) |n| ab.tool_name = try self.allocator.dupe(u8, n);
}
self.active = ab;
const block_type: ?provider_mod.ContentBlockType = switch (kind) {
@@ -282,7 +282,7 @@ const StreamState = struct {
.unsupported => null,
};
if (block_type) |bt| {
- try receiver.onBlockStart(bt, wire_index, tool_meta);
+ try receiver.onBlockStart(bt, wire_index);
}
}
@@ -418,11 +418,7 @@ fn handleEvent(
.tool_use => .tool_use,
.unknown => .unsupported,
};
- const meta: ?provider_mod.BlockMeta = if (s.kind == .tool_use)
- .{ .tool_id = s.tool_id, .tool_name = s.tool_name }
- else
- null;
- try state.openBlock(receiver, s.index, kind, meta);
+ try state.openBlock(receiver, s.index, kind, s.tool_id, s.tool_name);
},
.content_block_delta => |d| {
if (d.text_delta) |t| try state.appendTextDelta(receiver, t);
@@ -524,7 +520,6 @@ const RecordingReceiver = struct {
ptr: *anyopaque,
bt: provider_mod.ContentBlockType,
idx: usize,
- _: ?provider_mod.BlockMeta,
) anyerror!void {
const self: *RecordingReceiver = @ptrCast(@alignCast(ptr));
try self.events.append(self.allocator, .{ .block_start = .{ .kind = bt, .index = idx } });