@canonry/canonry 4.117.2 → 4.118.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/assets/agent-workspace/skills/canonry/references/canonry-cli.md +53 -1
- package/assets/assets/AuditHistoryPanel-Yh7VEe4P.js +1 -0
- package/assets/assets/{BacklinksPage-CschVQxC.js → BacklinksPage-BmO77kMs.js} +1 -1
- package/assets/assets/{ChartPrimitives-D4782Ifx.js → ChartPrimitives-H0ICVpw_.js} +1 -1
- package/assets/assets/HistoryPage-DkLV_iRc.js +1 -0
- package/assets/assets/ProjectPage-R3odr_eA.js +7 -0
- package/assets/assets/{RunRow-ggNGlwdN.js → RunRow-BDH9agxQ.js} +1 -1
- package/assets/assets/RunsPage-D9YsEeT3.js +1 -0
- package/assets/assets/{SettingsPage-Cy9SlBJX.js → SettingsPage-o5as3Ixw.js} +1 -1
- package/assets/assets/{TrafficPage-1S2PzSHB.js → TrafficPage-BCK203aQ.js} +1 -1
- package/assets/assets/{TrafficSourceDetailPage-CqXCoaod.js → TrafficSourceDetailPage-DsVMAZvS.js} +1 -1
- package/assets/assets/{arrow-left-kCK5M8Bp.js → arrow-left-B7ZR6VC9.js} +1 -1
- package/assets/assets/{extract-error-message-C82LAW6q.js → extract-error-message-DeYDUpew.js} +1 -1
- package/assets/assets/index-Bot6YiD6.css +1 -0
- package/assets/assets/index-QCFQv0xh.js +210 -0
- package/assets/assets/{trash-2-8Pe4v1T0.js → trash-2-xxHTqWbF.js} +1 -1
- package/assets/index.html +2 -2
- package/dist/{chunk-4PMMEFME.js → chunk-75UBTCKS.js} +499 -16
- package/dist/{chunk-BMPIV35C.js → chunk-CMZIPFNQ.js} +937 -104
- package/dist/{chunk-F2SRZJMY.js → chunk-HGNY5GL4.js} +384 -15
- package/dist/{chunk-EZME2J2G.js → chunk-KEZWLP4O.js} +1196 -1012
- package/dist/cli.js +319 -86
- package/dist/index.js +4 -4
- package/dist/{intelligence-service-GNOE4J35.js → intelligence-service-FWPXMAVK.js} +2 -2
- package/dist/mcp.js +2 -2
- package/package.json +8 -8
- package/assets/assets/ProjectPage-BSGTpBUJ.js +0 -7
- package/assets/assets/RunsPage-Bfp0K6Ry.js +0 -1
- package/assets/assets/index-DrDNyUhv.css +0 -1
- package/assets/assets/index-i-t64RXw.js +0 -210
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
loadConfig,
|
|
11
11
|
loadConfigRaw,
|
|
12
12
|
saveConfigPatch
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-75UBTCKS.js";
|
|
14
14
|
import {
|
|
15
15
|
CC_CACHE_DIR,
|
|
16
16
|
DUCKDB_SPEC,
|
|
@@ -115,7 +115,7 @@ import {
|
|
|
115
115
|
siteAuditPages,
|
|
116
116
|
siteAuditSnapshots,
|
|
117
117
|
usageCounters
|
|
118
|
-
} from "./chunk-
|
|
118
|
+
} from "./chunk-CMZIPFNQ.js";
|
|
119
119
|
import {
|
|
120
120
|
AGENT_MEMORY_VALUE_MAX_BYTES,
|
|
121
121
|
AGENT_PROVIDER_IDS,
|
|
@@ -178,7 +178,7 @@ import {
|
|
|
178
178
|
validationError,
|
|
179
179
|
winnabilityClassLabel,
|
|
180
180
|
withRetry
|
|
181
|
-
} from "./chunk-
|
|
181
|
+
} from "./chunk-KEZWLP4O.js";
|
|
182
182
|
|
|
183
183
|
// src/telemetry.ts
|
|
184
184
|
import crypto from "crypto";
|
|
@@ -4241,6 +4241,16 @@ var OPENAI_ADS_REQUEST_TIMEOUT_MS = 3e4;
|
|
|
4241
4241
|
var OPENAI_ADS_MAX_PAGES = 100;
|
|
4242
4242
|
|
|
4243
4243
|
// ../integration-openai-ads/src/types.ts
|
|
4244
|
+
var OpenAiAdsWriteStatuses = {
|
|
4245
|
+
active: "active",
|
|
4246
|
+
paused: "paused"
|
|
4247
|
+
};
|
|
4248
|
+
var OpenAiAdsBillingEventTypes = {
|
|
4249
|
+
impression: "impression"
|
|
4250
|
+
};
|
|
4251
|
+
var OpenAiAdsCreativeTypes = {
|
|
4252
|
+
chatCard: "chat_card"
|
|
4253
|
+
};
|
|
4244
4254
|
var OpenAiAdsApiError = class extends Error {
|
|
4245
4255
|
status;
|
|
4246
4256
|
code;
|
|
@@ -4264,6 +4274,16 @@ function parseErrorEnvelope(body) {
|
|
|
4264
4274
|
}
|
|
4265
4275
|
|
|
4266
4276
|
// ../integration-openai-ads/src/ads-client.ts
|
|
4277
|
+
var MIN_ENTITY_NAME_LENGTH = 3;
|
|
4278
|
+
var MAX_ENTITY_NAME_LENGTH = 1e3;
|
|
4279
|
+
var MIN_CAMPAIGN_TIMESTAMP = 946684800;
|
|
4280
|
+
var MAX_CAMPAIGN_TIMESTAMP = 4102444800;
|
|
4281
|
+
var MIN_LIFETIME_BUDGET_MICROS = 1e6;
|
|
4282
|
+
var MIN_BID_MICROS = 1;
|
|
4283
|
+
var MAX_BID_MICROS = 1e8;
|
|
4284
|
+
var MIN_AD_TITLE_LENGTH = 3;
|
|
4285
|
+
var MAX_AD_TITLE_LENGTH = 50;
|
|
4286
|
+
var MAX_AD_BODY_LENGTH = 100;
|
|
4267
4287
|
function validateApiKey(apiKey) {
|
|
4268
4288
|
if (!apiKey || typeof apiKey !== "string" || apiKey.trim().length === 0) {
|
|
4269
4289
|
throw new OpenAiAdsApiError("API key is required and must be a non-empty string", 400);
|
|
@@ -4274,6 +4294,174 @@ function validateId(value, label) {
|
|
|
4274
4294
|
throw new OpenAiAdsApiError(`${label} is required and must be a non-empty string`, 400);
|
|
4275
4295
|
}
|
|
4276
4296
|
}
|
|
4297
|
+
function isRecord(value) {
|
|
4298
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4299
|
+
}
|
|
4300
|
+
function validateRequestObject(value, label) {
|
|
4301
|
+
if (!isRecord(value)) {
|
|
4302
|
+
throw new OpenAiAdsApiError(`${label} must be a JSON object`, 400);
|
|
4303
|
+
}
|
|
4304
|
+
}
|
|
4305
|
+
function validateNonEmptyRequest(value, label) {
|
|
4306
|
+
validateRequestObject(value, label);
|
|
4307
|
+
if (Object.keys(value).length === 0) {
|
|
4308
|
+
throw new OpenAiAdsApiError(`${label} must include at least one field`, 400);
|
|
4309
|
+
}
|
|
4310
|
+
}
|
|
4311
|
+
function snapshotJsonRequest(value, label) {
|
|
4312
|
+
try {
|
|
4313
|
+
const serialized = JSON.stringify(value);
|
|
4314
|
+
return JSON.parse(serialized);
|
|
4315
|
+
} catch {
|
|
4316
|
+
throw new OpenAiAdsApiError(`${label} must be JSON-serializable`, 400);
|
|
4317
|
+
}
|
|
4318
|
+
}
|
|
4319
|
+
function validateEntityName(value, label) {
|
|
4320
|
+
if (typeof value !== "string" || value.trim().length < MIN_ENTITY_NAME_LENGTH || value.length > MAX_ENTITY_NAME_LENGTH) {
|
|
4321
|
+
throw new OpenAiAdsApiError(
|
|
4322
|
+
`${label} must be ${MIN_ENTITY_NAME_LENGTH}-${MAX_ENTITY_NAME_LENGTH} characters and include a non-space character`,
|
|
4323
|
+
400
|
|
4324
|
+
);
|
|
4325
|
+
}
|
|
4326
|
+
}
|
|
4327
|
+
function validatePausedCreateStatus(value, label) {
|
|
4328
|
+
if (value !== OpenAiAdsWriteStatuses.paused) {
|
|
4329
|
+
throw new OpenAiAdsApiError(`${label} status must be paused`, 400);
|
|
4330
|
+
}
|
|
4331
|
+
}
|
|
4332
|
+
function validatePublicUpdateRequest(value, label) {
|
|
4333
|
+
validateNonEmptyRequest(value, label);
|
|
4334
|
+
if (Object.hasOwn(value, "status")) {
|
|
4335
|
+
throw new OpenAiAdsApiError(`${label} cannot include status; use an explicit lifecycle action`, 400);
|
|
4336
|
+
}
|
|
4337
|
+
}
|
|
4338
|
+
function validateCampaignTimestamp(value, label) {
|
|
4339
|
+
if (value === void 0 || value === null) return;
|
|
4340
|
+
if (!Number.isInteger(value) || value < MIN_CAMPAIGN_TIMESTAMP || value > MAX_CAMPAIGN_TIMESTAMP) {
|
|
4341
|
+
throw new OpenAiAdsApiError(
|
|
4342
|
+
`${label} must be a Unix timestamp between ${MIN_CAMPAIGN_TIMESTAMP} and ${MAX_CAMPAIGN_TIMESTAMP}`,
|
|
4343
|
+
400
|
|
4344
|
+
);
|
|
4345
|
+
}
|
|
4346
|
+
}
|
|
4347
|
+
function validateCampaignBudget(value) {
|
|
4348
|
+
validateRequestObject(value, "Campaign budget");
|
|
4349
|
+
const limit = value.lifetime_spend_limit_micros;
|
|
4350
|
+
if (!Number.isInteger(limit) || limit < MIN_LIFETIME_BUDGET_MICROS) {
|
|
4351
|
+
throw new OpenAiAdsApiError(
|
|
4352
|
+
`Campaign budget lifetime_spend_limit_micros must be an integer of at least ${MIN_LIFETIME_BUDGET_MICROS}`,
|
|
4353
|
+
400
|
|
4354
|
+
);
|
|
4355
|
+
}
|
|
4356
|
+
}
|
|
4357
|
+
function validateCampaignTargeting(value) {
|
|
4358
|
+
if (value === void 0) return;
|
|
4359
|
+
if (value === null) {
|
|
4360
|
+
throw new OpenAiAdsApiError("Campaign targeting cannot be null; omit it to preserve existing targeting", 400);
|
|
4361
|
+
}
|
|
4362
|
+
validateRequestObject(value, "Campaign targeting");
|
|
4363
|
+
validateRequestObject(value.locations, "Campaign targeting locations");
|
|
4364
|
+
const include = value.locations.include;
|
|
4365
|
+
if (!Array.isArray(include) || include.length === 0) {
|
|
4366
|
+
throw new OpenAiAdsApiError("Campaign targeting locations include must be a non-empty array", 400);
|
|
4367
|
+
}
|
|
4368
|
+
for (const target of include) {
|
|
4369
|
+
validateRequestObject(target, "Campaign location target");
|
|
4370
|
+
validateId(target.id, "Campaign location id");
|
|
4371
|
+
}
|
|
4372
|
+
}
|
|
4373
|
+
function validateBiddingConfig(value) {
|
|
4374
|
+
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);
|
|
4377
|
+
}
|
|
4378
|
+
const maxBid = value.max_bid_micros;
|
|
4379
|
+
if (!Number.isInteger(maxBid) || maxBid < MIN_BID_MICROS || maxBid > MAX_BID_MICROS) {
|
|
4380
|
+
throw new OpenAiAdsApiError(
|
|
4381
|
+
`Ad group max_bid_micros must be an integer between ${MIN_BID_MICROS} and ${MAX_BID_MICROS}`,
|
|
4382
|
+
400
|
|
4383
|
+
);
|
|
4384
|
+
}
|
|
4385
|
+
}
|
|
4386
|
+
function validateContextHints(value) {
|
|
4387
|
+
if (value === void 0) return;
|
|
4388
|
+
if (!Array.isArray(value) || value.some((hint) => typeof hint !== "string" || hint.trim().length === 0)) {
|
|
4389
|
+
throw new OpenAiAdsApiError("Ad group context_hints must be an array of non-empty strings", 400);
|
|
4390
|
+
}
|
|
4391
|
+
}
|
|
4392
|
+
function validateHttpUrl(value, label) {
|
|
4393
|
+
if (typeof value !== "string" || value.trim().length === 0) {
|
|
4394
|
+
throw new OpenAiAdsApiError(`${label} is required and must be a non-empty URL`, 400);
|
|
4395
|
+
}
|
|
4396
|
+
try {
|
|
4397
|
+
const parsed = new URL(value);
|
|
4398
|
+
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
|
|
4399
|
+
throw new Error("unsupported protocol");
|
|
4400
|
+
}
|
|
4401
|
+
} catch {
|
|
4402
|
+
throw new OpenAiAdsApiError(`${label} must be an absolute HTTP or HTTPS URL`, 400);
|
|
4403
|
+
}
|
|
4404
|
+
}
|
|
4405
|
+
function validateChatCardCreative(value) {
|
|
4406
|
+
validateRequestObject(value, "Ad creative");
|
|
4407
|
+
if (value.type !== OpenAiAdsCreativeTypes.chatCard) {
|
|
4408
|
+
throw new OpenAiAdsApiError("Ad creative type must be chat_card", 400);
|
|
4409
|
+
}
|
|
4410
|
+
if (typeof value.title !== "string" || value.title.trim().length < MIN_AD_TITLE_LENGTH || value.title.length > MAX_AD_TITLE_LENGTH) {
|
|
4411
|
+
throw new OpenAiAdsApiError(
|
|
4412
|
+
`Ad creative title must be ${MIN_AD_TITLE_LENGTH}-${MAX_AD_TITLE_LENGTH} characters`,
|
|
4413
|
+
400
|
|
4414
|
+
);
|
|
4415
|
+
}
|
|
4416
|
+
if (typeof value.body !== "string" || value.body.trim().length === 0 || value.body.length > MAX_AD_BODY_LENGTH) {
|
|
4417
|
+
throw new OpenAiAdsApiError(`Ad creative body must be 1-${MAX_AD_BODY_LENGTH} characters`, 400);
|
|
4418
|
+
}
|
|
4419
|
+
validateId(value.file_id, "Ad creative file id");
|
|
4420
|
+
validateHttpUrl(value.target_url, "Ad creative target URL");
|
|
4421
|
+
}
|
|
4422
|
+
function validateCreateCampaignRequest(request) {
|
|
4423
|
+
validateRequestObject(request, "Campaign create request");
|
|
4424
|
+
validateEntityName(request.name, "Campaign name");
|
|
4425
|
+
validatePausedCreateStatus(request.status, "Campaign create request");
|
|
4426
|
+
validateCampaignBudget(request.budget);
|
|
4427
|
+
validateCampaignTimestamp(request.start_time, "Campaign start_time");
|
|
4428
|
+
validateCampaignTimestamp(request.end_time, "Campaign end_time");
|
|
4429
|
+
validateCampaignTargeting(request.targeting);
|
|
4430
|
+
}
|
|
4431
|
+
function validateUpdateCampaignRequest(request) {
|
|
4432
|
+
validatePublicUpdateRequest(request, "Campaign update request");
|
|
4433
|
+
if (request.name !== void 0) validateEntityName(request.name, "Campaign name");
|
|
4434
|
+
if (request.budget !== void 0) validateCampaignBudget(request.budget);
|
|
4435
|
+
validateCampaignTimestamp(request.start_time, "Campaign start_time");
|
|
4436
|
+
validateCampaignTimestamp(request.end_time, "Campaign end_time");
|
|
4437
|
+
validateCampaignTargeting(request.targeting);
|
|
4438
|
+
}
|
|
4439
|
+
function validateCreateAdGroupRequest(request) {
|
|
4440
|
+
validateRequestObject(request, "Ad group create request");
|
|
4441
|
+
validateId(request.campaign_id, "Campaign id");
|
|
4442
|
+
validateEntityName(request.name, "Ad group name");
|
|
4443
|
+
validatePausedCreateStatus(request.status, "Ad group create request");
|
|
4444
|
+
validateContextHints(request.context_hints);
|
|
4445
|
+
validateBiddingConfig(request.bidding_config);
|
|
4446
|
+
}
|
|
4447
|
+
function validateUpdateAdGroupRequest(request) {
|
|
4448
|
+
validatePublicUpdateRequest(request, "Ad group update request");
|
|
4449
|
+
if (request.name !== void 0) validateEntityName(request.name, "Ad group name");
|
|
4450
|
+
validateContextHints(request.context_hints);
|
|
4451
|
+
if (request.bidding_config !== void 0) validateBiddingConfig(request.bidding_config);
|
|
4452
|
+
}
|
|
4453
|
+
function validateCreateAdRequest(request) {
|
|
4454
|
+
validateRequestObject(request, "Ad create request");
|
|
4455
|
+
validateId(request.ad_group_id, "Ad group id");
|
|
4456
|
+
validateEntityName(request.name, "Ad name");
|
|
4457
|
+
validatePausedCreateStatus(request.status, "Ad create request");
|
|
4458
|
+
validateChatCardCreative(request.creative);
|
|
4459
|
+
}
|
|
4460
|
+
function validateUpdateAdRequest(request) {
|
|
4461
|
+
validatePublicUpdateRequest(request, "Ad update request");
|
|
4462
|
+
if (request.name !== void 0) validateEntityName(request.name, "Ad name");
|
|
4463
|
+
if (request.creative !== void 0) validateChatCardCreative(request.creative);
|
|
4464
|
+
}
|
|
4277
4465
|
function adsClientLog(level, action, ctx) {
|
|
4278
4466
|
const entry = {
|
|
4279
4467
|
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -4290,14 +4478,15 @@ function buildUrl(path10, queryPairs) {
|
|
|
4290
4478
|
const qs = queryPairs.join("&");
|
|
4291
4479
|
return qs ? `${OPENAI_ADS_API_BASE}/${path10}?${qs}` : `${OPENAI_ADS_API_BASE}/${path10}`;
|
|
4292
4480
|
}
|
|
4293
|
-
async function adsFetch(apiKey, path10, queryPairs = []) {
|
|
4481
|
+
async function adsFetch(apiKey, path10, queryPairs = [], method = "GET", body) {
|
|
4294
4482
|
const url = buildUrl(path10, queryPairs);
|
|
4295
4483
|
const res = await fetch(url, {
|
|
4296
|
-
method
|
|
4484
|
+
method,
|
|
4297
4485
|
headers: {
|
|
4298
4486
|
Authorization: `Bearer ${apiKey}`,
|
|
4299
4487
|
"Content-Type": "application/json"
|
|
4300
4488
|
},
|
|
4489
|
+
body: body === void 0 ? void 0 : JSON.stringify(body),
|
|
4301
4490
|
signal: AbortSignal.timeout(OPENAI_ADS_REQUEST_TIMEOUT_MS)
|
|
4302
4491
|
});
|
|
4303
4492
|
if (res.status === 401 || res.status === 403) {
|
|
@@ -4311,10 +4500,10 @@ async function adsFetch(apiKey, path10, queryPairs = []) {
|
|
|
4311
4500
|
throw new OpenAiAdsApiError("OpenAI Ads API rate limit exceeded", 429, code);
|
|
4312
4501
|
}
|
|
4313
4502
|
if (!res.ok) {
|
|
4314
|
-
const
|
|
4315
|
-
const { message, code } = parseErrorEnvelope(
|
|
4503
|
+
const body2 = await res.text();
|
|
4504
|
+
const { message, code } = parseErrorEnvelope(body2);
|
|
4316
4505
|
adsClientLog("error", "http.error", { path: path10, httpStatus: res.status, code });
|
|
4317
|
-
const detail = message ?? (
|
|
4506
|
+
const detail = message ?? (body2.length <= 500 ? body2 : `${body2.slice(0, 500)}... [truncated]`);
|
|
4318
4507
|
throw new OpenAiAdsApiError(`OpenAI Ads API error (${res.status}): ${detail}`, res.status, code);
|
|
4319
4508
|
}
|
|
4320
4509
|
const text = await res.text();
|
|
@@ -4350,16 +4539,91 @@ async function listCampaigns(apiKey) {
|
|
|
4350
4539
|
validateApiKey(apiKey);
|
|
4351
4540
|
return fetchAllPages(apiKey, "campaigns", []);
|
|
4352
4541
|
}
|
|
4542
|
+
async function getCampaign(apiKey, campaignId) {
|
|
4543
|
+
validateApiKey(apiKey);
|
|
4544
|
+
validateId(campaignId, "Campaign id");
|
|
4545
|
+
return adsFetch(apiKey, `campaigns/${encodeURIComponent(campaignId)}`);
|
|
4546
|
+
}
|
|
4547
|
+
async function createCampaign(apiKey, request) {
|
|
4548
|
+
validateApiKey(apiKey);
|
|
4549
|
+
const outbound = snapshotJsonRequest(request, "Campaign create request");
|
|
4550
|
+
validateCreateCampaignRequest(outbound);
|
|
4551
|
+
return adsFetch(apiKey, "campaigns", [], "POST", outbound);
|
|
4552
|
+
}
|
|
4553
|
+
async function updateCampaign(apiKey, campaignId, request) {
|
|
4554
|
+
validateApiKey(apiKey);
|
|
4555
|
+
validateId(campaignId, "Campaign id");
|
|
4556
|
+
const outbound = snapshotJsonRequest(request, "Campaign update request");
|
|
4557
|
+
validateUpdateCampaignRequest(outbound);
|
|
4558
|
+
return adsFetch(apiKey, `campaigns/${encodeURIComponent(campaignId)}`, [], "POST", outbound);
|
|
4559
|
+
}
|
|
4560
|
+
async function pauseCampaign(apiKey, campaignId) {
|
|
4561
|
+
validateApiKey(apiKey);
|
|
4562
|
+
validateId(campaignId, "Campaign id");
|
|
4563
|
+
return adsFetch(apiKey, `campaigns/${encodeURIComponent(campaignId)}/pause`, [], "POST");
|
|
4564
|
+
}
|
|
4353
4565
|
async function listAdGroups(apiKey, campaignId) {
|
|
4354
4566
|
validateApiKey(apiKey);
|
|
4355
4567
|
validateId(campaignId, "Campaign id");
|
|
4356
4568
|
return fetchAllPages(apiKey, "ad_groups", [`campaign_id=${encodeURIComponent(campaignId)}`]);
|
|
4357
4569
|
}
|
|
4570
|
+
async function getAdGroup(apiKey, adGroupId) {
|
|
4571
|
+
validateApiKey(apiKey);
|
|
4572
|
+
validateId(adGroupId, "Ad group id");
|
|
4573
|
+
return adsFetch(apiKey, `ad_groups/${encodeURIComponent(adGroupId)}`);
|
|
4574
|
+
}
|
|
4575
|
+
async function createAdGroup(apiKey, request) {
|
|
4576
|
+
validateApiKey(apiKey);
|
|
4577
|
+
const outbound = snapshotJsonRequest(request, "Ad group create request");
|
|
4578
|
+
validateCreateAdGroupRequest(outbound);
|
|
4579
|
+
return adsFetch(apiKey, "ad_groups", [], "POST", outbound);
|
|
4580
|
+
}
|
|
4581
|
+
async function updateAdGroup(apiKey, adGroupId, request) {
|
|
4582
|
+
validateApiKey(apiKey);
|
|
4583
|
+
validateId(adGroupId, "Ad group id");
|
|
4584
|
+
const outbound = snapshotJsonRequest(request, "Ad group update request");
|
|
4585
|
+
validateUpdateAdGroupRequest(outbound);
|
|
4586
|
+
return adsFetch(apiKey, `ad_groups/${encodeURIComponent(adGroupId)}`, [], "POST", outbound);
|
|
4587
|
+
}
|
|
4588
|
+
async function pauseAdGroup(apiKey, adGroupId) {
|
|
4589
|
+
validateApiKey(apiKey);
|
|
4590
|
+
validateId(adGroupId, "Ad group id");
|
|
4591
|
+
return adsFetch(apiKey, `ad_groups/${encodeURIComponent(adGroupId)}/pause`, [], "POST");
|
|
4592
|
+
}
|
|
4358
4593
|
async function listAds(apiKey, adGroupId) {
|
|
4359
4594
|
validateApiKey(apiKey);
|
|
4360
4595
|
validateId(adGroupId, "Ad group id");
|
|
4361
4596
|
return fetchAllPages(apiKey, "ads", [`ad_group_id=${encodeURIComponent(adGroupId)}`]);
|
|
4362
4597
|
}
|
|
4598
|
+
async function getAd(apiKey, adId) {
|
|
4599
|
+
validateApiKey(apiKey);
|
|
4600
|
+
validateId(adId, "Ad id");
|
|
4601
|
+
return adsFetch(apiKey, `ads/${encodeURIComponent(adId)}`);
|
|
4602
|
+
}
|
|
4603
|
+
async function createAd(apiKey, request) {
|
|
4604
|
+
validateApiKey(apiKey);
|
|
4605
|
+
const outbound = snapshotJsonRequest(request, "Ad create request");
|
|
4606
|
+
validateCreateAdRequest(outbound);
|
|
4607
|
+
return adsFetch(apiKey, "ads", [], "POST", outbound);
|
|
4608
|
+
}
|
|
4609
|
+
async function updateAd(apiKey, adId, request) {
|
|
4610
|
+
validateApiKey(apiKey);
|
|
4611
|
+
validateId(adId, "Ad id");
|
|
4612
|
+
const outbound = snapshotJsonRequest(request, "Ad update request");
|
|
4613
|
+
validateUpdateAdRequest(outbound);
|
|
4614
|
+
return adsFetch(apiKey, `ads/${encodeURIComponent(adId)}`, [], "POST", outbound);
|
|
4615
|
+
}
|
|
4616
|
+
async function pauseAd(apiKey, adId) {
|
|
4617
|
+
validateApiKey(apiKey);
|
|
4618
|
+
validateId(adId, "Ad id");
|
|
4619
|
+
return adsFetch(apiKey, `ads/${encodeURIComponent(adId)}/pause`, [], "POST");
|
|
4620
|
+
}
|
|
4621
|
+
async function uploadImageFromUrl(apiKey, imageUrl) {
|
|
4622
|
+
validateApiKey(apiKey);
|
|
4623
|
+
validateHttpUrl(imageUrl, "Image URL");
|
|
4624
|
+
const request = { image_url: imageUrl };
|
|
4625
|
+
return adsFetch(apiKey, "upload", [], "POST", request);
|
|
4626
|
+
}
|
|
4363
4627
|
async function getCampaignInsights(apiKey, campaignId, opts) {
|
|
4364
4628
|
validateApiKey(apiKey);
|
|
4365
4629
|
validateId(campaignId, "Campaign id");
|
|
@@ -4491,7 +4755,10 @@ async function executeAdsSync(db, runId, projectId, opts) {
|
|
|
4491
4755
|
id: campaign.id,
|
|
4492
4756
|
projectId,
|
|
4493
4757
|
name: campaign.name,
|
|
4758
|
+
description: campaign.description ?? null,
|
|
4494
4759
|
status: campaign.status,
|
|
4760
|
+
startTime: campaign.start_time ?? null,
|
|
4761
|
+
endTime: campaign.end_time ?? null,
|
|
4495
4762
|
biddingType: campaign.bidding_type,
|
|
4496
4763
|
dailySpendLimitMicros: campaign.budget?.daily_spend_limit_micros ?? null,
|
|
4497
4764
|
lifetimeSpendLimitMicros: campaign.budget?.lifetime_spend_limit_micros ?? null,
|
|
@@ -4507,6 +4774,7 @@ async function executeAdsSync(db, runId, projectId, opts) {
|
|
|
4507
4774
|
projectId,
|
|
4508
4775
|
campaignId: campaign.id,
|
|
4509
4776
|
name: group.name,
|
|
4777
|
+
description: group.description ?? null,
|
|
4510
4778
|
status: group.status,
|
|
4511
4779
|
billingEventType: group.bidding_config?.billing_event_type ?? null,
|
|
4512
4780
|
maxBidMicros: group.bidding_config?.max_bid_micros ?? null,
|
|
@@ -6515,7 +6783,7 @@ function readStoredGroundingSources(rawResponse) {
|
|
|
6515
6783
|
return result;
|
|
6516
6784
|
}
|
|
6517
6785
|
async function backfillInsightsCommand(project, opts) {
|
|
6518
|
-
const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-
|
|
6786
|
+
const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-FWPXMAVK.js");
|
|
6519
6787
|
const config = loadConfig();
|
|
6520
6788
|
const db = createClient(config.database);
|
|
6521
6789
|
migrate(db);
|
|
@@ -8605,6 +8873,17 @@ var AERO_ADS_OPERATOR_MCP_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
|
8605
8873
|
CanonryMcpToolNames.canonry_ads_campaigns,
|
|
8606
8874
|
CanonryMcpToolNames.canonry_ads_insights,
|
|
8607
8875
|
CanonryMcpToolNames.canonry_ads_summary,
|
|
8876
|
+
CanonryMcpToolNames.canonry_ads_operation_get,
|
|
8877
|
+
CanonryMcpToolNames.canonry_ads_image_upload,
|
|
8878
|
+
CanonryMcpToolNames.canonry_ads_campaign_create,
|
|
8879
|
+
CanonryMcpToolNames.canonry_ads_campaign_update,
|
|
8880
|
+
CanonryMcpToolNames.canonry_ads_campaign_pause,
|
|
8881
|
+
CanonryMcpToolNames.canonry_ads_ad_group_create,
|
|
8882
|
+
CanonryMcpToolNames.canonry_ads_ad_group_update,
|
|
8883
|
+
CanonryMcpToolNames.canonry_ads_ad_group_pause,
|
|
8884
|
+
CanonryMcpToolNames.canonry_ads_ad_create,
|
|
8885
|
+
CanonryMcpToolNames.canonry_ads_ad_update,
|
|
8886
|
+
CanonryMcpToolNames.canonry_ads_ad_pause,
|
|
8608
8887
|
CanonryMcpToolNames.canonry_ads_sync
|
|
8609
8888
|
]);
|
|
8610
8889
|
function toolResult(details) {
|
|
@@ -8666,6 +8945,7 @@ function compactCampaigns(response, limit) {
|
|
|
8666
8945
|
adGroups: campaign.adGroups.slice(0, 8).map((group) => ({
|
|
8667
8946
|
id: group.id,
|
|
8668
8947
|
name: group.name,
|
|
8948
|
+
description: group.description,
|
|
8669
8949
|
status: group.status,
|
|
8670
8950
|
billingEventType: group.billingEventType,
|
|
8671
8951
|
maxBidMicros: group.maxBidMicros,
|
|
@@ -8677,14 +8957,25 @@ function compactCampaigns(response, limit) {
|
|
|
8677
8957
|
name: ad.name,
|
|
8678
8958
|
status: ad.status,
|
|
8679
8959
|
reviewStatus: ad.reviewStatus,
|
|
8960
|
+
upstreamUpdatedAt: ad.upstreamUpdatedAt,
|
|
8961
|
+
syncedAt: ad.syncedAt,
|
|
8680
8962
|
creative: ad.creative ? {
|
|
8681
8963
|
type: ad.creative.type,
|
|
8682
8964
|
title: ad.creative.title,
|
|
8683
8965
|
body: ad.creative.body,
|
|
8684
|
-
targetUrl: ad.creative.targetUrl
|
|
8966
|
+
targetUrl: ad.creative.targetUrl,
|
|
8967
|
+
fileId: ad.creative.fileId
|
|
8685
8968
|
} : ad.creative
|
|
8686
|
-
}))
|
|
8687
|
-
|
|
8969
|
+
})),
|
|
8970
|
+
upstreamUpdatedAt: group.upstreamUpdatedAt,
|
|
8971
|
+
syncedAt: group.syncedAt
|
|
8972
|
+
})),
|
|
8973
|
+
description: campaign.description,
|
|
8974
|
+
startTime: campaign.startTime,
|
|
8975
|
+
endTime: campaign.endTime,
|
|
8976
|
+
locationIds: campaign.locationIds ?? [],
|
|
8977
|
+
upstreamUpdatedAt: campaign.upstreamUpdatedAt,
|
|
8978
|
+
syncedAt: campaign.syncedAt
|
|
8688
8979
|
}))
|
|
8689
8980
|
};
|
|
8690
8981
|
}
|
|
@@ -8845,11 +9136,11 @@ function recordLlmUsageEvent(args) {
|
|
|
8845
9136
|
var AERO_MEMORY_SEPARATOR = "\n\n---\n\n";
|
|
8846
9137
|
var AERO_MEMORY_BLOCK_PREFIX = `${AERO_MEMORY_SEPARATOR}<memory>
|
|
8847
9138
|
`;
|
|
8848
|
-
function
|
|
9139
|
+
function isRecord2(value) {
|
|
8849
9140
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
8850
9141
|
}
|
|
8851
9142
|
function isTextSystemBlock(value) {
|
|
8852
|
-
return
|
|
9143
|
+
return isRecord2(value) && value.type === "text" && typeof value.text === "string";
|
|
8853
9144
|
}
|
|
8854
9145
|
function splitAeroHydratedSystemPrompt(systemPrompt) {
|
|
8855
9146
|
const idx = systemPrompt.lastIndexOf(AERO_MEMORY_BLOCK_PREFIX);
|
|
@@ -8861,7 +9152,7 @@ function splitAeroHydratedSystemPrompt(systemPrompt) {
|
|
|
8861
9152
|
}
|
|
8862
9153
|
function splitAeroAnthropicSystemCachePayload(payload, model) {
|
|
8863
9154
|
if (model.api !== "anthropic-messages") return void 0;
|
|
8864
|
-
if (!
|
|
9155
|
+
if (!isRecord2(payload) || !Array.isArray(payload.system)) return void 0;
|
|
8865
9156
|
let changed = false;
|
|
8866
9157
|
const nextSystem = [];
|
|
8867
9158
|
for (const block of payload.system) {
|
|
@@ -11371,6 +11662,83 @@ async function createServer(opts) {
|
|
|
11371
11662
|
timezone: account.timezone ?? null
|
|
11372
11663
|
};
|
|
11373
11664
|
};
|
|
11665
|
+
const adsEntityResult = (entity) => ({
|
|
11666
|
+
id: entity.id,
|
|
11667
|
+
status: entity.status,
|
|
11668
|
+
updatedAt: entity.updated_at,
|
|
11669
|
+
reviewStatus: entity.review_status ?? null
|
|
11670
|
+
});
|
|
11671
|
+
const adsOperator = {
|
|
11672
|
+
uploadImage: async (apiKey, imageUrl) => {
|
|
11673
|
+
const result = await uploadImageFromUrl(apiKey, imageUrl);
|
|
11674
|
+
return { fileId: result.file_id };
|
|
11675
|
+
},
|
|
11676
|
+
getCampaign: async (apiKey, id) => adsEntityResult(await getCampaign(apiKey, id)),
|
|
11677
|
+
createCampaign: async (apiKey, input) => adsEntityResult(await createCampaign(apiKey, {
|
|
11678
|
+
name: input.name,
|
|
11679
|
+
description: input.description,
|
|
11680
|
+
start_time: input.startTime,
|
|
11681
|
+
end_time: input.endTime,
|
|
11682
|
+
status: OpenAiAdsWriteStatuses.paused,
|
|
11683
|
+
budget: { lifetime_spend_limit_micros: input.lifetimeSpendLimitMicros },
|
|
11684
|
+
targeting: { locations: { include: input.locationIds.map((id) => ({ id })) } }
|
|
11685
|
+
})),
|
|
11686
|
+
updateCampaign: async (apiKey, id, input) => adsEntityResult(await updateCampaign(apiKey, id, {
|
|
11687
|
+
name: input.name,
|
|
11688
|
+
description: input.description,
|
|
11689
|
+
start_time: input.startTime,
|
|
11690
|
+
end_time: input.endTime,
|
|
11691
|
+
budget: input.lifetimeSpendLimitMicros === void 0 ? void 0 : { lifetime_spend_limit_micros: input.lifetimeSpendLimitMicros },
|
|
11692
|
+
targeting: input.locationIds === void 0 ? void 0 : { locations: { include: input.locationIds.map((locationId) => ({ id: locationId })) } }
|
|
11693
|
+
})),
|
|
11694
|
+
pauseCampaign: async (apiKey, id) => adsEntityResult(await pauseCampaign(apiKey, id)),
|
|
11695
|
+
getAdGroup: async (apiKey, id) => adsEntityResult(await getAdGroup(apiKey, id)),
|
|
11696
|
+
createAdGroup: async (apiKey, input) => adsEntityResult(await createAdGroup(apiKey, {
|
|
11697
|
+
campaign_id: input.campaignId,
|
|
11698
|
+
name: input.name,
|
|
11699
|
+
description: input.description,
|
|
11700
|
+
context_hints: input.contextHints,
|
|
11701
|
+
status: OpenAiAdsWriteStatuses.paused,
|
|
11702
|
+
bidding_config: {
|
|
11703
|
+
billing_event_type: OpenAiAdsBillingEventTypes.impression,
|
|
11704
|
+
max_bid_micros: input.maxBidMicros
|
|
11705
|
+
}
|
|
11706
|
+
})),
|
|
11707
|
+
updateAdGroup: async (apiKey, id, input) => adsEntityResult(await updateAdGroup(apiKey, id, {
|
|
11708
|
+
name: input.name,
|
|
11709
|
+
description: input.description,
|
|
11710
|
+
context_hints: input.contextHints,
|
|
11711
|
+
bidding_config: input.maxBidMicros === void 0 ? void 0 : {
|
|
11712
|
+
billing_event_type: OpenAiAdsBillingEventTypes.impression,
|
|
11713
|
+
max_bid_micros: input.maxBidMicros
|
|
11714
|
+
}
|
|
11715
|
+
})),
|
|
11716
|
+
pauseAdGroup: async (apiKey, id) => adsEntityResult(await pauseAdGroup(apiKey, id)),
|
|
11717
|
+
getAd: async (apiKey, id) => adsEntityResult(await getAd(apiKey, id)),
|
|
11718
|
+
createAd: async (apiKey, input) => adsEntityResult(await createAd(apiKey, {
|
|
11719
|
+
ad_group_id: input.adGroupId,
|
|
11720
|
+
name: input.name,
|
|
11721
|
+
status: OpenAiAdsWriteStatuses.paused,
|
|
11722
|
+
creative: {
|
|
11723
|
+
type: OpenAiAdsCreativeTypes.chatCard,
|
|
11724
|
+
title: input.creative.title,
|
|
11725
|
+
body: input.creative.body,
|
|
11726
|
+
target_url: input.creative.targetUrl,
|
|
11727
|
+
file_id: input.creative.fileId
|
|
11728
|
+
}
|
|
11729
|
+
})),
|
|
11730
|
+
updateAd: async (apiKey, id, input) => adsEntityResult(await updateAd(apiKey, id, {
|
|
11731
|
+
name: input.name,
|
|
11732
|
+
creative: input.creative ? {
|
|
11733
|
+
type: OpenAiAdsCreativeTypes.chatCard,
|
|
11734
|
+
title: input.creative.title,
|
|
11735
|
+
body: input.creative.body,
|
|
11736
|
+
target_url: input.creative.targetUrl,
|
|
11737
|
+
file_id: input.creative.fileId
|
|
11738
|
+
} : void 0
|
|
11739
|
+
})),
|
|
11740
|
+
pauseAd: async (apiKey, id) => adsEntityResult(await pauseAd(apiKey, id))
|
|
11741
|
+
};
|
|
11374
11742
|
const scheduler = new Scheduler(opts.db, {
|
|
11375
11743
|
onRunCreated: (runId, projectId, providers2, location) => {
|
|
11376
11744
|
jobRunner.executeRun(runId, projectId, providers2, location).catch((err) => {
|
|
@@ -11963,6 +12331,7 @@ async function createServer(opts) {
|
|
|
11963
12331
|
},
|
|
11964
12332
|
adsCredentialStore,
|
|
11965
12333
|
verifyAdsAccount,
|
|
12334
|
+
adsOperator,
|
|
11966
12335
|
onAdsSyncRequested: (runId, projectId) => {
|
|
11967
12336
|
runAdsSync(runId, projectId);
|
|
11968
12337
|
},
|