llm: customize the message on `llm install` and `llm uninstall` with the list of plugins possible

This way, users know what they can specify as far as plugins go. It serves as a plugin directory.

Changed files
+59 -16
pkgs
+30 -8
pkgs/development/python-modules/llm/001-disable-install-uninstall-commands.patch
···
-
diff --git a/llm/cli.py b/llm/cli.py
-
index af37feb..18b078a 100644
-
--- a/llm/cli.py
-
+++ b/llm/cli.py
-
@@ -1014,18 +1014,7 @@ def templates_path():
+
diff --git i/llm/cli.py w/llm/cli.py
+
index 09e4e2d..8424a5e 100644
+
--- i/llm/cli.py
+
+++ w/llm/cli.py
+
@@ -2383,18 +2383,18 @@ def display_truncated(text):
)
def install(packages, upgrade, editable, force_reinstall, no_cache_dir):
"""Install packages from PyPI into the same environment as LLM"""
···
- 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.")
+
+ click.echo(
+
+"""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):
+
@@ -2402,8 +2402,18 @@ def install(packages, upgrade, editable, force_reinstall, no_cache_dir):
@click.option("-y", "--yes", is_flag=True, help="Don't ask for confirmation")
def uninstall(packages, yes):
"""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.")
+
+ click.echo(
+
+"""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()
+29 -8
pkgs/development/python-modules/llm/default.nix
···
fetchFromGitHub,
pytestCheckHook,
pythonOlder,
+
replaceVars,
setuptools,
click-default-group,
condense-json,
···
sqlite-utils,
}:
let
-
# The function signature of `withPlugins` is the list of all the plugins `llm` knows about.
-
# The plugin directory is at <https://llm.datasette.io/en/stable/plugins/directory.html>
-
withPluginsArgNames = lib.functionArgs withPlugins;
-
/**
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
···
llm-templates-github ? false,
llm-venice ? false,
llm-video-frames ? false,
+
...
}@args:
let
# Filter to just the attributes which are set to a true value.
···
ps:
let
# Throw a diagnostic if this list gets out of sync with the names in python3Packages
-
allPluginsPresent = pluginNames == (lib.attrNames withPluginsArgNames);
-
pluginNames = lib.attrNames (lib.intersectAttrs ps withPluginsArgNames);
-
missingNamesList = lib.attrNames (lib.removeAttrs withPluginsArgNames pluginNames);
+
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.
···
'';
# Uses the `withPlugins` names to make a Python environment with everything.
-
withAllPlugins = withPlugins (lib.genAttrs (lib.attrNames withPluginsArgNames) (name: true));
+
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 <https://llm.datasette.io/en/stable/plugins/directory.html>
+
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";
···
};
patches = [ ./001-disable-install-uninstall-commands.patch ];
+
+
postPatch = ''
+
substituteInPlace llm/cli.py --replace-fail "@listOfPackagedPlugins@" "$(< ${listOfPackagedPlugins})"
+
'';
dependencies = [
click-default-group