新增: AI Chat多项增强(审批去重/编辑重发/导出/实体引用/会话置顶搜索)+任务推进链df-nodes落地
This commit is contained in:
@@ -19,7 +19,7 @@
|
||||
//! 故 useAiStore() 之外无需手动 init;以下 import 即触发恢复逻辑
|
||||
//! - state 为模块级单例,全应用共享同一引用
|
||||
|
||||
import { reactive, watch } from 'vue'
|
||||
import { computed, reactive, watch } from 'vue'
|
||||
import type { AiChatEvent, AiConversationSummary, AiMessage, AiProviderConfig, AiToolCallInfo, SkillInfo } from '@/api/types'
|
||||
|
||||
/**
|
||||
@@ -73,6 +73,9 @@ export const state = reactive({
|
||||
agentRound: 0,
|
||||
// 归档分组折叠态(默认折叠)
|
||||
archivedCollapsed: true,
|
||||
// 对话搜索关键字(UX-06 §3.1):非空时侧栏取消时间分组,平铺展示标题匹配的会话(updated_at DESC)。
|
||||
// 清空恢复原分组。消费方:Sidebar 渲染(读 searchQuery 决定走 filteredConversations 还是 groupedActive)。
|
||||
searchQuery: '',
|
||||
// token 用量展示(受 df-show-token-usage 开关控制;lastTokenUsage=最近一条回复,convTokenTotal=当前对话累计)
|
||||
lastTokenUsage: null as { prompt: number; completion: number; total: number } | null,
|
||||
convTokenTotal: null as { prompt: number; completion: number; total: number } | null,
|
||||
@@ -101,6 +104,25 @@ watch(
|
||||
},
|
||||
)
|
||||
|
||||
/**
|
||||
* 对话搜索过滤结果(UX-06 §3.1)。
|
||||
*
|
||||
* 行为:
|
||||
* - searchQuery 为空 → 返回 null(信号:消费方走原时间分组 groupedActive / 归档分组)。
|
||||
* - 非空 → 在全部对话(活跃+归档)中按标题做 case-insensitive 子串匹配,平铺返回
|
||||
* (取消分组),按 updated_at DESC 排序,最近改过的在最前。
|
||||
*
|
||||
* 设计:过滤逻辑放 store 而非组件,供主窗口/分离窗口两处侧栏复用同一结果;
|
||||
* 消费方仅需 `store.filteredConversations` 即得数组或 null,UI 连接在侧栏视图内完成。
|
||||
*/
|
||||
const filteredConversations = computed<AiConversationSummary[] | null>(() => {
|
||||
const q = state.searchQuery.trim().toLowerCase()
|
||||
if (!q) return null
|
||||
return state.conversations
|
||||
.filter(c => (c.title ?? '').toLowerCase().includes(q))
|
||||
.sort((a, b) => (b.updated_at > a.updated_at ? 1 : b.updated_at < a.updated_at ? -1 : 0))
|
||||
})
|
||||
|
||||
/**
|
||||
* AI Store 统一入口 — 返回单例 state + 全部方法。
|
||||
*
|
||||
@@ -110,6 +132,7 @@ watch(
|
||||
export function useAiStore() {
|
||||
return {
|
||||
state,
|
||||
filteredConversations,
|
||||
...useAiEvents(),
|
||||
...useAiStream(),
|
||||
...useAiSend(),
|
||||
|
||||
@@ -55,7 +55,9 @@ export function parseTags(tags: string | null): string[] {
|
||||
}
|
||||
|
||||
export function useKnowledgeStore() {
|
||||
// ── 加载列表(默认排除 archived) ──
|
||||
// ── 加载列表(library:默认仅 published,F-260616-02 决策 a) ──
|
||||
// 后端 knowledge_list 默认收窄为 published,无需前端传 status。
|
||||
// 显式 status 仍透传(如 status='archived' 查归档)。
|
||||
async function loadList(status?: string) {
|
||||
const seq = ++_itemsReqSeq
|
||||
state.loading = true
|
||||
@@ -72,7 +74,8 @@ export function useKnowledgeStore() {
|
||||
}
|
||||
}
|
||||
|
||||
// ── 加载审核收件箱(候选列表) ──
|
||||
// ── 加载待处理收件箱(candidate + pending_review,F-260616-02 决策 a) ──
|
||||
// 后端 knowledge_list_candidates 已收两种待处理状态,前端调用不变。
|
||||
async function loadCandidates() {
|
||||
const seq = ++_itemsReqSeq
|
||||
try {
|
||||
|
||||
@@ -12,8 +12,18 @@ const t = ((i18n as any).global.t as (k: string) => string).bind((i18n as any).g
|
||||
* src/api/workflow.ts,本子 store 不再直接 invoke IPC。
|
||||
*/
|
||||
export function createWorkflowStore() {
|
||||
async function runWorkflow(name: string, dag: unknown, config?: Record<string, unknown>) {
|
||||
return await workflowApi.run(name, dag, config)
|
||||
/**
|
||||
* 触发工作流执行。
|
||||
* F-260616-06 阶段2(②-2): taskId/targetStatus 可选,同时传时工作流完成/失败联动推进任务。
|
||||
*/
|
||||
async function runWorkflow(
|
||||
name: string,
|
||||
dag: unknown,
|
||||
config?: Record<string, unknown>,
|
||||
taskId?: string,
|
||||
targetStatus?: string,
|
||||
) {
|
||||
return await workflowApi.run(name, dag, config, taskId, targetStatus)
|
||||
}
|
||||
|
||||
async function loadWorkflowExecutions() {
|
||||
|
||||
Reference in New Issue
Block a user