From b0d3330c67b6874a1eaf23978749b26d99fbdfab Mon Sep 17 00:00:00 2001 From: Ben Sima Date: Tue, 6 May 2025 18:01:11 -0400 Subject: Switch Python to unstable and add pydantic-ai Pydantic-ai is an agent framework that seems simple and good: well-typed with pydantic, tool usage is just an `@tool` decorator on a function, and so on. While building these I realized there were some deps they needed that were already in nixpkgs unstable, so I just switched to that instead of trying to backport all the versions and stuff. --- Omni/Bild.nix | 7 ++- Omni/Bild/Deps/Python.nix | 4 ++ Omni/Bild/Deps/logfire-api.nix | 24 +++++++++ Omni/Bild/Deps/openai-python.nix | 99 ------------------------------------- Omni/Bild/Deps/pydantic-ai-slim.nix | 90 +++++++++++++++++++++++++++++++++ Omni/Bild/Deps/pydantic-ai.nix | 75 ++++++++++++++++++++++++++++ Omni/Bild/Deps/pydantic-graph.nix | 45 +++++++++++++++++ Omni/Bild/Python.nix | 6 ++- Omni/Bild/Sources.json | 41 ++++++++++----- 9 files changed, 274 insertions(+), 117 deletions(-) create mode 100644 Omni/Bild/Deps/logfire-api.nix delete mode 100644 Omni/Bild/Deps/openai-python.nix create mode 100644 Omni/Bild/Deps/pydantic-ai-slim.nix create mode 100644 Omni/Bild/Deps/pydantic-ai.nix create mode 100644 Omni/Bild/Deps/pydantic-graph.nix (limited to 'Omni') diff --git a/Omni/Bild.nix b/Omni/Bild.nix index c6c0fe7..bdaefd6 100644 --- a/Omni/Bild.nix +++ b/Omni/Bild.nix @@ -13,7 +13,6 @@ ccacheStdenv haskell sbcl - python312 nixos mkShell dockerTools @@ -97,9 +96,9 @@ python = { packages = self.lib.attrsets.getAttrs (import ./Bild/Deps/Python.nix) - stable.python312.pkgs; - pythonWith = stable.python312.withPackages; - buildPythonApplication = stable.python312.pkgs.buildPythonApplication; + unstable.python312.pkgs; + pythonWith = unstable.python312.withPackages; + buildPythonApplication = unstable.python312.pkgs.buildPythonApplication; }; # c packages are just stable, filtered to just the list of deps i want diff --git a/Omni/Bild/Deps/Python.nix b/Omni/Bild/Deps/Python.nix index 3a0562d..e7c796d 100644 --- a/Omni/Bild/Deps/Python.nix +++ b/Omni/Bild/Deps/Python.nix @@ -8,6 +8,10 @@ "nltk" "ollama" "openai" + "pydantic" + "pydantic-ai" + "pydantic-ai-slim" + "pydantic-graph" "requests" "slixmpp" "sqids" diff --git a/Omni/Bild/Deps/logfire-api.nix b/Omni/Bild/Deps/logfire-api.nix new file mode 100644 index 0000000..af6eedf --- /dev/null +++ b/Omni/Bild/Deps/logfire-api.nix @@ -0,0 +1,24 @@ +{ + lib, + buildPythonPackage, + sources, + hatchling, + pythonOlder, +}: +buildPythonPackage rec { + pname = "logfire-api"; + version = sources.logfire.rev; + pyproject = true; + disabled = pythonOlder "3.8"; + src = sources.logfire; + sourceRoot = "logfire-src/logfire-api"; + build-system = [hatchling]; + pythonImportsCheck = ["logfire_api"]; + meta = { + description = "Shim for the Logfire SDK which does nothing unless Logfire is installed"; + homepage = "https://pypi.org/project/logfire-api/"; + changelog = "https://github.com/pydantic/logfire/releases/tag/v${version}"; + license = lib.licenses.mit; + maintainers = with lib.maintainers; [bsima]; + }; +} diff --git a/Omni/Bild/Deps/openai-python.nix b/Omni/Bild/Deps/openai-python.nix deleted file mode 100644 index 79db11c..0000000 --- a/Omni/Bild/Deps/openai-python.nix +++ /dev/null @@ -1,99 +0,0 @@ -{ - lib, - buildPythonPackage, - pythonOlder, - # build-system - hatchling, - hatch-fancy-pypi-readme, - # dependencies - anyio, - distro, - httpx, - jiter, - pydantic, - sniffio, - tqdm, - typing-extensions, - numpy, - pandas, - pandas-stubs, - # check deps - pytestCheckHook, - dirty-equals, - inline-snapshot, - nest-asyncio, - pytest-asyncio, - pytest-mock, - respx, - sources, -}: -buildPythonPackage rec { - pname = "openai"; - version = sources.openai-python.version; - pyproject = true; - - disabled = pythonOlder "3.8"; - - src = sources.openai-python; - - build-system = [ - hatchling - hatch-fancy-pypi-readme - ]; - - dependencies = [ - anyio - distro - httpx - jiter - pydantic - sniffio - tqdm - typing-extensions - ]; - - optional-dependencies = { - datalib = [ - numpy - pandas - pandas-stubs - ]; - }; - - pythonImportsCheck = ["openai"]; - - nativeCheckInputs = [ - pytestCheckHook - dirty-equals - inline-snapshot - nest-asyncio - pytest-asyncio - pytest-mock - respx - ]; - - pytestFlagsArray = [ - "-W" - "ignore::DeprecationWarning" - ]; - - disabledTests = [ - # Tests make network requests - "test_copy_build_request" - "test_basic_attribute_access_works" - ]; - - disabledTestPaths = [ - # Test makes network requests - "tests/api_resources" - ]; - - meta = with lib; { - description = "Python client library for the OpenAI API"; - homepage = "https://github.com/openai/openai-python"; - changelog = "https://github.com/openai/openai-python/releases/tag/v${version}"; - license = licenses.mit; - maintainers = with maintainers; [malo]; - mainProgram = "openai"; - }; -} diff --git a/Omni/Bild/Deps/pydantic-ai-slim.nix b/Omni/Bild/Deps/pydantic-ai-slim.nix new file mode 100644 index 0000000..067508b --- /dev/null +++ b/Omni/Bild/Deps/pydantic-ai-slim.nix @@ -0,0 +1,90 @@ +{ + lib, + buildPythonPackage, + hatchling, + pydantic, + logfire-api, + httpx, + eval-type-backport, + griffe, + pydantic-graph, + pythonOlder, + sources, + writeTextFile, +}: let + version = sources.pydantic-ai.version; + pyproject_toml = writeTextFile { + name = "pyproject.toml"; + text = '' + [build-system] + requires = ["hatchling"] + build-backend = "hatchling.build" + + [project] + name = "pydantic-ai-slim" + version = "${version}" + description = "Agent Framework / shim to use Pydantic with LLMs, slim package" + authors = [{ name = "Samuel Colvin", email = "samuel@pydantic.dev" }] + license = "MIT" + readme = "README.md" + requires-python = ">=3.9" + dependencies = [ + "eval-type-backport>=0.2.0", + "griffe>=1.3.2", + "httpx>=0.27", + "pydantic>=2.10", + "pydantic-graph==0.1.9", + "exceptiongroup; python_version < '3.11'", + "opentelemetry-api>=1.28.0", + "typing-inspection>=0.4.0", + ] + + [tool.hatch.metadata] + allow-direct-references = true + + [project.scripts] + pai = "pydantic_ai._cli:app" + + [tool.hatch.build.targets.wheel] + packages = ["pydantic_ai"] + ''; + }; +in + buildPythonPackage rec { + pname = "pydantic-ai-slim"; + inherit version; + pyproject = true; + disabled = pythonOlder "3.8"; + src = sources.pydantic-ai; + build-system = [hatchling]; + sourceRoot = "pydantic-ai-src/pydantic_ai_slim"; + dependencies = [ + pydantic + logfire-api + httpx + eval-type-backport + griffe + pydantic-graph + ]; + nativeCheckInputs = [ + pydantic + logfire-api + httpx + eval-type-backport + griffe + pydantic-graph + ]; + preBuild = '' + cp ${pyproject_toml} ./pyproject.toml + ''; + pythonImportsCheck = [ + "pydantic-ai-slim[openai,vertexai,groq,anthropic,mistral,cohere]" + ]; + meta = { + description = "Graph and finite state machine library"; + homepage = "https://github.com/pydantic/pydantic-ai"; + changelog = "https://github.com/pydantic/pydantic-ai/releases/tag/v${version}"; + license = lib.licenses.mit; + maintainers = with lib.maintainers; [bsima]; + }; + } diff --git a/Omni/Bild/Deps/pydantic-ai.nix b/Omni/Bild/Deps/pydantic-ai.nix new file mode 100644 index 0000000..399649d --- /dev/null +++ b/Omni/Bild/Deps/pydantic-ai.nix @@ -0,0 +1,75 @@ +{ + lib, + buildPythonPackage, + hatchling, + pydantic-ai-slim, + pythonOlder, + pytest-vcr, + dirty-equals, + sources, + writeTextFile, +}: let + version = sources.pydantic-ai.version; + pyproject_toml = writeTextFile { + name = "pyproject.toml"; + text = '' + [build-system] + requires = ["hatchling"] + build-backend = "hatchling.build" + + [project] + name = "pydantic-ai" + version = "${version}" + description = "Agent Framework / shim to use Pydantic with LLMs" + authors = [ + { name = "Samuel Colvin", email = "samuel@pydantic.dev" }, + { name = "Marcelo Trylesinski", email = "marcelotryle@gmail.com" }, + { name = "David Montague", email = "david@pydantic.dev" }, + { name = "Alex Hall", email = "alex@pydantic.dev" }, + ] + license = "MIT" + readme = "README.md" + requires-python = ">=3.9" + dependencies = [ + "pydantic-ai-slim[openai,vertexai,groq,anthropic,mistral,cohere,bedrock,cli,mcp,evals]==${version}", + ] + + [project.urls] + Homepage = "https://ai.pydantic.dev" + Source = "https://github.com/pydantic/pydantic-ai" + Documentation = "https://ai.pydantic.dev" + Changelog = "https://github.com/pydantic/pydantic-ai/releases" + + [project.scripts] + pai = "pydantic_ai._cli:app" + ''; + }; +in + buildPythonPackage rec { + pname = "pydantic-ai"; + inherit version; + pyproject = true; + disabled = pythonOlder "3.8"; + src = sources.pydantic-ai; + build-system = [hatchling]; + dependencies = [pydantic-ai-slim]; + nativeCheckInputs = [ + pydantic-ai-slim + pytest-vcr + dirty-equals + # pytestCheckHook + ]; + preBuild = '' + cp ${pyproject_toml} ./pyproject.toml + ''; + pythonImportsCheck = [ + "pydantic_ai" + ]; + meta = { + description = "Agent Framework / shim to use Pydantic with LLMs"; + homepage = "https://github.com/pydantic/pydantic-ai"; + changelog = "https://github.com/pydantic/pydantic-ai/releases/tag/v${version}"; + license = lib.licenses.mit; + maintainers = with lib.maintainers; [bsima]; + }; + } diff --git a/Omni/Bild/Deps/pydantic-graph.nix b/Omni/Bild/Deps/pydantic-graph.nix new file mode 100644 index 0000000..e2797b9 --- /dev/null +++ b/Omni/Bild/Deps/pydantic-graph.nix @@ -0,0 +1,45 @@ +{ + lib, + buildPythonPackage, + hatchling, + pydantic, + logfire-api, + httpx, + opentelemetry-api, + pythonOlder, + sources, +}: +buildPythonPackage rec { + pname = "pydantic-graph"; + version = sources.pydantic-ai.version; + pyproject = true; + disabled = pythonOlder "3.8"; + src = sources.pydantic-ai; + sourceRoot = "pydantic-ai-src/pydantic_graph"; + build-system = [hatchling]; + dependencies = [ + pydantic + logfire-api + httpx + opentelemetry-api + ]; + nativeCheckInputs = [ + pydantic + logfire-api + httpx + ]; + pythonRelaxDeps = true; + postPatch = '' + substituteInPlace pyproject.toml \ + --replace-fail ', "uv-dynamic-versioning>=0.7.0"' "" \ + --replace-fail 'dynamic = ["version"]' 'version = "${version}"' + ''; + pythonImportsCheck = ["pydantic_graph"]; + meta = { + description = "PydanticAI core logic with minimal required dependencies."; + homepage = "https://github.com/pydantic/pydantic-ai"; + changelog = "https://github.com/pydantic/pydantic-ai/releases/tag/v${version}"; + license = lib.licenses.mit; + maintainers = with lib.maintainers; [bsima]; + }; +} diff --git a/Omni/Bild/Python.nix b/Omni/Bild/Python.nix index 36abe25..7ae9aa9 100644 --- a/Omni/Bild/Python.nix +++ b/Omni/Bild/Python.nix @@ -4,6 +4,7 @@ _self: super: { with pysuper.pkgs.python312Packages; let dontCheck = p: p.overridePythonAttrs (_: {doCheck = false;}); in { + anyio = dontCheck pysuper.anyio; interegular = callPackage ./Deps/interegular.nix {}; ipython = dontCheck pysuper.ipython; llm = super.overrideSrc pysuper.llm super.sources.llm; @@ -11,6 +12,7 @@ _self: super: { ollama = pyself.ollama; }; llm-sentence-transformers = callPackage ./Deps/llm-sentence-transformers.nix {}; + logfire-api = callPackage ./Deps/logfire-api.nix {}; ludic = callPackage ./Deps/ludic.nix {}; mypy = dontCheck pysuper.mypy; ollama = pysuper.ollama.overridePythonAttrs (old: rec { @@ -22,8 +24,10 @@ _self: super: { --replace-fail "0.0.0" "${version}" ''; }); - openai = callPackage ./Deps/openai-python.nix {}; outlines = callPackage ./Deps/outlines.nix {}; + pydantic-ai = callPackage ./Deps/pydantic-ai.nix {}; + pydantic-ai-slim = callPackage ./Deps/pydantic-ai-slim.nix {}; + pydantic-graph = callPackage ./Deps/pydantic-graph.nix {}; perscache = callPackage ./Deps/perscache.nix {}; tokenizers = dontCheck pysuper.tokenizers; }; diff --git a/Omni/Bild/Sources.json b/Omni/Bild/Sources.json index cf5f856..93abac1 100644 --- a/Omni/Bild/Sources.json +++ b/Omni/Bild/Sources.json @@ -86,6 +86,18 @@ "url_template": "https://github.com///archive/.tar.gz", "version": "0.21" }, + "logfire": { + "branch": "main", + "description": "Uncomplicated Observability for Python and beyond! 🪵🔥", + "homepage": "https://logfire.pydantic.dev/docs/", + "owner": "pydantic", + "repo": "logfire", + "rev": "0ef05d9414232c82fb03d34860fb1a2ec9a50488", + "sha256": "16ffikhdh810lhj7rx9gy0sy9x4kk2621l02j5ydkar0vkcpy6vd", + "type": "tarball", + "url": "https://github.com/pydantic/logfire/archive/0ef05d9414232c82fb03d34860fb1a2ec9a50488.tar.gz", + "url_template": "https://github.com///archive/.tar.gz" + }, "niv": { "branch": "master", "description": "Easy dependency management for Nix projects", @@ -162,10 +174,10 @@ "homepage": "", "owner": "nixos", "repo": "nixpkgs", - "rev": "1750f3c1c89488e2ffdd47cab9d05454dddfb734", - "sha256": "1nrwlaxd0f875r2g6v9brrwmxanra8pga5ppvawv40hcalmlccm0", + "rev": "0a072c9decccf3a97974db48cda1457bfaf5d5c5", + "sha256": "0wvwkadd6d7vznb0lwclzxqz9cpr7zb0b27xbdxc6kgmgi4sfbw2", "type": "tarball", - "url": "https://github.com/nixos/nixpkgs/archive/1750f3c1c89488e2ffdd47cab9d05454dddfb734.tar.gz", + "url": "https://github.com/nixos/nixpkgs/archive/0a072c9decccf3a97974db48cda1457bfaf5d5c5.tar.gz", "url_template": "https://github.com///archive/.tar.gz" }, "nvidia-patch-nixos": { @@ -193,16 +205,6 @@ "url_template": "https://github.com///archive/refs/tags/v.tar.gz", "version": "0.4.5" }, - "openai-python": { - "branch": "main", - "description": "The official Python library for the OpenAI API", - "homepage": "https://pypi.org/project/openai/", - "owner": "openai", - "repo": "https://github.com/openai/openai-python", - "rev": "5e3e4d1b0f16ccc4469a90a5bff09cafe0de7a2e", - "type": "git", - "version": "1.56.1" - }, "outlines": { "branch": "main", "description": "Generative Model Programming", @@ -227,6 +229,19 @@ "url": "https://github.com/leshchenko1979/perscache/archive/0.6.1.tar.gz", "url_template": "https://github.com///archive/.tar.gz" }, + "pydantic-ai": { + "branch": "main", + "description": "Agent Framework / shim to use Pydantic with LLMs", + "homepage": "https://ai.pydantic.dev", + "owner": "pydantic", + "repo": "pydantic-ai", + "rev": "1e561011e4d9e654b1eaecb6b96890bcc047982d", + "sha256": "02kx6j9nck4b8qxz86lzs5jvq01rh4641wdal2nwznwxwlinnyp5", + "type": "tarball", + "url": "https://github.com/pydantic/pydantic-ai/archive/1e561011e4d9e654b1eaecb6b96890bcc047982d.tar.gz", + "url_template": "https://github.com///archive/.tar.gz", + "version": "0.1.9" + }, "radicale": { "branch": "master", "description": "A simple CalDAV (calendar) and CardDAV (contact) server.", -- cgit v1.2.3