diff --git a/Cargo.lock b/Cargo.lock index 1b95c9b..19483db 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -476,7 +476,7 @@ checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" [[package]] name = "c0mpute-api" -version = "0.2.27" +version = "0.2.28" dependencies = [ "anyhow", "c0mpute-proto", @@ -491,7 +491,7 @@ dependencies = [ [[package]] name = "c0mpute-bench" -version = "0.2.27" +version = "0.2.28" dependencies = [ "anyhow", "blake3", @@ -502,7 +502,7 @@ dependencies = [ [[package]] name = "c0mpute-cli" -version = "0.2.27" +version = "0.2.28" dependencies = [ "anyhow", "axum", @@ -532,7 +532,7 @@ dependencies = [ [[package]] name = "c0mpute-core" -version = "0.2.27" +version = "0.2.28" dependencies = [ "anyhow", "async-trait", @@ -566,7 +566,7 @@ dependencies = [ [[package]] name = "c0mpute-doctor" -version = "0.2.27" +version = "0.2.28" dependencies = [ "anyhow", "serde", @@ -578,7 +578,7 @@ dependencies = [ [[package]] name = "c0mpute-envelope" -version = "0.2.27" +version = "0.2.28" dependencies = [ "blake3", "bs58", @@ -591,7 +591,7 @@ dependencies = [ [[package]] name = "c0mpute-gateway" -version = "0.2.27" +version = "0.2.28" dependencies = [ "anyhow", "axum", @@ -613,7 +613,7 @@ dependencies = [ [[package]] name = "c0mpute-market" -version = "0.2.27" +version = "0.2.28" dependencies = [ "c0mpute-envelope", "serde", @@ -623,7 +623,7 @@ dependencies = [ [[package]] name = "c0mpute-net" -version = "0.2.27" +version = "0.2.28" dependencies = [ "anyhow", "async-trait", @@ -640,7 +640,7 @@ dependencies = [ [[package]] name = "c0mpute-placement" -version = "0.2.27" +version = "0.2.28" dependencies = [ "anyhow", "async-trait", @@ -661,7 +661,7 @@ dependencies = [ [[package]] name = "c0mpute-proto" -version = "0.2.27" +version = "0.2.28" dependencies = [ "blake3", "hex", @@ -673,7 +673,7 @@ dependencies = [ [[package]] name = "c0mpute-secure-chat" -version = "0.2.27" +version = "0.2.28" dependencies = [ "aes-gcm", "anyhow", @@ -696,7 +696,7 @@ dependencies = [ [[package]] name = "c0mpute-store" -version = "0.2.27" +version = "0.2.28" dependencies = [ "anyhow", "blake3", @@ -714,7 +714,7 @@ dependencies = [ [[package]] name = "c0mpute-transcode" -version = "0.2.27" +version = "0.2.28" dependencies = [ "anyhow", "c0mpute-proto", @@ -726,7 +726,7 @@ dependencies = [ [[package]] name = "c0mpute-update" -version = "0.2.27" +version = "0.2.28" dependencies = [ "anyhow", "hex", @@ -740,7 +740,7 @@ dependencies = [ [[package]] name = "c0mpute-verify" -version = "0.2.27" +version = "0.2.28" dependencies = [ "anyhow", "blake3", diff --git a/Cargo.toml b/Cargo.toml index 0c2ebad..eb33b6b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,7 +23,7 @@ members = [ ] [workspace.package] -version = "0.2.27" +version = "0.2.28" edition = "2024" license = "MIT" repository = "https://github.com/profullstack/c0mpute" diff --git a/README.md b/README.md index 7fef0c4..57f2e33 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,12 @@ c0mpute worker start --gpu # submit jobs c0mpute transcode submit input.mov --preset hls --max-price 1.25 -c0mpute infernet run prompts.jsonl --model qwen --max-price 5.00 +c0mpute infernet chat --model qwen2.5:7b "hello" + +# infernet: see what serves what, reserve a node +c0mpute pool qwen # live nodes per model +c0mpute infernet model list --node # one node's advertised models +c0mpute infernet reservation pricing # managed endpoints, by GPU class # monitor c0mpute job status diff --git a/apps/tui/package.json b/apps/tui/package.json index eca63a5..88a5ca8 100644 --- a/apps/tui/package.json +++ b/apps/tui/package.json @@ -1,6 +1,6 @@ { "name": "@c0mpute/tui", - "version": "0.2.27", + "version": "0.2.28", "private": true, "type": "module", "bin": { diff --git a/apps/web/next-env.d.ts b/apps/web/next-env.d.ts index 9edff1c..ce4e94a 100644 --- a/apps/web/next-env.d.ts +++ b/apps/web/next-env.d.ts @@ -1,6 +1,7 @@ /// /// import "./.next/types/routes.d.ts"; +import "./.next/types/root-params.d.ts"; // NOTE: This file should not be edited // see https://nextjs.org/docs/app/api-reference/config/typescript for more information. diff --git a/apps/web/package.json b/apps/web/package.json index b85af47..540ee6e 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -1,6 +1,6 @@ { "name": "c0mpute", - "version": "0.2.27", + "version": "0.2.28", "private": true, "type": "module", "scripts": { diff --git a/apps/web/src/app/docs/page.tsx b/apps/web/src/app/docs/page.tsx index db8d1ad..a781fdb 100644 --- a/apps/web/src/app/docs/page.tsx +++ b/apps/web/src/app/docs/page.tsx @@ -160,21 +160,36 @@ c0mpute transcode preset list`} spot-check duplicate execution.

-{`# Simple batch with default model -c0mpute infernet run prompts.jsonl \\ - --model qwen \\ - --max-price 5.00 +{`# Run a prompt on the network (stdin works too) +c0mpute infernet chat --model qwen2.5:7b "summarise this" +cat prompt.txt | c0mpute infernet chat --model qwen2.5:7b + +# How many live nodes serve each model +c0mpute pool +c0mpute pool qwen -# Pin a specific model + runtime image hash for reproducible runs -c0mpute infernet run prompts.jsonl \\ - --model llama-3.1-8b \\ - --max-price 0.25 +# The models one node advertises (node_id or row id) +c0mpute infernet model list --node -# List models the network advertises -c0mpute infernet models list +# Models pulled on this machine +c0mpute infernet model list`} + + -# Benchmark a model against the network's workers -c0mpute infernet benchmark --model qwen`} +
+

+ Infernet managed endpoints reserve one identified GPU operator + with an exact set of models, by the hour. You get your own API + keys, rate limits and usage reports, and pay only for hours that + pass the uptime checks. Every infernet reservation{" "} + command works through c0mpute infernet. +

+ +{`c0mpute infernet reservation pricing # price list by GPU class +c0mpute infernet reservation create --name N --operator O --models m1,m2 +c0mpute infernet reservation key-issue --label customer-a +c0mpute infernet reservation report +c0mpute infernet reservation --help`}
diff --git a/apps/web/src/app/getting-started/page.tsx b/apps/web/src/app/getting-started/page.tsx index cb8c300..55f7934 100644 --- a/apps/web/src/app/getting-started/page.tsx +++ b/apps/web/src/app/getting-started/page.tsx @@ -42,7 +42,7 @@ $ c0mpute worker start --gpu`}
{`$ c0mpute transcode submit input.mov --preset hls --max-price 1.25 -$ c0mpute infernet run prompts.jsonl --model qwen +$ c0mpute infernet chat --model qwen2.5:7b "hello" $ c0mpute job status `}
diff --git a/apps/web/src/app/page.tsx b/apps/web/src/app/page.tsx index 53f591c..b9c065f 100644 --- a/apps/web/src/app/page.tsx +++ b/apps/web/src/app/page.tsx @@ -66,7 +66,7 @@ $ c0mpute worker start --gpu`}

// submit a job

{`$ c0mpute transcode submit input.mov --preset hls -$ c0mpute infernet run prompts.jsonl --model qwen --max-price 0.10`} +$ c0mpute infernet chat --model qwen2.5:7b "hello"`}
diff --git a/apps/web/src/app/releases/latest.json/route.ts b/apps/web/src/app/releases/latest.json/route.ts index 4530942..52217cd 100644 --- a/apps/web/src/app/releases/latest.json/route.ts +++ b/apps/web/src/app/releases/latest.json/route.ts @@ -28,7 +28,7 @@ export const dynamic = "force-dynamic"; * this in sync with the workspace version in `Cargo.toml` on each release so a * freshly built CLI reports "already latest" rather than a phantom upgrade. */ -const FALLBACK_VERSION = "0.2.27"; +const FALLBACK_VERSION = "0.2.28"; const FALLBACK_MIN_REQUIRED = "0.0.1"; type Channel = "stable" | "beta" | "nightly"; diff --git a/node/crates/c0mpute-cli/src/main.rs b/node/crates/c0mpute-cli/src/main.rs index 836ffb1..6aa8473 100644 --- a/node/crates/c0mpute-cli/src/main.rs +++ b/node/crates/c0mpute-cli/src/main.rs @@ -40,7 +40,7 @@ use c0mpute_secure_chat as chat; name = "c0mpute", version, about = "c0mpute.com — decentralized compute network", - long_about = "c0mpute.com CLI. Submit jobs, run a worker, manage modules.\n\nBuilt-in plugins:\n transcode (FFmpeg, in-process)\n coinpay (DID + payments, peer CLI)\n infernet (AI inference, peer CLI)\n\n c0mpute coinpay reputation did claim\n c0mpute transcode submit input.mov --preset hls\n c0mpute infernet run prompts.jsonl --model qwen" + long_about = "c0mpute.com CLI. Submit jobs, run a worker, manage modules.\n\nBuilt-in plugins:\n transcode (FFmpeg, in-process)\n coinpay (DID + payments, peer CLI)\n infernet (AI inference, peer CLI)\n\n c0mpute coinpay reputation did claim\n c0mpute transcode submit input.mov --preset hls\n c0mpute infernet chat --model qwen2.5:7b \"hello\"\n c0mpute infernet model list --node \n c0mpute infernet reservation pricing" )] struct Cli { /// Override the config file location. @@ -183,10 +183,14 @@ enum Cmd { /// Show the live infernet distribution pool: how many nodes are serving /// each model right now (from the control plane's peer list). Pass a model - /// id to see just that model + which nodes. + /// id to see just that model + which nodes, or --node for the models one + /// node advertises. To reserve a node: `c0mpute infernet reservation pricing`. Pool { /// Model id to filter on (substring match, e.g. `9b`). Omit for all. model: Option, + /// List the models one node advertises (its node_id or row id), live or not. + #[arg(long, conflicts_with = "model")] + node: Option, }, } @@ -469,7 +473,8 @@ async fn run_app(cli: Cli) -> Result<()> { print_all_versions(); Ok(()) } - Cmd::Pool { model } => run_pool(model), + Cmd::Pool { node: Some(id), .. } => run_pool_node(&id), + Cmd::Pool { model, node: None } => run_pool(model), Cmd::Doctor => run_doctor().await, Cmd::Bench { cmd, quick, json, threads } => run_bench(cmd, quick, json, threads), Cmd::StatusAggregator { bind } => c0mpute_core::status_aggregator::run(bind).await, @@ -527,6 +532,40 @@ fn peer_label(bin: &str) -> &'static str { if which_on_path(bin).is_some() { "OK" } else { "WARN" } } +/// The installed version of a peer CLI, from the first line of ` --version`. +/// Only that line is read: `infernet --version` goes on to check npm for updates, +/// so the child is killed rather than waited on. +fn peer_version(bin: &str) -> Option { + use std::io::BufRead; + let path = which_on_path(bin)?; + let mut child = Command::new(path) + .arg("--version") + .stdout(std::process::Stdio::piped()) + .stderr(std::process::Stdio::null()) + .spawn() + .ok()?; + let mut line = String::new(); + let read = child + .stdout + .take() + .map(|out| std::io::BufReader::new(out).read_line(&mut line)); + let _ = child.kill(); + let _ = child.wait(); + read?.ok()?; + parse_version(&line) +} + +/// The first dotted version in a line: "infernet v0.1.58" and "0.15.0" both work. +fn parse_version(line: &str) -> Option { + line.split_whitespace() + .map(|w| w.trim_start_matches('v')) + .find(|w| { + let parts: Vec<&str> = w.split('.').collect(); + parts.len() >= 2 && parts.iter().all(|p| !p.is_empty() && p.chars().all(|c| c.is_ascii_digit())) + }) + .map(str::to_string) +} + fn peer_status_text(bin: &str) -> String { match which_on_path(bin) { Some(p) => format!("Ok ({})", p.display()), @@ -1259,9 +1298,11 @@ fn prompt_new_password() -> Result { fn run_plugin(cmd: PluginCmd) -> Result<()> { match cmd { PluginCmd::List => { - println!("transcode v0.1.0 in-process built-in"); - println!("coinpay v0.1.0 subprocess {}", peer_status_text("coinpay")); - println!("infernet v0.1.0 subprocess {}", peer_status_text("infernet")); + println!("transcode v{:<8} in-process built-in", env!("CARGO_PKG_VERSION")); + for bin in ["coinpay", "infernet"] { + let v = peer_version(bin).map(|v| format!("v{v}")).unwrap_or_else(|| "-".into()); + println!("{bin:<9} {v:<9} subprocess {}", peer_status_text(bin)); + } Ok(()) } PluginCmd::Install { target } => install_plugin(&target), @@ -1670,7 +1711,8 @@ fn infernet_control_plane_url() -> String { /// that actually decides how a fits-one-node model distributes. fn run_pool(model: Option) -> Result<()> { let base = infernet_control_plane_url(); - let url = format!("{base}/api/peers?limit=1000"); + // The control plane caps /api/peers at 100. + let url = format!("{base}/api/peers?limit=100"); let out = Command::new("curl") .args(["-fsSL", "--max-time", "12", &url]) .output() @@ -1687,7 +1729,15 @@ fn run_pool(model: Option) -> Result<()> { .or_else(|| json.as_array().cloned()) .unwrap_or_default(); - println!("infernet pool @ {base} — {} live nodes", peers.len()); + println!( + "infernet pool @ {base} — {} dialable nodes (public address, seen in the last 15 min)", + peers.len() + ); + // /api/peers only lists nodes another node can dial, so NAT'd nodes that + // still take jobs are missing from it. The overview has the full count. + if let Some((online, registered)) = fetch_online_nodes(&base) { + println!("{online} online of {registered} registered (incl. nodes behind NAT)"); + } let served = |p: &serde_json::Value| -> Vec { p.get("served_models") @@ -1727,9 +1777,90 @@ fn run_pool(model: Option) -> Result<()> { } } } + println!("one node's models: c0mpute pool --node reserve one: c0mpute infernet reservation pricing"); + Ok(()) +} + +/// `c0mpute pool --node ` — one node's advertised models, from the control +/// plane's public GET /api/nodes//models (the same data as +/// `infernet model list --node`, without needing infernet installed). +fn run_pool_node(id: &str) -> Result<()> { + let base = infernet_control_plane_url(); + let url = format!("{base}/api/nodes/{}/models", url_path_segment(id)); + let out = Command::new("curl") + .args(["-sSL", "--max-time", "12", "-w", "\n%{http_code}", &url]) + .output() + .map_err(|e| anyhow::anyhow!("run curl: {e}"))?; + let text = String::from_utf8_lossy(&out.stdout); + let (body, code) = text.trim_end().rsplit_once('\n').unwrap_or(("", text.trim())); + match code { + "200" => {} + "404" => anyhow::bail!("node {id} not found (or not public) at {base}"), + _ => anyhow::bail!("failed to fetch {url} (HTTP {code})"), + } + let json: serde_json::Value = serde_json::from_str(body) + .map_err(|e| anyhow::anyhow!("parse node models from {url}: {e}"))?; + let node = json.get("data").unwrap_or(&json); + let field = |k: &str| node.get(k).and_then(|v| v.as_str()).unwrap_or("-"); + let models: Vec<&str> = node + .get("served_models") + .and_then(|m| m.as_array()) + .map(|a| a.iter().filter_map(|m| m.as_str()).collect()) + .unwrap_or_default(); + println!( + "node {} ({}) status {} last_seen {}", + field("node_id"), + field("name"), + field("status"), + field("last_seen") + ); + println!("advertised models: {}", models.len()); + for m in models { + println!(" {m}"); + } Ok(()) } +/// Percent-encode everything but unreserved characters, so an id can't add +/// path segments or a query string. +fn url_path_segment(s: &str) -> String { + s.bytes() + .map(|b| match b { + b'A'..=b'Z' | b'a'..=b'z' | b'0'..=b'9' | b'-' | b'_' | b'.' | b'~' => (b as char).to_string(), + _ => format!("%{b:02X}"), + }) + .collect() +} + +/// (online, registered) from the control plane's /api/overview "Online nodes" +/// card, whose note reads "of N registered". Best-effort: None on any failure. +fn fetch_online_nodes(base: &str) -> Option<(u64, u64)> { + let out = Command::new("curl") + .args(["-fsSL", "--max-time", "8", &format!("{base}/api/overview")]) + .output() + .ok()?; + if !out.status.success() { + return None; + } + let json: serde_json::Value = serde_json::from_slice(&out.stdout).ok()?; + parse_online_card(&json) +} + +fn parse_online_card(json: &serde_json::Value) -> Option<(u64, u64)> { + let card = json + .get("cards")? + .as_array()? + .iter() + .find(|c| c.get("label").and_then(|l| l.as_str()) == Some("Online nodes"))?; + let online = card.get("value")?.as_u64()?; + let registered = card + .get("note")? + .as_str()? + .split_whitespace() + .find_map(|w| w.parse::().ok())?; + Some((online, registered)) +} + fn delegate(bin: &str, args: &[String]) -> Result<()> { let path = which_on_path(bin).ok_or_else(|| { anyhow::anyhow!( @@ -2452,3 +2583,31 @@ fn which_on_path(bin: &str) -> Option { } None } + +#[cfg(test)] +mod infernet_tests { + use super::*; + + #[test] + fn parse_version_reads_infernet_and_coinpay_lines() { + assert_eq!(parse_version("infernet v0.1.58\n").as_deref(), Some("0.1.58")); + assert_eq!(parse_version("0.15.0").as_deref(), Some("0.15.0")); + assert_eq!(parse_version("update check failed (offline?)"), None); + } + + #[test] + fn online_card_parses_value_and_registered() { + let json = serde_json::json!({ "cards": [ + { "label": "Models served", "value": 3, "note": "a, b, c" }, + { "label": "Online nodes", "value": 2, "note": "of 41 registered" } + ]}); + assert_eq!(parse_online_card(&json), Some((2, 41))); + assert_eq!(parse_online_card(&serde_json::json!({})), None); + } + + #[test] + fn node_id_is_one_path_segment() { + assert_eq!(url_path_segment("provider-0f44326c"), "provider-0f44326c"); + assert_eq!(url_path_segment("../x?y"), "..%2Fx%3Fy"); + } +} diff --git a/package.json b/package.json index 003cc09..72871de 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "c0mpute-monorepo", - "version": "0.2.27", + "version": "0.2.28", "private": true, "workspaces": [ "apps/*", diff --git a/packages/shared/package.json b/packages/shared/package.json index 56ac95d..a5b4415 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -1,6 +1,6 @@ { "name": "@c0mpute/shared", - "version": "0.2.27", + "version": "0.2.28", "private": true, "type": "module", "main": "./dist/index.js", diff --git a/plugins/ads-manager/module.toml b/plugins/ads-manager/module.toml index 9956bfe..41a25cc 100644 --- a/plugins/ads-manager/module.toml +++ b/plugins/ads-manager/module.toml @@ -18,7 +18,7 @@ [module] id = "ads-manager" name = "Ads Manager — shared ad operations layer" -version = "0.2.27" +version = "0.2.28" kind = "service" category = "applications" description = "Unified ad operations for the c0mpute network: campaign management, creative registry, publisher inventory, OpenRTB auction primitives, CoinPay escrow, and reporting. Required dependency for ctv-ads and all future ad format plugins." diff --git a/plugins/coinpay/module.toml b/plugins/coinpay/module.toml index 46da5b4..fdd8093 100644 --- a/plugins/coinpay/module.toml +++ b/plugins/coinpay/module.toml @@ -7,7 +7,7 @@ [module] id = "coinpay" name = "CoinPay — DID, payments, escrow, reputation" -version = "0.2.27" +version = "0.2.28" kind = "service" category = "applications" description = "Decentralized identifiers, wallet linking, escrow, signed receipts, and worker reputation. The trust spine of the c0mpute network." diff --git a/plugins/crawl/module.toml b/plugins/crawl/module.toml index 726a839..d8eae4e 100644 --- a/plugins/crawl/module.toml +++ b/plugins/crawl/module.toml @@ -14,7 +14,7 @@ [module] id = "crawl" name = "Crawl — distributed web fetching" -version = "0.2.27" +version = "0.2.28" kind = "workload" category = "data" description = "Decentralized web crawling and page-rendering pool. Static fetches and JS-rendered pages, robots-aware, WARC-capable." diff --git a/plugins/ctv-ads/module.toml b/plugins/ctv-ads/module.toml index 01ba7c1..2a4e391 100644 --- a/plugins/ctv-ads/module.toml +++ b/plugins/ctv-ads/module.toml @@ -20,7 +20,7 @@ [module] id = "ctv-ads" name = "CTV Ads — Connected TV ad marketplace" -version = "0.2.27" +version = "0.2.28" kind = "service" category = "applications" description = "Decentralised Connected TV advertising on the c0mpute network. VAST 4.x endpoint, OpenRTB real-time auction, cryptographically verified impressions, CoinPay settlement. Supports Roku, Fire TV, Apple TV, Smart TVs, and FAST channels. Live-stream integration for ad-monetised broadcasts." diff --git a/plugins/diffusion/module.toml b/plugins/diffusion/module.toml index 7cce708..04fd81d 100644 --- a/plugins/diffusion/module.toml +++ b/plugins/diffusion/module.toml @@ -14,7 +14,7 @@ [module] id = "diffusion" name = "Diffusion — image generation" -version = "0.2.27" +version = "0.2.28" kind = "workload" category = "ai" description = "Decentralized image generation (Stable Diffusion, SDXL, Flux) on consumer/prosumer GPUs." diff --git a/plugins/embed/module.toml b/plugins/embed/module.toml index f2274ff..3af54a8 100644 --- a/plugins/embed/module.toml +++ b/plugins/embed/module.toml @@ -13,7 +13,7 @@ [module] id = "embed" name = "Embeddings — vector generation" -version = "0.2.27" +version = "0.2.28" kind = "workload" category = "ai" description = "Bulk text-embedding generation (sentence-transformers, BGE, Nomic) with CPU fallback and optional GPU acceleration." diff --git a/plugins/gameserver/module.toml b/plugins/gameserver/module.toml index 6b7ef65..4681934 100644 --- a/plugins/gameserver/module.toml +++ b/plugins/gameserver/module.toml @@ -14,7 +14,7 @@ [module] id = "gameserver" name = "Game server — Minecraft / Factorio / Valheim" -version = "0.2.27" +version = "0.2.28" kind = "workload" category = "infrastructure" description = "Continuous-reservation hosting for game servers. Multi-replica placement, persistent world state on c0mpute storage, proof-of-serve settlement." diff --git a/plugins/hosting/module.toml b/plugins/hosting/module.toml index 504749c..9780008 100644 --- a/plugins/hosting/module.toml +++ b/plugins/hosting/module.toml @@ -12,7 +12,7 @@ [module] id = "hosting" name = "Hosting — censorship-resistant static sites" -version = "0.2.27" +version = "0.2.28" kind = "workload" category = "data" description = "Static-site hosting with multi-replica placement, mutable naming, epoch settlement, and slashable proof-of-serve. See DIP-0015." diff --git a/plugins/infernet/module.toml b/plugins/infernet/module.toml index b839765..88400ed 100644 --- a/plugins/infernet/module.toml +++ b/plugins/infernet/module.toml @@ -2,11 +2,15 @@ # # Source code lives upstream at github.com/infernetprotocol/infernet-protocol, NOT # this repo. This directory is a marketplace wrapper only. +# +# `version` is this wrapper's, kept in lockstep with c0mpute by +# scripts/bump-version.sh. The installed infernet CLI's own version is what +# `c0mpute plugin list` reports. [module] id = "infernet" name = "Infernet Protocol — AI inference" -version = "0.2.27" +version = "0.2.28" kind = "workload" category = "ai" description = "Decentralized AI inference workloads on c0mpute. Runs models on consumer/prosumer GPUs with model-hash and runtime-image verification." @@ -23,7 +27,7 @@ arch = ["x86_64", "aarch64"] capabilities = ["gpu:nvidia?", "model-runtime"] [module.workloads] -"infernet.inference" = { command = "run", validation = "schema_and_spotcheck" } +"infernet.inference" = { command = "chat", validation = "schema_and_spotcheck" } [module.dispatch] mode = "subprocess" diff --git a/plugins/live-stream/module.toml b/plugins/live-stream/module.toml index dc0240f..328cf17 100644 --- a/plugins/live-stream/module.toml +++ b/plugins/live-stream/module.toml @@ -23,7 +23,7 @@ [module] id = "live-stream" name = "Live Stream — p2p HLS live streaming" -version = "0.2.27" +version = "0.2.28" kind = "service" category = "media" description = "Decentralized live video streaming via BitTorrent-style HLS segment swarming. Broadcaster pushes RTMP/SRT; c0mpute nodes swarm segments to viewers. No central CDN. Censorship-resistant. Per-GB micropayments via CoinPay." diff --git a/plugins/ocr/module.toml b/plugins/ocr/module.toml index a49eeb4..8431b87 100644 --- a/plugins/ocr/module.toml +++ b/plugins/ocr/module.toml @@ -12,7 +12,7 @@ [module] id = "ocr" name = "OCR — document text extraction" -version = "0.2.27" +version = "0.2.28" kind = "workload" category = "ai" description = "Decentralized OCR for PDFs and scanned documents (Tesseract, PaddleOCR, docTR) with CPU or GPU runners." diff --git a/plugins/podcast-ads/module.toml b/plugins/podcast-ads/module.toml index c5bf9f4..018a751 100644 --- a/plugins/podcast-ads/module.toml +++ b/plugins/podcast-ads/module.toml @@ -22,7 +22,7 @@ [module] id = "podcast-ads" name = "Podcast Ads — audio ad marketplace" -version = "0.2.27" +version = "0.2.28" kind = "service" category = "applications" description = "Decentralised audio advertising for c0mpute-hosted podcasts. DAAST 1.0 endpoint, dynamic ad insertion, Podcasting 2.0 revenue splits, and CoinPay settlement. Publishers sell ad slots; advertisers run campaigns — zero platform cut beyond protocol split." diff --git a/plugins/podcasting/module.toml b/plugins/podcasting/module.toml index 198e02b..99115ef 100644 --- a/plugins/podcasting/module.toml +++ b/plugins/podcasting/module.toml @@ -20,7 +20,7 @@ [module] id = "podcasting" name = "Podcasting — p2p podcast publishing" -version = "0.2.27" +version = "0.2.28" kind = "service" category = "media" description = "Censorship-resistant podcast hosting on the c0mpute network. Upload episodes, stream live shows, auto-transcribe, and monetise via CoinPay subscriptions, pay-per-episode, value-for-value, and audio ads — with zero platform cut. RSS 2.0 + Podcasting 2.0 compatible with all major podcast apps." diff --git a/plugins/podcasts/module.toml b/plugins/podcasts/module.toml index 286785b..b27b3c0 100644 --- a/plugins/podcasts/module.toml +++ b/plugins/podcasts/module.toml @@ -19,7 +19,7 @@ [module] id = "podcasts" name = "Podcasts — p2p podcast listener" -version = "0.2.27" +version = "0.2.28" kind = "service" category = "media" description = "Discover, subscribe to, and play podcasts hosted on the c0mpute network or any standard RSS feed. Stream live episodes, tip creators directly via CoinPay, and participate in value-for-value streaming payments. Works alongside any existing podcast app via OPML export and local RSS proxy." diff --git a/plugins/render/module.toml b/plugins/render/module.toml index 7565d56..f6b7a9d 100644 --- a/plugins/render/module.toml +++ b/plugins/render/module.toml @@ -13,7 +13,7 @@ [module] id = "render" name = "Render — Blender 3D rendering" -version = "0.2.27" +version = "0.2.28" kind = "workload" category = "media" description = "Decentralized 3D rendering using Blender headless (Cycles/Eevee) across consumer GPUs and CPUs." diff --git a/plugins/secure-chat/module.toml b/plugins/secure-chat/module.toml index a209e6c..9c02513 100644 --- a/plugins/secure-chat/module.toml +++ b/plugins/secure-chat/module.toml @@ -18,7 +18,7 @@ [module] id = "secure-chat" name = "Secure Chat — E2E encrypted p2p messaging" -version = "0.2.27" +version = "0.2.28" kind = "service" category = "applications" description = "End-to-end encrypted peer-to-peer messaging across the c0mpute network. No central server. Keys stay with the user. Identity and reputation via CoinPay DID. Group chats, sealed-sender mode, and offline store-and-forward included." diff --git a/plugins/storage/module.toml b/plugins/storage/module.toml index 33c62fe..c4d50d3 100644 --- a/plugins/storage/module.toml +++ b/plugins/storage/module.toml @@ -12,7 +12,7 @@ [module] id = "storage" name = "Storage — Reed-Solomon shard service" -version = "0.2.27" +version = "0.2.28" kind = "service" category = "data" description = "Reed-Solomon 10/14 shard storage with auto-repair. Compute-locality, E2E encryption, content-addressed, pay-as-you-go. See DIP-0012." diff --git a/plugins/train/module.toml b/plugins/train/module.toml index 8bc81ef..052546d 100644 --- a/plugins/train/module.toml +++ b/plugins/train/module.toml @@ -13,7 +13,7 @@ [module] id = "train" name = "Fine-tune — LoRA/QLoRA training" -version = "0.2.27" +version = "0.2.28" kind = "workload" category = "ai" description = "Decentralized model fine-tuning (LoRA, QLoRA) on consumer/prosumer GPUs using axolotl or unsloth." diff --git a/plugins/transcode/module.toml b/plugins/transcode/module.toml index df09f3d..4ee86da 100644 --- a/plugins/transcode/module.toml +++ b/plugins/transcode/module.toml @@ -7,7 +7,7 @@ [module] id = "transcode" name = "FFmpeg Transcoding" -version = "0.2.27" +version = "0.2.28" kind = "workload" category = "media" description = "Decentralized audio/video transcoding via FFmpeg with hardware acceleration (NVENC, QSV, AMF, VideoToolbox, AV1)." diff --git a/plugins/tts/module.toml b/plugins/tts/module.toml index 898031f..0c8ede5 100644 --- a/plugins/tts/module.toml +++ b/plugins/tts/module.toml @@ -12,7 +12,7 @@ [module] id = "tts" name = "TTS — text-to-speech" -version = "0.2.27" +version = "0.2.28" kind = "workload" category = "ai" description = "Decentralized text-to-speech synthesis (Piper, Coqui XTTS, Kokoro) for narration, audiobooks, and accessibility." diff --git a/plugins/whisper/module.toml b/plugins/whisper/module.toml index a9b952e..8c065a2 100644 --- a/plugins/whisper/module.toml +++ b/plugins/whisper/module.toml @@ -11,7 +11,7 @@ [module] id = "whisper" name = "Whisper — speech-to-text" -version = "0.2.27" +version = "0.2.28" kind = "workload" category = "ai" description = "Decentralized speech-to-text transcription via whisper.cpp with optional GPU acceleration (CUDA, Metal, Vulkan)."