diff --git a/packages/client-discord/src/messages.ts b/packages/client-discord/src/messages.ts index 1ca673f948..f6778564fe 100644 --- a/packages/client-discord/src/messages.ts +++ b/packages/client-discord/src/messages.ts @@ -1,4 +1,4 @@ -import { composeContext } from "@elizaos/core"; +import { composeContext, composeRandomUser } from "@elizaos/core"; import { generateMessageResponse, generateShouldRespond } from "@elizaos/core"; import { Content, @@ -1228,7 +1228,7 @@ export class MessageManager { this.runtime.character.templates ?.discordShouldRespondTemplate || this.runtime.character.templates?.shouldRespondTemplate || - discordShouldRespondTemplate, + composeRandomUser(discordShouldRespondTemplate, 2), }); const response = await generateShouldRespond({ diff --git a/packages/client-discord/src/templates.ts b/packages/client-discord/src/templates.ts index 0fea262016..46d3f2333a 100644 --- a/packages/client-discord/src/templates.ts +++ b/packages/client-discord/src/templates.ts @@ -8,48 +8,48 @@ About {{agentName}}: # INSTRUCTIONS: Determine if {{agentName}} should respond to the message and participate in the conversation. Do not comment. Just respond with "RESPOND" or "IGNORE" or "STOP". # RESPONSE EXAMPLES -: I just saw a really great movie -: Oh? Which movie? +{{user1}}: I just saw a really great movie +{{user2}}: Oh? Which movie? Result: [IGNORE] {{agentName}}: Oh, this is my favorite scene -: sick -: wait, why is it your favorite scene +{{user1}}: sick +{{user2}}: wait, why is it your favorite scene Result: [RESPOND] -: stfu bot +{{user1}}: stfu bot Result: [STOP] -: Hey {{agent}}, can you help me with something +{{user1}}: Hey {{agent}}, can you help me with something Result: [RESPOND] -: {{agentName}} stfu plz +{{user1}}: {{agentName}} stfu plz Result: [STOP] -: i need help +{{user1}}: i need help {{agentName}}: how can I help you? -: no. i need help from someone else +{{user1}}: no. i need help from someone else Result: [IGNORE] -: Hey {{agent}}, can I ask you a question +{{user1}}: Hey {{agent}}, can I ask you a question {{agentName}}: Sure, what is it -: can you ask claude to create a basic react module that demonstrates a counter +{{user1}}: can you ask claude to create a basic react module that demonstrates a counter Result: [RESPOND] -: {{agentName}} can you tell me a story -: {about a girl named elara +{{user1}}: {{agentName}} can you tell me a story +{{user1}}: about a girl named elara {{agentName}}: Sure. {{agentName}}: Once upon a time, in a quaint little village, there was a curious girl named Elara. {{agentName}}: Elara was known for her adventurous spirit and her knack for finding beauty in the mundane. -: I'm loving it, keep going +{{user1}}: I'm loving it, keep going Result: [RESPOND] -: {{agentName}} stop responding plz +{{user1}}: {{agentName}} stop responding plz Result: [STOP] -: okay, i want to test something. can you say marco? +{{user1}}: okay, i want to test something. can you say marco? {{agentName}}: marco -: great. okay, now do it again +{{user1}}: great. okay, now do it again Result: [RESPOND] Response options are [RESPOND], [IGNORE] and [STOP]. diff --git a/packages/client-discord/src/voice.ts b/packages/client-discord/src/voice.ts index 85c14c03ed..036806f610 100644 --- a/packages/client-discord/src/voice.ts +++ b/packages/client-discord/src/voice.ts @@ -8,6 +8,7 @@ import { State, UUID, composeContext, + composeRandomUser, elizaLogger, getEmbeddingZeroVector, generateMessageResponse, @@ -840,7 +841,7 @@ export class VoiceManager extends EventEmitter { this.runtime.character.templates ?.discordShouldRespondTemplate || this.runtime.character.templates?.shouldRespondTemplate || - discordShouldRespondTemplate, + composeRandomUser(discordShouldRespondTemplate, 2), }); const response = await generateShouldRespond({ diff --git a/packages/client-telegram/src/messageManager.ts b/packages/client-telegram/src/messageManager.ts index 850f2f3bf6..3450ca853f 100644 --- a/packages/client-telegram/src/messageManager.ts +++ b/packages/client-telegram/src/messageManager.ts @@ -1,7 +1,6 @@ import { Message } from "@telegraf/types"; import { Context, Telegraf } from "telegraf"; - -import { composeContext, elizaLogger, ServiceType } from "@elizaos/core"; +import { composeContext, elizaLogger, ServiceType, composeRandomUser } from "@elizaos/core"; import { getEmbeddingZeroVector } from "@elizaos/core"; import { Content, @@ -661,7 +660,7 @@ export class MessageManager { this.runtime.character.templates ?.telegramShouldRespondTemplate || this.runtime.character?.templates?.shouldRespondTemplate || - telegramShouldRespondTemplate, + composeRandomUser(telegramShouldRespondTemplate, 2), }); const response = await generateShouldRespond({ diff --git a/packages/core/src/context.ts b/packages/core/src/context.ts index 190a876edd..a682e6794c 100644 --- a/packages/core/src/context.ts +++ b/packages/core/src/context.ts @@ -1,5 +1,6 @@ import handlebars from "handlebars"; import { type State } from "./types.ts"; +import { names, uniqueNamesGenerator } from "unique-names-generator"; /** * Composes a context string by replacing placeholders in a template with corresponding values from the state. @@ -69,3 +70,35 @@ export const composeContext = ({ export const addHeader = (header: string, body: string) => { return body.length > 0 ? `${header ? header + "\n" : header}${body}\n` : ""; }; + +/** + * Generates a string with random user names populated in a template. + * + * This function generates a specified number of random user names and populates placeholders + * in the provided template with these names. Placeholders in the template should follow the format `{{userX}}` + * where `X` is the position of the user (e.g., `{{user1}}`, `{{user2}}`). + * + * @param {string} params.template - The template string containing placeholders for random user names. + * @param {number} params.length - The number of random user names to generate. + * @returns {string} The template string with placeholders replaced by random user names. + * + * @example + * // Given a template and a length + * const template = "Hello, {{user1}}! Meet {{user2}} and {{user3}}."; + * const length = 3; + * + * // Composing the random user string will result in: + * // "Hello, John! Meet Alice and Bob." + * const result = composeRandomUser({ template, length }); + */ +export const composeRandomUser = (template: string, length: number) => { + const exampleNames = Array.from({ length }, () => + uniqueNamesGenerator({ dictionaries: [names] }) + ); + let result = template; + for (let i = 0; i < exampleNames.length; i++) { + result = result.replaceAll(`{{user${i + 1}}}`, exampleNames[i]); + } + + return result; +};