add: initial files

This commit is contained in:
2026-05-13 13:09:52 -07:00
commit e1961f7687
4 changed files with 2021 additions and 0 deletions
+109
View File
@@ -0,0 +1,109 @@
use clap::Parser;
use serde::{Deserialize, Serialize};
use std::io::{self, Read};
use std::path::PathBuf;
#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
struct Args {
/// Optional prompt to append to stdin
#[arg(short, long)]
prompt: Option<String>,
}
#[derive(Deserialize)]
struct Config {
api_key: String,
server_url: String,
}
#[derive(Serialize)]
struct Message {
role: String,
content: String,
}
#[derive(Serialize)]
struct ChatRequest {
model: String,
messages: Vec<Message>,
}
#[derive(Deserialize)]
struct ChatResponse {
choices: Vec<Choice>,
}
#[derive(Deserialize)]
struct Choice {
message: MessageResponse,
}
#[derive(Deserialize)]
struct MessageResponse {
content: String,
}
async fn run() -> Result<(), Box<dyn std::error::Error>> {
let args = Args::parse();
// Load configuration
let config_path = PathBuf::from(std::env::var("HOME")?)
.join(".config/slm/config.toml");
let config_str = std::fs::read_to_string(&config_path)
.map_err(|e| format!("Failed to read config file {}: {}", config_path.display(), e))?;
let config: Config = toml::from_str(&config_str)
.map_err(|e| format!("Failed to parse config TOML: {}", e))?;
// Read stdin
let mut stdin_buffer = String::new();
io::stdin().read_to_string(&mut stdin_buffer)?;
// Combine stdin and optional prompt
let mut final_content = stdin_buffer;
if let Some(p) = args.prompt {
if !final_content.is_empty() {
final_content.push('\n');
}
final_content.push_str(&p);
}
// Construct the API request
let request_body = ChatRequest {
model: "nvidia/Gemma-4-31B-IT-NVFP4".to_string(), // Default model
messages: vec![Message {
role: "user".to_string(),
content: final_content,
}],
};
let client = reqwest::Client::new();
let response = client
.post(&config.server_url)
.header("Authorization", format!("Bearer {}", config.api_key))
.json(&request_body)
.send()
.await?;
let status = response.status();
if !status.is_success() {
let error_text = response.text().await?;
return Err(format!("API request failed with status {}: {}", status, error_text).into());
}
let chat_response: ChatResponse = response.json().await?;
if let Some(choice) = chat_response.choices.first() {
println!("{}", choice.message.content);
}
Ok(())
}
#[tokio::main]
async fn main() {
if let Err(e) = run().await {
eprintln!("Error: {}", e);
std::process::exit(1);
}
}