diff --git a/pkgs/by-name/fi/files-to-prompt/package.nix b/pkgs/by-name/fi/files-to-prompt/package.nix index b671e52e9504..bba3859edb6b 100644 --- a/pkgs/by-name/fi/files-to-prompt/package.nix +++ b/pkgs/by-name/fi/files-to-prompt/package.nix @@ -1,43 +1,3 @@ -{ - lib, - python3Packages, - fetchFromGitHub, - versionCheckHook, -}: +{ python3Packages }: -python3Packages.buildPythonApplication rec { - pname = "files-to-prompt"; - version = "0.6"; - pyproject = true; - - src = fetchFromGitHub { - owner = "simonw"; - repo = "files-to-prompt"; - tag = version; - hash = "sha256-LWp/DNP3bsh7/goQGkpi4x2N11tRuhLVh2J8H6AUH0w="; - }; - - build-system = with python3Packages; [ - setuptools - ]; - - dependencies = with python3Packages; [ - click - ]; - - nativeCheckInputs = with python3Packages; [ - pytestCheckHook - versionCheckHook - ]; - - versionCheckProgramArg = "--version"; - - meta = { - description = "Concatenate a directory full of files into a single prompt for use with LLMs"; - homepage = "https://github.com/simonw/files-to-prompt/"; - changelog = "https://github.com/simonw/files-to-prompt/releases/tag/${src.tag}"; - license = lib.licenses.asl20; - maintainers = with lib.maintainers; [ erethon ]; - mainProgram = "files-to-prompt"; - }; -} +python3Packages.toPythonApplication python3Packages.files-to-prompt diff --git a/pkgs/by-name/ic/icdiff/package.nix b/pkgs/by-name/ic/icdiff/package.nix index d34b976f068e..98144d145cd0 100644 --- a/pkgs/by-name/ic/icdiff/package.nix +++ b/pkgs/by-name/ic/icdiff/package.nix @@ -1,41 +1,3 @@ -{ - lib, - python3Packages, - fetchFromGitHub, - bash, - git, - less, -}: +{ python3Packages }: -python3Packages.buildPythonApplication rec { - pname = "icdiff"; - version = "2.0.7"; - - src = fetchFromGitHub { - owner = "jeffkaufman"; - repo = "icdiff"; - tag = "release-${version}"; - hash = "sha256-XOw/xhPGlzi1hAgzQ1EtioUM476A+lQWLlvvaxd9j08="; - }; - - # error: could not lock config file /homeless-shelter/.gitconfig: No such file or directory - doCheck = false; - - nativeCheckInputs = [ - bash - git - less - ]; - - checkPhase = '' - patchShebangs test.sh - ./test.sh ${python3Packages.python.interpreter} - ''; - - meta = { - homepage = "https://www.jefftk.com/icdiff"; - description = "Side-by-side highlighted command line diffs"; - maintainers = [ ]; - license = lib.licenses.psfl; - }; -} +python3Packages.toPythonApplication python3Packages.icdiff diff --git a/pkgs/by-name/ll/llm/package.nix b/pkgs/by-name/ll/llm/package.nix new file mode 100644 index 000000000000..f2bb127d32aa --- /dev/null +++ b/pkgs/by-name/ll/llm/package.nix @@ -0,0 +1,46 @@ +# The `...` allows this derivation to be overridden with `enable-`. +# +# Example: +# +# ```nix +# llm.override { +# enable-llm-anthropic = true; +# enable-llm-gemini = true; +# enable-llm-cmd = true; +# enable-llm-templates-github = true; +# } +# ``` +# +# Whatever names are accepted by `llm.withPlugins` are accepted with an added `enable-` prefix as +# an override of this derivation. The user can also do `llm.withPlugins { llm-anthropic = true; }`. +{ lib, python3Packages, ... }@args: + +let + inherit (python3Packages) llm; + + hasEnablePrefix = lib.hasPrefix "enable-"; + addEnablePrefix = name: "enable-${name}"; + removeEnablePrefix = lib.removePrefix "enable-"; + + # Filter to just the attributes which are named "enable-" + enableArgs = lib.filterAttrs (name: value: hasEnablePrefix name) args; + pluginArgs = lib.mapAttrs' ( + name: value: lib.nameValuePair (removeEnablePrefix name) value + ) enableArgs; + + # Provide some diagnostics for the plugin names + pluginNames = lib.attrNames (lib.functionArgs llm.withPlugins); + enableNames = lib.map addEnablePrefix pluginNames; + unknownPluginNames = lib.removeAttrs pluginArgs pluginNames; + unknownNames = lib.map addEnablePrefix (lib.attrNames unknownPluginNames); + unknownNamesDiagnostic = '' + Unknown plugins specified in override: ${lib.concatStringsSep ", " unknownNames} + + Valid overrides: + - ${lib.concatStringsSep "\n - " enableNames} + ''; +in + +assert lib.assertMsg (lib.length unknownNames == 0) unknownNamesDiagnostic; + +llm.withPlugins pluginArgs diff --git a/pkgs/development/python-modules/files-to-prompt/default.nix b/pkgs/development/python-modules/files-to-prompt/default.nix new file mode 100644 index 000000000000..f4392672429a --- /dev/null +++ b/pkgs/development/python-modules/files-to-prompt/default.nix @@ -0,0 +1,45 @@ +{ + lib, + click, + setuptools, + fetchFromGitHub, + buildPythonPackage, + pytestCheckHook, + versionCheckHook, +}: + +buildPythonPackage rec { + pname = "files-to-prompt"; + version = "0.6"; + pyproject = true; + + src = fetchFromGitHub { + owner = "simonw"; + repo = "files-to-prompt"; + tag = version; + hash = "sha256-LWp/DNP3bsh7/goQGkpi4x2N11tRuhLVh2J8H6AUH0w="; + }; + + build-system = [ setuptools ]; + + dependencies = [ click ]; + + nativeCheckInputs = [ + pytestCheckHook + versionCheckHook + ]; + + versionCheckProgramArg = "--version"; + + meta = { + mainProgram = "files-to-prompt"; + description = "Concatenate a directory full of files into a single prompt for use with LLMs"; + homepage = "https://github.com/simonw/files-to-prompt"; + changelog = "https://github.com/simonw/files-to-prompt/releases/tag/${src.tag}"; + license = lib.licenses.asl20; + maintainers = with lib.maintainers; [ + erethon + philiptaron + ]; + }; +} diff --git a/pkgs/development/python-modules/icdiff/0001-Don-t-test-black-or-flake8.patch b/pkgs/development/python-modules/icdiff/0001-Don-t-test-black-or-flake8.patch new file mode 100644 index 000000000000..3e8a067c7841 --- /dev/null +++ b/pkgs/development/python-modules/icdiff/0001-Don-t-test-black-or-flake8.patch @@ -0,0 +1,35 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Philip Taron +Date: Thu, 29 May 2025 14:47:58 -0700 +Subject: [PATCH] Don't test black or flake8 + +Signed-off-by: Philip Taron +--- + test.sh | 14 -------------- + 1 file changed, 14 deletions(-) + +diff --git a/test.sh b/test.sh +index 1dd6c4be579e8a61d2d284b042c54cd2a1e0ff77..dc9ecab4a9097878a0a65c45df38a4fa25eb9fa2 100755 +--- a/test.sh ++++ b/test.sh +@@ -210,20 +210,6 @@ function ensure_installed() { + fi + } + +-ensure_installed "black" +-echo 'Running black formatter...' +-if ! black icdiff --quiet --line-length 79 --check; then +- echo "" +- echo 'Consider running `black icdiff --line-length 79`' +- fail +-fi +- +-ensure_installed "flake8" +-echo 'Running flake8 linter...' +-if ! flake8 icdiff; then +- fail +-fi +- + if ! $REGOLD; then + echo PASS + fi diff --git a/pkgs/development/python-modules/icdiff/default.nix b/pkgs/development/python-modules/icdiff/default.nix new file mode 100644 index 000000000000..b1bd7addd69b --- /dev/null +++ b/pkgs/development/python-modules/icdiff/default.nix @@ -0,0 +1,61 @@ +{ + lib, + stdenv, + python, + buildPythonPackage, + fetchFromGitHub, + setuptools, + pytestCheckHook, + writableTmpDirAsHomeHook, + pkgs, +}: +let + inherit (pkgs) bash git less; +in + +buildPythonPackage rec { + pname = "icdiff"; + version = "2.0.7"; + pyproject = true; + + src = fetchFromGitHub { + owner = "jeffkaufman"; + repo = "icdiff"; + tag = "release-${version}"; + hash = "sha256-XOw/xhPGlzi1hAgzQ1EtioUM476A+lQWLlvvaxd9j08="; + leaveDotGit = true; + }; + + patches = [ ./0001-Don-t-test-black-or-flake8.patch ]; + + build-system = [ setuptools ]; + + pythonImportsCheck = [ "icdiff" ]; + + nativeCheckInputs = [ + bash + git + less + writableTmpDirAsHomeHook + ]; + + # Odd behavior in the sandbox + doCheck = !stdenv.hostPlatform.isDarwin; + + checkPhase = '' + runHook preCheck + + patchShebangs test.sh + ./test.sh ${python.interpreter} + + runHook postCheck + ''; + + meta = { + description = "Improved colorized diff"; + homepage = "https://github.com/jeffkaufman/icdiff"; + changelog = "https://github.com/jeffkaufman/icdiff/releases/tag/release-${version}/CHANGELOG.md"; + license = lib.licenses.psfl; + maintainers = with lib.maintainers; [ philiptaron ]; + }; +} diff --git a/pkgs/development/python-modules/llm-anthropic/default.nix b/pkgs/development/python-modules/llm-anthropic/default.nix index a7377833ff54..41bc86f10a15 100644 --- a/pkgs/development/python-modules/llm-anthropic/default.nix +++ b/pkgs/development/python-modules/llm-anthropic/default.nix @@ -1,10 +1,10 @@ { lib, - callPackage, buildPythonPackage, fetchFromGitHub, setuptools, llm, + llm-anthropic, anthropic, pytestCheckHook, pytest-asyncio, @@ -14,21 +14,24 @@ buildPythonPackage rec { pname = "llm-anthropic"; - version = "0.15.1"; + version = "0.17"; pyproject = true; src = fetchFromGitHub { owner = "simonw"; repo = "llm-anthropic"; tag = version; - hash = "sha256-8bVs3MJteOTCiw7n/4pMf+oXMhsQbCSzUFVQqm2ezcE="; + hash = "sha256-2fatBKZMttC5flzfC7MWCpduc3m6IOVWZiW1K2dYqis="; }; build-system = [ setuptools + ]; + + dependencies = [ + anthropic llm ]; - dependencies = [ anthropic ]; nativeCheckInputs = [ pytestCheckHook @@ -39,9 +42,7 @@ buildPythonPackage rec { pythonImportsCheck = [ "llm_anthropic" ]; - passthru.tests = { - llm-plugin = callPackage ./tests/llm-plugin.nix { }; - }; + passthru.tests = llm.mkPluginTest llm-anthropic; meta = { description = "LLM access to models by Anthropic, including the Claude series"; diff --git a/pkgs/development/python-modules/llm-anthropic/tests/llm-plugin.nix b/pkgs/development/python-modules/llm-anthropic/tests/llm-plugin.nix deleted file mode 100644 index a57802a8ad08..000000000000 --- a/pkgs/development/python-modules/llm-anthropic/tests/llm-plugin.nix +++ /dev/null @@ -1,22 +0,0 @@ -{ - runCommand, - python, - yq, -}: -let - venv = python.withPackages (ps: [ - ps.llm - ps.llm-anthropic - ]); -in -runCommand "llm-anthropic-test-llm-plugin" - { - nativeBuildInputs = [ - venv - yq - ]; - } - '' - llm plugins | yq --exit-status 'any(.name == "llm-anthropic")' - touch "$out" - '' diff --git a/pkgs/development/python-modules/llm-cmd/default.nix b/pkgs/development/python-modules/llm-cmd/default.nix index 9fca11cad544..30b1cd22250c 100644 --- a/pkgs/development/python-modules/llm-cmd/default.nix +++ b/pkgs/development/python-modules/llm-cmd/default.nix @@ -1,6 +1,5 @@ { lib, - callPackage, buildPythonPackage, fetchFromGitHub, # build-system @@ -11,6 +10,7 @@ pygments, # tests pytestCheckHook, + llm-cmd, }: buildPythonPackage rec { @@ -27,13 +27,11 @@ buildPythonPackage rec { # Only needed until https://github.com/simonw/llm-cmd/pull/18 is merged and released patches = [ ./fix-test.patch ]; - build-system = [ - setuptools - # Follows the reasoning from https://github.com/NixOS/nixpkgs/pull/327800#discussion_r1681586659 about including llm in build-system - llm - ]; + + build-system = [ setuptools ]; dependencies = [ + llm prompt-toolkit pygments ]; @@ -46,15 +44,16 @@ buildPythonPackage rec { "llm_cmd" ]; - passthru.tests = { - llm-plugin = callPackage ./tests/llm-plugin.nix { }; - }; + passthru.tests = llm.mkPluginTest llm-cmd; meta = { description = "Use LLM to generate and execute commands in your shell"; homepage = "https://github.com/simonw/llm-cmd"; changelog = "https://github.com/simonw/llm-cmd/releases/tag/${version}"; license = lib.licenses.asl20; - maintainers = with lib.maintainers; [ erethon ]; + maintainers = with lib.maintainers; [ + erethon + philiptaron + ]; }; } diff --git a/pkgs/development/python-modules/llm-cmd/tests/llm-plugin.nix b/pkgs/development/python-modules/llm-cmd/tests/llm-plugin.nix deleted file mode 100644 index 1707195abbc7..000000000000 --- a/pkgs/development/python-modules/llm-cmd/tests/llm-plugin.nix +++ /dev/null @@ -1,22 +0,0 @@ -{ - runCommand, - python, - yq, -}: -let - venv = python.withPackages (ps: [ - ps.llm - ps.llm-cmd - ]); -in -runCommand "llm-cmd-test-llm-plugin" - { - nativeBuildInputs = [ - venv - yq - ]; - } - '' - llm plugins | yq --exit-status 'any(.name == "llm-cmd")' - touch "$out" - '' diff --git a/pkgs/development/python-modules/llm-command-r/default.nix b/pkgs/development/python-modules/llm-command-r/default.nix new file mode 100644 index 000000000000..386973b2df4a --- /dev/null +++ b/pkgs/development/python-modules/llm-command-r/default.nix @@ -0,0 +1,50 @@ +{ + lib, + buildPythonPackage, + fetchFromGitHub, + setuptools, + llm, + llm-command-r, + cohere, + pytestCheckHook, + pytest-recording, + writableTmpDirAsHomeHook, +}: + +buildPythonPackage rec { + pname = "llm-command-r"; + version = "0.3.1"; + pyproject = true; + + src = fetchFromGitHub { + owner = "simonw"; + repo = "llm-command-r"; + tag = version; + hash = "sha256-PxICRds9NJQP64HwoL7Oxd39yaIrMdAyQEbhaumJCgo="; + }; + + build-system = [ setuptools ]; + + dependencies = [ + cohere + llm + ]; + + nativeCheckInputs = [ + pytestCheckHook + pytest-recording + writableTmpDirAsHomeHook + ]; + + pythonImportsCheck = [ "llm_command_r" ]; + + passthru.tests = llm.mkPluginTest llm-command-r; + + meta = { + description = "Access the Cohere Command R family of models"; + homepage = "https://github.com/simonw/llm-command-r"; + changelog = "https://github.com/simonw/llm-command-r/releases/tag/${version}/CHANGELOG.md"; + license = lib.licenses.asl20; + maintainers = with lib.maintainers; [ philiptaron ]; + }; +} diff --git a/pkgs/development/python-modules/llm-deepseek/default.nix b/pkgs/development/python-modules/llm-deepseek/default.nix new file mode 100644 index 000000000000..c0cb3668dc7f --- /dev/null +++ b/pkgs/development/python-modules/llm-deepseek/default.nix @@ -0,0 +1,37 @@ +{ + lib, + buildPythonPackage, + fetchFromGitHub, + setuptools, + llm, + llm-deepseek, +}: + +buildPythonPackage rec { + pname = "llm-deepseek"; + version = "0.1.6"; + pyproject = true; + + src = fetchFromGitHub { + owner = "abrasumente233"; + repo = "llm-deepseek"; + tag = version; + hash = "sha256-yrNvIGnU9Q/0H786DsM0wGEwfxZYIk8IXhqC4mWaQAA="; + }; + + build-system = [ setuptools ]; + + dependencies = [ llm ]; + + pythonImportsCheck = [ "llm_deepseek" ]; + + passthru.tests = llm.mkPluginTest llm-deepseek; + + meta = { + description = "LLM plugin providing access to Deepseek models."; + homepage = "https://github.com/abrasumente233/llm-deepseek"; + changelog = "https://github.com/abrasumente233/llm-deepseek/releases/tag/${version}/CHANGELOG.md"; + license = lib.licenses.asl20; + maintainers = with lib.maintainers; [ philiptaron ]; + }; +} diff --git a/pkgs/development/python-modules/llm-docs/default.nix b/pkgs/development/python-modules/llm-docs/default.nix new file mode 100644 index 000000000000..c1d07f8b1c49 --- /dev/null +++ b/pkgs/development/python-modules/llm-docs/default.nix @@ -0,0 +1,37 @@ +{ + lib, + buildPythonPackage, + fetchFromGitHub, + setuptools, + llm, + llm-docs, +}: + +buildPythonPackage rec { + pname = "llm-docs"; + version = "0.2.1"; + pyproject = true; + + src = fetchFromGitHub { + owner = "simonw"; + repo = "llm-docs"; + tag = version; + hash = "sha256-+Ha6L2h8p/yA073MfO2Uvd6E4bKA2xAvaBWtvjqglOw="; + }; + + build-system = [ setuptools ]; + + dependencies = [ llm ]; + + pythonImportsCheck = [ "llm_docs" ]; + + passthru.tests = llm.mkPluginTest llm-docs; + + meta = { + description = "Ask questions of LLM documentation using LLM"; + homepage = "https://github.com/simonw/llm-docs"; + changelog = "https://github.com/simonw/llm-docs/releases/tag/${version}/CHANGELOG.md"; + license = lib.licenses.asl20; + maintainers = with lib.maintainers; [ philiptaron ]; + }; +} diff --git a/pkgs/development/python-modules/llm-echo/default.nix b/pkgs/development/python-modules/llm-echo/default.nix new file mode 100644 index 000000000000..588b6f64909d --- /dev/null +++ b/pkgs/development/python-modules/llm-echo/default.nix @@ -0,0 +1,44 @@ +{ + lib, + buildPythonPackage, + fetchFromGitHub, + setuptools, + llm, + llm-echo, + pytestCheckHook, + writableTmpDirAsHomeHook, +}: + +buildPythonPackage rec { + pname = "llm-echo"; + version = "0.3a3"; + pyproject = true; + + src = fetchFromGitHub { + owner = "simonw"; + repo = "llm-echo"; + tag = version; + hash = "sha256-4345UIyaQx+mYYBAFD5AaX5YbjbnJQt8bKMD5Vl8VJc="; + }; + + build-system = [ setuptools ]; + + dependencies = [ llm ]; + + nativeCheckInputs = [ + pytestCheckHook + writableTmpDirAsHomeHook + ]; + + pythonImportsCheck = [ "llm_echo" ]; + + passthru.tests = llm.mkPluginTest llm-echo; + + meta = { + description = "Debug plugin for LLM"; + homepage = "https://github.com/simonw/llm-echo"; + changelog = "https://github.com/simonw/llm-echo/releases/tag/${version}/CHANGELOG.md"; + license = lib.licenses.asl20; + maintainers = with lib.maintainers; [ philiptaron ]; + }; +} diff --git a/pkgs/development/python-modules/llm-fragments-github/default.nix b/pkgs/development/python-modules/llm-fragments-github/default.nix new file mode 100644 index 000000000000..cf4874805c79 --- /dev/null +++ b/pkgs/development/python-modules/llm-fragments-github/default.nix @@ -0,0 +1,37 @@ +{ + lib, + buildPythonPackage, + fetchFromGitHub, + setuptools, + llm, + llm-fragments-github, +}: + +buildPythonPackage rec { + pname = "llm-fragments-github"; + version = "0.4"; + pyproject = true; + + src = fetchFromGitHub { + owner = "simonw"; + repo = "llm-fragments-github"; + tag = version; + hash = "sha256-7i1WRix5AAEG5EXJqtaU+QY56aL0SePdqz84z+C+iYM="; + }; + + build-system = [ setuptools ]; + + dependencies = [ llm ]; + + pythonImportsCheck = [ "llm_fragments_github" ]; + + passthru.tests = llm.mkPluginTest llm-fragments-github; + + meta = { + description = "Load GitHub repository contents as LLM fragments"; + homepage = "https://github.com/simonw/llm-fragments-github"; + changelog = "https://github.com/simonw/llm-fragments-github/releases/tag/${version}/CHANGELOG.md"; + license = lib.licenses.asl20; + maintainers = with lib.maintainers; [ philiptaron ]; + }; +} diff --git a/pkgs/development/python-modules/llm-fragments-pypi/default.nix b/pkgs/development/python-modules/llm-fragments-pypi/default.nix new file mode 100644 index 000000000000..c07f2cbc4f01 --- /dev/null +++ b/pkgs/development/python-modules/llm-fragments-pypi/default.nix @@ -0,0 +1,41 @@ +{ + lib, + buildPythonPackage, + fetchFromGitHub, + hatchling, + llm, + llm-fragments-pypi, + httpx, +}: + +buildPythonPackage rec { + pname = "llm-fragments-pypi"; + version = "0.1.1"; + pyproject = true; + + src = fetchFromGitHub { + owner = "samueldg"; + repo = "llm-fragments-pypi"; + tag = version; + hash = "sha256-1XqAmuZ1WMHD6JbLbLsK9K4Uf3FvvKJD4mn1G2J/3C8="; + }; + + build-system = [ hatchling ]; + + dependencies = [ + httpx + llm + ]; + + pythonImportsCheck = [ "llm_fragments_pypi" ]; + + passthru.tests = llm.mkPluginTest llm-fragments-pypi; + + meta = { + description = "LLM fragments plugin for PyPI packages metadata"; + homepage = "https://github.com/samueldg/llm-fragments-pypi"; + changelog = "https://github.com/samueldg/llm-fragments-pypi/releases/tag/${version}/CHANGELOG.md"; + license = lib.licenses.asl20; + maintainers = with lib.maintainers; [ philiptaron ]; + }; +} diff --git a/pkgs/development/python-modules/llm-fragments-reader/default.nix b/pkgs/development/python-modules/llm-fragments-reader/default.nix new file mode 100644 index 000000000000..b3b5aa4ad9ce --- /dev/null +++ b/pkgs/development/python-modules/llm-fragments-reader/default.nix @@ -0,0 +1,49 @@ +{ + lib, + buildPythonPackage, + fetchFromGitHub, + setuptools, + httpx, + httpx-sse, + llm, + llm-fragments-reader, + pytestCheckHook, + pytest-asyncio, + pytest-httpx, + writableTmpDirAsHomeHook, +}: + +buildPythonPackage rec { + pname = "llm-fragments-reader"; + version = "0.1"; + pyproject = true; + + src = fetchFromGitHub { + owner = "simonw"; + repo = "llm-fragments-reader"; + tag = version; + hash = "sha256-2xdvOpMGsTtnerrlGiVSHoJrM+GQ7Zgv+zn2SAwYAL4="; + }; + + build-system = [ setuptools ]; + + dependencies = [ llm ]; + + nativeCheckInputs = [ + pytestCheckHook + pytest-httpx + writableTmpDirAsHomeHook + ]; + + pythonImportsCheck = [ "llm_fragments_reader" ]; + + passthru.tests = llm.mkPluginTest llm-fragments-reader; + + meta = { + description = "Run URLs through the Jina Reader API"; + homepage = "https://github.com/simonw/llm-fragments-reader"; + changelog = "https://github.com/simonw/llm-fragments-reader/releases/tag/${version}/CHANGELOG.md"; + license = lib.licenses.asl20; + maintainers = with lib.maintainers; [ philiptaron ]; + }; +} diff --git a/pkgs/development/python-modules/llm-fragments-symbex/default.nix b/pkgs/development/python-modules/llm-fragments-symbex/default.nix new file mode 100644 index 000000000000..c476c6a9ec6e --- /dev/null +++ b/pkgs/development/python-modules/llm-fragments-symbex/default.nix @@ -0,0 +1,48 @@ +{ + lib, + buildPythonPackage, + fetchFromGitHub, + setuptools, + symbex, + llm, + llm-fragments-symbex, + pytestCheckHook, + writableTmpDirAsHomeHook, +}: + +buildPythonPackage rec { + pname = "llm-fragments-symbex"; + version = "0.1"; + pyproject = true; + + src = fetchFromGitHub { + owner = "simonw"; + repo = "llm-fragments-symbex"; + tag = version; + hash = "sha256-LECMHv4tGMCY60JU68y2Sfxp97Px7T/RJVhYVDSFCy4="; + }; + + build-system = [ setuptools ]; + + dependencies = [ + llm + symbex + ]; + + nativeCheckInputs = [ + pytestCheckHook + writableTmpDirAsHomeHook + ]; + + pythonImportsCheck = [ "llm_fragments_symbex" ]; + + passthru.tests = llm.mkPluginTest llm-fragments-symbex; + + meta = { + description = "LLM fragment loader for Python symbols"; + homepage = "https://github.com/simonw/llm-fragments-symbex"; + changelog = "https://github.com/simonw/llm-fragments-symbex/releases/tag/${version}/CHANGELOG.md"; + license = lib.licenses.asl20; + maintainers = with lib.maintainers; [ philiptaron ]; + }; +} diff --git a/pkgs/development/python-modules/llm-gemini/default.nix b/pkgs/development/python-modules/llm-gemini/default.nix index 0d0c33a4c446..ab0976f2a97b 100644 --- a/pkgs/development/python-modules/llm-gemini/default.nix +++ b/pkgs/development/python-modules/llm-gemini/default.nix @@ -1,10 +1,10 @@ { lib, - callPackage, buildPythonPackage, fetchFromGitHub, setuptools, llm, + llm-gemini, httpx, ijson, pytestCheckHook, @@ -15,24 +15,22 @@ }: buildPythonPackage rec { pname = "llm-gemini"; - version = "0.20"; + version = "0.21"; pyproject = true; src = fetchFromGitHub { owner = "simonw"; repo = "llm-gemini"; tag = version; - hash = "sha256-haaJtJ9RqV5/n/j8PNXPS7zc332W+gU20x0wGPRdzOQ="; + hash = "sha256-aCP0YjcghzpgceuZRKGTN15wm7OIPCwcJAJJBxh78f4="; }; - build-system = [ - setuptools - ]; + build-system = [ setuptools ]; dependencies = [ - llm httpx ijson + llm ]; nativeCheckInputs = [ @@ -45,9 +43,7 @@ buildPythonPackage rec { pythonImportsCheck = [ "llm_gemini" ]; - passthru.tests = { - llm-plugin = callPackage ./tests/llm-plugin.nix { }; - }; + passthru.tests = llm.mkPluginTest llm-gemini; meta = { description = "LLM plugin to access Google's Gemini family of models"; diff --git a/pkgs/development/python-modules/llm-gemini/tests/llm-plugin.nix b/pkgs/development/python-modules/llm-gemini/tests/llm-plugin.nix deleted file mode 100644 index d1f2f6ffbe67..000000000000 --- a/pkgs/development/python-modules/llm-gemini/tests/llm-plugin.nix +++ /dev/null @@ -1,22 +0,0 @@ -{ - runCommand, - python, - yq, -}: -let - venv = python.withPackages (ps: [ - ps.llm - ps.llm-gemini - ]); -in -runCommand "llm-gemini-test-llm-plugin" - { - nativeBuildInputs = [ - venv - yq - ]; - } - '' - llm plugins | yq --exit-status 'any(.name == "llm-gemini")' - touch "$out" - '' diff --git a/pkgs/development/python-modules/llm-gguf/default.nix b/pkgs/development/python-modules/llm-gguf/default.nix index 76a01159b2b8..1a399f3861e6 100644 --- a/pkgs/development/python-modules/llm-gguf/default.nix +++ b/pkgs/development/python-modules/llm-gguf/default.nix @@ -1,6 +1,5 @@ { lib, - callPackage, buildPythonPackage, fetchFromGitHub, @@ -11,6 +10,7 @@ httpx, llama-cpp-python, llm, + llm-gguf, }: buildPythonPackage rec { @@ -25,14 +25,12 @@ buildPythonPackage rec { hash = "sha256-ihMOiQnTfgZKICVDoQHLOMahrd+GiB+HwWFBMyIcs0A="; }; - build-system = [ - setuptools - ]; + build-system = [ setuptools ]; dependencies = [ httpx - llama-cpp-python llm + llama-cpp-python ]; pythonImportsCheck = [ "llm_gguf" ]; @@ -40,9 +38,7 @@ buildPythonPackage rec { # Tests require internet access (downloading models) doCheck = false; - passthru.tests = { - llm-plugin = callPackage ./tests/llm-plugin.nix { }; - }; + passthru.tests = llm.mkPluginTest llm-gguf; meta = { description = "Run models distributed as GGUF files using LLM"; diff --git a/pkgs/development/python-modules/llm-gguf/tests/llm-plugin.nix b/pkgs/development/python-modules/llm-gguf/tests/llm-plugin.nix deleted file mode 100644 index 97e1f51d6c26..000000000000 --- a/pkgs/development/python-modules/llm-gguf/tests/llm-plugin.nix +++ /dev/null @@ -1,22 +0,0 @@ -{ - runCommand, - python, - yq, -}: -let - venv = python.withPackages (ps: [ - ps.llm - ps.llm-gguf - ]); -in -runCommand "llm-gguf-test-llm-plugin" - { - nativeBuildInputs = [ - venv - yq - ]; - } - '' - llm plugins | yq --exit-status 'any(.name == "llm-gguf")' - touch "$out" - '' diff --git a/pkgs/development/python-modules/llm-git/default.nix b/pkgs/development/python-modules/llm-git/default.nix new file mode 100644 index 000000000000..957a54581de6 --- /dev/null +++ b/pkgs/development/python-modules/llm-git/default.nix @@ -0,0 +1,62 @@ +{ + lib, + buildPythonPackage, + fetchFromGitHub, + setuptools, + click, + deepmerge, + pyyaml, + rich, + pygments, + llm, + llm-git, + pytestCheckHook, + pytest-cov-stub, + pytest-asyncio, + pytest-httpx, + writableTmpDirAsHomeHook, +}: + +buildPythonPackage rec { + pname = "llm-git"; + version = "0.2.2"; + pyproject = true; + + src = fetchFromGitHub { + owner = "OttoAllmendinger"; + repo = "llm-git"; + tag = "v${version}"; + hash = "sha256-LcIsJPQgZ4gj2t7sSa0Wu35WHWYyquZZTS/UxojH+XU="; + }; + + build-system = [ + setuptools + ]; + + dependencies = [ + click + deepmerge + llm + pyyaml + rich + pygments + ]; + + nativeCheckInputs = [ + pytestCheckHook + pytest-cov-stub + writableTmpDirAsHomeHook + ]; + + pythonImportsCheck = [ "llm_git" ]; + + passthru.tests = llm.mkPluginTest llm-git; + + meta = { + description = "AI-powered Git commands for the LLM CLI tool"; + homepage = "https://github.com/OttoAllmendinger/llm-git"; + changelog = "https://github.com/OttoAllmendinger/llm-git/releases/tag/${version}/CHANGELOG.md"; + license = lib.licenses.asl20; + maintainers = with lib.maintainers; [ philiptaron ]; + }; +} diff --git a/pkgs/development/python-modules/llm-grok/default.nix b/pkgs/development/python-modules/llm-grok/default.nix new file mode 100644 index 000000000000..a2c5ac03adc3 --- /dev/null +++ b/pkgs/development/python-modules/llm-grok/default.nix @@ -0,0 +1,54 @@ +{ + lib, + buildPythonPackage, + fetchFromGitHub, + setuptools, + llm, + llm-grok, + httpx, + httpx-sse, + rich, + pytestCheckHook, + pytest-httpx, + writableTmpDirAsHomeHook, +}: + +buildPythonPackage rec { + pname = "llm-grok"; + version = "1.0.1"; + pyproject = true; + + src = fetchFromGitHub { + owner = "Hiepler"; + repo = "llm-grok"; + tag = "v${version}"; + hash = "sha256-OeeU/53XKucLCtGvnl5RWc/QqF0TprB/SO8pnnK5fdw="; + }; + + build-system = [ setuptools ]; + + dependencies = [ + llm + httpx + httpx-sse + rich + ]; + + nativeCheckInputs = [ + pytestCheckHook + pytest-httpx + writableTmpDirAsHomeHook + ]; + + pythonImportsCheck = [ "llm_grok" ]; + + passthru.tests = llm.mkPluginTest llm-grok; + + meta = { + description = "LLM plugin providing access to Grok models using the xAI API"; + homepage = "https://github.com/Hiepler/llm-grok"; + changelog = "https://github.com/Hiepler/llm-grok/releases/tag/${src.tag}/CHANGELOG.md"; + license = lib.licenses.asl20; + maintainers = with lib.maintainers; [ philiptaron ]; + }; +} diff --git a/pkgs/development/python-modules/llm-groq/default.nix b/pkgs/development/python-modules/llm-groq/default.nix new file mode 100644 index 000000000000..55364db0921b --- /dev/null +++ b/pkgs/development/python-modules/llm-groq/default.nix @@ -0,0 +1,43 @@ +{ + lib, + buildPythonPackage, + fetchFromGitHub, + setuptools, + llm, + llm-groq, + groq, +}: + +buildPythonPackage rec { + pname = "llm-groq"; + version = "0.8"; + pyproject = true; + + src = fetchFromGitHub { + owner = "angerman"; + repo = "llm-groq"; + tag = "v${version}"; + hash = "sha256-sZ5d9w43NvypaPrebwZ5BLgRaCHAhd7gBU6uHEdUaF4="; + }; + + build-system = [ + setuptools + ]; + + dependencies = [ + groq + llm + ]; + + pythonImportsCheck = [ "llm_groq" ]; + + passthru.tests = llm.mkPluginTest llm-groq; + + meta = { + description = "LLM plugin providing access to Groqcloud models."; + homepage = "https://github.com/angerman/llm-groq"; + changelog = "https://github.com/angerman/llm-groq/releases/tag/${src.tag}/CHANGELOG.md"; + license = lib.licenses.asl20; + maintainers = with lib.maintainers; [ philiptaron ]; + }; +} diff --git a/pkgs/development/python-modules/llm-hacker-news/default.nix b/pkgs/development/python-modules/llm-hacker-news/default.nix new file mode 100644 index 000000000000..6c481e0212b6 --- /dev/null +++ b/pkgs/development/python-modules/llm-hacker-news/default.nix @@ -0,0 +1,37 @@ +{ + lib, + buildPythonPackage, + fetchFromGitHub, + setuptools, + llm, + llm-hacker-news, +}: + +buildPythonPackage rec { + pname = "llm-hacker-news"; + version = "0.1.1"; + pyproject = true; + + src = fetchFromGitHub { + owner = "simonw"; + repo = "llm-hacker-news"; + tag = version; + hash = "sha256-pywx9TAN/mnGR6Vv6YsPhLO4R5Geagw/bcydQjvTH5s="; + }; + + build-system = [ setuptools ]; + + dependencies = [ llm ]; + + pythonImportsCheck = [ "llm_hacker_news" ]; + + passthru.tests = llm.mkPluginTest llm-hacker-news; + + meta = { + description = "LLM plugin for pulling content from Hacker News"; + homepage = "https://github.com/simonw/llm-hacker-news"; + changelog = "https://github.com/simonw/llm-hacker-news/releases/tag/${version}/CHANGELOG.md"; + license = lib.licenses.asl20; + maintainers = with lib.maintainers; [ philiptaron ]; + }; +} diff --git a/pkgs/development/python-modules/llm-jq/default.nix b/pkgs/development/python-modules/llm-jq/default.nix index 14ab4046712e..f88e6ae566f4 100644 --- a/pkgs/development/python-modules/llm-jq/default.nix +++ b/pkgs/development/python-modules/llm-jq/default.nix @@ -1,11 +1,10 @@ { lib, - callPackage, buildPythonPackage, fetchFromGitHub, setuptools, llm, - nix-update-script, + llm-jq, }: buildPythonPackage rec { pname = "llm-jq"; @@ -19,19 +18,13 @@ buildPythonPackage rec { hash = "sha256-Mf/tbB9+UdmSRpulqv5Wagr8wjDcRrNs2741DNQZhO4="; }; - build-system = [ - setuptools - ]; + build-system = [ setuptools ]; - dependencies = [ - llm - ]; + dependencies = [ llm ]; pythonImportsCheck = [ "llm_jq" ]; - passthru.tests = { - llm-plugin = callPackage ./tests/llm-plugin.nix { }; - }; + passthru.tests = llm.mkPluginTest llm-jq; meta = { description = "Write and execute jq programs with the help of LLM"; diff --git a/pkgs/development/python-modules/llm-jq/tests/llm-plugin.nix b/pkgs/development/python-modules/llm-jq/tests/llm-plugin.nix deleted file mode 100644 index d659a2d52198..000000000000 --- a/pkgs/development/python-modules/llm-jq/tests/llm-plugin.nix +++ /dev/null @@ -1,23 +0,0 @@ -{ - runCommand, - python, - yq, -}: -let - venv = python.withPackages (ps: [ - ps.llm - ps.llm-jq - ]); -in -runCommand "llm-jq-test-llm-plugin" - { - nativeBuildInputs = [ - venv - yq - ]; - } - '' - llm plugins | yq --exit-status 'any(.name == "llm-jq")' - llm jq --help - touch "$out" - '' diff --git a/pkgs/development/python-modules/llm-llama-server/default.nix b/pkgs/development/python-modules/llm-llama-server/default.nix new file mode 100644 index 000000000000..cb0887020d41 --- /dev/null +++ b/pkgs/development/python-modules/llm-llama-server/default.nix @@ -0,0 +1,44 @@ +{ + lib, + buildPythonPackage, + fetchFromGitHub, + setuptools, + llm, + llm-llama-server, + pytestCheckHook, + writableTmpDirAsHomeHook, +}: + +buildPythonPackage rec { + pname = "llm-llama-server"; + version = "0.2"; + pyproject = true; + + src = fetchFromGitHub { + owner = "simonw"; + repo = "llm-llama-server"; + tag = version; + hash = "sha256-jtFSfGu3JhNUfTsspY+OFLTMt9jQrh6R05sK9KBOKTE="; + }; + + build-system = [ setuptools ]; + + dependencies = [ llm ]; + + nativeCheckInputs = [ + pytestCheckHook + writableTmpDirAsHomeHook + ]; + + pythonImportsCheck = [ "llm_llama_server" ]; + + passthru.tests = llm.mkPluginTest llm-llama-server; + + meta = { + description = "LLM plugin providing access to Mistral models using the Mistral API"; + homepage = "https://github.com/simonw/llm-llama-server"; + changelog = "https://github.com/simonw/llm-llama-server/releases/tag/${version}/CHANGELOG.md"; + license = lib.licenses.asl20; + maintainers = with lib.maintainers; [ philiptaron ]; + }; +} diff --git a/pkgs/development/python-modules/llm-mistral/default.nix b/pkgs/development/python-modules/llm-mistral/default.nix new file mode 100644 index 000000000000..773868d5a875 --- /dev/null +++ b/pkgs/development/python-modules/llm-mistral/default.nix @@ -0,0 +1,56 @@ +{ + lib, + buildPythonPackage, + fetchFromGitHub, + setuptools, + httpx, + httpx-sse, + llm, + llm-mistral, + pytestCheckHook, + pytest-asyncio, + pytest-httpx, + writableTmpDirAsHomeHook, +}: + +buildPythonPackage rec { + pname = "llm-mistral"; + version = "0.14"; + pyproject = true; + + src = fetchFromGitHub { + owner = "simonw"; + repo = "llm-mistral"; + tag = version; + hash = "sha256-NuiqRA/SCjGq0hJsnHJ/vgdncIKu3oE9WqWGht7QRMc="; + }; + + build-system = [ + setuptools + ]; + + dependencies = [ + httpx + httpx-sse + llm + ]; + + nativeCheckInputs = [ + pytestCheckHook + pytest-asyncio + pytest-httpx + writableTmpDirAsHomeHook + ]; + + pythonImportsCheck = [ "llm_mistral" ]; + + passthru.tests = llm.mkPluginTest llm-mistral; + + meta = { + description = "LLM plugin providing access to Mistral models using the Mistral API"; + homepage = "https://github.com/simonw/llm-mistral"; + changelog = "https://github.com/simonw/llm-mistral/releases/tag/${version}/CHANGELOG.md"; + license = lib.licenses.asl20; + maintainers = with lib.maintainers; [ philiptaron ]; + }; +} diff --git a/pkgs/development/python-modules/llm-ollama/default.nix b/pkgs/development/python-modules/llm-ollama/default.nix index e8d13d4926c6..0df527ee0241 100644 --- a/pkgs/development/python-modules/llm-ollama/default.nix +++ b/pkgs/development/python-modules/llm-ollama/default.nix @@ -1,6 +1,5 @@ { lib, - callPackage, buildPythonPackage, fetchFromGitHub, @@ -18,28 +17,26 @@ pytest-asyncio, pytest-mock, writableTmpDirAsHomeHook, + llm-ollama, }: buildPythonPackage rec { pname = "llm-ollama"; - version = "0.10.0"; + version = "0.11.0"; pyproject = true; src = fetchFromGitHub { owner = "taketwo"; repo = "llm-ollama"; tag = version; - hash = "sha256-IA9Tb82XB+Gr6YwMVqzsw1dPtT3GWK2W/ZtuDVznF1A"; + hash = "sha256-iwrDqrPt/zwXypBwD7zDAcen4fQq6PXl7Xj5VUL2KWA="; }; - build-system = [ - setuptools - # Follows the reasoning from https://github.com/NixOS/nixpkgs/pull/327800#discussion_r1681586659 about including llm in build-system - llm - ]; + build-system = [ setuptools ]; dependencies = [ click + llm ollama pydantic ]; @@ -55,9 +52,7 @@ buildPythonPackage rec { "llm_ollama" ]; - passthru.tests = { - llm-plugin = callPackage ./tests/llm-plugin.nix { }; - }; + passthru.tests = llm.mkPluginTest llm-ollama; meta = { description = "LLM plugin providing access to Ollama models using HTTP API"; diff --git a/pkgs/development/python-modules/llm-ollama/tests/llm-plugin.nix b/pkgs/development/python-modules/llm-ollama/tests/llm-plugin.nix deleted file mode 100644 index c601b393ac62..000000000000 --- a/pkgs/development/python-modules/llm-ollama/tests/llm-plugin.nix +++ /dev/null @@ -1,24 +0,0 @@ -{ - runCommand, - python, - yq, - cacert, -}: -let - venv = python.withPackages (ps: [ - ps.llm - ps.llm-ollama - ]); -in -runCommand "llm-ollama-test-llm-plugin" - { - nativeBuildInputs = [ - venv - yq - ]; - env.SSL_CERT_FILE = "${cacert}/etc/ssl/certs/ca-bundle.crt"; - } - '' - llm plugins | yq --exit-status 'any(.name == "llm-ollama")' - touch "$out" - '' diff --git a/pkgs/development/python-modules/llm-openai-plugin/default.nix b/pkgs/development/python-modules/llm-openai-plugin/default.nix index 76f13696a877..49fd64c6acd2 100644 --- a/pkgs/development/python-modules/llm-openai-plugin/default.nix +++ b/pkgs/development/python-modules/llm-openai-plugin/default.nix @@ -1,10 +1,10 @@ { lib, - callPackage, buildPythonPackage, fetchFromGitHub, setuptools, llm, + llm-openai-plugin, openai, pytestCheckHook, pytest-asyncio, @@ -25,9 +25,7 @@ buildPythonPackage rec { hash = "sha256-UoUxCwR+qOUufHuS0gw6A5Q7sB77VO4HYuMjFGN7mhA="; }; - build-system = [ - setuptools - ]; + build-system = [ setuptools ]; dependencies = [ llm @@ -45,9 +43,7 @@ buildPythonPackage rec { pythonImportsCheck = [ "llm_openai" ]; - passthru.tests = { - llm-plugin = callPackage ./tests/llm-plugin.nix { }; - }; + passthru.tests = llm.mkPluginTest llm-openai-plugin; meta = { description = "OpenAI plugin for LLM"; diff --git a/pkgs/development/python-modules/llm-openai-plugin/tests/llm-plugin.nix b/pkgs/development/python-modules/llm-openai-plugin/tests/llm-plugin.nix deleted file mode 100644 index 8092b15a5c90..000000000000 --- a/pkgs/development/python-modules/llm-openai-plugin/tests/llm-plugin.nix +++ /dev/null @@ -1,22 +0,0 @@ -{ - runCommand, - python, - yq, -}: -let - venv = python.withPackages (ps: [ - ps.llm - ps.llm-openai-plugin - ]); -in -runCommand "llm-openai-plugin-test-llm-plugin" - { - nativeBuildInputs = [ - venv - yq - ]; - } - '' - llm plugins | yq --exit-status 'any(.name == "llm-openai-plugin")' - touch "$out" - '' diff --git a/pkgs/development/python-modules/llm-openrouter/default.nix b/pkgs/development/python-modules/llm-openrouter/default.nix new file mode 100644 index 000000000000..ada713681c69 --- /dev/null +++ b/pkgs/development/python-modules/llm-openrouter/default.nix @@ -0,0 +1,56 @@ +{ + lib, + buildPythonPackage, + fetchFromGitHub, + setuptools, + llm, + llm-openrouter, + httpx, + openai, + pytestCheckHook, + inline-snapshot, + pytest-recording, + writableTmpDirAsHomeHook, +}: + +buildPythonPackage rec { + pname = "llm-openrouter"; + version = "0.4.1"; + pyproject = true; + + src = fetchFromGitHub { + owner = "simonw"; + repo = "llm-openrouter"; + tag = version; + hash = "sha256-ojBkyXqEaqTcOv7mzTWL5Ihhb50zeVzeQZNA6DySuVg="; + }; + + build-system = [ + setuptools + ]; + + dependencies = [ + httpx + llm + openai + ]; + + nativeCheckInputs = [ + pytestCheckHook + inline-snapshot + pytest-recording + writableTmpDirAsHomeHook + ]; + + pythonImportsCheck = [ "llm_openrouter" ]; + + passthru.tests = llm.mkPluginTest llm-openrouter; + + meta = { + description = "LLM plugin for models hosted by OpenRouter"; + homepage = "https://github.com/simonw/llm-openrouter"; + changelog = "https://github.com/simonw/llm-openrouter/releases/tag/${version}/CHANGELOG.md"; + license = lib.licenses.asl20; + maintainers = with lib.maintainers; [ philiptaron ]; + }; +} diff --git a/pkgs/development/python-modules/llm-pdf-to-images/default.nix b/pkgs/development/python-modules/llm-pdf-to-images/default.nix new file mode 100644 index 000000000000..fd39db4914dd --- /dev/null +++ b/pkgs/development/python-modules/llm-pdf-to-images/default.nix @@ -0,0 +1,49 @@ +{ + lib, + buildPythonPackage, + fetchFromGitHub, + setuptools, + pymupdf, + llm, + llm-pdf-to-images, + pytestCheckHook, + pytest-asyncio, + writableTmpDirAsHomeHook, +}: + +buildPythonPackage rec { + pname = "llm-pdf-to-images"; + version = "0.1"; + pyproject = true; + + src = fetchFromGitHub { + owner = "simonw"; + repo = "llm-pdf-to-images"; + tag = version; + hash = "sha256-UWtCPdKrGE93NNjCroct5fPhq1pWIkngXXtRb+BHm8k="; + }; + + build-system = [ setuptools ]; + + dependencies = [ + llm + pymupdf + ]; + + nativeCheckInputs = [ + pytestCheckHook + writableTmpDirAsHomeHook + ]; + + pythonImportsCheck = [ "llm_pdf_to_images" ]; + + passthru.tests = llm.mkPluginTest llm-pdf-to-images; + + meta = { + description = "LLM fragment plugin to load a PDF as a sequence of images"; + homepage = "https://github.com/simonw/llm-pdf-to-images"; + changelog = "https://github.com/simonw/llm-pdf-to-images/releases/tag/${version}/CHANGELOG.md"; + license = lib.licenses.asl20; + maintainers = with lib.maintainers; [ philiptaron ]; + }; +} diff --git a/pkgs/development/python-modules/llm-sentence-transformers/default.nix b/pkgs/development/python-modules/llm-sentence-transformers/default.nix new file mode 100644 index 000000000000..db7439998e87 --- /dev/null +++ b/pkgs/development/python-modules/llm-sentence-transformers/default.nix @@ -0,0 +1,56 @@ +{ + lib, + buildPythonPackage, + fetchFromGitHub, + setuptools, + llm, + llm-sentence-transformers, + einops, + sentence-transformers, + pytestCheckHook, + writableTmpDirAsHomeHook, +}: + +buildPythonPackage rec { + pname = "llm-sentence-transformers"; + version = "0.3.2"; + pyproject = true; + + src = fetchFromGitHub { + owner = "simonw"; + repo = "llm-sentence-transformers"; + tag = version; + hash = "sha256-FDDMItKFEYEptiL3EHKgKVxClqRU9RaM3uD3xP0F4OM="; + }; + + build-system = [ setuptools ]; + + dependencies = [ + einops + llm + sentence-transformers + ]; + + nativeCheckInputs = [ + pytestCheckHook + writableTmpDirAsHomeHook + ]; + + # Disabled because they access the network + disabledTests = [ + "test_run_embedding" + "test_embed_multi_with_generator" + ]; + + pythonImportsCheck = [ "llm_sentence_transformers" ]; + + passthru.tests = llm.mkPluginTest llm-sentence-transformers; + + meta = { + description = "LLM plugin for embeddings using sentence-transformers"; + homepage = "https://github.com/simonw/llm-sentence-transformers"; + changelog = "https://github.com/simonw/llm-sentence-transformers/releases/tag/${version}/CHANGELOG.md"; + license = lib.licenses.asl20; + maintainers = with lib.maintainers; [ philiptaron ]; + }; +} diff --git a/pkgs/development/python-modules/llm-templates-fabric/default.nix b/pkgs/development/python-modules/llm-templates-fabric/default.nix new file mode 100644 index 000000000000..c966d21915ea --- /dev/null +++ b/pkgs/development/python-modules/llm-templates-fabric/default.nix @@ -0,0 +1,37 @@ +{ + lib, + buildPythonPackage, + fetchFromGitHub, + setuptools, + llm, + llm-templates-fabric, +}: + +buildPythonPackage rec { + pname = "llm-templates-fabric"; + version = "0.2"; + pyproject = true; + + src = fetchFromGitHub { + owner = "simonw"; + repo = "llm-templates-fabric"; + tag = version; + hash = "sha256-tfkSjeT9WstUsNCtVr3fMzqELFCtfYphqf3xFGvHaV0="; + }; + + build-system = [ setuptools ]; + + dependencies = [ llm ]; + + pythonImportsCheck = [ "llm_templates_fabric" ]; + + passthru.tests = llm.mkPluginTest llm-templates-fabric; + + meta = { + description = "Load LLM templates from Fabric"; + homepage = "https://github.com/simonw/llm-templates-fabric"; + changelog = "https://github.com/simonw/llm-templates-fabric/releases/tag/${version}/CHANGELOG.md"; + license = lib.licenses.asl20; + maintainers = with lib.maintainers; [ philiptaron ]; + }; +} diff --git a/pkgs/development/python-modules/llm-templates-github/default.nix b/pkgs/development/python-modules/llm-templates-github/default.nix new file mode 100644 index 000000000000..ccf0d937f05d --- /dev/null +++ b/pkgs/development/python-modules/llm-templates-github/default.nix @@ -0,0 +1,37 @@ +{ + lib, + buildPythonPackage, + fetchFromGitHub, + setuptools, + llm, + llm-templates-github, +}: + +buildPythonPackage rec { + pname = "llm-templates-github"; + version = "0.1"; + pyproject = true; + + src = fetchFromGitHub { + owner = "simonw"; + repo = "llm-templates-github"; + tag = version; + hash = "sha256-SFXrvpKrvfIP0JmXQt6OZ52kne4AEtiggbshyac9XQc="; + }; + + build-system = [ setuptools ]; + + dependencies = [ llm ]; + + pythonImportsCheck = [ "llm_templates_github" ]; + + passthru.tests = llm.mkPluginTest llm-templates-github; + + meta = { + description = "Load LLM templates from GitHub repositories"; + homepage = "https://github.com/simonw/llm-templates-github"; + changelog = "https://github.com/simonw/llm-templates-github/releases/tag/${version}/CHANGELOG.md"; + license = lib.licenses.asl20; + maintainers = with lib.maintainers; [ philiptaron ]; + }; +} diff --git a/pkgs/development/python-modules/llm-tools-datasette/default.nix b/pkgs/development/python-modules/llm-tools-datasette/default.nix new file mode 100644 index 000000000000..4320fa797a1e --- /dev/null +++ b/pkgs/development/python-modules/llm-tools-datasette/default.nix @@ -0,0 +1,48 @@ +{ + lib, + buildPythonPackage, + fetchFromGitHub, + setuptools, + llm, + llm-tools-datasette, + llm-echo, + pytestCheckHook, + pytest-httpx, + writableTmpDirAsHomeHook, +}: + +buildPythonPackage rec { + pname = "llm-tools-datasette"; + version = "0.1"; + pyproject = true; + + src = fetchFromGitHub { + owner = "simonw"; + repo = "llm-tools-datasette"; + tag = version; + hash = "sha256-Us9bPk2qpTlgJqQ0Cl9QdeqW+h8j+pmnkriM0WXEyyA="; + }; + + build-system = [ setuptools ]; + + dependencies = [ llm ]; + + nativeCheckInputs = [ + llm-echo + pytestCheckHook + pytest-httpx + writableTmpDirAsHomeHook + ]; + + pythonImportsCheck = [ "llm_tools_datasette" ]; + + passthru.tests = llm.mkPluginTest llm-tools-datasette; + + meta = { + description = "Expose Datasette instances to LLM as a tool"; + homepage = "https://github.com/simonw/llm-tools-datasette"; + changelog = "https://github.com/simonw/llm-tools-datasette/releases/tag/${version}/CHANGELOG.md"; + license = lib.licenses.asl20; + maintainers = with lib.maintainers; [ philiptaron ]; + }; +} diff --git a/pkgs/development/python-modules/llm-tools-quickjs/default.nix b/pkgs/development/python-modules/llm-tools-quickjs/default.nix new file mode 100644 index 000000000000..ad447a01ade1 --- /dev/null +++ b/pkgs/development/python-modules/llm-tools-quickjs/default.nix @@ -0,0 +1,50 @@ +{ + lib, + buildPythonPackage, + fetchFromGitHub, + setuptools, + quickjs, + llm, + llm-tools-quickjs, + llm-echo, + pytestCheckHook, + writableTmpDirAsHomeHook, +}: + +buildPythonPackage rec { + pname = "llm-tools-quickjs"; + version = "0.1"; + pyproject = true; + + src = fetchFromGitHub { + owner = "simonw"; + repo = "llm-tools-quickjs"; + tag = version; + hash = "sha256-Si3VcHnRUj8Q/N8pRhltPOM6K64TX9DBH/u4WQxQJjQ="; + }; + + build-system = [ setuptools ]; + + dependencies = [ + llm + quickjs + ]; + + nativeCheckInputs = [ + llm-echo + pytestCheckHook + writableTmpDirAsHomeHook + ]; + + pythonImportsCheck = [ "llm_tools_quickjs" ]; + + passthru.tests = llm.mkPluginTest llm-tools-quickjs; + + meta = { + description = "JavaScript execution as a tool for LLM"; + homepage = "https://github.com/simonw/llm-tools-quickjs"; + changelog = "https://github.com/simonw/llm-tools-quickjs/releases/tag/${version}/CHANGELOG.md"; + license = lib.licenses.asl20; + maintainers = with lib.maintainers; [ philiptaron ]; + }; +} diff --git a/pkgs/development/python-modules/llm-tools-simpleeval/default.nix b/pkgs/development/python-modules/llm-tools-simpleeval/default.nix new file mode 100644 index 000000000000..06b5a31f8ea5 --- /dev/null +++ b/pkgs/development/python-modules/llm-tools-simpleeval/default.nix @@ -0,0 +1,50 @@ +{ + lib, + buildPythonPackage, + fetchFromGitHub, + setuptools, + llm, + llm-tools-simpleeval, + llm-echo, + pytestCheckHook, + simpleeval, + writableTmpDirAsHomeHook, +}: + +buildPythonPackage rec { + pname = "llm-tools-simpleeval"; + version = "0.1.1"; + pyproject = true; + + src = fetchFromGitHub { + owner = "simonw"; + repo = "llm-tools-simpleeval"; + tag = version; + hash = "sha256-IOmYu7zoim7Co/xIm5VLaGkCPI0o+2Nb2Pu3U2fH0BU="; + }; + + build-system = [ setuptools ]; + + dependencies = [ + llm + simpleeval + ]; + + nativeCheckInputs = [ + llm-echo + pytestCheckHook + writableTmpDirAsHomeHook + ]; + + pythonImportsCheck = [ "llm_tools_simpleeval" ]; + + passthru.tests = llm.mkPluginTest llm-tools-simpleeval; + + meta = { + description = "Make simple_eval available as an LLM tool"; + homepage = "https://github.com/simonw/llm-tools-simpleeval"; + changelog = "https://github.com/simonw/llm-tools-simpleeval/releases/tag/${version}/CHANGELOG.md"; + license = lib.licenses.asl20; + maintainers = with lib.maintainers; [ philiptaron ]; + }; +} diff --git a/pkgs/development/python-modules/llm-tools-sqlite/default.nix b/pkgs/development/python-modules/llm-tools-sqlite/default.nix new file mode 100644 index 000000000000..494c4c5994e5 --- /dev/null +++ b/pkgs/development/python-modules/llm-tools-sqlite/default.nix @@ -0,0 +1,46 @@ +{ + lib, + buildPythonPackage, + fetchFromGitHub, + setuptools, + llm, + llm-tools-sqlite, + llm-echo, + pytestCheckHook, + writableTmpDirAsHomeHook, +}: + +buildPythonPackage rec { + pname = "llm-tools-sqlite"; + version = "0.1"; + pyproject = true; + + src = fetchFromGitHub { + owner = "simonw"; + repo = "llm-tools-sqlite"; + tag = version; + hash = "sha256-VAmK4cXzZWTWCU92TwMdhNJPvYPZ88t5BZe8vo60SZY="; + }; + + build-system = [ setuptools ]; + + dependencies = [ llm ]; + + nativeCheckInputs = [ + llm-echo + pytestCheckHook + writableTmpDirAsHomeHook + ]; + + pythonImportsCheck = [ "llm_tools_sqlite" ]; + + passthru.tests = llm.mkPluginTest llm-tools-sqlite; + + meta = { + description = "LLM tools for running queries against SQLite"; + homepage = "https://github.com/simonw/llm-tools-sqlite"; + changelog = "https://github.com/simonw/llm-tools-sqlite/releases/tag/${version}/CHANGELOG.md"; + license = lib.licenses.asl20; + maintainers = with lib.maintainers; [ philiptaron ]; + }; +} diff --git a/pkgs/development/python-modules/llm-venice/default.nix b/pkgs/development/python-modules/llm-venice/default.nix new file mode 100644 index 000000000000..df24b6a20967 --- /dev/null +++ b/pkgs/development/python-modules/llm-venice/default.nix @@ -0,0 +1,40 @@ +{ + lib, + buildPythonPackage, + fetchFromGitHub, + setuptools, + llm, + llm-venice, +}: + +buildPythonPackage rec { + pname = "llm-venice"; + version = "0.7.0"; + pyproject = true; + + src = fetchFromGitHub { + owner = "ar-jan"; + repo = "llm-venice"; + tag = version; + hash = "sha256-vsb3oXGr+2FDJnTwYomICfald1ptben28hAJ8ypKiBI="; + }; + + build-system = [ setuptools ]; + + dependencies = [ llm ]; + + # Reaches out to the real API + doCheck = false; + + pythonImportsCheck = [ "llm_venice" ]; + + passthru.tests = llm.mkPluginTest llm-venice; + + meta = { + description = "LLM plugin to access models available via the Venice API"; + homepage = "https://github.com/ar-jan/llm-venice"; + changelog = "https://github.com/ar-jan/llm-venice/releases/tag/${version}/CHANGELOG.md"; + license = lib.licenses.asl20; + maintainers = with lib.maintainers; [ philiptaron ]; + }; +} diff --git a/pkgs/development/python-modules/llm-video-frames/default.nix b/pkgs/development/python-modules/llm-video-frames/default.nix new file mode 100644 index 000000000000..1591ead64395 --- /dev/null +++ b/pkgs/development/python-modules/llm-video-frames/default.nix @@ -0,0 +1,37 @@ +{ + lib, + buildPythonPackage, + fetchFromGitHub, + setuptools, + llm, + llm-video-frames, +}: + +buildPythonPackage rec { + pname = "llm-video-frames"; + version = "0.1"; + pyproject = true; + + src = fetchFromGitHub { + owner = "simonw"; + repo = "llm-video-frames"; + tag = version; + hash = "sha256-brTyBymoFuvSQzsD/4aWzFGCrh3yEmWbpsUNGKT9dcU="; + }; + + build-system = [ setuptools ]; + + dependencies = [ llm ]; + + pythonImportsCheck = [ "llm_video_frames" ]; + + passthru.tests = llm.mkPluginTest llm-video-frames; + + meta = { + description = "LLM plugin to turn a video into individual frames"; + homepage = "https://github.com/simonw/llm-video-frames"; + changelog = "https://github.com/simonw/llm-video-frames/releases/tag/${version}/CHANGELOG.md"; + license = lib.licenses.asl20; + maintainers = with lib.maintainers; [ philiptaron ]; + }; +} diff --git a/pkgs/development/python-modules/llm/001-disable-install-uninstall-commands.patch b/pkgs/development/python-modules/llm/001-disable-install-uninstall-commands.patch index cef7fba13343..a9012c98f3b5 100644 --- a/pkgs/development/python-modules/llm/001-disable-install-uninstall-commands.patch +++ b/pkgs/development/python-modules/llm/001-disable-install-uninstall-commands.patch @@ -1,11 +1,12 @@ diff --git a/llm/cli.py b/llm/cli.py -index af37feb..18b078a 100644 +index 5d53e74..c2b4707 100644 --- a/llm/cli.py +++ b/llm/cli.py -@@ -1014,18 +1014,7 @@ def templates_path(): +@@ -2895,30 +2895,38 @@ def display_truncated(text): + help="Include pre-release and development versions", ) - def install(packages, upgrade, editable, force_reinstall, no_cache_dir): - """Install packages from PyPI into the same environment as LLM""" + def install(packages, upgrade, editable, force_reinstall, no_cache_dir, pre): +- """Install packages from PyPI into the same environment as LLM""" - args = ["pip", "install"] - if upgrade: - args += ["--upgrade"] @@ -15,20 +16,49 @@ index af37feb..18b078a 100644 - args += ["--force-reinstall"] - if no_cache_dir: - args += ["--no-cache-dir"] +- if pre: +- args += ["--pre"] - args += list(packages) - sys.argv = args - run_module("pip", run_name="__main__") -+ click.echo("Install command has been disabled for Nix. If you want to install extra llm plugins, use llm.withPlugins([]) expression.") - - ++ """Install packages from PyPI into the same environment as LLM. Disabled for nixpkgs.""" ++ raise click.ClickException( ++"""Install command has been disabled for Nix. To install extra `llm` plugins, use the `llm.withPlugins` function. ++ ++Example: ++ ++```nix ++llm.withPlugins { ++ @listOfPackagedPlugins@ ++} ++``` ++""" ++ ) + + @cli.command() -@@ -1033,8 +1022,7 @@ def install(packages, upgrade, editable, force_reinstall, no_cache_dir): + @click.argument("packages", nargs=-1, required=True) @click.option("-y", "--yes", is_flag=True, help="Don't ask for confirmation") def uninstall(packages, yes): - """Uninstall Python packages from the LLM environment""" +- """Uninstall Python packages from the LLM environment""" - sys.argv = ["pip", "uninstall"] + list(packages) + (["-y"] if yes else []) - run_module("pip", run_name="__main__") -+ 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.") - - ++ """Uninstall Python packages from the LLM environment. Disabled for nixpkgs.""" ++ raise click.ClickException( ++"""Uninstall command has been disabled for Nix. To remove `llm` plugins, use the `llm.withPlugins` function with the desired set of plugins specified. ++ ++Example: ++ ++```nix ++llm.withPlugins { ++ @listOfPackagedPlugins@ ++} ++``` ++""" ++ ) + + @cli.command() +-- +2.49.0 + diff --git a/pkgs/development/python-modules/llm/default.nix b/pkgs/development/python-modules/llm/default.nix index aa2515f19c73..70d606ec556b 100644 --- a/pkgs/development/python-modules/llm/default.nix +++ b/pkgs/development/python-modules/llm/default.nix @@ -1,9 +1,12 @@ { lib, + runCommand, + callPackage, buildPythonPackage, fetchFromGitHub, pytestCheckHook, pythonOlder, + replaceVars, setuptools, click-default-group, condense-json, @@ -13,18 +16,154 @@ pluggy, puremagic, pydantic, + python, python-ulid, pyyaml, sqlite-migrate, cogapp, pytest-asyncio, pytest-httpx, + pytest-recording, sqlite-utils, + syrupy, + llm-echo, }: let + /** + Make a derivation for `llm` that contains `llm` plus the relevant plugins. + The function signature of `withPlugins` is the list of all the plugins `llm` knows about. + Adding a parameter here requires that it be in `python3Packages` attrset. + + # Type + + ``` + withPlugins :: + { + llm-anthropic :: bool, + llm-gemini :: bool, + ... + } + -> derivation + ``` + + See `lib.attrNames (lib.functionArgs llm.withPlugins)` for the total list of plugins supported. + + # Examples + :::{.example} + ## `llm.withPlugins` usage example + + ```nix + llm.withPlugins { llm-gemini = true; llm-groq = true; } + => «derivation /nix/store/-python3-3.12.10-llm-with-llm-gemini-llm-groq.drv» + ``` + + ::: + */ + withPlugins = + # Keep this list up to date with the plugins in python3Packages! + { + llm-anthropic ? false, + llm-cmd ? false, + llm-command-r ? false, + llm-deepseek ? false, + llm-docs ? false, + llm-echo ? false, + llm-fragments-github ? false, + llm-fragments-pypi ? false, + llm-fragments-reader ? false, + llm-fragments-symbex ? false, + llm-gemini ? false, + llm-gguf ? false, + llm-git ? false, + llm-grok ? false, + llm-groq ? false, + llm-hacker-news ? false, + llm-jq ? false, + llm-llama-server ? false, + llm-mistral ? false, + llm-ollama ? false, + llm-openai-plugin ? false, + llm-openrouter ? false, + llm-pdf-to-images ? false, + llm-sentence-transformers ? false, + llm-templates-fabric ? false, + llm-templates-github ? false, + llm-tools-datasette ? false, + llm-tools-quickjs ? false, + llm-tools-simpleeval ? false, + llm-tools-sqlite ? false, + llm-venice ? false, + llm-video-frames ? false, + ... + }@args: + let + # Filter to just the attributes which are set to a true value. + setArgs = lib.filterAttrs (name: lib.id) args; + + # Make the derivation name reflect what's inside it, up to a certain limit. + setArgNames = lib.attrNames setArgs; + drvName = + let + len = builtins.length setArgNames; + in + if len == 0 then + "llm-${llm.version}" + else if len > 20 then + "llm-${llm.version}-with-${toString len}-plugins" + else + # Make a string with those names separated with a dash. + "llm-${llm.version}-with-${lib.concatStringsSep "-" setArgNames}"; + + # Make a python environment with just those plugins. + python-environment = python.withPackages ( + ps: + let + # Throw a diagnostic if this list gets out of sync with the names in python3Packages + allPluginsPresent = pluginNames == withPluginsArgNames; + pluginNames = lib.attrNames (lib.intersectAttrs ps withPluginsArgs); + missingNamesList = lib.attrNames (lib.removeAttrs withPluginsArgs pluginNames); + missingNames = lib.concatStringsSep ", " missingNamesList; + + # The relevant plugins are the ones the user asked for. + plugins = lib.intersectAttrs setArgs ps; + in + assert lib.assertMsg allPluginsPresent "Missing these plugins: ${missingNames}"; + ([ ps.llm ] ++ lib.attrValues plugins) + ); + + in + # That Python environment produced above contains too many irrelevant binaries, due to how + # Python needs to use propagatedBuildInputs. Let's make one with just what's needed: `llm`. + # Since we include the `passthru` and `meta` information, it's as good as the original + # derivation. + runCommand "${python.name}-${drvName}" { inherit (llm) passthru meta; } '' + mkdir -p $out/bin + ln -s ${python-environment}/bin/llm $out/bin/llm + ''; + + # Uses the `withPlugins` names to make a Python environment with everything. + withAllPlugins = withPlugins (lib.genAttrs withPluginsArgNames (name: true)); + + # The function signature of `withPlugins` is the list of all the plugins `llm` knows about. + # The plugin directory is at + withPluginsArgs = lib.functionArgs withPlugins; + withPluginsArgNames = lib.attrNames withPluginsArgs; + + # In order to help with usability, we patch `llm install` and `llm uninstall` to tell users how to + # customize `llm` with plugins in Nix, including the name of the plugin, its description, and + # where it's coming from. + listOfPackagedPlugins = builtins.toFile "plugins.txt" ( + lib.concatStringsSep "\n " ( + map (name: '' + # ${python.pkgs.${name}.meta.description} <${python.pkgs.${name}.meta.homepage}> + ${name} = true; + '') withPluginsArgNames + ) + ); + llm = buildPythonPackage rec { pname = "llm"; - version = "0.25"; + version = "0.26"; pyproject = true; build-system = [ setuptools ]; @@ -35,11 +174,16 @@ let owner = "simonw"; repo = "llm"; tag = version; - hash = "sha256-iH1P0VdpwIItY1In7vlM0Sn44Db23TqFp8GZ79/GMJs="; + hash = "sha256-KTlNajuZrR0kBX3LatepsNM3PfRVsQn+evEfXTu6juE="; }; patches = [ ./001-disable-install-uninstall-commands.patch ]; + postPatch = '' + substituteInPlace llm/cli.py \ + --replace-fail "@listOfPackagedPlugins@" "$(< ${listOfPackagedPlugins})" + ''; + dependencies = [ click-default-group condense-json @@ -61,11 +205,19 @@ let numpy pytest-asyncio pytest-httpx + pytest-recording + syrupy pytestCheckHook ]; doCheck = true; + # The tests make use of `llm_echo` but that would be a circular dependency. + # So we make a local copy in this derivation, as it's a super-simple package of one file. + preCheck = '' + cp ${llm-echo.src}/llm_echo.py llm_echo.py + ''; + pytestFlagsArray = [ "-svv" "tests/" @@ -74,27 +226,28 @@ let pythonImportsCheck = [ "llm" ]; passthru = { - inherit withPlugins; + inherit withPlugins withAllPlugins; + + mkPluginTest = plugin: { + ${plugin.pname} = callPackage ./mk-plugin-test.nix { inherit llm plugin; }; + }; + + # include tests for all the plugins + tests = lib.mergeAttrsList (map (name: python.pkgs.${name}.tests) withPluginsArgNames); }; - meta = with lib; { + meta = { homepage = "https://github.com/simonw/llm"; description = "Access large language models from the command-line"; changelog = "https://github.com/simonw/llm/releases/tag/${src.tag}"; - license = licenses.asl20; + license = lib.licenses.asl20; mainProgram = "llm"; - maintainers = with maintainers; [ + maintainers = with lib.maintainers; [ aldoborrero mccartykim + philiptaron ]; }; }; - - withPlugins = throw '' - llm.withPlugins was confusing to use and has been removed. - Please migrate to using python3.withPackages(ps: [ ps.llm ]) instead. - - See https://nixos.org/manual/nixpkgs/stable/#python.withpackages-function for more usage examples. - ''; in llm diff --git a/pkgs/development/python-modules/llm/mk-plugin-test.nix b/pkgs/development/python-modules/llm/mk-plugin-test.nix new file mode 100644 index 000000000000..01a53ab28348 --- /dev/null +++ b/pkgs/development/python-modules/llm/mk-plugin-test.nix @@ -0,0 +1,27 @@ +{ + cacert, + runCommand, + writableTmpDirAsHomeHook, + yq, + llm, + plugin, +}: +let + venv = llm.pythonModule.withPackages (_: [ + llm + plugin + ]); +in +runCommand "${plugin.pname}-test" + { + nativeBuildInputs = [ + venv + writableTmpDirAsHomeHook + yq + ]; + env.SSL_CERT_FILE = "${cacert}/etc/ssl/certs/ca-bundle.crt"; + } + '' + llm plugins | yq --exit-status 'any(.name == "${plugin.pname}")' + touch "$out" + '' diff --git a/pkgs/development/python-modules/pytest-icdiff/default.nix b/pkgs/development/python-modules/pytest-icdiff/default.nix new file mode 100644 index 000000000000..6b0ba2adfd42 --- /dev/null +++ b/pkgs/development/python-modules/pytest-icdiff/default.nix @@ -0,0 +1,52 @@ +{ + lib, + buildPythonPackage, + fetchFromGitHub, + setuptools, + icdiff, + pprintpp, + pytest, + pytestCheckHook, + writableTmpDirAsHomeHook, +}: + +buildPythonPackage rec { + pname = "pytest-icdiff"; + version = "0.5-unstable-2024-09-04"; + pyproject = true; + + src = fetchFromGitHub { + owner = "hjwp"; + repo = "pytest-icdiff"; + rev = "6e2fb8de35e37428a9f7a268c8abb57e9ee285e5"; + hash = "sha256-kSeGz5IExldgi955XOEkQnc8uqxkbyvuDOdz9y3AFIY="; + }; + + build-system = [ setuptools ]; + + dependencies = [ + pytest + icdiff + pprintpp + ]; + + # These are failing on the main branch; disable for now + disabledTests = [ + "test_long_dict" + "test_mutliline_strings_have_no_escaped_newlines" + ]; + + nativeCheckInputs = [ + pytestCheckHook + writableTmpDirAsHomeHook + ]; + + pythonImportsCheck = [ "pytest_icdiff" ]; + + meta = { + description = "Better error messages in pytest assertions using icdiff"; + homepage = "https://github.com/hjwp/pytest-icdiff"; + license = lib.licenses.unlicense; + maintainers = with lib.maintainers; [ philiptaron ]; + }; +} diff --git a/pkgs/development/python-modules/quickjs/0001-Update-for-QuickJS-2025-04-26-release.patch b/pkgs/development/python-modules/quickjs/0001-Update-for-QuickJS-2025-04-26-release.patch new file mode 100644 index 000000000000..05501f6a220c --- /dev/null +++ b/pkgs/development/python-modules/quickjs/0001-Update-for-QuickJS-2025-04-26-release.patch @@ -0,0 +1,66 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Philip Taron +Date: Thu, 29 May 2025 17:16:43 -0700 +Subject: [PATCH] Update for QuickJS 2025-04-26 release + +Signed-off-by: Philip Taron +--- + setup.py | 6 +++--- + test_quickjs.py | 6 +++--- + 2 files changed, 6 insertions(+), 6 deletions(-) + +diff --git a/setup.py b/setup.py +index 9d17af357dcadc40478789ef9c82ac82632967d3..d0b4ff2bd7f3450f6f055ee9e2eda6b591d70689 100644 +--- a/setup.py ++++ b/setup.py +@@ -16,7 +16,7 @@ if sys.platform == "win32": + # system PATH when compiling. + # 3. The code below will moneky-patch distutils to work. + import distutils.cygwinccompiler +- distutils.cygwinccompiler.get_msvcr = lambda: [] ++ distutils.cygwinccompiler.get_msvcr = lambda: [] + # Make sure that pthreads is linked statically, otherwise we run into problems + # on computers where it is not installed. + extra_link_args = ["-static"] +@@ -26,7 +26,7 @@ def get_c_sources(include_headers=False): + sources = [ + "module.c", + "upstream-quickjs/cutils.c", +- "upstream-quickjs/libbf.c", ++ "upstream-quickjs/dtoa.c", + "upstream-quickjs/libregexp.c", + "upstream-quickjs/libunicode.c", + "upstream-quickjs/quickjs.c", +@@ -34,7 +34,7 @@ def get_c_sources(include_headers=False): + if include_headers: + sources += [ + "upstream-quickjs/cutils.h", +- "upstream-quickjs/libbf.h", ++ "upstream-quickjs/dtoa.h", + "upstream-quickjs/libregexp-opcode.h", + "upstream-quickjs/libregexp.h", + "upstream-quickjs/libunicode-table.h", +diff --git a/test_quickjs.py b/test_quickjs.py +index 1f6dec7ccd15092e98e80a9139ae2acff359b010..9444234655fba9d932ce92c82b9d8da8fe83ad5b 100644 +--- a/test_quickjs.py ++++ b/test_quickjs.py +@@ -105,8 +105,8 @@ class Context(unittest.TestCase): + else: + self.fail("Expected exception.") + +- self.assertIn("at funcA (:3)\n", msg) +- self.assertIn("at funcB (:6)\n", msg) ++ self.assertIn("at funcA (:3:24)\n", msg) ++ self.assertIn("at funcB (:6:26)\n", msg) + + def test_memory_limit(self): + code = """ +@@ -508,7 +508,7 @@ class FunctionTest(unittest.TestCase): + """) + + self.assertEqual(f(100), 100) +- limit = 500 ++ limit = 1500 + with self.assertRaises(quickjs.StackOverflow): + f(limit) + f.set_max_stack_size(2000 * limit) diff --git a/pkgs/development/python-modules/quickjs/default.nix b/pkgs/development/python-modules/quickjs/default.nix new file mode 100644 index 000000000000..1d5726bee259 --- /dev/null +++ b/pkgs/development/python-modules/quickjs/default.nix @@ -0,0 +1,58 @@ +{ + lib, + buildPythonPackage, + fetchFromGitHub, + setuptools, + poetry-core, + pytestCheckHook, + pkgs, +}: + +let + inherit (pkgs) quickjs srcOnly; +in + +buildPythonPackage rec { + pname = "quickjs"; + version = "1.19.4"; + pyproject = true; + + src = fetchFromGitHub { + owner = "PetterS"; + repo = "quickjs"; + tag = version; + hash = "sha256-nLloXJWOuaK/enZfwXJI94IcsAMYrkBtG4i3gmxuhfw="; + }; + + patches = [ ./0001-Update-for-QuickJS-2025-04-26-release.patch ]; + + # Upstream uses Git submodules; let's de-vendor and use Nix, so that we gain security fixes like + # https://github.com/NixOS/nixpkgs/pull/407469 + prePatch = '' + rmdir upstream-quickjs + ln -s ${srcOnly quickjs} upstream-quickjs + ''; + + postPatch = '' + substituteInPlace pyproject.toml \ + --replace-fail poetry>=1.5.0 poetry \ + --replace-fail poetry poetry-core \ + --replace-fail 'version = "0"' 'version = "${version}"' + ''; + + build-system = [ + poetry-core + setuptools + ]; + + nativeCheckInputs = [ pytestCheckHook ]; + + pythonImportsCheck = [ "quickjs" ]; + + meta = { + description = "Python wrapper around the quickjs C library"; + homepage = "https://github.com/PetterS/quickjs"; + license = lib.licenses.mit; + maintainers = with lib.maintainers; [ philiptaron ]; + }; +} diff --git a/pkgs/development/python-modules/symbex/default.nix b/pkgs/development/python-modules/symbex/default.nix new file mode 100644 index 000000000000..47405f4b8223 --- /dev/null +++ b/pkgs/development/python-modules/symbex/default.nix @@ -0,0 +1,45 @@ +{ + lib, + buildPythonPackage, + fetchFromGitHub, + setuptools, + click, + pytestCheckHook, + pyyaml, + pytest-icdiff, + writableTmpDirAsHomeHook, +}: + +buildPythonPackage rec { + pname = "symbex"; + version = "2.0"; + pyproject = true; + + src = fetchFromGitHub { + owner = "simonw"; + repo = "symbex"; + tag = version; + hash = "sha256-swg98z4DpQJ5rq7tdsd3FofbYF7O5S+9ZR0weoM2DoI="; + }; + + build-system = [ setuptools ]; + + dependencies = [ click ]; + + pythonImportsCheck = [ "symbex" ]; + + nativeCheckInputs = [ + pytestCheckHook + pyyaml + pytest-icdiff + writableTmpDirAsHomeHook + ]; + + meta = { + description = "Find the Python code for specified symbols"; + homepage = "https://github.com/simonw/symbex"; + changelog = "https://github.com/simonw/symbex/releases/tag/${version}/CHANGELOG.md"; + license = lib.licenses.asl20; + maintainers = with lib.maintainers; [ philiptaron ]; + }; +} diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index e5d3682cdcca..a77f483bac66 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -3502,8 +3502,6 @@ with pkgs; ocamlPackages = ocaml-ng.ocamlPackages_4_14; }; - llm = with python3Packages; toPythonApplication llm; - loganalyzer = libsForQt5.callPackage ../development/tools/loganalyzer { }; logstash7 = callPackage ../tools/misc/logstash/7.x.nix { diff --git a/pkgs/top-level/python-packages.nix b/pkgs/top-level/python-packages.nix index 3aad48eeb4c9..79acec4ff1e0 100644 --- a/pkgs/top-level/python-packages.nix +++ b/pkgs/top-level/python-packages.nix @@ -4971,6 +4971,8 @@ self: super: with self; { filelock = callPackage ../development/python-modules/filelock { }; + files-to-prompt = callPackage ../development/python-modules/files-to-prompt { }; + filetype = callPackage ../development/python-modules/filetype { }; filterpy = callPackage ../development/python-modules/filterpy { }; @@ -6654,6 +6656,8 @@ self: super: with self; { icalevents = callPackage ../development/python-modules/icalevents { }; + icdiff = callPackage ../development/python-modules/icdiff { }; + icecream = callPackage ../development/python-modules/icecream { }; iceportal = callPackage ../development/python-modules/iceportal { }; @@ -8306,16 +8310,66 @@ self: super: with self; { llm-cmd = callPackage ../development/python-modules/llm-cmd { }; + llm-command-r = callPackage ../development/python-modules/llm-command-r { }; + + llm-deepseek = callPackage ../development/python-modules/llm-deepseek { }; + + llm-docs = callPackage ../development/python-modules/llm-docs { }; + + llm-echo = callPackage ../development/python-modules/llm-echo { }; + + llm-fragments-github = callPackage ../development/python-modules/llm-fragments-github { }; + + llm-fragments-pypi = callPackage ../development/python-modules/llm-fragments-pypi { }; + + llm-fragments-reader = callPackage ../development/python-modules/llm-fragments-reader { }; + + llm-fragments-symbex = callPackage ../development/python-modules/llm-fragments-symbex { }; + llm-gemini = callPackage ../development/python-modules/llm-gemini { }; llm-gguf = callPackage ../development/python-modules/llm-gguf { }; + llm-git = callPackage ../development/python-modules/llm-git { }; + + llm-grok = callPackage ../development/python-modules/llm-grok { }; + + llm-groq = callPackage ../development/python-modules/llm-groq { }; + + llm-hacker-news = callPackage ../development/python-modules/llm-hacker-news { }; + llm-jq = callPackage ../development/python-modules/llm-jq { }; + llm-llama-server = callPackage ../development/python-modules/llm-llama-server { }; + + llm-mistral = callPackage ../development/python-modules/llm-mistral { }; + llm-ollama = callPackage ../development/python-modules/llm-ollama { }; llm-openai-plugin = callPackage ../development/python-modules/llm-openai-plugin { }; + llm-openrouter = callPackage ../development/python-modules/llm-openrouter { }; + + llm-pdf-to-images = callPackage ../development/python-modules/llm-pdf-to-images { }; + + llm-sentence-transformers = callPackage ../development/python-modules/llm-sentence-transformers { }; + + llm-templates-fabric = callPackage ../development/python-modules/llm-templates-fabric { }; + + llm-templates-github = callPackage ../development/python-modules/llm-templates-github { }; + + llm-tools-datasette = callPackage ../development/python-modules/llm-tools-datasette { }; + + llm-tools-quickjs = callPackage ../development/python-modules/llm-tools-quickjs { }; + + llm-tools-simpleeval = callPackage ../development/python-modules/llm-tools-simpleeval { }; + + llm-tools-sqlite = callPackage ../development/python-modules/llm-tools-sqlite { }; + + llm-venice = callPackage ../development/python-modules/llm-venice { }; + + llm-video-frames = callPackage ../development/python-modules/llm-video-frames { }; + llmx = callPackage ../development/python-modules/llmx { }; llvmlite = callPackage ../development/python-modules/llvmlite { @@ -13827,6 +13881,8 @@ self: super: with self; { pytest-httpx = callPackage ../development/python-modules/pytest-httpx { }; + pytest-icdiff = callPackage ../development/python-modules/pytest-icdiff { }; + pytest-image-diff = callPackage ../development/python-modules/pytest-image-diff { }; pytest-instafail = callPackage ../development/python-modules/pytest-instafail { }; @@ -14876,6 +14932,8 @@ self: super: with self; { queuelib = callPackage ../development/python-modules/queuelib { }; + quickjs = callPackage ../development/python-modules/quickjs { }; + quil = callPackage ../development/python-modules/quil { }; quixote = callPackage ../development/python-modules/quixote { }; @@ -17033,6 +17091,8 @@ self: super: with self; { sybil = callPackage ../development/python-modules/sybil { }; + symbex = callPackage ../development/python-modules/symbex { }; + symbolic = callPackage ../development/python-modules/symbolic { }; symengine = callPackage ../development/python-modules/symengine { inherit (pkgs) symengine; };