mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-02-12 02:37:45 +08:00
- #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:
@@ -72,6 +72,10 @@ export async function testApiKeyConnection(
|
||||
return { valid: false, error: urlValidation.error };
|
||||
}
|
||||
|
||||
// Normalize apiBase: remove trailing slashes to prevent URL construction issues
|
||||
// e.g., "https://api.openai.com/v1/" -> "https://api.openai.com/v1"
|
||||
const normalizedApiBase = apiBase.replace(/\/+$/, '');
|
||||
|
||||
const controller = new AbortController();
|
||||
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
||||
const startTime = Date.now();
|
||||
@@ -80,7 +84,7 @@ export async function testApiKeyConnection(
|
||||
if (providerType === 'anthropic') {
|
||||
// Anthropic format: Use /v1/models endpoint (no cost, no model dependency)
|
||||
// This validates the API key without making a billable request
|
||||
const response = await fetch(`${apiBase}/models`, {
|
||||
const response = await fetch(`${normalizedApiBase}/models`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'x-api-key': apiKey,
|
||||
@@ -114,8 +118,10 @@ export async function testApiKeyConnection(
|
||||
|
||||
return { valid: false, error: errorMessage };
|
||||
} else {
|
||||
// OpenAI-compatible format: GET /v1/models
|
||||
const modelsUrl = apiBase.endsWith('/v1') ? `${apiBase}/models` : `${apiBase}/v1/models`;
|
||||
// OpenAI-compatible format: GET /v{N}/models
|
||||
// Detect if URL already ends with a version pattern like /v1, /v2, /v4, etc.
|
||||
const hasVersionSuffix = /\/v\d+$/.test(normalizedApiBase);
|
||||
const modelsUrl = hasVersionSuffix ? `${normalizedApiBase}/models` : `${normalizedApiBase}/v1/models`;
|
||||
const response = await fetch(modelsUrl, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
|
||||
Reference in New Issue
Block a user