diff options
Diffstat (limited to 'libpanto/src/provider.zig')
| -rw-r--r-- | libpanto/src/provider.zig | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/libpanto/src/provider.zig b/libpanto/src/provider.zig index bc39026..ab60678 100644 --- a/libpanto/src/provider.zig +++ b/libpanto/src/provider.zig @@ -3,7 +3,9 @@ const std = @import("std"); const config_mod = @import("config.zig"); const conversation = @import("conversation.zig"); const tool_registry_mod = @import("tool_registry.zig"); +const session_mod = @import("session.zig"); pub const ToolRegistry = tool_registry_mod.ToolRegistry; +pub const Usage = session_mod.Usage; pub const ContentBlockType = enum { Text, @@ -35,13 +37,21 @@ pub const ContentBlockType = enum { /// or in the Provider (HTTP/parse/stream failure). It is the last callback the /// receiver will see for that turn. `onError` itself cannot fail; receivers /// must swallow secondary failures during cleanup. +/// +/// `onMessageComplete`'s `usage` argument carries the wire-reported token +/// counts for the just-finished assistant turn. Providers fire this exactly +/// once per successful turn. `usage` is `null` only when the wire genuinely +/// did not deliver any usage information — chiefly OpenAI-compatible proxies +/// (OpenRouter, vLLM, some self-hosted backends) that ignore +/// `stream_options.include_usage`. Receivers that compute cost should record +/// the null case explicitly ("unknown") rather than treating it as zero. pub const ReceiverVTable = struct { onMessageStart: *const fn (*anyopaque, conversation.MessageRole) anyerror!void, onBlockStart: *const fn (*anyopaque, ContentBlockType, usize) anyerror!void, onToolDetails: *const fn (*anyopaque, usize, []const u8, []const u8) 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, + onMessageComplete: *const fn (*anyopaque, conversation.Message, ?Usage) anyerror!void, onError: *const fn (*anyopaque, anyerror) void, }; @@ -69,8 +79,8 @@ pub const Receiver = struct { try self.vtable.onBlockComplete(self.ptr, block_index, block); } - pub fn onMessageComplete(self: Receiver, message: conversation.Message) !void { - try self.vtable.onMessageComplete(self.ptr, message); + pub fn onMessageComplete(self: Receiver, message: conversation.Message, usage: ?Usage) !void { + try self.vtable.onMessageComplete(self.ptr, message, usage); } pub fn onError(self: Receiver, err: anyerror) void { |
