调整公共模块结构,方便后续延伸
This commit is contained in:
Generated
+1
@@ -324,6 +324,7 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|||||||
+1
-1
@@ -14,4 +14,4 @@ serde = { version = "1.0", features = ["derive"] } # 序列化/反序
|
|||||||
serde_json = "1.0" # JSON 处理
|
serde_json = "1.0" # JSON 处理
|
||||||
serde_yaml = "0.9" # YAML 解析(工具规范文件)
|
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 crate::toolkit::{call_tools, get_tool};
|
||||||
use common::ai::{
|
use common::model::ai::{
|
||||||
ChatCompletionRequestBody, ChatCompletionRequestExtra, ChatCompletionRequestMessage,
|
ChatCompletionRequestBody, ChatCompletionRequestExtra, ChatCompletionRequestMessage,
|
||||||
ChatCompletionRequestThinking, ChatCompletionResponseBody,
|
ChatCompletionRequestThinking, ChatCompletionResponseBody,
|
||||||
};
|
};
|
||||||
@@ -13,7 +13,6 @@ pub async fn send_message(
|
|||||||
let result = request_llm(messages).await;
|
let result = request_llm(messages).await;
|
||||||
match result {
|
match result {
|
||||||
Ok(result) => {
|
Ok(result) => {
|
||||||
// println!("result:");
|
|
||||||
for choice in result.unwrap().choices {
|
for choice in result.unwrap().choices {
|
||||||
let messsage_content = choice.message.content;
|
let messsage_content = choice.message.content;
|
||||||
let messsage_reasoning = choice.message.reasoning_content.unwrap_or_default();
|
let messsage_reasoning = choice.message.reasoning_content.unwrap_or_default();
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@ use chrono::Local;
|
|||||||
use serde_json::error;
|
use serde_json::error;
|
||||||
|
|
||||||
use common::{
|
use common::{
|
||||||
ai::ChatCompletionToolCall,
|
model::ai::ChatCompletionToolCall,
|
||||||
queue::{ChannelMessage, QueueMessage},
|
queue::{ChannelMessage, QueueMessage},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+3
-1
@@ -6,4 +6,6 @@ edition = "2024"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
# ── 序列化 ──
|
# ── 序列化 ──
|
||||||
serde = { version = "1.0", features = ["derive"] } # 序列化/反序列化
|
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;
|
pub mod queue;
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::ai::ChatCompletionToolCall;
|
use crate::model::ai::ChatCompletionToolCall;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub enum QueueMessage {
|
pub enum QueueMessage {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ use std::sync::OnceLock;
|
|||||||
|
|
||||||
use tokio::sync::Mutex;
|
use tokio::sync::Mutex;
|
||||||
|
|
||||||
use common::ai::{ChatCompletionRequestMessage, ChatCompletionToolCall};
|
use common::model::ai::{ChatCompletionRequestMessage, ChatCompletionToolCall};
|
||||||
|
|
||||||
static CHAT_CONTEXT: OnceLock<Mutex<Vec<ChatCompletionRequestMessage>>> = OnceLock::new();
|
static CHAT_CONTEXT: OnceLock<Mutex<Vec<ChatCompletionRequestMessage>>> = OnceLock::new();
|
||||||
|
|
||||||
@@ -24,11 +24,8 @@ pub async fn add_assistant_message(
|
|||||||
content: String,
|
content: String,
|
||||||
tool_calls: Option<Vec<ChatCompletionToolCall>>,
|
tool_calls: Option<Vec<ChatCompletionToolCall>>,
|
||||||
) {
|
) {
|
||||||
let message = ChatCompletionRequestMessage::assistant(
|
let message =
|
||||||
"assistant".to_string(),
|
ChatCompletionRequestMessage::assistant("assistant".to_string(), content, tool_calls);
|
||||||
content,
|
|
||||||
tool_calls,
|
|
||||||
);
|
|
||||||
push_context_message(message).await;
|
push_context_message(message).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ use crate::core::context::{
|
|||||||
};
|
};
|
||||||
use ai::core::send_message;
|
use ai::core::send_message;
|
||||||
use common::queue::QueueMessage;
|
use common::queue::QueueMessage;
|
||||||
use serde_json::error;
|
|
||||||
use tokio::sync::{mpsc::Receiver, mpsc::Sender};
|
use tokio::sync::{mpsc::Receiver, mpsc::Sender};
|
||||||
use wechat::manager::WeChatMultiAccountManager;
|
use wechat::manager::WeChatMultiAccountManager;
|
||||||
|
|
||||||
@@ -11,7 +10,7 @@ pub async fn create_queue(
|
|||||||
sender: Sender<QueueMessage>,
|
sender: Sender<QueueMessage>,
|
||||||
mut receiver: Receiver<QueueMessage>,
|
mut receiver: Receiver<QueueMessage>,
|
||||||
manager: WeChatMultiAccountManager,
|
manager: WeChatMultiAccountManager,
|
||||||
) -> Result<(), error::Error> {
|
) -> anyhow::Result<()> {
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
while let Some(msg) = receiver.recv().await {
|
while let Some(msg) = receiver.recv().await {
|
||||||
let queue_sender = sender.clone();
|
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 channel;
|
||||||
mod core;
|
mod core;
|
||||||
mod error;
|
|
||||||
mod http;
|
mod http;
|
||||||
mod model;
|
mod model;
|
||||||
mod repository;
|
mod repository;
|
||||||
|
|||||||
Reference in New Issue
Block a user