@adcp/sdk 15.7.1 → 15.8.1
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/lib/core/SingleAgentClient.d.mts +14 -0
- package/dist/lib/core/SingleAgentClient.d.ts +14 -0
- package/dist/lib/core/SingleAgentClient.js +138 -54
- package/dist/lib/core/SingleAgentClient.mjs +141 -54
- package/dist/lib/core/agent-discovery-cache.d.mts +2 -0
- package/dist/lib/core/agent-discovery-cache.d.ts +2 -0
- package/dist/lib/core/creative-schema-support.d.mts +3 -0
- package/dist/lib/core/creative-schema-support.d.ts +3 -0
- package/dist/lib/core/creative-schema-support.js +113 -0
- package/dist/lib/core/creative-schema-support.mjs +89 -0
- package/dist/lib/core/product-cache.js +4 -3
- package/dist/lib/core/product-cache.mjs +4 -3
- package/dist/lib/reporting/ledger/handler.d.mts +10 -3
- package/dist/lib/reporting/ledger/handler.d.ts +10 -3
- package/dist/lib/reporting/ledger/handler.js +17 -4
- package/dist/lib/reporting/ledger/handler.mjs +17 -4
- package/dist/lib/reporting/ledger/managed.d.mts +3 -1
- package/dist/lib/reporting/ledger/managed.d.ts +3 -1
- package/dist/lib/reporting/ledger/managed.js +4 -1
- package/dist/lib/reporting/ledger/managed.mjs +4 -1
- package/dist/lib/reporting/ledger/postgres.d.mts +87 -0
- package/dist/lib/reporting/ledger/postgres.d.ts +87 -0
- package/dist/lib/reporting/ledger/postgres.js +316 -15
- package/dist/lib/reporting/ledger/postgres.mjs +316 -15
- package/dist/lib/reporting/ledger/row-storage.d.mts +23 -0
- package/dist/lib/reporting/ledger/row-storage.d.ts +23 -0
- package/dist/lib/reporting/ledger/row-storage.js +56 -0
- package/dist/lib/reporting/ledger/row-storage.mjs +56 -0
- package/dist/lib/reporting/ledger/types.d.mts +26 -0
- package/dist/lib/reporting/ledger/types.d.ts +26 -0
- package/dist/lib/reporting/service/index.d.mts +33 -3
- package/dist/lib/reporting/service/index.d.ts +33 -3
- package/dist/lib/reporting/service/index.js +20 -2
- package/dist/lib/reporting/service/index.mjs +20 -2
- package/dist/lib/reporting/service/maintenance.d.mts +20 -1
- package/dist/lib/reporting/service/maintenance.d.ts +20 -1
- package/dist/lib/reporting/service/maintenance.js +25 -2
- package/dist/lib/reporting/service/maintenance.mjs +25 -2
- package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
- package/dist/lib/testing/storyboard/request-builder.js +14 -16
- package/dist/lib/testing/storyboard/request-builder.mjs +14 -16
- package/dist/lib/testing/storyboard/validations.d.mts +1 -1
- package/dist/lib/testing/storyboard/validations.d.ts +1 -1
- package/dist/lib/v2/projection/creative-delivery.d.mts +22 -0
- package/dist/lib/v2/projection/creative-delivery.d.ts +22 -0
- package/dist/lib/v2/projection/creative-delivery.js +92 -0
- package/dist/lib/v2/projection/creative-delivery.mjs +91 -0
- package/dist/lib/v2/projection/legacy-metadata.d.mts +6 -3
- package/dist/lib/v2/projection/legacy-metadata.d.ts +6 -3
- package/dist/lib/v2/projection/legacy-metadata.js +17 -0
- package/dist/lib/v2/projection/legacy-metadata.mjs +15 -0
- package/dist/lib/version.d.mts +3 -3
- package/dist/lib/version.d.ts +3 -3
- package/dist/lib/version.js +3 -3
- package/dist/lib/version.mjs +3 -3
- package/docs/TYPE-SUMMARY.md +2 -2
- package/docs/guides/CREATIVE-DELIVERY.md +16 -0
- package/docs/guides/REPORTING-LEDGER-CUTOVER.md +405 -0
- package/docs/guides/REPORTING-LEDGER.md +130 -0
- package/docs/guides/REPORTING-OPERATIONS.md +12 -0
- package/docs/llms.txt +3 -2
- package/docs/migration-14.x-rc-worksheet.md +4 -4
- package/package.json +1 -1
|
@@ -159,6 +159,7 @@ import {
|
|
|
159
159
|
projectMediaBuyCreativesForDelivery,
|
|
160
160
|
projectCreativeForDelivery,
|
|
161
161
|
projectSyncCreativesForDelivery,
|
|
162
|
+
projectUndeclaredFormatOptionSelectors,
|
|
162
163
|
resolveCreativeFormatWireMode,
|
|
163
164
|
stripLegacyCreativeIdentity
|
|
164
165
|
} from "../v2/projection/creative-delivery.mjs";
|
|
@@ -168,10 +169,13 @@ import {
|
|
|
168
169
|
import { toCanonicalOnlyResponse } from "../v2/projection/augment-response.mjs";
|
|
169
170
|
import {
|
|
170
171
|
legacyFormatRefsForDeclaration,
|
|
172
|
+
rememberSellerDeclaredFormatOption,
|
|
173
|
+
sellerDeclaredFormatOption,
|
|
171
174
|
structuredCloneWithLegacyCreativeMetadata
|
|
172
175
|
} from "../v2/projection/legacy-metadata.mjs";
|
|
173
176
|
import { isProjectionProductInput } from "../v2/projection/types.mjs";
|
|
174
177
|
import { canonicalize as canonicalizeJson } from "../utils/jcs.mjs";
|
|
178
|
+
const toolInputSchemasByProperties = /* @__PURE__ */ new WeakMap();
|
|
175
179
|
const CAPABILITY_DISCOVERY_CONTEXT = /* @__PURE__ */ Symbol("capabilityDiscoveryContext");
|
|
176
180
|
function a2aUrlString(input) {
|
|
177
181
|
return typeof input === "string" ? input : input instanceof URL ? input.toString() : input.url;
|
|
@@ -218,32 +222,6 @@ function selectA2AJsonRpcUrl(agentCard, protocolVersion, configuredAgentUrl) {
|
|
|
218
222
|
}
|
|
219
223
|
return resolved.toString();
|
|
220
224
|
}
|
|
221
|
-
function creativeSchemaSupport(value, depth = 0) {
|
|
222
|
-
if (depth > 24 || value === null || typeof value !== "object") return "unknown";
|
|
223
|
-
if (Array.isArray(value)) {
|
|
224
|
-
let legacy2 = false;
|
|
225
|
-
for (const item of value) {
|
|
226
|
-
const support = creativeSchemaSupport(item, depth + 1);
|
|
227
|
-
if (support === "canonical") return support;
|
|
228
|
-
if (support === "legacy") legacy2 = true;
|
|
229
|
-
}
|
|
230
|
-
return legacy2 ? "legacy" : "unknown";
|
|
231
|
-
}
|
|
232
|
-
const object = value;
|
|
233
|
-
const properties = object.properties;
|
|
234
|
-
if (properties !== null && typeof properties === "object" && !Array.isArray(properties)) {
|
|
235
|
-
const keys = properties;
|
|
236
|
-
if ("creative_id" in keys && "format_kind" in keys) return "canonical";
|
|
237
|
-
if ("creative_id" in keys && "format_id" in keys) return "legacy";
|
|
238
|
-
}
|
|
239
|
-
let legacy = false;
|
|
240
|
-
for (const child of Object.values(object)) {
|
|
241
|
-
const support = creativeSchemaSupport(child, depth + 1);
|
|
242
|
-
if (support === "canonical") return support;
|
|
243
|
-
if (support === "legacy") legacy = true;
|
|
244
|
-
}
|
|
245
|
-
return legacy ? "legacy" : "unknown";
|
|
246
|
-
}
|
|
247
225
|
function hasMediaBuyCreativeFormatData(request) {
|
|
248
226
|
if (request === null || typeof request !== "object" || Array.isArray(request)) return false;
|
|
249
227
|
const record = request;
|
|
@@ -1404,9 +1382,10 @@ class SingleAgentClient {
|
|
|
1404
1382
|
}
|
|
1405
1383
|
}
|
|
1406
1384
|
}
|
|
1407
|
-
rememberCanonicalProductRoutes(products, account, authoritativeProducts
|
|
1408
|
-
this.invalidateCanonicalProductRoutes(authoritativeProducts, account);
|
|
1385
|
+
rememberCanonicalProductRoutes(products, account, authoritativeProducts) {
|
|
1386
|
+
this.invalidateCanonicalProductRoutes(authoritativeProducts ?? products, account);
|
|
1409
1387
|
const accountScope = this.canonicalAccountScope(account);
|
|
1388
|
+
const declaredOptions = authoritativeProducts ? this.sellerDeclaredFormatOptions(authoritativeProducts) : void 0;
|
|
1410
1389
|
for (const value of products) {
|
|
1411
1390
|
if (!value || typeof value !== "object" || Array.isArray(value)) continue;
|
|
1412
1391
|
const product = value;
|
|
@@ -1422,16 +1401,78 @@ class SingleAgentClient {
|
|
|
1422
1401
|
} : { scope: "product", format_option_id: option.format_option_id };
|
|
1423
1402
|
const refs = legacyFormatRefsForDeclaration(option);
|
|
1424
1403
|
if (refs.length === 0) continue;
|
|
1404
|
+
const declared = declaredOptions ? declaredOptions.get(product.product_id)?.some((declaredRef) => this.sameCanonicalOptionRef(declaredRef, ref)) : sellerDeclaredFormatOption(option);
|
|
1405
|
+
if (declared !== void 0) rememberSellerDeclaredFormatOption(option, declared);
|
|
1425
1406
|
this.rememberCanonicalLegacyRoute(this.canonicalLegacyRouteKey(account, product.product_id, ref), {
|
|
1426
1407
|
kind: "product",
|
|
1427
1408
|
accountScope,
|
|
1428
1409
|
productId: product.product_id,
|
|
1429
1410
|
optionRef: ref,
|
|
1430
|
-
refs
|
|
1411
|
+
refs,
|
|
1412
|
+
...declared === false ? {
|
|
1413
|
+
undeclaredSelector: {
|
|
1414
|
+
format_kind: typeof option.format_kind === "string" ? option.format_kind : "",
|
|
1415
|
+
...option.params !== void 0 && { params: structuredClone(option.params) },
|
|
1416
|
+
...(typeof option.format_kind !== "string" || option.format_kind === "custom" || option.format_shape !== void 0 || option.format_schema !== void 0) && { unrepresentable: true }
|
|
1417
|
+
}
|
|
1418
|
+
} : {}
|
|
1431
1419
|
});
|
|
1432
1420
|
}
|
|
1433
1421
|
}
|
|
1434
1422
|
}
|
|
1423
|
+
/**
|
|
1424
|
+
* Option refs each product declared in the seller's own response. A product
|
|
1425
|
+
* absent from the response yields no entry, so its options are treated as
|
|
1426
|
+
* declared rather than guessed undeclared.
|
|
1427
|
+
*/
|
|
1428
|
+
sellerDeclaredFormatOptions(authoritativeProducts) {
|
|
1429
|
+
const declared = /* @__PURE__ */ new Map();
|
|
1430
|
+
for (const value of authoritativeProducts) {
|
|
1431
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) continue;
|
|
1432
|
+
const product = value;
|
|
1433
|
+
if (typeof product.product_id !== "string") continue;
|
|
1434
|
+
const refs = [];
|
|
1435
|
+
for (const optionValue of Array.isArray(product.format_options) ? product.format_options : []) {
|
|
1436
|
+
if (!optionValue || typeof optionValue !== "object" || Array.isArray(optionValue)) continue;
|
|
1437
|
+
const option = optionValue;
|
|
1438
|
+
if (typeof option.format_option_id !== "string") continue;
|
|
1439
|
+
refs.push(
|
|
1440
|
+
typeof option.publisher_domain === "string" ? {
|
|
1441
|
+
scope: "publisher",
|
|
1442
|
+
publisher_domain: option.publisher_domain,
|
|
1443
|
+
format_option_id: option.format_option_id
|
|
1444
|
+
} : { scope: "product", format_option_id: option.format_option_id }
|
|
1445
|
+
);
|
|
1446
|
+
}
|
|
1447
|
+
declared.set(product.product_id, refs);
|
|
1448
|
+
}
|
|
1449
|
+
return declared;
|
|
1450
|
+
}
|
|
1451
|
+
/**
|
|
1452
|
+
* The direct selector for an option this client derived from the seller's
|
|
1453
|
+
* legacy `format_ids`. Without a product id, every remembered route for the
|
|
1454
|
+
* option must agree that the seller did not declare it.
|
|
1455
|
+
*/
|
|
1456
|
+
undeclaredFormatOptionSelector(account, ref, productId) {
|
|
1457
|
+
if (productId !== void 0) {
|
|
1458
|
+
const route = this.routeForOption(account, productId, ref);
|
|
1459
|
+
return route?.kind === "product" ? route.undeclaredSelector : void 0;
|
|
1460
|
+
}
|
|
1461
|
+
const accountScope = this.canonicalAccountScope(account);
|
|
1462
|
+
const routes = [...this.canonicalLegacyRoutes.values()].filter(
|
|
1463
|
+
(route) => route.kind === "product" && (route.accountScope === accountScope || route.accountScope === "none") && this.sameCanonicalOptionRef(route.optionRef, ref)
|
|
1464
|
+
);
|
|
1465
|
+
if (routes.length === 0 || routes.some((route) => route.undeclaredSelector === void 0)) return void 0;
|
|
1466
|
+
return routes[0].undeclaredSelector;
|
|
1467
|
+
}
|
|
1468
|
+
projectUndeclaredFormatOptions(request, operation, wireMode, account) {
|
|
1469
|
+
if (wireMode !== "canonical") return request;
|
|
1470
|
+
return projectUndeclaredFormatOptionSelectors(
|
|
1471
|
+
request,
|
|
1472
|
+
operation,
|
|
1473
|
+
(ref, productId) => this.undeclaredFormatOptionSelector(account, ref, productId)
|
|
1474
|
+
);
|
|
1475
|
+
}
|
|
1435
1476
|
rememberCanonicalProductRoutesForCompletion(taskType, data, legacyFormatConverter, account) {
|
|
1436
1477
|
if (taskType !== "get_products" || !data || typeof data !== "object" || Array.isArray(data)) return;
|
|
1437
1478
|
const authoritativeProducts = Array.isArray(data.products) ? data.products : [];
|
|
@@ -4560,7 +4601,7 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
4560
4601
|
if (hit) {
|
|
4561
4602
|
throwIfAborted(effectiveOptions.signal);
|
|
4562
4603
|
if (hit.success && hit.status === "completed")
|
|
4563
|
-
this.rememberCanonicalProductRoutes(hit.data.products ?? [], account
|
|
4604
|
+
this.rememberCanonicalProductRoutes(hit.data.products ?? [], account);
|
|
4564
4605
|
return attachMatch(
|
|
4565
4606
|
await this.applyProductPropertyPolicy(
|
|
4566
4607
|
hit,
|
|
@@ -4604,11 +4645,7 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
4604
4645
|
[SKIP_PRODUCT_CACHE]: true
|
|
4605
4646
|
});
|
|
4606
4647
|
}
|
|
4607
|
-
this.rememberCanonicalProductRoutes(
|
|
4608
|
-
cachedResult.data.products ?? [],
|
|
4609
|
-
account,
|
|
4610
|
-
cachedResult.data.products ?? []
|
|
4611
|
-
);
|
|
4648
|
+
this.rememberCanonicalProductRoutes(cachedResult.data.products ?? [], account);
|
|
4612
4649
|
}
|
|
4613
4650
|
if (cachedResult.submitted) {
|
|
4614
4651
|
const submitted = cachedResult.submitted;
|
|
@@ -4764,12 +4801,17 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
4764
4801
|
const result = await this.executeAndHandle(
|
|
4765
4802
|
"create_media_buy",
|
|
4766
4803
|
"onCreateMediaBuyStatusChange",
|
|
4767
|
-
|
|
4768
|
-
|
|
4769
|
-
|
|
4804
|
+
this.projectUndeclaredFormatOptions(
|
|
4805
|
+
projectMediaBuyCreativesForDelivery(
|
|
4806
|
+
wireParams,
|
|
4807
|
+
wireMode,
|
|
4808
|
+
"create_media_buy",
|
|
4809
|
+
effectiveLegacyFormatConverter,
|
|
4810
|
+
effectiveCanonicalFormatLegacyResolver
|
|
4811
|
+
),
|
|
4770
4812
|
"create_media_buy",
|
|
4771
|
-
|
|
4772
|
-
|
|
4813
|
+
wireMode,
|
|
4814
|
+
wireParams.account
|
|
4773
4815
|
),
|
|
4774
4816
|
inputHandler,
|
|
4775
4817
|
taskOptions,
|
|
@@ -4845,12 +4887,17 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
4845
4887
|
const result = await this.executeAndHandle(
|
|
4846
4888
|
"update_media_buy",
|
|
4847
4889
|
"onUpdateMediaBuyStatusChange",
|
|
4848
|
-
|
|
4849
|
-
|
|
4850
|
-
|
|
4890
|
+
this.projectUndeclaredFormatOptions(
|
|
4891
|
+
projectMediaBuyCreativesForDelivery(
|
|
4892
|
+
params,
|
|
4893
|
+
wireMode,
|
|
4894
|
+
"update_media_buy",
|
|
4895
|
+
effectiveLegacyFormatConverter,
|
|
4896
|
+
effectiveCanonicalFormatLegacyResolver
|
|
4897
|
+
),
|
|
4851
4898
|
"update_media_buy",
|
|
4852
|
-
|
|
4853
|
-
|
|
4899
|
+
wireMode,
|
|
4900
|
+
params.account
|
|
4854
4901
|
),
|
|
4855
4902
|
inputHandler,
|
|
4856
4903
|
taskOptions,
|
|
@@ -4936,12 +4983,17 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
4936
4983
|
const assignmentPackageContainers = Array.isArray(params.assignments) ? params.assignments.flatMap(
|
|
4937
4984
|
(assignment) => typeof assignment.package_id === "string" && !configuredPackageIds.has(assignment.package_id) ? [{ package_id: assignment.package_id }] : []
|
|
4938
4985
|
) : [];
|
|
4939
|
-
const wireParams =
|
|
4940
|
-
|
|
4941
|
-
|
|
4986
|
+
const wireParams = this.projectUndeclaredFormatOptions(
|
|
4987
|
+
projectSyncCreativesForDelivery(
|
|
4988
|
+
params,
|
|
4989
|
+
[...configuredSelectorContainers, ...assignmentPackageContainers],
|
|
4990
|
+
wireMode,
|
|
4991
|
+
effectiveLegacyFormatConverter,
|
|
4992
|
+
effectiveCanonicalFormatLegacyResolver
|
|
4993
|
+
),
|
|
4994
|
+
"sync_creatives",
|
|
4942
4995
|
wireMode,
|
|
4943
|
-
|
|
4944
|
-
effectiveCanonicalFormatLegacyResolver
|
|
4996
|
+
params.account
|
|
4945
4997
|
);
|
|
4946
4998
|
return this.executeAndHandle(
|
|
4947
4999
|
"sync_creatives",
|
|
@@ -4980,6 +5032,9 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
4980
5032
|
* `CreativeFormatCapabilityError`, just as they do during a write.
|
|
4981
5033
|
*/
|
|
4982
5034
|
async resolveCreativeFormatWireMode(taskType, options) {
|
|
5035
|
+
return this.resolveCreativeWireMode(taskType, options, true);
|
|
5036
|
+
}
|
|
5037
|
+
async resolveCreativeWireMode(taskType, options, canRediscover) {
|
|
4983
5038
|
const discoveryContext = {};
|
|
4984
5039
|
const capabilities = await this.getCapabilities({
|
|
4985
5040
|
...options,
|
|
@@ -4989,7 +5044,10 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
4989
5044
|
const toolSchemas = discoveryContext.toolSchemas ?? (usesScopedFetch ? void 0 : this.cachedToolSchemas);
|
|
4990
5045
|
const wireRelease = this.config.wireAdcpVersion ?? this.resolvedAdcpVersion;
|
|
4991
5046
|
const declared = resolveCreativeFormatWireMode(capabilities, wireRelease);
|
|
4992
|
-
const
|
|
5047
|
+
const document = toolSchemas && toolInputSchemasByProperties.get(toolSchemas)?.get(taskType);
|
|
5048
|
+
const { creativeSchemaSupport } = await import("./creative-schema-support.mjs");
|
|
5049
|
+
throwIfAborted(options?.signal);
|
|
5050
|
+
const schema = creativeSchemaSupport(document ?? { properties: toolSchemas?.get(taskType) });
|
|
4993
5051
|
if (declared !== "unknown" && schema !== "unknown" && declared !== schema) {
|
|
4994
5052
|
throw new CreativeFormatCapabilityError(
|
|
4995
5053
|
`Seller capability and ${taskType} input schema disagree about canonical creative support`
|
|
@@ -4999,6 +5057,10 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
4999
5057
|
const release = /^v?(\d+)\.(\d+)(?:\.|-|$)/.exec(wireRelease.trim());
|
|
5000
5058
|
const canonicalRequiredByBuyerPin = release !== null && (Number(release[1]) > 3 || Number(release[1]) === 3 && Number(release[2]) >= 2);
|
|
5001
5059
|
if (resolved === "unknown" && canonicalRequiredByBuyerPin) {
|
|
5060
|
+
if (canRediscover && !usesScopedFetch && this.normalizedAgent.protocol === "mcp" && this.capabilitiesFromSharedCache && toolSchemas?.has(taskType) && !toolInputSchemasByProperties.has(toolSchemas)) {
|
|
5061
|
+
await this.invalidateDiscoveryCache(options);
|
|
5062
|
+
return this.resolveCreativeWireMode(taskType, options, false);
|
|
5063
|
+
}
|
|
5002
5064
|
throw new CreativeFormatCapabilityError(
|
|
5003
5065
|
`Cannot prove which AdCP release the seller serves for ${taskType}; a 3.2+ client will not guess a legacy creative wire shape`
|
|
5004
5066
|
);
|
|
@@ -6658,11 +6720,20 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
6658
6720
|
if (toolSchemas !== void 0 && !isToolSchemaRecord(toolSchemas)) {
|
|
6659
6721
|
return void 0;
|
|
6660
6722
|
}
|
|
6723
|
+
if (entry.toolInputSchemas !== void 0 && (!toolSchemas || !isToolSchemaRecord(entry.toolInputSchemas))) {
|
|
6724
|
+
return void 0;
|
|
6725
|
+
}
|
|
6661
6726
|
let installed;
|
|
6662
6727
|
let schemas;
|
|
6663
6728
|
try {
|
|
6664
6729
|
installed = structuredClone(capabilities);
|
|
6665
6730
|
schemas = toolSchemas ? new Map(Object.entries(toolSchemas).map(([tool, properties]) => [tool, structuredClone(properties)])) : void 0;
|
|
6731
|
+
if (schemas && entry.toolInputSchemas) {
|
|
6732
|
+
toolInputSchemasByProperties.set(
|
|
6733
|
+
schemas,
|
|
6734
|
+
new Map(Object.entries(entry.toolInputSchemas).map(([tool, schema]) => [tool, structuredClone(schema)]))
|
|
6735
|
+
);
|
|
6736
|
+
}
|
|
6666
6737
|
} catch {
|
|
6667
6738
|
return void 0;
|
|
6668
6739
|
}
|
|
@@ -6683,9 +6754,13 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
6683
6754
|
name: t.name,
|
|
6684
6755
|
description: t.description
|
|
6685
6756
|
}));
|
|
6757
|
+
const discoveredInputSchemas = new Map(
|
|
6758
|
+
agentInfo.tools.filter((t) => t.inputSchema).map((t) => [t.name, t.inputSchema])
|
|
6759
|
+
);
|
|
6686
6760
|
const discoveredToolSchemas = new Map(
|
|
6687
|
-
|
|
6761
|
+
[...discoveredInputSchemas].map(([name, schema]) => [name, schema.properties ?? {}])
|
|
6688
6762
|
);
|
|
6763
|
+
toolInputSchemasByProperties.set(discoveredToolSchemas, discoveredInputSchemas);
|
|
6689
6764
|
if (discoveryContext) discoveryContext.toolSchemas = discoveredToolSchemas;
|
|
6690
6765
|
if (!usesScopedFetch && !superseded()) this.cachedToolSchemas = discoveredToolSchemas;
|
|
6691
6766
|
const advertisesCapabilitiesTool = tools.some((t) => t.name === "get_adcp_capabilities");
|
|
@@ -6728,7 +6803,8 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
6728
6803
|
options,
|
|
6729
6804
|
{
|
|
6730
6805
|
capabilities: structuredClone(capabilities2),
|
|
6731
|
-
toolSchemas: Object.fromEntries(discoveredToolSchemas)
|
|
6806
|
+
toolSchemas: Object.fromEntries(discoveredToolSchemas),
|
|
6807
|
+
toolInputSchemas: Object.fromEntries(discoveredInputSchemas)
|
|
6732
6808
|
},
|
|
6733
6809
|
false,
|
|
6734
6810
|
startedAtEpoch
|
|
@@ -7126,7 +7202,11 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
7126
7202
|
const key = this.sharedDiscoveryKey(options);
|
|
7127
7203
|
if (!key) return void 0;
|
|
7128
7204
|
if (patch.endpoint && !this.isDiscoverableEndpoint(patch.endpoint.agentUri)) {
|
|
7129
|
-
patch = {
|
|
7205
|
+
patch = {
|
|
7206
|
+
capabilities: patch.capabilities,
|
|
7207
|
+
toolSchemas: patch.toolSchemas,
|
|
7208
|
+
toolInputSchemas: patch.toolInputSchemas
|
|
7209
|
+
};
|
|
7130
7210
|
if (!patch.capabilities && !patch.toolSchemas) return void 0;
|
|
7131
7211
|
}
|
|
7132
7212
|
const config = this.config.discoveryCache;
|
|
@@ -7154,10 +7234,17 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
7154
7234
|
const entry = {
|
|
7155
7235
|
...existing?.capabilities && { capabilities: existing.capabilities },
|
|
7156
7236
|
...existing?.toolSchemas && { toolSchemas: existing.toolSchemas },
|
|
7237
|
+
// Endpoint-only writes retain schema documents. Fresh tool evidence
|
|
7238
|
+
// replaces them together, including clearing older full documents
|
|
7239
|
+
// when the caller supplies only a property map.
|
|
7240
|
+
...patch.toolSchemas === void 0 && existing?.toolInputSchemas && {
|
|
7241
|
+
toolInputSchemas: existing.toolInputSchemas
|
|
7242
|
+
},
|
|
7157
7243
|
...existing?.endpoint && { endpoint: existing.endpoint },
|
|
7158
7244
|
...patch.endpoint && { endpoint: { ...patch.endpoint, observedAt: now } },
|
|
7159
7245
|
...patch.capabilities && { capabilities: patch.capabilities },
|
|
7160
7246
|
...patch.toolSchemas && { toolSchemas: patch.toolSchemas },
|
|
7247
|
+
...patch.toolInputSchemas && { toolInputSchemas: patch.toolInputSchemas },
|
|
7161
7248
|
observedAt: restartsClock || !existing ? now : Math.min(existing.observedAt, now),
|
|
7162
7249
|
expiresAt: restartsClock || !existing ? now + ttl : Math.min(existing.expiresAt, now + ttl)
|
|
7163
7250
|
};
|
|
@@ -20,6 +20,8 @@ export interface AgentDiscoveryEntry {
|
|
|
20
20
|
capabilities?: AdcpCapabilities;
|
|
21
21
|
/** `tools/list` input-schema properties keyed by tool name. */
|
|
22
22
|
toolSchemas?: Record<string, Record<string, unknown>>;
|
|
23
|
+
/** Complete listed input schemas, including local reference targets; absent in older entries. Backends must allow space for both these documents and their property maps. */
|
|
24
|
+
toolInputSchemas?: Record<string, Record<string, unknown>>;
|
|
23
25
|
/** Epoch milliseconds when this evidence was observed. */
|
|
24
26
|
observedAt: number;
|
|
25
27
|
/** Epoch milliseconds after which the entry must not be used. Enforced by the SDK on read. */
|
|
@@ -20,6 +20,8 @@ export interface AgentDiscoveryEntry {
|
|
|
20
20
|
capabilities?: AdcpCapabilities;
|
|
21
21
|
/** `tools/list` input-schema properties keyed by tool name. */
|
|
22
22
|
toolSchemas?: Record<string, Record<string, unknown>>;
|
|
23
|
+
/** Complete listed input schemas, including local reference targets; absent in older entries. Backends must allow space for both these documents and their property maps. */
|
|
24
|
+
toolInputSchemas?: Record<string, Record<string, unknown>>;
|
|
23
25
|
/** Epoch milliseconds when this evidence was observed. */
|
|
24
26
|
observedAt: number;
|
|
25
27
|
/** Epoch milliseconds after which the entry must not be used. Enforced by the SDK on read. */
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { CreativeFormatWireMode } from '../v2/projection/creative-delivery.mjs';
|
|
2
|
+
/** Inspect reachable input schemas without fetching references or treating unused definitions as evidence. */
|
|
3
|
+
export declare function creativeSchemaSupport(inputSchema: unknown): CreativeFormatWireMode;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { CreativeFormatWireMode } from '../v2/projection/creative-delivery';
|
|
2
|
+
/** Inspect reachable input schemas without fetching references or treating unused definitions as evidence. */
|
|
3
|
+
export declare function creativeSchemaSupport(inputSchema: unknown): CreativeFormatWireMode;
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var creative_schema_support_exports = {};
|
|
20
|
+
__export(creative_schema_support_exports, {
|
|
21
|
+
creativeSchemaSupport: () => creativeSchemaSupport
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(creative_schema_support_exports);
|
|
24
|
+
function creativeSchemaSupport(inputSchema) {
|
|
25
|
+
const visited = /* @__PURE__ */ new WeakSet();
|
|
26
|
+
let remaining = 1e4;
|
|
27
|
+
let truncated = false;
|
|
28
|
+
function resolvePointer(reference, root) {
|
|
29
|
+
if (!reference.startsWith("#")) return void 0;
|
|
30
|
+
let pointer;
|
|
31
|
+
try {
|
|
32
|
+
pointer = decodeURIComponent(reference.slice(1));
|
|
33
|
+
} catch {
|
|
34
|
+
return void 0;
|
|
35
|
+
}
|
|
36
|
+
if (pointer === "") return { value: root, root };
|
|
37
|
+
if (!pointer.startsWith("/") || /~(?![01])/.test(pointer)) return void 0;
|
|
38
|
+
let value = root;
|
|
39
|
+
for (const token of pointer.slice(1).split("/")) {
|
|
40
|
+
const key = token.replace(/~1/g, "/").replace(/~0/g, "~");
|
|
41
|
+
if (value === null || typeof value !== "object" || !Object.hasOwn(value, key)) return void 0;
|
|
42
|
+
const resource = value;
|
|
43
|
+
if (typeof resource.$id === "string" && resource.$id !== "" && !resource.$id.startsWith("#")) root = resource;
|
|
44
|
+
value = value[key];
|
|
45
|
+
}
|
|
46
|
+
return { value, root };
|
|
47
|
+
}
|
|
48
|
+
function visit(value, root, depth) {
|
|
49
|
+
if (value === null || typeof value !== "object" || visited.has(value)) {
|
|
50
|
+
return "unknown";
|
|
51
|
+
}
|
|
52
|
+
if (--remaining < 0 || depth > 64) {
|
|
53
|
+
truncated = true;
|
|
54
|
+
return "unknown";
|
|
55
|
+
}
|
|
56
|
+
visited.add(value);
|
|
57
|
+
let legacy = false;
|
|
58
|
+
const inspect = (child) => {
|
|
59
|
+
const mode2 = visit(child, root, depth + 1);
|
|
60
|
+
if (mode2 === "legacy") legacy = true;
|
|
61
|
+
return mode2 === "canonical";
|
|
62
|
+
};
|
|
63
|
+
if (Array.isArray(value)) {
|
|
64
|
+
for (const child of value) if (inspect(child)) return "canonical";
|
|
65
|
+
return legacy ? "legacy" : "unknown";
|
|
66
|
+
}
|
|
67
|
+
const schema = value;
|
|
68
|
+
if (typeof schema.$id === "string" && schema.$id !== "" && !schema.$id.startsWith("#")) root = schema;
|
|
69
|
+
const properties = schema.properties;
|
|
70
|
+
if (properties !== null && typeof properties === "object" && !Array.isArray(properties)) {
|
|
71
|
+
const fields = properties;
|
|
72
|
+
if (Object.hasOwn(fields, "creative_id") && fields.creative_id !== false) {
|
|
73
|
+
if (Object.hasOwn(fields, "format_kind") && fields.format_kind !== false) return "canonical";
|
|
74
|
+
if (Object.hasOwn(fields, "format_id") && fields.format_id !== false) legacy = true;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
if (typeof schema.$ref === "string") {
|
|
78
|
+
const target = resolvePointer(schema.$ref, root);
|
|
79
|
+
if (target) {
|
|
80
|
+
const mode2 = visit(target.value, target.root, depth + 1);
|
|
81
|
+
if (mode2 === "canonical") return mode2;
|
|
82
|
+
if (mode2 === "legacy") legacy = true;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
for (const keyword of ["properties", "patternProperties", "dependentSchemas"]) {
|
|
86
|
+
const children = schema[keyword];
|
|
87
|
+
if (children !== null && typeof children === "object" && !Array.isArray(children)) {
|
|
88
|
+
for (const child of Object.values(children)) if (inspect(child)) return "canonical";
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
for (const keyword of [
|
|
92
|
+
"items",
|
|
93
|
+
"prefixItems",
|
|
94
|
+
"contains",
|
|
95
|
+
"additionalItems",
|
|
96
|
+
"additionalProperties",
|
|
97
|
+
"unevaluatedItems",
|
|
98
|
+
"unevaluatedProperties",
|
|
99
|
+
"allOf",
|
|
100
|
+
"anyOf",
|
|
101
|
+
"oneOf"
|
|
102
|
+
]) {
|
|
103
|
+
if (inspect(schema[keyword])) return "canonical";
|
|
104
|
+
}
|
|
105
|
+
return legacy ? "legacy" : "unknown";
|
|
106
|
+
}
|
|
107
|
+
const mode = visit(inputSchema, inputSchema, 0);
|
|
108
|
+
return truncated ? "unknown" : mode;
|
|
109
|
+
}
|
|
110
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
111
|
+
0 && (module.exports = {
|
|
112
|
+
creativeSchemaSupport
|
|
113
|
+
});
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
function creativeSchemaSupport(inputSchema) {
|
|
2
|
+
const visited = /* @__PURE__ */ new WeakSet();
|
|
3
|
+
let remaining = 1e4;
|
|
4
|
+
let truncated = false;
|
|
5
|
+
function resolvePointer(reference, root) {
|
|
6
|
+
if (!reference.startsWith("#")) return void 0;
|
|
7
|
+
let pointer;
|
|
8
|
+
try {
|
|
9
|
+
pointer = decodeURIComponent(reference.slice(1));
|
|
10
|
+
} catch {
|
|
11
|
+
return void 0;
|
|
12
|
+
}
|
|
13
|
+
if (pointer === "") return { value: root, root };
|
|
14
|
+
if (!pointer.startsWith("/") || /~(?![01])/.test(pointer)) return void 0;
|
|
15
|
+
let value = root;
|
|
16
|
+
for (const token of pointer.slice(1).split("/")) {
|
|
17
|
+
const key = token.replace(/~1/g, "/").replace(/~0/g, "~");
|
|
18
|
+
if (value === null || typeof value !== "object" || !Object.hasOwn(value, key)) return void 0;
|
|
19
|
+
const resource = value;
|
|
20
|
+
if (typeof resource.$id === "string" && resource.$id !== "" && !resource.$id.startsWith("#")) root = resource;
|
|
21
|
+
value = value[key];
|
|
22
|
+
}
|
|
23
|
+
return { value, root };
|
|
24
|
+
}
|
|
25
|
+
function visit(value, root, depth) {
|
|
26
|
+
if (value === null || typeof value !== "object" || visited.has(value)) {
|
|
27
|
+
return "unknown";
|
|
28
|
+
}
|
|
29
|
+
if (--remaining < 0 || depth > 64) {
|
|
30
|
+
truncated = true;
|
|
31
|
+
return "unknown";
|
|
32
|
+
}
|
|
33
|
+
visited.add(value);
|
|
34
|
+
let legacy = false;
|
|
35
|
+
const inspect = (child) => {
|
|
36
|
+
const mode2 = visit(child, root, depth + 1);
|
|
37
|
+
if (mode2 === "legacy") legacy = true;
|
|
38
|
+
return mode2 === "canonical";
|
|
39
|
+
};
|
|
40
|
+
if (Array.isArray(value)) {
|
|
41
|
+
for (const child of value) if (inspect(child)) return "canonical";
|
|
42
|
+
return legacy ? "legacy" : "unknown";
|
|
43
|
+
}
|
|
44
|
+
const schema = value;
|
|
45
|
+
if (typeof schema.$id === "string" && schema.$id !== "" && !schema.$id.startsWith("#")) root = schema;
|
|
46
|
+
const properties = schema.properties;
|
|
47
|
+
if (properties !== null && typeof properties === "object" && !Array.isArray(properties)) {
|
|
48
|
+
const fields = properties;
|
|
49
|
+
if (Object.hasOwn(fields, "creative_id") && fields.creative_id !== false) {
|
|
50
|
+
if (Object.hasOwn(fields, "format_kind") && fields.format_kind !== false) return "canonical";
|
|
51
|
+
if (Object.hasOwn(fields, "format_id") && fields.format_id !== false) legacy = true;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
if (typeof schema.$ref === "string") {
|
|
55
|
+
const target = resolvePointer(schema.$ref, root);
|
|
56
|
+
if (target) {
|
|
57
|
+
const mode2 = visit(target.value, target.root, depth + 1);
|
|
58
|
+
if (mode2 === "canonical") return mode2;
|
|
59
|
+
if (mode2 === "legacy") legacy = true;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
for (const keyword of ["properties", "patternProperties", "dependentSchemas"]) {
|
|
63
|
+
const children = schema[keyword];
|
|
64
|
+
if (children !== null && typeof children === "object" && !Array.isArray(children)) {
|
|
65
|
+
for (const child of Object.values(children)) if (inspect(child)) return "canonical";
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
for (const keyword of [
|
|
69
|
+
"items",
|
|
70
|
+
"prefixItems",
|
|
71
|
+
"contains",
|
|
72
|
+
"additionalItems",
|
|
73
|
+
"additionalProperties",
|
|
74
|
+
"unevaluatedItems",
|
|
75
|
+
"unevaluatedProperties",
|
|
76
|
+
"allOf",
|
|
77
|
+
"anyOf",
|
|
78
|
+
"oneOf"
|
|
79
|
+
]) {
|
|
80
|
+
if (inspect(schema[keyword])) return "canonical";
|
|
81
|
+
}
|
|
82
|
+
return legacy ? "legacy" : "unknown";
|
|
83
|
+
}
|
|
84
|
+
const mode = visit(inputSchema, inputSchema, 0);
|
|
85
|
+
return truncated ? "unknown" : mode;
|
|
86
|
+
}
|
|
87
|
+
export {
|
|
88
|
+
creativeSchemaSupport
|
|
89
|
+
};
|
|
@@ -23,6 +23,7 @@ __export(product_cache_exports, {
|
|
|
23
23
|
});
|
|
24
24
|
module.exports = __toCommonJS(product_cache_exports);
|
|
25
25
|
var import_account_key = require('./account-key.js');
|
|
26
|
+
var import_legacy_metadata = require('../v2/projection/legacy-metadata.js');
|
|
26
27
|
function stable(value) {
|
|
27
28
|
if (Array.isArray(value)) return value.map(stable);
|
|
28
29
|
if (value && typeof value === "object")
|
|
@@ -69,7 +70,7 @@ class ProductCache {
|
|
|
69
70
|
if (!allowExpired && Date.now() - entry.storedAt >= ttl) return void 0;
|
|
70
71
|
return {
|
|
71
72
|
...entry.result,
|
|
72
|
-
data:
|
|
73
|
+
data: (0, import_legacy_metadata.structuredCloneWithLegacyCreativeMetadata)(entry.result.data),
|
|
73
74
|
metadata: structuredClone(entry.result.metadata),
|
|
74
75
|
...entry.result.debug_logs && { debug_logs: structuredClone(entry.result.debug_logs) }
|
|
75
76
|
};
|
|
@@ -107,14 +108,14 @@ class ProductCache {
|
|
|
107
108
|
if (!old || old.scope !== data.cache_scope || !oldData || data.wholesale_feed_version !== oldData.wholesale_feed_version || data.pricing_version !== void 0 && data.pricing_version !== oldData.pricing_version)
|
|
108
109
|
return result;
|
|
109
110
|
if (params.if_wholesale_feed_version !== void 0 || params.if_pricing_version !== void 0) return result;
|
|
110
|
-
completed = { ...result, data:
|
|
111
|
+
completed = { ...result, data: (0, import_legacy_metadata.structuredCloneWithLegacyCreativeMetadata)(oldData) };
|
|
111
112
|
} else if (!Array.isArray(data.products)) return result;
|
|
112
113
|
if (!this.entries.has(key) && this.entries.size >= (this.options.maxEntries ?? 1e3))
|
|
113
114
|
this.entries.delete(this.entries.keys().next().value);
|
|
114
115
|
this.entries.set(key, {
|
|
115
116
|
result: {
|
|
116
117
|
...completed,
|
|
117
|
-
data:
|
|
118
|
+
data: (0, import_legacy_metadata.structuredCloneWithLegacyCreativeMetadata)(completed.data),
|
|
118
119
|
metadata: structuredClone(completed.metadata),
|
|
119
120
|
...completed.debug_logs && { debug_logs: structuredClone(completed.debug_logs) }
|
|
120
121
|
},
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { accountReferenceKey } from "./account-key.mjs";
|
|
2
|
+
import { structuredCloneWithLegacyCreativeMetadata } from "../v2/projection/legacy-metadata.mjs";
|
|
2
3
|
function stable(value) {
|
|
3
4
|
if (Array.isArray(value)) return value.map(stable);
|
|
4
5
|
if (value && typeof value === "object")
|
|
@@ -45,7 +46,7 @@ class ProductCache {
|
|
|
45
46
|
if (!allowExpired && Date.now() - entry.storedAt >= ttl) return void 0;
|
|
46
47
|
return {
|
|
47
48
|
...entry.result,
|
|
48
|
-
data:
|
|
49
|
+
data: structuredCloneWithLegacyCreativeMetadata(entry.result.data),
|
|
49
50
|
metadata: structuredClone(entry.result.metadata),
|
|
50
51
|
...entry.result.debug_logs && { debug_logs: structuredClone(entry.result.debug_logs) }
|
|
51
52
|
};
|
|
@@ -83,14 +84,14 @@ class ProductCache {
|
|
|
83
84
|
if (!old || old.scope !== data.cache_scope || !oldData || data.wholesale_feed_version !== oldData.wholesale_feed_version || data.pricing_version !== void 0 && data.pricing_version !== oldData.pricing_version)
|
|
84
85
|
return result;
|
|
85
86
|
if (params.if_wholesale_feed_version !== void 0 || params.if_pricing_version !== void 0) return result;
|
|
86
|
-
completed = { ...result, data:
|
|
87
|
+
completed = { ...result, data: structuredCloneWithLegacyCreativeMetadata(oldData) };
|
|
87
88
|
} else if (!Array.isArray(data.products)) return result;
|
|
88
89
|
if (!this.entries.has(key) && this.entries.size >= (this.options.maxEntries ?? 1e3))
|
|
89
90
|
this.entries.delete(this.entries.keys().next().value);
|
|
90
91
|
this.entries.set(key, {
|
|
91
92
|
result: {
|
|
92
93
|
...completed,
|
|
93
|
-
data:
|
|
94
|
+
data: structuredCloneWithLegacyCreativeMetadata(completed.data),
|
|
94
95
|
metadata: structuredClone(completed.metadata),
|
|
95
96
|
...completed.debug_logs && { debug_logs: structuredClone(completed.debug_logs) }
|
|
96
97
|
},
|