feat(coordinator): 添加团队节点默认最大工具迭代次数配置
添加 DEFAULT_TEAM_NODE_MAX_TOOL_ITERATIONS 配置项以控制团队节点的最大工具迭代次数, 并修改 LocalAgentRunner 中的逻辑来使用此默认值当 envelope 中未指定时。 fix(runtime): 修复团队节点运行成功判断逻辑 更新运行成功判断条件,将 finish_reason 为 "max_tool_iterations_finalized" 的情况 视为运行失败,并添加对原始工具调用输出的检测,避免将其误判为成功完成。 feat(mcp): 添加团队工作流MCP工具类别支持 增加新的本地MCP工具类别 "team_workflow" 及其对应的工具创建功能, 为团队工作流提供本地工具支持。 refactor(engine): 调整AgentLoop最大工具迭代次数设置 将 AgentProfile 中的默认 max_tool_iterations 从 30 增加到 100, 同时移除 TaskExecutionPlanner 构造函数中的重复参数传递。 perf(mcp): 优化MCP连接管理避免重复连接 添加 mcp_connected 标志来跟踪MCP连接状态,确保 connect_all 只执行一次, 提高性能并避免不必要的重复连接。 refactor(skills): 移除技能团队模板相关功能 移除与技能团队模板相关的代码,包括解析、存储和处理逻辑, 简化技能记录结构和加载流程。 feat(process): 增强会话过程投影器功能 添加技能激活快照事件处理,改进团队运行完成消息显示, 并增强技能激活事件的时间戳记录功能。 refactor(tasks): 简化任务尝试编排器团队执行逻辑 移除团队执行相关代码,将所有任务统一按单步执行处理, 简化任务编排器的复杂度并提升执行效率。 fix(evidence): 修复节点证据评估中需求验证逻辑 更新节点证据评估逻辑,跳过自然语言证据需求的确定性验证, 只执行机器可读的需求验证,避免因自然语言需求导致的节点失败。
This commit is contained in:
@ -146,11 +146,6 @@ export default function NotificationDetailPage() {
|
||||
isThinking={submitting}
|
||||
messagesEndRef={messagesEndRef}
|
||||
messageViewportRef={viewportRef}
|
||||
processRuns={[]}
|
||||
processEvents={[]}
|
||||
processArtifacts={[]}
|
||||
selectedRunId={null}
|
||||
onSelectRun={() => {}}
|
||||
onFeedback={() => {}}
|
||||
onRequestRevision={() => {}}
|
||||
/>
|
||||
|
||||
@ -77,7 +77,6 @@ export default function ChatPage() {
|
||||
processRuns,
|
||||
processEvents,
|
||||
processArtifacts,
|
||||
selectedRunId,
|
||||
setSessionId,
|
||||
setMessages,
|
||||
addMessage,
|
||||
@ -128,12 +127,6 @@ export default function ChatPage() {
|
||||
[processEvents, sessionRunIds]
|
||||
);
|
||||
|
||||
const sessionProcessArtifacts = useMemo(
|
||||
() => processArtifacts.filter((artifact) => sessionRunIds.has(artifact.run_id)),
|
||||
[processArtifacts, sessionRunIds]
|
||||
);
|
||||
|
||||
const selectedSessionRunId = selectedRunId && sessionRunIds.has(selectedRunId) ? selectedRunId : null;
|
||||
const activeTaskTimelineView = useMemo(
|
||||
() =>
|
||||
buildTaskTimelineView({
|
||||
@ -710,11 +703,6 @@ export default function ChatPage() {
|
||||
isThinking={isThinking || (isLoading && messages[messages.length - 1]?.role === 'user')}
|
||||
messagesEndRef={messagesEndRef}
|
||||
messageViewportRef={messageViewportRef}
|
||||
processRuns={sessionProcessRuns}
|
||||
processEvents={sessionProcessEvents}
|
||||
processArtifacts={sessionProcessArtifacts}
|
||||
selectedRunId={selectedSessionRunId}
|
||||
onSelectRun={(runId) => setSelectedRunId(selectedSessionRunId === runId ? null : runId)}
|
||||
onFeedback={handleFeedback}
|
||||
onRequestRevision={handleRequestRevision}
|
||||
/>
|
||||
@ -881,6 +869,8 @@ export default function ChatPage() {
|
||||
|
||||
{activeTaskDetail ? (
|
||||
<CurrentSessionProgressSidebar
|
||||
task={activeTaskDetail}
|
||||
process={activeTaskTimelineView?.process ?? null}
|
||||
cards={activeTaskTimelineView?.cards ?? []}
|
||||
isLive={Boolean(activeTaskDetail.is_open && wsStatus === 'connected')}
|
||||
/>
|
||||
|
||||
@ -1,20 +1,19 @@
|
||||
'use client';
|
||||
|
||||
import Link from 'next/link';
|
||||
import { useParams, useRouter } from 'next/navigation';
|
||||
import { useParams } from 'next/navigation';
|
||||
import React, { useMemo, useState } from 'react';
|
||||
import { AlertCircle, ArrowLeft, Loader2, Trash2 } from 'lucide-react';
|
||||
import { AlertCircle, ArrowLeft, Loader2 } from 'lucide-react';
|
||||
|
||||
import {
|
||||
TaskExecutionWorkspace,
|
||||
TaskLiveHeader,
|
||||
TaskSideRail,
|
||||
TaskTimeline,
|
||||
type TaskFeedbackItem,
|
||||
type TaskFeedbackType,
|
||||
} from '@/components/task-detail';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Card, CardContent } from '@/components/ui/card';
|
||||
import { deleteBackendTask, getBackendTask, submitChatFeedback } from '@/lib/api';
|
||||
import { getBackendTask, submitChatFeedback } from '@/lib/api';
|
||||
import { pickAppText } from '@/lib/i18n/core';
|
||||
import { useAppI18n } from '@/lib/i18n/provider';
|
||||
import { useChatStore } from '@/lib/store';
|
||||
@ -27,7 +26,6 @@ const TASK_RESULT_REVIEW_ID = 'task-result-review';
|
||||
|
||||
export default function TaskDetailPage() {
|
||||
const { locale } = useAppI18n();
|
||||
const router = useRouter();
|
||||
const params = useParams<{ taskId: string }>();
|
||||
const taskId = decodeURIComponent(Array.isArray(params?.taskId) ? params.taskId[0] : params?.taskId ?? '');
|
||||
const processRuns = useChatStore((state) => state.processRuns);
|
||||
@ -120,18 +118,6 @@ export default function TaskDetailPage() {
|
||||
}
|
||||
};
|
||||
|
||||
const deleteCurrentBackendTask = async () => {
|
||||
if (!backendTask) return;
|
||||
const title = backendTask.short_title || backendTask.description || backendTask.goal || backendTask.task_id;
|
||||
if (!window.confirm(pickAppText(locale, `删除任务“${title}”?`, `Delete task "${title}"?`))) {
|
||||
return;
|
||||
}
|
||||
await runAction('delete-backend-task', async () => {
|
||||
await deleteBackendTask(backendTask.task_id);
|
||||
router.push('/tasks');
|
||||
});
|
||||
};
|
||||
|
||||
if (backendTask) {
|
||||
const feedbackItems = backendTask.feedback || [];
|
||||
|
||||
@ -139,64 +125,44 @@ export default function TaskDetailPage() {
|
||||
<div className="min-h-screen bg-background">
|
||||
<TaskLiveHeader task={backendTask} activeLabel={activeLabel} durationMs={durationMs} reviewTargetId={TASK_RESULT_REVIEW_ID} />
|
||||
|
||||
<main className="mx-auto grid min-w-0 max-w-7xl gap-6 p-4 sm:p-6 xl:grid-cols-[minmax(0,1fr)_360px]">
|
||||
<div className="min-w-0 space-y-4">
|
||||
<div className="flex justify-end">
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
className="h-11 text-destructive hover:text-destructive"
|
||||
disabled={Boolean(actionBusy)}
|
||||
onClick={() => void deleteCurrentBackendTask()}
|
||||
>
|
||||
<Trash2 className="mr-2 h-4 w-4" />
|
||||
{pickAppText(locale, '删除任务', 'Delete task')}
|
||||
</Button>
|
||||
</div>
|
||||
<main className="mx-auto min-w-0 max-w-[1720px] space-y-5 px-4 py-1 sm:px-6 lg:px-8">
|
||||
{actionError ? (
|
||||
<Card className="border-destructive">
|
||||
<CardContent className="flex items-center gap-2 p-4 text-sm text-destructive">
|
||||
<AlertCircle className="h-4 w-4" />
|
||||
{actionError}
|
||||
</CardContent>
|
||||
</Card>
|
||||
) : null}
|
||||
|
||||
{actionError ? (
|
||||
<Card className="border-destructive">
|
||||
<CardContent className="flex items-center gap-2 p-4 text-sm text-destructive">
|
||||
<AlertCircle className="h-4 w-4" />
|
||||
{actionError}
|
||||
</CardContent>
|
||||
</Card>
|
||||
) : null}
|
||||
|
||||
<TaskTimeline
|
||||
cards={timelineCards}
|
||||
isLive={isTaskLive && wsStatus === 'connected'}
|
||||
reviewTargetId={TASK_RESULT_REVIEW_ID}
|
||||
resultAcceptance={{
|
||||
sessionId: backendTask.session_id,
|
||||
runId: feedbackRunId,
|
||||
taskStatus: backendTask.status,
|
||||
feedbackItems: feedbackItems as TaskFeedbackItem[],
|
||||
actionBusy,
|
||||
revision,
|
||||
onRevisionChange: setRevision,
|
||||
onSubmit: (feedbackType: TaskFeedbackType, comment?: string) =>
|
||||
runAction(`backend-feedback-${feedbackType}`, async () => {
|
||||
if (!feedbackRunId) throw new Error(pickAppText(locale, '暂无可验收的运行记录。', 'No run is available for acceptance yet.'));
|
||||
await submitChatFeedback({
|
||||
sessionId: backendTask.session_id,
|
||||
runId: feedbackRunId,
|
||||
feedbackType,
|
||||
comment,
|
||||
});
|
||||
updateMessageFeedback(feedbackRunId, feedbackType);
|
||||
setRevision('');
|
||||
await loadBackendTask();
|
||||
}),
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<TaskSideRail
|
||||
<TaskExecutionWorkspace
|
||||
task={backendTask}
|
||||
runs={timelineView?.process.runs ?? []}
|
||||
artifacts={timelineView?.process.artifacts ?? []}
|
||||
process={timelineView?.process ?? { runs: [], events: [], artifacts: [] }}
|
||||
cards={timelineCards}
|
||||
isLive={isTaskLive && wsStatus === 'connected'}
|
||||
reviewTargetId={TASK_RESULT_REVIEW_ID}
|
||||
resultAcceptance={{
|
||||
sessionId: backendTask.session_id,
|
||||
runId: feedbackRunId,
|
||||
taskStatus: backendTask.status,
|
||||
feedbackItems: feedbackItems as TaskFeedbackItem[],
|
||||
actionBusy,
|
||||
revision,
|
||||
onRevisionChange: setRevision,
|
||||
onSubmit: (feedbackType: TaskFeedbackType, comment?: string) =>
|
||||
runAction(`backend-feedback-${feedbackType}`, async () => {
|
||||
if (!feedbackRunId) throw new Error(pickAppText(locale, '暂无可验收的运行记录。', 'No run is available for acceptance yet.'));
|
||||
await submitChatFeedback({
|
||||
sessionId: backendTask.session_id,
|
||||
runId: feedbackRunId,
|
||||
feedbackType,
|
||||
comment,
|
||||
});
|
||||
updateMessageFeedback(feedbackRunId, feedbackType);
|
||||
setRevision('');
|
||||
await loadBackendTask();
|
||||
}),
|
||||
}}
|
||||
/>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user