Skip to content

Commit eb6bbcb

Browse files
authored
Add 'create a new prompt' context to bottom of prompts list (#8)
* feat(amazonq): saved prompts * fix: remove unecessary change * feat(amazonq): saved prompts * fix: remove unecessary change * feat(amazonq): add Create a new prompt button to context
1 parent 7a3f7fe commit eb6bbcb

File tree

11 files changed

+122
-44
lines changed

11 files changed

+122
-44
lines changed

package-lock.json

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/core/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -510,7 +510,7 @@
510510
"@aws-sdk/property-provider": "<3.696.0",
511511
"@aws-sdk/smithy-client": "<3.696.0",
512512
"@aws-sdk/util-arn-parser": "<3.696.0",
513-
"@aws/mynah-ui": "^4.23.0-beta.5",
513+
"@aws/mynah-ui": "^4.23.0-beta.7",
514514
"@gerhobbelt/gitignore-parser": "^0.2.0-9",
515515
"@iarna/toml": "^2.2.5",
516516
"@smithy/middleware-retry": "^3.0.0",

packages/core/src/amazonq/webview/ui/apps/cwChatConnector.ts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@
33
* SPDX-License-Identifier: Apache-2.0
44
*/
55

6-
import { ChatItemButton, ChatItemFormItem, ChatItemType, MynahUIDataModel } from '@aws/mynah-ui'
6+
import { ChatItemButton, ChatItemFormItem, ChatItemType, MynahUIDataModel, QuickActionCommand } from '@aws/mynah-ui'
77
import { TabType } from '../storages/tabsStorage'
88
import { CWCChatItem } from '../connector'
99
import { BaseConnector, BaseConnectorProps } from './baseConnector'
10+
import { createPromptCommand } from '../tabs/constants'
1011

1112
export interface ConnectorProps extends BaseConnectorProps {
1213
onCWCContextCommandMessage: (message: CWCChatItem, command?: string) => string | undefined
@@ -171,7 +172,7 @@ export class Connector extends BaseConnector {
171172
}
172173

173174
if (messageData.type === 'contextCommandData') {
174-
await this.processContextCommandData(messageData)
175+
this.processContextCommandData(messageData)
175176
return
176177
}
177178
if (messageData.type === 'showCustomFormMessage') {
@@ -196,6 +197,20 @@ export class Connector extends BaseConnector {
196197
})
197198
}
198199

200+
onContextSelected = (tabID: string, contextItem: QuickActionCommand) => {
201+
this.sendMessageToExtension({
202+
command: 'context-selected',
203+
contextItem,
204+
tabID,
205+
tabType: this.getTabType(),
206+
})
207+
208+
if (contextItem.command === createPromptCommand) {
209+
return false
210+
}
211+
return true
212+
}
213+
199214
onCustomFormAction(
200215
tabId: string,
201216
action: {

packages/core/src/amazonq/webview/ui/commands.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,5 +43,6 @@ type MessageCommand =
4343
| 'send-telemetry'
4444
| 'update-welcome-count'
4545
| 'quick-command-group-action-click'
46+
| 'context-selected'
4647

4748
export type ExtensionMessage = Record<string, any> & { command: MessageCommand }

packages/core/src/amazonq/webview/ui/connector.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -623,12 +623,27 @@ export class Connector {
623623

624624
onQuickCommandGroupActionClick = (tabId: string, action: { id: string }) => {
625625
switch (this.tabsStorage.getTab(tabId)?.type) {
626+
case 'welcome':
627+
case 'unknown':
626628
case 'cwc':
629+
this.tabsStorage.updateTabTypeFromUnknown(tabId, 'cwc')
627630
this.cwChatConnector.onQuickCommandGroupActionClick(tabId, action)
628631
break
629632
}
630633
}
631634

635+
onContextSelected = (contextItem: QuickActionCommand, tabId: string) => {
636+
switch (this.tabsStorage.getTab(tabId)?.type) {
637+
case 'welcome':
638+
case 'unknown':
639+
case 'cwc':
640+
this.tabsStorage.updateTabTypeFromUnknown(tabId, 'cwc')
641+
return this.cwChatConnector.onContextSelected(tabId, contextItem)
642+
default:
643+
return true
644+
}
645+
}
646+
632647
onChatItemVoted = (tabId: string, messageId: string, vote: 'upvote' | 'downvote'): void | undefined => {
633648
switch (this.tabsStorage.getTab(tabId)?.type) {
634649
case 'cwc':

packages/core/src/amazonq/webview/ui/main.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -682,6 +682,7 @@ export const createMynahUI = (
682682
textMessageHandler.handle(prompt, tabID, eventId as string)
683683
},
684684
onQuickCommandGroupActionClick: connector.onQuickCommandGroupActionClick,
685+
onContextSelected: connector.onContextSelected,
685686
onVote: connector.onChatItemVoted,
686687
onInBodyButtonClicked: (tabId, messageId, action, eventId) => {
687688
switch (action.id) {

packages/core/src/amazonq/webview/ui/tabs/constants.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ export type TabTypeData = {
1313
contextCommands?: QuickActionCommandGroup[]
1414
}
1515

16+
export const createPromptCommand = 'Create a new prompt'
17+
1618
export const workspaceCommand: QuickActionCommandGroup = {
1719
groupName: 'Mention code',
1820
commands: [

packages/core/src/codewhispererChat/app.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import {
2929
QuickCommandGroupActionClick,
3030
} from './controllers/chat/model'
3131
import { EditorContextCommand, registerCommands } from './commands/registerCommands'
32-
import { CustomFormActionMessage } from './view/connector/connector'
32+
import { ContextSelectedMessage, CustomFormActionMessage } from './view/connector/connector'
3333

3434
export function init(appContext: AmazonQAppInitContext) {
3535
const cwChatControllerEventEmitters = {
@@ -53,6 +53,7 @@ export function init(appContext: AmazonQAppInitContext) {
5353
processContextCommandUpdateMessage: new EventEmitter<any>(),
5454
processQuickCommandGroupActionClicked: new EventEmitter<QuickCommandGroupActionClick>(),
5555
processCustomFormAction: new EventEmitter<CustomFormActionMessage>(),
56+
processContextSelected: new EventEmitter<ContextSelectedMessage>(),
5657
}
5758

5859
const cwChatControllerMessageListeners = {
@@ -110,6 +111,9 @@ export function init(appContext: AmazonQAppInitContext) {
110111
processCustomFormAction: new MessageListener<CustomFormActionMessage>(
111112
cwChatControllerEventEmitters.processCustomFormAction
112113
),
114+
processContextSelected: new MessageListener<ContextSelectedMessage>(
115+
cwChatControllerEventEmitters.processContextSelected
116+
),
113117
}
114118

115119
const cwChatControllerMessagePublishers = {
@@ -169,6 +173,9 @@ export function init(appContext: AmazonQAppInitContext) {
169173
processCustomFormAction: new MessagePublisher<CustomFormActionMessage>(
170174
cwChatControllerEventEmitters.processCustomFormAction
171175
),
176+
processContextSelected: new MessagePublisher<ContextSelectedMessage>(
177+
cwChatControllerEventEmitters.processContextSelected
178+
),
172179
}
173180

174181
new CwChatController(

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

Lines changed: 55 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,11 @@ import {
2929
AcceptDiff,
3030
QuickCommandGroupActionClick,
3131
} from './model'
32-
import { AppToWebViewMessageDispatcher, CustomFormActionMessage } from '../../view/connector/connector'
32+
import {
33+
AppToWebViewMessageDispatcher,
34+
ContextSelectedMessage,
35+
CustomFormActionMessage,
36+
} from '../../view/connector/connector'
3337
import { MessagePublisher } from '../../../amazonq/messages/messagePublisher'
3438
import { MessageListener } from '../../../amazonq/messages/messageListener'
3539
import { EditorContentController } from '../../../amazonq/commons/controllers/contentController'
@@ -60,7 +64,7 @@ import { waitUntil } from '../../../shared/utilities/timeoutUtils'
6064
import { MynahIconsType, MynahUIDataModel, QuickActionCommand } from '@aws/mynah-ui'
6165
import { LspClient } from '../../../amazonq/lsp/lspClient'
6266
import { ContextCommandItem } from '../../../amazonq/lsp/types'
63-
import { workspaceCommand } from '../../../amazonq/webview/ui/tabs/constants'
67+
import { createPromptCommand, workspaceCommand } from '../../../amazonq/webview/ui/tabs/constants'
6468
import fs from '../../../shared/fs/fs'
6569
import * as vscode from 'vscode'
6670

@@ -85,6 +89,7 @@ export interface ChatControllerMessagePublishers {
8589
readonly processContextCommandUpdateMessage: MessagePublisher<void>
8690
readonly processQuickCommandGroupActionClicked: MessagePublisher<QuickCommandGroupActionClick>
8791
readonly processCustomFormAction: MessagePublisher<CustomFormActionMessage>
92+
readonly processContextSelected: MessagePublisher<ContextSelectedMessage>
8893
}
8994

9095
export interface ChatControllerMessageListeners {
@@ -108,6 +113,7 @@ export interface ChatControllerMessageListeners {
108113
readonly processContextCommandUpdateMessage: MessageListener<void>
109114
readonly processQuickCommandGroupActionClicked: MessageListener<QuickCommandGroupActionClick>
110115
readonly processCustomFormAction: MessageListener<CustomFormActionMessage>
116+
readonly processContextSelected: MessageListener<ContextSelectedMessage>
111117
}
112118

113119
export class ChatController {
@@ -234,6 +240,9 @@ export class ChatController {
234240
this.chatControllerMessageListeners.processCustomFormAction.onMessage((data) => {
235241
return this.processCustomFormAction(data)
236242
})
243+
this.chatControllerMessageListeners.processContextSelected.onMessage((data) => {
244+
return this.processContextSelected(data)
245+
})
237246
}
238247

239248
private processFooterInfoLinkClick(click: FooterInfoLinkClick) {
@@ -411,7 +420,6 @@ export class ChatController {
411420
{
412421
id: 'create-prompt',
413422
icon: 'plus',
414-
text: 'Create',
415423
description: 'Create new prompt',
416424
},
417425
],
@@ -478,40 +486,47 @@ export class ChatController {
478486
getLogger().verbose(`Could not read prompts from ~/.aws/prompts: ${e}`)
479487
}
480488

489+
// Add create prompt button to the bottom of the prompts list
490+
promptsCmd.children?.[0].commands.push({ command: createPromptCommand, icon: 'list-add' as MynahIconsType })
491+
481492
this.messenger.sendContextCommandData(contextCommand)
482493
}
483494

484-
private async processQuickCommandGroupActionClicked(message: QuickCommandGroupActionClick) {
495+
private handlePromptCreate(tabID: string) {
496+
this.messenger.showCustomForm(
497+
tabID,
498+
[
499+
{
500+
id: 'prompt-name',
501+
type: 'textinput',
502+
mandatory: true,
503+
title: 'Prompt name',
504+
placeholder: 'Enter prompt name',
505+
description: 'Use this prompt in the chat by typing `@` followed by the prompt name.',
506+
},
507+
{
508+
id: 'shared-scope',
509+
type: 'select',
510+
title: 'Save globally for all projects?',
511+
mandatory: true,
512+
value: 'system',
513+
description: 'If yes is selected, .prompt file will be saved in ~/.aws/prompts.',
514+
options: [
515+
{ value: 'project', label: 'No' },
516+
{ value: 'system', label: 'Yes' },
517+
],
518+
},
519+
],
520+
[
521+
{ id: 'cancel-create-prompt', text: 'Cancel', status: 'clear' },
522+
{ id: 'submit-create-prompt', text: 'Create', status: 'main' },
523+
],
524+
`Create a saved prompt`
525+
)
526+
}
527+
private processQuickCommandGroupActionClicked(message: QuickCommandGroupActionClick) {
485528
if (message.actionId === 'create-prompt') {
486-
this.messenger.showCustomForm(
487-
message.tabID,
488-
[
489-
{
490-
id: 'prompt-name',
491-
type: 'textinput',
492-
mandatory: true,
493-
title: 'Prompt name',
494-
placeholder: 'Enter prompt name',
495-
},
496-
{
497-
id: 'shared-scope',
498-
type: 'select',
499-
title: 'Save globally for all projects?',
500-
mandatory: true,
501-
value: 'system',
502-
options: [
503-
{ value: 'project', label: 'No' },
504-
{ value: 'system', label: 'Yes' },
505-
],
506-
},
507-
],
508-
[
509-
{ id: 'cancel-create-prompt', text: 'Cancel', status: 'clear' },
510-
{ id: 'submit-create-prompt', text: 'Create', status: 'main' },
511-
],
512-
`Create a saved prompt`,
513-
'Use this prompt by typing `@` followed by the prompt name.'
514-
)
529+
this.handlePromptCreate(message.tabID)
515530
}
516531
}
517532

@@ -533,11 +548,17 @@ export class ChatController {
533548
await fs.writeFile(newFilePath, newFileContent)
534549
const newFileDoc = await vscode.workspace.openTextDocument(newFilePath)
535550
await vscode.window.showTextDocument(newFileDoc)
536-
// TO-DO: Trigger regeneration of prompt list in context menu
551+
await this.processContextCommandUpdateMessage()
537552
}
538553
}
539554
}
540555

556+
private async processContextSelected(message: ContextSelectedMessage) {
557+
if (message.tabID && message.contextItem.command === createPromptCommand) {
558+
this.handlePromptCreate(message.tabID)
559+
}
560+
}
561+
541562
private processException(e: any, tabID: string) {
542563
let errorMessage = ''
543564
let requestID = undefined

packages/core/src/codewhispererChat/view/connector/connector.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { Timestamp } from 'aws-sdk/clients/apigateway'
77
import { MessagePublisher } from '../../../amazonq/messages/messagePublisher'
88
import { EditorContextCommandType } from '../../commands/registerCommands'
99
import { AuthFollowUpType } from '../../../amazonq/auth/model'
10-
import { ChatItemButton, ChatItemFormItem, MynahUIDataModel } from '@aws/mynah-ui'
10+
import { ChatItemButton, ChatItemFormItem, MynahUIDataModel, QuickActionCommand } from '@aws/mynah-ui'
1111

1212
class UiMessage {
1313
readonly time: number = Date.now()
@@ -185,6 +185,16 @@ export class ShowCustomFormMessage extends UiMessage {
185185
}
186186
}
187187

188+
export class ContextSelectedMessage extends UiMessage {
189+
override type = 'contextSelectedMessage'
190+
readonly contextItem: QuickActionCommand
191+
192+
constructor(tabID: string, contextItem: QuickActionCommand) {
193+
super(tabID)
194+
this.contextItem = contextItem
195+
}
196+
}
197+
188198
export interface ChatMessageProps {
189199
readonly message: string | undefined
190200
readonly messageType: ChatMessageType

0 commit comments

Comments
 (0)