@agentek/tools
Version:
Blockchain tools for AI agents
273 lines • 11.2 kB
JavaScript
;
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