-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathflake.nix
More file actions
270 lines (231 loc) · 8.77 KB
/
flake.nix
File metadata and controls
270 lines (231 loc) · 8.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
{
description = "Elixir/Phoenix development shell and runnable app";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
flake-utils.url = "github:numtide/flake-utils";
};
outputs = { self, nixpkgs, flake-utils }:
flake-utils.lib.eachDefaultSystem (system:
let
pkgs = import nixpkgs { inherit system; };
elixirToolchain = with pkgs; [
beam.packages.erlang_27.elixir_1_18
rebar3
hex
nodejs_20
ffmpeg-headless
inotify-tools
watchman
git
];
llm-chat = pkgs.writeShellApplication {
name = "llm-chat";
runtimeInputs = elixirToolchain ++ [ pkgs.bash ];
text = ''
set -euo pipefail
repo_root="''${REPO_ROOT:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"
app_dir="$repo_root/llm_chat"
env_file="$app_dir/.env"
if [ ! -d "$app_dir" ] || [ ! -f "$repo_root/flake.nix" ]; then
echo "Run this command from the repository checkout or set REPO_ROOT." >&2
exit 1
fi
if [ -f "$env_file" ]; then
set -a
# shellcheck disable=SC1090
. "$env_file"
set +a
fi
export MIX_ENV="''${MIX_ENV:-dev}"
export PHX_HOST="''${PHX_HOST:-localhost}"
export PORT="''${PORT:-4000}"
export SECRET_KEY_BASE="''${SECRET_KEY_BASE:-dev_secret_key_base_change_me}"
cd "$app_dir"
mix deps.get
mix setup
exec mix phx.server "$@"
'';
};
clawrouter = pkgs.writeShellApplication {
name = "clawrouter-proxy";
runtimeInputs = [ pkgs.nodejs_20 pkgs.bash ];
text = ''
set -euo pipefail
export BLOCKRUN_PROXY_PORT="''${BLOCKRUN_PROXY_PORT:-8402}"
exec npx @blockrun/clawrouter --port "$BLOCKRUN_PROXY_PORT" "$@"
'';
};
whisper-server = pkgs.writeShellApplication {
name = "whisper-stt-server";
runtimeInputs = [ pkgs.whisper-cpp pkgs.ffmpeg-headless pkgs.bash ];
text = ''
set -euo pipefail
export WHISPER_HOST="''${WHISPER_HOST:-127.0.0.1}"
export WHISPER_PORT="''${WHISPER_PORT:-9000}"
export WHISPER_MODEL="''${WHISPER_MODEL:-large-v3-turbo}"
cache_root="''${XDG_CACHE_HOME:-$HOME/.cache}/llmChatElixir/whisper.cpp"
models_dir="$cache_root/models"
model_path="$models_dir/ggml-''${WHISPER_MODEL}.bin"
mkdir -p "$models_dir"
if [ ! -f "$model_path" ]; then
echo "Downloading whisper.cpp model ''${WHISPER_MODEL} into $models_dir"
whisper-cpp-download-ggml-model "$WHISPER_MODEL" "$models_dir"
fi
exec whisper-server \
--host "$WHISPER_HOST" \
--port "$WHISPER_PORT" \
--convert \
--language auto \
--model "$model_path" \
"$@"
'';
};
faster-whisper-python = pkgs.python3.withPackages (ps: [
ps.fastapi
ps.uvicorn
ps."faster-whisper"
ps."python-multipart"
]);
faster-whisper-server = pkgs.writeShellApplication {
name = "faster-whisper-stt-server";
runtimeInputs = [ faster-whisper-python pkgs.ffmpeg-headless pkgs.bash ];
text = ''
set -euo pipefail
repo_root="''${REPO_ROOT:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"
app_dir="$repo_root/llm_chat"
if [ ! -d "$app_dir" ] || [ ! -f "$app_dir/scripts/faster_whisper_server.py" ]; then
echo "Run this command from the repository checkout or set REPO_ROOT." >&2
exit 1
fi
export FASTER_WHISPER_HOST="''${FASTER_WHISPER_HOST:-127.0.0.1}"
export FASTER_WHISPER_PORT="''${FASTER_WHISPER_PORT:-9100}"
export FASTER_WHISPER_MODEL="''${FASTER_WHISPER_MODEL:-turbo}"
export FASTER_WHISPER_DEVICE="''${FASTER_WHISPER_DEVICE:-cpu}"
export FASTER_WHISPER_COMPUTE_TYPE="''${FASTER_WHISPER_COMPUTE_TYPE:-int8}"
export FASTER_WHISPER_CPU_THREADS="''${FASTER_WHISPER_CPU_THREADS:-8}"
export OMP_NUM_THREADS="''${OMP_NUM_THREADS:-$FASTER_WHISPER_CPU_THREADS}"
export OPENBLAS_NUM_THREADS="''${OPENBLAS_NUM_THREADS:-1}"
cd "$app_dir"
exec python scripts/faster_whisper_server.py "$@"
'';
};
full-dev = pkgs.writeShellApplication {
name = "llm-chat-full-dev";
runtimeInputs = [
pkgs.bash
pkgs.curl
llm-chat
clawrouter
whisper-server
faster-whisper-server
];
text = ''
set -euo pipefail
repo_root="''${REPO_ROOT:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"
env_file="$repo_root/llm_chat/.env"
if [ -f "$env_file" ]; then
set -a
# shellcheck disable=SC1090
. "$env_file"
set +a
fi
export PORT="''${PORT:-4000}"
export BLOCKRUN_PROXY_PORT="''${BLOCKRUN_PROXY_PORT:-8402}"
export WHISPER_PORT="''${WHISPER_PORT:-9000}"
export FASTER_WHISPER_PORT="''${FASTER_WHISPER_PORT:-9100}"
export STT_BACKEND="''${STT_BACKEND:-faster_whisper}"
pids=""
cleanup() {
for pid in $pids; do
kill "$pid" 2>/dev/null || true
done
}
trap cleanup EXIT INT TERM
port_open() {
local host="$1"
local port="$2"
bash -c "exec 3<>/dev/tcp/$host/$port" >/dev/null 2>&1
}
wait_for_port() {
local name="$1"
local host="$2"
local port="$3"
for _ in $(seq 1 60); do
if port_open "$host" "$port"; then
echo "$name is listening on $host:$port"
return 0
fi
sleep 1
done
echo "$name failed to start on $host:$port" >&2
return 1
}
if ! port_open 127.0.0.1 "$BLOCKRUN_PROXY_PORT"; then
echo "Starting ClawRouter on :$BLOCKRUN_PROXY_PORT"
clawrouter-proxy &
pids="$pids $!"
wait_for_port "ClawRouter" 127.0.0.1 "$BLOCKRUN_PROXY_PORT"
else
echo "Reusing ClawRouter on :$BLOCKRUN_PROXY_PORT"
fi
if [ "$STT_BACKEND" = "local_whisper" ]; then
if ! port_open 127.0.0.1 "$WHISPER_PORT"; then
echo "Starting whisper.cpp server on :$WHISPER_PORT"
whisper-stt-server &
pids="$pids $!"
wait_for_port "whisper.cpp" 127.0.0.1 "$WHISPER_PORT"
else
echo "Reusing whisper.cpp server on :$WHISPER_PORT"
fi
fi
if [ "$STT_BACKEND" = "faster_whisper" ]; then
if ! port_open 127.0.0.1 "$FASTER_WHISPER_PORT"; then
echo "Starting faster-whisper server on :$FASTER_WHISPER_PORT"
faster-whisper-stt-server &
pids="$pids $!"
wait_for_port "faster-whisper" 127.0.0.1 "$FASTER_WHISPER_PORT"
else
echo "Reusing faster-whisper server on :$FASTER_WHISPER_PORT"
fi
fi
exec llm-chat "$@"
'';
};
in
{
devShells.default = pkgs.mkShell {
buildInputs = elixirToolchain;
shellHook = ''
if [ -f llm_chat/.env ]; then
set -a
. llm_chat/.env
set +a
unset MIX_ENV
echo "Loaded llm_chat/.env"
fi
echo "Dev shell ready. Run: cd llm_chat && mix phx.server"
'';
};
packages.default = llm-chat;
packages.clawrouter = clawrouter;
packages.faster-whisper-server = faster-whisper-server;
packages.whisper-server = whisper-server;
packages.full-dev = full-dev;
apps.default = flake-utils.lib.mkApp {
drv = llm-chat;
};
apps.clawrouter = flake-utils.lib.mkApp {
drv = clawrouter;
};
apps.faster-whisper-server = flake-utils.lib.mkApp {
drv = faster-whisper-server;
};
apps.whisper-server = flake-utils.lib.mkApp {
drv = whisper-server;
};
apps.full-dev = flake-utils.lib.mkApp {
drv = full-dev;
};
}
);
}