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:
thzxx
2026-07-05 19:15:48 +08:00
parent ba85328c4f
commit f4532a2bb2
50 changed files with 1474 additions and 2042 deletions
@@ -125,7 +125,6 @@ export class AgnesAdapter extends BaseAdapter {
contentParts.push({ type: 'text', text: origMsg.content });
}
for (const img of origMsg.images) {
const isDataUrl = img.url.startsWith('data:');
contentParts.push({
type: 'image_url',
image_url: { url: img.url },
+11 -1
View File
@@ -30,7 +30,7 @@ export abstract class BaseAdapter implements IMetonaProviderAdapter {
async healthCheck(): Promise<boolean> {
try {
await this.listModels?.();
await this.listModels();
return true;
} catch {
return false;
@@ -58,6 +58,16 @@ export abstract class BaseAdapter implements IMetonaProviderAdapter {
};
}
if (msg.includes('ECONNREFUSED') || msg.includes('ENOTFOUND') || msg.includes('ECONNRESET')) {
return {
code: MetonaErrorCode.NETWORK_ERROR,
message: error.message,
provider: this.provider,
retryable: true,
retryAfterMs: 3000,
};
}
if (msg.includes('401') || msg.includes('unauthorized')) {
return {
code: MetonaErrorCode.AUTH_INVALID,
+12 -2
View File
@@ -66,6 +66,7 @@ export class OllamaAdapter extends BaseAdapter {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ ...nativeRequest, stream: true }),
signal: AbortSignal.timeout(300_000),
});
if (!response.ok || !response.body) {
@@ -124,6 +125,8 @@ export class OllamaAdapter extends BaseAdapter {
// 工具调用(Ollama 在最后一个 chunk 中整块返回)
if (chunk.message?.tool_calls) {
for (const tc of chunk.message.tool_calls) {
const args = tc.function?.arguments;
const parsedArgs = typeof args === 'string' ? JSON.parse(args) : (args ?? {});
yield {
type: MetonaStreamEventType.TOOL_CALL_COMPLETE,
requestId: request.meta.requestId,
@@ -134,7 +137,7 @@ export class OllamaAdapter extends BaseAdapter {
toolCall: {
id: `tc_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`,
name: tc.function?.name ?? '',
args: tc.function?.arguments ?? {},
args: parsedArgs,
iteration: request.meta.iteration,
timestamp: Date.now(),
},
@@ -441,10 +444,17 @@ export class OllamaAdapter extends BaseAdapter {
reasoningContent: message?.thinking as string | undefined,
toolCalls: toolCalls?.map((tc, i) => {
const fn = tc.function as Record<string, unknown>;
const rawArgs = fn?.arguments;
let args: Record<string, unknown> = {};
try {
args = typeof rawArgs === 'string' ? JSON.parse(rawArgs) : (rawArgs as Record<string, unknown>) ?? {};
} catch {
args = {};
}
return {
id: `tc_${Date.now()}_${i}`,
name: (fn?.name as string) ?? '',
args: (fn?.arguments as Record<string, unknown>) ?? {},
args,
iteration: 0,
timestamp: Date.now(),
};
@@ -166,7 +166,7 @@ export async function* parseSSEStream(
// 非 [DONE] 但 finish_reason 为 tool_calls 时提前 flush 缓冲区
const finishReason = chunk.choices?.[0]?.finish_reason as string | undefined;
if (finishReason === 'tool_calls' || finishReason === 'stop') {
if (finishReason === 'tool_calls') {
for (const [index, buf] of toolCallsBuffer) {
try {
yield {