Something went wrong. Try again.
fork of Kludex/zigai, ported to zig 0.17
Something went wrong. Try again.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768//! Test doubles that exercise the same public Model interface as live clients.
const std = @import("std");const model_types = @import("model.zig");
pub const ScriptedModel = struct { responses: []const model_types.ModelResponse, next_response: usize = 0, request_count: usize = 0, inspectFn: ?*const fn (request_index: usize, request: model_types.ModelRequest) anyerror!void = null, profile: model_types.ModelProfile = .{}, provider_name: ?[]const u8 = null, model_name: ?[]const u8 = null,
pub fn model(self: *ScriptedModel) model_types.Model { return .{ .context = self, .profile = self.profile, .provider_name = self.provider_name, .model_name = self.model_name, .requestFn = request, .streamFn = stream, }; }
fn request(context: *anyopaque, _: std.mem.Allocator, value: model_types.ModelRequest) !model_types.ModelResponse { const self: *ScriptedModel = @ptrCast(@alignCast(context)); const current = self.request_count; self.request_count += 1; if (self.inspectFn) |inspect| try inspect(current, value); if (self.next_response >= self.responses.len) return error.ScriptExhausted; const response = self.responses[self.next_response]; self.next_response += 1; return response; }
fn stream(context: *anyopaque, allocator: std.mem.Allocator, value: model_types.ModelRequest, sink: model_types.ModelStreamSink) !model_types.ModelResponse { const response = try request(context, allocator, value); for (response.parts, 0..) |part, index| try model_types.emitCompletePart(sink, index, part); try sink.emit(.{ .usage = response.usage }); return response; }};
test "scripted model reports exhaustion" { var scripted = ScriptedModel{ .responses = &.{} }; try std.testing.expectError(error.ScriptExhausted, scripted.model().request(std.testing.allocator, .{ .messages = &.{} })); try std.testing.expectEqual(@as(usize, 1), scripted.request_count);}
/// `std.testing.allocator` with in-place growth refused. Its in-place growth/// succeeds on some runs and not others, and `checkAllAllocationFailures` needs/// the same allocation count on every run.pub const non_resizing_allocator: std.mem.Allocator = .{ .ptr = undefined, .vtable = &.{ .alloc = nonResizingAlloc, .resize = std.mem.Allocator.noResize, .remap = std.mem.Allocator.noRemap, .free = nonResizingFree,} };
fn nonResizingAlloc(_: *anyopaque, len: usize, alignment: std.mem.Alignment, ret_addr: usize) ?[*]u8 { return std.testing.allocator.rawAlloc(len, alignment, ret_addr);}
fn nonResizingFree(_: *anyopaque, memory: []u8, alignment: std.mem.Alignment, ret_addr: usize) void { std.testing.allocator.rawFree(memory, alignment, ret_addr);}