调整公共模块结构,方便后续延伸

This commit is contained in:
2026-06-29 11:58:16 +08:00
parent 46544e9c42
commit 6d45b8fb7a
12 changed files with 14 additions and 170 deletions
Generated
+1
View File
@@ -324,6 +324,7 @@ version = "0.1.0"
dependencies = [
"serde",
"serde_json",
"thiserror",
]
[[package]]
+1 -2
View File
@@ -1,5 +1,5 @@
use crate::toolkit::{call_tools, get_tool};
use common::ai::{
use common::model::ai::{
ChatCompletionRequestBody, ChatCompletionRequestExtra, ChatCompletionRequestMessage,
ChatCompletionRequestThinking, ChatCompletionResponseBody,
};
@@ -13,7 +13,6 @@ pub async fn send_message(
let result = request_llm(messages).await;
match result {
Ok(result) => {
// println!("result:");
for choice in result.unwrap().choices {
let messsage_content = choice.message.content;
let messsage_reasoning = choice.message.reasoning_content.unwrap_or_default();
+1 -1
View File
@@ -2,7 +2,7 @@ use chrono::Local;
use serde_json::error;
use common::{
ai::ChatCompletionToolCall,
model::ai::ChatCompletionToolCall,
queue::{ChannelMessage, QueueMessage},
};
+2
View File
@@ -7,3 +7,5 @@ edition = "2024"
# ── 序列化 ──
serde = { version = "1.0", features = ["derive"] } # 序列化/反序列化
serde_json = "1.0"
# ── 错误处理 ──
thiserror = "2"
-120
View File
@@ -1,120 +0,0 @@
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize)]
pub struct ChatCompletionRequestBody {
pub model: String,
pub messages: Vec<ChatCompletionRequestMessage>,
pub stream: bool,
pub tools: Vec<serde_json::Value>,
pub extra_body: Option<ChatCompletionRequestExtra>,
}
#[derive(Debug, Serialize)]
pub struct ChatCompletionRequestExtra {
pub thinking: ChatCompletionRequestThinking,
}
#[derive(Debug, Serialize)]
pub struct ChatCompletionRequestThinking {
#[serde(rename = "type")]
pub thinking_type: String,
}
#[derive(Debug, Clone, Serialize)]
pub struct ChatCompletionRequestMessage {
pub role: String,
pub content: String,
pub tool_call_id: Option<String>,
pub tool_calls: Option<Vec<ChatCompletionToolCall>>,
}
impl ChatCompletionRequestMessage {
pub fn new(role: String, content: String) -> Self {
Self {
role,
content,
tool_call_id: None,
tool_calls: None,
}
}
pub fn assistant(
role: String,
content: String,
tool_calls: Option<Vec<ChatCompletionToolCall>>,
) -> Self {
Self {
role,
content,
tool_call_id: None,
tool_calls: tool_calls,
}
}
pub fn tool(role: String, content: String, tool_call_id: String) -> Self {
Self {
role,
content,
tool_call_id: Some(tool_call_id),
tool_calls: None,
}
}
}
// {"choices":[{"finish_reason":"stop","index":0,"logprobs":null,"message":{"content":"你好!😊 有什么我可以帮你的吗?","role":"assistant"}}],"created":1782208455,"id":"02178220845277286f296e4c58ddf650991f54d763d292af8529b","model":"deepseek-v4-flash-260425","service_tier":"default","object":"chat.completion","usage":{"prompt_tokens":2005,"completion_tokens":125,"total_tokens":2130,"prompt_tokens_details":{"cached_tokens":0},"completion_tokens_details":{"reasoning_tokens":114}}}
#[allow(dead_code)]
#[derive(Debug, Deserialize)]
pub struct ChatCompletionResponseBody {
id: String,
object: String,
created: i64,
model: String,
service_tier: String,
pub choices: Vec<ChatCompletionResponseChoice>,
pub usage: ChatCompletionUsage,
}
#[allow(dead_code)]
#[derive(Debug, Deserialize)]
pub struct ChatCompletionResponseChoice {
index: u32,
pub message: ChatCompletionResponseMessage,
logprobs: Option<serde_json::Value>,
finish_reason: String,
}
#[allow(dead_code)]
#[derive(Debug, Deserialize)]
pub struct ChatCompletionResponseMessage {
pub role: String,
pub content: String,
pub reasoning_content: Option<String>,
pub tool_calls: Option<Vec<ChatCompletionToolCall>>,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct ChatCompletionToolCall {
pub function: Option<ChatCompletionFunction>,
pub id: String,
#[serde(rename = "type")]
pub call_type: String,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct ChatCompletionFunction {
pub arguments: String,
pub name: String,
}
#[derive(Debug, Deserialize)]
pub struct ChatCompletionUsage {
pub prompt_tokens: u32,
pub completion_tokens: u32,
pub total_tokens: u32,
pub prompt_tokens_details: ChatCompletionUsagePrompt,
pub completion_tokens_details: ChatCompletionUsageCompletion,
}
#[allow(dead_code)]
#[derive(Debug, Deserialize)]
pub struct ChatCompletionUsagePrompt {
pub cached_tokens: u32,
}
#[allow(dead_code)]
#[derive(Debug, Deserialize)]
pub struct ChatCompletionUsageCompletion {
pub reasoning_tokens: u32,
}
+2 -1
View File
@@ -1,2 +1,3 @@
pub mod ai;
pub mod error;
pub mod model;
pub mod queue;
+1 -1
View File
@@ -1,6 +1,6 @@
use serde::{Deserialize, Serialize};
use crate::ai::ChatCompletionToolCall;
use crate::model::ai::ChatCompletionToolCall;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum QueueMessage {
+3 -6
View File
@@ -2,7 +2,7 @@ use std::sync::OnceLock;
use tokio::sync::Mutex;
use common::ai::{ChatCompletionRequestMessage, ChatCompletionToolCall};
use common::model::ai::{ChatCompletionRequestMessage, ChatCompletionToolCall};
static CHAT_CONTEXT: OnceLock<Mutex<Vec<ChatCompletionRequestMessage>>> = OnceLock::new();
@@ -24,11 +24,8 @@ pub async fn add_assistant_message(
content: String,
tool_calls: Option<Vec<ChatCompletionToolCall>>,
) {
let message = ChatCompletionRequestMessage::assistant(
"assistant".to_string(),
content,
tool_calls,
);
let message =
ChatCompletionRequestMessage::assistant("assistant".to_string(), content, tool_calls);
push_context_message(message).await;
}
+1 -2
View File
@@ -3,7 +3,6 @@ use crate::core::context::{
};
use ai::core::send_message;
use common::queue::QueueMessage;
use serde_json::error;
use tokio::sync::{mpsc::Receiver, mpsc::Sender};
use wechat::manager::WeChatMultiAccountManager;
@@ -11,7 +10,7 @@ pub async fn create_queue(
sender: Sender<QueueMessage>,
mut receiver: Receiver<QueueMessage>,
manager: WeChatMultiAccountManager,
) -> Result<(), error::Error> {
) -> anyhow::Result<()> {
tokio::spawn(async move {
while let Some(msg) = receiver.recv().await {
let queue_sender = sender.clone();
-34
View File
@@ -1,34 +0,0 @@
use axum::{
Json,
http::StatusCode,
response::{IntoResponse, Response},
};
use serde_json::json;
#[allow(unused)]
#[derive(Debug, thiserror::Error)]
pub enum AppError {
#[error("not found")]
NotFound,
#[error(transparent)]
AnyHow(#[from] anyhow::Error),
}
impl IntoResponse for AppError {
fn into_response(self) -> Response {
let (status, message) = match self {
AppError::NotFound => (StatusCode::NOT_FOUND, "resource not found".to_string()),
AppError::AnyHow(err) => {
eprintln!("internal error: {err:?}");
(
StatusCode::INTERNAL_SERVER_ERROR,
"internal server error".to_string(),
)
}
};
(status, Json(json!({"error":message}))).into_response()
}
}
#[allow(unused)]
pub type AppResult<T> = Result<T, AppError>;
-1
View File
@@ -1,6 +1,5 @@
mod channel;
mod core;
mod error;
mod http;
mod model;
mod repository;