@aws/lsp-codewhisperer 0.0.60 → 0.0.61

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 (61) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/out/language-server/agenticChat/agenticChatController.d.ts +6 -3
  3. package/out/language-server/agenticChat/agenticChatController.js +122 -11
  4. package/out/language-server/agenticChat/agenticChatController.js.map +1 -1
  5. package/out/language-server/agenticChat/context/additionalContextProvider.d.ts +84 -0
  6. package/out/language-server/agenticChat/context/{addtionalContextProvider.js → additionalContextProvider.js} +167 -12
  7. package/out/language-server/agenticChat/context/additionalContextProvider.js.map +1 -0
  8. package/out/language-server/agenticChat/context/agenticChatTriggerContext.d.ts +7 -2
  9. package/out/language-server/agenticChat/context/agenticChatTriggerContext.js +5 -3
  10. package/out/language-server/agenticChat/context/agenticChatTriggerContext.js.map +1 -1
  11. package/out/language-server/agenticChat/context/contextCommandsProvider.js +14 -3
  12. package/out/language-server/agenticChat/context/contextCommandsProvider.js.map +1 -1
  13. package/out/language-server/agenticChat/errors.js +2 -4
  14. package/out/language-server/agenticChat/errors.js.map +1 -1
  15. package/out/language-server/agenticChat/qAgenticChatServer.d.ts +2 -1
  16. package/out/language-server/agenticChat/qAgenticChatServer.js +12 -1
  17. package/out/language-server/agenticChat/qAgenticChatServer.js.map +1 -1
  18. package/out/language-server/agenticChat/tools/chatDb/chatDb.d.ts +10 -1
  19. package/out/language-server/agenticChat/tools/chatDb/chatDb.js +66 -22
  20. package/out/language-server/agenticChat/tools/chatDb/chatDb.js.map +1 -1
  21. package/out/language-server/agenticChat/tools/chatDb/util.d.ts +3 -0
  22. package/out/language-server/agenticChat/tools/chatDb/util.js +15 -2
  23. package/out/language-server/agenticChat/tools/chatDb/util.js.map +1 -1
  24. package/out/language-server/chat/chatController.d.ts +3 -2
  25. package/out/language-server/chat/chatController.js +48 -0
  26. package/out/language-server/chat/chatController.js.map +1 -1
  27. package/out/language-server/chat/contexts/documentContext.d.ts +1 -0
  28. package/out/language-server/chat/contexts/documentContext.js +2 -0
  29. package/out/language-server/chat/contexts/documentContext.js.map +1 -1
  30. package/out/language-server/configuration/qConfigurationServer.d.ts +1 -0
  31. package/out/language-server/configuration/qConfigurationServer.js.map +1 -1
  32. package/out/language-server/inline-completion/auto-trigger/EditPredictionAutoTriggerTestConstants.js +0 -10
  33. package/out/language-server/inline-completion/auto-trigger/EditPredictionAutoTriggerTestConstants.js.map +1 -1
  34. package/out/language-server/inline-completion/auto-trigger/autoTrigger.d.ts +2 -1
  35. package/out/language-server/inline-completion/auto-trigger/autoTrigger.js +19 -1
  36. package/out/language-server/inline-completion/auto-trigger/autoTrigger.js.map +1 -1
  37. package/out/language-server/inline-completion/auto-trigger/coefficients.json +1 -1
  38. package/out/language-server/inline-completion/auto-trigger/editPredictionAutoTrigger.d.ts +3 -2
  39. package/out/language-server/inline-completion/auto-trigger/editPredictionAutoTrigger.js +6 -34
  40. package/out/language-server/inline-completion/auto-trigger/editPredictionAutoTrigger.js.map +1 -1
  41. package/out/language-server/inline-completion/codeWhispererServer.js +11 -1
  42. package/out/language-server/inline-completion/codeWhispererServer.js.map +1 -1
  43. package/out/language-server/inline-completion/mergeRightUtils.d.ts +20 -1
  44. package/out/language-server/inline-completion/mergeRightUtils.js +83 -5
  45. package/out/language-server/inline-completion/mergeRightUtils.js.map +1 -1
  46. package/out/language-server/inline-completion/session/sessionManager.d.ts +1 -0
  47. package/out/language-server/inline-completion/session/sessionManager.js +1 -0
  48. package/out/language-server/inline-completion/session/sessionManager.js.map +1 -1
  49. package/out/language-server/workspaceContext/util.js +2 -2
  50. package/out/language-server/workspaceContext/util.js.map +1 -1
  51. package/out/shared/codeWhispererService.js +8 -0
  52. package/out/shared/codeWhispererService.js.map +1 -1
  53. package/out/shared/imageVerification.d.ts +31 -0
  54. package/out/shared/imageVerification.js +94 -0
  55. package/out/shared/imageVerification.js.map +1 -0
  56. package/out/shared/testUtils.d.ts +3 -0
  57. package/out/shared/testUtils.js +21 -1
  58. package/out/shared/testUtils.js.map +1 -1
  59. package/package.json +5 -4
  60. package/out/language-server/agenticChat/context/addtionalContextProvider.d.ts +0 -46
  61. package/out/language-server/agenticChat/context/addtionalContextProvider.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,32 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.0.61](https://github.com/aws/language-servers/compare/lsp-codewhisperer/v0.0.60...lsp-codewhisperer/v0.0.61) (2025-07-02)
4
+
5
+
6
+ ### Features
7
+
8
+ * add logic to merge with previous suggestions for EDITS ([#1791](https://github.com/aws/language-servers/issues/1791)) ([072d13b](https://github.com/aws/language-servers/commit/072d13b08168f256ea3695bea03cf37b27d91f81))
9
+ * **amazonq:** migrating / agents to q agentic chat ([#1799](https://github.com/aws/language-servers/issues/1799)) ([559b2ba](https://github.com/aws/language-servers/commit/559b2baec7da7b8fffb697990e3b249ffffcb85c))
10
+ * **amazonq:** read and validate the images as context ([#1716](https://github.com/aws/language-servers/issues/1716)) ([7a5d41f](https://github.com/aws/language-servers/commit/7a5d41f3cff7309d04d952fbb5dc063fb8658a06))
11
+
12
+
13
+ ### Bug Fixes
14
+
15
+ * adjust vs code auto trigger coefficients ([#1806](https://github.com/aws/language-servers/issues/1806)) ([25b1d1a](https://github.com/aws/language-servers/commit/25b1d1a1930f7d0cb922d3a085cbaac2a09340b9))
16
+ * **amazonq:** remove the stack trace check from service unavailable exceptions ([#1810](https://github.com/aws/language-servers/issues/1810)) ([a5677f0](https://github.com/aws/language-servers/commit/a5677f03d54aa8e42a71e71c524700c23825ed35))
17
+
18
+ * **amazonq:** send pinned context and rules as message pair ([#1762](https://github.com/aws/language-servers/issues/1762)) ([322add6](https://github.com/aws/language-servers/commit/322add6f8b3b6edd5b3e4b37fc783a1079f15596))
19
+ * connect chat history to workspace file ([#1767](https://github.com/aws/language-servers/issues/1767)) ([4575727](https://github.com/aws/language-servers/commit/4575727911a4efb21a3f24a3d400c7844451c243))
20
+ * do not auto trigger when there is immediate right context for VSC/JB ([#1802](https://github.com/aws/language-servers/issues/1802)) ([fdb29d4](https://github.com/aws/language-servers/commit/fdb29d472c5a0bc7e0a89f5611245248c380cfe8))
21
+ * setting shouldDisplayMessage to false for /agents ([#1811](https://github.com/aws/language-servers/issues/1811)) ([4a72cf7](https://github.com/aws/language-servers/commit/4a72cf7bbc9081f65c4e88c3ab42441a21ec6e03))
22
+
23
+
24
+ ### Dependencies
25
+
26
+ * The following workspace dependencies were updated
27
+ * dependencies
28
+ * @aws/lsp-core bumped from ^0.0.10 to ^0.0.11
29
+
3
30
  ## [0.0.60](https://github.com/aws/language-servers/compare/lsp-codewhisperer/v0.0.59...lsp-codewhisperer/v0.0.60) (2025-06-30)
4
31
 
5
32
 
@@ -4,7 +4,7 @@
4
4
  */
5
5
  import { 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 } from '@aws/language-server-runtimes/protocol';
7
+ import { Status, ButtonClickParams, ButtonClickResult, InlineChatResultParams, PromptInputOptionChangeParams, RuleClickParams, ListRulesParams, ActiveEditorChangedParams, PinnedContextParams, ExecuteCommandParams, FollowUpClickParams, OpenFileDialogParams, OpenFileDialogResult } from '@aws/language-server-runtimes/protocol';
8
8
  import { FeedbackParams, InsertToCursorPositionParams, InlineChatParams, ConversationClickParams, ListConversationsParams, ListMcpServersParams, McpServerClickParams, TabBarActionParams, CreatePromptParams, FileClickParams } from '@aws/language-server-runtimes/protocol';
9
9
  import { CancellationToken, Chat, ChatParams, ChatResult, EndChatParams, QuickActionParams, ResponseError, TabAddParams, TabRemoveParams, TabChangeParams, InlineChatResult } from '@aws/language-server-runtimes/server-interface';
10
10
  import { Features, LspHandlers } from '../types';
@@ -14,13 +14,15 @@ import { AmazonQBaseServiceManager } from '../../shared/amazonQServiceManager/Ba
14
14
  import { AmazonQWorkspaceConfig } from '../../shared/amazonQServiceManager/configurationUtils';
15
15
  import { ChatSessionService } from '../chat/chatSessionService';
16
16
  import { AgenticChatResultStream } from './agenticChatResultStream';
17
+ import { AdditionalContentEntryAddition } from './context/agenticChatTriggerContext';
17
18
  import { PaidTierMode } from '../paidTier/paidTier';
18
- type ChatHandlers = Omit<LspHandlers<Chat>, 'openTab' | 'sendChatUpdate' | 'sendContextCommands' | 'onListConversations' | 'onConversationClick' | 'onListMcpServers' | 'onMcpServerClick' | 'onTabBarAction' | 'getSerializedChat' | 'chatOptionsUpdate' | 'onListMcpServers' | 'onMcpServerClick' | 'onListRules' | 'sendPinnedContext' | 'onActiveEditorChanged' | 'onPinnedContextAdd' | 'onPinnedContextRemove' | 'onOpenFileDialog'>;
19
+ type ChatHandlers = Omit<LspHandlers<Chat>, 'openTab' | 'sendChatUpdate' | 'sendContextCommands' | 'onListConversations' | 'onConversationClick' | 'onListMcpServers' | 'onMcpServerClick' | 'onTabBarAction' | 'getSerializedChat' | 'chatOptionsUpdate' | 'onListMcpServers' | 'onMcpServerClick' | 'onListRules' | 'sendPinnedContext' | 'onActiveEditorChanged' | 'onPinnedContextAdd' | 'onPinnedContextRemove' | 'onOpenFileDialog' | 'onListAvailableModels'>;
19
20
  export declare class AgenticChatController implements ChatHandlers {
20
21
  #private;
21
22
  constructor(chatSessionManagementService: ChatSessionManagementService, features: Features, telemetryService: TelemetryService, serviceManager?: AmazonQBaseServiceManager);
22
23
  onExecuteCommand(params: ExecuteCommandParams, _token: CancellationToken): Promise<any>;
23
24
  onButtonClick(params: ButtonClickParams): Promise<ButtonClickResult>;
25
+ onOpenFileDialog(params: OpenFileDialogParams, token: CancellationToken): Promise<OpenFileDialogResult>;
24
26
  onCreatePrompt(params: CreatePromptParams): Promise<void>;
25
27
  dispose(): void;
26
28
  onListConversations(params: ListConversationsParams): Promise<import("@aws/language-server-runtimes/protocol").ListConversationsResult>;
@@ -41,12 +43,13 @@ export declare class AgenticChatController implements ChatHandlers {
41
43
  }>;
42
44
  onMcpServerClick(params: McpServerClickParams): Promise<any>;
43
45
  onChatPrompt(params: ChatParams, token: CancellationToken): Promise<ChatResult | ResponseError<ChatResult>>;
46
+ truncatePinnedContext(remainingCharacterBudget: number, pinnedContext?: AdditionalContentEntryAddition[]): number;
44
47
  /**
45
48
  * performs truncation of request before sending to backend service.
46
49
  * Returns the remaining character budget for chat history.
47
50
  * @param request
48
51
  */
49
- truncateRequest(request: ChatCommandInput): number;
52
+ truncateRequest(request: ChatCommandInput, pinnedContext?: AdditionalContentEntryAddition[]): number;
50
53
  /**
51
54
  * Creates a promise that does not resolve until the user accepts or rejects the tool usage.
52
55
  * @param toolUseId
@@ -28,7 +28,7 @@ const agenticChatEventParser_1 = require("./agenticChatEventParser");
28
28
  const agenticChatResultStream_1 = require("./agenticChatResultStream");
29
29
  const textFormatting_1 = require("./textFormatting");
30
30
  const agenticChatTriggerContext_1 = require("./context/agenticChatTriggerContext");
31
- const addtionalContextProvider_1 = require("./context/addtionalContextProvider");
31
+ const additionalContextProvider_1 = require("./context/additionalContextProvider");
32
32
  const contextUtils_1 = require("./context/contextUtils");
33
33
  const contextCommandsProvider_1 = require("./context/contextCommandsProvider");
34
34
  const localProjectContextController_1 = require("../../shared/localProjectContextController");
@@ -54,6 +54,8 @@ const mcpManager_1 = require("./tools/mcp/mcpManager");
54
54
  const mcpTool_1 = require("./tools/mcp/mcpTool");
55
55
  const paidTier_1 = require("../paidTier/paidTier");
56
56
  const util_1 = require("./tools/chatDb/util");
57
+ const imageVerification_1 = require("../../shared/imageVerification");
58
+ const path_1 = require("@aws/lsp-core/out/util/path");
57
59
  class AgenticChatController {
58
60
  #features;
59
61
  #chatSessionManagementService;
@@ -104,7 +106,7 @@ class AgenticChatController {
104
106
  });
105
107
  this.#chatHistoryDb = new chatDb_1.ChatDatabase(features);
106
108
  this.#tabBarController = new tabBarController_1.TabBarController(features, this.#chatHistoryDb, telemetryService, (tabId) => this.sendPinnedContext(tabId));
107
- this.#additionalContextProvider = new addtionalContextProvider_1.AdditionalContextProvider(features, this.#chatHistoryDb);
109
+ this.#additionalContextProvider = new additionalContextProvider_1.AdditionalContextProvider(features, this.#chatHistoryDb);
108
110
  this.#contextCommandsProvider = new contextCommandsProvider_1.ContextCommandsProvider(this.#features.logging, this.#features.chat, this.#features.workspace, this.#features.lsp);
109
111
  this.#mcpEventHandler = new mcpEventHandler_1.McpEventHandler(features, telemetryService);
110
112
  this.#origin = (0, utils_2.getOriginFromClientInfo)(this.#features.lsp.getClientInitializeParams()?.clientInfo?.name);
@@ -261,6 +263,71 @@ class AgenticChatController {
261
263
  await this.onButtonClick({ buttonId: 'undo-changes', messageId, tabId });
262
264
  }
263
265
  }
266
+ async onOpenFileDialog(params, token) {
267
+ if (params.fileType === 'image') {
268
+ // 1. Prompt user for file selection
269
+ const supportedExtensions = imageVerification_1.DEFAULT_IMAGE_VERIFICATION_OPTIONS.supportedExtensions;
270
+ const filters = { 'Image Files': supportedExtensions.map(ext => `*.${ext}`) };
271
+ const result = await this.#features.lsp.window.showOpenDialog({
272
+ canSelectFiles: true,
273
+ canSelectFolders: false,
274
+ canSelectMany: false,
275
+ filters,
276
+ });
277
+ if (!result.uris || result.uris.length === 0) {
278
+ return {
279
+ tabId: params.tabId,
280
+ filePaths: [],
281
+ fileType: params.fileType,
282
+ insertPosition: params.insertPosition,
283
+ errorMessage: 'No file selected.',
284
+ };
285
+ }
286
+ const validFilePaths = [];
287
+ let errorMessage;
288
+ for (const filePath of result.uris) {
289
+ // Extract filename from the URI for error messages
290
+ const fileName = filePath.split('/').pop() || '';
291
+ const sanitizedPath = (0, path_1.sanitize)(filePath);
292
+ // Get file size and content for verification
293
+ const size = await this.#features.workspace.fs.getFileSize(sanitizedPath);
294
+ const fileContent = await this.#features.workspace.fs.readFile(sanitizedPath, {
295
+ encoding: 'binary',
296
+ });
297
+ const imageBuffer = Buffer.from(fileContent, 'binary');
298
+ // Use centralized verification utility
299
+ const verificationResult = await (0, imageVerification_1.verifyServerImage)(fileName, size.size, imageBuffer);
300
+ if (verificationResult.isValid) {
301
+ validFilePaths.push(filePath);
302
+ }
303
+ else {
304
+ errorMessage = verificationResult.errors[0]; // Use first error message
305
+ }
306
+ }
307
+ if (validFilePaths.length === 0) {
308
+ return {
309
+ tabId: params.tabId,
310
+ filePaths: [],
311
+ fileType: params.fileType,
312
+ insertPosition: params.insertPosition,
313
+ errorMessage: errorMessage || 'No valid image selected.',
314
+ };
315
+ }
316
+ // All valid files
317
+ return {
318
+ tabId: params.tabId,
319
+ filePaths: validFilePaths,
320
+ fileType: params.fileType,
321
+ insertPosition: params.insertPosition,
322
+ };
323
+ }
324
+ return {
325
+ tabId: params.tabId,
326
+ filePaths: [],
327
+ fileType: params.fileType,
328
+ insertPosition: params.insertPosition,
329
+ };
330
+ }
264
331
  async onCreatePrompt(params) {
265
332
  if (params.isRule) {
266
333
  let workspaceFolders = lsp_core_1.workspaceUtils.getWorkspaceFolderPaths(this.#features.workspace);
@@ -370,17 +437,35 @@ class AgenticChatController {
370
437
  });
371
438
  session.setConversationType('AgenticChat');
372
439
  const additionalContext = await this.#additionalContextProvider.getAdditionalContext(triggerContext, params.tabId, params.context);
440
+ // Add active file to context list if it exists
441
+ const activeFile = triggerContext.text && triggerContext.relativeFilePath && triggerContext.activeFilePath
442
+ ? [
443
+ {
444
+ name: path.basename(triggerContext.relativeFilePath),
445
+ description: '',
446
+ type: 'file',
447
+ relativePath: triggerContext.relativeFilePath,
448
+ path: triggerContext.activeFilePath,
449
+ startLine: -1,
450
+ endLine: -1,
451
+ },
452
+ ]
453
+ : [];
454
+ // Combine additional context with active file and get file list to display at top of response
455
+ const contextItems = [...additionalContext, ...activeFile];
456
+ triggerContext.documentReference = this.#additionalContextProvider.getFileListFromContext(contextItems);
373
457
  if (additionalContext.length) {
374
458
  triggerContext.documentReference =
375
459
  this.#additionalContextProvider.getFileListFromContext(additionalContext);
376
460
  }
461
+ const customContext = await this.#additionalContextProvider.getImageBlocksFromContext(params.context, params.tabId);
377
462
  // Get the initial request input
378
- const initialRequestInput = await this.#prepareRequestInput(params, session, triggerContext, additionalContext, chatResultStream);
463
+ const initialRequestInput = await this.#prepareRequestInput(params, session, triggerContext, additionalContext, chatResultStream, customContext);
379
464
  // Generate a unique ID for this prompt
380
465
  const promptId = crypto.randomUUID();
381
466
  session.setCurrentPromptId(promptId);
382
467
  // Start the agent loop
383
- const finalResult = await this.#runAgentLoop(initialRequestInput, session, metric, chatResultStream, params.tabId, promptId, session.conversationId, token, triggerContext.documentReference);
468
+ const finalResult = await this.#runAgentLoop(initialRequestInput, session, metric, chatResultStream, params.tabId, promptId, session.conversationId, token, triggerContext.documentReference, additionalContext.filter(item => item.pinned));
384
469
  // Phase 5: Result Handling - This happens only once
385
470
  return await this.#handleFinalResult(finalResult, session, params, metric, triggerContext, isNewConversation, chatResultStream);
386
471
  }
@@ -414,17 +499,17 @@ class AgenticChatController {
414
499
  /**
415
500
  * Prepares the initial request input for the chat prompt
416
501
  */
417
- async #prepareRequestInput(params, session, triggerContext, additionalContext, chatResultStream) {
502
+ async #prepareRequestInput(params, session, triggerContext, additionalContext, chatResultStream, customContext) {
418
503
  this.#debug('Preparing request input');
419
504
  // Get profileArn from the service manager if available
420
505
  const profileArn = this.#serviceManager?.getActiveProfileArn();
421
- const requestInput = await this.#triggerContext.getChatParamsFromTrigger(params, triggerContext, codewhisperer_streaming_1.ChatTriggerType.MANUAL, this.#customizationArn, chatResultStream, profileArn, [], this.#getTools(session), additionalContext, session.modelId, this.#origin);
506
+ const requestInput = await this.#triggerContext.getChatParamsFromTrigger(params, triggerContext, codewhisperer_streaming_1.ChatTriggerType.MANUAL, this.#customizationArn, chatResultStream, profileArn, [], this.#getTools(session), additionalContext, session.modelId, this.#origin, customContext);
422
507
  return requestInput;
423
508
  }
424
509
  /**
425
510
  * Runs the agent loop, making requests and processing tool uses until completion
426
511
  */
427
- async #runAgentLoop(initialRequestInput, session, metric, chatResultStream, tabId, promptId, conversationIdentifier, token, documentReference) {
512
+ async #runAgentLoop(initialRequestInput, session, metric, chatResultStream, tabId, promptId, conversationIdentifier, token, documentReference, pinnedContext) {
428
513
  let currentRequestInput = { ...initialRequestInput };
429
514
  let finalResult = null;
430
515
  let iterationCount = 0;
@@ -441,17 +526,20 @@ class AgenticChatController {
441
526
  this.#debug('Stopping agent loop - cancelled by user');
442
527
  throw new lsp_core_1.CancellationError('user');
443
528
  }
444
- this.truncateRequest(currentRequestInput);
529
+ this.truncateRequest(currentRequestInput, pinnedContext);
445
530
  const currentMessage = currentRequestInput.conversationState?.currentMessage;
446
531
  const conversationId = conversationIdentifier ?? '';
447
532
  if (!currentMessage || !conversationId) {
448
533
  this.#debug(`Warning: ${!currentMessage ? 'currentMessage' : ''}${!currentMessage && !conversationId ? ' and ' : ''}${!conversationId ? 'conversationIdentifier' : ''} is empty in agent loop iteration ${iterationCount}.`);
449
534
  }
450
535
  let messages = [];
536
+ // Prepend pinned context to history as a fake message pair
537
+ // This ensures pinned context doesn't get added to history file, and fulfills API contract requiring message pairs.
538
+ let pinnedContextMessages = await this.#additionalContextProvider.convertPinnedContextToChatMessages(pinnedContext, this.#features.workspace.getWorkspaceFolder);
451
539
  if (currentMessage) {
452
540
  // Get and process the messages from history DB to maintain invariants for service requests
453
541
  try {
454
- messages = this.#chatHistoryDb.fixAndGetHistory(tabId, currentMessage);
542
+ messages = this.#chatHistoryDb.fixAndGetHistory(tabId, currentMessage, pinnedContextMessages);
455
543
  }
456
544
  catch (err) {
457
545
  if (err instanceof chatDb_1.ToolResultValidationError) {
@@ -493,7 +581,8 @@ class AgenticChatController {
493
581
  userIntent: currentMessage.userInputMessage?.userIntent,
494
582
  origin: currentMessage.userInputMessage?.origin,
495
583
  userInputMessageContext: currentMessage.userInputMessage?.userInputMessageContext,
496
- shouldDisplayMessage: shouldDisplayMessage,
584
+ shouldDisplayMessage: shouldDisplayMessage &&
585
+ !currentMessage.userInputMessage?.content?.startsWith('You are Amazon Q'),
497
586
  timestamp: new Date(),
498
587
  });
499
588
  }
@@ -614,12 +703,30 @@ class AgenticChatController {
614
703
  data: { chatResult: {}, toolUses: {} },
615
704
  });
616
705
  }
706
+ truncatePinnedContext(remainingCharacterBudget, pinnedContext) {
707
+ if (!pinnedContext) {
708
+ return remainingCharacterBudget;
709
+ }
710
+ for (const [i, pinnedContextEntry] of pinnedContext.entries()) {
711
+ const pinnedContextEntryLength = pinnedContextEntry.innerContext?.length || 0;
712
+ if (remainingCharacterBudget >= pinnedContextEntryLength) {
713
+ remainingCharacterBudget -= pinnedContextEntryLength;
714
+ }
715
+ else {
716
+ // Budget exceeded, truncate the array at this point
717
+ pinnedContext.splice(i);
718
+ remainingCharacterBudget = 0;
719
+ break;
720
+ }
721
+ }
722
+ return remainingCharacterBudget;
723
+ }
617
724
  /**
618
725
  * performs truncation of request before sending to backend service.
619
726
  * Returns the remaining character budget for chat history.
620
727
  * @param request
621
728
  */
622
- truncateRequest(request) {
729
+ truncateRequest(request, pinnedContext) {
623
730
  // TODO: Confirm if this limit applies to SendMessage and rename this constant
624
731
  let remainingCharacterBudget = constants_2.generateAssistantResponseInputLimit;
625
732
  if (!request?.conversationState?.currentMessage?.userInputMessage) {
@@ -668,6 +775,10 @@ class AgenticChatController {
668
775
  request.conversationState.currentMessage.userInputMessage.userInputMessageContext.editorState.document =
669
776
  truncatedCurrentDocument;
670
777
  }
778
+ // 4. try to fit pinned context into budget
779
+ if (pinnedContext && pinnedContext.length > 0) {
780
+ remainingCharacterBudget = this.truncatePinnedContext(remainingCharacterBudget, pinnedContext);
781
+ }
671
782
  return remainingCharacterBudget;
672
783
  }
673
784
  /**