This repository has no description
4.9 kB
184 lines
1{
2 lib,
3 fetchPypi,
4 python313Packages,
5}:
6let
7 py = python313Packages;
8
9 # 0.18.1 added a runtime dependency on `websockets` (realtime transport) that
10 # nixpkgs' derivation does not declare yet, so its wheel fails the
11 # runtime-deps check. Add it until nixpkgs catches up.
12 openai-agents = py.openai-agents.overridePythonAttrs (o: {
13 dependencies = o.dependencies ++ [ py.websockets ];
14 });
15
16 # omnigent-client declares `omnigent` as a dependency, and omnigent declares
17 # omnigent-client: the two are released in lockstep from the same repo. Break
18 # the cycle by dropping the back-reference here; the final application below
19 # provides `omnigent` itself.
20 omnigent-client = py.buildPythonPackage rec {
21 pname = "omnigent_client";
22 version = "0.17.0";
23 format = "wheel";
24
25 src = fetchPypi {
26 inherit pname version format;
27 dist = "py3";
28 python = "py3";
29 hash = "sha256-840EK8+ZfBOPP0lp5h974rkKtIs4eLC8uLaK23y8FhY=";
30 };
31
32 pythonRemoveDeps = [ "omnigent" ];
33
34 dependencies = [
35 py.httpx
36 py.pydantic
37 ];
38
39 # No pythonImportsCheck: every module imports `omnigent`, which only exists
40 # in the application closure below.
41 doCheck = false;
42
43 meta = {
44 description = "Python client library for the Omnigent server API";
45 homepage = "https://omnigent.ai";
46 license = lib.licenses.asl20;
47 };
48 };
49
50 omnigent-ui-sdk = py.buildPythonPackage rec {
51 pname = "omnigent_ui_sdk";
52 version = "0.17.0";
53 format = "wheel";
54
55 src = fetchPypi {
56 inherit pname version format;
57 dist = "py3";
58 python = "py3";
59 hash = "sha256-2I9JWM64pqFNawr6exvQRJ1uOvZ+6J6NZ37JBy2OLFA=";
60 };
61
62 dependencies = [
63 omnigent-client
64 py.prompt-toolkit
65 py.pyyaml
66 py.rich
67 ];
68
69 doCheck = false;
70
71 meta = {
72 description = "Terminal UI SDK for Omnigent";
73 homepage = "https://omnigent.ai";
74 license = lib.licenses.asl20;
75 };
76 };
77in
78py.buildPythonApplication rec {
79 pname = "omnigent";
80 version = "0.17.0";
81 format = "wheel";
82
83 # The published wheel ships the prebuilt web SPA under
84 # omnigent/server/static/web-ui; the sdist does not.
85 src = fetchPypi {
86 inherit pname version format;
87 dist = "py3";
88 python = "py3";
89 hash = "sha256-/ygrFeQOlXXilVU5H1zqdYBqR3YVZUo/HlfIfsxR/IQ=";
90 };
91
92 # Upper bounds that nixpkgs has already moved past. All of these are
93 # conservative caps in omnigent's pyproject, not known incompatibilities.
94 pythonRelaxDeps = [
95 "argon2-cffi" # nixpkgs 25.1.0 vs <24
96 "cachetools" # nixpkgs 7.1.4 vs <7
97 "openai" # nixpkgs 2.53.0 vs <2.45
98 "packaging" # nixpkgs 26.2 vs <26
99 "protobuf" # nixpkgs 7.35.1 vs <7
100 "rich" # nixpkgs 15.0.0 vs <15
101 "websockets" # nixpkgs 16.1 vs <15
102 ];
103
104 dependencies = [
105 omnigent-client
106 omnigent-ui-sdk
107 ]
108 ++ (with py; [
109 alembic
110 anyio
111 argon2-cffi
112 cachetools
113 cel-python
114 certifi
115 claude-agent-sdk
116 click
117 fastapi
118 filelock
119 ftfy
120 httpx
121 json5
122 keyring
123 mcp
124 openai
125 openai-agents
126 opentelemetry-api
127 opentelemetry-exporter-otlp-proto-grpc
128 opentelemetry-exporter-otlp-proto-http
129 opentelemetry-instrumentation-fastapi
130 opentelemetry-instrumentation-httpx
131 opentelemetry-instrumentation-sqlalchemy
132 packaging
133 pexpect
134 pillow
135 prompt-toolkit
136 protobuf
137 psutil
138 pydantic
139 pyjwt
140 pyte
141 python-dateutil
142 pyyaml
143 rich
144 sqlalchemy
145 starlette
146 tiktoken
147 tomlkit
148 uvicorn
149 websockets
150 zstandard
151 ])
152 ++ py.pyjwt.optional-dependencies.crypto
153 ++ py.uvicorn.optional-dependencies.standard;
154
155 # The CLI respawns itself as `sys.executable -m omnigent.host._daemon_entry`
156 # (cli.py:2945) for the host daemon, and the daemon spawns runners the same
157 # way. That is the *bare* interpreter, without the site-dirs that
158 # wrapPythonPrograms bakes into the console script, so those children die
159 # with ModuleNotFoundError: No module named 'omnigent' and every session hangs
160 # on "the connect daemon did not come online within 30s". Hand them the
161 # transitive dependency closure through PYTHONPATH, which omnigent's own
162 # daemon/runner env allowlist preserves (host/connect.py) while the agent
163 # spawn allowlist drops it (inner/agent_env.py), so it never reaches omp.
164 postFixup = ''
165 buildPythonPath "$out $pythonPath"
166 wrapProgram $out/bin/omnigent --prefix PYTHONPATH : "$program_PYTHONPATH"
167 '';
168
169 pythonImportsCheck = [
170 "omnigent"
171 "omnigent_client"
172 "omnigent_ui_sdk"
173 ];
174
175 passthru.updateScript = ./update.sh;
176
177 meta = {
178 description = "Open-source meta-harness giving a common orchestration layer over AI coding agents";
179 homepage = "https://omnigent.ai";
180 license = lib.licenses.asl20;
181 mainProgram = "omnigent";
182 platforms = lib.platforms.unix;
183 };
184}