diff options
Diffstat (limited to 'backend/api/src/model.zig')
| -rw-r--r-- | backend/api/src/model.zig | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/backend/api/src/model.zig b/backend/api/src/model.zig new file mode 100644 index 0000000..b35104f --- /dev/null +++ b/backend/api/src/model.zig @@ -0,0 +1,123 @@ +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 } ) ); +} |
