新增: AI Chat多项增强(审批去重/编辑重发/导出/实体引用/会话置顶搜索)+任务推进链df-nodes落地
This commit is contained in:
@@ -15,11 +15,47 @@ export const aiApi = {
|
||||
return invoke('ai_chat_force_send', { message, language: language || 'zh-CN', skill: skill || null })
|
||||
},
|
||||
|
||||
/**
|
||||
* 重新生成最后一条 AI 回复(UX-02)。
|
||||
* 后端:占用 generating → 弹出末尾 AI 回复(保留触发它的 user 消息)→ 重跑 agentic loop。
|
||||
* 前端消费:与 sendMessage 一样需本地 push 空气泡占位 + 置 streaming(见 useAiSend.regenerate)。
|
||||
*/
|
||||
regenerate(conversationId: string, language?: string): Promise<string> {
|
||||
return invoke('ai_regenerate', { conversationId, language: language || 'zh-CN' })
|
||||
},
|
||||
|
||||
/**
|
||||
* 编辑最后一条 user 消息并重新生成(UX-09)。
|
||||
* 后端:占用 generating → 替换末条 user content → 其后消息标 truncated(软删)→ 重跑 agentic loop。
|
||||
* 前端消费:调 editMessage 前需移除被编辑消息之后的所有消息(视图截断)+ push 空气泡占位 + 置 streaming。
|
||||
* 中间 user 消息编辑被后端拒绝(只允许末条)。
|
||||
*/
|
||||
editMessage(conversationId: string, newMessage: string, language?: string): Promise<string> {
|
||||
return invoke('ai_chat_edit', { conversationId, newMessage, language: language || 'zh-CN' })
|
||||
},
|
||||
|
||||
/** 批准/拒绝工具调用 */
|
||||
approve(toolCallId: string, approved: boolean): Promise<string> {
|
||||
return invoke('ai_approve', { toolCallId, approved })
|
||||
},
|
||||
|
||||
/**
|
||||
* 续跑 agentic 循环(F-260616-03:达 max_iterations 暂停态点继续)。
|
||||
* 后端 ai_continue_loop:复位 stop_flag → try_continue_agent_loop 重新 spawn
|
||||
* run_agentic_loop(iteration 从 0 重计,再跑 max_iterations 轮)。
|
||||
*/
|
||||
continueLoop(conversationId: string): Promise<string> {
|
||||
return invoke('ai_continue_loop', { conversationId })
|
||||
},
|
||||
|
||||
/**
|
||||
* 停止 agentic 循环并走完成流程(F-260616-03:达 max_iterations 暂停态点停止)。
|
||||
* 后端 ai_stop_loop:复位 generating + emit AiCompleted(暂停前已 save)。
|
||||
*/
|
||||
stopLoop(conversationId: string): Promise<string> {
|
||||
return invoke('ai_stop_loop', { conversationId })
|
||||
},
|
||||
|
||||
/** 查询某对话积压的待审批工具(重启后恢复 toolCard pending_approval 态用) */
|
||||
pendingToolCalls(convId: string): Promise<{ tool_call_id: string; conversation_id: string | null }[]> {
|
||||
return invoke('ai_pending_tool_calls', { convId })
|
||||
@@ -74,6 +110,11 @@ export const aiApi = {
|
||||
return invoke('ai_set_concurrency_config', { globalLimit, perConvLimit })
|
||||
},
|
||||
|
||||
/** 设置 Agentic 循环最大轮次(运行时调整;loop 入口锁定边界,热改下次发消息生效) */
|
||||
setAgentMaxIterations(value: number): Promise<void> {
|
||||
return invoke('ai_set_agent_max_iterations', { value })
|
||||
},
|
||||
|
||||
/** 列出本机 Claude 技能(skills + commands + plugins) */
|
||||
listSkills(): Promise<SkillInfo[]> {
|
||||
return invoke('ai_list_skills')
|
||||
@@ -120,4 +161,18 @@ export const aiApi = {
|
||||
archiveConversation(conversationId: string, archived: boolean): Promise<void> {
|
||||
return invoke('ai_conversation_archive', { conversationId, archived })
|
||||
},
|
||||
|
||||
/** 置顶/取消置顶对话(UX-17) */
|
||||
setPinnedConversation(conversationId: string, pinned: boolean): Promise<void> {
|
||||
return invoke('ai_conversation_set_pinned', { conversationId, pinned })
|
||||
},
|
||||
|
||||
/**
|
||||
* 导出对话为指定格式(UX-18:对话导出;消费 batch46 ai_conversation_export IPC)。
|
||||
* 后端返回导出内容 String(markdown/json/txt),前端落 Blob 下载或复制剪贴板。
|
||||
* @param format 'markdown' | 'json' | 'txt'
|
||||
*/
|
||||
exportConversation(conversationId: string, format: 'markdown' | 'json' | 'txt'): Promise<string> {
|
||||
return invoke('ai_conversation_export', { conversationId, format })
|
||||
},
|
||||
}
|
||||
|
||||
@@ -125,7 +125,7 @@ export interface WorkflowRecord {
|
||||
/** 工作流事件载荷(后端 emit 的结构) */
|
||||
/** 工作流事件类型字面量联合(对应后端 WorkflowEvent serde tag=type rename_all=snake_case,R7收窄防写错 type 字符串) */
|
||||
export type WorkflowEventType =
|
||||
| 'node_started' | 'node_progress' | 'node_output' | 'node_completed' | 'node_failed'
|
||||
| 'node_started' | 'node_progress' | 'node_output' | 'node_completed' | 'node_failed' | 'node_cancelled'
|
||||
| 'workflow_paused' | 'workflow_completed' | 'workflow_failed'
|
||||
| 'human_approval_request' | 'human_approval_response'
|
||||
|
||||
@@ -180,6 +180,13 @@ export interface AiProviderConfig {
|
||||
updated_at: string
|
||||
}
|
||||
|
||||
/**
|
||||
* AI 错误分类字面量集(B-260615-42)。
|
||||
* 与后端 `commands::ai::ErrorType` 的 serde(rename_all = "snake_case") 严格对齐。
|
||||
* 前端消费方 switch 于此常量集做差异化提示(auth 引导填 key / network 提示连接 / 等)。
|
||||
*/
|
||||
export type AiErrorType = 'auth' | 'network' | 'timeout' | 'provider_config' | 'unknown'
|
||||
|
||||
/** AI 聊天事件(后端 emit 的结构,conversation_id 用于多对话流式路由) */
|
||||
export type AiChatEvent = ({
|
||||
type: 'AiTextDelta'; delta: string
|
||||
@@ -194,11 +201,14 @@ export type AiChatEvent = ({
|
||||
} | {
|
||||
type: 'AiCompleted'; total_tokens: number; prompt_tokens: number; completion_tokens: number
|
||||
} | {
|
||||
type: 'AiError'; error: string
|
||||
type: 'AiError'; error: string; error_type?: AiErrorType
|
||||
} | {
|
||||
type: 'AiAgentRound'; round: number
|
||||
} | {
|
||||
type: 'AiHeartbeat'
|
||||
} | {
|
||||
// F-260616-03: 达 max_iterations 暂停态(后端仍 generating=true),前端展示操作卡询问继续/停止
|
||||
type: 'AiMaxRoundsReached'
|
||||
}) & {
|
||||
conversation_id?: string
|
||||
}
|
||||
@@ -233,6 +243,7 @@ export interface AiConversationSummary {
|
||||
provider_id: string | null
|
||||
model: string | null
|
||||
archived: boolean
|
||||
pinned?: boolean
|
||||
prompt_tokens?: number | null
|
||||
completion_tokens?: number | null
|
||||
created_at: string
|
||||
|
||||
@@ -3,12 +3,25 @@ import { listen } from '@tauri-apps/api/event'
|
||||
import type { WorkflowRecord, WorkflowEventPayload } from './types'
|
||||
|
||||
export const workflowApi = {
|
||||
/** 触发工作流执行,返回 execution_id */
|
||||
run(name: string, dag: unknown, config?: Record<string, unknown>): Promise<string> {
|
||||
/**
|
||||
* 触发工作流执行,返回 execution_id。
|
||||
*
|
||||
* F-260616-06 阶段2(②-2): taskId/targetStatus 可选,同时传时工作流完成/失败联动推进任务。
|
||||
* B-260615-34:Tauri 2 IPC 不转 camelCase,snake_case 对齐后端 workflow.rs。
|
||||
*/
|
||||
run(
|
||||
name: string,
|
||||
dag: unknown,
|
||||
config?: Record<string, unknown>,
|
||||
taskId?: string,
|
||||
targetStatus?: string,
|
||||
): Promise<string> {
|
||||
return invoke('run_workflow', {
|
||||
name,
|
||||
dag,
|
||||
config: config ?? {},
|
||||
task_id: taskId,
|
||||
target_status: targetStatus,
|
||||
})
|
||||
},
|
||||
|
||||
|
||||
Reference in New Issue
Block a user