@canonry/canonry 4.118.0 → 4.123.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -0
- package/assets/agent-workspace/skills/canonry/SKILL.md +3 -0
- package/assets/agent-workspace/skills/canonry/references/canonry-cli.md +135 -28
- package/assets/assets/{AuditHistoryPanel-Yh7VEe4P.js → AuditHistoryPanel-BVQMDIhQ.js} +1 -1
- package/assets/assets/{BacklinksPage-BmO77kMs.js → BacklinksPage-nrHT9VMG.js} +1 -1
- package/assets/assets/ChartPrimitives-_8qLsQzI.js +1 -0
- package/assets/assets/{HistoryPage-DkLV_iRc.js → HistoryPage-DqsKKdyy.js} +1 -1
- package/assets/assets/ProjectPage-GyKoQUv_.js +7 -0
- package/assets/assets/{RunRow-BDH9agxQ.js → RunRow-BRZZcSjQ.js} +1 -1
- package/assets/assets/{RunsPage-D9YsEeT3.js → RunsPage-24aI8DKF.js} +1 -1
- package/assets/assets/{SettingsPage-o5as3Ixw.js → SettingsPage-BaNeTG1i.js} +1 -1
- package/assets/assets/{TrafficPage-BCK203aQ.js → TrafficPage-ByvcLSjv.js} +1 -1
- package/assets/assets/{TrafficSourceDetailPage-DsVMAZvS.js → TrafficSourceDetailPage-B-siTXVg.js} +1 -1
- package/assets/assets/{arrow-left-B7ZR6VC9.js → arrow-left-CBh1cZNH.js} +1 -1
- package/assets/assets/{extract-error-message-DeYDUpew.js → extract-error-message-DJZCPudR.js} +1 -1
- package/assets/assets/index-jymsMBpZ.css +1 -0
- package/assets/assets/index-mzLganDP.js +210 -0
- package/assets/assets/{trash-2-xxHTqWbF.js → trash-2-Bh-Yvkgc.js} +1 -1
- package/assets/assets/vendor-recharts-DSxTZhaH.js +36 -0
- package/assets/index.html +3 -3
- package/dist/{chunk-CMZIPFNQ.js → chunk-4AZ7VES6.js} +4915 -719
- package/dist/{chunk-75UBTCKS.js → chunk-HJIIJI7K.js} +321 -6
- package/dist/{chunk-HGNY5GL4.js → chunk-JYBNBK25.js} +273 -37
- package/dist/{chunk-KEZWLP4O.js → chunk-MMFSI3OG.js} +3281 -2341
- package/dist/cli.js +554 -35
- package/dist/index.js +4 -4
- package/dist/{intelligence-service-FWPXMAVK.js → intelligence-service-K35EN43I.js} +2 -2
- package/dist/mcp.js +4 -4
- package/package.json +7 -7
- package/assets/assets/ChartPrimitives-H0ICVpw_.js +0 -1
- package/assets/assets/ProjectPage-R3odr_eA.js +0 -7
- package/assets/assets/index-Bot6YiD6.css +0 -1
- package/assets/assets/index-QCFQv0xh.js +0 -210
- package/assets/assets/vendor-recharts-C9EZkgbP.js +0 -36
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
loadConfig,
|
|
11
11
|
loadConfigRaw,
|
|
12
12
|
saveConfigPatch
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-HJIIJI7K.js";
|
|
14
14
|
import {
|
|
15
15
|
CC_CACHE_DIR,
|
|
16
16
|
DUCKDB_SPEC,
|
|
@@ -115,12 +115,14 @@ import {
|
|
|
115
115
|
siteAuditPages,
|
|
116
116
|
siteAuditSnapshots,
|
|
117
117
|
usageCounters
|
|
118
|
-
} from "./chunk-
|
|
118
|
+
} from "./chunk-4AZ7VES6.js";
|
|
119
119
|
import {
|
|
120
120
|
AGENT_MEMORY_VALUE_MAX_BYTES,
|
|
121
121
|
AGENT_PROVIDER_IDS,
|
|
122
122
|
AI_ENGINE_DOMAINS,
|
|
123
123
|
AI_ENGINE_SELF_DOMAINS,
|
|
124
|
+
AdsAdGroupBillingEventTypes,
|
|
125
|
+
AdsCampaignBiddingTypes,
|
|
124
126
|
AgentProviderIds,
|
|
125
127
|
BacklinkSources,
|
|
126
128
|
CcReleaseSyncStatuses,
|
|
@@ -142,6 +144,10 @@ import {
|
|
|
142
144
|
TrafficSourceTypes,
|
|
143
145
|
VERTEX_AI_SEARCH_PROXY_DOMAIN,
|
|
144
146
|
actionConfidenceLabel,
|
|
147
|
+
adsAccountDtoSchema,
|
|
148
|
+
adsConversionEventSettingListResponseSchema,
|
|
149
|
+
adsConversionPixelListResponseSchema,
|
|
150
|
+
adsGeoSearchResponseSchema,
|
|
145
151
|
agentBusy,
|
|
146
152
|
agentMemoryDeleteRequestSchema,
|
|
147
153
|
agentMemoryUpsertRequestSchema,
|
|
@@ -166,6 +172,7 @@ import {
|
|
|
166
172
|
isGhostTelemetryEvent,
|
|
167
173
|
isRetryableHttpError,
|
|
168
174
|
normalizeIdTokens,
|
|
175
|
+
normalizeServedModel,
|
|
169
176
|
normalizeUrlPath,
|
|
170
177
|
notFound,
|
|
171
178
|
parseOriginList,
|
|
@@ -178,7 +185,7 @@ import {
|
|
|
178
185
|
validationError,
|
|
179
186
|
winnabilityClassLabel,
|
|
180
187
|
withRetry
|
|
181
|
-
} from "./chunk-
|
|
188
|
+
} from "./chunk-MMFSI3OG.js";
|
|
182
189
|
|
|
183
190
|
// src/telemetry.ts
|
|
184
191
|
import crypto from "crypto";
|
|
@@ -594,6 +601,7 @@ async function executeTrackedQuery(input) {
|
|
|
594
601
|
provider: "gemini",
|
|
595
602
|
rawResponse,
|
|
596
603
|
model,
|
|
604
|
+
servedModel: extractServedModel(rawResponse),
|
|
597
605
|
groundingSources: parsed.groundingSources,
|
|
598
606
|
searchQueries: parsed.searchQueries
|
|
599
607
|
};
|
|
@@ -619,6 +627,9 @@ function normalizeResult(raw) {
|
|
|
619
627
|
function hasParsedResponseContent(rawResponse) {
|
|
620
628
|
return Array.isArray(rawResponse.candidates) && rawResponse.candidates.length > 0;
|
|
621
629
|
}
|
|
630
|
+
function extractServedModel(rawResponse) {
|
|
631
|
+
return normalizeServedModel(rawResponse.modelVersion);
|
|
632
|
+
}
|
|
622
633
|
function reparseStoredResult(rawResponse) {
|
|
623
634
|
const groundingSources = extractGroundingMetadataFromRaw(rawResponse);
|
|
624
635
|
const searchQueries = extractSearchQueriesFromRaw(rawResponse);
|
|
@@ -767,7 +778,11 @@ function responseToRecord(response) {
|
|
|
767
778
|
}));
|
|
768
779
|
return {
|
|
769
780
|
candidates: candidates ?? [],
|
|
770
|
-
usageMetadata: response.usageMetadata ?? null
|
|
781
|
+
usageMetadata: response.usageMetadata ?? null,
|
|
782
|
+
// Gemini reports the identity it actually served here — the only place it
|
|
783
|
+
// appears. Preserved so `servedModel` can be read back off a stored snapshot.
|
|
784
|
+
modelVersion: response.modelVersion ?? null,
|
|
785
|
+
responseId: response.responseId ?? null
|
|
771
786
|
};
|
|
772
787
|
} catch {
|
|
773
788
|
return { error: "failed to serialize response" };
|
|
@@ -884,6 +899,7 @@ var geminiAdapter = {
|
|
|
884
899
|
provider: "gemini",
|
|
885
900
|
rawResponse: raw.rawResponse,
|
|
886
901
|
model: raw.model,
|
|
902
|
+
servedModel: raw.servedModel,
|
|
887
903
|
groundingSources: raw.groundingSources,
|
|
888
904
|
searchQueries: raw.searchQueries
|
|
889
905
|
};
|
|
@@ -1006,6 +1022,7 @@ async function executeTrackedQuery2(input) {
|
|
|
1006
1022
|
provider: "openai",
|
|
1007
1023
|
rawResponse,
|
|
1008
1024
|
model,
|
|
1025
|
+
servedModel: extractServedModel2(rawResponse),
|
|
1009
1026
|
groundingSources: parsed.groundingSources,
|
|
1010
1027
|
searchQueries: parsed.searchQueries
|
|
1011
1028
|
};
|
|
@@ -1031,6 +1048,9 @@ function normalizeResult2(raw) {
|
|
|
1031
1048
|
function hasParsedResponseContent2(rawResponse) {
|
|
1032
1049
|
return Array.isArray(rawResponse.output) && rawResponse.output.length > 0;
|
|
1033
1050
|
}
|
|
1051
|
+
function extractServedModel2(rawResponse) {
|
|
1052
|
+
return normalizeServedModel(rawResponse.model);
|
|
1053
|
+
}
|
|
1034
1054
|
function reparseStoredResult2(rawResponse) {
|
|
1035
1055
|
const groundingSources = extractGroundingSourcesFromRaw(rawResponse);
|
|
1036
1056
|
const searchQueries = extractSearchQueriesFromRaw2(rawResponse);
|
|
@@ -1228,6 +1248,7 @@ var openaiAdapter = {
|
|
|
1228
1248
|
provider: "openai",
|
|
1229
1249
|
rawResponse: raw.rawResponse,
|
|
1230
1250
|
model: raw.model,
|
|
1251
|
+
servedModel: raw.servedModel,
|
|
1231
1252
|
groundingSources: raw.groundingSources,
|
|
1232
1253
|
searchQueries: raw.searchQueries
|
|
1233
1254
|
};
|
|
@@ -1365,6 +1386,7 @@ async function executeTrackedQuery3(input) {
|
|
|
1365
1386
|
provider: "claude",
|
|
1366
1387
|
rawResponse,
|
|
1367
1388
|
model,
|
|
1389
|
+
servedModel: extractServedModel3(rawResponse),
|
|
1368
1390
|
groundingSources: parsed.groundingSources,
|
|
1369
1391
|
searchQueries: parsed.searchQueries
|
|
1370
1392
|
};
|
|
@@ -1390,6 +1412,9 @@ function normalizeResult3(raw) {
|
|
|
1390
1412
|
function hasParsedResponseContent3(rawResponse) {
|
|
1391
1413
|
return Array.isArray(rawResponse.content) && rawResponse.content.length > 0;
|
|
1392
1414
|
}
|
|
1415
|
+
function extractServedModel3(rawResponse) {
|
|
1416
|
+
return normalizeServedModel(rawResponse.model);
|
|
1417
|
+
}
|
|
1393
1418
|
function reparseStoredResult3(rawResponse) {
|
|
1394
1419
|
const groundingSources = extractGroundingSourcesFromRaw2(rawResponse);
|
|
1395
1420
|
const searchQueries = extractSearchQueriesFromRaw3(rawResponse);
|
|
@@ -1589,6 +1614,7 @@ var claudeAdapter = {
|
|
|
1589
1614
|
provider: "claude",
|
|
1590
1615
|
rawResponse: raw.rawResponse,
|
|
1591
1616
|
model: raw.model,
|
|
1617
|
+
servedModel: raw.servedModel,
|
|
1592
1618
|
groundingSources: raw.groundingSources,
|
|
1593
1619
|
searchQueries: raw.searchQueries
|
|
1594
1620
|
};
|
|
@@ -1704,10 +1730,12 @@ async function executeTrackedQuery4(input) {
|
|
|
1704
1730
|
]
|
|
1705
1731
|
})
|
|
1706
1732
|
);
|
|
1733
|
+
const rawResponse = responseToRecord4(response);
|
|
1707
1734
|
return {
|
|
1708
1735
|
provider: "local",
|
|
1709
|
-
rawResponse
|
|
1736
|
+
rawResponse,
|
|
1710
1737
|
model,
|
|
1738
|
+
servedModel: extractServedModel4(rawResponse),
|
|
1711
1739
|
groundingSources: [],
|
|
1712
1740
|
searchQueries: []
|
|
1713
1741
|
};
|
|
@@ -1771,6 +1799,9 @@ function extractDomainMentions(text) {
|
|
|
1771
1799
|
}
|
|
1772
1800
|
return [...domains];
|
|
1773
1801
|
}
|
|
1802
|
+
function extractServedModel4(rawResponse) {
|
|
1803
|
+
return normalizeServedModel(rawResponse.model);
|
|
1804
|
+
}
|
|
1774
1805
|
function responseToRecord4(response) {
|
|
1775
1806
|
try {
|
|
1776
1807
|
return JSON.parse(JSON.stringify(response));
|
|
@@ -1830,6 +1861,7 @@ var localAdapter = {
|
|
|
1830
1861
|
provider: "local",
|
|
1831
1862
|
rawResponse: raw.rawResponse,
|
|
1832
1863
|
model: raw.model,
|
|
1864
|
+
servedModel: raw.servedModel,
|
|
1833
1865
|
groundingSources: raw.groundingSources,
|
|
1834
1866
|
searchQueries: raw.searchQueries
|
|
1835
1867
|
};
|
|
@@ -2505,6 +2537,7 @@ async function executeTrackedQuery5(input) {
|
|
|
2505
2537
|
provider: "perplexity",
|
|
2506
2538
|
rawResponse,
|
|
2507
2539
|
model,
|
|
2540
|
+
servedModel: extractServedModel5(rawResponse),
|
|
2508
2541
|
groundingSources: parsed.groundingSources,
|
|
2509
2542
|
searchQueries: parsed.searchQueries
|
|
2510
2543
|
};
|
|
@@ -2535,6 +2568,9 @@ function hasParsedResponseContent4(rawResponse) {
|
|
|
2535
2568
|
if (!nestedResponse) return false;
|
|
2536
2569
|
return Array.isArray(nestedResponse.choices) && nestedResponse.choices.length > 0 || Array.isArray(nestedResponse.search_results) && nestedResponse.search_results.length > 0 || Array.isArray(nestedResponse.citations) && nestedResponse.citations.length > 0;
|
|
2537
2570
|
}
|
|
2571
|
+
function extractServedModel5(rawResponse) {
|
|
2572
|
+
return normalizeServedModel(rawResponse.model);
|
|
2573
|
+
}
|
|
2538
2574
|
function reparseStoredResult4(rawResponse) {
|
|
2539
2575
|
const groundingSources = extractGroundingSources(rawResponse);
|
|
2540
2576
|
return {
|
|
@@ -2725,6 +2761,7 @@ var perplexityAdapter = {
|
|
|
2725
2761
|
provider: "perplexity",
|
|
2726
2762
|
rawResponse: raw.rawResponse,
|
|
2727
2763
|
model: raw.model,
|
|
2764
|
+
servedModel: raw.servedModel,
|
|
2728
2765
|
groundingSources: raw.groundingSources,
|
|
2729
2766
|
searchQueries: raw.searchQueries
|
|
2730
2767
|
};
|
|
@@ -3303,7 +3340,10 @@ var JobRunner = class {
|
|
|
3303
3340
|
}
|
|
3304
3341
|
}
|
|
3305
3342
|
const projectProviders = providerOverride ?? project.providers;
|
|
3306
|
-
activeProviders = this.registry.getForProject(projectProviders)
|
|
3343
|
+
activeProviders = this.registry.getForProject(projectProviders).map((entry) => {
|
|
3344
|
+
const model = project.providerModels[entry.adapter.name];
|
|
3345
|
+
return model === void 0 ? entry : { ...entry, config: { ...entry.config, model } };
|
|
3346
|
+
});
|
|
3307
3347
|
if (activeProviders.length === 0) {
|
|
3308
3348
|
throw new Error("No providers configured. Add at least one provider API key.");
|
|
3309
3349
|
}
|
|
@@ -3406,6 +3446,7 @@ var JobRunner = class {
|
|
|
3406
3446
|
queryText: q.query,
|
|
3407
3447
|
provider: providerName,
|
|
3408
3448
|
model: raw.model,
|
|
3449
|
+
servedModel: raw.servedModel ?? null,
|
|
3409
3450
|
citationState,
|
|
3410
3451
|
answerMentioned,
|
|
3411
3452
|
answerText: normalized.answerText,
|
|
@@ -3416,6 +3457,7 @@ var JobRunner = class {
|
|
|
3416
3457
|
screenshotPath: screenshotRelPath,
|
|
3417
3458
|
rawResponse: JSON.stringify({
|
|
3418
3459
|
model: raw.model,
|
|
3460
|
+
servedModel: raw.servedModel ?? null,
|
|
3419
3461
|
groundingSources: normalized.groundingSources,
|
|
3420
3462
|
searchQueries: normalized.searchQueries,
|
|
3421
3463
|
apiResponse: raw.rawResponse
|
|
@@ -3430,6 +3472,7 @@ var JobRunner = class {
|
|
|
3430
3472
|
queryText: q.query,
|
|
3431
3473
|
provider: providerName,
|
|
3432
3474
|
model: raw.model,
|
|
3475
|
+
servedModel: raw.servedModel ?? null,
|
|
3433
3476
|
citationState,
|
|
3434
3477
|
answerMentioned,
|
|
3435
3478
|
answerText: normalized.answerText,
|
|
@@ -3439,6 +3482,7 @@ var JobRunner = class {
|
|
|
3439
3482
|
location: runLocation?.label ?? null,
|
|
3440
3483
|
rawResponse: JSON.stringify({
|
|
3441
3484
|
model: raw.model,
|
|
3485
|
+
servedModel: raw.servedModel ?? null,
|
|
3442
3486
|
groundingSources: normalized.groundingSources,
|
|
3443
3487
|
searchQueries: normalized.searchQueries,
|
|
3444
3488
|
apiResponse: raw.rawResponse
|
|
@@ -4245,9 +4289,8 @@ var OpenAiAdsWriteStatuses = {
|
|
|
4245
4289
|
active: "active",
|
|
4246
4290
|
paused: "paused"
|
|
4247
4291
|
};
|
|
4248
|
-
var
|
|
4249
|
-
|
|
4250
|
-
};
|
|
4292
|
+
var OpenAiAdsBiddingTypes = AdsCampaignBiddingTypes;
|
|
4293
|
+
var OpenAiAdsBillingEventTypes = AdsAdGroupBillingEventTypes;
|
|
4251
4294
|
var OpenAiAdsCreativeTypes = {
|
|
4252
4295
|
chatCard: "chat_card"
|
|
4253
4296
|
};
|
|
@@ -4284,6 +4327,8 @@ var MAX_BID_MICROS = 1e8;
|
|
|
4284
4327
|
var MIN_AD_TITLE_LENGTH = 3;
|
|
4285
4328
|
var MAX_AD_TITLE_LENGTH = 50;
|
|
4286
4329
|
var MAX_AD_BODY_LENGTH = 100;
|
|
4330
|
+
var MIN_GEO_SEARCH_LIMIT = 1;
|
|
4331
|
+
var MAX_GEO_SEARCH_LIMIT = 500;
|
|
4287
4332
|
function validateApiKey(apiKey) {
|
|
4288
4333
|
if (!apiKey || typeof apiKey !== "string" || apiKey.trim().length === 0) {
|
|
4289
4334
|
throw new OpenAiAdsApiError("API key is required and must be a non-empty string", 400);
|
|
@@ -4294,6 +4339,15 @@ function validateId(value, label) {
|
|
|
4294
4339
|
throw new OpenAiAdsApiError(`${label} is required and must be a non-empty string`, 400);
|
|
4295
4340
|
}
|
|
4296
4341
|
}
|
|
4342
|
+
function validateGeoSearchLimit(limit) {
|
|
4343
|
+
if (limit === void 0) return;
|
|
4344
|
+
if (!Number.isInteger(limit) || limit < MIN_GEO_SEARCH_LIMIT || limit > MAX_GEO_SEARCH_LIMIT) {
|
|
4345
|
+
throw new OpenAiAdsApiError(
|
|
4346
|
+
`Geo search limit must be an integer between ${MIN_GEO_SEARCH_LIMIT} and ${MAX_GEO_SEARCH_LIMIT}`,
|
|
4347
|
+
400
|
|
4348
|
+
);
|
|
4349
|
+
}
|
|
4350
|
+
}
|
|
4297
4351
|
function isRecord(value) {
|
|
4298
4352
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4299
4353
|
}
|
|
@@ -4370,10 +4424,34 @@ function validateCampaignTargeting(value) {
|
|
|
4370
4424
|
validateId(target.id, "Campaign location id");
|
|
4371
4425
|
}
|
|
4372
4426
|
}
|
|
4427
|
+
function validateCampaignBidding(request) {
|
|
4428
|
+
const biddingType = request.bidding_type;
|
|
4429
|
+
if (biddingType !== void 0 && biddingType !== OpenAiAdsBiddingTypes.impressions && biddingType !== OpenAiAdsBiddingTypes.clicks) {
|
|
4430
|
+
throw new OpenAiAdsApiError("Campaign bidding_type must be impressions or clicks", 400);
|
|
4431
|
+
}
|
|
4432
|
+
const conversionIds = request.conversion_event_setting_ids;
|
|
4433
|
+
if (conversionIds !== void 0) {
|
|
4434
|
+
if (!Array.isArray(conversionIds)) {
|
|
4435
|
+
throw new OpenAiAdsApiError("Campaign conversion_event_setting_ids must be an array of unique IDs", 400);
|
|
4436
|
+
}
|
|
4437
|
+
for (const conversionId of conversionIds) {
|
|
4438
|
+
validateId(conversionId, "Campaign conversion event setting id");
|
|
4439
|
+
}
|
|
4440
|
+
if (new Set(conversionIds).size !== conversionIds.length) {
|
|
4441
|
+
throw new OpenAiAdsApiError("Campaign conversion_event_setting_ids must contain unique IDs", 400);
|
|
4442
|
+
}
|
|
4443
|
+
}
|
|
4444
|
+
if (biddingType === OpenAiAdsBiddingTypes.clicks && (!Array.isArray(conversionIds) || conversionIds.length === 0)) {
|
|
4445
|
+
throw new OpenAiAdsApiError(
|
|
4446
|
+
"Click campaigns require at least one conversion_event_setting_id",
|
|
4447
|
+
400
|
|
4448
|
+
);
|
|
4449
|
+
}
|
|
4450
|
+
}
|
|
4373
4451
|
function validateBiddingConfig(value) {
|
|
4374
4452
|
validateRequestObject(value, "Ad group bidding_config");
|
|
4375
|
-
if (value.billing_event_type !== OpenAiAdsBillingEventTypes.impression) {
|
|
4376
|
-
throw new OpenAiAdsApiError("Ad group billing_event_type must be impression", 400);
|
|
4453
|
+
if (value.billing_event_type !== OpenAiAdsBillingEventTypes.impression && value.billing_event_type !== OpenAiAdsBillingEventTypes.click) {
|
|
4454
|
+
throw new OpenAiAdsApiError("Ad group billing_event_type must be impression or click", 400);
|
|
4377
4455
|
}
|
|
4378
4456
|
const maxBid = value.max_bid_micros;
|
|
4379
4457
|
if (!Number.isInteger(maxBid) || maxBid < MIN_BID_MICROS || maxBid > MAX_BID_MICROS) {
|
|
@@ -4426,6 +4504,7 @@ function validateCreateCampaignRequest(request) {
|
|
|
4426
4504
|
validateCampaignBudget(request.budget);
|
|
4427
4505
|
validateCampaignTimestamp(request.start_time, "Campaign start_time");
|
|
4428
4506
|
validateCampaignTimestamp(request.end_time, "Campaign end_time");
|
|
4507
|
+
validateCampaignBidding(request);
|
|
4429
4508
|
validateCampaignTargeting(request.targeting);
|
|
4430
4509
|
}
|
|
4431
4510
|
function validateUpdateCampaignRequest(request) {
|
|
@@ -4526,7 +4605,11 @@ async function fetchAllPages(apiKey, path10, queryPairs) {
|
|
|
4526
4605
|
after = response.last_id;
|
|
4527
4606
|
}
|
|
4528
4607
|
adsClientLog("error", "pagination.cap-reached", { path: path10, pages: OPENAI_ADS_MAX_PAGES, items: items.length });
|
|
4529
|
-
|
|
4608
|
+
throw new OpenAiAdsApiError(
|
|
4609
|
+
`OpenAI Ads API collection remained incomplete after the ${OPENAI_ADS_MAX_PAGES}-page safety cap`,
|
|
4610
|
+
502,
|
|
4611
|
+
"pagination_limit_exceeded"
|
|
4612
|
+
);
|
|
4530
4613
|
}
|
|
4531
4614
|
function insightsPairs(opts) {
|
|
4532
4615
|
return (opts?.fields ?? []).map((field) => `fields[]=${encodeURIComponent(field)}`);
|
|
@@ -4535,6 +4618,22 @@ async function getAdAccount(apiKey) {
|
|
|
4535
4618
|
validateApiKey(apiKey);
|
|
4536
4619
|
return adsFetch(apiKey, "ad_account");
|
|
4537
4620
|
}
|
|
4621
|
+
async function searchGeoLocations(apiKey, query, limit) {
|
|
4622
|
+
validateApiKey(apiKey);
|
|
4623
|
+
validateId(query, "Geo search query");
|
|
4624
|
+
validateGeoSearchLimit(limit);
|
|
4625
|
+
const queryPairs = [`q=${encodeURIComponent(query)}`];
|
|
4626
|
+
if (limit !== void 0) queryPairs.push(`limit=${limit}`);
|
|
4627
|
+
return adsFetch(apiKey, "geo_lookup/search", queryPairs);
|
|
4628
|
+
}
|
|
4629
|
+
async function listConversionPixels(apiKey) {
|
|
4630
|
+
validateApiKey(apiKey);
|
|
4631
|
+
return fetchAllPages(apiKey, "conversions/pixels", []);
|
|
4632
|
+
}
|
|
4633
|
+
async function listConversionEventSettings(apiKey) {
|
|
4634
|
+
validateApiKey(apiKey);
|
|
4635
|
+
return fetchAllPages(apiKey, "conversions/event_settings", []);
|
|
4636
|
+
}
|
|
4538
4637
|
async function listCampaigns(apiKey) {
|
|
4539
4638
|
validateApiKey(apiKey);
|
|
4540
4639
|
return fetchAllPages(apiKey, "campaigns", []);
|
|
@@ -4557,6 +4656,11 @@ async function updateCampaign(apiKey, campaignId, request) {
|
|
|
4557
4656
|
validateUpdateCampaignRequest(outbound);
|
|
4558
4657
|
return adsFetch(apiKey, `campaigns/${encodeURIComponent(campaignId)}`, [], "POST", outbound);
|
|
4559
4658
|
}
|
|
4659
|
+
async function activateCampaign(apiKey, campaignId) {
|
|
4660
|
+
validateApiKey(apiKey);
|
|
4661
|
+
validateId(campaignId, "Campaign id");
|
|
4662
|
+
return adsFetch(apiKey, `campaigns/${encodeURIComponent(campaignId)}/activate`, [], "POST");
|
|
4663
|
+
}
|
|
4560
4664
|
async function pauseCampaign(apiKey, campaignId) {
|
|
4561
4665
|
validateApiKey(apiKey);
|
|
4562
4666
|
validateId(campaignId, "Campaign id");
|
|
@@ -4585,6 +4689,11 @@ async function updateAdGroup(apiKey, adGroupId, request) {
|
|
|
4585
4689
|
validateUpdateAdGroupRequest(outbound);
|
|
4586
4690
|
return adsFetch(apiKey, `ad_groups/${encodeURIComponent(adGroupId)}`, [], "POST", outbound);
|
|
4587
4691
|
}
|
|
4692
|
+
async function activateAdGroup(apiKey, adGroupId) {
|
|
4693
|
+
validateApiKey(apiKey);
|
|
4694
|
+
validateId(adGroupId, "Ad group id");
|
|
4695
|
+
return adsFetch(apiKey, `ad_groups/${encodeURIComponent(adGroupId)}/activate`, [], "POST");
|
|
4696
|
+
}
|
|
4588
4697
|
async function pauseAdGroup(apiKey, adGroupId) {
|
|
4589
4698
|
validateApiKey(apiKey);
|
|
4590
4699
|
validateId(adGroupId, "Ad group id");
|
|
@@ -4613,6 +4722,11 @@ async function updateAd(apiKey, adId, request) {
|
|
|
4613
4722
|
validateUpdateAdRequest(outbound);
|
|
4614
4723
|
return adsFetch(apiKey, `ads/${encodeURIComponent(adId)}`, [], "POST", outbound);
|
|
4615
4724
|
}
|
|
4725
|
+
async function activateAd(apiKey, adId) {
|
|
4726
|
+
validateApiKey(apiKey);
|
|
4727
|
+
validateId(adId, "Ad id");
|
|
4728
|
+
return adsFetch(apiKey, `ads/${encodeURIComponent(adId)}/activate`, [], "POST");
|
|
4729
|
+
}
|
|
4616
4730
|
async function pauseAd(apiKey, adId) {
|
|
4617
4731
|
validateApiKey(apiKey);
|
|
4618
4732
|
validateId(adId, "Ad id");
|
|
@@ -4762,6 +4876,7 @@ async function executeAdsSync(db, runId, projectId, opts) {
|
|
|
4762
4876
|
biddingType: campaign.bidding_type,
|
|
4763
4877
|
dailySpendLimitMicros: campaign.budget?.daily_spend_limit_micros ?? null,
|
|
4764
4878
|
lifetimeSpendLimitMicros: campaign.budget?.lifetime_spend_limit_micros ?? null,
|
|
4879
|
+
conversionEventSettingIds: campaign.conversion_event_setting_ids ?? [],
|
|
4765
4880
|
targeting: campaign.targeting,
|
|
4766
4881
|
upstreamCreatedAt: campaign.created_at,
|
|
4767
4882
|
upstreamUpdatedAt: campaign.updated_at,
|
|
@@ -4824,6 +4939,9 @@ async function executeAdsSync(db, runId, projectId, opts) {
|
|
|
4824
4939
|
currencyCode: account.currency_code,
|
|
4825
4940
|
timezone: account.timezone,
|
|
4826
4941
|
status: account.status,
|
|
4942
|
+
reviewStatus: account.review?.status ?? null,
|
|
4943
|
+
integrityReviewStatus: account.account_integrity_review?.review?.status ?? null,
|
|
4944
|
+
integrityDecision: account.account_integrity_review?.details?.decision ?? null,
|
|
4827
4945
|
conversionTrackingConfigured,
|
|
4828
4946
|
lastSyncedAt: insertNow,
|
|
4829
4947
|
updatedAt: insertNow
|
|
@@ -6783,7 +6901,7 @@ function readStoredGroundingSources(rawResponse) {
|
|
|
6783
6901
|
return result;
|
|
6784
6902
|
}
|
|
6785
6903
|
async function backfillInsightsCommand(project, opts) {
|
|
6786
|
-
const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-
|
|
6904
|
+
const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-K35EN43I.js");
|
|
6787
6905
|
const config = loadConfig();
|
|
6788
6906
|
const db = createClient(config.database);
|
|
6789
6907
|
migrate(db);
|
|
@@ -8870,14 +8988,22 @@ var AERO_ADS_OPERATOR_MCP_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
|
8870
8988
|
CanonryMcpToolNames.canonry_memory_forget,
|
|
8871
8989
|
CanonryMcpToolNames.canonry_run_trigger,
|
|
8872
8990
|
CanonryMcpToolNames.canonry_ads_status,
|
|
8991
|
+
CanonryMcpToolNames.canonry_ads_account,
|
|
8992
|
+
CanonryMcpToolNames.canonry_ads_geo_search,
|
|
8993
|
+
CanonryMcpToolNames.canonry_ads_conversion_pixels,
|
|
8994
|
+
CanonryMcpToolNames.canonry_ads_conversion_event_settings,
|
|
8873
8995
|
CanonryMcpToolNames.canonry_ads_campaigns,
|
|
8874
8996
|
CanonryMcpToolNames.canonry_ads_insights,
|
|
8875
8997
|
CanonryMcpToolNames.canonry_ads_summary,
|
|
8998
|
+
CanonryMcpToolNames.canonry_ads_operations_unresolved,
|
|
8876
8999
|
CanonryMcpToolNames.canonry_ads_operation_get,
|
|
9000
|
+
CanonryMcpToolNames.canonry_ads_operation_reconcile,
|
|
9001
|
+
CanonryMcpToolNames.canonry_ads_operation_resume_activation,
|
|
8877
9002
|
CanonryMcpToolNames.canonry_ads_image_upload,
|
|
8878
9003
|
CanonryMcpToolNames.canonry_ads_campaign_create,
|
|
8879
9004
|
CanonryMcpToolNames.canonry_ads_campaign_update,
|
|
8880
9005
|
CanonryMcpToolNames.canonry_ads_campaign_pause,
|
|
9006
|
+
CanonryMcpToolNames.canonry_ads_campaign_activate_tree,
|
|
8881
9007
|
CanonryMcpToolNames.canonry_ads_ad_group_create,
|
|
8882
9008
|
CanonryMcpToolNames.canonry_ads_ad_group_update,
|
|
8883
9009
|
CanonryMcpToolNames.canonry_ads_ad_group_pause,
|
|
@@ -11652,38 +11778,130 @@ async function createServer(opts) {
|
|
|
11652
11778
|
return removed;
|
|
11653
11779
|
}
|
|
11654
11780
|
};
|
|
11781
|
+
const normalizeAdsAccount = (account) => adsAccountDtoSchema.parse({
|
|
11782
|
+
id: account.id,
|
|
11783
|
+
name: account.name,
|
|
11784
|
+
status: account.status,
|
|
11785
|
+
currencyCode: account.currency_code ?? null,
|
|
11786
|
+
timezone: account.timezone ?? null,
|
|
11787
|
+
url: account.url ?? null,
|
|
11788
|
+
reviewStatus: account.review?.status ?? null,
|
|
11789
|
+
integrityReviewStatus: account.account_integrity_review?.review?.status ?? null,
|
|
11790
|
+
integrityDecision: account.account_integrity_review?.details?.decision ?? null
|
|
11791
|
+
});
|
|
11655
11792
|
const verifyAdsAccount = async (apiKey) => {
|
|
11656
|
-
const account = await getAdAccount(apiKey);
|
|
11793
|
+
const account = normalizeAdsAccount(await getAdAccount(apiKey));
|
|
11657
11794
|
return {
|
|
11658
11795
|
id: account.id,
|
|
11659
11796
|
name: account.name,
|
|
11660
11797
|
status: account.status,
|
|
11661
|
-
currencyCode: account.
|
|
11662
|
-
timezone: account.timezone
|
|
11798
|
+
currencyCode: account.currencyCode,
|
|
11799
|
+
timezone: account.timezone,
|
|
11800
|
+
reviewStatus: account.reviewStatus,
|
|
11801
|
+
integrityReviewStatus: account.integrityReviewStatus,
|
|
11802
|
+
integrityDecision: account.integrityDecision
|
|
11663
11803
|
};
|
|
11664
11804
|
};
|
|
11805
|
+
const adsReader = {
|
|
11806
|
+
getAccount: async (apiKey) => normalizeAdsAccount(await getAdAccount(apiKey)),
|
|
11807
|
+
searchGeo: async (apiKey, input) => {
|
|
11808
|
+
const response = await searchGeoLocations(apiKey, input.q, input.limit);
|
|
11809
|
+
return adsGeoSearchResponseSchema.parse({
|
|
11810
|
+
count: response.count,
|
|
11811
|
+
query: response.query,
|
|
11812
|
+
results: response.results.map((location) => ({
|
|
11813
|
+
id: location.id,
|
|
11814
|
+
type: location.type,
|
|
11815
|
+
canonicalName: location.canonical_name,
|
|
11816
|
+
countryCode: location.country_code,
|
|
11817
|
+
name: location.name,
|
|
11818
|
+
regionCode: location.region_code
|
|
11819
|
+
}))
|
|
11820
|
+
});
|
|
11821
|
+
},
|
|
11822
|
+
listConversionPixels: async (apiKey) => {
|
|
11823
|
+
const pixels = await listConversionPixels(apiKey);
|
|
11824
|
+
return adsConversionPixelListResponseSchema.parse({
|
|
11825
|
+
pixels: pixels.map((pixel) => ({
|
|
11826
|
+
id: pixel.id,
|
|
11827
|
+
clientType: pixel.client_type,
|
|
11828
|
+
name: pixel.name,
|
|
11829
|
+
pixelId: pixel.pixel_id
|
|
11830
|
+
}))
|
|
11831
|
+
});
|
|
11832
|
+
},
|
|
11833
|
+
listConversionEventSettings: async (apiKey) => {
|
|
11834
|
+
const eventSettings = await listConversionEventSettings(apiKey);
|
|
11835
|
+
return adsConversionEventSettingListResponseSchema.parse({
|
|
11836
|
+
eventSettings: eventSettings.map((eventSetting) => ({
|
|
11837
|
+
id: eventSetting.id,
|
|
11838
|
+
name: eventSetting.name,
|
|
11839
|
+
eventType: eventSetting.event_type,
|
|
11840
|
+
customEventName: eventSetting.custom_event_name,
|
|
11841
|
+
attributionWindowDays: eventSetting.attribution_window_days,
|
|
11842
|
+
adAccountId: eventSetting.ad_account_id,
|
|
11843
|
+
sourceIds: eventSetting.source_ids,
|
|
11844
|
+
sources: eventSetting.sources,
|
|
11845
|
+
archived: eventSetting.archived,
|
|
11846
|
+
version: eventSetting.version
|
|
11847
|
+
}))
|
|
11848
|
+
});
|
|
11849
|
+
}
|
|
11850
|
+
};
|
|
11665
11851
|
const adsEntityResult = (entity) => ({
|
|
11666
11852
|
id: entity.id,
|
|
11853
|
+
name: entity.name,
|
|
11667
11854
|
status: entity.status,
|
|
11668
11855
|
updatedAt: entity.updated_at,
|
|
11669
|
-
reviewStatus: entity.review_status ?? null
|
|
11856
|
+
reviewStatus: entity.review_status ?? null,
|
|
11857
|
+
creative: typeof entity.creative?.title === "string" && typeof entity.creative.body === "string" && typeof entity.creative.target_url === "string" && typeof entity.creative.file_id === "string" ? {
|
|
11858
|
+
title: entity.creative.title,
|
|
11859
|
+
body: entity.creative.body,
|
|
11860
|
+
targetUrl: entity.creative.target_url,
|
|
11861
|
+
fileId: entity.creative.file_id
|
|
11862
|
+
} : null
|
|
11863
|
+
});
|
|
11864
|
+
const adsCampaignEntityResult = (entity) => ({
|
|
11865
|
+
...adsEntityResult(entity),
|
|
11866
|
+
description: entity.description,
|
|
11867
|
+
startTime: entity.start_time,
|
|
11868
|
+
endTime: entity.end_time,
|
|
11869
|
+
lifetimeSpendLimitMicros: entity.budget?.lifetime_spend_limit_micros ?? null,
|
|
11870
|
+
locationIds: entity.targeting?.locations?.include?.map((location) => location.id) ?? [],
|
|
11871
|
+
biddingType: entity.bidding_type,
|
|
11872
|
+
conversionEventSettingIds: entity.conversion_event_setting_ids
|
|
11873
|
+
});
|
|
11874
|
+
const adsAdGroupEntityResult = (entity, campaignId) => ({
|
|
11875
|
+
...adsEntityResult(entity),
|
|
11876
|
+
description: entity.description,
|
|
11877
|
+
campaignId: campaignId ?? null,
|
|
11878
|
+
contextHints: entity.context_hints,
|
|
11879
|
+
maxBidMicros: entity.bidding_config?.max_bid_micros ?? null,
|
|
11880
|
+
billingEventType: entity.bidding_config?.billing_event_type ?? null
|
|
11881
|
+
});
|
|
11882
|
+
const adsAdEntityResult = (entity, adGroupId) => ({
|
|
11883
|
+
...adsEntityResult(entity),
|
|
11884
|
+
adGroupId: adGroupId ?? null
|
|
11670
11885
|
});
|
|
11671
11886
|
const adsOperator = {
|
|
11672
11887
|
uploadImage: async (apiKey, imageUrl) => {
|
|
11673
11888
|
const result = await uploadImageFromUrl(apiKey, imageUrl);
|
|
11674
11889
|
return { fileId: result.file_id };
|
|
11675
11890
|
},
|
|
11676
|
-
getCampaign: async (apiKey, id) =>
|
|
11677
|
-
|
|
11891
|
+
getCampaign: async (apiKey, id) => adsCampaignEntityResult(await getCampaign(apiKey, id)),
|
|
11892
|
+
listCampaigns: async (apiKey) => (await listCampaigns(apiKey)).map(adsCampaignEntityResult),
|
|
11893
|
+
createCampaign: async (apiKey, input) => adsCampaignEntityResult(await createCampaign(apiKey, {
|
|
11678
11894
|
name: input.name,
|
|
11679
11895
|
description: input.description,
|
|
11680
11896
|
start_time: input.startTime,
|
|
11681
11897
|
end_time: input.endTime,
|
|
11682
11898
|
status: OpenAiAdsWriteStatuses.paused,
|
|
11683
11899
|
budget: { lifetime_spend_limit_micros: input.lifetimeSpendLimitMicros },
|
|
11900
|
+
bidding_type: input.biddingType,
|
|
11901
|
+
conversion_event_setting_ids: input.conversionEventSettingIds,
|
|
11684
11902
|
targeting: { locations: { include: input.locationIds.map((id) => ({ id })) } }
|
|
11685
11903
|
})),
|
|
11686
|
-
updateCampaign: async (apiKey, id, input) =>
|
|
11904
|
+
updateCampaign: async (apiKey, id, input) => adsCampaignEntityResult(await updateCampaign(apiKey, id, {
|
|
11687
11905
|
name: input.name,
|
|
11688
11906
|
description: input.description,
|
|
11689
11907
|
start_time: input.startTime,
|
|
@@ -11691,31 +11909,44 @@ async function createServer(opts) {
|
|
|
11691
11909
|
budget: input.lifetimeSpendLimitMicros === void 0 ? void 0 : { lifetime_spend_limit_micros: input.lifetimeSpendLimitMicros },
|
|
11692
11910
|
targeting: input.locationIds === void 0 ? void 0 : { locations: { include: input.locationIds.map((locationId) => ({ id: locationId })) } }
|
|
11693
11911
|
})),
|
|
11694
|
-
|
|
11695
|
-
|
|
11696
|
-
|
|
11912
|
+
activateCampaign: async (apiKey, id) => adsCampaignEntityResult(await activateCampaign(apiKey, id)),
|
|
11913
|
+
pauseCampaign: async (apiKey, id) => adsCampaignEntityResult(await pauseCampaign(apiKey, id)),
|
|
11914
|
+
getAdGroup: async (apiKey, id) => adsAdGroupEntityResult(await getAdGroup(apiKey, id)),
|
|
11915
|
+
listAdGroups: async (apiKey, campaignId) => (await listAdGroups(apiKey, campaignId)).map((entity) => adsAdGroupEntityResult(entity, campaignId)),
|
|
11916
|
+
createAdGroup: async (apiKey, input) => adsAdGroupEntityResult(await createAdGroup(apiKey, {
|
|
11697
11917
|
campaign_id: input.campaignId,
|
|
11698
11918
|
name: input.name,
|
|
11699
11919
|
description: input.description,
|
|
11700
11920
|
context_hints: input.contextHints,
|
|
11701
11921
|
status: OpenAiAdsWriteStatuses.paused,
|
|
11702
11922
|
bidding_config: {
|
|
11703
|
-
billing_event_type:
|
|
11923
|
+
billing_event_type: input.billingEventType,
|
|
11704
11924
|
max_bid_micros: input.maxBidMicros
|
|
11705
11925
|
}
|
|
11706
11926
|
})),
|
|
11707
|
-
updateAdGroup: async (apiKey, id, input) =>
|
|
11708
|
-
|
|
11709
|
-
|
|
11710
|
-
|
|
11711
|
-
|
|
11712
|
-
|
|
11713
|
-
|
|
11927
|
+
updateAdGroup: async (apiKey, id, input) => {
|
|
11928
|
+
let biddingConfig;
|
|
11929
|
+
if (input.maxBidMicros !== void 0) {
|
|
11930
|
+
if (input.billingEventType === void 0) {
|
|
11931
|
+
throw new Error("Ad group max-bid updates require the current billing event type");
|
|
11932
|
+
}
|
|
11933
|
+
biddingConfig = {
|
|
11934
|
+
billing_event_type: input.billingEventType,
|
|
11935
|
+
max_bid_micros: input.maxBidMicros
|
|
11936
|
+
};
|
|
11714
11937
|
}
|
|
11715
|
-
|
|
11716
|
-
|
|
11717
|
-
|
|
11718
|
-
|
|
11938
|
+
return adsAdGroupEntityResult(await updateAdGroup(apiKey, id, {
|
|
11939
|
+
name: input.name,
|
|
11940
|
+
description: input.description,
|
|
11941
|
+
context_hints: input.contextHints,
|
|
11942
|
+
bidding_config: biddingConfig
|
|
11943
|
+
}));
|
|
11944
|
+
},
|
|
11945
|
+
activateAdGroup: async (apiKey, id) => adsAdGroupEntityResult(await activateAdGroup(apiKey, id)),
|
|
11946
|
+
pauseAdGroup: async (apiKey, id) => adsAdGroupEntityResult(await pauseAdGroup(apiKey, id)),
|
|
11947
|
+
getAd: async (apiKey, id) => adsAdEntityResult(await getAd(apiKey, id)),
|
|
11948
|
+
listAds: async (apiKey, adGroupId) => (await listAds(apiKey, adGroupId)).map((entity) => adsAdEntityResult(entity, adGroupId)),
|
|
11949
|
+
createAd: async (apiKey, input) => adsAdEntityResult(await createAd(apiKey, {
|
|
11719
11950
|
ad_group_id: input.adGroupId,
|
|
11720
11951
|
name: input.name,
|
|
11721
11952
|
status: OpenAiAdsWriteStatuses.paused,
|
|
@@ -11727,7 +11958,7 @@ async function createServer(opts) {
|
|
|
11727
11958
|
file_id: input.creative.fileId
|
|
11728
11959
|
}
|
|
11729
11960
|
})),
|
|
11730
|
-
updateAd: async (apiKey, id, input) =>
|
|
11961
|
+
updateAd: async (apiKey, id, input) => adsAdEntityResult(await updateAd(apiKey, id, {
|
|
11731
11962
|
name: input.name,
|
|
11732
11963
|
creative: input.creative ? {
|
|
11733
11964
|
type: OpenAiAdsCreativeTypes.chatCard,
|
|
@@ -11737,7 +11968,8 @@ async function createServer(opts) {
|
|
|
11737
11968
|
file_id: input.creative.fileId
|
|
11738
11969
|
} : void 0
|
|
11739
11970
|
})),
|
|
11740
|
-
|
|
11971
|
+
activateAd: async (apiKey, id) => adsAdEntityResult(await activateAd(apiKey, id)),
|
|
11972
|
+
pauseAd: async (apiKey, id) => adsAdEntityResult(await pauseAd(apiKey, id))
|
|
11741
11973
|
};
|
|
11742
11974
|
const scheduler = new Scheduler(opts.db, {
|
|
11743
11975
|
onRunCreated: (runId, projectId, providers2, location) => {
|
|
@@ -12331,6 +12563,7 @@ async function createServer(opts) {
|
|
|
12331
12563
|
},
|
|
12332
12564
|
adsCredentialStore,
|
|
12333
12565
|
verifyAdsAccount,
|
|
12566
|
+
adsReader,
|
|
12334
12567
|
adsOperator,
|
|
12335
12568
|
onAdsSyncRequested: (runId, projectId) => {
|
|
12336
12569
|
runAdsSync(runId, projectId);
|
|
@@ -12475,6 +12708,9 @@ async function createServer(opts) {
|
|
|
12475
12708
|
name: a.name,
|
|
12476
12709
|
displayName: a.displayName,
|
|
12477
12710
|
mode: a.mode,
|
|
12711
|
+
modelConfigurable: a.mode === "api",
|
|
12712
|
+
defaultModel: a.modelRegistry.defaultModel,
|
|
12713
|
+
knownModels: a.modelRegistry.knownModels,
|
|
12478
12714
|
modelValidationPattern: a.modelRegistry.validationPattern,
|
|
12479
12715
|
modelValidationHint: a.modelRegistry.validationHint
|
|
12480
12716
|
})),
|