From bd57c44b3f5f7f606927fb5d5def7a8c8e76b7d6 Mon Sep 17 00:00:00 2001 From: Ryan Levick Date: Wed, 25 Oct 2023 19:10:23 +0200 Subject: [PATCH 1/3] No longer depend on Spin unversioned world in 2.0 world Signed-off-by: Ryan Levick --- crates/outbound-mysql/src/lib.rs | 40 ++-- crates/outbound-pg/src/lib.rs | 40 ++-- crates/outbound-redis/src/lib.rs | 17 +- crates/redis/tests/rust/src/lib.rs | 2 +- .../benches/spin-http-benchmark/src/lib.rs | 2 +- .../tests/rust-http-test/src/lib.rs | 2 +- crates/world/src/conversions.rs | 174 ++++++++++++++++++ crates/world/src/lib.rs | 2 + sdk/rust/src/lib.rs | 3 +- sdk/rust/src/llm.rs | 2 +- sdk/rust/src/mysql.rs | 4 +- sdk/rust/src/pg.rs | 4 +- .../config.wit | 0 .../http-types.wit | 0 .../{spin@1.0.0 => spin@unversioned}/http.wit | 0 .../inbound-http.wit | 0 .../inbound-redis.wit | 0 .../key-value.wit | 0 .../{spin@1.0.0 => spin@unversioned}/llm.wit | 0 .../mysql.wit | 0 .../postgres.wit | 0 .../rdbms-types.wit | 0 .../redis-types.wit | 0 .../redis.wit | 0 .../sqlite.wit | 0 .../world.wit | 6 - wit/preview2/llm.wit | 70 +++++++ wit/preview2/mysql.wit | 11 +- wit/preview2/postgres.wit | 11 +- wit/preview2/rdbms-types.wit | 80 ++++++++ wit/preview2/redis-types.wit | 18 ++ wit/preview2/redis.wit | 2 +- wit/preview2/world.wit | 14 +- 33 files changed, 412 insertions(+), 92 deletions(-) create mode 100644 crates/world/src/conversions.rs rename wit/preview2/deps/{spin@1.0.0 => spin@unversioned}/config.wit (100%) rename wit/preview2/deps/{spin@1.0.0 => spin@unversioned}/http-types.wit (100%) rename wit/preview2/deps/{spin@1.0.0 => spin@unversioned}/http.wit (100%) rename wit/preview2/deps/{spin@1.0.0 => spin@unversioned}/inbound-http.wit (100%) rename wit/preview2/deps/{spin@1.0.0 => spin@unversioned}/inbound-redis.wit (100%) rename wit/preview2/deps/{spin@1.0.0 => spin@unversioned}/key-value.wit (100%) rename wit/preview2/deps/{spin@1.0.0 => spin@unversioned}/llm.wit (100%) rename wit/preview2/deps/{spin@1.0.0 => spin@unversioned}/mysql.wit (100%) rename wit/preview2/deps/{spin@1.0.0 => spin@unversioned}/postgres.wit (100%) rename wit/preview2/deps/{spin@1.0.0 => spin@unversioned}/rdbms-types.wit (100%) rename wit/preview2/deps/{spin@1.0.0 => spin@unversioned}/redis-types.wit (100%) rename wit/preview2/deps/{spin@1.0.0 => spin@unversioned}/redis.wit (100%) rename wit/preview2/deps/{spin@1.0.0 => spin@unversioned}/sqlite.wit (100%) rename wit/preview2/deps/{spin@1.0.0 => spin@unversioned}/world.wit (70%) create mode 100644 wit/preview2/llm.wit create mode 100644 wit/preview2/rdbms-types.wit create mode 100644 wit/preview2/redis-types.wit diff --git a/crates/outbound-mysql/src/lib.rs b/crates/outbound-mysql/src/lib.rs index 8c2cd639a..354fd1fff 100644 --- a/crates/outbound-mysql/src/lib.rs +++ b/crates/outbound-mysql/src/lib.rs @@ -3,8 +3,9 @@ use mysql_async::{consts::ColumnType, from_value_opt, prelude::*, Opts, OptsBuil use spin_core::wasmtime::component::Resource; use spin_core::{async_trait, HostComponent}; use spin_world::v1::mysql as v1; -use spin_world::v1::rdbms_types::{Column, DbDataType, DbValue, ParameterValue, RowSet}; use spin_world::v2::mysql::{self as v2, Connection}; +use spin_world::v2::rdbms_types as v2_types; +use spin_world::v2::rdbms_types::{Column, DbDataType, DbValue, ParameterValue}; use std::sync::Arc; use url::Url; @@ -85,7 +86,7 @@ impl v2::HostConnection for OutboundMysql { connection: Resource, statement: String, params: Vec, - ) -> Result> { + ) -> Result> { Ok(async { let db_params = params.into_iter().map(to_sql_parameter).collect::>(); let parameters = mysql_async::Params::Positional(db_params); @@ -108,7 +109,7 @@ impl v2::HostConnection for OutboundMysql { .map(|row| convert_row(row, &columns)) .collect::, _>>()?; - Ok(RowSet { columns, rows }) + Ok(v2_types::RowSet { columns, rows }) } } } @@ -126,11 +127,11 @@ macro_rules! delegate { ($self:ident.$name:ident($address:expr, $($arg:expr),*)) => {{ let connection = match ::open($self, $address).await? { Ok(c) => c, - Err(e) => return Ok(Err(to_legacy_error(e))), + Err(e) => return Ok(Err(e.into())), }; Ok(::$name($self, connection, $($arg),*) .await? - .map_err(|e| to_legacy_error(e))) + .map_err(Into::into)) }}; } @@ -140,28 +141,27 @@ impl v1::Host for OutboundMysql { &mut self, address: String, statement: String, - params: Vec, + params: Vec, ) -> Result> { - delegate!(self.execute(address, statement, params)) + delegate!(self.execute( + address, + statement, + params.into_iter().map(Into::into).collect() + )) } async fn query( &mut self, address: String, statement: String, - params: Vec, - ) -> Result> { - delegate!(self.query(address, statement, params)) - } -} - -fn to_legacy_error(error: v2::Error) -> v1::MysqlError { - match error { - v2::Error::ConnectionFailed(e) => v1::MysqlError::ConnectionFailed(e), - v2::Error::BadParameter(e) => v1::MysqlError::BadParameter(e), - v2::Error::QueryFailed(e) => v1::MysqlError::QueryFailed(e), - v2::Error::ValueConversionFailed(e) => v1::MysqlError::ValueConversionFailed(e), - v2::Error::Other(e) => v1::MysqlError::OtherError(e), + params: Vec, + ) -> Result> { + delegate!(self.query( + address, + statement, + params.into_iter().map(Into::into).collect() + )) + .map(|r| r.map(Into::into)) } } diff --git a/crates/outbound-pg/src/lib.rs b/crates/outbound-pg/src/lib.rs index 980d728e5..3c4ab4f0d 100644 --- a/crates/outbound-pg/src/lib.rs +++ b/crates/outbound-pg/src/lib.rs @@ -2,11 +2,10 @@ use anyhow::{anyhow, Result}; use native_tls::TlsConnector; use postgres_native_tls::MakeTlsConnector; use spin_core::{async_trait, wasmtime::component::Resource, HostComponent}; -use spin_world::v1::{ - postgres as v1, - rdbms_types::{Column, DbDataType, DbValue, ParameterValue, RowSet}, -}; +use spin_world::v1::postgres as v1; +use spin_world::v1::rdbms_types as v1_types; use spin_world::v2::postgres::{self as v2, Connection}; +use spin_world::v2::rdbms_types::{Column, DbDataType, DbValue, ParameterValue, RowSet}; use tokio_postgres::{ config::SslMode, types::{ToSql, Type}, @@ -350,11 +349,11 @@ macro_rules! delegate { ($self:ident.$name:ident($address:expr, $($arg:expr),*)) => {{ let connection = match ::open($self, $address).await? { Ok(c) => c, - Err(e) => return Ok(Err(to_legacy_error(e))), + Err(e) => return Ok(Err(e.into())), }; Ok(::$name($self, connection, $($arg),*) .await? - .map_err(|e| to_legacy_error(e))) + .map_err(|e| e.into())) }}; } @@ -364,27 +363,26 @@ impl v1::Host for OutboundPg { &mut self, address: String, statement: String, - params: Vec, + params: Vec, ) -> Result> { - delegate!(self.execute(address, statement, params)) + delegate!(self.execute( + address, + statement, + params.into_iter().map(Into::into).collect() + )) } async fn query( &mut self, address: String, statement: String, - params: Vec, - ) -> Result> { - delegate!(self.query(address, statement, params)) - } -} - -fn to_legacy_error(error: v2::Error) -> v1::PgError { - match error { - v2::Error::ConnectionFailed(e) => v1::PgError::ConnectionFailed(e), - v2::Error::BadParameter(e) => v1::PgError::BadParameter(e), - v2::Error::QueryFailed(e) => v1::PgError::QueryFailed(e), - v2::Error::ValueConversionFailed(e) => v1::PgError::ValueConversionFailed(e), - v2::Error::Other(e) => v1::PgError::OtherError(e), + params: Vec, + ) -> Result> { + delegate!(self.query( + address, + statement, + params.into_iter().map(Into::into).collect() + )) + .map(|r| r.map(Into::into)) } } diff --git a/crates/outbound-redis/src/lib.rs b/crates/outbound-redis/src/lib.rs index ddfe1bf85..5a02dc8c9 100644 --- a/crates/outbound-redis/src/lib.rs +++ b/crates/outbound-redis/src/lib.rs @@ -4,8 +4,10 @@ use anyhow::Result; use redis::{aio::Connection, AsyncCommands, FromRedisValue, Value}; use spin_core::{async_trait, wasmtime::component::Resource}; use spin_locked_app::MetadataKey; -use spin_world::v1::redis::{self as v1, RedisParameter, RedisResult}; -use spin_world::v2::redis::{self as v2, Connection as RedisConnection, Error}; +use spin_world::v1::redis as v1; +use spin_world::v2::redis::{ + self as v2, Connection as RedisConnection, Error, RedisParameter, RedisResult, +}; pub const ALLOWED_HOSTS_KEY: MetadataKey>> = MetadataKey::new("allowed_outbound_hosts"); @@ -332,9 +334,14 @@ impl v1::Host for OutboundRedis { &mut self, address: String, command: String, - arguments: Vec, - ) -> Result, v1::Error>> { - delegate!(self.execute(address, command, arguments)) + arguments: Vec, + ) -> Result, v1::Error>> { + delegate!(self.execute( + address, + command, + arguments.into_iter().map(Into::into).collect() + )) + .map(|r| r.map(|v| v.into_iter().map(Into::into).collect())) } } diff --git a/crates/redis/tests/rust/src/lib.rs b/crates/redis/tests/rust/src/lib.rs index 15ced0c09..acfb45483 100644 --- a/crates/redis/tests/rust/src/lib.rs +++ b/crates/redis/tests/rust/src/lib.rs @@ -2,7 +2,7 @@ use std::str::{from_utf8, Utf8Error}; wit_bindgen::generate!({ world: "redis-trigger", - path: "../../../../wit/preview2", + path: "../../../../wit/preview2/deps/spin@unversioned", exports: { "fermyon:spin/inbound-redis": SpinRedis, } diff --git a/crates/trigger-http/benches/spin-http-benchmark/src/lib.rs b/crates/trigger-http/benches/spin-http-benchmark/src/lib.rs index 4c37e3d27..feabc06f2 100644 --- a/crates/trigger-http/benches/spin-http-benchmark/src/lib.rs +++ b/crates/trigger-http/benches/spin-http-benchmark/src/lib.rs @@ -1,6 +1,6 @@ wit_bindgen::generate!({ world: "http-trigger", - path: "../../../../wit/preview2", + path: "../../../../wit/preview2/deps/spin@unversioned", exports: { "fermyon:spin/inbound-http": SpinHttp, } diff --git a/crates/trigger-http/tests/rust-http-test/src/lib.rs b/crates/trigger-http/tests/rust-http-test/src/lib.rs index 5d0e21b7e..13e6def21 100644 --- a/crates/trigger-http/tests/rust-http-test/src/lib.rs +++ b/crates/trigger-http/tests/rust-http-test/src/lib.rs @@ -1,6 +1,6 @@ wit_bindgen::generate!({ world: "http-trigger", - path: "../../../../wit/preview2", + path: "../../../../wit/preview2/deps/spin@unversioned", exports: { "fermyon:spin/inbound-http": SpinHttp, } diff --git a/crates/world/src/conversions.rs b/crates/world/src/conversions.rs new file mode 100644 index 000000000..f80cb8087 --- /dev/null +++ b/crates/world/src/conversions.rs @@ -0,0 +1,174 @@ +use super::*; + +mod rdbms_types { + use super::*; + + impl From for v1::rdbms_types::Column { + fn from(value: v2::rdbms_types::Column) -> Self { + v1::rdbms_types::Column { + name: value.name, + data_type: value.data_type.into(), + } + } + } + + impl From for v1::rdbms_types::DbValue { + fn from(value: v2::rdbms_types::DbValue) -> v1::rdbms_types::DbValue { + match value { + v2::rdbms_types::DbValue::Boolean(b) => v1::rdbms_types::DbValue::Boolean(b), + v2::rdbms_types::DbValue::Int8(i) => v1::rdbms_types::DbValue::Int8(i), + v2::rdbms_types::DbValue::Int16(i) => v1::rdbms_types::DbValue::Int16(i), + v2::rdbms_types::DbValue::Int32(i) => v1::rdbms_types::DbValue::Int32(i), + v2::rdbms_types::DbValue::Int64(i) => v1::rdbms_types::DbValue::Int64(i), + v2::rdbms_types::DbValue::Uint8(j) => v1::rdbms_types::DbValue::Uint8(j), + v2::rdbms_types::DbValue::Uint16(u) => v1::rdbms_types::DbValue::Uint16(u), + v2::rdbms_types::DbValue::Uint32(u) => v1::rdbms_types::DbValue::Uint32(u), + v2::rdbms_types::DbValue::Uint64(u) => v1::rdbms_types::DbValue::Uint64(u), + v2::rdbms_types::DbValue::Floating32(r) => v1::rdbms_types::DbValue::Floating32(r), + v2::rdbms_types::DbValue::Floating64(r) => v1::rdbms_types::DbValue::Floating64(r), + v2::rdbms_types::DbValue::Str(s) => v1::rdbms_types::DbValue::Str(s), + v2::rdbms_types::DbValue::Binary(b) => v1::rdbms_types::DbValue::Binary(b), + v2::rdbms_types::DbValue::DbNull => v1::rdbms_types::DbValue::DbNull, + v2::rdbms_types::DbValue::Unsupported => v1::rdbms_types::DbValue::Unsupported, + } + } + } + + impl From for v1::rdbms_types::DbDataType { + fn from(value: v2::rdbms_types::DbDataType) -> v1::rdbms_types::DbDataType { + match value { + v2::rdbms_types::DbDataType::Boolean => v1::rdbms_types::DbDataType::Boolean, + v2::rdbms_types::DbDataType::Int8 => v1::rdbms_types::DbDataType::Int8, + v2::rdbms_types::DbDataType::Int16 => v1::rdbms_types::DbDataType::Int16, + v2::rdbms_types::DbDataType::Int32 => v1::rdbms_types::DbDataType::Int32, + v2::rdbms_types::DbDataType::Int64 => v1::rdbms_types::DbDataType::Int64, + v2::rdbms_types::DbDataType::Uint8 => v1::rdbms_types::DbDataType::Uint8, + v2::rdbms_types::DbDataType::Uint16 => v1::rdbms_types::DbDataType::Uint16, + v2::rdbms_types::DbDataType::Uint32 => v1::rdbms_types::DbDataType::Uint32, + v2::rdbms_types::DbDataType::Uint64 => v1::rdbms_types::DbDataType::Uint64, + v2::rdbms_types::DbDataType::Floating32 => v1::rdbms_types::DbDataType::Floating32, + v2::rdbms_types::DbDataType::Floating64 => v1::rdbms_types::DbDataType::Floating64, + v2::rdbms_types::DbDataType::Str => v1::rdbms_types::DbDataType::Str, + v2::rdbms_types::DbDataType::Binary => v1::rdbms_types::DbDataType::Binary, + v2::rdbms_types::DbDataType::Other => v1::rdbms_types::DbDataType::Other, + } + } + } + + impl From for v2::rdbms_types::ParameterValue { + fn from(value: v1::rdbms_types::ParameterValue) -> v2::rdbms_types::ParameterValue { + match value { + v1::rdbms_types::ParameterValue::Boolean(b) => { + v2::rdbms_types::ParameterValue::Boolean(b) + } + v1::rdbms_types::ParameterValue::Int8(i) => { + v2::rdbms_types::ParameterValue::Int8(i) + } + v1::rdbms_types::ParameterValue::Int16(i) => { + v2::rdbms_types::ParameterValue::Int16(i) + } + v1::rdbms_types::ParameterValue::Int32(i) => { + v2::rdbms_types::ParameterValue::Int32(i) + } + v1::rdbms_types::ParameterValue::Int64(i) => { + v2::rdbms_types::ParameterValue::Int64(i) + } + v1::rdbms_types::ParameterValue::Uint8(u) => { + v2::rdbms_types::ParameterValue::Uint8(u) + } + v1::rdbms_types::ParameterValue::Uint16(u) => { + v2::rdbms_types::ParameterValue::Uint16(u) + } + v1::rdbms_types::ParameterValue::Uint32(u) => { + v2::rdbms_types::ParameterValue::Uint32(u) + } + v1::rdbms_types::ParameterValue::Uint64(u) => { + v2::rdbms_types::ParameterValue::Uint64(u) + } + v1::rdbms_types::ParameterValue::Floating32(r) => { + v2::rdbms_types::ParameterValue::Floating32(r) + } + v1::rdbms_types::ParameterValue::Floating64(r) => { + v2::rdbms_types::ParameterValue::Floating64(r) + } + v1::rdbms_types::ParameterValue::Str(s) => v2::rdbms_types::ParameterValue::Str(s), + v1::rdbms_types::ParameterValue::Binary(b) => { + v2::rdbms_types::ParameterValue::Binary(b) + } + v1::rdbms_types::ParameterValue::DbNull => v2::rdbms_types::ParameterValue::DbNull, + } + } + } + + impl From for v1::mysql::MysqlError { + fn from(error: v2::rdbms_types::Error) -> v1::mysql::MysqlError { + match error { + v2::mysql::Error::ConnectionFailed(e) => v1::mysql::MysqlError::ConnectionFailed(e), + v2::mysql::Error::BadParameter(e) => v1::mysql::MysqlError::BadParameter(e), + v2::mysql::Error::QueryFailed(e) => v1::mysql::MysqlError::QueryFailed(e), + v2::mysql::Error::ValueConversionFailed(e) => { + v1::mysql::MysqlError::ValueConversionFailed(e) + } + v2::mysql::Error::Other(e) => v1::mysql::MysqlError::OtherError(e), + } + } + } + + impl From for v1::postgres::PgError { + fn from(error: v2::rdbms_types::Error) -> v1::postgres::PgError { + match error { + v2::mysql::Error::ConnectionFailed(e) => v1::postgres::PgError::ConnectionFailed(e), + v2::mysql::Error::BadParameter(e) => v1::postgres::PgError::BadParameter(e), + v2::mysql::Error::QueryFailed(e) => v1::postgres::PgError::QueryFailed(e), + v2::mysql::Error::ValueConversionFailed(e) => { + v1::postgres::PgError::ValueConversionFailed(e) + } + v2::mysql::Error::Other(e) => v1::postgres::PgError::OtherError(e), + } + } + } +} + +mod mysql { + use super::*; + impl From for v1::mysql::RowSet { + fn from(value: v2::mysql::RowSet) -> v1::mysql::RowSet { + v1::mysql::RowSet { + columns: value.columns.into_iter().map(Into::into).collect(), + rows: value + .rows + .into_iter() + .map(|r| r.into_iter().map(Into::into).collect()) + .collect(), + } + } + } +} + +mod redis { + use super::*; + + impl From for v2::redis::RedisParameter { + fn from(value: v1::redis::RedisParameter) -> Self { + match value { + v1::redis_types::RedisParameter::Int64(i) => { + v2::redis_types::RedisParameter::Int64(i) + } + v1::redis_types::RedisParameter::Binary(b) => { + v2::redis_types::RedisParameter::Binary(b) + } + } + } + } + + impl From for v1::redis::RedisResult { + fn from(value: v2::redis::RedisResult) -> Self { + match value { + v2::redis_types::RedisResult::Nil => v1::redis_types::RedisResult::Nil, + v2::redis_types::RedisResult::Status(s) => v1::redis_types::RedisResult::Status(s), + v2::redis_types::RedisResult::Int64(i) => v1::redis_types::RedisResult::Int64(i), + v2::redis_types::RedisResult::Binary(b) => v1::redis_types::RedisResult::Binary(b), + } + } + } +} diff --git a/crates/world/src/lib.rs b/crates/world/src/lib.rs index 0ed064d9d..54ede435b 100644 --- a/crates/world/src/lib.rs +++ b/crates/world/src/lib.rs @@ -8,3 +8,5 @@ wasmtime::component::bindgen!({ pub use fermyon::spin as v1; pub use fermyon::spin2_0_0 as v2; + +mod conversions; diff --git a/sdk/rust/src/lib.rs b/sdk/rust/src/lib.rs index bc1e2b287..a14338d43 100644 --- a/sdk/rust/src/lib.rs +++ b/sdk/rust/src/lib.rs @@ -25,7 +25,6 @@ pub mod wit { world: "platform", path: "../../wit/preview2", }); - pub use fermyon::spin as v1; pub use fermyon::spin2_0_0 as v2; } @@ -54,8 +53,8 @@ pub mod http; pub mod redis { use std::hash::{Hash, Hasher}; - pub use super::wit::v1::redis_types::{Payload, RedisParameter, RedisResult}; pub use super::wit::v2::redis::{Connection, Error}; + pub use super::wit::v2::redis_types::{Payload, RedisParameter, RedisResult}; impl PartialEq for RedisResult { fn eq(&self, other: &Self) -> bool { diff --git a/sdk/rust/src/llm.rs b/sdk/rust/src/llm.rs index f53132ec0..adad39ae0 100644 --- a/sdk/rust/src/llm.rs +++ b/sdk/rust/src/llm.rs @@ -1,4 +1,4 @@ -pub use crate::wit::v1::llm::{ +pub use crate::wit::v2::llm::{ self, EmbeddingsResult, EmbeddingsUsage, Error, InferencingParams, InferencingResult, InferencingUsage, }; diff --git a/sdk/rust/src/mysql.rs b/sdk/rust/src/mysql.rs index 2a7ac8d28..104ded4a1 100644 --- a/sdk/rust/src/mysql.rs +++ b/sdk/rust/src/mysql.rs @@ -18,10 +18,10 @@ //! | `String` | str(string) | VARCHAR, CHAR, TEXT | //! | `Vec` | binary(list\) | VARBINARY, BINARY, BLOB | -#[doc(inline)] -pub use super::wit::v1::rdbms_types::*; #[doc(inline)] pub use super::wit::v2::mysql::{Connection, Error as MysqlError}; +#[doc(inline)] +pub use super::wit::v2::rdbms_types::*; /// A MySQL error #[derive(Debug, thiserror::Error)] diff --git a/sdk/rust/src/pg.rs b/sdk/rust/src/pg.rs index d757d0ec5..07e120f9d 100644 --- a/sdk/rust/src/pg.rs +++ b/sdk/rust/src/pg.rs @@ -13,10 +13,10 @@ //! | `String` | str(string) | VARCHAR, CHAR(N), TEXT | //! | `Vec` | binary(list\) | BYTEA | -#[doc(inline)] -pub use super::wit::v1::rdbms_types::*; #[doc(inline)] pub use super::wit::v2::postgres::{Connection, Error as PgError}; +#[doc(inline)] +pub use super::wit::v2::rdbms_types::*; /// A pg error #[derive(Debug, thiserror::Error)] diff --git a/wit/preview2/deps/spin@1.0.0/config.wit b/wit/preview2/deps/spin@unversioned/config.wit similarity index 100% rename from wit/preview2/deps/spin@1.0.0/config.wit rename to wit/preview2/deps/spin@unversioned/config.wit diff --git a/wit/preview2/deps/spin@1.0.0/http-types.wit b/wit/preview2/deps/spin@unversioned/http-types.wit similarity index 100% rename from wit/preview2/deps/spin@1.0.0/http-types.wit rename to wit/preview2/deps/spin@unversioned/http-types.wit diff --git a/wit/preview2/deps/spin@1.0.0/http.wit b/wit/preview2/deps/spin@unversioned/http.wit similarity index 100% rename from wit/preview2/deps/spin@1.0.0/http.wit rename to wit/preview2/deps/spin@unversioned/http.wit diff --git a/wit/preview2/deps/spin@1.0.0/inbound-http.wit b/wit/preview2/deps/spin@unversioned/inbound-http.wit similarity index 100% rename from wit/preview2/deps/spin@1.0.0/inbound-http.wit rename to wit/preview2/deps/spin@unversioned/inbound-http.wit diff --git a/wit/preview2/deps/spin@1.0.0/inbound-redis.wit b/wit/preview2/deps/spin@unversioned/inbound-redis.wit similarity index 100% rename from wit/preview2/deps/spin@1.0.0/inbound-redis.wit rename to wit/preview2/deps/spin@unversioned/inbound-redis.wit diff --git a/wit/preview2/deps/spin@1.0.0/key-value.wit b/wit/preview2/deps/spin@unversioned/key-value.wit similarity index 100% rename from wit/preview2/deps/spin@1.0.0/key-value.wit rename to wit/preview2/deps/spin@unversioned/key-value.wit diff --git a/wit/preview2/deps/spin@1.0.0/llm.wit b/wit/preview2/deps/spin@unversioned/llm.wit similarity index 100% rename from wit/preview2/deps/spin@1.0.0/llm.wit rename to wit/preview2/deps/spin@unversioned/llm.wit diff --git a/wit/preview2/deps/spin@1.0.0/mysql.wit b/wit/preview2/deps/spin@unversioned/mysql.wit similarity index 100% rename from wit/preview2/deps/spin@1.0.0/mysql.wit rename to wit/preview2/deps/spin@unversioned/mysql.wit diff --git a/wit/preview2/deps/spin@1.0.0/postgres.wit b/wit/preview2/deps/spin@unversioned/postgres.wit similarity index 100% rename from wit/preview2/deps/spin@1.0.0/postgres.wit rename to wit/preview2/deps/spin@unversioned/postgres.wit diff --git a/wit/preview2/deps/spin@1.0.0/rdbms-types.wit b/wit/preview2/deps/spin@unversioned/rdbms-types.wit similarity index 100% rename from wit/preview2/deps/spin@1.0.0/rdbms-types.wit rename to wit/preview2/deps/spin@unversioned/rdbms-types.wit diff --git a/wit/preview2/deps/spin@1.0.0/redis-types.wit b/wit/preview2/deps/spin@unversioned/redis-types.wit similarity index 100% rename from wit/preview2/deps/spin@1.0.0/redis-types.wit rename to wit/preview2/deps/spin@unversioned/redis-types.wit diff --git a/wit/preview2/deps/spin@1.0.0/redis.wit b/wit/preview2/deps/spin@unversioned/redis.wit similarity index 100% rename from wit/preview2/deps/spin@1.0.0/redis.wit rename to wit/preview2/deps/spin@unversioned/redis.wit diff --git a/wit/preview2/deps/spin@1.0.0/sqlite.wit b/wit/preview2/deps/spin@unversioned/sqlite.wit similarity index 100% rename from wit/preview2/deps/spin@1.0.0/sqlite.wit rename to wit/preview2/deps/spin@unversioned/sqlite.wit diff --git a/wit/preview2/deps/spin@1.0.0/world.wit b/wit/preview2/deps/spin@unversioned/world.wit similarity index 70% rename from wit/preview2/deps/spin@1.0.0/world.wit rename to wit/preview2/deps/spin@unversioned/world.wit index 46ed53a68..e881baf8a 100644 --- a/wit/preview2/deps/spin@1.0.0/world.wit +++ b/wit/preview2/deps/spin@unversioned/world.wit @@ -17,12 +17,6 @@ world http-trigger { export inbound-http } -world wasi-http-trigger { - include platform - import wasi:http/outgoing-handler@0.2.0-rc-2023-10-18 - export wasi:http/incoming-handler@0.2.0-rc-2023-10-18 -} - world platform { import config import http diff --git a/wit/preview2/llm.wit b/wit/preview2/llm.wit new file mode 100644 index 000000000..2b1533c34 --- /dev/null +++ b/wit/preview2/llm.wit @@ -0,0 +1,70 @@ +// A WASI interface dedicated to performing inferencing for Large Language Models. +interface llm { + /// A Large Language Model. + type inferencing-model = string + + /// Inference request parameters + record inferencing-params { + /// The maximum tokens that should be inferred. + /// + /// Note: the backing implementation may return less tokens. + max-tokens: u32, + /// The amount the model should avoid repeating tokens. + repeat-penalty: float32, + /// The number of tokens the model should apply the repeat penalty to. + repeat-penalty-last-n-token-count: u32, + /// The randomness with which the next token is selected. + temperature: float32, + /// The number of possible next tokens the model will choose from. + top-k: u32, + /// The probability total of next tokens the model will choose from. + top-p: float32 + } + + /// The set of errors which may be raised by functions in this interface + variant error { + model-not-supported, + runtime-error(string), + invalid-input(string) + } + + /// An inferencing result + record inferencing-result { + /// The text generated by the model + // TODO: this should be a stream + text: string, + /// Usage information about the inferencing request + usage: inferencing-usage + } + + /// Usage information related to the inferencing result + record inferencing-usage { + /// Number of tokens in the prompt + prompt-token-count: u32, + /// Number of tokens generated by the inferencing operation + generated-token-count: u32 + } + + /// Perform inferencing using the provided model and prompt with the given optional params + infer: func(model: inferencing-model, prompt: string, params: option) -> result + + /// The model used for generating embeddings + type embedding-model = string + + /// Generate embeddings for the supplied list of text + generate-embeddings: func(model: embedding-model, text: list) -> result + + /// Result of generating embeddings + record embeddings-result { + /// The embeddings generated by the request + embeddings: list>, + /// Usage related to the embeddings generation request + usage: embeddings-usage + } + + /// Usage related to an embeddings generation request + record embeddings-usage { + /// Number of tokens in the prompt + prompt-token-count: u32, + } +} diff --git a/wit/preview2/mysql.wit b/wit/preview2/mysql.wit index afc436057..2315485fd 100644 --- a/wit/preview2/mysql.wit +++ b/wit/preview2/mysql.wit @@ -1,14 +1,5 @@ interface mysql { - use fermyon:spin/rdbms-types.{parameter-value, row-set} - - /// Errors related to interacting with MySQL. - variant error { - connection-failed(string), - bad-parameter(string), - query-failed(string), - value-conversion-failed(string), - other(string) - } + use rdbms-types.{parameter-value, row-set, error} /// A connection to a MySQL database. resource connection { diff --git a/wit/preview2/postgres.wit b/wit/preview2/postgres.wit index 97bc78285..3cd53bcb7 100644 --- a/wit/preview2/postgres.wit +++ b/wit/preview2/postgres.wit @@ -1,14 +1,5 @@ interface postgres { - use fermyon:spin/rdbms-types.{parameter-value, row-set} - - /// Errors related to interacting with Postgres. - variant error { - connection-failed(string), - bad-parameter(string), - query-failed(string), - value-conversion-failed(string), - other(string) - } + use rdbms-types.{parameter-value, row-set, error} /// A connection to a postgres database. resource connection { diff --git a/wit/preview2/rdbms-types.wit b/wit/preview2/rdbms-types.wit new file mode 100644 index 000000000..0946ccc6e --- /dev/null +++ b/wit/preview2/rdbms-types.wit @@ -0,0 +1,80 @@ +interface rdbms-types { + /// Errors related to interacting with a database. + variant error { + connection-failed(string), + bad-parameter(string), + query-failed(string), + value-conversion-failed(string), + other(string) + } + + /// Data types for a database column + enum db-data-type { + boolean, + int8, + int16, + int32, + int64, + uint8, + uint16, + uint32, + uint64, + floating32, + floating64, + str, + binary, + other, + } + + /// Database values + variant db-value { + boolean(bool), + int8(s8), + int16(s16), + int32(s32), + int64(s64), + uint8(u8), + uint16(u16), + uint32(u32), + uint64(u64), + floating32(float32), + floating64(float64), + str(string), + binary(list), + db-null, + unsupported, + } + + /// Values used in parameterized queries + variant parameter-value { + boolean(bool), + int8(s8), + int16(s16), + int32(s32), + int64(s64), + uint8(u8), + uint16(u16), + uint32(u32), + uint64(u64), + floating32(float32), + floating64(float64), + str(string), + binary(list), + db-null, + } + + /// A database column + record column { + name: string, + data-type: db-data-type, + } + + /// A database row + type row = list + + /// A set of database rows + record row-set { + columns: list, + rows: list, + } +} diff --git a/wit/preview2/redis-types.wit b/wit/preview2/redis-types.wit new file mode 100644 index 000000000..37b998991 --- /dev/null +++ b/wit/preview2/redis-types.wit @@ -0,0 +1,18 @@ +interface redis-types { + /// The message payload. + type payload = list + + /// A parameter type for the general-purpose `execute` function. + variant redis-parameter { + int64(s64), + binary(payload) + } + + /// A return type for the general-purpose `execute` function. + variant redis-result { + nil, + status(string), + int64(s64), + binary(payload) + } +} diff --git a/wit/preview2/redis.wit b/wit/preview2/redis.wit index f5c4c05fb..c7166ee15 100644 --- a/wit/preview2/redis.wit +++ b/wit/preview2/redis.wit @@ -1,5 +1,5 @@ interface redis { - use fermyon:spin/redis-types.{payload, redis-parameter, redis-result} + use redis-types.{payload, redis-parameter, redis-result} /// Errors related to interacting with Redis variant error { diff --git a/wit/preview2/world.wit b/wit/preview2/world.wit index 6c90cbf8e..6a3754736 100644 --- a/wit/preview2/world.wit +++ b/wit/preview2/world.wit @@ -1,25 +1,21 @@ package fermyon:spin@2.0.0 +// All worlds the Spin host supports world host { include fermyon:spin/host include platform } -world redis-trigger { - include platform - export fermyon:spin/inbound-redis -} - +// The full world of a guest targeting an http-trigger world http-trigger { include platform - export fermyon:spin/inbound-http + export wasi:http/outgoing-handler@0.2.0-rc-2023-10-18 } +// The imports needed for a guest to run on a Spin host world platform { - import fermyon:spin/http - import fermyon:spin/llm import wasi:http/outgoing-handler@0.2.0-rc-2023-10-18 - + import llm import redis import postgres import mysql From df2330636433482901e542674baa46b556a79298 Mon Sep 17 00:00:00 2001 From: Ryan Levick Date: Thu, 26 Oct 2023 11:28:20 +0200 Subject: [PATCH 2/3] Move redis-types to redis interface Signed-off-by: Ryan Levick --- crates/world/src/conversions.rs | 16 ++++++---------- sdk/rust/src/lib.rs | 3 +-- wit/preview2/redis-types.wit | 18 ------------------ wit/preview2/redis.wit | 19 +++++++++++++++++-- 4 files changed, 24 insertions(+), 32 deletions(-) delete mode 100644 wit/preview2/redis-types.wit diff --git a/crates/world/src/conversions.rs b/crates/world/src/conversions.rs index f80cb8087..f2b068b14 100644 --- a/crates/world/src/conversions.rs +++ b/crates/world/src/conversions.rs @@ -151,12 +151,8 @@ mod redis { impl From for v2::redis::RedisParameter { fn from(value: v1::redis::RedisParameter) -> Self { match value { - v1::redis_types::RedisParameter::Int64(i) => { - v2::redis_types::RedisParameter::Int64(i) - } - v1::redis_types::RedisParameter::Binary(b) => { - v2::redis_types::RedisParameter::Binary(b) - } + v1::redis::RedisParameter::Int64(i) => v2::redis::RedisParameter::Int64(i), + v1::redis::RedisParameter::Binary(b) => v2::redis::RedisParameter::Binary(b), } } } @@ -164,10 +160,10 @@ mod redis { impl From for v1::redis::RedisResult { fn from(value: v2::redis::RedisResult) -> Self { match value { - v2::redis_types::RedisResult::Nil => v1::redis_types::RedisResult::Nil, - v2::redis_types::RedisResult::Status(s) => v1::redis_types::RedisResult::Status(s), - v2::redis_types::RedisResult::Int64(i) => v1::redis_types::RedisResult::Int64(i), - v2::redis_types::RedisResult::Binary(b) => v1::redis_types::RedisResult::Binary(b), + v2::redis::RedisResult::Nil => v1::redis::RedisResult::Nil, + v2::redis::RedisResult::Status(s) => v1::redis::RedisResult::Status(s), + v2::redis::RedisResult::Int64(i) => v1::redis::RedisResult::Int64(i), + v2::redis::RedisResult::Binary(b) => v1::redis::RedisResult::Binary(b), } } } diff --git a/sdk/rust/src/lib.rs b/sdk/rust/src/lib.rs index a14338d43..af607aacb 100644 --- a/sdk/rust/src/lib.rs +++ b/sdk/rust/src/lib.rs @@ -53,8 +53,7 @@ pub mod http; pub mod redis { use std::hash::{Hash, Hasher}; - pub use super::wit::v2::redis::{Connection, Error}; - pub use super::wit::v2::redis_types::{Payload, RedisParameter, RedisResult}; + pub use super::wit::v2::redis::{Connection, Error, Payload, RedisParameter, RedisResult}; impl PartialEq for RedisResult { fn eq(&self, other: &Self) -> bool { diff --git a/wit/preview2/redis-types.wit b/wit/preview2/redis-types.wit deleted file mode 100644 index 37b998991..000000000 --- a/wit/preview2/redis-types.wit +++ /dev/null @@ -1,18 +0,0 @@ -interface redis-types { - /// The message payload. - type payload = list - - /// A parameter type for the general-purpose `execute` function. - variant redis-parameter { - int64(s64), - binary(payload) - } - - /// A return type for the general-purpose `execute` function. - variant redis-result { - nil, - status(string), - int64(s64), - binary(payload) - } -} diff --git a/wit/preview2/redis.wit b/wit/preview2/redis.wit index c7166ee15..8d8104a40 100644 --- a/wit/preview2/redis.wit +++ b/wit/preview2/redis.wit @@ -1,6 +1,4 @@ interface redis { - use redis-types.{payload, redis-parameter, redis-result} - /// Errors related to interacting with Redis variant error { /// An invalid address string @@ -52,4 +50,21 @@ interface redis { /// Execute an arbitrary Redis command and receive the result. execute: func(command: string, arguments: list) -> result, error> } + + /// The message payload. + type payload = list + + /// A parameter type for the general-purpose `execute` function. + variant redis-parameter { + int64(s64), + binary(payload) + } + + /// A return type for the general-purpose `execute` function. + variant redis-result { + nil, + status(string), + int64(s64), + binary(payload) + } } From 0873a644c0a5ecd037edc28524f6514126a8a9e6 Mon Sep 17 00:00:00 2001 From: Ryan Levick Date: Thu, 26 Oct 2023 18:51:41 +0200 Subject: [PATCH 3/3] Fix typos Signed-off-by: Ryan Levick --- wit/preview2/world.wit | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/wit/preview2/world.wit b/wit/preview2/world.wit index 6a3754736..852e629aa 100644 --- a/wit/preview2/world.wit +++ b/wit/preview2/world.wit @@ -1,18 +1,18 @@ package fermyon:spin@2.0.0 -// All worlds the Spin host supports +/// All worlds the Spin host supports world host { include fermyon:spin/host include platform } -// The full world of a guest targeting an http-trigger +/// The full world of a guest targeting an http-trigger world http-trigger { include platform - export wasi:http/outgoing-handler@0.2.0-rc-2023-10-18 + export wasi:http/incoming-handler@0.2.0-rc-2023-10-18 } -// The imports needed for a guest to run on a Spin host +/// The imports needed for a guest to run on a Spin host world platform { import wasi:http/outgoing-handler@0.2.0-rc-2023-10-18 import llm