12 releases
new 0.1.80 | Apr 28, 2025 |
---|---|
0.1.75 | Mar 5, 2025 |
0.1.70 | Feb 21, 2025 |
0.1.51 | Dec 28, 2024 |
0.1.1 | Oct 1, 2024 |
#308 in Asynchronous
347 downloads per month
76KB
1.5K
SLoC
Gem-rs
Gem-rs is a Rust library that serves as a wrapper around the Gemini API, providing support for streaming. This library is designed to facilitate interaction with the Gemini API, making it easier to integrate its functionalities into Rust projects. Future updates will include support for uploading files and images, as well as caching files to Gemini.
TODO List
-
Improve Documentation: Enhance the documentation with more examples and detailed explanations.
-
Error Logging: Implement a comprehensive error logging system.
-
Concurrency Support [✅]: Add support for concurrent data processing.
-
Optimization: Few functions and data structres need to be optimized.
-
Upload Files and Images [✅]: Add support for uploading files and images to Gemini.
-
Caching Files [✅]: Implement file caching to Gemini.
-
More File Types: Add support to more file types eg. gif, doc, docx, code files, etc.
-
APIs abnormalites: DELETE "files/x" dosen't delete the cloud cache related to the API key, it only change the URI.
-
API Key Env [✅]
-
Adding tool use e.g. grounding []
-
Configure thinking to be separated from the response in the response handling []
Notes
- 2.5 Pro preview models isn't a free model! be aware, use the experimental models instead.
- The default 'timeout(...)' is None, and you should set it if you want to.
- When 'timeout(...)' is set, 'read_timeout(...)' is ignored according to the reqwest docs.
- Use 'timeout(...)' for non-streaming requests. otherwise, the stream will be closed after the timeout even if the server is still responding.
- When using a thinking model, you may indicate to the user as "thinking" while waiting for the first tokens, cause as far i know, currently there's no way to get the thinking tokens in the gemini APIs (if possible, PR!).
- Using "thinking_budget" isn't necessary as the thinking models will decide whether to think or not, and decide how many tokens they require.
Dependencies
To use the Gem-rs library, add the following dependencies to your Cargo.toml
file:
[dependencies]
futures = "*"
tokio = { version = "*", features = ["full"] }
gem-rs = "*"
Example Usage
Here's a basic example of how to use the Gem-rs library (Further examples in examples folder):
use futures::stream::StreamExt;
use gem_rs::api::Models;
use gem_rs::client::{GemSession, GemSessionBuilder};
use gem_rs::init_log;
use gem_rs::types::{Context, HarmBlockThreshold, Role, Settings};
#[tokio::main]
async fn main() {
init_log();
test().await;
test_stream().await;
test_file().await;
}
async fn test_file() {
let mut session = GemSession::Builder()
.connect_timeout(std::time::Duration::from_secs(30))
.timeout(std::time::Duration::from_secs(30))
.model(Models::Gemini25FlashPreview0417)
.context(Context::new())
.build();
let mut settings = Settings::new();
settings.set_all_safety_settings(HarmBlockThreshold::BlockNone);
settings.set_system_instruction("Summraize the PDFs that I send to you, in a (UwU) style");
settings.set_max_output_tokens(8192);
settings.set_temperature(1.5);
let mut file_manager = FileManager::new();
file_manager.fetch_list().await.unwrap();
let data = file_manager
.add_file(Path::new("C:/Users/0xhades/Downloads/9.pdf"))
.await
.unwrap();
let response = session
.send_file(data, Role::User, &settings)
.await;
match response {
Ok(response) => {
println!("Response: {:#?}", response.get_results());
}
Err(e) => {
println!("Error: {:?}", e);
}
}
}
async fn test_stream() {
let mut session = GemSession::Builder()
.connect_timeout(std::time::Duration::from_secs(30))
.read_timeout(std::time::Duration::from_secs(30))
.model(Models::Gemini25FlashPreview0417)
.context(Context::new())
.build();
let mut settings = Settings::new();
settings.set_all_safety_settings(HarmBlockThreshold::BlockNone);
let stream_result = session
.send_message_stream("Hello! What is your name?", Role::User, &settings)
.await;
match stream_result {
Ok(mut stream) => {
while let Some(response) = stream.next().await {
match response {
Ok(response) => {
println!(
"{}",
response.get_results().get(0).unwrap_or(&"".to_string())
);
}
Err(e) => {
println!("Error: {:?}", e);
}
}
}
}
Err(e) => {
println!("Error: {:?}", e);
}
}
}
async fn test() {
let mut session = GemSession::Builder()
.connect_timeout(std::time::Duration::from_secs(30))
.timeout(std::time::Duration::from_secs(30))
.model(Models::Gemini25FlashPreview0417)
.context(Context::new())
.build();
let mut settings = Settings::new();
settings.set_all_safety_settings(HarmBlockThreshold::BlockNone);
let response = session
.send_message("Hello! What is your name?", Role::User, &settings)
.await;
match response {
Ok(response) => {
println!("Response: {:#?}", response.get_results());
}
Err(e) => {
println!("Error: {:?}", e);
}
}
}
Dependencies
~12–25MB
~353K SLoC