Skip to content

Commit fe06af6

Browse files
authored
fix: refresh prompt list when project prompt is added (#16)
* fix: refresh prompt list when project prompt is added * fix: validate length and size of additionalContents * fix: truncate additionalContents based on api validation limits * fix: move constants
1 parent a5044f4 commit fe06af6

File tree

2 files changed

+59
-45
lines changed

2 files changed

+59
-45
lines changed

packages/core/src/amazonq/lsp/lspController.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ export interface Manifest {
6161
targets: Target[]
6262
}[]
6363
}
64-
const manifestUrl = 'https://ducvaeoffl85c.cloudfront.net/manifest-0.1.39.json'
64+
const manifestUrl = 'https://aws-toolkit-language-servers.amazonaws.com/q-context/manifest.json'
6565
// this LSP client in Q extension is only going to work with these LSP server versions
6666
const supportedLspServerVersions = ['0.1.39']
6767

packages/core/src/codewhispererChat/controllers/chat/controller.ts

Lines changed: 58 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,12 @@ export interface ChatControllerMessageListeners {
121121
readonly processFileClick: MessageListener<FileClick>
122122
}
123123

124+
const promptFileExtension = '.prompt'
125+
126+
const additionalContentInnerContextLimit = 8192
127+
128+
const aditionalContentNameLimit = 1024
129+
124130
export class ChatController {
125131
private readonly sessionStorage: ChatSessionStorage
126132
private readonly triggerEventsStorage: TriggerEventsStorage
@@ -450,55 +456,31 @@ export class ChatController {
450456
commands: [{ command: commandName, description: commandDescription }],
451457
})
452458
}
453-
454-
const lspClientReady = await LspClient.instance.waitUntilReady()
455-
if (!lspClientReady) {
456-
return
457-
}
458-
const contextCommandItems = await LspClient.instance.getContextCommandItems()
459-
const folderCmd: QuickActionCommand = contextCommand[0].commands?.[1]
460-
const filesCmd: QuickActionCommand = contextCommand[0].commands?.[2]
461459
const promptsCmd: QuickActionCommand = contextCommand[0].commands?.[3]
462460

463-
for (const contextCommandItem of contextCommandItems) {
464-
const wsFolderName = path.basename(contextCommandItem.workspaceFolder)
465-
if (contextCommandItem.type === 'file') {
466-
filesCmd.children?.[0].commands.push({
467-
command: path.basename(contextCommandItem.relativePath),
468-
description: path.join(wsFolderName, contextCommandItem.relativePath),
469-
route: [contextCommandItem.workspaceFolder, contextCommandItem.relativePath],
470-
icon: 'file' as MynahIconsType,
471-
})
461+
// Check .aws/prompts for prompt files in workspace
462+
const workspacePromptFiles = await vscode.workspace.findFiles(`.aws/prompts/*${promptFileExtension}`)
472463

473-
// If file is a .prompt type, add to prompts list
474-
if (contextCommandItem.relativePath.endsWith('.prompt')) {
475-
promptsCmd.children?.[0].commands.push({
476-
command: path.basename(contextCommandItem.relativePath, '.prompt'),
477-
route: [contextCommandItem.workspaceFolder, contextCommandItem.relativePath],
478-
icon: 'magic' as MynahIconsType,
479-
})
480-
}
481-
} else {
482-
folderCmd.children?.[0].commands.push({
483-
command: path.basename(contextCommandItem.relativePath),
484-
description: path.join(wsFolderName, contextCommandItem.relativePath),
485-
route: [contextCommandItem.workspaceFolder, contextCommandItem.relativePath],
486-
icon: 'folder' as MynahIconsType,
487-
})
488-
}
464+
if (workspacePromptFiles.length > 0) {
465+
promptsCmd.children?.[0].commands.push(
466+
...workspacePromptFiles.map((file) => ({
467+
command: path.basename(file.path, promptFileExtension),
468+
icon: 'magic' as MynahIconsType,
469+
route: [path.dirname(file.path), path.basename(file.path)],
470+
}))
471+
)
489472
}
490-
491-
// Check ~/.aws/prompts for saved prompts
473+
// Check ~/.aws/prompts for global prompt files
492474
try {
493475
const systemPromptsDirectory = path.join(fs.getUserHomeDir(), '.aws', 'prompts')
494476
const directoryExists = await fs.exists(systemPromptsDirectory)
495477
if (directoryExists) {
496478
const systemPromptFiles = await fs.readdir(systemPromptsDirectory)
497479
promptsCmd.children?.[0].commands.push(
498480
...systemPromptFiles
499-
.filter(([name]) => name.endsWith('.prompt'))
481+
.filter(([name]) => name.endsWith(promptFileExtension))
500482
.map(([name]) => ({
501-
command: name.replace(/\.prompt$/, ''),
483+
command: path.basename(name, promptFileExtension),
502484
icon: 'magic' as MynahIconsType,
503485
route: [systemPromptsDirectory, name],
504486
}))
@@ -511,6 +493,32 @@ export class ChatController {
511493
// Add create prompt button to the bottom of the prompts list
512494
promptsCmd.children?.[0].commands.push({ command: createPromptCommand, icon: 'list-add' as MynahIconsType })
513495

496+
const lspClientReady = await LspClient.instance.waitUntilReady()
497+
if (lspClientReady) {
498+
const contextCommandItems = await LspClient.instance.getContextCommandItems()
499+
const folderCmd: QuickActionCommand = contextCommand[0].commands?.[1]
500+
const filesCmd: QuickActionCommand = contextCommand[0].commands?.[2]
501+
502+
for (const contextCommandItem of contextCommandItems) {
503+
const wsFolderName = path.basename(contextCommandItem.workspaceFolder)
504+
if (contextCommandItem.type === 'file') {
505+
filesCmd.children?.[0].commands.push({
506+
command: path.basename(contextCommandItem.relativePath),
507+
description: path.join(wsFolderName, contextCommandItem.relativePath),
508+
route: [contextCommandItem.workspaceFolder, contextCommandItem.relativePath],
509+
icon: 'file' as MynahIconsType,
510+
})
511+
} else {
512+
folderCmd.children?.[0].commands.push({
513+
command: path.basename(contextCommandItem.relativePath),
514+
description: path.join(wsFolderName, contextCommandItem.relativePath),
515+
route: [contextCommandItem.workspaceFolder, contextCommandItem.relativePath],
516+
icon: 'folder' as MynahIconsType,
517+
})
518+
}
519+
}
520+
}
521+
514522
this.messenger.sendContextCommandData(contextCommand)
515523
}
516524

@@ -532,7 +540,7 @@ export class ChatController {
532540
title: 'Save globally for all projects?',
533541
mandatory: true,
534542
value: 'system',
535-
description: 'If yes is selected, .prompt file will be saved in ~/.aws/prompts.',
543+
description: `If yes is selected, ${promptFileExtension} file will be saved in ~/.aws/prompts.`,
536544
options: [
537545
{ value: 'project', label: 'No' },
538546
{ value: 'system', label: 'Yes' },
@@ -566,7 +574,10 @@ export class ChatController {
566574
}
567575

568576
const title = message.action.formItemValues?.['prompt-name']
569-
const newFilePath = path.join(promptsDirectory, title ? `${title}.prompt` : 'default.prompt')
577+
const newFilePath = path.join(
578+
promptsDirectory,
579+
title ? `${title}${promptFileExtension}` : `default${promptFileExtension}`
580+
)
570581
const newFileContent = new Uint8Array(Buffer.from(''))
571582
await fs.writeFile(newFilePath, newFileContent)
572583
const newFileDoc = await vscode.workspace.openTextDocument(newFilePath)
@@ -878,11 +889,14 @@ export class ChatController {
878889
if (prompts.length > 0) {
879890
triggerPayload.additionalContents = []
880891
for (const prompt of prompts) {
881-
triggerPayload.additionalContents.push({
882-
name: prompt.name,
883-
description: prompt.description,
884-
innerContext: prompt.content,
885-
})
892+
// Todo: add mechanism for sorting/prioritization of additional context
893+
if (triggerPayload.additionalContents.length < 20) {
894+
triggerPayload.additionalContents.push({
895+
name: prompt.name.substring(0, aditionalContentNameLimit),
896+
description: prompt.description.substring(0, aditionalContentNameLimit),
897+
innerContext: prompt.content.substring(0, additionalContentInnerContextLimit),
898+
})
899+
}
886900
}
887901
getLogger().info(
888902
`Retrieved chunks of additional context count: ${triggerPayload.additionalContents.length} `

0 commit comments

Comments
 (0)