Add llama_proxy_man pkg
This commit is contained in:
parent
3171dc6c63
commit
8692b5bda4
9 changed files with 826 additions and 72 deletions
340
Cargo.lock
generated
340
Cargo.lock
generated
|
@ -170,9 +170,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "anyhow"
|
name = "anyhow"
|
||||||
version = "1.0.87"
|
version = "1.0.89"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "10f00e1f6e58a40e807377c75c6a7f97bf9044fab57816f2414e6f5f4499d7b8"
|
checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"backtrace",
|
"backtrace",
|
||||||
]
|
]
|
||||||
|
@ -188,9 +188,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "arrayref"
|
name = "arrayref"
|
||||||
version = "0.3.8"
|
version = "0.3.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9d151e35f61089500b617991b791fc8bfd237ae50cd5950803758a179b41e67a"
|
checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "arrayvec"
|
name = "arrayvec"
|
||||||
|
@ -309,9 +309,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "async-process"
|
name = "async-process"
|
||||||
version = "2.2.4"
|
version = "2.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a8a07789659a4d385b79b18b9127fc27e1a59e1e89117c78c5ea3b806f016374"
|
checksum = "63255f1dc2381611000436537bbedfe83183faa303a5a0edaf191edef06526bb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-channel",
|
"async-channel",
|
||||||
"async-io",
|
"async-io",
|
||||||
|
@ -324,7 +324,6 @@ dependencies = [
|
||||||
"futures-lite",
|
"futures-lite",
|
||||||
"rustix",
|
"rustix",
|
||||||
"tracing",
|
"tracing",
|
||||||
"windows-sys 0.59.0",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -775,9 +774,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bytes"
|
name = "bytes"
|
||||||
version = "1.7.1"
|
version = "1.7.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50"
|
checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cached"
|
name = "cached"
|
||||||
|
@ -896,9 +895,9 @@ checksum = "8b96ec4966b5813e2c0507c1f86115c8c5abaadc3980879c3424042a02fd1ad3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.1.18"
|
version = "1.1.21"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b62ac837cdb5cb22e10a256099b4fc502b1dfe560cb282963a974d7abd80e476"
|
checksum = "07b1695e2c7e8fc85310cde85aeaab7e3097f593c91d209d3f9df76c928100f0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"jobserver",
|
"jobserver",
|
||||||
"libc",
|
"libc",
|
||||||
|
@ -1199,6 +1198,34 @@ dependencies = [
|
||||||
"unicode-segmentation",
|
"unicode-segmentation",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cookie"
|
||||||
|
version = "0.18.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747"
|
||||||
|
dependencies = [
|
||||||
|
"percent-encoding",
|
||||||
|
"time",
|
||||||
|
"version_check",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cookie_store"
|
||||||
|
version = "0.21.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4934e6b7e8419148b6ef56950d277af8561060b56afd59e2aadf98b59fce6baa"
|
||||||
|
dependencies = [
|
||||||
|
"cookie",
|
||||||
|
"idna 0.5.0",
|
||||||
|
"log",
|
||||||
|
"publicsuffix",
|
||||||
|
"serde",
|
||||||
|
"serde_derive",
|
||||||
|
"serde_json",
|
||||||
|
"time",
|
||||||
|
"url",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "core-foundation"
|
name = "core-foundation"
|
||||||
version = "0.9.4"
|
version = "0.9.4"
|
||||||
|
@ -1572,6 +1599,15 @@ dependencies = [
|
||||||
"zeroize",
|
"zeroize",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "deranged"
|
||||||
|
version = "0.3.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4"
|
||||||
|
dependencies = [
|
||||||
|
"powerfmt",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "derive-where"
|
name = "derive-where"
|
||||||
version = "1.2.7"
|
version = "1.2.7"
|
||||||
|
@ -1884,9 +1920,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "error-code"
|
name = "error-code"
|
||||||
version = "3.2.0"
|
version = "3.3.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a0474425d51df81997e2f90a21591180b38eccf27292d755f3e30750225c175b"
|
checksum = "a5d9305ccc6942a704f4335694ecd3de2ea531b114ac2d51f5f843750787a92f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "etagere"
|
name = "etagere"
|
||||||
|
@ -3066,9 +3102,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hyper-util"
|
name = "hyper-util"
|
||||||
version = "0.1.7"
|
version = "0.1.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cde7055719c54e36e95e8719f95883f22072a48ede39db7fc17a4e1d5281e9b9"
|
checksum = "da62f120a8a37763efb0cf8fdf264b884c7b8b9ac8660b900c8661030c00e6ba"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"futures-channel",
|
"futures-channel",
|
||||||
|
@ -3086,9 +3122,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iana-time-zone"
|
name = "iana-time-zone"
|
||||||
version = "0.1.60"
|
version = "0.1.61"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141"
|
checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"android_system_properties",
|
"android_system_properties",
|
||||||
"core-foundation-sys",
|
"core-foundation-sys",
|
||||||
|
@ -3109,8 +3145,8 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iced"
|
name = "iced"
|
||||||
version = "0.13.0-dev"
|
version = "0.13.1"
|
||||||
source = "git+https://github.com/iced-rs/iced.git?branch=master#630f3525ddc58f1ee8dfec2f7567f52ea77eaa6e"
|
source = "git+https://github.com/iced-rs/iced.git?branch=master#bf3b6f100df7b1585dfac88da432bc29784ed534"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"iced_core",
|
"iced_core",
|
||||||
"iced_futures",
|
"iced_futures",
|
||||||
|
@ -3122,8 +3158,8 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iced_core"
|
name = "iced_core"
|
||||||
version = "0.13.0-dev"
|
version = "0.13.1"
|
||||||
source = "git+https://github.com/iced-rs/iced.git?branch=master#630f3525ddc58f1ee8dfec2f7567f52ea77eaa6e"
|
source = "git+https://github.com/iced-rs/iced.git?branch=master#bf3b6f100df7b1585dfac88da432bc29784ed534"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.6.0",
|
"bitflags 2.6.0",
|
||||||
"bytes",
|
"bytes",
|
||||||
|
@ -3141,8 +3177,8 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iced_futures"
|
name = "iced_futures"
|
||||||
version = "0.13.0-dev"
|
version = "0.13.1"
|
||||||
source = "git+https://github.com/iced-rs/iced.git?branch=master#630f3525ddc58f1ee8dfec2f7567f52ea77eaa6e"
|
source = "git+https://github.com/iced-rs/iced.git?branch=master#bf3b6f100df7b1585dfac88da432bc29784ed534"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures",
|
"futures",
|
||||||
"iced_core",
|
"iced_core",
|
||||||
|
@ -3154,8 +3190,8 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iced_graphics"
|
name = "iced_graphics"
|
||||||
version = "0.13.0-dev"
|
version = "0.13.1"
|
||||||
source = "git+https://github.com/iced-rs/iced.git?branch=master#630f3525ddc58f1ee8dfec2f7567f52ea77eaa6e"
|
source = "git+https://github.com/iced-rs/iced.git?branch=master#bf3b6f100df7b1585dfac88da432bc29784ed534"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.6.0",
|
"bitflags 2.6.0",
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
|
@ -3173,8 +3209,8 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iced_renderer"
|
name = "iced_renderer"
|
||||||
version = "0.13.0-dev"
|
version = "0.13.1"
|
||||||
source = "git+https://github.com/iced-rs/iced.git?branch=master#630f3525ddc58f1ee8dfec2f7567f52ea77eaa6e"
|
source = "git+https://github.com/iced-rs/iced.git?branch=master#bf3b6f100df7b1585dfac88da432bc29784ed534"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"iced_graphics",
|
"iced_graphics",
|
||||||
"iced_tiny_skia",
|
"iced_tiny_skia",
|
||||||
|
@ -3185,8 +3221,8 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iced_runtime"
|
name = "iced_runtime"
|
||||||
version = "0.13.0-dev"
|
version = "0.13.1"
|
||||||
source = "git+https://github.com/iced-rs/iced.git?branch=master#630f3525ddc58f1ee8dfec2f7567f52ea77eaa6e"
|
source = "git+https://github.com/iced-rs/iced.git?branch=master#bf3b6f100df7b1585dfac88da432bc29784ed534"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"iced_core",
|
"iced_core",
|
||||||
|
@ -3197,8 +3233,8 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iced_tiny_skia"
|
name = "iced_tiny_skia"
|
||||||
version = "0.13.0-dev"
|
version = "0.13.1"
|
||||||
source = "git+https://github.com/iced-rs/iced.git?branch=master#630f3525ddc58f1ee8dfec2f7567f52ea77eaa6e"
|
source = "git+https://github.com/iced-rs/iced.git?branch=master#bf3b6f100df7b1585dfac88da432bc29784ed534"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
"cosmic-text",
|
"cosmic-text",
|
||||||
|
@ -3212,8 +3248,8 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iced_wgpu"
|
name = "iced_wgpu"
|
||||||
version = "0.13.0-dev"
|
version = "0.13.1"
|
||||||
source = "git+https://github.com/iced-rs/iced.git?branch=master#630f3525ddc58f1ee8dfec2f7567f52ea77eaa6e"
|
source = "git+https://github.com/iced-rs/iced.git?branch=master#bf3b6f100df7b1585dfac88da432bc29784ed534"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.6.0",
|
"bitflags 2.6.0",
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
|
@ -3231,8 +3267,8 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iced_widget"
|
name = "iced_widget"
|
||||||
version = "0.13.0-dev"
|
version = "0.13.1"
|
||||||
source = "git+https://github.com/iced-rs/iced.git?branch=master#630f3525ddc58f1ee8dfec2f7567f52ea77eaa6e"
|
source = "git+https://github.com/iced-rs/iced.git?branch=master#bf3b6f100df7b1585dfac88da432bc29784ed534"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"iced_renderer",
|
"iced_renderer",
|
||||||
"iced_runtime",
|
"iced_runtime",
|
||||||
|
@ -3245,8 +3281,8 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iced_winit"
|
name = "iced_winit"
|
||||||
version = "0.13.0-dev"
|
version = "0.13.1"
|
||||||
source = "git+https://github.com/iced-rs/iced.git?branch=master#630f3525ddc58f1ee8dfec2f7567f52ea77eaa6e"
|
source = "git+https://github.com/iced-rs/iced.git?branch=master#bf3b6f100df7b1585dfac88da432bc29784ed534"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"iced_futures",
|
"iced_futures",
|
||||||
"iced_graphics",
|
"iced_graphics",
|
||||||
|
@ -3279,6 +3315,16 @@ version = "1.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
|
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "idna"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-bidi",
|
||||||
|
"unicode-normalization",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "idna"
|
name = "idna"
|
||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
|
@ -3338,6 +3384,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222"
|
checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
|
"js-sys",
|
||||||
|
"wasm-bindgen",
|
||||||
|
"web-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -4119,6 +4168,29 @@ dependencies = [
|
||||||
"x11-dl",
|
"x11-dl",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "llama_proxy_man"
|
||||||
|
version = "0.1.1"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"axum",
|
||||||
|
"futures",
|
||||||
|
"hyper",
|
||||||
|
"pin-project-lite",
|
||||||
|
"reqwest",
|
||||||
|
"reqwest-middleware",
|
||||||
|
"reqwest-retry",
|
||||||
|
"serde",
|
||||||
|
"serde_yaml",
|
||||||
|
"thiserror",
|
||||||
|
"tokio",
|
||||||
|
"tower",
|
||||||
|
"tower-http",
|
||||||
|
"tracing",
|
||||||
|
"tracing-subscriber",
|
||||||
|
"uuid",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lock_api"
|
name = "lock_api"
|
||||||
version = "0.4.12"
|
version = "0.4.12"
|
||||||
|
@ -4241,9 +4313,9 @@ checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memmap2"
|
name = "memmap2"
|
||||||
version = "0.9.4"
|
version = "0.9.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fe751422e4a8caa417e13c3ea66452215d7d63e19e604f4980461212f3ae1322"
|
checksum = "fd3f7eed9d3848f8b98834af67102b720745c4ec028fcd0aa0239277e7de374f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
@ -4533,6 +4605,12 @@ dependencies = [
|
||||||
"zeroize",
|
"zeroize",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-conv"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-integer"
|
name = "num-integer"
|
||||||
version = "0.1.46"
|
version = "0.1.46"
|
||||||
|
@ -5095,7 +5173,7 @@ checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"libc",
|
"libc",
|
||||||
"redox_syscall 0.5.3",
|
"redox_syscall 0.5.4",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"windows-targets 0.52.6",
|
"windows-targets 0.52.6",
|
||||||
]
|
]
|
||||||
|
@ -5129,9 +5207,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pest"
|
name = "pest"
|
||||||
version = "2.7.12"
|
version = "2.7.13"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9c73c26c01b8c87956cea613c907c9d6ecffd8d18a2a5908e5de0adfaa185cea"
|
checksum = "fdbef9d1d47087a895abd220ed25eb4ad973a5e26f6a4367b038c25e28dfc2d9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
|
@ -5140,9 +5218,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pest_derive"
|
name = "pest_derive"
|
||||||
version = "2.7.12"
|
version = "2.7.13"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "664d22978e2815783adbdd2c588b455b1bd625299ce36b2a99881ac9627e6d8d"
|
checksum = "4d3a6e3394ec80feb3b6393c725571754c6188490265c61aaf260810d6b95aa0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"pest",
|
"pest",
|
||||||
"pest_generator",
|
"pest_generator",
|
||||||
|
@ -5150,9 +5228,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pest_generator"
|
name = "pest_generator"
|
||||||
version = "2.7.12"
|
version = "2.7.13"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a2d5487022d5d33f4c30d91c22afa240ce2a644e87fe08caad974d4eab6badbe"
|
checksum = "94429506bde1ca69d1b5601962c73f4172ab4726571a59ea95931218cb0e930e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"pest",
|
"pest",
|
||||||
"pest_meta",
|
"pest_meta",
|
||||||
|
@ -5163,9 +5241,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pest_meta"
|
name = "pest_meta"
|
||||||
version = "2.7.12"
|
version = "2.7.13"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0091754bbd0ea592c4deb3a122ce8ecbb0753b738aa82bc055fcc2eccc8d8174"
|
checksum = "ac8a071862e93690b6e34e9a5fb8e33ff3734473ac0245b27232222c4906a33f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"pest",
|
"pest",
|
||||||
|
@ -5404,6 +5482,12 @@ dependencies = [
|
||||||
"windows-sys 0.59.0",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "powerfmt"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ppv-lite86"
|
name = "ppv-lite86"
|
||||||
version = "0.2.20"
|
version = "0.2.20"
|
||||||
|
@ -5460,7 +5544,7 @@ version = "3.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b"
|
checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"toml_edit 0.22.20",
|
"toml_edit 0.22.21",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -5596,6 +5680,12 @@ dependencies = [
|
||||||
"prost",
|
"prost",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "psl-types"
|
||||||
|
version = "2.0.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "33cb294fe86a74cbcf50d4445b37da762029549ebeea341421c7c70370f86cac"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ptr_meta"
|
name = "ptr_meta"
|
||||||
version = "0.1.4"
|
version = "0.1.4"
|
||||||
|
@ -5616,6 +5706,16 @@ dependencies = [
|
||||||
"syn 1.0.109",
|
"syn 1.0.109",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "publicsuffix"
|
||||||
|
version = "2.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "96a8c1bda5ae1af7f99a2962e49df150414a43d62404644d98dd5c3a93d07457"
|
||||||
|
dependencies = [
|
||||||
|
"idna 0.3.0",
|
||||||
|
"psl-types",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pulldown-cmark"
|
name = "pulldown-cmark"
|
||||||
version = "0.12.1"
|
version = "0.12.1"
|
||||||
|
@ -5924,9 +6024,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "redox_syscall"
|
name = "redox_syscall"
|
||||||
version = "0.5.3"
|
version = "0.5.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4"
|
checksum = "0884ad60e090bf1345b93da0a5de8923c93884cd03f40dfcfddd3b4bee661853"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.6.0",
|
"bitflags 2.6.0",
|
||||||
]
|
]
|
||||||
|
@ -6009,6 +6109,8 @@ checksum = "f8f4955649ef5c38cc7f9e8aa41761d48fb9677197daea9984dc54f56aad5e63"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.22.1",
|
"base64 0.22.1",
|
||||||
"bytes",
|
"bytes",
|
||||||
|
"cookie",
|
||||||
|
"cookie_store",
|
||||||
"encoding_rs",
|
"encoding_rs",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
|
@ -6024,6 +6126,7 @@ dependencies = [
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"log",
|
"log",
|
||||||
"mime",
|
"mime",
|
||||||
|
"mime_guess",
|
||||||
"native-tls",
|
"native-tls",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
|
@ -6068,6 +6171,51 @@ dependencies = [
|
||||||
"thiserror",
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "reqwest-middleware"
|
||||||
|
version = "0.3.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "562ceb5a604d3f7c885a792d42c199fd8af239d0a51b2fa6a78aafa092452b04"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"async-trait",
|
||||||
|
"http 1.1.0",
|
||||||
|
"reqwest",
|
||||||
|
"serde",
|
||||||
|
"thiserror",
|
||||||
|
"tower-service",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "reqwest-retry"
|
||||||
|
version = "0.6.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a83df1aaec00176d0fabb65dea13f832d2a446ca99107afc17c5d2d4981221d0"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"async-trait",
|
||||||
|
"futures",
|
||||||
|
"getrandom 0.2.15",
|
||||||
|
"http 1.1.0",
|
||||||
|
"hyper",
|
||||||
|
"parking_lot 0.11.2",
|
||||||
|
"reqwest",
|
||||||
|
"reqwest-middleware",
|
||||||
|
"retry-policies",
|
||||||
|
"tokio",
|
||||||
|
"tracing",
|
||||||
|
"wasm-timer",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "retry-policies"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5875471e6cab2871bc150ecb8c727db5113c9338cc3354dc5ee3425b6aa40a1c"
|
||||||
|
dependencies = [
|
||||||
|
"rand 0.8.5",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ring"
|
name = "ring"
|
||||||
version = "0.17.8"
|
version = "0.17.8"
|
||||||
|
@ -6240,9 +6388,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustix"
|
name = "rustix"
|
||||||
version = "0.38.36"
|
version = "0.38.37"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3f55e80d50763938498dd5ebb18647174e0c76dc38c5505294bb224624f30f36"
|
checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.6.0",
|
"bitflags 2.6.0",
|
||||||
"errno",
|
"errno",
|
||||||
|
@ -6253,9 +6401,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustls"
|
name = "rustls"
|
||||||
version = "0.23.12"
|
version = "0.23.13"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c58f8c84392efc0a126acce10fa59ff7b3d2ac06ab451a33f2741989b806b044"
|
checksum = "f2dabaac7466917e566adb06783a81ca48944c6898a1b08b9374106dd671f4c8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
|
@ -6310,9 +6458,9 @@ checksum = "fc0a2ce646f8655401bb81e7927b812614bd5d91dbc968696be50603510fcaf0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustls-webpki"
|
name = "rustls-webpki"
|
||||||
version = "0.102.7"
|
version = "0.102.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "84678086bd54edf2b415183ed7a94d0efb049f1b646a33e22a36f3794be6ae56"
|
checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ring",
|
"ring",
|
||||||
"rustls-pki-types",
|
"rustls-pki-types",
|
||||||
|
@ -6590,6 +6738,19 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_yaml"
|
||||||
|
version = "0.9.34+deprecated"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47"
|
||||||
|
dependencies = [
|
||||||
|
"indexmap 2.5.0",
|
||||||
|
"itoa 1.0.11",
|
||||||
|
"ryu",
|
||||||
|
"serde",
|
||||||
|
"unsafe-libyaml",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "server_fn"
|
name = "server_fn"
|
||||||
version = "0.6.15"
|
version = "0.6.15"
|
||||||
|
@ -6930,7 +7091,7 @@ dependencies = [
|
||||||
"objc2-foundation",
|
"objc2-foundation",
|
||||||
"objc2-quartz-core",
|
"objc2-quartz-core",
|
||||||
"raw-window-handle 0.6.2",
|
"raw-window-handle 0.6.2",
|
||||||
"redox_syscall 0.5.3",
|
"redox_syscall 0.5.4",
|
||||||
"rustix",
|
"rustix",
|
||||||
"tiny-xlib",
|
"tiny-xlib",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
|
@ -7752,6 +7913,37 @@ dependencies = [
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "time"
|
||||||
|
version = "0.3.36"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885"
|
||||||
|
dependencies = [
|
||||||
|
"deranged",
|
||||||
|
"itoa 1.0.11",
|
||||||
|
"num-conv",
|
||||||
|
"powerfmt",
|
||||||
|
"serde",
|
||||||
|
"time-core",
|
||||||
|
"time-macros",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "time-core"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "time-macros"
|
||||||
|
version = "0.2.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf"
|
||||||
|
dependencies = [
|
||||||
|
"num-conv",
|
||||||
|
"time-core",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tiny-skia"
|
name = "tiny-skia"
|
||||||
version = "0.11.4"
|
version = "0.11.4"
|
||||||
|
@ -7892,7 +8084,7 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
"serde_spanned",
|
"serde_spanned",
|
||||||
"toml_datetime",
|
"toml_datetime",
|
||||||
"toml_edit 0.22.20",
|
"toml_edit 0.22.21",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -7928,9 +8120,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toml_edit"
|
name = "toml_edit"
|
||||||
version = "0.22.20"
|
version = "0.22.21"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d"
|
checksum = "3b072cee73c449a636ffd6f32bd8de3a9f7119139aff882f44943ce2986dc5cf"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"indexmap 2.5.0",
|
"indexmap 2.5.0",
|
||||||
"serde",
|
"serde",
|
||||||
|
@ -8294,9 +8486,9 @@ checksum = "1df77b101bcc4ea3d78dafc5ad7e4f58ceffe0b2b16bf446aeb50b6cb4157656"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
version = "1.0.12"
|
version = "1.0.13"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-linebreak"
|
name = "unicode-linebreak"
|
||||||
|
@ -8306,9 +8498,9 @@ checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-normalization"
|
name = "unicode-normalization"
|
||||||
version = "0.1.23"
|
version = "0.1.24"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5"
|
checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"tinyvec",
|
"tinyvec",
|
||||||
]
|
]
|
||||||
|
@ -8327,9 +8519,9 @@ checksum = "ad8d71f5726e5f285a935e9fe8edfd53f0491eb6e9a5774097fdabee7cd8c9cd"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-segmentation"
|
name = "unicode-segmentation"
|
||||||
version = "1.11.0"
|
version = "1.12.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202"
|
checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-width"
|
name = "unicode-width"
|
||||||
|
@ -8349,6 +8541,12 @@ version = "0.1.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e"
|
checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unsafe-libyaml"
|
||||||
|
version = "0.2.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "untrusted"
|
name = "untrusted"
|
||||||
version = "0.9.0"
|
version = "0.9.0"
|
||||||
|
@ -8362,7 +8560,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c"
|
checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"form_urlencoded",
|
"form_urlencoded",
|
||||||
"idna",
|
"idna 0.5.0",
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -8761,9 +8959,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "webpki-roots"
|
name = "webpki-roots"
|
||||||
version = "0.26.5"
|
version = "0.26.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0bd24728e5af82c6c4ec1b66ac4844bdf8156257fccda846ec58b42cd0cdbe6a"
|
checksum = "841c67bff177718f1d4dfefde8d8f0e78f9b6589319ba88312f567fc5841a958"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rustls-pki-types",
|
"rustls-pki-types",
|
||||||
]
|
]
|
||||||
|
@ -8917,7 +9115,7 @@ version = "1.5.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "372d5b87f58ec45c384ba03563b03544dc5fadc3983e434b286913f5b4a9bb6d"
|
checksum = "372d5b87f58ec45c384ba03563b03544dc5fadc3983e434b286913f5b4a9bb6d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"redox_syscall 0.5.3",
|
"redox_syscall 0.5.4",
|
||||||
"wasite",
|
"wasite",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ lto = "fat"
|
||||||
panic = "abort"
|
panic = "abort"
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
members = ["llama_forge_rs", "leptos_stub", "frozen_llama"]
|
members = ["llama_forge_rs", "leptos_stub", "frozen_llama", "llama_proxy_man"]
|
||||||
resolver = "2"
|
resolver = "2"
|
||||||
|
|
||||||
[workspace.package]
|
[workspace.package]
|
||||||
|
|
29
llama_proxy_man/Cargo.toml
Normal file
29
llama_proxy_man/Cargo.toml
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
[package]
|
||||||
|
name = "llama_proxy_man"
|
||||||
|
edition = "2021"
|
||||||
|
authors.workspace = true
|
||||||
|
description.workspace = true
|
||||||
|
license.workspace = true
|
||||||
|
publish.workspace = true
|
||||||
|
readme.workspace = true
|
||||||
|
repository.workspace = true
|
||||||
|
version.workspace = true
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
tokio = { version = "1", features = ["full", "process"] }
|
||||||
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
|
serde_yaml = "0.9"
|
||||||
|
axum = { version = "0.7", features = ["macros"] }
|
||||||
|
hyper = { version = "1.4", features = ["full"] }
|
||||||
|
reqwest = { version = "0.12", features = ["cookies", "multipart", "json", "stream", "native-tls"] }
|
||||||
|
futures = "0.3.30"
|
||||||
|
anyhow = { version = "1.0.89", features = ["backtrace"] }
|
||||||
|
thiserror = "1.0.63"
|
||||||
|
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
|
||||||
|
tracing = "0.1.40"
|
||||||
|
uuid = { version = "1.10.0", features = ["v4", "v7", "serde"] }
|
||||||
|
pin-project-lite = "0.2.14"
|
||||||
|
tower = { version = "0.4", features = ["tokio", "tracing"] }
|
||||||
|
tower-http = { version = "0.5.2", features = ["trace"] }
|
||||||
|
reqwest-retry = "0.6.1"
|
||||||
|
reqwest-middleware = { version = "0.3.3", features = ["charset", "http2", "json", "multipart", "rustls-tls"] }
|
5
llama_proxy_man/README.md
Normal file
5
llama_proxy_man/README.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
# LLama Herder
|
||||||
|
|
||||||
|
- manages multiple llama.cpp instances in the background
|
||||||
|
- keeps track of used & available video & cpu memory
|
||||||
|
- starts/stops llama.cpp instances as needed, to ensure memory limit is never reached
|
34
llama_proxy_man/TODO.org
Normal file
34
llama_proxy_man/TODO.org
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
#+title: Todo
|
||||||
|
|
||||||
|
|
||||||
|
* Name ideas
|
||||||
|
- llama herder
|
||||||
|
- llama herdsman/women/boy ??
|
||||||
|
- llama shepherd ?
|
||||||
|
|
||||||
|
* MVP
|
||||||
|
- [X] fix stopping (doesn't work correctly at all)
|
||||||
|
- seems done
|
||||||
|
|
||||||
|
* Future Features
|
||||||
|
- [ ] support for model selection by name on a unified port for /api & /completions
|
||||||
|
- [ ] separation of proxy/selection stuff ? config for unmanaged instances for auto model-selection by name
|
||||||
|
- [ ] automatic internal port management (search for free ports)
|
||||||
|
- [ ] Diagnostic Overview UI/API
|
||||||
|
- [ ] Config UI/API ?
|
||||||
|
- [ ] better book-keeping abt inflight requests ? (needed ?)
|
||||||
|
- [ ] multi node stuff
|
||||||
|
- how exactly ?
|
||||||
|
- clustering ? (one manager per node ?)
|
||||||
|
- ssh support ???
|
||||||
|
- [ ] automatic ram usage calc ?
|
||||||
|
- [ ] other runners
|
||||||
|
- e.g. docker/ run in path etc
|
||||||
|
- [ ] other backends ?
|
||||||
|
- [ ] more advanced start/stop behavior
|
||||||
|
- more config ? e.g. pinning/priorities/prefer-to-kill/start-initially
|
||||||
|
- LRU /most used prioritized to keep running
|
||||||
|
- speculative relaunch
|
||||||
|
- scheduling of how to order in-flight requests + restarts to handle them optimally
|
||||||
|
- [ ] advanced high-level foo
|
||||||
|
- automatic context-size selection per request/ start with bigger context if current instance has to low context
|
26
llama_proxy_man/config.yaml
Normal file
26
llama_proxy_man/config.yaml
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
hardware:
|
||||||
|
ram: 64G
|
||||||
|
vram: 8G
|
||||||
|
models:
|
||||||
|
- port: 18080
|
||||||
|
internal_port: 28080
|
||||||
|
env:
|
||||||
|
CUDA_VISIBLE_DEVICES: 0
|
||||||
|
HSA_OVERRIDE_GFX_VERSION: '11.0.0'
|
||||||
|
args:
|
||||||
|
model: /home/tristand/Downloads/models/Phi-3.5-mini-instruct-Q6_K_L.gguf
|
||||||
|
gpu-layers: 9999
|
||||||
|
ctx-size: 4096
|
||||||
|
vram_usage: 6G
|
||||||
|
ram_usage: 500M
|
||||||
|
- port: 18081
|
||||||
|
internal_port: 28081
|
||||||
|
env:
|
||||||
|
CUDA_VISIBLE_DEVICES: 0
|
||||||
|
HSA_OVERRIDE_GFX_VERSION: '11.0.0'
|
||||||
|
args:
|
||||||
|
model: /home/tristand/Downloads/models/Phi-3.5-mini-instruct-Q6_K_L.gguf
|
||||||
|
gpu-layers: 9999
|
||||||
|
ctx-size: 4096
|
||||||
|
vram_usage: 6G
|
||||||
|
ram_usage: 500M
|
16
llama_proxy_man/src/audit.json
Normal file
16
llama_proxy_man/src/audit.json
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
{
|
||||||
|
"keepSettings": {
|
||||||
|
"type": 1,
|
||||||
|
"amount": 30
|
||||||
|
},
|
||||||
|
"auditFilename": "audit.json",
|
||||||
|
"hashType": "md5",
|
||||||
|
"extension": ".log",
|
||||||
|
"files": [
|
||||||
|
{
|
||||||
|
"date": 1726742235723,
|
||||||
|
"name": "/home/tristand/.tabby-client/agent/logs/20240919.0.log",
|
||||||
|
"hash": "13392f16f09c9e264d7c9b82880ae40c"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
83
llama_proxy_man/src/logging.rs
Normal file
83
llama_proxy_man/src/logging.rs
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
use std::{
|
||||||
|
future::Future,
|
||||||
|
pin::Pin,
|
||||||
|
sync::Arc,
|
||||||
|
task::{Context, Poll},
|
||||||
|
};
|
||||||
|
|
||||||
|
use axum::{body::Body, http::Request};
|
||||||
|
use pin_project_lite::pin_project;
|
||||||
|
use tower::{Layer, Service};
|
||||||
|
use uuid::Uuid; // Make sure to include `uuid` crate in your Cargo.toml
|
||||||
|
|
||||||
|
pub struct LoggingLayer;
|
||||||
|
|
||||||
|
impl<S> Layer<S> for LoggingLayer {
|
||||||
|
type Service = LoggingService<S>;
|
||||||
|
|
||||||
|
fn layer(&self, inner: S) -> Self::Service {
|
||||||
|
LoggingService { inner }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct LoggingService<T> {
|
||||||
|
inner: T,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Service<Request<Body>> for LoggingService<T>
|
||||||
|
where
|
||||||
|
T: Service<Request<Body>>,
|
||||||
|
{
|
||||||
|
type Error = T::Error;
|
||||||
|
type Future = LoggingServiceFuture<T::Future>;
|
||||||
|
type Response = T::Response;
|
||||||
|
|
||||||
|
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||||
|
self.inner.poll_ready(cx)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn call(&mut self, req: Request<Body>) -> Self::Future {
|
||||||
|
let request_uuid = Uuid::now_v7(); // Generate UUID v7
|
||||||
|
|
||||||
|
tracing::info!("[{}] {} {}", request_uuid, req.method(), req.uri());
|
||||||
|
for (k, v) in req.headers() {
|
||||||
|
tracing::info!(
|
||||||
|
"[{}] {}: {}",
|
||||||
|
request_uuid,
|
||||||
|
k,
|
||||||
|
v.to_str().unwrap_or("invalid header")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
LoggingServiceFuture {
|
||||||
|
inner: self.inner.call(req),
|
||||||
|
uuid: Arc::new(request_uuid), // Store UUID in an Arc for shared ownership
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pin_project! {
|
||||||
|
pub struct LoggingServiceFuture<T> {
|
||||||
|
#[pin]
|
||||||
|
inner: T,
|
||||||
|
uuid: Arc<Uuid>, // Shared state between LoggingService and LoggingServiceFuture
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Future for LoggingServiceFuture<T>
|
||||||
|
where
|
||||||
|
T: Future,
|
||||||
|
{
|
||||||
|
type Output = T::Output;
|
||||||
|
|
||||||
|
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||||
|
let this = self.project();
|
||||||
|
match this.inner.poll(cx) {
|
||||||
|
Poll::Pending => Poll::Pending,
|
||||||
|
Poll::Ready(output) => {
|
||||||
|
tracing::trace!("[{}] request finished", this.uuid);
|
||||||
|
Poll::Ready(output)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
363
llama_proxy_man/src/main.rs
Normal file
363
llama_proxy_man/src/main.rs
Normal file
|
@ -0,0 +1,363 @@
|
||||||
|
mod logging;
|
||||||
|
|
||||||
|
use anyhow::anyhow;
|
||||||
|
use axum::{
|
||||||
|
body::Body,
|
||||||
|
http::{self, Request, Response},
|
||||||
|
response::IntoResponse,
|
||||||
|
routing::any,
|
||||||
|
Router,
|
||||||
|
};
|
||||||
|
use futures;
|
||||||
|
use reqwest::Client;
|
||||||
|
use serde::Deserialize;
|
||||||
|
use std::{collections::HashMap, net::SocketAddr, process::Stdio, sync::Arc};
|
||||||
|
use tokio::{
|
||||||
|
net::TcpStream,
|
||||||
|
process::{Child, Command},
|
||||||
|
sync::Mutex,
|
||||||
|
time::{sleep, Duration},
|
||||||
|
};
|
||||||
|
use tower_http::trace::{
|
||||||
|
DefaultMakeSpan, DefaultOnEos, DefaultOnFailure, DefaultOnRequest, DefaultOnResponse,
|
||||||
|
TraceLayer,
|
||||||
|
};
|
||||||
|
use tracing::Level;
|
||||||
|
|
||||||
|
use std::sync::Once;
|
||||||
|
|
||||||
|
pub static INIT: Once = Once::new();
|
||||||
|
|
||||||
|
pub fn initialize_logger() {
|
||||||
|
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()
|
||||||
|
.compact()
|
||||||
|
.with_env_filter(env_filter)
|
||||||
|
.init();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
struct Config {
|
||||||
|
hardware: Hardware,
|
||||||
|
models: Vec<ModelConfig>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
struct Hardware {
|
||||||
|
ram: String,
|
||||||
|
vram: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Clone)]
|
||||||
|
struct ModelConfig {
|
||||||
|
port: u16,
|
||||||
|
internal_port: u16,
|
||||||
|
env: HashMap<String, String>,
|
||||||
|
args: HashMap<String, String>,
|
||||||
|
vram_usage: String,
|
||||||
|
ram_usage: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct LlamaInstance {
|
||||||
|
config: ModelConfig,
|
||||||
|
process: Arc<Mutex<Child>>,
|
||||||
|
// busy: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SharedState {
|
||||||
|
total_ram: u64,
|
||||||
|
total_vram: u64,
|
||||||
|
used_ram: u64,
|
||||||
|
used_vram: u64,
|
||||||
|
instances: HashMap<u16, LlamaInstance>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
async fn main() {
|
||||||
|
initialize_logger();
|
||||||
|
// Read and parse the YAML configuration
|
||||||
|
let config_str = std::fs::read_to_string("config.yaml").expect("Failed to read config.yaml");
|
||||||
|
let config: Config = serde_yaml::from_str(&config_str).expect("Failed to parse config.yaml");
|
||||||
|
|
||||||
|
// Parse hardware resources
|
||||||
|
let total_ram = parse_size(&config.hardware.ram).expect("Invalid RAM size in config");
|
||||||
|
let total_vram = parse_size(&config.hardware.vram).expect("Invalid VRAM size in config");
|
||||||
|
|
||||||
|
// Initialize shared state
|
||||||
|
let shared_state = Arc::new(Mutex::new(SharedState {
|
||||||
|
total_ram,
|
||||||
|
total_vram,
|
||||||
|
used_ram: 0,
|
||||||
|
used_vram: 0,
|
||||||
|
instances: HashMap::new(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
// For each model, set up an axum server listening on the specified port
|
||||||
|
let mut handles = Vec::new();
|
||||||
|
|
||||||
|
for model_config in config.models {
|
||||||
|
let state = shared_state.clone();
|
||||||
|
let model_config = model_config.clone();
|
||||||
|
|
||||||
|
let handle = tokio::spawn(async move {
|
||||||
|
let model_config = model_config.clone();
|
||||||
|
|
||||||
|
let app = Router::new()
|
||||||
|
.route(
|
||||||
|
"/",
|
||||||
|
any({
|
||||||
|
let state = state.clone();
|
||||||
|
let model_config = model_config.clone();
|
||||||
|
move |req| handle_request(req, model_config, state)
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.route(
|
||||||
|
"/*path",
|
||||||
|
any({
|
||||||
|
let state = state.clone();
|
||||||
|
let model_config = model_config.clone();
|
||||||
|
move |req| handle_request(req, model_config, state)
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.layer(
|
||||||
|
TraceLayer::new_for_http()
|
||||||
|
.make_span_with(DefaultMakeSpan::new().include_headers(true))
|
||||||
|
.on_request(DefaultOnRequest::new().level(Level::DEBUG))
|
||||||
|
.on_response(DefaultOnResponse::new().level(Level::TRACE))
|
||||||
|
.on_eos(DefaultOnEos::new().level(Level::DEBUG))
|
||||||
|
.on_failure(DefaultOnFailure::new().level(Level::ERROR)),
|
||||||
|
);
|
||||||
|
|
||||||
|
let addr = SocketAddr::from(([0, 0, 0, 0], model_config.port));
|
||||||
|
|
||||||
|
println!("Listening on port {}", model_config.port);
|
||||||
|
let listener = tokio::net::TcpListener::bind(&addr).await.unwrap();
|
||||||
|
|
||||||
|
axum::serve(listener, app.into_make_service())
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
});
|
||||||
|
|
||||||
|
handles.push(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
futures::future::join_all(handles).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
|
#[derive(Error, Debug)]
|
||||||
|
pub enum AppError {
|
||||||
|
#[error("Axum Error")]
|
||||||
|
AxumError(#[from] axum::Error),
|
||||||
|
#[error("Axum Http Error")]
|
||||||
|
AxumHttpError(#[from] axum::http::Error),
|
||||||
|
#[error("Reqwest Error")]
|
||||||
|
ReqwestError(#[from] reqwest::Error),
|
||||||
|
#[error("Reqwest Middleware Error")]
|
||||||
|
ReqwestMiddlewareError(#[from] reqwest_middleware::Error),
|
||||||
|
#[error("Client Error")]
|
||||||
|
ClientError(#[from] hyper::Error),
|
||||||
|
#[error("Unknown error")]
|
||||||
|
Unknown(#[from] anyhow::Error),
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tell axum how to convert `AppError` into a response.
|
||||||
|
impl IntoResponse for AppError {
|
||||||
|
fn into_response(self) -> axum::response::Response {
|
||||||
|
tracing::error!("::AppError::into_response:: {:?}", self);
|
||||||
|
(
|
||||||
|
http::StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
format!("Something went wrong: {:?}", self),
|
||||||
|
)
|
||||||
|
.into_response()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn handle_request(
|
||||||
|
req: Request<Body>,
|
||||||
|
model_config: ModelConfig,
|
||||||
|
state: Arc<Mutex<SharedState>>,
|
||||||
|
// ) -> Result<Response<Body>, anyhow::Error> {
|
||||||
|
) -> impl IntoResponse {
|
||||||
|
let model_ram_usage = parse_size(&model_config.ram_usage).expect("Invalid ram_usage");
|
||||||
|
let model_vram_usage = parse_size(&model_config.vram_usage).expect("Invalid vram_usage");
|
||||||
|
|
||||||
|
let instance = {
|
||||||
|
let mut state = state.lock().await;
|
||||||
|
|
||||||
|
// Check if instance is running
|
||||||
|
if let Some(instance) = state.instances.get_mut(&model_config.port) {
|
||||||
|
// instance.busy = true;
|
||||||
|
instance.to_owned()
|
||||||
|
} else {
|
||||||
|
// Check resources
|
||||||
|
if state.used_ram + model_ram_usage > state.total_ram
|
||||||
|
|| state.used_vram + model_vram_usage > state.total_vram
|
||||||
|
{
|
||||||
|
// Stop other instances
|
||||||
|
let mut to_remove = Vec::new();
|
||||||
|
for (port, instance) in state.instances.clone() {
|
||||||
|
// if !instance.busy {
|
||||||
|
tracing::info!("Stopping instance on port {}", port);
|
||||||
|
let mut process = instance.process.lock().await;
|
||||||
|
process.kill().await.ok();
|
||||||
|
state.used_ram -= parse_size(&instance.config.ram_usage).unwrap_or(0);
|
||||||
|
state.used_vram -= parse_size(&instance.config.vram_usage).unwrap_or(0);
|
||||||
|
to_remove.push(port);
|
||||||
|
if state.used_ram + model_ram_usage <= state.total_ram
|
||||||
|
&& state.used_vram + model_vram_usage <= state.total_vram
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
for port in to_remove {
|
||||||
|
tracing::info!("Removing instance on port {}", port);
|
||||||
|
state.instances.remove(&port);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start new instance
|
||||||
|
let args = model_config
|
||||||
|
.args
|
||||||
|
.iter()
|
||||||
|
.flat_map(|(k, v)| vec![format!("--{}", k), v.clone()])
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
let mut cmd = Command::new("llama-server");
|
||||||
|
cmd.envs(model_config.env.clone());
|
||||||
|
cmd.args(&args);
|
||||||
|
cmd.arg("--port");
|
||||||
|
cmd.arg(format!("{}", model_config.internal_port));
|
||||||
|
cmd.stdout(Stdio::null()).stderr(Stdio::null());
|
||||||
|
|
||||||
|
tracing::info!("Starting llama-server with {:?}", cmd);
|
||||||
|
let process = Arc::new(Mutex::new(
|
||||||
|
cmd.spawn().expect("Failed to start llama-server"),
|
||||||
|
));
|
||||||
|
|
||||||
|
state.used_ram += model_ram_usage;
|
||||||
|
state.used_vram += model_vram_usage;
|
||||||
|
|
||||||
|
let instance = LlamaInstance {
|
||||||
|
config: model_config.clone(),
|
||||||
|
process,
|
||||||
|
// busy: true,
|
||||||
|
};
|
||||||
|
sleep(Duration::from_millis(500)).await;
|
||||||
|
state.instances.insert(model_config.port, instance.clone());
|
||||||
|
|
||||||
|
instance
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Wait for the instance to be ready
|
||||||
|
is_llama_instance_running(&instance).await?;
|
||||||
|
wait_for_port(model_config.internal_port).await?;
|
||||||
|
|
||||||
|
// Proxy the request
|
||||||
|
let retry_policy = reqwest_retry::policies::ExponentialBackoff::builder()
|
||||||
|
.retry_bounds(Duration::from_secs(1), Duration::from_secs(8))
|
||||||
|
.jitter(reqwest_retry::Jitter::None)
|
||||||
|
.base(2)
|
||||||
|
.build_with_max_retries(8);
|
||||||
|
|
||||||
|
let client = reqwest_middleware::ClientBuilder::new(Client::new())
|
||||||
|
.with(reqwest_retry::RetryTransientMiddleware::new_with_policy(
|
||||||
|
retry_policy,
|
||||||
|
))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let uri = format!(
|
||||||
|
"http://127.0.0.1:{}{}",
|
||||||
|
model_config.internal_port,
|
||||||
|
req.uri().path_and_query().map(|x| x.as_str()).unwrap_or("")
|
||||||
|
);
|
||||||
|
|
||||||
|
let mut request_builder = client.request(req.method().clone(), &uri);
|
||||||
|
// let mut request_builder = reqwest::RequestBuilder::from_parts(client, req.method().clone())
|
||||||
|
|
||||||
|
for (name, value) in req.headers() {
|
||||||
|
request_builder = request_builder.header(name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
let body_bytes = axum::body::to_bytes(
|
||||||
|
req.into_body(),
|
||||||
|
parse_size("1G").unwrap().try_into().unwrap(),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
let request = request_builder.body(body_bytes).build()?;
|
||||||
|
// tracing::info!("Proxying request to {}", uri);
|
||||||
|
let response = client.execute(request).await?;
|
||||||
|
|
||||||
|
// tracing::info!("Received response from {}", uri);
|
||||||
|
let mut builder = Response::builder().status(response.status());
|
||||||
|
for (name, value) in response.headers() {
|
||||||
|
builder = builder.header(name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// let bytes = response.bytes().await?;
|
||||||
|
|
||||||
|
let byte_stream = response.bytes_stream();
|
||||||
|
|
||||||
|
let body = axum::body::Body::from_stream(byte_stream);
|
||||||
|
|
||||||
|
tracing::info!("streaming response on port: {}", model_config.port);
|
||||||
|
let response = builder.body(body)?;
|
||||||
|
Ok::<axum::http::Response<Body>, AppError>(response)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn wait_for_port(port: u16) -> Result<(), anyhow::Error> {
|
||||||
|
for _ in 0..10 {
|
||||||
|
if TcpStream::connect(("127.0.0.1", port)).await.is_ok() {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
sleep(Duration::from_millis(500)).await;
|
||||||
|
}
|
||||||
|
Err(anyhow!("Timeout waiting for port"))
|
||||||
|
}
|
||||||
|
|
||||||
|
// reimplement wait_for_port using a LlamaInstance, also check if the process is still running
|
||||||
|
async fn is_llama_instance_running(instance: &LlamaInstance) -> Result<(), anyhow::Error> {
|
||||||
|
match instance.process.to_owned().lock_owned().await.try_wait()? {
|
||||||
|
Some(exit_status) => {
|
||||||
|
let msg = "Llama instance exited";
|
||||||
|
tracing::error!(msg, ?exit_status);
|
||||||
|
Err(anyhow!(msg))
|
||||||
|
}
|
||||||
|
|
||||||
|
None => Ok(()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_size(size_str: &str) -> Option<u64> {
|
||||||
|
let mut num = String::new();
|
||||||
|
let mut unit = String::new();
|
||||||
|
|
||||||
|
for c in size_str.chars() {
|
||||||
|
if c.is_digit(10) {
|
||||||
|
num.push(c);
|
||||||
|
} else {
|
||||||
|
unit.push(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let num: f64 = num.parse().ok()?;
|
||||||
|
|
||||||
|
let multiplier = match unit.to_lowercase().as_str() {
|
||||||
|
"g" | "gb" => 1024 * 1024 * 1024,
|
||||||
|
"m" | "mb" => 1024 * 1024,
|
||||||
|
"k" | "kb" => 1024,
|
||||||
|
_ => 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
let res = (num * multiplier as f64) as u64;
|
||||||
|
Some(res)
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue