@adcp/sdk 9.0.0-beta.29 → 9.0.0-beta.31
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/bin/adcp.js +46 -2
- package/dist/lib/adapters/version/3.0/brand-fields.d.ts +4 -0
- package/dist/lib/adapters/version/3.0/brand-fields.d.ts.map +1 -0
- package/dist/lib/adapters/version/3.0/brand-fields.js +30 -0
- package/dist/lib/adapters/version/3.0/brand-fields.js.map +1 -0
- package/dist/lib/adapters/version/3.0/index.d.ts +3 -0
- package/dist/lib/adapters/version/3.0/index.d.ts.map +1 -0
- package/dist/lib/adapters/version/3.0/index.js +11 -0
- package/dist/lib/adapters/version/3.0/index.js.map +1 -0
- package/dist/lib/adapters/version/3.0/sync-accounts.d.ts +3 -0
- package/dist/lib/adapters/version/3.0/sync-accounts.d.ts.map +1 -0
- package/dist/lib/adapters/version/3.0/sync-accounts.js +34 -0
- package/dist/lib/adapters/version/3.0/sync-accounts.js.map +1 -0
- package/dist/lib/adapters/version/index.d.ts +38 -0
- package/dist/lib/adapters/version/index.d.ts.map +1 -0
- package/dist/lib/adapters/version/index.js +53 -0
- package/dist/lib/adapters/version/index.js.map +1 -0
- package/dist/lib/adapters/version/types.d.ts +34 -0
- package/dist/lib/adapters/version/types.d.ts.map +1 -0
- package/dist/lib/adapters/version/types.js +15 -0
- package/dist/lib/adapters/version/types.js.map +1 -0
- package/dist/lib/core/AgentClient.d.ts.map +1 -1
- package/dist/lib/core/ProtocolResponseParser.d.ts +2 -20
- package/dist/lib/core/ProtocolResponseParser.d.ts.map +1 -1
- package/dist/lib/core/ProtocolResponseParser.js +16 -113
- package/dist/lib/core/ProtocolResponseParser.js.map +1 -1
- package/dist/lib/core/SingleAgentClient.d.ts +25 -4
- package/dist/lib/core/SingleAgentClient.d.ts.map +1 -1
- package/dist/lib/core/SingleAgentClient.js +161 -67
- package/dist/lib/core/SingleAgentClient.js.map +1 -1
- package/dist/lib/core/task-status.d.ts +34 -0
- package/dist/lib/core/task-status.d.ts.map +1 -0
- package/dist/lib/core/task-status.js +87 -0
- package/dist/lib/core/task-status.js.map +1 -0
- package/dist/lib/index.d.ts +3 -2
- package/dist/lib/index.d.ts.map +1 -1
- package/dist/lib/index.js +7 -6
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/registry/index.d.ts +17 -2
- package/dist/lib/registry/index.d.ts.map +1 -1
- package/dist/lib/registry/index.js +84 -0
- package/dist/lib/registry/index.js.map +1 -1
- package/dist/lib/registry/types.d.ts +89 -0
- package/dist/lib/registry/types.d.ts.map +1 -1
- package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
- package/dist/lib/server/create-adcp-server.d.ts +20 -5
- package/dist/lib/server/create-adcp-server.d.ts.map +1 -1
- package/dist/lib/server/create-adcp-server.js +29 -16
- package/dist/lib/server/create-adcp-server.js.map +1 -1
- package/dist/lib/server/decisioning/tenant-registry.d.ts.map +1 -1
- package/dist/lib/server/decisioning/tenant-registry.js +14 -12
- package/dist/lib/server/decisioning/tenant-registry.js.map +1 -1
- package/dist/lib/server/webhook-emitter.d.ts +14 -14
- package/dist/lib/server/webhook-emitter.d.ts.map +1 -1
- package/dist/lib/signing/errors.d.ts.map +1 -1
- package/dist/lib/signing/errors.js.map +1 -1
- package/dist/lib/signing/jwks-helpers.d.ts +16 -2
- package/dist/lib/signing/jwks-helpers.d.ts.map +1 -1
- package/dist/lib/signing/jwks-helpers.js.map +1 -1
- package/dist/lib/signing/signer-async.d.ts.map +1 -1
- package/dist/lib/signing/signer-async.js +1 -1
- package/dist/lib/signing/signer-async.js.map +1 -1
- package/dist/lib/signing/signer.d.ts +9 -2
- package/dist/lib/signing/signer.d.ts.map +1 -1
- package/dist/lib/signing/signer.js +28 -1
- package/dist/lib/signing/signer.js.map +1 -1
- package/dist/lib/signing/webhook-verifier.d.ts +2 -1
- package/dist/lib/signing/webhook-verifier.d.ts.map +1 -1
- package/dist/lib/signing/webhook-verifier.js +25 -14
- package/dist/lib/signing/webhook-verifier.js.map +1 -1
- package/dist/lib/testing/storyboard/compliance.d.ts +18 -0
- package/dist/lib/testing/storyboard/compliance.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/compliance.js +30 -1
- package/dist/lib/testing/storyboard/compliance.js.map +1 -1
- package/dist/lib/testing/storyboard/runner.d.ts +6 -8
- package/dist/lib/testing/storyboard/runner.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/runner.js +107 -47
- package/dist/lib/testing/storyboard/runner.js.map +1 -1
- package/dist/lib/testing/storyboard/task-map.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/task-map.js +6 -0
- package/dist/lib/testing/storyboard/task-map.js.map +1 -1
- package/dist/lib/testing/storyboard/types.d.ts +31 -12
- package/dist/lib/testing/storyboard/types.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/types.js.map +1 -1
- package/dist/lib/types/adcp.d.ts +13 -5
- package/dist/lib/types/adcp.d.ts.map +1 -1
- package/dist/lib/utils/adcp-version-config.d.ts +22 -0
- package/dist/lib/utils/adcp-version-config.d.ts.map +1 -1
- package/dist/lib/utils/adcp-version-config.js +37 -0
- package/dist/lib/utils/adcp-version-config.js.map +1 -1
- package/dist/lib/utils/index.d.ts +1 -0
- package/dist/lib/utils/index.d.ts.map +1 -1
- package/dist/lib/utils/index.js +4 -2
- package/dist/lib/utils/index.js.map +1 -1
- package/dist/lib/utils/response-unwrapper.d.ts.map +1 -1
- package/dist/lib/utils/response-unwrapper.js +3 -2
- package/dist/lib/utils/response-unwrapper.js.map +1 -1
- package/dist/lib/utils/task-state.d.ts +30 -0
- package/dist/lib/utils/task-state.d.ts.map +1 -0
- package/dist/lib/utils/task-state.js +109 -0
- package/dist/lib/utils/task-state.js.map +1 -0
- package/dist/lib/version.d.ts +3 -3
- package/dist/lib/version.js +3 -3
- package/package.json +4 -3
|
@@ -41,6 +41,7 @@ const schemas = __importStar(require("../types/schemas.generated"));
|
|
|
41
41
|
const adcp_1 = require("../types/adcp");
|
|
42
42
|
const version_1 = require("../version");
|
|
43
43
|
const adcp_version_config_1 = require("../utils/adcp-version-config");
|
|
44
|
+
const version_2 = require("../adapters/version");
|
|
44
45
|
const idempotency_1 = require("../utils/idempotency");
|
|
45
46
|
const TaskExecutor_1 = require("./TaskExecutor");
|
|
46
47
|
const match_1 = require("./match");
|
|
@@ -1045,6 +1046,10 @@ class SingleAgentClient {
|
|
|
1045
1046
|
skipAccountValidation: options?.skipAccountValidation,
|
|
1046
1047
|
});
|
|
1047
1048
|
this.assertRequestSupportedByConfiguredVersion(taskType, normalizedParams, options);
|
|
1049
|
+
// Degrade an auto-injected discovery webhook to polling for pre-3.1 pins
|
|
1050
|
+
// (get_products / get_signals). `effectiveOptions` carries disableWebhook
|
|
1051
|
+
// so no push_notification_config reaches a seller that can't accept it.
|
|
1052
|
+
const { options: effectiveOptions, driftLog: webhookDriftLog } = this.suppressPre31DiscoveryWebhook(taskType, options);
|
|
1048
1053
|
// Inject an idempotency_key for mutating tools before schema validation
|
|
1049
1054
|
// so callers don't have to supply one. TaskExecutor also guards against
|
|
1050
1055
|
// missing keys, but validation happens here first — do the injection up
|
|
@@ -1088,27 +1093,32 @@ class SingleAgentClient {
|
|
|
1088
1093
|
if (!options?.skipIdempotencyAutoInject && !options?.skipAccountValidation) {
|
|
1089
1094
|
this.executor.validateRequest(taskType, normalizedParams);
|
|
1090
1095
|
}
|
|
1091
|
-
// Adapt request for
|
|
1096
|
+
// Adapt request for the detected server and AdCP protocol versions.
|
|
1092
1097
|
const serverVersion = await this.detectServerVersion();
|
|
1093
|
-
const
|
|
1098
|
+
const inputSchemaStripLogs = [];
|
|
1099
|
+
const { params: adaptedParams, driftLogs: adaptDriftLogs } = this.adaptRequest(taskType, normalizedParams, serverVersion, inputSchemaStripLogs);
|
|
1094
1100
|
// Symmetric to the pre-adapter v3 pass above: when the adapter
|
|
1095
1101
|
// rewrote the request for a v2 server, warn-validate the adapted
|
|
1096
1102
|
// shape against the cached v2.5 schema bundle. Drift gets collected
|
|
1097
1103
|
// here and merged into result.metadata.debug_logs after executeTask
|
|
1098
1104
|
// returns — without that merge the warning would silently drop on
|
|
1099
1105
|
// the floor and adapter drift would land in production unnoticed.
|
|
1100
|
-
const v25DriftLogs = [];
|
|
1106
|
+
const v25DriftLogs = [...adaptDriftLogs];
|
|
1107
|
+
if (webhookDriftLog)
|
|
1108
|
+
v25DriftLogs.push(webhookDriftLog);
|
|
1101
1109
|
if (serverVersion === 'v2') {
|
|
1102
1110
|
this.executor.validateAdaptedRequestAgainstV2(taskType, adaptedParams, v25DriftLogs);
|
|
1103
1111
|
}
|
|
1104
|
-
let result = await this.executor.executeTask(agent, taskType, adaptedParams, inputHandler,
|
|
1112
|
+
let result = await this.executor.executeTask(agent, taskType, adaptedParams, inputHandler, effectiveOptions, serverVersion);
|
|
1105
1113
|
// Merge collected drift into the executor's debug_logs so adopters
|
|
1106
|
-
// reading result.debug_logs see post-adapter
|
|
1114
|
+
// reading result.debug_logs see input-schema stripping, post-adapter
|
|
1115
|
+
// v2.5 warnings, and any pre-3.1 webhook-degradation notice alongside
|
|
1107
1116
|
// the executor's own logs. On error paths the executor may not surface
|
|
1108
|
-
// result.debug_logs at all
|
|
1117
|
+
// result.debug_logs at all; logs collected before the failure are
|
|
1109
1118
|
// dropped, matching the executor's own debug-log behavior.
|
|
1110
|
-
|
|
1111
|
-
|
|
1119
|
+
const postAdapterLogs = [...inputSchemaStripLogs, ...v25DriftLogs];
|
|
1120
|
+
if (postAdapterLogs.length > 0) {
|
|
1121
|
+
result.debug_logs = [...(result.debug_logs ?? []), ...postAdapterLogs];
|
|
1112
1122
|
}
|
|
1113
1123
|
// Normalize response to v3 format
|
|
1114
1124
|
if (result.success && result.data) {
|
|
@@ -1428,15 +1438,19 @@ class SingleAgentClient {
|
|
|
1428
1438
|
};
|
|
1429
1439
|
}
|
|
1430
1440
|
/**
|
|
1431
|
-
* Adapt request
|
|
1441
|
+
* Adapt a request for the detected server wire version and the seller's
|
|
1442
|
+
* AdCP protocol version. Applies wire-format adapters (v2.5) when talking
|
|
1443
|
+
* to a v2 server, then applies protocol-version adapters (e.g. stripping
|
|
1444
|
+
* 3.1-only fields for a 3.0 seller). Returns the adapted params and any
|
|
1445
|
+
* drift log entries describing what was changed.
|
|
1432
1446
|
*
|
|
1433
|
-
*
|
|
1447
|
+
* Runs after `detectServerVersion` so `cachedCapabilities` is populated
|
|
1448
|
+
* and the protocol-version adapters see the seller's declared caps.
|
|
1434
1449
|
*/
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
const version = await this.detectServerVersion();
|
|
1450
|
+
adaptRequest(taskType, params, serverVersion, debugLogs) {
|
|
1451
|
+
const driftLogs = [];
|
|
1438
1452
|
let adapted = params;
|
|
1439
|
-
if (
|
|
1453
|
+
if (serverVersion !== 'v3') {
|
|
1440
1454
|
// Dispatch through the legacy v2.5 adapter registry. Per-tool pairs
|
|
1441
1455
|
// live in `src/lib/adapters/legacy/v2-5/<tool>.ts`. Tools without a
|
|
1442
1456
|
// registered pair (or pairs whose request side is pass-through)
|
|
@@ -1445,7 +1459,7 @@ class SingleAgentClient {
|
|
|
1445
1459
|
// this dispatch.
|
|
1446
1460
|
const pair = (0, v2_5_1.getV25Adapter)(taskType);
|
|
1447
1461
|
if (pair)
|
|
1448
|
-
adapted = pair.adaptRequest(
|
|
1462
|
+
adapted = pair.adaptRequest(adapted);
|
|
1449
1463
|
}
|
|
1450
1464
|
// Strip any top-level fields not declared in the agent's tool schema.
|
|
1451
1465
|
// This handles partial implementations (agents that omit some fields)
|
|
@@ -1469,49 +1483,82 @@ class SingleAgentClient {
|
|
|
1469
1483
|
// (e.g. `applyBrandInvariant` in the storyboard runner — see #940),
|
|
1470
1484
|
// not to lean on this strip path as a backstop.
|
|
1471
1485
|
const toolSchema = this.cachedToolSchemas?.get(taskType);
|
|
1472
|
-
if (
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1486
|
+
if (toolSchema && Object.keys(toolSchema).length > 0) {
|
|
1487
|
+
const declaredFields = new Set(Object.keys(toolSchema));
|
|
1488
|
+
// The v2 adapter may rename fields (e.g. brand → brand_manifest) that a
|
|
1489
|
+
// v3 server — misdetected as v2 — doesn't declare. Reconcile known
|
|
1490
|
+
// adapter mappings so the value isn't silently dropped.
|
|
1491
|
+
//
|
|
1492
|
+
// CRITICAL: only alias when the JS type of the moved value is
|
|
1493
|
+
// compatible with the destination field's declared shape. v2.5 sellers
|
|
1494
|
+
// (e.g. Wonderstruck) declare `brand` in their tool schema as a
|
|
1495
|
+
// BrandReference object — v2 adapter produces a `brand_manifest` URL
|
|
1496
|
+
// string, and blindly aliasing the string into the object slot causes
|
|
1497
|
+
// the seller to reject with `Input should be a valid dictionary or
|
|
1498
|
+
// instance of BrandReference`. Skip the alias when shapes don't match
|
|
1499
|
+
// and let the field-stripping path drop the v2-shaped value cleanly.
|
|
1500
|
+
const adapterAliases = [['brand_manifest', 'brand']];
|
|
1501
|
+
for (const [adapterField, schemaField] of adapterAliases) {
|
|
1502
|
+
if (adapted[adapterField] !== undefined &&
|
|
1503
|
+
!declaredFields.has(adapterField) &&
|
|
1504
|
+
declaredFields.has(schemaField) &&
|
|
1505
|
+
adapted[schemaField] === undefined &&
|
|
1506
|
+
valueMatchesSchemaType(adapted[adapterField], toolSchema[schemaField])) {
|
|
1507
|
+
adapted[schemaField] = adapted[adapterField];
|
|
1508
|
+
delete adapted[adapterField];
|
|
1509
|
+
}
|
|
1496
1510
|
}
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1511
|
+
// Protocol envelope fields are always preserved — they live at the
|
|
1512
|
+
// protocol layer, not in individual tool schemas.
|
|
1513
|
+
const envelopeFields = adcp_1.ADCP_ENVELOPE_FIELDS;
|
|
1514
|
+
const filtered = {};
|
|
1515
|
+
const schemaStripped = [];
|
|
1516
|
+
for (const [key, value] of Object.entries(adapted)) {
|
|
1517
|
+
if (declaredFields.has(key) || envelopeFields.has(key)) {
|
|
1518
|
+
filtered[key] = value;
|
|
1519
|
+
}
|
|
1520
|
+
else {
|
|
1521
|
+
schemaStripped.push(key);
|
|
1522
|
+
}
|
|
1506
1523
|
}
|
|
1507
|
-
|
|
1508
|
-
|
|
1524
|
+
if (schemaStripped.length > 0) {
|
|
1525
|
+
console.warn(`[AdCP] Stripping fields not declared in agent "${this.agent.id}" schema for ${taskType}: ${schemaStripped.join(', ')}`);
|
|
1526
|
+
debugLogs?.push({
|
|
1527
|
+
type: 'warning',
|
|
1528
|
+
message: `Stripped fields not declared in agent tool input schema for ${taskType}: ${schemaStripped.join(', ')}`,
|
|
1529
|
+
timestamp: new Date().toISOString(),
|
|
1530
|
+
details: {
|
|
1531
|
+
code: 'input_schema_field_stripped',
|
|
1532
|
+
task: taskType,
|
|
1533
|
+
fields: schemaStripped,
|
|
1534
|
+
agent_id: this.agent.id,
|
|
1535
|
+
},
|
|
1536
|
+
});
|
|
1537
|
+
}
|
|
1538
|
+
adapted = filtered;
|
|
1539
|
+
}
|
|
1540
|
+
// Protocol version adaptation: strip fields not accepted by the target
|
|
1541
|
+
// AdCP version. `resolveAdapterKey` returns the effective target version
|
|
1542
|
+
// based on the client pin and the seller's advertised caps; adapters live
|
|
1543
|
+
// in `src/lib/adapters/version/<target>/`.
|
|
1544
|
+
const adapterKey = (0, version_2.resolveAdapterKey)(this.resolvedAdcpVersion, this.cachedCapabilities);
|
|
1545
|
+
if (adapterKey) {
|
|
1546
|
+
const versionAdapter = (0, version_2.getVersionAdapter)(adapterKey, taskType);
|
|
1547
|
+
if (versionAdapter) {
|
|
1548
|
+
const result = versionAdapter.adaptRequest(adapted);
|
|
1549
|
+
adapted = result.params;
|
|
1550
|
+
if (result.drift) {
|
|
1551
|
+
driftLogs.push({
|
|
1552
|
+
...result.drift,
|
|
1553
|
+
taskName: taskType,
|
|
1554
|
+
clientVersion: this.resolvedAdcpVersion,
|
|
1555
|
+
targetVersion: adapterKey,
|
|
1556
|
+
timestamp: new Date().toISOString(),
|
|
1557
|
+
});
|
|
1558
|
+
}
|
|
1509
1559
|
}
|
|
1510
1560
|
}
|
|
1511
|
-
|
|
1512
|
-
console.warn(`[AdCP] Stripping fields not declared in agent "${this.agent.id}" schema for ${taskType}: ${stripped.join(', ')}`);
|
|
1513
|
-
}
|
|
1514
|
-
return filtered;
|
|
1561
|
+
return { params: adapted, driftLogs };
|
|
1515
1562
|
}
|
|
1516
1563
|
/**
|
|
1517
1564
|
* Normalize response to v3 format
|
|
@@ -1955,6 +2002,10 @@ class SingleAgentClient {
|
|
|
1955
2002
|
skipAccountValidation: options?.skipAccountValidation,
|
|
1956
2003
|
});
|
|
1957
2004
|
this.assertRequestSupportedByConfiguredVersion(taskName, normalizedParams, options);
|
|
2005
|
+
// Degrade an auto-injected discovery webhook to polling for pre-3.1 pins
|
|
2006
|
+
// (get_products / get_signals). `effectiveOptions` carries disableWebhook
|
|
2007
|
+
// so no push_notification_config reaches a seller that can't accept it.
|
|
2008
|
+
const { options: effectiveOptions, driftLog: webhookDriftLog } = this.suppressPre31DiscoveryWebhook(taskName, options);
|
|
1958
2009
|
await this.validateTaskFeatures(taskName);
|
|
1959
2010
|
if (this.config.requireV3ForMutations && (0, idempotency_1.isMutatingTask)(taskName)) {
|
|
1960
2011
|
await this.requireSupportedMajor(taskName);
|
|
@@ -1968,20 +2019,23 @@ class SingleAgentClient {
|
|
|
1968
2019
|
if (!options?.skipIdempotencyAutoInject && !options?.skipAccountValidation) {
|
|
1969
2020
|
this.executor.validateRequest(taskName, normalizedParams);
|
|
1970
2021
|
}
|
|
1971
|
-
// Adapt request for the server
|
|
1972
|
-
// fields like buying_mode when talking to v2 agents).
|
|
2022
|
+
// Adapt request for the detected server and AdCP protocol versions.
|
|
1973
2023
|
const serverVersion = await this.detectServerVersion();
|
|
1974
|
-
const
|
|
2024
|
+
const inputSchemaStripLogs = [];
|
|
2025
|
+
const { params: adaptedParams, driftLogs: adaptDriftLogs } = this.adaptRequest(taskName, normalizedParams, serverVersion, inputSchemaStripLogs);
|
|
1975
2026
|
// Symmetric warn-only post-adapter pass against the v2.5 schema bundle.
|
|
1976
2027
|
// Drift gets surfaced via result.metadata.debug_logs so adapter
|
|
1977
2028
|
// regressions in production aren't silently swallowed.
|
|
1978
|
-
const v25DriftLogs = [];
|
|
2029
|
+
const v25DriftLogs = [...adaptDriftLogs];
|
|
2030
|
+
if (webhookDriftLog)
|
|
2031
|
+
v25DriftLogs.push(webhookDriftLog);
|
|
1979
2032
|
if (serverVersion === 'v2') {
|
|
1980
2033
|
this.executor.validateAdaptedRequestAgainstV2(taskName, adaptedParams, v25DriftLogs);
|
|
1981
2034
|
}
|
|
1982
|
-
let result = await this.executor.executeTask(agent, taskName, adaptedParams, inputHandler,
|
|
1983
|
-
|
|
1984
|
-
|
|
2035
|
+
let result = await this.executor.executeTask(agent, taskName, adaptedParams, inputHandler, effectiveOptions, serverVersion);
|
|
2036
|
+
const postAdapterLogs = [...inputSchemaStripLogs, ...v25DriftLogs];
|
|
2037
|
+
if (postAdapterLogs.length > 0) {
|
|
2038
|
+
result.debug_logs = [...(result.debug_logs ?? []), ...postAdapterLogs];
|
|
1985
2039
|
}
|
|
1986
2040
|
// Normalize response to v3 format for consistent API surface
|
|
1987
2041
|
if (result.success && result.data) {
|
|
@@ -2518,7 +2572,7 @@ class SingleAgentClient {
|
|
|
2518
2572
|
}));
|
|
2519
2573
|
// Cache raw tool schemas for field-level compatibility checks (e.g. buying_mode on get_products).
|
|
2520
2574
|
// INVARIANT: must be assigned before cachedCapabilities below so that any code path
|
|
2521
|
-
// reaching
|
|
2575
|
+
// reaching adaptRequest always finds the schemas populated.
|
|
2522
2576
|
this.cachedToolSchemas = new Map(agentInfo.tools
|
|
2523
2577
|
.filter(t => t.inputSchema?.properties)
|
|
2524
2578
|
.map(t => [t.name, t.inputSchema.properties]));
|
|
@@ -2808,19 +2862,22 @@ class SingleAgentClient {
|
|
|
2808
2862
|
* result set. A pre-3.1 client pin should not silently drop those controls
|
|
2809
2863
|
* or let a generic schema error hide the recovery path.
|
|
2810
2864
|
*/
|
|
2811
|
-
assertRequestSupportedByConfiguredVersion(taskName, params,
|
|
2865
|
+
assertRequestSupportedByConfiguredVersion(taskName, params, _options) {
|
|
2812
2866
|
if (!(0, adcp_version_config_1.isPre31AdcpVersion)(this.resolvedAdcpVersion))
|
|
2813
2867
|
return;
|
|
2814
2868
|
const request = params && typeof params === 'object' && !Array.isArray(params) ? params : {};
|
|
2815
|
-
const willInjectDiscoveryWebhook = !options?.disableWebhook && (0, webhook_url_1.selectWebhookTemplate)(this.config.webhookUrlTemplate, taskName) !== undefined;
|
|
2816
2869
|
if (taskName === 'get_signals' && request.discovery_mode === 'wholesale') {
|
|
2817
2870
|
this.throwPre31UnsupportedFeature(taskName, 'discovery_mode', 'get_signals.discovery_mode=wholesale', {
|
|
2818
2871
|
capabilityPath: 'signals.discovery_modes',
|
|
2819
2872
|
suffix: 'Probe get_adcp_capabilities at signals.discovery_modes before issuing wholesale calls.',
|
|
2820
2873
|
});
|
|
2821
2874
|
}
|
|
2822
|
-
|
|
2823
|
-
|
|
2875
|
+
// An EXPLICIT push_notification_config on a discovery task is caller misuse
|
|
2876
|
+
// while hard-pinned <3.1: surface it rather than silently dropping the
|
|
2877
|
+
// caller's webhook. An AUTO-injected discovery webhook (from
|
|
2878
|
+
// `webhookUrlTemplate`) is degraded to polling instead; see
|
|
2879
|
+
// `suppressPre31DiscoveryWebhook`.
|
|
2880
|
+
if ((taskName === 'get_products' || taskName === 'get_signals') && request.push_notification_config !== undefined) {
|
|
2824
2881
|
this.throwPre31UnsupportedFeature(taskName, 'push_notification_config', `${taskName}.push_notification_config`, {
|
|
2825
2882
|
capabilityPath: 'adcp.supported_versions',
|
|
2826
2883
|
suffix: 'Probe get_adcp_capabilities at adcp.supported_versions before relying on discovery task webhooks.',
|
|
@@ -2831,6 +2888,43 @@ class SingleAgentClient {
|
|
|
2831
2888
|
// probes, and pre-3.1 sellers may safely ignore them and return the full
|
|
2832
2889
|
// payload.
|
|
2833
2890
|
}
|
|
2891
|
+
/**
|
|
2892
|
+
* Degrade the auto-injected get_products / get_signals discovery webhook to
|
|
2893
|
+
* polling when the client is pinned below 3.1. Discovery-task
|
|
2894
|
+
* `push_notification_config` is an AdCP 3.1 feature; a pre-3.1 seller would
|
|
2895
|
+
* reject it. Rather than throwing on the library's own auto-injected webhook
|
|
2896
|
+
* (which the caller never asked for), suppress it via `disableWebhook` and
|
|
2897
|
+
* record a `pre31_webhook_degraded` drift entry so the loss of push is
|
|
2898
|
+
* visible in `debug_logs`.
|
|
2899
|
+
*
|
|
2900
|
+
* Returns the effective options (a `disableWebhook` copy when suppressing,
|
|
2901
|
+
* otherwise the caller's unchanged) and an optional drift log to merge into
|
|
2902
|
+
* the result. Explicit caller-supplied `push_notification_config` is handled
|
|
2903
|
+
* by `assertRequestSupportedByConfiguredVersion` (it throws) and never
|
|
2904
|
+
* reaches here.
|
|
2905
|
+
*/
|
|
2906
|
+
suppressPre31DiscoveryWebhook(taskName, options) {
|
|
2907
|
+
if (!(0, adcp_version_config_1.isPre31AdcpVersion)(this.resolvedAdcpVersion))
|
|
2908
|
+
return { options };
|
|
2909
|
+
if (taskName !== 'get_products' && taskName !== 'get_signals')
|
|
2910
|
+
return { options };
|
|
2911
|
+
if (options?.disableWebhook)
|
|
2912
|
+
return { options };
|
|
2913
|
+
if ((0, webhook_url_1.selectWebhookTemplate)(this.config.webhookUrlTemplate, taskName) === undefined)
|
|
2914
|
+
return { options };
|
|
2915
|
+
return {
|
|
2916
|
+
options: { ...options, disableWebhook: true },
|
|
2917
|
+
driftLog: {
|
|
2918
|
+
type: 'pre31_webhook_degraded',
|
|
2919
|
+
message: `${taskName} discovery webhook degraded to polling: discovery-task push_notification_config ` +
|
|
2920
|
+
`requires AdCP 3.1, but this client is pinned to ${this.resolvedAdcpVersion}. ` +
|
|
2921
|
+
'The seller will not receive a push webhook; poll for the result instead.',
|
|
2922
|
+
timestamp: new Date().toISOString(),
|
|
2923
|
+
taskName,
|
|
2924
|
+
clientVersion: this.resolvedAdcpVersion,
|
|
2925
|
+
},
|
|
2926
|
+
};
|
|
2927
|
+
}
|
|
2834
2928
|
throwPre31UnsupportedFeature(taskName, field, feature, opts) {
|
|
2835
2929
|
throw new errors_1.ProtocolFeatureUnsupportedError([feature], [], this.agent.agent_uri, {
|
|
2836
2930
|
message: `${taskName} ${field} requires AdCP 3.1 or later; ` +
|
|
@@ -2986,7 +3080,7 @@ class SingleAgentClient {
|
|
|
2986
3080
|
* but unknown top-level keys pass through. This matters because callers —
|
|
2987
3081
|
* including the storyboard runner's `applyBrandInvariant` — inject
|
|
2988
3082
|
* scoping fields (`brand`, `account`) onto every outgoing request, and
|
|
2989
|
-
* `
|
|
3083
|
+
* `adaptRequest` strips those fields downstream for tools
|
|
2990
3084
|
* whose schema doesn't declare them. A strict parse here rejects the
|
|
2991
3085
|
* injected fields before the adapter gets a chance to clean them up, so
|
|
2992
3086
|
* the two passes have to agree on "extra keys are fine."
|