Template code

This commit is contained in:
2026-07-23 18:23:20 +03:00
parent de28edb4c3
commit b54676ed8e
3 changed files with 1760 additions and 3 deletions
Generated
+1634
View File
File diff suppressed because it is too large Load Diff
+13 -1
View File
@@ -1,6 +1,18 @@
[package]
name = "rust-llm-agent"
version = "0.1.0"
edition = "2024"
edition = "2021"
[dependencies]
# Асинхронный runtime
tokio = { version = "1.38", features = ["full"] }
# HTTP-клиент
reqwest = { version = "0.12", features = ["json"] }
# Сериализация / Десериализация JSON
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
# Парсинг аргументов CLI (флаги --session-id и т.д.)
clap = { version = "4.5", features = ["derive"] }
+113 -2
View File
@@ -1,3 +1,114 @@
fn main() {
println!("Hello, world!");
use clap::Parser;
use serde_json::json;
use std::io::{self, Write};
use tokio::io::{AsyncBufReadExt, BufReader};
/// CLI-утилита для взаимодействия с LLM в рамках указанной сессии
#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
struct Args {
/// Идентификатор сессии/беседы (на будущее для VK peer_id)
#[arg(short, long, default_value = "default_session")]
session_id: String,
/// URL OpenAI-совместимого эндпоинта (vLLM / llama.cpp / Ollama)
#[arg(
short,
long,
default_value = "http://localhost:11434/v1/chat/completions"
)]
api_url: String,
/// Название модели (для Ollama/vLLM)
#[arg(m_flag, short, long, default_value = "qwen2.5-coder")]
model: String,
}
/// Функция отправки Stateless-запроса к LLM
async fn send_llm_request(
client: &reqwest::Client,
api_url: &str,
model: &str,
user_message: &str,
) -> Result<String, Box<dyn std::error::Error>> {
let payload = json!({
"model": model,
"messages": [
{
"role": "user",
"content": user_message
}
],
"temperature": 0.7
});
let response = client.post(api_url).json(&payload).send().await?;
if !response.status().is_success() {
let status = response.status();
let error_text = response.text().await?;
return Err(format!("API вернул ошибку [{status}]: {error_text}").into());
}
let res_body: serde_json::Value = response.json().await?;
if let Some(content) = res_body["choices"][0]["message"]["content"].as_str() {
Ok(content.to_string())
} else {
Err(format!("Не удалось вытащить текст ответа из JSON: {res_body}").into())
}
}
#[tokio::main]
async fn main() {
let args = Args::parse();
let client = reqwest::Client::new();
println!("==================================================");
println!(" LLM CLI Agent (Stage 1)");
println!(" Session ID: {}", args.session_id);
println!(" API URL: {}", args.api_url);
println!(" Model: {}", args.model);
println!("==================================================");
println!("Введите сообщение и нажмите Enter. Для выхода наберите 'exit' или 'quit'.\n");
let stdin = tokio::io::stdin();
let mut reader = BufReader::new(stdin);
loop {
print!("[Session: {}] > ", args.session_id);
io::stdout().flush().unwrap();
let mut input = String::new();
let bytes_read = reader.read_line(&mut input).await.unwrap_or(0);
if bytes_read == 0 {
break; // EOF (Ctrl+D)
}
let trimmed_input = input.trim();
if trimmed_input.is_empty() {
continue;
}
if trimmed_input.eq_ignore_ascii_case("exit")
|| trimmed_input.eq_ignore_ascii_case("quit")
{
println!("Завершение работы.");
break;
}
print!("[Ожидание ответа от LLM...]\r");
io::stdout().flush().unwrap();
match send_llm_request(&client, &args.api_url, &args.model, trimmed_input).await {
Ok(reply) => {
println!("\r[LLM]: {}\n", reply);
}
Err(e) => {
eprintln!("\r[Ошибка]: {}\n", e);
}
}
}
}