Skip to content

Commit 6c51d67

Browse files
feat(ai-gateway): add direct Qwen3.7 Plus model (#3655)
Co-authored-by: Christiaan Arnoldus <christiaan@kilocode.ai>
1 parent 8658847 commit 6c51d67

3 files changed

Lines changed: 89 additions & 1 deletion

File tree

apps/web/src/lib/ai-gateway/models.test.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,12 @@ import {
1212
claude_sonnet_4_6_stealth_model,
1313
claude_opus_4_6_stealth_model,
1414
} from './providers/anthropic.constants';
15-
import { isAlibabaDirectModel, qwen36_plus_model, qwen37_max_model } from './providers/qwen';
15+
import {
16+
isAlibabaDirectModel,
17+
qwen36_plus_model,
18+
qwen37_max_model,
19+
qwen37_plus_model,
20+
} from './providers/qwen';
1621

1722
describe('isFreeModel', () => {
1823
describe('free models', () => {
@@ -79,6 +84,14 @@ describe('isFreeModel', () => {
7984
expect(getInferenceProvider(qwen37_max_model)).toBe('alibaba');
8085
});
8186

87+
test('routes Qwen3.7 Plus directly through Alibaba', () => {
88+
expect(findKiloExclusiveModel(qwen37_plus_model.public_id)).toBe(qwen37_plus_model);
89+
expect(isAlibabaDirectModel(qwen37_plus_model.public_id)).toBe(true);
90+
expect(qwen37_plus_model.gateway).toBe('alibaba');
91+
expect(qwen37_plus_model.internal_id).toBe('qwen3.7-plus');
92+
expect(getInferenceProvider(qwen37_plus_model)).toBe('alibaba');
93+
});
94+
8295
test('requires data collection for paid training-enabled offerings', () => {
8396
expect(
8497
isKiloExclusiveModelRequiringDataCollection(claude_opus_4_7_stealth_model.public_id)

apps/web/src/lib/ai-gateway/processUsage.calculatKiloExclusiveCost.test.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
qwen36_max_preview_model,
1010
qwen36_plus_model,
1111
qwen37_max_model,
12+
qwen37_plus_model,
1213
} from '@/lib/ai-gateway/providers/qwen';
1314

1415
const makeUsage = (overrides: Partial<JustTheCostsUsageStats> = {}): JustTheCostsUsageStats => ({
@@ -41,6 +42,44 @@ describe('calculatKiloExclusiveCost_mUsd with qwen3.7-max', () => {
4142
});
4243
});
4344

45+
describe('calculatKiloExclusiveCost_mUsd with qwen3.7-plus', () => {
46+
test('uses direct Alibaba pricing with the Kilo discount in the <=256k tier', () => {
47+
const result = calculateKiloExclusiveCost_mUsd(
48+
qwen37_plus_model,
49+
makeUsage({ inputTokens: 100_000, outputTokens: 10_000 })
50+
);
51+
52+
expect(result).toBe(Math.round(100_000 * 0.26 + 10_000 * 1.04));
53+
});
54+
55+
test('charges explicit cache reads and writes at discounted rates', () => {
56+
const result = calculateKiloExclusiveCost_mUsd(
57+
qwen37_plus_model,
58+
makeUsage({ inputTokens: 100_000, cacheHitTokens: 20_000, cacheWriteTokens: 30_000 })
59+
);
60+
61+
expect(result).toBe(Math.round(50_000 * 0.26 + 20_000 * 0.026 + 30_000 * 0.325));
62+
});
63+
64+
test('uses direct Alibaba pricing with the Kilo discount in the >256k tier', () => {
65+
const result = calculateKiloExclusiveCost_mUsd(
66+
qwen37_plus_model,
67+
makeUsage({ inputTokens: 300_000, outputTokens: 10_000 })
68+
);
69+
70+
expect(result).toBe(Math.round(300_000 * 0.78 + 10_000 * 3.12));
71+
});
72+
73+
test('moves to the long-context tier above the 256k boundary', () => {
74+
expect(
75+
calculateKiloExclusiveCost_mUsd(qwen37_plus_model, makeUsage({ inputTokens: 262_144 }))
76+
).toBe(Math.round(262_144 * 0.26));
77+
expect(
78+
calculateKiloExclusiveCost_mUsd(qwen37_plus_model, makeUsage({ inputTokens: 262_145 }))
79+
).toBe(Math.round(262_145 * 0.78));
80+
});
81+
});
82+
4483
describe('calculatKiloExclusiveCost_mUsd with qwen3.6-plus', () => {
4584
// Pre-discount prices from Qwen pricing page (35% Kilo discount applied in code):
4685
//

apps/web/src/lib/ai-gateway/providers/qwen.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,41 @@ export const qwen37_max_model: KiloExclusiveModel = {
9696
inference_provider_restriction: [],
9797
};
9898

99+
export const qwen37_plus_model: KiloExclusiveModel = {
100+
public_id: 'qwen/qwen3.7-plus',
101+
display_name: 'Qwen: Qwen3.7 Plus',
102+
description:
103+
"Qwen3.7-Plus is Alibaba's native multimodal agent model for visual-language reasoning, agentic coding, tool use, and productivity workflows. It supports text, image, and video inputs. Note: a surcharge applies to long-context workloads exceeding 256K input tokens.",
104+
context_length: 1_000_000,
105+
max_completion_tokens: 65_536,
106+
status: 'public',
107+
flags: ['reasoning', 'vision'],
108+
gateway: 'alibaba',
109+
internal_id: 'qwen3.7-plus',
110+
pricing: makeTieredPricing([
111+
{
112+
maxInputTokens: TOKENS_256K,
113+
undiscounted: {
114+
prompt_per_million: 0.4,
115+
completion_per_million: 1.6,
116+
input_cache_read_per_million: 0.04,
117+
input_cache_write_per_million: 0.5,
118+
},
119+
},
120+
{
121+
maxInputTokens: TOKENS_1M,
122+
undiscounted: {
123+
prompt_per_million: 1.2,
124+
completion_per_million: 4.8,
125+
input_cache_read_per_million: 0.12,
126+
input_cache_write_per_million: 1.5,
127+
},
128+
},
129+
]),
130+
exclusive_to: [],
131+
inference_provider_restriction: [],
132+
};
133+
99134
export const qwen36_plus_model: KiloExclusiveModel = {
100135
public_id: 'qwen/qwen3.6-plus',
101136
display_name: 'Qwen: Qwen3.6 Plus',
@@ -262,6 +297,7 @@ export const qwen36_27b_model: KiloExclusiveModel = {
262297

263298
export const alibabaDirectModels: ReadonlyArray<KiloExclusiveModel> = [
264299
qwen37_max_model,
300+
qwen37_plus_model,
265301
qwen36_plus_model,
266302
qwen36_flash_model,
267303
qwen36_max_preview_model,

0 commit comments

Comments
 (0)