feat: 先进智能体功能上线
- 基于 agent-runtime 打造,默认 ReAct agent - 支持 agent 能力对接,已对接工作流、插件、知识库等 tool 能力 - 全新 agent 编排界面,支持可视化便捷配置 agent - 全新 agent 聊天界面,支持快捷操作、额外知识库选择等
This commit is contained in:
@@ -54,6 +54,38 @@ function normalizeToolCallId(payload: Record<string, any>) {
|
||||
return asText(payload.toolCallId ?? payload.tool_call_id ?? payload.id);
|
||||
}
|
||||
|
||||
function isBlankToolName(value: unknown) {
|
||||
return !normalizeToolName(value);
|
||||
}
|
||||
|
||||
function shouldSkipToolProjection(value: unknown) {
|
||||
const normalizedName = normalizeToolName(value).toLowerCase();
|
||||
return (
|
||||
normalizedName === 'context_reload' ||
|
||||
normalizedName === '__fragment__'
|
||||
);
|
||||
}
|
||||
|
||||
function normalizeToolCallName(payload: Record<string, any>) {
|
||||
const fn = asRecord(payload.function);
|
||||
return normalizeToolName(payload.name ?? payload.toolName ?? fn.name);
|
||||
}
|
||||
|
||||
function normalizeToolCallInput(payload: Record<string, any>) {
|
||||
const fn = asRecord(payload.function);
|
||||
return payload.arguments ?? payload.input ?? fn.arguments;
|
||||
}
|
||||
|
||||
function statusKeyForProjection(
|
||||
payload: Record<string, any>,
|
||||
metadata?: Partial<ChatTimelineMessageItem>,
|
||||
fallback = 'status',
|
||||
) {
|
||||
const statusKey = asText(payload.statusKey) || fallback;
|
||||
const roundId = asText(metadata?.roundId);
|
||||
return roundId ? `${statusKey}:${roundId}` : statusKey;
|
||||
}
|
||||
|
||||
function normalizeMetadata(record: AgentChatMessageRecord) {
|
||||
return {
|
||||
createdAt: asTimestamp(record.created),
|
||||
@@ -139,14 +171,10 @@ function appendAssistantText(
|
||||
if (!text) {
|
||||
return;
|
||||
}
|
||||
ChatTimelineBuilder.appendMessageDelta(
|
||||
items,
|
||||
text,
|
||||
{
|
||||
...assistantMetadata(record, suffix),
|
||||
...metadata,
|
||||
},
|
||||
);
|
||||
ChatTimelineBuilder.appendMessageDelta(items, text, {
|
||||
...assistantMetadata(record, suffix),
|
||||
...metadata,
|
||||
});
|
||||
}
|
||||
|
||||
function appendAssistantThinking(
|
||||
@@ -160,14 +188,10 @@ function appendAssistantThinking(
|
||||
if (!text) {
|
||||
return;
|
||||
}
|
||||
ChatTimelineBuilder.appendThinkingDelta(
|
||||
items,
|
||||
text,
|
||||
{
|
||||
...assistantMetadata(record, suffix),
|
||||
...metadata,
|
||||
},
|
||||
);
|
||||
ChatTimelineBuilder.appendThinkingDelta(items, text, {
|
||||
...assistantMetadata(record, suffix),
|
||||
...metadata,
|
||||
});
|
||||
}
|
||||
|
||||
function projectHistoryChain(
|
||||
@@ -177,6 +201,7 @@ function projectHistoryChain(
|
||||
const payload = asRecord(record.contentPayload);
|
||||
let hasAssistantText = false;
|
||||
let hasAssistantThinking = false;
|
||||
const toolNameByCallId = new Map<string, string>();
|
||||
const displayChains = asArray(payload.displayChains ?? payload.chains);
|
||||
for (const chain of displayChains) {
|
||||
const item = asRecord(chain);
|
||||
@@ -187,12 +212,21 @@ function projectHistoryChain(
|
||||
continue;
|
||||
}
|
||||
const toolName = normalizeToolName(item.name ?? item.toolName);
|
||||
if (toolName) {
|
||||
const toolCallId = normalizeToolCallId(item);
|
||||
if (toolCallId && toolName) {
|
||||
toolNameByCallId.set(toolCallId, toolName);
|
||||
}
|
||||
if (toolName && !shouldSkipToolProjection(toolName)) {
|
||||
ChatTimelineBuilder.upsertToolCall(items, {
|
||||
input: item.arguments ?? item.input,
|
||||
output: item.result ?? item.output,
|
||||
status: asText(item.status) === 'TOOL_RESULT' ? 'success' : 'running',
|
||||
toolCallId: asText(item.id ?? item.toolCallId),
|
||||
statusKey: statusKeyForProjection(
|
||||
item,
|
||||
normalizeMetadata(record),
|
||||
'knowledge-retrieval',
|
||||
),
|
||||
toolCallId,
|
||||
toolName,
|
||||
});
|
||||
}
|
||||
@@ -213,21 +247,45 @@ function projectHistoryChain(
|
||||
}
|
||||
for (const toolCall of asArray(item.toolCalls)) {
|
||||
const tool = asRecord(toolCall);
|
||||
const toolCallId = normalizeToolCallId(tool);
|
||||
const toolName = normalizeToolCallName(tool);
|
||||
if (toolCallId && toolName) {
|
||||
toolNameByCallId.set(toolCallId, toolName);
|
||||
}
|
||||
if (isBlankToolName(toolName) || shouldSkipToolProjection(toolName)) {
|
||||
continue;
|
||||
}
|
||||
ChatTimelineBuilder.upsertToolCall(items, {
|
||||
input: tool.arguments ?? tool.input,
|
||||
input: normalizeToolCallInput(tool),
|
||||
status: 'running',
|
||||
toolCallId: asText(tool.id ?? tool.toolCallId),
|
||||
toolName: normalizeToolName(tool.name ?? tool.toolName),
|
||||
statusKey: statusKeyForProjection(
|
||||
tool,
|
||||
normalizeMetadata(record),
|
||||
'knowledge-retrieval',
|
||||
),
|
||||
toolCallId,
|
||||
toolName,
|
||||
});
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (role === 'tool') {
|
||||
const toolCallId = normalizeToolCallId(item);
|
||||
const toolName =
|
||||
normalizeToolCallName(item) || toolNameByCallId.get(toolCallId) || '';
|
||||
if (isBlankToolName(toolName) || shouldSkipToolProjection(toolName)) {
|
||||
continue;
|
||||
}
|
||||
ChatTimelineBuilder.upsertToolCall(items, {
|
||||
output: item.content ?? item.result,
|
||||
status: 'success',
|
||||
toolCallId: asText(item.toolCallId ?? item.id),
|
||||
toolName: normalizeToolName(item.name ?? item.toolName) || '工具调用',
|
||||
statusKey: statusKeyForProjection(
|
||||
item,
|
||||
normalizeMetadata(record),
|
||||
'knowledge-retrieval',
|
||||
),
|
||||
toolCallId,
|
||||
toolName,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -369,7 +427,11 @@ export function applyAgentSseEnvelope(
|
||||
input: payload.input ?? payload.toolInput,
|
||||
output: payload.output ?? payload.result ?? payload.text,
|
||||
status: type === 'TOOL_RESULT' ? 'success' : 'running',
|
||||
statusKey: asText(payload.statusKey) || undefined,
|
||||
statusKey: statusKeyForProjection(
|
||||
payload,
|
||||
metadata,
|
||||
'knowledge-retrieval',
|
||||
),
|
||||
toolCallId: normalizeToolCallId(payload),
|
||||
toolName: normalizeToolName(
|
||||
payload.toolDisplayName ?? payload.toolName ?? payload.name,
|
||||
@@ -394,7 +456,11 @@ export function applyAgentSseEnvelope(
|
||||
label: asText(payload.label),
|
||||
phase: asText(payload.phase),
|
||||
status: asText(payload.status),
|
||||
statusKey: asText(payload.statusKey),
|
||||
statusKey: statusKeyForProjection(
|
||||
payload,
|
||||
metadata,
|
||||
'memory-compression',
|
||||
),
|
||||
});
|
||||
return;
|
||||
}
|
||||
@@ -402,7 +468,7 @@ export function applyAgentSseEnvelope(
|
||||
ChatTimelineBuilder.upsertKnowledgeRetrievalStatus(
|
||||
items,
|
||||
asText(payload.status) === 'running' ? 'running' : 'done',
|
||||
asText(payload.statusKey),
|
||||
statusKeyForProjection(payload, metadata, 'knowledge-retrieval'),
|
||||
);
|
||||
}
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user