feat(ai): Phase 2 SQL 风险分类 + Agent 模式工具调用结果渲染

后端:
  - 新增 sql_risk.rs:基于 sqlparser AST 的 SQL 风险分类(ReadOnly/Write/Ddl/Transaction)
  - agent_tools.rs:新增 execute_query 和 get_sample_data 工具,写操作/DDL 被风险分类阻止
  - agent_loop.rs:支持 is_agent_mode 参数,Agent 模式下暴露全部工具,Ask 模式仅暴露只读工具
  - agent_loop/web/tauri:mode 参数全链路传递(前端→HTTP→Tauri→Rust)

  前端:
  - AiAgentStepItem 接口扩展:toolName/toolArgs/toolResult/isError 字段
  - AiAssistant.vue:工具调用结果实时+最终渲染,SQL 查询结果/错误信息展示
  - ai.ts/http.ts/tauri.ts:mode 参数透传到后端
This commit is contained in:
runstone committed 2026-06-12 17:42:23 +08:00
1 parent 84a9fd6a0f
commit 100124da3e
11 files changed
+501 -32

No files matched your search

+4 -1
View File
@@ -1,4 +1,4 @@
use std::sync::Arc;
use std::sync::Arc;
use tauri::{AppHandle, Emitter, State};
use super::connection::AppState;
@@ -60,6 +60,7 @@ pub async fn ai_agent_stream(
connection_id: String,
database: String,
db_type: String,
mode: Option<String>,
) -> Result<String, String> {
let cancelled = dbx_core::ai::register_stream(&session_id).await;
@@ -67,6 +68,7 @@ pub async fn ai_agent_stream(
serde_json::from_str(&format!("\"{}\"", db_type)).map_err(|_| format!("Unknown database type: {db_type}"))?;
let agent_ctx = AgentLoopContext { state: state.inner().clone(), connection_id, database, db_type: parsed_db_type };
let is_agent_mode = mode.as_deref() == Some("agent");
let result = run_agent_loop(
&request.config,
@@ -82,6 +84,7 @@ pub async fn ai_agent_stream(
&cancelled,
request.max_tokens,
request.temperature,
is_agent_mode,
)
.await;