UNPKG

@agentek/tools

Version:

Blockchain tools for AI agents

273 lines 11.2 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.createSearchRecentTweetsTool = createSearchRecentTweetsTool; exports.createGetTweetByIdTool = createGetTweetByIdTool; exports.createGetUserByUsernameTool = createGetUserByUsernameTool; exports.createGetUserTweetsTool = createGetUserTweetsTool; exports.createGetHomeTimelineTool = createGetHomeTimelineTool; const zod_1 = __importDefault(require("zod")); const client_js_1 = require("../client.js"); const X_API_BASE = "https://api.x.com/2"; const DEFAULT_TWEET_FIELDS = "created_at,author_id,public_metrics,entities,referenced_tweets,conversation_id,lang"; const DEFAULT_USER_FIELDS = "created_at,description,public_metrics,profile_image_url,verified,location,url"; const DEFAULT_EXPANSIONS = "author_id"; async function xFetch(url, bearerToken) { const response = await fetch(url, { headers: { Authorization: `Bearer ${bearerToken}`, }, }); if (!response.ok) { const body = await response.text(); throw new Error(`X API error ${response.status}: ${body}`); } return response.json(); } function createSearchRecentTweetsTool(bearerToken) { return (0, client_js_1.createTool)({ name: "searchRecentTweets", description: "Search recent tweets (last 7 days) on X/Twitter. Supports operators like from:user, #hashtag, $cashtag, -is:retweet, has:media, lang:en, etc. Useful for finding discussions about tokens, projects, trends, and people.", supportedChains: [], parameters: zod_1.default.object({ query: zod_1.default .string() .describe('Search query (max 512 chars). Supports operators: from:user, #hashtag, $cashtag, -is:retweet, -is:reply, has:media, has:links, lang:en, "exact phrase", OR, etc.'), maxResults: zod_1.default .number() .min(10) .max(100) .optional() .describe("Number of results (10-100, default 10)"), sortOrder: zod_1.default .enum(["recency", "relevancy"]) .optional() .describe("Sort by recency or relevancy (default recency)"), }), execute: async (_client, args) => { const params = new URLSearchParams({ query: args.query, "tweet.fields": DEFAULT_TWEET_FIELDS, "user.fields": DEFAULT_USER_FIELDS, expansions: DEFAULT_EXPANSIONS, }); if (args.maxResults) params.set("max_results", String(args.maxResults)); if (args.sortOrder) params.set("sort_order", args.sortOrder); const data = await xFetch(`${X_API_BASE}/tweets/search/recent?${params}`, bearerToken); return formatTweetResponse(data); }, }); } function createGetTweetByIdTool(bearerToken) { return (0, client_js_1.createTool)({ name: "getTweetById", description: "Get a specific tweet by its ID from X/Twitter. Returns the full tweet with author info and engagement metrics.", supportedChains: [], parameters: zod_1.default.object({ tweetId: zod_1.default.string().describe("The tweet ID"), }), execute: async (_client, args) => { const params = new URLSearchParams({ "tweet.fields": DEFAULT_TWEET_FIELDS, "user.fields": DEFAULT_USER_FIELDS, expansions: DEFAULT_EXPANSIONS, }); const data = await xFetch(`${X_API_BASE}/tweets/${encodeURIComponent(args.tweetId)}?${params}`, bearerToken); return formatSingleTweet(data); }, }); } function createGetUserByUsernameTool(bearerToken) { return (0, client_js_1.createTool)({ name: "getXUserByUsername", description: "Look up an X/Twitter user by their username/handle. Returns their profile info, follower counts, and bio.", supportedChains: [], parameters: zod_1.default.object({ username: zod_1.default .string() .describe("The X/Twitter username (without the @ symbol)"), }), execute: async (_client, args) => { const params = new URLSearchParams({ "user.fields": DEFAULT_USER_FIELDS, expansions: "pinned_tweet_id", "tweet.fields": "created_at,text,public_metrics", }); const data = await xFetch(`${X_API_BASE}/users/by/username/${encodeURIComponent(args.username)}?${params}`, bearerToken); return formatUserResponse(data); }, }); } function createGetUserTweetsTool(bearerToken) { return (0, client_js_1.createTool)({ name: "getXUserTweets", description: "Get recent tweets from a specific X/Twitter user by their user ID. Use getXUserByUsername first to get the user ID from a handle.", supportedChains: [], parameters: zod_1.default.object({ userId: zod_1.default.string().describe("The numeric X/Twitter user ID"), maxResults: zod_1.default .number() .min(5) .max(100) .optional() .describe("Number of results (5-100, default 10)"), excludeReplies: zod_1.default .boolean() .optional() .describe("Exclude replies (default false)"), excludeRetweets: zod_1.default .boolean() .optional() .describe("Exclude retweets (default false)"), }), execute: async (_client, args) => { const params = new URLSearchParams({ "tweet.fields": DEFAULT_TWEET_FIELDS, "user.fields": DEFAULT_USER_FIELDS, expansions: DEFAULT_EXPANSIONS, }); if (args.maxResults) params.set("max_results", String(args.maxResults)); const excludes = []; if (args.excludeReplies) excludes.push("replies"); if (args.excludeRetweets) excludes.push("retweets"); if (excludes.length > 0) params.set("exclude", excludes.join(",")); const data = await xFetch(`${X_API_BASE}/users/${encodeURIComponent(args.userId)}/tweets?${params}`, bearerToken); return formatTweetResponse(data); }, }); } function createGetHomeTimelineTool(twitterClient) { return (0, client_js_1.createTool)({ name: "getHomeTimeline", description: "Get the authenticated user's home timeline (feed) from X/Twitter. Returns recent tweets from accounts the user follows and suggested content. Requires user OAuth credentials.", supportedChains: [], parameters: zod_1.default.object({ maxResults: zod_1.default .number() .min(1) .max(100) .optional() .describe("Number of results (1-100, default 10)"), excludeReplies: zod_1.default .boolean() .optional() .describe("Exclude replies (default false)"), excludeRetweets: zod_1.default .boolean() .optional() .describe("Exclude retweets (default false)"), }), execute: async (_client, args) => { const me = await twitterClient.v2.me(); const userId = me.data.id; const exclude = []; if (args.excludeReplies) exclude.push("replies"); if (args.excludeRetweets) exclude.push("retweets"); const timeline = await twitterClient.v2.homeTimeline({ max_results: args.maxResults || 10, "tweet.fields": DEFAULT_TWEET_FIELDS.split(","), "user.fields": DEFAULT_USER_FIELDS.split(","), expansions: DEFAULT_EXPANSIONS.split(","), ...(exclude.length > 0 ? { exclude } : {}), }); return formatTweetResponse({ data: timeline.data.data, includes: timeline.data.includes, meta: timeline.data.meta, }); }, }); } // --- Response formatters --- function formatTweetResponse(data) { if (!data.data) return { tweets: [], meta: data.meta }; const usersMap = new Map(); if (data.includes?.users) { for (const user of data.includes.users) { usersMap.set(user.id, user); } } const tweets = data.data.map((tweet) => { const author = usersMap.get(tweet.author_id); return { id: tweet.id, text: tweet.text, createdAt: tweet.created_at, lang: tweet.lang, author: author ? { id: author.id, username: author.username, name: author.name, followers: author.public_metrics?.followers_count, } : { id: tweet.author_id }, metrics: tweet.public_metrics, entities: tweet.entities, referencedTweets: tweet.referenced_tweets, }; }); return { tweets, resultCount: data.meta?.result_count }; } function formatSingleTweet(data) { if (!data.data) return { error: "Tweet not found" }; const tweet = data.data; const author = data.includes?.users?.[0]; return { id: tweet.id, text: tweet.text, createdAt: tweet.created_at, lang: tweet.lang, author: author ? { id: author.id, username: author.username, name: author.name, followers: author.public_metrics?.followers_count, } : { id: tweet.author_id }, metrics: tweet.public_metrics, entities: tweet.entities, referencedTweets: tweet.referenced_tweets, conversationId: tweet.conversation_id, }; } function formatUserResponse(data) { if (!data.data) return { error: "User not found" }; const user = data.data; const pinnedTweet = data.includes?.tweets?.[0]; return { id: user.id, username: user.username, name: user.name, description: user.description, location: user.location, url: user.url, createdAt: user.created_at, verified: user.verified, profileImageUrl: user.profile_image_url, metrics: user.public_metrics, pinnedTweet: pinnedTweet ? { id: pinnedTweet.id, text: pinnedTweet.text, createdAt: pinnedTweet.created_at, metrics: pinnedTweet.public_metrics, } : undefined, }; } //# sourceMappingURL=tools.js.map