From 531312c66397e8e7e995f1dbc247de7eae384707 Mon Sep 17 00:00:00 2001 From: streamer45 Date: Fri, 30 Jan 2026 17:34:26 +0100 Subject: [PATCH 1/2] fix: download timeout and resume support for marketplace installs --- apps/skit/src/marketplace_installer.rs | 157 ++++++++++++--- apps/skit/src/marketplace_security.rs | 7 +- .../plugins/supertonic/0.1.0/manifest.json | 2 +- .../plugins/supertonic/0.1.0/manifest.json | 2 +- marketplace/official-plugins.json | 2 +- plugins/native/supertonic/plugin.yml | 2 +- .../plugins/MarketplaceModelsSection.tsx | 39 +--- ui/src/views/plugins/MarketplacePanels.tsx | 8 +- ui/src/views/plugins/MarketplaceTab.tsx | 182 +++++++++++------- 9 files changed, 259 insertions(+), 142 deletions(-) diff --git a/apps/skit/src/marketplace_installer.rs b/apps/skit/src/marketplace_installer.rs index 47d52907..7e2a059a 100644 --- a/apps/skit/src/marketplace_installer.rs +++ b/apps/skit/src/marketplace_installer.rs @@ -46,6 +46,8 @@ const REGISTRY_TIMEOUT_SECS: u64 = 20; const REGISTRY_INDEX_TTL_SECS: u64 = 60; const REGISTRY_MANIFEST_TTL_SECS: u64 = 60; const MAX_JOB_HISTORY: usize = 200; +const DOWNLOAD_CONNECT_TIMEOUT_SECS: u64 = 30; +const DOWNLOAD_READ_TIMEOUT_SECS: u64 = 60; #[derive(Debug, Clone, Deserialize)] pub struct InstallPluginRequest { @@ -300,6 +302,7 @@ impl InstallJobQueue { tracker.mark_cancelled("Cancelled").await; }, Err(InstallError::Other(err)) => { + tracing::error!(job_id = %context.job_id, error = %err, "Install job failed"); tracker.set_status(JobStatus::Failed, format!("Install failed: {err}")).await; }, } @@ -456,6 +459,7 @@ impl JobTracker { } async fn fail_step(&self, step_name: &str, error: String) { + tracing::error!(job_id = %self.job_id, step = %step_name, error = %error, "Install step failed"); self.queue .update_job(&self.job_id, |info| { if let Some(step) = info.steps.iter_mut().find(|step| step.name == step_name) { @@ -533,7 +537,8 @@ impl PluginInstaller { settings: PluginInstallerSettings, ) -> Result { let download_client = Client::builder() - .timeout(Duration::from_secs(REGISTRY_TIMEOUT_SECS)) + .connect_timeout(Duration::from_secs(DOWNLOAD_CONNECT_TIMEOUT_SECS)) + .read_timeout(Duration::from_secs(DOWNLOAD_READ_TIMEOUT_SECS)) .redirect(reqwest::redirect::Policy::none()) .build() .context("Failed to build bundle HTTP client")?; @@ -935,9 +940,14 @@ impl PluginInstaller { plugin_paths::validate_path_component("bundle file name", file_name)?; let bundle_path = cache_dir.join(file_name); - let temp_path = cache_dir.join(format!(".download-{}", Uuid::new_v4())); + let temp_path = cache_dir.join(format!(".download-{file_name}")); + let mut hash_mismatch = false; let download_result: Result<(), InstallError> = async { + // Check for existing partial download to enable resume. + let existing_len = tokio::fs::metadata(&temp_path).await.ok().map(|m| m.len()); + let resume_from = existing_len.filter(|&len| len > 0); + let (response, final_url) = validated_get_response( &self.download_client, &self.marketplace_policy, @@ -945,23 +955,58 @@ impl PluginInstaller { &bundle_url, Some(registry_origin), None, + resume_from, ) .await?; let response = response .error_for_status() .with_context(|| format!("Bundle download failed for {final_url}"))?; - let total_bytes = response.content_length(); + + let is_partial = response.status() == reqwest::StatusCode::PARTIAL_CONTENT; + let total_bytes = if is_partial { + // For 206 responses, content_length is the remaining bytes. + response.content_length().map(|cl| cl + resume_from.unwrap_or(0)) + } else { + response.content_length() + }; let mut stream = response.bytes_stream(); - let mut file = tokio::fs::File::create(&temp_path).await.with_context(|| { - format!("Failed to create bundle file {temp_path}", temp_path = temp_path.display()) - })?; - let mut hasher = Sha256::new(); - let mut bytes_done = 0u64; + let (mut file, mut hasher, mut bytes_done) = if is_partial { + let offset = resume_from.unwrap_or(0); + // Re-hash existing bytes for SHA256 continuity. + let existing_data = tokio::fs::read(&temp_path).await.with_context(|| { + format!( + "Failed to read existing temp file {temp_path}", + temp_path = temp_path.display() + ) + })?; + let mut hasher = Sha256::new(); + hasher.update(&existing_data); + let file = tokio::fs::OpenOptions::new() + .append(true) + .open(&temp_path) + .await + .with_context(|| { + format!( + "Failed to open bundle file for append {temp_path}", + temp_path = temp_path.display() + ) + })?; + (file, hasher, offset) + } else { + let file = tokio::fs::File::create(&temp_path).await.with_context(|| { + format!( + "Failed to create bundle file {temp_path}", + temp_path = temp_path.display() + ) + })?; + (file, Sha256::new(), 0u64) + }; while let Some(chunk) = stream.next().await { let chunk = chunk.with_context(|| "Failed to read bundle download stream")?; if cancel.is_cancelled() { + let _ = file.flush().await; return Err(InstallError::Cancelled); } file.write_all(&chunk).await.with_context(|| { @@ -989,6 +1034,7 @@ impl PluginInstaller { if !actual_hash.eq_ignore_ascii_case(&manifest.bundle.sha256) { let expected = manifest.bundle.sha256.as_str(); let actual = actual_hash.as_str(); + hash_mismatch = true; return Err( anyhow!("Bundle hash mismatch: expected {expected}, got {actual}").into() ); @@ -999,7 +1045,11 @@ impl PluginInstaller { .await; if let Err(err) = download_result { - let _ = tokio::fs::remove_file(&temp_path).await; + // Only delete temp file on hash mismatch; keep it for network errors + // and cancellations so the next attempt can resume from the partial file. + if hash_mismatch { + let _ = tokio::fs::remove_file(&temp_path).await; + } return Err(err); } @@ -1375,33 +1425,77 @@ impl PluginInstaller { .marketplace_policy .validate_url("model url", url, registry_origin.as_ref()) .await?; - let (response, final_url) = validated_get_response( - &self.download_client, - &self.marketplace_policy, - "model url", - &parsed, - registry_origin.as_ref(), - bearer_token, - ) - .await?; - let response = response - .error_for_status() - .with_context(|| format!("Model download failed for {final_url}"))?; - let total_bytes = response.content_length().or(expected_size); - let mut stream = response.bytes_stream(); - let temp_path = target_path.with_extension(format!("download-{}", Uuid::new_v4())); + let temp_path = target_path.with_extension("download-part"); + let mut hash_mismatch = false; let download_result: Result<(), InstallError> = async { - let mut file = tokio::fs::File::create(&temp_path).await.with_context(|| { - format!("Failed to create model file {temp_path}", temp_path = temp_path.display()) - })?; + // Check for existing partial download to enable resume. + let existing_len = tokio::fs::metadata(&temp_path).await.ok().map(|m| m.len()); + let resume_from = existing_len.filter(|&len| len > 0); - let mut hasher = expected_sha256.map(|_| Sha256::new()); - let mut bytes_done = 0u64; + let (response, final_url) = validated_get_response( + &self.download_client, + &self.marketplace_policy, + "model url", + &parsed, + registry_origin.as_ref(), + bearer_token, + resume_from, + ) + .await?; + let response = response + .error_for_status() + .with_context(|| format!("Model download failed for {final_url}"))?; + + let is_partial = response.status() == reqwest::StatusCode::PARTIAL_CONTENT; + let total_bytes = if is_partial { + response.content_length().map(|cl| cl + resume_from.unwrap_or(0)) + } else { + response.content_length() + } + .or(expected_size); + let mut stream = response.bytes_stream(); + + let (mut file, mut hasher, mut bytes_done) = if is_partial { + let offset = resume_from.unwrap_or(0); + // Re-hash existing bytes for SHA256 continuity. + let existing_data = tokio::fs::read(&temp_path).await.with_context(|| { + format!( + "Failed to read existing temp file {temp_path}", + temp_path = temp_path.display() + ) + })?; + let h = expected_sha256.map(|_| { + let mut hasher = Sha256::new(); + hasher.update(&existing_data); + hasher + }); + let file = tokio::fs::OpenOptions::new() + .append(true) + .open(&temp_path) + .await + .with_context(|| { + format!( + "Failed to open model file for append {temp_path}", + temp_path = temp_path.display() + ) + })?; + (file, h, offset) + } else { + let file = tokio::fs::File::create(&temp_path).await.with_context(|| { + format!( + "Failed to create model file {temp_path}", + temp_path = temp_path.display() + ) + })?; + let h = expected_sha256.map(|_| Sha256::new()); + (file, h, 0u64) + }; while let Some(chunk) = stream.next().await { let chunk = chunk.with_context(|| "Failed to read model download stream")?; if cancel.is_cancelled() { + let _ = file.flush().await; return Err(InstallError::Cancelled); } file.write_all(&chunk).await.with_context(|| { @@ -1440,6 +1534,7 @@ impl PluginInstaller { if let (Some(expected_hash), Some(hasher)) = (expected_sha256, hasher) { let actual_hash = to_hex(&hasher.finalize()); if !actual_hash.eq_ignore_ascii_case(expected_hash) { + hash_mismatch = true; return Err(anyhow!( "Model hash mismatch: expected {expected_hash}, got {actual_hash}" ) @@ -1452,7 +1547,9 @@ impl PluginInstaller { .await; if let Err(err) = download_result { - let _ = tokio::fs::remove_file(&temp_path).await; + if hash_mismatch { + let _ = tokio::fs::remove_file(&temp_path).await; + } return Err(err); } diff --git a/apps/skit/src/marketplace_security.rs b/apps/skit/src/marketplace_security.rs index 463be7d8..3b40a16b 100644 --- a/apps/skit/src/marketplace_security.rs +++ b/apps/skit/src/marketplace_security.rs @@ -101,6 +101,7 @@ pub async fn validated_get_response( start: &Url, registry_origin: Option<&OriginKey>, bearer_token: Option<&str>, + resume_from_byte: Option, ) -> Result<(Response, Url)> { let mut current = start.clone(); let token_origin = if bearer_token.is_some() { Some(origin_key(start)?) } else { None }; @@ -113,6 +114,9 @@ pub async fn validated_get_response( request = request.bearer_auth(token); } } + if let Some(offset) = resume_from_byte { + request = request.header(reqwest::header::RANGE, format!("bytes={offset}-")); + } let response = request.send().await.with_context(|| format!("Failed to fetch {label} {current}"))?; if response.status().is_redirection() { @@ -158,7 +162,8 @@ pub async fn validated_get_bytes( bearer_token: Option<&str>, ) -> Result { let (response, final_url) = - validated_get_response(client, policy, label, start, registry_origin, bearer_token).await?; + validated_get_response(client, policy, label, start, registry_origin, bearer_token, None) + .await?; let response = response .error_for_status() .with_context(|| format!("{label} request failed for {final_url}"))?; diff --git a/dist/registry/plugins/supertonic/0.1.0/manifest.json b/dist/registry/plugins/supertonic/0.1.0/manifest.json index daa3bc65..a9333cf0 100644 --- a/dist/registry/plugins/supertonic/0.1.0/manifest.json +++ b/dist/registry/plugins/supertonic/0.1.0/manifest.json @@ -27,7 +27,7 @@ "expected_size_bytes": 244451376, "license": "MIT", "license_url": "https://github.com/supertone-inc/supertonic/blob/main/LICENSE", - "sha256": "29e18bfdcbfbdd8bef25204b19be21d13fda36d4e66fe31c74e2a01dad457cec" + "sha256": "3c3ba6326cd6c8ee48d4c7322322d1f1f4ebf188bf4a7d80fc218babca186f41" } ] } \ No newline at end of file diff --git a/docs/public/registry/plugins/supertonic/0.1.0/manifest.json b/docs/public/registry/plugins/supertonic/0.1.0/manifest.json index daa3bc65..a9333cf0 100644 --- a/docs/public/registry/plugins/supertonic/0.1.0/manifest.json +++ b/docs/public/registry/plugins/supertonic/0.1.0/manifest.json @@ -27,7 +27,7 @@ "expected_size_bytes": 244451376, "license": "MIT", "license_url": "https://github.com/supertone-inc/supertonic/blob/main/LICENSE", - "sha256": "29e18bfdcbfbdd8bef25204b19be21d13fda36d4e66fe31c74e2a01dad457cec" + "sha256": "3c3ba6326cd6c8ee48d4c7322322d1f1f4ebf188bf4a7d80fc218babca186f41" } ] } \ No newline at end of file diff --git a/marketplace/official-plugins.json b/marketplace/official-plugins.json index 3db42b4c..96892d2c 100644 --- a/marketplace/official-plugins.json +++ b/marketplace/official-plugins.json @@ -262,7 +262,7 @@ "expected_size_bytes": 244451376, "license": "MIT", "license_url": "https://github.com/supertone-inc/supertonic/blob/main/LICENSE", - "sha256": "29e18bfdcbfbdd8bef25204b19be21d13fda36d4e66fe31c74e2a01dad457cec" + "sha256": "3c3ba6326cd6c8ee48d4c7322322d1f1f4ebf188bf4a7d80fc218babca186f41" } ] }, diff --git a/plugins/native/supertonic/plugin.yml b/plugins/native/supertonic/plugin.yml index 3bd440b9..1a2d029c 100644 --- a/plugins/native/supertonic/plugin.yml +++ b/plugins/native/supertonic/plugin.yml @@ -19,4 +19,4 @@ models: expected_size_bytes: 244451376 license: MIT license_url: https://github.com/supertone-inc/supertonic/blob/main/LICENSE - sha256: 29e18bfdcbfbdd8bef25204b19be21d13fda36d4e66fe31c74e2a01dad457cec + sha256: 3c3ba6326cd6c8ee48d4c7322322d1f1f4ebf188bf4a7d80fc218babca186f41 diff --git a/ui/src/views/plugins/MarketplaceModelsSection.tsx b/ui/src/views/plugins/MarketplaceModelsSection.tsx index 411672cc..70c5ae6a 100644 --- a/ui/src/views/plugins/MarketplaceModelsSection.tsx +++ b/ui/src/views/plugins/MarketplaceModelsSection.tsx @@ -20,70 +20,41 @@ import { formatBytes } from './marketplaceFormatters'; type MarketplaceModelsSectionProps = { hasModels: boolean; hasModelSelection: boolean; - installModels: boolean; hasGatedModels: boolean; models: MarketplacePluginDetails['manifest']['models']; selectedModelIds: string[]; onModelToggle: (modelId: string, checked: boolean) => void; - onInstallModelsChange: (value: boolean) => void; }; export const MarketplaceModelsSection: React.FC = ({ hasModels, hasModelSelection, - installModels, hasGatedModels, models, selectedModelIds, onModelToggle, - onInstallModelsChange, }) => { if (!hasModels) return null; return ( <> Models - + {hasGatedModels && ( + Gated models require a Hugging Face token configured on the server. + )} - {installModels && !hasModelSelection && ( + {!hasModelSelection && ( Model selection is not available for this plugin. )} ); }; -const MarketplaceModelsToggle: React.FC<{ - enabled: boolean; - checked: boolean; - hasGatedModels: boolean; - onChange: (value: boolean) => void; -}> = ({ enabled, checked, hasGatedModels, onChange }) => { - if (!enabled) return null; - return ( - <> - onChange(Boolean(value))} - /> - {hasGatedModels && ( - Gated models require a Hugging Face token configured on the server. - )} - - ); -}; - const MarketplaceModelsSelection: React.FC<{ enabled: boolean; models: MarketplacePluginDetails['manifest']['models']; diff --git a/ui/src/views/plugins/MarketplacePanels.tsx b/ui/src/views/plugins/MarketplacePanels.tsx index d0481922..f258763a 100644 --- a/ui/src/views/plugins/MarketplacePanels.tsx +++ b/ui/src/views/plugins/MarketplacePanels.tsx @@ -112,14 +112,14 @@ const buildInstallBlockedReasons = ({ reasons.push('License acceptance required.'); } if (missingModelSelection) { - reasons.push('Select at least one model or disable model downloads.'); + reasons.push('Select at least one model to download.'); } if (!allowNativeMarketplace) { reasons.push('Native marketplace installs are disabled in server config.'); } if (installedPlugin) { if (!installModels) { - reasons.push('Plugin already installed. Enable model downloads or uninstall to replace it.'); + reasons.push('Plugin already installed. Select models to download or uninstall first.'); } else if (!hasModels) { reasons.push('Plugin already installed and has no models to download.'); } else if (versionMismatch && installedVersion) { @@ -199,7 +199,6 @@ type MarketplaceDetailsPanelProps = { installing: boolean; onVersionChange: (value: string) => void; onLicenseAccepted: (value: boolean) => void; - onInstallModelsChange: (value: boolean) => void; onInstall: () => void; }; @@ -222,7 +221,6 @@ export const MarketplaceDetailsPanel: React.FC = ( installing, onVersionChange, onLicenseAccepted, - onInstallModelsChange, onInstall, }) => { if (!details && loading) return ; @@ -274,12 +272,10 @@ export const MarketplaceDetailsPanel: React.FC = ( > -) => { - if (!details) { - setInstallModels(false); - return; - } - setInstallModels(details.manifest.models.length > 0); -}; - const defaultModelSelection = (details: MarketplacePluginDetails | null) => { const models = details?.manifest.models ?? []; if (models.length === 0) return []; @@ -192,17 +181,12 @@ const useInstalledPlugin = ( }, [details, installedPlugins]); }; -const useModelFlags = ( - details: MarketplacePluginDetails | null, - selectedModelIds: string[], - installModels: boolean -) => { +const useModelFlags = (details: MarketplacePluginDetails | null, selectedModelIds: string[]) => { const flags = useMemo( () => deriveModelFlags(details, selectedModelIds), [details, selectedModelIds] ); - const missingModelSelection = - installModels && flags.hasModelSelection && selectedModelIds.length === 0; + const missingModelSelection = false; return { ...flags, missingModelSelection }; }; @@ -268,6 +252,82 @@ const startInstall = async ({ } }; +const useMarketplaceHandlers = ({ + details, + selectedModelIds, + resetJob, + setInstalling, + setJobId, + setSelectedRegistry, + setSelectedPluginId, + setSelectedModelIds, + toast, +}: { + details: MarketplacePluginDetails | null; + selectedModelIds: string[]; + resetJob: () => void; + setInstalling: React.Dispatch>; + setJobId: React.Dispatch>; + setSelectedRegistry: (value: string) => void; + setSelectedPluginId: React.Dispatch>; + setSelectedModelIds: React.Dispatch>; + toast: ReturnType; +}) => { + const handleInstall = useCallback(() => { + const hasSelectedModels = + (details?.manifest.models.length ?? 0) > 0 && selectedModelIds.length > 0; + void startInstall({ + details, + installModels: hasSelectedModels, + selectedModelIds, + resetJob, + setInstalling, + setJobId, + toast, + }); + }, [details, selectedModelIds, resetJob, setInstalling, setJobId, toast]); + + const handleClearJob = useCallback(() => { + setJobId(null); + resetJob(); + }, [setJobId, resetJob]); + + const handleSelectRegistry = useCallback( + (value: string) => { + setSelectedRegistry(value); + setSelectedPluginId(null); + }, + [setSelectedRegistry, setSelectedPluginId] + ); + + const handleSelectPlugin = useCallback( + (pluginId: string) => { + setSelectedPluginId(pluginId); + }, + [setSelectedPluginId] + ); + + const handleToggleModel = useCallback( + (modelId: string, checked: boolean) => { + setSelectedModelIds((current) => { + if (checked) { + return current.includes(modelId) ? current : [...current, modelId]; + } + return current.filter((id) => id !== modelId); + }); + }, + [setSelectedModelIds] + ); + + return { + handleInstall, + handleClearJob, + handleSelectRegistry, + handleSelectPlugin, + handleToggleModel, + }; +}; + const MarketplaceTab: React.FC = ({ active }) => { const { can } = usePermissions(); const toast = useToast(); @@ -284,10 +344,10 @@ const MarketplaceTab: React.FC = ({ active }) => { const { searchInput, setSearchInput, debouncedSearch } = useDebouncedSearch('', 300); const [selectedPluginId, setSelectedPluginId] = useState(null); const [licenseAccepted, setLicenseAccepted] = useState(false); - const [installModels, setInstallModels] = useState(false); const [selectedModelIds, setSelectedModelIds] = useState([]); const [jobId, setJobId] = useState(null); const [installing, setInstalling] = useState(false); + const jobPanelRef = useRef(null); const { index, @@ -312,7 +372,6 @@ const MarketplaceTab: React.FC = ({ active }) => { }, [selectedPluginId, selectedVersion]); useEffect(() => { - syncInstallModels(details, setInstallModels); setSelectedModelIds(defaultModelSelection(details)); }, [details, selectedVersion]); @@ -335,42 +394,29 @@ const MarketplaceTab: React.FC = ({ active }) => { const { jobInfo, jobError, cancelJob, resetJob } = useMarketplaceJob(jobId, jobCallbacks); - const handleInstall = useCallback(() => { - void startInstall({ - details, - installModels, - selectedModelIds, - resetJob, - setInstalling, - setJobId, - toast, - }); - }, [details, installModels, selectedModelIds, resetJob, setInstalling, setJobId, toast]); - - const handleClearJob = useCallback(() => { - setJobId(null); - resetJob(); - }, [resetJob]); - - const handleSelectRegistry = useCallback( - (value: string) => { - setSelectedRegistry(value); - setSelectedPluginId(null); - }, - [setSelectedRegistry] - ); + useEffect(() => { + if (jobId && jobPanelRef.current) { + jobPanelRef.current.scrollIntoView({ behavior: 'smooth', block: 'nearest' }); + } + }, [jobId]); - const handleSelectPlugin = useCallback((pluginId: string) => { - setSelectedPluginId(pluginId); - }, []); - const handleToggleModel = useCallback((modelId: string, checked: boolean) => { - setSelectedModelIds((current) => { - if (checked) { - return current.includes(modelId) ? current : [...current, modelId]; - } - return current.filter((id) => id !== modelId); - }); - }, []); + const { + handleInstall, + handleClearJob, + handleSelectRegistry, + handleSelectPlugin, + handleToggleModel, + } = useMarketplaceHandlers({ + details, + selectedModelIds, + resetJob, + setInstalling, + setJobId, + setSelectedRegistry, + setSelectedPluginId, + setSelectedModelIds, + toast, + }); const installedPlugin = useInstalledPlugin(details, active); const { @@ -379,7 +425,8 @@ const MarketplaceTab: React.FC = ({ active }) => { hasGatedModels, requiresLicenseAcceptance, missingModelSelection, - } = useModelFlags(details, selectedModelIds, installModels); + } = useModelFlags(details, selectedModelIds); + const installModels = hasModels && selectedModelIds.length > 0; const installedVersion = installedPlugin?.version ?? null; const canInstall = useMemo( @@ -467,7 +514,6 @@ const MarketplaceTab: React.FC = ({ active }) => { onLicenseAccepted={setLicenseAccepted} requiresLicenseAcceptance={requiresLicenseAcceptance} installModels={installModels} - onInstallModelsChange={setInstallModels} hasModels={hasModels} hasModelSelection={hasModelSelection} hasGatedModels={hasGatedModels} @@ -482,15 +528,17 @@ const MarketplaceTab: React.FC = ({ active }) => { /> - +
+ +
); }; From 7077103785aa42942ce7d64bd9900127b276a671 Mon Sep 17 00:00:00 2001 From: streamer45 Date: Fri, 30 Jan 2026 18:13:34 +0100 Subject: [PATCH 2/2] fix: reset marketplace --- .github/workflows/release.yml | 10 +- docs/public/registry/index.json | 145 +----------------- .../plugins/helsinki/0.1.0/manifest.json | 46 ------ .../plugins/helsinki/0.1.0/manifest.minisig | 4 - .../plugins/kokoro/0.1.0/manifest.json | 33 ---- .../plugins/kokoro/0.1.0/manifest.minisig | 4 - .../plugins/matcha/0.1.0/manifest.json | 33 ---- .../plugins/matcha/0.1.0/manifest.minisig | 4 - .../registry/plugins/nllb/0.1.0/manifest.json | 32 ---- .../plugins/nllb/0.1.0/manifest.minisig | 4 - .../plugins/piper/0.1.0/manifest.json | 48 ------ .../plugins/piper/0.1.0/manifest.minisig | 4 - .../plugins/pocket-tts/0.1.0/manifest.json | 33 ---- .../plugins/pocket-tts/0.1.0/manifest.minisig | 4 - .../plugins/sensevoice/0.1.0/manifest.json | 48 ------ .../plugins/sensevoice/0.1.0/manifest.minisig | 4 - .../plugins/supertonic/0.1.0/manifest.json | 33 ---- .../plugins/supertonic/0.1.0/manifest.minisig | 4 - .../registry/plugins/vad/0.1.0/manifest.json | 33 ---- .../plugins/vad/0.1.0/manifest.minisig | 4 - .../plugins/whisper/0.1.1/manifest.json | 78 ---------- .../plugins/whisper/0.1.1/manifest.minisig | 4 - 22 files changed, 3 insertions(+), 609 deletions(-) delete mode 100644 docs/public/registry/plugins/helsinki/0.1.0/manifest.json delete mode 100644 docs/public/registry/plugins/helsinki/0.1.0/manifest.minisig delete mode 100644 docs/public/registry/plugins/kokoro/0.1.0/manifest.json delete mode 100644 docs/public/registry/plugins/kokoro/0.1.0/manifest.minisig delete mode 100644 docs/public/registry/plugins/matcha/0.1.0/manifest.json delete mode 100644 docs/public/registry/plugins/matcha/0.1.0/manifest.minisig delete mode 100644 docs/public/registry/plugins/nllb/0.1.0/manifest.json delete mode 100644 docs/public/registry/plugins/nllb/0.1.0/manifest.minisig delete mode 100644 docs/public/registry/plugins/piper/0.1.0/manifest.json delete mode 100644 docs/public/registry/plugins/piper/0.1.0/manifest.minisig delete mode 100644 docs/public/registry/plugins/pocket-tts/0.1.0/manifest.json delete mode 100644 docs/public/registry/plugins/pocket-tts/0.1.0/manifest.minisig delete mode 100644 docs/public/registry/plugins/sensevoice/0.1.0/manifest.json delete mode 100644 docs/public/registry/plugins/sensevoice/0.1.0/manifest.minisig delete mode 100644 docs/public/registry/plugins/supertonic/0.1.0/manifest.json delete mode 100644 docs/public/registry/plugins/supertonic/0.1.0/manifest.minisig delete mode 100644 docs/public/registry/plugins/vad/0.1.0/manifest.json delete mode 100644 docs/public/registry/plugins/vad/0.1.0/manifest.minisig delete mode 100644 docs/public/registry/plugins/whisper/0.1.1/manifest.json delete mode 100644 docs/public/registry/plugins/whisper/0.1.1/manifest.minisig diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b9514c3a..28ea8769 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -80,16 +80,9 @@ jobs: streamkit-${{ github.ref_name }}-linux-x64.tar.gz streamkit-${{ github.ref_name }}-linux-x64.tar.gz.sha256 - marketplace: - uses: ./.github/workflows/marketplace-build.yml - permissions: - contents: write - pull-requests: write - secrets: inherit - create-release: name: Create GitHub Release - needs: [build-linux-x64, marketplace] + needs: [build-linux-x64] runs-on: ubuntu-22.04 permissions: contents: write @@ -130,7 +123,6 @@ jobs: files: | artifacts/**/streamkit-*.tar.gz artifacts/**/streamkit-*.tar.gz.sha256 - artifacts/**/marketplace-bundles/*.tar.zst body_path: changelog.md draft: false prerelease: ${{ contains(github.ref_name, '-rc') || contains(github.ref_name, '-beta') || contains(github.ref_name, '-alpha') }} diff --git a/docs/public/registry/index.json b/docs/public/registry/index.json index 1dea6734..ea952a7b 100644 --- a/docs/public/registry/index.json +++ b/docs/public/registry/index.json @@ -1,145 +1,4 @@ { "schema_version": 1, - "plugins": [ - { - "id": "helsinki", - "name": "Helsinki", - "description": "Neural machine translation using OPUS-MT", - "latest": "0.1.0", - "versions": [ - { - "version": "0.1.0", - "manifest_url": "https://streamkit.dev/registry/plugins/helsinki/0.1.0/manifest.json", - "signature_url": "https://streamkit.dev/registry/plugins/helsinki/0.1.0/manifest.minisig", - "published_at": "2026-01-29" - } - ] - }, - { - "id": "kokoro", - "name": "Kokoro", - "description": "Text-to-speech using Sherpa-ONNX Kokoro models", - "latest": "0.1.0", - "versions": [ - { - "version": "0.1.0", - "manifest_url": "https://streamkit.dev/registry/plugins/kokoro/0.1.0/manifest.json", - "signature_url": "https://streamkit.dev/registry/plugins/kokoro/0.1.0/manifest.minisig", - "published_at": "2026-01-29" - } - ] - }, - { - "id": "matcha", - "name": "Matcha", - "description": "Text-to-speech using Matcha models", - "latest": "0.1.0", - "versions": [ - { - "version": "0.1.0", - "manifest_url": "https://streamkit.dev/registry/plugins/matcha/0.1.0/manifest.json", - "signature_url": "https://streamkit.dev/registry/plugins/matcha/0.1.0/manifest.minisig", - "published_at": "2026-01-29" - } - ] - }, - { - "id": "nllb", - "name": "NLLB", - "description": "Neural machine translation using NLLB", - "latest": "0.1.0", - "versions": [ - { - "version": "0.1.0", - "manifest_url": "https://streamkit.dev/registry/plugins/nllb/0.1.0/manifest.json", - "signature_url": "https://streamkit.dev/registry/plugins/nllb/0.1.0/manifest.minisig", - "published_at": "2026-01-29" - } - ] - }, - { - "id": "piper", - "name": "Piper", - "description": "Text-to-speech using Piper VITS models", - "latest": "0.1.0", - "versions": [ - { - "version": "0.1.0", - "manifest_url": "https://streamkit.dev/registry/plugins/piper/0.1.0/manifest.json", - "signature_url": "https://streamkit.dev/registry/plugins/piper/0.1.0/manifest.minisig", - "published_at": "2026-01-29" - } - ] - }, - { - "id": "pocket-tts", - "name": "Pocket TTS", - "description": "Lightweight CPU TTS using Kyutai Pocket TTS (Candle)", - "latest": "0.1.0", - "versions": [ - { - "version": "0.1.0", - "manifest_url": "https://streamkit.dev/registry/plugins/pocket-tts/0.1.0/manifest.json", - "signature_url": "https://streamkit.dev/registry/plugins/pocket-tts/0.1.0/manifest.minisig", - "published_at": "2026-01-29" - } - ] - }, - { - "id": "sensevoice", - "name": "SenseVoice", - "description": "Streaming speech-to-text using SenseVoice", - "latest": "0.1.0", - "versions": [ - { - "version": "0.1.0", - "manifest_url": "https://streamkit.dev/registry/plugins/sensevoice/0.1.0/manifest.json", - "signature_url": "https://streamkit.dev/registry/plugins/sensevoice/0.1.0/manifest.minisig", - "published_at": "2026-01-29" - } - ] - }, - { - "id": "supertonic", - "name": "Supertonic", - "description": "Multilingual TTS using Supertonic (66M params, 5 languages, up to 167x real-time)", - "latest": "0.1.0", - "versions": [ - { - "version": "0.1.0", - "manifest_url": "https://streamkit.dev/registry/plugins/supertonic/0.1.0/manifest.json", - "signature_url": "https://streamkit.dev/registry/plugins/supertonic/0.1.0/manifest.minisig", - "published_at": "2026-01-29" - } - ] - }, - { - "id": "vad", - "name": "VAD", - "description": "Voice activity detection", - "latest": "0.1.0", - "versions": [ - { - "version": "0.1.0", - "manifest_url": "https://streamkit.dev/registry/plugins/vad/0.1.0/manifest.json", - "signature_url": "https://streamkit.dev/registry/plugins/vad/0.1.0/manifest.minisig", - "published_at": "2026-01-29" - } - ] - }, - { - "id": "whisper", - "name": "Whisper", - "description": "Streaming speech-to-text using whisper.cpp", - "latest": "0.1.1", - "versions": [ - { - "version": "0.1.1", - "manifest_url": "https://streamkit.dev/registry/plugins/whisper/0.1.1/manifest.json", - "signature_url": "https://streamkit.dev/registry/plugins/whisper/0.1.1/manifest.minisig", - "published_at": "2026-01-29" - } - ] - } - ] -} \ No newline at end of file + "plugins": [] +} diff --git a/docs/public/registry/plugins/helsinki/0.1.0/manifest.json b/docs/public/registry/plugins/helsinki/0.1.0/manifest.json deleted file mode 100644 index 0992563a..00000000 --- a/docs/public/registry/plugins/helsinki/0.1.0/manifest.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "schema_version": 1, - "id": "helsinki", - "name": "Helsinki", - "version": "0.1.0", - "node_kind": "helsinki", - "kind": "native", - "description": "Neural machine translation using OPUS-MT", - "license": "MPL-2.0", - "entrypoint": "libhelsinki.so", - "bundle": { - "url": "https://github.com/streamer45/streamkit/releases/download/plugin-helsinki-v0.1.0/helsinki-0.1.0-bundle.tar.zst", - "sha256": "de5535e66d7b8fc15f66d121508e9fcb683004ca5805a0d8165a52cab9c88396", - "size_bytes": 2789232 - }, - "models": [ - { - "id": "opus-mt-en-es", - "name": "OPUS-MT en-es", - "default": true, - "source": "huggingface", - "repo_id": "streamkit/helsinki-models", - "revision": "main", - "files": [ - "opus-mt-en-es.tar.bz2" - ], - "expected_size_bytes": 284844308, - "license": "Apache-2.0", - "license_url": "https://huggingface.co/Helsinki-NLP/opus-mt-en-es" - }, - { - "id": "opus-mt-es-en", - "name": "OPUS-MT es-en", - "default": false, - "source": "huggingface", - "repo_id": "streamkit/helsinki-models", - "revision": "main", - "files": [ - "opus-mt-es-en.tar.bz2" - ], - "expected_size_bytes": 285443600, - "license": "Apache-2.0", - "license_url": "https://huggingface.co/Helsinki-NLP/opus-mt-es-en" - } - ] -} \ No newline at end of file diff --git a/docs/public/registry/plugins/helsinki/0.1.0/manifest.minisig b/docs/public/registry/plugins/helsinki/0.1.0/manifest.minisig deleted file mode 100644 index 3619c0d7..00000000 --- a/docs/public/registry/plugins/helsinki/0.1.0/manifest.minisig +++ /dev/null @@ -1,4 +0,0 @@ -untrusted comment: signature from minisign secret key -RUQ/85JEqYXEgQu2106jYZ2KJ6PwUN14VB81DAPedhLxxHtee0QvxCMy+8iSwSr7hZicI0FgNBXv++Km4lgNwdXV+Awa6VLD9wo= -trusted comment: timestamp:1769717268 file:manifest.json hashed -e/o1RyUNwNxYO3Fhg9jroLmCcDoF4zvkfyD16pbwcdCtBdi+WvrX3gASAL18RQjFwI0+rtuT51f7CjeT2dEPDg== diff --git a/docs/public/registry/plugins/kokoro/0.1.0/manifest.json b/docs/public/registry/plugins/kokoro/0.1.0/manifest.json deleted file mode 100644 index f9151716..00000000 --- a/docs/public/registry/plugins/kokoro/0.1.0/manifest.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "schema_version": 1, - "id": "kokoro", - "name": "Kokoro", - "version": "0.1.0", - "node_kind": "kokoro", - "kind": "native", - "description": "Text-to-speech using Sherpa-ONNX Kokoro models", - "license": "MPL-2.0", - "entrypoint": "libkokoro.so", - "bundle": { - "url": "https://github.com/streamer45/streamkit/releases/download/plugin-kokoro-v0.1.0/kokoro-0.1.0-bundle.tar.zst", - "sha256": "5eb0a35e1b5fe836db3670613797e6a7c171833c8266bea897d05c3ca8647f83", - "size_bytes": 7644486 - }, - "models": [ - { - "id": "kokoro-multi-lang-v1_1", - "name": "Kokoro multi-lang v1.1", - "default": true, - "source": "huggingface", - "repo_id": "streamkit/kokoro-models", - "revision": "main", - "files": [ - "kokoro-multi-lang-v1_1.tar.bz2" - ], - "expected_size_bytes": 364816464, - "license": "Apache-2.0", - "license_url": "https://github.com/k2-fsa/sherpa-onnx/blob/master/LICENSE", - "sha256": "a3f4c73d043860e3fd2e5b06f36795eb81de0fc8e8de6df703245edddd87dbad" - } - ] -} \ No newline at end of file diff --git a/docs/public/registry/plugins/kokoro/0.1.0/manifest.minisig b/docs/public/registry/plugins/kokoro/0.1.0/manifest.minisig deleted file mode 100644 index fc409fa6..00000000 --- a/docs/public/registry/plugins/kokoro/0.1.0/manifest.minisig +++ /dev/null @@ -1,4 +0,0 @@ -untrusted comment: signature from minisign secret key -RUQ/85JEqYXEgVOIqqCRZrnapQZRodQxOUEi2ICAVcR0IjY7mCueJhHMZxYk6aQKQ9bGub1VODdtTaiYfK/Uj8/q9TsgHP8+ZAk= -trusted comment: timestamp:1769717268 file:manifest.json hashed -y4jobNdLx+BrIonZpMEihNlOGCprEJ56PNOPBESkzas0/SLem84MezhwTscu1CZ72RC7SzLOSv2VnuYGairbBw== diff --git a/docs/public/registry/plugins/matcha/0.1.0/manifest.json b/docs/public/registry/plugins/matcha/0.1.0/manifest.json deleted file mode 100644 index 877a955c..00000000 --- a/docs/public/registry/plugins/matcha/0.1.0/manifest.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "schema_version": 1, - "id": "matcha", - "name": "Matcha", - "version": "0.1.0", - "node_kind": "matcha", - "kind": "native", - "description": "Text-to-speech using Matcha models", - "license": "MPL-2.0", - "entrypoint": "libmatcha.so", - "bundle": { - "url": "https://github.com/streamer45/streamkit/releases/download/plugin-matcha-v0.1.0/matcha-0.1.0-bundle.tar.zst", - "sha256": "cfb69717101ba630b93f09ece2e7764e7f26d36891001806a8fedc5d650aa5a5", - "size_bytes": 7636827 - }, - "models": [ - { - "id": "matcha-icefall-en_US-ljspeech", - "name": "Matcha LJSpeech", - "default": true, - "source": "huggingface", - "repo_id": "streamkit/matcha-models", - "revision": "main", - "files": [ - "matcha-icefall-en_US-ljspeech.tar.bz2", - "matcha-icefall-en_US-ljspeech/vocos-22khz-univ.onnx" - ], - "expected_size_bytes": 130630855, - "license": "CC-BY-4.0", - "license_url": "https://keithito.com/LJ-Speech-Dataset/" - } - ] -} \ No newline at end of file diff --git a/docs/public/registry/plugins/matcha/0.1.0/manifest.minisig b/docs/public/registry/plugins/matcha/0.1.0/manifest.minisig deleted file mode 100644 index 5a68303e..00000000 --- a/docs/public/registry/plugins/matcha/0.1.0/manifest.minisig +++ /dev/null @@ -1,4 +0,0 @@ -untrusted comment: signature from minisign secret key -RUQ/85JEqYXEgR0kiQugS1mMiyGd06qZIlzBzfhXEM5MdNmeBl0Ik0CKRAPsfSUjMlIYL2RFk2Vrzc1gTM1WefHAeSrjYbPsBQc= -trusted comment: timestamp:1769717268 file:manifest.json hashed -ZeroDvu5xAIdY1Fq3VV2BZby3I+WHfJ3Kd6MhjX5o8CqtKCvzcoZptWTdpLHOv10I0iwY+C+h63EKXMTE13KCQ== diff --git a/docs/public/registry/plugins/nllb/0.1.0/manifest.json b/docs/public/registry/plugins/nllb/0.1.0/manifest.json deleted file mode 100644 index 8af8a540..00000000 --- a/docs/public/registry/plugins/nllb/0.1.0/manifest.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "schema_version": 1, - "id": "nllb", - "name": "NLLB", - "version": "0.1.0", - "node_kind": "nllb", - "kind": "native", - "description": "Neural machine translation using NLLB", - "license": "MPL-2.0", - "entrypoint": "libnllb.so", - "bundle": { - "url": "https://github.com/streamer45/streamkit/releases/download/plugin-nllb-v0.1.0/nllb-0.1.0-bundle.tar.zst", - "sha256": "d12cdc5e2497aeddb40a0882c53063f487b37362a370138daa28d2b3f3c3a60c", - "size_bytes": 2991075 - }, - "models": [ - { - "id": "nllb-200-distilled-600M-ct2-int8", - "name": "NLLB-200 distilled 600M (CTranslate2 int8)", - "default": false, - "source": "huggingface", - "repo_id": "streamkit/nllb-models", - "revision": "main", - "files": [ - "nllb-200-distilled-600M-ct2-int8.tar.bz2" - ], - "expected_size_bytes": 1135260128, - "license": "CC-BY-NC-4.0", - "license_url": "https://huggingface.co/facebook/nllb-200-distilled-600M" - } - ] -} \ No newline at end of file diff --git a/docs/public/registry/plugins/nllb/0.1.0/manifest.minisig b/docs/public/registry/plugins/nllb/0.1.0/manifest.minisig deleted file mode 100644 index ccc44719..00000000 --- a/docs/public/registry/plugins/nllb/0.1.0/manifest.minisig +++ /dev/null @@ -1,4 +0,0 @@ -untrusted comment: signature from minisign secret key -RUQ/85JEqYXEgedOcpPsUjfT9dnv0Smz6LOlVfL9s188ObHESxJ0+coB5jz9NB/h7iBIBpcOff2sWo10OZ3j951SPNeHGrdF+AA= -trusted comment: timestamp:1769717268 file:manifest.json hashed -qk4wpijq5ICCBVX1Xh9S+BKCftvkDerYiFx2hc9h4rU+ACYHrtx/RgoxwCV4JOGf+EeJOKd2ej20Q6NS4Q6HCQ== diff --git a/docs/public/registry/plugins/piper/0.1.0/manifest.json b/docs/public/registry/plugins/piper/0.1.0/manifest.json deleted file mode 100644 index 1d199183..00000000 --- a/docs/public/registry/plugins/piper/0.1.0/manifest.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - "schema_version": 1, - "id": "piper", - "name": "Piper", - "version": "0.1.0", - "node_kind": "piper", - "kind": "native", - "description": "Text-to-speech using Piper VITS models", - "license": "MPL-2.0", - "entrypoint": "libpiper.so", - "bundle": { - "url": "https://github.com/streamer45/streamkit/releases/download/plugin-piper-v0.1.0/piper-0.1.0-bundle.tar.zst", - "sha256": "7217234a2b4244cff3e2a3586282cf6d3050204f913a5a0f365a61c0c83190e9", - "size_bytes": 7627068 - }, - "models": [ - { - "id": "piper-en_US-libritts_r-medium", - "name": "Piper en_US libritts_r (medium)", - "default": true, - "source": "huggingface", - "repo_id": "streamkit/piper-models", - "revision": "main", - "files": [ - "vits-piper-en_US-libritts_r-medium.tar.bz2" - ], - "expected_size_bytes": 82018491, - "license": "CC-BY-4.0 + GPL-3.0", - "license_url": "http://www.openslr.org/141/", - "sha256": "78c137daa7eddaf57190cf05c020efd6e593015f62c82ee999ef570fc2dff496" - }, - { - "id": "piper-es_MX-claude-high", - "name": "Piper es_MX claude (high)", - "default": false, - "source": "huggingface", - "repo_id": "streamkit/piper-models", - "revision": "main", - "files": [ - "vits-piper-es_MX-claude-high.tar.bz2" - ], - "expected_size_bytes": 67207890, - "license": "Apache-2.0 + GPL-3.0", - "license_url": "https://huggingface.co/spaces/HirCoir/Piper-TTS-Spanish", - "sha256": "ec33fb689c248fe64810aab564cba97babf0f506672cfd404928d46e751a4721" - } - ] -} \ No newline at end of file diff --git a/docs/public/registry/plugins/piper/0.1.0/manifest.minisig b/docs/public/registry/plugins/piper/0.1.0/manifest.minisig deleted file mode 100644 index 14c56539..00000000 --- a/docs/public/registry/plugins/piper/0.1.0/manifest.minisig +++ /dev/null @@ -1,4 +0,0 @@ -untrusted comment: signature from minisign secret key -RUQ/85JEqYXEgURefh3Phw25TcQnOL8W9tEM75QUoSwbyoaDo/4dMsbTGRF/iF03QK2QupXU4Q4BMZybW/fNHAsLA6Sb9I0fiQw= -trusted comment: timestamp:1769717268 file:manifest.json hashed -ttGX8Ad/afYR4bhAU3P7EuctYDQkMTaDAoG7mHJI0lSIPpuF3xcmKuZeVnRNPm99DtmezI7+qZYzdyySvqbKCA== diff --git a/docs/public/registry/plugins/pocket-tts/0.1.0/manifest.json b/docs/public/registry/plugins/pocket-tts/0.1.0/manifest.json deleted file mode 100644 index 31e21518..00000000 --- a/docs/public/registry/plugins/pocket-tts/0.1.0/manifest.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "schema_version": 1, - "id": "pocket-tts", - "name": "Pocket TTS", - "version": "0.1.0", - "node_kind": "pocket-tts", - "kind": "native", - "description": "Lightweight CPU TTS using Kyutai Pocket TTS (Candle)", - "license": "MPL-2.0", - "entrypoint": "libpocket_tts.so", - "bundle": { - "url": "https://github.com/streamer45/streamkit/releases/download/plugin-pocket-tts-v0.1.0/pocket-tts-0.1.0-bundle.tar.zst", - "sha256": "2886408704e27df88df0ed72000cf00615b54a0ecb1d3391785e5926fbdad114", - "size_bytes": 3809057 - }, - "models": [ - { - "id": "pocket-tts-b6369a24", - "name": "Pocket TTS b6369a24", - "default": true, - "source": "huggingface", - "repo_id": "streamkit/pocket-tts-models", - "revision": "main", - "files": [ - "pocket-tts-b6369a24.tar.bz2" - ], - "expected_size_bytes": 169847585, - "license": "CC-BY-4.0", - "license_url": "https://huggingface.co/kyutai/pocket-tts", - "sha256": "7661d610217e8d2b0ae1d8739d384756e50c734fb136047679ca651385ed3035" - } - ] -} \ No newline at end of file diff --git a/docs/public/registry/plugins/pocket-tts/0.1.0/manifest.minisig b/docs/public/registry/plugins/pocket-tts/0.1.0/manifest.minisig deleted file mode 100644 index 285845bd..00000000 --- a/docs/public/registry/plugins/pocket-tts/0.1.0/manifest.minisig +++ /dev/null @@ -1,4 +0,0 @@ -untrusted comment: signature from minisign secret key -RUQ/85JEqYXEgbuH5QNW3vBIjqIz7jdJoSNuO2vIedM8RM2DdfIVkr+gMvQqHJpjOSiFq9bGK4koacCqrOQBpkXTE+YLskYTcAw= -trusted comment: timestamp:1769717268 file:manifest.json hashed -MXoCAAbUV9i3pZp8+h+UMF6HmFF2EnyOvNE43CoDxJYegHW6sUO85Lxfyq+7Ce6heykgLmr4acK6PD4XN9NgCw== diff --git a/docs/public/registry/plugins/sensevoice/0.1.0/manifest.json b/docs/public/registry/plugins/sensevoice/0.1.0/manifest.json deleted file mode 100644 index dd504b35..00000000 --- a/docs/public/registry/plugins/sensevoice/0.1.0/manifest.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - "schema_version": 1, - "id": "sensevoice", - "name": "SenseVoice", - "version": "0.1.0", - "node_kind": "sensevoice", - "kind": "native", - "description": "Streaming speech-to-text using SenseVoice", - "license": "MPL-2.0", - "entrypoint": "libsensevoice.so", - "bundle": { - "url": "https://github.com/streamer45/streamkit/releases/download/plugin-sensevoice-v0.1.0/sensevoice-0.1.0-bundle.tar.zst", - "sha256": "794a6613ce878e8cd1991aefd350dfce8795cd1734a6f8bd5bf72a8b8a429217", - "size_bytes": 15627755 - }, - "models": [ - { - "id": "sensevoice-small-yue", - "name": "SenseVoice small (yue)", - "default": true, - "source": "huggingface", - "repo_id": "streamkit/sensevoice-models", - "revision": "main", - "files": [ - "sherpa-onnx-sense-voice-zh-en-ja-ko-yue-int8-2025-09-09.tar.bz2" - ], - "expected_size_bytes": 165783878, - "license": "Apache-2.0", - "license_url": "https://huggingface.co/ASLP-lab/WSYue-ASR", - "sha256": "7305f7905bfcf77fa0b39388a313f3da35c68d971661a65475b56fb2162c8e63" - }, - { - "id": "silero-vad", - "name": "Silero VAD (v6.2)", - "default": true, - "source": "huggingface", - "repo_id": "streamkit/sensevoice-models", - "revision": "main", - "files": [ - "silero_vad.onnx" - ], - "expected_size_bytes": 2327524, - "license": "MIT", - "license_url": "https://github.com/snakers4/silero-vad/blob/master/LICENSE", - "sha256": "1a153a22f4509e292a94e67d6f9b85e8deb25b4988682b7e174c65279d8788e3" - } - ] -} \ No newline at end of file diff --git a/docs/public/registry/plugins/sensevoice/0.1.0/manifest.minisig b/docs/public/registry/plugins/sensevoice/0.1.0/manifest.minisig deleted file mode 100644 index 26635dae..00000000 --- a/docs/public/registry/plugins/sensevoice/0.1.0/manifest.minisig +++ /dev/null @@ -1,4 +0,0 @@ -untrusted comment: signature from minisign secret key -RUQ/85JEqYXEgY0p6W3HWAXJoAjLz/mX2qaHuIiYcgaXUM/QdZZVYK9WrLycAMMI9hj+ojwduSzCDQ4jFNLhWS3gOzceICUULQ4= -trusted comment: timestamp:1769717269 file:manifest.json hashed -2nrnxCQmxrvy5RQxKTba4A1ci2Bbit1b+w6QgiJWZVEv0PV0Wqc37Wd4CmZvbI/qoUg3V/raDcXl9NkapPoICA== diff --git a/docs/public/registry/plugins/supertonic/0.1.0/manifest.json b/docs/public/registry/plugins/supertonic/0.1.0/manifest.json deleted file mode 100644 index a9333cf0..00000000 --- a/docs/public/registry/plugins/supertonic/0.1.0/manifest.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "schema_version": 1, - "id": "supertonic", - "name": "Supertonic", - "version": "0.1.0", - "node_kind": "supertonic", - "kind": "native", - "description": "Multilingual TTS using Supertonic (66M params, 5 languages, up to 167x real-time)", - "license": "MPL-2.0", - "entrypoint": "libsupertonic.so", - "bundle": { - "url": "https://github.com/streamer45/streamkit/releases/download/plugin-supertonic-v0.1.0/supertonic-0.1.0-bundle.tar.zst", - "sha256": "c39ea1021cb476693d70ecb08f3d3c6fdb5128e6b33acfd50f7b34c8dc3c4601", - "size_bytes": 9164768 - }, - "models": [ - { - "id": "supertonic-v2-onnx", - "name": "Supertonic v2 ONNX models", - "default": true, - "source": "huggingface", - "repo_id": "streamkit/supertonic-models", - "revision": "main", - "files": [ - "supertonic-v2-onnx.tar.bz2" - ], - "expected_size_bytes": 244451376, - "license": "MIT", - "license_url": "https://github.com/supertone-inc/supertonic/blob/main/LICENSE", - "sha256": "3c3ba6326cd6c8ee48d4c7322322d1f1f4ebf188bf4a7d80fc218babca186f41" - } - ] -} \ No newline at end of file diff --git a/docs/public/registry/plugins/supertonic/0.1.0/manifest.minisig b/docs/public/registry/plugins/supertonic/0.1.0/manifest.minisig deleted file mode 100644 index 7f88546a..00000000 --- a/docs/public/registry/plugins/supertonic/0.1.0/manifest.minisig +++ /dev/null @@ -1,4 +0,0 @@ -untrusted comment: signature from minisign secret key -RUQ/85JEqYXEgYQvN4GdkRgrQjbRVt1FWCkqrsWLz4KZtadWIecZR341I2keF35uSHRPJ0YDMg94pXi9QefppUlD3EX8jINESA4= -trusted comment: timestamp:1769717269 file:manifest.json hashed -eRg8tlBkfOdHXc4hP7rGBEvlfpxybtcOFwfMjPDJ91t3kKeiqdbBo23rG7Q8+27n2kTqu7fQMrkhGM1+9KqkAg== diff --git a/docs/public/registry/plugins/vad/0.1.0/manifest.json b/docs/public/registry/plugins/vad/0.1.0/manifest.json deleted file mode 100644 index f07dc0c5..00000000 --- a/docs/public/registry/plugins/vad/0.1.0/manifest.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "schema_version": 1, - "id": "vad", - "name": "VAD", - "version": "0.1.0", - "node_kind": "vad", - "kind": "native", - "description": "Voice activity detection", - "license": "MPL-2.0", - "entrypoint": "libvad.so", - "bundle": { - "url": "https://github.com/streamer45/streamkit/releases/download/plugin-vad-v0.1.0/vad-0.1.0-bundle.tar.zst", - "sha256": "bf8e4d120eddc1252780f62b37ad165689f354ac617b1a36b2533f2f13b5c4ab", - "size_bytes": 7617833 - }, - "models": [ - { - "id": "ten-vad", - "name": "ten-vad", - "default": true, - "source": "huggingface", - "repo_id": "streamkit/vad-models", - "revision": "main", - "files": [ - "ten-vad.onnx" - ], - "expected_size_bytes": 332211, - "license": "LicenseRef-ten-vad", - "license_url": "https://github.com/TEN-framework/ten-vad", - "sha256": "718cb7eef47e3cf5ddbe7e967a7503f46b8b469c0706872f494dfa921b486206" - } - ] -} \ No newline at end of file diff --git a/docs/public/registry/plugins/vad/0.1.0/manifest.minisig b/docs/public/registry/plugins/vad/0.1.0/manifest.minisig deleted file mode 100644 index 9e99affe..00000000 --- a/docs/public/registry/plugins/vad/0.1.0/manifest.minisig +++ /dev/null @@ -1,4 +0,0 @@ -untrusted comment: signature from minisign secret key -RUQ/85JEqYXEgfqO7Fzh/mcQns+gDnKrjCKiCsIk7uqSQ/bF3OknbJTwkMfIrKTgS8X95TBzpIOWE4HRbnz6WSNfe3RwfllgXQM= -trusted comment: timestamp:1769717269 file:manifest.json hashed -I4qDY2MKUmgznrS7px3kHY98p0pUa1RIn37RGAYi/L6Yrrtx7bevPFwn4r8GwqugLhM5Vr+1jizrcfq8ZwguBw== diff --git a/docs/public/registry/plugins/whisper/0.1.1/manifest.json b/docs/public/registry/plugins/whisper/0.1.1/manifest.json deleted file mode 100644 index ea933a12..00000000 --- a/docs/public/registry/plugins/whisper/0.1.1/manifest.json +++ /dev/null @@ -1,78 +0,0 @@ -{ - "schema_version": 1, - "id": "whisper", - "name": "Whisper", - "version": "0.1.1", - "node_kind": "whisper", - "kind": "native", - "description": "Streaming speech-to-text using whisper.cpp", - "license": "MPL-2.0", - "entrypoint": "libwhisper.so", - "bundle": { - "url": "https://github.com/streamer45/streamkit/releases/download/plugin-whisper-v0.1.1/whisper-0.1.1-bundle.tar.zst", - "sha256": "ff81371bf0a9c89c8ecf0f8d8607810bd461b7ff81f9e803260aa5c7a91b9578", - "size_bytes": 8761041 - }, - "models": [ - { - "id": "whisper-tiny-en-q5_1", - "name": "Whisper tiny.en (q5_1)", - "default": true, - "source": "huggingface", - "repo_id": "streamkit/whisper-models", - "revision": "main", - "files": [ - "ggml-tiny.en-q5_1.bin" - ], - "expected_size_bytes": 32166155, - "license": "MIT", - "license_url": "https://github.com/openai/whisper/blob/main/LICENSE", - "sha256": "c77c5766f1cef09b6b7d47f21b546cbddd4157886b3b5d6d4f709e91e66c7c2b" - }, - { - "id": "whisper-base-en-q5_1", - "name": "Whisper base.en (q5_1)", - "default": false, - "source": "huggingface", - "repo_id": "streamkit/whisper-models", - "revision": "main", - "files": [ - "ggml-base.en-q5_1.bin" - ], - "expected_size_bytes": 59721011, - "license": "MIT", - "license_url": "https://github.com/openai/whisper/blob/main/LICENSE", - "sha256": "4baf70dd0d7c4247ba2b81fafd9c01005ac77c2f9ef064e00dcf195d0e2fdd2f" - }, - { - "id": "whisper-base-q5_1", - "name": "Whisper base (q5_1)", - "default": false, - "source": "huggingface", - "repo_id": "streamkit/whisper-models", - "revision": "main", - "files": [ - "ggml-base-q5_1.bin" - ], - "expected_size_bytes": 59707625, - "license": "MIT", - "license_url": "https://github.com/openai/whisper/blob/main/LICENSE", - "sha256": "422f1ae452ade6f30a004d7e5c6a43195e4433bc370bf23fac9cc591f01a8898" - }, - { - "id": "silero-vad", - "name": "Silero VAD (v6.2)", - "default": true, - "source": "huggingface", - "repo_id": "streamkit/whisper-models", - "revision": "main", - "files": [ - "silero_vad.onnx" - ], - "expected_size_bytes": 2327524, - "license": "MIT", - "license_url": "https://github.com/snakers4/silero-vad/blob/master/LICENSE", - "sha256": "1a153a22f4509e292a94e67d6f9b85e8deb25b4988682b7e174c65279d8788e3" - } - ] -} \ No newline at end of file diff --git a/docs/public/registry/plugins/whisper/0.1.1/manifest.minisig b/docs/public/registry/plugins/whisper/0.1.1/manifest.minisig deleted file mode 100644 index 5c9e07fd..00000000 --- a/docs/public/registry/plugins/whisper/0.1.1/manifest.minisig +++ /dev/null @@ -1,4 +0,0 @@ -untrusted comment: signature from minisign secret key -RUQ/85JEqYXEgULvwCe2crZXTQOZud/knEPBf1SW2W8f0u6BhYxi0Gpko+iUcrl7P3uE5M2f6a1HWbwAUQzy7flRuaP1ZInhlgs= -trusted comment: timestamp:1769717269 file:manifest.json hashed -h3zyY86zG2ooBmwJ7Vlnuy/JYHHACsa6cMDAQfxkopaNScodanbN4m2H/PPkaFFdJzq5IZDVHpA3aS8t4GwxAw==