@aws/lsp-codewhisperer 0.0.71 → 0.0.73

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 (102) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/out/language-server/agenticChat/agenticChatController.js +116 -71
  3. package/out/language-server/agenticChat/agenticChatController.js.map +1 -1
  4. package/out/language-server/agenticChat/agenticChatResultStream.d.ts +4 -27
  5. package/out/language-server/agenticChat/agenticChatResultStream.js +14 -31
  6. package/out/language-server/agenticChat/agenticChatResultStream.js.map +1 -1
  7. package/out/language-server/agenticChat/constants/modelSelection.js +1 -1
  8. package/out/language-server/agenticChat/constants/modelSelection.js.map +1 -1
  9. package/out/language-server/agenticChat/tools/chatDb/chatDb.d.ts +7 -1
  10. package/out/language-server/agenticChat/tools/chatDb/chatDb.js +64 -17
  11. package/out/language-server/agenticChat/tools/chatDb/chatDb.js.map +1 -1
  12. package/out/language-server/agenticChat/tools/chatDb/util.d.ts +3 -2
  13. package/out/language-server/agenticChat/tools/chatDb/util.js.map +1 -1
  14. package/out/language-server/agenticChat/tools/executeBash.d.ts +1 -0
  15. package/out/language-server/agenticChat/tools/executeBash.js +33 -0
  16. package/out/language-server/agenticChat/tools/executeBash.js.map +1 -1
  17. package/out/language-server/agenticChat/tools/fileSearch.d.ts +1 -0
  18. package/out/language-server/agenticChat/tools/fileSearch.js +4 -0
  19. package/out/language-server/agenticChat/tools/fileSearch.js.map +1 -1
  20. package/out/language-server/agenticChat/tools/mcp/mcpEventHandler.js +22 -18
  21. package/out/language-server/agenticChat/tools/mcp/mcpEventHandler.js.map +1 -1
  22. package/out/language-server/agenticChat/tools/mcp/mcpManager.d.ts +1 -0
  23. package/out/language-server/agenticChat/tools/mcp/mcpManager.js +68 -32
  24. package/out/language-server/agenticChat/tools/mcp/mcpManager.js.map +1 -1
  25. package/out/language-server/agenticChat/tools/mcp/mcpTypes.d.ts +1 -0
  26. package/out/language-server/agenticChat/tools/mcp/mcpTypes.js.map +1 -1
  27. package/out/language-server/agenticChat/tools/mcp/mcpUtils.d.ts +1 -1
  28. package/out/language-server/agenticChat/tools/mcp/mcpUtils.js +70 -7
  29. package/out/language-server/agenticChat/tools/mcp/mcpUtils.js.map +1 -1
  30. package/out/language-server/agenticChat/tools/qCodeAnalysis/displayFindingsConstants.js +1 -0
  31. package/out/language-server/agenticChat/tools/qCodeAnalysis/displayFindingsConstants.js.map +1 -1
  32. package/out/language-server/agenticChat/utils/agenticChatControllerHelper.js +1 -1
  33. package/out/language-server/agenticChat/utils/agenticChatControllerHelper.js.map +1 -1
  34. package/out/language-server/chat/chatSessionService.js +1 -1
  35. package/out/language-server/chat/chatSessionService.js.map +1 -1
  36. package/out/language-server/chat/telemetry/chatTelemetryController.d.ts +1 -0
  37. package/out/language-server/chat/telemetry/chatTelemetryController.js +11 -0
  38. package/out/language-server/chat/telemetry/chatTelemetryController.js.map +1 -1
  39. package/out/language-server/inline-completion/codeDiffTracker.d.ts +9 -0
  40. package/out/language-server/inline-completion/codeDiffTracker.js.map +1 -1
  41. package/out/language-server/inline-completion/codePercentage.d.ts +2 -0
  42. package/out/language-server/inline-completion/codePercentage.js +10 -2
  43. package/out/language-server/inline-completion/codePercentage.js.map +1 -1
  44. package/out/language-server/inline-completion/codeWhispererServer.d.ts +0 -3
  45. package/out/language-server/inline-completion/codeWhispererServer.js +91 -200
  46. package/out/language-server/inline-completion/codeWhispererServer.js.map +1 -1
  47. package/out/language-server/inline-completion/constants.d.ts +10 -0
  48. package/out/language-server/inline-completion/constants.js +35 -0
  49. package/out/language-server/inline-completion/constants.js.map +1 -0
  50. package/out/language-server/inline-completion/diffUtils.d.ts +15 -0
  51. package/out/language-server/inline-completion/diffUtils.js +53 -0
  52. package/out/language-server/inline-completion/diffUtils.js.map +1 -1
  53. package/out/language-server/inline-completion/documentChangedListener.d.ts +8 -0
  54. package/out/language-server/inline-completion/documentChangedListener.js +20 -0
  55. package/out/language-server/inline-completion/documentChangedListener.js.map +1 -0
  56. package/out/language-server/inline-completion/editCompletionHandler.d.ts +49 -0
  57. package/out/language-server/inline-completion/editCompletionHandler.js +328 -0
  58. package/out/language-server/inline-completion/editCompletionHandler.js.map +1 -0
  59. package/out/language-server/inline-completion/session/sessionManager.d.ts +9 -3
  60. package/out/language-server/inline-completion/session/sessionManager.js +31 -7
  61. package/out/language-server/inline-completion/session/sessionManager.js.map +1 -1
  62. package/out/language-server/inline-completion/telemetry.d.ts +3 -3
  63. package/out/language-server/inline-completion/telemetry.js +11 -5
  64. package/out/language-server/inline-completion/telemetry.js.map +1 -1
  65. package/out/language-server/inline-completion/trigger.d.ts +17 -0
  66. package/out/language-server/inline-completion/trigger.js +42 -0
  67. package/out/language-server/inline-completion/trigger.js.map +1 -0
  68. package/out/language-server/workspaceContext/IdleWorkspaceManager.d.ts +13 -0
  69. package/out/language-server/workspaceContext/IdleWorkspaceManager.js +39 -0
  70. package/out/language-server/workspaceContext/IdleWorkspaceManager.js.map +1 -0
  71. package/out/language-server/workspaceContext/artifactManager.js +14 -0
  72. package/out/language-server/workspaceContext/artifactManager.js.map +1 -1
  73. package/out/language-server/workspaceContext/dependency/dependencyDiscoverer.d.ts +1 -1
  74. package/out/language-server/workspaceContext/dependency/dependencyDiscoverer.js +2 -1
  75. package/out/language-server/workspaceContext/dependency/dependencyDiscoverer.js.map +1 -1
  76. package/out/language-server/workspaceContext/workspaceContextServer.js +2 -6
  77. package/out/language-server/workspaceContext/workspaceContextServer.js.map +1 -1
  78. package/out/language-server/workspaceContext/workspaceFolderManager.d.ts +8 -5
  79. package/out/language-server/workspaceContext/workspaceFolderManager.js +109 -82
  80. package/out/language-server/workspaceContext/workspaceFolderManager.js.map +1 -1
  81. package/out/shared/codeWhispererService.d.ts +36 -1
  82. package/out/shared/codeWhispererService.js +112 -9
  83. package/out/shared/codeWhispererService.js.map +1 -1
  84. package/out/shared/constants.d.ts +1 -0
  85. package/out/shared/constants.js +2 -1
  86. package/out/shared/constants.js.map +1 -1
  87. package/out/shared/supplementalContextUtil/crossFileContextUtil.d.ts +3 -4
  88. package/out/shared/supplementalContextUtil/crossFileContextUtil.js +5 -5
  89. package/out/shared/supplementalContextUtil/crossFileContextUtil.js.map +1 -1
  90. package/out/shared/supplementalContextUtil/supplementalContextUtil.d.ts +1 -2
  91. package/out/shared/supplementalContextUtil/supplementalContextUtil.js +2 -2
  92. package/out/shared/supplementalContextUtil/supplementalContextUtil.js.map +1 -1
  93. package/out/shared/telemetry/telemetryService.d.ts +2 -2
  94. package/out/shared/telemetry/telemetryService.js +8 -5
  95. package/out/shared/telemetry/telemetryService.js.map +1 -1
  96. package/out/shared/telemetry/types.d.ts +8 -0
  97. package/out/shared/telemetry/types.js +1 -0
  98. package/out/shared/telemetry/types.js.map +1 -1
  99. package/out/shared/utils.d.ts +1 -0
  100. package/out/shared/utils.js +10 -1
  101. package/out/shared/utils.js.map +1 -1
  102. package/package.json +2 -2
package/CHANGELOG.md CHANGED
@@ -1,5 +1,42 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.0.73](https://github.com/aws/language-servers/compare/lsp-codewhisperer/v0.0.72...lsp-codewhisperer/v0.0.73) (2025-08-11)
4
+
5
+
6
+ ### Features
7
+
8
+ * **amazonq:** read tool ui revamp ([c65428b](https://github.com/aws/language-servers/commit/c65428bab2cf5e47badf1e3a9453babcf881e60c))
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * **amazonq:** add fallback classpath generation ([#2077](https://github.com/aws/language-servers/issues/2077)) ([3a6ef14](https://github.com/aws/language-servers/commit/3a6ef14e78fa2e75b837bba6524751d65038f416))
14
+ * **amazonq:** emit failed status for amazonq_invokeLLM ([#2071](https://github.com/aws/language-servers/issues/2071)) ([ee52a41](https://github.com/aws/language-servers/commit/ee52a41bc869b275fff708d7955b59f43b93bbd4))
15
+ * **amazonq:** fix fallout of [#2051](https://github.com/aws/language-servers/issues/2051) ([#2057](https://github.com/aws/language-servers/issues/2057)) ([565066b](https://github.com/aws/language-servers/commit/565066bb61adda60333c9646db958d4208bcc8af))
16
+ * **amazonq:** leverage lcs to find the chars added and removed ([#2092](https://github.com/aws/language-servers/issues/2092)) ([40379a8](https://github.com/aws/language-servers/commit/40379a887f8d42cc184239ca3175b4e673cc5286))
17
+ * **amazonq:** skips continuous monitoring when WCS sees workspace as idle ([#2066](https://github.com/aws/language-servers/issues/2066)) ([9cb959d](https://github.com/aws/language-servers/commit/9cb959d4cc450d0907f8bf5265ba01d2aa68bcd0))
18
+ * creating a new sesion for Edits trigger with next token ([#2094](https://github.com/aws/language-servers/issues/2094)) ([1da8730](https://github.com/aws/language-servers/commit/1da8730b6ed6ad53b6561368bf722e56d59596a4))
19
+ * remove edit cache logic ([#2079](https://github.com/aws/language-servers/issues/2079)) ([9bc5b9c](https://github.com/aws/language-servers/commit/9bc5b9c1d77e5fee6f518f7f5016d3a0043a5a77))
20
+ * sessionManager misused because there are 2 types of manager now ([#2090](https://github.com/aws/language-servers/issues/2090)) ([8db059a](https://github.com/aws/language-servers/commit/8db059ab83d94fd7c3ba3eb265044add31c80aea))
21
+ * update client name to support Sagemaker AI origin for agentic chat ([#2093](https://github.com/aws/language-servers/issues/2093)) ([a746fe8](https://github.com/aws/language-servers/commit/a746fe845d5e09563b475f01ce44059dca9fd10f))
22
+
23
+ ## [0.0.72](https://github.com/aws/language-servers/compare/lsp-codewhisperer/v0.0.71...lsp-codewhisperer/v0.0.72) (2025-08-06)
24
+
25
+
26
+ ### Features
27
+
28
+ * add support for SMUS Q CodeEditor client to send MD IDE origin ([#2032](https://github.com/aws/language-servers/issues/2032)) ([a8725b4](https://github.com/aws/language-servers/commit/a8725b4b7dcb7718864620721aa3633151e8877b))
29
+ * **amazonq:** enable sonnet 4 for fra region ([#2069](https://github.com/aws/language-servers/issues/2069)) ([3a4b8df](https://github.com/aws/language-servers/commit/3a4b8df981b2c3b0532360a11472169fffec7924))
30
+
31
+
32
+ ### Bug Fixes
33
+
34
+ * **amazonq:** add distinctive identifier for cloud trail ([#2059](https://github.com/aws/language-servers/issues/2059)) ([18bbc2c](https://github.com/aws/language-servers/commit/18bbc2c54f5cc72e2624020fc17214c448926b0e))
35
+ * **amazonq:** fix to add disable/enable feature back to mcp servers ([#2052](https://github.com/aws/language-servers/issues/2052)) ([c03e017](https://github.com/aws/language-servers/commit/c03e017b9ccbbbb9c80a3c3afd5da38a50bd6cff))
36
+ * **amazonq:** make display findings tool run more often ([#2067](https://github.com/aws/language-servers/issues/2067)) ([479ccd0](https://github.com/aws/language-servers/commit/479ccd0a1b8b7e98684275c66274d284599c5933))
37
+ * outdated history when trimming happens, add missing metric for compaction ([#2047](https://github.com/aws/language-servers/issues/2047)) ([8390f66](https://github.com/aws/language-servers/commit/8390f6686c804dfbeff91018635df21e9dd89236))
38
+ * should keep reporting UTDE telemetry if there are still pending Edits suggestions ([#2051](https://github.com/aws/language-servers/issues/2051)) ([78c67b1](https://github.com/aws/language-servers/commit/78c67b1a29821f54006d160695e997870d17f3b5))
39
+
3
40
  ## [0.0.71](https://github.com/aws/language-servers/compare/lsp-codewhisperer/v0.0.70...lsp-codewhisperer/v0.0.71) (2025-08-04)
4
41
 
5
42
 
@@ -65,6 +65,7 @@ const path_1 = require("@aws/lsp-core/out/util/path");
65
65
  const agenticChatControllerHelper_1 = require("./utils/agenticChatControllerHelper");
66
66
  const activeUserTracker_1 = require("../../shared/activeUserTracker");
67
67
  const displayFindings_1 = require("./tools/qCodeAnalysis/displayFindings");
68
+ const IdleWorkspaceManager_1 = require("../workspaceContext/IdleWorkspaceManager");
68
69
  class AgenticChatController {
69
70
  #features;
70
71
  #chatSessionManagementService;
@@ -149,7 +150,7 @@ class AgenticChatController {
149
150
  this.#additionalContextProvider = new additionalContextProvider_1.AdditionalContextProvider(features, this.#chatHistoryDb);
150
151
  this.#contextCommandsProvider = new contextCommandsProvider_1.ContextCommandsProvider(this.#features.logging, this.#features.chat, this.#features.workspace, this.#features.lsp);
151
152
  this.#mcpEventHandler = new mcpEventHandler_1.McpEventHandler(features, telemetryService);
152
- this.#origin = (0, utils_2.getOriginFromClientInfo)(this.#features.lsp.getClientInitializeParams()?.clientInfo?.name);
153
+ this.#origin = (0, utils_2.getOriginFromClientInfo)((0, utils_2.getClientName)(this.#features.lsp.getClientInitializeParams()));
153
154
  this.#activeUserTracker = activeUserTracker_1.ActiveUserTracker.getInstance(this.#features);
154
155
  }
155
156
  async onExecuteCommand(params, _token) {
@@ -465,6 +466,7 @@ class AgenticChatController {
465
466
  async onChatPrompt(params, token) {
466
467
  // Phase 1: Initial Setup - This happens only once
467
468
  params.prompt.prompt = (0, utils_2.sanitizeInput)(params.prompt.prompt || '');
469
+ IdleWorkspaceManager_1.IdleWorkspaceManager.recordActivityTimestamp();
468
470
  const maybeDefaultResponse = !params.prompt.command && (0, utils_1.getDefaultChatResponse)(params.prompt.prompt);
469
471
  if (maybeDefaultResponse) {
470
472
  return maybeDefaultResponse;
@@ -645,7 +647,7 @@ class AgenticChatController {
645
647
  if (currentMessage) {
646
648
  // Get and process the messages from history DB to maintain invariants for service requests
647
649
  try {
648
- const { messages: historyMessages, count: historyCharCount } = this.#chatHistoryDb.fixAndGetHistory(tabId, currentMessage, []);
650
+ const { history: historyMessages, historyCount: historyCharCount } = this.#chatHistoryDb.fixAndGetHistory(tabId, conversationIdentifier ?? '', currentMessage, []);
649
651
  messages = historyMessages;
650
652
  characterCount = historyCharCount;
651
653
  }
@@ -763,10 +765,9 @@ class AgenticChatController {
763
765
  if (currentMessage) {
764
766
  // Get and process the messages from history DB to maintain invariants for service requests
765
767
  try {
766
- const newUserInputCount = this.#chatHistoryDb.calculateNewMessageCharacterCount(currentMessage, pinnedContextMessages);
767
- const { messages: historyMessages, count: historyCharacterCount } = this.#chatHistoryDb.fixAndGetHistory(tabId, currentMessage, pinnedContextMessages, newUserInputCount);
768
+ const { history: historyMessages, historyCount: historyCharacterCount, currentCount: currentInputCount, } = this.#chatHistoryDb.fixAndGetHistory(tabId, conversationId, currentMessage, pinnedContextMessages);
768
769
  messages = historyMessages;
769
- currentRequestCount = newUserInputCount + historyCharacterCount;
770
+ currentRequestCount = currentInputCount + historyCharacterCount;
770
771
  this.#debug(`Request total character count: ${currentRequestCount}`);
771
772
  }
772
773
  catch (err) {
@@ -845,6 +846,8 @@ class AgenticChatController {
845
846
  shouldDisplayMessage = false;
846
847
  // set the in progress tool use UI status to Error
847
848
  await chatResultStream.updateOngoingProgressResult('Error');
849
+ // emit invokeLLM event with status Failed for timeout calls
850
+ this.#telemetryController.emitAgencticLoop_InvokeLLM(response.$metadata.requestId, conversationId, 'AgenticChat', undefined, undefined, 'Failed', this.#features.runtime.serverInfo.version ?? '', session.modelId, llmLatency, this.#toolCallLatencies, this.#timeToFirstChunk, this.#timeBetweenChunks, session.pairProgrammingMode, this.#abTestingAllocation?.experimentName, this.#abTestingAllocation?.userVariation);
848
851
  continue;
849
852
  }
850
853
  // Add the current assistantResponse message to the history DB
@@ -882,7 +885,7 @@ class AgenticChatController {
882
885
  if (pendingToolUses.length === 0) {
883
886
  this.recordChunk('agent_loop_done');
884
887
  // No more tool uses, we're done
885
- this.#telemetryController.emitAgencticLoop_InvokeLLM(response.$metadata.requestId, conversationId, 'AgenticChat', undefined, undefined, 'Succeeded', this.#features.runtime.serverInfo.version ?? '', session.modelId, llmLatency, this.#toolCallLatencies, this.#timeToFirstChunk, this.#timeBetweenChunks, session.pairProgrammingMode, this.#abTestingAllocation?.experimentName, this.#abTestingAllocation?.userVariation);
888
+ this.#telemetryController.emitAgencticLoop_InvokeLLM(response.$metadata.requestId, conversationId, 'AgenticChat', undefined, undefined, result.success ? 'Succeeded' : 'Failed', this.#features.runtime.serverInfo.version ?? '', session.modelId, llmLatency, this.#toolCallLatencies, this.#timeToFirstChunk, this.#timeBetweenChunks, session.pairProgrammingMode, this.#abTestingAllocation?.experimentName, this.#abTestingAllocation?.userVariation);
886
889
  finalResult = result;
887
890
  break;
888
891
  }
@@ -928,6 +931,7 @@ class AgenticChatController {
928
931
  currentRequestInput = this.#updateRequestInputWithToolResults(currentRequestInput, toolResults, content);
929
932
  }
930
933
  if (this.#shouldCompact(currentRequestCount)) {
934
+ this.#telemetryController.emitCompactNudge(currentRequestCount, this.#features.runtime.serverInfo.version ?? '');
931
935
  const messageId = this.#getMessageIdForCompact((0, uuid_1.v4)());
932
936
  const confirmationResult = this.#processCompactConfirmation(messageId, currentRequestCount);
933
937
  const cachedButtonBlockId = await chatResultStream.writeResultBlock(confirmationResult);
@@ -1112,8 +1116,7 @@ class AgenticChatController {
1112
1116
  this.#toolStartTime = Date.now();
1113
1117
  // remove progress UI
1114
1118
  await chatResultStream.removeResultBlockAndUpdateUI(agenticChatResultStream_1.progressPrefix + toolUse.toolUseId);
1115
- // fsRead and listDirectory write to an existing card and could show nothing in the current position
1116
- if (![toolConstants_1.FS_WRITE, toolConstants_1.FS_REPLACE, toolConstants_1.FS_READ, toolConstants_1.LIST_DIRECTORY].includes(toolUse.name)) {
1119
+ if (![toolConstants_1.FS_WRITE, toolConstants_1.FS_REPLACE].includes(toolUse.name)) {
1117
1120
  await this.#showUndoAllIfRequired(chatResultStream, session);
1118
1121
  }
1119
1122
  // fsWrite can take a long time, so we render fsWrite Explanatory upon partial streaming responses.
@@ -1270,10 +1273,14 @@ class AgenticChatController {
1270
1273
  switch (toolUse.name) {
1271
1274
  case toolConstants_1.FS_READ:
1272
1275
  case toolConstants_1.LIST_DIRECTORY:
1276
+ const readToolResult = await this.#processReadTool(toolUse, chatResultStream);
1277
+ if (readToolResult) {
1278
+ await chatResultStream.writeResultBlock(readToolResult);
1279
+ }
1280
+ break;
1273
1281
  case toolConstants_1.FILE_SEARCH:
1274
- const initialListDirResult = this.#processReadOrListOrSearch(toolUse, chatResultStream);
1275
- if (initialListDirResult) {
1276
- await chatResultStream.writeResultBlock(initialListDirResult);
1282
+ if ((0, fileSearch_1.isFileSearchParams)(toolUse.input)) {
1283
+ await this.#processFileSearchTool(toolUse.input, toolUse.toolUseId, result, chatResultStream);
1277
1284
  }
1278
1285
  break;
1279
1286
  // no need to write tool result for listDir,fsRead,fileSearch into chat stream
@@ -1617,7 +1624,6 @@ class AgenticChatController {
1617
1624
  return;
1618
1625
  }
1619
1626
  const toolMsgId = toolUse.toolUseId;
1620
- const chatMsgId = chatResultStream.getResult().messageId;
1621
1627
  let headerEmitted = false;
1622
1628
  const initialHeader = {
1623
1629
  body: 'shell',
@@ -1649,12 +1655,6 @@ class AgenticChatController {
1649
1655
  body: '```',
1650
1656
  header: completedHeader,
1651
1657
  });
1652
- await chatResultStream.writeResultBlock({
1653
- type: 'answer',
1654
- messageId: chatMsgId,
1655
- body: '',
1656
- header: undefined,
1657
- });
1658
1658
  this.#stoppedToolUses.add(toolMsgId);
1659
1659
  },
1660
1660
  });
@@ -2085,72 +2085,123 @@ class AgenticChatController {
2085
2085
  },
2086
2086
  };
2087
2087
  }
2088
- #processReadOrListOrSearch(toolUse, chatResultStream) {
2089
- let messageIdToUpdate = toolUse.toolUseId;
2090
- const currentId = chatResultStream.getMessageIdToUpdateForTool(toolUse.name);
2091
- if (currentId) {
2092
- messageIdToUpdate = currentId;
2093
- }
2094
- else {
2095
- chatResultStream.setMessageIdToUpdateForTool(toolUse.name, messageIdToUpdate);
2096
- }
2088
+ async #processFileSearchTool(toolInput, toolUseId, result, chatResultStream) {
2089
+ if (typeof result.output.content !== 'string')
2090
+ return;
2091
+ const { queryName, path: inputPath } = toolInput;
2092
+ const resultCount = result.output.content
2093
+ .split('\n')
2094
+ .filter(line => line.trim().startsWith('[F]') || line.trim().startsWith('[D]')).length;
2095
+ const chatMessage = {
2096
+ type: 'tool',
2097
+ messageId: toolUseId,
2098
+ header: {
2099
+ body: `Searched for "${queryName}" in `,
2100
+ icon: 'search',
2101
+ status: {
2102
+ text: `${resultCount} result${resultCount !== 1 ? 's' : ''} found`,
2103
+ },
2104
+ fileList: {
2105
+ filePaths: [inputPath],
2106
+ details: {
2107
+ [inputPath]: {
2108
+ description: inputPath,
2109
+ visibleName: path.basename(inputPath),
2110
+ clickable: false,
2111
+ },
2112
+ },
2113
+ },
2114
+ },
2115
+ };
2116
+ await chatResultStream.writeResultBlock(chatMessage);
2117
+ }
2118
+ async #processReadTool(toolUse, chatResultStream) {
2097
2119
  let currentPaths = [];
2098
2120
  if (toolUse.name === toolConstants_1.FS_READ) {
2099
- currentPaths = toolUse.input?.paths;
2121
+ currentPaths = toolUse.input?.paths || [];
2100
2122
  }
2101
- else {
2102
- currentPaths.push(toolUse.input?.path);
2123
+ else if (toolUse.name === toolConstants_1.LIST_DIRECTORY) {
2124
+ const singlePath = toolUse.input?.path;
2125
+ if (singlePath) {
2126
+ currentPaths = [singlePath];
2127
+ }
2103
2128
  }
2104
- if (!currentPaths)
2105
- return;
2106
- for (const currentPath of currentPaths) {
2107
- const existingPaths = chatResultStream.getMessageOperation(messageIdToUpdate)?.filePaths || [];
2108
- // Check if path already exists in the list
2109
- const isPathAlreadyProcessed = existingPaths.some(path => path.relativeFilePath === currentPath);
2110
- if (!isPathAlreadyProcessed) {
2111
- const currentFileDetail = {
2112
- relativeFilePath: currentPath,
2113
- lineRanges: [{ first: -1, second: -1 }],
2114
- };
2115
- chatResultStream.addMessageOperation(messageIdToUpdate, toolUse.name, [
2116
- ...existingPaths,
2117
- currentFileDetail,
2118
- ]);
2129
+ else if (toolUse.name === toolConstants_1.FILE_SEARCH) {
2130
+ const queryName = toolUse.input?.queryName;
2131
+ if (queryName) {
2132
+ currentPaths = [queryName];
2119
2133
  }
2120
2134
  }
2135
+ else {
2136
+ return;
2137
+ }
2138
+ if (currentPaths.length === 0)
2139
+ return;
2140
+ // Check if the last message is the same tool type
2141
+ const lastMessage = chatResultStream.getLastMessage();
2142
+ const isSameToolType = lastMessage?.type === 'tool' && lastMessage.header?.icon === this.#toolToIcon(toolUse.name);
2143
+ let allPaths = currentPaths;
2144
+ if (isSameToolType && lastMessage.messageId) {
2145
+ // Combine with existing paths and overwrite the last message
2146
+ const existingPaths = lastMessage.header?.fileList?.filePaths || [];
2147
+ allPaths = [...existingPaths, ...currentPaths];
2148
+ const blockId = chatResultStream.getMessageBlockId(lastMessage.messageId);
2149
+ if (blockId !== undefined) {
2150
+ // Create the updated message with combined paths
2151
+ const updatedMessage = this.#createFileListToolMessage(toolUse, allPaths, lastMessage.messageId);
2152
+ // Overwrite the existing block
2153
+ await chatResultStream.overwriteResultBlock(updatedMessage, blockId);
2154
+ return undefined; // Don't return a message since we already wrote it
2155
+ }
2156
+ }
2157
+ // Create new message with current paths
2158
+ return this.#createFileListToolMessage(toolUse, allPaths, toolUse.toolUseId);
2159
+ }
2160
+ #createFileListToolMessage(toolUse, filePaths, messageId) {
2161
+ const itemCount = filePaths.length;
2121
2162
  let title;
2122
- const itemCount = chatResultStream.getMessageOperation(messageIdToUpdate)?.filePaths.length;
2123
- const filePathsPushed = chatResultStream.getMessageOperation(messageIdToUpdate)?.filePaths ?? [];
2124
- if (!itemCount) {
2163
+ if (itemCount === 0) {
2125
2164
  title = 'Gathering context';
2126
2165
  }
2127
2166
  else {
2128
2167
  title =
2129
2168
  toolUse.name === toolConstants_1.FS_READ
2130
2169
  ? `${itemCount} file${itemCount > 1 ? 's' : ''} read`
2131
- : toolUse.name === toolConstants_1.FILE_SEARCH
2132
- ? `${itemCount} ${itemCount === 1 ? 'directory' : 'directories'} searched`
2133
- : `${itemCount} ${itemCount === 1 ? 'directory' : 'directories'} listed`;
2170
+ : toolUse.name === toolConstants_1.LIST_DIRECTORY
2171
+ ? `${itemCount} ${itemCount === 1 ? 'directory' : 'directories'} listed`
2172
+ : '';
2134
2173
  }
2135
2174
  const details = {};
2136
- for (const item of filePathsPushed) {
2137
- details[item.relativeFilePath] = {
2138
- lineRanges: item.lineRanges,
2139
- description: item.relativeFilePath,
2175
+ for (const filePath of filePaths) {
2176
+ details[filePath] = {
2177
+ description: filePath,
2178
+ visibleName: path.basename(filePath),
2179
+ clickable: toolUse.name === toolConstants_1.FS_READ,
2140
2180
  };
2141
2181
  }
2142
- const fileList = {
2143
- rootFolderTitle: title,
2144
- filePaths: filePathsPushed.map(item => item.relativeFilePath),
2145
- details,
2146
- };
2147
2182
  return {
2148
2183
  type: 'tool',
2149
- fileList,
2150
- messageId: messageIdToUpdate,
2151
- body: '',
2184
+ header: {
2185
+ body: title,
2186
+ icon: this.#toolToIcon(toolUse.name),
2187
+ fileList: {
2188
+ filePaths,
2189
+ details,
2190
+ },
2191
+ },
2192
+ messageId,
2152
2193
  };
2153
2194
  }
2195
+ #toolToIcon(toolName) {
2196
+ switch (toolName) {
2197
+ case toolConstants_1.FS_READ:
2198
+ return 'eye';
2199
+ case toolConstants_1.LIST_DIRECTORY:
2200
+ return 'check-list';
2201
+ default:
2202
+ return undefined;
2203
+ }
2204
+ }
2154
2205
  /**
2155
2206
  * Process grep search results and format them for display in the chat UI
2156
2207
  */
@@ -2158,14 +2209,7 @@ class AgenticChatController {
2158
2209
  if (toolUse.name !== toolConstants_1.GREP_SEARCH) {
2159
2210
  return undefined;
2160
2211
  }
2161
- let messageIdToUpdate = toolUse.toolUseId;
2162
- const currentId = chatResultStream.getMessageIdToUpdateForTool(toolUse.name);
2163
- if (currentId) {
2164
- messageIdToUpdate = currentId;
2165
- }
2166
- else {
2167
- chatResultStream.setMessageIdToUpdateForTool(toolUse.name, messageIdToUpdate);
2168
- }
2212
+ const messageIdToUpdate = toolUse.toolUseId;
2169
2213
  // Extract search results from the tool output
2170
2214
  const output = result.output.content;
2171
2215
  if (!output || !output.fileMatches || !Array.isArray(output.fileMatches)) {
@@ -2414,6 +2458,7 @@ class AgenticChatController {
2414
2458
  const metric = new metric_1.Metric({
2415
2459
  cwsprChatConversationType: 'Chat',
2416
2460
  });
2461
+ IdleWorkspaceManager_1.IdleWorkspaceManager.recordActivityTimestamp();
2417
2462
  const triggerContext = await this.#getInlineChatTriggerContext(params);
2418
2463
  let response;
2419
2464
  let requestInput;