summaryrefslogtreecommitdiff
path: root/libpanto/src/provider.zig
diff options
context:
space:
mode:
Diffstat (limited to 'libpanto/src/provider.zig')
-rw-r--r--libpanto/src/provider.zig19
1 files changed, 10 insertions, 9 deletions
diff --git a/libpanto/src/provider.zig b/libpanto/src/provider.zig
index 177fc2f..fd170f0 100644
--- a/libpanto/src/provider.zig
+++ b/libpanto/src/provider.zig
@@ -12,12 +12,6 @@ pub const ContentBlockType = enum {
ToolResult,
};
-pub const BlockMeta = struct {
- /// Only populated for ToolUse blocks. Null for Text/Thinking.
- tool_id: ?[]const u8 = null,
- tool_name: ?[]const u8 = null,
-};
-
/// Vtable for receiving streaming events from a Provider.
///
/// The lifecycle callbacks (`onMessageStart` ... `onMessageComplete`) return
@@ -25,6 +19,13 @@ pub const BlockMeta = struct {
/// stops streaming, calls `onError(err)`, and propagates `err` out of
/// `streamStep`. No partial assistant message is appended to the conversation.
///
+/// Identity fields (tool id/name for ToolUse blocks) are intentionally *not*
+/// surfaced at `onBlockStart`. They cannot be reliably known at start time
+/// across all wire protocols — OpenAI streaming may deliver `id` and `name`
+/// in fragments across multiple deltas — so any "meta" we passed at start
+/// would be a phantom guarantee. Receivers that need identity get it from
+/// the fully-assembled `ContentBlock` delivered to `onBlockComplete`.
+///
/// `onError` is the receiver's cleanup hook. It fires exactly once per failed
/// turn, whether the error originated in the receiver itself (a write failure)
/// or in the Provider (HTTP/parse/stream failure). It is the last callback the
@@ -32,7 +33,7 @@ pub const BlockMeta = struct {
/// must swallow secondary failures during cleanup.
pub const ReceiverVTable = struct {
onMessageStart: *const fn (*anyopaque, conversation.MessageRole) anyerror!void,
- onBlockStart: *const fn (*anyopaque, ContentBlockType, usize, ?BlockMeta) anyerror!void,
+ onBlockStart: *const fn (*anyopaque, ContentBlockType, usize) anyerror!void,
onContentDelta: *const fn (*anyopaque, usize, []const u8) anyerror!void,
onBlockComplete: *const fn (*anyopaque, usize, conversation.ContentBlock) anyerror!void,
onMessageComplete: *const fn (*anyopaque, conversation.Message) anyerror!void,
@@ -47,8 +48,8 @@ pub const Receiver = struct {
try self.vtable.onMessageStart(self.ptr, role);
}
- pub fn onBlockStart(self: Receiver, block_type: ContentBlockType, index: usize, meta: ?BlockMeta) !void {
- try self.vtable.onBlockStart(self.ptr, block_type, index, meta);
+ pub fn onBlockStart(self: Receiver, block_type: ContentBlockType, index: usize) !void {
+ try self.vtable.onBlockStart(self.ptr, block_type, index);
}
pub fn onContentDelta(self: Receiver, block_index: usize, delta: []const u8) !void {