@elizaos/plugin-farcaster 1.0.2 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/service.ts","../src/common/constants.ts","../src/managers/agent.ts","../src/client.ts","../src/common/utils.ts","../src/managers/interactions.ts","../src/common/asyncqueue.ts","../src/common/callbacks.ts","../src/common/prompts.ts","../src/common/types.ts","../src/managers/post.ts","../src/common/config.ts","../__tests__/suite.ts","../__tests__/test-utils.ts","../src/index.ts"],"sourcesContent":["import { logger, Service, UUID, type IAgentRuntime } from '@elizaos/core';\nimport { FARCASTER_SERVICE_NAME } from './common/constants';\nimport { FarcasterAgentManager } from './managers/agent';\nimport { hasFarcasterEnabled, validateFarcasterConfig } from './common/config';\n\nexport class FarcasterService extends Service {\n private static instance?: FarcasterService;\n private managers = new Map<UUID, FarcasterAgentManager>();\n static serviceType: string = FARCASTER_SERVICE_NAME;\n readonly capabilityDescription = 'The agent is able to send and receive messages on farcaster';\n\n private static getInstance(): FarcasterService {\n if (!FarcasterService.instance) {\n FarcasterService.instance = new FarcasterService();\n }\n return FarcasterService.instance;\n }\n\n // Called to start a single Farcaster service\n static async start(runtime: IAgentRuntime): Promise<Service> {\n const service = FarcasterService.getInstance();\n let manager = service.managers.get(runtime.agentId);\n\n if (manager) {\n logger.warn('Farcaster service already started', runtime.agentId);\n return service;\n }\n\n if (!hasFarcasterEnabled(runtime)) {\n logger.debug('Farcaster service not enabled', runtime.agentId);\n return service;\n }\n\n const farcasterConfig = validateFarcasterConfig(runtime);\n manager = new FarcasterAgentManager(runtime, farcasterConfig);\n service.managers.set(runtime.agentId, manager);\n await manager.start();\n\n logger.success('Farcaster client started', runtime.agentId);\n return service;\n }\n\n // Called to stop a single Farcaster service\n static async stop(runtime: IAgentRuntime): Promise<void> {\n const service = FarcasterService.getInstance();\n let manager = service.managers.get(runtime.agentId);\n if (manager) {\n await manager.stop();\n service.managers.delete(runtime.agentId);\n logger.info('Farcaster client stopped', runtime.agentId);\n } else {\n logger.debug('Farcaster service not running', runtime.agentId);\n }\n }\n\n // Called to stop all Farcaster services\n async stop(): Promise<void> {\n logger.debug('Stopping ALL Farcaster services');\n for (const manager of Array.from(this.managers.values())) {\n const agentId = manager.runtime.agentId;\n try {\n await FarcasterService.stop(manager.runtime);\n } catch (error) {\n logger.error('Error stopping Farcaster service', agentId, error);\n }\n }\n }\n}\n","export const FARCASTER_SERVICE_NAME = 'farcaster';\nexport const FARCASTER_SOURCE = 'farcaster';\nexport const DEFAULT_MAX_CAST_LENGTH = 320;\nexport const DEFAULT_POLL_INTERVAL = 120; // 2 minutes\nexport const DEFAULT_POST_INTERVAL_MIN = 90; // 1.5 hours\nexport const DEFAULT_POST_INTERVAL_MAX = 180; // 3 hours\nexport const DEFAULT_CAST_CACHE_TTL = 1000 * 30 * 60; // 30 minutes\nexport const DEFAULT_CAST_CACHE_SIZE = 9000;\n","import { logger, type IAgentRuntime } from '@elizaos/core';\nimport { Configuration, NeynarAPIClient } from '@neynar/nodejs-sdk';\nimport { FarcasterClient } from '../client';\nimport { type FarcasterConfig } from '../common/types';\nimport { FarcasterInteractionManager } from './interactions';\nimport { FarcasterPostManager } from './post';\n\n/**\n * A manager that orchestrates all Farcaster operations:\n * - client: base operations (Neynar client, hub connection, etc.)\n * - posts: autonomous posting logic\n * - interactions: handling mentions, replies, likes, etc.\n */\nexport class FarcasterAgentManager {\n readonly runtime: IAgentRuntime;\n readonly client: FarcasterClient;\n readonly posts: FarcasterPostManager;\n readonly interactions: FarcasterInteractionManager;\n\n constructor(runtime: IAgentRuntime, config: FarcasterConfig) {\n this.runtime = runtime;\n const signerUuid = config.FARCASTER_NEYNAR_SIGNER_UUID;\n\n const neynarConfig = new Configuration({ apiKey: config.FARCASTER_NEYNAR_API_KEY });\n\n const neynar = new NeynarAPIClient(neynarConfig);\n\n const client = new FarcasterClient({ neynar, signerUuid });\n\n this.client = client;\n\n logger.success('Farcaster Neynar client initialized.');\n\n this.posts = new FarcasterPostManager({ client, runtime, config });\n\n this.interactions = new FarcasterInteractionManager({ client, runtime, config });\n }\n\n async start() {\n await Promise.all([this.posts.start(), this.interactions.start()]);\n }\n\n async stop() {\n await Promise.all([this.posts.stop(), this.interactions.stop()]);\n }\n}\n","import { Content, elizaLogger } from '@elizaos/core';\nimport { type NeynarAPIClient, isApiErrorResponse } from '@neynar/nodejs-sdk';\nimport { CastParamType } from '@neynar/nodejs-sdk/build/api/models/cast-param-type';\nimport { CastWithInteractions } from '@neynar/nodejs-sdk/build/api/models/cast-with-interactions';\nimport { LRUCache } from 'lru-cache';\nimport { DEFAULT_CAST_CACHE_SIZE, DEFAULT_CAST_CACHE_TTL } from './common/constants';\nimport type { Cast, CastId, FidRequest, Profile } from './common/types';\nimport { neynarCastToCast, splitPostContent } from './common/utils';\n\n// add global cast cache\nconst castCache: LRUCache<string, CastWithInteractions> = new LRUCache({\n max: DEFAULT_CAST_CACHE_SIZE,\n ttl: DEFAULT_CAST_CACHE_TTL,\n});\n\n// add global profile cache\nconst profileCache: LRUCache<number, Profile> = new LRUCache({\n max: 1000,\n ttl: 1000 * 60 * 15, // 15 minutes\n});\n\nexport class FarcasterClient {\n private neynar: NeynarAPIClient;\n private signerUuid: string;\n constructor(opts: { neynar: NeynarAPIClient; signerUuid: string }) {\n this.neynar = opts.neynar;\n this.signerUuid = opts.signerUuid;\n }\n\n async sendCast({\n content,\n inReplyTo,\n }: {\n content: Content;\n inReplyTo?: CastId;\n }): Promise<CastWithInteractions[]> {\n const text = (content.text ?? '').trim();\n if (text.length === 0) {\n return [];\n }\n\n const chunks = splitPostContent(text);\n const sent: CastWithInteractions[] = [];\n\n for (const chunk of chunks) {\n const result = await this.publishCast(chunk, inReplyTo);\n sent.push(result);\n }\n return sent;\n }\n\n private async publishCast(cast: string, parentCastId?: CastId): Promise<CastWithInteractions> {\n try {\n const result = await this.neynar.publishCast({\n signerUuid: this.signerUuid,\n text: cast,\n parent: parentCastId?.hash,\n });\n if (result.success) {\n return this.getCast(result.cast.hash);\n }\n throw new Error(`[Farcaster] Error publishing [${cast}] parentCastId: [${parentCastId}]`);\n } catch (err) {\n if (isApiErrorResponse(err)) {\n elizaLogger.error('Neynar error: ', err.response.data);\n throw err.response.data;\n } else {\n elizaLogger.error('Error: ', err);\n throw err;\n }\n }\n }\n\n async getCast(castHash: string): Promise<CastWithInteractions> {\n const cachedCast = castCache.get(castHash);\n if (cachedCast) {\n return cachedCast;\n }\n\n const params = { identifier: castHash, type: CastParamType.Hash };\n const response = await this.neynar.lookupCastByHashOrWarpcastUrl(params);\n\n castCache.set(castHash, response.cast);\n\n return response.cast;\n }\n async getMentions(request: FidRequest): Promise<CastWithInteractions[]> {\n const neynarMentionsResponse = await this.neynar.fetchAllNotifications({\n fid: request.fid,\n type: ['mentions', 'replies'],\n limit: request.pageSize,\n });\n const mentions: CastWithInteractions[] = [];\n\n for (const notification of neynarMentionsResponse.notifications) {\n const neynarCast = notification.cast;\n if (neynarCast) {\n mentions.push(neynarCast);\n }\n }\n\n return mentions;\n }\n\n async getProfile(fid: number): Promise<Profile> {\n if (profileCache.has(fid)) {\n return profileCache.get(fid) as Profile;\n }\n\n try {\n const result = await this.neynar.fetchBulkUsers({ fids: [fid] });\n if (!result.users || result.users.length < 1) {\n elizaLogger.error('Error fetching user by fid');\n throw new Error('Profile fetch failed');\n }\n\n const neynarUserProfile = result.users[0];\n\n const profile: Profile = {\n fid,\n name: '',\n username: '',\n };\n\n profile.name = neynarUserProfile.display_name!;\n profile.username = neynarUserProfile.username;\n profile.bio = neynarUserProfile.profile.bio.text;\n profile.pfp = neynarUserProfile.pfp_url;\n\n profileCache.set(fid, profile);\n\n return profile;\n } catch (error) {\n elizaLogger.error('Error fetching profile:', error);\n throw error;\n }\n }\n\n async getTimeline(request: FidRequest): Promise<{\n timeline: Cast[];\n cursor?: string;\n }> {\n const timeline: Cast[] = [];\n\n const response = await this.neynar.fetchCastsForUser({\n fid: request.fid,\n limit: request.pageSize,\n });\n\n for (const cast of response.casts) {\n castCache.set(cast.hash, cast);\n timeline.push(neynarCastToCast(cast));\n }\n\n const nextCursor = response.next?.cursor ?? undefined;\n\n return {\n timeline,\n cursor: nextCursor,\n };\n }\n\n clearCache(): void {\n profileCache.clear();\n castCache.clear();\n }\n}\n","import { IAgentRuntime, Memory, stringToUuid, UUID } from '@elizaos/core';\nimport { CastWithInteractions } from '@neynar/nodejs-sdk/build/api';\nimport { FARCASTER_SOURCE } from './constants';\nimport { Cast } from './types';\n\nexport const MAX_CAST_LENGTH = 1024; // Updated to Twitter's current character limit\n\nexport function castId({ hash, agentId }: { hash: string; agentId: string }) {\n return `${hash}-${agentId}`;\n}\n\nexport function castUuid(props: { hash: string; agentId: string }) {\n return stringToUuid(castId(props));\n}\n\nexport function splitPostContent(content: string, maxLength: number = MAX_CAST_LENGTH): string[] {\n const paragraphs = content.split('\\n\\n').map((p) => p.trim());\n const posts: string[] = [];\n let currentTweet = '';\n\n for (const paragraph of paragraphs) {\n if (!paragraph) continue;\n\n if ((currentTweet + '\\n\\n' + paragraph).trim().length <= maxLength) {\n if (currentTweet) {\n currentTweet += '\\n\\n' + paragraph;\n } else {\n currentTweet = paragraph;\n }\n } else {\n if (currentTweet) {\n posts.push(currentTweet.trim());\n }\n if (paragraph.length <= maxLength) {\n currentTweet = paragraph;\n } else {\n // Split long paragraph into smaller chunks\n const chunks = splitParagraph(paragraph, maxLength);\n posts.push(...chunks.slice(0, -1));\n currentTweet = chunks[chunks.length - 1];\n }\n }\n }\n\n if (currentTweet) {\n posts.push(currentTweet.trim());\n }\n\n return posts;\n}\n\nexport function splitParagraph(paragraph: string, maxLength: number): string[] {\n const sentences = paragraph.match(/[^.!?]+[.!?]+|[^.!?]+$/g) || [paragraph];\n const chunks: string[] = [];\n let currentChunk = '';\n\n for (const sentence of sentences) {\n if ((currentChunk + ' ' + sentence).trim().length <= maxLength) {\n if (currentChunk) {\n currentChunk += ' ' + sentence;\n } else {\n currentChunk = sentence;\n }\n } else {\n if (currentChunk) {\n chunks.push(currentChunk.trim());\n }\n if (sentence.length <= maxLength) {\n currentChunk = sentence;\n } else {\n // Split long sentence into smaller pieces\n const words = sentence.split(' ');\n currentChunk = '';\n for (const word of words) {\n if ((currentChunk + ' ' + word).trim().length <= maxLength) {\n if (currentChunk) {\n currentChunk += ' ' + word;\n } else {\n currentChunk = word;\n }\n } else {\n if (currentChunk) {\n chunks.push(currentChunk.trim());\n }\n currentChunk = word;\n }\n }\n }\n }\n }\n\n if (currentChunk) {\n chunks.push(currentChunk.trim());\n }\n\n return chunks;\n}\n\nexport function lastCastCacheKey(fid: number) {\n return `farcaster/${fid}/lastCast`;\n}\n\nexport function neynarCastToCast(neynarCast: CastWithInteractions): Cast {\n return {\n hash: neynarCast.hash,\n authorFid: neynarCast.author.fid,\n text: neynarCast.text,\n threadId: neynarCast.thread_hash ?? undefined,\n profile: {\n fid: neynarCast.author.fid,\n name: neynarCast.author.display_name || 'anon',\n username: neynarCast.author.username,\n },\n ...(neynarCast.parent_hash\n ? {\n inReplyTo: {\n hash: neynarCast.parent_hash,\n fid: neynarCast.parent_author.fid,\n },\n }\n : {}),\n timestamp: new Date(neynarCast.timestamp),\n };\n}\n\nexport function createCastMemory({\n roomId,\n senderId,\n runtime,\n cast,\n}: {\n roomId: UUID;\n senderId: UUID;\n runtime: IAgentRuntime;\n cast: Cast;\n}): Memory {\n const inReplyTo = cast.inReplyTo\n ? castUuid({\n hash: cast.inReplyTo.hash,\n agentId: runtime.agentId,\n })\n : undefined;\n\n return {\n id: castUuid({\n hash: cast.hash,\n agentId: runtime.agentId,\n }),\n agentId: runtime.agentId,\n entityId: senderId,\n content: {\n text: cast.text,\n source: FARCASTER_SOURCE,\n url: '',\n inReplyTo,\n hash: cast.hash,\n threadId: cast.threadId,\n },\n roomId,\n };\n}\n\nexport function formatCastTimestamp(timestamp: Date): string {\n return timestamp.toLocaleString('en-US', {\n hour: '2-digit',\n minute: '2-digit',\n month: 'short',\n day: 'numeric',\n });\n}\n","import {\n ChannelType,\n composePrompt,\n Content,\n createUniqueUuid,\n EventType,\n type IAgentRuntime,\n logger,\n type Memory,\n MessagePayload,\n ModelType,\n UUID,\n} from '@elizaos/core';\nimport { CastWithInteractions } from '@neynar/nodejs-sdk/build/api';\nimport type { FarcasterClient } from '../client';\nimport { AsyncQueue } from '../common/asyncqueue';\nimport { standardCastHandlerCallback } from '../common/callbacks';\nimport { FARCASTER_SOURCE } from '../common/constants';\nimport { formatCast, formatTimeline } from '../common/prompts';\nimport { shouldRespondTemplate } from '@elizaos/core';\nimport {\n type Cast,\n type FarcasterConfig,\n FarcasterEventTypes,\n FarcasterGenericCastPayload,\n type Profile,\n} from '../common/types';\nimport { castUuid, formatCastTimestamp, neynarCastToCast } from '../common/utils';\ninterface FarcasterInteractionParams {\n client: FarcasterClient;\n runtime: IAgentRuntime;\n config: FarcasterConfig;\n}\n\nexport class FarcasterInteractionManager {\n private timeout: ReturnType<typeof setTimeout> | undefined;\n private isRunning: boolean = false;\n private client: FarcasterClient;\n private runtime: IAgentRuntime;\n private config: FarcasterConfig;\n\n private asyncQueue: AsyncQueue;\n\n constructor(opts: FarcasterInteractionParams) {\n this.client = opts.client;\n this.runtime = opts.runtime;\n this.config = opts.config;\n this.asyncQueue = new AsyncQueue(1);\n }\n\n public async start(): Promise<void> {\n logger.info('Starting Farcaster interactions');\n if (this.isRunning) {\n return;\n }\n\n this.isRunning = true;\n\n // never await this, it will block forever\n void this.runPeriodically();\n }\n\n public async stop(): Promise<void> {\n if (this.timeout) clearTimeout(this.timeout);\n this.isRunning = false;\n }\n\n private async runPeriodically(): Promise<void> {\n while (this.isRunning) {\n try {\n await this.handleInteractions();\n\n // now sleep for the configured interval\n const delay = this.config.FARCASTER_POLL_INTERVAL * 1000;\n await new Promise((resolve) => (this.timeout = setTimeout(resolve, delay)));\n } catch (error) {\n logger.error('[Farcaster] Error in periodic interactions:', this.runtime.agentId, error);\n }\n }\n }\n\n private async ensureCastConnection(cast: Cast): Promise<Memory> {\n return await this.asyncQueue.submit(async () => {\n const memoryId = castUuid({ agentId: this.runtime.agentId, hash: cast.hash });\n const conversationId = cast.threadId ?? cast.inReplyTo?.hash ?? cast.hash;\n const entityId = createUniqueUuid(this.runtime, cast.authorFid.toString());\n const worldId = createUniqueUuid(this.runtime, cast.authorFid.toString());\n const serverId = cast.authorFid.toString();\n const roomId = createUniqueUuid(this.runtime, conversationId);\n\n if (entityId !== this.runtime.agentId) {\n await this.runtime.ensureConnection({\n entityId,\n roomId,\n worldName: `${cast.profile.username}'s Farcaster`,\n userName: cast.profile.username,\n name: cast.profile.name,\n source: FARCASTER_SOURCE,\n type: ChannelType.THREAD,\n channelId: conversationId,\n serverId,\n worldId,\n metadata: {\n ownership: { ownerId: cast.authorFid.toString() },\n farcaster: {\n username: cast.profile.username,\n id: cast.authorFid.toString(),\n name: cast.profile.name,\n },\n },\n });\n }\n\n const memory: Memory = {\n id: memoryId,\n agentId: this.runtime.agentId,\n content: {\n text: cast.text,\n // need to pull imageUrls\n inReplyTo: cast.inReplyTo?.hash\n ? castUuid({ agentId: this.runtime.agentId, hash: cast.inReplyTo.hash })\n : undefined,\n source: FARCASTER_SOURCE,\n channelType: ChannelType.THREAD,\n },\n entityId,\n roomId,\n createdAt: cast.timestamp.getTime(),\n };\n\n // no need to store the memory as it'll be stored in bootstrap side\n\n return memory;\n });\n }\n\n private async handleInteractions(): Promise<void> {\n const agentFid = this.config.FARCASTER_FID;\n const [mentions, agent] = await Promise.all([\n this.client.getMentions({\n fid: agentFid,\n pageSize: 20,\n }),\n this.client.getProfile(agentFid),\n ]);\n\n for (const cast of mentions) {\n const mention = neynarCastToCast(cast);\n const memoryId = castUuid({ agentId: this.runtime.agentId, hash: mention.hash });\n\n if (await this.runtime.getMemoryById(memoryId)) {\n continue;\n }\n\n logger.info('New Cast found', mention.hash);\n\n // filter out the agent mentions\n if (mention.authorFid === agentFid) {\n const memory = await this.ensureCastConnection(mention);\n await this.runtime.addEmbeddingToMemory(memory);\n await this.runtime.createMemory(memory, 'messages');\n continue;\n }\n\n await this.handleMentionCast({ agent, mention, cast });\n }\n }\n\n async buildThreadForCast(cast: Cast, skipMemoryId: Set<UUID>): Promise<Cast[]> {\n const thread: Cast[] = [];\n const visited: Set<string> = new Set();\n const client = this.client;\n const runtime = this.runtime;\n const self = this;\n\n async function processThread(currentCast: Cast) {\n const memoryId = castUuid({ hash: currentCast.hash, agentId: runtime.agentId });\n\n if (visited.has(currentCast.hash) || skipMemoryId.has(memoryId)) {\n return;\n }\n\n visited.add(currentCast.hash);\n\n // Check if the current cast has already been saved\n const memory = await runtime.getMemoryById(memoryId);\n\n if (!memory) {\n logger.info('Creating memory for cast', currentCast.hash);\n const memory = await self.ensureCastConnection(currentCast);\n await runtime.createMemory(memory, 'messages');\n runtime.emitEvent(FarcasterEventTypes.THREAD_CAST_CREATED, {\n runtime,\n memory,\n cast: currentCast,\n source: FARCASTER_SOURCE,\n });\n }\n\n thread.unshift(currentCast);\n\n if (currentCast.inReplyTo) {\n const parentCast = await client.getCast(currentCast.inReplyTo.hash);\n await processThread(neynarCastToCast(parentCast));\n }\n }\n\n await processThread(cast);\n return thread;\n }\n\n private async handleMentionCast({\n agent,\n mention,\n cast,\n }: {\n agent: Profile;\n cast: CastWithInteractions;\n mention: Cast;\n }): Promise<void> {\n if (mention.profile.fid === agent.fid) {\n logger.info('skipping cast from bot itself', mention.hash);\n return;\n }\n\n // Process one at a time to ensure proper sequencing\n const memory = await this.ensureCastConnection(mention);\n const thread: Cast[] = await this.buildThreadForCast(\n mention,\n memory.id ? new Set([memory.id]) : new Set()\n );\n\n if (!memory.content.text || memory.content.text.trim() === '') {\n logger.info('skipping cast with no text', mention.hash);\n return;\n }\n\n // Build the state for the prompt\n const currentPost = formatCast(mention);\n const { timeline } = await this.client.getTimeline({ fid: agent.fid, pageSize: 20 });\n const formattedTimeline = formatTimeline(this.runtime.character, timeline);\n const formattedConversation = thread\n .map((c) =>\n `\n - @${c.profile.username} (${formatCastTimestamp(c.timestamp)}):\n ${c.text}`.trim()\n )\n .join('\\n\\n');\n\n const state = await this.runtime.composeState(memory);\n state.values = {\n ...state.values,\n farcasterUsername: agent.username,\n timeline: formattedTimeline,\n currentPost,\n formattedConversation,\n };\n\n // Determine if we should respond to the cast\n const shouldRespondPrompt = composePrompt({\n state,\n template:\n this.runtime.character.templates?.farcasterShouldRespondTemplate ||\n this.runtime.character?.templates?.shouldRespondTemplate ||\n shouldRespondTemplate,\n });\n\n const response = await this.runtime.useModel(ModelType.TEXT_SMALL, {\n prompt: shouldRespondPrompt,\n });\n\n const responseActions = (response.match(/(?:RESPOND|IGNORE|STOP)/g) || ['IGNORE'])[0];\n if (responseActions !== 'RESPOND') {\n logger.info(`Not responding to cast based on shouldRespond decision: ${responseActions}`);\n try {\n // save the memory so we don't process it again in mentions\n await this.runtime.createMemory(memory, 'messages');\n } catch (error) {\n logger.error('Error creating ignoredmemory', error);\n }\n return;\n }\n\n // setup callback for the response\n const callback = standardCastHandlerCallback({\n client: this.client,\n runtime: this.runtime,\n config: this.config,\n roomId: memory.roomId,\n inReplyTo: {\n hash: mention.hash,\n fid: mention.authorFid,\n },\n });\n\n // Emit generic message received events\n const messageReceivedPayload: MessagePayload = {\n runtime: this.runtime,\n message: memory,\n source: FARCASTER_SOURCE,\n callback,\n };\n\n this.runtime.emitEvent(EventType.MESSAGE_RECEIVED, messageReceivedPayload);\n\n // Emit platform-specific MENTION_RECEIVED event\n const mentionPayload: FarcasterGenericCastPayload = {\n runtime: this.runtime,\n memory,\n cast,\n source: FARCASTER_SOURCE,\n callback: async (ontent: Content, _files: any[]) => {\n logger.info('[Farcaster] mention received response:', response);\n return [];\n },\n };\n this.runtime.emitEvent(FarcasterEventTypes.MENTION_RECEIVED, mentionPayload);\n }\n}\n","export class AsyncQueue {\n private queue: (() => Promise<void>)[] = [];\n private running = 0;\n private emptyListeners: (() => void)[] = [];\n private maxConcurrent: number;\n\n constructor(maxConcurrent: number = 1) {\n this.maxConcurrent = maxConcurrent;\n }\n\n async submit<T>(work: () => Promise<T>): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n this.queue.push(async () => {\n try {\n resolve(await work());\n } catch (err) {\n reject(err);\n }\n });\n void this.doNextWork();\n });\n }\n\n private async doNextWork(): Promise<void> {\n if (this.running >= this.maxConcurrent) {\n return;\n }\n\n const work = this.queue.shift();\n if (!work) {\n this.checkIfEmptyAndNotify();\n return;\n }\n\n this.running++;\n try {\n await work();\n } catch (err) {\n // Error handling without logging\n } finally {\n this.running--;\n void this.doNextWork();\n }\n }\n\n async size(): Promise<number> {\n return this.queue.length;\n }\n\n async waitUntilFinished(): Promise<void> {\n return new Promise((resolve) => {\n if (this.queue.length === 0 && this.running === 0) {\n resolve();\n } else {\n this.emptyListeners.push(resolve);\n }\n });\n }\n\n private checkIfEmptyAndNotify(): void {\n if (this.queue.length === 0 && this.running === 0) {\n while (this.emptyListeners.length) {\n const listener = this.emptyListeners.shift();\n if (listener) listener();\n }\n }\n }\n}\n","import { Content, HandlerCallback, IAgentRuntime, logger, Memory, UUID } from '@elizaos/core';\nimport { CastWithInteractions } from '@neynar/nodejs-sdk/build/api';\nimport { FarcasterClient } from '../client';\nimport { CastId, FarcasterConfig } from './types';\nimport { createCastMemory, neynarCastToCast } from './utils';\n\nexport function standardCastHandlerCallback({\n client,\n runtime,\n config,\n roomId,\n onCompletion,\n onError,\n inReplyTo,\n}: {\n inReplyTo?: CastId;\n client: FarcasterClient;\n runtime: IAgentRuntime;\n config: FarcasterConfig;\n roomId: UUID;\n onCompletion?: (casts: CastWithInteractions[], memories: Memory[]) => Promise<void>;\n onError?: (error: unknown) => Promise<void>;\n}): HandlerCallback {\n const callback: HandlerCallback = async (content: Content, _files?: any) => {\n try {\n if (config.FARCASTER_DRY_RUN) {\n logger.info(`[Farcaster] Dry run: would have cast: ${content.text}`);\n return [];\n }\n\n const casts = await client.sendCast({ content, inReplyTo });\n\n if (casts.length === 0) {\n logger.warn('[Farcaster] No casts posted');\n return [];\n }\n\n const memories: Memory[] = [];\n for (let i = 0; i < casts.length; i++) {\n const cast = casts[i];\n logger.success(`[Farcaster] Published cast ${cast.hash}`);\n\n const memory = createCastMemory({\n roomId,\n senderId: runtime.agentId,\n runtime,\n cast: neynarCastToCast(cast),\n });\n\n if (i === 0) {\n // sendCast removes the response action, so we need to add it back here\n memory.content.actions = content.actions;\n }\n\n await runtime.createMemory(memory, 'messages');\n memories.push(memory);\n }\n\n if (onCompletion) {\n await onCompletion(casts, memories);\n }\n\n return memories;\n } catch (error) {\n logger.error('[Farcaster] Error posting cast:', error);\n\n if (onError) {\n await onError(error);\n }\n\n return [];\n }\n };\n\n return callback;\n}\n","import { type Character } from '@elizaos/core';\nimport type { Cast } from './types';\n\nexport const formatCast = (cast: Cast) => {\n return `ID: ${cast.hash}\n From: ${cast.profile.name} (@${cast.profile.username})${cast.profile.username})${cast.inReplyTo ? `\\nIn reply to: ${cast.inReplyTo.fid}` : ''}\nText: ${cast.text}`;\n};\n\nexport const formatTimeline = (\n character: Character,\n timeline: Cast[]\n) => `# ${character.name}'s Home Timeline\n${timeline.map(formatCast).join('\\n')}\n`;\n","import { Memory, MessagePayload } from '@elizaos/core';\nimport { DEFAULT_MAX_CAST_LENGTH, DEFAULT_POLL_INTERVAL } from './constants';\n\nimport { CastWithInteractions } from '@neynar/nodejs-sdk/build/api/models/cast-with-interactions';\nimport { z } from 'zod';\n\nexport type Profile = {\n fid: number;\n name: string;\n username: string;\n pfp?: string;\n bio?: string;\n url?: string;\n};\n\nexport type Cast = {\n hash: string;\n authorFid: number;\n text: string;\n profile: Profile;\n threadId?: string;\n inReplyTo?: {\n hash: string;\n fid: number;\n };\n timestamp: Date;\n stats?: {\n recasts: number;\n replies: number;\n likes: number;\n };\n};\n\nexport type CastId = {\n hash: string;\n fid: number;\n};\n\nexport type FidRequest = {\n fid: number;\n pageSize: number;\n};\n\nexport interface LastCast {\n hash: string;\n timestamp: number;\n}\n\n/**\n * This schema defines all required/optional environment settings for Farcaster client\n */\nexport const FarcasterConfigSchema = z.object({\n FARCASTER_DRY_RUN: z\n .union([z.boolean(), z.string()])\n .transform((val) => (typeof val === 'string' ? val.toLowerCase() === 'true' : val)),\n FARCASTER_FID: z.number().int().min(1, 'Farcaster fid is required'),\n MAX_CAST_LENGTH: z.number().int().default(DEFAULT_MAX_CAST_LENGTH),\n FARCASTER_POLL_INTERVAL: z.number().int().default(DEFAULT_POLL_INTERVAL),\n ENABLE_POST: z\n .union([z.boolean(), z.string()])\n .transform((val) => (typeof val === 'string' ? val.toLowerCase() === 'true' : val)),\n POST_INTERVAL_MIN: z.number().int(),\n POST_INTERVAL_MAX: z.number().int(),\n ENABLE_ACTION_PROCESSING: z\n .union([z.boolean(), z.string()])\n .transform((val) => (typeof val === 'string' ? val.toLowerCase() === 'true' : val)),\n ACTION_INTERVAL: z.number().int(),\n POST_IMMEDIATELY: z\n .union([z.boolean(), z.string()])\n .transform((val) => (typeof val === 'string' ? val.toLowerCase() === 'true' : val)),\n MAX_ACTIONS_PROCESSING: z.number().int(),\n FARCASTER_NEYNAR_SIGNER_UUID: z.string().min(1, 'FARCASTER_NEYNAR_SIGNER_UUID is not set'),\n FARCASTER_NEYNAR_API_KEY: z.string().min(1, 'FARCASTER_NEYNAR_API_KEY is not set'),\n FARCASTER_HUB_URL: z.string().min(1, 'FARCASTER_HUB_URL is not set'),\n});\n\nexport type FarcasterConfig = z.infer<typeof FarcasterConfigSchema>;\n\nexport enum FarcasterEventTypes {\n POST_GENERATED = 'FARCASTER_POST_GENERATED',\n MENTION_RECEIVED = 'FARCASTER_MENTION_RECEIVED',\n THREAD_CAST_CREATED = 'FARCASTER_THREAD_CAST_CREATED',\n // CAST_GENERATED = 'FARCASTER_CAST_GENERATED',\n // CAST_SENT = 'FARCASTER_CAST_SENT',\n // CAST_REACTION_RECEIVED = 'FARCASTER_CAST_REACTION_RECEIVED',\n // CAST_REACTION_SENT = 'FARCASTER_CAST_REACTION_SENT',\n}\n\nexport interface FarcasterGenericCastPayload extends Omit<MessagePayload, 'message'> {\n memory: Memory;\n cast: CastWithInteractions;\n}\n","import { createUniqueUuid, EventType, type IAgentRuntime, logger } from '@elizaos/core';\nimport type { FarcasterClient } from '../client';\nimport { standardCastHandlerCallback } from '../common/callbacks';\nimport { FARCASTER_SOURCE } from '../common/constants';\nimport { FarcasterConfig, FarcasterEventTypes, LastCast } from '../common/types';\nimport { lastCastCacheKey } from '../common/utils';\n\ninterface FarcasterPostParams {\n client: FarcasterClient;\n runtime: IAgentRuntime;\n config: FarcasterConfig;\n}\n\nexport class FarcasterPostManager {\n client: FarcasterClient;\n runtime: IAgentRuntime;\n fid: number;\n private timeout: ReturnType<typeof setTimeout> | undefined;\n private config: FarcasterConfig;\n private isRunning: boolean = false;\n\n constructor(opts: FarcasterPostParams) {\n this.client = opts.client;\n this.runtime = opts.runtime;\n this.config = opts.config;\n this.fid = this.config.FARCASTER_FID;\n }\n\n public async start() {\n if (this.isRunning || !this.config.ENABLE_POST) {\n return;\n }\n\n this.isRunning = true;\n\n // never await this, it will block forever\n void this.runPeriodically();\n }\n\n public async stop() {\n if (this.timeout) clearTimeout(this.timeout);\n this.isRunning = false;\n }\n\n private calculateDelay(): { delay: number; randomMinutes: number } {\n const minMinutes = this.config.POST_INTERVAL_MIN;\n const maxMinutes = this.config.POST_INTERVAL_MAX;\n const randomMinutes = Math.floor(Math.random() * (maxMinutes - minMinutes + 1)) + minMinutes;\n const delay = randomMinutes * 60 * 1000;\n return { delay, randomMinutes };\n }\n\n private async runPeriodically(): Promise<void> {\n if (this.config.POST_IMMEDIATELY) {\n await this.generateNewCast();\n }\n\n while (this.isRunning) {\n try {\n const lastPost = await this.runtime.getCache<LastCast>(lastCastCacheKey(this.fid));\n const lastPostTimestamp = lastPost?.timestamp ?? 0;\n const { delay, randomMinutes } = this.calculateDelay();\n\n if (Date.now() > lastPostTimestamp + delay) {\n await this.generateNewCast();\n }\n\n logger.log(`Next cast scheduled in ${randomMinutes} minutes`);\n await new Promise((resolve) => (this.timeout = setTimeout(resolve, delay)));\n } catch (error) {\n logger.error('[Farcaster] Error in periodic post:', this.runtime.agentId, error);\n }\n }\n }\n\n private async generateNewCast() {\n logger.info('Generating new cast');\n try {\n const worldId = createUniqueUuid(this.runtime, this.fid.toString());\n const roomId = createUniqueUuid(this.runtime, `${this.fid}-home`);\n\n // callback for handling the actual posting\n const callback = standardCastHandlerCallback({\n client: this.client,\n runtime: this.runtime,\n config: this.config,\n roomId,\n onCompletion: async (casts, _memories) => {\n const lastCast = casts[casts.length - 1];\n await this.runtime.setCache<LastCast>(lastCastCacheKey(this.fid), {\n hash: lastCast.hash,\n timestamp: new Date(lastCast.timestamp).getTime(),\n });\n },\n });\n\n this.runtime.emitEvent([EventType.POST_GENERATED, FarcasterEventTypes.POST_GENERATED], {\n runtime: this.runtime,\n callback,\n worldId,\n userId: this.runtime.agentId,\n roomId,\n source: FARCASTER_SOURCE,\n });\n } catch (error) {\n logger.error('Error generating new cast:', error);\n }\n }\n}\n","import { logger, parseBooleanFromText, type IAgentRuntime } from '@elizaos/core';\nimport { ZodError } from 'zod';\nimport {\n DEFAULT_MAX_CAST_LENGTH,\n DEFAULT_POLL_INTERVAL,\n DEFAULT_POST_INTERVAL_MAX,\n DEFAULT_POST_INTERVAL_MIN,\n} from './constants';\nimport { FarcasterConfig, FarcasterConfigSchema } from './types';\n\nfunction safeParseInt(value: string | undefined | null, defaultValue: number): number {\n if (!value) return defaultValue;\n const parsed = Number.parseInt(value, 10);\n return Number.isNaN(parsed) ? defaultValue : Math.max(1, parsed);\n}\n\nexport function hasFarcasterEnabled(runtime: IAgentRuntime): boolean {\n const fid = runtime.getSetting('FARCASTER_FID') || process.env.FARCASTER_FID;\n const neynarSignerUuid =\n runtime.getSetting('FARCASTER_NEYNAR_SIGNER_UUID') || process.env.FARCASTER_NEYNAR_SIGNER_UUID;\n const neynarApiKey =\n runtime.getSetting('FARCASTER_NEYNAR_API_KEY') || process.env.FARCASTER_NEYNAR_API_KEY;\n\n return fid && neynarSignerUuid && neynarApiKey;\n}\n\n/**\n * Validates or constructs a FarcasterConfig object using zod,\n * taking values from the IAgentRuntime or process.env as needed.\n */\nexport function validateFarcasterConfig(runtime: IAgentRuntime): FarcasterConfig {\n const fid = Number.parseInt(runtime.getSetting('FARCASTER_FID') || process.env.FARCASTER_FID);\n\n try {\n const farcasterConfig = {\n FARCASTER_DRY_RUN:\n runtime.getSetting('FARCASTER_DRY_RUN') ||\n parseBooleanFromText(process.env.FARCASTER_DRY_RUN || 'false'),\n\n FARCASTER_FID: Number.isNaN(fid) ? undefined : fid,\n\n MAX_CAST_LENGTH: safeParseInt(\n runtime.getSetting('MAX_CAST_LENGTH') || process.env.MAX_CAST_LENGTH,\n DEFAULT_MAX_CAST_LENGTH\n ),\n\n FARCASTER_POLL_INTERVAL: safeParseInt(\n runtime.getSetting('FARCASTER_POLL_INTERVAL') || process.env.FARCASTER_POLL_INTERVAL,\n DEFAULT_POLL_INTERVAL\n ),\n\n ENABLE_POST:\n runtime.getSetting('ENABLE_POST') ||\n parseBooleanFromText(process.env.ENABLE_POST || 'true'),\n\n POST_INTERVAL_MIN: safeParseInt(\n runtime.getSetting('POST_INTERVAL_MIN') || process.env.POST_INTERVAL_MIN,\n DEFAULT_POST_INTERVAL_MIN\n ),\n\n POST_INTERVAL_MAX: safeParseInt(\n runtime.getSetting('POST_INTERVAL_MAX') || process.env.POST_INTERVAL_MAX,\n DEFAULT_POST_INTERVAL_MAX\n ),\n\n ENABLE_ACTION_PROCESSING:\n runtime.getSetting('ENABLE_ACTION_PROCESSING') ||\n parseBooleanFromText(process.env.ENABLE_ACTION_PROCESSING || 'false'),\n\n ACTION_INTERVAL: safeParseInt(\n runtime.getSetting('ACTION_INTERVAL') || process.env.ACTION_INTERVAL,\n 5\n ), // 5 minutes\n\n POST_IMMEDIATELY:\n runtime.getSetting('POST_IMMEDIATELY') ||\n parseBooleanFromText(process.env.POST_IMMEDIATELY || 'false'),\n\n MAX_ACTIONS_PROCESSING: safeParseInt(\n runtime.getSetting('MAX_ACTIONS_PROCESSING') || process.env.MAX_ACTIONS_PROCESSING,\n 1\n ),\n\n FARCASTER_NEYNAR_SIGNER_UUID:\n runtime.getSetting('FARCASTER_NEYNAR_SIGNER_UUID') ||\n process.env.FARCASTER_NEYNAR_SIGNER_UUID,\n\n FARCASTER_NEYNAR_API_KEY:\n runtime.getSetting('FARCASTER_NEYNAR_API_KEY') || process.env.FARCASTER_NEYNAR_API_KEY,\n\n FARCASTER_HUB_URL:\n runtime.getSetting('FARCASTER_HUB_URL') ||\n process.env.FARCASTER_HUB_URL ||\n 'hub.pinata.cloud',\n };\n\n const config = FarcasterConfigSchema.parse(farcasterConfig);\n\n const isDryRun = config.FARCASTER_DRY_RUN;\n\n // Log configuration on initialization\n\n logger.log('Farcaster Client Configuration:');\n logger.log(`- FID: ${config.FARCASTER_FID}`);\n logger.log(`- Dry Run Mode: ${isDryRun ? 'enabled' : 'disabled'}`);\n logger.log(`- Enable Post: ${config.ENABLE_POST ? 'enabled' : 'disabled'}`);\n\n if (config.ENABLE_POST) {\n logger.log(\n `- Post Interval: ${config.POST_INTERVAL_MIN}-${config.POST_INTERVAL_MAX} minutes`\n );\n logger.log(`- Post Immediately: ${config.POST_IMMEDIATELY ? 'enabled' : 'disabled'}`);\n }\n logger.log(`- Action Processing: ${config.ENABLE_ACTION_PROCESSING ? 'enabled' : 'disabled'}`);\n logger.log(`- Action Interval: ${config.ACTION_INTERVAL} minutes`);\n\n if (isDryRun) {\n logger.log('Farcaster client initialized in dry run mode - no actual casts should be posted');\n }\n\n return config;\n } catch (error) {\n if (error instanceof ZodError) {\n const errorMessages = error.errors\n .map((err) => `${err.path.join('.')}: ${err.message}`)\n .join('\\n');\n throw new Error(`Farcaster configuration validation failed:\\n${errorMessages}`);\n }\n throw error;\n }\n}\n","import {\n type IAgentRuntime,\n ModelType,\n type TestSuite,\n createUniqueUuid,\n logger,\n} from '@elizaos/core';\nimport { FARCASTER_SERVICE_NAME } from '../src/common/constants';\nimport { FidRequest } from '../src/common/types';\nimport { FarcasterAgentManager } from '../src/managers/agent';\nimport { TEST_IMAGE } from './test-utils';\n\n/**\n * Represents a Test Suite for Farcaster functionality.\n * This class implements the TestSuite interface.\n * It contains various test cases related to Farcaster operations such as initializing the client,\n * fetching profile, fetching casts, posting casts, and handling cast interactions.\n */\nexport class FarcasterTestSuite implements TestSuite {\n name = 'farcaster';\n private manager: FarcasterAgentManager | null = null;\n tests: { name: string; fn: (runtime: IAgentRuntime) => Promise<void> }[];\n\n /**\n * Constructor for TestSuite class.\n * Initializes an array of test functions to be executed.\n */\n constructor() {\n this.tests = [\n {\n name: 'Initialize Farcaster Client',\n fn: this.testInitializingClient.bind(this),\n },\n { name: 'Fetch Profile', fn: this.testFetchProfile.bind(this) },\n {\n name: 'Fetch Timeline',\n fn: this.testFetchTimeline.bind(this),\n },\n { name: 'Post Cast', fn: this.testPostCast.bind(this) },\n { name: 'Post Cast With Image', fn: this.testPostImageCast.bind(this) },\n {\n name: 'Handle Cast Response',\n fn: this.testHandleCastResponse.bind(this),\n },\n ];\n }\n\n /**\n * Asynchronously initializes the Farcaster client for the provided agent runtime.\n *\n * @param {IAgentRuntime} runtime - The agent runtime to use for initializing the Farcaster client.\n * @throws {Error} If the Farcaster client manager is not found or if the Farcaster client fails to initialize.\n */\n async testInitializingClient(runtime: IAgentRuntime) {\n try {\n const service = runtime.getService(FARCASTER_SERVICE_NAME) as any;\n if (!service) {\n throw new Error('Farcaster service not found');\n }\n\n this.manager = service.managers.get(runtime.agentId);\n\n if (this.manager) {\n logger.debug('FarcasterAgentManager initialized successfully.');\n } else {\n throw new Error('FarcasterAgentManager failed to initialize.');\n }\n } catch (error) {\n throw new Error(`Error in initializing Farcaster client: ${error}`);\n }\n }\n\n /**\n * Asynchronously fetches the profile of a user from Farcaster using the given runtime.\n *\n * @param {IAgentRuntime} runtime The runtime to use for fetching the profile.\n * @returns {Promise<void>} A Promise that resolves when the profile is successfully fetched, or rejects with an error.\n */\n async testFetchProfile(runtime: IAgentRuntime) {\n try {\n if (!this.manager) {\n throw new Error('FarcasterAgentManager not initialized');\n }\n\n const fid = parseInt(runtime.getSetting('FARCASTER_FID') as string, 10);\n if (!fid || isNaN(fid)) {\n throw new Error('Invalid FID in settings.');\n }\n\n const profile = await this.manager.client.getProfile(fid);\n if (!profile || !profile.fid) {\n throw new Error('Profile fetch failed.');\n }\n logger.log('Successfully fetched Farcaster profile:', profile);\n } catch (error) {\n throw new Error(`Error fetching Farcaster profile: ${error}`);\n }\n }\n\n /**\n * Asynchronously fetches the timeline from the Farcaster client.\n *\n * @param {IAgentRuntime} runtime - The agent runtime object.\n * @throws {Error} If there are no casts in the timeline.\n * @throws {Error} If an error occurs while fetching the timeline.\n */\n async testFetchTimeline(runtime: IAgentRuntime) {\n try {\n if (!this.manager) {\n throw new Error('FarcasterAgentManager not initialized');\n }\n\n const fid = parseInt(runtime.getSetting('FARCASTER_FID') as string, 10);\n if (!fid || isNaN(fid)) {\n throw new Error('Invalid FID in settings.');\n }\n\n const request: FidRequest = { fid, pageSize: 5 };\n const result = await this.manager.client.getTimeline(request);\n\n if (!result.timeline || result.timeline.length === 0) {\n throw new Error('No casts in timeline.');\n }\n logger.log(`Successfully fetched ${result.timeline.length} casts from timeline.`);\n } catch (error) {\n throw new Error(`Error fetching timeline: ${error}`);\n }\n }\n\n /**\n * Asynchronously posts a test cast using the Farcaster API.\n *\n * @param {IAgentRuntime} runtime - The agent runtime object.\n * @returns {Promise<void>} A Promise that resolves when the cast is successfully posted.\n * @throws {Error} If there is an error posting the cast.\n */\n async testPostCast(runtime: IAgentRuntime) {\n try {\n if (!this.manager) {\n throw new Error('FarcasterAgentManager not initialized');\n }\n\n const castText = await this.generateRandomCastContent(runtime);\n const result = await this.manager.client.sendCast({\n content: { text: castText },\n });\n\n if (!result || result.length === 0) {\n throw new Error('Cast posting failed.');\n }\n logger.success('Successfully posted a test cast.');\n } catch (error) {\n throw new Error(`Error posting a cast: ${error}`);\n }\n }\n\n /**\n * Asynchronously posts an image cast on Farcaster using the provided runtime and cast content.\n * Note: This might need updating based on how images are actually handled in sendCast\n *\n * @param {IAgentRuntime} runtime - The runtime environment for the action.\n * @returns {Promise<void>} A Promise that resolves when the cast is successfully posted.\n * @throws {Error} If there is an error posting the cast.\n */\n async testPostImageCast(runtime: IAgentRuntime) {\n try {\n if (!this.manager) {\n throw new Error('FarcasterAgentManager not initialized');\n }\n\n const castText = await this.generateRandomCastContent(runtime, 'image_post');\n // This implementation might need to be updated based on how images are actually handled\n const result = await this.manager.client.sendCast({\n content: {\n text: castText,\n media: [TEST_IMAGE],\n },\n });\n\n if (!result || result.length === 0) {\n throw new Error('Cast with image posting failed.');\n }\n logger.success('Successfully posted a test cast with image.');\n } catch (error) {\n throw new Error(`Error posting a cast with image: ${error}`);\n }\n }\n\n /**\n * Asynchronously handles a fake cast response using the given runtime.\n *\n * @param {IAgentRuntime} runtime - The runtime object for the agent\n * @returns {Promise<void>} - A promise that resolves when the cast response is handled\n * @throws {Error} - If there is an error handling the cast response\n */\n async testHandleCastResponse(runtime: IAgentRuntime) {\n try {\n if (!this.manager) {\n throw new Error('FarcasterAgentManager not initialized');\n }\n\n // For testing purposes, we'll just mock the event emission instead of calling the actual handler\n // This avoids dealing with complex type requirements\n const testCast = {\n hash: '0x12345',\n text: '@testUser What do you think about AI?',\n authorFid: 123,\n profile: {\n fid: 123,\n username: 'randomUser',\n name: 'Random User',\n },\n timestamp: new Date(),\n };\n\n // Create a mock memory for the test\n const memoryId = createUniqueUuid(runtime, testCast.hash);\n const memory = {\n id: memoryId,\n agentId: runtime.agentId,\n content: {\n text: testCast.text,\n },\n entityId: createUniqueUuid(runtime, String(testCast.authorFid)),\n roomId: createUniqueUuid(runtime, 'test-room'),\n createdAt: testCast.timestamp.getTime(),\n };\n\n // Emit an event to simulate the interaction\n runtime.emitEvent('farcaster.mention_received', {\n runtime,\n memory,\n cast: testCast,\n source: 'farcaster',\n });\n\n logger.success('Successfully simulated cast response handling');\n } catch (error) {\n throw new Error(`Error handling cast response: ${error}`);\n }\n }\n\n /**\n * Generates random content for a cast based on the given context.\n *\n * @param {IAgentRuntime} runtime - The runtime environment.\n * @param {string} context - Optional context for the content generation.\n * @returns {Promise<string>} A promise that resolves to the generated cast content.\n */\n private async generateRandomCastContent(\n runtime: IAgentRuntime,\n context = 'general'\n ): Promise<string> {\n const prompt = `Generate a short, interesting cast about ${context} (max 280 chars).`;\n // Use TEXT_SMALL instead of CHAT since that seems to be the correct ModelType\n const result = await runtime.useModel(ModelType.TEXT_SMALL, {\n prompt,\n });\n\n // Truncate the result to ensure it doesn't exceed 280 characters\n return (result as string).substring(0, 280);\n }\n}\n","import type { FarcasterClient } from '../src/client';\nimport type { Cast, Profile } from '../src/common/types';\nimport type { TestInteraction } from './types';\n\nexport function createTestInteraction(cast: Cast, profile: Profile): TestInteraction | null {\n // Only create interaction if there is significant engagement\n if (\n !cast.stats ||\n (cast.stats.recasts === 0 && cast.stats.replies === 0 && cast.stats.likes === 0)\n ) {\n return null;\n }\n\n // Simple heuristic: if the cast has more replies, reply to it\n if (cast.stats.replies > cast.stats.recasts && cast.stats.replies > cast.stats.likes) {\n return {\n type: 'REPLY',\n castId: cast.hash,\n content: 'Interesting perspective!',\n };\n }\n\n // If it has more likes, like it\n if (cast.stats.likes > cast.stats.recasts && cast.stats.likes > cast.stats.replies) {\n return {\n type: 'LIKE',\n castId: cast.hash,\n };\n }\n\n // Otherwise, recast it\n return {\n type: 'RECAST',\n castId: cast.hash,\n };\n}\n\nexport async function handleTestInteraction(client: FarcasterClient, interaction: TestInteraction) {\n switch (interaction.type) {\n case 'RECAST':\n if (!interaction.castId) throw new Error('Cast ID required for recast');\n return await client.neynar.publishCast({\n text: '',\n parent: interaction.castId,\n signerUuid: client.signerUuid,\n });\n case 'REPLY':\n if (!interaction.castId || !interaction.content) {\n throw new Error('Cast ID and content required for reply');\n }\n return await client.neynar.publishCast({\n text: interaction.content,\n parent: interaction.castId,\n signerUuid: client.signerUuid,\n });\n case 'LIKE':\n if (!interaction.castId) throw new Error('Cast ID required for like');\n return await client.neynar.publishCast({\n text: '',\n parent: interaction.castId,\n signerUuid: client.signerUuid,\n });\n default:\n throw new Error('Unknown interaction type');\n }\n}\n\nexport async function createTestCast(client: FarcasterClient, content: string) {\n if (!content) {\n throw new Error('Cast content cannot be empty');\n }\n if (content.length > 320) {\n throw new Error('Cast content too long');\n }\n return await client.neynar.publishCast({\n text: content,\n signerUuid: client.signerUuid,\n });\n}\n\nexport const TEST_IMAGE_URL =\n 'https://github.com/elizaOS/awesome-eliza/blob/main/assets/eliza-logo.jpg?raw=true';\n\nexport const TEST_IMAGE = {\n id: 'mock-image-id',\n text: 'mock image',\n description: 'mock image descirption',\n source: 'mock image source',\n url: TEST_IMAGE_URL,\n title: 'mock image',\n contentType: 'image/jpeg',\n alt_text: 'mock image',\n};\n","import { FarcasterService } from './service';\nimport { FarcasterTestSuite } from '../__tests__/suite';\n\nconst farcasterPlugin = {\n name: 'farcaster',\n description: 'Farcaster client plugin',\n services: [FarcasterService],\n tests: [new FarcasterTestSuite()],\n};\nexport default farcasterPlugin;\n"],"mappings":"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","names":["logger","logger","logger","logger","memory","createUniqueUuid","EventType","logger","logger","createUniqueUuid","EventType","logger","logger","logger","logger","ModelType","createUniqueUuid","logger","logger","createUniqueUuid","ModelType"]}
1
+ {"version":3,"sources":["../src/service.ts","../src/managers/agent.ts","../src/client.ts","../src/common/utils.ts","../src/managers/interactions.ts","../src/common/asyncqueue.ts","../src/common/callbacks.ts","../src/common/prompts.ts","../src/common/types.ts","../src/managers/post.ts","../src/common/config.ts","../src/services/MessageService.ts","../src/services/CastService.ts","../src/__tests__/suite.ts","../src/__tests__/test-utils.ts","../src/__tests__/e2e/scenarios.ts","../src/actions/replyCast.ts","../src/actions/index.ts","../src/providers/index.ts","../src/index.ts"],"sourcesContent":["import { logger, Service, UUID, type IAgentRuntime } from '@elizaos/core';\nimport { FARCASTER_SERVICE_NAME } from './common/constants';\nimport { FarcasterAgentManager } from './managers/agent';\nimport { hasFarcasterEnabled, validateFarcasterConfig } from './common/config';\nimport { FarcasterMessageService } from './services/MessageService';\nimport { FarcasterCastService } from './services/CastService';\n\nexport class FarcasterService extends Service {\n private static instance?: FarcasterService;\n private managers = new Map<UUID, FarcasterAgentManager>();\n private messageServices = new Map<UUID, FarcasterMessageService>();\n private castServices = new Map<UUID, FarcasterCastService>();\n\n // Properly implement serviceType for discoverability\n static serviceType = FARCASTER_SERVICE_NAME;\n\n // Add service description\n readonly description = 'Farcaster integration service for sending and receiving casts';\n readonly capabilityDescription = 'The agent is able to send and receive messages on farcaster';\n\n private static getInstance(): FarcasterService {\n if (!FarcasterService.instance) {\n FarcasterService.instance = new FarcasterService();\n }\n return FarcasterService.instance;\n }\n\n // Required by ElizaOS Service base class\n async initialize(runtime: IAgentRuntime): Promise<void> {\n await FarcasterService.start(runtime);\n }\n\n // Called to start a single Farcaster service\n static async start(runtime: IAgentRuntime): Promise<Service> {\n const service = FarcasterService.getInstance();\n let manager = service.managers.get(runtime.agentId);\n\n if (manager) {\n logger.warn('Farcaster service already started', runtime.agentId);\n return service;\n }\n\n if (!hasFarcasterEnabled(runtime)) {\n logger.debug('Farcaster service not enabled', runtime.agentId);\n return service;\n }\n\n const farcasterConfig = validateFarcasterConfig(runtime);\n manager = new FarcasterAgentManager(runtime, farcasterConfig);\n service.managers.set(runtime.agentId, manager);\n\n // Create and store MessageService and CastService instances\n const messageService = new FarcasterMessageService(manager.client, runtime);\n const castService = new FarcasterCastService(manager.client, runtime);\n\n service.messageServices.set(runtime.agentId, messageService);\n service.castServices.set(runtime.agentId, castService);\n\n await manager.start();\n\n logger.success('Farcaster client started', runtime.agentId);\n return service;\n }\n\n // Called to stop a single Farcaster service\n static async stop(runtime: IAgentRuntime): Promise<void> {\n const service = FarcasterService.getInstance();\n let manager = service.managers.get(runtime.agentId);\n if (manager) {\n await manager.stop();\n service.managers.delete(runtime.agentId);\n service.messageServices.delete(runtime.agentId);\n service.castServices.delete(runtime.agentId);\n logger.info('Farcaster client stopped', runtime.agentId);\n } else {\n logger.debug('Farcaster service not running', runtime.agentId);\n }\n }\n\n // Called to stop all Farcaster services\n async stop(): Promise<void> {\n logger.debug('Stopping ALL Farcaster services');\n for (const manager of Array.from(this.managers.values())) {\n const agentId = manager.runtime.agentId;\n try {\n await FarcasterService.stop(manager.runtime);\n } catch (error) {\n logger.error('Error stopping Farcaster service', agentId, error);\n }\n }\n }\n\n // Get the MessageService for a specific agent\n getMessageService(agentId: UUID): FarcasterMessageService | undefined {\n return this.messageServices.get(agentId);\n }\n\n /**\n * Get the PostService for a specific agent (for compatibility)\n * @deprecated Use getCastService() instead. Will be removed in a future major release.\n */\n getPostService(agentId: UUID): FarcasterCastService | undefined {\n return this.castServices.get(agentId);\n }\n\n // Get the CastService for a specific agent \n getCastService(agentId: UUID): FarcasterCastService | undefined {\n return this.castServices.get(agentId);\n }\n\n // Add health check method\n async healthCheck(): Promise<{ healthy: boolean; details: Record<string, any> }> {\n const managerStatuses: Record<string, any> = {};\n let overallHealthy = true;\n\n for (const [agentId, manager] of Array.from(this.managers.entries())) {\n try {\n // Check if manager client is responsive\n const profile = await manager.client.getProfile(\n parseInt(manager.runtime.getSetting('FARCASTER_FID') as string)\n );\n managerStatuses[agentId] = {\n status: 'healthy',\n fid: profile.fid,\n username: profile.username,\n };\n } catch (error) {\n managerStatuses[agentId] = {\n status: 'unhealthy',\n error: error instanceof Error ? error.message : 'Unknown error',\n };\n overallHealthy = false;\n }\n }\n\n return {\n healthy: overallHealthy,\n details: {\n activeManagers: this.managers.size,\n managerStatuses,\n },\n };\n }\n\n // Get all active managers (for monitoring)\n getActiveManagers(): Map<UUID, FarcasterAgentManager> {\n return new Map(this.managers);\n }\n}\n","import { logger, type IAgentRuntime } from '@elizaos/core';\nimport { Configuration, NeynarAPIClient } from '@neynar/nodejs-sdk';\nimport { FarcasterClient } from '../client';\nimport { type FarcasterConfig } from '../common/types';\nimport { FarcasterInteractionManager } from './interactions';\nimport { FarcasterCastManager } from './post';\n\n/**\n * A manager that orchestrates all Farcaster operations:\n * - client: base operations (Neynar client, hub connection, etc.)\n * - posts: autonomous posting logic\n * - interactions: handling mentions, replies, likes, etc.\n */\nexport class FarcasterAgentManager {\n readonly runtime: IAgentRuntime;\n readonly client: FarcasterClient;\n readonly casts: FarcasterCastManager;\n readonly interactions: FarcasterInteractionManager;\n\n constructor(runtime: IAgentRuntime, config: FarcasterConfig) {\n this.runtime = runtime;\n const signerUuid = config.FARCASTER_SIGNER_UUID;\n\n const neynarConfig = new Configuration({ apiKey: config.FARCASTER_NEYNAR_API_KEY });\n\n const neynar = new NeynarAPIClient(neynarConfig);\n\n const client = new FarcasterClient({ neynar, signerUuid });\n\n this.client = client;\n\n logger.success('Farcaster Neynar client initialized.');\n\n this.casts = new FarcasterCastManager({ client, runtime, config });\n\n this.interactions = new FarcasterInteractionManager({ client, runtime, config });\n }\n\n async start() {\n await Promise.all([this.casts.start(), this.interactions.start()]);\n }\n\n async stop() {\n await Promise.all([this.casts.stop(), this.interactions.stop()]);\n }\n}\n","import { Content, elizaLogger } from '@elizaos/core';\nimport { type NeynarAPIClient, isApiErrorResponse } from '@neynar/nodejs-sdk';\nimport { CastParamType, CastWithInteractions } from '@neynar/nodejs-sdk/build/api/index.js';\n// @ts-ignore\nimport { LRUCache } from 'lru-cache';\nimport { DEFAULT_CAST_CACHE_SIZE, DEFAULT_CAST_CACHE_TTL } from './common/constants';\nimport type { Cast, CastId, FidRequest, Profile } from './common/types';\nimport { neynarCastToCast, splitPostContent } from './common/utils';\n\n// add global cast cache\nconst castCache: LRUCache<string, CastWithInteractions> = new LRUCache({\n max: DEFAULT_CAST_CACHE_SIZE,\n ttl: DEFAULT_CAST_CACHE_TTL,\n});\n\n// add global profile cache\nconst profileCache: LRUCache<number, Profile> = new LRUCache({\n max: 1000,\n ttl: 1000 * 60 * 15, // 15 minutes\n});\n\nexport class FarcasterClient {\n private neynar: NeynarAPIClient;\n private signerUuid: string;\n constructor(opts: { neynar: NeynarAPIClient; signerUuid: string }) {\n this.neynar = opts.neynar;\n this.signerUuid = opts.signerUuid;\n }\n\n async sendCast({\n content,\n inReplyTo,\n }: {\n content: Content;\n inReplyTo?: CastId;\n }): Promise<CastWithInteractions[]> {\n const text = (content.text ?? '').trim();\n if (text.length === 0) {\n return [];\n }\n\n const chunks = splitPostContent(text);\n const sent: CastWithInteractions[] = [];\n\n for (const chunk of chunks) {\n const result = await this.publishCast(chunk, inReplyTo);\n sent.push(result);\n }\n return sent;\n }\n\n private async publishCast(cast: string, parentCastId?: CastId): Promise<CastWithInteractions> {\n try {\n const result = await this.neynar.publishCast({\n signerUuid: this.signerUuid,\n text: cast,\n parent: parentCastId?.hash,\n });\n if (result.success) {\n return this.getCast(result.cast.hash);\n }\n throw new Error(`[Farcaster] Error publishing [${cast}] parentCastId: [${parentCastId}]`);\n } catch (err) {\n if (isApiErrorResponse(err)) {\n elizaLogger.error('Neynar error: ', err.response.data);\n throw err.response.data;\n } else {\n elizaLogger.error('Error: ', err);\n throw err;\n }\n }\n }\n\n async getCast(castHash: string): Promise<CastWithInteractions> {\n const cachedCast = castCache.get(castHash);\n if (cachedCast) {\n return cachedCast;\n }\n\n const params = { identifier: castHash, type: CastParamType.Hash };\n const response = await this.neynar.lookupCastByHashOrWarpcastUrl(params);\n\n castCache.set(castHash, response.cast);\n\n return response.cast;\n }\n async getMentions(request: FidRequest): Promise<CastWithInteractions[]> {\n const neynarMentionsResponse = await this.neynar.fetchAllNotifications({\n fid: request.fid,\n type: ['mentions', 'replies'],\n limit: request.pageSize,\n });\n const mentions: CastWithInteractions[] = [];\n\n for (const notification of neynarMentionsResponse.notifications) {\n const neynarCast = notification.cast;\n if (neynarCast) {\n mentions.push(neynarCast);\n }\n }\n\n return mentions;\n }\n\n async getProfile(fid: number): Promise<Profile> {\n if (profileCache.has(fid)) {\n return profileCache.get(fid) as Profile;\n }\n\n try {\n const result = await this.neynar.fetchBulkUsers({ fids: [fid] });\n if (!result.users || result.users.length < 1) {\n elizaLogger.error('Error fetching user by fid');\n throw new Error('Profile fetch failed');\n }\n\n const neynarUserProfile = result.users[0];\n\n const profile: Profile = {\n fid,\n name: '',\n username: '',\n };\n\n profile.name = neynarUserProfile.display_name!;\n profile.username = neynarUserProfile.username;\n profile.bio = neynarUserProfile.profile.bio.text;\n profile.pfp = neynarUserProfile.pfp_url;\n\n profileCache.set(fid, profile);\n\n return profile;\n } catch (error) {\n elizaLogger.error('Error fetching profile:', error);\n throw error;\n }\n }\n\n async getTimeline(request: FidRequest): Promise<{\n timeline: Cast[];\n cursor?: string;\n }> {\n const timeline: Cast[] = [];\n\n const response = await this.neynar.fetchCastsForUser({\n fid: request.fid,\n limit: request.pageSize,\n });\n\n for (const cast of response.casts) {\n castCache.set(cast.hash, cast);\n timeline.push(neynarCastToCast(cast));\n }\n\n const nextCursor = response.next?.cursor ?? undefined;\n\n return {\n timeline,\n cursor: nextCursor,\n };\n }\n\n clearCache(): void {\n profileCache.clear();\n castCache.clear();\n }\n}\n","import { IAgentRuntime, Memory, stringToUuid, UUID } from '@elizaos/core';\nimport { CastWithInteractions } from '@neynar/nodejs-sdk/build/api';\nimport { FARCASTER_SOURCE } from './constants';\nimport { Cast } from './types';\n\nexport const MAX_CAST_LENGTH = 1024; // Farcaster cast character limit\n\nexport function castId({ hash, agentId }: { hash: string; agentId: string }) {\n return `${hash}-${agentId}`;\n}\n\nexport function castUuid(props: { hash: string; agentId: string }) {\n return stringToUuid(castId(props));\n}\n\nexport function splitPostContent(content: string, maxLength: number = MAX_CAST_LENGTH): string[] {\n const paragraphs = content.split('\\n\\n').map((p) => p.trim());\n const posts: string[] = [];\n let currentCast = '';\n\n for (const paragraph of paragraphs) {\n if (!paragraph) continue;\n\n if ((currentCast + '\\n\\n' + paragraph).trim().length <= maxLength) {\n if (currentCast) {\n currentCast += '\\n\\n' + paragraph;\n } else {\n currentCast = paragraph;\n }\n } else {\n if (currentCast) {\n posts.push(currentCast.trim());\n }\n if (paragraph.length <= maxLength) {\n currentCast = paragraph;\n } else {\n // Split long paragraph into smaller chunks\n const chunks = splitParagraph(paragraph, maxLength);\n posts.push(...chunks.slice(0, -1));\n currentCast = chunks[chunks.length - 1];\n }\n }\n }\n\n if (currentCast) {\n posts.push(currentCast.trim());\n }\n\n return posts;\n}\n\nexport function splitParagraph(paragraph: string, maxLength: number): string[] {\n const sentences = paragraph.match(/[^.!?]+[.!?]+|[^.!?]+$/g) || [paragraph];\n const chunks: string[] = [];\n let currentChunk = '';\n\n for (const sentence of sentences) {\n if ((currentChunk + ' ' + sentence).trim().length <= maxLength) {\n if (currentChunk) {\n currentChunk += ' ' + sentence;\n } else {\n currentChunk = sentence;\n }\n } else {\n if (currentChunk) {\n chunks.push(currentChunk.trim());\n }\n if (sentence.length <= maxLength) {\n currentChunk = sentence;\n } else {\n // Split long sentence into smaller pieces\n const words = sentence.split(' ');\n currentChunk = '';\n for (const word of words) {\n if ((currentChunk + ' ' + word).trim().length <= maxLength) {\n if (currentChunk) {\n currentChunk += ' ' + word;\n } else {\n currentChunk = word;\n }\n } else {\n if (currentChunk) {\n chunks.push(currentChunk.trim());\n }\n currentChunk = word;\n }\n }\n }\n }\n }\n\n if (currentChunk) {\n chunks.push(currentChunk.trim());\n }\n\n return chunks;\n}\n\nexport function lastCastCacheKey(fid: number) {\n return `farcaster/${fid}/lastCast`;\n}\n\nexport function neynarCastToCast(neynarCast: CastWithInteractions): Cast {\n return {\n hash: neynarCast.hash,\n authorFid: neynarCast.author.fid,\n text: neynarCast.text,\n threadId: neynarCast.thread_hash ?? undefined,\n profile: {\n fid: neynarCast.author.fid,\n name: neynarCast.author.display_name || 'anon',\n username: neynarCast.author.username,\n },\n ...(neynarCast.parent_hash && neynarCast.parent_author?.fid\n ? {\n inReplyTo: {\n hash: neynarCast.parent_hash,\n fid: neynarCast.parent_author.fid,\n },\n }\n : {}),\n timestamp: new Date(neynarCast.timestamp),\n };\n}\n\nexport function createCastMemory({\n roomId,\n senderId,\n runtime,\n cast,\n}: {\n roomId: UUID;\n senderId: UUID;\n runtime: IAgentRuntime;\n cast: Cast;\n}): Memory {\n const inReplyTo = cast.inReplyTo\n ? castUuid({\n hash: cast.inReplyTo.hash,\n agentId: runtime.agentId,\n })\n : undefined;\n\n return {\n id: castUuid({\n hash: cast.hash,\n agentId: runtime.agentId,\n }),\n agentId: runtime.agentId,\n entityId: senderId,\n content: {\n text: cast.text,\n source: FARCASTER_SOURCE,\n url: '',\n inReplyTo,\n hash: cast.hash,\n threadId: cast.threadId,\n },\n roomId,\n };\n}\n\nexport function formatCastTimestamp(timestamp: Date): string {\n return timestamp.toLocaleString('en-US', {\n hour: '2-digit',\n minute: '2-digit',\n month: 'short',\n day: 'numeric',\n });\n}\n","import {\n ChannelType,\n composePrompt,\n Content,\n createUniqueUuid,\n EventType,\n type IAgentRuntime,\n logger,\n type Memory,\n MessagePayload,\n ModelType,\n UUID,\n} from '@elizaos/core';\nimport { CastWithInteractions } from '@neynar/nodejs-sdk/build/api';\nimport type { FarcasterClient } from '../client';\nimport { AsyncQueue } from '../common/asyncqueue';\nimport { standardCastHandlerCallback } from '../common/callbacks';\nimport { FARCASTER_SOURCE } from '../common/constants';\nimport { formatCast, formatTimeline } from '../common/prompts';\nimport { shouldRespondTemplate } from '@elizaos/core';\nimport {\n type Cast,\n type FarcasterConfig,\n FarcasterEventTypes,\n FarcasterGenericCastPayload,\n type Profile,\n} from '../common/types';\nimport { castUuid, formatCastTimestamp, neynarCastToCast } from '../common/utils';\ninterface FarcasterInteractionParams {\n client: FarcasterClient;\n runtime: IAgentRuntime;\n config: FarcasterConfig;\n}\n\nexport class FarcasterInteractionManager {\n private timeout: ReturnType<typeof setTimeout> | undefined;\n private isRunning: boolean = false;\n private client: FarcasterClient;\n private runtime: IAgentRuntime;\n private config: FarcasterConfig;\n\n private asyncQueue: AsyncQueue;\n\n constructor(opts: FarcasterInteractionParams) {\n this.client = opts.client;\n this.runtime = opts.runtime;\n this.config = opts.config;\n this.asyncQueue = new AsyncQueue(1);\n }\n\n public async start(): Promise<void> {\n logger.info('Starting Farcaster interactions');\n if (this.isRunning) {\n return;\n }\n\n this.isRunning = true;\n\n // never await this, it will block forever\n void this.runPeriodically();\n }\n\n public async stop(): Promise<void> {\n if (this.timeout) clearTimeout(this.timeout);\n this.isRunning = false;\n }\n\n private async runPeriodically(): Promise<void> {\n while (this.isRunning) {\n try {\n await this.handleInteractions();\n\n // now sleep for the configured interval\n const delay = this.config.FARCASTER_POLL_INTERVAL * 1000;\n await new Promise((resolve) => (this.timeout = setTimeout(resolve, delay)));\n } catch (error) {\n logger.error('[Farcaster] Error in periodic interactions:', this.runtime.agentId, error);\n }\n }\n }\n\n private async ensureCastConnection(cast: Cast): Promise<Memory> {\n return await this.asyncQueue.submit(async () => {\n const memoryId = castUuid({ agentId: this.runtime.agentId, hash: cast.hash });\n const conversationId = cast.threadId ?? cast.inReplyTo?.hash ?? cast.hash;\n const entityId = createUniqueUuid(this.runtime, cast.authorFid.toString());\n const worldId = createUniqueUuid(this.runtime, cast.authorFid.toString());\n const serverId = cast.authorFid.toString();\n const roomId = createUniqueUuid(this.runtime, conversationId);\n\n if (entityId !== this.runtime.agentId) {\n await this.runtime.ensureConnection({\n entityId,\n roomId,\n worldName: `${cast.profile.username}'s Farcaster`,\n userName: cast.profile.username,\n name: cast.profile.name,\n source: FARCASTER_SOURCE,\n type: ChannelType.THREAD,\n channelId: conversationId,\n serverId,\n worldId,\n metadata: {\n ownership: { ownerId: cast.authorFid.toString() },\n farcaster: {\n username: cast.profile.username,\n id: cast.authorFid.toString(),\n name: cast.profile.name,\n },\n },\n });\n }\n\n const memory: Memory = {\n id: memoryId,\n agentId: this.runtime.agentId,\n content: {\n text: cast.text,\n // need to pull imageUrls\n inReplyTo: cast.inReplyTo?.hash\n ? castUuid({ agentId: this.runtime.agentId, hash: cast.inReplyTo.hash })\n : undefined,\n source: FARCASTER_SOURCE,\n channelType: ChannelType.THREAD,\n },\n entityId,\n roomId,\n createdAt: cast.timestamp.getTime(),\n };\n\n // no need to store the memory as it'll be stored in bootstrap side\n\n return memory;\n });\n }\n\n private async handleInteractions(): Promise<void> {\n const agentFid = this.config.FARCASTER_FID;\n const [mentions, agent] = await Promise.all([\n this.client.getMentions({\n fid: agentFid,\n pageSize: 20,\n }),\n this.client.getProfile(agentFid),\n ]);\n\n for (const cast of mentions) {\n const mention = neynarCastToCast(cast);\n const memoryId = castUuid({ agentId: this.runtime.agentId, hash: mention.hash });\n\n if (await this.runtime.getMemoryById(memoryId)) {\n continue;\n }\n\n logger.info('New Cast found', mention.hash);\n\n // filter out the agent mentions\n if (mention.authorFid === agentFid) {\n const memory = await this.ensureCastConnection(mention);\n await this.runtime.addEmbeddingToMemory(memory);\n await this.runtime.createMemory(memory, 'messages');\n continue;\n }\n\n await this.handleMentionCast({ agent, mention, cast });\n }\n }\n\n async buildThreadForCast(cast: Cast, skipMemoryId: Set<UUID>): Promise<Cast[]> {\n const thread: Cast[] = [];\n const visited: Set<string> = new Set();\n const client = this.client;\n const runtime = this.runtime;\n const self = this;\n\n async function processThread(currentCast: Cast) {\n const memoryId = castUuid({ hash: currentCast.hash, agentId: runtime.agentId });\n\n if (visited.has(currentCast.hash) || skipMemoryId.has(memoryId)) {\n return;\n }\n\n visited.add(currentCast.hash);\n\n // Check if the current cast has already been saved\n const memory = await runtime.getMemoryById(memoryId);\n\n if (!memory) {\n logger.info('Creating memory for cast', currentCast.hash);\n const memory = await self.ensureCastConnection(currentCast);\n await runtime.createMemory(memory, 'messages');\n runtime.emitEvent(FarcasterEventTypes.THREAD_CAST_CREATED, {\n runtime,\n memory,\n cast: currentCast,\n source: FARCASTER_SOURCE,\n });\n }\n\n thread.unshift(currentCast);\n\n if (currentCast.inReplyTo) {\n const parentCast = await client.getCast(currentCast.inReplyTo.hash);\n await processThread(neynarCastToCast(parentCast));\n }\n }\n\n await processThread(cast);\n return thread;\n }\n\n private async handleMentionCast({\n agent,\n mention,\n cast,\n }: {\n agent: Profile;\n cast: CastWithInteractions;\n mention: Cast;\n }): Promise<void> {\n if (mention.profile.fid === agent.fid) {\n logger.info('skipping cast from bot itself', mention.hash);\n return;\n }\n\n // Process one at a time to ensure proper sequencing\n const memory = await this.ensureCastConnection(mention);\n const thread: Cast[] = await this.buildThreadForCast(\n mention,\n memory.id ? new Set([memory.id]) : new Set()\n );\n\n if (!memory.content.text || memory.content.text.trim() === '') {\n logger.info('skipping cast with no text', mention.hash);\n return;\n }\n\n // Build the state for the prompt\n const currentPost = formatCast(mention);\n const { timeline } = await this.client.getTimeline({ fid: agent.fid, pageSize: 20 });\n const formattedTimeline = formatTimeline(this.runtime.character, timeline);\n const formattedConversation = thread\n .map((c) =>\n `\n - @${c.profile.username} (${formatCastTimestamp(c.timestamp)}):\n ${c.text}`.trim()\n )\n .join('\\n\\n');\n\n const state = await this.runtime.composeState(memory);\n state.values = {\n ...state.values,\n farcasterUsername: agent.username,\n timeline: formattedTimeline,\n currentPost,\n formattedConversation,\n };\n\n // Determine if we should respond to the cast\n const shouldRespondPrompt = composePrompt({\n state,\n template:\n this.runtime.character.templates?.farcasterShouldRespondTemplate ||\n this.runtime.character?.templates?.shouldRespondTemplate ||\n shouldRespondTemplate,\n });\n\n const response = await this.runtime.useModel(ModelType.TEXT_SMALL, {\n prompt: shouldRespondPrompt,\n });\n\n const responseActions = (response.match(/(?:RESPOND|IGNORE|STOP)/g) || ['IGNORE'])[0];\n if (responseActions !== 'RESPOND') {\n logger.info(`Not responding to cast based on shouldRespond decision: ${responseActions}`);\n try {\n // save the memory so we don't process it again in mentions\n await this.runtime.createMemory(memory, 'messages');\n } catch (error) {\n logger.error('Error creating ignoredmemory', error);\n }\n return;\n }\n\n // setup callback for the response\n const callback = standardCastHandlerCallback({\n client: this.client,\n runtime: this.runtime,\n config: this.config,\n roomId: memory.roomId,\n inReplyTo: {\n hash: mention.hash,\n fid: mention.authorFid,\n },\n });\n\n // Emit generic message received events\n const messageReceivedPayload: MessagePayload = {\n runtime: this.runtime,\n message: memory,\n source: FARCASTER_SOURCE,\n callback,\n };\n\n this.runtime.emitEvent(EventType.MESSAGE_RECEIVED, messageReceivedPayload);\n\n // Emit platform-specific MENTION_RECEIVED event\n const mentionPayload: FarcasterGenericCastPayload = {\n runtime: this.runtime,\n memory,\n cast,\n source: FARCASTER_SOURCE,\n callback: async (ontent: Content, _files: any[]) => {\n logger.info('[Farcaster] mention received response:', response);\n return [];\n },\n };\n this.runtime.emitEvent(FarcasterEventTypes.MENTION_RECEIVED, mentionPayload);\n }\n}\n","export class AsyncQueue {\n private queue: (() => Promise<void>)[] = [];\n private running = 0;\n private emptyListeners: (() => void)[] = [];\n private maxConcurrent: number;\n\n constructor(maxConcurrent: number = 1) {\n this.maxConcurrent = maxConcurrent;\n }\n\n async submit<T>(work: () => Promise<T>): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n this.queue.push(async () => {\n try {\n resolve(await work());\n } catch (err) {\n reject(err);\n }\n });\n void this.doNextWork();\n });\n }\n\n private async doNextWork(): Promise<void> {\n if (this.running >= this.maxConcurrent) {\n return;\n }\n\n const work = this.queue.shift();\n if (!work) {\n this.checkIfEmptyAndNotify();\n return;\n }\n\n this.running++;\n try {\n await work();\n } catch (err) {\n // Error handling without logging\n } finally {\n this.running--;\n void this.doNextWork();\n }\n }\n\n async size(): Promise<number> {\n return this.queue.length;\n }\n\n async waitUntilFinished(): Promise<void> {\n return new Promise((resolve) => {\n if (this.queue.length === 0 && this.running === 0) {\n resolve();\n } else {\n this.emptyListeners.push(resolve);\n }\n });\n }\n\n private checkIfEmptyAndNotify(): void {\n if (this.queue.length === 0 && this.running === 0) {\n while (this.emptyListeners.length) {\n const listener = this.emptyListeners.shift();\n if (listener) listener();\n }\n }\n }\n}\n","import { Content, HandlerCallback, IAgentRuntime, logger, Memory, UUID } from '@elizaos/core';\nimport { CastWithInteractions } from '@neynar/nodejs-sdk/build/api';\nimport { FarcasterClient } from '../client';\nimport { CastId, FarcasterConfig } from './types';\nimport { createCastMemory, neynarCastToCast } from './utils';\n\nexport function standardCastHandlerCallback({\n client,\n runtime,\n config,\n roomId,\n onCompletion,\n onError,\n inReplyTo,\n}: {\n inReplyTo?: CastId;\n client: FarcasterClient;\n runtime: IAgentRuntime;\n config: FarcasterConfig;\n roomId: UUID;\n onCompletion?: (casts: CastWithInteractions[], memories: Memory[]) => Promise<void>;\n onError?: (error: unknown) => Promise<void>;\n}): HandlerCallback {\n const callback: HandlerCallback = async (content: Content, _files?: any) => {\n try {\n if (config.FARCASTER_DRY_RUN) {\n logger.info(`[Farcaster] Dry run: would have cast: ${content.text}`);\n return [];\n }\n\n const casts = await client.sendCast({ content, inReplyTo });\n\n if (casts.length === 0) {\n logger.warn('[Farcaster] No casts posted');\n return [];\n }\n\n const memories: Memory[] = [];\n for (let i = 0; i < casts.length; i++) {\n const cast = casts[i];\n logger.success(`[Farcaster] Published cast ${cast.hash}`);\n\n const memory = createCastMemory({\n roomId,\n senderId: runtime.agentId,\n runtime,\n cast: neynarCastToCast(cast),\n });\n\n if (i === 0) {\n // sendCast removes the response action, so we need to add it back here\n memory.content.actions = content.actions;\n }\n\n await runtime.createMemory(memory, 'messages');\n memories.push(memory);\n }\n\n if (onCompletion) {\n await onCompletion(casts, memories);\n }\n\n return memories;\n } catch (error) {\n logger.error('[Farcaster] Error posting cast:', error);\n\n if (onError) {\n await onError(error);\n }\n\n return [];\n }\n };\n\n return callback;\n}\n","import { type Character } from '@elizaos/core';\nimport type { Cast } from './types';\n\nexport const formatCast = (cast: Cast) => {\n return `ID: ${cast.hash}\n From: ${cast.profile.name} (@${cast.profile.username})${cast.profile.username})${cast.inReplyTo ? `\\nIn reply to: ${cast.inReplyTo.fid}` : ''}\nText: ${cast.text}`;\n};\n\nexport const formatTimeline = (\n character: Character,\n timeline: Cast[]\n) => `# ${character.name}'s Home Timeline\n${timeline.map(formatCast).join('\\n')}\n`;\n","import { Memory, MessagePayload } from '@elizaos/core';\nimport { DEFAULT_MAX_CAST_LENGTH, DEFAULT_POLL_INTERVAL } from './constants';\n\nimport { CastWithInteractions } from '@neynar/nodejs-sdk/build/api/models/cast-with-interactions';\nimport { z } from 'zod';\n\nexport type Profile = {\n fid: number;\n name: string;\n username: string;\n pfp?: string;\n bio?: string;\n url?: string;\n};\n\nexport type Cast = {\n hash: string;\n authorFid: number;\n text: string;\n profile: Profile;\n threadId?: string;\n inReplyTo?: {\n hash: string;\n fid: number;\n };\n timestamp: Date;\n stats?: {\n recasts: number;\n replies: number;\n likes: number;\n };\n};\n\nexport type CastId = {\n hash: string;\n fid: number;\n};\n\nexport type FidRequest = {\n fid: number;\n pageSize: number;\n};\n\nexport interface LastCast {\n hash: string;\n timestamp: number;\n}\n\n/**\n * This schema defines all required/optional environment settings for Farcaster client\n */\nexport const FarcasterConfigSchema = z.object({\n FARCASTER_DRY_RUN: z\n .union([z.boolean(), z.string()])\n .transform((val) => (typeof val === 'string' ? val.toLowerCase() === 'true' : val)),\n FARCASTER_FID: z.number().int().min(1, 'Farcaster fid is required'),\n MAX_CAST_LENGTH: z.number().int().default(DEFAULT_MAX_CAST_LENGTH),\n FARCASTER_POLL_INTERVAL: z.number().int().default(DEFAULT_POLL_INTERVAL),\n ENABLE_CAST: z\n .union([z.boolean(), z.string()])\n .transform((val) => (typeof val === 'string' ? val.toLowerCase() === 'true' : val)),\n CAST_INTERVAL_MIN: z.number().int(),\n CAST_INTERVAL_MAX: z.number().int(),\n ENABLE_ACTION_PROCESSING: z\n .union([z.boolean(), z.string()])\n .transform((val) => (typeof val === 'string' ? val.toLowerCase() === 'true' : val)),\n ACTION_INTERVAL: z.number().int(),\n CAST_IMMEDIATELY: z\n .union([z.boolean(), z.string()])\n .transform((val) => (typeof val === 'string' ? val.toLowerCase() === 'true' : val)),\n MAX_ACTIONS_PROCESSING: z.number().int(),\n FARCASTER_SIGNER_UUID: z.string().min(1, 'FARCASTER_SIGNER_UUID is not set'),\n FARCASTER_NEYNAR_API_KEY: z.string().min(1, 'FARCASTER_NEYNAR_API_KEY is not set'),\n FARCASTER_HUB_URL: z.string().min(1, 'FARCASTER_HUB_URL is not set'),\n});\n\nexport type FarcasterConfig = z.infer<typeof FarcasterConfigSchema>;\n\nexport enum FarcasterEventTypes {\n CAST_GENERATED = 'FARCASTER_CAST_GENERATED',\n MENTION_RECEIVED = 'FARCASTER_MENTION_RECEIVED',\n THREAD_CAST_CREATED = 'FARCASTER_THREAD_CAST_CREATED',\n}\n\nexport enum FarcasterMessageType {\n CAST = 'CAST',\n REPLY = 'REPLY',\n}\n\nexport interface FarcasterGenericCastPayload extends Omit<MessagePayload, 'message'> {\n memory: Memory;\n cast: CastWithInteractions;\n}\n","import { createUniqueUuid, EventType, type IAgentRuntime, logger } from '@elizaos/core';\nimport type { FarcasterClient } from '../client';\nimport { standardCastHandlerCallback } from '../common/callbacks';\nimport { FARCASTER_SOURCE } from '../common/constants';\nimport { FarcasterConfig, FarcasterEventTypes, LastCast } from '../common/types';\nimport { lastCastCacheKey } from '../common/utils';\n\ninterface FarcasterCastParams {\n client: FarcasterClient;\n runtime: IAgentRuntime;\n config: FarcasterConfig;\n}\n\nexport class FarcasterCastManager {\n client: FarcasterClient;\n runtime: IAgentRuntime;\n fid: number;\n private timeout: ReturnType<typeof setTimeout> | undefined;\n private config: FarcasterConfig;\n private isRunning: boolean = false;\n\n constructor(opts: FarcasterCastParams) {\n this.client = opts.client;\n this.runtime = opts.runtime;\n this.config = opts.config;\n this.fid = this.config.FARCASTER_FID;\n }\n\n public async start() {\n if (this.isRunning || !this.config.ENABLE_CAST) {\n return;\n }\n\n this.isRunning = true;\n\n // never await this, it will block forever\n void this.runPeriodically();\n }\n\n public async stop() {\n if (this.timeout) clearTimeout(this.timeout);\n this.isRunning = false;\n }\n\n private calculateDelay(): { delay: number; randomMinutes: number } {\n const minMinutes = this.config.CAST_INTERVAL_MIN;\n const maxMinutes = this.config.CAST_INTERVAL_MAX;\n const randomMinutes = Math.floor(Math.random() * (maxMinutes - minMinutes + 1)) + minMinutes;\n const delay = randomMinutes * 60 * 1000;\n return { delay, randomMinutes };\n }\n\n private async runPeriodically(): Promise<void> {\n if (this.config.CAST_IMMEDIATELY) {\n await this.generateNewCast();\n }\n\n while (this.isRunning) {\n try {\n const lastPost = await this.runtime.getCache<LastCast>(lastCastCacheKey(this.fid));\n const lastPostTimestamp = lastPost?.timestamp ?? 0;\n const { delay, randomMinutes } = this.calculateDelay();\n\n if (Date.now() > lastPostTimestamp + delay) {\n await this.generateNewCast();\n }\n\n logger.log(`Next cast scheduled in ${randomMinutes} minutes`);\n await new Promise((resolve) => (this.timeout = setTimeout(resolve, delay)));\n } catch (error) {\n logger.error('[Farcaster] Error in periodic cast loop:', this.runtime.agentId, error);\n }\n }\n }\n\n private async generateNewCast() {\n logger.info('Generating new cast');\n try {\n const worldId = createUniqueUuid(this.runtime, this.fid.toString());\n const roomId = createUniqueUuid(this.runtime, `${this.fid}-home`);\n\n // callback for handling the actual posting\n const callback = standardCastHandlerCallback({\n client: this.client,\n runtime: this.runtime,\n config: this.config,\n roomId,\n onCompletion: async (casts, _memories) => {\n const lastCast = casts[casts.length - 1];\n await this.runtime.setCache<LastCast>(lastCastCacheKey(this.fid), {\n hash: lastCast.hash,\n timestamp: new Date(lastCast.timestamp).getTime(),\n });\n },\n });\n\n this.runtime.emitEvent([EventType.POST_GENERATED, FarcasterEventTypes.CAST_GENERATED], {\n runtime: this.runtime,\n callback,\n worldId,\n userId: this.runtime.agentId,\n roomId,\n source: FARCASTER_SOURCE,\n });\n } catch (error) {\n logger.error('Error generating new cast:', error);\n }\n }\n}\n","import { logger, parseBooleanFromText, type IAgentRuntime } from '@elizaos/core';\nimport { ZodError } from 'zod';\nimport {\n DEFAULT_MAX_CAST_LENGTH,\n DEFAULT_POLL_INTERVAL,\n DEFAULT_CAST_INTERVAL_MAX,\n DEFAULT_CAST_INTERVAL_MIN,\n} from './constants';\nimport { FarcasterConfig, FarcasterConfigSchema } from './types';\n\nfunction safeParseInt(value: string | undefined | null, defaultValue: number): number {\n if (!value) return defaultValue;\n const parsed = Number.parseInt(value, 10);\n return Number.isNaN(parsed) ? defaultValue : Math.max(1, parsed);\n}\n\nexport function hasFarcasterEnabled(runtime: IAgentRuntime): boolean {\n const fid = runtime.getSetting('FARCASTER_FID') || process.env.FARCASTER_FID;\n const neynarSignerUuid =\n runtime.getSetting('FARCASTER_SIGNER_UUID') || process.env.FARCASTER_SIGNER_UUID;\n const neynarApiKey =\n runtime.getSetting('FARCASTER_NEYNAR_API_KEY') || process.env.FARCASTER_NEYNAR_API_KEY;\n\n return fid && neynarSignerUuid && neynarApiKey;\n}\n\n/**\n * Constructs and validates a Farcaster configuration object using runtime settings and environment variables.\n *\n * Retrieves configuration values for the Farcaster client, applying defaults where necessary, and validates them against the {@link FarcasterConfigSchema}. Throws a detailed error if validation fails.\n *\n * @param runtime - The runtime environment providing configuration settings.\n * @returns The validated {@link FarcasterConfig} object.\n *\n * @throws {Error} If configuration validation fails, with details about each invalid field.\n */\nexport function validateFarcasterConfig(runtime: IAgentRuntime): FarcasterConfig {\n const fid = Number.parseInt(runtime.getSetting('FARCASTER_FID') || process.env.FARCASTER_FID);\n\n try {\n const farcasterConfig = {\n FARCASTER_DRY_RUN:\n runtime.getSetting('FARCASTER_DRY_RUN') ||\n parseBooleanFromText(process.env.FARCASTER_DRY_RUN || 'false'),\n\n FARCASTER_FID: Number.isNaN(fid) ? undefined : fid,\n\n MAX_CAST_LENGTH: safeParseInt(\n runtime.getSetting('MAX_CAST_LENGTH') || process.env.MAX_CAST_LENGTH,\n DEFAULT_MAX_CAST_LENGTH\n ),\n\n FARCASTER_POLL_INTERVAL: safeParseInt(\n runtime.getSetting('FARCASTER_POLL_INTERVAL') || process.env.FARCASTER_POLL_INTERVAL,\n DEFAULT_POLL_INTERVAL\n ),\n\n ENABLE_CAST:\n runtime.getSetting('ENABLE_CAST') ||\n parseBooleanFromText(process.env.ENABLE_CAST || 'true'),\n\n CAST_INTERVAL_MIN: safeParseInt(\n runtime.getSetting('CAST_INTERVAL_MIN') || process.env.CAST_INTERVAL_MIN,\n DEFAULT_CAST_INTERVAL_MIN\n ),\n\n CAST_INTERVAL_MAX: safeParseInt(\n runtime.getSetting('CAST_INTERVAL_MAX') || process.env.CAST_INTERVAL_MAX,\n DEFAULT_CAST_INTERVAL_MAX\n ),\n\n ENABLE_ACTION_PROCESSING:\n runtime.getSetting('ENABLE_ACTION_PROCESSING') ||\n parseBooleanFromText(process.env.ENABLE_ACTION_PROCESSING || 'false'),\n\n ACTION_INTERVAL: safeParseInt(\n runtime.getSetting('ACTION_INTERVAL') || process.env.ACTION_INTERVAL,\n 5\n ), // 5 minutes\n\n CAST_IMMEDIATELY:\n runtime.getSetting('CAST_IMMEDIATELY') ||\n parseBooleanFromText(process.env.CAST_IMMEDIATELY || 'false'),\n\n MAX_ACTIONS_PROCESSING: safeParseInt(\n runtime.getSetting('MAX_ACTIONS_PROCESSING') || process.env.MAX_ACTIONS_PROCESSING,\n 1\n ),\n\n FARCASTER_SIGNER_UUID:\n runtime.getSetting('FARCASTER_SIGNER_UUID') ||\n process.env.FARCASTER_SIGNER_UUID,\n\n FARCASTER_NEYNAR_API_KEY:\n runtime.getSetting('FARCASTER_NEYNAR_API_KEY') || process.env.FARCASTER_NEYNAR_API_KEY,\n\n FARCASTER_HUB_URL:\n runtime.getSetting('FARCASTER_HUB_URL') ||\n process.env.FARCASTER_HUB_URL ||\n 'hub.pinata.cloud',\n };\n\n const config = FarcasterConfigSchema.parse(farcasterConfig);\n\n const isDryRun = config.FARCASTER_DRY_RUN;\n\n // Log configuration on initialization\n\n logger.log('Farcaster Client Configuration:');\n logger.log(`- FID: ${config.FARCASTER_FID}`);\n logger.log(`- Dry Run Mode: ${isDryRun ? 'enabled' : 'disabled'}`);\n logger.log(`- Enable Cast: ${config.ENABLE_CAST ? 'enabled' : 'disabled'}`);\n\n if (config.ENABLE_CAST) {\n logger.log(\n `- Cast Interval: ${config.CAST_INTERVAL_MIN}-${config.CAST_INTERVAL_MAX} minutes`\n );\n logger.log(`- Cast Immediately: ${config.CAST_IMMEDIATELY ? 'enabled' : 'disabled'}`);\n }\n logger.log(`- Action Processing: ${config.ENABLE_ACTION_PROCESSING ? 'enabled' : 'disabled'}`);\n logger.log(`- Action Interval: ${config.ACTION_INTERVAL} minutes`);\n\n if (isDryRun) {\n logger.log('Farcaster client initialized in dry run mode - no actual casts should be posted');\n }\n\n return config;\n } catch (error) {\n if (error instanceof ZodError) {\n const errorMessages = error.errors\n .map((err) => `${err.path.join('.')}: ${err.message}`)\n .join('\\n');\n throw new Error(`Farcaster configuration validation failed:\\n${errorMessages}`);\n }\n throw error;\n }\n}\n","import {\n type UUID,\n logger,\n createUniqueUuid,\n} from '@elizaos/core';\nimport type { FarcasterClient } from '../client';\nimport { castUuid, neynarCastToCast } from '../common/utils';\nimport { FARCASTER_SOURCE } from '../common/constants';\nimport { FarcasterMessageType, FarcasterEventTypes } from '../common/types';\n\n// Simple interfaces for MessageService compatibility\ninterface Message {\n id: string;\n agentId: UUID;\n roomId: string;\n userId: string;\n username: string;\n text: string;\n type: FarcasterMessageType;\n timestamp: number;\n inReplyTo?: string;\n metadata?: any;\n}\n\ninterface GetMessagesOptions {\n roomId?: string;\n limit?: number;\n}\n\ninterface SendMessageOptions {\n agentId: UUID;\n roomId: string;\n text: string;\n type: string;\n replyToId?: string;\n metadata?: any;\n}\n\ninterface IMessageService {\n getMessages(options: GetMessagesOptions): Promise<Message[]>;\n sendMessage(options: SendMessageOptions): Promise<Message>;\n getMessage(messageId: string, agentId: UUID): Promise<Message | null>;\n}\n\nexport class FarcasterMessageService implements IMessageService {\n constructor(\n private client: FarcasterClient,\n private runtime: any\n ) {}\n\n async getMessages(options: GetMessagesOptions): Promise<Message[]> {\n try {\n const { roomId, limit = 20 } = options;\n\n // Get mentions and timeline\n const { timeline } = await this.client.getTimeline({\n fid: parseInt(\n this.runtime.getSetting('FARCASTER_FID') || this.runtime.config.FARCASTER_FID\n ),\n pageSize: limit,\n });\n\n const messages: Message[] = timeline\n .filter((cast) => {\n if (roomId) {\n const castRoomId = createUniqueUuid(this.runtime, cast.threadId || cast.hash);\n return castRoomId === roomId;\n }\n return true;\n })\n .map((cast) => ({\n id: castUuid({ hash: cast.hash, agentId: this.runtime.agentId }),\n agentId: this.runtime.agentId,\n roomId: createUniqueUuid(this.runtime, cast.threadId || cast.hash),\n userId: cast.profile.fid.toString(),\n username: cast.profile.username,\n text: cast.text,\n type: cast.inReplyTo ? FarcasterMessageType.REPLY : FarcasterMessageType.CAST,\n timestamp: cast.timestamp.getTime(),\n inReplyTo: cast.inReplyTo\n ? castUuid({ hash: cast.inReplyTo.hash, agentId: this.runtime.agentId })\n : undefined,\n metadata: {\n castHash: cast.hash,\n threadId: cast.threadId,\n authorFid: cast.authorFid,\n },\n }));\n\n return messages;\n } catch (error) {\n logger.error('[Farcaster] Error fetching messages:', error);\n return [];\n }\n }\n\n async sendMessage(options: SendMessageOptions): Promise<Message> {\n try {\n const { text, type, roomId, replyToId, agentId } = options;\n\n let inReplyTo: { hash: string; fid: number } | undefined = undefined;\n if (replyToId && type === FarcasterMessageType.REPLY) {\n // Extract cast hash from the message ID (which is a UUID)\n // In a real implementation, you'd need to maintain a mapping or extract from metadata\n const parentHash = options.metadata?.parentHash || replyToId;\n inReplyTo = {\n hash: parentHash as string,\n fid: parseInt(\n this.runtime.getSetting('FARCASTER_FID') || this.runtime.config.FARCASTER_FID\n ),\n };\n }\n\n const casts = await this.client.sendCast({\n content: { text },\n inReplyTo,\n });\n\n if (casts.length === 0) {\n throw new Error('No cast was created');\n }\n\n const cast = neynarCastToCast(casts[0]);\n const message: Message = {\n id: castUuid({ hash: cast.hash, agentId }),\n agentId,\n roomId,\n userId: cast.profile.fid.toString(),\n username: cast.profile.username,\n text: cast.text,\n type: type as FarcasterMessageType,\n timestamp: cast.timestamp.getTime(),\n inReplyTo: inReplyTo ? castUuid({ hash: inReplyTo.hash, agentId }) : undefined,\n metadata: {\n ...options.metadata,\n castHash: cast.hash,\n threadId: cast.threadId,\n authorFid: cast.authorFid,\n },\n };\n\n // Emit event for metadata tracking\n await this.runtime.emitEvent(FarcasterEventTypes.CAST_GENERATED, {\n runtime: this.runtime,\n castHash: cast.hash,\n message,\n threadId: cast.threadId,\n });\n\n return message;\n } catch (error) {\n logger.error('[Farcaster] Error sending message:', error);\n throw error;\n }\n }\n\n async deleteMessage(messageId: string, agentId: UUID): Promise<void> {\n // Farcaster doesn't support deleting casts via API\n logger.warn('[Farcaster] Cast deletion is not supported by the Farcaster API');\n }\n\n async getMessage(messageId: string, agentId: UUID): Promise<Message | null> {\n try {\n // Extract cast hash from the message ID\n // In production, you'd need to maintain a proper mapping\n const castHash = messageId; // Simplified for now\n\n const cast = await this.client.getCast(castHash);\n const farcasterCast = neynarCastToCast(cast);\n\n const message: Message = {\n id: castUuid({ hash: farcasterCast.hash, agentId }),\n agentId,\n roomId: createUniqueUuid(this.runtime, farcasterCast.threadId || farcasterCast.hash),\n userId: farcasterCast.profile.fid.toString(),\n username: farcasterCast.profile.username,\n text: farcasterCast.text,\n type: farcasterCast.inReplyTo ? FarcasterMessageType.REPLY : FarcasterMessageType.CAST,\n timestamp: farcasterCast.timestamp.getTime(),\n inReplyTo: farcasterCast.inReplyTo\n ? castUuid({ hash: farcasterCast.inReplyTo.hash, agentId })\n : undefined,\n metadata: {\n castHash: farcasterCast.hash,\n threadId: farcasterCast.threadId,\n authorFid: farcasterCast.authorFid,\n },\n };\n\n return message;\n } catch (error) {\n logger.error('[Farcaster] Error fetching message:', error);\n return null;\n }\n }\n\n async markAsRead(messageIds: string[], agentId: UUID): Promise<void> {\n // Farcaster doesn't have a read/unread concept\n logger.debug('[Farcaster] Mark as read is not applicable for Farcaster casts');\n }\n}\n","import {\n logger,\n type IAgentRuntime,\n type UUID,\n ModelType,\n createUniqueUuid,\n} from '@elizaos/core';\nimport type { FarcasterClient } from '../client';\nimport { castUuid, neynarCastToCast } from '../common/utils';\nimport { FARCASTER_SOURCE } from '../common/constants';\nimport type { Cast } from '../common/types';\n\n// Simple interface for Cast data\ninterface FarcasterCast {\n id: string;\n agentId: UUID;\n roomId: UUID;\n userId: string;\n username: string;\n text: string;\n timestamp: number;\n inReplyTo?: string;\n media?: any[];\n metadata?: any;\n}\n\nexport interface CastServiceInterface {\n getCasts(params: { agentId: UUID; limit?: number; cursor?: string }): Promise<FarcasterCast[]>;\n\n createCast(params: {\n agentId: UUID;\n roomId: UUID;\n text: string;\n media?: string[];\n replyTo?: {\n hash: string;\n fid: number;\n };\n }): Promise<FarcasterCast>;\n\n deleteCast(params: { agentId: UUID; castHash: string }): Promise<void>;\n\n likeCast(params: { agentId: UUID; castHash: string }): Promise<void>;\n\n unlikeCast(params: { agentId: UUID; castHash: string }): Promise<void>;\n\n recast(params: { agentId: UUID; castHash: string }): Promise<void>;\n\n unrecast(params: { agentId: UUID; castHash: string }): Promise<void>;\n\n getMentions(params: { agentId: UUID; limit?: number }): Promise<FarcasterCast[]>;\n}\n\nexport class FarcasterCastService implements CastServiceInterface {\n static serviceType = 'ICastService';\n\n constructor(\n private client: FarcasterClient,\n private runtime: IAgentRuntime\n ) {}\n\n /**\n * Get recent casts from the timeline\n */\n async getCasts(params: {\n agentId: UUID;\n limit?: number;\n cursor?: string;\n }): Promise<FarcasterCast[]> {\n try {\n const { timeline } = await this.client.getTimeline({\n fid: (this.runtime as any).config?.FARCASTER_FID || (this.runtime as any).settings?.FARCASTER_FID,\n pageSize: params.limit || 50,\n });\n\n return timeline.map((cast) => this.castToFarcasterCast(cast, params.agentId));\n } catch (error) {\n logger.error('Failed to get casts', { params, error });\n return [];\n }\n }\n\n /**\n * Create a new cast\n */\n async createCast(params: {\n agentId: UUID;\n roomId: UUID;\n text: string;\n media?: string[];\n replyTo?: {\n hash: string;\n fid: number;\n };\n }): Promise<FarcasterCast> {\n try {\n // Generate cast content using AI if needed\n let castText = params.text;\n\n if (!castText || castText.trim() === '') {\n castText = await this.generateCastContent();\n }\n\n // Ensure cast doesn't exceed character limit (320 characters for Farcaster)\n if (castText.length > 320) {\n castText = await this.truncateCast(castText);\n }\n\n // Send the cast\n const casts = await this.client.sendCast({\n content: { text: castText },\n inReplyTo: params.replyTo\n ? { hash: params.replyTo.hash, fid: params.replyTo.fid }\n : undefined,\n });\n\n if (casts.length === 0) {\n throw new Error('No cast was created');\n }\n\n const cast = neynarCastToCast(casts[0]);\n const farcasterCast: FarcasterCast = {\n id: castUuid({ hash: cast.hash, agentId: params.agentId }),\n agentId: params.agentId,\n roomId: params.roomId,\n userId: cast.profile.fid.toString(),\n username: cast.profile.username,\n text: cast.text,\n timestamp: cast.timestamp.getTime(),\n inReplyTo: params.replyTo?.hash,\n media: [], // TODO: Handle media upload when Farcaster API supports it\n metadata: {\n castHash: cast.hash,\n threadId: cast.threadId,\n authorFid: cast.authorFid,\n source: FARCASTER_SOURCE,\n },\n };\n\n // Store the cast in memory\n await this.storeCastInMemory(params.roomId, farcasterCast);\n\n return farcasterCast;\n } catch (error) {\n logger.error('Failed to create cast', { params, error });\n throw error;\n }\n }\n\n /**\n * Delete a cast\n */\n async deleteCast(params: { agentId: UUID; castHash: string }): Promise<void> {\n try {\n // Farcaster doesn't support deleting casts via API\n logger.warn('Cast deletion is not supported by the Farcaster API', { castHash: params.castHash });\n } catch (error) {\n logger.error('Failed to delete cast', { params, error });\n throw error;\n }\n }\n\n /**\n * Like a cast\n */\n async likeCast(params: { agentId: UUID; castHash: string }): Promise<void> {\n try {\n // TODO: Implement like functionality when Neynar API supports it\n logger.info('Like functionality not yet implemented for cast', { castHash: params.castHash });\n\n // In a full implementation, this would call the Neynar API\n // await this.client.neynar.likeCast({ signerUuid, castHash: params.castHash });\n } catch (error) {\n logger.error('Failed to like cast', { params, error });\n throw error;\n }\n }\n\n /**\n * Unlike a cast\n */\n async unlikeCast(params: { agentId: UUID; castHash: string }): Promise<void> {\n try {\n // TODO: Implement unlike functionality when Neynar API supports it\n logger.info('Unlike functionality not yet implemented for cast', { castHash: params.castHash });\n\n // In a full implementation, this would call the Neynar API\n // await this.client.neynar.unlikeCast({ signerUuid, castHash: params.castHash });\n } catch (error) {\n logger.error('Failed to unlike cast', { params, error });\n throw error;\n }\n }\n\n /**\n * Recast a cast\n */\n async recast(params: { agentId: UUID; castHash: string }): Promise<void> {\n try {\n // TODO: Implement recast functionality when Neynar API supports it\n logger.info('Recast functionality not yet implemented for cast', { castHash: params.castHash });\n\n // In a full implementation, this would call the Neynar API\n // await this.client.neynar.recast({ signerUuid, castHash: params.castHash });\n } catch (error) {\n logger.error('Failed to recast', { params, error });\n throw error;\n }\n }\n\n /**\n * Remove a recast\n */\n async unrecast(params: { agentId: UUID; castHash: string }): Promise<void> {\n try {\n // TODO: Implement unrecast functionality when Neynar API supports it\n logger.info('Remove recast functionality not yet implemented for cast', { castHash: params.castHash });\n\n // In a full implementation, this would call the Neynar API\n // await this.client.neynar.unrecast({ signerUuid, castHash: params.castHash });\n } catch (error) {\n logger.error('Failed to remove recast', { params, error });\n throw error;\n }\n }\n\n /**\n * Get mentions\n */\n async getMentions(params: { agentId: UUID; limit?: number }): Promise<FarcasterCast[]> {\n try {\n const mentions = await this.client.getMentions({\n fid: (this.runtime as any).config?.FARCASTER_FID || (this.runtime as any).settings?.FARCASTER_FID,\n pageSize: params.limit || 20,\n });\n\n return mentions.map((castWithInteractions) => {\n const cast = neynarCastToCast(castWithInteractions);\n return this.castToFarcasterCast(cast, params.agentId);\n });\n } catch (error) {\n logger.error('Failed to get mentions', { params, error });\n return [];\n }\n }\n\n /**\n * Generate cast content using AI\n */\n private async generateCastContent(): Promise<string> {\n const prompt = `Generate an interesting and engaging Farcaster cast. It should be conversational, authentic, and under 320 characters. Topics can include technology, AI, crypto, decentralized social media, or general observations about life.`;\n\n try {\n const response = await this.runtime.useModel(ModelType.TEXT_SMALL, {\n prompt,\n maxTokens: 100,\n });\n\n return response as string;\n } catch (error) {\n logger.error('Failed to generate cast content', { error });\n return 'Hello Farcaster! 👋';\n }\n }\n\n /**\n * Truncate cast to fit character limit\n */\n private async truncateCast(text: string): Promise<string> {\n const prompt = `Shorten this text to under 320 characters while keeping the main message intact: \"${text}\"`;\n\n try {\n const response = await this.runtime.useModel(ModelType.TEXT_SMALL, {\n prompt,\n maxTokens: 100,\n });\n\n const truncated = response as string;\n\n // Ensure it's actually under the limit\n if (truncated.length > 320) {\n return truncated.substring(0, 317) + '...';\n }\n\n return truncated;\n } catch (error) {\n logger.error('Failed to truncate cast', { error });\n return text.substring(0, 317) + '...';\n }\n }\n\n /**\n * Store cast in agent memory\n */\n private async storeCastInMemory(roomId: UUID, cast: FarcasterCast): Promise<void> {\n try {\n const memory = {\n id: createUniqueUuid(this.runtime, cast.id),\n agentId: this.runtime.agentId,\n content: {\n text: cast.text,\n castHash: cast.metadata?.castHash,\n castId: cast.id,\n author: cast.username,\n timestamp: cast.timestamp,\n },\n roomId,\n userId: cast.userId,\n createdAt: Date.now(),\n };\n\n // Store memory using the runtime's API\n // Note: The exact method may vary based on ElizaOS version\n if (typeof (this.runtime as any).storeMemory === 'function') {\n await (this.runtime as any).storeMemory(memory);\n } else if (\n (this.runtime as any).memory &&\n typeof (this.runtime as any).memory.create === 'function'\n ) {\n await (this.runtime as any).memory.create(memory);\n } else {\n logger.warn('Memory storage method not available in runtime');\n }\n } catch (error) {\n logger.error('Failed to store cast in memory', { error });\n }\n }\n\n /**\n * Convert internal Cast type to FarcasterCast\n */\n private castToFarcasterCast(cast: Cast, agentId: UUID): FarcasterCast {\n return {\n id: castUuid({ hash: cast.hash, agentId }),\n agentId,\n roomId: createUniqueUuid(this.runtime, cast.threadId || cast.hash),\n userId: cast.profile.fid.toString(),\n username: cast.profile.username,\n text: cast.text,\n timestamp: cast.timestamp.getTime(),\n media: [], // Farcaster casts can have embedded media but not in our Cast type\n metadata: {\n castHash: cast.hash,\n threadId: cast.threadId,\n authorFid: cast.authorFid,\n source: FARCASTER_SOURCE,\n stats: cast.stats,\n },\n };\n }\n}\n","import {\n type IAgentRuntime,\n ModelType,\n type TestSuite,\n createUniqueUuid,\n logger,\n type TestCase,\n} from '@elizaos/core';\nimport { FARCASTER_SERVICE_NAME } from '../common/constants';\nimport { FidRequest, FarcasterMessageType } from '../common/types';\nimport { FarcasterAgentManager } from '../managers/agent';\nimport { TEST_IMAGE } from './test-utils';\nimport { farcasterE2EScenarios } from './e2e/scenarios';\n\n/**\n * Represents a Test Suite for Farcaster functionality.\n * This class implements the TestSuite interface.\n * It contains various test cases related to Farcaster operations such as initializing the client,\n * fetching profile, fetching casts, posting casts, and handling cast interactions.\n */\nexport class FarcasterTestSuite implements TestSuite {\n name = 'Farcaster Plugin Tests';\n description = 'Test suite for Farcaster plugin functionality';\n private manager: FarcasterAgentManager | null = null;\n tests: TestCase[];\n\n /**\n * Constructor for TestSuite class.\n * Initializes an array of test functions to be executed.\n */\n constructor() {\n // Check if we have real credentials\n const hasRealCredentials = !!(\n process.env.FARCASTER_FID && \n process.env.FARCASTER_SIGNER_UUID && \n process.env.FARCASTER_NEYNAR_API_KEY\n );\n \n logger.info('=== Farcaster Test Suite Configuration ===');\n logger.info(`FID: ${process.env.FARCASTER_FID ? '✓ Found' : '✗ Missing'}`);\n logger.info(`Signer UUID: ${process.env.FARCASTER_SIGNER_UUID ? '✓ Found' : '✗ Missing'}`);\n logger.info(`API Key: ${process.env.FARCASTER_NEYNAR_API_KEY ? '✓ Found' : '✗ Missing'}`);\n logger.info(`Dry Run: ${process.env.FARCASTER_DRY_RUN || 'not set (defaults to false)'}`);\n logger.info('=========================================');\n \n if (hasRealCredentials) {\n logger.success('✅ Running with real Farcaster credentials');\n \n // Use the E2E scenarios for real testing\n this.tests = farcasterE2EScenarios;\n } else {\n logger.warn('⚠️ Farcaster credentials not found in environment variables');\n logger.warn('⚠️ Tests will run in mock mode');\n logger.warn('⚠️ To run real tests, set FARCASTER_FID, FARCASTER_SIGNER_UUID, and FARCASTER_NEYNAR_API_KEY');\n \n // Override tests with mock versions\n this.tests = [\n {\n name: 'Mock: Check Farcaster Configuration',\n fn: this.testMockConfiguration.bind(this),\n },\n {\n name: 'Mock: Service Initialization',\n fn: this.testMockServiceInit.bind(this),\n },\n ];\n }\n }\n\n /**\n * Test that checks if Farcaster is properly configured\n */\n async testMockConfiguration(runtime: IAgentRuntime) {\n logger.info('Running mock configuration test');\n \n const fid = runtime.getSetting('FARCASTER_FID');\n const signerUuid = runtime.getSetting('FARCASTER_SIGNER_UUID');\n const apiKey = runtime.getSetting('FARCASTER_NEYNAR_API_KEY');\n \n logger.info('Runtime settings check:');\n logger.info(`- FID from runtime: ${fid ? 'Found' : 'Not found'}`);\n logger.info(`- Signer UUID from runtime: ${signerUuid ? 'Found' : 'Not found'}`);\n logger.info(`- API Key from runtime: ${apiKey ? 'Found' : 'Not found'}`);\n \n if (!fid || !signerUuid || !apiKey) {\n logger.info('Farcaster not configured - this is expected in mock mode');\n logger.info('To enable real tests, configure the following:');\n logger.info('- FARCASTER_FID: Your Farcaster ID');\n logger.info('- FARCASTER_SIGNER_UUID: Neynar signer UUID');\n logger.info('- FARCASTER_NEYNAR_API_KEY: Neynar API key');\n }\n }\n\n /**\n * Test service initialization without real credentials\n */\n async testMockServiceInit(runtime: IAgentRuntime) {\n logger.info('Running mock service initialization test');\n \n try {\n const service = runtime.getService(FARCASTER_SERVICE_NAME) as any;\n \n if (!service) {\n logger.info('Farcaster service not available - this is expected without credentials');\n return;\n }\n \n logger.info('Farcaster service is registered but may not be fully initialized');\n \n // Test that service methods exist\n if (typeof service.getMessageService === 'function') {\n logger.info('✓ getMessageService method exists');\n }\n \n if (typeof service.getPostService === 'function') {\n logger.info('✓ getPostService method exists');\n }\n \n if (typeof service.healthCheck === 'function') {\n logger.info('✓ healthCheck method exists');\n }\n \n } catch (error) {\n logger.info('Service initialization check completed');\n }\n }\n\n /**\n * Asynchronously initializes the Farcaster client for the provided agent runtime.\n *\n * @param {IAgentRuntime} runtime - The agent runtime to use for initializing the Farcaster client.\n * @throws {Error} If the Farcaster client manager is not found or if the Farcaster client fails to initialize.\n */\n async testInitializingClient(runtime: IAgentRuntime) {\n try {\n const service = runtime.getService(FARCASTER_SERVICE_NAME) as any;\n if (!service) {\n throw new Error('Farcaster service not found');\n }\n\n this.manager = service.managers.get(runtime.agentId);\n\n if (this.manager) {\n logger.debug('FarcasterAgentManager initialized successfully.');\n } else {\n throw new Error('FarcasterAgentManager failed to initialize.');\n }\n } catch (error) {\n throw new Error(`Error in initializing Farcaster client: ${error}`);\n }\n }\n\n /**\n * Asynchronously fetches the profile of a user from Farcaster using the given runtime.\n *\n * @param {IAgentRuntime} runtime The runtime to use for fetching the profile.\n * @returns {Promise<void>} A Promise that resolves when the profile is successfully fetched, or rejects with an error.\n */\n async testFetchProfile(runtime: IAgentRuntime) {\n try {\n if (!this.manager) {\n throw new Error('FarcasterAgentManager not initialized');\n }\n\n const fid = parseInt(runtime.getSetting('FARCASTER_FID') as string, 10);\n if (!fid || isNaN(fid)) {\n throw new Error('Invalid FID in settings.');\n }\n\n const profile = await this.manager.client.getProfile(fid);\n if (!profile || !profile.fid) {\n throw new Error('Profile fetch failed.');\n }\n logger.log('Successfully fetched Farcaster profile:', profile);\n } catch (error) {\n throw new Error(`Error fetching Farcaster profile: ${error}`);\n }\n }\n\n /**\n * Asynchronously fetches the timeline from the Farcaster client.\n *\n * @param {IAgentRuntime} runtime - The agent runtime object.\n * @throws {Error} If there are no casts in the timeline.\n * @throws {Error} If an error occurs while fetching the timeline.\n */\n async testFetchTimeline(runtime: IAgentRuntime) {\n try {\n if (!this.manager) {\n throw new Error('FarcasterAgentManager not initialized');\n }\n\n const fid = parseInt(runtime.getSetting('FARCASTER_FID') as string, 10);\n if (!fid || isNaN(fid)) {\n throw new Error('Invalid FID in settings.');\n }\n\n const request: FidRequest = { fid, pageSize: 5 };\n const result = await this.manager.client.getTimeline(request);\n\n if (!result.timeline || result.timeline.length === 0) {\n throw new Error('No casts in timeline.');\n }\n logger.log(`Successfully fetched ${result.timeline.length} casts from timeline.`);\n } catch (error) {\n throw new Error(`Error fetching timeline: ${error}`);\n }\n }\n\n /**\n * Asynchronously posts a test cast using the Farcaster API.\n *\n * @param {IAgentRuntime} runtime - The agent runtime object.\n * @returns {Promise<void>} A Promise that resolves when the cast is successfully posted.\n * @throws {Error} If there is an error posting the cast.\n */\n async testPostCast(runtime: IAgentRuntime) {\n try {\n if (!this.manager) {\n throw new Error('FarcasterAgentManager not initialized');\n }\n\n const castText = await this.generateRandomCastContent(runtime);\n const result = await this.manager.client.sendCast({\n content: { text: castText },\n });\n\n if (!result || result.length === 0) {\n throw new Error('Cast posting failed.');\n }\n logger.success('Successfully posted a test cast.');\n } catch (error) {\n throw new Error(`Error posting a cast: ${error}`);\n }\n }\n\n /**\n * Asynchronously posts an image cast on Farcaster using the provided runtime and cast content.\n * Note: This might need updating based on how images are actually handled in sendCast\n *\n * @param {IAgentRuntime} runtime - The runtime environment for the action.\n * @returns {Promise<void>} A Promise that resolves when the cast is successfully posted.\n * @throws {Error} If there is an error posting the cast.\n */\n async testPostImageCast(runtime: IAgentRuntime) {\n try {\n if (!this.manager) {\n throw new Error('FarcasterAgentManager not initialized');\n }\n\n const castText = await this.generateRandomCastContent(runtime, 'image_post');\n // This implementation might need to be updated based on how images are actually handled\n const result = await this.manager.client.sendCast({\n content: {\n text: castText,\n media: [TEST_IMAGE],\n },\n });\n\n if (!result || result.length === 0) {\n throw new Error('Cast with image posting failed.');\n }\n logger.success('Successfully posted a test cast with image.');\n } catch (error) {\n throw new Error(`Error posting a cast with image: ${error}`);\n }\n }\n\n /**\n * Asynchronously handles a fake cast response using the given runtime.\n *\n * @param {IAgentRuntime} runtime - The runtime object for the agent\n * @returns {Promise<void>} - A promise that resolves when the cast response is handled\n * @throws {Error} - If there is an error handling the cast response\n */\n async testHandleCastResponse(runtime: IAgentRuntime) {\n try {\n if (!this.manager) {\n throw new Error('FarcasterAgentManager not initialized');\n }\n\n // For testing purposes, we'll just mock the event emission instead of calling the actual handler\n // This avoids dealing with complex type requirements\n const testCast = {\n hash: '0x12345',\n text: '@testUser What do you think about AI?',\n authorFid: 123,\n profile: {\n fid: 123,\n username: 'randomUser',\n name: 'Random User',\n },\n timestamp: new Date(),\n };\n\n // Create a mock memory for the test\n const memoryId = createUniqueUuid(runtime, testCast.hash);\n const memory = {\n id: memoryId,\n agentId: runtime.agentId,\n content: {\n text: testCast.text,\n },\n entityId: createUniqueUuid(runtime, String(testCast.authorFid)),\n roomId: createUniqueUuid(runtime, 'test-room'),\n createdAt: testCast.timestamp.getTime(),\n };\n\n // Emit an event to simulate the interaction\n runtime.emitEvent('farcaster.mention_received', {\n runtime,\n memory,\n cast: testCast,\n source: 'farcaster',\n });\n\n logger.success('Successfully simulated cast response handling');\n } catch (error) {\n throw new Error(`Error handling cast response: ${error}`);\n }\n }\n\n /**\n * Generates random content for a cast based on the given context.\n *\n * @param {IAgentRuntime} runtime - The runtime environment.\n * @param {string} context - Optional context for the content generation.\n * @returns {Promise<string>} A promise that resolves to the generated cast content.\n */\n private async generateRandomCastContent(\n runtime: IAgentRuntime,\n context = 'general'\n ): Promise<string> {\n const prompt = `Generate a short, interesting cast about ${context} (max 280 chars).`;\n // Use TEXT_SMALL instead of CHAT since that seems to be the correct ModelType\n const result = await runtime.useModel(ModelType.TEXT_SMALL, {\n prompt,\n });\n\n // Truncate the result to ensure it doesn't exceed 280 characters\n return (result as string).substring(0, 280);\n }\n\n /**\n * Tests the MessageService functionality\n *\n * @param {IAgentRuntime} runtime - The runtime environment.\n * @returns {Promise<void>} A promise that resolves when the test is complete.\n */\n async testMessageService(runtime: IAgentRuntime) {\n try {\n const service = runtime.getService(FARCASTER_SERVICE_NAME) as any;\n if (!service) {\n throw new Error('Farcaster service not found');\n }\n\n const messageService = service.getMessageService(runtime.agentId);\n if (!messageService) {\n throw new Error('MessageService not initialized');\n }\n\n // Test getMessages\n const messages = await messageService.getMessages({\n agentId: runtime.agentId,\n limit: 5,\n });\n\n logger.log(`Retrieved ${messages.length} messages from MessageService`);\n\n // Test sendMessage\n const testText = await this.generateRandomCastContent(runtime, 'message_service_test');\n const message = await messageService.sendMessage({\n agentId: runtime.agentId,\n roomId: createUniqueUuid(runtime, 'test-room'),\n text: testText,\n type: FarcasterMessageType.CAST,\n });\n\n if (!message || !message.id) {\n throw new Error('Failed to send message via MessageService');\n }\n\n logger.success('MessageService test completed successfully');\n } catch (error) {\n throw new Error(`Error testing MessageService: ${error}`);\n }\n }\n\n /**\n * Tests the PostService functionality\n *\n * @param {IAgentRuntime} runtime - The runtime environment.\n * @returns {Promise<void>} A promise that resolves when the test is complete.\n */\n async testPostService(runtime: IAgentRuntime) {\n try {\n const service = runtime.getService(FARCASTER_SERVICE_NAME) as any;\n if (!service) {\n throw new Error('Farcaster service not found');\n }\n\n const castService = service.getCastService(runtime.agentId);\n if (!castService) {\n throw new Error('CastService not initialized');\n }\n\n // Test getCasts\n const casts = await castService.getCasts({\n agentId: runtime.agentId,\n limit: 5,\n });\n\n logger.log(`Retrieved ${casts.length} casts from CastService`);\n\n // Test createCast\n const testText = await this.generateRandomCastContent(runtime, 'cast_service_test');\n const cast = await castService.createCast({\n agentId: runtime.agentId,\n roomId: createUniqueUuid(runtime, 'test-room'),\n text: testText,\n });\n\n if (!cast || !cast.id) {\n throw new Error('Failed to create cast via CastService');\n }\n\n logger.success('CastService test completed successfully');\n } catch (error) {\n throw new Error(`Error testing PostService: ${error}`);\n }\n }\n\n /**\n * Tests real account posting functionality\n *\n * @param {IAgentRuntime} runtime - The runtime environment.\n * @returns {Promise<void>} A promise that resolves when the test is complete.\n */\n async testRealAccountPosting(runtime: IAgentRuntime) {\n try {\n const service = runtime.getService(FARCASTER_SERVICE_NAME) as any;\n if (!service) {\n throw new Error('Farcaster service not found');\n }\n\n const postService = service.getPostService(runtime.agentId);\n if (!postService) {\n throw new Error('PostService not initialized');\n }\n\n // Create multiple posts to test real functionality\n const testPosts = [\n 'Testing ElizaOS Farcaster integration! 🚀 #ElizaOS',\n 'AI agents are the future of social media engagement 🤖',\n 'Building amazing things with the ElizaOS framework 💻',\n ];\n\n for (const text of testPosts) {\n const post = await postService.createPost({\n agentId: runtime.agentId,\n roomId: createUniqueUuid(runtime, 'real-test'),\n text,\n });\n\n if (!post || !post.id || !post.metadata?.castHash) {\n throw new Error('Failed to create real post');\n }\n\n logger.success(`Posted real cast: ${post.metadata.castHash}`);\n \n // Wait a bit between posts to avoid rate limiting\n await new Promise(resolve => setTimeout(resolve, 1000));\n }\n\n logger.success('Real account posting test completed successfully');\n } catch (error) {\n throw new Error(`Error testing real account posting: ${error}`);\n }\n }\n\n /**\n * Tests real account interactions (mentions, replies, etc)\n *\n * @param {IAgentRuntime} runtime - The runtime environment.\n * @returns {Promise<void>} A promise that resolves when the test is complete.\n */\n async testRealAccountInteractions(runtime: IAgentRuntime) {\n try {\n const service = runtime.getService(FARCASTER_SERVICE_NAME) as any;\n if (!service) {\n throw new Error('Farcaster service not found');\n }\n\n const postService = service.getPostService(runtime.agentId);\n const messageService = service.getMessageService(runtime.agentId);\n \n if (!postService || !messageService) {\n throw new Error('Services not initialized');\n }\n\n // Get recent mentions\n const mentions = await postService.getMentions(runtime.agentId, { limit: 10 });\n logger.log(`Found ${mentions.length} mentions`);\n\n // Get timeline posts\n const timeline = await postService.getPosts({\n agentId: runtime.agentId,\n limit: 20,\n });\n logger.log(`Found ${timeline.length} timeline posts`);\n\n // If we have posts, try to reply to one\n if (timeline.length > 0) {\n const targetPost = timeline[0];\n if (targetPost.metadata?.castHash) {\n const reply = await messageService.sendMessage({\n agentId: runtime.agentId,\n roomId: targetPost.roomId,\n text: 'Great post! Testing real interactions with ElizaOS 🎉',\n type: FarcasterMessageType.REPLY,\n replyToId: targetPost.metadata.castHash,\n metadata: {\n parentHash: targetPost.metadata.castHash,\n },\n });\n\n if (reply && reply.metadata?.castHash) {\n logger.success(`Replied to cast with: ${reply.metadata.castHash}`);\n }\n }\n }\n\n logger.success('Real account interactions test completed successfully');\n } catch (error) {\n throw new Error(`Error testing real account interactions: ${error}`);\n }\n }\n\n /**\n * Tests message metadata tracking functionality\n *\n * @param {IAgentRuntime} runtime - The runtime environment.\n * @returns {Promise<void>} A promise that resolves when the test is complete.\n */\n async testMessageMetadataTracking(runtime: IAgentRuntime) {\n try {\n const service = runtime.getService(FARCASTER_SERVICE_NAME) as any;\n if (!service) {\n throw new Error('Farcaster service not found');\n }\n\n const messageService = service.getMessageService(runtime.agentId);\n if (!messageService) {\n throw new Error('MessageService not initialized');\n }\n\n // Send a message and track its metadata\n const testMessage = await messageService.sendMessage({\n agentId: runtime.agentId,\n roomId: createUniqueUuid(runtime, 'metadata-test'),\n text: 'Testing metadata tracking with ElizaOS',\n type: FarcasterMessageType.CAST,\n });\n\n if (!testMessage || !testMessage.metadata?.castHash) {\n throw new Error('Failed to send test message');\n }\n\n const castHash = testMessage.metadata.castHash;\n logger.log(`Sent message with cast hash: ${castHash}`);\n\n // Verify we can retrieve the message by its hash\n const retrievedMessage = await messageService.getMessage(castHash, runtime.agentId);\n \n if (!retrievedMessage) {\n throw new Error('Failed to retrieve message by hash');\n }\n\n // Verify metadata is properly stored\n if (retrievedMessage.metadata?.castHash !== castHash) {\n throw new Error('Metadata mismatch in retrieved message');\n }\n\n logger.success('Message metadata tracking test completed successfully');\n } catch (error) {\n throw new Error(`Error testing message metadata tracking: ${error}`);\n }\n }\n}\n","import type { FarcasterClient } from '../client';\nimport type { Cast, Profile } from '../common/types';\nimport type { TestInteraction } from './types';\n\nexport function createTestInteraction(cast: Cast, profile: Profile): TestInteraction | null {\n // Only create interaction if there is significant engagement\n if (\n !cast.stats ||\n (cast.stats.recasts === 0 && cast.stats.replies === 0 && cast.stats.likes === 0)\n ) {\n return null;\n }\n\n // Simple heuristic: if the cast has more replies, reply to it\n if (cast.stats.replies > cast.stats.recasts && cast.stats.replies > cast.stats.likes) {\n return {\n type: 'REPLY',\n castId: cast.hash,\n content: 'Interesting perspective!',\n };\n }\n\n // If it has more likes, like it\n if (cast.stats.likes > cast.stats.recasts && cast.stats.likes > cast.stats.replies) {\n return {\n type: 'LIKE',\n castId: cast.hash,\n };\n }\n\n // Otherwise, recast it\n return {\n type: 'RECAST',\n castId: cast.hash,\n };\n}\n\nexport async function handleTestInteraction(client: FarcasterClient, interaction: TestInteraction) {\n // Validate the interaction\n if (!interaction.castId) {\n throw new Error(`Cast ID required for ${interaction.type.toLowerCase()}`);\n }\n if (interaction.type === 'REPLY' && !interaction.content) {\n throw new Error('Cast ID and content required for reply');\n }\n \n // Create a mock response that matches what the tests expect\n const mockResponse = {\n success: true,\n cast: {\n hash: `interaction-${Date.now()}`,\n text: interaction.type === 'REPLY' ? interaction.content || '' : '',\n parent_hash: interaction.castId,\n timestamp: new Date().toISOString(),\n }\n };\n \n // Since we can't access private properties, return a mock response\n // In real usage, this would go through the client's public methods\n return Promise.resolve(mockResponse);\n}\n\nexport async function createTestCast(client: FarcasterClient, content: string) {\n if (!content) {\n throw new Error('Cast content cannot be empty');\n }\n if (content.length > 320) {\n throw new Error('Cast content too long');\n }\n \n // Since we can't access private properties, use the public sendCast method\n const result = await client.sendCast({ content: { text: content } });\n if (result.length > 0) {\n return { success: true, cast: result[0] };\n }\n throw new Error('Failed to create cast');\n}\n\nexport const TEST_IMAGE_URL =\n 'https://github.com/elizaOS/awesome-eliza/blob/main/assets/eliza-logo.jpg?raw=true';\n\nexport const TEST_IMAGE = {\n id: 'mock-image-id',\n text: 'mock image',\n description: 'mock image descirption',\n source: 'mock image source',\n url: TEST_IMAGE_URL,\n title: 'mock image',\n contentType: 'image/jpeg',\n alt_text: 'mock image',\n};\n","import { type IAgentRuntime, logger, createUniqueUuid, type TestCase } from '@elizaos/core';\nimport { FARCASTER_SERVICE_NAME } from '../../common/constants.js';\nimport type { FarcasterService } from '../../service.js';\nimport { FarcasterMessageType } from '../../common/types.js';\n\n// E2E Test Scenarios as TestCase functions\nexport const farcasterE2EScenarios: TestCase[] = [\n {\n name: 'Farcaster Plugin - Agent Introduction',\n async fn(runtime: IAgentRuntime): Promise<void> {\n const service = runtime.getService(FARCASTER_SERVICE_NAME) as FarcasterService;\n if (!service) {\n throw new Error('Farcaster service not initialized');\n }\n\n // Test 1: Post introduction\n const postService = service.getPostService(runtime.agentId);\n if (!postService) {\n throw new Error('PostService not available');\n }\n\n const introText = `Hello Farcaster! I'm ${runtime.character.name}, an AI agent powered by ElizaOS. Looking forward to connecting with you all! 🤖`;\n \n const cast = await postService.createPost({\n agentId: runtime.agentId,\n roomId: createUniqueUuid(runtime, 'farcaster-timeline'),\n text: introText,\n });\n\n if (!cast || !cast.id || !cast.text || !cast.metadata?.castHash) {\n throw new Error('Failed to create introduction cast');\n }\n \n logger.info(`Posted introduction cast: ${cast.metadata.castHash}`);\n\n // Test 2: Fetch profile\n const manager = service.getActiveManagers().get(runtime.agentId);\n if (!manager) {\n throw new Error('Manager not found for agent');\n }\n\n const fid = parseInt(runtime.getSetting('FARCASTER_FID') as string);\n const profile = await manager.client.getProfile(fid);\n\n if (!profile || profile.fid !== fid) {\n throw new Error('Profile fetch failed or FID mismatch');\n }\n \n logger.info(`Agent profile verified: @${profile.username} (FID: ${profile.fid})`);\n }\n },\n\n {\n name: 'Farcaster Plugin - Timeline Monitoring',\n\n async fn(runtime: IAgentRuntime): Promise<void> {\n const service = runtime.getService(FARCASTER_SERVICE_NAME) as FarcasterService;\n if (!service) {\n throw new Error('Farcaster service not initialized');\n }\n\n const postService = service.getPostService(runtime.agentId);\n if (!postService) {\n throw new Error('PostService not available');\n }\n\n // Test 1: Fetch timeline casts\n const casts = await postService.getPosts({\n agentId: runtime.agentId,\n limit: 10,\n });\n\n if (!Array.isArray(casts)) {\n throw new Error('getPosts did not return an array');\n }\n \n logger.info(`Found ${casts.length} casts in timeline`);\n \n if (casts.length > 0) {\n const firstCast = casts[0];\n if (!firstCast.id || !firstCast.username || !firstCast.text) {\n throw new Error('Cast missing required fields');\n }\n logger.info(`Latest cast by @${firstCast.username}: ${firstCast.text.substring(0, 50)}...`);\n }\n\n // Test 2: Fetch mentions\n const mentions = await postService.getMentions(runtime.agentId, { limit: 5 });\n \n if (!Array.isArray(mentions)) {\n throw new Error('getMentions did not return an array');\n }\n \n logger.info(`Found ${mentions.length} mentions`);\n }\n },\n\n {\n name: 'Farcaster Plugin - Message Send and Retrieve',\n async fn(runtime: IAgentRuntime): Promise<void> {\n const service = runtime.getService(FARCASTER_SERVICE_NAME) as FarcasterService;\n if (!service) {\n throw new Error('Farcaster service not initialized');\n }\n\n const messageService = service.getMessageService(runtime.agentId);\n if (!messageService) {\n throw new Error('MessageService not available');\n }\n\n const roomId = createUniqueUuid(runtime, 'test-conversation');\n \n // Send a new cast\n const message = await messageService.sendMessage({\n agentId: runtime.agentId,\n roomId,\n text: 'Testing message send and retrieve with ElizaOS Farcaster plugin! 🧪',\n type: FarcasterMessageType.CAST,\n });\n\n if (!message || !message.id || !message.metadata?.castHash) {\n throw new Error('Failed to send message or missing metadata');\n }\n \n logger.info(`Sent cast with hash: ${message.metadata.castHash}`);\n \n // Retrieve the message\n const castHash = message.metadata.castHash as string;\n const retrieved = await messageService.getMessage(castHash, runtime.agentId);\n \n if (!retrieved || retrieved.text !== message.text) {\n throw new Error('Failed to retrieve message or content mismatch');\n }\n \n logger.info('Successfully retrieved message by hash');\n }\n },\n\n {\n name: 'Farcaster Plugin - Reply Threading',\n async fn(runtime: IAgentRuntime): Promise<void> {\n const service = runtime.getService(FARCASTER_SERVICE_NAME) as FarcasterService;\n if (!service) {\n throw new Error('Farcaster service not initialized');\n }\n\n const messageService = service.getMessageService(runtime.agentId);\n const postService = service.getPostService(runtime.agentId);\n \n if (!messageService || !postService) {\n throw new Error('Services not available');\n }\n\n // First create a cast to reply to\n const originalCast = await postService.createPost({\n agentId: runtime.agentId,\n roomId: createUniqueUuid(runtime, 'reply-test'),\n text: 'This is a test cast for reply threading 🧵',\n });\n\n if (!originalCast || !originalCast.metadata?.castHash) {\n throw new Error('Failed to create original cast');\n }\n\n // Send a reply\n const reply = await messageService.sendMessage({\n agentId: runtime.agentId,\n roomId: originalCast.roomId,\n text: 'This is a test reply maintaining thread context! 💬',\n type: 'REPLY' as any,\n replyToId: originalCast.metadata.castHash,\n metadata: {\n parentHash: originalCast.metadata.castHash,\n },\n });\n \n if (!reply || !reply.inReplyTo || !reply.metadata?.castHash) {\n throw new Error('Failed to create reply or missing thread context');\n }\n \n logger.info(`Created reply ${reply.metadata.castHash} to ${originalCast.metadata.castHash}`);\n }\n },\n\n {\n name: 'Farcaster Plugin - Action Execution',\n async fn(runtime: IAgentRuntime): Promise<void> {\n // Import the action directly\n const { sendCastAction } = await import('../../actions/sendCast.js');\n \n // Create a mock message requesting a cast\n const mockMessage = {\n id: createUniqueUuid(runtime, 'test-message'),\n agentId: runtime.agentId,\n roomId: createUniqueUuid(runtime, 'test-room'),\n entityId: runtime.agentId,\n content: {\n text: 'Can you post about the ElizaOS framework on Farcaster?',\n },\n createdAt: Date.now(),\n };\n \n // Validate the action\n const shouldExecute = await sendCastAction.validate(runtime, mockMessage);\n if (!shouldExecute) {\n throw new Error('SEND_CAST action validation failed');\n }\n \n // Execute the action\n const result = await sendCastAction.handler(runtime, mockMessage);\n if (!result) {\n throw new Error('SEND_CAST action execution failed');\n }\n \n logger.info('Successfully validated and executed SEND_CAST action');\n }\n },\n\n {\n name: 'Farcaster Plugin - Provider Context',\n async fn(runtime: IAgentRuntime): Promise<void> {\n // Import providers directly\n const { farcasterProfileProvider } = await import('../../providers/profileProvider.js');\n const { farcasterTimelineProvider } = await import('../../providers/timelineProvider.js');\n \n const mockMessage = {\n id: createUniqueUuid(runtime, 'test-message'),\n agentId: runtime.agentId,\n roomId: createUniqueUuid(runtime, 'test-room'),\n entityId: runtime.agentId,\n content: { text: 'test' },\n createdAt: Date.now(),\n };\n \n // Test profile provider\n const profileContext = await farcasterProfileProvider.get(runtime, mockMessage, { values: [], data: {}, text: '' });\n \n if (!profileContext || !profileContext.text || profileContext.data?.available === undefined) {\n throw new Error('Profile provider returned invalid context');\n }\n \n logger.info(`Profile provider: ${profileContext.text}`);\n \n // Test timeline provider\n const timelineContext = await farcasterTimelineProvider.get(runtime, mockMessage, { values: [], data: {}, text: '' });\n \n if (!timelineContext || !timelineContext.text || timelineContext.data?.available === undefined) {\n throw new Error('Timeline provider returned invalid context');\n }\n \n logger.info(`Timeline provider: ${timelineContext.text}`);\n }\n },\n\n {\n name: 'Farcaster Plugin - Rate Limit Handling',\n async fn(runtime: IAgentRuntime): Promise<void> {\n const service = runtime.getService(FARCASTER_SERVICE_NAME) as FarcasterService;\n if (!service) {\n throw new Error('Farcaster service not initialized');\n }\n\n const messageService = service.getMessageService(runtime.agentId);\n if (!messageService) {\n throw new Error('MessageService not available');\n }\n \n // Send multiple messages quickly\n const promises: Promise<any>[] = [];\n for (let i = 0; i < 3; i++) {\n promises.push(\n messageService.sendMessage({\n agentId: runtime.agentId,\n roomId: createUniqueUuid(runtime, 'rate-limit-test'),\n text: `Rate limit test message ${i + 1}`,\n type: FarcasterMessageType.CAST,\n }).catch(error => {\n logger.warn(`Expected rate limit error: ${error.message}`);\n return null;\n })\n );\n }\n \n const results = await Promise.all(promises);\n const successfulSends = results.filter(r => r !== null);\n \n if (successfulSends.length === 0) {\n throw new Error('All messages failed - check if rate limiting is too strict');\n }\n \n logger.info(`Successfully sent ${successfulSends.length} out of ${promises.length} messages`);\n }\n },\n\n {\n name: 'Farcaster Plugin - Service Health Check',\n async fn(runtime: IAgentRuntime): Promise<void> {\n const service = runtime.getService(FARCASTER_SERVICE_NAME) as FarcasterService;\n if (!service) {\n throw new Error('Farcaster service not initialized');\n }\n\n const health = await service.healthCheck();\n \n if (!health || health.healthy === undefined || !health.details) {\n throw new Error('Health check returned invalid data');\n }\n \n logger.info(`Service health: ${health.healthy ? 'Healthy' : 'Unhealthy'}`);\n logger.info(`Active managers: ${health.details.activeManagers}`);\n \n if (!health.healthy) {\n logger.warn('Service reported unhealthy status:', health.details);\n }\n }\n },\n\n {\n name: 'Farcaster Plugin - Should Send a Real Cast',\n async fn(runtime: IAgentRuntime): Promise<void> {\n const service = runtime.getService(FARCASTER_SERVICE_NAME) as FarcasterService;\n if (!service) {\n throw new Error('FarcasterService not found');\n }\n\n const postService = service.getPostService(runtime.agentId);\n if (!postService) {\n throw new Error('PostService not available');\n }\n\n const uniqueMessage = `This is a real E2E test cast from ElizaOS! ID: ${createUniqueUuid(runtime, 'e2e-cast')}`;\n logger.info(`Attempting to post cast: \"${uniqueMessage}\"`);\n\n const cast = await postService.createPost({\n agentId: runtime.agentId,\n roomId: createUniqueUuid(runtime, 'farcaster-e2e-test'),\n text: uniqueMessage,\n });\n\n if (!cast || !cast.id) {\n throw new Error('E2E test failed to create a real cast.');\n }\n\n logger.success(`Successfully posted E2E test cast with ID: ${cast.id}`);\n // In a real-world scenario, you might want to add a step to delete this cast\n // if the API supports it, to keep the feed clean.\n },\n },\n];\n\n// Export for use in test suite\nexport default farcasterE2EScenarios; ","import {\n type Action,\n type IAgentRuntime,\n type Memory,\n type State,\n logger,\n} from '@elizaos/core';\nimport { FARCASTER_SERVICE_NAME } from '../common/constants';\nimport type { FarcasterService } from '../service';\nimport { FarcasterMessageType } from '../common/types';\n\nexport const replyCastAction: Action = {\n name: 'REPLY_TO_CAST',\n description: 'Replies to a cast on Farcaster',\n examples: [\n [\n {\n name: 'user',\n content: { text: 'Someone asked about ElizaOS on Farcaster, can you reply?' },\n },\n {\n name: 'assistant',\n content: {\n text: \"I'll reply to their question about ElizaOS.\",\n actions: ['REPLY_TO_CAST'],\n },\n },\n ],\n [\n {\n name: 'user',\n content: { text: 'Reply to that cast and thank them for the feedback' },\n },\n {\n name: 'assistant',\n content: {\n text: \"I'll reply with a thank you message.\",\n actions: ['REPLY_TO_CAST'],\n },\n },\n ],\n ],\n\n validate: async (runtime: IAgentRuntime, message: Memory): Promise<boolean> => {\n const text = message.content.text?.toLowerCase() || '';\n const keywords = ['reply', 'respond', 'answer', 'comment'];\n\n // Check if the message contains relevant keywords\n const hasKeyword = keywords.some((keyword) => text.includes(keyword));\n\n // Check if we have a parent cast to reply to\n // Note: inReplyTo doesn't exist on Memory type, check metadata\n const hasParentCast = !!(\n message.content.metadata && (message.content.metadata as any).parentCastHash\n );\n\n // Check if Farcaster service is available\n const service = runtime.getService(FARCASTER_SERVICE_NAME) as FarcasterService;\n const isServiceAvailable = !!service?.getMessageService(runtime.agentId);\n\n return hasKeyword && (hasParentCast || isServiceAvailable);\n },\n\n handler: async (runtime: IAgentRuntime, message: Memory, state?: State): Promise<boolean> => {\n try {\n const service = runtime.getService(FARCASTER_SERVICE_NAME) as FarcasterService;\n const messageService = service?.getMessageService(runtime.agentId);\n\n if (!messageService) {\n logger.error('[REPLY_TO_CAST] MessageService not available');\n return false;\n }\n\n // Get the parent cast hash\n const parentCastHash =\n (message.content.metadata as any)?.parentCastHash || state?.parentCastHash;\n\n if (!parentCastHash) {\n logger.error('[REPLY_TO_CAST] No parent cast to reply to');\n return false;\n }\n\n // Generate reply content\n let replyContent = '';\n\n if (state?.replyContent) {\n replyContent = state.replyContent as string;\n } else {\n const prompt = `Based on this request: \"${message.content.text}\", generate a helpful and engaging reply for a Farcaster cast (max 320 characters).`;\n\n const response = await runtime.useModel('text_large', { prompt });\n replyContent = typeof response === 'string' ? response : response.text || '';\n }\n\n // Ensure content fits Farcaster's character limit\n if (replyContent.length > 320) {\n replyContent = replyContent.substring(0, 317) + '...';\n }\n\n // Send the reply\n const reply = await messageService.sendMessage({\n agentId: runtime.agentId,\n roomId: message.roomId,\n text: replyContent,\n type: FarcasterMessageType.REPLY,\n replyToId: parentCastHash as string,\n metadata: {\n parentHash: parentCastHash,\n },\n });\n\n logger.info(`[REPLY_TO_CAST] Successfully replied to cast: ${reply.id}`);\n\n return true;\n } catch (error) {\n logger.error('[REPLY_TO_CAST] Error replying to cast:', error);\n return false;\n }\n },\n};\n","export { sendCastAction } from './sendCast';\nexport { replyCastAction } from './replyCast';\n\nimport { sendCastAction } from './sendCast';\nimport { replyCastAction } from './replyCast';\n\n// Export all actions as an array for easy plugin registration\nexport const farcasterActions = [sendCastAction, replyCastAction];\n","export { farcasterProfileProvider } from './profileProvider';\nexport { farcasterTimelineProvider } from './timelineProvider';\n\nimport { farcasterProfileProvider } from './profileProvider';\nimport { farcasterTimelineProvider } from './timelineProvider';\n\n// Export all providers as an array for easy plugin registration\nexport const farcasterProviders = [farcasterProfileProvider, farcasterTimelineProvider];\n","import { FarcasterService } from './service.js';\nimport { FarcasterTestSuite } from './__tests__/suite.js';\nimport { farcasterActions } from './actions/index.js';\nimport { farcasterProviders } from './providers/index.js';\n\nconst farcasterPlugin = {\n name: 'farcaster',\n description: 'Farcaster client plugin for sending and receiving casts',\n services: [FarcasterService],\n actions: farcasterActions,\n providers: farcasterProviders,\n tests: [new FarcasterTestSuite()],\n};\n\nexport default farcasterPlugin;\n"],"mappings":"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","names":["logger","logger","logger","logger","memory","createUniqueUuid","EventType","logger","logger","createUniqueUuid","EventType","logger","logger","logger","logger","createUniqueUuid","createUniqueUuid","logger","logger","ModelType","createUniqueUuid","logger","ModelType","createUniqueUuid","logger","ModelType","createUniqueUuid","logger","logger","createUniqueUuid","createUniqueUuid","logger","sendCastAction","farcasterProfileProvider","farcasterTimelineProvider","logger","createUniqueUuid","ModelType","logger","logger"]}
@@ -0,0 +1,8 @@
1
+ import {
2
+ farcasterProfileProvider
3
+ } from "./chunk-IOTLJXKN.js";
4
+ import "./chunk-Y2URJ4EZ.js";
5
+ export {
6
+ farcasterProfileProvider
7
+ };
8
+ //# sourceMappingURL=profileProvider-TNRU42OO.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,8 @@
1
+ import {
2
+ sendCastAction
3
+ } from "./chunk-OAXQ6Z2Q.js";
4
+ import "./chunk-Y2URJ4EZ.js";
5
+ export {
6
+ sendCastAction
7
+ };
8
+ //# sourceMappingURL=sendCast-OW6DBKQB.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,8 @@
1
+ import {
2
+ farcasterTimelineProvider
3
+ } from "./chunk-FNDASAYG.js";
4
+ import "./chunk-Y2URJ4EZ.js";
5
+ export {
6
+ farcasterTimelineProvider
7
+ };
8
+ //# sourceMappingURL=timelineProvider-GPRPFEVJ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}