Compare commits

..

2 commits

Author SHA1 Message Date
6eaad79f9a
Run fmt 2025-02-20 02:13:21 +01:00
c545161878
Add DARM stack test 2025-02-20 02:13:05 +01:00
40 changed files with 2459 additions and 98 deletions

2
.npmrc Normal file
View file

@ -0,0 +1,2 @@
audit=false
fund=false

229
Cargo.lock generated
View file

@ -33,6 +33,12 @@ version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627"
[[package]]
name = "adler32"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234"
[[package]] [[package]]
name = "ahash" name = "ahash"
version = "0.7.8" version = "0.7.8"
@ -296,8 +302,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "edca88bc138befd0323b20752846e6587272d3b03b0343c8ea28a6f819e6e71f" checksum = "edca88bc138befd0323b20752846e6587272d3b03b0343c8ea28a6f819e6e71f"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"axum-core", "axum-core 0.4.5",
"axum-macros", "axum-macros 0.4.2",
"bytes", "bytes",
"futures-util", "futures-util",
"http 1.2.0", "http 1.2.0",
@ -306,7 +312,7 @@ dependencies = [
"hyper", "hyper",
"hyper-util", "hyper-util",
"itoa 1.0.14", "itoa 1.0.14",
"matchit", "matchit 0.7.3",
"memchr", "memchr",
"mime", "mime",
"multer", "multer",
@ -325,6 +331,40 @@ dependencies = [
"tracing", "tracing",
] ]
[[package]]
name = "axum"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d6fd624c75e18b3b4c6b9caf42b1afe24437daaee904069137d8bab077be8b8"
dependencies = [
"axum-core 0.5.0",
"bytes",
"form_urlencoded",
"futures-util",
"http 1.2.0",
"http-body",
"http-body-util",
"hyper",
"hyper-util",
"itoa 1.0.14",
"matchit 0.8.4",
"memchr",
"mime",
"percent-encoding",
"pin-project-lite",
"rustversion",
"serde",
"serde_json",
"serde_path_to_error",
"serde_urlencoded",
"sync_wrapper",
"tokio",
"tower 0.5.2",
"tower-layer",
"tower-service",
"tracing",
]
[[package]] [[package]]
name = "axum-core" name = "axum-core"
version = "0.4.5" version = "0.4.5"
@ -346,6 +386,26 @@ dependencies = [
"tracing", "tracing",
] ]
[[package]]
name = "axum-core"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df1362f362fd16024ae199c1970ce98f9661bf5ef94b9808fee734bc3698b733"
dependencies = [
"bytes",
"futures-util",
"http 1.2.0",
"http-body",
"http-body-util",
"mime",
"pin-project-lite",
"rustversion",
"sync_wrapper",
"tower-layer",
"tower-service",
"tracing",
]
[[package]] [[package]]
name = "axum-macros" name = "axum-macros"
version = "0.4.2" version = "0.4.2"
@ -357,6 +417,37 @@ dependencies = [
"syn 2.0.98", "syn 2.0.98",
] ]
[[package]]
name = "axum-macros"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "604fde5e028fea851ce1d8570bbdc034bec850d157f7569d10f347d06808c05c"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.98",
]
[[package]]
name = "axum-typed-routing"
version = "0.2.0"
source = "git+https://github.com/jvdwrf/axum-typed-routing#160684a406d616974d851bbfc6d0d9ffa65367e5"
dependencies = [
"axum 0.8.1",
"axum-macros 0.5.0",
"axum-typed-routing-macros",
]
[[package]]
name = "axum-typed-routing-macros"
version = "0.2.0"
source = "git+https://github.com/jvdwrf/axum-typed-routing#160684a406d616974d851bbfc6d0d9ffa65367e5"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.98",
]
[[package]] [[package]]
name = "backtrace" name = "backtrace"
version = "0.3.74" version = "0.3.74"
@ -884,6 +975,15 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "core2"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b49ba7ef1ad6107f8824dbe97de947cbaac53c44e7f9756a1fba0d37c1eec505"
dependencies = [
"memchr",
]
[[package]] [[package]]
name = "cpufeatures" name = "cpufeatures"
version = "0.2.17" version = "0.2.17"
@ -1092,6 +1192,28 @@ dependencies = [
"syn 1.0.109", "syn 1.0.109",
] ]
[[package]]
name = "darm_test"
version = "0.1.1"
dependencies = [
"axum 0.8.1",
"axum-typed-routing",
"datastar",
"maud",
"mime_guess",
"rust-embed",
"serde",
"tokio",
"tracing",
"tracing-subscriber",
]
[[package]]
name = "dary_heap"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04d2cd9c18b9f454ed67da600630b021a8a80bf33f8c95896ab33aaf1c26b728"
[[package]] [[package]]
name = "dashmap" name = "dashmap"
version = "5.5.3" version = "5.5.3"
@ -1106,6 +1228,14 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "datastar"
version = "0.1.0"
source = "git+https://github.com/starfederation/datastar.git#3bc1f2801963ffbfed5a1a5bc98cc8e29574f623"
dependencies = [
"futures-util",
]
[[package]] [[package]]
name = "der" name = "der"
version = "0.7.9" version = "0.7.9"
@ -2497,6 +2627,29 @@ dependencies = [
"icu_properties", "icu_properties",
] ]
[[package]]
name = "include-flate"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df49c16750695486c1f34de05da5b7438096156466e7f76c38fcdf285cf0113e"
dependencies = [
"include-flate-codegen",
"lazy_static",
"libflate",
]
[[package]]
name = "include-flate-codegen"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c5b246c6261be723b85c61ecf87804e8ea4a35cb68be0ff282ed84b95ffe7d7"
dependencies = [
"libflate",
"proc-macro2",
"quote",
"syn 2.0.98",
]
[[package]] [[package]]
name = "indexmap" name = "indexmap"
version = "1.9.3" version = "1.9.3"
@ -2700,7 +2853,7 @@ version = "0.6.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "910681b920c48a43508b2bd0261bdb67c4ef9456a0b3613f956a0d30e832e9de" checksum = "910681b920c48a43508b2bd0261bdb67c4ef9456a0b3613f956a0d30e832e9de"
dependencies = [ dependencies = [
"axum", "axum 0.7.9",
"cfg-if", "cfg-if",
"futures", "futures",
"http-body-util", "http-body-util",
@ -2912,6 +3065,30 @@ version = "0.2.169"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a"
[[package]]
name = "libflate"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "45d9dfdc14ea4ef0900c1cddbc8dcd553fbaacd8a4a282cf4018ae9dd04fb21e"
dependencies = [
"adler32",
"core2",
"crc32fast",
"dary_heap",
"libflate_lz77",
]
[[package]]
name = "libflate_lz77"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6e0d73b369f386f1c44abd9c570d5318f55ccde816ff4b562fa452e5182863d"
dependencies = [
"core2",
"hashbrown 0.14.5",
"rle-decode-fast",
]
[[package]] [[package]]
name = "libloading" name = "libloading"
version = "0.5.2" version = "0.5.2"
@ -2995,7 +3172,7 @@ dependencies = [
"anyhow", "anyhow",
"async-broadcast", "async-broadcast",
"async-trait", "async-trait",
"axum", "axum 0.7.9",
"bytes", "bytes",
"cfg-if", "cfg-if",
"chrono", "chrono",
@ -3053,7 +3230,7 @@ name = "llama_proxy_man"
version = "0.1.1" version = "0.1.1"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"axum", "axum 0.7.9",
"derive_more 2.0.1", "derive_more 2.0.1",
"figment", "figment",
"futures", "futures",
@ -3173,6 +3350,36 @@ version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94"
[[package]]
name = "matchit"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3"
[[package]]
name = "maud"
version = "0.27.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8156733e27020ea5c684db5beac5d1d611e1272ab17901a49466294b84fc217e"
dependencies = [
"axum-core 0.5.0",
"http 1.2.0",
"itoa 1.0.14",
"maud_macros",
]
[[package]]
name = "maud_macros"
version = "0.27.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7261b00f3952f617899bc012e3dbd56e4f0110a038175929fa5d18e5a19913ca"
dependencies = [
"proc-macro2",
"proc-macro2-diagnostics",
"quote",
"syn 2.0.98",
]
[[package]] [[package]]
name = "md-5" name = "md-5"
version = "0.10.6" version = "0.10.6"
@ -4606,6 +4813,12 @@ dependencies = [
"syn 1.0.109", "syn 1.0.109",
] ]
[[package]]
name = "rle-decode-fast"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3582f63211428f83597b51b2ddb88e2a91a9d52d12831f9d08f5e624e8977422"
[[package]] [[package]]
name = "rsa" name = "rsa"
version = "0.9.7" version = "0.9.7"
@ -4646,6 +4859,8 @@ version = "8.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa66af4a4fdd5e7ebc276f115e895611a34739a9c1c01028383d612d550953c0" checksum = "fa66af4a4fdd5e7ebc276f115e895611a34739a9c1c01028383d612d550953c0"
dependencies = [ dependencies = [
"axum 0.7.9",
"include-flate",
"rust-embed-impl", "rust-embed-impl",
"rust-embed-utils", "rust-embed-utils",
"walkdir", "walkdir",
@ -5030,7 +5245,7 @@ version = "0.6.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fae7a3038a32e5a34ba32c6c45eb4852f8affaf8b794ebfcd4b1099e2d62ebe" checksum = "4fae7a3038a32e5a34ba32c6c45eb4852f8affaf8b794ebfcd4b1099e2d62ebe"
dependencies = [ dependencies = [
"axum", "axum 0.7.9",
"bytes", "bytes",
"ciborium", "ciborium",
"const_format", "const_format",

View file

@ -20,7 +20,7 @@ lto = "fat"
panic = "abort" panic = "abort"
[workspace] [workspace]
members = ["llama_forge_rs", "llama_proxy_man", "redvault_el_rs"] members = ["darm_test", "llama_forge_rs", "llama_proxy_man", "redvault_el_rs"]
resolver = "2" resolver = "2"
[workspace.package] [workspace.package]
@ -29,7 +29,7 @@ description = "The redvault AI monorepo"
license = "AGPL-3.0-or-later" license = "AGPL-3.0-or-later"
publish = false publish = false
readme = "README.md" readme = "README.md"
repository = "https://git.vlt81.de/oekonzept/oeko-mono" repository = "https://git.vlt81.de/vault81/redvault-ai"
version = "0.1.1" version = "0.1.1"
edition = "2021" edition = "2021"

View file

@ -75,10 +75,12 @@ dependencies = ["mksitedir", "make-docset", "cp-docset"]
[tasks.make-docset] [tasks.make-docset]
workspace = false workspace = false
dependencies = ["mksitedir"]
script = "cargo docset --workspace --no-clean --platform-family redvault-ai && sleep 1 && sync" script = "cargo docset --workspace --no-clean --platform-family redvault-ai && sleep 1 && sync"
[tasks.cp-docset] [tasks.cp-docset]
workspace = false workspace = false
dependencies = ["make-docset"]
script = "cp -r target/docset/redvault-ai.docset ~/.local/share/Zeal/Zeal/docsets/" script = "cp -r target/docset/redvault-ai.docset ~/.local/share/Zeal/Zeal/docsets/"
[tasks.watch-test] [tasks.watch-test]

22
darm_test/Cargo.toml Normal file
View file

@ -0,0 +1,22 @@
[package]
name = "darm_test"
authors.workspace = true
description.workspace = true
license.workspace = true
publish.workspace = true
readme.workspace = true
repository.workspace = true
version.workspace = true
edition.workspace = true
[dependencies]
axum = { version = "0.8", features = ["http2"] }
axum-typed-routing = { git = "https://github.com/jvdwrf/axum-typed-routing", version = "0.2.0" }
datastar = { git = "https://github.com/starfederation/datastar.git", version = "0.1.0" }
maud = { version = "0.27.0", features = ["axum"] }
mime_guess = "2.0.5"
rust-embed = { version = "8.5.0", features = ["axum", "compression"] }
serde = { version = "1.0", features = ["derive"] }
tokio = { version = "1.43", features = ["full", "tracing"] }
tracing = "0.1.41"
tracing-subscriber = { version = "0.3.19", features = ["env-filter"] }

30
darm_test/TODO.org Normal file
View file

@ -0,0 +1,30 @@
* Todos
** Starter boilerplate
*** [X] Server: Axum
**** [X] Typed routes via macro
**** [X] Nested Router
**** [X] Fallbacks
*** [X] "embd tmpl": Maud
*** [ ] "html tmpl": minijinja
- only index yaml for now, test in app wether inline or external templates feel better
*** [ ] CSS Basic
- UnoCSS
- daisyUI?
*** [ ] UI framework
- data* js basic
- data* axum sdk
*** [ ] Asset bundle testing
*** [ ] DB
- SqlX/SurrealDB?
** Basic streaming chat
- build with inline html via maud
*** Stream same token in loop
*** ???
*** Finish
** Basic Proxy Settings
- build with jinja templates
** Markdown streaming chat
*** Moar Feats
**** Tauri webview/wry?
**** Jinja tmplts for models ??
**** Proxy integration ?

1
darm_test/public/datastar.min.js vendored Symbolic link
View file

@ -0,0 +1 @@
css/datastar-1-0-0-beta-7.js

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

1
darm_test/public/js/datastar.min.js vendored Symbolic link
View file

@ -0,0 +1 @@
datastar-1-0-0-beta-7.js

1
darm_test/public/styles.min.css vendored Normal file
View file

@ -0,0 +1 @@
*,::before,::after{--un-rotate:0;--un-rotate-x:0;--un-rotate-y:0;--un-rotate-z:0;--un-scale-x:1;--un-scale-y:1;--un-scale-z:1;--un-skew-x:0;--un-skew-y:0;--un-translate-x:0;--un-translate-y:0;--un-translate-z:0;--un-pan-x: ;--un-pan-y: ;--un-pinch-zoom: ;--un-scroll-snap-strictness:proximity;--un-ordinal: ;--un-slashed-zero: ;--un-numeric-figure: ;--un-numeric-spacing: ;--un-numeric-fraction: ;--un-border-spacing-x:0;--un-border-spacing-y:0;--un-ring-offset-shadow:0 0 rgba(0,0,0,0);--un-ring-shadow:0 0 rgba(0,0,0,0);--un-shadow-inset: ;--un-shadow:0 0 rgba(0,0,0,0);--un-ring-inset: ;--un-ring-offset-width:0px;--un-ring-offset-color:#fff;--un-ring-width:0px;--un-ring-color:rgba(147,197,253,0.5);--un-blur: ;--un-brightness: ;--un-contrast: ;--un-drop-shadow: ;--un-grayscale: ;--un-hue-rotate: ;--un-invert: ;--un-saturate: ;--un-sepia: ;--un-backdrop-blur: ;--un-backdrop-brightness: ;--un-backdrop-contrast: ;--un-backdrop-grayscale: ;--un-backdrop-hue-rotate: ;--un-backdrop-invert: ;--un-backdrop-opacity: ;--un-backdrop-saturate: ;--un-backdrop-sepia: }::backdrop{--un-rotate:0;--un-rotate-x:0;--un-rotate-y:0;--un-rotate-z:0;--un-scale-x:1;--un-scale-y:1;--un-scale-z:1;--un-skew-x:0;--un-skew-y:0;--un-translate-x:0;--un-translate-y:0;--un-translate-z:0;--un-pan-x: ;--un-pan-y: ;--un-pinch-zoom: ;--un-scroll-snap-strictness:proximity;--un-ordinal: ;--un-slashed-zero: ;--un-numeric-figure: ;--un-numeric-spacing: ;--un-numeric-fraction: ;--un-border-spacing-x:0;--un-border-spacing-y:0;--un-ring-offset-shadow:0 0 rgba(0,0,0,0);--un-ring-shadow:0 0 rgba(0,0,0,0);--un-shadow-inset: ;--un-shadow:0 0 rgba(0,0,0,0);--un-ring-inset: ;--un-ring-offset-width:0px;--un-ring-offset-color:#fff;--un-ring-width:0px;--un-ring-color:rgba(147,197,253,0.5);--un-blur: ;--un-brightness: ;--un-contrast: ;--un-drop-shadow: ;--un-grayscale: ;--un-hue-rotate: ;--un-invert: ;--un-saturate: ;--un-sepia: ;--un-backdrop-blur: ;--un-backdrop-brightness: ;--un-backdrop-contrast: ;--un-backdrop-grayscale: ;--un-backdrop-hue-rotate: ;--un-backdrop-invert: ;--un-backdrop-opacity: ;--un-backdrop-saturate: ;--un-backdrop-sepia: }.static{position:static}.m-1,.m1,[m-1=""],m1{margin:.25rem}.ms,[ms=""]{margin-inline-start:1rem}contents{display:contents}.h1{height:.25rem}.b,[b=""]{border-width:1px}[pe=""]{padding-inline-end:1rem}

View file

@ -0,0 +1 @@
<h1> Test </h1>

132
darm_test/src/main.rs Normal file
View file

@ -0,0 +1,132 @@
use std::sync::Once;
use axum::{
body::Body,
extract::State,
http::{header, Response, StatusCode, Uri},
response::IntoResponse,
routing::get,
};
use axum_typed_routing::{route, TypedRouter};
use maud::{html, Markup};
use rust_embed::RustEmbed;
#[route(GET "/hello")]
async fn hello_world(State(_): State<String>) -> Markup {
html! {
h1 { "Hello, World!" }
}
}
#[allow(unused)]
#[route(GET "/item/:id?amount&offset")]
async fn item_handler(
id: u32,
amount: Option<u32>,
offset: Option<u32>,
State(state): State<String>,
// Json(json): Json<u32>,
) -> Markup {
// todo!("handle request")
html! {
h1 { "Item" }
p {
(format!("{id:?} {amount:?} {offset:?} {state:?}"))
}
}
}
// We use a wildcard matcher ("/dist/*file") to match against everything
// within our defined assets directory. This is the directory on our Asset
// struct below, where folder = "examples/public/".
#[route(GET "/dist/*path")]
async fn static_handler(path: String, _: State<String>) -> impl IntoResponse {
let path = path.trim_start_matches('/').to_string();
StaticFile(path)
}
fn markup_404(uri: String) -> Markup {
html! {
h1 { "404" }
p { (format!("{uri:?} Not Found")) }
}
}
fn markup_405() -> Markup {
html! {
h1 { "404" }
p { "Method not allowed!" }
}
}
// Finally, we use a fallback route for anything that didn't match.
async fn handle_404(uri: Uri) -> impl IntoResponse {
(StatusCode::NOT_FOUND, markup_404(format!("{uri:?}"))).into_response()
}
async fn handle_405() -> impl IntoResponse {
(StatusCode::METHOD_NOT_ALLOWED, markup_405()).into_response()
}
#[derive(RustEmbed)]
#[folder = "public/"]
struct Asset;
pub struct StaticFile<T>(pub T);
impl<T> IntoResponse for StaticFile<T>
where
T: Into<String>,
{
fn into_response(self) -> Response<Body> {
let path = self.0.into();
match Asset::get(path.as_str()) {
Some(content) => {
let mime = mime_guess::from_path(path).first_or_octet_stream();
([(header::CONTENT_TYPE, mime.as_ref())], content.data).into_response()
}
None => (StatusCode::NOT_FOUND, markup_404(path)).into_response(),
}
}
}
pub fn initialize_logger() {
static INIT: Once = Once::new();
INIT.call_once(|| {
let env_filter = tracing_subscriber::EnvFilter::builder()
.with_default_directive(tracing::level_filters::LevelFilter::INFO.into())
.from_env_lossy();
tracing_subscriber::fmt()
.pretty()
.with_env_filter(env_filter)
.init();
});
}
#[tokio::main]
async fn main() {
initialize_logger();
// TODO pick free port/config
let listener = tokio::net::TcpListener::bind("0.0.0.0:8000").await.unwrap();
let ui_router = axum::Router::new()
.typed_route(item_handler)
.typed_route(hello_world);
let router: axum::Router = axum::Router::new()
.merge(ui_router.clone())
.nest("/ui", ui_router)
.typed_route(static_handler)
.fallback_service(get(handle_404))
.method_not_allowed_fallback(handle_405)
.with_state("state".to_string());
let _ = axum::serve(listener, router.into_make_service()).await;
}

View file

@ -0,0 +1,24 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>My Website</title>
<!-- TODO!!!: Add favico -->
<!-- <link rel="icon" href="./favicon.ico" type="image/x-icon"> -->
<script type="module" src="/dist/datastar.min.js"></script>
<link rel="stylesheet" href="./dist/styles.min.css">
</head>
<body>
<main>
<h1>Welcome to My Website</h1>
<div m-1>div</div>
<div class="m-1">div</div>
<div class="m1">div</div>
<m1>div</m1>
</main>
<script src="index.js"></script>
</body>
</html>

0
darm_test/src/ui/mod.rs Normal file
View file

View file

View file

View file

@ -0,0 +1 @@
@use 'uno';

15
darm_test/style/uno.css Normal file
View file

@ -0,0 +1,15 @@
/* layer: preflights */
*,::before,::after{--un-rotate:0;--un-rotate-x:0;--un-rotate-y:0;--un-rotate-z:0;--un-scale-x:1;--un-scale-y:1;--un-scale-z:1;--un-skew-x:0;--un-skew-y:0;--un-translate-x:0;--un-translate-y:0;--un-translate-z:0;--un-pan-x: ;--un-pan-y: ;--un-pinch-zoom: ;--un-scroll-snap-strictness:proximity;--un-ordinal: ;--un-slashed-zero: ;--un-numeric-figure: ;--un-numeric-spacing: ;--un-numeric-fraction: ;--un-border-spacing-x:0;--un-border-spacing-y:0;--un-ring-offset-shadow:0 0 rgba(0,0,0,0);--un-ring-shadow:0 0 rgba(0,0,0,0);--un-shadow-inset: ;--un-shadow:0 0 rgba(0,0,0,0);--un-ring-inset: ;--un-ring-offset-width:0px;--un-ring-offset-color:#fff;--un-ring-width:0px;--un-ring-color:rgba(147,197,253,0.5);--un-blur: ;--un-brightness: ;--un-contrast: ;--un-drop-shadow: ;--un-grayscale: ;--un-hue-rotate: ;--un-invert: ;--un-saturate: ;--un-sepia: ;--un-backdrop-blur: ;--un-backdrop-brightness: ;--un-backdrop-contrast: ;--un-backdrop-grayscale: ;--un-backdrop-hue-rotate: ;--un-backdrop-invert: ;--un-backdrop-opacity: ;--un-backdrop-saturate: ;--un-backdrop-sepia: ;}::backdrop{--un-rotate:0;--un-rotate-x:0;--un-rotate-y:0;--un-rotate-z:0;--un-scale-x:1;--un-scale-y:1;--un-scale-z:1;--un-skew-x:0;--un-skew-y:0;--un-translate-x:0;--un-translate-y:0;--un-translate-z:0;--un-pan-x: ;--un-pan-y: ;--un-pinch-zoom: ;--un-scroll-snap-strictness:proximity;--un-ordinal: ;--un-slashed-zero: ;--un-numeric-figure: ;--un-numeric-spacing: ;--un-numeric-fraction: ;--un-border-spacing-x:0;--un-border-spacing-y:0;--un-ring-offset-shadow:0 0 rgba(0,0,0,0);--un-ring-shadow:0 0 rgba(0,0,0,0);--un-shadow-inset: ;--un-shadow:0 0 rgba(0,0,0,0);--un-ring-inset: ;--un-ring-offset-width:0px;--un-ring-offset-color:#fff;--un-ring-width:0px;--un-ring-color:rgba(147,197,253,0.5);--un-blur: ;--un-brightness: ;--un-contrast: ;--un-drop-shadow: ;--un-grayscale: ;--un-hue-rotate: ;--un-invert: ;--un-saturate: ;--un-sepia: ;--un-backdrop-blur: ;--un-backdrop-brightness: ;--un-backdrop-contrast: ;--un-backdrop-grayscale: ;--un-backdrop-hue-rotate: ;--un-backdrop-invert: ;--un-backdrop-opacity: ;--un-backdrop-saturate: ;--un-backdrop-sepia: ;}
/* layer: default */
.static{position:static;}
.m-1,
.m1,
[m-1=""],
m1{margin:0.25rem;}
.ms,
[ms=""]{margin-inline-start:1rem;}
contents{display:contents;}
.h1{height:0.25rem;}
.b,
[b=""]{border-width:1px;}
[pe=""]{padding-inline-end:1rem;}

31
darm_test/uno.config.ts Normal file
View file

@ -0,0 +1,31 @@
// import presetAttributify from '@unocss/preset-attributify'
import {
defineConfig,
presetAttributify,
presetIcons,
presetTagify,
presetWind,
transformerDirectives,
transformerVariantGroup,
} from "unocss";
export default defineConfig({
content: {
filesystem: ["**/*.{html,js,ts,jsx,tsx,rs,rsx}"],
},
cli: {
entry: {
patterns: ["**/*.{html,js,ts,jsx,tsx,rs,rsx}"],
outFile: "./style/uno.css",
},
},
presets: [
presetAttributify({
/* preset options */
}),
presetTagify({}),
presetIcons({}),
presetWind({}),
],
transformers: [transformerDirectives(), transformerVariantGroup()],
});

View file

@ -1,19 +1,19 @@
[package] [package]
name = "llama_forge_rs" name = "llama_forge_rs"
edition.workspace=true edition.workspace = true
authors.workspace=true authors.workspace = true
description = "The LLama Forge RS" description = "The LLama Forge RS"
license.workspace=true license.workspace = true
publish.workspace=true publish.workspace = true
readme = "README.md" readme = "README.md"
repository.workspace=true repository.workspace = true
version.workspace=true version.workspace = true
[lib] [lib]
crate-type = ["cdylib", "rlib"] crate-type = ["cdylib", "rlib"]
[dependencies] [dependencies]
llama_proxy_man = {path="../llama_proxy_man", optional = true} llama_proxy_man = { path = "../llama_proxy_man", optional = true }
wasm-bindgen = "=0.2.100" wasm-bindgen = "=0.2.100"
# TODO Update to 0.7 # TODO Update to 0.7
leptos = { version = "0.6", features = [ leptos = { version = "0.6", features = [
@ -84,7 +84,13 @@ mime_guess = { version = "2.0.4", optional = true }
tracing-test = "0.2.4" tracing-test = "0.2.4"
sysinfo = { version = "0.30.11", optional = true } sysinfo = { version = "0.30.11", optional = true }
derive_more = { version = "0.99.17", features = ["nightly"] } derive_more = { version = "0.99.17", features = ["nightly"] }
sqlx-macros = { version = "0.7.4", optional = true, features = ["chrono", "json", "migrate", "sqlite", "uuid"] } sqlx-macros = { version = "0.7.4", optional = true, features = [
"chrono",
"json",
"migrate",
"sqlite",
"uuid",
] }
pulldown-cmark = { version = "0.12.2", features = ["serde"] } pulldown-cmark = { version = "0.12.2", features = ["serde"] }
# qdrant-client = "1.11.2" # qdrant-client = "1.11.2"
# swiftide = "0.9.1" # swiftide = "0.9.1"

View file

@ -11,16 +11,16 @@ use crate::api::{ChannelMessage, Chat, ChatMessage};
#[derive(Serialize, Debug)] #[derive(Serialize, Debug)]
struct LlamaChatCompletionRequest { struct LlamaChatCompletionRequest {
stream: bool, stream: bool,
model: String, model: String,
messages: Vec<LlamaChatMessage>, messages: Vec<LlamaChatMessage>,
} }
impl From<Chat> for LlamaChatCompletionRequest { impl From<Chat> for LlamaChatCompletionRequest {
fn from(value: Chat) -> Self { fn from(value: Chat) -> Self {
Self { Self {
stream: true, stream: true,
model: "default".to_string(), model: "default".to_string(),
messages: value.history.into_iter().map(|e| e.into()).collect(), messages: value.history.into_iter().map(|e| e.into()).collect(),
} }
} }
@ -28,14 +28,14 @@ impl From<Chat> for LlamaChatCompletionRequest {
#[derive(Serialize, Debug)] #[derive(Serialize, Debug)]
struct LlamaChatMessage { struct LlamaChatMessage {
role: String, role: String,
content: String, content: String,
} }
impl From<ChatMessage> for LlamaChatMessage { impl From<ChatMessage> for LlamaChatMessage {
fn from(chat_message: ChatMessage) -> Self { fn from(chat_message: ChatMessage) -> Self {
Self { Self {
role: chat_message.role.into(), role: chat_message.role.into(),
content: chat_message.content, content: chat_message.content,
} }
} }
@ -68,7 +68,9 @@ pub struct LlamaService {
impl LlamaService { impl LlamaService {
pub fn new(id: Uuid) -> Self { pub fn new(id: Uuid) -> Self {
Self { id } Self {
id,
}
} }
} }

View file

@ -177,7 +177,10 @@ mod tests {
use crate::{ use crate::{
api::{ChannelMessage, ChatMessage, ChatRole}, api::{ChannelMessage, ChatMessage, ChatRole},
server::backends::{ server::backends::{
llama_chat::LlamaService, BackendService, BackendServiceStatus, ChatService, llama_chat::LlamaService,
BackendService,
BackendServiceStatus,
ChatService,
}, },
}; };
@ -216,7 +219,7 @@ mod tests {
tracing::debug!("response: {}", response); tracing::debug!("response: {}", response);
assert!(response.contains('4')); assert!(response.contains('4'));
service_handle.stop().await; service_handle.stop().await.expect("Stop failed");
assert_eq!(service_handle.status().await, BackendServiceStatus::Stopped); assert_eq!(service_handle.status().await, BackendServiceStatus::Stopped);
} }

View file

@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize};
use tokio::process::Command; use tokio::process::Command;
pub struct RunnerArgs { pub struct RunnerArgs {
ctx_size: i64, ctx_size: i64,
gpu_layers: i64, gpu_layers: i64,
model_path: String, model_path: String,
} }
@ -36,8 +36,8 @@ impl From<RunnerArgs> for Vec<String> {
#[derive(Debug, Serialize, Deserialize, Clone)] #[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Runner { pub struct Runner {
pwd: Option<String>, pwd: Option<String>,
cmd: String, cmd: String,
args: Vec<String>, args: Vec<String>,
} }
@ -45,8 +45,8 @@ impl Runner {
// FIXME does not exit properly when it is killed // FIXME does not exit properly when it is killed
pub fn new_llamafile_bin(runner_args: RunnerArgs) -> Self { pub fn new_llamafile_bin(runner_args: RunnerArgs) -> Self {
Self { Self {
pwd: None, pwd: None,
cmd: "bash".to_string(), cmd: "bash".to_string(),
args: vec![ args: vec![
format!( format!(
"{}/llamafile", "{}/llamafile",
@ -64,8 +64,8 @@ impl Runner {
pub fn new_llama_server_bin(runner_args: RunnerArgs) -> Self { pub fn new_llama_server_bin(runner_args: RunnerArgs) -> Self {
Self { Self {
pwd: None, pwd: None,
cmd: "llama-server".to_string(), cmd: "llama-server".to_string(),
args: runner_args.into(), args: runner_args.into(),
} }
} }

View file

@ -18,7 +18,9 @@ impl<S> Layer<S> for LoggingLayer {
type Service = LoggingService<S>; type Service = LoggingService<S>;
fn layer(&self, inner: S) -> Self::Service { fn layer(&self, inner: S) -> Self::Service {
LoggingService { inner } LoggingService {
inner,
}
} }
} }
@ -48,8 +50,8 @@ where
LoggingServiceFuture { LoggingServiceFuture {
inner: self.inner.call(req), inner: self.inner.call(req),
uuid: Arc::new(request_uuid), // Store UUID in an Arc for shared ownership uuid: Arc::new(request_uuid), // Store UUID in an Arc for shared ownership
span: Arc::new(span), span: Arc::new(span),
} }
} }
} }

View file

@ -6,20 +6,26 @@ use axum::{
http::Request, http::Request,
response::IntoResponse, response::IntoResponse,
routing::get, routing::get,
Extension, Router, Extension,
Router,
}; };
use leptos::*; use leptos::*;
use leptos_axum::{generate_route_list, handle_server_fns_with_context, LeptosRoutes}; use leptos_axum::{generate_route_list, handle_server_fns_with_context, LeptosRoutes};
use leptos_router::RouteListing; use leptos_router::RouteListing;
use sqlx::{ use sqlx::{
sqlite::{SqliteConnectOptions, SqliteJournalMode, SqlitePoolOptions, SqliteSynchronous}, sqlite::{SqliteConnectOptions, SqliteJournalMode, SqlitePoolOptions, SqliteSynchronous},
ConnectOptions, SqlitePool, ConnectOptions,
SqlitePool,
}; };
use tower::Layer; use tower::Layer;
use tower_http::{ use tower_http::{
compression::CompressionLayer, compression::CompressionLayer,
trace::{ trace::{
DefaultMakeSpan, DefaultOnEos, DefaultOnFailure, DefaultOnRequest, DefaultOnResponse, DefaultMakeSpan,
DefaultOnEos,
DefaultOnFailure,
DefaultOnRequest,
DefaultOnResponse,
TraceLayer, TraceLayer,
}, },
CompressionLevel, CompressionLevel,

View file

@ -15,7 +15,13 @@ serde = { version = "1.0", features = ["derive"] }
serde_yaml = "0.9" serde_yaml = "0.9"
axum = { version = "0.7", features = ["macros"] } axum = { version = "0.7", features = ["macros"] }
hyper = { version = "1.4", features = ["full"] } hyper = { version = "1.4", features = ["full"] }
reqwest = { version = "0.12", features = ["cookies", "multipart", "json", "stream", "native-tls"] } reqwest = { version = "0.12", features = [
"cookies",
"multipart",
"json",
"stream",
"native-tls",
] }
futures = "0.3.30" futures = "0.3.30"
anyhow = { version = "1.0.89", features = ["backtrace"] } anyhow = { version = "1.0.89", features = ["backtrace"] }
thiserror = "1.0.63" thiserror = "1.0.63"
@ -26,7 +32,13 @@ pin-project-lite = "0.2.14"
tower = { version = "0.4", features = ["tokio", "tracing"] } tower = { version = "0.4", features = ["tokio", "tracing"] }
tower-http = { version = "0.5.2", features = ["trace"] } tower-http = { version = "0.5.2", features = ["trace"] }
reqwest-retry = "0.6.1" reqwest-retry = "0.6.1"
reqwest-middleware = { version = "0.3.3", features = ["charset", "http2", "json", "multipart", "rustls-tls"] } reqwest-middleware = { version = "0.3.3", features = [
"charset",
"http2",
"json",
"multipart",
"rustls-tls",
] }
itertools = "0.13.0" itertools = "0.13.0"
openport = { version = "0.1.1", features = ["rand"] } openport = { version = "0.1.1", features = ["rand"] }
derive_more = { version = "2.0.1", features = ["deref"] } derive_more = { version = "2.0.1", features = ["deref"] }

View file

@ -1,10 +1,10 @@
use serde::Deserialize;
use std::{collections::HashMap, fs}; use std::{collections::HashMap, fs};
use figment::{ use figment::{
providers::{Env, Format, Json, Toml, Yaml}, providers::{Env, Format, Json, Toml, Yaml},
Figment, Figment,
}; };
use serde::Deserialize;
#[derive(Clone, Debug, Deserialize)] #[derive(Clone, Debug, Deserialize)]
pub struct AppConfig { pub struct AppConfig {
@ -50,7 +50,7 @@ impl AppConfig {
#[derive(Clone, Debug, Deserialize)] #[derive(Clone, Debug, Deserialize)]
pub struct SystemResources { pub struct SystemResources {
pub ram: String, pub ram: String,
pub vram: String, pub vram: String,
} }

View file

@ -1,9 +1,10 @@
use std::io;
use anyhow::Error as AnyError; use anyhow::Error as AnyError;
use axum::{http, response::IntoResponse}; use axum::{http, response::IntoResponse};
use hyper; use hyper;
use reqwest; use reqwest;
use reqwest_middleware; use reqwest_middleware;
use std::io;
use thiserror::Error; use thiserror::Error;
#[derive(Error, Debug)] #[derive(Error, Debug)]

View file

@ -1,7 +1,7 @@
use crate::{config::ModelSpec, error::AppError, state::AppState, util::parse_size}; use std::{process::Stdio, sync::Arc};
use anyhow::anyhow; use anyhow::anyhow;
use itertools::Itertools; use itertools::Itertools;
use std::{process::Stdio, sync::Arc};
use tokio::{ use tokio::{
net::TcpStream, net::TcpStream,
process::{Child, Command}, process::{Child, Command},
@ -9,9 +9,11 @@ use tokio::{
time::{sleep, Duration}, time::{sleep, Duration},
}; };
use crate::{config::ModelSpec, error::AppError, state::AppState, util::parse_size};
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct InferenceProcess { pub struct InferenceProcess {
pub spec: ModelSpec, pub spec: ModelSpec,
pub process: Arc<Mutex<Child>>, pub process: Arc<Mutex<Child>>,
} }
@ -115,7 +117,7 @@ impl InferenceProcess {
let child = cmd.spawn().expect("Failed to start llama-server"); let child = cmd.spawn().expect("Failed to start llama-server");
Ok(InferenceProcess { Ok(InferenceProcess {
spec: spec.clone(), spec: spec.clone(),
process: Arc::new(Mutex::new(child)), process: Arc::new(Mutex::new(child)),
}) })
} }

View file

@ -6,12 +6,17 @@ pub mod proxy;
pub mod state; pub mod state;
pub mod util; pub mod util;
use std::net::SocketAddr;
use axum::{routing::any, Router}; use axum::{routing::any, Router};
use config::{AppConfig, ModelSpec}; use config::{AppConfig, ModelSpec};
use state::AppState; use state::AppState;
use std::net::SocketAddr;
use tower_http::trace::{ use tower_http::trace::{
DefaultMakeSpan, DefaultOnEos, DefaultOnFailure, DefaultOnRequest, DefaultOnResponse, DefaultMakeSpan,
DefaultOnEos,
DefaultOnFailure,
DefaultOnRequest,
DefaultOnResponse,
TraceLayer, TraceLayer,
}; };
use tracing::Level; use tracing::Level;

View file

@ -1,12 +1,10 @@
use std::{ use std::{
future::Future, future::Future,
pin::Pin, pin::Pin,
sync::Arc, sync::{Arc, Once},
task::{Context, Poll}, task::{Context, Poll},
}; };
use std::sync::Once;
use axum::{body::Body, http::Request}; use axum::{body::Body, http::Request};
use pin_project_lite::pin_project; use pin_project_lite::pin_project;
use tower::{Layer, Service}; use tower::{Layer, Service};
@ -18,7 +16,9 @@ impl<S> Layer<S> for LoggingLayer {
type Service = LoggingService<S>; type Service = LoggingService<S>;
fn layer(&self, inner: S) -> Self::Service { fn layer(&self, inner: S) -> Self::Service {
LoggingService { inner } LoggingService {
inner,
}
} }
} }
@ -53,7 +53,7 @@ where
LoggingServiceFuture { LoggingServiceFuture {
inner: self.inner.call(req), inner: self.inner.call(req),
uuid: Arc::new(request_uuid), // Store UUID in an Arc for shared ownership uuid: Arc::new(request_uuid), // Store UUID in an Arc for shared ownership
} }
} }
} }

View file

@ -1,7 +1,3 @@
use crate::{
config::ModelSpec, error::AppError, inference_process::InferenceProcess, state::AppState,
util::parse_size,
};
use axum::{ use axum::{
body::Body, body::Body,
http::{Request, Response}, http::{Request, Response},
@ -11,6 +7,14 @@ use reqwest::Client;
use reqwest_middleware::{ClientBuilder, ClientWithMiddleware}; use reqwest_middleware::{ClientBuilder, ClientWithMiddleware};
use reqwest_retry::{policies::ExponentialBackoff, RetryTransientMiddleware}; use reqwest_retry::{policies::ExponentialBackoff, RetryTransientMiddleware};
use crate::{
config::ModelSpec,
error::AppError,
inference_process::InferenceProcess,
state::AppState,
util::parse_size,
};
pub async fn proxy_request( pub async fn proxy_request(
req: Request<Body>, req: Request<Body>,
spec: &ModelSpec, spec: &ModelSpec,

View file

@ -1,14 +1,16 @@
use crate::{config::AppConfig, inference_process::InferenceProcess, util::parse_size};
use std::{collections::HashMap, sync::Arc}; use std::{collections::HashMap, sync::Arc};
use tokio::sync::Mutex; use tokio::sync::Mutex;
use crate::{config::AppConfig, inference_process::InferenceProcess, util::parse_size};
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct ResourceManager { pub struct ResourceManager {
pub total_ram: u64, pub total_ram: u64,
pub total_vram: u64, pub total_vram: u64,
pub used_ram: u64, pub used_ram: u64,
pub used_vram: u64, pub used_vram: u64,
pub processes: HashMap<u16, InferenceProcess>, pub processes: HashMap<u16, InferenceProcess>,
} }
pub type ResourceManagerHandle = Arc<Mutex<ResourceManager>>; pub type ResourceManagerHandle = Arc<Mutex<ResourceManager>>;

1835
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -4,10 +4,23 @@
"version": "0.1.1", "version": "0.1.1",
"author": "Tristan Druyen <tristan@vault81.mozmail.com>", "author": "Tristan Druyen <tristan@vault81.mozmail.com>",
"license": "AGPL", "license": "AGPL",
"scripts": {
"watch-unocss": "cd ./darm_test && unocss --watch",
"watch-bundle": "npm run build-bundle",
"build-unocss": "cd ./darm_test && unocss",
"build-bundle": "cd ./darm_test && sass -scompressed style/main.scss > public/styles.min.css",
"watch-all": "npm run watch-unocss & npm run watch-bundle",
"build-all": "npm run build-unocss & npm run build-bundle"
},
"devDependencies": { "devDependencies": {
"@starfederation/datastar": "^1.0.0-beta.7",
"@tailwindcss/forms": "0.5.7", "@tailwindcss/forms": "0.5.7",
"@tailwindcss/typography": "0.5.10", "@tailwindcss/typography": "0.5.10",
"@unocss/reset": "^66.0.0",
"daisyui": "4.7.3", "daisyui": "4.7.3",
"tailwindcss": "3.4.17" "sass": "^1.85.0",
"tailwindcss": "3.4.17",
"typescript": "^5.7.3",
"unocss": "^0.54.3"
} }
} }

View file

@ -1,5 +1,6 @@
use emacs::{defun, Env, IntoLisp, Result, Value};
use std::sync::OnceLock; use std::sync::OnceLock;
use emacs::{defun, Env, IntoLisp, Result, Value};
use tokio::runtime::{Builder, Runtime}; use tokio::runtime::{Builder, Runtime};
// Emacs won't load the module without this. // Emacs won't load the module without this.
@ -48,12 +49,9 @@ fn init(env: &Env) -> Result<Value<'_>> {
#[defun] #[defun]
fn say_hello(env: &Env, name: String) -> Result<Value<'_>> { fn say_hello(env: &Env, name: String) -> Result<Value<'_>> {
// env.message(&format!("Helloo Broooooooo, {}!", name)) // env.message(&format!("Helloo Broooooooo, {}!", name))
env.call( env.call("message", [format!("Henlo whatsup, {}!!!!", name)
"message", .as_str()
[format!("Henlo whatsup, {}!!!!", name) .into_lisp(env)?])?;
.as_str()
.into_lisp(env)?],
)?;
RUNTIME RUNTIME
.get() .get()
.ok_or_else(|| anyhow::anyhow!("No runtime"))? .ok_or_else(|| anyhow::anyhow!("No runtime"))?

23
rustfmt.toml Normal file
View file

@ -0,0 +1,23 @@
edition = "2021"
max_width = 100
tab_spaces = 4
# unstable
format_macro_bodies = true
format_macro_matchers = true
format_strings = true
group_imports = "StdExternalCrate"
imports_granularity = "Crate"
imports_layout = "HorizontalVertical"
overflow_delimited_expr = true
reorder_impl_items = true
struct_field_align_threshold = 4
struct_lit_single_line = false
trailing_comma = "Vertical"
unstable_features = true
use_field_init_shorthand = true
use_try_shorthand = true
wrap_comments = false
# format_brace_macros = true