fix(dashboard): probe the interpreter from the repo root in gen:api

The version guard ran execFileSync without a cwd, so a repo-root-relative
LITELLM_PYTHON (e.g. .venv/bin/python) was resolved against the dashboard
directory the npm script runs in, while the later spec dump resolves it
against the repo root. Thread repoRoot into the probe so both calls agree.
This commit is contained in:
mateo-berri 2026-06-28 00:19:53 +00:00
parent 016c12c866
commit 0a16db0f53
No known key found for this signature in database
2 changed files with 36 additions and 4 deletions

View file

@ -55,12 +55,17 @@ export function unsupportedPythonMessage(pythonCommand, version) {
);
}
function assertSupportedPython(pythonCommand) {
export function probePythonVersion(pythonCommand, cwd, exec = execFileSync) {
const probe = "import sys; print('.'.join(map(str, sys.version_info[:2])))";
const stdout = execFileSync(pythonCommand[0], [...pythonCommand.slice(1), "-c", probe], {
const stdout = exec(pythonCommand[0], [...pythonCommand.slice(1), "-c", probe], {
cwd,
encoding: "utf8",
});
const version = parsePythonVersion(stdout);
return parsePythonVersion(stdout);
}
function assertSupportedPython(pythonCommand, cwd) {
const version = probePythonVersion(pythonCommand, cwd);
if (!isSupportedPython(version)) {
throw new Error(unsupportedPythonMessage(pythonCommand, version));
}
@ -89,7 +94,7 @@ function main() {
].join("\n");
try {
assertSupportedPython(python);
assertSupportedPython(python, repoRoot);
execFileSync(python[0], [...python.slice(1), "-c", dumpSpec, specPath], {
cwd: repoRoot,

View file

@ -2,6 +2,7 @@ import { describe, it, expect } from "vitest";
import {
resolvePythonCommand,
parsePythonVersion,
probePythonVersion,
isSupportedPython,
unsupportedPythonMessage,
} from "../scripts/gen-api-types.mjs";
@ -49,6 +50,32 @@ describe("parsePythonVersion", () => {
});
});
describe("probePythonVersion", () => {
it("probes the interpreter from the repo root, matching the spec-dump cwd", () => {
let seenCwd: string | undefined;
const exec = (_bin: string, _args: string[], opts: { cwd?: string }) => {
seenCwd = opts.cwd;
return "3.11\n";
};
const version = probePythonVersion(["python3"], repoRoot, exec);
expect(seenCwd).toBe(repoRoot);
expect(version).toEqual({ major: 3, minor: 11 });
});
it("resolves a repo-root-relative interpreter against the repo root, not the dashboard cwd", () => {
let seenBin: string | undefined;
let seenCwd: string | undefined;
const exec = (bin: string, _args: string[], opts: { cwd?: string }) => {
seenBin = bin;
seenCwd = opts.cwd;
return "3.12\n";
};
probePythonVersion([".venv/bin/python"], repoRoot, exec);
expect(seenBin).toBe(".venv/bin/python");
expect(seenCwd).toBe(repoRoot);
});
});
describe("isSupportedPython", () => {
it("rejects the 3.9 interpreter that breaks on dataclass slots=True", () => {
expect(isSupportedPython({ major: 3, minor: 9 })).toBe(false);