feat(goose2): voice dictation via direct-ACP pattern (#8609)
Signed-off-by: tulsi <tulsi@block.xyz> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
use sacp::{JsonRpcRequest, JsonRpcResponse};
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::HashMap;
|
||||
|
||||
/// Schema descriptor for a single custom method, produced by the
|
||||
/// `#[custom_methods]` macro's generated `custom_method_schemas()` function.
|
||||
@@ -309,6 +310,154 @@ pub struct ProviderConfigKey {
|
||||
pub primary: bool,
|
||||
}
|
||||
|
||||
/// Transcribe audio via a dictation provider.
|
||||
#[derive(Debug, Default, Clone, Serialize, Deserialize, JsonSchema, JsonRpcRequest)]
|
||||
#[request(method = "_goose/dictation/transcribe", response = DictationTranscribeResponse)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct DictationTranscribeRequest {
|
||||
/// Base64-encoded audio data
|
||||
pub audio: String,
|
||||
/// MIME type (e.g. "audio/wav", "audio/webm")
|
||||
pub mime_type: String,
|
||||
/// Provider to use: "openai", "groq", "elevenlabs", or "local"
|
||||
pub provider: String,
|
||||
}
|
||||
|
||||
/// Transcription result.
|
||||
#[derive(Debug, Default, Clone, Serialize, Deserialize, JsonSchema, JsonRpcResponse)]
|
||||
pub struct DictationTranscribeResponse {
|
||||
pub text: String,
|
||||
}
|
||||
|
||||
/// Get the configuration status of all dictation providers.
|
||||
#[derive(Debug, Default, Clone, Serialize, Deserialize, JsonSchema, JsonRpcRequest)]
|
||||
#[request(method = "_goose/dictation/config", response = DictationConfigResponse)]
|
||||
pub struct DictationConfigRequest {}
|
||||
|
||||
#[derive(Debug, Default, Clone, Serialize, Deserialize, JsonSchema)]
|
||||
pub struct DictationModelOption {
|
||||
pub id: String,
|
||||
pub label: String,
|
||||
pub description: String,
|
||||
}
|
||||
|
||||
/// Per-provider configuration status.
|
||||
#[derive(Debug, Default, Clone, Serialize, Deserialize, JsonSchema)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct DictationProviderStatusEntry {
|
||||
pub configured: bool,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub host: Option<String>,
|
||||
pub description: String,
|
||||
pub uses_provider_config: bool,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub settings_path: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub config_key: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub model_config_key: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub default_model: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub selected_model: Option<String>,
|
||||
#[serde(default)]
|
||||
pub available_models: Vec<DictationModelOption>,
|
||||
}
|
||||
|
||||
/// Dictation config response — map of provider name to status.
|
||||
#[derive(Debug, Default, Clone, Serialize, Deserialize, JsonSchema, JsonRpcResponse)]
|
||||
pub struct DictationConfigResponse {
|
||||
pub providers: HashMap<String, DictationProviderStatusEntry>,
|
||||
}
|
||||
|
||||
/// Empty success response for operations that return no data.
|
||||
#[derive(Debug, Default, Clone, Serialize, Deserialize, JsonSchema, JsonRpcResponse)]
|
||||
pub struct EmptyResponse {}
|
||||
|
||||
/// List available local Whisper models with their download status.
|
||||
#[derive(Debug, Default, Clone, Serialize, Deserialize, JsonSchema, JsonRpcRequest)]
|
||||
#[request(
|
||||
method = "_goose/dictation/models/list",
|
||||
response = DictationModelsListResponse
|
||||
)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct DictationModelsListRequest {}
|
||||
|
||||
#[derive(Debug, Default, Clone, Serialize, Deserialize, JsonSchema, JsonRpcResponse)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct DictationModelsListResponse {
|
||||
pub models: Vec<DictationLocalModelStatus>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, Serialize, Deserialize, JsonSchema)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct DictationLocalModelStatus {
|
||||
pub id: String,
|
||||
pub label: String,
|
||||
pub description: String,
|
||||
pub size_mb: u32,
|
||||
pub downloaded: bool,
|
||||
pub download_in_progress: bool,
|
||||
}
|
||||
|
||||
/// Kick off a background download of a local Whisper model.
|
||||
#[derive(Debug, Default, Clone, Serialize, Deserialize, JsonSchema, JsonRpcRequest)]
|
||||
#[request(method = "_goose/dictation/models/download", response = EmptyResponse)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct DictationModelDownloadRequest {
|
||||
pub model_id: String,
|
||||
}
|
||||
|
||||
/// Poll the progress of an in-flight download.
|
||||
#[derive(Debug, Default, Clone, Serialize, Deserialize, JsonSchema, JsonRpcRequest)]
|
||||
#[request(
|
||||
method = "_goose/dictation/models/download/progress",
|
||||
response = DictationModelDownloadProgressResponse
|
||||
)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct DictationModelDownloadProgressRequest {
|
||||
pub model_id: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, Serialize, Deserialize, JsonSchema, JsonRpcResponse)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct DictationModelDownloadProgressResponse {
|
||||
/// None when no download is active for this model id.
|
||||
pub progress: Option<DictationDownloadProgress>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, Serialize, Deserialize, JsonSchema)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct DictationDownloadProgress {
|
||||
pub bytes_downloaded: u64,
|
||||
pub total_bytes: u64,
|
||||
pub progress_percent: f32,
|
||||
/// serde lowercase of DownloadStatus: "downloading" | "completed" | "failed" | "cancelled"
|
||||
pub status: String,
|
||||
pub error: Option<String>,
|
||||
}
|
||||
|
||||
/// Cancel an in-flight download.
|
||||
#[derive(Debug, Default, Clone, Serialize, Deserialize, JsonSchema, JsonRpcRequest)]
|
||||
#[request(method = "_goose/dictation/models/cancel", response = EmptyResponse)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct DictationModelCancelRequest {
|
||||
pub model_id: String,
|
||||
}
|
||||
|
||||
/// Delete a downloaded local Whisper model from disk.
|
||||
#[derive(Debug, Default, Clone, Serialize, Deserialize, JsonSchema, JsonRpcRequest)]
|
||||
#[request(method = "_goose/dictation/models/delete", response = EmptyResponse)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct DictationModelDeleteRequest {
|
||||
pub model_id: String,
|
||||
}
|
||||
|
||||
/// Persist the user's model selection for a given provider.
|
||||
#[derive(Debug, Default, Clone, Serialize, Deserialize, JsonSchema, JsonRpcRequest)]
|
||||
#[request(method = "_goose/dictation/model/select", response = EmptyResponse)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct DictationModelSelectRequest {
|
||||
pub provider: String,
|
||||
pub model_id: String,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user