[feat] implement backend abstraction, dynamic backend selection, and GPU feature integration

This commit is contained in:
2025-08-13 11:36:09 +02:00
parent 5ace0a0d7e
commit 3344a3b18c
22 changed files with 2746 additions and 1004 deletions

View File

@@ -0,0 +1,17 @@
[package]
name = "polyscribe-plugin-tubescribe"
version = "0.1.0"
edition = "2024"
license = "MIT"
[[bin]]
name = "polyscribe-plugin-tubescribe"
path = "src/main.rs"
[dependencies]
anyhow = "1.0.98"
clap = { version = "4.5.43", features = ["derive"] }
serde = { version = "1.0.219", features = ["derive"] }
serde_json = "1.0.142"
tokio = { version = "1", features = ["full"] }
polyscribe-protocol = { path = "../../crates/polyscribe-protocol" }

View File

@@ -0,0 +1,18 @@
# Simple helper to build and link the plugin into the user's XDG data dir
# Usage:
# make build
# make link
PLUGIN := polyscribe-plugin-tubescribe
BIN := ../../target/release/$(PLUGIN)
.PHONY: build link
build:
cargo build -p $(PLUGIN) --release
link: build
@DATA_DIR=$${XDG_DATA_HOME:-$$HOME/.local/share}; \
mkdir -p $$DATA_DIR/polyscribe/plugins; \
ln -sf "$(CURDIR)/$(BIN)" $$DATA_DIR/polyscribe/plugins/$(PLUGIN); \
echo "Linked: $$DATA_DIR/polyscribe/plugins/$(PLUGIN) -> $(CURDIR)/$(BIN)"

View File

@@ -0,0 +1,99 @@
// SPDX-License-Identifier: MIT
// Stub plugin: tubescribe
use anyhow::{Context, Result};
use clap::Parser;
use polyscribe_protocol as psp;
use serde_json::json;
use std::io::{BufRead, BufReader, Write};
#[derive(Parser, Debug)]
#[command(name = "polyscribe-plugin-tubescribe", version, about = "Stub tubescribe plugin for PolyScribe PSP/1")]
struct Args {
/// Print capabilities JSON and exit
#[arg(long)]
capabilities: bool,
/// Serve mode: read one JSON-RPC request from stdin, stream progress and final result
#[arg(long)]
serve: bool,
}
fn main() -> Result<()> {
let args = Args::parse();
if args.capabilities {
let caps = psp::Capabilities {
name: "tubescribe".to_string(),
version: env!("CARGO_PKG_VERSION").to_string(),
protocol: "psp/1".to_string(),
role: "pipeline".to_string(),
commands: vec!["generate_metadata".to_string()],
};
let s = serde_json::to_string(&caps)?;
println!("{}", s);
return Ok(());
}
if args.serve {
serve_once()?;
return Ok(());
}
// Default: show capabilities (friendly behavior if run without flags)
let caps = psp::Capabilities {
name: "tubescribe".to_string(),
version: env!("CARGO_PKG_VERSION").to_string(),
protocol: "psp/1".to_string(),
role: "pipeline".to_string(),
commands: vec!["generate_metadata".to_string()],
};
println!("{}", serde_json::to_string(&caps)?);
Ok(())
}
fn serve_once() -> Result<()> {
// Read exactly one line (one request)
let stdin = std::io::stdin();
let mut reader = BufReader::new(stdin.lock());
let mut line = String::new();
reader.read_line(&mut line).context("failed to read request line")?;
let req: psp::JsonRpcRequest = serde_json::from_str(line.trim()).context("invalid JSON-RPC request")?;
// Simulate doing some work with progress
emit(&psp::StreamItem::progress(5, Some("start".into()), Some("initializing".into())))?;
std::thread::sleep(std::time::Duration::from_millis(50));
emit(&psp::StreamItem::progress(25, Some("probe".into()), Some("probing sources".into())))?;
std::thread::sleep(std::time::Duration::from_millis(50));
emit(&psp::StreamItem::progress(60, Some("analyze".into()), Some("analyzing".into())))?;
std::thread::sleep(std::time::Duration::from_millis(50));
emit(&psp::StreamItem::progress(90, Some("finalize".into()), Some("finalizing".into())))?;
// Handle method and produce result
let result = match req.method.as_str() {
"generate_metadata" => {
let title = "Canned title";
let description = "Canned description for demonstration";
let tags = vec!["demo", "tubescribe", "polyscribe"];
json!({
"title": title,
"description": description,
"tags": tags,
})
}
other => {
// Unknown method
let err = psp::StreamItem::err(req.id.clone(), -32601, format!("Method not found: {}", other), None);
emit(&err)?;
return Ok(());
}
};
emit(&psp::StreamItem::ok(req.id.clone(), result))?;
Ok(())
}
fn emit(item: &psp::StreamItem) -> Result<()> {
let mut stdout = std::io::stdout().lock();
let s = serde_json::to_string(item)?;
stdout.write_all(s.as_bytes())?;
stdout.write_all(b"\n")?;
stdout.flush()?;
Ok(())
}