const z = @import( "std" ); const zap = @import( "zap" ); const net = @import( "net-util.zig" ); const u = struct { usingnamespace @import( "util.zig" ); usingnamespace @import( "user.zig" ); usingnamespace @import( "userdefs.zig" ); }; const alloc = z.heap.page_allocator; const ArrayList = z.ArrayList; const OkRes = net.OkResponse; const ErrRes = net.ErrorResponse; const memeql = z.mem.eql; threadlocal var modelcache: ?u.JsonResponse([]Model) = null; pub const routes = .{ .@"models" = models }; pub const ModelCapabilities = struct { vision: u32 = 0, remind: u32 = 0, notes: u32 = 0, web: u32 = 0, thinker: ?u32 = 0, pub const @"getty.db" = u.@"json.ignore.unknown"; }; pub const Model = struct { name: []const u8, modelname: []const u8, capabilities: ModelCapabilities = .{}, system: []const u8 = "", description: []const u8 = "", short_description: []const u8 = "", free: u32 = 0, license: []const u8 = "", }; pub const UserResponse = struct { name: []const u8, capabilities: ModelCapabilities = .{}, description: struct { full: []const u8 = "", short: []const u8 = "", }, license: []const u8 = "", free: u32 = 0, pub fn fromModel( model: Model ) UserResponse { return UserResponse { .name = model.name, .capabilities = model.capabilities, .description = .{ .full = model.description, .short = model.short_description }, .free = model.free, .license = model.license }; } }; pub fn canBeUsedByUser( model: Model, user: *const u.UserEntry ) bool { if( memeql( u8, user.subscription_data.plan, "free" ) ) { return model.free == 1; } return true; } pub fn loadModels() !*u.JsonResponse([]Model) { const modelmap = try u.readFileAlloc( "../data/modelmap.json", alloc ); defer alloc.free( modelmap ); if( modelcache ) |cache| { cache.deinit(); } modelcache = u.jsonParseAlloc( []Model, modelmap, alloc ) catch |e| { return e; }; return &(modelcache.?); } pub fn getModelByDisplayName( modelname: []const u8 ) !*const Model { const modelmap = loadModels() catch |e| { z.debug.print( "failed to load model map: {any} {any}", .{ e, @errorReturnTrace() } ); return e; }; for( modelmap.v ) |*model| { if( memeql( u8, model.name, modelname ) ) { return model; } } return error.ModelNotFound; } ///assuming endpoint for models is supposed to be pub for support page use? ///route @/models pub fn models( r: zap.Request ) void { const modelmap = loadModels() catch |e| { z.debug.print( "failed to load model map: {any} {any}", .{ e, @errorReturnTrace() } ); return net.sendJson( r, .internal_server_error, ErrRes{ .msg = "failed to load model info" } ); }; var list = ArrayList( UserResponse ).init( alloc ); defer list.deinit(); for( modelmap.v ) |model| { list.append( UserResponse.fromModel( model ) ) catch {}; } net.sendJson( r, .ok, OkRes( .{ .models = list.items } ) ); }