diff --git a/runtimes/README.md b/runtimes/README.md index c77cca56..797401ed 100644 --- a/runtimes/README.md +++ b/runtimes/README.md @@ -184,6 +184,8 @@ The runtime supports chat by default | Send request to open existing tab, if `tabId` is passed or create and open new tab, if `tabId` is not passed. For the new tab, it's also possible to set tab state and content. | `aws/chat/openTab` | `OpenTabParams` | [Request](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#requestMessage) Server to Client | `OpenTabResult` | | Send chat messages and tab state update to specific tab. Depending on new vs existing`messageId` within `ChatMessage` message, the massgage will be added or updated. | `aws/chat/sendChatUpdate` | `ChatUpdateParams` | [Notification](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#notificationMessage) Server to Client | n/a | | Send file or file action click event. | `aws/chat/fileClick` | `FileClickParams` | [Notification](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#notificationMessage) Client to Server | n/a | +| Send or update context commands that customer can attach to their prompt request (available via `@` in chat UI). | `aws/chat/sendContextCommands` | `ContextCommandParams` | [Notification](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#notificationMessage) Server to Client | n/a | +| Send create prompt event that triggers new prompt creation flow on server. | `aws/chat/createPrompt` | `CreatePromptParams` | [Notification](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#notificationMessage) Client to Server | n/a | ```ts export interface ChatPrompt { diff --git a/runtimes/protocol/chat.ts b/runtimes/protocol/chat.ts index b6fc6c73..a1680997 100644 --- a/runtimes/protocol/chat.ts +++ b/runtimes/protocol/chat.ts @@ -42,6 +42,10 @@ import { INLINE_CHAT_REQUEST_METHOD, InlineChatParams, InlineChatResult, + CONTEXT_COMMAND_NOTIFICATION_METHOD, + ContextCommandParams, + CREATE_PROMPT_NOTIFICATION_METHOD, + CreatePromptParams, } from './lsp' export const chatRequestType = new AutoParameterStructuresProtocolRequestType< @@ -101,3 +105,9 @@ export const chatUpdateNotificationType = new ProtocolNotificationType( FILE_CLICK_NOTIFICATION_METHOD ) +export const contextCommandsNotificationType = new ProtocolNotificationType( + CONTEXT_COMMAND_NOTIFICATION_METHOD +) +export const createPromptNotificationType = new ProtocolNotificationType( + CREATE_PROMPT_NOTIFICATION_METHOD +) diff --git a/runtimes/runtimes/auth/auth.test.ts b/runtimes/runtimes/auth/auth.test.ts index 3bdd9414..0d2800f0 100644 --- a/runtimes/runtimes/auth/auth.test.ts +++ b/runtimes/runtimes/auth/auth.test.ts @@ -48,7 +48,7 @@ function clearHandlers() { authHandlers.bearerDeleteHandler = () => {} } -const serverLspConnectionMock = { +const serverLspConnectionMock = { onRequest: (requestType: any, handler: any) => { if (requestType.method === credentialsProtocolMethodNames.iamCredentialsUpdate) { authHandlers.iamUpdateHandler = handler @@ -83,7 +83,7 @@ const serverLspConnectionMock = { onExecuteCommand: (handler: ServerRequestHandler) => {}, onInitialize: (handler: ServerRequestHandler) => {}, onInitialized: (handler: NotificationHandler) => {}, -} +} as Connection const lspRouter = new LspRouter(serverLspConnectionMock, 'name') diff --git a/runtimes/runtimes/base-runtime.ts b/runtimes/runtimes/base-runtime.ts index 0d6c4e02..bf978dc8 100644 --- a/runtimes/runtimes/base-runtime.ts +++ b/runtimes/runtimes/base-runtime.ts @@ -39,6 +39,8 @@ import { chatUpdateNotificationType, fileClickNotificationType, inlineChatRequestType, + contextCommandsNotificationType, + createPromptNotificationType, } from '../protocol' import { createConnection } from 'vscode-languageserver/browser' import { @@ -144,6 +146,8 @@ export const baseRuntime = (connections: { reader: MessageReader; writer: Messag openTab: params => lspConnection.sendRequest(openTabRequestType.method, params), sendChatUpdate: params => lspConnection.sendNotification(chatUpdateNotificationType.method, params), onFileClicked: handler => lspConnection.onNotification(fileClickNotificationType.method, handler), + sendContextCommands: params => lspConnection.sendNotification(contextCommandsNotificationType.method, params), + onCreatePrompt: handler => lspConnection.onNotification(createPromptNotificationType.method, handler), } const identityManagement: IdentityManagement = { diff --git a/runtimes/runtimes/chat/baseChat.ts b/runtimes/runtimes/chat/baseChat.ts index 63146ef1..ac5f48af 100644 --- a/runtimes/runtimes/chat/baseChat.ts +++ b/runtimes/runtimes/chat/baseChat.ts @@ -39,6 +39,10 @@ import { inlineChatRequestType, InlineChatParams, InlineChatResult, + ContextCommandParams, + contextCommandsNotificationType, + CreatePromptParams, + createPromptNotificationType, } from '../../protocol' import { Chat } from '../../server-interface' @@ -114,4 +118,12 @@ export class BaseChat implements Chat { public onFileClicked(handler: NotificationHandler) { this.connection.onNotification(fileClickNotificationType.method, handler) } + + public sendContextCommands(params: ContextCommandParams) { + this.connection.sendNotification(contextCommandsNotificationType.method, params) + } + + public onCreatePrompt(handler: NotificationHandler) { + this.connection.onNotification(createPromptNotificationType.method, handler) + } } diff --git a/runtimes/runtimes/encoding.test.ts b/runtimes/runtimes/encoding.test.ts index 8581aebb..5f5942ea 100644 --- a/runtimes/runtimes/encoding.test.ts +++ b/runtimes/runtimes/encoding.test.ts @@ -3,7 +3,7 @@ import { WebBase64Encoding } from './encoding' import sinon, { StubbedInstance, stubInterface } from 'ts-sinon' describe('WebBase64Encoding', () => { - const wdw = {} + const wdw = {} as WindowOrWorkerGlobalScope const encoding = new WebBase64Encoding(wdw) it('encodes and decodes string', () => { diff --git a/runtimes/runtimes/lsp/router/lspRouter.test.ts b/runtimes/runtimes/lsp/router/lspRouter.test.ts index d510baab..bce3b0cb 100644 --- a/runtimes/runtimes/lsp/router/lspRouter.test.ts +++ b/runtimes/runtimes/lsp/router/lspRouter.test.ts @@ -28,13 +28,13 @@ describe('LspRouter', () => { encode: (value: string) => value, decode: (value: string) => value, } - const logging = { + const logging = { log: sandbox.stub(), debug: sandbox.stub(), error: sandbox.stub(), warn: sandbox.stub(), info: sandbox.stub(), - } + } as Logging const lspConnection = stubLspConnection() let executeCommandHandler: RequestHandler @@ -613,7 +613,7 @@ describe('LspRouter', () => { }) function stubLspConnection(overrides = {}): Connection { - return { + return { console: { info: (message: any) => {}, }, @@ -627,7 +627,7 @@ describe('LspRouter', () => { onNotification: (handler: any) => {}, onDidChangeConfiguration: (handler: any) => {}, ...overrides, - } + } as Connection } function newServer({ diff --git a/runtimes/runtimes/lsp/router/routerByServerName.test.ts b/runtimes/runtimes/lsp/router/routerByServerName.test.ts index 94db6bc4..8d0ae919 100644 --- a/runtimes/runtimes/lsp/router/routerByServerName.test.ts +++ b/runtimes/runtimes/lsp/router/routerByServerName.test.ts @@ -4,10 +4,10 @@ import { EventIdentifier, FollowupIdentifier } from '../../../protocol' import { RouterByServerName } from './routerByServerName' describe('RouterByServerName', () => { - const encoding = { + const encoding = { encode: value => Buffer.from(value).toString('base64'), decode: value => Buffer.from(value, 'base64').toString('utf-8'), - } + } as Encoding const serverName = 'Server_XXX' let router: RouterByServerName, FollowupIdentifier> diff --git a/runtimes/server-interface/chat.ts b/runtimes/server-interface/chat.ts index 2ed74eb8..32367c4a 100644 --- a/runtimes/server-interface/chat.ts +++ b/runtimes/server-interface/chat.ts @@ -22,6 +22,8 @@ import { FileClickParams, InlineChatParams, InlineChatResult, + ContextCommandParams, + CreatePromptParams, } from '../protocol' /** @@ -49,4 +51,6 @@ export type Chat = { onFollowUpClicked: (handler: NotificationHandler) => void sendChatUpdate: (params: ChatUpdateParams) => void onFileClicked: (handler: NotificationHandler) => void + sendContextCommands: (params: ContextCommandParams) => void + onCreatePrompt: (handler: NotificationHandler) => void } diff --git a/types/chat.ts b/types/chat.ts index 73dcd120..748938d8 100644 --- a/types/chat.ts +++ b/types/chat.ts @@ -18,6 +18,8 @@ export const OPEN_TAB_REQUEST_METHOD = 'aws/chat/openTab' export const CHAT_UPDATE_NOTIFICATION_METHOD = 'aws/chat/sendChatUpdate' export const FILE_CLICK_NOTIFICATION_METHOD = 'aws/chat/fileClick' export const INLINE_CHAT_REQUEST_METHOD = 'aws/chat/sendInlineChatPrompt' +export const CONTEXT_COMMAND_NOTIFICATION_METHOD = 'aws/chat/sendContextCommands' +export const CREATE_PROMPT_NOTIFICATION_METHOD = 'aws/chat/createPrompt' export interface ChatItemAction { pillText: string @@ -129,8 +131,11 @@ export interface QuickActionCommand { command: string description?: string placeholder?: string + icon?: IconType } +export type IconType = 'file' | 'folder' | 'code-block' | 'list-add' | 'magic' | 'help' | 'trash' + /** * Configuration object for registering chat quick actions groups. */ @@ -259,3 +264,23 @@ export interface FileClickParams { filePath: string action?: FileAction } + +export interface ContextCommandGroup { + groupName?: string + commands: ContextCommand[] +} + +export interface ContextCommand extends QuickActionCommand { + id?: string + route?: string[] + label?: 'file' | 'folder' | 'code' + children?: ContextCommandGroup[] +} + +export interface ContextCommandParams { + contextCommandGroups: ContextCommandGroup[] +} + +export interface CreatePromptParams { + promptName: string +}