Closed alenakhineika closed 3 months ago
cc @isidorn
Sounds similar to https://github.com/microsoft/vscode/issues/211136
Do you want the current request to wait on the user clicking the button, or send a new request to call back to the participant? You can do either.
You can wait on the command yourself by setting up some callback to do await somePromiseThatIsResolvedWhenTheCommandIsInvoked
inside your chat handler, after sending the button.
Or, you can do the workbench.action.chat.open
trick, with some other query that you want to show, even an empty string. I'm guessing the first is what you'd prefer though. Does that help?
For workbench.action.chat.open
we would need to print the command that we want to return control to, right? Like:
@MongoDB /query
Otherwise, it won't know which action to take.
To await somePromiseThatIsResolvedWhenTheCommandIsInvoked
, I thought about Promise + setInterval with a condition and timeout as a workaround. That would work, but wanted to enquire if there is no better more native copilot way to do so, e.g. awaing stream buttons.
I'd recommend awaiting a Promise, not polling with a setInterval, especially because the user might never click the button. But yeah, either of those work, but we don't have anything better for you right now.
After experimenting a bit more, I see how this would be useful if you supported the following command:
await vscode.commands.executeCommand('workbench.action.chat.requestHandler', { command: 'query' })
This would call the required handler directly, without printing the command itself to the chat.
Here is the use case:
@MongoDB /query find all docs by name lena
Now we need somehow to tell the copilot to proceed with query generation. With workbench.action.chat.open
, we would need to print @MongoDB /query find all docs by name lena
again.
With workbench.action.chat.requestHandler
it would not print anything and just returned a generated query.
I find it better than awaiting a promise, because as you said, what if the user didn't click anything, what if they want to call another command, what will happen with all unresolved promises? We kind of block the flow while awaiting. With workbench.action.chat.requestHandler
, the user could also scroll the history and click those links again to change the selection.
What do you think?
Another command that could be useful is something like:
await vscode.commands.executeCommand('workbench.action.chat.userPrompt', { query: '@MongoDB /query' })
This could be similar to workbench.action.chat.open
, with the difference that it won't send the message to chat, but only insert the text into the input, suggesting to the user the next step.
with the difference that it won't send the message to chat, but only insert the text into the input, suggesting to the user the next step.
I like this suggestion and see the need for this. Especially since we want to put the user in control to review the query before it is run.
@roblourens could it be an argument sent to the open
command - send: boolean
? And maybe even false
is the default?
You can use the isPartialQuery
argument to fill in the input but not send the query.
I wonder whether you actually want the confirmation
API though, this shows a confirmation box inline, the response ends, and it makes another request when the user picks an option: https://github.com/microsoft/vscode/blob/24da11d618d76e825966709b3dd8d40de399a3d5/src/vscode-dts/vscode.proposed.chatParticipantAdditions.d.ts#L151
The isPartialQuery
is exactly what I wanted, thank you!
What about supporting something like await vscode.commands.executeCommand('workbench.action.chat.requestHandler', { command: 'query' })
? So instead of printing and sending a query, or partially printing without sending it, we would send a request to a handler without printing to chat.
I currently hide these commands in the package.json with the where condition to prevent users from running them directly in chat, because those are a sequence of actions, at it might lead to unexpected flow if they call them at any time. The conversation would look cleaner without these auxiliary hystory in the chat.
Or maybe there is also some cool flag that I haven't found in your codebase? :)
I don't think we should do that, because if there's a response in chat, there should be a request that shows you why that response is showing up. Remember that the user could run some other chat request with a different participant before they go back and click that button.
I see your point. Feel free to close the issue. I will be printing to chat then with workbench.action.chat.open
and keep an eye on new features that you deliver. Maybe in the future, there will be something to improve this flow.
And thank you so much for your quick and detailed responses. They’ve been incredibly helpful in moving our participant's progress forward!
Thanks, I appreciate the feedback!
It would be handy if the
stream.button()
could wait for the attached command to be resolved.When generating a participant answer for a particular command, we might encounter that a user is not connected yet. We want to expand the command palette, so users can select one of the existing connections, and then the extension would proceed with the answer generation.
Currently, we do it without the button, and just open the command palette directly, but this has proven to be confusing and difficult to notice for users.
I tried to pass
vscode.ChatRequest
andvscode.ChatResponseStream
to my connect function and after connecting call thethis._participant.requestHandler()
with the same request and response. But it looks like the stream lives within one iterationuser prompt -> the handler response
and when I invoke the handler again the stream is already closed.I also tried to solve it with
await vscode.commands.executeCommand('workbench.action.chat.open', { query: chatHandlerArgs.request.prompt })
, but it prints the initial user prompt the second time to the chat, what is expected, but not ideal experience for our use case. Something likeawait vscode.commands.executeCommand('workbench.action.chat.open', { response })
would do the job, so we could print messages to the chat at any time, without requiring a user prompt.Please let me know if there is an existing way to handle this. Thank you!