Internationalizes error messages and console logs.
This commit is contained in:
1 parent
fa126651de
commit
c7735cc6f9
4 files changed
+50
-57
No files matched your search
+32
-35
@@ -41,7 +41,7 @@ export class TelegramBot {
|
||||
const message =
|
||||
status === 'started'
|
||||
? `<b>${stepName}</b> ${emoji}`
|
||||
: `<b>${stepName}</b> ${emoji}\n\n<pre>${result?.substring(0, 3000) || 'Готово'}</pre>`;
|
||||
: `<b>${stepName}</b> ${emoji}\n\n<pre>${result?.substring(0, 3000) || 'Done'}</pre>`;
|
||||
|
||||
await this.sendMessage(chatId, message);
|
||||
};
|
||||
@@ -50,7 +50,7 @@ export class TelegramBot {
|
||||
private setupHandlers(): void {
|
||||
this.bot.start((ctx) => {
|
||||
ctx.reply(
|
||||
'Привет! Я бот для работы с AI пайплайнами. Просто отправь мне сообщение, и я обработаю его через пайплайн.',
|
||||
'Hello! I am a bot for working with AI pipelines. Just send me a message and I will process it through the pipeline.',
|
||||
);
|
||||
});
|
||||
|
||||
@@ -61,50 +61,49 @@ export class TelegramBot {
|
||||
|
||||
try {
|
||||
const userPipeline: Pipeline = {
|
||||
description: 'Криптокошелёк анализатор для Liquidswap',
|
||||
systemPrompt: `Вы — профессиональный криптоаналитик и портфельный менеджер.
|
||||
Анализируйте криптовалютный рынок, используя актуальные веб-данные.
|
||||
Проведите анализ портфеля пользователя, адаптируясь к широкому (рыночные тренды, новости) или ограниченному (только портфель) набору данных.
|
||||
Если данные портфеля отсутствуют, запросите их. Охватите по возможности:
|
||||
- Технический анализ (тренды, волатильность, индикаторы).
|
||||
- Фундаментальный анализ (новости, проекты).
|
||||
- Риски (корреляции, ликвидность, регуляторные факторы).
|
||||
- Диверсификацию и оптимизацию.
|
||||
Предоставьте рекомендации по улучшению портфеля.
|
||||
Формат ответа: отчет с разделами "Текущая ситуация на рынке", "Анализ портфеля", "Риски", "Рекомендации".
|
||||
Тон профессиональный, без сложного жаргона.
|
||||
Если данных недостаточно, задайте уточняющие вопросы.
|
||||
Обеспечьте точность ≥ 95%, избегая неподтвержденных предположений.`,
|
||||
description: 'Crypto wallet analyzer for Liquidswap',
|
||||
systemPrompt: `You are a professional crypto analyst and portfolio manager.
|
||||
Analyze the cryptocurrency market using up-to-date web data.
|
||||
Conduct a portfolio analysis, adapting to either a broad (market trends, news) or limited (portfolio only) dataset.
|
||||
If portfolio data is missing, request it. Cover the following aspects if possible:
|
||||
- Technical analysis (trends, volatility, indicators).
|
||||
- Fundamental analysis (news, projects).
|
||||
- Risks (correlations, liquidity, regulatory factors).
|
||||
- Diversification and optimization.
|
||||
Provide recommendations for portfolio improvement.
|
||||
Response format: a report with sections "Current Market Situation", "Portfolio Analysis", "Risks", "Recommendations".
|
||||
Maintain a professional tone without complex jargon.
|
||||
If data is insufficient, ask clarifying questions.
|
||||
Ensure accuracy ≥ 95%, avoiding unsubstantiated assumptions.`,
|
||||
steps: [
|
||||
{
|
||||
name: 'Обработка запроса',
|
||||
name: 'Request Processing',
|
||||
prompt: userMessage,
|
||||
},
|
||||
{
|
||||
name: 'Анализ',
|
||||
prompt: `Я хочу грамотно распределить свой криптовалютный портфель, используя данные DeFi-протокола Liquidswap.
|
||||
Пожалуйста, предоставьте рекомендации по распределению активов,
|
||||
основываясь на данных от инструментов:
|
||||
name: 'Analysis',
|
||||
prompt: `I want to properly allocate my cryptocurrency portfolio using data from the Liquidswap DeFi protocol.
|
||||
Please provide asset allocation recommendations based on data from the following tools:
|
||||
\`get_tokens\`,
|
||||
\`get_pools\`,
|
||||
\`get_pools_historical_aprs\` (за 5 дней),
|
||||
\`get_pools_historical_tvls\` (за 5 дней),
|
||||
\`get_balances_by_address\` (мой адрес Aptos, если потребуется, запросите его) и \`multi_tool_use.parallel\`.
|
||||
Затем напиши доступную информацию об указанном адресе.`,
|
||||
\`get_pools_historical_aprs\` (last 5 days),
|
||||
\`get_pools_historical_tvls\` (last 5 days),
|
||||
\`get_balances_by_address\` (my Aptos address, request it if needed) and \`multi_tool_use.parallel\`.
|
||||
Then provide the available information about the specified address.`,
|
||||
},
|
||||
{
|
||||
name: 'Форматирование ответа',
|
||||
prompt: `Отлично, теперь используя эмодзи давай сделаем из этих данных telegram пост.
|
||||
Сначала кратко напиши простыми словами что следовало бы сделать пользователю,
|
||||
затем напиши подробную детальную информацию.
|
||||
В конце поста должен быть текст: "${process.env.PROMO_TEXT}"`,
|
||||
name: 'Response Formatting',
|
||||
prompt: `Great, now let's create a Telegram post from this data using emojis.
|
||||
First, briefly explain in simple terms what the user should do,
|
||||
then provide detailed information.
|
||||
The post should end with the text: "${process.env.PROMO_TEXT}"`,
|
||||
},
|
||||
],
|
||||
};
|
||||
this.activePipelines.set(chatId, { pipeline: userPipeline, chatId });
|
||||
|
||||
await ctx.sendChatAction('typing');
|
||||
await ctx.reply('🚀 Запускаю анализ...');
|
||||
await ctx.reply('🚀 Starting analysis...');
|
||||
|
||||
const results = await this.pipelineExecutor.executeChain({
|
||||
pipeline: userPipeline,
|
||||
@@ -131,13 +130,11 @@ export class TelegramBot {
|
||||
console.log(`Sending response to chat ${chatId}:`, trimmedResult);
|
||||
await ctx.replyWithHTML(trimmedResult);
|
||||
} else {
|
||||
await ctx.reply(
|
||||
'Не удалось обработать запрос. Пожалуйста, попробуйте еще раз.',
|
||||
);
|
||||
await ctx.reply('Failed to process the request. Please try again.');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error processing message:', error);
|
||||
await ctx.reply('Произошла ошибка при обработке вашего запроса.');
|
||||
await ctx.reply('An error occurred while processing your request.');
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
+5
-11
@@ -9,33 +9,27 @@ async function main() {
|
||||
const mcpServerUrl = process.env.MCP_SERVER_URL;
|
||||
|
||||
if (!telegramToken) {
|
||||
console.error(
|
||||
'Ошибка: Переменная окружения TELEGRAM_BOT_TOKEN не установлена.',
|
||||
);
|
||||
console.error('Error: TELEGRAM_BOT_TOKEN environment variable is not set.');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (!openAIApiKey) {
|
||||
console.error(
|
||||
'Ошибка: Переменная окружения OPENAI_API_KEY не установлена.',
|
||||
);
|
||||
console.error('Error: OPENAI_API_KEY environment variable is not set.');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (!mcpServerUrl) {
|
||||
console.error(
|
||||
'Ошибка: Переменная окружения MCP_SERVER_URL не установлена.',
|
||||
);
|
||||
console.error('Error: MCP_SERVER_URL environment variable is not set.');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const bot = new TelegramBot(telegramToken, mcpServerUrl);
|
||||
bot.launch();
|
||||
|
||||
console.log('Бот запущен и готов к работе!');
|
||||
console.log('Bot is up and running!');
|
||||
}
|
||||
|
||||
main().catch((error) => {
|
||||
console.error('Произошла ошибка:', error);
|
||||
console.error('An error occurred:', error);
|
||||
process.exit(1);
|
||||
});
|
||||
@@ -98,7 +98,7 @@ export class PipelineExecutor {
|
||||
|
||||
for (let i = 0; i < totalSteps; i++) {
|
||||
const { name, prompt } = steps[i]!;
|
||||
const stepName = name || 'Без названия';
|
||||
const stepName = name || 'Untitled';
|
||||
const isLastStep = i === totalSteps - 1;
|
||||
|
||||
try {
|
||||
@@ -120,7 +120,7 @@ export class PipelineExecutor {
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`Error in step "${stepName}":`, error);
|
||||
const errorMessage = `❌ Ошибка на шаге "${stepName}": ${error instanceof Error ? error.message : String(error)}`;
|
||||
const errorMessage = `❌ Error in step "${stepName}": ${error instanceof Error ? error.message : String(error)}`;
|
||||
if (options.onStepComplete) {
|
||||
await options.onStepComplete(stepName, errorMessage, isLastStep);
|
||||
}
|
||||
|
||||
@@ -24,10 +24,10 @@ export class McpToolsService {
|
||||
version: '1.0.0',
|
||||
});
|
||||
await this.mcpClient.connect(this.transport);
|
||||
console.log(`[MCP Service] Подключено к MCP серверу: ${this.serverUrl}`);
|
||||
console.log(`[MCP Service] Connected to MCP server: ${this.serverUrl}`);
|
||||
} catch (error) {
|
||||
console.error(
|
||||
`[MCP Service] Ошибка подключения к MCP серверу ${this.serverUrl}:`,
|
||||
`[MCP Service] Error connecting to MCP server ${this.serverUrl}:`,
|
||||
error,
|
||||
);
|
||||
throw error;
|
||||
@@ -39,13 +39,15 @@ export class McpToolsService {
|
||||
await this.mcpClient.close();
|
||||
this.mcpClient = null;
|
||||
this.transport = null;
|
||||
console.log(`[MCP Service] Отключено от MCP сервера: ${this.serverUrl}`);
|
||||
console.log(
|
||||
`[MCP Service] Disconnected from MCP server: ${this.serverUrl}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async getLangchainTools(): Promise<DynamicStructuredTool[]> {
|
||||
if (!this.mcpClient) {
|
||||
throw new Error('MCP клиент не подключен. Сначала вызовите .connect()');
|
||||
throw new Error('MCP client is not connected. Call .connect() first');
|
||||
}
|
||||
|
||||
const mcpTools: McpTool[] = (await this.mcpClient.listTools()).tools;
|
||||
@@ -89,7 +91,7 @@ export class McpToolsService {
|
||||
schema: zodSchema,
|
||||
func: async (args: Record<string, unknown>) => {
|
||||
console.log(
|
||||
`[MCP Tool Call] Вызов инструмента MCP: ${mcpTool.name} с аргументами:`,
|
||||
`[MCP Tool Call] Calling MCP tool: ${mcpTool.name} with arguments:`,
|
||||
args,
|
||||
);
|
||||
const result = await this.mcpClient!.callTool({
|
||||
@@ -103,7 +105,7 @@ export class McpToolsService {
|
||||
.map((c) => (c as TextContent).text || '')
|
||||
.join('\n');
|
||||
throw new Error(
|
||||
`Ошибка выполнения инструмента ${mcpTool.name}: ${errorContent}`,
|
||||
`Error executing tool ${mcpTool.name}: ${errorContent}`,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -114,9 +116,9 @@ export class McpToolsService {
|
||||
return (result.content as any[])
|
||||
.map((c) => {
|
||||
if (c.type === 'text') return (c as TextContent).text;
|
||||
if (c.type === 'image') return `[Изображение: ${c.mimeType}]`;
|
||||
if (c.type === 'audio') return `[Аудио: ${c.mimeType}]`;
|
||||
if (c.type === 'resource') return `[Ресурс: ${c.uri}]`;
|
||||
if (c.type === 'image') return `[Image: ${c.mimeType}]`;
|
||||
if (c.type === 'audio') return `[Audio: ${c.mimeType}]`;
|
||||
if (c.type === 'resource') return `[Resource: ${c.uri}]`;
|
||||
return JSON.stringify(c);
|
||||
})
|
||||
.join('\n');
|
||||
|
||||
Reference in new issue
Block a user