Skip to content

Commit 0fc07b9

Browse files
committed
refactor: Organize Bedrock provider into subdirectory structure
Move all Bedrock-specific provider files into provider/bedrock subdirectory with a barrel export file for better code organization and modularity. - Create provider/bedrock directory structure - Move bedrock.ts → bedrock/provider.ts - Move bedrockTypes.ts → bedrock/types.ts - Move bedrockConverter.ts → bedrock/converter.ts - Move test files to bedrock/ subdirectory - Add barrel file (index.ts) for clean exports - Update all import paths throughout codebase - Apply Prettier formatting to documentation and tests All 2728 tests passing (2703 core + 25 VSCode) ESLint passing with 0 warnings
1 parent 6641e7c commit 0fc07b9

File tree

11 files changed

+1834
-1456
lines changed

11 files changed

+1834
-1456
lines changed

docs/cli/bedrock.md

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,12 @@ Qwen Code now supports using Qwen3-Coder models via Amazon Bedrock, allowing you
1313
Amazon Bedrock provides access to Qwen models. Model availability varies by region:
1414

1515
### us-east-1
16+
1617
- `qwen.qwen3-coder-30b-a3b-v1:0` - Qwen3-Coder-30B-A3B-Instruct (code generation)
1718
- `qwen.qwen3-32b-v1:0` - Qwen3 32B dense (general purpose)
1819

1920
### us-west-2
21+
2022
- `qwen.qwen3-coder-480b-a35b-v1:0` - Qwen3 Coder 480B A35B Instruct (code generation)
2123
- `qwen.qwen3-235b-a22b-2507-v1:0` - Qwen3 235B A22B 2507 (general purpose)
2224
- `qwen.qwen3-coder-30b-a3b-v1:0` - Qwen3-Coder-30B-A3B-Instruct (code generation)
@@ -81,12 +83,12 @@ export BEDROCK_MODEL=qwen.qwen3-32b-v1:0
8183

8284
### Environment Variables
8385

84-
| Variable | Description | Default |
85-
| ----------------------- | ------------------------------------ | ----------------------------------- |
86-
| `AWS_REGION` | AWS region for Bedrock | `us-east-1` |
87-
| `AWS_PROFILE` | Named AWS profile to use | None |
88-
| `AWS_ACCESS_KEY_ID` | AWS access key | None |
89-
| `AWS_SECRET_ACCESS_KEY` | AWS secret key | None |
90-
| `BEDROCK_MODEL` | Full Bedrock model ID | `qwen.qwen3-coder-30b-a3b-v1:0` |
86+
| Variable | Description | Default |
87+
| ----------------------- | ------------------------ | ------------------------------- |
88+
| `AWS_REGION` | AWS region for Bedrock | `us-east-1` |
89+
| `AWS_PROFILE` | Named AWS profile to use | None |
90+
| `AWS_ACCESS_KEY_ID` | AWS access key | None |
91+
| `AWS_SECRET_ACCESS_KEY` | AWS secret key | None |
92+
| `BEDROCK_MODEL` | Full Bedrock model ID | `qwen.qwen3-coder-30b-a3b-v1:0` |
9193

9294
**Note**: You must use the exact Bedrock model ID (e.g., `qwen.qwen3-coder-30b-a3b-v1:0`). Model name shortcuts are not supported.

package-lock.json

Lines changed: 1682 additions & 1376 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/core/src/core/openaiContentGenerator/provider/bedrockConverter.test.ts renamed to packages/core/src/core/openaiContentGenerator/provider/bedrock/converter.test.ts

Lines changed: 102 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,8 @@ import {
1010
convertOpenAIToBedrock,
1111
convertBedrockToOpenAI,
1212
convertBedrockStreamToOpenAI,
13-
} from './bedrockConverter.js';
14-
import type {
15-
BedrockConverseResponse,
16-
BedrockStreamEvent,
17-
} from './bedrockTypes.js';
13+
} from './converter.js';
14+
import type { BedrockConverseResponse, BedrockStreamEvent } from './types.js';
1815

1916
describe('bedrockConverter', () => {
2017
describe('convertOpenAIToBedrock', () => {
@@ -24,7 +21,10 @@ describe('bedrockConverter', () => {
2421
messages: [{ role: 'user', content: 'Hello, world!' }],
2522
};
2623

27-
const result = convertOpenAIToBedrock(openaiRequest, 'qwen.qwen3-coder-30b-a3b-v1:0');
24+
const result = convertOpenAIToBedrock(
25+
openaiRequest,
26+
'qwen.qwen3-coder-30b-a3b-v1:0',
27+
);
2828

2929
expect(result.modelId).toBe('qwen.qwen3-coder-30b-a3b-v1:0');
3030
expect(result.messages).toHaveLength(1);
@@ -42,7 +42,10 @@ describe('bedrockConverter', () => {
4242
],
4343
};
4444

45-
const result = convertOpenAIToBedrock(openaiRequest, 'qwen.qwen3-coder-30b-a3b-v1:0');
45+
const result = convertOpenAIToBedrock(
46+
openaiRequest,
47+
'qwen.qwen3-coder-30b-a3b-v1:0',
48+
);
4649

4750
expect(result.system).toBeDefined();
4851
expect(result.system).toHaveLength(1);
@@ -60,7 +63,10 @@ describe('bedrockConverter', () => {
6063
top_p: 0.9,
6164
};
6265

63-
const result = convertOpenAIToBedrock(openaiRequest, 'qwen.qwen3-coder-30b-a3b-v1:0');
66+
const result = convertOpenAIToBedrock(
67+
openaiRequest,
68+
'qwen.qwen3-coder-30b-a3b-v1:0',
69+
);
6470

6571
expect(result.inferenceConfig).toBeDefined();
6672
expect(result.inferenceConfig!.temperature).toBe(0.7);
@@ -77,7 +83,10 @@ describe('bedrockConverter', () => {
7783
top_p: 0,
7884
};
7985

80-
const result = convertOpenAIToBedrock(openaiRequest, 'qwen.qwen3-coder-30b-a3b-v1:0');
86+
const result = convertOpenAIToBedrock(
87+
openaiRequest,
88+
'qwen.qwen3-coder-30b-a3b-v1:0',
89+
);
8190

8291
expect(result.inferenceConfig).toBeDefined();
8392
expect(result.inferenceConfig!.temperature).toBeUndefined();
@@ -92,7 +101,10 @@ describe('bedrockConverter', () => {
92101
stop: ['END', 'STOP'],
93102
};
94103

95-
const result = convertOpenAIToBedrock(openaiRequest, 'qwen.qwen3-coder-30b-a3b-v1:0');
104+
const result = convertOpenAIToBedrock(
105+
openaiRequest,
106+
'qwen.qwen3-coder-30b-a3b-v1:0',
107+
);
96108

97109
expect(result.inferenceConfig!.stopSequences).toEqual(['END', 'STOP']);
98110
});
@@ -104,7 +116,10 @@ describe('bedrockConverter', () => {
104116
stop: 'END',
105117
};
106118

107-
const result = convertOpenAIToBedrock(openaiRequest, 'qwen.qwen3-coder-30b-a3b-v1:0');
119+
const result = convertOpenAIToBedrock(
120+
openaiRequest,
121+
'qwen.qwen3-coder-30b-a3b-v1:0',
122+
);
108123

109124
expect(result.inferenceConfig!.stopSequences).toEqual(['END']);
110125
});
@@ -116,7 +131,10 @@ describe('bedrockConverter', () => {
116131
stop: ['END', null as never, 'STOP'],
117132
};
118133

119-
const result = convertOpenAIToBedrock(openaiRequest, 'qwen.qwen3-coder-30b-a3b-v1:0');
134+
const result = convertOpenAIToBedrock(
135+
openaiRequest,
136+
'qwen.qwen3-coder-30b-a3b-v1:0',
137+
);
120138

121139
expect(result.inferenceConfig!.stopSequences).toEqual(['END', 'STOP']);
122140
});
@@ -142,7 +160,10 @@ describe('bedrockConverter', () => {
142160
],
143161
};
144162

145-
const result = convertOpenAIToBedrock(openaiRequest, 'qwen.qwen3-coder-30b-a3b-v1:0');
163+
const result = convertOpenAIToBedrock(
164+
openaiRequest,
165+
'qwen.qwen3-coder-30b-a3b-v1:0',
166+
);
146167

147168
expect(result.toolConfig).toBeDefined();
148169
expect(result.toolConfig!.tools).toHaveLength(1);
@@ -165,7 +186,10 @@ describe('bedrockConverter', () => {
165186
tool_choice: 'auto',
166187
};
167188

168-
const result = convertOpenAIToBedrock(openaiRequest, 'qwen.qwen3-coder-30b-a3b-v1:0');
189+
const result = convertOpenAIToBedrock(
190+
openaiRequest,
191+
'qwen.qwen3-coder-30b-a3b-v1:0',
192+
);
169193

170194
expect(result.toolConfig!.toolChoice).toEqual({ auto: {} });
171195
});
@@ -183,7 +207,10 @@ describe('bedrockConverter', () => {
183207
tool_choice: 'required',
184208
};
185209

186-
const result = convertOpenAIToBedrock(openaiRequest, 'qwen.qwen3-coder-30b-a3b-v1:0');
210+
const result = convertOpenAIToBedrock(
211+
openaiRequest,
212+
'qwen.qwen3-coder-30b-a3b-v1:0',
213+
);
187214

188215
expect(result.toolConfig!.toolChoice).toEqual({ any: {} });
189216
});
@@ -201,7 +228,10 @@ describe('bedrockConverter', () => {
201228
tool_choice: { type: 'function', function: { name: 'test_tool' } },
202229
};
203230

204-
const result = convertOpenAIToBedrock(openaiRequest, 'qwen.qwen3-coder-30b-a3b-v1:0');
231+
const result = convertOpenAIToBedrock(
232+
openaiRequest,
233+
'qwen.qwen3-coder-30b-a3b-v1:0',
234+
);
205235

206236
expect(result.toolConfig!.toolChoice).toEqual({
207237
tool: { name: 'test_tool' },
@@ -219,7 +249,10 @@ describe('bedrockConverter', () => {
219249
],
220250
};
221251

222-
const result = convertOpenAIToBedrock(openaiRequest, 'qwen.qwen3-coder-30b-a3b-v1:0');
252+
const result = convertOpenAIToBedrock(
253+
openaiRequest,
254+
'qwen.qwen3-coder-30b-a3b-v1:0',
255+
);
223256

224257
expect(result.system).toHaveLength(1);
225258
expect(result.messages).toHaveLength(3);
@@ -250,7 +283,10 @@ describe('bedrockConverter', () => {
250283
],
251284
};
252285

253-
const result = convertOpenAIToBedrock(openaiRequest, 'qwen.qwen3-coder-30b-a3b-v1:0');
286+
const result = convertOpenAIToBedrock(
287+
openaiRequest,
288+
'qwen.qwen3-coder-30b-a3b-v1:0',
289+
);
254290

255291
expect(result.messages).toHaveLength(2);
256292
expect(result.messages[1].role).toBe('assistant');
@@ -289,7 +325,10 @@ describe('bedrockConverter', () => {
289325
],
290326
};
291327

292-
const result = convertOpenAIToBedrock(openaiRequest, 'qwen.qwen3-coder-30b-a3b-v1:0');
328+
const result = convertOpenAIToBedrock(
329+
openaiRequest,
330+
'qwen.qwen3-coder-30b-a3b-v1:0',
331+
);
293332

294333
expect(result.messages).toHaveLength(3);
295334
expect(result.messages[2].role).toBe('user');
@@ -318,7 +357,10 @@ describe('bedrockConverter', () => {
318357
],
319358
};
320359

321-
const result = convertOpenAIToBedrock(openaiRequest, 'qwen.qwen3-coder-30b-a3b-v1:0');
360+
const result = convertOpenAIToBedrock(
361+
openaiRequest,
362+
'qwen.qwen3-coder-30b-a3b-v1:0',
363+
);
322364

323365
expect(result.messages[0].content).toHaveLength(2);
324366
expect(result.messages[0].content[0]).toEqual({ text: 'Hello' });
@@ -335,7 +377,10 @@ describe('bedrockConverter', () => {
335377
],
336378
};
337379

338-
const result = convertOpenAIToBedrock(openaiRequest, 'qwen.qwen3-coder-30b-a3b-v1:0');
380+
const result = convertOpenAIToBedrock(
381+
openaiRequest,
382+
'qwen.qwen3-coder-30b-a3b-v1:0',
383+
);
339384

340385
expect(result.system).toHaveLength(2);
341386
expect(result.system![0].text).toBe('You are helpful');
@@ -348,7 +393,10 @@ describe('bedrockConverter', () => {
348393
messages: [],
349394
};
350395

351-
const result = convertOpenAIToBedrock(openaiRequest, 'qwen.qwen3-coder-30b-a3b-v1:0');
396+
const result = convertOpenAIToBedrock(
397+
openaiRequest,
398+
'qwen.qwen3-coder-30b-a3b-v1:0',
399+
);
352400

353401
expect(result.messages).toEqual([]);
354402
expect(result.system).toBeUndefined();
@@ -372,7 +420,10 @@ describe('bedrockConverter', () => {
372420
],
373421
};
374422

375-
const result = convertOpenAIToBedrock(openaiRequest, 'qwen.qwen3-coder-30b-a3b-v1:0');
423+
const result = convertOpenAIToBedrock(
424+
openaiRequest,
425+
'qwen.qwen3-coder-30b-a3b-v1:0',
426+
);
376427

377428
expect(result.messages[0].content).toHaveLength(2);
378429
expect(result.messages[0].content[0]).toEqual({
@@ -399,7 +450,10 @@ describe('bedrockConverter', () => {
399450
},
400451
};
401452

402-
const result = convertBedrockToOpenAI(bedrockResponse, 'qwen.qwen3-coder-30b-a3b-v1:0');
453+
const result = convertBedrockToOpenAI(
454+
bedrockResponse,
455+
'qwen.qwen3-coder-30b-a3b-v1:0',
456+
);
403457

404458
expect(result.choices).toHaveLength(1);
405459
expect(result.choices[0].message.role).toBe('assistant');
@@ -436,7 +490,10 @@ describe('bedrockConverter', () => {
436490
},
437491
};
438492

439-
const result = convertBedrockToOpenAI(bedrockResponse, 'qwen.qwen3-coder-30b-a3b-v1:0');
493+
const result = convertBedrockToOpenAI(
494+
bedrockResponse,
495+
'qwen.qwen3-coder-30b-a3b-v1:0',
496+
);
440497

441498
expect(result.choices[0].message.tool_calls).toBeDefined();
442499
expect(result.choices[0].message.tool_calls).toHaveLength(1);
@@ -459,7 +516,10 @@ describe('bedrockConverter', () => {
459516
usage: { inputTokens: 5, outputTokens: 5, totalTokens: 10 },
460517
};
461518

462-
const result = convertBedrockToOpenAI(bedrockResponse, 'qwen.qwen3-coder-30b-a3b-v1:0');
519+
const result = convertBedrockToOpenAI(
520+
bedrockResponse,
521+
'qwen.qwen3-coder-30b-a3b-v1:0',
522+
);
463523

464524
expect(result.choices[0].message.content).toBe('Hello world!');
465525
});
@@ -485,7 +545,10 @@ describe('bedrockConverter', () => {
485545
usage: { inputTokens: 10, outputTokens: 15, totalTokens: 25 },
486546
};
487547

488-
const result = convertBedrockToOpenAI(bedrockResponse, 'qwen.qwen3-coder-30b-a3b-v1:0');
548+
const result = convertBedrockToOpenAI(
549+
bedrockResponse,
550+
'qwen.qwen3-coder-30b-a3b-v1:0',
551+
);
489552

490553
expect(result.choices[0].message.content).toBe('Let me check that.');
491554
expect(result.choices[0].message.tool_calls).toHaveLength(1);
@@ -500,7 +563,10 @@ describe('bedrockConverter', () => {
500563
usage: { inputTokens: 10, outputTokens: 1000, totalTokens: 1010 },
501564
};
502565

503-
const result = convertBedrockToOpenAI(bedrockResponse, 'qwen.qwen3-coder-30b-a3b-v1:0');
566+
const result = convertBedrockToOpenAI(
567+
bedrockResponse,
568+
'qwen.qwen3-coder-30b-a3b-v1:0',
569+
);
504570

505571
expect(result.choices[0].finish_reason).toBe('length');
506572
});
@@ -514,7 +580,10 @@ describe('bedrockConverter', () => {
514580
usage: { inputTokens: 10, outputTokens: 5, totalTokens: 15 },
515581
};
516582

517-
const result = convertBedrockToOpenAI(bedrockResponse, 'qwen.qwen3-coder-30b-a3b-v1:0');
583+
const result = convertBedrockToOpenAI(
584+
bedrockResponse,
585+
'qwen.qwen3-coder-30b-a3b-v1:0',
586+
);
518587

519588
expect(result.choices[0].finish_reason).toBe('content_filter');
520589
});
@@ -528,7 +597,10 @@ describe('bedrockConverter', () => {
528597
usage: { inputTokens: 10, outputTokens: 5, totalTokens: 15 },
529598
};
530599

531-
const result = convertBedrockToOpenAI(bedrockResponse, 'qwen.qwen3-coder-30b-a3b-v1:0');
600+
const result = convertBedrockToOpenAI(
601+
bedrockResponse,
602+
'qwen.qwen3-coder-30b-a3b-v1:0',
603+
);
532604

533605
expect(result.choices[0].finish_reason).toBe('stop');
534606
});

packages/core/src/core/openaiContentGenerator/provider/bedrockConverter.ts renamed to packages/core/src/core/openaiContentGenerator/provider/bedrock/converter.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import type {
1919
BedrockToolConfig,
2020
BedrockTool,
2121
BedrockSystemContent,
22-
} from './bedrockTypes.js';
22+
} from './types.js';
2323

2424
/**
2525
* Convert OpenAI chat completion request to Bedrock Converse format
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/**
2+
* @license
3+
* Copyright 2025 Qwen
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
// Re-export the main provider class
8+
export { BedrockOpenAICompatibleProvider } from './provider.js';
9+
10+
// Re-export types for external use
11+
export type {
12+
BedrockConverseRequest,
13+
BedrockConverseResponse,
14+
BedrockMessage,
15+
BedrockContentBlock,
16+
BedrockStreamEvent,
17+
} from './types.js';
18+
19+
// Re-export converter functions for testing/advanced use
20+
export {
21+
convertOpenAIToBedrock,
22+
convertBedrockToOpenAI,
23+
convertBedrockStreamToOpenAI,
24+
} from './converter.js';

packages/core/src/core/openaiContentGenerator/provider/bedrock.test.ts renamed to packages/core/src/core/openaiContentGenerator/provider/bedrock/provider.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ import {
1212
vi,
1313
type MockedFunction,
1414
} from 'vitest';
15-
import type { ContentGeneratorConfig } from '../../contentGenerator.js';
16-
import { AuthType } from '../../contentGenerator.js';
17-
import { BedrockOpenAICompatibleProvider } from './bedrock.js';
18-
import type { Config } from '../../../config/config.js';
15+
import type { ContentGeneratorConfig } from '../../../contentGenerator.js';
16+
import { AuthType } from '../../../contentGenerator.js';
17+
import { BedrockOpenAICompatibleProvider } from './provider.js';
18+
import type { Config } from '../../../../config/config.js';
1919

2020
describe('BedrockOpenAICompatibleProvider', () => {
2121
let mockConfig: Config;

0 commit comments

Comments
 (0)