From 468053c92a2d3b91d848a037b68f9c7242f856b8 Mon Sep 17 00:00:00 2001 From: yiliang114 Date: Thu, 13 Aug 2026 22:04:03 +0800 Subject: [PATCH 1/2] feat(core): inject request metadata for alicloudapi.com gateways Treat *.alicloudapi.com (Alibaba Cloud API Gateway) as a DashScope-compatible origin so request bodies carry the session tracking metadata (sessionId, promptId, channel), matching the existing handling for internal Alibaba domains. Fixes #9101 --- .../provider/dashscope.test.ts | 35 +++++++++++++++++++ .../provider/dashscope.ts | 13 ++++++- 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/packages/core/src/core/openaiContentGenerator/provider/dashscope.test.ts b/packages/core/src/core/openaiContentGenerator/provider/dashscope.test.ts index 3ff250b059d..8768b2444bb 100644 --- a/packages/core/src/core/openaiContentGenerator/provider/dashscope.test.ts +++ b/packages/core/src/core/openaiContentGenerator/provider/dashscope.test.ts @@ -246,6 +246,39 @@ describe('DashScopeOpenAICompatibleProvider', () => { expect(result).toBe(true); }); + it('should return true for alicloudapi.com subdomain', () => { + const config = { + authType: AuthType.USE_OPENAI, + baseUrl: 'https://api-id.cn-hangzhou.alicloudapi.com/v1', + } as ContentGeneratorConfig; + + const result = + DashScopeOpenAICompatibleProvider.isDashScopeProvider(config); + expect(result).toBe(true); + }); + + it('should return true for port-bearing alicloudapi.com URL', () => { + const config = { + authType: AuthType.USE_OPENAI, + baseUrl: 'https://gateway.alicloudapi.com:8443/v1', + } as ContentGeneratorConfig; + + const result = + DashScopeOpenAICompatibleProvider.isDashScopeProvider(config); + expect(result).toBe(true); + }); + + it('should return false for bare alicloudapi.com domain', () => { + const config = { + authType: AuthType.USE_OPENAI, + baseUrl: 'https://alicloudapi.com/v1', + } as ContentGeneratorConfig; + + const result = + DashScopeOpenAICompatibleProvider.isDashScopeProvider(config); + expect(result).toBe(false); + }); + it('should return false for bare alibaba-inc.com domain', () => { const config = { authType: AuthType.USE_OPENAI, @@ -276,6 +309,8 @@ describe('DashScopeOpenAICompatibleProvider', () => { 'https://aliyun-inc.com.evil.com/v1', 'https://not-token-plan.cn-beijing.maas.aliyuncs.com/v1', 'https://token-plan.cn-beijing.maas.aliyuncs.com.evil.com/v1', + 'https://notalicloudapi.com/v1', + 'https://alicloudapi.com.evil.com/v1', ]; configs.forEach((baseUrl) => { diff --git a/packages/core/src/core/openaiContentGenerator/provider/dashscope.ts b/packages/core/src/core/openaiContentGenerator/provider/dashscope.ts index d375990ba31..6a3c5fb31b1 100644 --- a/packages/core/src/core/openaiContentGenerator/provider/dashscope.ts +++ b/packages/core/src/core/openaiContentGenerator/provider/dashscope.ts @@ -170,6 +170,7 @@ export class DashScopeOpenAICompatibleProvider extends DefaultOpenAICompatiblePr * Covers the official regional hosts (DASHSCOPE_REGIONAL_HOSTS), * Token Plan endpoints under token-plan..maas.aliyuncs.com, * internal Alibaba domains (*.alibaba-inc.com, *.aliyun-inc.com), + * Alibaba Cloud API Gateway domains (*.alicloudapi.com), * and proxy matches. * * Note: any *.alibaba-inc.com / *.aliyun-inc.com host is treated as a @@ -217,6 +218,11 @@ export class DashScopeOpenAICompatibleProvider extends DefaultOpenAICompatiblePr (hostname.endsWith('.alibaba-inc.com') || hostname.endsWith('.aliyun-inc.com')); + // Alibaba Cloud API Gateway domains proxying to DashScope-compatible + // APIs. Covers *.alicloudapi.com. + const isAliCloudApiOrigin = + hostname !== null && hostname.endsWith('.alicloudapi.com'); + // Check if proxy is configured and matches const normalizedProxyUrl = DASHSCOPE_PROXY_BASE_URL?.endsWith('/') ? DASHSCOPE_PROXY_BASE_URL.slice(0, -1) @@ -232,6 +238,7 @@ export class DashScopeOpenAICompatibleProvider extends DefaultOpenAICompatiblePr !isDashscopeOrigin && !isTokenPlanOrigin && !isInternalOrigin && + !isAliCloudApiOrigin && !isProxyMatch ) { debugLogger.debug( @@ -246,7 +253,11 @@ export class DashScopeOpenAICompatibleProvider extends DefaultOpenAICompatiblePr } return ( - isDashscopeOrigin || isTokenPlanOrigin || isInternalOrigin || isProxyMatch + isDashscopeOrigin || + isTokenPlanOrigin || + isInternalOrigin || + isAliCloudApiOrigin || + isProxyMatch ); } From 834d24005e47f67a0164034841318a519c8c66e4 Mon Sep 17 00:00:00 2001 From: yiliang114 Date: Thu, 13 Aug 2026 22:14:07 +0800 Subject: [PATCH 2/2] test(core): cover alicloudapi.com routing and log activation Add an end-to-end determineProvider + buildRequest regression proving the acceptance criteria (metadata in the request body), and assert the alicloudapi origin activation debug log for parity with internal origins. --- .../provider/dashscope.test.ts | 40 +++++++++++++++++++ .../provider/dashscope.ts | 6 +++ 2 files changed, 46 insertions(+) diff --git a/packages/core/src/core/openaiContentGenerator/provider/dashscope.test.ts b/packages/core/src/core/openaiContentGenerator/provider/dashscope.test.ts index 8768b2444bb..84acedd4d3d 100644 --- a/packages/core/src/core/openaiContentGenerator/provider/dashscope.test.ts +++ b/packages/core/src/core/openaiContentGenerator/provider/dashscope.test.ts @@ -17,6 +17,7 @@ import { DashScopeOpenAICompatibleProvider, selectDashScopeThinkingKnob, } from './dashscope.js'; +import { determineProvider } from '../index.js'; import type { Config } from '../../../config/config.js'; import type { ContentGeneratorConfig } from '../../contentGenerator.js'; import { AuthType } from '../../contentGenerator.js'; @@ -255,6 +256,9 @@ describe('DashScopeOpenAICompatibleProvider', () => { const result = DashScopeOpenAICompatibleProvider.isDashScopeProvider(config); expect(result).toBe(true); + expect(mockDebugLogger.debug).toHaveBeenCalledWith( + 'DashScope provider activated via alicloudapi origin: api-id.cn-hangzhou.alicloudapi.com', + ); }); it('should return true for port-bearing alicloudapi.com URL', () => { @@ -475,6 +479,42 @@ describe('DashScopeOpenAICompatibleProvider', () => { }); }); + // Guards the full acceptance path end-to-end: an alicloudapi.com base URL + // must route through the DashScope provider so buildRequest injects the + // session-tracking metadata into the request body. + describe('determineProvider routing for alicloudapi.com', () => { + const alicloudapiConfig = { + authType: AuthType.USE_OPENAI, + baseUrl: 'https://api-id.cn-hangzhou.alicloudapi.com/v1', + model: 'qwen-max', + } as ContentGeneratorConfig; + + it('routes alicloudapi.com base URLs to the DashScope provider', () => { + const routed = determineProvider(alicloudapiConfig, mockCliConfig); + expect(routed).toBeInstanceOf(DashScopeOpenAICompatibleProvider); + }); + + it('injects session-tracking metadata into the request body', () => { + const routed = determineProvider( + alicloudapiConfig, + mockCliConfig, + ) as DashScopeOpenAICompatibleProvider; + + const result = routed.buildRequest( + { + model: 'qwen-max', + messages: [{ role: 'user', content: 'Hello!' }], + }, + 'test-prompt-id', + ); + + expect(result.metadata).toEqual({ + sessionId: 'test-session-id', + promptId: 'test-prompt-id', + }); + }); + }); + describe('buildHeaders', () => { it('should build DashScope-specific headers', () => { const headers = provider.buildHeaders(); diff --git a/packages/core/src/core/openaiContentGenerator/provider/dashscope.ts b/packages/core/src/core/openaiContentGenerator/provider/dashscope.ts index 6a3c5fb31b1..a41a1abeb6b 100644 --- a/packages/core/src/core/openaiContentGenerator/provider/dashscope.ts +++ b/packages/core/src/core/openaiContentGenerator/provider/dashscope.ts @@ -252,6 +252,12 @@ export class DashScopeOpenAICompatibleProvider extends DefaultOpenAICompatiblePr ); } + if (isAliCloudApiOrigin) { + debugLogger.debug( + `DashScope provider activated via alicloudapi origin: ${hostname}`, + ); + } + return ( isDashscopeOrigin || isTokenPlanOrigin ||