composio-scavio 0.2.0 → 0.3.0
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/README.md +54 -7
- package/dist/index.cjs +630 -27
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -2
- package/dist/index.d.ts +5 -2
- package/dist/index.js +630 -27
- package/dist/index.js.map +1 -1
- package/package.json +11 -5
package/dist/index.js
CHANGED
|
@@ -9,15 +9,14 @@ var str = (d) => z.string().describe(d);
|
|
|
9
9
|
var ostr = (d) => z.string().optional().describe(d);
|
|
10
10
|
var onum = (d) => z.number().optional().describe(d);
|
|
11
11
|
var obool = (d) => z.boolean().optional().describe(d);
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
}
|
|
12
|
+
var gl = ostr("Country of the search (ISO 3166-1 alpha-2, e.g. 'us', 'gb', 'de').");
|
|
13
|
+
var hl = ostr("UI language (ISO 639-1, e.g. 'en').");
|
|
14
|
+
var googleDomain = ostr("Regional Google domain, e.g. 'google.co.uk'.");
|
|
15
|
+
var location = ostr("Canonical location name, e.g. 'Austin, Texas, United States'. Encoded server-side.");
|
|
16
|
+
var device = ostr("Device to emulate: 'desktop' or 'mobile'.");
|
|
17
|
+
var currency = ostr("Currency code (ISO 4217, e.g. 'USD').");
|
|
18
|
+
var checkInDate = str("Check-in date (YYYY-MM-DD).");
|
|
19
|
+
var checkOutDate = str("Check-out date (YYYY-MM-DD).");
|
|
21
20
|
function buildScavioToolkit(options = {}) {
|
|
22
21
|
const {
|
|
23
22
|
apiKey,
|
|
@@ -27,7 +26,10 @@ function buildScavioToolkit(options = {}) {
|
|
|
27
26
|
enableYoutube = true,
|
|
28
27
|
enableReddit = true,
|
|
29
28
|
enableTiktok = true,
|
|
29
|
+
enableTiktokShop = true,
|
|
30
30
|
enableInstagram = true,
|
|
31
|
+
enableX = true,
|
|
32
|
+
enableLinkedin = true,
|
|
31
33
|
all = false
|
|
32
34
|
} = options;
|
|
33
35
|
const client = new Scavio({ apiKey: apiKey ?? process.env.SCAVIO_API_KEY });
|
|
@@ -45,16 +47,239 @@ function buildScavioToolkit(options = {}) {
|
|
|
45
47
|
tool(
|
|
46
48
|
"GOOGLE_SEARCH",
|
|
47
49
|
"Scavio Google Search",
|
|
48
|
-
"Search Google for real-time web results (
|
|
50
|
+
"Search Google for real-time web results. Returns organic_results (each with title, link and snippet) plus knowledge_graph, related_questions, ads and the AI Overview when Google shows one. The body is flat - read organic_results at the top level, not under data. Costs 1 credit.",
|
|
49
51
|
z.object({
|
|
50
|
-
query: str("The search query."),
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
52
|
+
query: str("The search query (1-500 characters)."),
|
|
53
|
+
gl,
|
|
54
|
+
hl,
|
|
55
|
+
google_domain: googleDomain,
|
|
56
|
+
location,
|
|
57
|
+
device,
|
|
58
|
+
start: onum("Result offset, NOT a page number: 0 is page 1, 10 is page 2, up to 990."),
|
|
59
|
+
time_period: ostr("Restrict results to a recent time window: 'last_hour', 'last_day', 'last_week', 'last_month', or 'last_year'."),
|
|
60
|
+
safe: ostr("Turn SafeSearch on with 'active'."),
|
|
61
|
+
nfpr: obool("Disable spelling correction and auto-fixes when true.")
|
|
62
|
+
}),
|
|
63
|
+
(i) => client.google.search(i)
|
|
64
|
+
),
|
|
65
|
+
tool(
|
|
66
|
+
"GOOGLE_AI_MODE",
|
|
67
|
+
"Scavio Google AI Mode",
|
|
68
|
+
"Ask Google AI Mode a question. Returns Google's generated answer with its cited sources - use this for a synthesized answer and GOOGLE_SEARCH for a ranked result list. Costs 1 credit.",
|
|
69
|
+
z.object({
|
|
70
|
+
query: str("Question or prompt (1-500 characters)."),
|
|
71
|
+
gl,
|
|
72
|
+
hl,
|
|
73
|
+
google_domain: googleDomain,
|
|
74
|
+
location,
|
|
75
|
+
device,
|
|
76
|
+
safe: ostr("Turn SafeSearch on with 'active'.")
|
|
77
|
+
}),
|
|
78
|
+
(i) => client.google.aiMode(i)
|
|
79
|
+
),
|
|
80
|
+
tool(
|
|
81
|
+
"GOOGLE_MAPS_SEARCH",
|
|
82
|
+
"Scavio Google Maps Search",
|
|
83
|
+
"Search Google Maps for local businesses and places. Returns local results with ratings, review counts, addresses, phone numbers and place ids. Feed a place_id into GOOGLE_MAPS_PLACE or GOOGLE_MAPS_REVIEWS. Costs 1 credit.",
|
|
84
|
+
z.object({
|
|
85
|
+
query: str("Search query, e.g. 'coffee shops in Austin' (1-500 characters)."),
|
|
86
|
+
ll: ostr("Map centre as '@lat,lng,zoomz'; controls which area results come from. Maps localizes by map centre, not gl."),
|
|
87
|
+
start: onum("Result offset; must be a multiple of 20 (0, 20, 40, ...)."),
|
|
88
|
+
gl,
|
|
89
|
+
hl,
|
|
90
|
+
google_domain: googleDomain
|
|
91
|
+
}),
|
|
92
|
+
(i) => client.google.mapsSearch(i)
|
|
93
|
+
),
|
|
94
|
+
tool(
|
|
95
|
+
"GOOGLE_MAPS_PLACE",
|
|
96
|
+
"Scavio Google Maps Place",
|
|
97
|
+
"Fetch one Google Maps place in full: hours, address, phone, website, rating, price level and photos. Provide place_id or data_cid. Costs 1 credit.",
|
|
98
|
+
z.object({
|
|
99
|
+
place_id: ostr("Place ID (starts with ChIJ). Provide this or data_cid."),
|
|
100
|
+
data_cid: ostr("Numeric CID. Provide this or place_id.")
|
|
101
|
+
}),
|
|
102
|
+
(i) => client.google.mapsPlace(i)
|
|
103
|
+
),
|
|
104
|
+
tool(
|
|
105
|
+
"GOOGLE_MAPS_REVIEWS",
|
|
106
|
+
"Scavio Google Maps Reviews",
|
|
107
|
+
"List Google Maps reviews for a place. Provide data_id or place_id. Page with next_page_token; each page costs another credit. Costs 1 credit.",
|
|
108
|
+
z.object({
|
|
109
|
+
place_id: ostr("Place ID (starts with ChIJ). Provide this or data_id."),
|
|
110
|
+
data_id: ostr("Data ID in 0xHEX:0xHEX form. Provide this or place_id."),
|
|
111
|
+
num: onum("Reviews per page (1-20)."),
|
|
112
|
+
sort_by: ostr("Review sort order: 'relevance', 'newest', 'highest_rating', or 'lowest_rating'."),
|
|
113
|
+
next_page_token: ostr("Pagination cursor from a prior response."),
|
|
114
|
+
gl,
|
|
115
|
+
hl,
|
|
116
|
+
google_domain: googleDomain
|
|
117
|
+
}),
|
|
118
|
+
(i) => client.google.mapsReviews(i)
|
|
119
|
+
),
|
|
120
|
+
tool(
|
|
121
|
+
"GOOGLE_SHOPPING",
|
|
122
|
+
"Scavio Google Shopping",
|
|
123
|
+
"Search Google Shopping. Returns product cards with prices, merchants, ratings and catalog ids across retailers - use this for cross-retailer price comparison and AMAZON_SEARCH or WALMART_SEARCH for a single marketplace. Costs 1 credit.",
|
|
124
|
+
z.object({
|
|
125
|
+
query: str("Product search query (1-500 characters)."),
|
|
126
|
+
min_price: onum("Minimum price filter."),
|
|
127
|
+
max_price: onum("Maximum price filter."),
|
|
128
|
+
sort_by: onum("0 = relevance, 1 = price ascending, 2 = price descending."),
|
|
129
|
+
free_shipping: obool("Only items with free shipping."),
|
|
130
|
+
on_sale: obool("Only items on sale."),
|
|
131
|
+
start: onum("Result offset."),
|
|
132
|
+
gl,
|
|
133
|
+
hl,
|
|
134
|
+
google_domain: googleDomain,
|
|
135
|
+
location,
|
|
136
|
+
device
|
|
137
|
+
}),
|
|
138
|
+
(i) => client.google.shopping(i)
|
|
139
|
+
),
|
|
140
|
+
tool(
|
|
141
|
+
"GOOGLE_SHOPPING_PRODUCT",
|
|
142
|
+
"Scavio Google Shopping Product",
|
|
143
|
+
"Fetch one Google Shopping product: specs, reviews, and the sellers carrying it. Pass catalog_id together with query for full detail and the seller list. Costs 1 credit.",
|
|
144
|
+
z.object({
|
|
145
|
+
catalog_id: ostr("Durable product catalog id from a shopping search."),
|
|
146
|
+
query: ostr("Product query. Required when catalog_id is set."),
|
|
147
|
+
product_id: ostr("Product id, as an alternative to catalog_id."),
|
|
148
|
+
page_token: ostr("Immersive product page token."),
|
|
149
|
+
sort_by: ostr("Seller sort order: 'base_price', 'total_price', 'promotion', or 'seller_rating'."),
|
|
150
|
+
load_all_stores: obool("Load every available store."),
|
|
151
|
+
more_stores: obool("Fetch additional stores."),
|
|
152
|
+
gl,
|
|
153
|
+
hl,
|
|
154
|
+
google_domain: googleDomain,
|
|
155
|
+
location,
|
|
156
|
+
device: ostr("Device to emulate: 'desktop', 'mobile', or 'tablet'.")
|
|
157
|
+
}),
|
|
158
|
+
(i) => client.google.shoppingProduct(i)
|
|
159
|
+
),
|
|
160
|
+
tool(
|
|
161
|
+
"GOOGLE_SHOPPING_STORES",
|
|
162
|
+
"Scavio Google Shopping Stores",
|
|
163
|
+
"Fetch the next page of sellers for a Google Shopping product. Continuation of GOOGLE_SHOPPING_PRODUCT: pass the same catalog_id plus that response's next_page_token. Costs 1 credit.",
|
|
164
|
+
z.object({
|
|
165
|
+
catalog_id: str("Durable product catalog id."),
|
|
166
|
+
next_page_token: str("Pagination cursor from GOOGLE_SHOPPING_PRODUCT.")
|
|
167
|
+
}),
|
|
168
|
+
(i) => client.google.shoppingStores(i)
|
|
169
|
+
),
|
|
170
|
+
tool(
|
|
171
|
+
"GOOGLE_FLIGHTS",
|
|
172
|
+
"Scavio Google Flights",
|
|
173
|
+
"Search Google Flights. Returns itineraries with prices, airlines, stops, durations and carbon emissions. Airports are IATA codes; dates are YYYY-MM-DD. Costs 1 credit.",
|
|
174
|
+
z.object({
|
|
175
|
+
departure_id: str("Departure IATA code(s), comma-separated allowed, e.g. 'JFK'."),
|
|
176
|
+
arrival_id: str("Arrival IATA code(s), comma-separated allowed, e.g. 'LHR'."),
|
|
177
|
+
outbound_date: str("Outbound date (YYYY-MM-DD)."),
|
|
178
|
+
return_date: ostr("Return date (YYYY-MM-DD). Required when type is 1."),
|
|
179
|
+
type: onum("1 = round trip (default), 2 = one way, 3 = multi-city."),
|
|
180
|
+
adults: onum("Number of adults (1-9)."),
|
|
181
|
+
children: onum("Number of children (0-9)."),
|
|
182
|
+
infants_in_seat: onum("Infants in seat (0-4)."),
|
|
183
|
+
infants_on_lap: onum("Infants on lap (0-4)."),
|
|
184
|
+
travel_class: onum("1 = economy, 2 = premium economy, 3 = business, 4 = first."),
|
|
185
|
+
stops: onum("0 = any, 1 = nonstop, 2 = one stop or fewer, 3 = two or fewer."),
|
|
186
|
+
sort_by: onum("1 = top, 2 = price, 3 = departure, 4 = arrival, 5 = duration, 6 = emissions."),
|
|
187
|
+
include_airlines: ostr("Comma-separated airline or alliance codes to include."),
|
|
188
|
+
exclude_airlines: ostr("Comma-separated airline or alliance codes to exclude."),
|
|
189
|
+
currency,
|
|
190
|
+
gl,
|
|
191
|
+
hl
|
|
56
192
|
}),
|
|
57
|
-
(i) => client.google.
|
|
193
|
+
(i) => client.google.flights(i)
|
|
194
|
+
),
|
|
195
|
+
tool(
|
|
196
|
+
"GOOGLE_HOTELS",
|
|
197
|
+
"Scavio Google Hotels",
|
|
198
|
+
"Search Google Hotels. Returns properties with nightly prices, ratings, amenities and a detail_token for GOOGLE_HOTELS_DETAIL. Phrase the query as '<City> hotels'. Costs 1 credit.",
|
|
199
|
+
z.object({
|
|
200
|
+
query: str("Search query; use a '<City> hotels' form."),
|
|
201
|
+
check_in_date: checkInDate,
|
|
202
|
+
check_out_date: checkOutDate,
|
|
203
|
+
sort_by: onum("3 = lowest price, 8 = highest rating, 13 = most reviewed."),
|
|
204
|
+
min_price: onum("Minimum nightly price."),
|
|
205
|
+
max_price: onum("Maximum nightly price."),
|
|
206
|
+
rating: onum("7 = 3.5+, 8 = 4.0+, 9 = 4.5+."),
|
|
207
|
+
hotel_class: ostr("Comma-separated star ratings (2-5)."),
|
|
208
|
+
amenities: ostr("Comma-separated amenity ids."),
|
|
209
|
+
property_types: ostr("Comma-separated property-type ids, e.g. '12' for vacation rentals."),
|
|
210
|
+
free_cancellation: obool("Only properties with free cancellation."),
|
|
211
|
+
eco_certified: obool("Only eco-certified properties."),
|
|
212
|
+
special_offers: obool("Only properties with special offers."),
|
|
213
|
+
limit: onum("Number of properties to return (1-20)."),
|
|
214
|
+
next_page_token: ostr("Pagination cursor from a prior response."),
|
|
215
|
+
currency,
|
|
216
|
+
gl,
|
|
217
|
+
hl
|
|
218
|
+
}),
|
|
219
|
+
(i) => client.google.hotels(i)
|
|
220
|
+
),
|
|
221
|
+
tool(
|
|
222
|
+
"GOOGLE_HOTELS_DETAIL",
|
|
223
|
+
"Scavio Google Hotels Detail",
|
|
224
|
+
"Fetch one Google Hotels property in full: room types, per-night prices by provider, amenities, photos and reviews. Needs a detail_token from GOOGLE_HOTELS and the same stay dates. Costs 1 credit.",
|
|
225
|
+
z.object({
|
|
226
|
+
detail_token: str("Property detail token from a hotels listing."),
|
|
227
|
+
check_in_date: checkInDate,
|
|
228
|
+
check_out_date: checkOutDate,
|
|
229
|
+
currency,
|
|
230
|
+
gl,
|
|
231
|
+
hl
|
|
232
|
+
}),
|
|
233
|
+
(i) => client.google.hotelsDetail(i)
|
|
234
|
+
),
|
|
235
|
+
tool(
|
|
236
|
+
"GOOGLE_NEWS",
|
|
237
|
+
"Scavio Google News",
|
|
238
|
+
"Fetch Google News. Pass query to search, or a topic_token / story_token / publication_token from an earlier response to browse a topic, a full story or one publisher. Costs 1 credit.",
|
|
239
|
+
z.object({
|
|
240
|
+
query: ostr("Keyword search."),
|
|
241
|
+
topic_token: ostr("Browse a news topic."),
|
|
242
|
+
section_token: ostr("Browse a topic section."),
|
|
243
|
+
story_token: ostr("Fetch full coverage of one story."),
|
|
244
|
+
publication_token: ostr("Browse one publication."),
|
|
245
|
+
kgmid: ostr("Knowledge Graph entity id."),
|
|
246
|
+
so: onum("Sort: 0 = relevance, 1 = date. Only applies with query or kgmid."),
|
|
247
|
+
gl,
|
|
248
|
+
hl,
|
|
249
|
+
google_domain: googleDomain
|
|
250
|
+
}),
|
|
251
|
+
(i) => client.google.news(i)
|
|
252
|
+
),
|
|
253
|
+
tool(
|
|
254
|
+
"GOOGLE_TRENDS",
|
|
255
|
+
"Scavio Google Trends",
|
|
256
|
+
"Fetch Google Trends interest data. Comma-separate the query to compare terms, and pick the dataset with data_type: TIMESERIES for interest over time, GEO_MAP for interest by region, RELATED_QUERIES or RELATED_TOPICS for rising searches. Costs 1 credit.",
|
|
257
|
+
z.object({
|
|
258
|
+
query: str("Search term(s); comma-separated to compare up to five."),
|
|
259
|
+
data_type: ostr("Which trends dataset to return: 'TIMESERIES', 'GEO_MAP', 'GEO_MAP_0', 'RELATED_QUERIES', or 'RELATED_TOPICS'."),
|
|
260
|
+
geo: ostr("Location code, e.g. 'US', 'GB', 'US-CA'. Omit for worldwide."),
|
|
261
|
+
date: ostr("Time range, e.g. 'today 12-m', 'now 7-d'."),
|
|
262
|
+
cat: ostr("Category id."),
|
|
263
|
+
gprop: ostr("Restrict to a Google property: 'images', 'news', 'youtube', or 'froogle'."),
|
|
264
|
+
region: ostr("Resolution for GEO_MAP data: 'COUNTRY', 'REGION', 'DMA', or 'CITY'."),
|
|
265
|
+
tz: ostr("Timezone offset in minutes."),
|
|
266
|
+
hl
|
|
267
|
+
}),
|
|
268
|
+
(i) => client.google.trends(i)
|
|
269
|
+
),
|
|
270
|
+
tool(
|
|
271
|
+
"GOOGLE_TRENDING",
|
|
272
|
+
"Scavio Google Trending",
|
|
273
|
+
"List what is trending on Google right now for one country. geo is required. Use GOOGLE_TRENDS instead when you already know the term you care about. Costs 1 credit.",
|
|
274
|
+
z.object({
|
|
275
|
+
geo: str("Country code, e.g. 'US'."),
|
|
276
|
+
hours: onum("Trending window in hours: 4, 24, 48 or 168."),
|
|
277
|
+
cat: onum("Category id (0-20)."),
|
|
278
|
+
sort: ostr("Sort order: 'relevance', 'search_volume', 'recency', or 'title'."),
|
|
279
|
+
status: ostr("Filter by trend status: 'all' or 'active'."),
|
|
280
|
+
hl
|
|
281
|
+
}),
|
|
282
|
+
(i) => client.google.trending(i)
|
|
58
283
|
)
|
|
59
284
|
);
|
|
60
285
|
}
|
|
@@ -179,13 +404,6 @@ function buildScavioToolkit(options = {}) {
|
|
|
179
404
|
z.object({ video_id: str("YouTube video id or a full watch URL.") }),
|
|
180
405
|
(i) => client.youtube.video(i)
|
|
181
406
|
),
|
|
182
|
-
tool(
|
|
183
|
-
"YOUTUBE_METADATA",
|
|
184
|
-
"Scavio YouTube Metadata",
|
|
185
|
-
"Fetch metadata for a YouTube video by id. Deprecated alias of YOUTUBE_VIDEO.",
|
|
186
|
-
z.object({ video_id: str("YouTube video id or a full watch URL.") }),
|
|
187
|
-
(i) => client.youtube.metadata(i)
|
|
188
|
-
),
|
|
189
407
|
tool(
|
|
190
408
|
"YOUTUBE_COMMENTS",
|
|
191
409
|
"Scavio YouTube Comments",
|
|
@@ -303,12 +521,105 @@ function buildScavioToolkit(options = {}) {
|
|
|
303
521
|
}),
|
|
304
522
|
(i) => client.reddit.search(i)
|
|
305
523
|
),
|
|
524
|
+
tool(
|
|
525
|
+
"REDDIT_SEARCH_SUGGESTIONS",
|
|
526
|
+
"Scavio Reddit Search Suggestions",
|
|
527
|
+
"Get Reddit search autocomplete suggestions for a query. Returns data.suggestions (plain strings) and total_count. Costs 1 credit.",
|
|
528
|
+
z.object({ query: str("The partial or full query to expand.") }),
|
|
529
|
+
(i) => client.reddit.searchSuggestions(i)
|
|
530
|
+
),
|
|
306
531
|
tool(
|
|
307
532
|
"REDDIT_POST",
|
|
308
533
|
"Scavio Reddit Post",
|
|
309
|
-
"Fetch one Reddit post by URL. Returns a
|
|
310
|
-
z.object({
|
|
534
|
+
"Fetch one Reddit post by URL or post id. Returns a FLAT post object under data (post_id, title, text, url, subreddit, author, score, upvote_ratio, num_comments, created_at, is_nsfw, is_video, thumbnail, media); comments are NOT included - call REDDIT_POST_COMMENTS for those. Costs 1 credit.",
|
|
535
|
+
z.object({
|
|
536
|
+
url: ostr("Full URL of the Reddit post. Provide this or post_id."),
|
|
537
|
+
post_id: ostr("Post fullname (t3_...) or bare id. Provide this or url.")
|
|
538
|
+
}),
|
|
311
539
|
(i) => client.reddit.post(i)
|
|
540
|
+
),
|
|
541
|
+
tool(
|
|
542
|
+
"REDDIT_POST_COMMENTS",
|
|
543
|
+
"Scavio Reddit Post Comments",
|
|
544
|
+
"List top-level comments on a Reddit post. Returns data.comments with next_cursor and has_more; each comment carries a reply_cursor for REDDIT_COMMENT_REPLIES. Costs 1 credit.",
|
|
545
|
+
z.object({
|
|
546
|
+
post_id: str("Post fullname (t3_...), bare id, or post URL."),
|
|
547
|
+
sort: ostr("Comment sort order (UPPERCASE): 'HOT', 'NEW', 'TOP', 'BEST', or 'CONTROVERSIAL'. Defaults to TOP."),
|
|
548
|
+
cursor: ostr("Pagination cursor from a prior response.")
|
|
549
|
+
}),
|
|
550
|
+
(i) => client.reddit.postComments(i)
|
|
551
|
+
),
|
|
552
|
+
tool(
|
|
553
|
+
"REDDIT_COMMENT_REPLIES",
|
|
554
|
+
"Scavio Reddit Comment Replies",
|
|
555
|
+
"List replies to one Reddit comment. cursor is REQUIRED here and must be a comment's 'reply_cursor' from REDDIT_POST_COMMENTS, not a 'next_cursor'. Costs 1 credit.",
|
|
556
|
+
z.object({
|
|
557
|
+
post_id: str("Post fullname (t3_...) the comment belongs to."),
|
|
558
|
+
cursor: str("A comment's 'reply_cursor' from REDDIT_POST_COMMENTS. Required."),
|
|
559
|
+
sort: ostr("Comment sort order (UPPERCASE): 'HOT', 'NEW', 'TOP', 'BEST', or 'CONTROVERSIAL'. Defaults to TOP.")
|
|
560
|
+
}),
|
|
561
|
+
(i) => client.reddit.commentReplies(i)
|
|
562
|
+
),
|
|
563
|
+
tool(
|
|
564
|
+
"REDDIT_SUBREDDIT",
|
|
565
|
+
"Scavio Reddit Subreddit",
|
|
566
|
+
"Fetch a subreddit's profile: title, description, subscribers, active_count, type, icon, banner and created_at. Costs 1 credit.",
|
|
567
|
+
z.object({ subreddit: str("Subreddit name without the r/ prefix, e.g. 'AskReddit'.") }),
|
|
568
|
+
(i) => client.reddit.subreddit(i)
|
|
569
|
+
),
|
|
570
|
+
tool(
|
|
571
|
+
"REDDIT_SUBREDDIT_POSTS",
|
|
572
|
+
"Scavio Reddit Subreddit Posts",
|
|
573
|
+
"List posts in a subreddit feed. Returns data.posts with next_cursor and has_more. This feed shape has no text and no thumbnail - use REDDIT_POST for a post's body. Costs 1 credit.",
|
|
574
|
+
z.object({
|
|
575
|
+
subreddit: str("Subreddit name without the r/ prefix."),
|
|
576
|
+
sort: ostr("Feed sort order (UPPERCASE): 'BEST', 'HOT', 'NEW', 'TOP', 'CONTROVERSIAL', or 'RISING'. Defaults to HOT. This is the only endpoint accepting RISING."),
|
|
577
|
+
cursor: ostr("Pagination cursor from a prior response.")
|
|
578
|
+
}),
|
|
579
|
+
(i) => client.reddit.subredditPosts(i)
|
|
580
|
+
),
|
|
581
|
+
tool(
|
|
582
|
+
"REDDIT_USER",
|
|
583
|
+
"Scavio Reddit User",
|
|
584
|
+
"Fetch a redditor's profile: karma split, account_type, avatar, description, verification flags and created_at. Costs 1 credit.",
|
|
585
|
+
z.object({ username: str("Redditor username without the u/ prefix, e.g. 'spez'.") }),
|
|
586
|
+
(i) => client.reddit.user(i)
|
|
587
|
+
),
|
|
588
|
+
tool(
|
|
589
|
+
"REDDIT_USER_POSTS",
|
|
590
|
+
"Scavio Reddit User Posts",
|
|
591
|
+
"List posts submitted by a redditor. Returns data.posts with next_cursor and has_more. Costs 1 credit.",
|
|
592
|
+
z.object({
|
|
593
|
+
username: str("Redditor username without the u/ prefix."),
|
|
594
|
+
sort: ostr("Sort order (UPPERCASE): 'HOT', 'NEW', 'TOP', 'BEST', or 'CONTROVERSIAL'. Defaults to NEW."),
|
|
595
|
+
cursor: ostr("Pagination cursor from a prior response.")
|
|
596
|
+
}),
|
|
597
|
+
(i) => client.reddit.userPosts(i)
|
|
598
|
+
),
|
|
599
|
+
tool(
|
|
600
|
+
"REDDIT_USER_COMMENTS",
|
|
601
|
+
"Scavio Reddit User Comments",
|
|
602
|
+
"List comments written by a redditor. Returns data.comments with next_cursor and has_more; each item nests the post it belongs to. Costs 1 credit.",
|
|
603
|
+
z.object({
|
|
604
|
+
username: str("Redditor username without the u/ prefix."),
|
|
605
|
+
sort: ostr("Sort order (UPPERCASE): 'HOT', 'NEW', 'TOP', 'BEST', or 'CONTROVERSIAL'. Defaults to NEW."),
|
|
606
|
+
cursor: ostr("Pagination cursor from a prior response.")
|
|
607
|
+
}),
|
|
608
|
+
(i) => client.reddit.userComments(i)
|
|
609
|
+
),
|
|
610
|
+
tool(
|
|
611
|
+
"REDDIT_POPULAR",
|
|
612
|
+
"Scavio Reddit Popular",
|
|
613
|
+
"List the site-wide r/popular feed. Returns data.posts with next_cursor and has_more. Costs 1 credit.",
|
|
614
|
+
z.object({ cursor: ostr("Pagination cursor from a prior response. Omit for page 1.") }),
|
|
615
|
+
(i) => client.reddit.popular(i)
|
|
616
|
+
),
|
|
617
|
+
tool(
|
|
618
|
+
"REDDIT_TRENDING",
|
|
619
|
+
"Scavio Reddit Trending",
|
|
620
|
+
"List Reddit's currently trending searches. Returns data.trending (query plus raw_query) and total_count. Takes no parameters. Costs 1 credit.",
|
|
621
|
+
z.object({}),
|
|
622
|
+
() => client.reddit.trending()
|
|
312
623
|
)
|
|
313
624
|
);
|
|
314
625
|
}
|
|
@@ -437,6 +748,92 @@ function buildScavioToolkit(options = {}) {
|
|
|
437
748
|
)
|
|
438
749
|
);
|
|
439
750
|
}
|
|
751
|
+
if (all || enableTiktokShop) {
|
|
752
|
+
tools.push(
|
|
753
|
+
tool(
|
|
754
|
+
"TIKTOK_SHOP_SEARCH",
|
|
755
|
+
"Scavio TikTok Shop Search",
|
|
756
|
+
"Search TikTok Shop products by keyword (US catalog only), up to 30 per page with exact prices, ratings and shop details. One of the three endpoints that return exact prices. Paginate with next_cursor and dedupe by product_id across pages. Costs 1 credit.",
|
|
757
|
+
z.object({
|
|
758
|
+
search: str("Search query (1-200 characters). The keyword field is named 'search', not 'query'."),
|
|
759
|
+
cursor: ostr("Opaque cursor from a prior response's next_cursor.")
|
|
760
|
+
}),
|
|
761
|
+
(i) => client.tiktokShop.search(i)
|
|
762
|
+
),
|
|
763
|
+
tool(
|
|
764
|
+
"TIKTOK_SHOP_SEARCH_SUGGESTIONS",
|
|
765
|
+
"Scavio TikTok Shop Search Suggestions",
|
|
766
|
+
"Expand a partial TikTok Shop query into keyword suggestions across 8 marketplace regions. Suggestions are not guaranteed prefix matches: a misspelling returns typo corrections, and results can include brand and shop names. Costs 1 credit.",
|
|
767
|
+
z.object({
|
|
768
|
+
search: str("Partial query to expand (1-100 characters). The field is 'search', not 'query'."),
|
|
769
|
+
region: ostr("Marketplace region: 'US' (default), 'GB', 'SG', 'MY', 'PH', 'TH', 'VN', or 'ID'.")
|
|
770
|
+
}),
|
|
771
|
+
(i) => client.tiktokShop.searchSuggestions(i)
|
|
772
|
+
),
|
|
773
|
+
tool(
|
|
774
|
+
"TIKTOK_SHOP_PRODUCT",
|
|
775
|
+
"Scavio TikTok Shop Product",
|
|
776
|
+
"Full TikTok Shop product detail: description, images, variants with stock, shipping, shop profile, category path and top reviews. Two limits: it does NOT return a price (upstream masks it - get prices from TIKTOK_SHOP_SEARCH, TIKTOK_SHOP_SHOP_PRODUCTS or TIKTOK_SHOP_CATEGORY_PRODUCTS), and it resolves only about 44% of the product ids returned by search, so a 404 is a normal outcome to skip rather than retry. Costs 1 credit.",
|
|
777
|
+
z.object({
|
|
778
|
+
product_id: str("TikTok Shop product id (6-25 digits)."),
|
|
779
|
+
region: ostr("Marketplace region: 'US' (default), 'GB', 'SG', 'MY', 'PH', 'TH', 'VN', or 'ID'.")
|
|
780
|
+
}),
|
|
781
|
+
(i) => client.tiktokShop.product(i)
|
|
782
|
+
),
|
|
783
|
+
tool(
|
|
784
|
+
"TIKTOK_SHOP_PRODUCT_REVIEWS",
|
|
785
|
+
"Scavio TikTok Shop Product Reviews",
|
|
786
|
+
"Paginated TikTok Shop product reviews with text, images, star histogram and verified-purchase flags, up to 200 per call. total_reviews drifts between calls and must NOT be used to compute a page count - page with has_more instead. Often works for ids TIKTOK_SHOP_PRODUCT cannot resolve. Costs 1 credit.",
|
|
787
|
+
z.object({
|
|
788
|
+
product_id: str("TikTok Shop product id (6-25 digits)."),
|
|
789
|
+
page: onum("1-based page number (1-500, default 1)."),
|
|
790
|
+
page_size: onum("Reviews per page (1-200, default 20)."),
|
|
791
|
+
sort: ostr("'relevant' (default) is text-complete and image-heavy; 'recent' is fresher but far more text-sparse."),
|
|
792
|
+
rating: onum("Only reviews with this star rating (1-5)."),
|
|
793
|
+
has_media: obool("Only reviews with a photo or video. Shares one upstream slot with verified_only, and wins when both are set."),
|
|
794
|
+
verified_only: obool("Only verified purchases. Ignored when has_media is also set."),
|
|
795
|
+
region: ostr("Marketplace region: 'US' (default), 'GB', 'SG', 'MY', 'PH', 'TH', 'VN', or 'ID'.")
|
|
796
|
+
}),
|
|
797
|
+
(i) => client.tiktokShop.productReviews(i)
|
|
798
|
+
),
|
|
799
|
+
tool(
|
|
800
|
+
"TIKTOK_SHOP_CATEGORIES",
|
|
801
|
+
"Scavio TikTok Shop Categories",
|
|
802
|
+
"The global TikTok Shop category tree: 28 top-level categories, 240 nodes, two levels deep. Category ids are identical in every region and names are always English. Takes no parameters. Costs 1 credit.",
|
|
803
|
+
z.object({}),
|
|
804
|
+
() => client.tiktokShop.categories()
|
|
805
|
+
),
|
|
806
|
+
tool(
|
|
807
|
+
"TIKTOK_SHOP_CATEGORY_PRODUCTS",
|
|
808
|
+
"Scavio TikTok Shop Category Products",
|
|
809
|
+
"Products listed under a category id from TIKTOK_SHOP_CATEGORIES, with exact prices. Level 1 or 2 ids both work. Page size is inconsistent upstream (15 to 20), so always paginate with next_cursor; when has_more turns false after a few pages that is the end of a shallow listing, not an error. Costs 1 credit.",
|
|
810
|
+
z.object({
|
|
811
|
+
category_id: str("Category id from TIKTOK_SHOP_CATEGORIES; level 1 or 2 both work."),
|
|
812
|
+
cursor: ostr("Opaque cursor from a prior response's next_cursor."),
|
|
813
|
+
region: ostr("Marketplace region, 'US' (default) or 'GB' only - not the 8-region list.")
|
|
814
|
+
}),
|
|
815
|
+
(i) => client.tiktokShop.categoryProducts(i)
|
|
816
|
+
),
|
|
817
|
+
tool(
|
|
818
|
+
"TIKTOK_SHOP_SHOP_PRODUCTS",
|
|
819
|
+
"Scavio TikTok Shop Shop Products",
|
|
820
|
+
"A shop's TikTok Shop catalog, 30 per page, with exact prices. Shop follower count, location and shop-level rating are not available here - call TIKTOK_SHOP_PRODUCT for the full shop profile. Costs 1 credit.",
|
|
821
|
+
z.object({
|
|
822
|
+
shop_id: str("TikTok Shop seller id (also called seller_id elsewhere on TikTok)."),
|
|
823
|
+
cursor: ostr("Opaque cursor from a prior response's next_cursor."),
|
|
824
|
+
region: ostr("Marketplace region: 'US' (default), 'GB', 'SG', 'MY', 'PH', 'TH', 'VN', or 'ID'.")
|
|
825
|
+
}),
|
|
826
|
+
(i) => client.tiktokShop.shopProducts(i)
|
|
827
|
+
),
|
|
828
|
+
tool(
|
|
829
|
+
"TIKTOK_SHOP_RESOLVE",
|
|
830
|
+
"Scavio TikTok Shop Resolve",
|
|
831
|
+
"Resolve any TikTok Shop URL or share link to a product_id or shop_id, ready for the other TikTok Shop tools. Accepts shop.tiktok.com product and store pages, tiktok.com/view links, affiliate share links, and vt.tiktok.com short links. Costs 1 credit.",
|
|
832
|
+
z.object({ url: str("A TikTok Shop product or store URL, affiliate share link, or vt.tiktok.com short link.") }),
|
|
833
|
+
(i) => client.tiktokShop.resolve(i)
|
|
834
|
+
)
|
|
835
|
+
);
|
|
836
|
+
}
|
|
440
837
|
if (all || enableInstagram) {
|
|
441
838
|
tools.push(
|
|
442
839
|
tool(
|
|
@@ -575,9 +972,215 @@ function buildScavioToolkit(options = {}) {
|
|
|
575
972
|
)
|
|
576
973
|
);
|
|
577
974
|
}
|
|
975
|
+
if (all || enableX) {
|
|
976
|
+
tools.push(
|
|
977
|
+
tool(
|
|
978
|
+
"X_SEARCH",
|
|
979
|
+
"Scavio X Search",
|
|
980
|
+
"Search X (Twitter) posts. Returns data.timeline with next_cursor, prev_cursor and has_more. Costs 1 credit.",
|
|
981
|
+
z.object({
|
|
982
|
+
search: str("Search query (1-500 characters). The field is 'search', not 'query'."),
|
|
983
|
+
search_type: ostr("Result category (Capitalized): 'Top' (default), 'Latest', 'People', 'Photos', or 'Videos'."),
|
|
984
|
+
cursor: ostr("Pagination cursor from a prior response.")
|
|
985
|
+
}),
|
|
986
|
+
(i) => client.x.search(i)
|
|
987
|
+
),
|
|
988
|
+
tool(
|
|
989
|
+
"X_TWEET",
|
|
990
|
+
"Scavio X Tweet",
|
|
991
|
+
"Fetch one X post by id. Returns the tweet object plus reply_to, in_reply_to_screen_name, in_reply_to_status_id, in_reply_to_user_id and sensitive. Costs 1 credit.",
|
|
992
|
+
z.object({ tweet_id: str("Numeric post id as a string, e.g. '1808168603721650364'.") }),
|
|
993
|
+
(i) => client.x.tweet(i)
|
|
994
|
+
),
|
|
995
|
+
tool(
|
|
996
|
+
"X_TWEET_COMMENTS",
|
|
997
|
+
"Scavio X Tweet Comments",
|
|
998
|
+
"List replies to an X post. Returns data.timeline with next_cursor, prev_cursor and has_more. rank switches the upstream feed: 'latest' is chronological, 'top' is ranked. Costs 1 credit.",
|
|
999
|
+
z.object({
|
|
1000
|
+
tweet_id: str("Numeric post id as a string."),
|
|
1001
|
+
rank: ostr("Reply ordering (lowercase): 'top' (default, ranked) or 'latest' (chronological)."),
|
|
1002
|
+
cursor: ostr("Pagination cursor from a prior response.")
|
|
1003
|
+
}),
|
|
1004
|
+
(i) => client.x.tweetComments(i)
|
|
1005
|
+
),
|
|
1006
|
+
tool(
|
|
1007
|
+
"X_TWEET_RETWEETERS",
|
|
1008
|
+
"Scavio X Tweet Retweeters",
|
|
1009
|
+
"List the accounts that reposted an X post. Returns data.retweeters with next_cursor and has_more. Costs 1 credit.",
|
|
1010
|
+
z.object({
|
|
1011
|
+
tweet_id: str("Numeric post id as a string."),
|
|
1012
|
+
cursor: ostr("Pagination cursor from a prior response.")
|
|
1013
|
+
}),
|
|
1014
|
+
(i) => client.x.tweetRetweeters(i)
|
|
1015
|
+
),
|
|
1016
|
+
tool(
|
|
1017
|
+
"X_USER",
|
|
1018
|
+
"Scavio X User",
|
|
1019
|
+
"Fetch an X profile by handle: followers_count, friends_count, statuses_count, media_count, blue_verified, location, website, avatar, header_image and pinned_tweet_ids. Costs 1 credit.",
|
|
1020
|
+
z.object({ screen_name: str("An X handle WITHOUT the @, e.g. 'elonmusk'.") }),
|
|
1021
|
+
(i) => client.x.user(i)
|
|
1022
|
+
),
|
|
1023
|
+
tool(
|
|
1024
|
+
"X_USER_TWEETS",
|
|
1025
|
+
"Scavio X User Tweets",
|
|
1026
|
+
"List an X user's posts. Returns data.timeline plus pinned and user; there is no has_more on this endpoint, so page on next_cursor. Costs 1 credit.",
|
|
1027
|
+
z.object({
|
|
1028
|
+
screen_name: str("An X handle WITHOUT the @."),
|
|
1029
|
+
cursor: ostr("Pagination cursor from a prior response.")
|
|
1030
|
+
}),
|
|
1031
|
+
(i) => client.x.userTweets(i)
|
|
1032
|
+
),
|
|
1033
|
+
tool(
|
|
1034
|
+
"X_USER_REPLIES",
|
|
1035
|
+
"Scavio X User Replies",
|
|
1036
|
+
"List an X user's replies. Returns data.timeline with next_cursor and prev_cursor; no has_more. Costs 1 credit.",
|
|
1037
|
+
z.object({
|
|
1038
|
+
screen_name: str("An X handle WITHOUT the @."),
|
|
1039
|
+
cursor: ostr("Pagination cursor from a prior response.")
|
|
1040
|
+
}),
|
|
1041
|
+
(i) => client.x.userReplies(i)
|
|
1042
|
+
),
|
|
1043
|
+
tool(
|
|
1044
|
+
"X_USER_MEDIA",
|
|
1045
|
+
"Scavio X User Media",
|
|
1046
|
+
"List an X user's posts that carry photos or videos. Returns data.timeline with next_cursor and prev_cursor; no has_more. Costs 1 credit.",
|
|
1047
|
+
z.object({
|
|
1048
|
+
screen_name: str("An X handle WITHOUT the @."),
|
|
1049
|
+
cursor: ostr("Pagination cursor from a prior response.")
|
|
1050
|
+
}),
|
|
1051
|
+
(i) => client.x.userMedia(i)
|
|
1052
|
+
),
|
|
1053
|
+
tool(
|
|
1054
|
+
"X_USER_FOLLOWERS",
|
|
1055
|
+
"Scavio X User Followers",
|
|
1056
|
+
"List an X user's followers. Returns data.followers with followers_count, next_cursor and has_more. Costs 1 credit.",
|
|
1057
|
+
z.object({
|
|
1058
|
+
screen_name: str("An X handle WITHOUT the @."),
|
|
1059
|
+
cursor: ostr("Pagination cursor from a prior response.")
|
|
1060
|
+
}),
|
|
1061
|
+
(i) => client.x.userFollowers(i)
|
|
1062
|
+
),
|
|
1063
|
+
tool(
|
|
1064
|
+
"X_USER_FOLLOWINGS",
|
|
1065
|
+
"Scavio X User Followings",
|
|
1066
|
+
"List the accounts an X user follows. The response array is data.following (singular), not followings, and there is no following_count. Costs 1 credit.",
|
|
1067
|
+
z.object({
|
|
1068
|
+
screen_name: str("An X handle WITHOUT the @."),
|
|
1069
|
+
cursor: ostr("Pagination cursor from a prior response.")
|
|
1070
|
+
}),
|
|
1071
|
+
(i) => client.x.userFollowings(i)
|
|
1072
|
+
),
|
|
1073
|
+
tool(
|
|
1074
|
+
"X_TRENDING",
|
|
1075
|
+
"Scavio X Trending",
|
|
1076
|
+
"List what is trending on X for one country. Returns data.trends with no cursor and no has_more. Costs 1 credit.",
|
|
1077
|
+
z.object({ country: ostr("Country NAME, not an ISO code, e.g. 'UnitedStates' (the default).") }),
|
|
1078
|
+
(i) => client.x.trending(i)
|
|
1079
|
+
)
|
|
1080
|
+
);
|
|
1081
|
+
}
|
|
1082
|
+
if (all || enableLinkedin) {
|
|
1083
|
+
tools.push(
|
|
1084
|
+
tool(
|
|
1085
|
+
"LINKEDIN_PERSON",
|
|
1086
|
+
"Scavio LinkedIn Person",
|
|
1087
|
+
"Fetch a full LinkedIn profile: headline, about, location, follower and connection counts, current_company, experiences, educations, honors_and_awards, bio_links and similar profiles. Costs 1 credit.",
|
|
1088
|
+
z.object({
|
|
1089
|
+
username: ostr("Public identifier / vanity handle, e.g. 'williamhgates'. Provide this or url."),
|
|
1090
|
+
url: ostr("Full LinkedIn profile URL. Provide this or username.")
|
|
1091
|
+
}),
|
|
1092
|
+
(i) => client.linkedin.person(i)
|
|
1093
|
+
),
|
|
1094
|
+
tool(
|
|
1095
|
+
"LINKEDIN_PERSON_ABOUT",
|
|
1096
|
+
"Scavio LinkedIn Person About",
|
|
1097
|
+
"The about-only slice of a LinkedIn profile: about, headline, education_summary, experiences, educations, honors_and_awards and bio_links. Same upstream call as LINKEDIN_PERSON, shaped down. Costs 1 credit.",
|
|
1098
|
+
z.object({
|
|
1099
|
+
username: ostr("Public identifier / vanity handle. Provide this or url."),
|
|
1100
|
+
url: ostr("Full LinkedIn profile URL. Provide this or username.")
|
|
1101
|
+
}),
|
|
1102
|
+
(i) => client.linkedin.personAbout(i)
|
|
1103
|
+
),
|
|
1104
|
+
tool(
|
|
1105
|
+
"LINKEDIN_PERSON_POSTS",
|
|
1106
|
+
"Scavio LinkedIn Person Posts",
|
|
1107
|
+
"A member's LinkedIn feed - their own posts, or posts they commented on or reacted to via type. 50 per page; advance with next_cursor. Costs 10 credits.",
|
|
1108
|
+
z.object({
|
|
1109
|
+
username: ostr("Public identifier / vanity handle. Provide this or url."),
|
|
1110
|
+
url: ostr("Full LinkedIn profile URL. Provide this or username."),
|
|
1111
|
+
type: ostr("Which feed: 'posts' (default), 'comments' (posts they commented on), or 'reactions' (posts they reacted to)."),
|
|
1112
|
+
cursor: ostr("Opaque cursor from a prior response's next_cursor.")
|
|
1113
|
+
}),
|
|
1114
|
+
(i) => client.linkedin.personPosts(i)
|
|
1115
|
+
),
|
|
1116
|
+
tool(
|
|
1117
|
+
"LINKEDIN_COMPANY",
|
|
1118
|
+
"Scavio LinkedIn Company",
|
|
1119
|
+
"Fetch a LinkedIn company profile: description, website, industries, specialties, employee and follower counts, headquarters, locations, similar and affiliated companies, and featured_employees (a 4-6 person sample, the documented substitute for the retired employee directory). Costs 1 credit.",
|
|
1120
|
+
z.object({
|
|
1121
|
+
company: ostr("Company universal name / slug, e.g. 'microsoft'. Provide this or url."),
|
|
1122
|
+
url: ostr("Full LinkedIn company URL. Provide this or company.")
|
|
1123
|
+
}),
|
|
1124
|
+
(i) => client.linkedin.company(i)
|
|
1125
|
+
),
|
|
1126
|
+
tool(
|
|
1127
|
+
"LINKEDIN_COMPANY_POSTS",
|
|
1128
|
+
"Scavio LinkedIn Company Posts",
|
|
1129
|
+
"Recent posts from a LinkedIn company page, 50 per page; advance with next_cursor. There is no type selector here - that is person-only. Costs 10 credits.",
|
|
1130
|
+
z.object({
|
|
1131
|
+
company: ostr("Company universal name / slug. Provide this or url."),
|
|
1132
|
+
url: ostr("Full LinkedIn company URL. Provide this or company."),
|
|
1133
|
+
cursor: ostr("Opaque cursor from a prior response's next_cursor.")
|
|
1134
|
+
}),
|
|
1135
|
+
(i) => client.linkedin.companyPosts(i)
|
|
1136
|
+
),
|
|
1137
|
+
tool(
|
|
1138
|
+
"LINKEDIN_SEARCH_JOBS",
|
|
1139
|
+
"Scavio LinkedIn Search Jobs",
|
|
1140
|
+
"Search LinkedIn job listings, 25 per page; advance with next_cursor. Upstream rotates its result set so pages overlap - dedupe by job id. Costs 10 credits.",
|
|
1141
|
+
z.object({
|
|
1142
|
+
search: str("Search keyword, e.g. 'software engineer'. The field is 'search', not 'query'."),
|
|
1143
|
+
location: ostr("Geographic filter; omit to search everywhere."),
|
|
1144
|
+
cursor: ostr("Opaque cursor from a prior response's next_cursor.")
|
|
1145
|
+
}),
|
|
1146
|
+
(i) => client.linkedin.searchJobs(i)
|
|
1147
|
+
),
|
|
1148
|
+
tool(
|
|
1149
|
+
"LINKEDIN_JOB",
|
|
1150
|
+
"Scavio LinkedIn Job",
|
|
1151
|
+
"Full detail for one LinkedIn job listing, including the hiring company. The most expensive endpoint in the API - about 1 in 5 ids from LINKEDIN_SEARCH_JOBS has no detail record upstream and answers 404 unbilled, so skip rather than retry. Costs 30 credits.",
|
|
1152
|
+
z.object({
|
|
1153
|
+
job_id: ostr("Job listing id, e.g. '4415427228'. Provide this or url."),
|
|
1154
|
+
url: ostr("Full LinkedIn job URL. Provide this or job_id.")
|
|
1155
|
+
}),
|
|
1156
|
+
(i) => client.linkedin.job(i)
|
|
1157
|
+
),
|
|
1158
|
+
tool(
|
|
1159
|
+
"LINKEDIN_POST",
|
|
1160
|
+
"Scavio LinkedIn Post",
|
|
1161
|
+
"Full detail for one LinkedIn post: text, media, hashtags, tagged companies and people, reaction and comment counts, author, and its top visible comments. Costs 1 credit.",
|
|
1162
|
+
z.object({
|
|
1163
|
+
post_id: ostr("Post id or activity urn, e.g. '7488618410256523265'. Provide this or url."),
|
|
1164
|
+
url: ostr("Full LinkedIn post URL. Provide this or post_id.")
|
|
1165
|
+
}),
|
|
1166
|
+
(i) => client.linkedin.post(i)
|
|
1167
|
+
),
|
|
1168
|
+
tool(
|
|
1169
|
+
"LINKEDIN_POST_COMMENTS",
|
|
1170
|
+
"Scavio LinkedIn Post Comments",
|
|
1171
|
+
"Comments on a LinkedIn post with their replies. This is the only LinkedIn endpoint paginated by a 1-based integer page rather than a cursor, and page size varies upstream - keep paging until a page comes back empty. Costs 10 credits.",
|
|
1172
|
+
z.object({
|
|
1173
|
+
post_id: ostr("Post id or activity urn. Provide this or url."),
|
|
1174
|
+
url: ostr("Full LinkedIn post URL. Provide this or post_id."),
|
|
1175
|
+
page: onum("1-based page number (default 1). Page size varies, so page until empty.")
|
|
1176
|
+
}),
|
|
1177
|
+
(i) => client.linkedin.postComments(i)
|
|
1178
|
+
)
|
|
1179
|
+
);
|
|
1180
|
+
}
|
|
578
1181
|
return experimental_createToolkit("SCAVIO", {
|
|
579
1182
|
name: "Scavio",
|
|
580
|
-
description: "Real-time structured search over Google,
|
|
1183
|
+
description: "Real-time structured search over Google (SERP, AI Mode, Maps, Shopping, Flights, Hotels, News, Trends), YouTube, Amazon, Walmart, Reddit, TikTok, TikTok Shop, Instagram, X and LinkedIn.",
|
|
581
1184
|
tools
|
|
582
1185
|
});
|
|
583
1186
|
}
|