grafana-alloy: don't build the frontend twice
[NixPkgs.git] / nixos / modules / services / web-apps / chatgpt-retrieval-plugin.nix
blobc1ab7ec40949c8111521671b2dc76d5c3c4bd438
1 { config, pkgs, lib, ... }:
3 with lib;
5 let
6   cfg = config.services.chatgpt-retrieval-plugin;
7 in
9   options.services.chatgpt-retrieval-plugin = {
10     enable = mkEnableOption "chatgpt-retrieval-plugin service";
12     port = mkOption {
13       type = types.port;
14       default = 8080;
15       description = "Port the chatgpt-retrieval-plugin service listens on.";
16     };
18     host = mkOption {
19       type = types.str;
20       default = "127.0.0.1";
21       example = "0.0.0.0";
22       description = "The hostname or IP address for chatgpt-retrieval-plugin to bind to.";
23     };
25     bearerTokenPath = mkOption {
26       type = types.path;
27       description = ''
28         Path to the secret bearer token used for the http api authentication.
29       '';
30       default = "";
31       example = "config.age.secrets.CHATGPT_RETRIEVAL_PLUGIN_BEARER_TOKEN.path";
32     };
34     openaiApiKeyPath = mkOption {
35       type = types.path;
36       description = ''
37         Path to the secret openai api key used for embeddings.
38       '';
39       default = "";
40       example = "config.age.secrets.CHATGPT_RETRIEVAL_PLUGIN_OPENAI_API_KEY.path";
41     };
43     datastore = mkOption {
44       type = types.enum [ "pinecone" "weaviate" "zilliz" "milvus" "qdrant" "redis" ];
45       default = "qdrant";
46       description = "This specifies the vector database provider you want to use to store and query embeddings.";
47     };
49     qdrantCollection = mkOption {
50       type = types.str;
51       description = ''
52         name of the qdrant collection used to store documents.
53       '';
54       default = "document_chunks";
55     };
56   };
58   config = mkIf cfg.enable {
60     assertions = [
61       {
62         assertion = cfg.bearerTokenPath != "";
63         message = "services.chatgpt-retrieval-plugin.bearerTokenPath should not be an empty string.";
64       }
65       {
66         assertion = cfg.openaiApiKeyPath != "";
67         message = "services.chatgpt-retrieval-plugin.openaiApiKeyPath should not be an empty string.";
68       }
69     ];
71     systemd.services.chatgpt-retrieval-plugin = {
72       description = "ChatGPT Retrieval Plugin";
73       after = [ "network.target" ];
74       wantedBy = [ "multi-user.target" ];
76       serviceConfig = {
77         DynamicUser = true;
78         Restart = "always";
79         LoadCredential = [
80           "BEARER_TOKEN:${cfg.bearerTokenPath}"
81           "OPENAI_API_KEY:${cfg.openaiApiKeyPath}"
82         ];
83         StateDirectory = "chatgpt-retrieval-plugin";
84         StateDirectoryMode = "0755";
85       };
87       # it doesn't make sense to pass secrets as env vars, this is a hack until
88       # upstream has proper secret management.
89       script = ''
90         export BEARER_TOKEN=$(${pkgs.systemd}/bin/systemd-creds cat BEARER_TOKEN)
91         export OPENAI_API_KEY=$(${pkgs.systemd}/bin/systemd-creds cat OPENAI_API_KEY)
92         exec ${pkgs.chatgpt-retrieval-plugin}/bin/start --host ${cfg.host} --port ${toString cfg.port}
93       '';
95       environment = {
96         DATASTORE = cfg.datastore;
97         QDRANT_COLLECTION = mkIf (cfg.datastore == "qdrant") cfg.qdrantCollection;
98       };
99     };
101     systemd.tmpfiles.rules = [
102       # create the directory for static files for fastapi
103       "C /var/lib/chatgpt-retrieval-plugin/.well-known - - - - ${pkgs.chatgpt-retrieval-plugin}/${pkgs.python3Packages.python.sitePackages}/.well-known"
104     ];
105   };