at 24.11-pre 6.9 kB view raw
1{ config, lib, pkgs, ... }: 2let 3 inherit (lib) types; 4 5 cfg = config.services.tabby; 6 format = pkgs.formats.toml { }; 7 tabbyPackage = cfg.package.override { 8 inherit (cfg) acceleration; 9 }; 10in 11{ 12 options = { 13 services.tabby = { 14 enable = lib.mkEnableOption "Self-hosted AI coding assistant using large language models"; 15 16 package = lib.mkPackageOption pkgs "tabby" { }; 17 18 port = lib.mkOption { 19 type = types.port; 20 default = 11029; 21 description = '' 22 Specifies the bind port on which the tabby server HTTP interface listens. 23 ''; 24 }; 25 26 model = lib.mkOption { 27 type = types.str; 28 default = "TabbyML/StarCoder-1B"; 29 description = '' 30 Specify the model that tabby will use to generate completions. 31 32 This model will be downloaded automatically if it is not already present. 33 34 If you want to utilize an existing model that you've already 35 downloaded you'll need to move it into tabby's state directory which 36 lives in `/var/lib/tabby`. Because the tabby.service is configured to 37 use a DyanmicUser the service will need to have been started at least 38 once before you can move the locally existing model into 39 `/var/lib/tabby`. You can set the model to 'none' and tabby will 40 startup and fail to download a model, but will have created the 41 `/var/lib/tabby` directory. You can then copy over the model manually 42 into `/var/lib/tabby`, update the model option to the name you just 43 downloaded and copied over then `nixos-rebuild switch` to start using 44 it. 45 46 $ tabby download --model TabbyML/DeepseekCoder-6.7B 47 $ find ~/.tabby/ | tail -n1 48 /home/ghthor/.tabby/models/TabbyML/DeepseekCoder-6.7B/ggml/q8_0.v2.gguf 49 $ sudo rsync -r ~/.tabby/models/ /var/lib/tabby/models/ 50 $ sudo chown -R tabby:tabby /var/lib/tabby/models/ 51 52 See for Model Options: 53 > https://github.com/TabbyML/registry-tabby 54 ''; 55 }; 56 57 acceleration = lib.mkOption { 58 type = types.nullOr (types.enum [ "cpu" "rocm" "cuda" "metal" ]); 59 default = null; 60 example = "rocm"; 61 description = '' 62 Specifies the device to use for hardware acceleration. 63 64 - `cpu`: no acceleration just use the CPU 65 - `rocm`: supported by modern AMD GPUs 66 - `cuda`: supported by modern NVIDIA GPUs 67 - `metal`: supported on darwin aarch64 machines 68 69 Tabby will try and determine what type of acceleration that is 70 already enabled in your configuration when `acceleration = null`. 71 72 - nixpkgs.config.cudaSupport 73 - nixpkgs.config.rocmSupport 74 - if stdenv.isDarwin && stdenv.isAarch64 75 76 IFF multiple acceleration methods are found to be enabled or if you 77 haven't set either `cudaSupport or rocmSupport` you will have to 78 specify the device type manually here otherwise it will default to 79 the first from the list above or to cpu. 80 ''; 81 }; 82 83 settings = lib.mkOption { 84 inherit (format) type; 85 default = { }; 86 description = '' 87 Tabby scheduler configuration 88 89 See for more details: 90 > https://tabby.tabbyml.com/docs/configuration/#repository-context-for-code-completion 91 ''; 92 example = lib.literalExpression '' 93 settings = { 94 repositories = [ 95 { name = "tabby"; git_url = "https://github.com/TabbyML/tabby.git"; } 96 { name = "CTranslate2"; git_url = "git@github.com:OpenNMT/CTranslate2.git"; } 97 98 # local directory is also supported, but limited by systemd DynamicUser=1 99 # adding local repositories will need to be done manually 100 { name = "repository_a"; git_url = "file:///var/lib/tabby/repository_a"; } 101 ]; 102 }; 103 ''; 104 }; 105 106 usageCollection = lib.mkOption { 107 type = types.bool; 108 default = false; 109 description = '' 110 Enable sending anonymous usage data. 111 112 See for more details: 113 > https://tabby.tabbyml.com/docs/configuration#usage-collection 114 ''; 115 }; 116 117 indexInterval = lib.mkOption { 118 type = types.str; 119 default = "5hours"; 120 example = "5hours"; 121 description = '' 122 Run tabby scheduler to generate the index database at this interval. 123 Updates by default every 5 hours. This value applies to 124 `OnUnitInactiveSec` 125 126 The format is described in 127 {manpage}`systemd.time(7)`. 128 129 To disable running `tabby scheduler --now` updates, set to `"never"` 130 ''; 131 }; 132 }; 133 }; 134 135 # TODO(ghthor): firewall config 136 137 config = lib.mkIf cfg.enable { 138 environment = { 139 etc."tabby/config.toml".source = format.generate "config.toml" cfg.settings; 140 systemPackages = [ tabbyPackage ]; 141 }; 142 143 144 systemd = let 145 serviceUser = { 146 WorkingDirectory = "/var/lib/tabby"; 147 StateDirectory = [ "tabby" ]; 148 ConfigurationDirectory = [ "tabby" ]; 149 DynamicUser = true; 150 User = "tabby"; 151 Group = "tabby"; 152 }; 153 154 serviceEnv = lib.mkMerge [ 155 { 156 TABBY_ROOT = "%S/tabby"; 157 } 158 (lib.mkIf (!cfg.usageCollection) { 159 TABBY_DISABLE_USAGE_COLLECTION = "1"; 160 }) 161 ]; 162 in { 163 services.tabby = { 164 wantedBy = [ "multi-user.target" ]; 165 description = "Self-hosted AI coding assistant using large language models"; 166 after = [ "network.target" ]; 167 environment = serviceEnv; 168 serviceConfig = lib.mkMerge [ 169 serviceUser 170 { 171 ExecStart = 172 "${lib.getExe tabbyPackage} serve --model ${cfg.model} --port ${toString cfg.port} --device ${tabbyPackage.featureDevice}"; 173 } 174 ]; 175 }; 176 177 services.tabby-scheduler = lib.mkIf (cfg.indexInterval != "never") { 178 wantedBy = [ "multi-user.target" ]; 179 description = "Tabby repository indexing service"; 180 after = [ "network.target" ]; 181 environment = serviceEnv; 182 preStart = "cp -f /etc/tabby/config.toml \${TABBY_ROOT}/config.toml"; 183 serviceConfig = lib.mkMerge [ 184 serviceUser 185 { 186 # Type = "oneshot"; 187 ExecStart = "${lib.getExe tabbyPackage} scheduler --now"; 188 } 189 ]; 190 }; 191 timers.tabby-scheduler = lib.mkIf (cfg.indexInterval != "never") { 192 description = "Update timer for tabby-scheduler"; 193 partOf = [ "tabby-scheduler.service" ]; 194 wantedBy = [ "timers.target" ]; 195 timerConfig.OnUnitInactiveSec = cfg.indexInterval; 196 }; 197 }; 198 }; 199 200 meta.maintainers = with lib.maintainers; [ ghthor ]; 201}