terse-types 0.1.4 → 0.1.6

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/dist/Tools.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { z } from "zod";
2
+ import { googleSearchConsoleSiteSchema } from "./Integrations.js";
2
3
  import { runHistoryActionBaseSchema } from "./RunHistoryTypes.js";
3
4
  import { LinearStateName } from "./TicketSystem.js";
4
5
  export const toolOutputBaseSchema = z.object({
@@ -2995,6 +2996,800 @@ export const apolloListJobPostingsTool = defineTool({
2995
2996
  perPage: z.number().int()
2996
2997
  })
2997
2998
  });
2999
+ const SITE_URL_DESCRIPTION = 'The Search Console property to operate on. Either a URL-prefix property including the trailing slash ("https://example.com/") or a Domain property ("sc-domain:example.com"). Must be within the properties this agent is allowed to use.';
3000
+ export const googleSearchConsoleIntegrationIdSchema = z.string().describe("The integration ID of the Google Search Console connection to use.");
3001
+ export const googleSearchConsoleListSitesTool = defineTool({
3002
+ name: "google_search_console_list_sites",
3003
+ description: "List every Search Console property the connected Google account can access, with the account's permission level on each. Use this to discover the exact property identifier (URL-prefix or sc-domain form) to pass to the other Search Console tools. Note that the account may be able to see properties this agent is not allowed to act on.",
3004
+ inputSchema: z.object({
3005
+ integrationId: googleSearchConsoleIntegrationIdSchema
3006
+ }),
3007
+ outputSchema: toolOutputBaseSchema.extend({
3008
+ sites: z.array(googleSearchConsoleSiteSchema)
3009
+ })
3010
+ });
3011
+ export const googleSearchConsoleGetSiteTool = defineTool({
3012
+ name: "google_search_console_get_site",
3013
+ description: "Retrieve one Search Console property and the connected account's permission level on it. Fails if the account has no access to the property.",
3014
+ inputSchema: z.object({
3015
+ integrationId: googleSearchConsoleIntegrationIdSchema,
3016
+ siteUrl: z.string().describe(SITE_URL_DESCRIPTION)
3017
+ }),
3018
+ outputSchema: toolOutputBaseSchema.extend({
3019
+ site: googleSearchConsoleSiteSchema
3020
+ })
3021
+ });
3022
+ export const googleSearchConsoleAddSiteTool = defineTool({
3023
+ name: "google_search_console_add_site",
3024
+ description: "Add a property to the connected Google account's Search Console. The property starts unverified and returns no Search Analytics data until ownership is verified out of band. Adding a property is a real change to the user's Google account, so only do it when explicitly asked.",
3025
+ inputSchema: z.object({
3026
+ integrationId: googleSearchConsoleIntegrationIdSchema,
3027
+ siteUrl: z.string().describe(SITE_URL_DESCRIPTION)
3028
+ }),
3029
+ outputSchema: toolOutputBaseSchema.extend({
3030
+ siteUrl: z.string()
3031
+ })
3032
+ });
3033
+ export const googleSearchConsoleDeleteSiteTool = defineTool({
3034
+ name: "google_search_console_delete_site",
3035
+ description: "Remove a property from the connected Google account's Search Console. This unlinks the account from the property and its historical Search Analytics data becomes inaccessible to this account. Destructive: confirm the exact property before calling.",
3036
+ inputSchema: z.object({
3037
+ integrationId: googleSearchConsoleIntegrationIdSchema,
3038
+ siteUrl: z.string().describe(SITE_URL_DESCRIPTION)
3039
+ }),
3040
+ outputSchema: toolOutputBaseSchema.extend({
3041
+ siteUrl: z.string()
3042
+ })
3043
+ });
3044
+ export const googleSearchConsoleSitemapContentSchema = z.object({
3045
+ type: z.string().nullable().describe('Content type of the URLs counted here: "web", "image", "video", "news", "mobile", "pattern", "androidApp", or "iosApp".'),
3046
+ submitted: z.number().nullable().describe("How many URLs of this content type the sitemap declares.")
3047
+ });
3048
+ export const googleSearchConsoleSitemapSchema = z.object({
3049
+ path: z.string().nullable(),
3050
+ type: z.string().nullable().describe('Sitemap format: "sitemap", "urlList", "rssFeed", "atomFeed", "patternSitemap", or "notSitemap".'),
3051
+ isPending: z.boolean().nullable(),
3052
+ isSitemapsIndex: z.boolean().nullable(),
3053
+ lastSubmitted: z.string().nullable(),
3054
+ lastDownloaded: z.string().nullable(),
3055
+ errors: z.number().nullable(),
3056
+ warnings: z.number().nullable(),
3057
+ contents: z.array(googleSearchConsoleSitemapContentSchema)
3058
+ });
3059
+ export const googleSearchConsoleListSitemapsTool = defineTool({
3060
+ name: "google_search_console_list_sitemaps",
3061
+ description: "List the sitemaps Google knows about for a property, including submission time, last download time, and error and warning counts. Use this to check whether a sitemap was picked up and processed.",
3062
+ inputSchema: z.object({
3063
+ integrationId: googleSearchConsoleIntegrationIdSchema,
3064
+ siteUrl: z.string().describe(SITE_URL_DESCRIPTION),
3065
+ sitemapIndex: z
3066
+ .string()
3067
+ .nullable()
3068
+ .optional()
3069
+ .describe('Full URL of a sitemap index file. When set, only the sitemaps contained in that index are returned, e.g. "https://example.com/sitemap_index.xml".')
3070
+ }),
3071
+ outputSchema: toolOutputBaseSchema.extend({
3072
+ sitemaps: z.array(googleSearchConsoleSitemapSchema)
3073
+ })
3074
+ });
3075
+ export const googleSearchConsoleGetSitemapTool = defineTool({
3076
+ name: "google_search_console_get_sitemap",
3077
+ description: "Retrieve the processing details of a single sitemap: pending state, error and warning counts, and per-content-type URL counts.",
3078
+ inputSchema: z.object({
3079
+ integrationId: googleSearchConsoleIntegrationIdSchema,
3080
+ siteUrl: z.string().describe(SITE_URL_DESCRIPTION),
3081
+ feedpath: z.string().describe('Full URL of the sitemap, e.g. "https://example.com/sitemap.xml".')
3082
+ }),
3083
+ outputSchema: toolOutputBaseSchema.extend({
3084
+ sitemap: googleSearchConsoleSitemapSchema
3085
+ })
3086
+ });
3087
+ export const googleSearchConsoleSubmitSitemapTool = defineTool({
3088
+ name: "google_search_console_submit_sitemap",
3089
+ description: "Submit a sitemap to Google for a property. Submission only queues the sitemap for crawling; processing results appear later via google_search_console_get_sitemap. The property must be verified and the account needs full or owner permission.",
3090
+ inputSchema: z.object({
3091
+ integrationId: googleSearchConsoleIntegrationIdSchema,
3092
+ siteUrl: z.string().describe(SITE_URL_DESCRIPTION),
3093
+ feedpath: z.string().describe('Full URL of the sitemap to submit, e.g. "https://example.com/sitemap.xml". Must be hosted under the property.')
3094
+ }),
3095
+ outputSchema: toolOutputBaseSchema.extend({
3096
+ feedpath: z.string()
3097
+ })
3098
+ });
3099
+ export const googleSearchConsoleDeleteSitemapTool = defineTool({
3100
+ name: "google_search_console_delete_sitemap",
3101
+ description: "Remove a sitemap submission from a property. Google stops tracking the sitemap; already-indexed URLs are not removed from the index. Destructive: confirm the exact sitemap before calling.",
3102
+ inputSchema: z.object({
3103
+ integrationId: googleSearchConsoleIntegrationIdSchema,
3104
+ siteUrl: z.string().describe(SITE_URL_DESCRIPTION),
3105
+ feedpath: z.string().describe('Full URL of the sitemap to remove, e.g. "https://example.com/sitemap.xml".')
3106
+ }),
3107
+ outputSchema: toolOutputBaseSchema.extend({
3108
+ feedpath: z.string()
3109
+ })
3110
+ });
3111
+ export const googleSearchConsoleDimensionSchema = z.enum(["country", "device", "page", "query", "searchAppearance", "date", "hour"]);
3112
+ export const googleSearchConsoleFilterDimensionSchema = z.enum(["country", "device", "page", "query", "searchAppearance"]);
3113
+ export const googleSearchConsoleDimensionFilterSchema = z.object({
3114
+ dimension: googleSearchConsoleFilterDimensionSchema.describe("The dimension to filter on. You do not have to group by a dimension to filter on it. Narrow by date with startDate and endDate instead, which are not filterable dimensions."),
3115
+ operator: z
3116
+ .enum(["contains", "equals", "notContains", "notEquals", "includingRegex", "excludingRegex"])
3117
+ .nullable()
3118
+ .optional()
3119
+ .describe('How to compare. Defaults to "equals". Regex operators use RE2 syntax.'),
3120
+ expression: z.string().describe("The value to compare against. Comparisons are not case sensitive.")
3121
+ });
3122
+ export const googleSearchConsoleDimensionFilterGroupSchema = z.object({
3123
+ groupType: z.enum(["and"]).nullable().optional().describe('How filters inside this group combine. Google currently only supports "and".'),
3124
+ filters: z.array(googleSearchConsoleDimensionFilterSchema)
3125
+ });
3126
+ export const googleSearchConsoleSearchAnalyticsRowSchema = z.object({
3127
+ dimensions: z.partialRecord(googleSearchConsoleDimensionSchema, z.string()).describe("The requested dimensions, keyed by dimension name. Empty when no dimensions were requested."),
3128
+ clicks: z.number(),
3129
+ impressions: z.number(),
3130
+ ctr: z.number(),
3131
+ position: z.number()
3132
+ });
3133
+ export const googleSearchConsoleQuerySearchAnalyticsTool = defineTool({
3134
+ name: "google_search_console_query_search_analytics",
3135
+ description: `Query Search Analytics for a property: clicks, impressions, CTR, and average position, optionally grouped and filtered by dimension.
3136
+
3137
+ WHEN TO USE THIS TOOL:
3138
+ - Top queries or top pages for a date range
3139
+ - Comparing performance between two periods (run one query per period)
3140
+ - Drilling into one page, country, or device using dimensionFilterGroups
3141
+
3142
+ IMPORTANT NOTES:
3143
+ - Dates are inclusive, YYYY-MM-DD, in Pacific Time. Search Console data lags by roughly 2-3 days, so a range ending today usually returns nothing for the most recent days.
3144
+ - Results are grouped in the order the dimensions are supplied, and each row's dimension values come back in the "dimensions" object keyed by dimension name.
3145
+ - Grouping or filtering by page forbids aggregationType "byProperty".
3146
+ - "searchAppearance" must be the only dimension when grouping by it. To combine it with other dimensions, run one query per appearance type using a searchAppearance filter instead.
3147
+ - "hour" is only available with dataState "hourly_all", and only over the last 10 days.
3148
+ - Google caps the result set at 25000 rows per request; page through larger result sets with startRow.
3149
+ - Anonymized queries are omitted from query-grouped results, so summing clicks across query rows will not match the property total.`,
3150
+ inputSchema: z.object({
3151
+ integrationId: googleSearchConsoleIntegrationIdSchema,
3152
+ siteUrl: z.string().describe(SITE_URL_DESCRIPTION),
3153
+ startDate: z.string().describe("First day of the range, inclusive, as YYYY-MM-DD in Pacific Time."),
3154
+ endDate: z.string().describe("Last day of the range, inclusive, as YYYY-MM-DD in Pacific Time. Must be on or after startDate."),
3155
+ dimensions: z
3156
+ .array(googleSearchConsoleDimensionSchema)
3157
+ .nullable()
3158
+ .optional()
3159
+ .describe("Dimensions to group by, applied in the order given. Omit for a single totals row covering the whole range."),
3160
+ dimensionFilterGroups: z.array(googleSearchConsoleDimensionFilterGroupSchema).nullable().optional().describe("Filters to apply. All groups must pass for a row to be returned."),
3161
+ type: z.enum(["web", "image", "video", "news", "discover", "googleNews"]).nullable().optional().describe('Report type to query. Defaults to "web".'),
3162
+ aggregationType: z
3163
+ .enum(["auto", "byPage", "byProperty", "byNewsShowcasePanel"])
3164
+ .nullable()
3165
+ .optional()
3166
+ .describe('How data is aggregated. Defaults to "auto". Use "auto" whenever grouping or filtering by page.'),
3167
+ rowLimit: z.number().int().min(1).max(25000).nullable().optional().describe("Maximum rows to return, 1 to 25000. Defaults to 1000."),
3168
+ startRow: z.number().int().min(0).nullable().optional().describe("Zero-based index of the first row to return. Use with rowLimit to page through large result sets."),
3169
+ dataState: z
3170
+ .enum(["final", "all", "hourly_all"])
3171
+ .nullable()
3172
+ .optional()
3173
+ .describe('Whether to include incomplete recent data. "final" (the default) excludes it; "all" includes partial days; "hourly_all" is required to group by the "hour" dimension.')
3174
+ }),
3175
+ outputSchema: toolOutputBaseSchema.extend({
3176
+ rows: z.array(googleSearchConsoleSearchAnalyticsRowSchema),
3177
+ responseAggregationType: z.string().nullable().describe('How Google actually aggregated the data: "auto", "byPage", "byProperty", or "byNewsShowcasePanel".'),
3178
+ firstIncompleteDate: z
3179
+ .string()
3180
+ .nullable()
3181
+ .describe('First date whose data is still being collected, so values from it onward may change. Only populated when dataState is "all", the results are grouped by date, and the requested range actually contains incomplete data.')
3182
+ })
3183
+ });
3184
+ export const googleSearchConsoleIndexStatusSchema = z.object({
3185
+ verdict: z.string().nullable().describe('Overall index status: "PASS", "PARTIAL", "FAIL", "NEUTRAL", or "VERDICT_UNSPECIFIED".'),
3186
+ coverageState: z.string().nullable().describe('Human-readable indexing summary, e.g. "Submitted and indexed" or "Crawled - currently not indexed".'),
3187
+ robotsTxtState: z.string().nullable().describe('Whether robots.txt allows crawling: "ALLOWED", "DISALLOWED", or "ROBOTS_TXT_STATE_UNSPECIFIED".'),
3188
+ indexingState: z
3189
+ .string()
3190
+ .nullable()
3191
+ .describe('Whether indexing is blocked by the page itself: "INDEXING_ALLOWED", "BLOCKED_BY_META_TAG", "BLOCKED_BY_HTTP_HEADER", "BLOCKED_BY_ROBOTS_TXT", or "INDEXING_STATE_UNSPECIFIED".'),
3192
+ pageFetchState: z
3193
+ .string()
3194
+ .nullable()
3195
+ .describe('Result of Google\'s last fetch: "SUCCESSFUL", "SOFT_404", "BLOCKED_ROBOTS_TXT", "NOT_FOUND", "ACCESS_DENIED", "SERVER_ERROR", "REDIRECT_ERROR", "ACCESS_FORBIDDEN", "BLOCKED_4XX", "INTERNAL_CRAWL_ERROR", "INVALID_URL", or "PAGE_FETCH_STATE_UNSPECIFIED".'),
3196
+ lastCrawlTime: z.string().nullable().describe("When Google last crawled the URL, RFC3339. Absent if the URL was never crawled."),
3197
+ crawledAs: z.string().nullable().describe('Which crawler fetched it: "DESKTOP", "MOBILE", or "CRAWLING_USER_AGENT_UNSPECIFIED".'),
3198
+ googleCanonical: z.string().nullable().describe("The canonical URL Google selected. Absent if Google has not indexed the page."),
3199
+ userCanonical: z.string().nullable().describe("The canonical URL the page declares. Absent if the page declares none."),
3200
+ referringUrls: z.array(z.string()),
3201
+ sitemap: z.array(z.string())
3202
+ });
3203
+ export const googleSearchConsoleInspectUrlTool = defineTool({
3204
+ name: "google_search_console_inspect_url",
3205
+ description: "Inspect Google's index status for one URL under a property: whether it is indexed, the canonical Google picked, robots.txt and fetch state, last crawl time, and which sitemaps reference it. Use this to diagnose why a specific page is not appearing in search. The URL must sit under the property being inspected. Google caps this at 2000 calls per day and 600 per minute per property, so inspect specific suspect URLs rather than looping over a whole site.",
3206
+ inputSchema: z.object({
3207
+ integrationId: googleSearchConsoleIntegrationIdSchema,
3208
+ siteUrl: z.string().describe(SITE_URL_DESCRIPTION),
3209
+ inspectionUrl: z.string().describe("The fully-qualified URL to inspect. Must be under the property given in siteUrl."),
3210
+ languageCode: z.string().nullable().optional().describe('BCP-47 language code for issue messages, e.g. "en-US". Defaults to "en-US".')
3211
+ }),
3212
+ outputSchema: toolOutputBaseSchema.extend({
3213
+ inspectionResultLink: z.string().nullable().describe("Link to the same inspection in the Search Console UI."),
3214
+ indexStatus: googleSearchConsoleIndexStatusSchema.nullable(),
3215
+ mobileUsabilityVerdict: z.string().nullable().describe('Deprecated by Google and may stop being returned. "PASS", "PARTIAL", "FAIL", "NEUTRAL", or "VERDICT_UNSPECIFIED".'),
3216
+ richResultsVerdict: z.string().nullable().describe('"PASS", "PARTIAL", "FAIL", "NEUTRAL", or "VERDICT_UNSPECIFIED". Absent when the page has no detected rich results.'),
3217
+ ampVerdict: z.string().nullable().describe('"PASS", "PARTIAL", "FAIL", "NEUTRAL", or "VERDICT_UNSPECIFIED". Absent when the page has no AMP version.')
3218
+ })
3219
+ });
3220
+ const metaAdsIntegrationIdField = z.string().describe("The integration ID of the Meta Ads connection to use.");
3221
+ const metaAdsAdAccountIdField = z.string().describe("The Meta ad account ID, with or without the 'act_' prefix (e.g. 'act_1234567890').");
3222
+ const metaAdsCollectionFields = {
3223
+ count: z.number(),
3224
+ truncated: z.boolean().describe("True when more results exist than were returned. Narrow the filters and fetch again.")
3225
+ };
3226
+ const metaAdsLimitField = (what, max) => z.number().int().min(1).max(max).nullable().optional().describe(`Maximum number of ${what} to return (default 100).`);
3227
+ export const metaAdsAdAccountEntitySchema = z.object({
3228
+ id: z.string(),
3229
+ account_id: z.string(),
3230
+ name: z.string(),
3231
+ currency: z.string().optional(),
3232
+ account_status: z.number().optional()
3233
+ });
3234
+ const BUDGET_MINOR_UNITS_DESCRIPTION = 'Minor units of the ad account currency, as a string. "5000" in USD is $50.00.';
3235
+ export const metaAdsCampaignEffectiveStatusSchema = z.enum(["ACTIVE", "PAUSED", "DELETED", "ARCHIVED", "IN_PROCESS", "WITH_ISSUES"]);
3236
+ export const metaAdsAdSetEffectiveStatusSchema = z.enum(["ACTIVE", "PAUSED", "DELETED", "ARCHIVED", "IN_PROCESS", "WITH_ISSUES", "CAMPAIGN_PAUSED"]);
3237
+ export const metaAdsAdEffectiveStatusSchema = z.enum([
3238
+ "ACTIVE",
3239
+ "PAUSED",
3240
+ "DELETED",
3241
+ "ARCHIVED",
3242
+ "IN_PROCESS",
3243
+ "WITH_ISSUES",
3244
+ "CAMPAIGN_PAUSED",
3245
+ "ADSET_PAUSED",
3246
+ "PENDING_REVIEW",
3247
+ "DISAPPROVED",
3248
+ "PREAPPROVED",
3249
+ "PENDING_BILLING_INFO"
3250
+ ]);
3251
+ export const metaAdsCampaignSchema = z.object({
3252
+ id: z.string(),
3253
+ name: z.string(),
3254
+ status: z.string(),
3255
+ effective_status: z.string().optional(),
3256
+ objective: z.string().optional(),
3257
+ daily_budget: z.string().optional().describe(BUDGET_MINOR_UNITS_DESCRIPTION),
3258
+ lifetime_budget: z.string().optional().describe(BUDGET_MINOR_UNITS_DESCRIPTION),
3259
+ start_time: z.string().optional(),
3260
+ stop_time: z.string().optional()
3261
+ });
3262
+ export const metaAdsAdSetSchema = z.object({
3263
+ id: z.string(),
3264
+ name: z.string(),
3265
+ status: z.string(),
3266
+ effective_status: z.string().optional(),
3267
+ campaign_id: z.string().optional(),
3268
+ daily_budget: z.string().optional().describe(BUDGET_MINOR_UNITS_DESCRIPTION),
3269
+ lifetime_budget: z.string().optional().describe(BUDGET_MINOR_UNITS_DESCRIPTION),
3270
+ optimization_goal: z.string().optional(),
3271
+ start_time: z.string().optional(),
3272
+ end_time: z.string().optional()
3273
+ });
3274
+ export const metaAdsInsightsRowSchema = z.object({
3275
+ date_start: z.string().optional(),
3276
+ date_stop: z.string().optional(),
3277
+ campaign_id: z.string().optional(),
3278
+ campaign_name: z.string().optional(),
3279
+ adset_id: z.string().optional(),
3280
+ adset_name: z.string().optional(),
3281
+ ad_id: z.string().optional(),
3282
+ ad_name: z.string().optional(),
3283
+ age: z.string().optional(),
3284
+ gender: z.string().optional(),
3285
+ country: z.string().optional(),
3286
+ publisher_platform: z.string().optional(),
3287
+ platform_position: z.string().optional(),
3288
+ impression_device: z.string().optional(),
3289
+ spend: z.string().optional(),
3290
+ impressions: z.string().optional(),
3291
+ clicks: z.string().optional(),
3292
+ ctr: z.string().optional(),
3293
+ cpc: z.string().optional(),
3294
+ reach: z.string().optional(),
3295
+ actions: z.array(z.object({ action_type: z.string(), value: z.string() })).optional()
3296
+ });
3297
+ export const metaAdsCustomAudienceSchema = z.object({
3298
+ id: z.string(),
3299
+ name: z.string(),
3300
+ subtype: z.string().optional(),
3301
+ approximate_count_lower_bound: z.number().optional(),
3302
+ approximate_count_upper_bound: z.number().optional(),
3303
+ delivery_status: z
3304
+ .object({
3305
+ code: z.number().optional(),
3306
+ description: z.string().optional()
3307
+ })
3308
+ .optional()
3309
+ });
3310
+ export const metaAdsListAdAccountsInputSchema = z.object({
3311
+ integrationId: metaAdsIntegrationIdField,
3312
+ limit: metaAdsLimitField("ad accounts", 500)
3313
+ });
3314
+ export const metaAdsListCampaignsInputSchema = z.object({
3315
+ integrationId: metaAdsIntegrationIdField,
3316
+ adAccountId: metaAdsAdAccountIdField,
3317
+ effectiveStatuses: z.array(metaAdsCampaignEffectiveStatusSchema).nullable().optional().describe("Only campaigns whose effective status is in this list."),
3318
+ limit: metaAdsLimitField("campaigns", 500)
3319
+ });
3320
+ export const metaAdsListAdSetsInputSchema = z.object({
3321
+ integrationId: metaAdsIntegrationIdField,
3322
+ adAccountId: metaAdsAdAccountIdField,
3323
+ campaignId: z.string().nullable().optional().describe("Only ad sets belonging to this campaign."),
3324
+ effectiveStatuses: z.array(metaAdsAdSetEffectiveStatusSchema).nullable().optional().describe("Only ad sets whose effective status is in this list."),
3325
+ limit: metaAdsLimitField("ad sets", 500)
3326
+ });
3327
+ export const metaAdsDatePresetSchema = z.enum([
3328
+ "today",
3329
+ "yesterday",
3330
+ "last_3d",
3331
+ "last_7d",
3332
+ "last_14d",
3333
+ "last_28d",
3334
+ "last_30d",
3335
+ "last_90d",
3336
+ "last_week_mon_sun",
3337
+ "last_week_sun_sat",
3338
+ "this_week_mon_today",
3339
+ "this_week_sun_today",
3340
+ "this_month",
3341
+ "last_month",
3342
+ "this_quarter",
3343
+ "last_quarter",
3344
+ "this_year",
3345
+ "last_year",
3346
+ "maximum",
3347
+ "data_maximum"
3348
+ ]);
3349
+ export const metaAdsBreakdownSchema = z.enum(["age", "gender", "country", "publisher_platform", "platform_position", "impression_device"]);
3350
+ export const metaAdsReadInsightsInputSchema = z.object({
3351
+ integrationId: metaAdsIntegrationIdField,
3352
+ adAccountId: metaAdsAdAccountIdField,
3353
+ level: z.enum(["account", "campaign", "adset", "ad"]).describe("Aggregation level for insight rows. Use 'ad' to compare individual creatives against each other."),
3354
+ datePreset: metaAdsDatePresetSchema.nullable().optional().describe("Relative date range. Ignored when since/until are supplied."),
3355
+ since: z.string().nullable().optional().describe("Start date (YYYY-MM-DD). Use together with until instead of datePreset."),
3356
+ until: z.string().nullable().optional().describe("End date (YYYY-MM-DD), inclusive."),
3357
+ campaignIds: z.array(z.string()).nullable().optional().describe("Restrict results to these campaign IDs."),
3358
+ adsetIds: z.array(z.string()).nullable().optional().describe("Restrict results to these ad set IDs."),
3359
+ adIds: z.array(z.string()).nullable().optional().describe("Restrict results to these ad IDs."),
3360
+ breakdowns: z
3361
+ .array(metaAdsBreakdownSchema)
3362
+ .nullable()
3363
+ .optional()
3364
+ .describe('Split each row by these dimensions. Meta only supports specific combinations, not arbitrary ones: "age" with "gender", or any of "publisher_platform", "platform_position", and "impression_device" together. "country" cannot be combined with the others. Every breakdown multiplies the row count, so expect truncation.'),
3365
+ timeIncrement: z
3366
+ .union([z.number().int().min(1).max(90), z.literal("monthly"), z.literal("all_days")])
3367
+ .nullable()
3368
+ .optional()
3369
+ .describe('Split rows into N-day windows (1 = daily), or use "monthly" or "all_days". Omit for a single aggregate row per entity.')
3370
+ });
3371
+ export const metaAdsPixelSchema = z.object({
3372
+ id: z.string(),
3373
+ name: z.string().optional(),
3374
+ last_fired_time: z.string().optional()
3375
+ });
3376
+ export const metaAdsListPixelsInputSchema = z.object({
3377
+ integrationId: metaAdsIntegrationIdField,
3378
+ adAccountId: metaAdsAdAccountIdField,
3379
+ limit: metaAdsLimitField("pixels", 500)
3380
+ });
3381
+ export const metaAdsListAudiencesInputSchema = z.object({
3382
+ integrationId: metaAdsIntegrationIdField,
3383
+ adAccountId: metaAdsAdAccountIdField,
3384
+ limit: metaAdsLimitField("audiences", 500)
3385
+ });
3386
+ const metaAdsAudienceUserSchema = z.object({
3387
+ email: z.string().nullable().optional().describe("Email address. Normalized and SHA-256 hashed before upload; never sent in plain text."),
3388
+ phone: z.string().nullable().optional().describe("Phone number including country code. Normalized and SHA-256 hashed before upload."),
3389
+ externalId: z.string().nullable().optional().describe("Your CRM identifier for this person (sent as EXTERN_ID).")
3390
+ });
3391
+ const metaAdsAudienceUsersFields = {
3392
+ integrationId: metaAdsIntegrationIdField,
3393
+ audienceId: z.string().describe("The custom audience ID."),
3394
+ users: z.array(metaAdsAudienceUserSchema).min(1).max(10000).describe("Users to match, up to 10000 per call. Each entry needs at least one of email, phone, or externalId.")
3395
+ };
3396
+ export const metaAdsAddAudienceUsersInputSchema = z.object(metaAdsAudienceUsersFields);
3397
+ export const metaAdsRemoveAudienceUsersInputSchema = z.object(metaAdsAudienceUsersFields);
3398
+ export const metaAdsConversionEventSchema = z.object({
3399
+ eventName: z.string().describe("Event name, e.g. 'Purchase', 'Lead', or a custom event name."),
3400
+ eventTime: z.number().int().describe("Unix timestamp in seconds when the conversion happened; must be within the last 7 days."),
3401
+ actionSource: z
3402
+ .enum(["website", "email", "phone_call", "chat", "physical_store", "system_generated", "app", "business_messaging", "other"])
3403
+ .describe("Where the conversion happened. Use 'system_generated' for CRM-sourced conversions."),
3404
+ userData: metaAdsAudienceUserSchema
3405
+ .extend({
3406
+ clickId: z.string().nullable().optional().describe("Meta click ID (fbc) captured from the original ad click, for click-through matching."),
3407
+ browserId: z.string().nullable().optional().describe("Meta browser ID (fbp) cookie value.")
3408
+ })
3409
+ .describe("Match keys for the person who converted. Provide as many as available; emails and phones are hashed before upload."),
3410
+ eventId: z.string().nullable().optional().describe("Deduplication ID shared with any pixel event for the same conversion."),
3411
+ value: z.number().nullable().optional().describe("Monetary value of the conversion."),
3412
+ currency: z.string().nullable().optional().describe("ISO 4217 currency code; required when value is set."),
3413
+ eventSourceUrl: z.string().nullable().optional().describe("URL where the conversion happened. Required when actionSource is 'website'.")
3414
+ });
3415
+ export const metaAdsSendConversionsInputSchema = z.object({
3416
+ integrationId: metaAdsIntegrationIdField,
3417
+ datasetId: z.string().describe("The dataset (pixel) ID that receives Conversions API events."),
3418
+ events: z.array(metaAdsConversionEventSchema).min(1).max(1000).describe("Conversion events to send.")
3419
+ });
3420
+ export const metaAdsPageSchema = z.object({
3421
+ id: z.string(),
3422
+ name: z.string(),
3423
+ category: z.string().optional()
3424
+ });
3425
+ export const metaAdsListPagesInputSchema = z.object({
3426
+ integrationId: metaAdsIntegrationIdField,
3427
+ limit: metaAdsLimitField("Pages", 200)
3428
+ });
3429
+ export const metaAdsAdCreativeSchema = z.object({
3430
+ id: z.string(),
3431
+ name: z.string().optional(),
3432
+ title: z.string().optional(),
3433
+ body: z.string().optional(),
3434
+ image_url: z.string().optional(),
3435
+ thumbnail_url: z.string().optional(),
3436
+ object_story_spec: z.unknown().optional()
3437
+ });
3438
+ export const metaAdsAdSchema = z.object({
3439
+ id: z.string(),
3440
+ name: z.string(),
3441
+ status: z.string(),
3442
+ effective_status: z.string().optional(),
3443
+ campaign_id: z.string().optional(),
3444
+ adset_id: z.string().optional(),
3445
+ created_time: z.string().optional(),
3446
+ creative: metaAdsAdCreativeSchema.optional()
3447
+ });
3448
+ export const metaAdsListAdsInputSchema = z.object({
3449
+ integrationId: metaAdsIntegrationIdField,
3450
+ adAccountId: metaAdsAdAccountIdField,
3451
+ adsetId: z.string().nullable().optional().describe("Only ads belonging to this ad set."),
3452
+ campaignId: z.string().nullable().optional().describe("Only ads belonging to this campaign."),
3453
+ effectiveStatuses: z.array(metaAdsAdEffectiveStatusSchema).nullable().optional().describe("Only ads whose effective status is in this list."),
3454
+ limit: metaAdsLimitField("ads", 500)
3455
+ });
3456
+ export const metaAdsCallToActionSchema = z.enum(["LEARN_MORE", "SHOP_NOW", "SIGN_UP", "SUBSCRIBE", "BOOK_TRAVEL", "DOWNLOAD", "GET_OFFER", "GET_QUOTE", "CONTACT_US", "APPLY_NOW", "NO_BUTTON"]);
3457
+ const metaAdsHeadlineField = z.string().nullable().optional().describe("Headline shown under the media.");
3458
+ const metaAdsDescriptionField = z.string().nullable().optional().describe("Link description shown under the headline.");
3459
+ const metaAdsMessageField = z.string().describe("Primary text shown above the creative.");
3460
+ const metaAdsCarouselCardFields = {
3461
+ headline: z.string().describe("Headline shown on this card. Facebook placements only; Instagram ignores it."),
3462
+ description: metaAdsDescriptionField,
3463
+ linkUrl: z.string().nullable().optional().describe("Per-card destination URL. Defaults to the ad's linkUrl.")
3464
+ };
3465
+ export const metaAdsCarouselCardSchema = z.discriminatedUnion("media", [
3466
+ z.object({
3467
+ media: z.literal("image").describe("This card shows an image."),
3468
+ imageUrl: z.string().describe("Publicly reachable image for this card."),
3469
+ ...metaAdsCarouselCardFields
3470
+ }),
3471
+ z.object({
3472
+ media: z.literal("video").describe("This card shows a video. Meta does not support video cards on Instagram placements, so a carousel with one is Facebook-only."),
3473
+ videoUrl: z.string().describe("Publicly reachable video for this card, uploaded and encoded before the ad is created."),
3474
+ ...metaAdsCarouselCardFields
3475
+ })
3476
+ ]);
3477
+ export const metaAdsSingleImageCreativeSchema = z.object({
3478
+ format: z.literal("single_image").describe("One still image with one headline. The standard feed ad."),
3479
+ imageUrl: z.string().describe("Publicly reachable image URL. Meta fetches it once at creation and copies it into the ad account's image library."),
3480
+ message: metaAdsMessageField,
3481
+ headline: metaAdsHeadlineField,
3482
+ description: metaAdsDescriptionField
3483
+ });
3484
+ export const metaAdsSingleVideoCreativeSchema = z.object({
3485
+ format: z.literal("single_video").describe("One video with one headline."),
3486
+ videoUrl: z.string().describe("Publicly reachable video file. Terse uploads it to the ad account and waits for Meta to finish encoding before creating the ad, so this can take a while."),
3487
+ thumbnailUrl: z.string().nullable().optional().describe("Poster frame shown before playback. Meta picks a frame when omitted."),
3488
+ message: metaAdsMessageField,
3489
+ headline: metaAdsHeadlineField,
3490
+ description: metaAdsDescriptionField
3491
+ });
3492
+ export const metaAdsCarouselCreativeSchema = z.object({
3493
+ format: z.literal("carousel").describe("Two to five swipeable cards, each its own image or video with its own headline and destination. Up to ten with optimizeCardOrder."),
3494
+ message: metaAdsMessageField,
3495
+ // Bounds live in the executor: a min above 1 makes the printer expand the array
3496
+ // into a union of tuple shapes, which buries the generated type.
3497
+ cards: z.array(metaAdsCarouselCardSchema).min(2).max(10).describe("Cards in display order. Two to five, or up to ten when optimizeCardOrder is set."),
3498
+ optimizeCardOrder: z.boolean().nullable().optional().describe("Let Meta reorder cards by predicted performance instead of keeping the given order. Required to use more than five cards."),
3499
+ showEndCard: z.boolean().nullable().optional().describe("Append a final card showing the Page profile image and the destination link. Omit to use Meta's own default.")
3500
+ });
3501
+ /**
3502
+ * Meta allows exactly one ad_format per asset feed, and SINGLE_IMAGE needs images
3503
+ * while SINGLE_VIDEO needs videos, so the media kind is part of the format rather
3504
+ * than two optional arrays that could disagree with it.
3505
+ */
3506
+ const metaAdsDynamicTextFields = {
3507
+ messages: z.array(z.string()).min(1).max(5).describe("Primary text variants, up to 5."),
3508
+ headlines: z.array(z.string()).min(1).max(5).describe("Headline variants, up to 5."),
3509
+ descriptions: z.array(z.string()).max(5).nullable().optional().describe("Link description variants, up to 5."),
3510
+ callToActions: z.array(metaAdsCallToActionSchema).min(1).max(5).describe("Button label variants, up to 5. Required: Meta rejects an asset feed with no call_to_action_types.")
3511
+ };
3512
+ const METAADS_DYNAMIC_PRECONDITION = "The ad set must already have dynamic creative enabled; Meta rejects the ad otherwise. Assets are capped at 30 in total across media and text.";
3513
+ export const metaAdsDynamicImageCreativeSchema = z.object({
3514
+ format: z.literal("dynamic_image").describe(`Several images plus several text variants, which Meta recombines per viewer as a single-image ad. ${METAADS_DYNAMIC_PRECONDITION}`),
3515
+ imageUrls: z.array(z.string()).min(1).max(10).describe("Image variants, up to 10. Terse uploads each one to the ad account to get the hash Meta requires here."),
3516
+ ...metaAdsDynamicTextFields
3517
+ });
3518
+ export const metaAdsDynamicVideoCreativeSchema = z.object({
3519
+ format: z.literal("dynamic_video").describe(`Several videos plus several text variants, which Meta recombines per viewer as a single-video ad. ${METAADS_DYNAMIC_PRECONDITION}`),
3520
+ videoUrls: z.array(z.string()).min(1).max(10).describe("Video variants, up to 10. Each is uploaded and encoded before the ad is created."),
3521
+ ...metaAdsDynamicTextFields
3522
+ });
3523
+ export const metaAdsDynamicMixedCreativeSchema = z.object({
3524
+ format: z
3525
+ .literal("dynamic_mixed")
3526
+ .describe(`Images and videos together, letting Meta pick the format per placement (AUTOMATIC_FORMAT) as well as the text combination. ${METAADS_DYNAMIC_PRECONDITION}`),
3527
+ imageUrls: z.array(z.string()).min(1).max(10).describe("Image variants, up to 10."),
3528
+ videoUrls: z.array(z.string()).min(1).max(10).describe("Video variants, up to 10."),
3529
+ ...metaAdsDynamicTextFields
3530
+ });
3531
+ export const metaAdsCreativeSchema = z
3532
+ .discriminatedUnion("format", [
3533
+ metaAdsSingleImageCreativeSchema,
3534
+ metaAdsSingleVideoCreativeSchema,
3535
+ metaAdsCarouselCreativeSchema,
3536
+ metaAdsDynamicImageCreativeSchema,
3537
+ metaAdsDynamicVideoCreativeSchema,
3538
+ metaAdsDynamicMixedCreativeSchema
3539
+ ])
3540
+ .describe("The creative to build, discriminated by format.");
3541
+ export const metaAdsCreateAdInputSchema = z.object({
3542
+ integrationId: metaAdsIntegrationIdField,
3543
+ adAccountId: metaAdsAdAccountIdField,
3544
+ adsetId: z.string().describe("The ad set the new ad belongs to. Ad sets own targeting and budget, so the new ad inherits both."),
3545
+ pageId: z.string().describe("The Facebook Page the ad is published as. Discover candidates with meta_ads_list_pages."),
3546
+ name: z.string().describe("Internal name for the new ad, e.g. 'Spring promo - variant C'."),
3547
+ linkUrl: z.string().describe("Destination URL for the click-through."),
3548
+ creative: metaAdsCreativeSchema,
3549
+ callToAction: metaAdsCallToActionSchema
3550
+ .nullable()
3551
+ .optional()
3552
+ .describe("Button label. Omit to let Meta pick its own default button, except on single_video where omitting it sends NO_BUTTON because the button is the only carrier for linkUrl. Ignored by the dynamic formats, which take callToActions instead."),
3553
+ instagramUserId: z.string().nullable().optional().describe("Instagram account to publish as when the ad set includes Instagram placements. Meta falls back to the Page when omitted."),
3554
+ urlTags: z.string().nullable().optional().describe("Query string appended to every click URL for attribution, e.g. 'utm_source=meta&utm_campaign=spring'."),
3555
+ status: z
3556
+ .enum(["ACTIVE", "PAUSED"])
3557
+ .nullable()
3558
+ .optional()
3559
+ .describe("Status the ad is created with. Defaults to PAUSED so a human can switch it on. Meta reviews new ads regardless, reporting PENDING_REVIEW as the effective status until review finishes.")
3560
+ });
3561
+ export const metaAdsSetStatusInputSchema = z.object({
3562
+ integrationId: metaAdsIntegrationIdField,
3563
+ entityType: z.enum(["campaign", "adset", "ad"]).describe("Which kind of object to update."),
3564
+ entityId: z.string().describe("The ID of the campaign, ad set, or ad."),
3565
+ status: z.enum(["ACTIVE", "PAUSED"]).describe("PAUSED stops delivery and spend; ACTIVE resumes it.")
3566
+ });
3567
+ export const metaAdsListAdAccountsOutputSchema = toolOutputBaseSchema.extend({
3568
+ adAccounts: z.array(metaAdsAdAccountEntitySchema),
3569
+ count: z.number(),
3570
+ truncated: z.boolean().describe("True when more ad accounts exist than were returned.")
3571
+ });
3572
+ export const metaAdsListCampaignsOutputSchema = toolOutputBaseSchema.extend({
3573
+ campaigns: z.array(metaAdsCampaignSchema),
3574
+ ...metaAdsCollectionFields
3575
+ });
3576
+ export const metaAdsListAdSetsOutputSchema = toolOutputBaseSchema.extend({
3577
+ adsets: z.array(metaAdsAdSetSchema),
3578
+ ...metaAdsCollectionFields
3579
+ });
3580
+ export const metaAdsListAdsOutputSchema = toolOutputBaseSchema.extend({
3581
+ ads: z.array(metaAdsAdSchema),
3582
+ ...metaAdsCollectionFields
3583
+ });
3584
+ export const metaAdsListAudiencesOutputSchema = toolOutputBaseSchema.extend({
3585
+ audiences: z.array(metaAdsCustomAudienceSchema),
3586
+ ...metaAdsCollectionFields
3587
+ });
3588
+ export const metaAdsListPixelsOutputSchema = toolOutputBaseSchema.extend({
3589
+ pixels: z.array(metaAdsPixelSchema),
3590
+ ...metaAdsCollectionFields
3591
+ });
3592
+ export const metaAdsListPagesOutputSchema = toolOutputBaseSchema.extend({
3593
+ pages: z.array(metaAdsPageSchema),
3594
+ count: z.number(),
3595
+ truncated: z.boolean().describe("True when more Pages exist than were returned.")
3596
+ });
3597
+ export const metaAdsReadInsightsOutputSchema = toolOutputBaseSchema.extend({
3598
+ rows: z.array(metaAdsInsightsRowSchema),
3599
+ ...metaAdsCollectionFields
3600
+ });
3601
+ const metaAdsAudienceUsersOutputFields = {
3602
+ audienceId: z.string(),
3603
+ numReceived: z.number(),
3604
+ numInvalidEntries: z.number()
3605
+ };
3606
+ export const metaAdsAddAudienceUsersOutputSchema = toolOutputBaseSchema.extend(metaAdsAudienceUsersOutputFields);
3607
+ export const metaAdsRemoveAudienceUsersOutputSchema = toolOutputBaseSchema.extend(metaAdsAudienceUsersOutputFields);
3608
+ export const metaAdsSendConversionsOutputSchema = toolOutputBaseSchema.extend({
3609
+ datasetId: z.string(),
3610
+ eventsReceived: z.number(),
3611
+ fbtraceId: z.string().optional()
3612
+ });
3613
+ export const metaAdsCreateAdOutputSchema = toolOutputBaseSchema.extend({
3614
+ adId: z.string(),
3615
+ creativeId: z.string(),
3616
+ adsetId: z.string(),
3617
+ pageId: z.string(),
3618
+ format: z.enum(["single_image", "single_video", "carousel", "dynamic_image", "dynamic_video", "dynamic_mixed"]),
3619
+ requestedStatus: z.enum(["ACTIVE", "PAUSED"]),
3620
+ videoIds: z.array(z.string()).describe("Meta video IDs created for this ad, in the order the videos were supplied."),
3621
+ imageHashes: z.array(z.string()).describe("Meta image hashes created for this ad, in the order the images were supplied.")
3622
+ });
3623
+ export const metaAdsSetStatusOutputSchema = toolOutputBaseSchema.extend({
3624
+ entityType: z.enum(["campaign", "adset", "ad"]),
3625
+ entityId: z.string(),
3626
+ status: z.enum(["ACTIVE", "PAUSED"])
3627
+ });
3628
+ export const metaAdsListAdAccountsTool = defineTool({
3629
+ name: "meta_ads_list_ad_accounts",
3630
+ description: "List the Meta ad accounts the connected user can access, with currency and account status. Use this to discover an adAccountId.",
3631
+ inputSchema: metaAdsListAdAccountsInputSchema,
3632
+ outputSchema: metaAdsListAdAccountsOutputSchema
3633
+ });
3634
+ export const metaAdsListCampaignsTool = defineTool({
3635
+ name: "meta_ads_list_campaigns",
3636
+ description: "List campaigns in a Meta ad account with status, objective, and budget.",
3637
+ inputSchema: metaAdsListCampaignsInputSchema,
3638
+ outputSchema: metaAdsListCampaignsOutputSchema
3639
+ });
3640
+ export const metaAdsListAdSetsTool = defineTool({
3641
+ name: "meta_ads_list_adsets",
3642
+ description: "List ad sets in a Meta ad account with status, optimization goal, and budget. Pass campaignId to narrow to one campaign. Ad sets own targeting and budget, so a new ad inherits both from the ad set it joins.",
3643
+ inputSchema: metaAdsListAdSetsInputSchema,
3644
+ outputSchema: metaAdsListAdSetsOutputSchema
3645
+ });
3646
+ export const metaAdsListAdsTool = defineTool({
3647
+ name: "meta_ads_list_ads",
3648
+ description: "List ads with the creative attached to each one (primary text, headline, image). Pair with meta_ads_read_insights at level='ad' to attribute performance to a specific creative, and check effective_status for PENDING_REVIEW or DISAPPROVED.",
3649
+ inputSchema: metaAdsListAdsInputSchema,
3650
+ outputSchema: metaAdsListAdsOutputSchema
3651
+ });
3652
+ export const metaAdsListAudiencesTool = defineTool({
3653
+ name: "meta_ads_list_audiences",
3654
+ description: "List the custom audiences in a Meta ad account, with approximate sizes and delivery status.",
3655
+ inputSchema: metaAdsListAudiencesInputSchema,
3656
+ outputSchema: metaAdsListAudiencesOutputSchema
3657
+ });
3658
+ export const metaAdsListPixelsTool = defineTool({
3659
+ name: "meta_ads_list_pixels",
3660
+ description: "List the Meta pixels (Conversions API datasets) in an ad account. Use a pixel ID as the datasetId for meta_ads_send_conversions.",
3661
+ inputSchema: metaAdsListPixelsInputSchema,
3662
+ outputSchema: metaAdsListPixelsOutputSchema
3663
+ });
3664
+ export const metaAdsListPagesTool = defineTool({
3665
+ name: "meta_ads_list_pages",
3666
+ description: "List the Facebook Pages the connected user manages. Every ad creative is published as a Page, so meta_ads_create_ad needs a pageId from here.",
3667
+ inputSchema: metaAdsListPagesInputSchema,
3668
+ outputSchema: metaAdsListPagesOutputSchema
3669
+ });
3670
+ export const metaAdsReadInsightsTool = defineTool({
3671
+ name: "meta_ads_read_insights",
3672
+ description: "Read Meta Ads performance insights (spend, impressions, clicks, conversions) at campaign, ad set, or ad level for a date range, optionally split by breakdowns. Use level='ad' to judge individual creatives. Follows pagination up to 2000 rows; the result sets truncated=true when more rows exist, so narrow the date range or filter by campaign/ad set/ad IDs to fetch the rest.",
3673
+ inputSchema: metaAdsReadInsightsInputSchema,
3674
+ outputSchema: metaAdsReadInsightsOutputSchema
3675
+ });
3676
+ export const metaAdsAddAudienceUsersTool = defineTool({
3677
+ name: "meta_ads_add_audience_users",
3678
+ description: "Add people to a Meta custom audience. Emails and phone numbers are normalized and SHA-256 hashed before upload, so pass raw values.",
3679
+ inputSchema: metaAdsAddAudienceUsersInputSchema,
3680
+ outputSchema: metaAdsAddAudienceUsersOutputSchema
3681
+ });
3682
+ export const metaAdsRemoveAudienceUsersTool = defineTool({
3683
+ name: "meta_ads_remove_audience_users",
3684
+ description: "Remove people from a Meta custom audience. Emails and phone numbers are normalized and SHA-256 hashed before upload, so pass raw values.",
3685
+ inputSchema: metaAdsRemoveAudienceUsersInputSchema,
3686
+ outputSchema: metaAdsRemoveAudienceUsersOutputSchema
3687
+ });
3688
+ export const metaAdsSendConversionsTool = defineTool({
3689
+ name: "meta_ads_send_conversions",
3690
+ description: "Send offline conversion events to Meta via the Conversions API so campaign delivery can optimize on downstream outcomes (e.g. deals won).",
3691
+ inputSchema: metaAdsSendConversionsInputSchema,
3692
+ outputSchema: metaAdsSendConversionsOutputSchema
3693
+ });
3694
+ export const higgsfieldImageSizeSchema = z.enum([
3695
+ "2048x1152",
3696
+ "2048x1536",
3697
+ "2016x1344",
3698
+ "1696x960",
3699
+ "1632x1088",
3700
+ "1152x2048",
3701
+ "1536x2048",
3702
+ "1344x2016",
3703
+ "960x1696",
3704
+ "1088x1632",
3705
+ "1536x1536",
3706
+ "1536x1152",
3707
+ "1152x1536"
3708
+ ]);
3709
+ export const higgsfieldGeneratedImageSchema = z.object({
3710
+ jobId: z.string().describe("Higgsfield job that produced this image."),
3711
+ url: z.string().describe("Signed Terse-hosted URL for the full-quality image. Valid for 24 hours; pass it straight to meta_ads_create_ad as pictureUrl."),
3712
+ thumbnailUrl: z.string().nullable().describe("Signed URL for a smaller preview of the same image, when Higgsfield returned one.")
3713
+ });
3714
+ export const higgsfieldGenerateImageInputSchema = z.object({
3715
+ integrationId: z.string().describe("The integration ID of the Higgsfield connection to use."),
3716
+ prompt: z.string().min(1).describe("What to generate. Describe the subject, setting, mood, and any on-image text."),
3717
+ size: higgsfieldImageSizeSchema.nullable().optional().describe("Output resolution and aspect ratio. Defaults to 1536x1536. Use a landscape size for feed ads."),
3718
+ quality: z.enum(["720p", "1080p"]).nullable().optional().describe("Render quality. Defaults to 1080p."),
3719
+ batchSize: z
3720
+ .union([z.literal(1), z.literal(4)])
3721
+ .nullable()
3722
+ .optional()
3723
+ .describe("Generate 1 or 4 variants in one call. Defaults to 1; use 4 when you want options to compare."),
3724
+ styleId: z.string().nullable().optional().describe("Optional Higgsfield style preset ID."),
3725
+ referenceImageUrl: z.string().nullable().optional().describe("A single publicly reachable reference image that steers style and subject consistency.")
3726
+ });
3727
+ export const higgsfieldGenerateImageOutputSchema = toolOutputBaseSchema.extend({
3728
+ images: z.array(higgsfieldGeneratedImageSchema),
3729
+ count: z.number()
3730
+ });
3731
+ export const higgsfieldVideoModelSchema = z.enum(["dop-lite", "dop-turbo", "dop-standard"]);
3732
+ export const higgsfieldGeneratedVideoSchema = z.object({
3733
+ jobId: z.string().describe("Higgsfield job that produced this video."),
3734
+ url: z.string().describe("Signed Terse-hosted URL for the video. Valid for 24 hours; pass it straight to meta_ads_create_ad as a videoUrl."),
3735
+ thumbnailUrl: z.string().nullable().describe("Signed URL for a poster frame, when Higgsfield returned one.")
3736
+ });
3737
+ export const higgsfieldGenerateVideoInputSchema = z.object({
3738
+ integrationId: z.string().describe("The integration ID of the Higgsfield connection to use."),
3739
+ imageUrl: z.string().describe("Publicly reachable still image to animate. A Terse-hosted URL from higgsfield_generate_image works directly."),
3740
+ prompt: z.string().min(1).describe("The motion to apply: camera movement, subject action, pacing."),
3741
+ model: higgsfieldVideoModelSchema.nullable().optional().describe("dop-lite is cheapest, dop-turbo is the default, dop-standard is the highest quality."),
3742
+ motionId: z.string().nullable().optional().describe("Motion preset ID from higgsfield_list_motions, applied on top of the prompt."),
3743
+ motionStrength: z.number().min(0).max(1).nullable().optional().describe("How strongly to apply motionId, 0 to 1. Defaults to 1. Ignored unless motionId is set."),
3744
+ seed: z.number().int().min(0).max(1000000).nullable().optional().describe("Fixed seed for a reproducible result.")
3745
+ });
3746
+ export const higgsfieldGenerateVideoOutputSchema = toolOutputBaseSchema.extend({
3747
+ videos: z.array(higgsfieldGeneratedVideoSchema),
3748
+ count: z.number()
3749
+ });
3750
+ export const higgsfieldMotionSchema = z.object({
3751
+ id: z.string(),
3752
+ name: z.string(),
3753
+ description: z.string().nullable(),
3754
+ previewUrl: z.string().nullable()
3755
+ });
3756
+ export const higgsfieldListMotionsInputSchema = z.object({
3757
+ integrationId: z.string().describe("The integration ID of the Higgsfield connection to use.")
3758
+ });
3759
+ export const higgsfieldListMotionsOutputSchema = toolOutputBaseSchema.extend({
3760
+ motions: z.array(higgsfieldMotionSchema),
3761
+ count: z.number()
3762
+ });
3763
+ export const higgsfieldGenerateImageTool = defineTool({
3764
+ name: "higgsfield_generate_image",
3765
+ description: "Generate ad creative images from a text prompt with Higgsfield. Each result is cached by Terse and returned as a signed URL valid for 24 hours, which can be shown to a human for approval and then handed to meta_ads_create_ad as an imageUrl. Generation is asynchronous and this waits for it to finish, so expect it to take a while.",
3766
+ inputSchema: higgsfieldGenerateImageInputSchema,
3767
+ outputSchema: higgsfieldGenerateImageOutputSchema
3768
+ });
3769
+ export const higgsfieldGenerateVideoTool = defineTool({
3770
+ name: "higgsfield_generate_video",
3771
+ description: "Animate a still image into an ad video with Higgsfield. This tool is image-to-video, so generate or pick an image first, then animate it here. The result is cached by Terse and returned as a signed URL valid for 24 hours, which can be shown to a human for approval and then handed to meta_ads_create_ad as a videoUrl. Generation is asynchronous and this waits for it to finish, so expect it to take a while.",
3772
+ inputSchema: higgsfieldGenerateVideoInputSchema,
3773
+ outputSchema: higgsfieldGenerateVideoOutputSchema
3774
+ });
3775
+ export const higgsfieldListMotionsTool = defineTool({
3776
+ name: "higgsfield_list_motions",
3777
+ description: "List Higgsfield motion presets with their IDs. A motion is a named camera move (a dolly, an orbit, a zoom) that Higgsfield applies on top of the prompt when animating a still image. Pass one as motionId to higgsfield_generate_video, scaled by motionStrength. The IDs are opaque, so call this first rather than guessing one.",
3778
+ inputSchema: higgsfieldListMotionsInputSchema,
3779
+ outputSchema: higgsfieldListMotionsOutputSchema
3780
+ });
3781
+ export const metaAdsCreateAdTool = defineTool({
3782
+ name: "meta_ads_create_ad",
3783
+ description: "Create an ad creative and the ad that uses it inside an existing ad set. Pick a creative.format: single_image, single_video, carousel (2-10 cards, each card an image or a video), or dynamic_image / dynamic_video / dynamic_mixed (several media assets plus several text variants that Meta recombines per viewer, which requires an ad set with dynamic creative enabled). Images are fetched by Meta and videos are uploaded and encoded before the ad is created, so temporary signed URLs are fine. Ad creatives are immutable, so improving a creative means creating a new ad here and pausing the old one with meta_ads_set_status. New ads enter PENDING_REVIEW before reaching the requested status.",
3784
+ inputSchema: metaAdsCreateAdInputSchema,
3785
+ outputSchema: metaAdsCreateAdOutputSchema
3786
+ });
3787
+ export const metaAdsSetStatusTool = defineTool({
3788
+ name: "meta_ads_set_status",
3789
+ description: "Pause or resume a campaign, ad set, or ad. PAUSED stops delivery and spend immediately and is reversible.",
3790
+ inputSchema: metaAdsSetStatusInputSchema,
3791
+ outputSchema: metaAdsSetStatusOutputSchema
3792
+ });
2998
3793
  export const ToolDefinitions = {
2999
3794
  [linearCreateTicketTool.name]: linearCreateTicketTool,
3000
3795
  [linearUpdateTicketTool.name]: linearUpdateTicketTool,
@@ -3082,7 +3877,33 @@ export const ToolDefinitions = {
3082
3877
  [apolloBulkEnrichPeopleTool.name]: apolloBulkEnrichPeopleTool,
3083
3878
  [apolloEnrichOrganizationTool.name]: apolloEnrichOrganizationTool,
3084
3879
  [apolloSearchPeopleTool.name]: apolloSearchPeopleTool,
3085
- [apolloListJobPostingsTool.name]: apolloListJobPostingsTool
3880
+ [apolloListJobPostingsTool.name]: apolloListJobPostingsTool,
3881
+ [googleSearchConsoleListSitesTool.name]: googleSearchConsoleListSitesTool,
3882
+ [googleSearchConsoleGetSiteTool.name]: googleSearchConsoleGetSiteTool,
3883
+ [googleSearchConsoleAddSiteTool.name]: googleSearchConsoleAddSiteTool,
3884
+ [googleSearchConsoleDeleteSiteTool.name]: googleSearchConsoleDeleteSiteTool,
3885
+ [googleSearchConsoleListSitemapsTool.name]: googleSearchConsoleListSitemapsTool,
3886
+ [googleSearchConsoleGetSitemapTool.name]: googleSearchConsoleGetSitemapTool,
3887
+ [googleSearchConsoleSubmitSitemapTool.name]: googleSearchConsoleSubmitSitemapTool,
3888
+ [googleSearchConsoleDeleteSitemapTool.name]: googleSearchConsoleDeleteSitemapTool,
3889
+ [googleSearchConsoleQuerySearchAnalyticsTool.name]: googleSearchConsoleQuerySearchAnalyticsTool,
3890
+ [googleSearchConsoleInspectUrlTool.name]: googleSearchConsoleInspectUrlTool,
3891
+ [metaAdsListAdAccountsTool.name]: metaAdsListAdAccountsTool,
3892
+ [metaAdsListCampaignsTool.name]: metaAdsListCampaignsTool,
3893
+ [metaAdsListAdSetsTool.name]: metaAdsListAdSetsTool,
3894
+ [metaAdsListAdsTool.name]: metaAdsListAdsTool,
3895
+ [metaAdsListAudiencesTool.name]: metaAdsListAudiencesTool,
3896
+ [metaAdsListPixelsTool.name]: metaAdsListPixelsTool,
3897
+ [metaAdsListPagesTool.name]: metaAdsListPagesTool,
3898
+ [metaAdsReadInsightsTool.name]: metaAdsReadInsightsTool,
3899
+ [metaAdsAddAudienceUsersTool.name]: metaAdsAddAudienceUsersTool,
3900
+ [metaAdsRemoveAudienceUsersTool.name]: metaAdsRemoveAudienceUsersTool,
3901
+ [metaAdsSendConversionsTool.name]: metaAdsSendConversionsTool,
3902
+ [metaAdsCreateAdTool.name]: metaAdsCreateAdTool,
3903
+ [metaAdsSetStatusTool.name]: metaAdsSetStatusTool,
3904
+ [higgsfieldGenerateImageTool.name]: higgsfieldGenerateImageTool,
3905
+ [higgsfieldGenerateVideoTool.name]: higgsfieldGenerateVideoTool,
3906
+ [higgsfieldListMotionsTool.name]: higgsfieldListMotionsTool
3086
3907
  };
3087
3908
  export const toolsWithIntegrationId = new Set(Object.entries(ToolDefinitions)
3088
3909
  .filter(([, def]) => {