mirror of
https://github.com/QwenLM/qwen-code.git
synced 2025-12-20 16:57:46 +00:00
feat: add URL trailing slash compatibility for system prompt mappings
- Add normalizeUrl() function to standardize URLs by removing trailing slashes - Add urlMatches() function to compare URLs ignoring trailing slash differences - Replace direct includes() comparison with urlMatches() for baseUrl matching - Add comprehensive tests to verify URL matching with/without trailing slashes - Fixes issue where URLs like 'https://api.example.com' and 'https://api.example.com/' were treated as different
This commit is contained in:
@@ -106,3 +106,96 @@ describe('Core System Prompt (prompts.ts)', () => {
|
|||||||
expect(prompt).toMatchSnapshot();
|
expect(prompt).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('URL matching with trailing slash compatibility', () => {
|
||||||
|
it('should match URLs with and without trailing slash', () => {
|
||||||
|
const config = {
|
||||||
|
systemPromptMappings: [
|
||||||
|
{
|
||||||
|
baseUrls: ['https://api.example.com'],
|
||||||
|
modelNames: ['gpt-4'],
|
||||||
|
template: 'Custom template for example.com',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
baseUrls: ['https://api.openai.com/'],
|
||||||
|
modelNames: ['gpt-3.5-turbo'],
|
||||||
|
template: 'Custom template for openai.com',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
// Simulate environment variables
|
||||||
|
const originalEnv = process.env;
|
||||||
|
|
||||||
|
// Test case 1: No trailing slash in config, actual URL has trailing slash
|
||||||
|
process.env = {
|
||||||
|
...originalEnv,
|
||||||
|
OPENAI_BASE_URL: 'https://api.example.com/',
|
||||||
|
OPENAI_MODEL: 'gpt-4',
|
||||||
|
};
|
||||||
|
|
||||||
|
const result1 = getCoreSystemPrompt(undefined, config);
|
||||||
|
expect(result1).toContain('Custom template for example.com');
|
||||||
|
|
||||||
|
// Test case 2: Config has trailing slash, actual URL has no trailing slash
|
||||||
|
process.env = {
|
||||||
|
...originalEnv,
|
||||||
|
OPENAI_BASE_URL: 'https://api.openai.com',
|
||||||
|
OPENAI_MODEL: 'gpt-3.5-turbo',
|
||||||
|
};
|
||||||
|
|
||||||
|
const result2 = getCoreSystemPrompt(undefined, config);
|
||||||
|
expect(result2).toContain('Custom template for openai.com');
|
||||||
|
|
||||||
|
// Test case 3: No trailing slash in config, actual URL has no trailing slash
|
||||||
|
process.env = {
|
||||||
|
...originalEnv,
|
||||||
|
OPENAI_BASE_URL: 'https://api.example.com',
|
||||||
|
OPENAI_MODEL: 'gpt-4',
|
||||||
|
};
|
||||||
|
|
||||||
|
const result3 = getCoreSystemPrompt(undefined, config);
|
||||||
|
expect(result3).toContain('Custom template for example.com');
|
||||||
|
|
||||||
|
// Test case 4: Config has trailing slash, actual URL has trailing slash
|
||||||
|
process.env = {
|
||||||
|
...originalEnv,
|
||||||
|
OPENAI_BASE_URL: 'https://api.openai.com/',
|
||||||
|
OPENAI_MODEL: 'gpt-3.5-turbo',
|
||||||
|
};
|
||||||
|
|
||||||
|
const result4 = getCoreSystemPrompt(undefined, config);
|
||||||
|
expect(result4).toContain('Custom template for openai.com');
|
||||||
|
|
||||||
|
// Restore original environment variables
|
||||||
|
process.env = originalEnv;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not match when URLs are different', () => {
|
||||||
|
const config = {
|
||||||
|
systemPromptMappings: [
|
||||||
|
{
|
||||||
|
baseUrls: ['https://api.example.com'],
|
||||||
|
modelNames: ['gpt-4'],
|
||||||
|
template: 'Custom template for example.com',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
const originalEnv = process.env;
|
||||||
|
|
||||||
|
// Test case: URLs do not match
|
||||||
|
process.env = {
|
||||||
|
...originalEnv,
|
||||||
|
OPENAI_BASE_URL: 'https://api.different.com',
|
||||||
|
OPENAI_MODEL: 'gpt-4',
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = getCoreSystemPrompt(undefined, config);
|
||||||
|
// Should return default template, not contain custom template
|
||||||
|
expect(result).not.toContain('Custom template for example.com');
|
||||||
|
|
||||||
|
// Restore original environment variables
|
||||||
|
process.env = originalEnv;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
@@ -28,6 +28,21 @@ export interface SystemPromptConfig {
|
|||||||
systemPromptMappings?: ModelTemplateMapping[];
|
systemPromptMappings?: ModelTemplateMapping[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalizes a URL by removing trailing slash for consistent comparison
|
||||||
|
*/
|
||||||
|
function normalizeUrl(url: string): string {
|
||||||
|
return url.endsWith('/') ? url.slice(0, -1) : url;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a URL matches any URL in the array, ignoring trailing slashes
|
||||||
|
*/
|
||||||
|
function urlMatches(urlArray: string[], targetUrl: string): boolean {
|
||||||
|
const normalizedTarget = normalizeUrl(targetUrl);
|
||||||
|
return urlArray.some((url) => normalizeUrl(url) === normalizedTarget);
|
||||||
|
}
|
||||||
|
|
||||||
export function getCoreSystemPrompt(
|
export function getCoreSystemPrompt(
|
||||||
userMemory?: string,
|
userMemory?: string,
|
||||||
config?: SystemPromptConfig,
|
config?: SystemPromptConfig,
|
||||||
@@ -59,13 +74,13 @@ export function getCoreSystemPrompt(
|
|||||||
if (
|
if (
|
||||||
baseUrls &&
|
baseUrls &&
|
||||||
modelNames &&
|
modelNames &&
|
||||||
baseUrls.includes(currentBaseUrl) &&
|
urlMatches(baseUrls, currentBaseUrl) &&
|
||||||
modelNames.includes(currentModel)
|
modelNames.includes(currentModel)
|
||||||
) {
|
) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (baseUrls && baseUrls.includes(currentBaseUrl) && !modelNames) {
|
if (baseUrls && urlMatches(baseUrls, currentBaseUrl) && !modelNames) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (modelNames && modelNames.includes(currentModel) && !baseUrls) {
|
if (modelNames && modelNames.includes(currentModel) && !baseUrls) {
|
||||||
|
|||||||
Reference in New Issue
Block a user