213 lines
6.4 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

pub mod ws_adapter;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SessionSummary {
pub session_id: String,
pub title: String,
pub channel_name: String,
pub chat_id: String,
pub message_count: i64,
pub last_active_at: i64,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub archived_at: Option<i64>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Channel {
pub id: String,
pub name: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
#[serde(rename = "isWritable")]
pub is_writable: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TopicSummary {
pub topic_id: String,
pub session_id: String,
pub title: String,
pub message_count: i64,
pub created_at: i64,
pub last_active_at: i64,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MediaSummary {
pub path: String,
pub media_type: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub mime_type: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub content_base64: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub file_name: Option<String>,
}
/// 定时任务会话查找键(用于前端加载执行对话)
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SchedulerJobSessionLookup {
pub channel: String,
pub chat_id: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SchedulerJobSummary {
pub id: String,
pub kind: String,
pub schedule: serde_json::Value,
pub enabled: bool,
pub state: String,
pub last_status: Option<String>,
pub last_error: Option<String>,
pub run_count: i64,
pub max_runs: Option<i64>,
pub last_fired_at: Option<i64>,
pub next_fire_at: Option<i64>,
pub created_at: i64,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub session_lookup: Option<SchedulerJobSessionLookup>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type")]
pub enum WsInbound {
/// 普通用户消息
#[serde(rename = "message")]
Message {
content: String,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
attachments: Vec<MediaSummary>,
#[serde(default, skip_serializing_if = "Option::is_none")]
channel: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
chat_id: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
sender_id: Option<String>,
},
/// 命令JSON 格式)
#[serde(rename = "command")]
Command { payload: String },
#[serde(rename = "ping")]
Ping,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type")]
pub enum WsOutbound {
#[serde(rename = "assistant_response")]
AssistantResponse {
id: String,
content: String,
role: String,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
attachments: Vec<MediaSummary>,
#[serde(default, skip_serializing_if = "Option::is_none")]
subagent_task_id: Option<String>,
},
#[serde(rename = "tool_call")]
ToolCall {
id: String,
tool_call_id: String,
tool_name: String,
arguments: serde_json::Value,
content: String,
role: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
subagent_task_id: Option<String>,
},
#[serde(rename = "tool_result")]
ToolResult {
id: String,
tool_call_id: String,
tool_name: String,
content: String,
role: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
subagent_task_id: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
duration_ms: Option<u64>,
},
#[serde(rename = "tool_pending")]
ToolPending {
id: String,
tool_call_id: String,
tool_name: String,
content: String,
role: String,
resume_hint: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
subagent_task_id: Option<String>,
},
#[serde(rename = "error")]
Error { code: String, message: String },
#[serde(rename = "task_started")]
TaskStarted {
task_id: String,
description: String,
subagent_type: String,
},
#[serde(rename = "session_established")]
SessionEstablished { session_id: String },
#[serde(rename = "session_created")]
SessionCreated { session_id: String, title: String },
#[serde(rename = "session_list")]
SessionList {
sessions: Vec<SessionSummary>,
#[serde(default, skip_serializing_if = "Option::is_none")]
current_session_id: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
channel_name: Option<String>,
},
#[serde(rename = "channel_list")]
ChannelList {
channels: Vec<Channel>,
},
#[serde(rename = "topic_list")]
TopicList {
topics: Vec<TopicSummary>,
session_id: String,
},
#[serde(rename = "session_loaded")]
SessionLoaded {
session_id: String,
title: String,
message_count: i64,
},
#[serde(rename = "session_saved")]
SessionSaved { session_id: String, filepath: String },
#[serde(rename = "task_messages_loaded")]
TaskMessagesLoaded {
task_id: String,
description: String,
subagent_type: String,
status: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
summary: Option<String>,
},
#[serde(rename = "scheduler_job_list")]
SchedulerJobList {
jobs: Vec<SchedulerJobSummary>,
},
#[serde(rename = "execution_cancelled")]
ExecutionCancelled { message: String },
#[serde(rename = "pong")]
Pong,
}
pub fn parse_inbound(raw: &str) -> Result<WsInbound, serde_json::Error> {
serde_json::from_str(raw)
}
pub fn serialize_inbound(msg: &WsInbound) -> Result<String, serde_json::Error> {
serde_json::to_string(msg)
}
pub fn serialize_outbound(msg: &WsOutbound) -> Result<String, serde_json::Error> {
serde_json::to_string(msg)
}