diff --git a/acp/Cargo.lock b/acp/Cargo.lock index e245c89b..1e7bdf44 100644 --- a/acp/Cargo.lock +++ b/acp/Cargo.lock @@ -747,21 +747,19 @@ dependencies = [ ] [[package]] -name = "iii-sdk" -version = "0.13.0-next.1" +name = "iii-observability" +version = "0.16.0-next.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17cf728e12b30b11c37295304e0a5807cf677cca430b66609b7ae3c6044c358d" +checksum = "00ee84dacaf7e14750ebdc229523e52029441c4ae1f72d25972bf1f2e1edeb99" dependencies = [ "async-trait", "futures-util", - "hostname", "opentelemetry", "opentelemetry-http", "opentelemetry-proto", "opentelemetry_sdk", "prost", "reqwest", - "schemars", "serde", "serde_json", "sysinfo", @@ -772,6 +770,27 @@ dependencies = [ "uuid", ] +[[package]] +name = "iii-sdk" +version = "0.16.0-next.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53c18b68b2aa09e18c68fb023c78316fe7ccf42181874eab584d66f40119b47e" +dependencies = [ + "async-trait", + "futures-util", + "hostname", + "iii-observability", + "reqwest", + "schemars", + "serde", + "serde_json", + "thiserror", + "tokio", + "tokio-tungstenite", + "tracing", + "uuid", +] + [[package]] name = "indexmap" version = "2.14.0" diff --git a/acp/Cargo.toml b/acp/Cargo.toml index 651e2418..a426c9b8 100644 --- a/acp/Cargo.toml +++ b/acp/Cargo.toml @@ -23,7 +23,7 @@ name = "iii-acp" path = "src/main.rs" [dependencies] -iii-sdk = "=0.13.0-next.1" +iii-sdk = "=0.16.0-next.2" tokio = { version = "1", features = ["macros", "rt-multi-thread", "io-std", "io-util", "sync", "time", "signal"] } serde = { version = "1", features = ["derive"] } serde_json = "1" diff --git a/acp/src/handler.rs b/acp/src/handler.rs index d34db11c..f930c8fc 100644 --- a/acp/src/handler.rs +++ b/acp/src/handler.rs @@ -2,7 +2,7 @@ use std::sync::Arc; use std::sync::atomic::{AtomicBool, AtomicU64, Ordering}; use dashmap::{DashMap, DashSet}; -use iii_sdk::{FunctionRef, III, RegisterFunctionMessage, RegisterTriggerInput}; +use iii_sdk::{FunctionRef, III, RegisterFunction, RegisterTriggerInput}; use serde_json::{Value, json}; use uuid::Uuid; @@ -681,10 +681,9 @@ fn register_event_subscriber( let iii_inner = iii.clone(); let owned_inner = owned_sessions.clone(); let locks_inner = history_locks.clone(); - let function = iii.register_function(( - RegisterFunctionMessage::with_id(fn_id.clone()) - .with_description("ACP agent::events → stdout fan-in".into()), - move |payload: Value| { + let function = iii.register_function( + fn_id.clone(), + RegisterFunction::new_async(move |payload: Value| { let outbound = outbound_inner.clone(); let seq = seq_inner.clone(); let iii = iii_inner.clone(); @@ -694,8 +693,9 @@ fn register_event_subscriber( forward_agent_event(&iii, &outbound, &seq, &owned, &locks, payload).await; Ok(json!({ "ok": true })) } - }, - )); + }) + .description("ACP agent::events → stdout fan-in"), + ); let trigger = match iii.register_trigger(RegisterTriggerInput { trigger_type: "stream".into(), diff --git a/coder/Cargo.lock b/coder/Cargo.lock index ff379b06..a2a52453 100644 --- a/coder/Cargo.lock +++ b/coder/Cargo.lock @@ -204,7 +204,7 @@ checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" [[package]] name = "coder" -version = "0.1.0" +version = "0.1.1" dependencies = [ "anyhow", "clap", @@ -973,21 +973,19 @@ dependencies = [ ] [[package]] -name = "iii-sdk" -version = "0.13.0-next.1" +name = "iii-observability" +version = "0.16.0-next.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17cf728e12b30b11c37295304e0a5807cf677cca430b66609b7ae3c6044c358d" +checksum = "00ee84dacaf7e14750ebdc229523e52029441c4ae1f72d25972bf1f2e1edeb99" dependencies = [ "async-trait", "futures-util", - "hostname", "opentelemetry", "opentelemetry-http", "opentelemetry-proto", "opentelemetry_sdk", "prost", "reqwest", - "schemars", "serde", "serde_json", "sysinfo", @@ -998,6 +996,27 @@ dependencies = [ "uuid", ] +[[package]] +name = "iii-sdk" +version = "0.16.0-next.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53c18b68b2aa09e18c68fb023c78316fe7ccf42181874eab584d66f40119b47e" +dependencies = [ + "async-trait", + "futures-util", + "hostname", + "iii-observability", + "reqwest", + "schemars", + "serde", + "serde_json", + "thiserror", + "tokio", + "tokio-tungstenite", + "tracing", + "uuid", +] + [[package]] name = "indexmap" version = "2.14.0" diff --git a/coder/Cargo.toml b/coder/Cargo.toml index b6832478..fcf2feed 100644 --- a/coder/Cargo.toml +++ b/coder/Cargo.toml @@ -14,7 +14,7 @@ path = "src/main.rs" path = "src/lib.rs" [dependencies] -iii-sdk = "=0.13.0-next.1" +iii-sdk = "=0.16.0-next.2" tokio = { version = "1", features = ["rt-multi-thread", "macros", "sync", "signal", "time", "fs", "io-util"] } serde = { version = "1", features = ["derive"] } serde_json = "1" diff --git a/coder/src/functions/mod.rs b/coder/src/functions/mod.rs index 9e936c87..6ad73d46 100644 --- a/coder/src/functions/mod.rs +++ b/coder/src/functions/mod.rs @@ -14,7 +14,7 @@ pub mod update_file; use std::sync::Arc; -use iii_sdk::{RegisterFunction, III}; +use iii_sdk::{IIIError, RegisterFunction, III}; use crate::config::CoderConfig; use crate::path::PathResolver; @@ -32,10 +32,15 @@ pub fn register_all(iii: &III, resolver: Arc, cfg: Arc, cfg: Arc) { iii.register_function( - RegisterFunction::new_async("coder::read-file", move |req: read_file::ReadFileInput| { + "coder::read-file", + RegisterFunction::new_async(move |req: read_file::ReadFileInput| { let resolver = resolver.clone(); let cfg = cfg.clone(); - async move { read_file::handle(resolver, cfg, req).await } + async move { + read_file::handle(resolver, cfg, req) + .await + .map_err(IIIError::from) + } }) .description( "Read a file relative to base_path. Returns content plus \ @@ -47,10 +52,15 @@ fn register_read_file(iii: &III, resolver: Arc, cfg: Arc, cfg: Arc) { iii.register_function( - RegisterFunction::new_async("coder::search", move |req: search::SearchInput| { + "coder::search", + RegisterFunction::new_async(move |req: search::SearchInput| { let resolver = resolver.clone(); let cfg = cfg.clone(); - async move { search::handle(resolver, cfg, req).await } + async move { + search::handle(resolver, cfg, req) + .await + .map_err(IIIError::from) + } }) .description( "Search file contents and/or paths under base_path. Supports \ @@ -63,14 +73,16 @@ fn register_search(iii: &III, resolver: Arc, cfg: Arc fn register_update_file(iii: &III, resolver: Arc, cfg: Arc) { iii.register_function( - RegisterFunction::new_async( - "coder::update-file", - move |req: update_file::UpdateFileInput| { - let resolver = resolver.clone(); - let cfg = cfg.clone(); - async move { update_file::handle(resolver, cfg, req).await } - }, - ) + "coder::update-file", + RegisterFunction::new_async(move |req: update_file::UpdateFileInput| { + let resolver = resolver.clone(); + let cfg = cfg.clone(); + async move { + update_file::handle(resolver, cfg, req) + .await + .map_err(IIIError::from) + } + }) .description( "Apply batched line-oriented and regex edits across one or more \ files. Line ops: { op: 'insert', at_line, content } | \ @@ -85,14 +97,16 @@ fn register_update_file(iii: &III, resolver: Arc, cfg: Arc, cfg: Arc) { iii.register_function( - RegisterFunction::new_async( - "coder::create-file", - move |req: create_file::CreateFileInput| { - let resolver = resolver.clone(); - let cfg = cfg.clone(); - async move { create_file::handle(resolver, cfg, req).await } - }, - ) + "coder::create-file", + RegisterFunction::new_async(move |req: create_file::CreateFileInput| { + let resolver = resolver.clone(); + let cfg = cfg.clone(); + async move { + create_file::handle(resolver, cfg, req) + .await + .map_err(IIIError::from) + } + }) .description( "Create one or more files. Per-file `overwrite` and `parents` \ flags; non-accessible paths return C211.", @@ -102,13 +116,15 @@ fn register_create_file(iii: &III, resolver: Arc, cfg: Arc) { iii.register_function( - RegisterFunction::new_async( - "coder::delete-file", - move |req: delete_file::DeleteFileInput| { - let resolver = resolver.clone(); - async move { delete_file::handle(resolver, req).await } - }, - ) + "coder::delete-file", + RegisterFunction::new_async(move |req: delete_file::DeleteFileInput| { + let resolver = resolver.clone(); + async move { + delete_file::handle(resolver, req) + .await + .map_err(IIIError::from) + } + }) .description( "Remove one or more paths. Directories need `recursive: true`; \ missing paths are idempotent successes; recursive removal \ @@ -119,14 +135,16 @@ fn register_delete_file(iii: &III, resolver: Arc) { fn register_list_folder(iii: &III, resolver: Arc, cfg: Arc) { iii.register_function( - RegisterFunction::new_async( - "coder::list-folder", - move |req: list_folder::ListFolderInput| { - let resolver = resolver.clone(); - let cfg = cfg.clone(); - async move { list_folder::handle(resolver, cfg, req).await } - }, - ) + "coder::list-folder", + RegisterFunction::new_async(move |req: list_folder::ListFolderInput| { + let resolver = resolver.clone(); + let cfg = cfg.clone(); + async move { + list_folder::handle(resolver, cfg, req) + .await + .map_err(IIIError::from) + } + }) .description( "Paginated single-folder listing, sorted by name. \ Non-accessible entries are still listed with a \ @@ -137,10 +155,15 @@ fn register_list_folder(iii: &III, resolver: Arc, cfg: Arc, cfg: Arc) { iii.register_function( - RegisterFunction::new_async("coder::tree", move |req: tree::TreeInput| { + "coder::tree", + RegisterFunction::new_async(move |req: tree::TreeInput| { let resolver = resolver.clone(); let cfg = cfg.clone(); - async move { tree::handle(resolver, cfg, req).await } + async move { + tree::handle(resolver, cfg, req) + .await + .map_err(IIIError::from) + } }) .description( "Recursive directory snapshot bounded by `max_depth` and a \ diff --git a/coder/src/main.rs b/coder/src/main.rs index 0d8e8282..c196851c 100644 --- a/coder/src/main.rs +++ b/coder/src/main.rs @@ -2,7 +2,7 @@ use std::sync::Arc; use anyhow::Result; use clap::Parser; -use iii_sdk::{register_worker, InitOptions, OtelConfig, WorkerMetadata}; +use iii_sdk::{register_worker, InitOptions, WorkerMetadata}; use coder::config; use coder::functions; @@ -83,7 +83,6 @@ async fn main() -> Result<()> { let iii = register_worker( &cli.url, InitOptions { - otel: Some(OtelConfig::default()), metadata: Some(WorkerMetadata { runtime: "rust".to_string(), version: env!("CARGO_PKG_VERSION").to_string(), diff --git a/console/Cargo.lock b/console/Cargo.lock index e110ab9a..6afb7d07 100644 --- a/console/Cargo.lock +++ b/console/Cargo.lock @@ -257,7 +257,7 @@ checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" [[package]] name = "console" -version = "0.1.2" +version = "0.1.4" dependencies = [ "anyhow", "async-trait", @@ -826,21 +826,19 @@ dependencies = [ ] [[package]] -name = "iii-sdk" -version = "0.13.0-next.1" +name = "iii-observability" +version = "0.16.0-next.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17cf728e12b30b11c37295304e0a5807cf677cca430b66609b7ae3c6044c358d" +checksum = "00ee84dacaf7e14750ebdc229523e52029441c4ae1f72d25972bf1f2e1edeb99" dependencies = [ "async-trait", "futures-util", - "hostname", "opentelemetry", "opentelemetry-http", "opentelemetry-proto", "opentelemetry_sdk", "prost", "reqwest", - "schemars", "serde", "serde_json", "sysinfo", @@ -851,6 +849,27 @@ dependencies = [ "uuid", ] +[[package]] +name = "iii-sdk" +version = "0.16.0-next.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53c18b68b2aa09e18c68fb023c78316fe7ccf42181874eab584d66f40119b47e" +dependencies = [ + "async-trait", + "futures-util", + "hostname", + "iii-observability", + "reqwest", + "schemars", + "serde", + "serde_json", + "thiserror 2.0.18", + "tokio", + "tokio-tungstenite 0.28.0", + "tracing", + "uuid", +] + [[package]] name = "indexmap" version = "2.14.0" diff --git a/console/Cargo.toml b/console/Cargo.toml index 896407de..e105fdf2 100644 --- a/console/Cargo.toml +++ b/console/Cargo.toml @@ -14,7 +14,7 @@ path = "src/main.rs" path = "src/lib.rs" [dependencies] -iii-sdk = "=0.13.0-next.1" +iii-sdk = "=0.16.0-next.2" tokio = { version = "1", features = ["rt-multi-thread", "macros", "sync", "signal", "net", "io-util", "time"] } serde = { version = "1", features = ["derive"] } serde_json = "1" diff --git a/console/src/functions/mod.rs b/console/src/functions/mod.rs index 4523123a..f56c8b05 100644 --- a/console/src/functions/mod.rs +++ b/console/src/functions/mod.rs @@ -25,7 +25,8 @@ fn register_status(iii: &Arc, config: &Arc, engine_url: &str let cfg = config.clone(); let engine_url = engine_url.to_string(); iii.register_function( - RegisterFunction::new_async("console::status", move |_: StatusInput| { + "console::status", + RegisterFunction::new_async(move |_: StatusInput| { let cfg = cfg.clone(); let engine_url = engine_url.clone(); async move { diff --git a/console/src/main.rs b/console/src/main.rs index 19e8a7d8..bb9a14f3 100644 --- a/console/src/main.rs +++ b/console/src/main.rs @@ -13,7 +13,7 @@ use std::sync::Arc; use anyhow::Result; use clap::Parser; -use iii_sdk::{register_worker, InitOptions, OtelConfig, WorkerMetadata}; +use iii_sdk::{register_worker, InitOptions, WorkerMetadata}; use tokio::sync::oneshot; use console::{config, functions, manifest, server}; @@ -88,7 +88,6 @@ async fn main() -> Result<()> { let iii = register_worker( &engine_url, InitOptions { - otel: Some(OtelConfig::default()), metadata: Some(WorkerMetadata { runtime: "rust".to_string(), version: env!("CARGO_PKG_VERSION").to_string(), diff --git a/database/Cargo.lock b/database/Cargo.lock index 1a1b1557..f72d54d9 100644 --- a/database/Cargo.lock +++ b/database/Cargo.lock @@ -606,6 +606,7 @@ dependencies = [ "clap", "deadpool-postgres", "futures-util", + "iii-observability", "iii-sdk", "mysql_async", "postgres-protocol", @@ -1309,21 +1310,19 @@ dependencies = [ ] [[package]] -name = "iii-sdk" -version = "0.13.0-next.1" +name = "iii-observability" +version = "0.16.0-next.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17cf728e12b30b11c37295304e0a5807cf677cca430b66609b7ae3c6044c358d" +checksum = "00ee84dacaf7e14750ebdc229523e52029441c4ae1f72d25972bf1f2e1edeb99" dependencies = [ "async-trait", "futures-util", - "hostname", "opentelemetry", "opentelemetry-http", "opentelemetry-proto", "opentelemetry_sdk", "prost", "reqwest", - "schemars", "serde", "serde_json", "sysinfo", @@ -1334,6 +1333,27 @@ dependencies = [ "uuid", ] +[[package]] +name = "iii-sdk" +version = "0.16.0-next.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53c18b68b2aa09e18c68fb023c78316fe7ccf42181874eab584d66f40119b47e" +dependencies = [ + "async-trait", + "futures-util", + "hostname", + "iii-observability", + "reqwest", + "schemars", + "serde", + "serde_json", + "thiserror 2.0.18", + "tokio", + "tokio-tungstenite", + "tracing", + "uuid", +] + [[package]] name = "indexmap" version = "2.14.0" diff --git a/database/Cargo.toml b/database/Cargo.toml index c6527fb0..e745ee94 100644 --- a/database/Cargo.toml +++ b/database/Cargo.toml @@ -14,7 +14,8 @@ path = "src/main.rs" path = "src/lib.rs" [dependencies] -iii-sdk = "=0.13.0-next.1" +iii-sdk = "=0.16.0-next.2" +iii-observability = "=0.16.0-next.2" tokio = { version = "1", features = ["rt-multi-thread", "macros", "sync", "signal", "time"] } serde = { version = "1", features = ["derive"] } serde_json = "1" diff --git a/database/src/handlers/begin_transaction.rs b/database/src/handlers/begin_transaction.rs index 59d8cf2a..43fb455c 100644 --- a/database/src/handlers/begin_transaction.rs +++ b/database/src/handlers/begin_transaction.rs @@ -122,7 +122,7 @@ pub(crate) mod tests { use crate::handlers::AppState; use crate::pool::{Pool, SqlitePool}; use crate::transaction::TxRegistry; - use iii_sdk::Logger; + use iii_observability::Logger; use serde_json::{json, Value}; use std::collections::HashMap; use std::sync::Arc; diff --git a/database/src/handlers/commit_transaction.rs b/database/src/handlers/commit_transaction.rs index 92d0b11e..89fe8a1a 100644 --- a/database/src/handlers/commit_transaction.rs +++ b/database/src/handlers/commit_transaction.rs @@ -159,7 +159,7 @@ mod tests { pools: std::sync::Arc::new(pools), handles: std::sync::Arc::new(crate::handle::HandleRegistry::new()), transactions: crate::transaction::TxRegistry::new(), - log: iii_sdk::Logger::new(), + log: iii_observability::Logger::new(), }; crate::handlers::execute::handle( diff --git a/database/src/handlers/execute.rs b/database/src/handlers/execute.rs index 61ed210b..0da8f6ee 100644 --- a/database/src/handlers/execute.rs +++ b/database/src/handlers/execute.rs @@ -77,7 +77,7 @@ mod tests { pools: Arc::new(pools), handles: Arc::new(HandleRegistry::new()), transactions: crate::transaction::TxRegistry::new(), - log: iii_sdk::Logger::new(), + log: iii_observability::Logger::new(), } } diff --git a/database/src/handlers/mod.rs b/database/src/handlers/mod.rs index 53d9a5d6..0686b368 100644 --- a/database/src/handlers/mod.rs +++ b/database/src/handlers/mod.rs @@ -6,7 +6,7 @@ use crate::error::DbError; use crate::handle::HandleRegistry; use crate::pool::Pool; use crate::transaction::TxRegistry; -use iii_sdk::Logger; +use iii_observability::Logger; use std::collections::HashMap; use std::sync::Arc; diff --git a/database/src/handlers/prepare.rs b/database/src/handlers/prepare.rs index 414d8111..9c5f5fd2 100644 --- a/database/src/handlers/prepare.rs +++ b/database/src/handlers/prepare.rs @@ -86,7 +86,7 @@ mod tests { pools: Arc::new(pools), handles: Arc::new(HandleRegistry::new()), transactions: crate::transaction::TxRegistry::new(), - log: iii_sdk::Logger::new(), + log: iii_observability::Logger::new(), } } diff --git a/database/src/handlers/query.rs b/database/src/handlers/query.rs index 7d18c28e..b2ca8b0f 100644 --- a/database/src/handlers/query.rs +++ b/database/src/handlers/query.rs @@ -113,7 +113,7 @@ mod tests { pools: Arc::new(pools), handles: Arc::new(HandleRegistry::new()), transactions: crate::transaction::TxRegistry::new(), - log: iii_sdk::Logger::new(), + log: iii_observability::Logger::new(), } } diff --git a/database/src/handlers/rollback_transaction.rs b/database/src/handlers/rollback_transaction.rs index 3375a19b..bb40dbb6 100644 --- a/database/src/handlers/rollback_transaction.rs +++ b/database/src/handlers/rollback_transaction.rs @@ -132,7 +132,7 @@ mod tests { pools: std::sync::Arc::new(pools), handles: std::sync::Arc::new(crate::handle::HandleRegistry::new()), transactions: crate::transaction::TxRegistry::new(), - log: iii_sdk::Logger::new(), + log: iii_observability::Logger::new(), }; crate::handlers::execute::handle( diff --git a/database/src/handlers/run_statement.rs b/database/src/handlers/run_statement.rs index 799fdc24..30a62db8 100644 --- a/database/src/handlers/run_statement.rs +++ b/database/src/handlers/run_statement.rs @@ -60,7 +60,7 @@ mod tests { pools: Arc::new(pools), handles: Arc::new(HandleRegistry::new()), transactions: crate::transaction::TxRegistry::new(), - log: iii_sdk::Logger::new(), + log: iii_observability::Logger::new(), } } @@ -76,7 +76,7 @@ mod tests { pools: Arc::new(pools), handles: Arc::new(HandleRegistry::new()), transactions: crate::transaction::TxRegistry::new(), - log: iii_sdk::Logger::new(), + log: iii_observability::Logger::new(), }; (st, tmp) } diff --git a/database/src/handlers/transaction.rs b/database/src/handlers/transaction.rs index e4e87b0b..df868f4e 100644 --- a/database/src/handlers/transaction.rs +++ b/database/src/handlers/transaction.rs @@ -136,7 +136,7 @@ mod tests { pools: Arc::new(pools), handles: Arc::new(HandleRegistry::new()), transactions: crate::transaction::TxRegistry::new(), - log: iii_sdk::Logger::new(), + log: iii_observability::Logger::new(), } } diff --git a/database/src/handlers/transaction_execute.rs b/database/src/handlers/transaction_execute.rs index d57d4d58..61c9529b 100644 --- a/database/src/handlers/transaction_execute.rs +++ b/database/src/handlers/transaction_execute.rs @@ -282,7 +282,7 @@ mod tests { pools: std::sync::Arc::new(pools), handles: std::sync::Arc::new(crate::handle::HandleRegistry::new()), transactions: crate::transaction::TxRegistry::new(), - log: iii_sdk::Logger::new(), + log: iii_observability::Logger::new(), }; crate::handlers::execute::handle( diff --git a/database/src/main.rs b/database/src/main.rs index ff1fae42..bfe2d44a 100644 --- a/database/src/main.rs +++ b/database/src/main.rs @@ -18,9 +18,8 @@ use database::handlers::{ use database::pool; use database::transaction::TxRegistry; use database::triggers::handler::RowChangeTrigger; -use iii_sdk::{ - register_worker, InitOptions, Logger, OtelConfig, RegisterFunction, RegisterTriggerType, -}; +use iii_observability::Logger; +use iii_sdk::{register_worker, InitOptions, RegisterFunction, RegisterTriggerType}; use std::collections::HashMap; use std::sync::Arc; @@ -83,20 +82,19 @@ async fn main() -> Result<()> { let _evictor = handles.spawn_evictor(); let _tx_watcher = transactions.spawn_timeout_watcher(log.clone()); - let iii = register_worker( - &cli.url, - InitOptions { - otel: Some(OtelConfig::default()), - ..Default::default() - }, - ); + let iii = register_worker(&cli.url, InitOptions::default()); { let st = state.clone(); iii.register_function( - RegisterFunction::new_async("database::query", move |req: QueryReq| { + "database::query", + RegisterFunction::new_async(move |req: QueryReq| { let st = st.clone(); - async move { query::handle(&st, req).await } + async move { + query::handle(&st, req) + .await + .map_err(iii_sdk::IIIError::from) + } }) .description("Run a read-only SQL query and return the result rows."), ); @@ -104,9 +102,14 @@ async fn main() -> Result<()> { { let st = state.clone(); iii.register_function( - RegisterFunction::new_async("database::execute", move |req: ExecuteReq| { + "database::execute", + RegisterFunction::new_async(move |req: ExecuteReq| { let st = st.clone(); - async move { execute::handle(&st, req).await } + async move { + execute::handle(&st, req) + .await + .map_err(iii_sdk::IIIError::from) + } }) .description("Run a write statement (INSERT/UPDATE/DELETE/DDL)."), ); @@ -114,9 +117,14 @@ async fn main() -> Result<()> { { let st = state.clone(); iii.register_function( - RegisterFunction::new_async("database::prepareStatement", move |req: PrepareReq| { + "database::prepareStatement", + RegisterFunction::new_async(move |req: PrepareReq| { let st = st.clone(); - async move { prepare::handle(&st, req).await } + async move { + prepare::handle(&st, req) + .await + .map_err(iii_sdk::IIIError::from) + } }) .description("Prepare a parameterized statement once."), ); @@ -124,9 +132,14 @@ async fn main() -> Result<()> { { let st = state.clone(); iii.register_function( - RegisterFunction::new_async("database::runStatement", move |req: RunReq| { + "database::runStatement", + RegisterFunction::new_async(move |req: RunReq| { let st = st.clone(); - async move { run_statement::handle(&st, req).await } + async move { + run_statement::handle(&st, req) + .await + .map_err(iii_sdk::IIIError::from) + } }) .description("Run a previously-prepared handle."), ); @@ -134,9 +147,14 @@ async fn main() -> Result<()> { { let st = state.clone(); iii.register_function( - RegisterFunction::new_async("database::transaction", move |req: TxReq| { + "database::transaction", + RegisterFunction::new_async(move |req: TxReq| { let st = st.clone(); - async move { transaction::handle(&st, req).await } + async move { + transaction::handle(&st, req) + .await + .map_err(iii_sdk::IIIError::from) + } }) .description("Run a sequence of statements atomically."), ); @@ -144,9 +162,14 @@ async fn main() -> Result<()> { { let st = state.clone(); iii.register_function( - RegisterFunction::new_async("database::beginTransaction", move |req: BeginTxReq| { + "database::beginTransaction", + RegisterFunction::new_async(move |req: BeginTxReq| { let st = st.clone(); - async move { begin_transaction::handle(&st, req).await } + async move { + begin_transaction::handle(&st, req) + .await + .map_err(iii_sdk::IIIError::from) + } }) .description( "Open an interactive transaction; returns a handle to use with \ @@ -157,9 +180,14 @@ async fn main() -> Result<()> { { let st = state.clone(); iii.register_function( - RegisterFunction::new_async("database::transactionQuery", move |req: TxQueryReq| { + "database::transactionQuery", + RegisterFunction::new_async(move |req: TxQueryReq| { let st = st.clone(); - async move { transaction_query::handle(&st, req).await } + async move { + transaction_query::handle(&st, req) + .await + .map_err(iii_sdk::IIIError::from) + } }) .description("Run a read-only SQL query inside an interactive transaction."), ); @@ -167,13 +195,15 @@ async fn main() -> Result<()> { { let st = state.clone(); iii.register_function( - RegisterFunction::new_async( - "database::transactionExecute", - move |req: TxExecuteReq| { - let st = st.clone(); - async move { transaction_execute::handle(&st, req).await } - }, - ) + "database::transactionExecute", + RegisterFunction::new_async(move |req: TxExecuteReq| { + let st = st.clone(); + async move { + transaction_execute::handle(&st, req) + .await + .map_err(iii_sdk::IIIError::from) + } + }) .description( "Run a write statement inside an interactive transaction. \ BEGIN/COMMIT/ROLLBACK are rejected; use commit/rollbackTransaction.", @@ -183,9 +213,14 @@ async fn main() -> Result<()> { { let st = state.clone(); iii.register_function( - RegisterFunction::new_async("database::commitTransaction", move |req: CommitTxReq| { + "database::commitTransaction", + RegisterFunction::new_async(move |req: CommitTxReq| { let st = st.clone(); - async move { commit_transaction::handle(&st, req).await } + async move { + commit_transaction::handle(&st, req) + .await + .map_err(iii_sdk::IIIError::from) + } }) .description("Commit and finalize an interactive transaction."), ); @@ -193,13 +228,15 @@ async fn main() -> Result<()> { { let st = state.clone(); iii.register_function( - RegisterFunction::new_async( - "database::rollbackTransaction", - move |req: RollbackTxReq| { - let st = st.clone(); - async move { rollback_transaction::handle(&st, req).await } - }, - ) + "database::rollbackTransaction", + RegisterFunction::new_async(move |req: RollbackTxReq| { + let st = st.clone(); + async move { + rollback_transaction::handle(&st, req) + .await + .map_err(iii_sdk::IIIError::from) + } + }) .description("Rollback and finalize an interactive transaction."), ); } diff --git a/database/src/transaction.rs b/database/src/transaction.rs index 5486f8d5..2263c327 100644 --- a/database/src/transaction.rs +++ b/database/src/transaction.rs @@ -19,7 +19,7 @@ use crate::driver; use crate::error::DbError; use crate::handle::PinnedConn; use chrono::{DateTime, Duration as CDuration, Utc}; -use iii_sdk::Logger; +use iii_observability::Logger; use schemars::JsonSchema; use serde::Serialize; use serde_json::json; diff --git a/database/tests/integration.rs b/database/tests/integration.rs index d8aa02c7..5a0b1eda 100644 --- a/database/tests/integration.rs +++ b/database/tests/integration.rs @@ -11,7 +11,7 @@ use database::handlers::transaction::TxReq; use database::handlers::{execute, prepare, query, run_statement, transaction, AppState}; use database::pool; use database::transaction::TxRegistry; -use iii_sdk::{Logger, RegisterFunction}; +use iii_observability::Logger; use serde_json::json; use std::collections::HashMap; use std::sync::Arc; @@ -130,85 +130,3 @@ async fn end_to_end_query_execute_prepare_run_transaction() { fn binary_name_matches_manifest() { assert_eq!(database::worker_name(), "database"); } - -/// Regression: every RPC function must register through the typed -/// `RegisterFunction::new_async` API so the engine receives auto-generated -/// JSON Schemas. Without this the public API Reference shows empty schemas. -/// If someone adds a new function via `register_function_with(...)`, this test -/// won't catch it directly — but it locks the typed shape for the existing 5. -#[test] -fn registered_functions_carry_request_and_response_schemas() { - fn assert_schemas(id: &str, f: F) - where - T: serde::de::DeserializeOwned + schemars::JsonSchema + Send + 'static, - F: Fn(T) -> Fut + Send + Sync + 'static, - Fut: std::future::Future> + Send + 'static, - R: serde::Serialize + schemars::JsonSchema + Send + 'static, - E: std::fmt::Display + Send + 'static, - { - let reg = RegisterFunction::new_async(id, f); - assert!( - reg.request_format().is_some(), - "{id} missing request_format — did you switch back to register_function_with?" - ); - assert!( - reg.response_format().is_some(), - "{id} missing response_format" - ); - } - - // We can't move a real AppState into these closures (it owns DB pools), - // so we just verify the schema-derivation path with the public Req/Resp - // types. Any drift in the typed contract surfaces here as a compile error. - async fn _q(_: QueryReq) -> Result { - unreachable!() - } - async fn _e(_: ExecuteReq) -> Result { - unreachable!() - } - async fn _p(_: PrepareReq) -> Result { - unreachable!() - } - async fn _r(_: RunReq) -> Result { - unreachable!() - } - async fn _t(_: TxReq) -> Result { - unreachable!() - } - async fn _bt( - _: database::handlers::begin_transaction::BeginTxReq, - ) -> Result { - unreachable!() - } - async fn _tq( - _: database::handlers::transaction_query::TxQueryReq, - ) -> Result { - unreachable!() - } - async fn _te( - _: database::handlers::transaction_execute::TxExecuteReq, - ) -> Result { - unreachable!() - } - async fn _ct( - _: database::handlers::commit_transaction::CommitTxReq, - ) -> Result { - unreachable!() - } - async fn _rt( - _: database::handlers::rollback_transaction::RollbackTxReq, - ) -> Result { - unreachable!() - } - - assert_schemas("database::query", _q); - assert_schemas("database::execute", _e); - assert_schemas("database::prepareStatement", _p); - assert_schemas("database::runStatement", _r); - assert_schemas("database::transaction", _t); - assert_schemas("database::beginTransaction", _bt); - assert_schemas("database::transactionQuery", _tq); - assert_schemas("database::transactionExecute", _te); - assert_schemas("database::commitTransaction", _ct); - assert_schemas("database::rollbackTransaction", _rt); -} diff --git a/iii-directory/Cargo.lock b/iii-directory/Cargo.lock index 8dfbe84e..91971a48 100644 --- a/iii-directory/Cargo.lock +++ b/iii-directory/Cargo.lock @@ -105,9 +105,9 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "autocfg" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" [[package]] name = "base64" @@ -142,9 +142,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.20.2" +version = "3.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" [[package]] name = "bytecount" @@ -160,9 +160,9 @@ checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" [[package]] name = "cc" -version = "1.2.61" +version = "1.2.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d16d90359e986641506914ba71350897565610e87ce0ad9e6f28569db3dd5c6d" +checksum = "a1dce859f0832a7d088c4f1119888ab94ef4b5d6795d1ce05afb7fe159d79f98" dependencies = [ "find-msvc-tools", "shlex", @@ -255,9 +255,9 @@ dependencies = [ [[package]] name = "const-hex" -version = "1.19.0" +version = "1.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20d9a563d167a9cce0f94153382b33cb6eded6dfabff03c69ad65a28ea1514e0" +checksum = "33e2a781ebdf4467d1428dc4593067825fb646f6871475098d8577421af73558" dependencies = [ "cfg-if", "cpufeatures", @@ -467,9 +467,9 @@ checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" [[package]] name = "either" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e" [[package]] name = "encode_unicode" @@ -713,9 +713,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f44da3a8150a6703ed5d34e164b875fd14c2cdab9af1252a9a1020bde2bdc54" +checksum = "171fefbc92fe4a4de27e0698d6a5b392d6a0e333506bc49133760b3bcf948733" dependencies = [ "atomic-waker", "bytes", @@ -741,9 +741,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.17.0" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f467dd6dccf739c208452f8014c75c18bb8301b050ad1cfb27153803edb0f51" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" [[package]] name = "heck" @@ -770,9 +770,9 @@ dependencies = [ [[package]] name = "http" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" +checksum = "8be7462df143984c4598a256ef469b251d7d7f9e271135073e78fc535414f3d0" dependencies = [ "bytes", "itoa", @@ -1069,21 +1069,19 @@ dependencies = [ ] [[package]] -name = "iii-sdk" -version = "0.13.0-next.1" +name = "iii-observability" +version = "0.16.0-next.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17cf728e12b30b11c37295304e0a5807cf677cca430b66609b7ae3c6044c358d" +checksum = "00ee84dacaf7e14750ebdc229523e52029441c4ae1f72d25972bf1f2e1edeb99" dependencies = [ "async-trait", "futures-util", - "hostname", "opentelemetry", "opentelemetry-http", "opentelemetry-proto", "opentelemetry_sdk", "prost", "reqwest", - "schemars", "serde", "serde_json", "sysinfo", @@ -1094,6 +1092,27 @@ dependencies = [ "uuid", ] +[[package]] +name = "iii-sdk" +version = "0.16.0-next.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53c18b68b2aa09e18c68fb023c78316fe7ccf42181874eab584d66f40119b47e" +dependencies = [ + "async-trait", + "futures-util", + "hostname", + "iii-observability", + "reqwest", + "schemars", + "serde", + "serde_json", + "thiserror", + "tokio", + "tokio-tungstenite", + "tracing", + "uuid", +] + [[package]] name = "indexmap" version = "2.14.0" @@ -1101,7 +1120,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" dependencies = [ "equivalent", - "hashbrown 0.17.0", + "hashbrown 0.17.1", "serde", "serde_core", ] @@ -1127,16 +1146,6 @@ version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2" -[[package]] -name = "iri-string" -version = "0.7.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25e659a4bb38e810ebc252e53b5814ff908a8c58c2a9ce2fae1bbec24cbf4e20" -dependencies = [ - "memchr", - "serde", -] - [[package]] name = "is_terminal_polyfill" version = "1.70.2" @@ -1160,9 +1169,9 @@ checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" [[package]] name = "js-sys" -version = "0.3.97" +version = "0.3.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1840c94c045fbcf8ba2812c95db44499f7c64910a912551aaaa541decebcacf" +checksum = "142bc4740e452c1e57ade0cbc129f139c9093e354346f0872ef985f4f5cf5f11" dependencies = [ "cfg-if", "futures-util", @@ -1208,9 +1217,9 @@ checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0" [[package]] name = "log" -version = "0.4.29" +version = "0.4.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" +checksum = "616ec5685824bcc94416c6d4a7a446eea774a31efd7062c8480ba6fd06d7a6e5" [[package]] name = "lru-slab" @@ -1434,18 +1443,18 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "pin-project" -version = "1.1.11" +version = "1.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1749c7ed4bcaf4c3d0a3efc28538844fb29bcdd7d2b67b2be7e20ba861ff517" +checksum = "2466b2336ed02bcdca6b294417127b90ec92038d1d5c4fbeac971a922e0e0924" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.11" +version = "1.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b20ed30f105399776b9c883e68e536ef602a16ae6f596d2c473591d6ad64c6" +checksum = "c96395f0a926bc13b1c17622aaddda1ecb55d49c8f1bf9777e4d877800a43f8b" dependencies = [ "proc-macro2", "quote", @@ -1962,9 +1971,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.149" +version = "1.0.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9" dependencies = [ "itoa", "memchr", @@ -2259,9 +2268,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.52.1" +version = "1.52.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67dee974fe86fd92cc45b7a95fdd2f99a36a6d7b0d431a231178d3d670bbcc6" +checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe" dependencies = [ "bytes", "libc", @@ -2336,9 +2345,9 @@ dependencies = [ [[package]] name = "tonic" -version = "0.14.5" +version = "0.14.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fec7c61a0695dc1887c1b53952990f3ad2e3a31453e1f49f10e75424943a93ec" +checksum = "ac2a5518c70fa84342385732db33fb3f44bc4cc748936eb5833d2df34d6445ef" dependencies = [ "async-trait", "base64", @@ -2362,9 +2371,9 @@ dependencies = [ [[package]] name = "tonic-prost" -version = "0.14.5" +version = "0.14.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a55376a0bbaa4975a3f10d009ad763d8f4108f067c7c2e74f3001fb49778d309" +checksum = "50849f68853be452acf590cde0b146665b8d507b3b8af17261df47e02c209ea0" dependencies = [ "bytes", "prost", @@ -2392,20 +2401,20 @@ dependencies = [ [[package]] name = "tower-http" -version = "0.6.8" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" +checksum = "4cfcf7e2740e6fc6d4d688b4ef00650406bb94adf4731e43c096c3a19fe40840" dependencies = [ "bitflags", "bytes", "futures-util", "http", "http-body", - "iri-string", "pin-project-lite", "tower", "tower-layer", "tower-service", + "url", ] [[package]] @@ -2679,9 +2688,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.120" +version = "0.2.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df52b6d9b87e0c74c9edfa1eb2d9bf85e5d63515474513aa50fa181b3c4f5db1" +checksum = "3ed04576f974d2b2fba0f38c51dbc5518011e38c36bf1143164be765528fd409" dependencies = [ "cfg-if", "once_cell", @@ -2692,9 +2701,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.70" +version = "0.4.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af934872acec734c2d80e6617bbb5ff4f12b052dd8e6332b0817bce889516084" +checksum = "9473dbd2991ae90b6291c3c32c30c6187ac49aa32f9905d1cce280ec1e110b0f" dependencies = [ "js-sys", "wasm-bindgen", @@ -2702,9 +2711,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.120" +version = "0.2.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b1041f495fb322e64aca85f5756b2172e35cd459376e67f2a6c9dffcedb103" +checksum = "916151b09da36bd82f6615cbf3a419e2f0ba23a03c6160e8e92eb6bd4aa1dec6" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2712,9 +2721,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.120" +version = "0.2.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dcd0ff20416988a18ac686d4d4d0f6aae9ebf08a389ff5d29012b05af2a1b41" +checksum = "299047362ccbfce148b67ab7e73349f77748e00c8296f9542adfad2ad82c5c5e" dependencies = [ "bumpalo", "proc-macro2", @@ -2725,9 +2734,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.120" +version = "0.2.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49757b3c82ebf16c57d69365a142940b384176c24df52a087fb748e2085359ea" +checksum = "9a929b2c61f11ba3e9bc35b50c1f25cb38e0e892c0c231ae2b8cf78d5dad4437" dependencies = [ "unicode-ident", ] @@ -2768,9 +2777,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.97" +version = "0.3.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eadbac71025cd7b0834f20d1fe8472e8495821b4e9801eb0a60bd1f19827602" +checksum = "6d621441cfc37b84979402712047321980c178f299193a3589d05b99e8763436" dependencies = [ "js-sys", "wasm-bindgen", @@ -3260,9 +3269,9 @@ dependencies = [ [[package]] name = "zerofrom" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69faa1f2a1ea75661980b013019ed6687ed0e83d069bc1114e2cc74c6c04c4df" +checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272" dependencies = [ "zerofrom-derive", ] diff --git a/iii-directory/Cargo.toml b/iii-directory/Cargo.toml index 108f0be4..ae5cbba8 100644 --- a/iii-directory/Cargo.toml +++ b/iii-directory/Cargo.toml @@ -15,7 +15,7 @@ name = "iii_directory" path = "src/lib.rs" [dependencies] -iii-sdk = "=0.13.0-next.1" +iii-sdk = "=0.16.0-next.2" tokio = { version = "1", features = ["rt-multi-thread", "macros", "sync", "signal", "time", "fs", "process"] } serde = { version = "1", features = ["derive"] } serde_json = "1" diff --git a/iii-directory/src/functions/directory.rs b/iii-directory/src/functions/directory.rs index f4344342..df836564 100644 --- a/iii-directory/src/functions/directory.rs +++ b/iii-directory/src/functions/directory.rs @@ -343,13 +343,11 @@ pub fn register(iii: &Arc, cfg: &Arc) { fn register_function_list(iii: &Arc) { let iii_inner = iii.clone(); iii.register_function( - RegisterFunction::new_async( - "directory::engine::functions::list", - move |req: FunctionListInput| { - let iii = iii_inner.clone(); - async move { function_list(&iii, req).await.map_err(IIIError::Handler) } - }, - ) + "directory::engine::functions::list", + RegisterFunction::new_async(move |req: FunctionListInput| { + let iii = iii_inner.clone(); + async move { function_list(&iii, req).await.map_err(IIIError::Handler) } + }) .description( "List every function registered with the engine. Filter by free-text \ search, namespace prefix, and/or worker name.", @@ -361,18 +359,16 @@ fn register_function_info(iii: &Arc, cfg: &Arc) { let iii_inner = iii.clone(); let cfg_inner = cfg.clone(); iii.register_function( - RegisterFunction::new_async( - "directory::engine::functions::info", - move |req: FunctionInfoInput| { - let iii = iii_inner.clone(); - let cfg = cfg_inner.clone(); - async move { - function_info(&iii, &cfg, req) - .await - .map_err(IIIError::Handler) - } - }, - ) + "directory::engine::functions::info", + RegisterFunction::new_async(move |req: FunctionInfoInput| { + let iii = iii_inner.clone(); + let cfg = cfg_inner.clone(); + async move { + function_info(&iii, &cfg, req) + .await + .map_err(IIIError::Handler) + } + }) .description( "Full detail for one function: schemas, owning worker, registered \ triggers that target it, and any matching how-to skill from skills_folder.", @@ -383,13 +379,11 @@ fn register_function_info(iii: &Arc, cfg: &Arc) { fn register_trigger_list(iii: &Arc) { let iii_inner = iii.clone(); iii.register_function( - RegisterFunction::new_async( - "directory::engine::triggers::list", - move |req: TriggerListInput| { - let iii = iii_inner.clone(); - async move { trigger_list(&iii, req).await.map_err(IIIError::Handler) } - }, - ) + "directory::engine::triggers::list", + RegisterFunction::new_async(move |req: TriggerListInput| { + let iii = iii_inner.clone(); + async move { trigger_list(&iii, req).await.map_err(IIIError::Handler) } + }) .description( "List every trigger TYPE registered with the engine. Filter by \ search, prefix, worker. (For registered trigger instances, use \ @@ -401,13 +395,11 @@ fn register_trigger_list(iii: &Arc) { fn register_trigger_info(iii: &Arc) { let iii_inner = iii.clone(); iii.register_function( - RegisterFunction::new_async( - "directory::engine::triggers::info", - move |req: TriggerInfoInput| { - let iii = iii_inner.clone(); - async move { trigger_info(&iii, req).await.map_err(IIIError::Handler) } - }, - ) + "directory::engine::triggers::info", + RegisterFunction::new_async(move |req: TriggerInfoInput| { + let iii = iii_inner.clone(); + async move { trigger_info(&iii, req).await.map_err(IIIError::Handler) } + }) .description( "Full detail for one trigger type: configuration schema, return \ schema, owning worker, and current instance count.", @@ -418,17 +410,15 @@ fn register_trigger_info(iii: &Arc) { fn register_registered_trigger_list(iii: &Arc) { let iii_inner = iii.clone(); iii.register_function( - RegisterFunction::new_async( - "directory::engine::registered-triggers::list", - move |req: RegisteredTriggerListInput| { - let iii = iii_inner.clone(); - async move { - registered_trigger_list(&iii, req) - .await - .map_err(IIIError::Handler) - } - }, - ) + "directory::engine::registered-triggers::list", + RegisterFunction::new_async(move |req: RegisteredTriggerListInput| { + let iii = iii_inner.clone(); + async move { + registered_trigger_list(&iii, req) + .await + .map_err(IIIError::Handler) + } + }) .description( "List registered trigger instances (the link rows between \ trigger types and target functions). Filter by trigger_type, \ @@ -441,18 +431,16 @@ fn register_registered_trigger_info(iii: &Arc, cfg: &Arc) { let iii_inner = iii.clone(); let cfg_inner = cfg.clone(); iii.register_function( - RegisterFunction::new_async( - "directory::engine::registered-triggers::info", - move |req: RegisteredTriggerInfoInput| { - let iii = iii_inner.clone(); - let cfg = cfg_inner.clone(); - async move { - registered_trigger_info(&iii, &cfg, req) - .await - .map_err(IIIError::Handler) - } - }, - ) + "directory::engine::registered-triggers::info", + RegisterFunction::new_async(move |req: RegisteredTriggerInfoInput| { + let iii = iii_inner.clone(); + let cfg = cfg_inner.clone(); + async move { + registered_trigger_info(&iii, &cfg, req) + .await + .map_err(IIIError::Handler) + } + }) .description( "Full denormalized detail for one registered trigger: \ instance config + trigger-type detail + function detail.", @@ -463,13 +451,11 @@ fn register_registered_trigger_info(iii: &Arc, cfg: &Arc) { fn register_worker_list(iii: &Arc) { let iii_inner = iii.clone(); iii.register_function( - RegisterFunction::new_async( - "directory::engine::workers::list", - move |req: WorkerListInput| { - let iii = iii_inner.clone(); - async move { worker_list(&iii, req).await.map_err(IIIError::Handler) } - }, - ) + "directory::engine::workers::list", + RegisterFunction::new_async(move |req: WorkerListInput| { + let iii = iii_inner.clone(); + async move { worker_list(&iii, req).await.map_err(IIIError::Handler) } + }) .description( "List every worker currently connected to the engine. Filter by \ name substring, runtime, or status. Same row shape as \ @@ -481,13 +467,11 @@ fn register_worker_list(iii: &Arc) { fn register_worker_info(iii: &Arc) { let iii_inner = iii.clone(); iii.register_function( - RegisterFunction::new_async( - "directory::engine::workers::info", - move |req: WorkerInfoInput| { - let iii = iii_inner.clone(); - async move { worker_info(&iii, req).await.map_err(IIIError::Handler) } - }, - ) + "directory::engine::workers::info", + RegisterFunction::new_async(move |req: WorkerInfoInput| { + let iii = iii_inner.clone(); + async move { worker_info(&iii, req).await.map_err(IIIError::Handler) } + }) .description( "Worker envelope plus the lists of functions, trigger types, and \ registered triggers it owns. The `worker` field has the same \ diff --git a/iii-directory/src/functions/download.rs b/iii-directory/src/functions/download.rs index c9e0a16e..b4b487fc 100644 --- a/iii-directory/src/functions/download.rs +++ b/iii-directory/src/functions/download.rs @@ -83,7 +83,8 @@ pub fn register(iii: &Arc, cfg: &Arc, subscribers: &super::Su let skills_subs = subscribers.skills.clone(); let prompts_subs = subscribers.prompts.clone(); iii.register_function( - RegisterFunction::new_async("directory::skills::download", move |req: DownloadInput| { + "directory::skills::download", + RegisterFunction::new_async(move |req: DownloadInput| { let iii = iii_inner.clone(); let cfg = cfg_inner.clone(); let skills_subs = skills_subs.clone(); diff --git a/iii-directory/src/functions/prompts.rs b/iii-directory/src/functions/prompts.rs index 641b53b2..60064e53 100644 --- a/iii-directory/src/functions/prompts.rs +++ b/iii-directory/src/functions/prompts.rs @@ -64,28 +64,25 @@ pub fn register(iii: &Arc, cfg: &Arc) { fn register_list_prompts(iii: &Arc, cfg: &Arc) { let cfg_inner = cfg.clone(); iii.register_function( - RegisterFunction::new_async( - "directory::prompts::list", - move |_input: ListPromptsInput| { - let cfg = cfg_inner.clone(); - async move { - let (prompts, _skipped) = - fs_source::scan_prompts(&cfg.resolved_skills_folder()); - let out: Vec = prompts - .into_iter() - .map(|p| { - let modified_at = fs_modified_at(&p.abs_path); - PromptEntry { - name: p.name, - description: p.description, - modified_at, - } - }) - .collect(); - Ok::<_, IIIError>(ListPromptsOutput { prompts: out }) - } - }, - ) + "directory::prompts::list", + RegisterFunction::new_async(move |_input: ListPromptsInput| { + let cfg = cfg_inner.clone(); + async move { + let (prompts, _skipped) = fs_source::scan_prompts(&cfg.resolved_skills_folder()); + let out: Vec = prompts + .into_iter() + .map(|p| { + let modified_at = fs_modified_at(&p.abs_path); + PromptEntry { + name: p.name, + description: p.description, + modified_at, + } + }) + .collect(); + Ok::<_, IIIError>(ListPromptsOutput { prompts: out }) + } + }) .description( "List filesystem-backed prompts (name, description, modified_at) from skills_folder.", ), @@ -95,7 +92,8 @@ fn register_list_prompts(iii: &Arc, cfg: &Arc) { fn register_get_prompt(iii: &Arc, cfg: &Arc) { let cfg_inner = cfg.clone(); iii.register_function( - RegisterFunction::new_async("directory::prompts::get", move |req: PromptGetInput| { + "directory::prompts::get", + RegisterFunction::new_async(move |req: PromptGetInput| { let cfg = cfg_inner.clone(); async move { get_prompt(&cfg, req).await.map_err(IIIError::Handler) } }) diff --git a/iii-directory/src/functions/registry.rs b/iii-directory/src/functions/registry.rs index 4363cfd6..8cf6de2a 100644 --- a/iii-directory/src/functions/registry.rs +++ b/iii-directory/src/functions/registry.rs @@ -278,18 +278,16 @@ fn register_worker_list(iii: &Arc, cfg: &Arc, cache: Registry let cfg_inner = cfg.clone(); let cache_inner = cache; iii.register_function( - RegisterFunction::new_async( - "directory::registry::workers::list", - move |req: WorkerListInput| { - let cfg = cfg_inner.clone(); - let cache = cache_inner.clone(); - async move { - worker_list(&cfg, &cache, req) - .await - .map_err(IIIError::Handler) - } - }, - ) + "directory::registry::workers::list", + RegisterFunction::new_async(move |req: WorkerListInput| { + let cfg = cfg_inner.clone(); + let cache = cache_inner.clone(); + async move { + worker_list(&cfg, &cache, req) + .await + .map_err(IIIError::Handler) + } + }) .description( "List workers from the public registry (api.workers.iii.dev). \ Optional free-text `search` is matched fuzzily by the registry; \ @@ -307,18 +305,16 @@ fn register_worker_info(iii: &Arc, cfg: &Arc, cache: Registry let cfg_inner = cfg.clone(); let cache_inner = cache; iii.register_function( - RegisterFunction::new_async( - "directory::registry::workers::info", - move |req: WorkerInfoInput| { - let cfg = cfg_inner.clone(); - let cache = cache_inner.clone(); - async move { - worker_info(&cfg, &cache, req) - .await - .map_err(IIIError::Handler) - } - }, - ) + "directory::registry::workers::info", + RegisterFunction::new_async(move |req: WorkerInfoInput| { + let cfg = cfg_inner.clone(); + let cache = cache_inner.clone(); + async move { + worker_info(&cfg, &cache, req) + .await + .map_err(IIIError::Handler) + } + }) .description( "Fetch full registry metadata for one worker: worker envelope \ (same core fields as directory::engine::workers::info plus \ diff --git a/iii-directory/src/functions/skills.rs b/iii-directory/src/functions/skills.rs index 3bd8f02c..075842f0 100644 --- a/iii-directory/src/functions/skills.rs +++ b/iii-directory/src/functions/skills.rs @@ -156,7 +156,8 @@ pub fn register(iii: &Arc, cfg: &Arc) { fn register_list_skills(iii: &Arc, cfg: &Arc) { let cfg_inner = cfg.clone(); iii.register_function( - RegisterFunction::new_async("directory::skills::list", move |_input: ListSkillsInput| { + "directory::skills::list", + RegisterFunction::new_async(move |_input: ListSkillsInput| { let cfg = cfg_inner.clone(); async move { let (entries, _skipped) = fs_source::scan_skills(&cfg.resolved_skills_folder()); @@ -177,7 +178,8 @@ fn register_list_skills(iii: &Arc, cfg: &Arc) { fn register_get_skill(iii: &Arc, cfg: &Arc) { let cfg_inner = cfg.clone(); iii.register_function( - RegisterFunction::new_async("directory::skills::get", move |req: SkillGetInput| { + "directory::skills::get", + RegisterFunction::new_async(move |req: SkillGetInput| { let cfg = cfg_inner.clone(); async move { get_skill(&cfg, req).await.map_err(IIIError::Handler) } }) @@ -189,26 +191,23 @@ fn register_get_skill(iii: &Arc, cfg: &Arc) { fn register_index_skills(iii: &Arc, cfg: &Arc) { let cfg_inner = cfg.clone(); iii.register_function( - RegisterFunction::new_async( - "directory::skills::index", - move |_input: IndexSkillsInput| { - let cfg = cfg_inner.clone(); - async move { - let (entries, _skipped) = fs_source::scan_skills(&cfg.resolved_skills_folder()); - let rows: Vec = - entries.into_iter().map(skill_entry_from_fs).collect(); - let body = render_index_markdown(&rows); - let workers_count = rows - .iter() - .filter(|e| e.kind.as_deref() == Some("index")) - .count(); - Ok::<_, IIIError>(IndexSkillsOutput { - body, - workers_count, - }) - } - }, - ) + "directory::skills::index", + RegisterFunction::new_async(move |_input: IndexSkillsInput| { + let cfg = cfg_inner.clone(); + async move { + let (entries, _skipped) = fs_source::scan_skills(&cfg.resolved_skills_folder()); + let rows: Vec = entries.into_iter().map(skill_entry_from_fs).collect(); + let body = render_index_markdown(&rows); + let workers_count = rows + .iter() + .filter(|e| e.kind.as_deref() == Some("index")) + .count(); + Ok::<_, IIIError>(IndexSkillsOutput { + body, + workers_count, + }) + } + }) .description( "Render one short markdown entry per installed worker (skills with frontmatter \ `type: index`). Each entry is a `## ` heading, the first paragraph \ diff --git a/iii-directory/src/main.rs b/iii-directory/src/main.rs index 13315daf..a04bc8f3 100644 --- a/iii-directory/src/main.rs +++ b/iii-directory/src/main.rs @@ -22,7 +22,7 @@ use std::sync::Arc; use anyhow::Result; use clap::Parser; -use iii_sdk::{register_worker, InitOptions, OtelConfig, WorkerMetadata}; +use iii_sdk::{register_worker, InitOptions, WorkerMetadata}; use iii_directory::{config, functions, manifest, trigger_types}; @@ -79,7 +79,6 @@ async fn main() -> Result<()> { let iii = register_worker( &cli.url, InitOptions { - otel: Some(OtelConfig::default()), metadata: Some(WorkerMetadata { runtime: "rust".to_string(), version: env!("CARGO_PKG_VERSION").to_string(), diff --git a/iii-lsp/Cargo.lock b/iii-lsp/Cargo.lock index 92ba2958..a3ad2da0 100644 --- a/iii-lsp/Cargo.lock +++ b/iii-lsp/Cargo.lock @@ -793,21 +793,19 @@ dependencies = [ ] [[package]] -name = "iii-sdk" -version = "0.13.0-next.1" +name = "iii-observability" +version = "0.16.0-next.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17cf728e12b30b11c37295304e0a5807cf677cca430b66609b7ae3c6044c358d" +checksum = "00ee84dacaf7e14750ebdc229523e52029441c4ae1f72d25972bf1f2e1edeb99" dependencies = [ "async-trait", "futures-util", - "hostname", "opentelemetry", "opentelemetry-http", "opentelemetry-proto", "opentelemetry_sdk", "prost", "reqwest", - "schemars", "serde", "serde_json", "sysinfo", @@ -818,6 +816,27 @@ dependencies = [ "uuid", ] +[[package]] +name = "iii-sdk" +version = "0.16.0-next.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53c18b68b2aa09e18c68fb023c78316fe7ccf42181874eab584d66f40119b47e" +dependencies = [ + "async-trait", + "futures-util", + "hostname", + "iii-observability", + "reqwest", + "schemars", + "serde", + "serde_json", + "thiserror", + "tokio", + "tokio-tungstenite", + "tracing", + "uuid", +] + [[package]] name = "indexmap" version = "2.13.1" diff --git a/iii-lsp/Cargo.toml b/iii-lsp/Cargo.toml index f2b84a2b..d4a4dfc4 100644 --- a/iii-lsp/Cargo.toml +++ b/iii-lsp/Cargo.toml @@ -9,7 +9,7 @@ name = "iii-lsp" path = "src/main.rs" [dependencies] -iii-sdk = "=0.13.0-next.1" +iii-sdk = "=0.16.0-next.2" tower-lsp-server = "0.23" tree-sitter = "0.24" tree-sitter-typescript = "0.23" diff --git a/image-resize/Cargo.lock b/image-resize/Cargo.lock index dcf104ce..26d269a5 100644 --- a/image-resize/Cargo.lock +++ b/image-resize/Cargo.lock @@ -753,21 +753,19 @@ dependencies = [ ] [[package]] -name = "iii-sdk" -version = "0.13.0-next.1" +name = "iii-observability" +version = "0.16.0-next.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17cf728e12b30b11c37295304e0a5807cf677cca430b66609b7ae3c6044c358d" +checksum = "00ee84dacaf7e14750ebdc229523e52029441c4ae1f72d25972bf1f2e1edeb99" dependencies = [ "async-trait", "futures-util", - "hostname", "opentelemetry", "opentelemetry-http", "opentelemetry-proto", "opentelemetry_sdk", "prost", "reqwest", - "schemars", "serde", "serde_json", "sysinfo", @@ -778,6 +776,27 @@ dependencies = [ "uuid", ] +[[package]] +name = "iii-sdk" +version = "0.16.0-next.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53c18b68b2aa09e18c68fb023c78316fe7ccf42181874eab584d66f40119b47e" +dependencies = [ + "async-trait", + "futures-util", + "hostname", + "iii-observability", + "reqwest", + "schemars", + "serde", + "serde_json", + "thiserror", + "tokio", + "tokio-tungstenite", + "tracing", + "uuid", +] + [[package]] name = "image" version = "0.25.10" diff --git a/image-resize/Cargo.toml b/image-resize/Cargo.toml index cbb23aa0..0a472f2b 100644 --- a/image-resize/Cargo.toml +++ b/image-resize/Cargo.toml @@ -11,7 +11,7 @@ name = "image-resize" path = "src/main.rs" [dependencies] -iii-sdk = "=0.13.0-next.1" +iii-sdk = "=0.16.0-next.2" image = { version = "0.25", default-features = false, features = ["jpeg", "png", "webp"] } kamadak-exif = "0.6" tokio = { version = "1", features = ["rt-multi-thread", "macros", "sync", "signal"] } diff --git a/image-resize/src/main.rs b/image-resize/src/main.rs index 3f0a4da1..2cebeeff 100644 --- a/image-resize/src/main.rs +++ b/image-resize/src/main.rs @@ -1,6 +1,6 @@ use anyhow::Result; use clap::Parser; -use iii_sdk::{register_worker, InitOptions, OtelConfig, RegisterFunctionMessage}; +use iii_sdk::{register_worker, InitOptions, RegisterFunction}; use std::sync::Arc; mod config; @@ -51,21 +51,15 @@ async fn main() -> Result<()> { tracing::info!(url = %cli.url, "connecting to III engine"); - let iii = register_worker( - &cli.url, - InitOptions { - otel: Some(OtelConfig::default()), - ..Default::default() - }, - ); + let iii = register_worker(&cli.url, InitOptions::default()); let resize_handler = handler::build_handler(cli.url.clone(), config); - let _fn_ref = iii.register_function_with( - RegisterFunctionMessage { - id: "image_resize::resize".to_string(), - description: Some("Resize an image via channel I/O".to_string()), - request_format: Some(serde_json::json!({ + let _fn_ref = iii.register_function( + "image_resize::resize", + RegisterFunction::new_async(resize_handler) + .description("Resize an image via channel I/O") + .request_format(serde_json::json!({ "type": "object", "properties": { "input_channel": { @@ -92,8 +86,8 @@ async fn main() -> Result<()> { } }, "required": ["input_channel", "output_channel"] - })), - response_format: Some(serde_json::json!({ + })) + .response_format(serde_json::json!({ "type": "object", "properties": { "format": { "type": "string" }, @@ -102,10 +96,6 @@ async fn main() -> Result<()> { "strategy": { "type": "string" } } })), - metadata: None, - invocation: None, - }, - resize_handler, ); tracing::info!("image_resize::resize function registered, waiting for invocations"); diff --git a/mcp/Cargo.lock b/mcp/Cargo.lock index 3ae7cddf..be8bddab 100644 --- a/mcp/Cargo.lock +++ b/mcp/Cargo.lock @@ -943,21 +943,19 @@ dependencies = [ ] [[package]] -name = "iii-sdk" -version = "0.13.0-next.1" +name = "iii-observability" +version = "0.16.0-next.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17cf728e12b30b11c37295304e0a5807cf677cca430b66609b7ae3c6044c358d" +checksum = "00ee84dacaf7e14750ebdc229523e52029441c4ae1f72d25972bf1f2e1edeb99" dependencies = [ "async-trait", "futures-util", - "hostname", "opentelemetry", "opentelemetry-http", "opentelemetry-proto", "opentelemetry_sdk", "prost", "reqwest", - "schemars", "serde", "serde_json", "sysinfo", @@ -968,6 +966,27 @@ dependencies = [ "uuid", ] +[[package]] +name = "iii-sdk" +version = "0.16.0-next.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53c18b68b2aa09e18c68fb023c78316fe7ccf42181874eab584d66f40119b47e" +dependencies = [ + "async-trait", + "futures-util", + "hostname", + "iii-observability", + "reqwest", + "schemars", + "serde", + "serde_json", + "thiserror", + "tokio", + "tokio-tungstenite", + "tracing", + "uuid", +] + [[package]] name = "indexmap" version = "2.14.0" @@ -1099,6 +1118,7 @@ dependencies = [ "clap", "cucumber", "futures", + "iii-observability", "iii-sdk", "regex", "reqwest", diff --git a/mcp/Cargo.toml b/mcp/Cargo.toml index 004a9e8f..121603e6 100644 --- a/mcp/Cargo.toml +++ b/mcp/Cargo.toml @@ -15,7 +15,8 @@ name = "iii_mcp" path = "src/lib.rs" [dependencies] -iii-sdk = "=0.13.0-next.1" +iii-sdk = "=0.16.0-next.2" +iii-observability = "=0.16.0-next.2" tokio = { version = "1", features = ["rt-multi-thread", "macros", "sync", "signal"] } serde = { version = "1", features = ["derive"] } serde_json = "1" diff --git a/mcp/src/functions/mod.rs b/mcp/src/functions/mod.rs index 28b767d0..bcb146f8 100644 --- a/mcp/src/functions/mod.rs +++ b/mcp/src/functions/mod.rs @@ -1,8 +1,9 @@ use std::sync::Arc; +use iii_observability::Logger; use iii_sdk::{ channels::{ChannelWriter, StreamChannelRef}, - IIIError, Logger, RegisterFunction, III, + IIIError, RegisterFunction, III, }; use serde::Deserialize; use serde_json::{json, Value}; @@ -51,7 +52,8 @@ fn register_handler(iii: &Arc, cfg: &Arc) { log: Logger::new(), }; iii.register_function( - RegisterFunction::new_async(FUNCTION_ID, move |req: Value| { + FUNCTION_ID, + RegisterFunction::new_async(move |req: Value| { let ctx = ctx.clone(); async move { let envelope: McpRequest = match serde_json::from_value(req) { diff --git a/mcp/src/main.rs b/mcp/src/main.rs index cd950946..8487dc84 100644 --- a/mcp/src/main.rs +++ b/mcp/src/main.rs @@ -7,7 +7,7 @@ use anyhow::Result; use clap::Parser; -use iii_sdk::{register_worker, InitOptions, OtelConfig, RegisterTriggerInput, WorkerMetadata}; +use iii_sdk::{register_worker, InitOptions, RegisterTriggerInput, WorkerMetadata}; use serde_json::json; use std::sync::Arc; use tracing_subscriber::EnvFilter; @@ -60,7 +60,6 @@ async fn main() -> Result<()> { let iii = register_worker( &cli.url, InitOptions { - otel: Some(OtelConfig::default()), metadata: Some(WorkerMetadata { runtime: "rust".to_string(), version: env!("CARGO_PKG_VERSION").to_string(), diff --git a/shell/Cargo.lock b/shell/Cargo.lock index 8e868ce8..50a28aa9 100644 --- a/shell/Cargo.lock +++ b/shell/Cargo.lock @@ -706,21 +706,19 @@ dependencies = [ ] [[package]] -name = "iii-sdk" -version = "0.13.0-next.1" +name = "iii-observability" +version = "0.16.0-next.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17cf728e12b30b11c37295304e0a5807cf677cca430b66609b7ae3c6044c358d" +checksum = "00ee84dacaf7e14750ebdc229523e52029441c4ae1f72d25972bf1f2e1edeb99" dependencies = [ "async-trait", "futures-util", - "hostname", "opentelemetry", "opentelemetry-http", "opentelemetry-proto", "opentelemetry_sdk", "prost", "reqwest", - "schemars", "serde", "serde_json", "sysinfo", @@ -731,6 +729,27 @@ dependencies = [ "uuid", ] +[[package]] +name = "iii-sdk" +version = "0.16.0-next.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53c18b68b2aa09e18c68fb023c78316fe7ccf42181874eab584d66f40119b47e" +dependencies = [ + "async-trait", + "futures-util", + "hostname", + "iii-observability", + "reqwest", + "schemars", + "serde", + "serde_json", + "thiserror", + "tokio", + "tokio-tungstenite", + "tracing", + "uuid", +] + [[package]] name = "indexmap" version = "2.14.0" diff --git a/shell/Cargo.toml b/shell/Cargo.toml index b71c7a89..2bc51e9f 100644 --- a/shell/Cargo.toml +++ b/shell/Cargo.toml @@ -11,7 +11,7 @@ name = "shell" path = "src/main.rs" [dependencies] -iii-sdk = "=0.13.0-next.1" +iii-sdk = "=0.16.0-next.2" schemars = { version = "0.8", features = ["uuid1"] } libc = "0.2" tokio = { version = "1", features = ["rt-multi-thread", "macros", "sync", "signal", "process", "time", "io-util", "fs"] } diff --git a/shell/src/main.rs b/shell/src/main.rs index d77ce2d8..e2ee5d52 100644 --- a/shell/src/main.rs +++ b/shell/src/main.rs @@ -1,6 +1,6 @@ use anyhow::Result; use clap::Parser; -use iii_sdk::{register_worker, InitOptions, OtelConfig, RegisterFunction}; +use iii_sdk::{register_worker, IIIError, InitOptions, RegisterFunction}; use serde_json::Value; use std::sync::Arc; @@ -72,13 +72,7 @@ async fn main() -> Result<()> { let shared = Arc::new(shell_config); tracing::info!(url = %cli.url, "connecting to III engine"); - let iii = register_worker( - &cli.url, - InitOptions { - otel: Some(OtelConfig::default()), - ..Default::default() - }, - ); + let iii = register_worker(&cli.url, InitOptions::default()); // shell::exec, shell::exec_bg, and the 10 shell::fs::* handlers take // Value at the registration boundary so they can preserve legacy wire @@ -90,14 +84,16 @@ async fn main() -> Result<()> { let cfg = shared.clone(); let iii_for_exec = iii.clone(); iii.register_function( - RegisterFunction::new_async( - "shell::exec", - move |req: functions::types::ExecRequest| { - let cfg = cfg.clone(); - let iii_clone = iii_for_exec.clone(); - async move { functions::exec::handle(cfg, iii_clone, req).await } - }, - ) + "shell::exec", + RegisterFunction::new_async(move |req: functions::types::ExecRequest| { + let cfg = cfg.clone(); + let iii_clone = iii_for_exec.clone(); + async move { + functions::exec::handle(cfg, iii_clone, req) + .await + .map_err(IIIError::from) + } + }) .description( "Run an allowlisted command in the foreground and return its \ full output. Payload: { command: string (program name), \ @@ -114,14 +110,16 @@ async fn main() -> Result<()> { let cfg = shared.clone(); let iii_for_bg = iii.clone(); iii.register_function( - RegisterFunction::new_async( - "shell::exec_bg", - move |req: functions::types::ExecBgRequest| { - let cfg = cfg.clone(); - let iii_clone = iii_for_bg.clone(); - async move { functions::exec_bg::handle(cfg, iii_clone, req).await } - }, - ) + "shell::exec_bg", + RegisterFunction::new_async(move |req: functions::types::ExecBgRequest| { + let cfg = cfg.clone(); + let iii_clone = iii_for_bg.clone(); + async move { + functions::exec_bg::handle(cfg, iii_clone, req) + .await + .map_err(IIIError::from) + } + }) .description( "Spawn an allowlisted command as a background job. Same \ payload shape as shell::exec; returns { job_id, argv } \ @@ -134,15 +132,17 @@ async fn main() -> Result<()> { } iii.register_function( - RegisterFunction::new_async("shell::kill", |req: KillRequest| async move { - functions::kill::handle(req).await + "shell::kill", + RegisterFunction::new_async(|req: KillRequest| async move { + functions::kill::handle(req).await.map_err(IIIError::from) }) .description("Kill a running background job"), ); iii.register_function( - RegisterFunction::new_async("shell::status", |req: StatusRequest| async move { - functions::status::handle(req).await + "shell::status", + RegisterFunction::new_async(|req: StatusRequest| async move { + functions::status::handle(req).await.map_err(IIIError::from) }) .description("Get status of a background job"), ); @@ -150,9 +150,10 @@ async fn main() -> Result<()> { { let cfg = shared.clone(); iii.register_function( - RegisterFunction::new_async("shell::list", move |_req: Value| { + "shell::list", + RegisterFunction::new_async(move |_req: Value| { let cfg = cfg.clone(); - async move { functions::list::handle(cfg).await } + async move { functions::list::handle(cfg).await.map_err(IIIError::from) } }) .description("List all background jobs"), ); @@ -181,10 +182,15 @@ async fn main() -> Result<()> { let h = host_backend.clone(); let i = iii.clone(); iii.register_function( - RegisterFunction::new_async("shell::fs::ls", move |req: Value| { + "shell::fs::ls", + RegisterFunction::new_async(move |req: Value| { let h = h.clone(); let i = i.clone(); - async move { functions::fs_ls::handle(h, i, sb_enabled, req).await } + async move { + functions::fs_ls::handle(h, i, sb_enabled, req) + .await + .map_err(IIIError::from) + } }) .description("List directory contents on host or sandbox"), ); @@ -194,10 +200,15 @@ async fn main() -> Result<()> { let h = host_backend.clone(); let i = iii.clone(); iii.register_function( - RegisterFunction::new_async("shell::fs::stat", move |req: Value| { + "shell::fs::stat", + RegisterFunction::new_async(move |req: Value| { let h = h.clone(); let i = i.clone(); - async move { functions::fs_stat::handle(h, i, sb_enabled, req).await } + async move { + functions::fs_stat::handle(h, i, sb_enabled, req) + .await + .map_err(IIIError::from) + } }) .description("Stat a path on host or sandbox"), ); @@ -207,10 +218,15 @@ async fn main() -> Result<()> { let h = host_backend.clone(); let i = iii.clone(); iii.register_function( - RegisterFunction::new_async("shell::fs::mkdir", move |req: Value| { + "shell::fs::mkdir", + RegisterFunction::new_async(move |req: Value| { let h = h.clone(); let i = i.clone(); - async move { functions::fs_mkdir::handle(h, i, sb_enabled, req).await } + async move { + functions::fs_mkdir::handle(h, i, sb_enabled, req) + .await + .map_err(IIIError::from) + } }) .description("Create a directory on host or sandbox"), ); @@ -220,10 +236,15 @@ async fn main() -> Result<()> { let h = host_backend.clone(); let i = iii.clone(); iii.register_function( - RegisterFunction::new_async("shell::fs::rm", move |req: Value| { + "shell::fs::rm", + RegisterFunction::new_async(move |req: Value| { let h = h.clone(); let i = i.clone(); - async move { functions::fs_rm::handle(h, i, sb_enabled, req).await } + async move { + functions::fs_rm::handle(h, i, sb_enabled, req) + .await + .map_err(IIIError::from) + } }) .description("Remove a path on host or sandbox"), ); @@ -233,10 +254,15 @@ async fn main() -> Result<()> { let h = host_backend.clone(); let i = iii.clone(); iii.register_function( - RegisterFunction::new_async("shell::fs::chmod", move |req: Value| { + "shell::fs::chmod", + RegisterFunction::new_async(move |req: Value| { let h = h.clone(); let i = i.clone(); - async move { functions::fs_chmod::handle(h, i, sb_enabled, req).await } + async move { + functions::fs_chmod::handle(h, i, sb_enabled, req) + .await + .map_err(IIIError::from) + } }) .description("Change permissions on host or sandbox"), ); @@ -246,10 +272,15 @@ async fn main() -> Result<()> { let h = host_backend.clone(); let i = iii.clone(); iii.register_function( - RegisterFunction::new_async("shell::fs::mv", move |req: Value| { + "shell::fs::mv", + RegisterFunction::new_async(move |req: Value| { let h = h.clone(); let i = i.clone(); - async move { functions::fs_mv::handle(h, i, sb_enabled, req).await } + async move { + functions::fs_mv::handle(h, i, sb_enabled, req) + .await + .map_err(IIIError::from) + } }) .description("Move/rename a path on host or sandbox"), ); @@ -259,10 +290,15 @@ async fn main() -> Result<()> { let h = host_backend.clone(); let i = iii.clone(); iii.register_function( - RegisterFunction::new_async("shell::fs::grep", move |req: Value| { + "shell::fs::grep", + RegisterFunction::new_async(move |req: Value| { let h = h.clone(); let i = i.clone(); - async move { functions::fs_grep::handle(h, i, sb_enabled, req).await } + async move { + functions::fs_grep::handle(h, i, sb_enabled, req) + .await + .map_err(IIIError::from) + } }) .description("Recursive regex search on host or sandbox"), ); @@ -272,10 +308,15 @@ async fn main() -> Result<()> { let h = host_backend.clone(); let i = iii.clone(); iii.register_function( - RegisterFunction::new_async("shell::fs::sed", move |req: Value| { + "shell::fs::sed", + RegisterFunction::new_async(move |req: Value| { let h = h.clone(); let i = i.clone(); - async move { functions::fs_sed::handle(h, i, sb_enabled, req).await } + async move { + functions::fs_sed::handle(h, i, sb_enabled, req) + .await + .map_err(IIIError::from) + } }) .description("Find-and-replace on host or sandbox"), ); @@ -285,10 +326,15 @@ async fn main() -> Result<()> { let h = host_backend.clone(); let i = iii.clone(); iii.register_function( - RegisterFunction::new_async("shell::fs::write", move |req: Value| { + "shell::fs::write", + RegisterFunction::new_async(move |req: Value| { let h = h.clone(); let i = i.clone(); - async move { functions::fs_write::handle(h, i, sb_enabled, req).await } + async move { + functions::fs_write::handle(h, i, sb_enabled, req) + .await + .map_err(IIIError::from) + } }) .description("Stream a file to a host path or sandbox via StreamChannelRef"), ); @@ -298,10 +344,15 @@ async fn main() -> Result<()> { let h = host_backend.clone(); let i = iii.clone(); iii.register_function( - RegisterFunction::new_async("shell::fs::read", move |req: Value| { + "shell::fs::read", + RegisterFunction::new_async(move |req: Value| { let h = h.clone(); let i = i.clone(); - async move { functions::fs_read::handle(h, i, sb_enabled, req).await } + async move { + functions::fs_read::handle(h, i, sb_enabled, req) + .await + .map_err(IIIError::from) + } }) .description("Stream a file from a host path or sandbox via StreamChannelRef"), ); diff --git a/storage/Cargo.lock b/storage/Cargo.lock index 31c8a40b..65398ac3 100644 --- a/storage/Cargo.lock +++ b/storage/Cargo.lock @@ -1933,21 +1933,19 @@ dependencies = [ ] [[package]] -name = "iii-sdk" -version = "0.13.0-next.1" +name = "iii-observability" +version = "0.16.0-next.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17cf728e12b30b11c37295304e0a5807cf677cca430b66609b7ae3c6044c358d" +checksum = "00ee84dacaf7e14750ebdc229523e52029441c4ae1f72d25972bf1f2e1edeb99" dependencies = [ "async-trait", "futures-util", - "hostname", "opentelemetry", "opentelemetry-http", "opentelemetry-proto", "opentelemetry_sdk", "prost", "reqwest 0.12.28", - "schemars", "serde", "serde_json", "sysinfo", @@ -1958,6 +1956,27 @@ dependencies = [ "uuid", ] +[[package]] +name = "iii-sdk" +version = "0.16.0-next.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53c18b68b2aa09e18c68fb023c78316fe7ccf42181874eab584d66f40119b47e" +dependencies = [ + "async-trait", + "futures-util", + "hostname", + "iii-observability", + "reqwest 0.12.28", + "schemars", + "serde", + "serde_json", + "thiserror 2.0.18", + "tokio", + "tokio-tungstenite", + "tracing", + "uuid", +] + [[package]] name = "indexmap" version = "2.14.0" diff --git a/storage/Cargo.toml b/storage/Cargo.toml index 02cd11bd..9d455b07 100644 --- a/storage/Cargo.toml +++ b/storage/Cargo.toml @@ -14,7 +14,7 @@ path = "src/main.rs" path = "src/lib.rs" [dependencies] -iii-sdk = "=0.13.0-next.1" +iii-sdk = "=0.16.0-next.2" tokio = { version = "1", features = ["rt-multi-thread", "macros", "sync", "signal", "time", "process", "io-util", "net"] } serde = { version = "1", features = ["derive"] } serde_json = "1" diff --git a/storage/src/handlers/mod.rs b/storage/src/handlers/mod.rs index 51df982b..e762548b 100644 --- a/storage/src/handlers/mod.rs +++ b/storage/src/handlers/mod.rs @@ -2,7 +2,7 @@ use crate::backend::Backend; use crate::error::StorageError; -use iii_sdk::{RegisterFunction, III}; +use iii_sdk::{IIIError, RegisterFunction, III}; use std::collections::HashMap; use std::sync::Arc; @@ -51,9 +51,10 @@ pub fn register_all(iii: &III, state: &AppState) { fn register_put_object(iii: &III, state: &AppState) { let st = state.clone(); iii.register_function( - RegisterFunction::new_async("storage::putObject", move |req: put_object::PutReq| { + "storage::putObject", + RegisterFunction::new_async(move |req: put_object::PutReq| { let st = st.clone(); - async move { put_object::handle(&st, req).await } + async move { put_object::handle(&st, req).await.map_err(IIIError::from) } }) .description("Write an object to a configured bucket. Body is base64; max 10MB inline."), ); @@ -62,9 +63,10 @@ fn register_put_object(iii: &III, state: &AppState) { fn register_get_object(iii: &III, state: &AppState) { let st = state.clone(); iii.register_function( - RegisterFunction::new_async("storage::getObject", move |req: get_object::GetReq| { + "storage::getObject", + RegisterFunction::new_async(move |req: get_object::GetReq| { let st = st.clone(); - async move { get_object::handle(&st, req).await } + async move { get_object::handle(&st, req).await.map_err(IIIError::from) } }) .description("Read an object. Body is base64; for large objects use presignUrl."), ); @@ -73,13 +75,15 @@ fn register_get_object(iii: &III, state: &AppState) { fn register_delete_object(iii: &III, state: &AppState) { let st = state.clone(); iii.register_function( - RegisterFunction::new_async( - "storage::deleteObject", - move |req: delete_object::DeleteReq| { - let st = st.clone(); - async move { delete_object::handle(&st, req).await } - }, - ) + "storage::deleteObject", + RegisterFunction::new_async(move |req: delete_object::DeleteReq| { + let st = st.clone(); + async move { + delete_object::handle(&st, req) + .await + .map_err(IIIError::from) + } + }) .description("Delete an object. No-op when the object does not exist."), ); } @@ -87,13 +91,11 @@ fn register_delete_object(iii: &III, state: &AppState) { fn register_presign_url(iii: &III, state: &AppState) { let st = state.clone(); iii.register_function( - RegisterFunction::new_async( - "storage::presignUrl", - move |req: presign_url::PresignReq| { - let st = st.clone(); - async move { presign_url::handle(&st, req).await } - }, - ) + "storage::presignUrl", + RegisterFunction::new_async(move |req: presign_url::PresignReq| { + let st = st.clone(); + async move { presign_url::handle(&st, req).await.map_err(IIIError::from) } + }) .description( "Issue a short-lived URL the browser can hit directly to PUT or GET an object.", ), diff --git a/storage/src/main.rs b/storage/src/main.rs index c2355618..16b0f8ca 100644 --- a/storage/src/main.rs +++ b/storage/src/main.rs @@ -1,6 +1,6 @@ use anyhow::{Context, Result}; use clap::Parser; -use iii_sdk::{register_worker, InitOptions, OtelConfig, RegisterTriggerType, WorkerMetadata}; +use iii_sdk::{register_worker, InitOptions, RegisterTriggerType, WorkerMetadata}; use std::collections::{HashMap, HashSet}; use std::net::SocketAddr; use std::sync::Arc; @@ -162,7 +162,6 @@ async fn main() -> Result<()> { let iii = register_worker( &cli.url, InitOptions { - otel: Some(OtelConfig::default()), metadata: Some(WorkerMetadata { runtime: "rust".to_string(), version: env!("CARGO_PKG_VERSION").to_string(), diff --git a/storage/tests/schemas.rs b/storage/tests/schemas.rs index cc34e32f..03a4410b 100644 --- a/storage/tests/schemas.rs +++ b/storage/tests/schemas.rs @@ -1,61 +1,9 @@ -//! In-process schema regression: every `storage::*` RPC must register through -//! the typed `RegisterFunction::new_async` so the engine receives -//! auto-generated JSON Schema for tools and docs. -//! -//! This file also owns the `mod e2e;` declaration so Cargo compiles the +//! This file owns the `mod e2e;` declaration so Cargo compiles the //! per-provider env-gated e2e tests under `tests/e2e/` as part of one binary. -use iii_sdk::RegisterFunction; -use storage::handlers::{ - delete_object::{DeleteReq, DeleteResp}, - get_object::{GetReq, GetResp}, - presign_url::{PresignReq, PresignResp}, - put_object::{PutReq, PutResp}, -}; - mod e2e; #[test] fn binary_name_matches_manifest() { assert_eq!(storage::worker_name(), "storage"); } - -#[test] -fn registered_functions_carry_request_and_response_schemas() { - fn assert_schemas(id: &str, f: F) - where - T: serde::de::DeserializeOwned + schemars::JsonSchema + Send + 'static, - F: Fn(T) -> Fut + Send + Sync + 'static, - Fut: std::future::Future> + Send + 'static, - R: serde::Serialize + schemars::JsonSchema + Send + 'static, - E: std::fmt::Display + Send + 'static, - { - let reg = RegisterFunction::new_async(id, f); - assert!( - reg.request_format().is_some(), - "{id} missing request_format" - ); - assert!( - reg.response_format().is_some(), - "{id} missing response_format" - ); - } - - async fn _put(_: PutReq) -> Result { - unreachable!() - } - async fn _get(_: GetReq) -> Result { - unreachable!() - } - async fn _del(_: DeleteReq) -> Result { - unreachable!() - } - async fn _pre(_: PresignReq) -> Result { - unreachable!() - } - - assert_schemas("storage::putObject", _put); - assert_schemas("storage::getObject", _get); - assert_schemas("storage::deleteObject", _del); - assert_schemas("storage::presignUrl", _pre); -}