fix: resolve GitHub issues #63, #66, #67, #68, #69, #70

- #70: Fix API Key Tester URL handling - normalize trailing slashes before
  version suffix detection to prevent double-slash URLs like //models
- #69: Fix memory embedder ignoring CodexLens config - add error handling
  for CodexLensConfig.load() with fallback to defaults
- #68: Fix ccw cli using wrong Python environment - add getCodexLensVenvPython()
  to resolve correct venv path on Windows/Unix
- #67: Fix LiteLLM API Provider test endpoint - actually test API key connection
  instead of just checking ccw-litellm installation
- #66: Fix help-routes.ts path configuration - use correct 'ccw-help' directory
  name and refactor getIndexDir to pure function
- #63: Fix CodexLens install state refresh - add cache invalidation after
  config save in codexlens-manager.js

Also includes targeted unit tests for the URL normalization logic.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
catlog22
2026-01-13 18:20:54 +08:00
parent 61cef8019a
commit 340137d347
12 changed files with 546 additions and 29 deletions

View File

@@ -10,14 +10,36 @@
*/
import { spawn } from 'child_process';
import { promisify } from 'util';
import { existsSync } from 'fs';
import { join } from 'path';
import { homedir } from 'os';
export interface LiteLLMConfig {
pythonPath?: string; // Default 'python'
pythonPath?: string; // Default: CodexLens venv Python
configPath?: string; // Configuration file path
timeout?: number; // Default 60000ms
}
// Platform-specific constants for CodexLens venv
const IS_WINDOWS = process.platform === 'win32';
const CODEXLENS_VENV = join(homedir(), '.codexlens', 'venv');
const VENV_BIN_DIR = IS_WINDOWS ? 'Scripts' : 'bin';
const PYTHON_EXECUTABLE = IS_WINDOWS ? 'python.exe' : 'python';
/**
* Get the Python path from CodexLens venv
* Falls back to system 'python' if venv doesn't exist
* @returns Path to Python executable
*/
export function getCodexLensVenvPython(): string {
const venvPython = join(CODEXLENS_VENV, VENV_BIN_DIR, PYTHON_EXECUTABLE);
if (existsSync(venvPython)) {
return venvPython;
}
// Fallback to system Python if venv not available
return 'python';
}
export interface ChatMessage {
role: 'system' | 'user' | 'assistant';
content: string;
@@ -51,7 +73,7 @@ export class LiteLLMClient {
private timeout: number;
constructor(config: LiteLLMConfig = {}) {
this.pythonPath = config.pythonPath || 'python';
this.pythonPath = config.pythonPath || getCodexLensVenvPython();
this.configPath = config.configPath;
this.timeout = config.timeout || 60000;
}

View File

@@ -3,7 +3,7 @@
* Integrates with context-cache for file packing and LiteLLM client for API calls
*/
import { getLiteLLMClient } from './litellm-client.js';
import { getLiteLLMClient, getCodexLensVenvPython } from './litellm-client.js';
import { handler as contextCacheHandler } from './context-cache.js';
import {
findEndpointById,
@@ -179,7 +179,7 @@ export async function executeLiteLLMEndpoint(
}
const client = getLiteLLMClient({
pythonPath: 'python',
pythonPath: getCodexLensVenvPython(),
timeout: 120000, // 2 minutes
});