Refactor: Remove redundant comments and simplify code
This commit is contained in:
1 parent
c348b4902e
commit
da064fcb66
1 file changed
+20
-41
+20
-41
@@ -7,16 +7,15 @@ import {
|
||||
import { Runnable } from '@langchain/core/runnables';
|
||||
import { DynamicStructuredTool } from '@langchain/core/tools';
|
||||
import { ChatOpenAI } from '@langchain/openai';
|
||||
import dotenv from 'dotenv'; // Импортируем dotenv для загрузки переменных окружения
|
||||
import dotenv from 'dotenv';
|
||||
import Handlebars from 'handlebars';
|
||||
import { z } from 'zod';
|
||||
|
||||
// MCP SDK imports
|
||||
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
||||
import { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js';
|
||||
import { Tool as McpTool, TextContent } from '@modelcontextprotocol/sdk/types';
|
||||
|
||||
dotenv.config(); // Загружаем переменные окружения из .env файла
|
||||
dotenv.config();
|
||||
|
||||
interface PipelineStep {
|
||||
name: string;
|
||||
@@ -29,9 +28,6 @@ interface Pipeline {
|
||||
steps: PipelineStep[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Сервис для взаимодействия с MCP сервером и предоставления инструментов LangChain.
|
||||
*/
|
||||
class McpToolsService {
|
||||
private mcpClient: Client | null = null;
|
||||
private transport: SSEClientTransport | null = null;
|
||||
@@ -41,12 +37,9 @@ class McpToolsService {
|
||||
this.serverUrl = serverUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Устанавливает соединение с MCP сервером.
|
||||
*/
|
||||
async connect(): Promise<void> {
|
||||
if (this.mcpClient && this.transport) {
|
||||
return; // Уже подключено
|
||||
return;
|
||||
}
|
||||
try {
|
||||
this.transport = new SSEClientTransport(new URL(this.serverUrl));
|
||||
@@ -65,9 +58,6 @@ class McpToolsService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Закрывает соединение с MCP сервером.
|
||||
*/
|
||||
async disconnect(): Promise<void> {
|
||||
if (this.mcpClient) {
|
||||
await this.mcpClient.close();
|
||||
@@ -77,10 +67,6 @@ class McpToolsService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Получает список инструментов с MCP сервера и преобразует их в формат LangChain.
|
||||
* @returns Массив инструментов LangChain.
|
||||
*/
|
||||
async getLangchainTools(): Promise<DynamicStructuredTool[]> {
|
||||
if (!this.mcpClient) {
|
||||
throw new Error('MCP клиент не подключен. Сначала вызовите .connect()');
|
||||
@@ -90,8 +76,6 @@ class McpToolsService {
|
||||
const langchainTools: DynamicStructuredTool[] = [];
|
||||
|
||||
for (const mcpTool of mcpTools) {
|
||||
// Простая конвертация JSON Schema в Zod schema.
|
||||
// Для сложных схем рекомендуется использовать специализированную библиотеку (например, json-schema-to-zod).
|
||||
const properties: Record<string, z.ZodTypeAny> = {};
|
||||
for (const key in mcpTool.inputSchema.properties) {
|
||||
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
||||
@@ -108,11 +92,9 @@ class McpToolsService {
|
||||
schemaType = z.boolean();
|
||||
break;
|
||||
case 'array':
|
||||
// Для массивов без явного типа элементов, используем z.array(z.any())
|
||||
schemaType = z.array(z.any());
|
||||
break;
|
||||
case 'object':
|
||||
// Для объектов без явной вложенной схемы, используем z.object({})
|
||||
schemaType = z.object({});
|
||||
break;
|
||||
default:
|
||||
@@ -149,7 +131,6 @@ class McpToolsService {
|
||||
);
|
||||
}
|
||||
|
||||
// Предпочтительно возвращаем структурированный контент, если он есть
|
||||
if (result.structuredContent) {
|
||||
return result.structuredContent;
|
||||
}
|
||||
@@ -160,7 +141,7 @@ class McpToolsService {
|
||||
if (c.type === 'image') return `[Изображение: ${c.mimeType}]`;
|
||||
if (c.type === 'audio') return `[Аудио: ${c.mimeType}]`;
|
||||
if (c.type === 'resource') return `[Ресурс: ${c.uri}]`;
|
||||
return JSON.stringify(c); // Запасной вариант для других типов
|
||||
return JSON.stringify(c);
|
||||
})
|
||||
.join('\n');
|
||||
},
|
||||
@@ -181,8 +162,8 @@ class PipelineExecutor {
|
||||
|
||||
private async _getOrLoadTools(): Promise<DynamicStructuredTool[]> {
|
||||
if (!this.cachedTools) {
|
||||
await this.mcpToolsService.connect(); // Устанавливаем соединение с MCP сервером
|
||||
this.cachedTools = await this.mcpToolsService.getLangchainTools(); // Получаем инструменты LangChain
|
||||
await this.mcpToolsService.connect();
|
||||
this.cachedTools = await this.mcpToolsService.getLangchainTools();
|
||||
}
|
||||
return this.cachedTools;
|
||||
}
|
||||
@@ -225,25 +206,25 @@ class PipelineExecutor {
|
||||
const variables = options.variables ?? {};
|
||||
const systemPrompts = options.systemPrompts ?? [];
|
||||
const chain = await this.initChain(options.openAIApiKey);
|
||||
const initialMessages = this.buildMessages(
|
||||
[options.pipeline.systemPrompt, ...systemPrompts],
|
||||
variables,
|
||||
);
|
||||
// Инициализируем массив сообщений, который будет накапливаться
|
||||
const messages: (HumanMessage | SystemMessage | AIMessage | ToolMessage)[] =
|
||||
this.buildMessages(
|
||||
[options.pipeline.systemPrompt, ...systemPrompts],
|
||||
variables,
|
||||
);
|
||||
const results: string[] = [];
|
||||
|
||||
for (const { prompt } of options.pipeline.steps) {
|
||||
const renderedPrompt = this.renderPrompt(prompt, variables);
|
||||
const currentMessages: (
|
||||
| HumanMessage
|
||||
| SystemMessage
|
||||
| AIMessage
|
||||
| ToolMessage
|
||||
)[] = [...initialMessages, new HumanMessage(renderedPrompt)];
|
||||
// Добавляем текущий промпт пользователя в общий массив сообщений
|
||||
messages.push(new HumanMessage(renderedPrompt));
|
||||
|
||||
const finalResponse = await this._resolveToolCalls(
|
||||
chain,
|
||||
currentMessages,
|
||||
messages, // Передаем накопительный массив сообщений
|
||||
);
|
||||
// Добавляем ответ ИИ в общий массив сообщений для сохранения контекста
|
||||
messages.push(finalResponse);
|
||||
results.push(finalResponse?.content.toString() ?? '<empty>');
|
||||
}
|
||||
return results;
|
||||
@@ -260,7 +241,7 @@ class PipelineExecutor {
|
||||
|
||||
for (const toolCall of response.tool_calls) {
|
||||
try {
|
||||
const tools = await this._getOrLoadTools(); // Получаем LangChain-совместимые инструменты
|
||||
const tools = await this._getOrLoadTools();
|
||||
const tool = tools.find((t) => t.name === toolCall.name);
|
||||
|
||||
if (!tool) {
|
||||
@@ -276,12 +257,11 @@ class PipelineExecutor {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Выполняем функцию LangChain инструмента, которая внутри вызывает MCP сервер
|
||||
const toolResult = await tool.func(toolCall.args);
|
||||
messages.push(
|
||||
new ToolMessage({
|
||||
tool_call_id: toolCall.id!,
|
||||
content: JSON.stringify(toolResult), // LangChain ожидает строковый контент здесь
|
||||
content: JSON.stringify(toolResult),
|
||||
}),
|
||||
);
|
||||
} catch (error) {
|
||||
@@ -305,7 +285,6 @@ class PipelineExecutor {
|
||||
|
||||
async function main() {
|
||||
const openAIApiKey = process.env.OPENAI_API_KEY;
|
||||
// Используйте переменную окружения для URL сервера MCP, с запасным вариантом по умолчанию
|
||||
const mcpServerUrl =
|
||||
process.env.MCP_SERVER_URL || 'https://santiment-mcp.dev.mind-dev.com/sse';
|
||||
|
||||
@@ -316,7 +295,7 @@ async function main() {
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const pipelineExecutor = new PipelineExecutor(mcpServerUrl); // Передаем URL сервера
|
||||
const pipelineExecutor = new PipelineExecutor(mcpServerUrl);
|
||||
|
||||
const testPipeline: Pipeline = {
|
||||
description: 'Тестовый пайплайн',
|
||||
|
||||
Reference in new issue
Block a user