chore: 保存当前架构收口与 bug 修复快照

归档本轮 P0/P1 bug 修复、设计审查迁移、AI selection scope 收口与 stream contract 调整,并保留当前 05 主线迁移起点。
This commit is contained in:
lix-2026
2026-05-18 17:01:35 +08:00
parent 61ee4a38a2
commit a2cb1338c8
953 changed files with 14383 additions and 211845 deletions
@@ -43,6 +43,13 @@ pub enum AcpSessionEvent {
},
/// Context usage update.
UsageUpdate { used: u64, size: u64 },
/// Agent 发起权限请求;当前 runtime 会自动拒绝并同步给前端。
PermissionRequest {
permission_id: String,
tool_name: String,
params: Value,
decision: String,
},
/// Session metadata update (e.g. auto-title).
SessionInfoUpdate { title: String },
/// Plan entries update.
@@ -51,6 +58,16 @@ pub enum AcpSessionEvent {
Disconnected { reason: String },
}
#[derive(Debug, Clone, Default)]
pub struct AcpMnoteToolContext {
pub mnote_session_id: Option<String>,
pub run_id: Option<String>,
pub actor_id: Option<String>,
pub trace_id: Option<String>,
pub workspace_id: Option<String>,
pub document_id: Option<String>,
}
/// Handler for session events.
pub type SessionEventHandler = Arc<dyn Fn(AcpSessionEvent) + Send + Sync + 'static>;
@@ -101,6 +118,34 @@ impl AcpSessionManager {
let in_prompt_clone = in_prompt.clone();
client.on_notification(move |method, params| {
if method == "session/request_permission" {
let permission_id = params
.get("permissionId")
.or_else(|| params.get("permission_id"))
.or_else(|| params.get("requestId"))
.or_else(|| params.get("id"))
.and_then(Value::as_str)
.unwrap_or("permission_auto_denied")
.to_string();
let tool_name = params
.get("toolName")
.or_else(|| params.get("tool"))
.or_else(|| params.get("name"))
.or_else(|| params.get("method"))
.and_then(Value::as_str)
.unwrap_or("session/request_permission")
.to_string();
let handler = event_handler_clone.lock().unwrap();
if let Some(ref h) = *handler {
h(AcpSessionEvent::PermissionRequest {
permission_id,
tool_name,
params,
decision: "denied".into(),
});
}
return;
}
if method != "session/update" {
return;
}
@@ -193,6 +238,14 @@ impl AcpSessionManager {
pub async fn run_prompt(
&self,
prompt: Vec<ContentBlock>,
) -> Result<SessionPromptResult, crate::acp_client::AcpError> {
self.run_prompt_with_mnote_context(prompt, None).await
}
pub async fn run_prompt_with_mnote_context(
&self,
prompt: Vec<ContentBlock>,
mnote_context: Option<AcpMnoteToolContext>,
) -> Result<SessionPromptResult, crate::acp_client::AcpError> {
{
let mut in_prompt = self.in_prompt.lock().unwrap();
@@ -215,9 +268,16 @@ impl AcpSessionManager {
)
})?;
let mnote_context = mnote_context.unwrap_or_default();
let params = SessionPromptParams {
session_id: session_id.clone(),
prompt,
mnote_session_id: mnote_context.mnote_session_id,
run_id: mnote_context.run_id,
actor_id: mnote_context.actor_id,
trace_id: mnote_context.trace_id,
workspace_id: mnote_context.workspace_id,
document_id: mnote_context.document_id,
};
debug!("ACP session/prompt (session={})", session_id);