summaryrefslogtreecommitdiff
path: root/libawl/src/provider.zig
diff options
context:
space:
mode:
authorT <t@tjp.lol>2026-04-26 11:09:37 -0600
committerT <t@tjp.lol>2026-05-25 11:48:47 -0700
commit52b2ca78aed7950af27d4865aee65da781514a99 (patch)
tree24f512e67afd677b6c0d8a8064819e8f5332d28d /libawl/src/provider.zig
parentd3d5a6295a67bdc99e35e5bfd77359d98a850c3f (diff)
Initial work, and name change to pantograph
Diffstat (limited to 'libawl/src/provider.zig')
-rw-r--r--libawl/src/provider.zig66
1 files changed, 66 insertions, 0 deletions
diff --git a/libawl/src/provider.zig b/libawl/src/provider.zig
new file mode 100644
index 0000000..8d6eea5
--- /dev/null
+++ b/libawl/src/provider.zig
@@ -0,0 +1,66 @@
+const std = @import("std");
+const conversation = @import("conversation.zig");
+
+pub const ContentBlockType = enum {
+ Text,
+ Thinking,
+ ToolUse,
+ ToolResult,
+};
+
+pub const BlockMeta = struct {
+ /// Only populated for ToolUse blocks. Null for Text/Thinking.
+ tool_id: ?[]const u8 = null,
+ tool_name: ?[]const u8 = null,
+};
+
+pub const ReceiverVTable = struct {
+ onMessageStart: *const fn (*anyopaque, conversation.MessageRole) void,
+ onBlockStart: *const fn (*anyopaque, ContentBlockType, usize, ?BlockMeta) void,
+ onContentDelta: *const fn (*anyopaque, usize, []const u8) void,
+ onBlockComplete: *const fn (*anyopaque, usize, conversation.ContentBlock) void,
+ onMessageComplete: *const fn (*anyopaque, conversation.Message) void,
+};
+
+pub const Receiver = struct {
+ ptr: *anyopaque,
+ vtable: *const ReceiverVTable,
+
+ pub fn onMessageStart(self: Receiver, role: conversation.MessageRole) void {
+ self.vtable.onMessageStart(self.ptr, role);
+ }
+
+ pub fn onBlockStart(self: Receiver, block_type: ContentBlockType, index: usize, meta: ?BlockMeta) void {
+ self.vtable.onBlockStart(self.ptr, block_type, index, meta);
+ }
+
+ pub fn onContentDelta(self: Receiver, block_index: usize, delta: []const u8) void {
+ self.vtable.onContentDelta(self.ptr, block_index, delta);
+ }
+
+ pub fn onBlockComplete(self: Receiver, block_index: usize, block: conversation.ContentBlock) void {
+ self.vtable.onBlockComplete(self.ptr, block_index, block);
+ }
+
+ pub fn onMessageComplete(self: Receiver, message: conversation.Message) void {
+ self.vtable.onMessageComplete(self.ptr, message);
+ }
+};
+
+pub const ProviderVTable = struct {
+ streamStep: *const fn (*anyopaque, *conversation.Conversation, *Receiver) anyerror!void,
+ deinit: *const fn (*anyopaque) void,
+};
+
+pub const Provider = struct {
+ ptr: *anyopaque,
+ vtable: *const ProviderVTable,
+
+ pub fn streamStep(self: Provider, conv: *conversation.Conversation, receiver: *Receiver) anyerror!void {
+ return self.vtable.streamStep(self.ptr, conv, receiver);
+ }
+
+ pub fn deinit(self: Provider) void {
+ self.vtable.deinit(self.ptr);
+ }
+};