@noimosai/platform-cli 0.1.2 → 0.1.4
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 +12 -56
- package/bin/noimos-platform.mjs +3 -4
- package/dist/cli/cli.js +477 -87
- package/dist/cli/command-help.js +349 -23
- package/dist/cli/download.js +25 -25
- package/dist/cli/input-error.js +48 -0
- package/dist/cli/local-agents.js +199 -0
- package/dist/cli/mcp-supervisor.js +136 -0
- package/dist/cli/noimos-cli.js +72 -0
- package/dist/cli/project-archive.js +27 -0
- package/dist/cli/project-files.js +25 -0
- package/dist/cli/project-sync.js +259 -0
- package/dist/cli/setup-lock.js +1 -0
- package/dist/cli/setup.js +347 -0
- package/dist/cli/skills.js +142 -0
- package/dist/cli/team-harness-targets.js +337 -0
- package/dist/cli/team-harness.js +1562 -0
- package/dist/cli/team-resources.js +222 -0
- package/dist/cli/team-skills.js +457 -0
- package/dist/cli/update-bootstrap.js +437 -0
- package/dist/cli/update-release.js +212 -0
- package/dist/cli/version.js +1 -0
- package/dist/cli/wallet.js +85 -0
- package/dist/client/agent-run.js +1425 -0
- package/dist/client/browser.js +905 -0
- package/dist/client/distribution.js +2 -0
- package/dist/client/evm-wallet.js +214 -0
- package/dist/client/execution-context.js +14 -0
- package/dist/client/failure-recovery.js +128 -0
- package/dist/client/index.js +4 -225
- package/dist/client/local-input.js +33 -12
- package/dist/client/local-profile-lock.js +52 -0
- package/dist/client/local-profile.js +181 -0
- package/dist/client/local-projects.js +131 -0
- package/dist/client/local-setup.js +93 -0
- package/dist/client/realtime-voice.js +184 -0
- package/dist/client/tool-name-hints.js +48 -0
- package/dist/client/wallet-access.js +214 -0
- package/dist/mcp/agent-server.js +345 -0
- package/dist/mcp/context.js +86 -0
- package/dist/mcp/host-schema.js +76 -0
- package/dist/mcp/icon.js +1 -0
- package/dist/mcp/index.js +3 -0
- package/dist/mcp/instructions.js +26 -0
- package/dist/mcp/local-projects.js +42 -0
- package/dist/mcp/local-upload.js +39 -0
- package/dist/mcp/noimos-runtime.js +18 -0
- package/dist/mcp/noimos-server.js +38 -0
- package/dist/mcp/operations.js +40 -0
- package/dist/mcp/parallel-result.js +17 -0
- package/dist/mcp/project-sync.js +105 -0
- package/dist/mcp/results-reply.js +15 -0
- package/dist/mcp/runtime.js +81 -0
- package/dist/mcp/server.js +410 -0
- package/dist/mcp/team-skill.js +63 -0
- package/dist/mcp/update-notice.js +75 -0
- package/dist/mcp/version.js +1 -0
- package/dist/schema/accountRequestMethods.js +1 -0
- package/dist/schema/boundedBody.js +30 -0
- package/dist/schema/cronValidator.js +150 -0
- package/dist/schema/platformApiKey.js +14 -0
- package/dist/schema/platformAppAuth.js +11 -0
- package/dist/schema/platformBillingConstants.js +4 -0
- package/dist/schema/platformCapabilityFamilies.js +293 -0
- package/dist/schema/platformConnectionCatalog.js +39 -0
- package/dist/schema/platformConnectionPolicy.js +33 -0
- package/dist/schema/platformCustomTools.js +148 -0
- package/dist/schema/platformEndUserApi.js +62 -0
- package/dist/schema/platformFunding.js +10 -0
- package/dist/schema/platformHttpConstraints.js +12 -0
- package/dist/schema/platformLocalSetup.js +25 -0
- package/dist/schema/platformMcpTools.js +7 -0
- package/dist/schema/platformMetaTools.js +63 -0
- package/dist/schema/platformMonitorSchedule.js +123 -0
- package/dist/schema/platformMonitors.js +159 -0
- package/dist/schema/platformOAuth.js +13 -0
- package/dist/schema/platformProjectPermissions.js +33 -0
- package/dist/schema/platformPublicExecution.js +202 -21
- package/dist/schema/platformRoutes.js +122 -0
- package/dist/schema/platformSkills.js +11 -0
- package/dist/schema/platformTeamSecretName.js +3 -0
- package/dist/schema/platformTeamSkillSlug.js +1 -0
- package/dist/schema/platformTeamSkills.js +302 -0
- package/dist/schema/platformToolAccess.js +62 -0
- package/dist/schema/platformTriggers.js +153 -0
- package/dist/schema/platformWorkflows.js +100 -0
- package/dist/schema/scheduleTimeZone.js +15 -0
- package/dist/schema/toolDiscovery.js +71 -0
- package/dist/schema/toolInputRepair.js +122 -0
- package/dist/schema/toolResultContext.js +51 -0
- package/dist/schema/untrustedContent.js +35 -0
- package/npm-shrinkwrap.json +73 -0
- package/package.json +6 -3
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export async function readBoundedBody(message, maximumBytes) {
|
|
2
|
+
const reader = message.body?.getReader();
|
|
3
|
+
if (!reader)
|
|
4
|
+
return { status: "missing" };
|
|
5
|
+
const chunks = [];
|
|
6
|
+
let size = 0;
|
|
7
|
+
try {
|
|
8
|
+
for (;;) {
|
|
9
|
+
const { value, done } = await reader.read();
|
|
10
|
+
if (done)
|
|
11
|
+
break;
|
|
12
|
+
size += value.byteLength;
|
|
13
|
+
if (size > maximumBytes) {
|
|
14
|
+
await reader.cancel();
|
|
15
|
+
return { status: "too_large" };
|
|
16
|
+
}
|
|
17
|
+
chunks.push(value);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
finally {
|
|
21
|
+
reader.releaseLock();
|
|
22
|
+
}
|
|
23
|
+
const bytes = new Uint8Array(size);
|
|
24
|
+
let offset = 0;
|
|
25
|
+
for (const chunk of chunks) {
|
|
26
|
+
bytes.set(chunk, offset);
|
|
27
|
+
offset += chunk.byteLength;
|
|
28
|
+
}
|
|
29
|
+
return { status: "ok", bytes };
|
|
30
|
+
}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
const STRICT_CRON_RE = /^([\*0-9A-Za-z,\-\/]+)\s+([\*0-9A-Za-z,\-\/]+)\s+([\*0-9A-Za-z,\-\/]+)\s+([\*0-9A-Za-z,\-\/]+)\s+([\*0-9A-Za-z,\-\/]+)$/;
|
|
2
|
+
export function isStrictCron5Field(cron) {
|
|
3
|
+
if (typeof cron !== "string")
|
|
4
|
+
return false;
|
|
5
|
+
return STRICT_CRON_RE.test(cron.trim());
|
|
6
|
+
}
|
|
7
|
+
const RANGES = {
|
|
8
|
+
minute: { min: 0, max: 59 },
|
|
9
|
+
hour: { min: 0, max: 23 },
|
|
10
|
+
dayOfMonth: { min: 1, max: 31 },
|
|
11
|
+
month: { min: 1, max: 12 },
|
|
12
|
+
dayOfWeek: { min: 0, max: 6 },
|
|
13
|
+
};
|
|
14
|
+
const MONTH_NAMES = {
|
|
15
|
+
JAN: 1, FEB: 2, MAR: 3, APR: 4, MAY: 5, JUN: 6,
|
|
16
|
+
JUL: 7, AUG: 8, SEP: 9, OCT: 10, NOV: 11, DEC: 12,
|
|
17
|
+
};
|
|
18
|
+
const DOW_NAMES = {
|
|
19
|
+
SUN: 0, MON: 1, TUE: 2, WED: 3, THU: 4, FRI: 5, SAT: 6,
|
|
20
|
+
};
|
|
21
|
+
function normalizeToken(token, names) {
|
|
22
|
+
if (!names)
|
|
23
|
+
return token;
|
|
24
|
+
const upper = token.trim().toUpperCase();
|
|
25
|
+
return upper in names ? String(names[upper]) : token;
|
|
26
|
+
}
|
|
27
|
+
function expandField(field, range, names) {
|
|
28
|
+
const out = new Set();
|
|
29
|
+
for (const part of field.split(",")) {
|
|
30
|
+
const stepMatch = part.match(/^(.+)\/(\d+)$/);
|
|
31
|
+
let base = part;
|
|
32
|
+
let step = 1;
|
|
33
|
+
if (stepMatch) {
|
|
34
|
+
base = stepMatch[1];
|
|
35
|
+
step = Number.parseInt(stepMatch[2], 10);
|
|
36
|
+
if (!Number.isFinite(step) || step <= 0)
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
let lo;
|
|
40
|
+
let hi;
|
|
41
|
+
if (base === "*") {
|
|
42
|
+
lo = range.min;
|
|
43
|
+
hi = range.openMax ?? range.max;
|
|
44
|
+
}
|
|
45
|
+
else if (base.includes("-")) {
|
|
46
|
+
const [a, b] = base.split("-");
|
|
47
|
+
lo = Number.parseInt(normalizeToken(a ?? "", names), 10);
|
|
48
|
+
hi = Number.parseInt(normalizeToken(b ?? "", names), 10);
|
|
49
|
+
if (!Number.isFinite(lo) || !Number.isFinite(hi))
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
const v = Number.parseInt(normalizeToken(base, names), 10);
|
|
54
|
+
if (!Number.isFinite(v))
|
|
55
|
+
return null;
|
|
56
|
+
lo = v;
|
|
57
|
+
hi = stepMatch ? (range.openMax ?? range.max) : v;
|
|
58
|
+
}
|
|
59
|
+
if (lo < range.min || hi > range.max || lo > hi)
|
|
60
|
+
return null;
|
|
61
|
+
for (let i = lo; i <= hi; i += step)
|
|
62
|
+
out.add(i);
|
|
63
|
+
}
|
|
64
|
+
return out.size > 0 ? out : null;
|
|
65
|
+
}
|
|
66
|
+
export function parseCron(cron) {
|
|
67
|
+
if (!isStrictCron5Field(cron))
|
|
68
|
+
return null;
|
|
69
|
+
const [minute, hour, dom, month, dow] = cron.trim().split(/\s+/);
|
|
70
|
+
const minutes = expandField(minute, RANGES.minute);
|
|
71
|
+
const hours = expandField(hour, RANGES.hour);
|
|
72
|
+
const daysOfMonth = expandField(dom, RANGES.dayOfMonth);
|
|
73
|
+
const months = expandField(month, RANGES.month, MONTH_NAMES);
|
|
74
|
+
const dowRaw = expandField(dow, { min: RANGES.dayOfWeek.min, max: 7, openMax: RANGES.dayOfWeek.max }, DOW_NAMES);
|
|
75
|
+
const dowExpanded = dowRaw && new Set([...dowRaw].map((d) => (d === 7 ? 0 : d)));
|
|
76
|
+
if (!minutes || !hours || !daysOfMonth || !months || !dowExpanded)
|
|
77
|
+
return null;
|
|
78
|
+
return {
|
|
79
|
+
minutes,
|
|
80
|
+
hours,
|
|
81
|
+
daysOfMonth,
|
|
82
|
+
months,
|
|
83
|
+
daysOfWeek: dowExpanded,
|
|
84
|
+
dayRestrictionOr: dom !== "*" && dow !== "*",
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
export function isValidCron(cron) {
|
|
88
|
+
if (typeof cron !== "string")
|
|
89
|
+
return false;
|
|
90
|
+
return parseCron(cron) !== null;
|
|
91
|
+
}
|
|
92
|
+
export function isCronTooFrequent(cron, minIntervalMinutes) {
|
|
93
|
+
const fields = cron.trim().split(/\s+/);
|
|
94
|
+
if (fields.length !== 5)
|
|
95
|
+
return true;
|
|
96
|
+
const minutes = expandField(fields[0], RANGES.minute);
|
|
97
|
+
const hours = expandField(fields[1], RANGES.hour);
|
|
98
|
+
if (!minutes || !hours)
|
|
99
|
+
return true;
|
|
100
|
+
const slots = [];
|
|
101
|
+
for (const h of hours) {
|
|
102
|
+
for (const m of minutes)
|
|
103
|
+
slots.push(h * 60 + m);
|
|
104
|
+
}
|
|
105
|
+
slots.sort((a, b) => a - b);
|
|
106
|
+
for (let i = 1; i < slots.length; i++) {
|
|
107
|
+
if (slots[i] - slots[i - 1] < minIntervalMinutes)
|
|
108
|
+
return true;
|
|
109
|
+
}
|
|
110
|
+
return slots[0] + 1440 - slots[slots.length - 1] < minIntervalMinutes;
|
|
111
|
+
}
|
|
112
|
+
function matches(parsed, d) {
|
|
113
|
+
if (!parsed.minutes.has(d.getMinutes()))
|
|
114
|
+
return false;
|
|
115
|
+
if (!parsed.hours.has(d.getHours()))
|
|
116
|
+
return false;
|
|
117
|
+
if (!parsed.months.has(d.getMonth() + 1))
|
|
118
|
+
return false;
|
|
119
|
+
const domMatch = parsed.daysOfMonth.has(d.getDate());
|
|
120
|
+
const dowMatch = parsed.daysOfWeek.has(d.getDay());
|
|
121
|
+
if (parsed.dayRestrictionOr)
|
|
122
|
+
return domMatch || dowMatch;
|
|
123
|
+
return domMatch && dowMatch;
|
|
124
|
+
}
|
|
125
|
+
export function findNextFires(cron, from, deadline, max = 30) {
|
|
126
|
+
const parsed = parseCron(cron);
|
|
127
|
+
if (!parsed)
|
|
128
|
+
return [];
|
|
129
|
+
if (!(deadline.getTime() > from.getTime()))
|
|
130
|
+
return [];
|
|
131
|
+
const fires = [];
|
|
132
|
+
const cursor = new Date(from.getTime());
|
|
133
|
+
cursor.setSeconds(0, 0);
|
|
134
|
+
cursor.setTime(cursor.getTime() + 60_000);
|
|
135
|
+
const HARD_CAP_MINUTES = 370 * 24 * 60;
|
|
136
|
+
let ticks = 0;
|
|
137
|
+
while (cursor.getTime() <= deadline.getTime() && ticks < HARD_CAP_MINUTES) {
|
|
138
|
+
if (matches(parsed, cursor)) {
|
|
139
|
+
fires.push(new Date(cursor.getTime()));
|
|
140
|
+
if (fires.length >= max)
|
|
141
|
+
break;
|
|
142
|
+
}
|
|
143
|
+
cursor.setTime(cursor.getTime() + 60_000);
|
|
144
|
+
ticks++;
|
|
145
|
+
}
|
|
146
|
+
return fires;
|
|
147
|
+
}
|
|
148
|
+
export function cronFiresBeforeDeadline(cron, deadline, from = new Date()) {
|
|
149
|
+
return findNextFires(cron, from, deadline, 1).length > 0;
|
|
150
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export const PLATFORM_KEY_PREFIXES = { noimos: "nmp_", relvo: "rlv_" };
|
|
2
|
+
export const PLATFORM_API_KEY_PATTERN = /^(?:nmp|rlv)_[A-Za-z0-9_-]{43}$/;
|
|
3
|
+
export const PLATFORM_API_KEY_LENGTH = 47;
|
|
4
|
+
export const PLATFORM_CLIENT_HEADERS = { noimos: "x-noimos-client", relvo: "x-relvo-client" };
|
|
5
|
+
export const PLATFORM_PRODUCT_NAMES = { noimos: "NoimosAI Platform", relvo: "Relvo" };
|
|
6
|
+
export function isRelvoProduct(product) {
|
|
7
|
+
return product === "relvo";
|
|
8
|
+
}
|
|
9
|
+
export function platformKeyProduct(key) {
|
|
10
|
+
for (const product of Object.keys(PLATFORM_KEY_PREFIXES))
|
|
11
|
+
if (key.startsWith(PLATFORM_KEY_PREFIXES[product]))
|
|
12
|
+
return product;
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export const PLATFORM_APP_LIMITS = { secretChars: 4096, plainChars: 256, labelChars: 80, fields: 8,
|
|
3
|
+
oauthClientIdChars: 2048, oauthScopeChars: 256, oauthScopes: 512, oauthScopeBytes: 16_384 };
|
|
4
|
+
export const platformAppOAuthClientSchema = z.object({
|
|
5
|
+
clientId: z.string().trim().min(1).max(PLATFORM_APP_LIMITS.oauthClientIdChars),
|
|
6
|
+
clientSecret: z.string().min(1).max(PLATFORM_APP_LIMITS.secretChars).optional(),
|
|
7
|
+
clientAuth: z.enum(["basic", "body", "none"]).optional(),
|
|
8
|
+
}).strict().refine(client => client.clientAuth === undefined || (client.clientAuth === "none" ? !client.clientSecret : Boolean(client.clientSecret)), "A confidential client needs a secret; a public client has none");
|
|
9
|
+
export const platformAppScopesSchema = z.array(z.string().min(1).max(PLATFORM_APP_LIMITS.oauthScopeChars).regex(/^\S+$/)).max(PLATFORM_APP_LIMITS.oauthScopes)
|
|
10
|
+
.refine(values => new Set(values).size === values.length, "Scopes must be unique")
|
|
11
|
+
.refine(values => new TextEncoder().encode(JSON.stringify(values)).byteLength <= PLATFORM_APP_LIMITS.oauthScopeBytes, "Scopes are too long to carry through a sign-in");
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
const variants = {
|
|
2
|
+
generate_video: ["generate_openrouter_video"],
|
|
3
|
+
generate_avatar_video: ["animate_kling_avatar", "generate_omnihuman_video"],
|
|
4
|
+
search_people: ["apollo_people_search", "anyapi_apollo_people_search", "anyapi_people_search_ai_ark", "anyapi_people_search_crustdata",
|
|
5
|
+
"anyapi_people_search_crustdata_v3", "anyapi_people_search_fullenrich", "anyapi_people_search_lusha", "anyapi_people_search_peopledatalabs",
|
|
6
|
+
"anyapi_people_search_prospeo", "anyapi_people_search_quickenrich", "pdl_people_search", "prospeo_people_search",
|
|
7
|
+
"firecrawl_fullenrich_people_search", "brightdata_business_people_search"],
|
|
8
|
+
search_organizations: ["apollo_company_search", "anyapi_apollo_organizations_search", "anyapi_company_search_ai_ark",
|
|
9
|
+
"anyapi_company_search_crustdata", "anyapi_company_search_crustdata_v3", "anyapi_company_search_fullenrich",
|
|
10
|
+
"anyapi_company_search_peopledatalabs", "anyapi_company_search_prospeo", "anyapi_company_search_quickenrich", "pdl_company_search",
|
|
11
|
+
"prospeo_company_search", "firecrawl_fullenrich_companies_search", "brightdata_business_company_search",
|
|
12
|
+
"predictleads_discover_companies", "predictleads_discover_extended_companies"],
|
|
13
|
+
find_companies: ["hunter_discover", "hunter_discover_people"],
|
|
14
|
+
enrich_organization: ["apollo_company_enrich", "apollo_companies_enrich", "anyapi_apollo_organization_enrich",
|
|
15
|
+
"anyapi_apollo_organizations_bulk_enrich", "anyapi_company_enrichment_crustdata", "anyapi_company_enrichment_crustdata_v3",
|
|
16
|
+
"anyapi_company_enrichment_lusha", "anyapi_company_enrichment_peopledatalabs", "anyapi_company_enrichment_prospeo", "pdl_company_enrich",
|
|
17
|
+
"pdl_companies_bulk_enrich", "prospeo_company_enrich", "prospeo_companies_enrich", "hunter_company_enrich", "findymail_company_enrich",
|
|
18
|
+
"firecrawl_datalegion_companies_enrich_base", "firecrawl_datalegion_companies_enrich_premium", "firecrawl_fullenrich_companies_lookup",
|
|
19
|
+
"predictleads_company", "predictleads_extended_company"],
|
|
20
|
+
get_organization_job_postings: ["apollo_company_jobs", "anyapi_apollo_organization_jobs"],
|
|
21
|
+
find_work_email: ["hunter_email_find", "findymail_email_find", "findymail_email_find_profile", "anyapi_email_find",
|
|
22
|
+
"anyapi_email_finding_dropleads", "anyapi_email_finding_icypeas", "anyapi_email_finding_quickenrich", "anyapi_email_finding_zerobounce",
|
|
23
|
+
"anyapi_linkedin_email", "anyapi_person_enrichment_bettercontact"],
|
|
24
|
+
find_company_emails: ["hunter_domain_search", "anyapi_email_finding_hunter_domain", "findymail_domain_contacts",
|
|
25
|
+
"anyapi_people_search_quickenrich_company"],
|
|
26
|
+
verify_email: ["hunter_email_verify", "debounce_email_verify", "findymail_email_verify", "anyapi_email_verify",
|
|
27
|
+
"anyapi_email_verification_allegrow", "anyapi_email_verification_bounceban", "anyapi_email_verification_icypeas",
|
|
28
|
+
"anyapi_email_verification_zerobounce"],
|
|
29
|
+
search_x_posts: ["anyapi_twitter_search", "tikhub_x_web_fetch_search_timeline"],
|
|
30
|
+
fetch_x_posts: ["tikhub_x_web_fetch_tweet_detail"],
|
|
31
|
+
fetch_x_posts_by_url: ["anyapi_twitter_tweet", "brightdata_twitter_posts_collect_by_url"],
|
|
32
|
+
get_x_post_comments: ["anyapi_twitter_replies", "tikhub_x_web_fetch_post_comments"],
|
|
33
|
+
get_x_profile: ["anyapi_twitter_profile", "tikhub_x_web_fetch_user_profile", "brightdata_twitter_profiles_collect_by_url"],
|
|
34
|
+
get_x_trends: ["anyapi_twitter_trends", "tikhub_x_web_fetch_trending"],
|
|
35
|
+
search_x_communities: ["anyapi_twitter_search_communities", "tikhub_x_web_fetch_search_communities"],
|
|
36
|
+
get_x_community_posts: ["anyapi_twitter_community_tweets", "tikhub_x_web_fetch_community_timeline"],
|
|
37
|
+
search_threads: ["anyapi_threads_search", "apify_threads_search", "tikhub_threads_web_search_posts", "tikhub_threads_web_search_top",
|
|
38
|
+
"tikhub_threads_web_search_recent"],
|
|
39
|
+
search_threads_profiles: ["anyapi_threads_search_users", "tikhub_threads_web_search_profiles"],
|
|
40
|
+
fetch_threads_post: ["anyapi_threads_post", "tikhub_threads_web_fetch_post_detail", "tikhub_threads_web_fetch_post_detail_v2",
|
|
41
|
+
"brightdata_threads_posts_collect_by_url"],
|
|
42
|
+
get_bluesky_profile: ["anyapi_bluesky_profile"],
|
|
43
|
+
get_instagram_profile: ["anyapi_instagram_profile", "anyapi_instagram_basic_profile", "tikhub_instagram_v1_fetch_user_info_by_username",
|
|
44
|
+
"tikhub_instagram_v1_fetch_user_info_by_username_v2", "tikhub_instagram_v1_fetch_user_info_by_username_v3",
|
|
45
|
+
"tikhub_instagram_v2_fetch_user_info", "tikhub_instagram_v3_get_user_profile", "apify_instagram_profile",
|
|
46
|
+
"brightdata_instagram_profiles_collect_by_url", "brightdata_instagram_profiles_discover_by_username", "searchapi_instagram_profile", "serpapi_instagram_profile",
|
|
47
|
+
"firecrawl_oriane_instagram_profile_lookup"],
|
|
48
|
+
search_instagram_posts: ["anyapi_instagram_user_posts", "tikhub_instagram_v1_fetch_user_posts", "tikhub_instagram_v1_fetch_user_posts_v2",
|
|
49
|
+
"tikhub_instagram_v2_fetch_user_posts", "tikhub_instagram_v3_get_user_posts", "apify_instagram_posts",
|
|
50
|
+
"brightdata_instagram_posts_discover_by_url"],
|
|
51
|
+
search_instagram_reels: ["anyapi_instagram_user_reels", "tikhub_instagram_v1_fetch_user_reels", "tikhub_instagram_v2_fetch_user_reels",
|
|
52
|
+
"tikhub_instagram_v3_get_user_reels", "apify_instagram_reels", "brightdata_instagram_reels_discover_by_url",
|
|
53
|
+
"brightdata_instagram_reels_discover_by_url_all_reels"],
|
|
54
|
+
search_instagram_by_keyword: ["anyapi_instagram_hashtag_recent_posts", "anyapi_instagram_hashtag_top_posts", "anyapi_instagram_search_hashtag",
|
|
55
|
+
"tikhub_instagram_v1_fetch_hashtag_posts", "tikhub_instagram_v2_fetch_hashtag_posts", "tikhub_instagram_v3_get_hashtag_posts",
|
|
56
|
+
"apify_instagram_hashtags"],
|
|
57
|
+
search_instagram_keyword: ["anyapi_instagram_search", "tikhub_instagram_v1_fetch_search", "tikhub_instagram_v2_search_users",
|
|
58
|
+
"tikhub_instagram_v2_search_hashtags", "tikhub_instagram_v3_search_users", "tikhub_instagram_v3_search_hashtags"],
|
|
59
|
+
search_instagram_phrase: ["tikhub_instagram_v2_general_search", "tikhub_instagram_v3_general_search"],
|
|
60
|
+
search_instagram_places: ["anyapi_instagram_search_locations", "tikhub_instagram_v2_search_locations",
|
|
61
|
+
"tikhub_instagram_v2_search_by_coordinates", "tikhub_instagram_v3_search_by_coordinates"],
|
|
62
|
+
search_instagram_audio: ["anyapi_instagram_audio_reels", "tikhub_instagram_v1_fetch_music_posts", "tikhub_instagram_v2_fetch_music_posts",
|
|
63
|
+
"tikhub_instagram_v3_get_music_posts", "tikhub_instagram_v2_search_music"],
|
|
64
|
+
get_instagram_post_comments: ["anyapi_instagram_post_comments", "tikhub_instagram_v1_fetch_post_comments_v2",
|
|
65
|
+
"tikhub_instagram_v2_fetch_post_comments", "tikhub_instagram_v3_get_post_comments", "brightdata_instagram_comments_collect_by_url",
|
|
66
|
+
"searchapi_instagram_comments"],
|
|
67
|
+
get_instagram_comment_replies: ["anyapi_instagram_comment_replies", "tikhub_instagram_v1_fetch_comment_replies",
|
|
68
|
+
"tikhub_instagram_v2_fetch_comment_replies", "tikhub_instagram_v3_get_comment_replies"],
|
|
69
|
+
get_instagram_stories: ["anyapi_instagram_stories_full", "anyapi_instagram_stories_thin", "tikhub_instagram_v2_fetch_user_stories",
|
|
70
|
+
"tikhub_instagram_v3_get_user_stories"],
|
|
71
|
+
get_instagram_highlights: ["anyapi_instagram_user_highlights", "tikhub_instagram_v2_fetch_user_highlights",
|
|
72
|
+
"tikhub_instagram_v3_get_user_highlights"],
|
|
73
|
+
get_instagram_tagged_posts: ["anyapi_instagram_tagged_posts", "tikhub_instagram_v1_fetch_user_tagged_posts",
|
|
74
|
+
"tikhub_instagram_v2_fetch_user_tagged_posts", "tikhub_instagram_v3_get_user_tagged_posts"],
|
|
75
|
+
get_instagram_former_usernames: ["tikhub_instagram_v3_get_user_former_usernames"],
|
|
76
|
+
get_instagram_account_network: ["anyapi_instagram_followers", "anyapi_instagram_following", "tikhub_instagram_v2_fetch_user_followers",
|
|
77
|
+
"tikhub_instagram_v2_fetch_user_following", "tikhub_instagram_v3_get_user_followers", "tikhub_instagram_v3_get_user_following"],
|
|
78
|
+
get_instagram_reposts: ["anyapi_instagram_user_reposts", "tikhub_instagram_v1_fetch_user_reposts"],
|
|
79
|
+
find_similar_instagram_accounts: ["anyapi_instagram_similar_profiles", "tikhub_instagram_v1_fetch_related_profiles",
|
|
80
|
+
"tikhub_instagram_v2_fetch_similar_users", "tikhub_instagram_v3_get_similar_users"],
|
|
81
|
+
scrape_facebook: ["anyapi_facebook_profile", "brightdata_facebook_pages_and_profiles_collect_by_url", "searchapi_facebook_business_page",
|
|
82
|
+
"serpapi_facebook_profile"],
|
|
83
|
+
scrape_facebook_posts: ["anyapi_facebook_profile_posts", "apify_facebook_posts", "brightdata_facebook_pages_posts_collect_by_url"],
|
|
84
|
+
search_facebook: ["anyapi_facebook_search_pages", "anyapi_facebook_page_lookup", "apify_facebook_search"],
|
|
85
|
+
search_facebook_posts: ["anyapi_facebook_search_posts", "apify_facebook_post_search"],
|
|
86
|
+
search_facebook_people: ["apify_facebook_people_search"],
|
|
87
|
+
fetch_facebook_post: ["anyapi_facebook_post", "brightdata_facebook_posts_collect_by_url"],
|
|
88
|
+
search_tiktok_posts: ["anyapi_tiktok_search_keyword", "anyapi_tiktok_search_top", "anyapi_tiktok_search_hashtag", "anyapi_tiktok_hashtag_videos",
|
|
89
|
+
"anyapi_tiktok_profile_videos", "tikhub_tiktok_app_v3_fetch_video_search_result", "tikhub_tiktok_web_fetch_search_video",
|
|
90
|
+
"tikhub_tiktok_app_v3_fetch_hashtag_video_list", "tikhub_tiktok_web_fetch_tag_post", "tikhub_tiktok_app_v3_fetch_user_post_videos",
|
|
91
|
+
"tikhub_tiktok_app_v3_fetch_user_post_videos_v2", "tikhub_tiktok_app_v3_fetch_user_post_videos_v3", "tikhub_tiktok_web_fetch_user_post",
|
|
92
|
+
"searchapi_tiktok_search", "searchapi_tiktok_profile_videos", "brightdata_tiktok_posts_discover_by_keyword",
|
|
93
|
+
"brightdata_tiktok_posts_discover_by_profile_url", "brightdata_tiktok_posts_by_profile_fast_api_collect_by_url",
|
|
94
|
+
"firecrawl_oriane_tiktok_posts_search", "apify_tiktok_scrape"],
|
|
95
|
+
get_tiktok_profile: ["anyapi_tiktok_profile", "tikhub_tiktok_web_fetch_user_profile", "tikhub_tiktok_app_v3_handler_user_profile",
|
|
96
|
+
"searchapi_tiktok_profile", "brightdata_tiktok_profiles_collect_by_url", "firecrawl_oriane_tiktok_profile_lookup"],
|
|
97
|
+
get_tiktok_comments: ["anyapi_tiktok_video_comments", "tiktok_comments", "tikhub_tiktok_web_fetch_post_comment",
|
|
98
|
+
"tikhub_tiktok_app_v3_fetch_video_comments", "searchapi_tiktok_comments", "brightdata_tiktok_comments_collect_by_url"],
|
|
99
|
+
get_tiktok_comment_replies: ["anyapi_tiktok_comment_replies", "tikhub_tiktok_web_fetch_post_comment_reply",
|
|
100
|
+
"tikhub_tiktok_app_v3_fetch_video_comment_replies"],
|
|
101
|
+
get_tiktok_video_metrics: ["tikhub_tiktok_analytics_fetch_video_metrics", "anyapi_tiktok_video", "tikhub_tiktok_app_v3_fetch_one_video",
|
|
102
|
+
"tikhub_tiktok_app_v3_fetch_one_video_v2", "tikhub_tiktok_app_v3_fetch_one_video_v3", "tikhub_tiktok_web_fetch_post_detail",
|
|
103
|
+
"tikhub_tiktok_web_fetch_post_detail_v2", "searchapi_tiktok_video", "brightdata_tiktok_posts_collect_by_url",
|
|
104
|
+
"firecrawl_oriane_tiktok_video_lookup"],
|
|
105
|
+
get_tiktok_video_transcript: ["anyapi_tiktok_video_transcript", "anyapi_tiktok_video_transcript_full", "searchapi_tiktok_transcripts",
|
|
106
|
+
"apify_tiktok_transcript"],
|
|
107
|
+
get_tiktok_sound_posts: ["anyapi_tiktok_song_videos", "tikhub_tiktok_app_v3_fetch_music_video_list"],
|
|
108
|
+
get_tiktok_sounds: ["tikhub_tiktok_app_v3_fetch_music_search_result", "tikhub_tiktok_app_v3_fetch_music_chart_list"],
|
|
109
|
+
get_tiktok_trends: ["apify_tiktok_trends", "anyapi_tiktok_trending_feed"],
|
|
110
|
+
get_tiktok_trending_hashtags: ["anyapi_tiktok_trending_hashtags", "tikhub_tiktok_ads_get_trends_hashtag_list"],
|
|
111
|
+
get_tiktok_hashtag_trend_detail: ["tikhub_tiktok_ads_get_trends_hashtag_detail"],
|
|
112
|
+
get_tiktok_search_insights: ["tikhub_tiktok_app_v3_fetch_creator_search_insights"],
|
|
113
|
+
get_tiktok_search_insight_detail: ["tikhub_tiktok_app_v3_fetch_creator_search_insights_detail"],
|
|
114
|
+
get_tiktok_comment_themes: ["tikhub_tiktok_analytics_fetch_comment_keywords"],
|
|
115
|
+
get_tiktok_video_article: ["tikhub_tiktok_web_fetch_post_ai_article"],
|
|
116
|
+
check_tiktok_video_authenticity: ["tikhub_tiktok_analytics_detect_fake_views"],
|
|
117
|
+
find_similar_tiktok_accounts: ["tikhub_tiktok_app_v3_fetch_similar_user_recommendations"],
|
|
118
|
+
search_tiktok_creators: ["anyapi_tiktok_search_users", "tikhub_tiktok_app_v3_fetch_user_search_result"],
|
|
119
|
+
get_tiktok_account_region: ["anyapi_tiktok_profile_region"],
|
|
120
|
+
get_tiktok_ad_detail: ["tikhub_tiktok_ads_get_ads_detail"],
|
|
121
|
+
search_tiktok_top_ads: ["anyapi_tiktok_top_ads_search", "tikhub_tiktok_ads_search_ads"],
|
|
122
|
+
search_tiktok_shop_products: ["anyapi_tiktok_shop_search", "tikhub_tiktok_shop_web_fetch_search_products_list",
|
|
123
|
+
"tikhub_tiktok_shop_web_fetch_search_products_list_v2", "brightdata_tiktok_shop_discover_by_keyword"],
|
|
124
|
+
get_tiktok_shop_product: ["anyapi_tiktok_shop_product", "tikhub_tiktok_shop_web_fetch_product_detail",
|
|
125
|
+
"tikhub_tiktok_shop_web_fetch_product_detail_v3"],
|
|
126
|
+
get_tiktok_shop_product_reviews: ["anyapi_tiktok_shop_product_reviews", "tikhub_tiktok_shop_web_fetch_product_reviews_v2"],
|
|
127
|
+
search_youtube: ["dataforseo_serp_youtube_organic_advanced", "anyapi_youtube_search", "tikhub_youtube_web_search_video", "tikhub_youtube_web_v2_get_general_search_v2",
|
|
128
|
+
"brightdata_youtube_videos_discover_by_keyword", "searchapi_youtube", "serpapi_youtube"],
|
|
129
|
+
search_youtube_channels: ["tikhub_youtube_web_search_channel", "tikhub_youtube_web_v2_search_channels",
|
|
130
|
+
"brightdata_youtube_channels_discover_by_keyword"],
|
|
131
|
+
search_youtube_shorts: ["anyapi_youtube_search_shorts", "tikhub_youtube_web_v2_get_shorts_search", "tikhub_youtube_web_v2_get_shorts_search_v2"],
|
|
132
|
+
get_youtube_video_info: ["dataforseo_serp_youtube_video_info_advanced", "anyapi_youtube_video", "tikhub_youtube_web_v2_get_video_info", "tikhub_youtube_web_v2_get_video_info_v2",
|
|
133
|
+
"brightdata_youtube_videos_collect_by_url", "searchapi_youtube_video", "serpapi_youtube_video"],
|
|
134
|
+
get_youtube_comments: ["dataforseo_serp_youtube_video_comments_advanced", "anyapi_youtube_video_comments", "tikhub_youtube_web_v2_get_video_comments", "searchapi_youtube_comments",
|
|
135
|
+
"brightdata_youtube_comments_collect_by_url"],
|
|
136
|
+
get_youtube_comment_replies: ["anyapi_youtube_comment_replies", "tikhub_youtube_web_v2_get_video_comment_replies",
|
|
137
|
+
"tikhub_youtube_web_v2_get_post_comment_replies"],
|
|
138
|
+
get_youtube_channel_about: ["tikhub_youtube_web_v2_get_channel_description", "tikhub_youtube_web_get_channel_info", "anyapi_youtube_channel",
|
|
139
|
+
"searchapi_youtube_channel", "serpapi_youtube_channel"],
|
|
140
|
+
get_youtube_channel_shorts: ["anyapi_youtube_channel_shorts", "tikhub_youtube_web_v2_get_channel_shorts",
|
|
141
|
+
"tikhub_youtube_web_get_channel_short_videos", "searchapi_youtube_channel_shorts"],
|
|
142
|
+
get_youtube_community_posts: ["anyapi_youtube_channel_community_posts", "tikhub_youtube_web_v2_get_channel_community_posts",
|
|
143
|
+
"searchapi_youtube_channel_posts"],
|
|
144
|
+
get_youtube_related_videos: ["tikhub_youtube_web_get_relate_video", "tikhub_youtube_web_v2_get_related_videos"],
|
|
145
|
+
get_youtube_transcript: ["dataforseo_serp_youtube_video_subtitles_advanced", "anyapi_youtube_video_transcript", "anyapi_youtube_video_transcript_full", "searchapi_youtube_transcripts",
|
|
146
|
+
"serpapi_youtube_video_transcript"],
|
|
147
|
+
get_youtube_trends: ["searchapi_youtube_trends"],
|
|
148
|
+
search_reddit: ["anyapi_reddit_search", "tikhub_reddit_app_fetch_dynamic_search", "brightdata_reddit_posts_discover_by_keyword",
|
|
149
|
+
"apify_reddit_scrape"],
|
|
150
|
+
fetch_reddit_post: ["anyapi_reddit_post", "tikhub_reddit_app_fetch_post_details", "brightdata_reddit_posts_collect_by_url"],
|
|
151
|
+
get_reddit_post_comments: ["anyapi_reddit_post_comments", "tikhub_reddit_app_fetch_post_comments", "brightdata_reddit_comments_collect_by_url"],
|
|
152
|
+
get_subreddit_posts: ["anyapi_reddit_subreddit_posts", "tikhub_reddit_app_fetch_subreddit_feed",
|
|
153
|
+
"brightdata_reddit_posts_discover_by_subreddit_url"],
|
|
154
|
+
get_subreddit_info: ["anyapi_reddit_subreddit_details", "tikhub_reddit_app_fetch_subreddit_info"],
|
|
155
|
+
get_reddit_popular_posts: ["tikhub_reddit_app_fetch_popular_feed", "anyapi_reddit_trending_posts"],
|
|
156
|
+
get_reddit_trending_searches: ["tikhub_reddit_app_fetch_trending_searches"],
|
|
157
|
+
get_reddit_user_profile: ["anyapi_reddit_profile", "tikhub_reddit_app_fetch_user_profile", "brightdata_reddit_profiles_1c7f260527ac"],
|
|
158
|
+
get_reddit_user_posts: ["anyapi_reddit_user_posts", "tikhub_reddit_app_fetch_user_posts"],
|
|
159
|
+
get_reddit_user_comments: ["anyapi_reddit_user_comments", "tikhub_reddit_app_fetch_user_comments"],
|
|
160
|
+
fetch_linkedin_post: ["anyapi_linkedin_post", "tikhub_linkedin_web_v2_get_post_detail", "brightdata_linkedin_posts_collect_by_url"],
|
|
161
|
+
get_linkedin_post_comments: ["anyapi_linkedin_post_comments", "tikhub_linkedin_web_v2_get_post_comments"],
|
|
162
|
+
get_linkedin_job_posting: ["anyapi_linkedin_job", "tikhub_linkedin_web_v2_get_job_detail", "searchapi_linkedin_job_details",
|
|
163
|
+
"brightdata_linkedin_jobs_collect_by_url"],
|
|
164
|
+
search_linkedin_job_postings: ["anyapi_linkedin_jobs", "anyapi_linkedin_jobs_thin", "tikhub_linkedin_web_v2_search_jobs",
|
|
165
|
+
"searchapi_linkedin_jobs", "brightdata_linkedin_jobs_discover_by_keyword"],
|
|
166
|
+
get_substack_post: ["firecrawl_substack_com_newsletters_post"],
|
|
167
|
+
list_substack_posts: ["firecrawl_substack_com_newsletters_archive"],
|
|
168
|
+
search_podcasts: ["firecrawl_particle_podcasts_search"],
|
|
169
|
+
search_podcast_episodes: ["firecrawl_particle_podcasts_episodes_search"],
|
|
170
|
+
get_podcast_show: ["firecrawl_particle_podcasts_show"],
|
|
171
|
+
get_podcast_episodes: ["firecrawl_particle_podcasts_show_episodes"],
|
|
172
|
+
web_search: ["search_web", "exa_search", "brave_web", "anyapi_brave_search", "crawl4ai_search", "tinyfish_search"],
|
|
173
|
+
search_news: ["dataforseo_serp_google_news_advanced", "dataforseo_serp_google_news_html", "anyapi_google_news", "searchapi_google_news", "searchapi_google_news_light", "searchapi_bing_news", "brave_news",
|
|
174
|
+
"anyapi_hackernews_search", "serpapi_google_news", "serpapi_google_news_light", "serpapi_bing_news", "serpapi_duckduckgo_news", "serpapi_baidu_news"],
|
|
175
|
+
search_image: ["dataforseo_serp_google_images_advanced", "dataforseo_serp_google_images_html", "brave_images", "anyapi_google_images", "searchapi_google_images", "searchapi_google_images_light", "searchapi_bing_images",
|
|
176
|
+
"searchapi_duckduckgo_images", "serpapi_google_images", "serpapi_google_images_light", "serpapi_bing_images", "serpapi_yahoo_images", "serpapi_yandex_images"],
|
|
177
|
+
search_maps: ["dataforseo_serp_google_maps_advanced", "dataforseo_serp_google_local_finder_advanced", "dataforseo_serp_google_local_finder_html",
|
|
178
|
+
"dataforseo_business_business_listings_search", "anyapi_maps_search", "searchapi_google_maps", "firecrawl_firecrawl_maps_businesses_search", "serpapi_google_maps", "serpapi_google_local",
|
|
179
|
+
"serpapi_bing_maps", "serpapi_apple_maps", "serpapi_duckduckgo_maps", "serpapi_naver_maps"],
|
|
180
|
+
search_github: ["searchapi_github_search"],
|
|
181
|
+
serp_lookup: ["dataforseo_serp_google_organic_advanced", "dataforseo_serp_google_organic_regular", "dataforseo_serp_google_organic_html",
|
|
182
|
+
"dataforseo_serp_bing_organic_advanced", "dataforseo_serp_bing_organic_regular", "dataforseo_serp_bing_organic_html",
|
|
183
|
+
"dataforseo_serp_yahoo_organic_advanced", "dataforseo_serp_yahoo_organic_regular", "dataforseo_serp_yahoo_organic_html",
|
|
184
|
+
"dataforseo_serp_baidu_organic_advanced", "dataforseo_serp_baidu_organic_regular", "dataforseo_serp_baidu_organic_html",
|
|
185
|
+
"dataforseo_serp_naver_organic_advanced", "dataforseo_serp_naver_organic_regular", "dataforseo_serp_naver_organic_html",
|
|
186
|
+
"dataforseo_serp_seznam_organic_advanced", "dataforseo_serp_seznam_organic_regular", "dataforseo_serp_seznam_organic_html", "anyapi_google_search", "anyapi_google_search_100", "anyapi_bing_search", "searchapi_google", "searchapi_google_light",
|
|
187
|
+
"searchapi_google_rank_tracking", "searchapi_bing", "searchapi_naver", "serpapi_google", "serpapi_google_light", "serpapi_bing", "serpapi_naver", "crawl4ai_serp"],
|
|
188
|
+
google_ai_mode: ["dataforseo_serp_google_ai_mode_advanced", "dataforseo_serp_google_ai_mode_html", "anyapi_google_ai_mode", "searchapi_google_ai_mode", "serpapi_google_ai_mode"],
|
|
189
|
+
ask_chatgpt: ["dataforseo_ai_chat_gpt_llm_scraper_advanced", "dataforseo_ai_chat_gpt_llm_scraper_html"],
|
|
190
|
+
ask_gemini: ["dataforseo_ai_gemini_llm_scraper_advanced", "dataforseo_ai_gemini_llm_scraper_html"],
|
|
191
|
+
google_ai_overview: ["anyapi_google_ai_overview", "searchapi_google_ai_overview", "serpapi_google_ai_overview"],
|
|
192
|
+
google_trends: ["searchapi_google_trends_trending_now", "firecrawl_firecrawl_trends_trends_trending_now", "serpapi_google_trends_trending_now"],
|
|
193
|
+
google_trends_interest: ["dataforseo_keywords_google_trends_explore", "dataforseo_keywords_dataforseo_trends_explore", "anyapi_google_trends", "searchapi_google_trends", "firecrawl_firecrawl_trends_trends_interest_over_time", "serpapi_google_trends"],
|
|
194
|
+
seo_keyword_metrics: ["dataforseo_labs_google_keyword_overview", "dataforseo_keywords_google_ads_search_volume", "dataforseo_labs_google_bulk_keyword_difficulty"],
|
|
195
|
+
seo_domain_overview: ["dataforseo_labs_google_domain_rank_overview", "dataforseo_labs_google_bulk_traffic_estimation"],
|
|
196
|
+
seo_domain_keywords: ["dataforseo_labs_google_ranked_keywords", "dataforseo_labs_google_keywords_for_site"],
|
|
197
|
+
get_website_traffic: ["anyapi_similarweb_overview", "firecrawl_similarweb_web_traffic"],
|
|
198
|
+
search_meta_ads_library: ["anyapi_facebook_ads_search", "anyapi_facebook_company_ads", "searchapi_meta_ad_library",
|
|
199
|
+
"brightdata_meta_ad_library__fe525218deb2", "apify_facebook_ads"],
|
|
200
|
+
search_meta_ad_library_details: ["anyapi_facebook_ad_details", "anyapi_facebook_ad_details_full", "searchapi_meta_ad_library_ad_details"],
|
|
201
|
+
search_meta_ad_library_pages: ["anyapi_facebook_search_companies", "searchapi_meta_ad_library_page_search"],
|
|
202
|
+
search_google_ads_transparency: ["anyapi_google_ads_company_ads", "anyapi_google_ads_search", "searchapi_google_ads_transparency_center",
|
|
203
|
+
"serpapi_google_ads_transparency_center"],
|
|
204
|
+
search_google_ads_transparency_details: ["anyapi_google_ads_ad_details", "searchapi_google_ads_transparency_center_ad_details",
|
|
205
|
+
"serpapi_google_ads_transparency_center_ad_details"],
|
|
206
|
+
search_linkedin_ads_library: ["anyapi_linkedin_ads_search", "searchapi_linkedin_ad_library"],
|
|
207
|
+
get_linkedin_ad_details: ["anyapi_linkedin_ad", "searchapi_linkedin_ad_library_ad_details"],
|
|
208
|
+
search_tiktok_ads_library: ["anyapi_tiktok_ad_library_search", "searchapi_tiktok_ads_library"],
|
|
209
|
+
search_tiktok_ads_library_details: ["searchapi_tiktok_ads_library_ad_details"],
|
|
210
|
+
search_mobile_apps: ["dataforseo_app_data_apple_app_searches_advanced", "dataforseo_app_data_google_app_searches_advanced", "dataforseo_app_data_google_app_searches_html",
|
|
211
|
+
"dataforseo_app_data_apple_app_listings_search", "dataforseo_app_data_google_app_listings_search", "anyapi_appstore_search", "anyapi_playstore_search", "searchapi_apple_app_store", "searchapi_google_play_store",
|
|
212
|
+
"firecrawl_apps_apple_com_apps_search", "firecrawl_play_google_com_media_app_search", "serpapi_apple_app_store", "serpapi_google_play"],
|
|
213
|
+
get_mobile_app: ["dataforseo_app_data_apple_app_info_advanced", "dataforseo_app_data_google_app_info_advanced", "dataforseo_app_data_google_app_info_html", "anyapi_appstore_app", "anyapi_playstore_app", "searchapi_google_play_product", "firecrawl_apps_apple_com_apps_app",
|
|
214
|
+
"firecrawl_play_google_com_media_app", "serpapi_google_play_product", "serpapi_apple_product"],
|
|
215
|
+
get_public_reviews: ["dataforseo_business_google_reviews", "dataforseo_business_google_extended_reviews", "dataforseo_business_trustpilot_reviews",
|
|
216
|
+
"dataforseo_business_tripadvisor_reviews", "anyapi_trustpilot_reviews", "anyapi_g2_reviews", "anyapi_maps_reviews", "brightdata_trustpilot_reviews_collect_by_url",
|
|
217
|
+
"brightdata_g2_reviews_collect_by_url", "brightdata_google_maps_reviews_collect_by_url", "searchapi_google_maps_reviews", "serpapi_google_maps_reviews",
|
|
218
|
+
"firecrawl_firecrawl_maps_businesses_reviews"],
|
|
219
|
+
};
|
|
220
|
+
const additions = {
|
|
221
|
+
extract_structured_data: ["firecrawl_extract", "crawl4ai_extract"],
|
|
222
|
+
scrape_page: ["read_jina_page", "crawl4ai_scrape", "anyapi_web_scrape", "tinyfish_fetch"],
|
|
223
|
+
get_x_profile: ["scrapecreators_v1_twitter_profile"],
|
|
224
|
+
get_x_community_posts: ["scrapecreators_v1_twitter_community_tweets"],
|
|
225
|
+
search_threads: ["scrapecreators_v1_threads_search"],
|
|
226
|
+
search_threads_profiles: ["scrapecreators_v1_threads_search_users"],
|
|
227
|
+
fetch_threads_post: ["scrapecreators_v1_threads_post"],
|
|
228
|
+
fetch_reddit_post: ["scrapecreators_v1_reddit_post"],
|
|
229
|
+
fetch_facebook_post: ["scrapecreators_v1_facebook_post"],
|
|
230
|
+
fetch_instagram_post: ["scrapecreators_v1_instagram_post"],
|
|
231
|
+
get_instagram_profile: ["scrapecreators_v1_instagram_profile", "scrapecreators_v1_instagram_basic_profile"],
|
|
232
|
+
search_instagram_posts: ["scrapecreators_v2_instagram_user_posts"],
|
|
233
|
+
search_instagram_keyword: ["scrapecreators_v1_instagram_search_profiles"],
|
|
234
|
+
get_instagram_post_comments: ["scrapecreators_v2_instagram_post_comments"],
|
|
235
|
+
get_instagram_highlights: ["scrapecreators_v1_instagram_user_highlights", "scrapecreators_v1_instagram_user_highlight_detail"],
|
|
236
|
+
get_instagram_comment_replies: ["scrapecreators_v1_instagram_post_comment_replies"],
|
|
237
|
+
get_instagram_tagged_posts: ["scrapecreators_v1_instagram_user_tagged_posts"],
|
|
238
|
+
scrape_facebook: ["scrapecreators_v1_facebook_profile"],
|
|
239
|
+
scrape_facebook_posts: ["scrapecreators_v1_facebook_profile_posts"],
|
|
240
|
+
search_tiktok_posts: ["scrapecreators_v1_tiktok_search_keyword", "scrapecreators_v1_tiktok_search_hashtag", "scrapecreators_v3_tiktok_profile_videos"],
|
|
241
|
+
get_tiktok_profile: ["scrapecreators_v1_tiktok_profile"],
|
|
242
|
+
get_tiktok_comments: ["scrapecreators_v1_tiktok_video_comments"],
|
|
243
|
+
get_tiktok_comment_replies: ["scrapecreators_v1_tiktok_video_comment_replies"],
|
|
244
|
+
get_tiktok_sound_posts: ["scrapecreators_v1_tiktok_song_videos"],
|
|
245
|
+
get_tiktok_video_metrics: ["scrapecreators_v2_tiktok_video"],
|
|
246
|
+
get_tiktok_video_transcript: ["scrapecreators_v1_tiktok_video_transcript"],
|
|
247
|
+
search_tiktok_shop_products: ["scrapecreators_v1_tiktok_shop_search"],
|
|
248
|
+
get_tiktok_shop_product_reviews: ["scrapecreators_v1_tiktok_shop_product_reviews"],
|
|
249
|
+
search_tiktok_creators: ["scrapecreators_v1_tiktok_search_users"],
|
|
250
|
+
get_tiktok_account_region: ["scrapecreators_v1_tiktok_profile_region"],
|
|
251
|
+
search_youtube: ["scrapecreators_v1_youtube_search"],
|
|
252
|
+
get_youtube_comments: ["scrapecreators_v1_youtube_video_comments"],
|
|
253
|
+
get_youtube_video_info: ["scrapecreators_v1_youtube_video"],
|
|
254
|
+
get_youtube_community_posts: ["scrapecreators_v1_youtube_channel_community_posts"],
|
|
255
|
+
get_youtube_channel_shorts: ["scrapecreators_v1_youtube_channel_shorts"],
|
|
256
|
+
get_youtube_channel_about: ["scrapecreators_v1_youtube_channel"],
|
|
257
|
+
get_youtube_transcript: ["scrapecreators_v1_youtube_video_transcript"],
|
|
258
|
+
get_youtube_community_post: ["scrapecreators_v1_youtube_community_post"],
|
|
259
|
+
search_reddit: ["scrapecreators_v1_reddit_search"],
|
|
260
|
+
get_subreddit_posts: ["scrapecreators_v1_reddit_subreddit"],
|
|
261
|
+
get_reddit_post_comments: ["scrapecreators_v1_reddit_post_comments", "scrapecreators_v1_reddit_post_comments_post"],
|
|
262
|
+
get_subreddit_info: ["scrapecreators_v1_reddit_subreddit_details"],
|
|
263
|
+
fetch_linkedin_post: ["scrapecreators_v1_linkedin_post"],
|
|
264
|
+
search_meta_ads_library: ["scrapecreators_v1_facebook_ad_library_search_ads", "scrapecreators_v1_facebook_ad_library_search_ads_post",
|
|
265
|
+
"scrapecreators_v1_facebook_ad_library_company_ads", "scrapecreators_v1_facebook_ad_library_company_ads_post"],
|
|
266
|
+
search_google_ads_transparency: ["scrapecreators_v1_google_company_ads"],
|
|
267
|
+
search_google_ads_transparency_details: ["scrapecreators_v1_google_ad"],
|
|
268
|
+
search_linkedin_ads_library: ["scrapecreators_v1_linkedin_ads_search"],
|
|
269
|
+
get_linkedin_ad_details: ["scrapecreators_v1_linkedin_ad"],
|
|
270
|
+
search_meta_ad_library_details: ["scrapecreators_v1_facebook_ad_library_ad"],
|
|
271
|
+
search_meta_ad_library_pages: ["scrapecreators_v1_facebook_ad_library_search_companies"],
|
|
272
|
+
search_tiktok_ads_library: ["scrapecreators_v1_tiktok_ad_library_search"],
|
|
273
|
+
get_tiktok_audience: ["anyapi_tiktok_audience_demographics", "scrapecreators_v1_tiktok_user_audience"],
|
|
274
|
+
get_tiktok_account_network: ["anyapi_tiktok_followers", "anyapi_tiktok_following", "tikhub_tiktok_app_v3_fetch_user_follower_list", "tikhub_tiktok_app_v3_fetch_user_following_list",
|
|
275
|
+
"tikhub_tiktok_web_fetch_user_fans", "tikhub_tiktok_web_fetch_user_follow", "scrapecreators_v1_tiktok_user_followers", "scrapecreators_v1_tiktok_user_following"],
|
|
276
|
+
get_youtube_video_sponsors: ["anyapi_youtube_video_sponsors", "scrapecreators_v1_youtube_video_sponsors"],
|
|
277
|
+
get_youtube_playlist: ["anyapi_youtube_playlist", "scrapecreators_v1_youtube_playlist", "searchapi_youtube_playlist"],
|
|
278
|
+
get_youtube_channel_playlists: ["anyapi_youtube_channel_playlists", "scrapecreators_v1_youtube_channel_playlists"],
|
|
279
|
+
get_instagram_trending_reels: ["anyapi_instagram_trending_reels", "scrapecreators_v1_instagram_reels_trending"],
|
|
280
|
+
get_youtube_trending_shorts: ["anyapi_youtube_trending_shorts", "scrapecreators_v1_youtube_shorts_trending"],
|
|
281
|
+
get_social_post_transcript: ["anyapi_facebook_post_transcript", "anyapi_linkedin_post_transcript", "anyapi_twitter_tweet_transcript", "anyapi_reddit_post_transcript",
|
|
282
|
+
"anyapi_instagram_media_transcript", "scrapecreators_v1_facebook_post_transcript", "scrapecreators_v1_linkedin_post_transcript", "scrapecreators_v1_twitter_tweet_transcript",
|
|
283
|
+
"scrapecreators_v1_reddit_post_transcript", "scrapecreators_v2_instagram_media_transcript"],
|
|
284
|
+
get_linkedin_company: ["anyapi_linkedin_company", "tikhub_linkedin_web_v2_get_company_profile", "scrapecreators_v1_linkedin_company", "brightdata_linkedin_companies_collect_by_url"],
|
|
285
|
+
get_linkedin_company_posts: ["anyapi_linkedin_company_posts", "anyapi_linkedin_company_posts_thin", "tikhub_linkedin_web_v2_get_company_posts", "scrapecreators_v1_linkedin_company_posts",
|
|
286
|
+
"brightdata_linkedin_posts_discover_by_company_url"],
|
|
287
|
+
read_link_in_bio: ["anyapi_linktree_profile", "scrapecreators_v1_linktree", "scrapecreators_v1_linkme", "scrapecreators_v1_komi", "scrapecreators_v1_pillar", "scrapecreators_v1_linkbio"],
|
|
288
|
+
get_facebook_post_comments: ["anyapi_facebook_post_comments", "scrapecreators_v1_facebook_post_comments", "brightdata_facebook_comments_collect_by_url"],
|
|
289
|
+
get_facebook_group_posts: ["anyapi_facebook_group_posts", "scrapecreators_v1_facebook_group_posts", "brightdata_facebook_posts_by_group_collect_by_url"],
|
|
290
|
+
find_creator_emails: ["scrapecreators_v1_find_creator_emails"],
|
|
291
|
+
find_creator_social_profiles: ["scrapecreators_v1_find_social_profiles"],
|
|
292
|
+
};
|
|
293
|
+
export const AUTO_CAPABILITY_VARIANTS = Object.fromEntries(Object.keys({ ...variants, ...additions }).map(name => [name, [...(variants[name] ?? []), ...(additions[name] ?? [])]]));
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { TOOL_RESULT_CONTEXT_MAX_BYTES } from "./toolResultContext.js";
|
|
3
|
+
import { platformConnectionPolicySchema } from "./platformConnectionPolicy.js";
|
|
4
|
+
import { platformAppApiPathSchema } from "./platformHttpConstraints.js";
|
|
5
|
+
export { platformOAuthScopeAlternativesSchema, platformOAuthPermissionSchema } from "./platformOAuth.js";
|
|
6
|
+
export const PLATFORM_APP_ID_PATTERN = /^[a-z0-9][a-z0-9_]{0,63}$/;
|
|
7
|
+
export const platformAppIdSchema = z.string().regex(PLATFORM_APP_ID_PATTERN);
|
|
8
|
+
export const platformAppConnectionProviderSchema = z.templateLiteral(["app:", platformAppIdSchema]);
|
|
9
|
+
export const PLATFORM_APP_CONNECT_METHODS = ["sign_in", "credentials"];
|
|
10
|
+
export const platformConnectionProviderSchema = z.enum(["x", "gsc", "ga", "google", "github", "notion", "slack", "linear", "linkedin", "pinterest", "tiktok", "microsoftAds", "amazonAds"]);
|
|
11
|
+
export const platformAnyConnectionProviderSchema = z.union([platformConnectionProviderSchema, platformAppConnectionProviderSchema]);
|
|
12
|
+
export function platformConnectionOAuthProvider(provider) {
|
|
13
|
+
return provider === "gsc" || provider === "ga" ? "google" : provider === "microsoftAds" ? "microsoft" : provider === "amazonAds" ? "amazon" : provider;
|
|
14
|
+
}
|
|
15
|
+
export const PLATFORM_CONNECTION_CATALOG_LIMITS = { maxRows: 20, responseBytes: 65_536, metadataBytes: 60_000, policyBytes: 8192, contextBytes: TOOL_RESULT_CONTEXT_MAX_BYTES };
|
|
16
|
+
export const PLATFORM_CONNECTION_PAGE_MAX = PLATFORM_CONNECTION_CATALOG_LIMITS.maxRows;
|
|
17
|
+
export const platformConnectionCatalogQuerySchema = z.object({
|
|
18
|
+
provider: platformAnyConnectionProviderSchema.optional(),
|
|
19
|
+
offset: z.number().int().min(0).max(Number.MAX_SAFE_INTEGER).default(0),
|
|
20
|
+
limit: z.number().int().min(1).max(PLATFORM_CONNECTION_PAGE_MAX).default(10),
|
|
21
|
+
}).strict();
|
|
22
|
+
export const platformConnectionAppSchema = z.object({ id: platformAppIdSchema, name: z.string(), docs: z.string(), baseUrl: z.string(),
|
|
23
|
+
baseUrls: z.array(z.string()).optional(),
|
|
24
|
+
apiPaths: z.array(platformAppApiPathSchema).optional(),
|
|
25
|
+
uploadUrls: z.array(z.object({ prefix: z.string(), credentials: z.boolean() })).optional(),
|
|
26
|
+
transport: z.literal("mcp").optional() });
|
|
27
|
+
export const platformConnectionCatalogSchema = z.object({
|
|
28
|
+
connections: z.array(z.object({
|
|
29
|
+
id: z.string(), provider: platformAnyConnectionProviderSchema, label: z.string(),
|
|
30
|
+
status: z.enum(["connected", "reauth_required"]), scopes: z.array(z.string()),
|
|
31
|
+
scopeSyncedAt: z.iso.datetime().nullable().default(null),
|
|
32
|
+
personal: z.boolean().optional(),
|
|
33
|
+
policy: platformConnectionPolicySchema.nullable().optional(),
|
|
34
|
+
policyRestricted: z.boolean().optional(),
|
|
35
|
+
app: platformConnectionAppSchema.optional(),
|
|
36
|
+
reconnectUrl: z.url().optional(),
|
|
37
|
+
})).max(PLATFORM_CONNECTION_PAGE_MAX),
|
|
38
|
+
total: z.number().int().nonnegative(), nextOffset: z.number().int().nonnegative().nullable(),
|
|
39
|
+
});
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { ACCOUNT_REQUEST_HTTP_METHODS } from "./accountRequestMethods.js";
|
|
3
|
+
export const PLATFORM_CONNECTION_POLICY_LIMITS = { rules: 64, subjects: 100, conditions: 16, pathChars: 2048, pointerChars: 256, valueChars: 2048, jsonChars: 12_000,
|
|
4
|
+
operations: 2_000, operationChars: 128, signInOperationsChars: 32_000, accounts: 2_000, accountChars: 256 };
|
|
5
|
+
const limits = PLATFORM_CONNECTION_POLICY_LIMITS;
|
|
6
|
+
const ids = z.array(z.string().min(1).max(128)).min(1).max(limits.subjects);
|
|
7
|
+
const condition = z.object({ pointer: z.string().startsWith("/").max(limits.pointerChars),
|
|
8
|
+
operator: z.enum(["equals", "prefix"]).default("equals"), value: z.union([z.string().max(limits.valueChars), z.number().finite(), z.boolean()]) }).strict()
|
|
9
|
+
.refine(value => value.operator !== "prefix" || typeof value.value === "string", "A prefix is a string");
|
|
10
|
+
const common = { effect: z.enum(["allow", "deny"]).default("allow"), memberIds: ids.optional(), apiKeyIds: ids.optional(),
|
|
11
|
+
directoryGroupIds: ids.optional(),
|
|
12
|
+
conditions: z.array(condition).max(limits.conditions).default([]), approvalRequired: z.boolean().default(false) };
|
|
13
|
+
const path = z.string().startsWith("/").max(limits.pathChars).refine(value => !/[?#\\\u0000-\u001f\u007f]/.test(value) && !value.includes("//") && !value.split("/").some(part => part === "." || part === ".."));
|
|
14
|
+
export const platformConnectionPolicyRuleSchema = z.discriminatedUnion("kind", [
|
|
15
|
+
z.object({ ...common, kind: z.literal("http"), methods: z.array(z.enum(ACCOUNT_REQUEST_HTTP_METHODS)).min(1).max(ACCOUNT_REQUEST_HTTP_METHODS.length),
|
|
16
|
+
path, prefix: z.boolean().default(false), baseUrl: z.string().max(limits.pathChars).optional() }).strict(),
|
|
17
|
+
z.object({ ...common, kind: z.literal("mcp"), tool: z.string().min(1).max(256) }).strict(),
|
|
18
|
+
z.object({ ...common, kind: z.literal("database"), operations: z.array(z.enum(["schema", "query", "execute"])).min(1).max(3) }).strict(),
|
|
19
|
+
z.object({ ...common, kind: z.literal("operation"), action: z.string().min(1).max(128) }).strict(),
|
|
20
|
+
]).refine(rule => rule.effect !== "deny" || !rule.approvalRequired, "A refusal cannot be approved");
|
|
21
|
+
export const PLATFORM_CONNECTION_READ_OPERATIONS = "reads";
|
|
22
|
+
const operationNames = z.array(z.string().min(1).max(limits.operationChars)).max(limits.operations);
|
|
23
|
+
export const platformConnectionOperationsSchema = z.object({ allow: operationNames.optional(), deny: operationNames.default([]) }).strict();
|
|
24
|
+
export const platformConnectionAccountsSchema = z.object({ kind: z.enum(["facebook_page", "meta_ad_account", "ga_property", "gsc_site", "tiktok_advertiser"]),
|
|
25
|
+
allow: z.array(z.string().min(1).max(limits.accountChars)).max(limits.accounts), autoLabel: z.string().max(limits.accountChars).optional() }).strict();
|
|
26
|
+
const APP_ACCOUNTS = new Map([["facebook", "facebook_page"], ["instagram_facebook_login", "facebook_page"],
|
|
27
|
+
["metaads", "meta_ad_account"], ["google_analytics", "ga_property"], ["google_search_console", "gsc_site"], ["tiktok_ads", "tiktok_advertiser"]]);
|
|
28
|
+
export const platformAppAccountsKind = (appId) => APP_ACCOUNTS.get(appId);
|
|
29
|
+
export const platformConnectionPolicySchema = z.object({ version: z.literal(1), defaultEffect: z.enum(["allow", "deny"]).default("deny"),
|
|
30
|
+
rules: z.array(platformConnectionPolicyRuleSchema).max(limits.rules), operations: platformConnectionOperationsSchema.optional(),
|
|
31
|
+
accounts: platformConnectionAccountsSchema.optional() }).strict()
|
|
32
|
+
.refine(value => JSON.stringify({ ...value, operations: undefined, accounts: undefined }).length <= limits.jsonChars, "Policy is too large");
|
|
33
|
+
export const relvoProjectConnectionPolicySchema = platformConnectionPolicySchema.refine(policy => policy.rules.every(rule => rule.memberIds === undefined && rule.directoryGroupIds === undefined), "Connection rules apply to every project member");
|