Extract ExtensionSlashCommand to assistant_slash_command crate (#20617)

This PR extracts the `ExtensionSlashCommand` implementation to the
`assistant_slash_command` crate.

The slash command related methods have been added to the `Extension`
trait. We also create separate data types for the slash command data
within the `extension` crate so that we can talk about them without
depending on the `extension_host` or `assistant_slash_command`.

Release Notes:

- N/A
This commit is contained in:
Marshall Bowers 2024-11-13 14:34:58 -05:00 committed by GitHub
parent b913cf2e02
commit 254ce74036
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 309 additions and 161 deletions

View file

@ -3,7 +3,10 @@ pub mod wit;
use crate::{ExtensionManifest, ExtensionRegistrationHooks};
use anyhow::{anyhow, bail, Context as _, Result};
use async_trait::async_trait;
use extension::KeyValueStoreDelegate;
use extension::{
KeyValueStoreDelegate, SlashCommand, SlashCommandArgumentCompletion, SlashCommandOutput,
WorktreeDelegate,
};
use fs::{normalize_path, Fs};
use futures::future::LocalBoxFuture;
use futures::{
@ -29,7 +32,7 @@ use wasmtime::{
};
use wasmtime_wasi::{self as wasi, WasiView};
use wit::Extension;
pub use wit::{ExtensionProject, SlashCommand};
pub use wit::ExtensionProject;
pub struct WasmHost {
engine: Engine,
@ -62,6 +65,51 @@ impl extension::Extension for WasmExtension {
self.work_dir.clone()
}
async fn complete_slash_command_argument(
&self,
command: SlashCommand,
arguments: Vec<String>,
) -> Result<Vec<SlashCommandArgumentCompletion>> {
self.call(|extension, store| {
async move {
let completions = extension
.call_complete_slash_command_argument(store, &command.into(), &arguments)
.await?
.map_err(|err| anyhow!("{err}"))?;
Ok(completions.into_iter().map(Into::into).collect())
}
.boxed()
})
.await
}
async fn run_slash_command(
&self,
command: SlashCommand,
arguments: Vec<String>,
delegate: Option<Arc<dyn WorktreeDelegate>>,
) -> Result<SlashCommandOutput> {
self.call(|extension, store| {
async move {
let resource = if let Some(delegate) = delegate {
Some(store.data_mut().table().push(delegate)?)
} else {
None
};
let output = extension
.call_run_slash_command(store, &command.into(), &arguments, resource)
.await?
.map_err(|err| anyhow!("{err}"))?;
Ok(output.into())
}
.boxed()
})
.await
}
async fn suggest_docs_packages(&self, provider: Arc<str>) -> Result<Vec<String>> {
self.call(|extension, store| {
async move {