Skip to content

Commit 1fac0ad

Browse files
committed
feat(amazonq): Fetching models from backend and adding cache implementation. (aws#2075)
* fix: removing and refactoring legacy code before implementing model selection * feat(amazonq): adding cache implementation and fetching models from listAvailableModels api * feat(amazonq): adding selected model in error case * feat(amazonq): adding test cases * fix: addressing comments * fix: fixing test cases and adding modelName to models * fix: minor edits * fix: minor edits * fix: minor modifications in logs * fix: adding default model if api throws any errors * fix: refactoring code
1 parent 4937e54 commit 1fac0ad

File tree

16 files changed

+409
-341
lines changed

16 files changed

+409
-341
lines changed

chat-client/src/client/chat.ts

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,6 @@ import { InboundChatApi, createMynahUi } from './mynahUi'
116116
import { TabFactory } from './tabs/tabFactory'
117117
import { ChatClientAdapter } from '../contracts/chatClientAdapter'
118118
import { toMynahContextCommand, toMynahIcon } from './utils'
119-
import { modelSelectionForRegion } from './texts/modelSelection'
120119

121120
const getDefaultTabConfig = (agenticMode?: boolean) => {
122121
return {
@@ -264,20 +263,6 @@ export const createChat = (
264263
return option
265264
}),
266265
})
267-
} else if (message.params.region) {
268-
// TODO: This can be removed after all clients support aws/chat/listAvailableModels
269-
// get all tabs and update region
270-
const allExistingTabs: MynahUITabStoreModel = mynahUi.getAllTabs()
271-
for (const tabId in allExistingTabs) {
272-
const options = mynahUi.getTabData(tabId).getStore()?.promptInputOptions
273-
mynahUi.updateStore(tabId, {
274-
promptInputOptions: options?.map(option =>
275-
option.id === 'model-selection'
276-
? modelSelectionForRegion[message.params.region]
277-
: option
278-
),
279-
})
280-
}
281266
} else {
282267
tabFactory.setInfoMessages((message.params as ChatOptionsUpdateParams).chatNotifications)
283268
}

chat-client/src/client/tabs/tabFactory.test.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { ChatHistory } from '../features/history'
22
import { TabFactory } from './tabFactory'
33
import * as assert from 'assert'
44
import { pairProgrammingPromptInput } from '../texts/pairProgramming'
5-
import { modelSelectionForRegion } from '../texts/modelSelection'
5+
import { modelSelection } from '../texts/modelSelection'
66

77
describe('tabFactory', () => {
88
describe('getDefaultTabData', () => {
@@ -92,10 +92,7 @@ describe('tabFactory', () => {
9292

9393
const result = tabFactory.createTab(false)
9494

95-
assert.deepStrictEqual(result.promptInputOptions, [
96-
pairProgrammingPromptInput,
97-
modelSelectionForRegion['us-east-1'],
98-
])
95+
assert.deepStrictEqual(result.promptInputOptions, [pairProgrammingPromptInput, modelSelection])
9996
})
10097

10198
it('should not include model selection when only agentic mode is enabled', () => {

chat-client/src/client/tabs/tabFactory.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { disclaimerCard } from '../texts/disclaimer'
1111
import { ChatMessage } from '@aws/language-server-runtimes-types'
1212
import { ChatHistory } from '../features/history'
1313
import { pairProgrammingPromptInput, programmerModeCard } from '../texts/pairProgramming'
14-
import { modelSelectionForRegion } from '../texts/modelSelection'
14+
import { modelSelection } from '../texts/modelSelection'
1515

1616
export type DefaultTabData = MynahUIDataModel
1717

@@ -52,10 +52,7 @@ export class TabFactory {
5252
...this.getDefaultTabData(),
5353
...(disclaimerCardActive ? { promptInputStickyCard: disclaimerCard } : {}),
5454
promptInputOptions: this.agenticMode
55-
? [
56-
pairProgrammingPromptInput,
57-
...(this.modelSelectionEnabled ? [modelSelectionForRegion['us-east-1']] : []),
58-
]
55+
? [pairProgrammingPromptInput, ...(this.modelSelectionEnabled ? [modelSelection] : [])]
5956
: [],
6057
cancelButtonWhenLoading: this.agenticMode, // supported for agentic chat only
6158
}

chat-client/src/client/texts/modelSelection.test.ts

Lines changed: 1 addition & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,11 @@
11
import * as assert from 'assert'
2-
import {
3-
BedrockModel,
4-
modelSelectionForRegion,
5-
getModelSelectionChatItem,
6-
modelUnavailableBanner,
7-
modelThrottledBanner,
8-
} from './modelSelection'
2+
import { getModelSelectionChatItem, modelUnavailableBanner, modelThrottledBanner } from './modelSelection'
93
import { ChatItemType } from '@aws/mynah-ui'
104

115
/**
126
* Tests for modelSelection functionality
13-
*
14-
* Note: Some tests are for deprecated code (marked with 'legacy') that is maintained
15-
* for backward compatibility with older clients. These should be removed once
16-
* all clients have been updated to use the new API (aws/chat/listAvailableModels).
177
*/
188
describe('modelSelection', () => {
19-
describe('BedrockModel enum (legacy)', () => {
20-
it('should have the correct model IDs', () => {
21-
assert.strictEqual(BedrockModel.CLAUDE_3_7_SONNET_20250219_V1_0, 'CLAUDE_3_7_SONNET_20250219_V1_0')
22-
assert.strictEqual(BedrockModel.CLAUDE_SONNET_4_20250514_V1_0, 'CLAUDE_SONNET_4_20250514_V1_0')
23-
})
24-
})
25-
26-
describe('modelSelectionForRegion (legacy)', () => {
27-
it('should provide all models for us-east-1 region', () => {
28-
const usEast1ModelSelection = modelSelectionForRegion['us-east-1']
29-
assert.ok(usEast1ModelSelection, 'usEast1ModelSelection should exist')
30-
assert.ok(usEast1ModelSelection.type === 'select', 'usEast1ModelSelection should be type select')
31-
assert.ok(Array.isArray(usEast1ModelSelection.options), 'options should be an array')
32-
assert.strictEqual(usEast1ModelSelection.options.length, 2, 'should have 2 options')
33-
34-
const modelIds = usEast1ModelSelection.options.map(option => option.value)
35-
assert.ok(modelIds.includes(BedrockModel.CLAUDE_SONNET_4_20250514_V1_0), 'should include Claude Sonnet 4')
36-
assert.ok(
37-
modelIds.includes(BedrockModel.CLAUDE_3_7_SONNET_20250219_V1_0),
38-
'should include Claude Sonnet 3.7'
39-
)
40-
})
41-
42-
it('should provide all models for eu-central-1 region', () => {
43-
const euCentral1ModelSelection = modelSelectionForRegion['eu-central-1']
44-
assert.ok(euCentral1ModelSelection, 'euCentral1ModelSelection should exist')
45-
assert.ok(euCentral1ModelSelection.type === 'select', 'euCentral1ModelSelection should be type select')
46-
assert.ok(Array.isArray(euCentral1ModelSelection.options), 'options should be an array')
47-
assert.strictEqual(euCentral1ModelSelection.options.length, 2, 'should have 2 option')
48-
49-
const modelIds = euCentral1ModelSelection.options.map(option => option.value)
50-
assert.ok(modelIds.includes(BedrockModel.CLAUDE_SONNET_4_20250514_V1_0), 'should include Claude Sonnet 4')
51-
assert.ok(
52-
modelIds.includes(BedrockModel.CLAUDE_3_7_SONNET_20250219_V1_0),
53-
'should include Claude Sonnet 3.7'
54-
)
55-
})
56-
})
57-
589
describe('getModelSelectionChatItem', () => {
5910
it('should return a chat item with the correct model name', () => {
6011
const modelName = 'Claude Sonnet 4'

chat-client/src/client/texts/modelSelection.ts

Lines changed: 1 addition & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,14 @@
11
import { ChatItem, ChatItemFormItem, ChatItemType } from '@aws/mynah-ui'
22

3-
/**
4-
* @deprecated use aws/chat/listAvailableModels server request instead
5-
*/
6-
export enum BedrockModel {
7-
CLAUDE_SONNET_4_20250514_V1_0 = 'CLAUDE_SONNET_4_20250514_V1_0',
8-
CLAUDE_3_7_SONNET_20250219_V1_0 = 'CLAUDE_3_7_SONNET_20250219_V1_0',
9-
}
10-
11-
type ModelDetails = {
12-
label: string
13-
}
14-
15-
const modelRecord: Record<BedrockModel, ModelDetails> = {
16-
[BedrockModel.CLAUDE_3_7_SONNET_20250219_V1_0]: { label: 'Claude Sonnet 3.7' },
17-
[BedrockModel.CLAUDE_SONNET_4_20250514_V1_0]: { label: 'Claude Sonnet 4' },
18-
}
19-
20-
const modelOptions = Object.entries(modelRecord).map(([value, { label }]) => ({
21-
value,
22-
label,
23-
}))
24-
25-
const modelSelection: ChatItemFormItem = {
3+
export const modelSelection: ChatItemFormItem = {
264
type: 'select',
275
id: 'model-selection',
28-
options: modelOptions,
296
mandatory: true,
307
hideMandatoryIcon: true,
318
border: false,
329
autoWidth: true,
3310
}
3411

35-
/**
36-
* @deprecated use aws/chat/listAvailableModels server request instead
37-
*/
38-
export const modelSelectionForRegion: Record<string, ChatItemFormItem> = {
39-
'us-east-1': modelSelection,
40-
'eu-central-1': modelSelection,
41-
}
42-
4312
export const getModelSelectionChatItem = (modelName: string): ChatItem => ({
4413
type: ChatItemType.DIRECTIVE,
4514
contentHorizontalAlignment: 'center',

server/aws-lsp-codewhisperer/src/client/sigv4/codewhisperersigv4client.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* THIS FILE IS AUTOGENERATED BY 'generateServiceClient.ts'.
44
* DO NOT EDIT BY HAND.
55
*/
6-
6+
77
import {Request} from 'aws-sdk/lib/request';
88
import {Response} from 'aws-sdk/lib/response';
99
import {AWSError} from 'aws-sdk/lib/error';

server/aws-lsp-codewhisperer/src/client/token/bearer-token-service.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3959,6 +3959,10 @@
39593959
"shape": "ModelId",
39603960
"documentation": "<p>Unique identifier for the model</p>"
39613961
},
3962+
"modelName": {
3963+
"shape": "ModelName",
3964+
"documentation": "<p>User-facing display name</p>"
3965+
},
39623966
"description": {
39633967
"shape": "Description",
39643968
"documentation": "<p>Description of the model</p>"
@@ -3976,6 +3980,13 @@
39763980
"min": 1,
39773981
"pattern": "[a-zA-Z0-9_:.-]+"
39783982
},
3983+
"ModelName": {
3984+
"type": "string",
3985+
"documentation": "<p>Identifier for the model Name</p>",
3986+
"max": 1024,
3987+
"min": 1,
3988+
"pattern": "[a-zA-Z0-9-_.]+"
3989+
},
39793990
"ModelMetadata": {
39803991
"type": "structure",
39813992
"members": {

server/aws-lsp-codewhisperer/src/client/token/codewhispererbearertokenclient.d.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1245,6 +1245,10 @@ declare namespace CodeWhispererBearerTokenClient {
12451245
* Unique identifier for the model
12461246
*/
12471247
modelId: ModelId;
1248+
/**
1249+
* User-facing display name
1250+
*/
1251+
modelName?: ModelName;
12481252
/**
12491253
* Description of the model
12501254
*/
@@ -1255,6 +1259,7 @@ declare namespace CodeWhispererBearerTokenClient {
12551259
modelMetadata?: ModelMetadata;
12561260
}
12571261
export type ModelId = string;
1262+
export type ModelName = string;
12581263
export interface ModelMetadata {
12591264
/**
12601265
* Maximum number of input tokens the model can process

0 commit comments

Comments
 (0)