From cba4d76b75a85d5f1c12e11a5da0380a77692db4 Mon Sep 17 00:00:00 2001 From: catlog22 Date: Mon, 12 Jan 2026 13:00:48 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=20ccw-litellm=20?= =?UTF-8?q?=E5=AE=89=E8=A3=85=E5=92=8C=E5=8D=B8=E8=BD=BD=E6=B5=81=E7=A8=8B?= =?UTF-8?q?=EF=BC=8C=E4=BC=98=E5=85=88=E4=BD=BF=E7=94=A8=20CodexLens=20?= =?UTF-8?q?=E8=99=9A=E6=8B=9F=E7=8E=AF=E5=A2=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ccw/src/core/routes/litellm-api-routes.ts | 90 ++++++++++++++--------- 1 file changed, 55 insertions(+), 35 deletions(-) diff --git a/ccw/src/core/routes/litellm-api-routes.ts b/ccw/src/core/routes/litellm-api-routes.ts index 8d38b575..701d6b88 100644 --- a/ccw/src/core/routes/litellm-api-routes.ts +++ b/ccw/src/core/routes/litellm-api-routes.ts @@ -662,7 +662,7 @@ export async function handleLiteLLMApiRoutes(ctx: RouteContext): Promise { try { - const { spawn } = await import('child_process'); + // Priority 1: Use UV to uninstall from CodexLens venv + if (await isUvAvailable()) { + const uv = createCodexLensUvManager(); + if (uv.isVenvValid()) { + console.log('[ccw-litellm uninstall] Using UV to uninstall from CodexLens venv...'); + const uvResult = await uv.uninstall(['ccw-litellm']); + clearCcwLitellmStatusCache(); - // Use shared Python detection for consistent cross-platform behavior + if (uvResult.success) { + broadcastToClients({ + type: 'CCW_LITELLM_UNINSTALLED', + payload: { timestamp: new Date().toISOString() } + }); + return { success: true, message: 'ccw-litellm uninstalled successfully via UV' }; + } + console.log('[ccw-litellm uninstall] UV uninstall failed, falling back to pip:', uvResult.error); + } + } + + // Priority 2: Fallback to system pip uninstall + console.log('[ccw-litellm uninstall] Using pip fallback...'); + const { spawn } = await import('child_process'); const pythonCmd = getSystemPython(); return new Promise((resolve) => {