调整公共模块结构,方便后续延伸
This commit is contained in:
Generated
+1
@@ -324,6 +324,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
+1
-1
@@ -14,4 +14,4 @@ serde = { version = "1.0", features = ["derive"] } # 序列化/反序
|
||||
serde_json = "1.0" # JSON 处理
|
||||
serde_yaml = "0.9" # YAML 解析(工具规范文件)
|
||||
# ── 时间 ──
|
||||
chrono = "0.4"
|
||||
chrono = "0.4"
|
||||
|
||||
+1
-2
@@ -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
@@ -2,7 +2,7 @@ use chrono::Local;
|
||||
use serde_json::error;
|
||||
|
||||
use common::{
|
||||
ai::ChatCompletionToolCall,
|
||||
model::ai::ChatCompletionToolCall,
|
||||
queue::{ChannelMessage, QueueMessage},
|
||||
};
|
||||
|
||||
|
||||
+3
-1
@@ -6,4 +6,6 @@ edition = "2024"
|
||||
[dependencies]
|
||||
# ── 序列化 ──
|
||||
serde = { version = "1.0", features = ["derive"] } # 序列化/反序列化
|
||||
serde_json = "1.0"
|
||||
serde_json = "1.0"
|
||||
# ── 错误处理 ──
|
||||
thiserror = "2"
|
||||
|
||||
@@ -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
@@ -1,2 +1,3 @@
|
||||
pub mod ai;
|
||||
pub mod error;
|
||||
pub mod model;
|
||||
pub mod queue;
|
||||
|
||||
+1
-1
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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,6 +1,5 @@
|
||||
mod channel;
|
||||
mod core;
|
||||
mod error;
|
||||
mod http;
|
||||
mod model;
|
||||
mod repository;
|
||||
|
||||
Reference in New Issue
Block a user