feat:任务执行结果性能优化
This commit is contained in:
@@ -34,6 +34,47 @@ export type IExecuteRawResponse = {
|
||||
ActionHistory: ActionHistory[]
|
||||
}
|
||||
|
||||
/**
|
||||
* SSE 流式事件类型
|
||||
*/
|
||||
export type StreamingEvent =
|
||||
| {
|
||||
type: 'step_start'
|
||||
step_index: number
|
||||
total_steps: number
|
||||
step_name: string
|
||||
task_description?: string
|
||||
}
|
||||
| {
|
||||
type: 'action_complete'
|
||||
step_index: number
|
||||
step_name: string
|
||||
action_index: number
|
||||
total_actions: number
|
||||
completed_actions: number
|
||||
action_result: ActionHistory
|
||||
batch_info?: {
|
||||
batch_index: number
|
||||
batch_size: number
|
||||
is_parallel: boolean
|
||||
}
|
||||
}
|
||||
| {
|
||||
type: 'step_complete'
|
||||
step_index: number
|
||||
step_name: string
|
||||
step_log_node: any
|
||||
object_log_node: any
|
||||
}
|
||||
| {
|
||||
type: 'execution_complete'
|
||||
total_steps: number
|
||||
}
|
||||
| {
|
||||
type: 'error'
|
||||
message: string
|
||||
}
|
||||
|
||||
export interface IFillAgentSelectionRequest {
|
||||
goal: string
|
||||
stepTask: IApiStepTask
|
||||
@@ -99,7 +140,95 @@ class Api {
|
||||
})
|
||||
}
|
||||
|
||||
// 分支任务大纲
|
||||
/**
|
||||
* 优化版流式执行计划(阶段1+2:步骤级流式 + 动作级智能并行)
|
||||
* 无依赖关系的动作并行执行,有依赖关系的动作串行执行
|
||||
*/
|
||||
executePlanOptimized = (
|
||||
plan: IRawPlanResponse,
|
||||
onMessage: (event: StreamingEvent) => void,
|
||||
onError?: (error: Error) => void,
|
||||
onComplete?: () => void,
|
||||
) => {
|
||||
const data = {
|
||||
RehearsalLog: [],
|
||||
num_StepToRun: null,
|
||||
plan: {
|
||||
'Initial Input Object': plan['Initial Input Object'],
|
||||
'General Goal': plan['General Goal'],
|
||||
'Collaboration Process': plan['Collaboration Process']?.map((step) => ({
|
||||
StepName: step.StepName,
|
||||
TaskContent: step.TaskContent,
|
||||
InputObject_List: step.InputObject_List,
|
||||
OutputObject: step.OutputObject,
|
||||
AgentSelection: step.AgentSelection,
|
||||
Collaboration_Brief_frontEnd: step.Collaboration_Brief_frontEnd,
|
||||
TaskProcess: step.TaskProcess.map((action) => ({
|
||||
ActionType: action.ActionType,
|
||||
AgentName: action.AgentName,
|
||||
Description: action.Description,
|
||||
ID: action.ID,
|
||||
ImportantInput: action.ImportantInput,
|
||||
})),
|
||||
})),
|
||||
},
|
||||
}
|
||||
|
||||
fetch('/api/executePlanOptimized', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(data),
|
||||
})
|
||||
.then(async (response) => {
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`)
|
||||
}
|
||||
|
||||
const reader = response.body?.getReader()
|
||||
const decoder = new TextDecoder()
|
||||
|
||||
if (!reader) {
|
||||
throw new Error('Response body is null')
|
||||
}
|
||||
|
||||
let buffer = ''
|
||||
|
||||
while (true) {
|
||||
const { done, value } = await reader.read()
|
||||
|
||||
if (done) {
|
||||
onComplete?.()
|
||||
break
|
||||
}
|
||||
|
||||
buffer += decoder.decode(value, { stream: true })
|
||||
|
||||
const lines = buffer.split('\n')
|
||||
buffer = lines.pop() || ''
|
||||
|
||||
for (const line of lines) {
|
||||
if (line.startsWith('data: ')) {
|
||||
const data = line.slice(6)
|
||||
try {
|
||||
const event = JSON.parse(data)
|
||||
onMessage(event)
|
||||
} catch (e) {
|
||||
console.error('Failed to parse SSE data:', e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
onError?.(error)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 分支任务大纲
|
||||
*/
|
||||
branchPlanOutline = (data: {
|
||||
branch_Number: number
|
||||
Modification_Requirement: string
|
||||
@@ -122,7 +251,9 @@ class Api {
|
||||
})
|
||||
}
|
||||
|
||||
// 分支任务流程
|
||||
/**
|
||||
* 分支任务流程
|
||||
*/
|
||||
branchTaskProcess = (data: {
|
||||
branch_Number: number
|
||||
Modification_Requirement: string
|
||||
@@ -146,7 +277,6 @@ class Api {
|
||||
}
|
||||
|
||||
fillStepTask = async (data: { goal: string; stepTask: any }): Promise<IRawStepTask> => {
|
||||
// 后端返回格式:包含 Collaboration_Brief_FrontEnd(大写 FrontEnd)
|
||||
const response = await request<
|
||||
{
|
||||
'General Goal': string
|
||||
@@ -179,14 +309,11 @@ class Api {
|
||||
},
|
||||
})
|
||||
|
||||
// 数据转换:后端的 Collaboration_Brief_FrontEnd → 前端的 Collaboration_Brief_frontEnd
|
||||
|
||||
const vec2Hsl = (color: number[]): string => {
|
||||
const [h, s, l] = color
|
||||
return `hsl(${h}, ${s}%, ${l}%)`
|
||||
}
|
||||
|
||||
// 转换 brief.data:后端格式 { "0": { text, color: [h,s,l] } } → 前端格式 { "0": { text, style: { background } } }
|
||||
const briefData: Record<string, { text: string; style?: Record<string, string> }> = {}
|
||||
if (response.Collaboration_Brief_FrontEnd?.data) {
|
||||
for (const [key, value] of Object.entries(response.Collaboration_Brief_FrontEnd.data)) {
|
||||
@@ -199,7 +326,9 @@ class Api {
|
||||
}
|
||||
}
|
||||
|
||||
// 构建前端格式的 IRawStepTask
|
||||
/**
|
||||
* 构建前端格式的 IRawStepTask
|
||||
*/
|
||||
return {
|
||||
StepName: response.StepName || '',
|
||||
TaskContent: response.TaskContent || '',
|
||||
@@ -219,7 +348,6 @@ class Api {
|
||||
stepTask: IApiStepTask
|
||||
agents: string[]
|
||||
}): Promise<IApiStepTask> => {
|
||||
// 后端返回格式: IRawStepTask
|
||||
const response = await request<
|
||||
{
|
||||
'General Goal': string
|
||||
@@ -264,16 +392,11 @@ class Api {
|
||||
},
|
||||
})
|
||||
|
||||
// 数据转换:后端格式 (IRawStepTask) → 前端格式 (IApiStepTask)
|
||||
// 注意:此转换逻辑与Mock API完全一致
|
||||
|
||||
// 1. 转换颜色格式:[h, s, l] → "hsl(h, s%, l%)"
|
||||
const vec2Hsl = (color: number[]): string => {
|
||||
const [h, s, l] = color
|
||||
return `hsl(${h}, ${s}%, ${l}%)`
|
||||
}
|
||||
|
||||
// 2. 转换 brief.data: { "0": { text, color: [h,s,l] } } → { "0": { text, style: { background } } }
|
||||
const briefData: Record<string, { text: string; style: { background: string } }> = {}
|
||||
if (response.Collaboration_Brief_FrontEnd?.data) {
|
||||
for (const [key, value] of Object.entries(response.Collaboration_Brief_FrontEnd.data)) {
|
||||
@@ -286,7 +409,6 @@ class Api {
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 转换 process: { ID, ActionType, AgentName, Description, ImportantInput } → { id, type, agent, description, inputs }
|
||||
const process = (response.TaskProcess || []).map((action) => ({
|
||||
id: action.ID,
|
||||
type: action.ActionType,
|
||||
@@ -295,7 +417,6 @@ class Api {
|
||||
inputs: action.ImportantInput,
|
||||
}))
|
||||
|
||||
// 4. 构建前端格式的 IApiStepTask
|
||||
return {
|
||||
name: response.StepName || '',
|
||||
content: response.TaskContent || '',
|
||||
@@ -310,12 +431,13 @@ class Api {
|
||||
}
|
||||
}
|
||||
|
||||
// 为每个智能体评分
|
||||
/**
|
||||
* 为每个智能体评分
|
||||
*/
|
||||
agentSelectModifyInit = async (data: {
|
||||
goal: string
|
||||
stepTask: any
|
||||
}): Promise<Record<string, Record<string, { reason: string; score: number }>>> => {
|
||||
// 后端返回:维度 -> agent -> { Reason, Score }
|
||||
const response = await request<
|
||||
{
|
||||
'General Goal': string
|
||||
@@ -336,11 +458,9 @@ class Api {
|
||||
},
|
||||
})
|
||||
|
||||
// 数据转换:后端格式 (维度->agent) → 前端格式 (agent->维度)
|
||||
const transformedData: Record<string, Record<string, { reason: string; score: number }>> = {}
|
||||
|
||||
for (const [aspect, agents] of Object.entries(response)) {
|
||||
// aspect: 维度名称, agents: { agentName: { Reason, Score } }
|
||||
for (const [agentName, scoreInfo] of Object.entries(agents)) {
|
||||
if (!transformedData[agentName]) {
|
||||
transformedData[agentName] = {}
|
||||
@@ -355,15 +475,15 @@ class Api {
|
||||
return transformedData
|
||||
}
|
||||
|
||||
// 添加新的评估维度
|
||||
// 定义返回类型(与 Mock 数据格式一致)
|
||||
/**
|
||||
* 添加新的评估维度
|
||||
*/
|
||||
agentSelectModifyAddAspect = async (data: {
|
||||
aspectList: string[]
|
||||
}): Promise<{
|
||||
aspectName: string
|
||||
agentScores: Record<string, { score: number; reason: string }>
|
||||
}> => {
|
||||
// 后端返回:维度 -> agent -> { Reason, Score }
|
||||
const response = await request<
|
||||
{
|
||||
aspectList: string[]
|
||||
@@ -377,13 +497,14 @@ class Api {
|
||||
},
|
||||
})
|
||||
|
||||
// 获取新添加的维度(最后一个)
|
||||
/**
|
||||
* 获取新添加的维度
|
||||
*/
|
||||
const newAspect = data.aspectList[data.aspectList.length - 1]
|
||||
if (!newAspect) {
|
||||
throw new Error('aspectList is empty')
|
||||
}
|
||||
|
||||
// 提取该维度的数据:维度 -> agent -> { Reason, Score } → agent -> { score, reason }
|
||||
const newAspectAgents = response[newAspect]
|
||||
const agentScores: Record<string, { score: number; reason: string }> = {}
|
||||
|
||||
@@ -401,23 +522,18 @@ class Api {
|
||||
agentScores,
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== Mock API(开发阶段使用)====================
|
||||
// Mock API 使用与真实 API 相同的数据转换逻辑,确保将来切换无缝
|
||||
|
||||
// Mock: 为每个智能体评分
|
||||
/**
|
||||
* ==================== Mock API(开发阶段使用)====================
|
||||
*为每个智能体评分
|
||||
*/
|
||||
mockAgentSelectModifyInit = async (): Promise<
|
||||
Record<string, Record<string, { reason: string; score: number }>>
|
||||
> => {
|
||||
// 调用Mock后端数据(维度 -> agent -> { Reason, Score })
|
||||
const response: BackendAgentScoreResponse = await mockBackendAgentSelectModifyInit()
|
||||
|
||||
// 数据转换:后端格式 (维度->agent) → 前端格式 (agent->维度)
|
||||
// 注意:此转换逻辑与真实API完全一致
|
||||
const transformedData: Record<string, Record<string, { reason: string; score: number }>> = {}
|
||||
|
||||
for (const [aspect, agents] of Object.entries(response)) {
|
||||
// aspect: 维度名称, agents: { agentName: { Reason, Score } }
|
||||
for (const [agentName, scoreInfo] of Object.entries(agents)) {
|
||||
if (!transformedData[agentName]) {
|
||||
transformedData[agentName] = {}
|
||||
@@ -432,26 +548,21 @@ class Api {
|
||||
return transformedData
|
||||
}
|
||||
|
||||
// Mock: 添加新的评估维度
|
||||
mockAgentSelectModifyAddAspect = async (data: {
|
||||
aspectList: string[]
|
||||
}): Promise<{
|
||||
aspectName: string
|
||||
agentScores: Record<string, { score: number; reason: string }>
|
||||
}> => {
|
||||
// 调用Mock后端数据(维度 -> agent -> { Reason, Score })
|
||||
const response: BackendAgentScoreResponse = await mockBackendAgentSelectModifyAddAspect(
|
||||
data.aspectList,
|
||||
)
|
||||
|
||||
// 获取新添加的维度(最后一个)
|
||||
const newAspect = data.aspectList[data.aspectList.length - 1]
|
||||
if (!newAspect) {
|
||||
throw new Error('aspectList is empty')
|
||||
}
|
||||
|
||||
// 提取该维度的数据:维度 -> agent -> { Reason, Score } → agent -> { score, reason }
|
||||
// 注意:此转换逻辑与真实API完全一致
|
||||
const newAspectAgents = response[newAspect]
|
||||
const agentScores: Record<string, { score: number; reason: string }> = {}
|
||||
|
||||
@@ -470,29 +581,22 @@ class Api {
|
||||
}
|
||||
}
|
||||
|
||||
// Mock: 填充智能体任务流程
|
||||
mockFillStepTaskTaskProcess = async (data: {
|
||||
goal: string
|
||||
stepTask: IApiStepTask
|
||||
agents: string[]
|
||||
}): Promise<IApiStepTask> => {
|
||||
// 调用Mock后端数据(后端原始格式)
|
||||
const response: RawAgentTaskProcessResponse = await mockBackendFillAgentTaskProcess(
|
||||
data.goal,
|
||||
data.stepTask,
|
||||
data.agents,
|
||||
)
|
||||
|
||||
// 数据转换:后端格式 → 前端格式
|
||||
// 注意:此转换逻辑与真实API完全一致
|
||||
|
||||
// 1. 转换颜色格式:[h, s, l] → "hsl(h, s%, l%)"
|
||||
const vec2Hsl = (color: number[]): string => {
|
||||
const [h, s, l] = color
|
||||
return `hsl(${h}, ${s}%, ${l}%)`
|
||||
}
|
||||
|
||||
// 2. 转换 brief.data: { "0": { text, color: [h,s,l] } } → { "0": { text, style: { background } } }
|
||||
const briefData: Record<string, { text: string; style: { background: string } }> = {}
|
||||
if (response.Collaboration_Brief_frontEnd?.data) {
|
||||
for (const [key, value] of Object.entries(response.Collaboration_Brief_frontEnd.data)) {
|
||||
@@ -505,7 +609,6 @@ class Api {
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 转换 process: { ID, ActionType, AgentName, Description, ImportantInput } → { id, type, agent, description, inputs }
|
||||
const process = (response.TaskProcess || []).map((action) => ({
|
||||
id: action.ID,
|
||||
type: action.ActionType,
|
||||
@@ -514,7 +617,6 @@ class Api {
|
||||
inputs: action.ImportantInput,
|
||||
}))
|
||||
|
||||
// 4. 构建前端格式的 IApiStepTask
|
||||
return {
|
||||
name: response.StepName || '',
|
||||
content: response.TaskContent || '',
|
||||
@@ -529,7 +631,6 @@ class Api {
|
||||
}
|
||||
}
|
||||
|
||||
// Mock: 分支任务大纲
|
||||
mockBranchPlanOutline = async (data: {
|
||||
branch_Number: number
|
||||
Modification_Requirement: string
|
||||
@@ -538,7 +639,6 @@ class Api {
|
||||
initialInputs: string[]
|
||||
goal: string
|
||||
}): Promise<IRawPlanResponse> => {
|
||||
// 直接调用 Mock API(已经返回 IRawPlanResponse 格式)
|
||||
const response = await mockBranchPlanOutlineAPI({
|
||||
branch_Number: data.branch_Number,
|
||||
Modification_Requirement: data.Modification_Requirement,
|
||||
@@ -551,9 +651,7 @@ class Api {
|
||||
return response
|
||||
}
|
||||
|
||||
// Mock: 填充任务流程
|
||||
mockFillStepTask = async (data: { goal: string; stepTask: any }): Promise<any> => {
|
||||
// 直接调用 Mock API(已经返回 IRawStepTask 格式)
|
||||
const response = await mockFillStepTaskAPI({
|
||||
General_Goal: data.goal,
|
||||
stepTask: data.stepTask,
|
||||
@@ -562,7 +660,6 @@ class Api {
|
||||
return response
|
||||
}
|
||||
|
||||
// Mock: 分支任务流程
|
||||
mockBranchTaskProcess = async (data: {
|
||||
branch_Number: number
|
||||
Modification_Requirement: string
|
||||
@@ -571,7 +668,6 @@ class Api {
|
||||
stepTaskExisting: any
|
||||
goal: string
|
||||
}): Promise<BranchAction[][]> => {
|
||||
// 直接调用 Mock API(已经返回 BranchAction[][] 格式,与后端完全一致)
|
||||
const response = await mockBranchTaskProcessAPI({
|
||||
branch_Number: data.branch_Number,
|
||||
Modification_Requirement: data.Modification_Requirement,
|
||||
|
||||
Reference in New Issue
Block a user