Commit e85e637
authored
fix: [AI-198] prioritize managed engine venv over CWD .venv (#199)
* fix: [AI-198] prioritize managed engine venv over CWD `.venv` in `resolvePython()`
`ensureEngine()` installs altimate-engine into the managed venv at
`~/.opencode/data/engine/venv/`, but `resolvePython()` checked for a
`.venv` in the user's current working directory first. When running
from any Python project with its own `.venv`, the bridge would spawn
that project's Python — which doesn't have altimate-engine — and fail.
Swap the priority so the managed engine venv is checked before the
CWD `.venv`. Add a test covering the new ordering.
Closes #198
* fix: [AI-196] install `altimate-engine[warehouses]` extra by default
The managed engine install was missing the `[warehouses]` optional
dependency group, which includes `snowflake-connector-python`,
`psycopg2-binary`, `duckdb`, and other database connectors. This
caused FinOps tools and warehouse operations to fail with
"snowflake-connector-python not installed" errors.
Closes #196
* fix: harden engine bootstrap — validate venv, track extras, fix Windows paths, add startup mutex
- Validate Python binary exists on disk before trusting manifest
(fixes: manifest exists but venv manually deleted → silent failure)
- Track installed extras in manifest so version match with different
extras (e.g. upgrading from no-extras to `[warehouses]`) triggers reinstall
- Use platform-aware `venvPythonBin()` helper for dev/cwd venv paths
(fixes: Windows uses `Scripts/python.exe`, not `bin/python`)
- Add `pendingStart` mutex to `Bridge.call()` preventing concurrent
`start()` calls from spawning duplicate Python processes
- Add 25 new tests covering: priority ordering, env var edge cases,
extras tracking, manifest validation, Windows paths, startup mutex,
concurrent calls
* fix: clean up child process on ping failure + use platform-aware paths in tests
Address Sentry bot review comments on PR #199:
1. When `start()` spawns a child but `ping` verification fails, kill
and clear the `child` handle so subsequent `call()` invocations
trigger a restart instead of writing to a broken process and
hanging for 30s timeout.
2. Use platform-aware `testVenvPythonBin()` helper in test file for
dev/cwd venv detection, matching production `venvPythonBin()`
behavior. Fixes incorrect test skip logic on Windows.
* fix: address multi-model code review feedback
- Remove dead else branch in `ENGINE_INSTALL_SPEC` conditional (constant
is always truthy)
- Add `extras` field to `engine_started` telemetry event for debugging
- Update `ENGINE_INSTALL_SPEC` comment to reflect production usage
- Tighten concurrent startup test assertion to verify mutex coalescing
(`ensureEngineCalls <= 2` instead of just `>= 1`)
* fix: handle spawn errors, venv recovery, and post-mutex child guard
Address Gemini review findings:
1. Add `error` event handler on spawned child process to prevent
unhandled ENOENT/EACCES from crashing the host process when
`resolvePython()` returns a nonexistent or non-executable path.
2. Recreate venv when Python binary is missing even if the venv
directory still exists (e.g. user deleted just the binary).
3. Re-check `child` state after awaiting `pendingStart` mutex —
the process may have died between startup completing and the
secondary caller resuming.
* fix: don't increment `restartCount` when process is killed by signal
When `child.kill()` is called (e.g. after ping failure), the exit
handler fires with `code = null`. The check `code !== 0` treated
this as a crash, incrementing `restartCount`. After two ping
failures, the bridge would be permanently disabled.
Changed to `code !== null && code !== 0` so only actual non-zero
exit codes (real crashes) count toward the restart limit.1 parent 31d8f52 commit e85e637
File tree
4 files changed
+524
-24
lines changed- packages/opencode
- src/altimate
- bridge
- telemetry
- test/bridge
4 files changed
+524
-24
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
14 | 14 | | |
15 | 15 | | |
16 | 16 | | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
17 | 24 | | |
18 | 25 | | |
19 | 26 | | |
| |||
22 | 29 | | |
23 | 30 | | |
24 | 31 | | |
25 | | - | |
| 32 | + | |
26 | 33 | | |
27 | 34 | | |
28 | | - | |
29 | | - | |
30 | | - | |
31 | | - | |
32 | | - | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
33 | 39 | | |
34 | 40 | | |
35 | 41 | | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
36 | 46 | | |
37 | 47 | | |
38 | 48 | | |
| |||
45 | 55 | | |
46 | 56 | | |
47 | 57 | | |
| 58 | + | |
| 59 | + | |
48 | 60 | | |
49 | 61 | | |
50 | 62 | | |
| |||
53 | 65 | | |
54 | 66 | | |
55 | 67 | | |
56 | | - | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
57 | 82 | | |
58 | 83 | | |
59 | 84 | | |
| |||
141 | 166 | | |
142 | 167 | | |
143 | 168 | | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
144 | 179 | | |
145 | | - | |
| 180 | + | |
146 | 181 | | |
147 | 182 | | |
148 | 183 | | |
| |||
154 | 189 | | |
155 | 190 | | |
156 | 191 | | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
157 | 197 | | |
158 | 198 | | |
159 | 199 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
25 | 25 | | |
26 | 26 | | |
27 | 27 | | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
28 | 32 | | |
29 | 33 | | |
30 | 34 | | |
31 | 35 | | |
32 | 36 | | |
33 | 37 | | |
| 38 | + | |
| 39 | + | |
34 | 40 | | |
35 | 41 | | |
36 | 42 | | |
| |||
158 | 164 | | |
159 | 165 | | |
160 | 166 | | |
161 | | - | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
162 | 173 | | |
163 | 174 | | |
164 | 175 | | |
| |||
168 | 179 | | |
169 | 180 | | |
170 | 181 | | |
171 | | - | |
172 | | - | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
173 | 185 | | |
174 | 186 | | |
175 | 187 | | |
| |||
189 | 201 | | |
190 | 202 | | |
191 | 203 | | |
192 | | - | |
| 204 | + | |
| 205 | + | |
193 | 206 | | |
194 | 207 | | |
195 | 208 | | |
| |||
212 | 225 | | |
213 | 226 | | |
214 | 227 | | |
| 228 | + | |
215 | 229 | | |
216 | 230 | | |
217 | 231 | | |
| |||
220 | 234 | | |
221 | 235 | | |
222 | 236 | | |
| 237 | + | |
223 | 238 | | |
224 | 239 | | |
225 | 240 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
153 | 153 | | |
154 | 154 | | |
155 | 155 | | |
| 156 | + | |
156 | 157 | | |
157 | 158 | | |
158 | 159 | | |
| |||
0 commit comments