Skip to content

Commit 211c25d

Browse files
catlog22claude
andcommitted
fix: Use pip show for more reliable ccw-litellm detection
- Primary method: pip show ccw-litellm (most reliable) - Fallback: Python import with simpler syntax - Increased timeout for pip show to 10s 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
1 parent 275684d commit 211c25d

File tree

1 file changed

+36
-19
lines changed

1 file changed

+36
-19
lines changed

ccw/src/core/routes/litellm-api-routes.ts

Lines changed: 36 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -566,33 +566,50 @@ export async function handleLiteLLMApiRoutes(ctx: RouteContext): Promise<boolean
566566
return true;
567567
}
568568

569-
// Async check
569+
// Async check - use pip show for more reliable detection
570570
try {
571571
const { exec } = await import('child_process');
572572
const { promisify } = await import('util');
573573
const execAsync = promisify(exec);
574574

575-
const pythonExecutables = ['python', 'python3', 'py'];
576-
const pythonCode = "import ccw_litellm; print(getattr(ccw_litellm, '__version__', 'installed'))";
577-
578575
let result: { installed: boolean; version?: string; error?: string } = { installed: false };
579576

580-
for (const pythonExe of pythonExecutables) {
581-
try {
582-
const { stdout } = await execAsync(`${pythonExe} -c "${pythonCode}"`, {
583-
timeout: 5000,
584-
windowsHide: true,
585-
shell: true, // Required for Windows PATH resolution
586-
});
587-
const version = stdout.trim();
588-
if (version) {
589-
result = { installed: true, version };
590-
console.log(`[ccw-litellm status] Found with ${pythonExe}: ${version}`);
591-
break;
577+
// Method 1: Try pip show ccw-litellm (most reliable)
578+
try {
579+
const { stdout } = await execAsync('pip show ccw-litellm', {
580+
timeout: 10000,
581+
windowsHide: true,
582+
shell: true,
583+
});
584+
// Parse version from pip show output
585+
const versionMatch = stdout.match(/Version:\s*(.+)/i);
586+
if (versionMatch) {
587+
result = { installed: true, version: versionMatch[1].trim() };
588+
console.log(`[ccw-litellm status] Found via pip show: ${result.version}`);
589+
}
590+
} catch (pipErr) {
591+
console.log('[ccw-litellm status] pip show failed, trying python import...');
592+
593+
// Method 2: Fallback to Python import
594+
const pythonExecutables = ['python', 'python3', 'py'];
595+
for (const pythonExe of pythonExecutables) {
596+
try {
597+
// Use simpler Python code without complex quotes
598+
const { stdout } = await execAsync(`${pythonExe} -c "import ccw_litellm; print(ccw_litellm.__version__)"`, {
599+
timeout: 5000,
600+
windowsHide: true,
601+
shell: true,
602+
});
603+
const version = stdout.trim();
604+
if (version) {
605+
result = { installed: true, version };
606+
console.log(`[ccw-litellm status] Found with ${pythonExe}: ${version}`);
607+
break;
608+
}
609+
} catch (err) {
610+
result.error = (err as Error).message;
611+
console.log(`[ccw-litellm status] ${pythonExe} failed:`, result.error.substring(0, 100));
592612
}
593-
} catch (err) {
594-
result.error = (err as Error).message;
595-
console.log(`[ccw-litellm status] ${pythonExe} failed:`, result.error.substring(0, 100));
596613
}
597614
}
598615

0 commit comments

Comments
 (0)