llm: re-add `withPlugins`, add many plugins, 0.25 -> 0.26 (#411459)

authored by philiptaron.tngl.sh and committed by GitHub 24f4a11d e0c2e8b0

+1892 -330
+2 -42
pkgs/by-name/fi/files-to-prompt/package.nix
··· 1 - { 2 - lib, 3 - python3Packages, 4 - fetchFromGitHub, 5 - versionCheckHook, 6 - }: 7 - 8 - python3Packages.buildPythonApplication rec { 9 - pname = "files-to-prompt"; 10 - version = "0.6"; 11 - pyproject = true; 12 - 13 - src = fetchFromGitHub { 14 - owner = "simonw"; 15 - repo = "files-to-prompt"; 16 - tag = version; 17 - hash = "sha256-LWp/DNP3bsh7/goQGkpi4x2N11tRuhLVh2J8H6AUH0w="; 18 - }; 19 - 20 - build-system = with python3Packages; [ 21 - setuptools 22 - ]; 23 - 24 - dependencies = with python3Packages; [ 25 - click 26 - ]; 27 - 28 - nativeCheckInputs = with python3Packages; [ 29 - pytestCheckHook 30 - versionCheckHook 31 - ]; 32 - 33 - versionCheckProgramArg = "--version"; 34 35 - meta = { 36 - description = "Concatenate a directory full of files into a single prompt for use with LLMs"; 37 - homepage = "https://github.com/simonw/files-to-prompt/"; 38 - changelog = "https://github.com/simonw/files-to-prompt/releases/tag/${src.tag}"; 39 - license = lib.licenses.asl20; 40 - maintainers = with lib.maintainers; [ erethon ]; 41 - mainProgram = "files-to-prompt"; 42 - }; 43 - }
··· 1 + { python3Packages }: 2 3 + python3Packages.toPythonApplication python3Packages.files-to-prompt
+2 -40
pkgs/by-name/ic/icdiff/package.nix
··· 1 - { 2 - lib, 3 - python3Packages, 4 - fetchFromGitHub, 5 - bash, 6 - git, 7 - less, 8 - }: 9 - 10 - python3Packages.buildPythonApplication rec { 11 - pname = "icdiff"; 12 - version = "2.0.7"; 13 - 14 - src = fetchFromGitHub { 15 - owner = "jeffkaufman"; 16 - repo = "icdiff"; 17 - tag = "release-${version}"; 18 - hash = "sha256-XOw/xhPGlzi1hAgzQ1EtioUM476A+lQWLlvvaxd9j08="; 19 - }; 20 - 21 - # error: could not lock config file /homeless-shelter/.gitconfig: No such file or directory 22 - doCheck = false; 23 24 - nativeCheckInputs = [ 25 - bash 26 - git 27 - less 28 - ]; 29 - 30 - checkPhase = '' 31 - patchShebangs test.sh 32 - ./test.sh ${python3Packages.python.interpreter} 33 - ''; 34 - 35 - meta = { 36 - homepage = "https://www.jefftk.com/icdiff"; 37 - description = "Side-by-side highlighted command line diffs"; 38 - maintainers = [ ]; 39 - license = lib.licenses.psfl; 40 - }; 41 - }
··· 1 + { python3Packages }: 2 3 + python3Packages.toPythonApplication python3Packages.icdiff
+46
pkgs/by-name/ll/llm/package.nix
···
··· 1 + # The `...` allows this derivation to be overridden with `enable-<llm-plugin>`. 2 + # 3 + # Example: 4 + # 5 + # ```nix 6 + # llm.override { 7 + # enable-llm-anthropic = true; 8 + # enable-llm-gemini = true; 9 + # enable-llm-cmd = true; 10 + # enable-llm-templates-github = true; 11 + # } 12 + # ``` 13 + # 14 + # Whatever names are accepted by `llm.withPlugins` are accepted with an added `enable-` prefix as 15 + # an override of this derivation. The user can also do `llm.withPlugins { llm-anthropic = true; }`. 16 + { lib, python3Packages, ... }@args: 17 + 18 + let 19 + inherit (python3Packages) llm; 20 + 21 + hasEnablePrefix = lib.hasPrefix "enable-"; 22 + addEnablePrefix = name: "enable-${name}"; 23 + removeEnablePrefix = lib.removePrefix "enable-"; 24 + 25 + # Filter to just the attributes which are named "enable-<plugin-name>" 26 + enableArgs = lib.filterAttrs (name: value: hasEnablePrefix name) args; 27 + pluginArgs = lib.mapAttrs' ( 28 + name: value: lib.nameValuePair (removeEnablePrefix name) value 29 + ) enableArgs; 30 + 31 + # Provide some diagnostics for the plugin names 32 + pluginNames = lib.attrNames (lib.functionArgs llm.withPlugins); 33 + enableNames = lib.map addEnablePrefix pluginNames; 34 + unknownPluginNames = lib.removeAttrs pluginArgs pluginNames; 35 + unknownNames = lib.map addEnablePrefix (lib.attrNames unknownPluginNames); 36 + unknownNamesDiagnostic = '' 37 + Unknown plugins specified in override: ${lib.concatStringsSep ", " unknownNames} 38 + 39 + Valid overrides: 40 + - ${lib.concatStringsSep "\n - " enableNames} 41 + ''; 42 + in 43 + 44 + assert lib.assertMsg (lib.length unknownNames == 0) unknownNamesDiagnostic; 45 + 46 + llm.withPlugins pluginArgs
+45
pkgs/development/python-modules/files-to-prompt/default.nix
···
··· 1 + { 2 + lib, 3 + click, 4 + setuptools, 5 + fetchFromGitHub, 6 + buildPythonPackage, 7 + pytestCheckHook, 8 + versionCheckHook, 9 + }: 10 + 11 + buildPythonPackage rec { 12 + pname = "files-to-prompt"; 13 + version = "0.6"; 14 + pyproject = true; 15 + 16 + src = fetchFromGitHub { 17 + owner = "simonw"; 18 + repo = "files-to-prompt"; 19 + tag = version; 20 + hash = "sha256-LWp/DNP3bsh7/goQGkpi4x2N11tRuhLVh2J8H6AUH0w="; 21 + }; 22 + 23 + build-system = [ setuptools ]; 24 + 25 + dependencies = [ click ]; 26 + 27 + nativeCheckInputs = [ 28 + pytestCheckHook 29 + versionCheckHook 30 + ]; 31 + 32 + versionCheckProgramArg = "--version"; 33 + 34 + meta = { 35 + mainProgram = "files-to-prompt"; 36 + description = "Concatenate a directory full of files into a single prompt for use with LLMs"; 37 + homepage = "https://github.com/simonw/files-to-prompt"; 38 + changelog = "https://github.com/simonw/files-to-prompt/releases/tag/${src.tag}"; 39 + license = lib.licenses.asl20; 40 + maintainers = with lib.maintainers; [ 41 + erethon 42 + philiptaron 43 + ]; 44 + }; 45 + }
+35
pkgs/development/python-modules/icdiff/0001-Don-t-test-black-or-flake8.patch
···
··· 1 + From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 2 + From: Philip Taron <philip.taron@gmail.com> 3 + Date: Thu, 29 May 2025 14:47:58 -0700 4 + Subject: [PATCH] Don't test black or flake8 5 + 6 + Signed-off-by: Philip Taron <philip.taron@gmail.com> 7 + --- 8 + test.sh | 14 -------------- 9 + 1 file changed, 14 deletions(-) 10 + 11 + diff --git a/test.sh b/test.sh 12 + index 1dd6c4be579e8a61d2d284b042c54cd2a1e0ff77..dc9ecab4a9097878a0a65c45df38a4fa25eb9fa2 100755 13 + --- a/test.sh 14 + +++ b/test.sh 15 + @@ -210,20 +210,6 @@ function ensure_installed() { 16 + fi 17 + } 18 + 19 + -ensure_installed "black" 20 + -echo 'Running black formatter...' 21 + -if ! black icdiff --quiet --line-length 79 --check; then 22 + - echo "" 23 + - echo 'Consider running `black icdiff --line-length 79`' 24 + - fail 25 + -fi 26 + - 27 + -ensure_installed "flake8" 28 + -echo 'Running flake8 linter...' 29 + -if ! flake8 icdiff; then 30 + - fail 31 + -fi 32 + - 33 + if ! $REGOLD; then 34 + echo PASS 35 + fi
+61
pkgs/development/python-modules/icdiff/default.nix
···
··· 1 + { 2 + lib, 3 + stdenv, 4 + python, 5 + buildPythonPackage, 6 + fetchFromGitHub, 7 + setuptools, 8 + pytestCheckHook, 9 + writableTmpDirAsHomeHook, 10 + pkgs, 11 + }: 12 + let 13 + inherit (pkgs) bash git less; 14 + in 15 + 16 + buildPythonPackage rec { 17 + pname = "icdiff"; 18 + version = "2.0.7"; 19 + pyproject = true; 20 + 21 + src = fetchFromGitHub { 22 + owner = "jeffkaufman"; 23 + repo = "icdiff"; 24 + tag = "release-${version}"; 25 + hash = "sha256-XOw/xhPGlzi1hAgzQ1EtioUM476A+lQWLlvvaxd9j08="; 26 + leaveDotGit = true; 27 + }; 28 + 29 + patches = [ ./0001-Don-t-test-black-or-flake8.patch ]; 30 + 31 + build-system = [ setuptools ]; 32 + 33 + pythonImportsCheck = [ "icdiff" ]; 34 + 35 + nativeCheckInputs = [ 36 + bash 37 + git 38 + less 39 + writableTmpDirAsHomeHook 40 + ]; 41 + 42 + # Odd behavior in the sandbox 43 + doCheck = !stdenv.hostPlatform.isDarwin; 44 + 45 + checkPhase = '' 46 + runHook preCheck 47 + 48 + patchShebangs test.sh 49 + ./test.sh ${python.interpreter} 50 + 51 + runHook postCheck 52 + ''; 53 + 54 + meta = { 55 + description = "Improved colorized diff"; 56 + homepage = "https://github.com/jeffkaufman/icdiff"; 57 + changelog = "https://github.com/jeffkaufman/icdiff/releases/tag/release-${version}/CHANGELOG.md"; 58 + license = lib.licenses.psfl; 59 + maintainers = with lib.maintainers; [ philiptaron ]; 60 + }; 61 + }
+8 -7
pkgs/development/python-modules/llm-anthropic/default.nix
··· 1 { 2 lib, 3 - callPackage, 4 buildPythonPackage, 5 fetchFromGitHub, 6 setuptools, 7 llm, 8 anthropic, 9 pytestCheckHook, 10 pytest-asyncio, ··· 14 15 buildPythonPackage rec { 16 pname = "llm-anthropic"; 17 - version = "0.15.1"; 18 pyproject = true; 19 20 src = fetchFromGitHub { 21 owner = "simonw"; 22 repo = "llm-anthropic"; 23 tag = version; 24 - hash = "sha256-8bVs3MJteOTCiw7n/4pMf+oXMhsQbCSzUFVQqm2ezcE="; 25 }; 26 27 build-system = [ 28 setuptools 29 llm 30 ]; 31 - dependencies = [ anthropic ]; 32 33 nativeCheckInputs = [ 34 pytestCheckHook ··· 39 40 pythonImportsCheck = [ "llm_anthropic" ]; 41 42 - passthru.tests = { 43 - llm-plugin = callPackage ./tests/llm-plugin.nix { }; 44 - }; 45 46 meta = { 47 description = "LLM access to models by Anthropic, including the Claude series";
··· 1 { 2 lib, 3 buildPythonPackage, 4 fetchFromGitHub, 5 setuptools, 6 llm, 7 + llm-anthropic, 8 anthropic, 9 pytestCheckHook, 10 pytest-asyncio, ··· 14 15 buildPythonPackage rec { 16 pname = "llm-anthropic"; 17 + version = "0.17"; 18 pyproject = true; 19 20 src = fetchFromGitHub { 21 owner = "simonw"; 22 repo = "llm-anthropic"; 23 tag = version; 24 + hash = "sha256-2fatBKZMttC5flzfC7MWCpduc3m6IOVWZiW1K2dYqis="; 25 }; 26 27 build-system = [ 28 setuptools 29 + ]; 30 + 31 + dependencies = [ 32 + anthropic 33 llm 34 ]; 35 36 nativeCheckInputs = [ 37 pytestCheckHook ··· 42 43 pythonImportsCheck = [ "llm_anthropic" ]; 44 45 + passthru.tests = llm.mkPluginTest llm-anthropic; 46 47 meta = { 48 description = "LLM access to models by Anthropic, including the Claude series";
-22
pkgs/development/python-modules/llm-anthropic/tests/llm-plugin.nix
··· 1 - { 2 - runCommand, 3 - python, 4 - yq, 5 - }: 6 - let 7 - venv = python.withPackages (ps: [ 8 - ps.llm 9 - ps.llm-anthropic 10 - ]); 11 - in 12 - runCommand "llm-anthropic-test-llm-plugin" 13 - { 14 - nativeBuildInputs = [ 15 - venv 16 - yq 17 - ]; 18 - } 19 - '' 20 - llm plugins | yq --exit-status 'any(.name == "llm-anthropic")' 21 - touch "$out" 22 - ''
···
+9 -10
pkgs/development/python-modules/llm-cmd/default.nix
··· 1 { 2 lib, 3 - callPackage, 4 buildPythonPackage, 5 fetchFromGitHub, 6 # build-system ··· 11 pygments, 12 # tests 13 pytestCheckHook, 14 }: 15 16 buildPythonPackage rec { ··· 27 28 # Only needed until https://github.com/simonw/llm-cmd/pull/18 is merged and released 29 patches = [ ./fix-test.patch ]; 30 - build-system = [ 31 - setuptools 32 - # Follows the reasoning from https://github.com/NixOS/nixpkgs/pull/327800#discussion_r1681586659 about including llm in build-system 33 - llm 34 - ]; 35 36 dependencies = [ 37 prompt-toolkit 38 pygments 39 ]; ··· 46 "llm_cmd" 47 ]; 48 49 - passthru.tests = { 50 - llm-plugin = callPackage ./tests/llm-plugin.nix { }; 51 - }; 52 53 meta = { 54 description = "Use LLM to generate and execute commands in your shell"; 55 homepage = "https://github.com/simonw/llm-cmd"; 56 changelog = "https://github.com/simonw/llm-cmd/releases/tag/${version}"; 57 license = lib.licenses.asl20; 58 - maintainers = with lib.maintainers; [ erethon ]; 59 }; 60 }
··· 1 { 2 lib, 3 buildPythonPackage, 4 fetchFromGitHub, 5 # build-system ··· 10 pygments, 11 # tests 12 pytestCheckHook, 13 + llm-cmd, 14 }: 15 16 buildPythonPackage rec { ··· 27 28 # Only needed until https://github.com/simonw/llm-cmd/pull/18 is merged and released 29 patches = [ ./fix-test.patch ]; 30 + 31 + build-system = [ setuptools ]; 32 33 dependencies = [ 34 + llm 35 prompt-toolkit 36 pygments 37 ]; ··· 44 "llm_cmd" 45 ]; 46 47 + passthru.tests = llm.mkPluginTest llm-cmd; 48 49 meta = { 50 description = "Use LLM to generate and execute commands in your shell"; 51 homepage = "https://github.com/simonw/llm-cmd"; 52 changelog = "https://github.com/simonw/llm-cmd/releases/tag/${version}"; 53 license = lib.licenses.asl20; 54 + maintainers = with lib.maintainers; [ 55 + erethon 56 + philiptaron 57 + ]; 58 }; 59 }
-22
pkgs/development/python-modules/llm-cmd/tests/llm-plugin.nix
··· 1 - { 2 - runCommand, 3 - python, 4 - yq, 5 - }: 6 - let 7 - venv = python.withPackages (ps: [ 8 - ps.llm 9 - ps.llm-cmd 10 - ]); 11 - in 12 - runCommand "llm-cmd-test-llm-plugin" 13 - { 14 - nativeBuildInputs = [ 15 - venv 16 - yq 17 - ]; 18 - } 19 - '' 20 - llm plugins | yq --exit-status 'any(.name == "llm-cmd")' 21 - touch "$out" 22 - ''
···
+50
pkgs/development/python-modules/llm-command-r/default.nix
···
··· 1 + { 2 + lib, 3 + buildPythonPackage, 4 + fetchFromGitHub, 5 + setuptools, 6 + llm, 7 + llm-command-r, 8 + cohere, 9 + pytestCheckHook, 10 + pytest-recording, 11 + writableTmpDirAsHomeHook, 12 + }: 13 + 14 + buildPythonPackage rec { 15 + pname = "llm-command-r"; 16 + version = "0.3.1"; 17 + pyproject = true; 18 + 19 + src = fetchFromGitHub { 20 + owner = "simonw"; 21 + repo = "llm-command-r"; 22 + tag = version; 23 + hash = "sha256-PxICRds9NJQP64HwoL7Oxd39yaIrMdAyQEbhaumJCgo="; 24 + }; 25 + 26 + build-system = [ setuptools ]; 27 + 28 + dependencies = [ 29 + cohere 30 + llm 31 + ]; 32 + 33 + nativeCheckInputs = [ 34 + pytestCheckHook 35 + pytest-recording 36 + writableTmpDirAsHomeHook 37 + ]; 38 + 39 + pythonImportsCheck = [ "llm_command_r" ]; 40 + 41 + passthru.tests = llm.mkPluginTest llm-command-r; 42 + 43 + meta = { 44 + description = "Access the Cohere Command R family of models"; 45 + homepage = "https://github.com/simonw/llm-command-r"; 46 + changelog = "https://github.com/simonw/llm-command-r/releases/tag/${version}/CHANGELOG.md"; 47 + license = lib.licenses.asl20; 48 + maintainers = with lib.maintainers; [ philiptaron ]; 49 + }; 50 + }
+37
pkgs/development/python-modules/llm-deepseek/default.nix
···
··· 1 + { 2 + lib, 3 + buildPythonPackage, 4 + fetchFromGitHub, 5 + setuptools, 6 + llm, 7 + llm-deepseek, 8 + }: 9 + 10 + buildPythonPackage rec { 11 + pname = "llm-deepseek"; 12 + version = "0.1.6"; 13 + pyproject = true; 14 + 15 + src = fetchFromGitHub { 16 + owner = "abrasumente233"; 17 + repo = "llm-deepseek"; 18 + tag = version; 19 + hash = "sha256-yrNvIGnU9Q/0H786DsM0wGEwfxZYIk8IXhqC4mWaQAA="; 20 + }; 21 + 22 + build-system = [ setuptools ]; 23 + 24 + dependencies = [ llm ]; 25 + 26 + pythonImportsCheck = [ "llm_deepseek" ]; 27 + 28 + passthru.tests = llm.mkPluginTest llm-deepseek; 29 + 30 + meta = { 31 + description = "LLM plugin providing access to Deepseek models."; 32 + homepage = "https://github.com/abrasumente233/llm-deepseek"; 33 + changelog = "https://github.com/abrasumente233/llm-deepseek/releases/tag/${version}/CHANGELOG.md"; 34 + license = lib.licenses.asl20; 35 + maintainers = with lib.maintainers; [ philiptaron ]; 36 + }; 37 + }
+37
pkgs/development/python-modules/llm-docs/default.nix
···
··· 1 + { 2 + lib, 3 + buildPythonPackage, 4 + fetchFromGitHub, 5 + setuptools, 6 + llm, 7 + llm-docs, 8 + }: 9 + 10 + buildPythonPackage rec { 11 + pname = "llm-docs"; 12 + version = "0.2.1"; 13 + pyproject = true; 14 + 15 + src = fetchFromGitHub { 16 + owner = "simonw"; 17 + repo = "llm-docs"; 18 + tag = version; 19 + hash = "sha256-+Ha6L2h8p/yA073MfO2Uvd6E4bKA2xAvaBWtvjqglOw="; 20 + }; 21 + 22 + build-system = [ setuptools ]; 23 + 24 + dependencies = [ llm ]; 25 + 26 + pythonImportsCheck = [ "llm_docs" ]; 27 + 28 + passthru.tests = llm.mkPluginTest llm-docs; 29 + 30 + meta = { 31 + description = "Ask questions of LLM documentation using LLM"; 32 + homepage = "https://github.com/simonw/llm-docs"; 33 + changelog = "https://github.com/simonw/llm-docs/releases/tag/${version}/CHANGELOG.md"; 34 + license = lib.licenses.asl20; 35 + maintainers = with lib.maintainers; [ philiptaron ]; 36 + }; 37 + }
+44
pkgs/development/python-modules/llm-echo/default.nix
···
··· 1 + { 2 + lib, 3 + buildPythonPackage, 4 + fetchFromGitHub, 5 + setuptools, 6 + llm, 7 + llm-echo, 8 + pytestCheckHook, 9 + writableTmpDirAsHomeHook, 10 + }: 11 + 12 + buildPythonPackage rec { 13 + pname = "llm-echo"; 14 + version = "0.3a3"; 15 + pyproject = true; 16 + 17 + src = fetchFromGitHub { 18 + owner = "simonw"; 19 + repo = "llm-echo"; 20 + tag = version; 21 + hash = "sha256-4345UIyaQx+mYYBAFD5AaX5YbjbnJQt8bKMD5Vl8VJc="; 22 + }; 23 + 24 + build-system = [ setuptools ]; 25 + 26 + dependencies = [ llm ]; 27 + 28 + nativeCheckInputs = [ 29 + pytestCheckHook 30 + writableTmpDirAsHomeHook 31 + ]; 32 + 33 + pythonImportsCheck = [ "llm_echo" ]; 34 + 35 + passthru.tests = llm.mkPluginTest llm-echo; 36 + 37 + meta = { 38 + description = "Debug plugin for LLM"; 39 + homepage = "https://github.com/simonw/llm-echo"; 40 + changelog = "https://github.com/simonw/llm-echo/releases/tag/${version}/CHANGELOG.md"; 41 + license = lib.licenses.asl20; 42 + maintainers = with lib.maintainers; [ philiptaron ]; 43 + }; 44 + }
+37
pkgs/development/python-modules/llm-fragments-github/default.nix
···
··· 1 + { 2 + lib, 3 + buildPythonPackage, 4 + fetchFromGitHub, 5 + setuptools, 6 + llm, 7 + llm-fragments-github, 8 + }: 9 + 10 + buildPythonPackage rec { 11 + pname = "llm-fragments-github"; 12 + version = "0.4"; 13 + pyproject = true; 14 + 15 + src = fetchFromGitHub { 16 + owner = "simonw"; 17 + repo = "llm-fragments-github"; 18 + tag = version; 19 + hash = "sha256-7i1WRix5AAEG5EXJqtaU+QY56aL0SePdqz84z+C+iYM="; 20 + }; 21 + 22 + build-system = [ setuptools ]; 23 + 24 + dependencies = [ llm ]; 25 + 26 + pythonImportsCheck = [ "llm_fragments_github" ]; 27 + 28 + passthru.tests = llm.mkPluginTest llm-fragments-github; 29 + 30 + meta = { 31 + description = "Load GitHub repository contents as LLM fragments"; 32 + homepage = "https://github.com/simonw/llm-fragments-github"; 33 + changelog = "https://github.com/simonw/llm-fragments-github/releases/tag/${version}/CHANGELOG.md"; 34 + license = lib.licenses.asl20; 35 + maintainers = with lib.maintainers; [ philiptaron ]; 36 + }; 37 + }
+41
pkgs/development/python-modules/llm-fragments-pypi/default.nix
···
··· 1 + { 2 + lib, 3 + buildPythonPackage, 4 + fetchFromGitHub, 5 + hatchling, 6 + llm, 7 + llm-fragments-pypi, 8 + httpx, 9 + }: 10 + 11 + buildPythonPackage rec { 12 + pname = "llm-fragments-pypi"; 13 + version = "0.1.1"; 14 + pyproject = true; 15 + 16 + src = fetchFromGitHub { 17 + owner = "samueldg"; 18 + repo = "llm-fragments-pypi"; 19 + tag = version; 20 + hash = "sha256-1XqAmuZ1WMHD6JbLbLsK9K4Uf3FvvKJD4mn1G2J/3C8="; 21 + }; 22 + 23 + build-system = [ hatchling ]; 24 + 25 + dependencies = [ 26 + httpx 27 + llm 28 + ]; 29 + 30 + pythonImportsCheck = [ "llm_fragments_pypi" ]; 31 + 32 + passthru.tests = llm.mkPluginTest llm-fragments-pypi; 33 + 34 + meta = { 35 + description = "LLM fragments plugin for PyPI packages metadata"; 36 + homepage = "https://github.com/samueldg/llm-fragments-pypi"; 37 + changelog = "https://github.com/samueldg/llm-fragments-pypi/releases/tag/${version}/CHANGELOG.md"; 38 + license = lib.licenses.asl20; 39 + maintainers = with lib.maintainers; [ philiptaron ]; 40 + }; 41 + }
+49
pkgs/development/python-modules/llm-fragments-reader/default.nix
···
··· 1 + { 2 + lib, 3 + buildPythonPackage, 4 + fetchFromGitHub, 5 + setuptools, 6 + httpx, 7 + httpx-sse, 8 + llm, 9 + llm-fragments-reader, 10 + pytestCheckHook, 11 + pytest-asyncio, 12 + pytest-httpx, 13 + writableTmpDirAsHomeHook, 14 + }: 15 + 16 + buildPythonPackage rec { 17 + pname = "llm-fragments-reader"; 18 + version = "0.1"; 19 + pyproject = true; 20 + 21 + src = fetchFromGitHub { 22 + owner = "simonw"; 23 + repo = "llm-fragments-reader"; 24 + tag = version; 25 + hash = "sha256-2xdvOpMGsTtnerrlGiVSHoJrM+GQ7Zgv+zn2SAwYAL4="; 26 + }; 27 + 28 + build-system = [ setuptools ]; 29 + 30 + dependencies = [ llm ]; 31 + 32 + nativeCheckInputs = [ 33 + pytestCheckHook 34 + pytest-httpx 35 + writableTmpDirAsHomeHook 36 + ]; 37 + 38 + pythonImportsCheck = [ "llm_fragments_reader" ]; 39 + 40 + passthru.tests = llm.mkPluginTest llm-fragments-reader; 41 + 42 + meta = { 43 + description = "Run URLs through the Jina Reader API"; 44 + homepage = "https://github.com/simonw/llm-fragments-reader"; 45 + changelog = "https://github.com/simonw/llm-fragments-reader/releases/tag/${version}/CHANGELOG.md"; 46 + license = lib.licenses.asl20; 47 + maintainers = with lib.maintainers; [ philiptaron ]; 48 + }; 49 + }
+48
pkgs/development/python-modules/llm-fragments-symbex/default.nix
···
··· 1 + { 2 + lib, 3 + buildPythonPackage, 4 + fetchFromGitHub, 5 + setuptools, 6 + symbex, 7 + llm, 8 + llm-fragments-symbex, 9 + pytestCheckHook, 10 + writableTmpDirAsHomeHook, 11 + }: 12 + 13 + buildPythonPackage rec { 14 + pname = "llm-fragments-symbex"; 15 + version = "0.1"; 16 + pyproject = true; 17 + 18 + src = fetchFromGitHub { 19 + owner = "simonw"; 20 + repo = "llm-fragments-symbex"; 21 + tag = version; 22 + hash = "sha256-LECMHv4tGMCY60JU68y2Sfxp97Px7T/RJVhYVDSFCy4="; 23 + }; 24 + 25 + build-system = [ setuptools ]; 26 + 27 + dependencies = [ 28 + llm 29 + symbex 30 + ]; 31 + 32 + nativeCheckInputs = [ 33 + pytestCheckHook 34 + writableTmpDirAsHomeHook 35 + ]; 36 + 37 + pythonImportsCheck = [ "llm_fragments_symbex" ]; 38 + 39 + passthru.tests = llm.mkPluginTest llm-fragments-symbex; 40 + 41 + meta = { 42 + description = "LLM fragment loader for Python symbols"; 43 + homepage = "https://github.com/simonw/llm-fragments-symbex"; 44 + changelog = "https://github.com/simonw/llm-fragments-symbex/releases/tag/${version}/CHANGELOG.md"; 45 + license = lib.licenses.asl20; 46 + maintainers = with lib.maintainers; [ philiptaron ]; 47 + }; 48 + }
+6 -10
pkgs/development/python-modules/llm-gemini/default.nix
··· 1 { 2 lib, 3 - callPackage, 4 buildPythonPackage, 5 fetchFromGitHub, 6 setuptools, 7 llm, 8 httpx, 9 ijson, 10 pytestCheckHook, ··· 15 }: 16 buildPythonPackage rec { 17 pname = "llm-gemini"; 18 - version = "0.20"; 19 pyproject = true; 20 21 src = fetchFromGitHub { 22 owner = "simonw"; 23 repo = "llm-gemini"; 24 tag = version; 25 - hash = "sha256-haaJtJ9RqV5/n/j8PNXPS7zc332W+gU20x0wGPRdzOQ="; 26 }; 27 28 - build-system = [ 29 - setuptools 30 - ]; 31 32 dependencies = [ 33 - llm 34 httpx 35 ijson 36 ]; 37 38 nativeCheckInputs = [ ··· 45 46 pythonImportsCheck = [ "llm_gemini" ]; 47 48 - passthru.tests = { 49 - llm-plugin = callPackage ./tests/llm-plugin.nix { }; 50 - }; 51 52 meta = { 53 description = "LLM plugin to access Google's Gemini family of models";
··· 1 { 2 lib, 3 buildPythonPackage, 4 fetchFromGitHub, 5 setuptools, 6 llm, 7 + llm-gemini, 8 httpx, 9 ijson, 10 pytestCheckHook, ··· 15 }: 16 buildPythonPackage rec { 17 pname = "llm-gemini"; 18 + version = "0.21"; 19 pyproject = true; 20 21 src = fetchFromGitHub { 22 owner = "simonw"; 23 repo = "llm-gemini"; 24 tag = version; 25 + hash = "sha256-aCP0YjcghzpgceuZRKGTN15wm7OIPCwcJAJJBxh78f4="; 26 }; 27 28 + build-system = [ setuptools ]; 29 30 dependencies = [ 31 httpx 32 ijson 33 + llm 34 ]; 35 36 nativeCheckInputs = [ ··· 43 44 pythonImportsCheck = [ "llm_gemini" ]; 45 46 + passthru.tests = llm.mkPluginTest llm-gemini; 47 48 meta = { 49 description = "LLM plugin to access Google's Gemini family of models";
-22
pkgs/development/python-modules/llm-gemini/tests/llm-plugin.nix
··· 1 - { 2 - runCommand, 3 - python, 4 - yq, 5 - }: 6 - let 7 - venv = python.withPackages (ps: [ 8 - ps.llm 9 - ps.llm-gemini 10 - ]); 11 - in 12 - runCommand "llm-gemini-test-llm-plugin" 13 - { 14 - nativeBuildInputs = [ 15 - venv 16 - yq 17 - ]; 18 - } 19 - '' 20 - llm plugins | yq --exit-status 'any(.name == "llm-gemini")' 21 - touch "$out" 22 - ''
···
+4 -8
pkgs/development/python-modules/llm-gguf/default.nix
··· 1 { 2 lib, 3 - callPackage, 4 buildPythonPackage, 5 fetchFromGitHub, 6 ··· 11 httpx, 12 llama-cpp-python, 13 llm, 14 }: 15 16 buildPythonPackage rec { ··· 25 hash = "sha256-ihMOiQnTfgZKICVDoQHLOMahrd+GiB+HwWFBMyIcs0A="; 26 }; 27 28 - build-system = [ 29 - setuptools 30 - ]; 31 32 dependencies = [ 33 httpx 34 - llama-cpp-python 35 llm 36 ]; 37 38 pythonImportsCheck = [ "llm_gguf" ]; ··· 40 # Tests require internet access (downloading models) 41 doCheck = false; 42 43 - passthru.tests = { 44 - llm-plugin = callPackage ./tests/llm-plugin.nix { }; 45 - }; 46 47 meta = { 48 description = "Run models distributed as GGUF files using LLM";
··· 1 { 2 lib, 3 buildPythonPackage, 4 fetchFromGitHub, 5 ··· 10 httpx, 11 llama-cpp-python, 12 llm, 13 + llm-gguf, 14 }: 15 16 buildPythonPackage rec { ··· 25 hash = "sha256-ihMOiQnTfgZKICVDoQHLOMahrd+GiB+HwWFBMyIcs0A="; 26 }; 27 28 + build-system = [ setuptools ]; 29 30 dependencies = [ 31 httpx 32 llm 33 + llama-cpp-python 34 ]; 35 36 pythonImportsCheck = [ "llm_gguf" ]; ··· 38 # Tests require internet access (downloading models) 39 doCheck = false; 40 41 + passthru.tests = llm.mkPluginTest llm-gguf; 42 43 meta = { 44 description = "Run models distributed as GGUF files using LLM";
-22
pkgs/development/python-modules/llm-gguf/tests/llm-plugin.nix
··· 1 - { 2 - runCommand, 3 - python, 4 - yq, 5 - }: 6 - let 7 - venv = python.withPackages (ps: [ 8 - ps.llm 9 - ps.llm-gguf 10 - ]); 11 - in 12 - runCommand "llm-gguf-test-llm-plugin" 13 - { 14 - nativeBuildInputs = [ 15 - venv 16 - yq 17 - ]; 18 - } 19 - '' 20 - llm plugins | yq --exit-status 'any(.name == "llm-gguf")' 21 - touch "$out" 22 - ''
···
+62
pkgs/development/python-modules/llm-git/default.nix
···
··· 1 + { 2 + lib, 3 + buildPythonPackage, 4 + fetchFromGitHub, 5 + setuptools, 6 + click, 7 + deepmerge, 8 + pyyaml, 9 + rich, 10 + pygments, 11 + llm, 12 + llm-git, 13 + pytestCheckHook, 14 + pytest-cov-stub, 15 + pytest-asyncio, 16 + pytest-httpx, 17 + writableTmpDirAsHomeHook, 18 + }: 19 + 20 + buildPythonPackage rec { 21 + pname = "llm-git"; 22 + version = "0.2.2"; 23 + pyproject = true; 24 + 25 + src = fetchFromGitHub { 26 + owner = "OttoAllmendinger"; 27 + repo = "llm-git"; 28 + tag = "v${version}"; 29 + hash = "sha256-LcIsJPQgZ4gj2t7sSa0Wu35WHWYyquZZTS/UxojH+XU="; 30 + }; 31 + 32 + build-system = [ 33 + setuptools 34 + ]; 35 + 36 + dependencies = [ 37 + click 38 + deepmerge 39 + llm 40 + pyyaml 41 + rich 42 + pygments 43 + ]; 44 + 45 + nativeCheckInputs = [ 46 + pytestCheckHook 47 + pytest-cov-stub 48 + writableTmpDirAsHomeHook 49 + ]; 50 + 51 + pythonImportsCheck = [ "llm_git" ]; 52 + 53 + passthru.tests = llm.mkPluginTest llm-git; 54 + 55 + meta = { 56 + description = "AI-powered Git commands for the LLM CLI tool"; 57 + homepage = "https://github.com/OttoAllmendinger/llm-git"; 58 + changelog = "https://github.com/OttoAllmendinger/llm-git/releases/tag/${version}/CHANGELOG.md"; 59 + license = lib.licenses.asl20; 60 + maintainers = with lib.maintainers; [ philiptaron ]; 61 + }; 62 + }
+54
pkgs/development/python-modules/llm-grok/default.nix
···
··· 1 + { 2 + lib, 3 + buildPythonPackage, 4 + fetchFromGitHub, 5 + setuptools, 6 + llm, 7 + llm-grok, 8 + httpx, 9 + httpx-sse, 10 + rich, 11 + pytestCheckHook, 12 + pytest-httpx, 13 + writableTmpDirAsHomeHook, 14 + }: 15 + 16 + buildPythonPackage rec { 17 + pname = "llm-grok"; 18 + version = "1.0.1"; 19 + pyproject = true; 20 + 21 + src = fetchFromGitHub { 22 + owner = "Hiepler"; 23 + repo = "llm-grok"; 24 + tag = "v${version}"; 25 + hash = "sha256-OeeU/53XKucLCtGvnl5RWc/QqF0TprB/SO8pnnK5fdw="; 26 + }; 27 + 28 + build-system = [ setuptools ]; 29 + 30 + dependencies = [ 31 + llm 32 + httpx 33 + httpx-sse 34 + rich 35 + ]; 36 + 37 + nativeCheckInputs = [ 38 + pytestCheckHook 39 + pytest-httpx 40 + writableTmpDirAsHomeHook 41 + ]; 42 + 43 + pythonImportsCheck = [ "llm_grok" ]; 44 + 45 + passthru.tests = llm.mkPluginTest llm-grok; 46 + 47 + meta = { 48 + description = "LLM plugin providing access to Grok models using the xAI API"; 49 + homepage = "https://github.com/Hiepler/llm-grok"; 50 + changelog = "https://github.com/Hiepler/llm-grok/releases/tag/${src.tag}/CHANGELOG.md"; 51 + license = lib.licenses.asl20; 52 + maintainers = with lib.maintainers; [ philiptaron ]; 53 + }; 54 + }
+43
pkgs/development/python-modules/llm-groq/default.nix
···
··· 1 + { 2 + lib, 3 + buildPythonPackage, 4 + fetchFromGitHub, 5 + setuptools, 6 + llm, 7 + llm-groq, 8 + groq, 9 + }: 10 + 11 + buildPythonPackage rec { 12 + pname = "llm-groq"; 13 + version = "0.8"; 14 + pyproject = true; 15 + 16 + src = fetchFromGitHub { 17 + owner = "angerman"; 18 + repo = "llm-groq"; 19 + tag = "v${version}"; 20 + hash = "sha256-sZ5d9w43NvypaPrebwZ5BLgRaCHAhd7gBU6uHEdUaF4="; 21 + }; 22 + 23 + build-system = [ 24 + setuptools 25 + ]; 26 + 27 + dependencies = [ 28 + groq 29 + llm 30 + ]; 31 + 32 + pythonImportsCheck = [ "llm_groq" ]; 33 + 34 + passthru.tests = llm.mkPluginTest llm-groq; 35 + 36 + meta = { 37 + description = "LLM plugin providing access to Groqcloud models."; 38 + homepage = "https://github.com/angerman/llm-groq"; 39 + changelog = "https://github.com/angerman/llm-groq/releases/tag/${src.tag}/CHANGELOG.md"; 40 + license = lib.licenses.asl20; 41 + maintainers = with lib.maintainers; [ philiptaron ]; 42 + }; 43 + }
+37
pkgs/development/python-modules/llm-hacker-news/default.nix
···
··· 1 + { 2 + lib, 3 + buildPythonPackage, 4 + fetchFromGitHub, 5 + setuptools, 6 + llm, 7 + llm-hacker-news, 8 + }: 9 + 10 + buildPythonPackage rec { 11 + pname = "llm-hacker-news"; 12 + version = "0.1.1"; 13 + pyproject = true; 14 + 15 + src = fetchFromGitHub { 16 + owner = "simonw"; 17 + repo = "llm-hacker-news"; 18 + tag = version; 19 + hash = "sha256-pywx9TAN/mnGR6Vv6YsPhLO4R5Geagw/bcydQjvTH5s="; 20 + }; 21 + 22 + build-system = [ setuptools ]; 23 + 24 + dependencies = [ llm ]; 25 + 26 + pythonImportsCheck = [ "llm_hacker_news" ]; 27 + 28 + passthru.tests = llm.mkPluginTest llm-hacker-news; 29 + 30 + meta = { 31 + description = "LLM plugin for pulling content from Hacker News"; 32 + homepage = "https://github.com/simonw/llm-hacker-news"; 33 + changelog = "https://github.com/simonw/llm-hacker-news/releases/tag/${version}/CHANGELOG.md"; 34 + license = lib.licenses.asl20; 35 + maintainers = with lib.maintainers; [ philiptaron ]; 36 + }; 37 + }
+4 -11
pkgs/development/python-modules/llm-jq/default.nix
··· 1 { 2 lib, 3 - callPackage, 4 buildPythonPackage, 5 fetchFromGitHub, 6 setuptools, 7 llm, 8 - nix-update-script, 9 }: 10 buildPythonPackage rec { 11 pname = "llm-jq"; ··· 19 hash = "sha256-Mf/tbB9+UdmSRpulqv5Wagr8wjDcRrNs2741DNQZhO4="; 20 }; 21 22 - build-system = [ 23 - setuptools 24 - ]; 25 26 - dependencies = [ 27 - llm 28 - ]; 29 30 pythonImportsCheck = [ "llm_jq" ]; 31 32 - passthru.tests = { 33 - llm-plugin = callPackage ./tests/llm-plugin.nix { }; 34 - }; 35 36 meta = { 37 description = "Write and execute jq programs with the help of LLM";
··· 1 { 2 lib, 3 buildPythonPackage, 4 fetchFromGitHub, 5 setuptools, 6 llm, 7 + llm-jq, 8 }: 9 buildPythonPackage rec { 10 pname = "llm-jq"; ··· 18 hash = "sha256-Mf/tbB9+UdmSRpulqv5Wagr8wjDcRrNs2741DNQZhO4="; 19 }; 20 21 + build-system = [ setuptools ]; 22 23 + dependencies = [ llm ]; 24 25 pythonImportsCheck = [ "llm_jq" ]; 26 27 + passthru.tests = llm.mkPluginTest llm-jq; 28 29 meta = { 30 description = "Write and execute jq programs with the help of LLM";
-23
pkgs/development/python-modules/llm-jq/tests/llm-plugin.nix
··· 1 - { 2 - runCommand, 3 - python, 4 - yq, 5 - }: 6 - let 7 - venv = python.withPackages (ps: [ 8 - ps.llm 9 - ps.llm-jq 10 - ]); 11 - in 12 - runCommand "llm-jq-test-llm-plugin" 13 - { 14 - nativeBuildInputs = [ 15 - venv 16 - yq 17 - ]; 18 - } 19 - '' 20 - llm plugins | yq --exit-status 'any(.name == "llm-jq")' 21 - llm jq --help 22 - touch "$out" 23 - ''
···
+44
pkgs/development/python-modules/llm-llama-server/default.nix
···
··· 1 + { 2 + lib, 3 + buildPythonPackage, 4 + fetchFromGitHub, 5 + setuptools, 6 + llm, 7 + llm-llama-server, 8 + pytestCheckHook, 9 + writableTmpDirAsHomeHook, 10 + }: 11 + 12 + buildPythonPackage rec { 13 + pname = "llm-llama-server"; 14 + version = "0.2"; 15 + pyproject = true; 16 + 17 + src = fetchFromGitHub { 18 + owner = "simonw"; 19 + repo = "llm-llama-server"; 20 + tag = version; 21 + hash = "sha256-jtFSfGu3JhNUfTsspY+OFLTMt9jQrh6R05sK9KBOKTE="; 22 + }; 23 + 24 + build-system = [ setuptools ]; 25 + 26 + dependencies = [ llm ]; 27 + 28 + nativeCheckInputs = [ 29 + pytestCheckHook 30 + writableTmpDirAsHomeHook 31 + ]; 32 + 33 + pythonImportsCheck = [ "llm_llama_server" ]; 34 + 35 + passthru.tests = llm.mkPluginTest llm-llama-server; 36 + 37 + meta = { 38 + description = "LLM plugin providing access to Mistral models using the Mistral API"; 39 + homepage = "https://github.com/simonw/llm-llama-server"; 40 + changelog = "https://github.com/simonw/llm-llama-server/releases/tag/${version}/CHANGELOG.md"; 41 + license = lib.licenses.asl20; 42 + maintainers = with lib.maintainers; [ philiptaron ]; 43 + }; 44 + }
+56
pkgs/development/python-modules/llm-mistral/default.nix
···
··· 1 + { 2 + lib, 3 + buildPythonPackage, 4 + fetchFromGitHub, 5 + setuptools, 6 + httpx, 7 + httpx-sse, 8 + llm, 9 + llm-mistral, 10 + pytestCheckHook, 11 + pytest-asyncio, 12 + pytest-httpx, 13 + writableTmpDirAsHomeHook, 14 + }: 15 + 16 + buildPythonPackage rec { 17 + pname = "llm-mistral"; 18 + version = "0.14"; 19 + pyproject = true; 20 + 21 + src = fetchFromGitHub { 22 + owner = "simonw"; 23 + repo = "llm-mistral"; 24 + tag = version; 25 + hash = "sha256-NuiqRA/SCjGq0hJsnHJ/vgdncIKu3oE9WqWGht7QRMc="; 26 + }; 27 + 28 + build-system = [ 29 + setuptools 30 + ]; 31 + 32 + dependencies = [ 33 + httpx 34 + httpx-sse 35 + llm 36 + ]; 37 + 38 + nativeCheckInputs = [ 39 + pytestCheckHook 40 + pytest-asyncio 41 + pytest-httpx 42 + writableTmpDirAsHomeHook 43 + ]; 44 + 45 + pythonImportsCheck = [ "llm_mistral" ]; 46 + 47 + passthru.tests = llm.mkPluginTest llm-mistral; 48 + 49 + meta = { 50 + description = "LLM plugin providing access to Mistral models using the Mistral API"; 51 + homepage = "https://github.com/simonw/llm-mistral"; 52 + changelog = "https://github.com/simonw/llm-mistral/releases/tag/${version}/CHANGELOG.md"; 53 + license = lib.licenses.asl20; 54 + maintainers = with lib.maintainers; [ philiptaron ]; 55 + }; 56 + }
+6 -11
pkgs/development/python-modules/llm-ollama/default.nix
··· 1 { 2 lib, 3 - callPackage, 4 buildPythonPackage, 5 fetchFromGitHub, 6 ··· 18 pytest-asyncio, 19 pytest-mock, 20 writableTmpDirAsHomeHook, 21 }: 22 23 buildPythonPackage rec { 24 pname = "llm-ollama"; 25 - version = "0.10.0"; 26 pyproject = true; 27 28 src = fetchFromGitHub { 29 owner = "taketwo"; 30 repo = "llm-ollama"; 31 tag = version; 32 - hash = "sha256-IA9Tb82XB+Gr6YwMVqzsw1dPtT3GWK2W/ZtuDVznF1A"; 33 }; 34 35 - build-system = [ 36 - setuptools 37 - # Follows the reasoning from https://github.com/NixOS/nixpkgs/pull/327800#discussion_r1681586659 about including llm in build-system 38 - llm 39 - ]; 40 41 dependencies = [ 42 click 43 ollama 44 pydantic 45 ]; ··· 55 "llm_ollama" 56 ]; 57 58 - passthru.tests = { 59 - llm-plugin = callPackage ./tests/llm-plugin.nix { }; 60 - }; 61 62 meta = { 63 description = "LLM plugin providing access to Ollama models using HTTP API";
··· 1 { 2 lib, 3 buildPythonPackage, 4 fetchFromGitHub, 5 ··· 17 pytest-asyncio, 18 pytest-mock, 19 writableTmpDirAsHomeHook, 20 + llm-ollama, 21 }: 22 23 buildPythonPackage rec { 24 pname = "llm-ollama"; 25 + version = "0.11.0"; 26 pyproject = true; 27 28 src = fetchFromGitHub { 29 owner = "taketwo"; 30 repo = "llm-ollama"; 31 tag = version; 32 + hash = "sha256-iwrDqrPt/zwXypBwD7zDAcen4fQq6PXl7Xj5VUL2KWA="; 33 }; 34 35 + build-system = [ setuptools ]; 36 37 dependencies = [ 38 click 39 + llm 40 ollama 41 pydantic 42 ]; ··· 52 "llm_ollama" 53 ]; 54 55 + passthru.tests = llm.mkPluginTest llm-ollama; 56 57 meta = { 58 description = "LLM plugin providing access to Ollama models using HTTP API";
-24
pkgs/development/python-modules/llm-ollama/tests/llm-plugin.nix
··· 1 - { 2 - runCommand, 3 - python, 4 - yq, 5 - cacert, 6 - }: 7 - let 8 - venv = python.withPackages (ps: [ 9 - ps.llm 10 - ps.llm-ollama 11 - ]); 12 - in 13 - runCommand "llm-ollama-test-llm-plugin" 14 - { 15 - nativeBuildInputs = [ 16 - venv 17 - yq 18 - ]; 19 - env.SSL_CERT_FILE = "${cacert}/etc/ssl/certs/ca-bundle.crt"; 20 - } 21 - '' 22 - llm plugins | yq --exit-status 'any(.name == "llm-ollama")' 23 - touch "$out" 24 - ''
···
+3 -7
pkgs/development/python-modules/llm-openai-plugin/default.nix
··· 1 { 2 lib, 3 - callPackage, 4 buildPythonPackage, 5 fetchFromGitHub, 6 setuptools, 7 llm, 8 openai, 9 pytestCheckHook, 10 pytest-asyncio, ··· 25 hash = "sha256-UoUxCwR+qOUufHuS0gw6A5Q7sB77VO4HYuMjFGN7mhA="; 26 }; 27 28 - build-system = [ 29 - setuptools 30 - ]; 31 32 dependencies = [ 33 llm ··· 45 46 pythonImportsCheck = [ "llm_openai" ]; 47 48 - passthru.tests = { 49 - llm-plugin = callPackage ./tests/llm-plugin.nix { }; 50 - }; 51 52 meta = { 53 description = "OpenAI plugin for LLM";
··· 1 { 2 lib, 3 buildPythonPackage, 4 fetchFromGitHub, 5 setuptools, 6 llm, 7 + llm-openai-plugin, 8 openai, 9 pytestCheckHook, 10 pytest-asyncio, ··· 25 hash = "sha256-UoUxCwR+qOUufHuS0gw6A5Q7sB77VO4HYuMjFGN7mhA="; 26 }; 27 28 + build-system = [ setuptools ]; 29 30 dependencies = [ 31 llm ··· 43 44 pythonImportsCheck = [ "llm_openai" ]; 45 46 + passthru.tests = llm.mkPluginTest llm-openai-plugin; 47 48 meta = { 49 description = "OpenAI plugin for LLM";
-22
pkgs/development/python-modules/llm-openai-plugin/tests/llm-plugin.nix
··· 1 - { 2 - runCommand, 3 - python, 4 - yq, 5 - }: 6 - let 7 - venv = python.withPackages (ps: [ 8 - ps.llm 9 - ps.llm-openai-plugin 10 - ]); 11 - in 12 - runCommand "llm-openai-plugin-test-llm-plugin" 13 - { 14 - nativeBuildInputs = [ 15 - venv 16 - yq 17 - ]; 18 - } 19 - '' 20 - llm plugins | yq --exit-status 'any(.name == "llm-openai-plugin")' 21 - touch "$out" 22 - ''
···
+56
pkgs/development/python-modules/llm-openrouter/default.nix
···
··· 1 + { 2 + lib, 3 + buildPythonPackage, 4 + fetchFromGitHub, 5 + setuptools, 6 + llm, 7 + llm-openrouter, 8 + httpx, 9 + openai, 10 + pytestCheckHook, 11 + inline-snapshot, 12 + pytest-recording, 13 + writableTmpDirAsHomeHook, 14 + }: 15 + 16 + buildPythonPackage rec { 17 + pname = "llm-openrouter"; 18 + version = "0.4.1"; 19 + pyproject = true; 20 + 21 + src = fetchFromGitHub { 22 + owner = "simonw"; 23 + repo = "llm-openrouter"; 24 + tag = version; 25 + hash = "sha256-ojBkyXqEaqTcOv7mzTWL5Ihhb50zeVzeQZNA6DySuVg="; 26 + }; 27 + 28 + build-system = [ 29 + setuptools 30 + ]; 31 + 32 + dependencies = [ 33 + httpx 34 + llm 35 + openai 36 + ]; 37 + 38 + nativeCheckInputs = [ 39 + pytestCheckHook 40 + inline-snapshot 41 + pytest-recording 42 + writableTmpDirAsHomeHook 43 + ]; 44 + 45 + pythonImportsCheck = [ "llm_openrouter" ]; 46 + 47 + passthru.tests = llm.mkPluginTest llm-openrouter; 48 + 49 + meta = { 50 + description = "LLM plugin for models hosted by OpenRouter"; 51 + homepage = "https://github.com/simonw/llm-openrouter"; 52 + changelog = "https://github.com/simonw/llm-openrouter/releases/tag/${version}/CHANGELOG.md"; 53 + license = lib.licenses.asl20; 54 + maintainers = with lib.maintainers; [ philiptaron ]; 55 + }; 56 + }
+49
pkgs/development/python-modules/llm-pdf-to-images/default.nix
···
··· 1 + { 2 + lib, 3 + buildPythonPackage, 4 + fetchFromGitHub, 5 + setuptools, 6 + pymupdf, 7 + llm, 8 + llm-pdf-to-images, 9 + pytestCheckHook, 10 + pytest-asyncio, 11 + writableTmpDirAsHomeHook, 12 + }: 13 + 14 + buildPythonPackage rec { 15 + pname = "llm-pdf-to-images"; 16 + version = "0.1"; 17 + pyproject = true; 18 + 19 + src = fetchFromGitHub { 20 + owner = "simonw"; 21 + repo = "llm-pdf-to-images"; 22 + tag = version; 23 + hash = "sha256-UWtCPdKrGE93NNjCroct5fPhq1pWIkngXXtRb+BHm8k="; 24 + }; 25 + 26 + build-system = [ setuptools ]; 27 + 28 + dependencies = [ 29 + llm 30 + pymupdf 31 + ]; 32 + 33 + nativeCheckInputs = [ 34 + pytestCheckHook 35 + writableTmpDirAsHomeHook 36 + ]; 37 + 38 + pythonImportsCheck = [ "llm_pdf_to_images" ]; 39 + 40 + passthru.tests = llm.mkPluginTest llm-pdf-to-images; 41 + 42 + meta = { 43 + description = "LLM fragment plugin to load a PDF as a sequence of images"; 44 + homepage = "https://github.com/simonw/llm-pdf-to-images"; 45 + changelog = "https://github.com/simonw/llm-pdf-to-images/releases/tag/${version}/CHANGELOG.md"; 46 + license = lib.licenses.asl20; 47 + maintainers = with lib.maintainers; [ philiptaron ]; 48 + }; 49 + }
+56
pkgs/development/python-modules/llm-sentence-transformers/default.nix
···
··· 1 + { 2 + lib, 3 + buildPythonPackage, 4 + fetchFromGitHub, 5 + setuptools, 6 + llm, 7 + llm-sentence-transformers, 8 + einops, 9 + sentence-transformers, 10 + pytestCheckHook, 11 + writableTmpDirAsHomeHook, 12 + }: 13 + 14 + buildPythonPackage rec { 15 + pname = "llm-sentence-transformers"; 16 + version = "0.3.2"; 17 + pyproject = true; 18 + 19 + src = fetchFromGitHub { 20 + owner = "simonw"; 21 + repo = "llm-sentence-transformers"; 22 + tag = version; 23 + hash = "sha256-FDDMItKFEYEptiL3EHKgKVxClqRU9RaM3uD3xP0F4OM="; 24 + }; 25 + 26 + build-system = [ setuptools ]; 27 + 28 + dependencies = [ 29 + einops 30 + llm 31 + sentence-transformers 32 + ]; 33 + 34 + nativeCheckInputs = [ 35 + pytestCheckHook 36 + writableTmpDirAsHomeHook 37 + ]; 38 + 39 + # Disabled because they access the network 40 + disabledTests = [ 41 + "test_run_embedding" 42 + "test_embed_multi_with_generator" 43 + ]; 44 + 45 + pythonImportsCheck = [ "llm_sentence_transformers" ]; 46 + 47 + passthru.tests = llm.mkPluginTest llm-sentence-transformers; 48 + 49 + meta = { 50 + description = "LLM plugin for embeddings using sentence-transformers"; 51 + homepage = "https://github.com/simonw/llm-sentence-transformers"; 52 + changelog = "https://github.com/simonw/llm-sentence-transformers/releases/tag/${version}/CHANGELOG.md"; 53 + license = lib.licenses.asl20; 54 + maintainers = with lib.maintainers; [ philiptaron ]; 55 + }; 56 + }
+37
pkgs/development/python-modules/llm-templates-fabric/default.nix
···
··· 1 + { 2 + lib, 3 + buildPythonPackage, 4 + fetchFromGitHub, 5 + setuptools, 6 + llm, 7 + llm-templates-fabric, 8 + }: 9 + 10 + buildPythonPackage rec { 11 + pname = "llm-templates-fabric"; 12 + version = "0.2"; 13 + pyproject = true; 14 + 15 + src = fetchFromGitHub { 16 + owner = "simonw"; 17 + repo = "llm-templates-fabric"; 18 + tag = version; 19 + hash = "sha256-tfkSjeT9WstUsNCtVr3fMzqELFCtfYphqf3xFGvHaV0="; 20 + }; 21 + 22 + build-system = [ setuptools ]; 23 + 24 + dependencies = [ llm ]; 25 + 26 + pythonImportsCheck = [ "llm_templates_fabric" ]; 27 + 28 + passthru.tests = llm.mkPluginTest llm-templates-fabric; 29 + 30 + meta = { 31 + description = "Load LLM templates from Fabric"; 32 + homepage = "https://github.com/simonw/llm-templates-fabric"; 33 + changelog = "https://github.com/simonw/llm-templates-fabric/releases/tag/${version}/CHANGELOG.md"; 34 + license = lib.licenses.asl20; 35 + maintainers = with lib.maintainers; [ philiptaron ]; 36 + }; 37 + }
+37
pkgs/development/python-modules/llm-templates-github/default.nix
···
··· 1 + { 2 + lib, 3 + buildPythonPackage, 4 + fetchFromGitHub, 5 + setuptools, 6 + llm, 7 + llm-templates-github, 8 + }: 9 + 10 + buildPythonPackage rec { 11 + pname = "llm-templates-github"; 12 + version = "0.1"; 13 + pyproject = true; 14 + 15 + src = fetchFromGitHub { 16 + owner = "simonw"; 17 + repo = "llm-templates-github"; 18 + tag = version; 19 + hash = "sha256-SFXrvpKrvfIP0JmXQt6OZ52kne4AEtiggbshyac9XQc="; 20 + }; 21 + 22 + build-system = [ setuptools ]; 23 + 24 + dependencies = [ llm ]; 25 + 26 + pythonImportsCheck = [ "llm_templates_github" ]; 27 + 28 + passthru.tests = llm.mkPluginTest llm-templates-github; 29 + 30 + meta = { 31 + description = "Load LLM templates from GitHub repositories"; 32 + homepage = "https://github.com/simonw/llm-templates-github"; 33 + changelog = "https://github.com/simonw/llm-templates-github/releases/tag/${version}/CHANGELOG.md"; 34 + license = lib.licenses.asl20; 35 + maintainers = with lib.maintainers; [ philiptaron ]; 36 + }; 37 + }
+48
pkgs/development/python-modules/llm-tools-datasette/default.nix
···
··· 1 + { 2 + lib, 3 + buildPythonPackage, 4 + fetchFromGitHub, 5 + setuptools, 6 + llm, 7 + llm-tools-datasette, 8 + llm-echo, 9 + pytestCheckHook, 10 + pytest-httpx, 11 + writableTmpDirAsHomeHook, 12 + }: 13 + 14 + buildPythonPackage rec { 15 + pname = "llm-tools-datasette"; 16 + version = "0.1"; 17 + pyproject = true; 18 + 19 + src = fetchFromGitHub { 20 + owner = "simonw"; 21 + repo = "llm-tools-datasette"; 22 + tag = version; 23 + hash = "sha256-Us9bPk2qpTlgJqQ0Cl9QdeqW+h8j+pmnkriM0WXEyyA="; 24 + }; 25 + 26 + build-system = [ setuptools ]; 27 + 28 + dependencies = [ llm ]; 29 + 30 + nativeCheckInputs = [ 31 + llm-echo 32 + pytestCheckHook 33 + pytest-httpx 34 + writableTmpDirAsHomeHook 35 + ]; 36 + 37 + pythonImportsCheck = [ "llm_tools_datasette" ]; 38 + 39 + passthru.tests = llm.mkPluginTest llm-tools-datasette; 40 + 41 + meta = { 42 + description = "Expose Datasette instances to LLM as a tool"; 43 + homepage = "https://github.com/simonw/llm-tools-datasette"; 44 + changelog = "https://github.com/simonw/llm-tools-datasette/releases/tag/${version}/CHANGELOG.md"; 45 + license = lib.licenses.asl20; 46 + maintainers = with lib.maintainers; [ philiptaron ]; 47 + }; 48 + }
+50
pkgs/development/python-modules/llm-tools-quickjs/default.nix
···
··· 1 + { 2 + lib, 3 + buildPythonPackage, 4 + fetchFromGitHub, 5 + setuptools, 6 + quickjs, 7 + llm, 8 + llm-tools-quickjs, 9 + llm-echo, 10 + pytestCheckHook, 11 + writableTmpDirAsHomeHook, 12 + }: 13 + 14 + buildPythonPackage rec { 15 + pname = "llm-tools-quickjs"; 16 + version = "0.1"; 17 + pyproject = true; 18 + 19 + src = fetchFromGitHub { 20 + owner = "simonw"; 21 + repo = "llm-tools-quickjs"; 22 + tag = version; 23 + hash = "sha256-Si3VcHnRUj8Q/N8pRhltPOM6K64TX9DBH/u4WQxQJjQ="; 24 + }; 25 + 26 + build-system = [ setuptools ]; 27 + 28 + dependencies = [ 29 + llm 30 + quickjs 31 + ]; 32 + 33 + nativeCheckInputs = [ 34 + llm-echo 35 + pytestCheckHook 36 + writableTmpDirAsHomeHook 37 + ]; 38 + 39 + pythonImportsCheck = [ "llm_tools_quickjs" ]; 40 + 41 + passthru.tests = llm.mkPluginTest llm-tools-quickjs; 42 + 43 + meta = { 44 + description = "JavaScript execution as a tool for LLM"; 45 + homepage = "https://github.com/simonw/llm-tools-quickjs"; 46 + changelog = "https://github.com/simonw/llm-tools-quickjs/releases/tag/${version}/CHANGELOG.md"; 47 + license = lib.licenses.asl20; 48 + maintainers = with lib.maintainers; [ philiptaron ]; 49 + }; 50 + }
+50
pkgs/development/python-modules/llm-tools-simpleeval/default.nix
···
··· 1 + { 2 + lib, 3 + buildPythonPackage, 4 + fetchFromGitHub, 5 + setuptools, 6 + llm, 7 + llm-tools-simpleeval, 8 + llm-echo, 9 + pytestCheckHook, 10 + simpleeval, 11 + writableTmpDirAsHomeHook, 12 + }: 13 + 14 + buildPythonPackage rec { 15 + pname = "llm-tools-simpleeval"; 16 + version = "0.1.1"; 17 + pyproject = true; 18 + 19 + src = fetchFromGitHub { 20 + owner = "simonw"; 21 + repo = "llm-tools-simpleeval"; 22 + tag = version; 23 + hash = "sha256-IOmYu7zoim7Co/xIm5VLaGkCPI0o+2Nb2Pu3U2fH0BU="; 24 + }; 25 + 26 + build-system = [ setuptools ]; 27 + 28 + dependencies = [ 29 + llm 30 + simpleeval 31 + ]; 32 + 33 + nativeCheckInputs = [ 34 + llm-echo 35 + pytestCheckHook 36 + writableTmpDirAsHomeHook 37 + ]; 38 + 39 + pythonImportsCheck = [ "llm_tools_simpleeval" ]; 40 + 41 + passthru.tests = llm.mkPluginTest llm-tools-simpleeval; 42 + 43 + meta = { 44 + description = "Make simple_eval available as an LLM tool"; 45 + homepage = "https://github.com/simonw/llm-tools-simpleeval"; 46 + changelog = "https://github.com/simonw/llm-tools-simpleeval/releases/tag/${version}/CHANGELOG.md"; 47 + license = lib.licenses.asl20; 48 + maintainers = with lib.maintainers; [ philiptaron ]; 49 + }; 50 + }
+46
pkgs/development/python-modules/llm-tools-sqlite/default.nix
···
··· 1 + { 2 + lib, 3 + buildPythonPackage, 4 + fetchFromGitHub, 5 + setuptools, 6 + llm, 7 + llm-tools-sqlite, 8 + llm-echo, 9 + pytestCheckHook, 10 + writableTmpDirAsHomeHook, 11 + }: 12 + 13 + buildPythonPackage rec { 14 + pname = "llm-tools-sqlite"; 15 + version = "0.1"; 16 + pyproject = true; 17 + 18 + src = fetchFromGitHub { 19 + owner = "simonw"; 20 + repo = "llm-tools-sqlite"; 21 + tag = version; 22 + hash = "sha256-VAmK4cXzZWTWCU92TwMdhNJPvYPZ88t5BZe8vo60SZY="; 23 + }; 24 + 25 + build-system = [ setuptools ]; 26 + 27 + dependencies = [ llm ]; 28 + 29 + nativeCheckInputs = [ 30 + llm-echo 31 + pytestCheckHook 32 + writableTmpDirAsHomeHook 33 + ]; 34 + 35 + pythonImportsCheck = [ "llm_tools_sqlite" ]; 36 + 37 + passthru.tests = llm.mkPluginTest llm-tools-sqlite; 38 + 39 + meta = { 40 + description = "LLM tools for running queries against SQLite"; 41 + homepage = "https://github.com/simonw/llm-tools-sqlite"; 42 + changelog = "https://github.com/simonw/llm-tools-sqlite/releases/tag/${version}/CHANGELOG.md"; 43 + license = lib.licenses.asl20; 44 + maintainers = with lib.maintainers; [ philiptaron ]; 45 + }; 46 + }
+40
pkgs/development/python-modules/llm-venice/default.nix
···
··· 1 + { 2 + lib, 3 + buildPythonPackage, 4 + fetchFromGitHub, 5 + setuptools, 6 + llm, 7 + llm-venice, 8 + }: 9 + 10 + buildPythonPackage rec { 11 + pname = "llm-venice"; 12 + version = "0.7.0"; 13 + pyproject = true; 14 + 15 + src = fetchFromGitHub { 16 + owner = "ar-jan"; 17 + repo = "llm-venice"; 18 + tag = version; 19 + hash = "sha256-vsb3oXGr+2FDJnTwYomICfald1ptben28hAJ8ypKiBI="; 20 + }; 21 + 22 + build-system = [ setuptools ]; 23 + 24 + dependencies = [ llm ]; 25 + 26 + # Reaches out to the real API 27 + doCheck = false; 28 + 29 + pythonImportsCheck = [ "llm_venice" ]; 30 + 31 + passthru.tests = llm.mkPluginTest llm-venice; 32 + 33 + meta = { 34 + description = "LLM plugin to access models available via the Venice API"; 35 + homepage = "https://github.com/ar-jan/llm-venice"; 36 + changelog = "https://github.com/ar-jan/llm-venice/releases/tag/${version}/CHANGELOG.md"; 37 + license = lib.licenses.asl20; 38 + maintainers = with lib.maintainers; [ philiptaron ]; 39 + }; 40 + }
+37
pkgs/development/python-modules/llm-video-frames/default.nix
···
··· 1 + { 2 + lib, 3 + buildPythonPackage, 4 + fetchFromGitHub, 5 + setuptools, 6 + llm, 7 + llm-video-frames, 8 + }: 9 + 10 + buildPythonPackage rec { 11 + pname = "llm-video-frames"; 12 + version = "0.1"; 13 + pyproject = true; 14 + 15 + src = fetchFromGitHub { 16 + owner = "simonw"; 17 + repo = "llm-video-frames"; 18 + tag = version; 19 + hash = "sha256-brTyBymoFuvSQzsD/4aWzFGCrh3yEmWbpsUNGKT9dcU="; 20 + }; 21 + 22 + build-system = [ setuptools ]; 23 + 24 + dependencies = [ llm ]; 25 + 26 + pythonImportsCheck = [ "llm_video_frames" ]; 27 + 28 + passthru.tests = llm.mkPluginTest llm-video-frames; 29 + 30 + meta = { 31 + description = "LLM plugin to turn a video into individual frames"; 32 + homepage = "https://github.com/simonw/llm-video-frames"; 33 + changelog = "https://github.com/simonw/llm-video-frames/releases/tag/${version}/CHANGELOG.md"; 34 + license = lib.licenses.asl20; 35 + maintainers = with lib.maintainers; [ philiptaron ]; 36 + }; 37 + }
+42 -12
pkgs/development/python-modules/llm/001-disable-install-uninstall-commands.patch
··· 1 diff --git a/llm/cli.py b/llm/cli.py 2 - index af37feb..18b078a 100644 3 --- a/llm/cli.py 4 +++ b/llm/cli.py 5 - @@ -1014,18 +1014,7 @@ def templates_path(): 6 ) 7 - def install(packages, upgrade, editable, force_reinstall, no_cache_dir): 8 - """Install packages from PyPI into the same environment as LLM""" 9 - args = ["pip", "install"] 10 - if upgrade: 11 - args += ["--upgrade"] ··· 15 - args += ["--force-reinstall"] 16 - if no_cache_dir: 17 - args += ["--no-cache-dir"] 18 - args += list(packages) 19 - sys.argv = args 20 - run_module("pip", run_name="__main__") 21 - + click.echo("Install command has been disabled for Nix. If you want to install extra llm plugins, use llm.withPlugins([]) expression.") 22 - 23 - 24 @cli.command() 25 - @@ -1033,8 +1022,7 @@ def install(packages, upgrade, editable, force_reinstall, no_cache_dir): 26 @click.option("-y", "--yes", is_flag=True, help="Don't ask for confirmation") 27 def uninstall(packages, yes): 28 - """Uninstall Python packages from the LLM environment""" 29 - sys.argv = ["pip", "uninstall"] + list(packages) + (["-y"] if yes else []) 30 - run_module("pip", run_name="__main__") 31 - + click.echo("Uninstall command has been disabled for Nix. If you want to uninstall extra llm plugins, just remove them from llm.withPlugins([]) list expression.") 32 - 33 - 34 @cli.command()
··· 1 diff --git a/llm/cli.py b/llm/cli.py 2 + index 5d53e74..c2b4707 100644 3 --- a/llm/cli.py 4 +++ b/llm/cli.py 5 + @@ -2895,30 +2895,38 @@ def display_truncated(text): 6 + help="Include pre-release and development versions", 7 ) 8 + def install(packages, upgrade, editable, force_reinstall, no_cache_dir, pre): 9 + - """Install packages from PyPI into the same environment as LLM""" 10 - args = ["pip", "install"] 11 - if upgrade: 12 - args += ["--upgrade"] ··· 16 - args += ["--force-reinstall"] 17 - if no_cache_dir: 18 - args += ["--no-cache-dir"] 19 + - if pre: 20 + - args += ["--pre"] 21 - args += list(packages) 22 - sys.argv = args 23 - run_module("pip", run_name="__main__") 24 + + """Install packages from PyPI into the same environment as LLM. Disabled for nixpkgs.""" 25 + + raise click.ClickException( 26 + +"""Install command has been disabled for Nix. To install extra `llm` plugins, use the `llm.withPlugins` function. 27 + + 28 + +Example: 29 + + 30 + +```nix 31 + +llm.withPlugins { 32 + + @listOfPackagedPlugins@ 33 + +} 34 + +``` 35 + +""" 36 + + ) 37 + 38 + 39 @cli.command() 40 + @click.argument("packages", nargs=-1, required=True) 41 @click.option("-y", "--yes", is_flag=True, help="Don't ask for confirmation") 42 def uninstall(packages, yes): 43 + - """Uninstall Python packages from the LLM environment""" 44 - sys.argv = ["pip", "uninstall"] + list(packages) + (["-y"] if yes else []) 45 - run_module("pip", run_name="__main__") 46 + + """Uninstall Python packages from the LLM environment. Disabled for nixpkgs.""" 47 + + raise click.ClickException( 48 + +"""Uninstall command has been disabled for Nix. To remove `llm` plugins, use the `llm.withPlugins` function with the desired set of plugins specified. 49 + + 50 + +Example: 51 + + 52 + +```nix 53 + +llm.withPlugins { 54 + + @listOfPackagedPlugins@ 55 + +} 56 + +``` 57 + +""" 58 + + ) 59 + 60 + 61 @cli.command() 62 + -- 63 + 2.49.0 64 +
+166 -13
pkgs/development/python-modules/llm/default.nix
··· 1 { 2 lib, 3 buildPythonPackage, 4 fetchFromGitHub, 5 pytestCheckHook, 6 pythonOlder, 7 setuptools, 8 click-default-group, 9 condense-json, ··· 13 pluggy, 14 puremagic, 15 pydantic, 16 python-ulid, 17 pyyaml, 18 sqlite-migrate, 19 cogapp, 20 pytest-asyncio, 21 pytest-httpx, 22 sqlite-utils, 23 }: 24 let 25 llm = buildPythonPackage rec { 26 pname = "llm"; 27 - version = "0.25"; 28 pyproject = true; 29 30 build-system = [ setuptools ]; ··· 35 owner = "simonw"; 36 repo = "llm"; 37 tag = version; 38 - hash = "sha256-iH1P0VdpwIItY1In7vlM0Sn44Db23TqFp8GZ79/GMJs="; 39 }; 40 41 patches = [ ./001-disable-install-uninstall-commands.patch ]; 42 43 dependencies = [ 44 click-default-group 45 condense-json ··· 61 numpy 62 pytest-asyncio 63 pytest-httpx 64 pytestCheckHook 65 ]; 66 67 doCheck = true; 68 69 pytestFlagsArray = [ 70 "-svv" 71 "tests/" ··· 74 pythonImportsCheck = [ "llm" ]; 75 76 passthru = { 77 - inherit withPlugins; 78 }; 79 80 - meta = with lib; { 81 homepage = "https://github.com/simonw/llm"; 82 description = "Access large language models from the command-line"; 83 changelog = "https://github.com/simonw/llm/releases/tag/${src.tag}"; 84 - license = licenses.asl20; 85 mainProgram = "llm"; 86 - maintainers = with maintainers; [ 87 aldoborrero 88 mccartykim 89 ]; 90 }; 91 }; 92 - 93 - withPlugins = throw '' 94 - llm.withPlugins was confusing to use and has been removed. 95 - Please migrate to using python3.withPackages(ps: [ ps.llm ]) instead. 96 - 97 - See https://nixos.org/manual/nixpkgs/stable/#python.withpackages-function for more usage examples. 98 - ''; 99 in 100 llm
··· 1 { 2 lib, 3 + runCommand, 4 + callPackage, 5 buildPythonPackage, 6 fetchFromGitHub, 7 pytestCheckHook, 8 pythonOlder, 9 + replaceVars, 10 setuptools, 11 click-default-group, 12 condense-json, ··· 16 pluggy, 17 puremagic, 18 pydantic, 19 + python, 20 python-ulid, 21 pyyaml, 22 sqlite-migrate, 23 cogapp, 24 pytest-asyncio, 25 pytest-httpx, 26 + pytest-recording, 27 sqlite-utils, 28 + syrupy, 29 + llm-echo, 30 }: 31 let 32 + /** 33 + Make a derivation for `llm` that contains `llm` plus the relevant plugins. 34 + The function signature of `withPlugins` is the list of all the plugins `llm` knows about. 35 + Adding a parameter here requires that it be in `python3Packages` attrset. 36 + 37 + # Type 38 + 39 + ``` 40 + withPlugins :: 41 + { 42 + llm-anthropic :: bool, 43 + llm-gemini :: bool, 44 + ... 45 + } 46 + -> derivation 47 + ``` 48 + 49 + See `lib.attrNames (lib.functionArgs llm.withPlugins)` for the total list of plugins supported. 50 + 51 + # Examples 52 + :::{.example} 53 + ## `llm.withPlugins` usage example 54 + 55 + ```nix 56 + llm.withPlugins { llm-gemini = true; llm-groq = true; } 57 + => «derivation /nix/store/<hash>-python3-3.12.10-llm-with-llm-gemini-llm-groq.drv» 58 + ``` 59 + 60 + ::: 61 + */ 62 + withPlugins = 63 + # Keep this list up to date with the plugins in python3Packages! 64 + { 65 + llm-anthropic ? false, 66 + llm-cmd ? false, 67 + llm-command-r ? false, 68 + llm-deepseek ? false, 69 + llm-docs ? false, 70 + llm-echo ? false, 71 + llm-fragments-github ? false, 72 + llm-fragments-pypi ? false, 73 + llm-fragments-reader ? false, 74 + llm-fragments-symbex ? false, 75 + llm-gemini ? false, 76 + llm-gguf ? false, 77 + llm-git ? false, 78 + llm-grok ? false, 79 + llm-groq ? false, 80 + llm-hacker-news ? false, 81 + llm-jq ? false, 82 + llm-llama-server ? false, 83 + llm-mistral ? false, 84 + llm-ollama ? false, 85 + llm-openai-plugin ? false, 86 + llm-openrouter ? false, 87 + llm-pdf-to-images ? false, 88 + llm-sentence-transformers ? false, 89 + llm-templates-fabric ? false, 90 + llm-templates-github ? false, 91 + llm-tools-datasette ? false, 92 + llm-tools-quickjs ? false, 93 + llm-tools-simpleeval ? false, 94 + llm-tools-sqlite ? false, 95 + llm-venice ? false, 96 + llm-video-frames ? false, 97 + ... 98 + }@args: 99 + let 100 + # Filter to just the attributes which are set to a true value. 101 + setArgs = lib.filterAttrs (name: lib.id) args; 102 + 103 + # Make the derivation name reflect what's inside it, up to a certain limit. 104 + setArgNames = lib.attrNames setArgs; 105 + drvName = 106 + let 107 + len = builtins.length setArgNames; 108 + in 109 + if len == 0 then 110 + "llm-${llm.version}" 111 + else if len > 20 then 112 + "llm-${llm.version}-with-${toString len}-plugins" 113 + else 114 + # Make a string with those names separated with a dash. 115 + "llm-${llm.version}-with-${lib.concatStringsSep "-" setArgNames}"; 116 + 117 + # Make a python environment with just those plugins. 118 + python-environment = python.withPackages ( 119 + ps: 120 + let 121 + # Throw a diagnostic if this list gets out of sync with the names in python3Packages 122 + allPluginsPresent = pluginNames == withPluginsArgNames; 123 + pluginNames = lib.attrNames (lib.intersectAttrs ps withPluginsArgs); 124 + missingNamesList = lib.attrNames (lib.removeAttrs withPluginsArgs pluginNames); 125 + missingNames = lib.concatStringsSep ", " missingNamesList; 126 + 127 + # The relevant plugins are the ones the user asked for. 128 + plugins = lib.intersectAttrs setArgs ps; 129 + in 130 + assert lib.assertMsg allPluginsPresent "Missing these plugins: ${missingNames}"; 131 + ([ ps.llm ] ++ lib.attrValues plugins) 132 + ); 133 + 134 + in 135 + # That Python environment produced above contains too many irrelevant binaries, due to how 136 + # Python needs to use propagatedBuildInputs. Let's make one with just what's needed: `llm`. 137 + # Since we include the `passthru` and `meta` information, it's as good as the original 138 + # derivation. 139 + runCommand "${python.name}-${drvName}" { inherit (llm) passthru meta; } '' 140 + mkdir -p $out/bin 141 + ln -s ${python-environment}/bin/llm $out/bin/llm 142 + ''; 143 + 144 + # Uses the `withPlugins` names to make a Python environment with everything. 145 + withAllPlugins = withPlugins (lib.genAttrs withPluginsArgNames (name: true)); 146 + 147 + # The function signature of `withPlugins` is the list of all the plugins `llm` knows about. 148 + # The plugin directory is at <https://llm.datasette.io/en/stable/plugins/directory.html> 149 + withPluginsArgs = lib.functionArgs withPlugins; 150 + withPluginsArgNames = lib.attrNames withPluginsArgs; 151 + 152 + # In order to help with usability, we patch `llm install` and `llm uninstall` to tell users how to 153 + # customize `llm` with plugins in Nix, including the name of the plugin, its description, and 154 + # where it's coming from. 155 + listOfPackagedPlugins = builtins.toFile "plugins.txt" ( 156 + lib.concatStringsSep "\n " ( 157 + map (name: '' 158 + # ${python.pkgs.${name}.meta.description} <${python.pkgs.${name}.meta.homepage}> 159 + ${name} = true; 160 + '') withPluginsArgNames 161 + ) 162 + ); 163 + 164 llm = buildPythonPackage rec { 165 pname = "llm"; 166 + version = "0.26"; 167 pyproject = true; 168 169 build-system = [ setuptools ]; ··· 174 owner = "simonw"; 175 repo = "llm"; 176 tag = version; 177 + hash = "sha256-KTlNajuZrR0kBX3LatepsNM3PfRVsQn+evEfXTu6juE="; 178 }; 179 180 patches = [ ./001-disable-install-uninstall-commands.patch ]; 181 182 + postPatch = '' 183 + substituteInPlace llm/cli.py \ 184 + --replace-fail "@listOfPackagedPlugins@" "$(< ${listOfPackagedPlugins})" 185 + ''; 186 + 187 dependencies = [ 188 click-default-group 189 condense-json ··· 205 numpy 206 pytest-asyncio 207 pytest-httpx 208 + pytest-recording 209 + syrupy 210 pytestCheckHook 211 ]; 212 213 doCheck = true; 214 215 + # The tests make use of `llm_echo` but that would be a circular dependency. 216 + # So we make a local copy in this derivation, as it's a super-simple package of one file. 217 + preCheck = '' 218 + cp ${llm-echo.src}/llm_echo.py llm_echo.py 219 + ''; 220 + 221 pytestFlagsArray = [ 222 "-svv" 223 "tests/" ··· 226 pythonImportsCheck = [ "llm" ]; 227 228 passthru = { 229 + inherit withPlugins withAllPlugins; 230 + 231 + mkPluginTest = plugin: { 232 + ${plugin.pname} = callPackage ./mk-plugin-test.nix { inherit llm plugin; }; 233 + }; 234 + 235 + # include tests for all the plugins 236 + tests = lib.mergeAttrsList (map (name: python.pkgs.${name}.tests) withPluginsArgNames); 237 }; 238 239 + meta = { 240 homepage = "https://github.com/simonw/llm"; 241 description = "Access large language models from the command-line"; 242 changelog = "https://github.com/simonw/llm/releases/tag/${src.tag}"; 243 + license = lib.licenses.asl20; 244 mainProgram = "llm"; 245 + maintainers = with lib.maintainers; [ 246 aldoborrero 247 mccartykim 248 + philiptaron 249 ]; 250 }; 251 }; 252 in 253 llm
+27
pkgs/development/python-modules/llm/mk-plugin-test.nix
···
··· 1 + { 2 + cacert, 3 + runCommand, 4 + writableTmpDirAsHomeHook, 5 + yq, 6 + llm, 7 + plugin, 8 + }: 9 + let 10 + venv = llm.pythonModule.withPackages (_: [ 11 + llm 12 + plugin 13 + ]); 14 + in 15 + runCommand "${plugin.pname}-test" 16 + { 17 + nativeBuildInputs = [ 18 + venv 19 + writableTmpDirAsHomeHook 20 + yq 21 + ]; 22 + env.SSL_CERT_FILE = "${cacert}/etc/ssl/certs/ca-bundle.crt"; 23 + } 24 + '' 25 + llm plugins | yq --exit-status 'any(.name == "${plugin.pname}")' 26 + touch "$out" 27 + ''
+52
pkgs/development/python-modules/pytest-icdiff/default.nix
···
··· 1 + { 2 + lib, 3 + buildPythonPackage, 4 + fetchFromGitHub, 5 + setuptools, 6 + icdiff, 7 + pprintpp, 8 + pytest, 9 + pytestCheckHook, 10 + writableTmpDirAsHomeHook, 11 + }: 12 + 13 + buildPythonPackage rec { 14 + pname = "pytest-icdiff"; 15 + version = "0.5-unstable-2024-09-04"; 16 + pyproject = true; 17 + 18 + src = fetchFromGitHub { 19 + owner = "hjwp"; 20 + repo = "pytest-icdiff"; 21 + rev = "6e2fb8de35e37428a9f7a268c8abb57e9ee285e5"; 22 + hash = "sha256-kSeGz5IExldgi955XOEkQnc8uqxkbyvuDOdz9y3AFIY="; 23 + }; 24 + 25 + build-system = [ setuptools ]; 26 + 27 + dependencies = [ 28 + pytest 29 + icdiff 30 + pprintpp 31 + ]; 32 + 33 + # These are failing on the main branch; disable for now 34 + disabledTests = [ 35 + "test_long_dict" 36 + "test_mutliline_strings_have_no_escaped_newlines" 37 + ]; 38 + 39 + nativeCheckInputs = [ 40 + pytestCheckHook 41 + writableTmpDirAsHomeHook 42 + ]; 43 + 44 + pythonImportsCheck = [ "pytest_icdiff" ]; 45 + 46 + meta = { 47 + description = "Better error messages in pytest assertions using icdiff"; 48 + homepage = "https://github.com/hjwp/pytest-icdiff"; 49 + license = lib.licenses.unlicense; 50 + maintainers = with lib.maintainers; [ philiptaron ]; 51 + }; 52 + }
+66
pkgs/development/python-modules/quickjs/0001-Update-for-QuickJS-2025-04-26-release.patch
···
··· 1 + From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 2 + From: Philip Taron <philip.taron@gmail.com> 3 + Date: Thu, 29 May 2025 17:16:43 -0700 4 + Subject: [PATCH] Update for QuickJS 2025-04-26 release 5 + 6 + Signed-off-by: Philip Taron <philip.taron@gmail.com> 7 + --- 8 + setup.py | 6 +++--- 9 + test_quickjs.py | 6 +++--- 10 + 2 files changed, 6 insertions(+), 6 deletions(-) 11 + 12 + diff --git a/setup.py b/setup.py 13 + index 9d17af357dcadc40478789ef9c82ac82632967d3..d0b4ff2bd7f3450f6f055ee9e2eda6b591d70689 100644 14 + --- a/setup.py 15 + +++ b/setup.py 16 + @@ -16,7 +16,7 @@ if sys.platform == "win32": 17 + # system PATH when compiling. 18 + # 3. The code below will moneky-patch distutils to work. 19 + import distutils.cygwinccompiler 20 + - distutils.cygwinccompiler.get_msvcr = lambda: [] 21 + + distutils.cygwinccompiler.get_msvcr = lambda: [] 22 + # Make sure that pthreads is linked statically, otherwise we run into problems 23 + # on computers where it is not installed. 24 + extra_link_args = ["-static"] 25 + @@ -26,7 +26,7 @@ def get_c_sources(include_headers=False): 26 + sources = [ 27 + "module.c", 28 + "upstream-quickjs/cutils.c", 29 + - "upstream-quickjs/libbf.c", 30 + + "upstream-quickjs/dtoa.c", 31 + "upstream-quickjs/libregexp.c", 32 + "upstream-quickjs/libunicode.c", 33 + "upstream-quickjs/quickjs.c", 34 + @@ -34,7 +34,7 @@ def get_c_sources(include_headers=False): 35 + if include_headers: 36 + sources += [ 37 + "upstream-quickjs/cutils.h", 38 + - "upstream-quickjs/libbf.h", 39 + + "upstream-quickjs/dtoa.h", 40 + "upstream-quickjs/libregexp-opcode.h", 41 + "upstream-quickjs/libregexp.h", 42 + "upstream-quickjs/libunicode-table.h", 43 + diff --git a/test_quickjs.py b/test_quickjs.py 44 + index 1f6dec7ccd15092e98e80a9139ae2acff359b010..9444234655fba9d932ce92c82b9d8da8fe83ad5b 100644 45 + --- a/test_quickjs.py 46 + +++ b/test_quickjs.py 47 + @@ -105,8 +105,8 @@ class Context(unittest.TestCase): 48 + else: 49 + self.fail("Expected exception.") 50 + 51 + - self.assertIn("at funcA (<input>:3)\n", msg) 52 + - self.assertIn("at funcB (<input>:6)\n", msg) 53 + + self.assertIn("at funcA (<input>:3:24)\n", msg) 54 + + self.assertIn("at funcB (<input>:6:26)\n", msg) 55 + 56 + def test_memory_limit(self): 57 + code = """ 58 + @@ -508,7 +508,7 @@ class FunctionTest(unittest.TestCase): 59 + """) 60 + 61 + self.assertEqual(f(100), 100) 62 + - limit = 500 63 + + limit = 1500 64 + with self.assertRaises(quickjs.StackOverflow): 65 + f(limit) 66 + f.set_max_stack_size(2000 * limit)
+58
pkgs/development/python-modules/quickjs/default.nix
···
··· 1 + { 2 + lib, 3 + buildPythonPackage, 4 + fetchFromGitHub, 5 + setuptools, 6 + poetry-core, 7 + pytestCheckHook, 8 + pkgs, 9 + }: 10 + 11 + let 12 + inherit (pkgs) quickjs srcOnly; 13 + in 14 + 15 + buildPythonPackage rec { 16 + pname = "quickjs"; 17 + version = "1.19.4"; 18 + pyproject = true; 19 + 20 + src = fetchFromGitHub { 21 + owner = "PetterS"; 22 + repo = "quickjs"; 23 + tag = version; 24 + hash = "sha256-nLloXJWOuaK/enZfwXJI94IcsAMYrkBtG4i3gmxuhfw="; 25 + }; 26 + 27 + patches = [ ./0001-Update-for-QuickJS-2025-04-26-release.patch ]; 28 + 29 + # Upstream uses Git submodules; let's de-vendor and use Nix, so that we gain security fixes like 30 + # https://github.com/NixOS/nixpkgs/pull/407469 31 + prePatch = '' 32 + rmdir upstream-quickjs 33 + ln -s ${srcOnly quickjs} upstream-quickjs 34 + ''; 35 + 36 + postPatch = '' 37 + substituteInPlace pyproject.toml \ 38 + --replace-fail poetry>=1.5.0 poetry \ 39 + --replace-fail poetry poetry-core \ 40 + --replace-fail 'version = "0"' 'version = "${version}"' 41 + ''; 42 + 43 + build-system = [ 44 + poetry-core 45 + setuptools 46 + ]; 47 + 48 + nativeCheckInputs = [ pytestCheckHook ]; 49 + 50 + pythonImportsCheck = [ "quickjs" ]; 51 + 52 + meta = { 53 + description = "Python wrapper around the quickjs C library"; 54 + homepage = "https://github.com/PetterS/quickjs"; 55 + license = lib.licenses.mit; 56 + maintainers = with lib.maintainers; [ philiptaron ]; 57 + }; 58 + }
+45
pkgs/development/python-modules/symbex/default.nix
···
··· 1 + { 2 + lib, 3 + buildPythonPackage, 4 + fetchFromGitHub, 5 + setuptools, 6 + click, 7 + pytestCheckHook, 8 + pyyaml, 9 + pytest-icdiff, 10 + writableTmpDirAsHomeHook, 11 + }: 12 + 13 + buildPythonPackage rec { 14 + pname = "symbex"; 15 + version = "2.0"; 16 + pyproject = true; 17 + 18 + src = fetchFromGitHub { 19 + owner = "simonw"; 20 + repo = "symbex"; 21 + tag = version; 22 + hash = "sha256-swg98z4DpQJ5rq7tdsd3FofbYF7O5S+9ZR0weoM2DoI="; 23 + }; 24 + 25 + build-system = [ setuptools ]; 26 + 27 + dependencies = [ click ]; 28 + 29 + pythonImportsCheck = [ "symbex" ]; 30 + 31 + nativeCheckInputs = [ 32 + pytestCheckHook 33 + pyyaml 34 + pytest-icdiff 35 + writableTmpDirAsHomeHook 36 + ]; 37 + 38 + meta = { 39 + description = "Find the Python code for specified symbols"; 40 + homepage = "https://github.com/simonw/symbex"; 41 + changelog = "https://github.com/simonw/symbex/releases/tag/${version}/CHANGELOG.md"; 42 + license = lib.licenses.asl20; 43 + maintainers = with lib.maintainers; [ philiptaron ]; 44 + }; 45 + }
-2
pkgs/top-level/all-packages.nix
··· 3502 ocamlPackages = ocaml-ng.ocamlPackages_4_14; 3503 }; 3504 3505 - llm = with python3Packages; toPythonApplication llm; 3506 - 3507 loganalyzer = libsForQt5.callPackage ../development/tools/loganalyzer { }; 3508 3509 logstash7 = callPackage ../tools/misc/logstash/7.x.nix {
··· 3502 ocamlPackages = ocaml-ng.ocamlPackages_4_14; 3503 }; 3504 3505 loganalyzer = libsForQt5.callPackage ../development/tools/loganalyzer { }; 3506 3507 logstash7 = callPackage ../tools/misc/logstash/7.x.nix {
+60
pkgs/top-level/python-packages.nix
··· 4971 4972 filelock = callPackage ../development/python-modules/filelock { }; 4973 4974 filetype = callPackage ../development/python-modules/filetype { }; 4975 4976 filterpy = callPackage ../development/python-modules/filterpy { }; ··· 6654 6655 icalevents = callPackage ../development/python-modules/icalevents { }; 6656 6657 icecream = callPackage ../development/python-modules/icecream { }; 6658 6659 iceportal = callPackage ../development/python-modules/iceportal { }; ··· 8306 8307 llm-cmd = callPackage ../development/python-modules/llm-cmd { }; 8308 8309 llm-gemini = callPackage ../development/python-modules/llm-gemini { }; 8310 8311 llm-gguf = callPackage ../development/python-modules/llm-gguf { }; 8312 8313 llm-jq = callPackage ../development/python-modules/llm-jq { }; 8314 8315 llm-ollama = callPackage ../development/python-modules/llm-ollama { }; 8316 8317 llm-openai-plugin = callPackage ../development/python-modules/llm-openai-plugin { }; 8318 8319 llmx = callPackage ../development/python-modules/llmx { }; 8320 ··· 13827 13828 pytest-httpx = callPackage ../development/python-modules/pytest-httpx { }; 13829 13830 pytest-image-diff = callPackage ../development/python-modules/pytest-image-diff { }; 13831 13832 pytest-instafail = callPackage ../development/python-modules/pytest-instafail { }; ··· 14875 questo = callPackage ../development/python-modules/questo { }; 14876 14877 queuelib = callPackage ../development/python-modules/queuelib { }; 14878 14879 quil = callPackage ../development/python-modules/quil { }; 14880 ··· 17032 swspotify = callPackage ../development/python-modules/swspotify { }; 17033 17034 sybil = callPackage ../development/python-modules/sybil { }; 17035 17036 symbolic = callPackage ../development/python-modules/symbolic { }; 17037
··· 4971 4972 filelock = callPackage ../development/python-modules/filelock { }; 4973 4974 + files-to-prompt = callPackage ../development/python-modules/files-to-prompt { }; 4975 + 4976 filetype = callPackage ../development/python-modules/filetype { }; 4977 4978 filterpy = callPackage ../development/python-modules/filterpy { }; ··· 6656 6657 icalevents = callPackage ../development/python-modules/icalevents { }; 6658 6659 + icdiff = callPackage ../development/python-modules/icdiff { }; 6660 + 6661 icecream = callPackage ../development/python-modules/icecream { }; 6662 6663 iceportal = callPackage ../development/python-modules/iceportal { }; ··· 8310 8311 llm-cmd = callPackage ../development/python-modules/llm-cmd { }; 8312 8313 + llm-command-r = callPackage ../development/python-modules/llm-command-r { }; 8314 + 8315 + llm-deepseek = callPackage ../development/python-modules/llm-deepseek { }; 8316 + 8317 + llm-docs = callPackage ../development/python-modules/llm-docs { }; 8318 + 8319 + llm-echo = callPackage ../development/python-modules/llm-echo { }; 8320 + 8321 + llm-fragments-github = callPackage ../development/python-modules/llm-fragments-github { }; 8322 + 8323 + llm-fragments-pypi = callPackage ../development/python-modules/llm-fragments-pypi { }; 8324 + 8325 + llm-fragments-reader = callPackage ../development/python-modules/llm-fragments-reader { }; 8326 + 8327 + llm-fragments-symbex = callPackage ../development/python-modules/llm-fragments-symbex { }; 8328 + 8329 llm-gemini = callPackage ../development/python-modules/llm-gemini { }; 8330 8331 llm-gguf = callPackage ../development/python-modules/llm-gguf { }; 8332 8333 + llm-git = callPackage ../development/python-modules/llm-git { }; 8334 + 8335 + llm-grok = callPackage ../development/python-modules/llm-grok { }; 8336 + 8337 + llm-groq = callPackage ../development/python-modules/llm-groq { }; 8338 + 8339 + llm-hacker-news = callPackage ../development/python-modules/llm-hacker-news { }; 8340 + 8341 llm-jq = callPackage ../development/python-modules/llm-jq { }; 8342 8343 + llm-llama-server = callPackage ../development/python-modules/llm-llama-server { }; 8344 + 8345 + llm-mistral = callPackage ../development/python-modules/llm-mistral { }; 8346 + 8347 llm-ollama = callPackage ../development/python-modules/llm-ollama { }; 8348 8349 llm-openai-plugin = callPackage ../development/python-modules/llm-openai-plugin { }; 8350 + 8351 + llm-openrouter = callPackage ../development/python-modules/llm-openrouter { }; 8352 + 8353 + llm-pdf-to-images = callPackage ../development/python-modules/llm-pdf-to-images { }; 8354 + 8355 + llm-sentence-transformers = callPackage ../development/python-modules/llm-sentence-transformers { }; 8356 + 8357 + llm-templates-fabric = callPackage ../development/python-modules/llm-templates-fabric { }; 8358 + 8359 + llm-templates-github = callPackage ../development/python-modules/llm-templates-github { }; 8360 + 8361 + llm-tools-datasette = callPackage ../development/python-modules/llm-tools-datasette { }; 8362 + 8363 + llm-tools-quickjs = callPackage ../development/python-modules/llm-tools-quickjs { }; 8364 + 8365 + llm-tools-simpleeval = callPackage ../development/python-modules/llm-tools-simpleeval { }; 8366 + 8367 + llm-tools-sqlite = callPackage ../development/python-modules/llm-tools-sqlite { }; 8368 + 8369 + llm-venice = callPackage ../development/python-modules/llm-venice { }; 8370 + 8371 + llm-video-frames = callPackage ../development/python-modules/llm-video-frames { }; 8372 8373 llmx = callPackage ../development/python-modules/llmx { }; 8374 ··· 13881 13882 pytest-httpx = callPackage ../development/python-modules/pytest-httpx { }; 13883 13884 + pytest-icdiff = callPackage ../development/python-modules/pytest-icdiff { }; 13885 + 13886 pytest-image-diff = callPackage ../development/python-modules/pytest-image-diff { }; 13887 13888 pytest-instafail = callPackage ../development/python-modules/pytest-instafail { }; ··· 14931 questo = callPackage ../development/python-modules/questo { }; 14932 14933 queuelib = callPackage ../development/python-modules/queuelib { }; 14934 + 14935 + quickjs = callPackage ../development/python-modules/quickjs { }; 14936 14937 quil = callPackage ../development/python-modules/quil { }; 14938 ··· 17090 swspotify = callPackage ../development/python-modules/swspotify { }; 17091 17092 sybil = callPackage ../development/python-modules/sybil { }; 17093 + 17094 + symbex = callPackage ../development/python-modules/symbex { }; 17095 17096 symbolic = callPackage ../development/python-modules/symbolic { }; 17097