Skip to content

Commit 8afef68

Browse files
committed
chore(example):format example
1 parent 09858d1 commit 8afef68

File tree

4 files changed

+88
-101
lines changed

4 files changed

+88
-101
lines changed
Lines changed: 26 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,53 @@
1-
import { Telegraf } from 'telegraf';
2-
import { setupHandlers } from './handlers';
3-
import { PolkadotAgentKit } from '@polkadot-agent-kit/sdk';
4-
import { getChainByName, KnownChainId, getAllSupportedChains } from '@polkadot-agent-kit/common';
5-
import { ChatModelFactory, ChatModelOptions, ChatModelWithTools } from './models';
6-
import { BaseChatModel } from '@langchain/core/language_models/chat_models';
7-
1+
import { Telegraf } from "telegraf";
2+
import { setupHandlers } from "./handlers";
3+
import { PolkadotAgentKit } from "@polkadot-agent-kit/sdk";
4+
import {
5+
getChainByName,
6+
KnownChainId,
7+
getAllSupportedChains,
8+
} from "@polkadot-agent-kit/common";
9+
import {
10+
ChatModelFactory,
11+
ChatModelOptions,
12+
ChatModelWithTools,
13+
} from "./models";
14+
import { BaseChatModel } from "@langchain/core/language_models/chat_models";
815

916
interface BotConfig {
1017
botToken: string;
1118
openAiApiKey?: string;
1219
privateKey?: string;
1320
}
1421

15-
16-
1722
export class TelegramBot {
1823
private bot: Telegraf;
1924
private agent: PolkadotAgentKit;
2025
private llm: ChatModelWithTools;
2126

22-
2327
private initializeLLM(openAiApiKey?: string): ChatModelWithTools {
2428
const options: ChatModelOptions = {
25-
provider: openAiApiKey ? 'openai' as const : 'ollama' as const,
26-
modelName: openAiApiKey ? 'gpt-4o-mini' : 'qwen3:latest',
29+
provider: openAiApiKey ? ("openai" as const) : ("ollama" as const),
30+
modelName: openAiApiKey ? "gpt-4o-mini" : "qwen3:latest",
2731
temperature: 0.7,
2832
verbose: false,
2933
};
3034
return ChatModelFactory.create(options);
3135
}
3236

3337
constructor(config: BotConfig) {
34-
const {
35-
botToken,
36-
openAiApiKey,
37-
privateKey,
38-
} = config;
38+
const { botToken, openAiApiKey, privateKey } = config;
3939

4040
if (!botToken) {
41-
throw new Error('TELEGRAM_BOT_TOKEN must be provided!');
41+
throw new Error("TELEGRAM_BOT_TOKEN must be provided!");
4242
}
4343

4444
this.bot = new Telegraf(botToken);
4545

46-
this.agent = new PolkadotAgentKit(privateKey as string, { keyType: 'Sr25519' });
47-
46+
this.agent = new PolkadotAgentKit(privateKey as string, {
47+
keyType: "Sr25519",
48+
});
4849

4950
this.llm = this.initializeLLM(openAiApiKey);
50-
5151
}
5252

5353
async initialize() {
@@ -57,7 +57,7 @@ export class TelegramBot {
5757
// Initialize APIs first
5858
await this.agent.initializeApi();
5959

60-
// Set up tools
60+
// Set up tools
6161
// Get balance of agent account
6262
const checkBalance = this.agent.getNativeBalanceTool();
6363
// Transfer native tokens to a recipient address on a specific chain.
@@ -75,17 +75,13 @@ export class TelegramBot {
7575
}
7676
}
7777

78-
79-
80-
8178
public async start(): Promise<void> {
8279
try {
8380
await this.initialize();
8481
await this.bot.launch();
85-
console.log('Bot is running!');
86-
82+
console.log("Bot is running!");
8783
} catch (error) {
88-
console.error('Failed to start bot:', error);
84+
console.error("Failed to start bot:", error);
8985
throw error;
9086
}
9187
}
@@ -95,7 +91,7 @@ export class TelegramBot {
9591
await this.agent.disconnect();
9692
this.bot.stop();
9793
} catch (error) {
98-
console.error('Error during shutdown:', error);
94+
console.error("Error during shutdown:", error);
9995
}
10096
}
101-
}
97+
}

examples/telegram-bot/src/handlers.ts

Lines changed: 23 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
1-
import { Telegraf } from 'telegraf';
2-
import { HumanMessage, SystemMessage } from '@langchain/core/messages';
3-
import { DynamicStructuredTool, Tool } from '@langchain/core/tools';
4-
import { ChatModelWithTools } from './models';
5-
6-
7-
1+
import { Telegraf } from "telegraf";
2+
import { HumanMessage, SystemMessage } from "@langchain/core/messages";
3+
import { DynamicStructuredTool, Tool } from "@langchain/core/tools";
4+
import { ChatModelWithTools } from "./models";
85

96
const SYSTEM_PROMPT = `I am a Telegram bot powered by PolkadotAgentKit. I can assist you with:
107
- Transferring native tokens on specific chain (e.g., "transfer 1 WND to 5CSox4ZSN4SGLKUG9NYPtfVK9sByXLtxP4hmoF4UgkM4jgDJ on westend_asset_hub")
@@ -30,24 +27,21 @@ export function setupHandlers(
3027
llm: ChatModelWithTools,
3128
toolsByName: Record<string, DynamicStructuredTool>,
3229
): void {
33-
3430
bot.start((ctx) => {
3531
ctx.reply(
36-
'Welcome to Polkadot Bot!\n' +
37-
'I can assist you with:\n' +
38-
'- Transferring native tokens (e.g., "transfer 1 token to westend_asset_hub to 5CSox4ZSN4SGLKUG9NYPtfVK9sByXLtxP4hmoF4UgkM4jgDJ")\n' +
39-
'- Checking balance (e.g., "check balance on west/polkadot/kusama")\n' +
40-
'- Checking proxies (e.g., "check proxies on westend" or "check proxies")\n' +
41-
'Try asking something!',
32+
"Welcome to Polkadot Bot!\n" +
33+
"I can assist you with:\n" +
34+
'- Transferring native tokens (e.g., "transfer 1 token to westend_asset_hub to 5CSox4ZSN4SGLKUG9NYPtfVK9sByXLtxP4hmoF4UgkM4jgDJ")\n' +
35+
'- Checking balance (e.g., "check balance on west/polkadot/kusama")\n' +
36+
'- Checking proxies (e.g., "check proxies on westend" or "check proxies")\n' +
37+
"Try asking something!",
4238
);
4339
});
4440

45-
46-
bot.on('text', async (ctx) => {
41+
bot.on("text", async (ctx) => {
4742
const message = ctx.message.text;
4843

49-
50-
if (message.startsWith('/')) return;
44+
if (message.startsWith("/")) return;
5145

5246
try {
5347
const llmWithTools = llm.bindTools(Object.values(toolsByName));
@@ -58,43 +52,43 @@ export function setupHandlers(
5852
const aiMessage = await llmWithTools.invoke(messages);
5953
if (aiMessage.tool_calls && aiMessage.tool_calls.length > 0) {
6054
for (const toolCall of aiMessage.tool_calls) {
61-
6255
const selectedTool = toolsByName[toCamelCase(toolCall.name)];
6356
if (selectedTool) {
6457
const toolMessage = await selectedTool.invoke(toolCall);
6558
if (!toolMessage || !toolMessage.content) {
66-
await ctx.reply('Tool did not return a response.');
59+
await ctx.reply("Tool did not return a response.");
6760
return;
6861
}
69-
const response = JSON.parse(toolMessage.content || '{}');
62+
const response = JSON.parse(toolMessage.content || "{}");
7063
if (response.error) {
7164
await ctx.reply(`Error: ${response.message}`);
7265
} else {
73-
const content = JSON.parse(response.content || '{}');
74-
await ctx.reply(content.data || 'No message from tool.');
66+
const content = JSON.parse(response.content || "{}");
67+
await ctx.reply(content.data || "No message from tool.");
7568
}
7669
} else {
7770
console.warn(`Tool not found: ${toolCall.name}`);
7871
await ctx.reply(`Tool ${toolCall.name} not found.`);
7972
}
8073
}
8174
} else {
82-
const content = String(aiMessage.content || 'No response from LLM.');
75+
const content = String(aiMessage.content || "No response from LLM.");
8376
await ctx.reply(content);
8477
}
8578
} catch (error) {
86-
console.error('Error handling message:', error);
79+
console.error("Error handling message:", error);
8780
if (error instanceof Error) {
88-
console.error('Error stack:', error.stack);
81+
console.error("Error stack:", error.stack);
8982
}
90-
await ctx.reply(`Sorry, an error occurred: ${error instanceof Error ? error.message : String(error)}`);
83+
await ctx.reply(
84+
`Sorry, an error occurred: ${error instanceof Error ? error.message : String(error)}`,
85+
);
9186
}
9287
});
9388

94-
9589
bot.catch((err, ctx) => {
9690
console.error(`Error for ${ctx.updateType}`, err);
97-
ctx.reply('An error occurred. Please try again.');
91+
ctx.reply("An error occurred. Please try again.");
9892
});
9993
}
10094

examples/telegram-bot/src/index.ts

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
1+
import { TelegramBot } from "./TelegramBot";
12

2-
import { TelegramBot } from './TelegramBot';
3-
4-
import * as dotenv from 'dotenv';
3+
import * as dotenv from "dotenv";
54
dotenv.config();
65

76
async function runBot() {
8-
97
const bot = new TelegramBot({
108
botToken: process.env.TELEGRAM_BOT_TOKEN!,
119
openAiApiKey: process.env.OPENAI_API_KEY!,
@@ -14,8 +12,8 @@ async function runBot() {
1412

1513
await bot.start();
1614

17-
process.once('SIGINT', () => bot.stop());
18-
process.once('SIGTERM', () => bot.stop());
15+
process.once("SIGINT", () => bot.stop());
16+
process.once("SIGTERM", () => bot.stop());
1917
}
2018

21-
runBot();
19+
runBot();
Lines changed: 34 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,47 @@
1-
import { BaseChatModel } from '@langchain/core/language_models/chat_models';
2-
import { ChatOpenAI } from '@langchain/openai';
3-
import { ChatOllama } from '@langchain/ollama';
1+
import { BaseChatModel } from "@langchain/core/language_models/chat_models";
2+
import { ChatOpenAI } from "@langchain/openai";
3+
import { ChatOllama } from "@langchain/ollama";
44

5-
export type ChatProvider = 'ollama' | 'openai';
5+
export type ChatProvider = "ollama" | "openai";
66

77
export type ChatModelWithTools = BaseChatModel & {
8-
bindTools: (tools: any[]) => any;
8+
bindTools: (tools: any[]) => any;
99
};
1010

11-
12-
1311
export interface ChatModelOptions {
14-
provider: ChatProvider;
15-
temperature?: number;
16-
modelName?: string;
17-
verbose?: boolean;
12+
provider: ChatProvider;
13+
temperature?: number;
14+
modelName?: string;
15+
verbose?: boolean;
1816
}
1917

20-
21-
const chatModelConstructors: Record<ChatProvider, (options: ChatModelOptions) => ChatModelWithTools > = {
22-
openai: ({ modelName, temperature = 0.7, verbose = false }) =>
23-
new ChatOpenAI({
24-
modelName: modelName ?? 'gpt-4o-mini',
25-
temperature,
26-
streaming: true,
27-
openAIApiKey: process.env.OPENAI_API_KEY!,
28-
verbose,
29-
}),
30-
ollama: ({ modelName, temperature = 0.7, verbose = false }) =>
31-
new ChatOllama({
32-
model: modelName ?? 'llama3',
33-
temperature,
34-
verbose,
35-
}),
18+
const chatModelConstructors: Record<
19+
ChatProvider,
20+
(options: ChatModelOptions) => ChatModelWithTools
21+
> = {
22+
openai: ({ modelName, temperature = 0.7, verbose = false }) =>
23+
new ChatOpenAI({
24+
modelName: modelName ?? "gpt-4o-mini",
25+
temperature,
26+
streaming: true,
27+
openAIApiKey: process.env.OPENAI_API_KEY!,
28+
verbose,
29+
}),
30+
ollama: ({ modelName, temperature = 0.7, verbose = false }) =>
31+
new ChatOllama({
32+
model: modelName ?? "llama3",
33+
temperature,
34+
verbose,
35+
}),
3636
};
3737

3838
export class ChatModelFactory {
39-
static create(options: ChatModelOptions): ChatModelWithTools {
40-
const { provider } = options;
41-
const constructor = chatModelConstructors[provider];
42-
if (!constructor) {
43-
throw new Error(`Unsupported provider: ${provider}`);
44-
}
45-
return constructor(options);
39+
static create(options: ChatModelOptions): ChatModelWithTools {
40+
const { provider } = options;
41+
const constructor = chatModelConstructors[provider];
42+
if (!constructor) {
43+
throw new Error(`Unsupported provider: ${provider}`);
4644
}
45+
return constructor(options);
46+
}
4747
}
48-

0 commit comments

Comments
 (0)