feat(user/malte): new ai tool

This commit is contained in:
Malte Tammena 2024-05-31 11:49:57 +02:00
parent a8f251eb83
commit 7914950387
5 changed files with 83 additions and 72 deletions

View file

@ -83,7 +83,7 @@ in {
inherit sopsFile owner mode; inherit sopsFile owner mode;
key = "restic-backup"; key = "restic-backup";
}; };
openai-heygpt-api-key = { openai-aichat-api-key = {
inherit sopsFile owner mode; inherit sopsFile owner mode;
}; };
nix-conf-secrets = { nix-conf-secrets = {

View file

@ -3,7 +3,7 @@ pw-mail-pm: ENC[AES256_GCM,data:v3EqEZyuy6r8qveDlq7t+UuyK7m2Zg==,iv:96HpxVd8bRub
pw-mail-uni: ENC[AES256_GCM,data:bjhlTpNHRfC8ty+i4bztKWq47IGB2qqJGPvKP+7N6xA=,iv:ZvpPado3BZ5FwEtSFmg22wPlbLR11d77JxygN9Steso=,tag:KIgJIR0sJIWZHKjl/p8KEg==,type:str] pw-mail-uni: ENC[AES256_GCM,data:bjhlTpNHRfC8ty+i4bztKWq47IGB2qqJGPvKP+7N6xA=,iv:ZvpPado3BZ5FwEtSFmg22wPlbLR11d77JxygN9Steso=,tag:KIgJIR0sJIWZHKjl/p8KEg==,type:str]
pw-mail-gmx: ENC[AES256_GCM,data:byvzb3zSVOHLjGzHwx43h0YhMoeDvUR2/g==,iv:tQEg751oi+LIjJ1dzW4Kv/irSgTCIuh2Fl4YQ0Pm6M8=,tag:1Uarz2dCkpTmJIh+/HYeEA==,type:str] pw-mail-gmx: ENC[AES256_GCM,data:byvzb3zSVOHLjGzHwx43h0YhMoeDvUR2/g==,iv:tQEg751oi+LIjJ1dzW4Kv/irSgTCIuh2Fl4YQ0Pm6M8=,tag:1Uarz2dCkpTmJIh+/HYeEA==,type:str]
pw-mail-schulverwalter: ENC[AES256_GCM,data:jEFDG1EDywlwdrB/5KlrLYxde0CTSaOxtjLgC0lZbl0=,iv:pYhX7cihkK7HfXoFe8lfkZ4G0TVuSKLIDUXZnh6P60Y=,tag:zMh13xBGsnjpvtci7EnFNg==,type:str] pw-mail-schulverwalter: ENC[AES256_GCM,data:jEFDG1EDywlwdrB/5KlrLYxde0CTSaOxtjLgC0lZbl0=,iv:pYhX7cihkK7HfXoFe8lfkZ4G0TVuSKLIDUXZnh6P60Y=,tag:zMh13xBGsnjpvtci7EnFNg==,type:str]
openai-heygpt-api-key: ENC[AES256_GCM,data:iC4NkkbMB2WIN9Z1Nw+KWPKG2NUitpH1EUrBfGFTta6y0XLRDs0o6D01EyF3vXOiEOcd,iv:W47ORUJv3KNTBBlFrBQvMAYvf3aeNFkSGYomirK/2xM=,tag:jBFjAfsk8TSmxBxge9zFeQ==,type:str] openai-aichat-api-key: ENC[AES256_GCM,data:/pY4PiV5nqzwv5vb3H0bI+Jde0CLgyBram0L2AH0A6+I5rLbnABIJ/rlOFd+EX5pRQpyaHBe6ZE=,iv:KpUFQi7HYKBl9Dnl6n3oN/29B8m61JstLad5eGzlA08=,tag:ypNdRk5ix08UZwme9JtXyQ==,type:str]
nix-conf-secrets: ENC[AES256_GCM,data:stl3MzKjBfqU7pp0+Dsn85KKFHKSl9pTI8vpYtNZ17UJ+sMitWElXdwem/NF5p9s74r5fJKrW5n/ug+YGrjUla5Hmc0=,iv:9EzSZmMXIWJ/RNDjnlhmwZVDnkCP20jHJRHqpjiPmA0=,tag:4VKuyFRVnO4VDqXGdKNJbg==,type:str] nix-conf-secrets: ENC[AES256_GCM,data:stl3MzKjBfqU7pp0+Dsn85KKFHKSl9pTI8vpYtNZ17UJ+sMitWElXdwem/NF5p9s74r5fJKrW5n/ug+YGrjUla5Hmc0=,iv:9EzSZmMXIWJ/RNDjnlhmwZVDnkCP20jHJRHqpjiPmA0=,tag:4VKuyFRVnO4VDqXGdKNJbg==,type:str]
sftp-key: ENC[AES256_GCM,data:4DTZnkaLvzeoGQowHqpcZfvvZls8LsOd/4ER5Fzw135nLDogVQWDN2ae8ce2CeCbfl4ZqCZNAlEueg3SIJ8Ew10zVkac4wU7mal1MPvqsDjH+ufiBIs5100DOCkWn376U0eZ/AVuwYY8/CA1ZeZ+LfQU3grpnN/9I4Q8QCZqW4zlPSJtF7V5/fU4Na1gJswKeaFXMdT7O+JWpfqb2jLl3HUO7m69VYlOD9/B8BcOU1PSfJGhat1bzeiNB6h22eEoZtUtLoF9P+O11IrOMiHbK610gSH8TM64Fu1Y8a7rx/UtlYpeDs1FA28Ldrb+YxZHfhJbhp8xNX/22NaDSDwFnZLIaY0KOv3lzICqpAmLB9s2r4kOAw64dopgYdw+XXb8qQ4o2iOwWQ3HCXCqKLxImRubktQu3jD6AOPoCDcDwPqzNfPDoo+OWNAGpLSS9LGN8+uRgtNIkfCEx+cU3gU9HhvBmbXVUFLObpNFo7XZJj3l/mHWKZ/rOKpyX8c6+Hx4zlQfUrChxt65X8f/8rSyB3Nq9SqCELBiaINu,iv:nUp0rBZjCyibnmVV8qIsFXmfqAjWExh5bH50ynVFwj0=,tag:TiaKa+lK0m6JC8tGcrfqIw==,type:str] sftp-key: ENC[AES256_GCM,data:4DTZnkaLvzeoGQowHqpcZfvvZls8LsOd/4ER5Fzw135nLDogVQWDN2ae8ce2CeCbfl4ZqCZNAlEueg3SIJ8Ew10zVkac4wU7mal1MPvqsDjH+ufiBIs5100DOCkWn376U0eZ/AVuwYY8/CA1ZeZ+LfQU3grpnN/9I4Q8QCZqW4zlPSJtF7V5/fU4Na1gJswKeaFXMdT7O+JWpfqb2jLl3HUO7m69VYlOD9/B8BcOU1PSfJGhat1bzeiNB6h22eEoZtUtLoF9P+O11IrOMiHbK610gSH8TM64Fu1Y8a7rx/UtlYpeDs1FA28Ldrb+YxZHfhJbhp8xNX/22NaDSDwFnZLIaY0KOv3lzICqpAmLB9s2r4kOAw64dopgYdw+XXb8qQ4o2iOwWQ3HCXCqKLxImRubktQu3jD6AOPoCDcDwPqzNfPDoo+OWNAGpLSS9LGN8+uRgtNIkfCEx+cU3gU9HhvBmbXVUFLObpNFo7XZJj3l/mHWKZ/rOKpyX8c6+Hx4zlQfUrChxt65X8f/8rSyB3Nq9SqCELBiaINu,iv:nUp0rBZjCyibnmVV8qIsFXmfqAjWExh5bH50ynVFwj0=,tag:TiaKa+lK0m6JC8tGcrfqIw==,type:str]
sops: sops:
@ -39,8 +39,8 @@ sops:
U05rN3hQTFkxTHFDVnpZWGxNY25maFUKdrn4Jtqc9U9GXyRAPhHE8iyVFL5NvnrZ U05rN3hQTFkxTHFDVnpZWGxNY25maFUKdrn4Jtqc9U9GXyRAPhHE8iyVFL5NvnrZ
0KVOCWycdGVltDjTFVpyLoCiwZcTDDza/vjFcCro1zgcsdVuPl0orA== 0KVOCWycdGVltDjTFVpyLoCiwZcTDDza/vjFcCro1zgcsdVuPl0orA==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
lastmodified: "2024-03-24T20:00:51Z" lastmodified: "2024-05-31T08:47:57Z"
mac: ENC[AES256_GCM,data:DqFT7rVf7ojxAdB75frzQ5BqonFSJcFoGRtABecDDA5g5/izKAWwhU701kT1s/9Di2tN6Cg6RnGd/qWrUr+XMiMr3cw/5q7OK0FUUDgHrE4al567+JYItq9vkr8Q88/uhMgbe1RU5RZQQ+8ERGLrDFt8+DPxFErgQcJJLDG6lSw=,iv:o9IDmrCHuc1k4KlYC+RSQdKjq0m3uA7kX2IwMv+o4O4=,tag:SKWAaAyUm/sjXRmAGZauUQ==,type:str] mac: ENC[AES256_GCM,data:/UUOI+mqqOHoOzxdPy9Q1CEEo+6kS2s+Nz4kVFaG53oOuJvqMCbp+YFEs+8xv6pmEFa82M68JnSE/2YzbxTHjjTc1kN7nUEIaDgGPFR1EQKmxfi3s5KF6aMuHxFYft9a8F86TLXkEQO7aRCqLcty2p7ipZJrW7mccg0m9JqIDhk=,iv:F6iarZsx/fTlQx8+chVoX/3Kx/xRsM31rcyKqJcvsms=,tag:i6cmoAdWXywKz6X1jl0kwQ==,type:str]
pgp: pgp:
- created_at: "2023-11-18T10:06:28Z" - created_at: "2023-11-18T10:06:28Z"
enc: |- enc: |-

View file

@ -45,63 +45,6 @@
''; '';
}; };
heygptRaw = pkgs.heygpt.overrideAttrs (_: {
src = builtins.trace "REMOVE heygpt override after hash fix lands" (pkgs.fetchFromGitHub {
owner = "fuyufjh";
repo = "heygpt";
rev = "v0.4.1";
hash = "sha256-oP0yIdYytXSsbZ2pNaZ8Rrak1qJsudTe/oP6dGncGUM=";
});
patches = [../../patches/heygpt-default-model.patch];
});
heygptWrapper = pkgs.writeShellApplication {
name = "heygpt";
text = ''
OPENAI_API_KEY=$(cat ${nixosConfig.sops.secrets.openai-heygpt-api-key.path}) ${heygptRaw}/bin/heygpt "$@"
'';
};
tren = pkgs.writeShellApplication {
name = "tren";
runtimeInputs = [heygptWrapper];
text = ''
POSITIONAL_ARGS=()
lang=en
while [[ $# -gt 0 ]]; do
case $1 in
-l|--lang)
lang="$2"
shift # past argument
shift # past value
;;
--*|-*)
echo "Unknown option $1"
exit 1
;;
*)
POSITIONAL_ARGS+=("$1") # save positional arg
shift # past argument
;;
esac
done
set -- "''${POSITIONAL_ARGS[@]}" # restore positional parameters
heygpt --system "Output an unordered list of up to 6 possible translations to language $lang for the given word. No explanation. Markdown format." "$@"
'';
};
fixWord = pkgs.writeShellApplication {
name = "fix-word";
runtimeInputs = [heygptWrapper];
text = ''
heygpt --system "You will correct any spelling mistakes in the input. No explanations." "$@"
'';
};
nnnIcons = pkgs.nnn.override {withNerdIcons = true;}; nnnIcons = pkgs.nnn.override {withNerdIcons = true;};
in { in {
imports = [ imports = [
@ -119,6 +62,7 @@ in {
./modules/notes.nix ./modules/notes.nix
../modules/restic-backup.nix ../modules/restic-backup.nix
../modules/profiles-cleanup.nix ../modules/profiles-cleanup.nix
../modules/aichat.nix
]; ];
config = { config = {
@ -154,7 +98,6 @@ in {
gnome3.sushi gnome3.sushi
gnome.simple-scan gnome.simple-scan
helvum helvum
heygptWrapper
hledger hledger
inkscape inkscape
kbdlight kbdlight
@ -176,8 +119,6 @@ in {
signal-desktop # FIXME: Once it works again? (fixElectron "signal-desktop" signal-desktop) signal-desktop # FIXME: Once it works again? (fixElectron "signal-desktop" signal-desktop)
sshfs sshfs
tdesktop tdesktop
tren
fixWord
unar unar
unison unison
vlc vlc
@ -191,7 +132,6 @@ in {
sessionVariables = { sessionVariables = {
MOZ_USE_XINPUT2 = "1"; MOZ_USE_XINPUT2 = "1";
OPENAI_API_BASE = "https://api.openai.com/v1";
}; };
pointerCursor = { pointerCursor = {
@ -223,6 +163,30 @@ in {
# Make sure firefox is my default browser # Make sure firefox is my default browser
programs.firefox.enable = true; programs.firefox.enable = true;
programs.aichat = {
enable = true;
openaiApiKeyFile = nixosConfig.sops.secrets.openai-aichat-api-key.path;
settings = {
model = "openai:gpt-4o";
clients = [
{type = "openai";}
];
save = true;
save_session = true;
highlight = true;
light_theme = true;
wrap = "auto";
keybindings = "vi";
};
roles = {
emoji = ''
I want you to translate the sentences I write into emojis.
I will write the sentence, and you will express it with emojis.
I don't want you to reply with anything but emoji.
'';
};
};
programs.obs-studio = { programs.obs-studio = {
enable = true; enable = true;
plugins = [ plugins = [

View file

@ -59,10 +59,6 @@
discord-hack = "NIXPKGS_ALLOW_UNFREE=1 nix run 'github:NixOS/nixpkgs?ref=master#discord' --impure"; discord-hack = "NIXPKGS_ALLOW_UNFREE=1 nix run 'github:NixOS/nixpkgs?ref=master#discord' --impure";
decklog = "ssh deck@polymita-picta gamelog"; decklog = "ssh deck@polymita-picta gamelog";
g = "heygpt";
g4 = "heygpt --model gpt-4o";
c4 = "c --model gpt-4o";
}; };
shellAliases = { shellAliases = {
# Prefix for date-based files/folders # Prefix for date-based files/folders
@ -75,9 +71,6 @@
wl-paste | silicon -f 'Hack Nerd Font Mono' --pad-horiz 40 --pad-vert 50 --theme gruvbox --shadow-blur-radius 30 -b '#ebdbb2' --shadow-color '#282828' --no-window-controls --output /tmp/image.png $argv && wl-copy < /tmp/image.png wl-paste | silicon -f 'Hack Nerd Font Mono' --pad-horiz 40 --pad-vert 50 --theme gruvbox --shadow-blur-radius 30 -b '#ebdbb2' --shadow-color '#282828' --no-window-controls --output /tmp/image.png $argv && wl-copy < /tmp/image.png
''; '';
nonix = "sed 's:/nix/store/[^-]\\+-\\([^/ ]*\\):< \\1>:g'"; nonix = "sed 's:/nix/store/[^-]\\+-\\([^/ ]*\\):< \\1>:g'";
c = ''
heygpt --system "Imagine you are linux terminal command selector. I will describe a task, and you will respond only using the linux command, without description, without explanation. Don't try to run anything. Just assemble a command and display it." $argv
'';
}; };
shellInit = '' shellInit = ''

54
users/modules/aichat.nix Normal file
View file

@ -0,0 +1,54 @@
{
pkgs,
lib,
config,
...
}: let
cfg = config.programs.aichat;
yamlFormat = pkgs.formats.yaml {};
aichatWrapper = pkgs.writeShellApplication {
name = "aichat";
runtimeInputs = [pkgs.aichat];
text = ''
OPENAI_API_KEY="$(cat ${cfg.openaiApiKeyFile})"; export OPENAI_API_KEY
${lib.getExe pkgs.aichat} "$@"
'';
};
in {
options.programs.aichat = {
enable = lib.mkEnableOption "aichat, the terminal ai interface";
openaiApiKeyFile = lib.mkOption {
type = lib.types.str;
description = "API key file for OpenAI";
};
settings = lib.mkOption {
type = lib.types.submodule {freeformType = yamlFormat.type;};
default = {};
description = ''
aichat configuration options.
See <https://github.com/sigoden/aichat?tab=readme-ov-file#configuration> for details.
'';
};
roles = lib.mkOption {
type = lib.types.attrsOf lib.types.lines;
default = {};
description = ''
aichat role configuration.
See <https://github.com/sigoden/aichat?tab=readme-ov-file#defining-roles> for details.
'';
};
};
config = lib.mkIf cfg.enable {
home.packages = [aichatWrapper];
programs.fish.shellAbbrs = {
g = "aichat";
c = "aichat -e";
};
xdg.configFile."aichat/config.yaml".source = yamlFormat.generate "config.yaml" cfg.settings;
xdg.configFile."aichat/roles.yaml".source = yamlFormat.generate "roles.yaml" cfg.roles;
};
}