refactor: remove dead code and unused state
This commit is contained in:
parent
560ace50c1
commit
c2d4fc5f09
@ -5,7 +5,6 @@ edition = "2024"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
reqwest = { version = "0.13.3", default-features = false, features = ["json", "rustls", "multipart"] }
|
reqwest = { version = "0.13.3", default-features = false, features = ["json", "rustls", "multipart"] }
|
||||||
dotenv = "0.15"
|
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
regex = "1.12"
|
regex = "1.12"
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
@ -35,7 +34,6 @@ crossterm = { version = "0.29", features = ["event-stream"] }
|
|||||||
termimad = "0.34"
|
termimad = "0.34"
|
||||||
textwrap = "0.16"
|
textwrap = "0.16"
|
||||||
chrono = "0.4"
|
chrono = "0.4"
|
||||||
hostname = "0.4"
|
|
||||||
sqlx = { version = "0.8", features = ["sqlite", "macros", "chrono", "runtime-tokio"] }
|
sqlx = { version = "0.8", features = ["sqlite", "macros", "chrono", "runtime-tokio"] }
|
||||||
jieba-rs = "0.9"
|
jieba-rs = "0.9"
|
||||||
which = "8"
|
which = "8"
|
||||||
@ -52,6 +50,9 @@ tar = "0.4"
|
|||||||
fantoccini = { version = "0.22", default-features = false, features = ["rustls-tls"] }
|
fantoccini = { version = "0.22", default-features = false, features = ["rustls-tls"] }
|
||||||
portable-pty = "0.9"
|
portable-pty = "0.9"
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
dotenv = "0.15"
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
zstd = "0.13"
|
zstd = "0.13"
|
||||||
tar = "0.4"
|
tar = "0.4"
|
||||||
|
|||||||
@ -391,16 +391,15 @@ impl SubAgentManager {
|
|||||||
// Update DB: running
|
// Update DB: running
|
||||||
if let Some(ref s) = storage {
|
if let Some(ref s) = storage {
|
||||||
let _ = s
|
let _ = s
|
||||||
.update_background_task_status(
|
.update_background_task_status(&tid, crate::storage::background_task::BackgroundTaskUpdate {
|
||||||
&tid,
|
status: "running",
|
||||||
"running",
|
result: None,
|
||||||
None,
|
error: None,
|
||||||
None,
|
started_at: Some(started_at),
|
||||||
Some(started_at),
|
finished_at: None,
|
||||||
None,
|
tool_calls_count: None,
|
||||||
None,
|
iterations: None,
|
||||||
None,
|
})
|
||||||
)
|
|
||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -513,16 +512,15 @@ impl SubAgentManager {
|
|||||||
|
|
||||||
if let Some(ref s) = storage {
|
if let Some(ref s) = storage {
|
||||||
let _ = s
|
let _ = s
|
||||||
.update_background_task_status(
|
.update_background_task_status(&tid, crate::storage::background_task::BackgroundTaskUpdate {
|
||||||
&tid,
|
status: &status_str,
|
||||||
&status_str,
|
result: Some(&result.content),
|
||||||
Some(&result.content),
|
error: error_val.as_deref(),
|
||||||
error_val.as_deref(),
|
started_at: Some(started_at),
|
||||||
Some(started_at),
|
finished_at: Some(finished_at),
|
||||||
Some(finished_at),
|
tool_calls_count: Some(result.tool_calls_count as i64),
|
||||||
Some(result.tool_calls_count as i64),
|
iterations: Some(result.iterations as i64),
|
||||||
Some(result.iterations as i64),
|
})
|
||||||
)
|
|
||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -544,13 +542,15 @@ impl SubAgentManager {
|
|||||||
let _ = storage
|
let _ = storage
|
||||||
.update_background_task_status(
|
.update_background_task_status(
|
||||||
&task_id,
|
&task_id,
|
||||||
"cancelled",
|
crate::storage::background_task::BackgroundTaskUpdate {
|
||||||
None,
|
status: "cancelled",
|
||||||
Some("gateway shutdown"),
|
result: None,
|
||||||
None,
|
error: Some("gateway shutdown"),
|
||||||
Some(chrono::Utc::now().timestamp_millis()),
|
started_at: None,
|
||||||
None,
|
finished_at: Some(chrono::Utc::now().timestamp_millis()),
|
||||||
None,
|
tool_calls_count: None,
|
||||||
|
iterations: None,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
@ -568,13 +568,15 @@ impl SubAgentManager {
|
|||||||
if let Some(ref s) = self.storage {
|
if let Some(ref s) = self.storage {
|
||||||
s.update_background_task_status(
|
s.update_background_task_status(
|
||||||
task_id,
|
task_id,
|
||||||
"cancelled",
|
crate::storage::background_task::BackgroundTaskUpdate {
|
||||||
None,
|
status: "cancelled",
|
||||||
None,
|
result: None,
|
||||||
None,
|
error: None,
|
||||||
Some(chrono::Utc::now().timestamp_millis()),
|
started_at: None,
|
||||||
None,
|
finished_at: Some(chrono::Utc::now().timestamp_millis()),
|
||||||
None,
|
tool_calls_count: None,
|
||||||
|
iterations: None,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| SubAgentError::Storage(e.to_string()))?;
|
.map_err(|e| SubAgentError::Storage(e.to_string()))?;
|
||||||
@ -662,6 +664,16 @@ fn truncate_sub_agent_result(content: &str) -> (String, bool) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn summarize_for_notification(content: &str, _duration_ms: u64) -> String {
|
||||||
|
const MAX_SUMMARY_BYTES: usize = 500;
|
||||||
|
if content.len() <= MAX_SUMMARY_BYTES {
|
||||||
|
content.to_string()
|
||||||
|
} else {
|
||||||
|
let truncate_at = content.floor_char_boundary(MAX_SUMMARY_BYTES);
|
||||||
|
format!("{}...", &content[..truncate_at])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
@ -723,13 +735,3 @@ mod tests {
|
|||||||
assert!(matches!(error, SubAgentError::TooManyTasks(1)));
|
assert!(matches!(error, SubAgentError::TooManyTasks(1)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn summarize_for_notification(content: &str, _duration_ms: u64) -> String {
|
|
||||||
const MAX_SUMMARY_BYTES: usize = 500;
|
|
||||||
if content.len() <= MAX_SUMMARY_BYTES {
|
|
||||||
content.to_string()
|
|
||||||
} else {
|
|
||||||
let truncate_at = content.floor_char_boundary(MAX_SUMMARY_BYTES);
|
|
||||||
format!("{}...", &content[..truncate_at])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@ -264,12 +264,6 @@ pub struct InboundMessage {
|
|||||||
pub forwarded_metadata: HashMap<String, String>,
|
pub forwarded_metadata: HashMap<String, String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InboundMessage {
|
|
||||||
pub fn session_key(&self) -> String {
|
|
||||||
format!("{}:{}", self.channel, self.chat_id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// OutboundMessage - Message from Agent to Channel (bot response)
|
// OutboundMessage - Message from Agent to Channel (bot response)
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
@ -284,12 +278,6 @@ pub struct OutboundMessage {
|
|||||||
pub metadata: HashMap<String, String>,
|
pub metadata: HashMap<String, String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OutboundMessage {
|
|
||||||
pub fn is_stream_delta(&self) -> bool {
|
|
||||||
self.metadata.contains_key("_stream_delta")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// ControlMessage - Message for control channel (session management)
|
// ControlMessage - Message for control channel (session management)
|
||||||
// Uses SessionCommand from session module
|
// Uses SessionCommand from session module
|
||||||
|
|||||||
@ -90,7 +90,6 @@ struct LarkEvent {
|
|||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
struct LarkEventHeader {
|
struct LarkEventHeader {
|
||||||
event_type: String,
|
event_type: String,
|
||||||
#[allow(dead_code)]
|
|
||||||
event_id: String,
|
event_id: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -122,19 +121,13 @@ struct LarkSenderId {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
#[allow(dead_code)]
|
|
||||||
struct LarkMessage {
|
struct LarkMessage {
|
||||||
message_id: String,
|
message_id: String,
|
||||||
chat_id: String,
|
chat_id: String,
|
||||||
chat_type: String,
|
|
||||||
message_type: String,
|
message_type: String,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
content: String,
|
content: String,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
mentions: Vec<serde_json::Value>,
|
|
||||||
#[serde(default)]
|
|
||||||
root_id: Option<String>,
|
|
||||||
#[serde(default)]
|
|
||||||
parent_id: Option<String>,
|
parent_id: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -21,7 +21,7 @@ pub async fn run(gateway_url: &str) -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
|
|
||||||
let (ws_sender, ws_receiver) = ws_stream.split();
|
let (ws_sender, ws_receiver) = ws_stream.split();
|
||||||
|
|
||||||
let mut app = App::new(gateway_url.to_string());
|
let mut app = App::new();
|
||||||
app.ws_sender = Some(ws_sender);
|
app.ws_sender = Some(ws_sender);
|
||||||
app.ws_receiver = Some(ws_receiver);
|
app.ws_receiver = Some(ws_receiver);
|
||||||
|
|
||||||
|
|||||||
@ -1,16 +1,7 @@
|
|||||||
#![allow(dead_code)]
|
|
||||||
use crate::protocol::{SessionSummary, SlashCommandInfo};
|
use crate::protocol::{SessionSummary, SlashCommandInfo};
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use tokio_tungstenite::tungstenite::Message;
|
use tokio_tungstenite::tungstenite::Message;
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
||||||
pub enum FocusArea {
|
|
||||||
TitleBar,
|
|
||||||
SessionList,
|
|
||||||
ChatHistory,
|
|
||||||
InputArea,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum MessageRole {
|
pub enum MessageRole {
|
||||||
User,
|
User,
|
||||||
@ -25,7 +16,6 @@ pub struct ChatMessage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct App {
|
pub struct App {
|
||||||
pub gateway_url: String,
|
|
||||||
pub ws_sender: Option<
|
pub ws_sender: Option<
|
||||||
futures_util::stream::SplitSink<
|
futures_util::stream::SplitSink<
|
||||||
tokio_tungstenite::WebSocketStream<
|
tokio_tungstenite::WebSocketStream<
|
||||||
@ -47,12 +37,10 @@ pub struct App {
|
|||||||
|
|
||||||
pub messages: VecDeque<ChatMessage>,
|
pub messages: VecDeque<ChatMessage>,
|
||||||
|
|
||||||
pub focus: FocusArea,
|
|
||||||
pub input: String,
|
pub input: String,
|
||||||
pub input_cursor_pos: usize,
|
pub input_cursor_pos: usize,
|
||||||
pub show_help: bool,
|
pub show_help: bool,
|
||||||
pub chat_scroll_offset: u16,
|
pub chat_scroll_offset: u16,
|
||||||
pub session_scroll_offset: u16,
|
|
||||||
pub should_quit: bool,
|
pub should_quit: bool,
|
||||||
|
|
||||||
// Quit confirmation state (double Ctrl+C to exit)
|
// Quit confirmation state (double Ctrl+C to exit)
|
||||||
@ -66,20 +54,17 @@ pub struct App {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl App {
|
impl App {
|
||||||
pub fn new(gateway_url: String) -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
gateway_url,
|
|
||||||
ws_sender: None,
|
ws_sender: None,
|
||||||
ws_receiver: None,
|
ws_receiver: None,
|
||||||
current_session_id: None,
|
current_session_id: None,
|
||||||
sessions: Vec::new(),
|
sessions: Vec::new(),
|
||||||
messages: VecDeque::new(),
|
messages: VecDeque::new(),
|
||||||
focus: FocusArea::InputArea,
|
|
||||||
input: String::new(),
|
input: String::new(),
|
||||||
input_cursor_pos: 0,
|
input_cursor_pos: 0,
|
||||||
show_help: false,
|
show_help: false,
|
||||||
chat_scroll_offset: 0,
|
chat_scroll_offset: 0,
|
||||||
session_scroll_offset: 0,
|
|
||||||
should_quit: false,
|
should_quit: false,
|
||||||
ctrl_c_count: 0,
|
ctrl_c_count: 0,
|
||||||
pending_quit: false,
|
pending_quit: false,
|
||||||
@ -111,14 +96,6 @@ impl App {
|
|||||||
self.chat_scroll_offset = self.chat_scroll_offset.saturating_sub(1);
|
self.chat_scroll_offset = self.chat_scroll_offset.saturating_sub(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn scroll_session_up(&mut self) {
|
|
||||||
self.session_scroll_offset = self.session_scroll_offset.saturating_add(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn scroll_session_down(&mut self) {
|
|
||||||
self.session_scroll_offset = self.session_scroll_offset.saturating_sub(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn input_insert_char(&mut self, c: char) {
|
pub fn input_insert_char(&mut self, c: char) {
|
||||||
self.input.insert(self.input_cursor_pos, c);
|
self.input.insert(self.input_cursor_pos, c);
|
||||||
self.input_cursor_pos += 1;
|
self.input_cursor_pos += 1;
|
||||||
@ -149,11 +126,6 @@ impl App {
|
|||||||
self.input_cursor_pos = self.input.len();
|
self.input_cursor_pos = self.input.len();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn input_clear(&mut self) {
|
|
||||||
self.input.clear();
|
|
||||||
self.input_cursor_pos = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn take_input(&mut self) -> String {
|
pub fn take_input(&mut self) -> String {
|
||||||
let input = std::mem::take(&mut self.input);
|
let input = std::mem::take(&mut self.input);
|
||||||
self.input_cursor_pos = 0;
|
self.input_cursor_pos = 0;
|
||||||
|
|||||||
@ -1,5 +0,0 @@
|
|||||||
#![allow(dead_code)]
|
|
||||||
|
|
||||||
pub fn render_markdown(content: &str) -> String {
|
|
||||||
content.to_string()
|
|
||||||
}
|
|
||||||
@ -1,5 +1,4 @@
|
|||||||
pub mod app;
|
pub mod app;
|
||||||
pub mod components;
|
pub mod components;
|
||||||
pub mod event;
|
pub mod event;
|
||||||
pub mod markdown;
|
|
||||||
pub mod ui;
|
pub mod ui;
|
||||||
|
|||||||
@ -59,20 +59,3 @@ pub fn init_logging() {
|
|||||||
|
|
||||||
tracing::info!("Logging initialized. Log directory: {}", log_dir.display());
|
tracing::info!("Logging initialized. Log directory: {}", log_dir.display());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Initialize logging without file output (console only)
|
|
||||||
pub fn init_logging_console_only() {
|
|
||||||
let env_filter = EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("info"));
|
|
||||||
|
|
||||||
let console_layer = fmt::layer()
|
|
||||||
.with_timer(LocalTime::rfc_3339())
|
|
||||||
.with_target(true)
|
|
||||||
.with_level(true);
|
|
||||||
|
|
||||||
tracing_subscriber::registry()
|
|
||||||
.with(env_filter)
|
|
||||||
.with(console_layer)
|
|
||||||
.init();
|
|
||||||
|
|
||||||
tracing::info!("Logging initialized (console only)");
|
|
||||||
}
|
|
||||||
|
|||||||
@ -47,8 +47,6 @@ fn update_mcp_status(servers: Vec<McpServerStatus>) {
|
|||||||
/// A connected MCP server. Holds a clonable Peer handle for tool calls,
|
/// A connected MCP server. Holds a clonable Peer handle for tool calls,
|
||||||
/// and keeps the underlying service alive via a background task.
|
/// and keeps the underlying service alive via a background task.
|
||||||
pub struct McpConnection {
|
pub struct McpConnection {
|
||||||
#[allow(dead_code)]
|
|
||||||
pub name: String,
|
|
||||||
peer: Peer<RoleClient>,
|
peer: Peer<RoleClient>,
|
||||||
/// Keep the service alive. When dropped, the MCP connection is closed.
|
/// Keep the service alive. When dropped, the MCP connection is closed.
|
||||||
_service: Option<Box<dyn std::any::Any + Send + Sync>>,
|
_service: Option<Box<dyn std::any::Any + Send + Sync>>,
|
||||||
@ -230,7 +228,6 @@ async fn connect_server(config: &McpServerConfig) -> anyhow::Result<McpConnectio
|
|||||||
let peer = service.peer().clone();
|
let peer = service.peer().clone();
|
||||||
|
|
||||||
Ok(McpConnection {
|
Ok(McpConnection {
|
||||||
name: config.name.clone(),
|
|
||||||
peer,
|
peer,
|
||||||
_service: Some(Box::new(service)),
|
_service: Some(Box::new(service)),
|
||||||
})
|
})
|
||||||
@ -268,7 +265,6 @@ async fn connect_server(config: &McpServerConfig) -> anyhow::Result<McpConnectio
|
|||||||
let peer = service.peer().clone();
|
let peer = service.peer().clone();
|
||||||
|
|
||||||
Ok(McpConnection {
|
Ok(McpConnection {
|
||||||
name: config.name.clone(),
|
|
||||||
peer,
|
peer,
|
||||||
_service: Some(Box::new(service)),
|
_service: Some(Box::new(service)),
|
||||||
})
|
})
|
||||||
|
|||||||
@ -70,16 +70,6 @@ impl ToolExecutionOutcome {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a successful outcome with duration.
|
|
||||||
pub fn success_with_duration(output: String, duration: Duration) -> Self {
|
|
||||||
Self {
|
|
||||||
output,
|
|
||||||
success: true,
|
|
||||||
error_reason: None,
|
|
||||||
duration,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Create a failed outcome with zero duration.
|
/// Create a failed outcome with zero duration.
|
||||||
pub fn failure(output: String, error_reason: Option<String>) -> Self {
|
pub fn failure(output: String, error_reason: Option<String>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
@ -89,20 +79,6 @@ impl ToolExecutionOutcome {
|
|||||||
duration: Duration::ZERO,
|
duration: Duration::ZERO,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a failed outcome with duration.
|
|
||||||
pub fn failure_with_duration(
|
|
||||||
output: String,
|
|
||||||
error_reason: Option<String>,
|
|
||||||
duration: Duration,
|
|
||||||
) -> Self {
|
|
||||||
Self {
|
|
||||||
output,
|
|
||||||
success: false,
|
|
||||||
error_reason,
|
|
||||||
duration,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// MultiObserver broadcasts events to multiple observers.
|
/// MultiObserver broadcasts events to multiple observers.
|
||||||
@ -204,16 +180,6 @@ mod tests {
|
|||||||
assert_eq!(outcome.duration, Duration::ZERO);
|
assert_eq!(outcome.duration, Duration::ZERO);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_tool_execution_outcome_success_with_duration() {
|
|
||||||
let outcome = ToolExecutionOutcome::success_with_duration(
|
|
||||||
"output content".to_string(),
|
|
||||||
Duration::from_millis(100),
|
|
||||||
);
|
|
||||||
assert!(outcome.success);
|
|
||||||
assert_eq!(outcome.duration, Duration::from_millis(100));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_tool_execution_outcome_failure() {
|
fn test_tool_execution_outcome_failure() {
|
||||||
let outcome = ToolExecutionOutcome::failure(
|
let outcome = ToolExecutionOutcome::failure(
|
||||||
|
|||||||
@ -167,7 +167,6 @@ enum AnthropicContent {
|
|||||||
},
|
},
|
||||||
Thinking {
|
Thinking {
|
||||||
#[serde(alias = "content")]
|
#[serde(alias = "content")]
|
||||||
#[allow(dead_code)]
|
|
||||||
thinking: String,
|
thinking: String,
|
||||||
},
|
},
|
||||||
#[serde(rename = "tool_use")]
|
#[serde(rename = "tool_use")]
|
||||||
|
|||||||
@ -28,17 +28,6 @@ impl Message {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn user_with_blocks(content: Vec<ContentBlock>) -> Self {
|
|
||||||
Self {
|
|
||||||
role: "user".to_string(),
|
|
||||||
content,
|
|
||||||
reasoning_content: None,
|
|
||||||
tool_call_id: None,
|
|
||||||
name: None,
|
|
||||||
tool_calls: None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn assistant(content: impl Into<String>) -> Self {
|
pub fn assistant(content: impl Into<String>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
role: "assistant".to_string(),
|
role: "assistant".to_string(),
|
||||||
|
|||||||
@ -82,7 +82,6 @@ pub struct Session {
|
|||||||
/// Messages before this time have been compressed into memory.
|
/// Messages before this time have been compressed into memory.
|
||||||
pub last_consolidated_at: Option<i64>,
|
pub last_consolidated_at: Option<i64>,
|
||||||
pub last_compressed_message_at: Option<i64>,
|
pub last_compressed_message_at: Option<i64>,
|
||||||
#[allow(dead_code)]
|
|
||||||
memory_manager: Arc<crate::memory::MemoryManager>,
|
memory_manager: Arc<crate::memory::MemoryManager>,
|
||||||
|
|
||||||
/// Task queue for per-session serial agent processing
|
/// Task queue for per-session serial agent processing
|
||||||
@ -2681,28 +2680,3 @@ fn format_task_notification(
|
|||||||
crate::agent::TaskStatus::TimedOut => format!("📋 后台任务超时\n\n任务 ID: {}", task_id),
|
crate::agent::TaskStatus::TimedOut => format!("📋 后台任务超时\n\n任务 ID: {}", task_id),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
use std::collections::HashMap;
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
fn test_provider_config() -> LLMProviderConfig {
|
|
||||||
LLMProviderConfig {
|
|
||||||
provider_type: "openai".to_string(),
|
|
||||||
name: "test".to_string(),
|
|
||||||
base_url: "http://localhost".to_string(),
|
|
||||||
api_key: "test-key".to_string(),
|
|
||||||
extra_headers: HashMap::new(),
|
|
||||||
model_id: "test-model".to_string(),
|
|
||||||
temperature: Some(0.0),
|
|
||||||
max_tokens: Some(32),
|
|
||||||
model_extra: HashMap::new(),
|
|
||||||
max_tool_iterations: 1,
|
|
||||||
token_limit: 4096,
|
|
||||||
workspace_dir: std::path::PathBuf::from("/tmp/test-workspace"),
|
|
||||||
input_types: vec!["text".to_string()],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@ -17,3 +17,13 @@ pub struct BackgroundTask {
|
|||||||
pub finished_at: Option<i64>,
|
pub finished_at: Option<i64>,
|
||||||
pub created_at: i64,
|
pub created_at: i64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) struct BackgroundTaskUpdate<'a> {
|
||||||
|
pub status: &'a str,
|
||||||
|
pub result: Option<&'a str>,
|
||||||
|
pub error: Option<&'a str>,
|
||||||
|
pub started_at: Option<i64>,
|
||||||
|
pub finished_at: Option<i64>,
|
||||||
|
pub tool_calls_count: Option<i64>,
|
||||||
|
pub iterations: Option<i64>,
|
||||||
|
}
|
||||||
|
|||||||
@ -1056,16 +1056,10 @@ impl Storage {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn update_background_task_status(
|
pub(crate) async fn update_background_task_status(
|
||||||
&self,
|
&self,
|
||||||
id: &str,
|
id: &str,
|
||||||
status: &str,
|
update: crate::storage::background_task::BackgroundTaskUpdate<'_>,
|
||||||
result: Option<&str>,
|
|
||||||
error: Option<&str>,
|
|
||||||
started_at: Option<i64>,
|
|
||||||
finished_at: Option<i64>,
|
|
||||||
tool_calls_count: Option<i64>,
|
|
||||||
iterations: Option<i64>,
|
|
||||||
) -> Result<(), StorageError> {
|
) -> Result<(), StorageError> {
|
||||||
sqlx::query(
|
sqlx::query(
|
||||||
r#"
|
r#"
|
||||||
@ -1077,13 +1071,13 @@ impl Storage {
|
|||||||
WHERE id = ?
|
WHERE id = ?
|
||||||
"#,
|
"#,
|
||||||
)
|
)
|
||||||
.bind(status)
|
.bind(update.status)
|
||||||
.bind(result)
|
.bind(update.result)
|
||||||
.bind(error)
|
.bind(update.error)
|
||||||
.bind(started_at)
|
.bind(update.started_at)
|
||||||
.bind(finished_at)
|
.bind(update.finished_at)
|
||||||
.bind(tool_calls_count)
|
.bind(update.tool_calls_count)
|
||||||
.bind(iterations)
|
.bind(update.iterations)
|
||||||
.bind(id)
|
.bind(id)
|
||||||
.execute(self.pool())
|
.execute(self.pool())
|
||||||
.await?;
|
.await?;
|
||||||
@ -1270,13 +1264,15 @@ mod tests {
|
|||||||
storage
|
storage
|
||||||
.update_background_task_status(
|
.update_background_task_status(
|
||||||
&task.id,
|
&task.id,
|
||||||
"completed",
|
crate::storage::background_task::BackgroundTaskUpdate {
|
||||||
Some("done"),
|
status: "completed",
|
||||||
None,
|
result: Some("done"),
|
||||||
Some(2),
|
error: None,
|
||||||
Some(3),
|
started_at: Some(2),
|
||||||
Some(4),
|
finished_at: Some(3),
|
||||||
Some(5),
|
tool_calls_count: Some(4),
|
||||||
|
iterations: Some(5),
|
||||||
|
},
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|||||||
@ -96,11 +96,7 @@ enum SessionStatus {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct PtySession {
|
struct PtySession {
|
||||||
#[allow(dead_code)]
|
|
||||||
id: String,
|
|
||||||
#[allow(dead_code)]
|
|
||||||
command: String,
|
command: String,
|
||||||
#[allow(dead_code)]
|
|
||||||
started_at: Instant,
|
started_at: Instant,
|
||||||
status: SessionStatus,
|
status: SessionStatus,
|
||||||
child: Arc<Mutex<Option<Box<dyn portable_pty::Child + Send + Sync>>>>,
|
child: Arc<Mutex<Option<Box<dyn portable_pty::Child + Send + Sync>>>>,
|
||||||
@ -111,13 +107,11 @@ struct PtySession {
|
|||||||
|
|
||||||
impl PtySession {
|
impl PtySession {
|
||||||
fn new(
|
fn new(
|
||||||
id: String,
|
|
||||||
command: String,
|
command: String,
|
||||||
child: Box<dyn portable_pty::Child + Send + Sync>,
|
child: Box<dyn portable_pty::Child + Send + Sync>,
|
||||||
writer: Box<dyn Write + Send>,
|
writer: Box<dyn Write + Send>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
id,
|
|
||||||
command,
|
command,
|
||||||
started_at: Instant::now(),
|
started_at: Instant::now(),
|
||||||
status: SessionStatus::Running,
|
status: SessionStatus::Running,
|
||||||
@ -225,8 +219,7 @@ impl PtyManager {
|
|||||||
.try_clone_reader()
|
.try_clone_reader()
|
||||||
.map_err(|e| format!("Failed to clone reader: {}", e))?;
|
.map_err(|e| format!("Failed to clone reader: {}", e))?;
|
||||||
|
|
||||||
let session_id_clone = session_id.clone();
|
let session = PtySession::new(command.to_string(), child, writer);
|
||||||
let session = PtySession::new(session_id_clone, command.to_string(), child, writer);
|
|
||||||
let session = Arc::new(Mutex::new(session));
|
let session = Arc::new(Mutex::new(session));
|
||||||
sessions.insert(session_id.clone(), session.clone());
|
sessions.insert(session_id.clone(), session.clone());
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user