@aws/lsp-codewhisperer 0.0.75 → 0.0.77

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/CHANGELOG.md +55 -0
  2. package/out/client/token/bearer-token-service.json +28 -0
  3. package/out/language-server/agenticChat/agenticChatController.d.ts +13 -2
  4. package/out/language-server/agenticChat/agenticChatController.js +174 -40
  5. package/out/language-server/agenticChat/agenticChatController.js.map +1 -1
  6. package/out/language-server/agenticChat/constants/modelSelection.d.ts +10 -2
  7. package/out/language-server/agenticChat/constants/modelSelection.js +11 -8
  8. package/out/language-server/agenticChat/constants/modelSelection.js.map +1 -1
  9. package/out/language-server/agenticChat/errors.d.ts +1 -1
  10. package/out/language-server/agenticChat/errors.js.map +1 -1
  11. package/out/language-server/agenticChat/tools/chatDb/chatDb.d.ts +10 -1
  12. package/out/language-server/agenticChat/tools/chatDb/chatDb.js +44 -0
  13. package/out/language-server/agenticChat/tools/chatDb/chatDb.js.map +1 -1
  14. package/out/language-server/agenticChat/tools/chatDb/util.d.ts +5 -1
  15. package/out/language-server/agenticChat/tools/chatDb/util.js +7 -0
  16. package/out/language-server/agenticChat/tools/chatDb/util.js.map +1 -1
  17. package/out/language-server/agenticChat/tools/mcp/mcpEventHandler.d.ts +1 -0
  18. package/out/language-server/agenticChat/tools/mcp/mcpEventHandler.js +50 -30
  19. package/out/language-server/agenticChat/tools/mcp/mcpEventHandler.js.map +1 -1
  20. package/out/language-server/agenticChat/tools/mcp/mcpManager.d.ts +4 -0
  21. package/out/language-server/agenticChat/tools/mcp/mcpManager.js +98 -52
  22. package/out/language-server/agenticChat/tools/mcp/mcpManager.js.map +1 -1
  23. package/out/language-server/agenticChat/tools/mcp/mcpOauthClient.d.ts +53 -0
  24. package/out/language-server/agenticChat/tools/mcp/mcpOauthClient.js +422 -0
  25. package/out/language-server/agenticChat/tools/mcp/mcpOauthClient.js.map +1 -0
  26. package/out/language-server/agenticChat/tools/mcp/mcpUtils.d.ts +4 -0
  27. package/out/language-server/agenticChat/tools/mcp/mcpUtils.js +89 -69
  28. package/out/language-server/agenticChat/tools/mcp/mcpUtils.js.map +1 -1
  29. package/out/language-server/agenticChat/tools/qCodeAnalysis/codeReview.js +15 -1
  30. package/out/language-server/agenticChat/tools/qCodeAnalysis/codeReview.js.map +1 -1
  31. package/out/language-server/agenticChat/tools/qCodeAnalysis/codeReviewSchemas.d.ts +4 -4
  32. package/out/language-server/agenticChat/tools/qCodeAnalysis/codeReviewTypes.d.ts +2 -1
  33. package/out/language-server/agenticChat/tools/qCodeAnalysis/codeReviewTypes.js +1 -0
  34. package/out/language-server/agenticChat/tools/qCodeAnalysis/codeReviewTypes.js.map +1 -1
  35. package/out/language-server/agenticChat/tools/qCodeAnalysis/displayFindingsSchemas.d.ts +16 -16
  36. package/out/language-server/agenticChat/utils/fileModificationMetrics.d.ts +8 -0
  37. package/out/language-server/agenticChat/utils/fileModificationMetrics.js +54 -0
  38. package/out/language-server/agenticChat/utils/fileModificationMetrics.js.map +1 -0
  39. package/out/language-server/chat/chatSessionService.d.ts +1 -0
  40. package/out/language-server/chat/chatSessionService.js +5 -0
  41. package/out/language-server/chat/chatSessionService.js.map +1 -1
  42. package/out/language-server/chat/telemetry/chatTelemetryController.d.ts +2 -2
  43. package/out/language-server/chat/telemetry/chatTelemetryController.js +4 -2
  44. package/out/language-server/chat/telemetry/chatTelemetryController.js.map +1 -1
  45. package/out/language-server/inline-completion/auto-trigger/autoTrigger.d.ts +1 -1
  46. package/out/language-server/inline-completion/auto-trigger/autoTrigger.js +16 -10
  47. package/out/language-server/inline-completion/auto-trigger/autoTrigger.js.map +1 -1
  48. package/out/language-server/inline-completion/codeWhispererServer.js +10 -7
  49. package/out/language-server/inline-completion/codeWhispererServer.js.map +1 -1
  50. package/out/language-server/inline-completion/editCompletionHandler.d.ts +2 -0
  51. package/out/language-server/inline-completion/editCompletionHandler.js +18 -3
  52. package/out/language-server/inline-completion/editCompletionHandler.js.map +1 -1
  53. package/out/language-server/inline-completion/session/sessionManager.d.ts +3 -2
  54. package/out/language-server/inline-completion/session/sessionManager.js +7 -13
  55. package/out/language-server/inline-completion/session/sessionManager.js.map +1 -1
  56. package/out/language-server/inline-completion/tracker/streakTracker.d.ts +21 -0
  57. package/out/language-server/inline-completion/tracker/streakTracker.js +43 -0
  58. package/out/language-server/inline-completion/tracker/streakTracker.js.map +1 -0
  59. package/out/shared/amazonQServiceManager/AmazonQTokenServiceManager.js +3 -0
  60. package/out/shared/amazonQServiceManager/AmazonQTokenServiceManager.js.map +1 -1
  61. package/out/shared/codeWhispererService.d.ts +4 -0
  62. package/out/shared/codeWhispererService.js +8 -0
  63. package/out/shared/codeWhispererService.js.map +1 -1
  64. package/out/shared/constants.d.ts +1 -0
  65. package/out/shared/constants.js +2 -1
  66. package/out/shared/constants.js.map +1 -1
  67. package/out/shared/supplementalContextUtil/crossFileContextUtil.js +2 -3
  68. package/out/shared/supplementalContextUtil/crossFileContextUtil.js.map +1 -1
  69. package/out/shared/supplementalContextUtil/supplementalContextUtil.js +16 -1
  70. package/out/shared/supplementalContextUtil/supplementalContextUtil.js.map +1 -1
  71. package/out/shared/telemetry/telemetryService.d.ts +1 -0
  72. package/out/shared/telemetry/telemetryService.js +7 -1
  73. package/out/shared/telemetry/telemetryService.js.map +1 -1
  74. package/out/shared/telemetry/types.d.ts +2 -1
  75. package/out/shared/telemetry/types.js +1 -0
  76. package/out/shared/telemetry/types.js.map +1 -1
  77. package/out/shared/telemetryUtils.js +2 -0
  78. package/out/shared/telemetryUtils.js.map +1 -1
  79. package/package.json +2 -2
  80. package/out/language-server/agenticChat/utils/agenticChatControllerHelper.d.ts +0 -8
  81. package/out/language-server/agenticChat/utils/agenticChatControllerHelper.js +0 -15
  82. package/out/language-server/agenticChat/utils/agenticChatControllerHelper.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,60 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.0.77](https://github.com/aws/language-servers/compare/lsp-codewhisperer/v0.0.76...lsp-codewhisperer/v0.0.77) (2025-09-02)
4
+
5
+
6
+ ### Features
7
+
8
+ * passing suggestionTypes and pluginVersion/lspVersion to STE ([#2180](https://github.com/aws/language-servers/issues/2180)) ([66742ad](https://github.com/aws/language-servers/commit/66742adfc44f33efbd8dd33b803000e08241e5ce))
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * auto trigger should only respect previous decisions in the past 2mins ([#2189](https://github.com/aws/language-servers/issues/2189)) ([852b21b](https://github.com/aws/language-servers/commit/852b21b66f793102c52e35c2baec07a772e5134a))
14
+ * compact UI is not updated correctly when multiple nudges are displayed ([#2192](https://github.com/aws/language-servers/issues/2192)) ([ef7d793](https://github.com/aws/language-servers/commit/ef7d7931954f5083e4a5c358e67c6dc652fa1a40))
15
+ * emit acceptedLineCount metric and AgenticCodeAccepted interaction type ([#2167](https://github.com/aws/language-servers/issues/2167)) ([c53f672](https://github.com/aws/language-servers/commit/c53f672b6173ebda530917ccb4e0c2f26f5c8f79))
16
+ * emit errorMessage in addMessage ([#2197](https://github.com/aws/language-servers/issues/2197)) ([58f2064](https://github.com/aws/language-servers/commit/58f20649d345f159080006120e23cde559826df1))
17
+ * fix calculation for num-lines contributed by the LLM ([#2191](https://github.com/aws/language-servers/issues/2191)) ([fd71e6c](https://github.com/aws/language-servers/commit/fd71e6cf3fc843242936564061061418edf83f56))
18
+ * should send classifier score after taking sigmoid ([#2188](https://github.com/aws/language-servers/issues/2188)) ([f4e2e6e](https://github.com/aws/language-servers/commit/f4e2e6e885e665834a5d7b7cbb5f4ba4ff9bbb65))
19
+
20
+
21
+ ### Performance Improvements
22
+
23
+ * only process edit requests 1 at a time ([#2187](https://github.com/aws/language-servers/issues/2187)) ([b497540](https://github.com/aws/language-servers/commit/b4975409a3ed518550290b72ac310895a293be4b))
24
+
25
+
26
+ ### Reverts
27
+
28
+ * PR 2172 dedupe openTabs supplemental contexts ([#2194](https://github.com/aws/language-servers/issues/2194)) ([94723d4](https://github.com/aws/language-servers/commit/94723d46073a1ea8211e7ae8f9dfce3fcb809604))
29
+
30
+ ## [0.0.76](https://github.com/aws/language-servers/compare/lsp-codewhisperer/v0.0.75...lsp-codewhisperer/v0.0.76) (2025-08-27)
31
+
32
+
33
+ ### Features
34
+
35
+ * add basic OAuth client for remote MCP ([#2136](https://github.com/aws/language-servers/issues/2136)) ([2fb896e](https://github.com/aws/language-servers/commit/2fb896e094de0bc5a1b4881067e7dcceb3826015))
36
+ * **amazonq:** emit metric for each issue ([#2179](https://github.com/aws/language-servers/issues/2179)) ([5a3f481](https://github.com/aws/language-servers/commit/5a3f481ebe8c6033e3833abcd81799d26c2aa03e))
37
+ * Auto fetch models from listAvailableModels API ([#2171](https://github.com/aws/language-servers/issues/2171)) ([8600c52](https://github.com/aws/language-servers/commit/8600c524877abb459e9338399352446c0dcff6f0))
38
+ * disable pkce flow during plugin load ([#2153](https://github.com/aws/language-servers/issues/2153)) ([71b3595](https://github.com/aws/language-servers/commit/71b35952333e7581921644ce40fabbc1e6d3c02f))
39
+ * update MCP manager and utilities ([#2158](https://github.com/aws/language-servers/issues/2158)) ([b99df82](https://github.com/aws/language-servers/commit/b99df82826d0ba1a1d52df578cb80674c90505b9))
40
+
41
+
42
+ ### Bug Fixes
43
+
44
+ * adding streakTracker to track streakLength across Completions and Edits ([#2147](https://github.com/aws/language-servers/issues/2147)) ([a6c64f2](https://github.com/aws/language-servers/commit/a6c64f2995a17697e3d71d30a1f411f5cf0db279))
45
+ * **amazonq:** dedupe openTabs supplemental contexts ([#2172](https://github.com/aws/language-servers/issues/2172)) ([aa87ae2](https://github.com/aws/language-servers/commit/aa87ae2bd95edc1f38bf90f56093c5bf5ff18c53))
46
+ * **amazonq:** fix for mcp servers operations to edit server config only ([#2165](https://github.com/aws/language-servers/issues/2165)) ([d28df09](https://github.com/aws/language-servers/commit/d28df09ae41871430cd53064eac1f3050c95ea84))
47
+ * **amazonq:** fix to add mcp server tool error handling and status for card ([#2176](https://github.com/aws/language-servers/issues/2176)) ([23f5ec3](https://github.com/aws/language-servers/commit/23f5ec343cb4e0de32926204dbcf99e51af829f9))
48
+ * **amazonq:** status message update for mcp tool permission accpetance ([#2178](https://github.com/aws/language-servers/issues/2178)) ([4893344](https://github.com/aws/language-servers/commit/489334466fa084774d6e4737569468d654dc6359))
49
+ * fix pkce windows url path ([#2173](https://github.com/aws/language-servers/issues/2173)) ([d7b184c](https://github.com/aws/language-servers/commit/d7b184cb12979877722fa0293e9aebec91ff2c18))
50
+ * multiple fixes on auth flow edge cases ([#2155](https://github.com/aws/language-servers/issues/2155)) ([472220a](https://github.com/aws/language-servers/commit/472220a745cff4fe91a2cabae4ae059a164ceddd))
51
+ * reduce auto trigger frequency for VSC ([#2168](https://github.com/aws/language-servers/issues/2168)) ([00e11ff](https://github.com/aws/language-servers/commit/00e11ff48eafaa0baec48177fa4aa6d60048af2f))
52
+
53
+
54
+ ### Reverts
55
+
56
+ * reduce auto trigger frequency for VSC ([#2168](https://github.com/aws/language-servers/issues/2168))" ([#2177](https://github.com/aws/language-servers/issues/2177)) ([08720c6](https://github.com/aws/language-servers/commit/08720c6c3fa83f9b3b6775d4ae4d848ce145b94b))
57
+
3
58
  ## [0.0.75](https://github.com/aws/language-servers/compare/lsp-codewhisperer/v0.0.74...lsp-codewhisperer/v0.0.75) (2025-08-21)
4
59
 
5
60
 
@@ -1890,6 +1890,10 @@
1890
1890
  "type": "string",
1891
1891
  "enum": ["BLOCK", "LINE"]
1892
1892
  },
1893
+ "SuggestionType": {
1894
+ "type": "string",
1895
+ "enum": ["COMPLETIONS", "EDITS"]
1896
+ },
1893
1897
  "Completions": {
1894
1898
  "type": "list",
1895
1899
  "member": {
@@ -3622,6 +3626,10 @@
3622
3626
  "shape": "Models",
3623
3627
  "documentation": "<p>List of available models</p>"
3624
3628
  },
3629
+ "defaultModel": {
3630
+ "shape": "Model",
3631
+ "documentation": "<p>Default model set by the client</p>"
3632
+ },
3625
3633
  "nextToken": {
3626
3634
  "shape": "Base64EncodedPaginationToken",
3627
3635
  "documentation": "<p>Token for retrieving the next page of results</p>"
@@ -3955,6 +3963,10 @@
3955
3963
  "shape": "ModelId",
3956
3964
  "documentation": "<p>Unique identifier for the model</p>"
3957
3965
  },
3966
+ "modelName": {
3967
+ "shape": "ModelName",
3968
+ "documentation": "<p>User-facing display name</p>"
3969
+ },
3958
3970
  "description": {
3959
3971
  "shape": "Description",
3960
3972
  "documentation": "<p>Description of the model</p>"
@@ -3972,6 +3984,13 @@
3972
3984
  "min": 1,
3973
3985
  "pattern": "[a-zA-Z0-9_:.-]+"
3974
3986
  },
3987
+ "ModelName": {
3988
+ "type": "string",
3989
+ "documentation": "<p>Identifier for the model Name</p>",
3990
+ "max": 1024,
3991
+ "min": 1,
3992
+ "pattern": "[a-zA-Z0-9-_.]+"
3993
+ },
3975
3994
  "ModelMetadata": {
3976
3995
  "type": "structure",
3977
3996
  "members": {
@@ -6284,6 +6303,12 @@
6284
6303
  },
6285
6304
  "ideVersion": {
6286
6305
  "shape": "String"
6306
+ },
6307
+ "pluginVersion": {
6308
+ "shape": "String"
6309
+ },
6310
+ "lspVersion": {
6311
+ "shape": "String"
6287
6312
  }
6288
6313
  }
6289
6314
  },
@@ -6525,6 +6550,9 @@
6525
6550
  },
6526
6551
  "streakLength": {
6527
6552
  "shape": "UserTriggerDecisionEventStreakLengthInteger"
6553
+ },
6554
+ "suggestionType": {
6555
+ "shape": "SuggestionType"
6528
6556
  }
6529
6557
  }
6530
6558
  },
@@ -4,8 +4,7 @@
4
4
  */
5
5
  import { ToolResult, ToolUse } from '@amzn/codewhisperer-streaming';
6
6
  import { ChatCommandInput } from '../../shared/streamingClientService';
7
- import { Status, ButtonClickParams, ButtonClickResult, InlineChatResultParams, PromptInputOptionChangeParams, RuleClickParams, ListRulesParams, ActiveEditorChangedParams, PinnedContextParams, ExecuteCommandParams, FollowUpClickParams, ListAvailableModelsParams, ListAvailableModelsResult, OpenFileDialogParams, OpenFileDialogResult } from '@aws/language-server-runtimes/protocol';
8
- import { FeedbackParams, InsertToCursorPositionParams, InlineChatParams, ConversationClickParams, ListConversationsParams, ListMcpServersParams, McpServerClickParams, TabBarActionParams, CreatePromptParams, FileClickParams } from '@aws/language-server-runtimes/protocol';
7
+ import { Status, ButtonClickParams, ButtonClickResult, InlineChatResultParams, PromptInputOptionChangeParams, RuleClickParams, ListRulesParams, ActiveEditorChangedParams, PinnedContextParams, ExecuteCommandParams, FollowUpClickParams, ListAvailableModelsParams, ListAvailableModelsResult, OpenFileDialogParams, OpenFileDialogResult, FeedbackParams, InsertToCursorPositionParams, InlineChatParams, ConversationClickParams, ListConversationsParams, ListMcpServersParams, McpServerClickParams, TabBarActionParams, CreatePromptParams, FileClickParams } from '@aws/language-server-runtimes/protocol';
9
8
  import { CancellationToken, Chat, ChatParams, ChatResult, EndChatParams, QuickActionParams, ResponseError, TabAddParams, TabRemoveParams, TabChangeParams, InlineChatResult } from '@aws/language-server-runtimes/server-interface';
10
9
  import { Features, LspHandlers } from '../types';
11
10
  import { ChatSessionManagementService } from '../chat/chatSessionManagementService';
@@ -54,6 +53,18 @@ export declare class AgenticChatController implements ChatHandlers {
54
53
  list: import("@aws/language-server-runtimes/protocol").DetailedListGroup[];
55
54
  }>;
56
55
  onMcpServerClick(params: McpServerClickParams): Promise<any>;
56
+ /**
57
+ * This function handles the model selection process for the chat interface.
58
+ * It first attempts to retrieve models from cache or API, then determines the appropriate model to select
59
+ * based on the following priority:
60
+ * 1. When errors occur or session is invalid: Use the default model as a fallback
61
+ * 2. When user has previously selected a model: Use that model (or its mapped version if the model ID has changed)
62
+ * 3. When there's a default model from the API: Use the server-recommended default model
63
+ * 4. Last resort: Use the newest model defined in modelSelection constants
64
+ *
65
+ * This ensures users maintain consistent model selection across sessions while also handling
66
+ * API failures and model ID migrations gracefully.
67
+ */
57
68
  onListAvailableModels(params: ListAvailableModelsParams): Promise<ListAvailableModelsResult>;
58
69
  onChatPrompt(params: ChatParams, token: CancellationToken): Promise<ChatResult | ResponseError<ChatResult>>;
59
70
  truncatePinnedContext(remainingCharacterBudget: number, pinnedContext?: AdditionalContentEntryAddition[]): number;
@@ -11,7 +11,6 @@ const os = require("os");
11
11
  const codewhisperer_streaming_1 = require("@amzn/codewhisperer-streaming");
12
12
  const toolConstants_1 = require("./constants/toolConstants");
13
13
  const protocol_1 = require("@aws/language-server-runtimes/protocol");
14
- const protocol_2 = require("@aws/language-server-runtimes/protocol");
15
14
  const server_interface_1 = require("@aws/language-server-runtimes/server-interface");
16
15
  const uuid_1 = require("uuid");
17
16
  const types_1 = require("../../shared/telemetry/types");
@@ -41,6 +40,7 @@ const fsWrite_1 = require("./tools/fsWrite");
41
40
  const executeBash_1 = require("./tools/executeBash");
42
41
  const toolShared_1 = require("./tools/toolShared");
43
42
  const pathValidation_1 = require("./utils/pathValidation");
43
+ const fileModificationMetrics_1 = require("./utils/fileModificationMetrics");
44
44
  const grepSearch_1 = require("./tools/grepSearch");
45
45
  const fileSearch_1 = require("./tools/fileSearch");
46
46
  const fsReplace_1 = require("./tools/fsReplace");
@@ -62,9 +62,9 @@ const util_1 = require("./tools/chatDb/util");
62
62
  const modelSelection_1 = require("./constants/modelSelection");
63
63
  const imageVerification_1 = require("../../shared/imageVerification");
64
64
  const path_1 = require("@aws/lsp-core/out/util/path");
65
- const agenticChatControllerHelper_1 = require("./utils/agenticChatControllerHelper");
66
65
  const activeUserTracker_1 = require("../../shared/activeUserTracker");
67
66
  const displayFindings_1 = require("./tools/qCodeAnalysis/displayFindings");
67
+ const constants_3 = require("../../shared/constants");
68
68
  const IdleWorkspaceManager_1 = require("../workspaceContext/IdleWorkspaceManager");
69
69
  class AgenticChatController {
70
70
  #features;
@@ -145,7 +145,7 @@ class AgenticChatController {
145
145
  // @ts-ignore
146
146
  this.#features.chat.chatOptionsUpdate({ region });
147
147
  });
148
- this.#chatHistoryDb = new chatDb_1.ChatDatabase(features);
148
+ this.#chatHistoryDb = chatDb_1.ChatDatabase.getInstance(features);
149
149
  this.#tabBarController = new tabBarController_1.TabBarController(features, this.#chatHistoryDb, telemetryService, (tabId) => this.sendPinnedContext(tabId));
150
150
  this.#additionalContextProvider = new additionalContextProvider_1.AdditionalContextProvider(features, this.#chatHistoryDb);
151
151
  this.#contextCommandsProvider = new contextCommandsProvider_1.ContextCommandsProvider(this.#features.logging, this.#features.chat, this.#features.workspace, this.#features.lsp);
@@ -431,21 +431,116 @@ class AgenticChatController {
431
431
  async onMcpServerClick(params) {
432
432
  return this.#mcpEventHandler.onMcpServerClick(params);
433
433
  }
434
+ /**
435
+ * Fetches available models either from cache or API
436
+ * If cache is valid (less than 5 minutes old), returns cached models
437
+ * If cache is invalid or empty, makes an API call and stores results in cache
438
+ * If the API throws errors (e.g., throttling), falls back to default models
439
+ */
440
+ async #fetchModelsWithCache() {
441
+ let models = [];
442
+ let defaultModelId;
443
+ let errorFromAPI = false;
444
+ // Check if cache is valid (less than 5 minutes old)
445
+ if (this.#chatHistoryDb.isCachedModelsValid()) {
446
+ const cachedData = this.#chatHistoryDb.getCachedModels();
447
+ if (cachedData && cachedData.models && cachedData.models.length > 0) {
448
+ this.#log('Using cached models, last updated at:', new Date(cachedData.timestamp).toISOString());
449
+ return {
450
+ models: cachedData.models,
451
+ defaultModelId: cachedData.defaultModelId,
452
+ errorFromAPI: false,
453
+ };
454
+ }
455
+ }
456
+ // If cache is invalid or empty, make an API call
457
+ this.#log('Cache miss or expired, fetching models from API');
458
+ try {
459
+ const client = AmazonQTokenServiceManager_1.AmazonQTokenServiceManager.getInstance().getCodewhispererService();
460
+ const responseResult = await client.listAvailableModels({
461
+ origin: constants_3.IDE,
462
+ profileArn: AmazonQTokenServiceManager_1.AmazonQTokenServiceManager.getInstance().getConnectionType()
463
+ ? AmazonQTokenServiceManager_1.AmazonQTokenServiceManager.getInstance().getActiveProfileArn()
464
+ : undefined,
465
+ });
466
+ // Wait for the response to be completed before proceeding
467
+ this.#log('Model Response: ', JSON.stringify(responseResult, null, 2));
468
+ models = Object.values(responseResult.models).map(({ modelId, modelName }) => ({
469
+ id: modelId,
470
+ name: modelName ?? modelId,
471
+ }));
472
+ defaultModelId = responseResult.defaultModel?.modelId;
473
+ // Cache the models with defaultModelId
474
+ this.#chatHistoryDb.setCachedModels(models, defaultModelId);
475
+ }
476
+ catch (err) {
477
+ // In case of API throttling or other errors, fall back to hardcoded models
478
+ this.#log('Error fetching models from API, using fallback models:', (0, utils_2.fmtError)(err));
479
+ errorFromAPI = true;
480
+ models = modelSelection_1.FALLBACK_MODEL_OPTIONS;
481
+ }
482
+ return {
483
+ models,
484
+ defaultModelId,
485
+ errorFromAPI,
486
+ };
487
+ }
488
+ /**
489
+ * This function handles the model selection process for the chat interface.
490
+ * It first attempts to retrieve models from cache or API, then determines the appropriate model to select
491
+ * based on the following priority:
492
+ * 1. When errors occur or session is invalid: Use the default model as a fallback
493
+ * 2. When user has previously selected a model: Use that model (or its mapped version if the model ID has changed)
494
+ * 3. When there's a default model from the API: Use the server-recommended default model
495
+ * 4. Last resort: Use the newest model defined in modelSelection constants
496
+ *
497
+ * This ensures users maintain consistent model selection across sessions while also handling
498
+ * API failures and model ID migrations gracefully.
499
+ */
434
500
  async onListAvailableModels(params) {
435
- const region = AmazonQTokenServiceManager_1.AmazonQTokenServiceManager.getInstance().getRegion();
436
- const models = region && modelSelection_1.MODEL_OPTIONS_FOR_REGION[region] ? modelSelection_1.MODEL_OPTIONS_FOR_REGION[region] : modelSelection_1.MODEL_OPTIONS;
501
+ // Get models from cache or API
502
+ const { models, defaultModelId, errorFromAPI } = await this.#fetchModelsWithCache();
503
+ // Get the first fallback model option as default
504
+ const defaultModelOption = modelSelection_1.FALLBACK_MODEL_OPTIONS[1];
505
+ const DEFAULT_MODEL_ID = defaultModelId || defaultModelOption?.id;
437
506
  const sessionResult = this.#chatSessionManagementService.getSession(params.tabId);
438
507
  const { data: session, success } = sessionResult;
439
- if (!success) {
508
+ // Handle error cases by returning default model
509
+ if (!success || errorFromAPI) {
440
510
  return {
441
511
  tabId: params.tabId,
442
512
  models: models,
513
+ selectedModelId: DEFAULT_MODEL_ID,
443
514
  };
444
515
  }
445
- const savedModelId = this.#chatHistoryDb.getModelId();
446
- const selectedModelId = savedModelId && models.some(model => model.id === savedModelId)
447
- ? savedModelId
448
- : (0, agenticChatControllerHelper_1.getLatestAvailableModel)(region).id;
516
+ // Determine selected model ID based on priority
517
+ let selectedModelId;
518
+ let modelId = this.#chatHistoryDb.getModelId();
519
+ // Helper function to get model label from FALLBACK_MODEL_RECORD
520
+ const getModelLabel = (modelKey) => modelSelection_1.FALLBACK_MODEL_RECORD[modelKey]?.label || modelKey;
521
+ // Helper function to map enum model ID to API model ID
522
+ const getMappedModelId = (modelKey) => modelSelection_1.BEDROCK_MODEL_TO_MODEL_ID[modelKey] || modelKey;
523
+ // Determine selected model ID based on priority
524
+ if (modelId) {
525
+ const mappedModelId = getMappedModelId(modelId);
526
+ // Priority 1: Use mapped modelId if it exists in available models from backend
527
+ if (models.some(model => model.id === mappedModelId)) {
528
+ selectedModelId = mappedModelId;
529
+ }
530
+ // Priority 2: Use mapped version if modelId exists in FALLBACK_MODEL_RECORD and no backend models available
531
+ else if (models.length === 0 && modelId in modelSelection_1.FALLBACK_MODEL_RECORD) {
532
+ selectedModelId = getModelLabel(modelId);
533
+ }
534
+ // Priority 3: Fall back to default or system default
535
+ else {
536
+ selectedModelId = defaultModelId || getMappedModelId(DEFAULT_MODEL_ID);
537
+ }
538
+ }
539
+ else {
540
+ // No user-selected model - use API default or system default
541
+ selectedModelId = defaultModelId || getMappedModelId(DEFAULT_MODEL_ID);
542
+ }
543
+ // Store the selected model in the session
449
544
  session.modelId = selectedModelId;
450
545
  return {
451
546
  tabId: params.tabId,
@@ -474,7 +569,7 @@ class AgenticChatController {
474
569
  const sessionResult = this.#chatSessionManagementService.getSession(params.tabId);
475
570
  const { data: session, success } = sessionResult;
476
571
  if (!success) {
477
- return new server_interface_1.ResponseError(protocol_2.ErrorCodes.InternalError, sessionResult.error);
572
+ return new server_interface_1.ResponseError(protocol_1.ErrorCodes.InternalError, sessionResult.error);
478
573
  }
479
574
  const compactIds = session.getAllDeferredCompactMessageIds();
480
575
  await this.#invalidateCompactCommand(params.tabId, compactIds);
@@ -1312,6 +1407,13 @@ class AgenticChatController {
1312
1407
  });
1313
1408
  }
1314
1409
  this.#telemetryController.emitInteractWithAgenticChat('GeneratedDiff', tabId, session.pairProgrammingMode, session.getConversationType(), this.#abTestingAllocation?.experimentName, this.#abTestingAllocation?.userVariation);
1410
+ // Emit acceptedLineCount when write tool is used and code changes are accepted
1411
+ const acceptedLineCount = (0, fileModificationMetrics_1.calculateModifiedLines)(toolUse, doc?.getText());
1412
+ await this.#telemetryController.emitInteractWithMessageMetric(tabId, {
1413
+ cwsprChatMessageId: chatResult.messageId ?? toolUse.toolUseId,
1414
+ cwsprChatInteractionType: types_1.ChatInteractionType.AgenticCodeAccepted,
1415
+ codewhispererCustomizationArn: this.#customizationArn,
1416
+ }, acceptedLineCount);
1315
1417
  await chatResultStream.writeResultBlock(chatResult);
1316
1418
  break;
1317
1419
  case codeReview_1.CodeReview.toolName:
@@ -1400,6 +1502,48 @@ class AgenticChatController {
1400
1502
  // only emit if this is an actual tool error (not a user rejecting/canceling tool)
1401
1503
  this.#telemetryController.emitToolUseSuggested(toolUse, session.conversationId ?? '', this.#features.runtime.serverInfo.version ?? '', undefined, session.pairProgrammingMode, this.#abTestingAllocation?.experimentName, this.#abTestingAllocation?.userVariation, 'Failed');
1402
1504
  }
1505
+ // Handle MCP tool failures
1506
+ const originalNames = mcpManager_1.McpManager.instance.getOriginalToolNames(toolUse.name);
1507
+ if (originalNames && toolUse.toolUseId) {
1508
+ const { toolName } = originalNames;
1509
+ const cachedToolUse = session.toolUseLookup.get(toolUse.toolUseId);
1510
+ const cachedButtonBlockId = cachedToolUse?.cachedButtonBlockId;
1511
+ const customerFacingError = (0, errors_2.getCustomerFacingErrorMessage)(err);
1512
+ const errorResult = {
1513
+ type: 'tool',
1514
+ messageId: toolUse.toolUseId,
1515
+ summary: {
1516
+ content: {
1517
+ header: {
1518
+ icon: 'tools',
1519
+ body: `${toolName}`,
1520
+ status: {
1521
+ status: 'error',
1522
+ icon: 'cancel-circle',
1523
+ text: 'Error',
1524
+ description: customerFacingError,
1525
+ },
1526
+ },
1527
+ },
1528
+ collapsedContent: [
1529
+ {
1530
+ header: { body: 'Parameters' },
1531
+ body: `\`\`\`json\n${JSON.stringify(toolUse.input, null, 2)}\n\`\`\``,
1532
+ },
1533
+ {
1534
+ header: { body: 'Error' },
1535
+ body: customerFacingError,
1536
+ },
1537
+ ],
1538
+ },
1539
+ };
1540
+ if (cachedButtonBlockId !== undefined) {
1541
+ await chatResultStream.overwriteResultBlock(errorResult, cachedButtonBlockId);
1542
+ }
1543
+ else {
1544
+ await chatResultStream.writeResultBlock(errorResult);
1545
+ }
1546
+ }
1403
1547
  // display fs write failure status in the UX of that file card
1404
1548
  if ((toolUse.name === toolConstants_1.FS_WRITE || toolUse.name === toolConstants_1.FS_REPLACE) && toolUse.toolUseId) {
1405
1549
  const existingCard = chatResultStream.getMessageBlockId(toolUse.toolUseId);
@@ -1729,7 +1873,7 @@ class AgenticChatController {
1729
1873
  status: {
1730
1874
  status: isAccept ? 'success' : 'error',
1731
1875
  icon: isAccept ? 'ok' : 'cancel',
1732
- text: isAccept ? 'Completed' : 'Rejected',
1876
+ text: isAccept ? 'Accepted' : 'Rejected',
1733
1877
  },
1734
1878
  fileList: undefined,
1735
1879
  },
@@ -1807,6 +1951,7 @@ class AgenticChatController {
1807
1951
  session.setDeferredToolExecution(messageId, deferred.resolve, deferred.reject);
1808
1952
  this.#log(`Prompting for compaction approval for messageId: ${messageId}`);
1809
1953
  await deferred.promise;
1954
+ session.removeDeferredToolExecution(messageId);
1810
1955
  // Note: we want to overwrite the button block because it already exists in the stream.
1811
1956
  await resultStream.overwriteResultBlock(this.#getUpdateCompactConfirmResult(messageId), promptBlockId);
1812
1957
  }
@@ -2344,7 +2489,7 @@ class AgenticChatController {
2344
2489
  * Handles errors that occur during the request
2345
2490
  */
2346
2491
  async #handleRequestError(conversationId, err, errorMessageId, tabId, metric, agenticCodingMode) {
2347
- const errorMessage = (0, utils_2.getErrorMsg)(err);
2492
+ const errorMessage = (0, utils_2.getErrorMsg)(err) ?? constants_2.GENERIC_ERROR_MS;
2348
2493
  const requestID = (0, utils_2.getRequestID)(err) ?? '';
2349
2494
  metric.setDimension('cwsprChatResponseCode', (0, utils_2.getHttpStatusCode)(err) ?? 0);
2350
2495
  metric.setDimension('languageServerVersion', this.#features.runtime.serverInfo.version);
@@ -2353,7 +2498,7 @@ class AgenticChatController {
2353
2498
  metric.metric.requestIds = [requestID];
2354
2499
  metric.metric.cwsprChatMessageId = errorMessageId;
2355
2500
  metric.metric.cwsprChatConversationId = conversationId;
2356
- await this.#telemetryController.emitAddMessageMetric(tabId, metric.metric, 'Failed');
2501
+ await this.#telemetryController.emitAddMessageMetric(tabId, metric.metric, 'Failed', errorMessage);
2357
2502
  if ((0, utils_2.isUsageLimitError)(err)) {
2358
2503
  if (this.#paidTierMode !== 'paidtier') {
2359
2504
  this.setPaidTierMode(tabId, 'freetier-limit');
@@ -2380,7 +2525,7 @@ class AgenticChatController {
2380
2525
  this.#telemetryController.emitMessageResponseError(tabId, metric.metric, requestID, customErrMessage, agenticCodingMode);
2381
2526
  }
2382
2527
  else {
2383
- this.#telemetryController.emitMessageResponseError(tabId, metric.metric, requestID, errorMessage ?? constants_2.GENERIC_ERROR_MS, agenticCodingMode);
2528
+ this.#telemetryController.emitMessageResponseError(tabId, metric.metric, requestID, errorMessage, agenticCodingMode);
2384
2529
  }
2385
2530
  let authFollowType = undefined;
2386
2531
  // first check if there is an AmazonQ related auth follow up
@@ -2554,8 +2699,8 @@ class AgenticChatController {
2554
2699
  const workspaceEdit = {
2555
2700
  edit: {
2556
2701
  documentChanges: [
2557
- protocol_2.TextDocumentEdit.create({ uri: params.textDocument.uri, version: 0 }, [
2558
- protocol_2.TextEdit.insert(cursorPosition, textWithIndent),
2702
+ protocol_1.TextDocumentEdit.create({ uri: params.textDocument.uri, version: 0 }, [
2703
+ protocol_1.TextEdit.insert(cursorPosition, textWithIndent),
2559
2704
  ]),
2560
2705
  ],
2561
2706
  },
@@ -2639,23 +2784,6 @@ class AgenticChatController {
2639
2784
  });
2640
2785
  }
2641
2786
  onSourceLinkClick() { }
2642
- /**
2643
- * @deprecated use aws/chat/listAvailableModels server request instead
2644
- */
2645
- #legacySetModelId(tabId, session) {
2646
- // Since model selection is mandatory, the only time modelId is not set is when the chat history is empty.
2647
- // In that case, we use the default modelId.
2648
- let modelId = this.#chatHistoryDb.getModelId() ?? constants_2.DEFAULT_MODEL_ID;
2649
- const region = AmazonQTokenServiceManager_1.AmazonQTokenServiceManager.getInstance().getRegion();
2650
- if (region === 'eu-central-1') {
2651
- // Only 3.7 Sonnet is available in eu-central-1 for now
2652
- modelId = 'CLAUDE_3_7_SONNET_20250219_V1_0';
2653
- // @ts-ignore
2654
- this.#features.chat.chatOptionsUpdate({ region });
2655
- }
2656
- this.#features.chat.chatOptionsUpdate({ modelId: modelId, tabId: tabId });
2657
- session.modelId = modelId;
2658
- }
2659
2787
  onTabAdd(params) {
2660
2788
  this.#telemetryController.activeTabId = params.tabId;
2661
2789
  if (!params.restoredTab) {
@@ -2664,22 +2792,21 @@ class AgenticChatController {
2664
2792
  const sessionResult = this.#chatSessionManagementService.createSession(params.tabId);
2665
2793
  const { data: session, success } = sessionResult;
2666
2794
  if (!success) {
2667
- return new server_interface_1.ResponseError(protocol_2.ErrorCodes.InternalError, sessionResult.error);
2795
+ return new server_interface_1.ResponseError(protocol_1.ErrorCodes.InternalError, sessionResult.error);
2668
2796
  }
2669
- this.#legacySetModelId(params.tabId, session);
2670
2797
  // Get the saved pair programming mode from the database or default to true if not found
2671
2798
  const savedPairProgrammingMode = this.#chatHistoryDb.getPairProgrammingMode();
2672
2799
  session.pairProgrammingMode = savedPairProgrammingMode !== undefined ? savedPairProgrammingMode : true;
2800
+ if (session) {
2801
+ // Set the logging object on the session
2802
+ session.setLogging(this.#features.logging);
2803
+ }
2673
2804
  // Update the client with the initial pair programming mode
2674
2805
  this.#features.chat.chatOptionsUpdate({
2675
2806
  tabId: params.tabId,
2676
2807
  // Type assertion to support pairProgrammingMode
2677
2808
  ...(session.pairProgrammingMode !== undefined ? { pairProgrammingMode: session.pairProgrammingMode } : {}),
2678
2809
  });
2679
- if (success && session) {
2680
- // Set the logging object on the session
2681
- session.setLogging(this.#features.logging);
2682
- }
2683
2810
  this.setPaidTierMode(params.tabId);
2684
2811
  }
2685
2812
  onTabChange(params) {
@@ -3393,6 +3520,13 @@ class AgenticChatController {
3393
3520
  }
3394
3521
  else {
3395
3522
  // Fallback to creating a new card
3523
+ if (toolResultCard.summary?.content?.header) {
3524
+ toolResultCard.summary.content.header.status = {
3525
+ status: 'success',
3526
+ icon: 'ok',
3527
+ text: 'Completed',
3528
+ };
3529
+ }
3396
3530
  this.#log(`Warning: No blockId found for tool use ${toolUse.toolUseId}, creating new card`);
3397
3531
  await chatResultStream.writeResultBlock(toolResultCard);
3398
3532
  }