@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.
Files changed (93) hide show
  1. package/README.md +12 -56
  2. package/bin/noimos-platform.mjs +3 -4
  3. package/dist/cli/cli.js +477 -87
  4. package/dist/cli/command-help.js +349 -23
  5. package/dist/cli/download.js +25 -25
  6. package/dist/cli/input-error.js +48 -0
  7. package/dist/cli/local-agents.js +199 -0
  8. package/dist/cli/mcp-supervisor.js +136 -0
  9. package/dist/cli/noimos-cli.js +72 -0
  10. package/dist/cli/project-archive.js +27 -0
  11. package/dist/cli/project-files.js +25 -0
  12. package/dist/cli/project-sync.js +259 -0
  13. package/dist/cli/setup-lock.js +1 -0
  14. package/dist/cli/setup.js +347 -0
  15. package/dist/cli/skills.js +142 -0
  16. package/dist/cli/team-harness-targets.js +337 -0
  17. package/dist/cli/team-harness.js +1562 -0
  18. package/dist/cli/team-resources.js +222 -0
  19. package/dist/cli/team-skills.js +457 -0
  20. package/dist/cli/update-bootstrap.js +437 -0
  21. package/dist/cli/update-release.js +212 -0
  22. package/dist/cli/version.js +1 -0
  23. package/dist/cli/wallet.js +85 -0
  24. package/dist/client/agent-run.js +1425 -0
  25. package/dist/client/browser.js +905 -0
  26. package/dist/client/distribution.js +2 -0
  27. package/dist/client/evm-wallet.js +214 -0
  28. package/dist/client/execution-context.js +14 -0
  29. package/dist/client/failure-recovery.js +128 -0
  30. package/dist/client/index.js +4 -225
  31. package/dist/client/local-input.js +33 -12
  32. package/dist/client/local-profile-lock.js +52 -0
  33. package/dist/client/local-profile.js +181 -0
  34. package/dist/client/local-projects.js +131 -0
  35. package/dist/client/local-setup.js +93 -0
  36. package/dist/client/realtime-voice.js +184 -0
  37. package/dist/client/tool-name-hints.js +48 -0
  38. package/dist/client/wallet-access.js +214 -0
  39. package/dist/mcp/agent-server.js +345 -0
  40. package/dist/mcp/context.js +86 -0
  41. package/dist/mcp/host-schema.js +76 -0
  42. package/dist/mcp/icon.js +1 -0
  43. package/dist/mcp/index.js +3 -0
  44. package/dist/mcp/instructions.js +26 -0
  45. package/dist/mcp/local-projects.js +42 -0
  46. package/dist/mcp/local-upload.js +39 -0
  47. package/dist/mcp/noimos-runtime.js +18 -0
  48. package/dist/mcp/noimos-server.js +38 -0
  49. package/dist/mcp/operations.js +40 -0
  50. package/dist/mcp/parallel-result.js +17 -0
  51. package/dist/mcp/project-sync.js +105 -0
  52. package/dist/mcp/results-reply.js +15 -0
  53. package/dist/mcp/runtime.js +81 -0
  54. package/dist/mcp/server.js +410 -0
  55. package/dist/mcp/team-skill.js +63 -0
  56. package/dist/mcp/update-notice.js +75 -0
  57. package/dist/mcp/version.js +1 -0
  58. package/dist/schema/accountRequestMethods.js +1 -0
  59. package/dist/schema/boundedBody.js +30 -0
  60. package/dist/schema/cronValidator.js +150 -0
  61. package/dist/schema/platformApiKey.js +14 -0
  62. package/dist/schema/platformAppAuth.js +11 -0
  63. package/dist/schema/platformBillingConstants.js +4 -0
  64. package/dist/schema/platformCapabilityFamilies.js +293 -0
  65. package/dist/schema/platformConnectionCatalog.js +39 -0
  66. package/dist/schema/platformConnectionPolicy.js +33 -0
  67. package/dist/schema/platformCustomTools.js +148 -0
  68. package/dist/schema/platformEndUserApi.js +62 -0
  69. package/dist/schema/platformFunding.js +10 -0
  70. package/dist/schema/platformHttpConstraints.js +12 -0
  71. package/dist/schema/platformLocalSetup.js +25 -0
  72. package/dist/schema/platformMcpTools.js +7 -0
  73. package/dist/schema/platformMetaTools.js +63 -0
  74. package/dist/schema/platformMonitorSchedule.js +123 -0
  75. package/dist/schema/platformMonitors.js +159 -0
  76. package/dist/schema/platformOAuth.js +13 -0
  77. package/dist/schema/platformProjectPermissions.js +33 -0
  78. package/dist/schema/platformPublicExecution.js +202 -21
  79. package/dist/schema/platformRoutes.js +122 -0
  80. package/dist/schema/platformSkills.js +11 -0
  81. package/dist/schema/platformTeamSecretName.js +3 -0
  82. package/dist/schema/platformTeamSkillSlug.js +1 -0
  83. package/dist/schema/platformTeamSkills.js +302 -0
  84. package/dist/schema/platformToolAccess.js +62 -0
  85. package/dist/schema/platformTriggers.js +153 -0
  86. package/dist/schema/platformWorkflows.js +100 -0
  87. package/dist/schema/scheduleTimeZone.js +15 -0
  88. package/dist/schema/toolDiscovery.js +71 -0
  89. package/dist/schema/toolInputRepair.js +122 -0
  90. package/dist/schema/toolResultContext.js +51 -0
  91. package/dist/schema/untrustedContent.js +35 -0
  92. package/npm-shrinkwrap.json +73 -0
  93. 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,4 @@
1
+ export const PLATFORM_CHECKOUT_MIN_CENTS = 500;
2
+ export const PLATFORM_SETTLEMENT_MIN_CENTS = 100;
3
+ export const PLATFORM_FREE_TOOL_OVERAGE_MICROS = 300;
4
+ export const USAGE_BREAKDOWN_MAX_DAYS = 366;
@@ -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");