Best practices: Python based pkgs and is this the best way to bring in dependent python packages for pkgs.llm?

Hi there, verrrry new nix user here.

Been slogging through nix-darwin setup the last few days. Emphasis on slog. But still excited.

I use a neat tool called llm to access llms via cli.

Happily I discovered that there was already a nixpkg created for it. Technically several. Which leads me to my first question. What is best practice for bringing in a nixpkg built from python? I see that there is a plain llm and python311Packages.llm. From what I can tell they point to the same derivation, so what is the difference?

Moving on…

llm supports plugins for using various providers. I wanted to get it setup for using claude. Luckily the derivation author included a way to bring in plugins, woo!

BUT, there are no nixpkgs for the claude plugins (or anything others from what I can see). So I used this really great post to create the packages I needed with nix-init.

I eventually got it working, here is my cfg, key part:

  llm-claude = pkgs.python311Packages.callPackage ../packages/llm-claude/default.nix {
    inherit (pkgs.python311Packages) anthropic;
  };
  llm-claude-3 = pkgs.python311Packages.callPackage ../packages/llm-claude-3/default.nix {
    inherit (pkgs.python311Packages) anthropic;
    inherit llm-claude;

  };
  llmWithPlugins = pkgs.python311Packages.llm.withPlugins [ llm-claude-3 ];

but I am not particularly fond of how I had to do a two step process of creating two pkgs (llm-claude and llm-claude-3). I feel that I’m handling the dependencies in the wrong place - creating llm-claude just to hand it off to llm-claude-3. I think it should be possible to do it “lower level”. Such as in the llm-claude-3

Here is the definition of llm-claude-3. My main question: Is there a better way to do this??

Lastly, once I’ve got this cleaned up, I’d like to publish the nix derivation. Would that make sense?

Thanks for any assistance!

1 Like

It’s possible. gist. Something like:

let 
  packageOverrides = self: super: {
    foo = self.callPackage ./foo.nix {};
    bar = self.callPackage ./bar.nix {};
  };
  pythonWithMyPackages = (pkgs.python3.override { inherit packageOverrides; }).withPackages (ps:
    [
      ps.foo
      ps.bar
    ]
  );
in
  pythonWithMyPackages
1 Like

I see, that makes sense thank you! After seeing your gist its super clear.

Though now that I’ve thought about it a little more, if I want to publish these they should be individual pkgs. In which case I think it is better to bring in the anthropic reference within the default.nix definition.

I’ve done that and its cleaned up the logic in my home.nix a little bit:

  llm-claude = pkgs.python311Packages.callPackage ../packages/llm-claude/default.nix { };
  llm-claude-3 = pkgs.python311Packages.callPackage ../packages/llm-claude-3/default.nix {
    inherit llm-claude;
  };
  llmWithPlugins = pkgs.python311Packages.llm.withPlugins [ llm-claude-3 ];

The last bit would be publish llm-claude so I don’t have to manually create it.