feat: improve agent workflow observability
This commit is contained in:
@@ -164,6 +164,12 @@ export function useEventHandler(config: EventHandlerConfig) {
|
||||
return fallbackLabel || nodeType || '';
|
||||
};
|
||||
|
||||
const getItemCount = (value: any): number => {
|
||||
if (Array.isArray(value)) return value.length;
|
||||
if (value && typeof value === 'object') return Object.keys(value).length;
|
||||
return 0;
|
||||
};
|
||||
|
||||
/** 处理流式事件 */
|
||||
const handleStreamEvent = (event: StreamEvent, msgId: string) => {
|
||||
switch (event.type) {
|
||||
@@ -272,9 +278,18 @@ export function useEventHandler(config: EventHandlerConfig) {
|
||||
}
|
||||
|
||||
case 'error': {
|
||||
currentSteps.value.push({
|
||||
type: 'error',
|
||||
content: event.message || event.content || '执行失败',
|
||||
node_id: event.node_id,
|
||||
node_type: event.node_type,
|
||||
status: 'completed',
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
updateAssistantMessage(msgId, {
|
||||
status: 'failed',
|
||||
error_message: event.message || event.content || '执行失败',
|
||||
reasoning_steps: [...currentSteps.value],
|
||||
});
|
||||
running.value = false;
|
||||
break;
|
||||
@@ -322,6 +337,19 @@ export function useEventHandler(config: EventHandlerConfig) {
|
||||
outputs[outputVar] = loopEvent.loop_results;
|
||||
}
|
||||
|
||||
currentSteps.value.push({
|
||||
type: 'loop_complete',
|
||||
content: '循环执行完成',
|
||||
node_id: loopEvent.node_id,
|
||||
node_type: 'loop',
|
||||
output: outputs,
|
||||
status: 'completed',
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
updateAssistantMessage(msgId, {
|
||||
reasoning_steps: [...currentSteps.value],
|
||||
});
|
||||
|
||||
if (props.enableNodeEvents) {
|
||||
emit('node-complete', {
|
||||
node_id: loopEvent.node_id,
|
||||
@@ -336,6 +364,19 @@ export function useEventHandler(config: EventHandlerConfig) {
|
||||
}
|
||||
|
||||
case 'loop_iteration_complete': {
|
||||
currentSteps.value.push({
|
||||
type: 'loop_iteration_complete',
|
||||
content: `循环第 ${event.iteration || '-'} 次完成`,
|
||||
node_id: event.node_id,
|
||||
node_type: 'loop',
|
||||
output: event.output,
|
||||
status: 'completed',
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
updateAssistantMessage(msgId, {
|
||||
reasoning_steps: [...currentSteps.value],
|
||||
});
|
||||
|
||||
if (props.enableNodeEvents) {
|
||||
emit('loop-iteration', {
|
||||
node_id: event.node_id,
|
||||
@@ -349,6 +390,18 @@ export function useEventHandler(config: EventHandlerConfig) {
|
||||
}
|
||||
|
||||
case 'loop_iteration_error': {
|
||||
currentSteps.value.push({
|
||||
type: 'loop_iteration_error',
|
||||
content: `循环第 ${event.iteration || '-'} 次失败:${event.error || '执行失败'}`,
|
||||
node_id: event.node_id,
|
||||
node_type: 'loop',
|
||||
status: 'completed',
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
updateAssistantMessage(msgId, {
|
||||
reasoning_steps: [...currentSteps.value],
|
||||
});
|
||||
|
||||
if (props.enableNodeEvents) {
|
||||
emit('loop-iteration', {
|
||||
node_id: event.node_id,
|
||||
@@ -362,6 +415,19 @@ export function useEventHandler(config: EventHandlerConfig) {
|
||||
}
|
||||
|
||||
case 'loop_iteration_start': {
|
||||
currentSteps.value.push({
|
||||
type: 'loop_iteration_start',
|
||||
content: `循环第 ${event.iteration || '-'} 次开始`,
|
||||
node_id: event.node_id,
|
||||
node_type: 'loop',
|
||||
params: { item: event.item, total: event.total },
|
||||
status: 'running',
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
updateAssistantMessage(msgId, {
|
||||
reasoning_steps: [...currentSteps.value],
|
||||
});
|
||||
|
||||
if (props.enableNodeEvents) {
|
||||
emit('loop-iteration', {
|
||||
node_id: event.node_id,
|
||||
@@ -423,6 +489,60 @@ export function useEventHandler(config: EventHandlerConfig) {
|
||||
break;
|
||||
}
|
||||
|
||||
case 'parallel_complete': {
|
||||
const existingIndex = currentSteps.value.findIndex(
|
||||
(s) => s.node_id === event.node_id && s.type === 'parallel_start',
|
||||
);
|
||||
const branchResults = event.branch_results || {};
|
||||
const content = `并行分支完成:${getItemCount(branchResults)} 个分支`;
|
||||
if (existingIndex === -1) {
|
||||
currentSteps.value.push({
|
||||
type: 'parallel_complete',
|
||||
content,
|
||||
node_id: event.node_id,
|
||||
node_type: 'parallel',
|
||||
output: {
|
||||
branch_results: branchResults,
|
||||
total_tokens: event.total_tokens,
|
||||
},
|
||||
status: 'completed',
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
} else {
|
||||
currentSteps.value[existingIndex] = {
|
||||
...currentSteps.value[existingIndex]!,
|
||||
type: 'parallel_complete',
|
||||
content,
|
||||
output: {
|
||||
branch_results: branchResults,
|
||||
total_tokens: event.total_tokens,
|
||||
},
|
||||
status: 'completed',
|
||||
};
|
||||
}
|
||||
updateAssistantMessage(msgId, {
|
||||
reasoning_steps: [...currentSteps.value],
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
case 'parallel_start': {
|
||||
const branches = event.branches || [];
|
||||
currentSteps.value.push({
|
||||
type: 'parallel_start',
|
||||
content: `并行分支开始:${getItemCount(branches)} 个分支`,
|
||||
node_id: event.node_id,
|
||||
node_type: 'parallel',
|
||||
params: { branches },
|
||||
status: 'running',
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
updateAssistantMessage(msgId, {
|
||||
reasoning_steps: [...currentSteps.value],
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
case 'node_event': {
|
||||
const nodeEvent = event.event;
|
||||
if (nodeEvent?.type === 'message') {
|
||||
@@ -493,12 +613,28 @@ export function useEventHandler(config: EventHandlerConfig) {
|
||||
waitingConfig.value = event.waiting_config || event.config;
|
||||
|
||||
const configData = event.waiting_config || (event as any).config;
|
||||
currentSteps.value.push({
|
||||
type: 'waiting_input',
|
||||
content:
|
||||
configData?.title ||
|
||||
configData?.question ||
|
||||
event.node_label ||
|
||||
'等待用户输入',
|
||||
node_id: event.node_id,
|
||||
node_type: event.node_type,
|
||||
params: configData,
|
||||
status: 'running',
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
|
||||
if (configData?.type === 'design_preview') {
|
||||
handleDesignPreview(event, msgId, configData);
|
||||
} else {
|
||||
handleDialogFlowInteraction(msgId, configData);
|
||||
}
|
||||
updateAssistantMessage(msgId, {
|
||||
reasoning_steps: [...currentSteps.value],
|
||||
});
|
||||
|
||||
running.value = false;
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user