From eceb46b0e3cc0cc4547bef0d99b54768eeb56129 Mon Sep 17 00:00:00 2001 From: astinz <28899947+astinz@users.noreply.github.com> Date: Mon, 23 Dec 2024 00:30:26 +0300 Subject: [PATCH 1/3] feat: ptb generation action --- packages/plugin-sui/src/actions/ptb.ts | 354 +++++++++++++++++++++++++ packages/plugin-sui/src/index.ts | 3 +- pnpm-lock.yaml | 20 +- 3 files changed, 366 insertions(+), 11 deletions(-) create mode 100644 packages/plugin-sui/src/actions/ptb.ts diff --git a/packages/plugin-sui/src/actions/ptb.ts b/packages/plugin-sui/src/actions/ptb.ts new file mode 100644 index 0000000000..661acada66 --- /dev/null +++ b/packages/plugin-sui/src/actions/ptb.ts @@ -0,0 +1,354 @@ +import { z } from "zod"; +import { + Action, + ActionExample, + composeContext, + Content, + elizaLogger, + generateObject, + HandlerCallback, + IAgentRuntime, + Memory, + ModelClass, + State, +} from "@ai16z/eliza"; + +const ArgSchema = z.union([ + z.object({ + kind: z.literal("Input"), + index: z.number(), + }), + z.object({ + kind: z.literal("Result"), + index: z.number(), + }), +]); + +const InputArgSchema = z.object({ + kind: z.literal("Input"), + index: z.number(), +}); + +const TransferObjectsSchema = z.object({ + TransferObjects: z.object({ + objects: z.array(ArgSchema), + address: ArgSchema, + }), +}); + +const SplitCoinsSchema = z.object({ + SplitCoins: z.object({ + coin: ArgSchema, + amounts: z.array(ArgSchema), + }), +}); + +const MergeCoinsSchema = z.object({ + MergeCoins: z.object({ + coin: ArgSchema, + toMerge: z.array(ArgSchema), + }), +}); + +const MakeMoveVecSchema = z.object({ + MakeMoveVec: z.object({ + args: z.array(InputArgSchema), + }), +}); + +const MoveCallSchema = z.object({ + MoveCall: z.object({ + target: InputArgSchema, + typeArgs: z.array(InputArgSchema), + args: z.array(ArgSchema), + }), +}); + +const PublishSchema = z.object({ + Publish: z.object({ + moduleBytes: z.array(InputArgSchema), + transitiveDependencies: z.array(InputArgSchema), + }), +}); + +const UpgradeSchema = z.object({ + Upgrade: z.object({ + moduleBytes: z.array(InputArgSchema), + transitiveDependencies: z.array(InputArgSchema), + package: InputArgSchema, + upgradeTicket: InputArgSchema, + }), +}); + +const CommandSchema = z.union([ + TransferObjectsSchema, + SplitCoinsSchema, + MergeCoinsSchema, + MakeMoveVecSchema, + MoveCallSchema, + PublishSchema, + UpgradeSchema, +]); + +const ptbSchema = z.object({ + inputs: z.array(z.union([z.string(), z.number(), z.boolean(), z.null()])), + commands: z.array(CommandSchema), +}); + +export interface PTBContent extends Content { + inputs: (string | number | boolean | null)[]; + commands: object[]; +} + +function isPTBContent(content: Content): content is PTBContent { + return ( + content && + typeof content === "object" && + Array.isArray(content.inputs) && + content.inputs.every((input) => + ["string", "number", "boolean"].includes(typeof input) + ) && + Array.isArray(content.commands) && + content.commands.every((command) => typeof command === "object") + ); +} + +const ptbTemplate = `Respond with a JSON markdown block containing only the extracted commands and inputs. Use null for any commands and inputs that cannot be determined. +TransferObjects sends multiple (one or more) objects to a specified address. +SplitCoins splits off multiple (one or more) coins from a single coin. +MergeCoins merges multiple (one or more) coins into a single coin. +MakeMoveVec creates a vector (potentially empty) of Move values. +MoveCall invokes either an entry or a public Move function in a published package. +Publish creates a new package and calls the init function of each module in the package. +Upgrade upgrades an existing package. + +Example responses: +\`\`\`json +{ + "inputs": ["0x1", 10, 20], + "commands": [ + { + "SplitCoins": { + "coin": { "kind": "Input", "index": 0 }, + "amounts": [ + { "kind": "Input", "index": 1 }, + { "kind": "Input", "index": 2 } + ] + } + } + ] +} +\`\`\` + +\`\`\`json +{ + "inputs": ["0x1", "0x2", "0x3"], + "commands": [{ + "MakeMoveVec": { + "args": [ + { "kind": "Input", "index": 0 }, + { "kind": "Input", "index": 1 }, + { "kind": "Input", "index": 2 } + ] + } + }] +} +\`\`\` + +\`\`\`json +{ + "inputs": ["0x1", "0x2", "0x3", "0x4"], + "commands": [{ + "TransferObjects": { + "objects": [ + { "kind": "Input", "index": 0 }, + { "kind": "Input", "index": 1 }, + { "kind": "Input", "index": 2 } + ], + "address": { "kind": "Input", "index": 3 } + } + }] +} +\`\`\` + +\`\`\`json +{ + "inputs": ["0x1", "0x2", "0x3", "0x4"], + "commands": [{ + "MergeCoins": { + "coin": { "kind": "Input", "index": 0 }, + "toMerge": [ + { "kind": "Input", "index": 1 }, + { "kind": "Input", "index": 2 }, + { "kind": "Input", "index": 3 } + ] + } + }] +} +\`\`\` + +\`\`\`json +{ + "inputs": ["0x1", "0x2", "0x3", "0x4"], + "commands": [{ + "MoveCall": { + "target": { "kind": "Input", "index": 0 }, + "typeArgs": [], + "args": [ + { "kind": "Input", "index": 1 }, + { "kind": "Input", "index": 2 }, + { "kind": "Input", "index": 3 } + ] + } + }] +} +\`\`\` + +\`\`\`json +{ + "inputs": ["0x1", "0x2", "0x3", "0x4", "0x5", "0x6"], + "commands": [ + { + "Publish": { + "moduleBytes": [ + { "kind": "Input", "index": 0 }, + { "kind": "Input", "index": 1 }, + { "kind": "Input", "index": 2 } + ], + "transitiveDependencies": [ + { "kind": "Input", "index": 3 }, + { "kind": "Input", "index": 4 }, + { "kind": "Input", "index": 5 } + ] + } + } + ] +} +\`\`\` + +{{recentMessages}} + +Respond with a JSON markdown block containing only the extracted commands and inputs.`; + +export default { + name: "BUILD_PTB", + similes: [ + "CONSTRUCT_PTB", + "COMPOSE_PTB", + "GENERATE_PTB", + "PTB", + "COMMAND", + "TRANSACTION", + ], + description: "Build a PTB from inputs and commands", + validate: async (runtime: IAgentRuntime, message: Memory) => { + console.log("Validating PTB build from user:", message.userId); + return true; + }, + handler: async ( + runtime: IAgentRuntime, + message: Memory, + state: State, + _options: { [key: string]: unknown }, + callback?: HandlerCallback + ): Promise => { + elizaLogger.log("Starting BUILD_PTB handler..."); + + if (!state) { + state = (await runtime.composeState(message)) as State; + } else { + state = await runtime.updateRecentMessageState(state); + } + + const ptbContext = composeContext({ + state, + template: ptbTemplate, + }); + + const content = await generateObject({ + runtime, + context: ptbContext, + schema: ptbSchema, + modelClass: ModelClass.SMALL, + }); + + const ptbContent = content.object as PTBContent; + + if (!isPTBContent(ptbContent)) { + console.error("Invalid PTB content:", ptbContent); + if (callback) { + await callback({ + text: "Unable to process PTB request. Invalid content provided.", + content: { error: "Invalid PTB content" }, + }); + } + } + + if (callback) { + await callback({ + text: JSON.stringify(ptbContent), + content: { + success: true, + }, + }); + } + + return true; + }, + examples: [ + [ + { + user: "{{user1}}", + content: { + text: "Transfer objects 0x1, 0x2, and 0x3 to address 0x4", + }, + }, + { + user: "{{user2}}", + content: { + text: "I will generate a PTB that transfers the objects 0x1, 0x2, 0x3 to the address 0x4", + action: "BUILD_PTB", + }, + }, + { + user: "{{user1}}", + content: { + text: "Split coin 0x1 into amounts 10 and 20", + }, + }, + { + user: "{{user2}}", + content: { + text: "I will generate a PTB that splits the coin 0x1 into amounts 10 and 20", + action: "BUILD_PTB", + }, + }, + { + user: "{{user1}}", + content: { + text: "Merge the coins 0x1, 0x2, and 0x3 into a single coin", + }, + }, + { + user: "{{user2}}", + content: { + text: "I will generate a PTB that merges the input coins 0x1, 0x2, into 0x3 coin", + action: "BUILD_PTB", + }, + }, + { + user: "{{user1}}", + content: { + text: "Construct a PTB that calls the target 0x883393ee444fb828aa0e977670cf233b0078b41d144e6208719557cb3888244d::hello_wolrd::hello_world with the argument 50", + }, + }, + { + user: "{{user2}}", + content: { + text: "I will generate a PTB that calls the input target 0x883393ee444fb828aa0e977670cf233b0078b41d144e6208719557cb3888244d::hello_wolrd::hello_world with the input argument 50", + action: "BUILD_PTB", + }, + }, + ], + ] as ActionExample[][], +} as Action; diff --git a/packages/plugin-sui/src/index.ts b/packages/plugin-sui/src/index.ts index 5f69381fda..3c0ab5eee2 100644 --- a/packages/plugin-sui/src/index.ts +++ b/packages/plugin-sui/src/index.ts @@ -1,5 +1,6 @@ import { Plugin } from "@elizaos/core"; import transferToken from "./actions/transfer.ts"; +import buildPTB from "./actions/ptb.ts"; import { WalletProvider, walletProvider } from "./providers/wallet.ts"; export { WalletProvider, transferToken as TransferSuiToken }; @@ -7,7 +8,7 @@ export { WalletProvider, transferToken as TransferSuiToken }; export const suiPlugin: Plugin = { name: "sui", description: "Sui Plugin for Eliza", - actions: [transferToken], + actions: [transferToken, buildPTB], evaluators: [], providers: [walletProvider], }; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6f0e904aa4..0f456ca6e0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -549,13 +549,13 @@ importers: version: link:../plugin-node '@discordjs/opus': specifier: github:discordjs/opus - version: https://codeload.github.com/discordjs/opus/tar.gz/31da49d8d2cc6c5a2ab1bfd332033ff7d5f9fb02(encoding@0.1.13) + version: git+https://git@github.com:discordjs/opus.git#31da49d8d2cc6c5a2ab1bfd332033ff7d5f9fb02(encoding@0.1.13) '@discordjs/rest': specifier: 2.4.0 version: 2.4.0 '@discordjs/voice': specifier: 0.17.0 - version: 0.17.0(@discordjs/opus@https://codeload.github.com/discordjs/opus/tar.gz/31da49d8d2cc6c5a2ab1bfd332033ff7d5f9fb02(encoding@0.1.13))(bufferutil@4.0.8)(ffmpeg-static@5.2.0)(utf-8-validate@5.0.10) + version: 0.17.0(@discordjs/opus@git+https://git@github.com:discordjs/opus.git#31da49d8d2cc6c5a2ab1bfd332033ff7d5f9fb02(encoding@0.1.13))(bufferutil@4.0.8)(ffmpeg-static@5.2.0)(utf-8-validate@5.0.10) discord.js: specifier: 14.16.3 version: 14.16.3(bufferutil@4.0.8)(utf-8-validate@5.0.10) @@ -564,7 +564,7 @@ importers: version: 0.7.15 prism-media: specifier: 1.3.5 - version: 1.3.5(@discordjs/opus@https://codeload.github.com/discordjs/opus/tar.gz/31da49d8d2cc6c5a2ab1bfd332033ff7d5f9fb02(encoding@0.1.13))(ffmpeg-static@5.2.0) + version: 1.3.5(@discordjs/opus@git+https://git@github.com:discordjs/opus.git#31da49d8d2cc6c5a2ab1bfd332033ff7d5f9fb02(encoding@0.1.13))(ffmpeg-static@5.2.0) whatwg-url: specifier: 7.1.0 version: 7.1.0 @@ -3417,8 +3417,8 @@ packages: resolution: {integrity: sha512-YJOVVZ545x24mHzANfYoy0BJX5PDyeZlpiJjDkUBM/V/Ao7TFX9lcUvCN4nr0tbr5ubeaXxtEBILUrHtTphVeQ==} hasBin: true - '@discordjs/opus@https://codeload.github.com/discordjs/opus/tar.gz/31da49d8d2cc6c5a2ab1bfd332033ff7d5f9fb02': - resolution: {tarball: https://codeload.github.com/discordjs/opus/tar.gz/31da49d8d2cc6c5a2ab1bfd332033ff7d5f9fb02} + '@discordjs/opus@git+https://git@github.com:discordjs/opus.git#31da49d8d2cc6c5a2ab1bfd332033ff7d5f9fb02': + resolution: {commit: 31da49d8d2cc6c5a2ab1bfd332033ff7d5f9fb02, repo: git@github.com:discordjs/opus.git, type: git} version: 0.9.0 engines: {node: '>=12.0.0'} @@ -21537,7 +21537,7 @@ snapshots: - encoding - supports-color - '@discordjs/opus@https://codeload.github.com/discordjs/opus/tar.gz/31da49d8d2cc6c5a2ab1bfd332033ff7d5f9fb02(encoding@0.1.13)': + '@discordjs/opus@git+https://git@github.com:discordjs/opus.git#31da49d8d2cc6c5a2ab1bfd332033ff7d5f9fb02(encoding@0.1.13)': dependencies: '@discordjs/node-pre-gyp': 0.4.5(encoding@0.1.13) node-addon-api: 8.3.0 @@ -21559,11 +21559,11 @@ snapshots: '@discordjs/util@1.1.1': {} - '@discordjs/voice@0.17.0(@discordjs/opus@https://codeload.github.com/discordjs/opus/tar.gz/31da49d8d2cc6c5a2ab1bfd332033ff7d5f9fb02(encoding@0.1.13))(bufferutil@4.0.8)(ffmpeg-static@5.2.0)(utf-8-validate@5.0.10)': + '@discordjs/voice@0.17.0(@discordjs/opus@git+https://git@github.com:discordjs/opus.git#31da49d8d2cc6c5a2ab1bfd332033ff7d5f9fb02(encoding@0.1.13))(bufferutil@4.0.8)(ffmpeg-static@5.2.0)(utf-8-validate@5.0.10)': dependencies: '@types/ws': 8.5.13 discord-api-types: 0.37.83 - prism-media: 1.3.5(@discordjs/opus@https://codeload.github.com/discordjs/opus/tar.gz/31da49d8d2cc6c5a2ab1bfd332033ff7d5f9fb02(encoding@0.1.13))(ffmpeg-static@5.2.0) + prism-media: 1.3.5(@discordjs/opus@git+https://git@github.com:discordjs/opus.git#31da49d8d2cc6c5a2ab1bfd332033ff7d5f9fb02(encoding@0.1.13))(ffmpeg-static@5.2.0) tslib: 2.8.1 ws: 8.18.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) transitivePeerDependencies: @@ -38456,9 +38456,9 @@ snapshots: pretty-time@1.1.0: {} - prism-media@1.3.5(@discordjs/opus@https://codeload.github.com/discordjs/opus/tar.gz/31da49d8d2cc6c5a2ab1bfd332033ff7d5f9fb02(encoding@0.1.13))(ffmpeg-static@5.2.0): + prism-media@1.3.5(@discordjs/opus@git+https://git@github.com:discordjs/opus.git#31da49d8d2cc6c5a2ab1bfd332033ff7d5f9fb02(encoding@0.1.13))(ffmpeg-static@5.2.0): optionalDependencies: - '@discordjs/opus': https://codeload.github.com/discordjs/opus/tar.gz/31da49d8d2cc6c5a2ab1bfd332033ff7d5f9fb02(encoding@0.1.13) + '@discordjs/opus': git+https://git@github.com:discordjs/opus.git#31da49d8d2cc6c5a2ab1bfd332033ff7d5f9fb02(encoding@0.1.13) ffmpeg-static: 5.2.0 prism-react-renderer@2.3.1(react@18.3.1): From 5f27d1329828d672553c7992772a83394cd666b5 Mon Sep 17 00:00:00 2001 From: astinz <28899947+astinz@users.noreply.github.com> Date: Tue, 24 Dec 2024 08:06:17 +0300 Subject: [PATCH 2/3] minor fix... --- packages/plugin-sui/src/actions/ptb.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/plugin-sui/src/actions/ptb.ts b/packages/plugin-sui/src/actions/ptb.ts index 661acada66..968bd22af0 100644 --- a/packages/plugin-sui/src/actions/ptb.ts +++ b/packages/plugin-sui/src/actions/ptb.ts @@ -11,7 +11,7 @@ import { Memory, ModelClass, State, -} from "@ai16z/eliza"; +} from "@elizaos/core"; const ArgSchema = z.union([ z.object({ From faa4d0c42447898831babcf68f34179c90e77544 Mon Sep 17 00:00:00 2001 From: astinz <28899947+astinz@users.noreply.github.com> Date: Sun, 5 Jan 2025 01:22:58 +0300 Subject: [PATCH 3/3] feat: extend telegram client multimedia support - default every other mediaType to document except audio, image, video --- .../client-telegram/src/messageManager.ts | 151 ++++++++++++------ 1 file changed, 102 insertions(+), 49 deletions(-) diff --git a/packages/client-telegram/src/messageManager.ts b/packages/client-telegram/src/messageManager.ts index bbf597232d..c1e96cbc4e 100644 --- a/packages/client-telegram/src/messageManager.ts +++ b/packages/client-telegram/src/messageManager.ts @@ -1,6 +1,7 @@ import { Message } from "@telegraf/types"; import { Context, Telegraf } from "telegraf"; -import { composeContext, elizaLogger, ServiceType, composeRandomUser } from "@elizaos/core"; + +import { composeContext, elizaLogger, ServiceType } from "@elizaos/core"; import { getEmbeddingZeroVector } from "@elizaos/core"; import { Content, @@ -18,7 +19,7 @@ import { stringToUuid } from "@elizaos/core"; import { generateMessageResponse, generateShouldRespond } from "@elizaos/core"; import { messageCompletionFooter, shouldRespondFooter } from "@elizaos/core"; -import { cosineSimilarity, escapeMarkdown } from "./utils"; +import { cosineSimilarity } from "./utils"; import { MESSAGE_CONSTANTS, TIMING_CONSTANTS, @@ -296,8 +297,8 @@ export class MessageManager { "text" in message ? message.text : "caption" in message - ? (message as any).caption - : ""; + ? (message as any).caption + : ""; if (!messageText) return false; @@ -359,8 +360,8 @@ export class MessageManager { "text" in message ? message.text : "caption" in message - ? (message as any).caption - : ""; + ? (message as any).caption + : ""; if (!messageText) return false; const isReplyToBot = @@ -375,7 +376,7 @@ export class MessageManager { isReplyToBot || isMentioned || (!this.runtime.character.clientConfig?.telegram - ?.shouldRespondOnlyToMentions && + ?.shouldRespondOnlyToMentions && hasUsername) ); } @@ -507,8 +508,8 @@ export class MessageManager { "text" in message ? message.text : "caption" in message - ? (message as any).caption - : ""; + ? (message as any).caption + : ""; // Check if team member has direct interest first if ( @@ -529,8 +530,8 @@ export class MessageManager { const randomDelay = Math.floor( Math.random() * - (TIMING_CONSTANTS.TEAM_MEMBER_DELAY_MAX - - TIMING_CONSTANTS.TEAM_MEMBER_DELAY_MIN) + (TIMING_CONSTANTS.TEAM_MEMBER_DELAY_MAX - + TIMING_CONSTANTS.TEAM_MEMBER_DELAY_MIN) ) + TIMING_CONSTANTS.TEAM_MEMBER_DELAY_MIN; // 1-3 second random delay await new Promise((resolve) => setTimeout(resolve, randomDelay) @@ -556,8 +557,8 @@ export class MessageManager { const leaderResponded = recentMessages.some( (m) => m.userId === - this.runtime.character.clientConfig?.telegram - ?.teamLeaderId && + this.runtime.character.clientConfig?.telegram + ?.teamLeaderId && Date.now() - chatState.lastMessageSent < 3000 ); @@ -578,8 +579,8 @@ export class MessageManager { const randomDelay = Math.floor( Math.random() * - (TIMING_CONSTANTS.LEADER_DELAY_MAX - - TIMING_CONSTANTS.LEADER_DELAY_MIN) + (TIMING_CONSTANTS.LEADER_DELAY_MAX - + TIMING_CONSTANTS.LEADER_DELAY_MIN) ) + TIMING_CONSTANTS.LEADER_DELAY_MIN; // 2-4 second random delay await new Promise((resolve) => setTimeout(resolve, randomDelay) @@ -617,7 +618,7 @@ export class MessageManager { if (chatState?.currentHandler) { if ( chatState.currentHandler !== - this.bot.botInfo?.id.toString() && + this.bot.botInfo?.id.toString() && this._isTeamMember(chatState.currentHandler) ) { return false; @@ -628,7 +629,7 @@ export class MessageManager { if (!this._isMessageForMe(message) && this.interestChats[chatId]) { const recentMessages = this.interestChats[ chatId - ].messages.slice(-MESSAGE_CONSTANTS.CHAT_HISTORY_COUNT); + ].messages.slice(-MESSAGE_CONSTANTS.CHAT_HISTORY_COUNT); const ourMessageCount = recentMessages.filter( (m) => m.userId === this.runtime.agentId ).length; @@ -660,7 +661,7 @@ export class MessageManager { this.runtime.character.templates ?.telegramShouldRespondTemplate || this.runtime.character?.templates?.shouldRespondTemplate || - composeRandomUser(telegramShouldRespondTemplate, 2), + telegramShouldRespondTemplate, }); const response = await generateShouldRespond({ @@ -684,7 +685,17 @@ export class MessageManager { if (content.attachments && content.attachments.length > 0) { content.attachments.map(async (attachment: Media) => { if (attachment.contentType.startsWith("image")) { - this.sendImage(ctx, attachment.url, attachment.description); + await this.sendImage(ctx, attachment.url, attachment.description); + } else if (attachment.contentType.startsWith("doc")) { + await this.sendDocument( + ctx, + attachment.url, + attachment.description + ); + } else if (attachment.contentType.startsWith("video")) { + await this.sendVideo(ctx, attachment.url, attachment.description); + } else if (attachment.contentType.startsWith("audio")) { + await this.sendAudio(ctx, attachment.url, attachment.description); } }); } else { @@ -692,7 +703,7 @@ export class MessageManager { const sentMessages: Message.TextMessage[] = []; for (let i = 0; i < chunks.length; i++) { - const chunk = escapeMarkdown(chunks[i]); + const chunk = chunks[i]; const sentMessage = (await ctx.telegram.sendMessage( ctx.chat.id, chunk, @@ -712,42 +723,84 @@ export class MessageManager { } } - private async sendImage( + private async sendMedia( ctx: Context, - imagePath: string, + mediaPath: string, + type: "photo" | "video" | "document" | "audio", caption?: string ): Promise { try { - if (/^(http|https):\/\//.test(imagePath)) { + const isUrl = /^(http|https):\/\//.test(mediaPath); + const sendFunctionMap = { + photo: ctx.telegram.sendPhoto.bind(ctx.telegram), + video: ctx.telegram.sendVideo.bind(ctx.telegram), + document: ctx.telegram.sendDocument.bind(ctx.telegram), + audio: ctx.telegram.sendAudio.bind(ctx.telegram), + }; + + if (!sendFunctionMap[type]) { + throw new Error(`Unsupported media type: ${type}`); + } + + const sendFunction = sendFunctionMap[type]; + + if (isUrl) { // Handle HTTP URLs - await ctx.telegram.sendPhoto(ctx.chat.id, imagePath, { - caption, - }); + await sendFunction(ctx.chat.id, mediaPath, { caption }); } else { // Handle local file paths - if (!fs.existsSync(imagePath)) { - throw new Error(`File not found: ${imagePath}`); + if (!fs.existsSync(mediaPath)) { + throw new Error(`File not found: ${mediaPath}`); } - const fileStream = fs.createReadStream(imagePath); - - await ctx.telegram.sendPhoto( + const fileStream = fs.createReadStream(mediaPath); + await sendFunction( ctx.chat.id, - { - source: fileStream, - }, - { - caption, - } + { source: fileStream }, + { caption } ); } - elizaLogger.info(`Image sent successfully: ${imagePath}`); + elizaLogger.info( + `${type.charAt(0).toUpperCase() + type.slice(1)} sent successfully: ${mediaPath}` + ); } catch (error) { - elizaLogger.error("Error sending image:", error); + elizaLogger.error(`Error sending ${type}:`, error); } } + private async sendImage( + ctx: Context, + imagePath: string, + caption?: string + ): Promise { + await this.sendMedia(ctx, imagePath, "photo", caption); + } + + private async sendVideo( + ctx: Context, + videoPath: string, + caption?: string + ): Promise { + await this.sendMedia(ctx, videoPath, "video", caption); + } + + private async sendDocument( + ctx: Context, + documentPath: string, + caption?: string + ): Promise { + await this.sendMedia(ctx, documentPath, "document", caption); + } + + private async sendAudio( + ctx: Context, + audioPath: string, + caption?: string + ): Promise { + await this.sendMedia(ctx, audioPath, "audio", caption); + } + // Split message into smaller parts private splitMessage(text: string): string[] { const chunks: string[] = []; @@ -823,8 +876,8 @@ export class MessageManager { "text" in message ? message.text : "caption" in message - ? (message as any).caption - : ""; + ? (message as any).caption + : ""; // Add team handling at the start if ( @@ -914,7 +967,7 @@ export class MessageManager { if ( hasInterest || this.interestChats[chatId]?.currentHandler === - this.bot.botInfo?.id.toString() + this.bot.botInfo?.id.toString() ) { delete this.interestChats[chatId]; @@ -953,7 +1006,7 @@ export class MessageManager { ) { this.interestChats[chatId].messages = this.interestChats[ chatId - ].messages.slice(-MESSAGE_CONSTANTS.MAX_MESSAGES); + ].messages.slice(-MESSAGE_CONSTANTS.MAX_MESSAGES); } } } @@ -1018,10 +1071,10 @@ export class MessageManager { inReplyTo: "reply_to_message" in message && message.reply_to_message ? stringToUuid( - message.reply_to_message.message_id.toString() + - "-" + - this.runtime.agentId - ) + message.reply_to_message.message_id.toString() + + "-" + + this.runtime.agentId + ) : undefined, }; @@ -1084,8 +1137,8 @@ export class MessageManager { const memory: Memory = { id: stringToUuid( sentMessage.message_id.toString() + - "-" + - this.runtime.agentId + "-" + + this.runtime.agentId ), agentId, userId: agentId,