dependencies delete aha_openai_dive,chrono

This commit is contained in:
jhqxxx
2026-03-31 12:30:12 +08:00
parent 363833d8fb
commit 3e510a4172
64 changed files with 1076 additions and 422 deletions
Generated
+9 -348
View File
@@ -23,7 +23,6 @@ dependencies = [
name = "aha"
version = "0.2.4"
dependencies = [
"aha_openai_dive",
"ahash",
"anyhow",
"base64 0.22.1",
@@ -32,8 +31,8 @@ dependencies = [
"candle-flash-attn",
"candle-nn",
"candle-transformers",
"chrono",
"clap",
"derive_builder",
"dirs",
"ffmpeg-next",
"half",
@@ -44,7 +43,7 @@ dependencies = [
"num",
"rayon",
"realfft",
"reqwest 0.13.2",
"reqwest",
"rocket",
"sentencepiece",
"serde",
@@ -59,25 +58,6 @@ dependencies = [
"zip",
]
[[package]]
name = "aha_openai_dive"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06be555744ef37a775e05d920ac6d4e0c5765fdc00a12cd8e221b3a1f2eaf982"
dependencies = [
"bytes",
"derive_builder",
"futures",
"reqwest 0.12.28",
"reqwest-eventsource",
"serde",
"serde_html_form",
"serde_json",
"tokio",
"tokio-stream",
"tokio-util",
]
[[package]]
name = "ahash"
version = "0.8.12"
@@ -125,15 +105,6 @@ version = "0.2.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
[[package]]
name = "android_system_properties"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
dependencies = [
"libc",
]
[[package]]
name = "anstream"
version = "1.0.0"
@@ -509,9 +480,6 @@ name = "bytes"
version = "1.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33"
dependencies = [
"serde",
]
[[package]]
name = "bzip2"
@@ -693,19 +661,6 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
[[package]]
name = "chrono"
version = "0.4.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0"
dependencies = [
"iana-time-zone",
"js-sys",
"num-traits",
"wasm-bindgen",
"windows-link",
]
[[package]]
name = "cipher"
version = "0.4.4"
@@ -1286,17 +1241,6 @@ dependencies = [
"cc",
]
[[package]]
name = "eventsource-stream"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74fef4569247a5f429d9156b9d0a2599914385dd189c539334c625d8099d90ab"
dependencies = [
"futures-core",
"nom 7.1.3",
"pin-project-lite",
]
[[package]]
name = "exr"
version = "1.74.0"
@@ -1460,15 +1404,6 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb"
[[package]]
name = "foreign-types"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
dependencies = [
"foreign-types-shared 0.1.1",
]
[[package]]
name = "foreign-types"
version = "0.5.0"
@@ -1476,7 +1411,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965"
dependencies = [
"foreign-types-macros",
"foreign-types-shared 0.3.1",
"foreign-types-shared",
]
[[package]]
@@ -1490,12 +1425,6 @@ dependencies = [
"syn",
]
[[package]]
name = "foreign-types-shared"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
[[package]]
name = "foreign-types-shared"
version = "0.3.1"
@@ -1525,7 +1454,6 @@ checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d"
dependencies = [
"futures-channel",
"futures-core",
"futures-executor",
"futures-io",
"futures-sink",
"futures-task",
@@ -1548,17 +1476,6 @@ version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d"
[[package]]
name = "futures-executor"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d"
dependencies = [
"futures-core",
"futures-task",
"futures-util",
]
[[package]]
name = "futures-io"
version = "0.3.32"
@@ -1588,12 +1505,6 @@ version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393"
[[package]]
name = "futures-timer"
version = "3.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24"
[[package]]
name = "futures-util"
version = "0.3.32"
@@ -2159,22 +2070,6 @@ dependencies = [
"tower-service",
]
[[package]]
name = "hyper-tls"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0"
dependencies = [
"bytes",
"http-body-util",
"hyper 1.8.1",
"hyper-util",
"native-tls",
"tokio",
"tokio-native-tls",
"tower-service",
]
[[package]]
name = "hyper-util"
version = "0.1.20"
@@ -2200,30 +2095,6 @@ dependencies = [
"windows-registry",
]
[[package]]
name = "iana-time-zone"
version = "0.1.65"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470"
dependencies = [
"android_system_properties",
"core-foundation-sys",
"iana-time-zone-haiku",
"js-sys",
"log",
"wasm-bindgen",
"windows-core 0.62.2",
]
[[package]]
name = "iana-time-zone-haiku"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
dependencies = [
"cc",
]
[[package]]
name = "icu_collections"
version = "2.1.1"
@@ -2745,7 +2616,7 @@ dependencies = [
"bitflags 2.11.0",
"block",
"core-graphics-types",
"foreign-types 0.5.0",
"foreign-types",
"log",
"objc",
"paste",
@@ -2757,16 +2628,6 @@ version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
[[package]]
name = "mime_guess"
version = "2.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e"
dependencies = [
"mime",
"unicase",
]
[[package]]
name = "minijinja"
version = "2.17.1"
@@ -2813,7 +2674,7 @@ dependencies = [
"clap",
"futures-util",
"indicatif",
"reqwest 0.13.2",
"reqwest",
"serde",
"serde_json",
"tokio",
@@ -2870,23 +2731,6 @@ dependencies = [
"version_check",
]
[[package]]
name = "native-tls"
version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "465500e14ea162429d264d44189adc38b199b62b1c21eea9f69e4b73cb03bbf2"
dependencies = [
"libc",
"log",
"openssl",
"openssl-probe",
"openssl-sys",
"schannel",
"security-framework",
"security-framework-sys",
"tempfile",
]
[[package]]
name = "new_debug_unreachable"
version = "1.0.6"
@@ -3134,50 +2978,12 @@ dependencies = [
"pkg-config",
]
[[package]]
name = "openssl"
version = "0.10.76"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "951c002c75e16ea2c65b8c7e4d3d51d5530d8dfa7d060b4776828c88cfb18ecf"
dependencies = [
"bitflags 2.11.0",
"cfg-if",
"foreign-types 0.3.2",
"libc",
"once_cell",
"openssl-macros",
"openssl-sys",
]
[[package]]
name = "openssl-macros"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "openssl-probe"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe"
[[package]]
name = "openssl-sys"
version = "0.9.112"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57d55af3b3e226502be1526dfdba67ab0e9c96fc293004e79576b2b9edb0dbdb"
dependencies = [
"cc",
"libc",
"pkg-config",
"vcpkg",
]
[[package]]
name = "option-ext"
version = "0.2.0"
@@ -3802,46 +3608,6 @@ version = "0.8.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a"
[[package]]
name = "reqwest"
version = "0.12.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147"
dependencies = [
"base64 0.22.1",
"bytes",
"futures-core",
"futures-util",
"http 1.4.0",
"http-body 1.0.1",
"http-body-util",
"hyper 1.8.1",
"hyper-tls",
"hyper-util",
"js-sys",
"log",
"mime_guess",
"native-tls",
"percent-encoding",
"pin-project-lite",
"rustls-pki-types",
"serde",
"serde_json",
"serde_urlencoded",
"sync_wrapper",
"tokio",
"tokio-native-tls",
"tokio-util",
"tower",
"tower-http",
"tower-service",
"url",
"wasm-bindgen",
"wasm-bindgen-futures",
"wasm-streams 0.4.2",
"web-sys",
]
[[package]]
name = "reqwest"
version = "0.13.2"
@@ -3884,26 +3650,10 @@ dependencies = [
"url",
"wasm-bindgen",
"wasm-bindgen-futures",
"wasm-streams 0.5.0",
"wasm-streams",
"web-sys",
]
[[package]]
name = "reqwest-eventsource"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "632c55746dbb44275691640e7b40c907c16a2dc1a5842aa98aaec90da6ec6bde"
dependencies = [
"eventsource-stream",
"futures-core",
"futures-timer",
"mime",
"nom 7.1.3",
"pin-project-lite",
"reqwest 0.12.28",
"thiserror 1.0.69",
]
[[package]]
name = "rgb"
version = "0.8.53"
@@ -4268,19 +4018,6 @@ dependencies = [
"syn",
]
[[package]]
name = "serde_html_form"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b2f2d7ff8a2140333718bb329f5c40fc5f0865b84c426183ce14c97d2ab8154f"
dependencies = [
"form_urlencoded",
"indexmap",
"itoa",
"ryu",
"serde_core",
]
[[package]]
name = "serde_json"
version = "1.0.149"
@@ -4312,18 +4049,6 @@ dependencies = [
"serde",
]
[[package]]
name = "serde_urlencoded"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"
dependencies = [
"form_urlencoded",
"itoa",
"ryu",
"serde",
]
[[package]]
name = "serde_yaml"
version = "0.9.34+deprecated"
@@ -4917,16 +4642,6 @@ dependencies = [
"syn",
]
[[package]]
name = "tokio-native-tls"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2"
dependencies = [
"native-tls",
"tokio",
]
[[package]]
name = "tokio-rustls"
version = "0.26.4"
@@ -5203,12 +4918,6 @@ dependencies = [
"version_check",
]
[[package]]
name = "unicase"
version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142"
[[package]]
name = "unicode-ident"
version = "1.0.24"
@@ -5454,19 +5163,6 @@ dependencies = [
"wasmparser",
]
[[package]]
name = "wasm-streams"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65"
dependencies = [
"futures-util",
"js-sys",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
]
[[package]]
name = "wasm-streams"
version = "0.5.0"
@@ -5573,7 +5269,7 @@ version = "0.57.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "12342cb4d8e3b046f3d80effd474a7a02447231330ef77d71daa6fbc40681143"
dependencies = [
"windows-core 0.57.0",
"windows-core",
"windows-targets 0.52.6",
]
@@ -5583,25 +5279,12 @@ version = "0.57.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2ed2439a290666cd67ecce2b0ffaad89c2a56b976b736e6ece670297897832d"
dependencies = [
"windows-implement 0.57.0",
"windows-interface 0.57.0",
"windows-implement",
"windows-interface",
"windows-result 0.1.2",
"windows-targets 0.52.6",
]
[[package]]
name = "windows-core"
version = "0.62.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb"
dependencies = [
"windows-implement 0.60.2",
"windows-interface 0.59.3",
"windows-link",
"windows-result 0.4.1",
"windows-strings",
]
[[package]]
name = "windows-implement"
version = "0.57.0"
@@ -5613,17 +5296,6 @@ dependencies = [
"syn",
]
[[package]]
name = "windows-implement"
version = "0.60.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "windows-interface"
version = "0.57.0"
@@ -5635,17 +5307,6 @@ dependencies = [
"syn",
]
[[package]]
name = "windows-interface"
version = "0.59.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "windows-link"
version = "0.2.1"
+3 -2
View File
@@ -21,9 +21,9 @@ base64 = "0.22.1"
num = "0.4.3"
minijinja = "2.12.0"
tokenizers = "0.22.1"
aha_openai_dive = { version = "1.4", features = ["stream"] }
# aha_openai_dive = { version = "1.4", features = ["stream"] }
uuid = { version = "1.18.1", features = ["v4"] }
chrono = "0.4"
# chrono = "0.4"
rocket = { version = "0.5.1", features = ["serde_json", "json"] }
tokio = "1.47.1"
hound = "3.5.1"
@@ -43,6 +43,7 @@ half = "2.7.1"
byteorder = "1.5.0"
sentencepiece = "0.13.1"
ahash = "0.8.12"
derive_builder = "0.20.2"
[features]
flash-attn = ["candle-flash-attn"]
+3
View File
@@ -25,6 +25,9 @@
aha is a high-performance, cross-platform AI inference engine built with Rust and the Candle framework. It brings state-of-the-art AI models to your local machine—no API keys, no cloud dependencies, just pure, fast AI running directly on your hardware.
## Changelog
### 2026-03-31
- dependencies delete aha_openai_dive,chrono
### v0.2.5 (2026-03-30)
- add LFM2.5VL-1.6B
- add LFM2VL-1.6B
+3
View File
@@ -25,6 +25,9 @@
aha 是一款基于 Rust 和 Candle 框架构建的高性能跨平台 AI 推理引擎。将最先进的 AI 模型带到您的本地机器——无需 API 密钥,无需云依赖,纯粹、快速的 AI,直接在您的硬件上运行。
## 更新日志
### 2026-03-31
- 删除 aha_openai_dive,chrono 依赖
### v0.2.5 (2026-03-30)
- 新增 LFM2.5VL-1.6B
- 新增 LFM2VL-1.6B
+3
View File
@@ -5,6 +5,9 @@ All notable changes to aha will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
### 2026-03-31
- dependencies delete aha_openai_dive,chrono
### v0.2.5 (2026-03-30)
- add LFM2.5VL-1.6B
- add LFM2VL-1.6B
+3
View File
@@ -5,6 +5,9 @@
格式基于 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.0.0/)
本项目遵循 [语义化版本](https://semver.org/lang/zh-CN/spec/v2.0.0.html)。
### 2026-03-31
- 删除 aha_openai_dive,chrono 依赖
### v0.2.5 (2026-03-30)
- 新增 LFM2.5VL-1.6B
- 新增 LFM2VL-1.6B
+3 -3
View File
@@ -1,12 +1,12 @@
// OpenAI-compatible ASR (Automatic Speech Recognition) API endpoint
// Implements POST /audio/transcriptions and /v1/audio/transcriptions
use aha::models::GenerateModel;
use aha::utils::{clean_asr_response, map_language_code};
use aha_openai_dive::v1::resources::chat::{
use aha::params::chat::{
AudioUrlType, ChatCompletionParameters, ChatMessage, ChatMessageAudioContentPart,
ChatMessageContent, ChatMessageContentPart,
};
use aha::models::GenerateModel;
use aha::utils::{clean_asr_response, map_language_code};
use rocket::http::Status;
use rocket::serde::json::Json;
use rocket::{form::Form, post};
+1 -1
View File
@@ -2,10 +2,10 @@ use std::pin::pin;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Arc, OnceLock};
use aha::params::chat::ChatCompletionParameters;
use aha::models::{GenerateModel, ModelInstance, WhichModel, load_model};
use aha::process::cleanup_pid_file;
use aha::utils::string_to_static_str;
use aha_openai_dive::v1::resources::chat::ChatCompletionParameters;
use rocket::futures::StreamExt;
use rocket::serde::{Serialize, json::Json};
use rocket::{
+1 -1
View File
@@ -1,4 +1,4 @@
use aha_openai_dive::v1::resources::chat::ChatCompletionParameters;
use crate::params::chat::ChatCompletionParameters;
use anyhow::{Result, anyhow};
use minijinja::{Environment, Value as MiniJinjaValue, context};
+1 -1
View File
@@ -5,5 +5,5 @@ pub mod position_embed;
pub mod process;
pub mod tokenizer;
pub mod utils;
pub mod params;
pub use aha_openai_dive::v1::resources::chat;
+1 -1
View File
@@ -1,4 +1,4 @@
use aha_openai_dive::v1::resources::chat::{
use crate::params::chat::{
ChatCompletionChunkResponse, ChatCompletionParameters, ChatCompletionResponse,
};
use anyhow::{Result, anyhow};
+1 -1
View File
@@ -1,4 +1,4 @@
use aha_openai_dive::v1::resources::chat::ChatCompletionParameters;
use crate::params::chat::ChatCompletionParameters;
use anyhow::Result;
use candle_core::{DType, Device, Tensor};
+1 -1
View File
@@ -1,6 +1,6 @@
use std::collections::HashMap;
use aha_openai_dive::v1::resources::chat::{
use crate::params::chat::{
ChatCompletionChunkResponse, ChatCompletionParameters, ChatCompletionResponse,
};
use anyhow::{Result, anyhow};
+1 -1
View File
@@ -1,4 +1,4 @@
use aha_openai_dive::v1::resources::chat::ChatCompletionParameters;
use crate::params::chat::ChatCompletionParameters;
use anyhow::Result;
use candle_core::{D, Device, Tensor};
+1 -1
View File
@@ -1,4 +1,4 @@
use aha_openai_dive::v1::resources::chat::{
use crate::params::chat::{
ChatCompletionChunkResponse, ChatCompletionParameters, ChatCompletionResponse,
};
use anyhow::{Result, anyhow};
+1 -1
View File
@@ -1,4 +1,4 @@
use aha_openai_dive::v1::resources::chat::ChatCompletionParameters;
use crate::params::chat::ChatCompletionParameters;
use anyhow::Result;
use candle_core::{D, DType, Device, IndexOp, Tensor};
+1 -1
View File
@@ -1,5 +1,5 @@
//! GLM-OCR Inference and Generation
use aha_openai_dive::v1::resources::chat::{
use crate::params::chat::{
ChatCompletionChunkResponse, ChatCompletionParameters, ChatCompletionResponse,
};
use anyhow::{Result, anyhow};
+1 -1
View File
@@ -1,4 +1,4 @@
use aha_openai_dive::v1::resources::chat::{
use crate::params::chat::{
ChatCompletionChunkResponse, ChatCompletionParameters, ChatCompletionResponse,
};
use anyhow::{Result, anyhow};
+1 -1
View File
@@ -1,4 +1,4 @@
use aha_openai_dive::v1::resources::chat::ChatCompletionParameters;
use crate::params::chat::ChatCompletionParameters;
use anyhow::Result;
use candle_core::{DType, Device, IndexOp, Shape, Tensor};
use image::DynamicImage;
+2 -5
View File
@@ -1,3 +1,4 @@
use crate::params::chat::{ChatCompletionParameters, ChatCompletionResponse};
use crate::utils::build_completion_chunk_response;
use crate::{
chat_template::ChatTemplate,
@@ -13,7 +14,6 @@ use crate::{
build_completion_response, find_type_files, get_device, get_dtype, get_logit_processor,
},
};
use aha_openai_dive::v1::resources::chat::{ChatCompletionParameters, ChatCompletionResponse};
use anyhow::Result;
use candle_core::{DType, Device, Tensor};
use candle_nn::VarBuilder;
@@ -109,10 +109,7 @@ impl<'a> GenerateModel for Lfm2GenerateModel<'a> {
) -> Result<
Box<
dyn rocket::futures::Stream<
Item = Result<
aha_openai_dive::v1::resources::chat::ChatCompletionChunkResponse,
anyhow::Error,
>,
Item = Result<crate::params::chat::ChatCompletionChunkResponse, anyhow::Error>,
> + Send
+ Unpin
+ '_,
+2 -5
View File
@@ -1,4 +1,4 @@
use aha_openai_dive::v1::resources::chat::{ChatCompletionParameters, ChatCompletionResponse};
use crate::params::chat::{ChatCompletionParameters, ChatCompletionResponse};
use anyhow::Result;
use candle_core::{DType, Device, Tensor};
use candle_nn::VarBuilder;
@@ -119,10 +119,7 @@ impl<'a> GenerateModel for Lfm2VLGenerateModel<'a> {
) -> Result<
Box<
dyn rocket::futures::Stream<
Item = Result<
aha_openai_dive::v1::resources::chat::ChatCompletionChunkResponse,
anyhow::Error,
>,
Item = Result<crate::params::chat::ChatCompletionChunkResponse, anyhow::Error>,
> + Send
+ Unpin
+ '_,
-2
View File
@@ -287,7 +287,6 @@ impl Lfm2VLModel {
&& let Some(shapes) = spatial_shapes
{
let image_embeds = self.vision_tower.forward(pixel, mask, shapes)?;
println!("image_embeds: {}", image_embeds);
let bs = image_embeds.dim(0)?;
let img_featrure_length = mask.sum(1)?.to_vec1::<u32>()?;
let mut image_features = vec![];
@@ -306,7 +305,6 @@ impl Lfm2VLModel {
image_features.push(img_embedding);
}
let image_embeds = Tensor::cat(&image_features, 0)?;
println!("image_embeds: {}", image_embeds);
let image_mask = get_equal_mask(input_ids, self.img_id)?;
inputs_embeds = masked_scatter_dim0(&inputs_embeds, &image_embeds, &image_mask)?;
}
+1 -1
View File
@@ -1,3 +1,4 @@
use crate::params::chat::ChatCompletionParameters;
use crate::{
models::lfm2vl::config::{Lfm2ImageConfig, Lfm2ProcessorConfig},
utils::{
@@ -8,7 +9,6 @@ use crate::{
round_by_factor,
},
};
use aha_openai_dive::v1::resources::chat::ChatCompletionParameters;
use anyhow::Result;
use candle_core::{DType, Device, Tensor};
use image::DynamicImage;
+1 -1
View File
@@ -1,4 +1,4 @@
use aha_openai_dive::v1::resources::chat::{
use crate::params::chat::{
ChatCompletionChunkResponse, ChatCompletionParameters, ChatCompletionResponse,
};
use anyhow::{Result, anyhow};
+1 -1
View File
@@ -22,7 +22,7 @@ pub mod rmbg2_0;
pub mod voxcpm;
pub mod w2v_bert_2_0;
use aha_openai_dive::v1::resources::chat::{
use crate::params::chat::{
ChatCompletionChunkResponse, ChatCompletionParameters, ChatCompletionResponse,
};
use anyhow::{Result, anyhow};
+1 -1
View File
@@ -1,4 +1,4 @@
use aha_openai_dive::v1::resources::chat::{
use crate::params::chat::{
ChatCompletionChunkResponse, ChatCompletionParameters, ChatCompletionResponse,
};
use anyhow::{Result, anyhow};
+1 -1
View File
@@ -1,4 +1,4 @@
use aha_openai_dive::v1::resources::chat::ChatCompletionParameters;
use crate::params::chat::ChatCompletionParameters;
use anyhow::Result;
use candle_core::{DType, Device, IndexOp, Shape, Tensor};
use image::DynamicImage;
+1 -1
View File
@@ -1,4 +1,4 @@
use aha_openai_dive::v1::resources::chat::{
use crate::params::chat::{
ChatCompletionChunkResponse, ChatCompletionParameters, ChatCompletionResponse,
};
use anyhow::{Result, anyhow};
+1 -1
View File
@@ -1,6 +1,6 @@
use std::collections::HashMap;
use aha_openai_dive::v1::resources::chat::{
use crate::params::chat::{
ChatCompletionParameters, ChatMessage, ChatMessageContent, ChatMessageContentPart,
};
use anyhow::{Result, anyhow};
+1 -1
View File
@@ -1,4 +1,4 @@
use aha_openai_dive::v1::resources::chat::{
use crate::params::chat::{
ChatCompletionChunkResponse, ChatCompletionParameters, ChatCompletionResponse,
};
use anyhow::{Result, anyhow};
+1 -1
View File
@@ -1,4 +1,4 @@
use aha_openai_dive::v1::resources::chat::{
use crate::params::chat::{
ChatCompletionChunkResponse, ChatCompletionParameters, ChatCompletionResponse,
};
use anyhow::{Result, anyhow};
+1 -1
View File
@@ -1,4 +1,4 @@
use aha_openai_dive::v1::resources::chat::{
use crate::params::chat::{
ChatCompletionChunkResponse, ChatCompletionParameters, ChatCompletionResponse,
};
use anyhow::{Result, anyhow};
+1 -1
View File
@@ -1,4 +1,4 @@
use aha_openai_dive::v1::resources::chat::ChatCompletionParameters;
use crate::params::chat::ChatCompletionParameters;
use anyhow::Result;
use candle_core::{Device, Tensor};
+1 -1
View File
@@ -1,4 +1,4 @@
use aha_openai_dive::v1::resources::chat::{
use crate::params::chat::{
ChatCompletionChunkResponse, ChatCompletionParameters, ChatCompletionResponse,
};
use anyhow::{Result, anyhow};
+1 -1
View File
@@ -1,6 +1,6 @@
use std::collections::HashMap;
use aha_openai_dive::v1::resources::chat::{
use crate::params::chat::{
ChatCompletionParameters, ChatMessage, ChatMessageContent, ChatMessageContentPart,
};
use anyhow::Result;
+1 -1
View File
@@ -1,6 +1,6 @@
use std::io::Cursor;
use aha_openai_dive::v1::resources::chat::{
use crate::params::chat::{
ChatCompletionChunkResponse, ChatCompletionParameters, ChatCompletionResponse,
};
use anyhow::Result;
+1 -1
View File
@@ -1,6 +1,6 @@
use std::collections::HashMap;
use aha_openai_dive::v1::resources::chat::{
use crate::params::chat::{
ChatCompletionChunkResponse, ChatCompletionParameters, ChatCompletionResponse,
};
use anyhow::{Ok, Result};
+760
View File
@@ -0,0 +1,760 @@
use super::shared::{ReasoningEffort, WebSearchContextSize};
use crate::params::shared::StopToken;
use crate::params::shared::{FinishReason, Usage};
use derive_builder::Builder;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use std::collections::HashMap;
use std::fmt::Display;
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct ChatCompletionResponse {
/// A unique identifier for the chat completion.
#[serde(skip_serializing_if = "Option::is_none")]
pub id: Option<String>,
/// A list of chat completion choices. Can be more than one if n is greater than 1.
pub choices: Vec<ChatCompletionChoice>,
/// The Unix timestamp (in seconds) of when the chat completion was created.
pub created: u32,
/// The model used for the chat completion.
pub model: String,
/// The service tier used for processing the request.
#[serde(skip_serializing_if = "Option::is_none")]
pub service_tier: Option<String>,
/// This fingerprint represents the backend configuration that the model runs with.
#[serde(skip_serializing_if = "Option::is_none")]
pub system_fingerprint: Option<String>,
/// The object type, which is always chat.completion.
pub object: String,
/// Usage statistics for the completion request.
#[serde(skip_serializing_if = "Option::is_none")]
pub usage: Option<Usage>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct ChatCompletionChunkResponse {
/// A unique identifier for the chat completion. Each chunk has the same ID.
#[serde(skip_serializing_if = "Option::is_none")]
pub id: Option<String>,
/// A list of chat completion choices. Can be more than one if n is greater than 1.
pub choices: Vec<ChatCompletionChunkChoice>,
/// The Unix timestamp (in seconds) of when the chat completion was created. Each chunk has the same timestamp.
pub created: u32,
/// The model to generate the completion.
pub model: String,
/// This fingerprint represents the backend configuration that the model runs with.
/// Can be used in conjunction with the seed request parameter to understand when backend changes have been made that might impact determinism.
#[serde(skip_serializing_if = "Option::is_none")]
pub system_fingerprint: Option<String>,
/// The object type, which is always chat.completion.chunk.
pub object: String,
/// An optional field that will only be present when you set stream_options: {"include_usage": true} in your request. When present, it contains a null value except for the last chunk which contains the token usage statistics for the entire request.
#[serde(skip_serializing_if = "Option::is_none")]
pub usage: Option<Usage>,
}
#[derive(Serialize, Deserialize, Debug, Default, Builder, Clone, PartialEq)]
#[builder(name = "ChatCompletionParametersBuilder")]
#[builder(setter(into, strip_option), default)]
pub struct ChatCompletionParameters {
/// A list of messages comprising the conversation so far.
pub messages: Vec<ChatMessage>,
/// ID of the model to use.
pub model: String,
/// Whether or not to store the output of this chat completion request for use in our model distillation or evals products.
#[serde(skip_serializing_if = "Option::is_none")]
pub store: Option<bool>,
/// Constrains effort on reasoning for reasoning models.
#[serde(skip_serializing_if = "Option::is_none")]
pub reasoning_effort: Option<ReasoningEffort>,
/// Developer-defined tags and values used for filtering completions in the dashboard.
#[serde(skip_serializing_if = "Option::is_none")]
pub metadata: Option<HashMap<String, String>>,
/// Number between -2.0 and 2.0. Positive values penalize new tokens based on their existing frequency in the text so far,
/// decreasing the model's likelihood to repeat the same line verbatim.
#[serde(skip_serializing_if = "Option::is_none")]
pub frequency_penalty: Option<f32>,
/// Modify the likelihood of specified tokens appearing in the completion.
#[serde(skip_serializing_if = "Option::is_none")]
pub logit_bias: Option<HashMap<String, i32>>,
/// Whether to return log probabilities of the output tokens or not.
/// If true, returns the log probabilities of each output token returned in the 'content' of 'message'.
#[serde(skip_serializing_if = "Option::is_none")]
pub logprobs: Option<bool>,
/// An integer between 0 and 5 specifying the number of most likely tokens to return at each token position,
/// each with an associated log probability. 'logprobs' must be set to 'true' if this parameter is used.
#[serde(skip_serializing_if = "Option::is_none")]
pub top_logprobs: Option<u32>,
/// Max completion tokens, deprecated (still used by vllm)
#[serde(skip_serializing_if = "Option::is_none")]
pub max_tokens: Option<u32>,
/// An upper bound for the number of tokens that can be generated for a completion, including visible output tokens and reasoning tokens.
#[serde(skip_serializing_if = "Option::is_none")]
pub max_completion_tokens: Option<u32>,
/// How many chat completion choices to generate for each input message.
#[serde(skip_serializing_if = "Option::is_none")]
pub n: Option<u32>,
/// Output types that you would like the model to generate for this request.
#[serde(skip_serializing_if = "Option::is_none")]
pub modalities: Option<Vec<Modality>>,
/// Configuration for a Predicted Output, which can greatly improve response times when large parts of the model response are known ahead of time.
/// This is most common when you are regenerating a file with only minor changes to most of the content.
#[serde(skip_serializing_if = "Option::is_none")]
pub prediction: Option<PredictedOutput>,
/// Parameters for audio output. Required when audio output is requested with modalities: ["audio"].
#[serde(skip_serializing_if = "Option::is_none")]
pub audio: Option<AudioParameters>,
/// Number between -2.0 and 2.0. Positive values penalize new tokens based on whether they appear in the text so far,
/// increasing the model's likelihood to talk about new topics.
#[serde(skip_serializing_if = "Option::is_none")]
pub presence_penalty: Option<f32>,
/// An object specifying the format that the model must output.
/// Compatible with GPT-4o, GPT-4o mini, GPT-4 Turbo and all GPT-3.5 Turbo models newer than gpt-3.5-turbo-1106.
/// Setting to { "type": "json_schema", "json_schema": {...} } enables Structured Outputs which ensures the model will match your supplied JSON schema.
/// Setting to { "type": "json_object" } enables JSON mode, which ensures the message the model generates is valid JSON.
#[serde(skip_serializing_if = "Option::is_none")]
pub response_format: Option<ChatCompletionResponseFormat>,
/// Deprecated (still used by vllm)
/// This feature is in Beta. If specified, our system will make a best effort to sample deterministically,
/// such that repeated requests with the same seed and parameters should return the same result.
/// Determinism is not guaranteed, and you should refer to the system_fingerprint response parameter to monitor changes in the backend.
#[serde(skip_serializing_if = "Option::is_none")]
pub seed: Option<u32>,
/// Up to 4 sequences where the API will stop generating further tokens.
#[serde(skip_serializing_if = "Option::is_none")]
pub stop: Option<StopToken>,
/// If set, partial messages will be sent, like in ChatGPT. Tokens will be sent as data-only server-sent events
/// as they become available, with the stream terminated by a data: [DONE] message.
#[serde(skip_serializing_if = "Option::is_none")]
pub stream: Option<bool>,
/// Options for streaming response. Only set this when you set stream: true.
#[serde(skip_serializing_if = "Option::is_none")]
pub stream_options: Option<ChatCompletionStreamOptions>,
/// What sampling temperature to use, between 0 and 2. Higher values like 0.8 will make the output more random,
/// while lower values like 0.2 will make it more focused and deterministic.
#[serde(skip_serializing_if = "Option::is_none")]
pub temperature: Option<f32>,
/// An alternative to sampling with temperature, called nucleus sampling, where the model considers the results of the tokens with top_p probability mass.
/// So 0.1 means only the tokens comprising the top 10% probability mass are considered.
#[serde(skip_serializing_if = "Option::is_none")]
pub top_p: Option<f32>,
/// A list of tools the model may call. Currently, only functions are supported as a tool.
/// Use this to provide a list of functions the model may generate JSON inputs for.
#[serde(skip_serializing_if = "Option::is_none")]
pub tools: Option<Vec<ChatCompletionTool>>,
/// Controls which (if any) tool is called by the model. none means the model will not call any tool and instead generates a message.
/// auto means the model can pick between generating a message or calling one or more tools.
/// required means the model must call one or more tools.
/// Specifying a particular tool via {"type": "function", "function": {"name": "my_function"}} forces the model to call that tool.
#[serde(skip_serializing_if = "Option::is_none")]
pub tool_choice: Option<ChatCompletionToolChoice>,
/// Whether to enable parallel function calling during tool use.
#[serde(skip_serializing_if = "Option::is_none")]
pub parallel_tool_calls: Option<bool>,
/// A stable identifier used to help detect users of your application that may be violating OpenAI's usage policies.
#[serde(skip_serializing_if = "Option::is_none")]
pub safety_identifier: Option<String>,
/// Used by OpenAI to cache responses for similar requests to optimize your cache hit rates.
#[serde(skip_serializing_if = "Option::is_none")]
pub prompt_cache_key: Option<String>,
/// This tool searches the web for relevant results to use in a response.
#[serde(skip_serializing_if = "Option::is_none")]
pub web_search_options: Option<WebSearchOptions>,
/// Allows to pass arbitrary json as an extra_body parameter, for specific features/openai-compatible endpoints.
#[serde(flatten)]
#[serde(skip_serializing_if = "Option::is_none")]
pub extra_body: Option<Value>,
/// Azure OpenAI and some other providers may require special query parameters to be set on the request URL.
/// This field allows you to specify those query parameters.
#[serde(skip_serializing_if = "Option::is_none")]
pub query_params: Option<HashMap<String, String>>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct ChatCompletionStreamOptions {
/// If set, an additional chunk will be streamed before the data: [DONE] message.
pub include_usage: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub continuous_usage_stats: Option<bool>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct ChatCompletionToolChoiceFunction {
/// The type of the tool. Currently, only 'function' is supported.
#[serde(skip_serializing_if = "Option::is_none")]
pub r#type: Option<ChatCompletionToolType>,
/// Name of the function.
pub function: ChatCompletionToolChoiceFunctionName,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct ChatCompletionToolChoiceFunctionName {
/// Name of the function.
pub name: String,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct ChatCompletionFunction {
/// Name of the function.
pub name: String,
/// Optional description of the function.
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
/// The parameters the function takes. The model will generate JSON inputs for these parameters.
pub parameters: serde_json::Value,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum ChatCompletionResponseFormat {
Text,
JsonObject,
JsonSchema { json_schema: JsonSchema },
}
#[derive(Serialize, Deserialize, Debug, Default, Builder, Clone, PartialEq)]
#[builder(name = "JsonSchemaBuilder")]
#[builder(setter(into, strip_option), default)]
pub struct JsonSchema {
/// A description of what the response format is for, used by the model to determine how to respond in the format.
#[serde(skip_serializing_if = "Option::is_none")]
description: Option<String>,
/// The name of the response format. Must be a-z, A-Z, 0-9, or contain underscores and dashes, with a maximum length of 64.
name: String,
/// The schema for the response format, described as a JSON Schema object.
#[serde(skip_serializing_if = "Option::is_none")]
schema: Option<serde_json::Value>,
/// Whether to enable strict schema adherence when generating the output.
#[serde(skip_serializing_if = "Option::is_none")]
strict: Option<bool>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct ChatCompletionTool {
/// The type of the tool. Currently, only 'function' is supported.
pub r#type: ChatCompletionToolType,
/// The name of the function to call.
pub function: ChatCompletionFunction,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
#[serde(tag = "role", rename_all = "snake_case")]
pub enum ChatMessage {
Developer {
/// The contents of the developer message.
content: ChatMessageContent,
/// An optional name for the participant. Provides the model information to differentiate between participants of the same role.
#[serde(skip_serializing_if = "Option::is_none")]
name: Option<String>,
},
System {
/// The contents of the system message.
content: ChatMessageContent,
/// An optional name for the participant. Provides the model information to differentiate between participants of the same role.
#[serde(skip_serializing_if = "Option::is_none")]
name: Option<String>,
},
User {
/// The contents of the user message.
content: ChatMessageContent,
/// An optional name for the participant. Provides the model information to differentiate between participants of the same role.
#[serde(skip_serializing_if = "Option::is_none")]
name: Option<String>,
},
Assistant {
/// The contents of the assistant message. Required unless tool_calls is specified.
#[serde(skip_serializing_if = "Option::is_none")]
content: Option<ChatMessageContent>,
/// The reasoning content by the assistant. (DeepSeek API only)
#[serde(skip_serializing_if = "Option::is_none")]
reasoning_content: Option<String>,
/// The refusal message by the assistant.
#[serde(skip_serializing_if = "Option::is_none")]
refusal: Option<String>,
/// An optional name for the participant. Provides the model information to differentiate between participants of the same role.
#[serde(skip_serializing_if = "Option::is_none")]
name: Option<String>,
/// Data about a previous audio response from the model.
#[serde(skip_serializing_if = "Option::is_none")]
audio: Option<AudioDataIdParameter>,
/// The tool calls generated by the model, such as function calls.
#[serde(skip_serializing_if = "Option::is_none")]
tool_calls: Option<Vec<ToolCall>>,
},
Tool {
/// The contents of the tool message.
content: ChatMessageContent,
/// Tool call that this message is responding to.
tool_call_id: String,
},
}
impl ChatMessage {
/// Get the ChatMessageContent data, if it exists.
pub fn message(&self) -> Option<&ChatMessageContent> {
match self {
ChatMessage::Developer { content, .. }
| ChatMessage::System { content, .. }
| ChatMessage::User { content, .. }
| ChatMessage::Assistant {
content: Some(content),
..
} => Some(content),
ChatMessage::Assistant { content: None, .. } => None,
ChatMessage::Tool { .. } => None,
}
}
/// Get the content of the message as text, if it is a simple text message.
pub fn text(&self) -> Option<&str> {
match self {
ChatMessage::Developer { content, .. }
| ChatMessage::System { content, .. }
| ChatMessage::User { content, .. }
| ChatMessage::Tool { content, .. }
| ChatMessage::Assistant {
content: Some(content),
..
} => {
if let ChatMessageContent::Text(text) = content {
Some(text)
} else {
None
}
}
ChatMessage::Assistant { content: None, .. } => None,
}
}
/// Get the name of the message sender, if it exists.
pub fn name(&self) -> Option<&str> {
match self {
ChatMessage::Developer { name, .. }
| ChatMessage::System { name, .. }
| ChatMessage::User { name, .. }
| ChatMessage::Assistant { name, .. } => name.as_deref(),
ChatMessage::Tool { .. } => None,
}
}
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
#[serde(tag = "role", rename_all = "snake_case")]
pub enum DeltaChatMessage {
Developer {
/// The contents of the developer message.
content: ChatMessageContent,
/// An optional name for the participant. Provides the model information to differentiate between participants of the same role.
#[serde(skip_serializing_if = "Option::is_none")]
name: Option<String>,
},
System {
/// The contents of the system message.
content: ChatMessageContent,
/// An optional name for the participant. Provides the model information to differentiate between participants of the same role.
#[serde(skip_serializing_if = "Option::is_none")]
name: Option<String>,
},
User {
/// The contents of the user message.
content: ChatMessageContent,
/// An optional name for the participant. Provides the model information to differentiate between participants of the same role.
#[serde(skip_serializing_if = "Option::is_none")]
name: Option<String>,
},
Assistant {
/// The contents of the assistant message. Required unless tool_calls is specified.
#[serde(skip_serializing_if = "Option::is_none")]
content: Option<ChatMessageContent>,
/// The reasoning content by the assistant. (DeepSeek API only)
#[serde(skip_serializing_if = "Option::is_none")]
reasoning_content: Option<String>,
/// The refusal message by the assistant.
#[serde(skip_serializing_if = "Option::is_none")]
refusal: Option<String>,
/// An optional name for the participant. Provides the model information to differentiate between participants of the same role.
#[serde(skip_serializing_if = "Option::is_none")]
name: Option<String>,
/// The tool calls generated by the model, such as function calls.
#[serde(skip_serializing_if = "Option::is_none")]
tool_calls: Option<Vec<DeltaToolCall>>,
},
Tool {
/// The contents of the tool message.
content: String,
/// Tool call that this message is responding to.
tool_call_id: String,
},
#[serde(untagged)]
Untagged {
#[serde(skip_serializing_if = "Option::is_none")]
content: Option<ChatMessageContent>,
#[serde(skip_serializing_if = "Option::is_none")]
reasoning_content: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
refusal: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
tool_calls: Option<Vec<DeltaToolCall>>,
#[serde(skip_serializing_if = "Option::is_none")]
tool_call_id: Option<String>,
},
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct ToolCall {
/// The ID of the tool call.
pub id: String,
/// The type of the tool. Currently, only function is supported.
pub r#type: String,
/// The function that the model called.
pub function: Function,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct DeltaToolCall {
/// The index of the tool call in the list of tool calls.
#[serde(skip_serializing_if = "Option::is_none")]
pub index: Option<u32>,
/// /// The ID of the tool call.
#[serde(skip_serializing_if = "Option::is_none")]
pub id: Option<String>,
/// The type of the tool. Currently, only 'function' is supported.
#[serde(skip_serializing_if = "Option::is_none")]
pub r#type: Option<String>,
/// The function that the model called.
pub function: DeltaFunction,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct Function {
/// The name of the function to call.
pub name: String,
/// The arguments to call the function with, as generated by the model in JSON format.
pub arguments: String,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct DeltaFunction {
/// The name of the function to call.
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
/// The arguments to call the function with, as generated by the model in JSON format.
#[serde(skip_serializing_if = "Option::is_none")]
pub arguments: Option<String>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct ChatCompletionChoice {
/// The index of the choice in the list of choices.
pub index: u32,
/// A chat completion message generated by the model.
pub message: ChatMessage,
/// The reason the model stopped generating tokens.
#[serde(skip_serializing_if = "Option::is_none")]
pub finish_reason: Option<FinishReason>,
/// Log probability information for the choice.
#[serde(skip_serializing_if = "Option::is_none")]
pub logprobs: Option<LogProps>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct AudioDataIdParameter {
/// Unique identifier for a previous audio response from the model.
pub id: String,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct AudioParameters {
/// The voice the model uses to respond.
pub voice: Voice,
/// Specifies the output audio format.
pub format: AudioFormat,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct LogProps {
/// A list of message content tokens with log probability information.
#[serde(skip_serializing_if = "Option::is_none")]
pub content: Option<Vec<LogPropsContent>>,
/// A list of message refusal tokens with log probability information.
#[serde(skip_serializing_if = "Option::is_none")]
pub refusal: Option<Vec<LogPropsContent>>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct LogPropsContent {
/// Token information
#[serde(flatten)]
pub token_info: LogProbsContentInfo,
/// List of the most likely tokens and their log probability, at this token position.
pub top_logprobs: Vec<LogProbsContentInfo>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct LogProbsContentInfo {
/// The token.
pub token: String,
/// The log probability of this token, if it is within the top 20 most likely tokens.
/// Otherwise, the value -9999.0 is used to signify that the token is very unlikely.
pub logprob: f32,
/// A list of integers representing the UTF-8 bytes representation of the token.
pub bytes: Option<Vec<u8>>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct ChatCompletionChunkChoice {
/// The index of the choice in the list of choices.
pub index: Option<u32>,
/// A chat completion delta generated by streamed model responses.
pub delta: DeltaChatMessage,
/// The reason the model stopped generating tokens.
#[serde(skip_serializing_if = "Option::is_none")]
pub finish_reason: Option<FinishReason>,
/// Log probability information for the choice.
#[serde(skip_serializing_if = "Option::is_none")]
pub logprobs: Option<LogProps>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct ImageUrlType {
/// Either a URL of the image or the base64 encoded image data.
pub url: String,
/// Specifies the detail level of the image.
#[serde(skip_serializing_if = "Option::is_none")]
pub detail: Option<ImageUrlDetail>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct AudioUrlType {
/// audio URL or base64
pub url: String,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct VideoUrlType {
/// video URL
pub url: String,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct PredictedOutput {
/// The type of the predicted content you want to provide.
pub r#type: PredictedOutputType,
/// The content that should be matched when generating a model response.
/// If generated tokens would match this content, the entire model response can be returned much more quickly.
pub content: PredictedOutputContent,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
#[serde(untagged)]
pub enum PredictedOutputContent {
String(String),
Array(Vec<PredictedOutputArrayPart>),
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct PredictedOutputArrayPart {
/// The type of the content part.
pub r#type: String,
/// The text content.
pub text: String,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum PredictedOutputType {
Content,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum Modality {
Text,
Audio,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum ImageUrlDetail {
Auto,
High,
Low,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
#[serde(untagged)]
pub enum ChatMessageContent {
Text(String),
ContentPart(Vec<ChatMessageContentPart>),
None,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
#[serde(untagged)]
pub enum ChatMessageContentPart {
Text(ChatMessageTextContentPart),
Image(ChatMessageImageContentPart),
Audio(ChatMessageAudioContentPart),
Video(ChatMessageVideoContentPart),
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct ChatMessageTextContentPart {
/// The type of the content part.
pub r#type: String,
/// The text content.
pub text: String,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct ChatMessageImageContentPart {
/// The type of the content part.
pub r#type: String,
/// The text content.
pub image_url: ImageUrlType
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct ChatMessageAudioContentPart {
/// The type of the content part. Always input_audio.
pub r#type: String,
/// The input audio data.
pub audio_url: AudioUrlType
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct ChatMessageVideoContentPart {
/// The type of the content part.
pub r#type: String,
/// The text content.
pub video_url: VideoUrlType,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct ChatMessageImageUrl {
/// Either a URL of the image or the base64 encoded image data.
pub url: String,
/// Specifies the detail level of the image.
pub detail: String,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct InputAudioData {
/// Base64 encoded audio data.
pub data: String,
/// The format of the encoded audio data. Currently supports "wav" and "mp3".
pub format: String,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct WebSearchOptions {
/// High level guidance for the amount of context window space to use for the search.
#[serde(skip_serializing_if = "Option::is_none")]
pub search_context_size: Option<WebSearchContextSize>,
/// Approximate location parameters for the search.
#[serde(skip_serializing_if = "Option::is_none")]
pub user_location: Option<ApproximateUserLocation>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct ApproximateUserLocation {
pub r#type: UserLocationType,
/// Approximate location parameters for the search.
pub approximate: WebSearchUserLocation,
}
impl Display for ChatMessageContent {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
ChatMessageContent::Text(text) => write!(f, "{text}"),
ChatMessageContent::ContentPart(tcp) => {
for part in tcp {
write!(f, "{part:?}")?;
}
Ok(())
}
ChatMessageContent::None => write!(f, ""),
}
}
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum ChatCompletionToolType {
Function,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum ChatCompletionToolChoice {
None,
Auto,
Required,
#[serde(untagged)]
ChatCompletionToolChoiceFunction(ChatCompletionToolChoiceFunction),
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct WebSearchUserLocation {
pub city: Option<String>,
pub country: Option<String>,
pub region: Option<String>,
pub timezone: Option<String>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum UserLocationType {
Approximate,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum Voice {
Alloy,
Ash,
Ballad,
Coral,
Echo,
Sage,
Shimmer,
Verse,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum AudioFormat {
Wav,
Mp3,
Flac,
Opus,
Pcm16,
}
impl Default for ChatMessageContent {
fn default() -> Self {
ChatMessageContent::Text("".to_string())
}
}
impl DeltaFunction {
pub fn merge(&mut self, other: &Self) {
if self.name.is_none() && other.name.is_some() {
self.name.clone_from(&other.name);
}
if let Some(arguments) = &other.arguments {
if let Some(self_arguments) = &mut self.arguments {
self_arguments.push_str(arguments);
} else {
self.arguments = Some(arguments.clone());
}
}
}
pub fn is_empty(&self) -> bool {
self.name.is_none() && self.arguments.is_none()
}
}
+2
View File
@@ -0,0 +1,2 @@
pub mod chat;
pub mod shared;
+203
View File
@@ -0,0 +1,203 @@
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct Usage {
/// Number of tokens in the prompt.
#[serde(skip_serializing_if = "Option::is_none")]
pub prompt_tokens: Option<u32>,
/// Number of tokens in the completion.
#[serde(skip_serializing_if = "Option::is_none")]
pub completion_tokens: Option<u32>,
/// Number of tokens in the entire response.
pub total_tokens: u32,
/// Breakdown of tokens used in the prompt.
#[serde(skip_serializing_if = "Option::is_none")]
pub prompt_tokens_details: Option<PromptTokensDetails>,
/// Breakdown of tokens used in a completion.
#[serde(skip_serializing_if = "Option::is_none")]
pub completion_tokens_details: Option<CompletionTokensDetails>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct InputTokensDetails {
/// The number of tokens that were retrieved from the cache.
pub cached_tokens: u32,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct OutputTokensDetails {
/// The number of reasoning tokens.
pub reasoning_tokens: u32,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct PromptTokensDetails {
/// Audio input tokens present in the prompt.
#[serde(skip_serializing_if = "Option::is_none")]
pub audio_tokens: Option<u32>,
/// Cached tokens present in the prompt.
pub cached_tokens: u32,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct CompletionTokensDetails {
/// Tokens generated by the model for reasoning.
pub reasoning_tokens: u32,
/// Audio input tokens generated by the model.
#[serde(skip_serializing_if = "Option::is_none")]
pub audio_tokens: Option<u32>,
/// When using Predicted Outputs, the number of tokens in the prediction that appeared in the completion.
#[serde(skip_serializing_if = "Option::is_none")]
pub accepted_prediction_tokens: Option<u32>,
/// When using Predicted Outputs, the number of tokens in the prediction that did not appear in the completion.
#[serde(skip_serializing_if = "Option::is_none")]
pub rejected_prediction_tokens: Option<u32>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct ResponseWrapper<T> {
pub data: T,
pub headers: Headers,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct Headers {
/// The maximum number of requests that are permitted before exhausting the rate limit.
#[serde(rename = "x-ratelimit-limit-requests")]
pub x_ratelimit_limit_requests: Option<u32>,
/// The maximum number of tokens that are permitted before exhausting the rate limit.
#[serde(rename = "x-ratelimit-limit-tokens")]
pub x_ratelimit_limit_tokens: Option<u32>,
/// The remaining number of requests that are permitted before exhausting the rate limit.
#[serde(rename = "x-ratelimit-remaining-requests")]
pub x_ratelimit_remaining_requests: Option<u32>,
/// The remaining number of tokens that are permitted before exhausting the rate limit.
#[serde(rename = "x-ratelimit-remaining-tokens")]
pub x_ratelimit_remaining_tokens: Option<u32>,
/// The time until the rate limit (based on requests) resets to its initial state.
#[serde(rename = "x-ratelimit-reset-requests")]
pub x_ratelimit_reset_requests: Option<String>,
/// The time until the rate limit (based on tokens) resets to its initial state.
#[serde(rename = "x-ratelimit-reset-tokens")]
pub x_ratelimit_reset_tokens: Option<String>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct SimpleListParameters {
/// Identifier for the last object from the previous pagination request.
pub after: Option<String>,
/// Number of objects to retrieve.
pub limit: Option<u32>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct ListParameters {
/// A limit on the number of objects to be returned. Limit can range between 1 and 100, and the default is 20.
#[serde(skip_serializing_if = "Option::is_none")]
pub limit: Option<u32>,
/// Sort order by the created_at timestamp of the objects. asc for ascending order and desc for descending order.
#[serde(skip_serializing_if = "Option::is_none")]
pub order: Option<String>,
/// A cursor for use in pagination. after is an object ID that defines your place in the list.
#[serde(skip_serializing_if = "Option::is_none")]
pub after: Option<String>,
/// A cursor for use in pagination. before is an object ID that defines your place in the list.
#[serde(skip_serializing_if = "Option::is_none")]
pub before: Option<String>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct ListResponse<T> {
// The object type, which is always "list".
pub object: String,
/// The list ob objects.
pub data: Vec<T>,
/// The ID of the first objects in the list.
pub first_id: Option<String>,
/// The ID of the last objects in the list.
pub last_id: Option<String>,
/// Indicates whether there are more objects to retrieve.
pub has_more: bool,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct DeletedObject {
/// ID of the deleted object.
pub id: String,
/// The object type.
pub object: String,
/// Indicates whether the file was successfully deleted.
pub deleted: bool,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct LastError {
/// One of 'server_error' or 'rate_limit_exceeded'.
pub code: LastErrorCode,
/// A human-readable description of the error.
pub message: String,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum LastErrorCode {
ServerError,
RateLimitExceeded,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum FinishReason {
/// API returned complete message, or a message terminated by one of the stop sequences provided via the stop parameter.
#[serde(rename = "stop", alias = "STOP")]
StopSequenceReached,
/// Incomplete model output due to max_tokens parameter or token limit.
#[serde(rename = "length", alias = "MAX_TOKENS")]
TokenLimitReached,
/// Omitted content due to a flag from our content filters.
#[serde(
rename = "content_filter",
alias = "SAFETY",
alias = "SPII",
alias = "PROHIBITED_CONTENT",
alias = "BLOCKLIST",
alias = "RECITATION"
)]
ContentFilterFlagged,
/// The model decided to call one or more tools.
ToolCalls,
/// The model reached a natural stopping point. [Claude]
EndTurn,
/// The finish reason is unspecified. [Gemini]
#[serde(rename = "FINISH_REASON_UNSPECIFIED ")]
FinishReasonUnspecified,
#[serde(rename = "MALFORMED_FUNCTION_CALL")]
MalformedFunctionCall,
#[serde(rename = "OTHER")]
Other,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum ReasoningEffort {
High,
Medium,
Low,
Minimal,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum WebSearchContextSize {
Low,
Medium,
Large,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
#[serde(untagged)]
pub enum StopToken {
String(String),
Array(Vec<String>),
}
+1 -1
View File
@@ -4,7 +4,7 @@ use std::path::{Path, PathBuf};
use std::thread;
use std::{f64::consts::PI, io::Cursor};
use aha_openai_dive::v1::resources::chat::{
use crate::params::chat::{
ChatCompletionParameters, ChatCompletionResponse, ChatMessage, ChatMessageContent,
ChatMessageContentPart,
};
+1 -1
View File
@@ -2,7 +2,7 @@ use std::io::Cursor;
use std::thread;
use std::{collections::HashSet, path::PathBuf};
use aha_openai_dive::v1::resources::chat::{
use crate::params::chat::{
ChatCompletionParameters, ChatMessage, ChatMessageContent, ChatMessageContentPart,
};
use anyhow::{Result, anyhow};
+24 -5
View File
@@ -6,9 +6,10 @@ pub mod video_utils;
use std::fs::File;
use std::io::{Cursor, Read};
use std::time::{SystemTime, UNIX_EPOCH};
use std::{collections::HashMap, fs, path::PathBuf, process::Command, time::Duration};
use aha_openai_dive::v1::resources::{
use crate::params::{
chat::{
AudioUrlType, ChatCompletionChoice, ChatCompletionChunkChoice, ChatCompletionChunkResponse,
ChatCompletionParameters, ChatCompletionResponse, ChatMessage, ChatMessageAudioContentPart,
@@ -377,6 +378,23 @@ pub fn read_pth_tensor_info_cycle<P: AsRef<std::path::Path>>(
Ok(dict_to_hashmap)
}
// 获取秒级时间戳
pub fn timestamp() -> u64 {
SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_secs()
}
// 获取毫秒级时间戳
pub fn timestamp_millis() -> u128 {
SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_millis()
}
pub fn round_by_factor(num: u32, factor: u32) -> u32 {
let round = (num as f32 / factor as f32).round() as u32;
round * factor
@@ -400,7 +418,8 @@ pub fn build_img_completion_response(
let mut response = ChatCompletionResponse {
id: Some(id),
choices: vec![],
created: chrono::Utc::now().timestamp() as u32,
// created: chrono::Utc::now().timestamp() as u32,
created: timestamp() as u32,
model: model_name.to_string(),
service_tier: None,
system_fingerprint: None,
@@ -444,7 +463,7 @@ pub fn build_audio_completion_response(
let mut response = ChatCompletionResponse {
id: Some(id),
choices: vec![],
created: chrono::Utc::now().timestamp() as u32,
created: timestamp() as u32,
model: model_name.to_string(),
service_tier: None,
system_fingerprint: None,
@@ -498,7 +517,7 @@ pub fn build_completion_response(
let mut response = ChatCompletionResponse {
id: Some(id),
choices: vec![],
created: chrono::Utc::now().timestamp() as u32,
created: timestamp() as u32,
model: model_name.to_string(),
service_tier: None,
system_fingerprint: None,
@@ -580,7 +599,7 @@ pub fn build_completion_chunk_response(
let mut response = ChatCompletionChunkResponse {
id: Some(id),
choices: vec![],
created: chrono::Utc::now().timestamp() as u32,
created: timestamp() as u32,
model: model_name.to_string(),
system_fingerprint: None,
object: "chat.completion.chunk".to_string(),
+5 -1
View File
@@ -5,8 +5,9 @@
// use std::io::{Read, Seek};
// use std::{io::Cursor, time::Instant};
use aha::utils::{timestamp, timestamp_millis};
// use aha::utils::tensor_utils::repeat_interleave;
// use aha_openai_dive::v1::resources::chat::ChatCompletionParameters;
// use crate::params::chat::ChatCompletionParameters;
use anyhow::Result;
// use byteorder::{LittleEndian, ReadBytesExt};
// use candle_core::Tensor;
@@ -35,6 +36,9 @@ async fn download_test() -> Result<()> {
#[test]
fn messy_test() -> Result<()> {
// RUST_BACKTRACE=1 cargo test -F cuda --test messy_test messy_test -r -- --nocapture
println!("当前秒级时间戳: {}", timestamp());
println!("当前毫秒级时间戳: {}", timestamp_millis());
// let t1 = Tensor::randn(0.0, 1.0, (1, 2, 6), device)?;
// println!(" t1: {}", t1);
// let t2 = t1.pad_with_zeros(D::Minus1, -3, 0)?;
+1 -1
View File
@@ -1,7 +1,7 @@
use std::{pin::pin, time::Instant};
use aha::params::chat::ChatCompletionParameters;
use aha::models::{GenerateModel, deepseek_ocr::generate::DeepseekOCRGenerateModel};
use aha_openai_dive::v1::resources::chat::ChatCompletionParameters;
use anyhow::Result;
use rocket::futures::StreamExt;
+1 -1
View File
@@ -1,7 +1,7 @@
use std::{pin::pin, time::Instant};
use aha::models::{GenerateModel, fun_asr_nano::generate::FunAsrNanoGenerateModel};
use aha_openai_dive::v1::resources::chat::ChatCompletionParameters;
use aha::params::chat::ChatCompletionParameters;
use anyhow::Result;
use rocket::futures::StreamExt;
#[test]
+1 -1
View File
@@ -1,7 +1,7 @@
use std::time::Instant;
use aha::models::{GenerateModel, qwen3vl::generate::Qwen3VLGenerateModel};
use aha_openai_dive::v1::resources::chat::ChatCompletionParameters;
use aha::params::chat::ChatCompletionParameters;
use anyhow::Result;
#[test]
+1 -1
View File
@@ -1,7 +1,7 @@
use std::time::Instant;
use aha::{
chat::ChatCompletionParameters,
params::chat::ChatCompletionParameters,
models::{GenerateModel, qwen3_5::generate::Qwen3_5GenerateModel},
};
use anyhow::Result;
+1 -1
View File
@@ -1,7 +1,7 @@
use std::{pin::pin, time::Instant};
use aha::models::{GenerateModel, glm_asr_nano::generate::GlmAsrNanoGenerateModel};
use aha_openai_dive::v1::resources::chat::ChatCompletionParameters;
use aha::params::chat::ChatCompletionParameters;
use anyhow::Result;
use rocket::futures::StreamExt;
+1 -1
View File
@@ -1,7 +1,7 @@
use std::{pin::pin, time::Instant};
use aha::models::{GenerateModel, glm_ocr::generate::GlmOcrGenerateModel};
use aha_openai_dive::v1::resources::chat::ChatCompletionParameters;
use aha::params::chat::ChatCompletionParameters;
use anyhow::Result;
use rocket::futures::StreamExt;
+1 -1
View File
@@ -1,7 +1,7 @@
use std::{pin::pin, time::Instant};
use aha::models::{GenerateModel, hunyuan_ocr::generate::HunyuanOCRGenerateModel};
use aha_openai_dive::v1::resources::chat::ChatCompletionParameters;
use aha::params::chat::ChatCompletionParameters;
use anyhow::Result;
use rocket::futures::StreamExt;
+1 -1
View File
@@ -1,5 +1,5 @@
use aha::{
chat::ChatCompletionParameters,
params::chat::ChatCompletionParameters,
models::{GenerateModel, lfm2::generate::Lfm2GenerateModel},
};
use anyhow::Result;
+3 -3
View File
@@ -1,7 +1,7 @@
use std::{pin::pin, time::Instant};
use aha::{
chat::ChatCompletionParameters,
params::chat::ChatCompletionParameters,
models::{GenerateModel, lfm2vl::generate::Lfm2VLGenerateModel},
};
use anyhow::Result;
@@ -12,8 +12,8 @@ fn lfm2vl_generate() -> Result<()> {
let save_dir =
aha::utils::get_default_save_dir().ok_or(anyhow::anyhow!("Failed to get save dir"))?;
// let model_path = format!("{}/LiquidAI/LFM2.5-VL-1.6B/", save_dir);
let model_path = format!("{}/LiquidAI/LFM2-VL-1.6B/", save_dir);
let model_path = format!("{}/LiquidAI/LFM2.5-VL-1.6B/", save_dir);
// let model_path = format!("{}/LiquidAI/LFM2-VL-1.6B/", save_dir);
let message = r#"
{
"model": "lfm2vl",
+1 -1
View File
@@ -1,7 +1,7 @@
use std::{pin::pin, time::Instant};
use aha::models::{GenerateModel, minicpm4::generate::MiniCPMGenerateModel};
use aha_openai_dive::v1::resources::chat::ChatCompletionParameters;
use aha::params::chat::ChatCompletionParameters;
use anyhow::Result;
use rocket::futures::StreamExt;
+1 -1
View File
@@ -1,7 +1,7 @@
use std::{pin::pin, time::Instant};
use aha::models::{GenerateModel, paddleocr_vl::generate::PaddleOCRVLGenerateModel};
use aha_openai_dive::v1::resources::chat::ChatCompletionParameters;
use aha::params::chat::ChatCompletionParameters;
use anyhow::Result;
use rocket::futures::StreamExt;
+1 -1
View File
@@ -1,7 +1,7 @@
use std::{pin::pin, time::Instant};
use aha::models::{GenerateModel, qwen2_5vl::generate::Qwen2_5VLGenerateModel};
use aha_openai_dive::v1::resources::chat::ChatCompletionParameters;
use aha::params::chat::ChatCompletionParameters;
use anyhow::Result;
use rocket::futures::StreamExt;
+1 -1
View File
@@ -1,7 +1,7 @@
use std::{pin::pin, time::Instant};
use aha::models::{GenerateModel, qwen3::generate::Qwen3GenerateModel};
use aha_openai_dive::v1::resources::chat::ChatCompletionParameters;
use aha::params::chat::ChatCompletionParameters;
use anyhow::Result;
use rocket::futures::StreamExt;
+1 -1
View File
@@ -1,7 +1,7 @@
use std::{pin::pin, time::Instant};
use aha::models::{GenerateModel, qwen3_5::generate::Qwen3_5GenerateModel};
use aha_openai_dive::v1::resources::chat::ChatCompletionParameters;
use aha::params::chat::ChatCompletionParameters;
use anyhow::Result;
use rocket::futures::StreamExt;
+1 -1
View File
@@ -1,7 +1,7 @@
use std::{pin::pin, time::Instant};
use aha::models::{GenerateModel, qwen3_asr::generate::Qwen3AsrGenerateModel};
use aha_openai_dive::v1::resources::chat::ChatCompletionParameters;
use aha::params::chat::ChatCompletionParameters;
use anyhow::Result;
use rocket::futures::StreamExt;
#[test]
+1 -1
View File
@@ -1,7 +1,7 @@
use std::{pin::pin, time::Instant};
use aha::models::{GenerateModel, qwen3vl::generate::Qwen3VLGenerateModel};
use aha_openai_dive::v1::resources::chat::ChatCompletionParameters;
use aha::params::chat::ChatCompletionParameters;
use anyhow::Result;
use rocket::futures::StreamExt;
+1 -1
View File
@@ -1,7 +1,7 @@
use std::time::Instant;
use aha::models::rmbg2_0::generate::RMBG2_0Model;
use aha_openai_dive::v1::resources::chat::ChatCompletionParameters;
use aha::params::chat::ChatCompletionParameters;
use anyhow::Result;
#[test]
+1 -1
View File
@@ -1,7 +1,7 @@
use std::time::Instant;
use aha::models::{GenerateModel, qwen2_5vl::generate::Qwen2_5VLGenerateModel};
use aha_openai_dive::v1::resources::chat::ChatCompletionParameters;
use aha::params::chat::ChatCompletionParameters;
use anyhow::Result;
#[test]
+1 -1
View File
@@ -1,5 +1,6 @@
use std::time::Instant;
use aha::params::chat::ChatCompletionParameters;
use aha::{
models::{
GenerateModel,
@@ -7,7 +8,6 @@ use aha::{
},
utils::audio_utils::{extract_and_save_audio_from_response, save_wav},
};
use aha_openai_dive::v1::resources::chat::ChatCompletionParameters;
use anyhow::{Ok, Result};
#[test]
+1 -1
View File
@@ -1,5 +1,6 @@
use std::time::Instant;
use aha::params::chat::ChatCompletionParameters;
use aha::{
models::{
GenerateModel,
@@ -7,7 +8,6 @@ use aha::{
},
utils::audio_utils::{extract_and_save_audio_from_response, save_wav},
};
use aha_openai_dive::v1::resources::chat::ChatCompletionParameters;
use anyhow::{Ok, Result};
#[test]