refactor: 移除多余依赖,统一 MUI 为唯一 UI 库
- 移除 radix-ui、clsx、tailwind-merge、class-variance-authority、react-router-dom - 前后端全面适配 MUI 组件,清理残留 Tailwind 工具类引用 - 优化 Agent Loop 引擎、IPC 处理器、Provider Adapter 等后端模块 - 新增 Agent 网络工具通用设计文档 v2
This commit is contained in:
@@ -44,6 +44,9 @@ const DEFAULT_CONFIG: AgentLoopConfig = {
|
||||
contextWindow: 128_000,
|
||||
retryCount: 3,
|
||||
temperature: 0.0,
|
||||
maxTokens: 63488,
|
||||
thinkingEnabled: true,
|
||||
thinkingEffort: 'high',
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -157,11 +160,11 @@ export class AgentLoopEngine extends EventEmitter {
|
||||
messages,
|
||||
tools: this.tools.length > 0 ? this.tools : undefined,
|
||||
params: {
|
||||
maxTokens: 63488,
|
||||
maxTokens: this.config.maxTokens,
|
||||
temperature: this.config.temperature,
|
||||
stream: true,
|
||||
thinkingEnabled: true,
|
||||
thinkingEffort: 'high',
|
||||
thinkingEnabled: this.config.thinkingEnabled,
|
||||
thinkingEffort: this.config.thinkingEffort,
|
||||
contextLength: this.config.contextLength,
|
||||
},
|
||||
};
|
||||
@@ -254,9 +257,12 @@ export class AgentLoopEngine extends EventEmitter {
|
||||
let tokenUsage: TokenUsage | undefined;
|
||||
|
||||
// 流式接收响应
|
||||
for await (const event of this.adapter.chatStream(request)) {
|
||||
for await (const event of this.chatStreamWithRetry(request)) {
|
||||
if (this.aborted) break;
|
||||
|
||||
// 过滤掉每轮的 DONE 事件 — 只在全部迭代完成后发送一个最终 DONE
|
||||
if (event.type === MetonaStreamEventType.DONE) continue;
|
||||
|
||||
// 转发流式事件到渲染进程
|
||||
this.emit('streamEvent', event);
|
||||
|
||||
@@ -299,9 +305,6 @@ export class AgentLoopEngine extends EventEmitter {
|
||||
}
|
||||
break;
|
||||
|
||||
case MetonaStreamEventType.DONE:
|
||||
break;
|
||||
|
||||
case MetonaStreamEventType.ERROR:
|
||||
if (event.error) {
|
||||
throw new Error(event.error.message);
|
||||
@@ -313,18 +316,21 @@ export class AgentLoopEngine extends EventEmitter {
|
||||
// 处理缓冲区中的工具调用(TOOL_CALL_DELTA 拼接)
|
||||
if (toolCallsBuffer.size > 0 && (!step.toolCalls || step.toolCalls.length === 0)) {
|
||||
step.toolCalls = [];
|
||||
for (const [index, buf] of toolCallsBuffer) {
|
||||
for (const [, buf] of toolCallsBuffer) {
|
||||
let args: Record<string, unknown>;
|
||||
try {
|
||||
step.toolCalls.push({
|
||||
id: `tc_${nanoid(8)}`,
|
||||
name: buf.name,
|
||||
args: buf.argsBuffer ? JSON.parse(buf.argsBuffer) : {},
|
||||
iteration: this.currentIteration,
|
||||
timestamp: Date.now(),
|
||||
});
|
||||
args = buf.argsBuffer ? JSON.parse(buf.argsBuffer) : {};
|
||||
} catch {
|
||||
// JSON 解析失败,跳过
|
||||
// JSON 解析失败,使用空参数(LLM 仍请求了该工具调用)
|
||||
args = {};
|
||||
}
|
||||
step.toolCalls.push({
|
||||
id: `tc_${nanoid(8)}`,
|
||||
name: buf.name,
|
||||
args,
|
||||
iteration: this.currentIteration,
|
||||
timestamp: Date.now(),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -361,7 +367,7 @@ export class AgentLoopEngine extends EventEmitter {
|
||||
|
||||
// 转发工具结果到渲染进程
|
||||
this.emit('streamEvent', {
|
||||
type: 'tool_result',
|
||||
type: MetonaStreamEventType.TOOL_RESULT,
|
||||
requestId: request.meta.requestId,
|
||||
sessionId,
|
||||
iteration: this.currentIteration,
|
||||
@@ -444,10 +450,37 @@ export class AgentLoopEngine extends EventEmitter {
|
||||
return toolResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* 带重试的流式调用
|
||||
*
|
||||
* 如果 adapter 抛出错误,在 retryCount 次数内重试,每次等待 1 秒。
|
||||
*/
|
||||
private async *chatStreamWithRetry(request: MetonaRequest): AsyncIterable<MetonaStreamEvent> {
|
||||
let lastError: unknown;
|
||||
for (let attempt = 0; attempt <= this.config.retryCount; attempt++) {
|
||||
try {
|
||||
yield* this.adapter.chatStream(request);
|
||||
return;
|
||||
} catch (error) {
|
||||
lastError = error;
|
||||
if (attempt < this.config.retryCount) {
|
||||
await new Promise((resolve) => setTimeout(resolve, 1000));
|
||||
}
|
||||
}
|
||||
}
|
||||
throw lastError;
|
||||
}
|
||||
|
||||
private async transitionTo(state: AgentLoopState): Promise<void> {
|
||||
const previous = this.currentState;
|
||||
this.currentState = state;
|
||||
this.emit('stateChange', { previous, current: state });
|
||||
this.emit('stateChange', {
|
||||
previous,
|
||||
current: state,
|
||||
state,
|
||||
sessionId: this.currentSessionId,
|
||||
iteration: this.currentIteration,
|
||||
});
|
||||
}
|
||||
|
||||
private accumulateTokens(usage: TokenUsage): void {
|
||||
@@ -461,6 +494,16 @@ export class AgentLoopEngine extends EventEmitter {
|
||||
answer?: string,
|
||||
error?: Error,
|
||||
): AgentLoopOutput {
|
||||
// 发送唯一的最终 DONE 事件 — UI 只在此处结束流式状态
|
||||
this.emit('streamEvent', {
|
||||
type: MetonaStreamEventType.DONE,
|
||||
requestId: this.currentRequestId,
|
||||
sessionId: this.currentSessionId,
|
||||
iteration: this.currentIteration,
|
||||
seq: 0,
|
||||
timestamp: Date.now(),
|
||||
});
|
||||
|
||||
this.currentState = AgentLoopState.TERMINATED;
|
||||
return {
|
||||
finalAnswer: answer ?? (error ? error.message : 'No answer produced'),
|
||||
|
||||
Reference in New Issue
Block a user