Skip to content

feat(chat-client): implement export conversation flow #944

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 18 commits into from
Apr 16, 2025

Conversation

viktorsaws
Copy link
Contributor

@viktorsaws viktorsaws commented Apr 10, 2025

Problem

We need to:

  • Implement Export Conversations feature in Chat Client
  • Add support for history option set in Q Language Server at initialization to toggle View History functionality in Chat Client

Solution

Integration of Chat History and Export features with Extension

To fully intergate export feature with IDE, Extension must add support for next features:

1. Implement support for showSaveFileDialog

Export feature is conditionally enabled by Q Chat server if client signals support for initializationOptions?.aws?.awsClientCapabilities?.window?.showSaveFileDialog feature.

Extension must implement aws/showSaveFileDialog protocol and set awsClientCapabilities?.window?.showSaveFileDialog flag to true.

2. Implement support of response routing for openTab and getSerializedChat requests

New getSerializedChat request in Chat Client requires Extension to support routing of responses between inbound and outbound messages from Chat Client to Language Server. This is archived by requestId argument in inbound getSerializedChat Chat Client message. getSerializedChat and openTab requests are sent from Language Server, and server expects response with result coming from the Chat Client.
Extension must attach and track requestId field for getSerializedChat and openTab requests, and route responses from Chat Client to corresponding incoming request from LSP Server.

Reference implementation of message routing can be found in Sample VSCode extension

const registerHandlerWithResponseRouter = (command: string) => {
const handler = async (params: any, _: any) => {
const mapErrorType = (type: string | undefined): number => {
switch (type) {
case 'InvalidRequest':
return ErrorCodes.InvalidRequest
case 'InternalError':
return ErrorCodes.InternalError
case 'UnknownError':
default:
return ErrorCodes.UnknownErrorCode
}
}
const requestId = uuidv4()
webviewView.webview.postMessage({
requestId: requestId,
command: command,
params: params,
})
const responsePromise = new Promise<UiMessageResultParams | undefined>((resolve, reject) => {
const timeout = setTimeout(() => {
disposable.dispose()
reject(new Error('Request timed out'))
}, 30000)
const disposable = webviewView.webview.onDidReceiveMessage((message: any) => {
if (message.requestId === requestId) {
clearTimeout(timeout)
disposable.dispose()
resolve(message.params)
}
})
})
const result = await responsePromise
if (result?.success) {
return result.result
} else {
return new ResponseError(
mapErrorType(result?.error.type),
result?.error.message ?? 'No response from client'
)
}
}
languageClient.onRequest(command, handler)
}
registerHandlerWithResponseRouter(openTabRequestType.method)
registerHandlerWithResponseRouter(getSerializedChatRequestType.method)
.

TODO

License

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

@viktorsaws viktorsaws force-pushed the feat/chat-client-export branch from 8755d18 to 65ecee5 Compare April 11, 2025 11:19
@viktorsaws viktorsaws force-pushed the feat/chat-client-export branch from 65ecee5 to 1cb809d Compare April 14, 2025 13:14
@viktorsaws viktorsaws force-pushed the feat/chat-client-export branch from e2dc015 to 33e9e3a Compare April 15, 2025 13:51
// @ts-ignore
assert.called(TabFactory.prototype.enableHistory)
// @ts-ignore
assert.called(TabFactory.prototype.enableExport)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: for completeness, we should also be checking for not called if not set

const defaultTabConfig: Partial<MynahUIDataModel> = {
quickActionCommands: tabFactory.getDefaultTabData().quickActionCommands,
quickActionCommands: defaultTabBarData.quickActionCommands,
tabBarButtons: defaultTabBarData.tabBarButtons,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice catch!


if (this.export) {
tabBarButtons.push({
id: 'export',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: introducing constants for this critical ids (as above) makes it a bit easier to track the logic across files

@viktorsaws viktorsaws marked this pull request as ready for review April 16, 2025 08:24
@viktorsaws viktorsaws requested a review from a team as a code owner April 16, 2025 08:24
@viktorsaws viktorsaws merged commit 63fd2dc into main Apr 16, 2025
6 checks passed
@viktorsaws viktorsaws deleted the feat/chat-client-export branch April 16, 2025 10:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants