Repository navigation
feat(dashscope): support DASHSCOPE_PROXY_BASE_URL for prompt cache via API gateway #3991
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 4 commits
1724132
7aa10d4
68e011e
79cb463
8144535
7d29bf5
669cd4a
68ef1f8
6524671
4696d34
420694b
e5bd8aa
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -38,6 +38,20 @@ vi.mock('../../../utils/runtimeFetchOptions.js', () => ({ | |||||||||||||||||||||
| buildRuntimeFetchOptions: vi.fn(), | ||||||||||||||||||||||
| })); | ||||||||||||||||||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [Suggestion] Test mock diverges from production and is fragile The
Suggested change
— glm-5.1 via Qwen Code /review
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This logic is already implemented at lines 60–62. Why is this recommendation showing up? |
||||||||||||||||||||||
|
|
||||||||||||||||||||||
| // Mock DASHSCOPE_PROXY_BASE_URL so tests can control its value | ||||||||||||||||||||||
| vi.mock('../constants.js', () => ({ | ||||||||||||||||||||||
| DEFAULT_TIMEOUT: 120000, | ||||||||||||||||||||||
| DEFAULT_MAX_RETRIES: 3, | ||||||||||||||||||||||
| DEFAULT_OPENAI_BASE_URL: 'https://api.openai.com/v1', | ||||||||||||||||||||||
| DEFAULT_DASHSCOPE_BASE_URL: | ||||||||||||||||||||||
| 'https://dashscope.aliyuncs.com/compatible-mode/v1', | ||||||||||||||||||||||
| DEFAULT_DEEPSEEK_BASE_URL: 'https://api.deepseek.com/v1', | ||||||||||||||||||||||
| DEFAULT_OPEN_ROUTER_BASE_URL: 'https://openrouter.ai/api/v1', | ||||||||||||||||||||||
| get DASHSCOPE_PROXY_BASE_URL() { | ||||||||||||||||||||||
| return process.env['DASHSCOPE_PROXY_BASE_URL']; | ||||||||||||||||||||||
| }, | ||||||||||||||||||||||
| })); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| describe('DashScopeOpenAICompatibleProvider', () => { | ||||||||||||||||||||||
| let provider: DashScopeOpenAICompatibleProvider; | ||||||||||||||||||||||
| let mockContentGeneratorConfig: ContentGeneratorConfig; | ||||||||||||||||||||||
|
|
@@ -162,6 +176,54 @@ describe('DashScopeOpenAICompatibleProvider', () => { | |||||||||||||||||||||
| expect(result).toBe(false); | ||||||||||||||||||||||
| }); | ||||||||||||||||||||||
| }); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| it('should return true when baseUrl matches DASHSCOPE_PROXY_BASE_URL', () => { | ||||||||||||||||||||||
| vi.stubEnv( | ||||||||||||||||||||||
| 'DASHSCOPE_PROXY_BASE_URL', | ||||||||||||||||||||||
| 'https://your-proxy.com/dashscope', | ||||||||||||||||||||||
| ); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| const config = { | ||||||||||||||||||||||
| authType: AuthType.USE_OPENAI, | ||||||||||||||||||||||
| baseUrl: 'https://your-proxy.com/dashscope', | ||||||||||||||||||||||
| } as ContentGeneratorConfig; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| const result = | ||||||||||||||||||||||
| DashScopeOpenAICompatibleProvider.isDashScopeProvider(config); | ||||||||||||||||||||||
| expect(result).toBe(true); | ||||||||||||||||||||||
| }); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| it('should return false when baseUrl does not match DASHSCOPE_PROXY_BASE_URL', () => { | ||||||||||||||||||||||
| vi.stubEnv( | ||||||||||||||||||||||
| 'DASHSCOPE_PROXY_BASE_URL', | ||||||||||||||||||||||
| 'https://your-proxy.com/dashscope', | ||||||||||||||||||||||
| ); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| const config = { | ||||||||||||||||||||||
| authType: AuthType.USE_OPENAI, | ||||||||||||||||||||||
| baseUrl: 'https://other-proxy.com/dashscope', | ||||||||||||||||||||||
| } as ContentGeneratorConfig; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| const result = | ||||||||||||||||||||||
| DashScopeOpenAICompatibleProvider.isDashScopeProvider(config); | ||||||||||||||||||||||
| expect(result).toBe(false); | ||||||||||||||||||||||
| }); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| it('should return true when baseUrl matches DASHSCOPE_PROXY_BASE_URL with trailing slash', () => { | ||||||||||||||||||||||
| vi.stubEnv( | ||||||||||||||||||||||
| 'DASHSCOPE_PROXY_BASE_URL', | ||||||||||||||||||||||
| 'https://your-proxy.com/dashscope', | ||||||||||||||||||||||
| ); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| const config = { | ||||||||||||||||||||||
| authType: AuthType.USE_OPENAI, | ||||||||||||||||||||||
| baseUrl: 'https://your-proxy.com/dashscope/', | ||||||||||||||||||||||
| } as ContentGeneratorConfig; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| const result = | ||||||||||||||||||||||
| DashScopeOpenAICompatibleProvider.isDashScopeProvider(config); | ||||||||||||||||||||||
| expect(result).toBe(true); | ||||||||||||||||||||||
| }); | ||||||||||||||||||||||
| }); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| describe('buildHeaders', () => { | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -7,6 +7,7 @@ import { | |||||||||||
| DEFAULT_TIMEOUT, | ||||||||||||
| DEFAULT_MAX_RETRIES, | ||||||||||||
| DEFAULT_DASHSCOPE_BASE_URL, | ||||||||||||
| DASHSCOPE_PROXY_BASE_URL, | ||||||||||||
| } from '../constants.js'; | ||||||||||||
| import type { | ||||||||||||
| DashScopeRequestMetadata, | ||||||||||||
|
|
@@ -33,8 +34,24 @@ export class DashScopeOpenAICompatibleProvider extends DefaultOpenAICompatiblePr | |||||||||||
| if (authType === AuthType.QWEN_OAUTH) return true; | ||||||||||||
| if (!baseUrl) return true; | ||||||||||||
|
|
||||||||||||
| const normalizedBaseUrl = baseUrl.endsWith('/') | ||||||||||||
|
HeZiGang marked this conversation as resolved.
|
||||||||||||
| ? baseUrl.slice(0, -1) | ||||||||||||
| : baseUrl; | ||||||||||||
|
|
||||||||||||
| // Matches: dashscope.aliyuncs.com, *.dashscope.aliyuncs.com, or *.dashscope-intl.aliyuncs.com | ||||||||||||
| return /([\w-]+\.)?dashscope(-intl)?\.aliyuncs\.com/i.test(baseUrl); | ||||||||||||
| const isDashscopeOrigin = | ||||||||||||
| /([\w-]+\.)?dashscope(-intl)?\.aliyuncs\.com/i.test(normalizedBaseUrl); | ||||||||||||
|
|
||||||||||||
|
|
||||||||||||
| // Check if proxy is configured and matches | ||||||||||||
| const normalizedProxyUrl = DASHSCOPE_PROXY_BASE_URL?.endsWith('/') | ||||||||||||
| ? DASHSCOPE_PROXY_BASE_URL.slice(0, -1) | ||||||||||||
| : DASHSCOPE_PROXY_BASE_URL; | ||||||||||||
|
|
||||||||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [Suggestion] Case-sensitivity inconsistency between origin check and proxy check The origin-domain regex on line 43 uses the
Suggested change
— glm-5.1 via Qwen Code /review |
||||||||||||
| const isProxyConfigured = Boolean( | ||||||||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [Suggestion] No diagnostic logging when proxy URL doesn't match When — glm-5.1 via Qwen Code /review
HeZiGang marked this conversation as resolved.
Outdated
|
||||||||||||
| normalizedProxyUrl && normalizedBaseUrl === normalizedProxyUrl, | ||||||||||||
| ); | ||||||||||||
|
|
||||||||||||
| return isDashscopeOrigin || isProxyConfigured; | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| override buildHeaders(): Record<string, string | undefined> { | ||||||||||||
|
|
||||||||||||
Uh oh!
There was an error while loading. Please reload this page.