diff --git a/src/bot/telegram-bot.ts b/src/bot/telegram-bot.ts index e620502..f4404e6 100644 --- a/src/bot/telegram-bot.ts +++ b/src/bot/telegram-bot.ts @@ -27,37 +27,43 @@ export class TelegramBot { try { const userPipeline: Pipeline = { - description: 'User message processing pipeline', - systemPrompt: `Ты полезный ассистент, который всегда отвечает на русском языке. - Анализируй сообщения пользователя и давай развернутые ответы. - Твой ответ всегда должен быть в стиле гопника, но не слишком длинный. - Всегда начинай своё сообщение со слов: "Мой господин". - Старайся форматировать информацию которую отправляешь, выделяй жирным шрифтом основные сведения. - Старайся использовать эмодзи.`, + description: 'Криптокошелёк анализатор для Liquidswap', + systemPrompt: `Вы — профессиональный криптоаналитик и портфельный менеджер. +Анализируйте криптовалютный рынок, используя актуальные веб-данные. +Проведите анализ портфеля пользователя, адаптируясь к широкому (рыночные тренды, новости) или ограниченному (только портфель) набору данных. +Если данные портфеля отсутствуют, запросите их. Охватите по возможности: +- Технический анализ (тренды, волатильность, индикаторы). +- Фундаментальный анализ (новости, проекты). +- Риски (корреляции, ликвидность, регуляторные факторы). +- Диверсификацию и оптимизацию. +Предоставьте рекомендации по улучшению портфеля. +Формат ответа: отчет с разделами "Текущая ситуация на рынке", "Анализ портфеля", "Риски", "Рекомендации". +Тон профессиональный, без сложного жаргона. +Если данных недостаточно, задайте уточняющие вопросы. +Обеспечьте точность ≥ 95%, избегая неподтвержденных предположений.`, steps: [ { - name: 'Обработка сообщения', + name: 'Обработка запроса', prompt: userMessage, }, { - name: 'Генерация ответа', + name: 'Анализ', + prompt: `Я хочу грамотно распределить свой криптовалютный портфель, используя данные DeFi-протокола Liquidswap. + Пожалуйста, предоставьте рекомендации по распределению активов, + основываясь на данных от инструментов: + \`get_tokens\`, + \`get_pools\`, + \`get_pools_historical_aprs\` (за 5 дней), + \`get_pools_historical_tvls\` (за 5 дней), + \`get_balances_by_address\` (мой адрес Aptos, если потребуется, запросите его) и \`multi_tool_use.parallel\`.`, + }, + { + name: 'Форматирование ответа', prompt: - 'Отформатируй свой ответ, в формат HTML для Telegram.' + - 'Не добавляй никакого дополнительного текста или других символов.' + - 'Твой ответ будет напрямую отправлен пользователю через Telegram.' + - '**Поддерживаемые теги**: \n' + - '- ``, ``: Жирный текст. \n' + - '- ``, ``: Курсив. \n' + - '- ``, ``: Подчёркивание. \n' + - '- ``, ``, ``: Зачёркивание. \n' + - '- ``: Ссылки (внешние или `tg://user?id=123`). \n' + - '- ``: Моноширинный текст (короткий код). \n' + - '- `
`: Блок кода (поддерживает ``).' +
-                'Используй ТОЛЬКО эти теги И НИКАКИЕ ДРУГИЕ!',
+                'Отлично, теперь используя эмодзи давай сделаем из этих данных telegram пост',
             },
           ],
         };
-
         this.activePipelines.set(chatId, userPipeline);
 
         await ctx.sendChatAction('typing');
diff --git a/src/pipelines/pipeline-executor.ts b/src/pipelines/pipeline-executor.ts
index 6064199..e99bc4d 100644
--- a/src/pipelines/pipeline-executor.ts
+++ b/src/pipelines/pipeline-executor.ts
@@ -31,9 +31,23 @@ export class PipelineExecutor {
   private async initChain(openAIApiKey: string): Promise {
     const tools = await this._getOrLoadTools();
     const llm = new ChatOpenAI({
-      model: 'gpt-4o',
+      model: 'gpt-4.1-2025-04-14',
       temperature: 0.2,
       openAIApiKey: openAIApiKey,
+      callbacks: [
+        {
+          handleLLMStart: async (_llm, prompts) => {
+            console.log('\n=== LLM CALL STARTED ===');
+            console.log('Prompts:', prompts);
+            console.log('========================\n');
+          },
+          handleLLMError: async (err) => {
+            console.error('\n=== LLM ERROR ===');
+            console.error(err);
+            console.error('=================\n');
+          },
+        },
+      ],
     });
     return llm.bindTools(tools);
   }
@@ -84,12 +98,43 @@ export class PipelineExecutor {
     return results;
   }
 
+  private logAIMessages(
+    messages: (HumanMessage | SystemMessage | AIMessage | ToolMessage)[],
+    direction: 'TO_AI' | 'FROM_AI',
+  ) {
+    console.log(`\n=== AI ${direction} MESSAGES ===`);
+    messages.forEach((msg, i) => {
+      console.log(`\nMessage ${i + 1} (${msg._getType()}):`);
+      if ('content' in msg) {
+        console.log('Content:', msg.content);
+      }
+      if ('tool_calls' in msg && msg.tool_calls) {
+        console.log('Tool calls:', JSON.stringify(msg.tool_calls, null, 2));
+      }
+      if ('tool_call_id' in msg) {
+        console.log('Tool call ID:', msg.tool_call_id);
+      }
+    });
+    console.log('==========================\n');
+  }
+
   private async _resolveToolCalls(
     chain: Runnable,
     messages: (HumanMessage | SystemMessage | AIMessage | ToolMessage)[],
   ): Promise {
+    // Log messages being sent to AI
+    this.logAIMessages(messages, 'TO_AI');
+
     let response: AIMessage = await chain.invoke(messages);
 
+    // Log response from AI
+    console.log('\n=== AI RESPONSE ===');
+    console.log('Content:', response.content);
+    if (response.tool_calls) {
+      console.log('Tool calls:', JSON.stringify(response.tool_calls, null, 2));
+    }
+    console.log('==================\n');
+
     while (response.tool_calls && response.tool_calls.length > 0) {
       messages.push(response);