@adcp/sdk 17.0.0-beta.0 → 17.0.0-beta.2
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/adapters/keyed-account-store.js +1 -1
- package/dist/lib/adapters/keyed-account-store.mjs +1 -1
- package/dist/lib/adapters/version/3.0/brand-fields.d.mts +7 -1
- package/dist/lib/adapters/version/3.0/brand-fields.d.ts +7 -1
- package/dist/lib/adapters/version/3.0/brand-fields.js +139 -3
- package/dist/lib/adapters/version/3.0/brand-fields.mjs +136 -2
- package/dist/lib/adapters/version/3.0/index.js +6 -0
- package/dist/lib/adapters/version/3.0/index.mjs +7 -1
- package/dist/lib/adapters/version/3.1/bidding.js +1 -1
- package/dist/lib/adapters/version/3.1/bidding.mjs +1 -1
- package/dist/lib/adapters/version/types.d.mts +5 -0
- package/dist/lib/adapters/version/types.d.ts +5 -0
- package/dist/lib/canonical-references/index.js +2 -0
- package/dist/lib/canonical-references/index.mjs +2 -0
- package/dist/lib/client/account-changes.d.mts +3 -1
- package/dist/lib/client/account-changes.d.ts +3 -1
- package/dist/lib/client/account-changes.js +22 -2
- package/dist/lib/client/account-changes.mjs +22 -2
- package/dist/lib/conformance/oracle.js +3 -2
- package/dist/lib/conformance/oracle.mjs +3 -2
- package/dist/lib/core/AgentClient.d.mts +165 -1
- package/dist/lib/core/AgentClient.d.ts +165 -1
- package/dist/lib/core/AgentClient.js +446 -8
- package/dist/lib/core/AgentClient.mjs +446 -8
- package/dist/lib/core/ConversationTypes.d.mts +8 -0
- package/dist/lib/core/ConversationTypes.d.ts +8 -0
- package/dist/lib/core/ProtocolResponseParser.d.mts +1 -1
- package/dist/lib/core/ProtocolResponseParser.d.ts +1 -1
- package/dist/lib/core/ProtocolResponseParser.js +28 -18
- package/dist/lib/core/ProtocolResponseParser.mjs +11 -1
- package/dist/lib/core/ResponseValidator.js +1 -1
- package/dist/lib/core/ResponseValidator.mjs +1 -1
- package/dist/lib/core/SingleAgentClient.d.mts +122 -7
- package/dist/lib/core/SingleAgentClient.d.ts +122 -7
- package/dist/lib/core/SingleAgentClient.js +601 -96
- package/dist/lib/core/SingleAgentClient.mjs +590 -84
- package/dist/lib/core/TaskExecutor.d.mts +7 -0
- package/dist/lib/core/TaskExecutor.d.ts +7 -0
- package/dist/lib/core/TaskExecutor.js +23 -8
- package/dist/lib/core/TaskExecutor.mjs +23 -8
- package/dist/lib/core/task-status.d.mts +2 -0
- package/dist/lib/core/task-status.d.ts +2 -0
- package/dist/lib/core/task-status.js +11 -2
- package/dist/lib/core/task-status.mjs +9 -1
- package/dist/lib/errors/index.d.mts +22 -0
- package/dist/lib/errors/index.d.ts +22 -0
- package/dist/lib/errors/index.js +43 -0
- package/dist/lib/errors/index.mjs +42 -0
- package/dist/lib/identity-3.3/trust.d.mts +1 -4
- package/dist/lib/identity-3.3/trust.d.ts +1 -4
- package/dist/lib/identity-3.3/trust.js +34 -21
- package/dist/lib/identity-3.3/trust.mjs +34 -21
- package/dist/lib/identity-3.3/validation.js +5 -3
- package/dist/lib/identity-3.3/validation.mjs +6 -4
- package/dist/lib/index.d.mts +7 -53
- package/dist/lib/index.d.ts +7 -53
- package/dist/lib/index.js +13 -0
- package/dist/lib/index.mjs +9 -0
- package/dist/lib/media-buy/compatibility.js +6 -1
- package/dist/lib/media-buy/compatibility.mjs +6 -1
- package/dist/lib/protocols/mcp-modern.d.mts +2 -0
- package/dist/lib/protocols/mcp-modern.d.ts +2 -0
- package/dist/lib/protocols/mcp-modern.js +31 -5
- package/dist/lib/protocols/mcp-modern.mjs +31 -5
- package/dist/lib/protocols/mcp-scope.d.mts +6 -1
- package/dist/lib/protocols/mcp-scope.d.ts +6 -1
- package/dist/lib/protocols/mcp-scope.js +25 -3
- package/dist/lib/protocols/mcp-scope.mjs +24 -3
- package/dist/lib/protocols/mcp.js +12 -6
- package/dist/lib/protocols/mcp.mjs +13 -6
- package/dist/lib/reporting/inspection.js +1 -0
- package/dist/lib/reporting/inspection.mjs +1 -0
- package/dist/lib/reporting/ledger/coverage.d.mts +5 -0
- package/dist/lib/reporting/ledger/coverage.d.ts +5 -0
- package/dist/lib/reporting/ledger/coverage.js +37 -3
- package/dist/lib/reporting/ledger/coverage.mjs +36 -3
- package/dist/lib/reporting/ledger/handler.js +7 -4
- package/dist/lib/reporting/ledger/handler.mjs +7 -4
- package/dist/lib/reporting/ledger/producer.js +215 -69
- package/dist/lib/reporting/ledger/producer.mjs +217 -70
- package/dist/lib/reporting/ledger/schedule.d.mts +2 -2
- package/dist/lib/reporting/ledger/schedule.d.ts +2 -2
- package/dist/lib/reporting/ledger/schedule.js +8 -5
- package/dist/lib/reporting/ledger/schedule.mjs +8 -5
- package/dist/lib/reporting/ledger/status-ingest.d.mts +1 -1
- package/dist/lib/reporting/ledger/status-ingest.d.ts +1 -1
- package/dist/lib/reporting/ledger/status-ingest.js +4 -3
- package/dist/lib/reporting/ledger/status-ingest.mjs +4 -3
- package/dist/lib/reporting/ledger/types.d.mts +36 -1
- package/dist/lib/reporting/ledger/types.d.ts +36 -1
- package/dist/lib/reporting/service/index.d.mts +14 -1
- package/dist/lib/reporting/service/index.d.ts +14 -1
- package/dist/lib/reporting/service/index.js +24 -12
- package/dist/lib/reporting/service/index.mjs +24 -12
- package/dist/lib/schemas/browser.d.mts +2 -0
- package/dist/lib/schemas/browser.d.ts +2 -0
- package/dist/lib/schemas/browser.js +3 -0
- package/dist/lib/schemas/browser.mjs +2 -0
- package/dist/lib/schemas/index.d.mts +5 -3
- package/dist/lib/schemas/index.d.ts +5 -3
- package/dist/lib/schemas/index.js +5 -0
- package/dist/lib/schemas/index.mjs +4 -0
- package/dist/lib/server/account-response-identity.d.mts +17 -0
- package/dist/lib/server/account-response-identity.d.ts +17 -0
- package/dist/lib/server/account-response-identity.js +52 -0
- package/dist/lib/server/account-response-identity.mjs +28 -0
- package/dist/lib/server/account-sync-contract.js +2 -2
- package/dist/lib/server/account-sync-contract.mjs +2 -2
- package/dist/lib/server/create-adcp-server.js +33 -20
- package/dist/lib/server/create-adcp-server.mjs +36 -12
- package/dist/lib/server/decisioning/account.d.mts +36 -10
- package/dist/lib/server/decisioning/account.d.ts +36 -10
- package/dist/lib/server/decisioning/account.js +33 -14
- package/dist/lib/server/decisioning/account.mjs +33 -14
- package/dist/lib/server/decisioning/runtime/from-platform.d.mts +5 -5
- package/dist/lib/server/decisioning/runtime/from-platform.d.ts +5 -5
- package/dist/lib/server/decisioning/runtime/from-platform.js +4 -4
- package/dist/lib/server/decisioning/runtime/from-platform.mjs +4 -4
- package/dist/lib/server/media-buy-store.d.mts +26 -12
- package/dist/lib/server/media-buy-store.d.ts +26 -12
- package/dist/lib/server/media-buy-store.js +69 -21
- package/dist/lib/server/media-buy-store.mjs +69 -21
- package/dist/lib/server/notification-subscriptions/runtime.d.mts +1 -1
- package/dist/lib/server/notification-subscriptions/runtime.d.ts +1 -1
- package/dist/lib/server/notification-subscriptions/runtime.js +4 -0
- package/dist/lib/server/notification-subscriptions/runtime.mjs +4 -0
- package/dist/lib/server/responses.js +9 -1
- package/dist/lib/server/responses.mjs +9 -1
- package/dist/lib/signing/agent-fetch.d.mts +1 -1
- package/dist/lib/signing/agent-fetch.d.ts +1 -1
- package/dist/lib/signing/agent-fetch.js +3 -3
- package/dist/lib/signing/agent-fetch.mjs +3 -3
- package/dist/lib/testing/client.d.mts +1 -0
- package/dist/lib/testing/client.d.ts +1 -0
- package/dist/lib/testing/client.js +6 -5
- package/dist/lib/testing/client.mjs +6 -5
- package/dist/lib/testing/storyboard/agent-routing.d.mts +5 -2
- package/dist/lib/testing/storyboard/agent-routing.d.ts +5 -2
- package/dist/lib/testing/storyboard/agent-routing.js +11 -4
- package/dist/lib/testing/storyboard/agent-routing.mjs +11 -4
- package/dist/lib/testing/storyboard/canonical-format-satisfaction.js +60 -14
- package/dist/lib/testing/storyboard/canonical-format-satisfaction.mjs +60 -14
- package/dist/lib/testing/storyboard/compliance.d.mts +2 -5
- package/dist/lib/testing/storyboard/compliance.d.ts +2 -5
- package/dist/lib/testing/storyboard/compliance.js +62 -13
- package/dist/lib/testing/storyboard/compliance.mjs +63 -14
- package/dist/lib/testing/storyboard/context.d.mts +13 -3
- package/dist/lib/testing/storyboard/context.d.ts +13 -3
- package/dist/lib/testing/storyboard/context.js +15 -10
- package/dist/lib/testing/storyboard/context.mjs +15 -10
- package/dist/lib/testing/storyboard/request-signing/vector-loader.d.mts +2 -0
- package/dist/lib/testing/storyboard/request-signing/vector-loader.d.ts +2 -0
- package/dist/lib/testing/storyboard/request-signing/vector-loader.js +11 -0
- package/dist/lib/testing/storyboard/request-signing/vector-loader.mjs +10 -0
- package/dist/lib/testing/storyboard/runner.js +141 -13
- package/dist/lib/testing/storyboard/runner.mjs +141 -13
- package/dist/lib/testing/storyboard/validations.d.mts +1 -1
- package/dist/lib/testing/storyboard/validations.d.ts +1 -1
- package/dist/lib/testing/storyboard/validations.js +4 -1
- package/dist/lib/testing/storyboard/validations.mjs +4 -1
- package/dist/lib/testing/test-controller.js +3 -0
- package/dist/lib/testing/test-controller.mjs +3 -0
- package/dist/lib/types/accept-proposal.d.ts +20 -28
- package/dist/lib/types/asset-instances.d.mts +1 -1
- package/dist/lib/types/asset-instances.d.ts +1 -1
- package/dist/lib/types/buy-products.d.ts +20 -28
- package/dist/lib/types/check-governance.d.ts +20 -28
- package/dist/lib/types/comply-test-controller.d.ts +20 -28
- package/dist/lib/types/control-media-buy.d.ts +20 -28
- package/dist/lib/types/core.generated.d.mts +273 -184
- package/dist/lib/types/core.generated.d.ts +273 -184
- package/dist/lib/types/create-media-buy.d.ts +20 -28
- package/dist/lib/types/get-media-buys.d.ts +20 -28
- package/dist/lib/types/get-products.d.ts +20 -28
- package/dist/lib/types/index.d.mts +6 -1
- package/dist/lib/types/index.d.ts +6 -1
- package/dist/lib/types/index.js +6 -1
- package/dist/lib/types/index.mjs +4 -1
- package/dist/lib/types/inline-enums.generated.d.mts +30 -4
- package/dist/lib/types/inline-enums.generated.d.ts +30 -4
- package/dist/lib/types/inline-enums.generated.js +41 -2
- package/dist/lib/types/inline-enums.generated.mjs +28 -2
- package/dist/lib/types/list-products.d.ts +20 -28
- package/dist/lib/types/list-proposals.d.ts +20 -28
- package/dist/lib/types/media-buy-delivery-report.d.mts +6 -0
- package/dist/lib/types/media-buy-delivery-report.d.ts +6 -0
- package/dist/lib/types/media-buy-delivery-report.js +16 -0
- package/dist/lib/types/media-buy-delivery-report.mjs +0 -0
- package/dist/lib/types/refine-proposals.d.ts +20 -28
- package/dist/lib/types/request-proposals.d.ts +20 -28
- package/dist/lib/types/schemas.generated.d.ts +63113 -127273
- package/dist/lib/types/schemas.generated.js +759 -770
- package/dist/lib/types/schemas.generated.mjs +759 -770
- package/dist/lib/types/targeting-keys.generated.d.mts +4 -0
- package/dist/lib/types/targeting-keys.generated.d.ts +4 -0
- package/dist/lib/types/targeting-keys.generated.js +109 -0
- package/dist/lib/types/targeting-keys.generated.mjs +84 -0
- package/dist/lib/types/tools.generated.d.mts +2 -68
- package/dist/lib/types/tools.generated.d.ts +2 -68
- package/dist/lib/types/update-media-buy.d.ts +20 -28
- package/dist/lib/utils/adcp-version-config.js +5 -2
- package/dist/lib/utils/adcp-version-config.mjs +5 -2
- package/dist/lib/utils/envelope-status-compat.d.mts +18 -1
- package/dist/lib/utils/envelope-status-compat.d.ts +18 -1
- package/dist/lib/utils/envelope-status-compat.js +11 -5
- package/dist/lib/utils/envelope-status-compat.mjs +11 -5
- package/dist/lib/utils/response-unwrapper.js +18 -10
- package/dist/lib/utils/response-unwrapper.mjs +18 -10
- package/dist/lib/v2/format-schema/resolver.js +1 -1
- package/dist/lib/v2/format-schema/resolver.mjs +1 -1
- package/dist/lib/v2/projection/creative-delivery.js +159 -39
- package/dist/lib/v2/projection/creative-delivery.mjs +163 -39
- package/dist/lib/v2/projection/index.d.mts +1 -0
- package/dist/lib/v2/projection/index.d.ts +1 -0
- package/dist/lib/v2/projection/index.js +3 -0
- package/dist/lib/v2/projection/index.mjs +2 -0
- package/dist/lib/v2/projection/legacy-metadata.d.mts +19 -0
- package/dist/lib/v2/projection/legacy-metadata.d.ts +19 -0
- package/dist/lib/v2/projection/legacy-metadata.js +91 -0
- package/dist/lib/v2/projection/legacy-metadata.mjs +86 -0
- package/dist/lib/v2/projection/v1-to-v2.d.mts +1 -1
- package/dist/lib/v2/projection/v1-to-v2.d.ts +1 -1
- package/dist/lib/v2/projection/v1-to-v2.js +12 -9
- package/dist/lib/v2/projection/v1-to-v2.mjs +12 -9
- package/dist/lib/validation/budget-allocation.d.mts +3 -3
- package/dist/lib/validation/budget-allocation.d.ts +3 -3
- package/dist/lib/validation/compact-schema.d.mts +27 -0
- package/dist/lib/validation/compact-schema.d.ts +27 -0
- package/dist/lib/validation/compact-schema.js +276 -0
- package/dist/lib/validation/compact-schema.mjs +250 -0
- package/dist/lib/validation/media-buy-delivery-report.d.mts +8 -0
- package/dist/lib/validation/media-buy-delivery-report.d.ts +8 -0
- package/dist/lib/validation/media-buy-delivery-report.js +31 -0
- package/dist/lib/validation/media-buy-delivery-report.mjs +7 -0
- package/dist/lib/validation/nonempty-array.d.mts +15 -0
- package/dist/lib/validation/nonempty-array.d.ts +15 -0
- package/dist/lib/validation/nonempty-array.js +41 -0
- package/dist/lib/validation/nonempty-array.mjs +7 -0
- package/dist/lib/validation/schema-diagnostic-origins.d.mts +21 -0
- package/dist/lib/validation/schema-diagnostic-origins.d.ts +21 -0
- package/dist/lib/validation/schema-diagnostic-origins.js +193 -0
- package/dist/lib/validation/schema-diagnostic-origins.mjs +169 -0
- package/dist/lib/validation/schema-loader.js +86 -16
- package/dist/lib/validation/schema-loader.mjs +82 -16
- package/dist/lib/validation/schema-validator.d.mts +10 -19
- package/dist/lib/validation/schema-validator.d.ts +10 -19
- package/dist/lib/validation/schema-validator.js +136 -43
- package/dist/lib/validation/schema-validator.mjs +140 -44
- package/dist/lib/validation/sync-creatives.d.mts +22 -22
- package/dist/lib/validation/sync-creatives.d.ts +22 -22
- 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/dist/lib/webhooks/index.d.mts +3 -0
- package/dist/lib/webhooks/index.d.ts +3 -0
- package/dist/lib/webhooks/index.js +3 -0
- package/dist/lib/webhooks/index.mjs +2 -0
- package/dist/lib/webhooks/media-buy-delivery.d.mts +43 -0
- package/dist/lib/webhooks/media-buy-delivery.d.ts +43 -0
- package/dist/lib/webhooks/media-buy-delivery.js +119 -0
- package/dist/lib/webhooks/media-buy-delivery.mjs +94 -0
- package/docs/TYPE-SUMMARY.md +2 -2
- package/docs/guides/COLLECTION-FIXTURE-FOUNDATION.md +11 -0
- package/docs/guides/DELIVERY-WEBHOOK-PARSING.md +142 -0
- package/docs/guides/DISCOVERY-CACHE-AND-SESSION-REUSE.md +27 -1
- package/docs/guides/REPORTING-LEDGER.md +93 -0
- package/docs/guides/REPORTING-STABILITY.md +1 -1
- package/docs/guides/TYPED-CLIENT-TOOLS.md +49 -0
- package/docs/llms.txt +2 -2
- package/docs/migration-14.x-rc-worksheet.md +4 -4
- package/docs/migration-16-to-17.md +202 -2
- package/docs/migration-6.6-to-6.7.md +14 -0
- package/docs/migration-account-change-feed.md +15 -0
- package/docs/migration-reporting-storage-package.md +1 -1
- package/docs/recipes/verifying-inbound-webhooks.md +18 -2
- package/package.json +2 -2
|
@@ -1,6 +1,25 @@
|
|
|
1
1
|
import { applyTargetingInput, resolveTargetingInput } from "../media-buy/targeting-input.mjs";
|
|
2
2
|
import { scopedStore } from "./state-store.mjs";
|
|
3
3
|
const DEFAULT_MEDIA_BUY_STORE_COLLECTION = "media_buys_targeting";
|
|
4
|
+
const PACKAGE_IDENTITY_FIELDS = ["package_id", "product_id", "buyer_ref"];
|
|
5
|
+
function compatibleIdentity(left, right) {
|
|
6
|
+
if (!left || !right) return false;
|
|
7
|
+
return PACKAGE_IDENTITY_FIELDS.every((key) => !left[key] || !right[key] || left[key] === right[key]);
|
|
8
|
+
}
|
|
9
|
+
function sharesIdentity(left, right) {
|
|
10
|
+
if (!left || !right) return false;
|
|
11
|
+
return compatibleIdentity(left, right) && PACKAGE_IDENTITY_FIELDS.some((key) => left[key] && left[key] === right[key]);
|
|
12
|
+
}
|
|
13
|
+
function matchContextPackage(requests, responses, index) {
|
|
14
|
+
const matches = requests.filter((request) => sharesIdentity(request, responses[index]));
|
|
15
|
+
if (matches.length === 1 && responses.filter((response) => sharesIdentity(matches[0], response)).length === 1) {
|
|
16
|
+
return matches[0];
|
|
17
|
+
}
|
|
18
|
+
if (requests.length === responses.length && requests.every((request, i) => compatibleIdentity(request, responses[i]))) {
|
|
19
|
+
return requests[index];
|
|
20
|
+
}
|
|
21
|
+
return void 0;
|
|
22
|
+
}
|
|
4
23
|
function createMediaBuyStore(options) {
|
|
5
24
|
const collection = options.collection ?? DEFAULT_MEDIA_BUY_STORE_COLLECTION;
|
|
6
25
|
function viewFor(accountId) {
|
|
@@ -18,8 +37,9 @@ function createMediaBuyStore(options) {
|
|
|
18
37
|
async persistFromCreate(accountId, request, result) {
|
|
19
38
|
const requestPackages = request.packages ?? [];
|
|
20
39
|
const responsePackages = result.packages ?? [];
|
|
21
|
-
if (
|
|
22
|
-
const
|
|
40
|
+
if (!result.media_buy_id) return;
|
|
41
|
+
const prior = await loadRecord(accountId, result.media_buy_id);
|
|
42
|
+
const byId = new Map((prior?.packages ?? []).map((pkg) => [pkg.package_id, { ...pkg }]));
|
|
23
43
|
for (let i = 0; i < requestPackages.length; i++) {
|
|
24
44
|
const reqPkg = requestPackages[i];
|
|
25
45
|
if (!reqPkg?.targeting_overlay) continue;
|
|
@@ -30,12 +50,26 @@ function createMediaBuyStore(options) {
|
|
|
30
50
|
if (!packageId) continue;
|
|
31
51
|
const persistedOverlay = respPkg?.targeting_overlay ?? resolveTargetingInput(reqPkg.targeting_overlay);
|
|
32
52
|
if (!persistedOverlay) continue;
|
|
33
|
-
|
|
53
|
+
byId.set(packageId, { ...byId.get(packageId), package_id: packageId, targeting_overlay: persistedOverlay });
|
|
34
54
|
}
|
|
35
|
-
|
|
55
|
+
for (const [index, response] of responsePackages.entries()) {
|
|
56
|
+
if (!response.package_id) continue;
|
|
57
|
+
const context2 = matchContextPackage(requestPackages, responsePackages, index)?.context ?? response.context;
|
|
58
|
+
const stored = byId.get(response.package_id);
|
|
59
|
+
if (context2 !== void 0 && stored?.context === void 0) {
|
|
60
|
+
byId.set(response.package_id, {
|
|
61
|
+
...stored,
|
|
62
|
+
package_id: response.package_id,
|
|
63
|
+
context: structuredClone(context2)
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
const context = prior?.context ?? request.context ?? result.context;
|
|
68
|
+
if (byId.size === 0 && context === void 0) return;
|
|
36
69
|
await writeRecord(accountId, {
|
|
37
70
|
media_buy_id: result.media_buy_id,
|
|
38
|
-
|
|
71
|
+
...context !== void 0 ? { context: structuredClone(context) } : {},
|
|
72
|
+
packages: Array.from(byId.values())
|
|
39
73
|
});
|
|
40
74
|
},
|
|
41
75
|
async mergeFromUpdate(accountId, mediaBuyId, patch) {
|
|
@@ -43,42 +77,56 @@ function createMediaBuyStore(options) {
|
|
|
43
77
|
media_buy_id: mediaBuyId,
|
|
44
78
|
packages: []
|
|
45
79
|
};
|
|
46
|
-
const byId = new Map(prior.packages.map((p) => [p.package_id, p
|
|
80
|
+
const byId = new Map(prior.packages.map((p) => [p.package_id, { ...p }]));
|
|
47
81
|
for (const pkg of patch.packages ?? []) {
|
|
48
82
|
const packageId = pkg?.package_id;
|
|
49
83
|
if (!packageId) continue;
|
|
50
84
|
if (!("targeting_overlay" in pkg)) continue;
|
|
51
85
|
const incoming = pkg.targeting_overlay;
|
|
52
86
|
if (incoming === void 0) continue;
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
|
|
87
|
+
const stored = byId.get(packageId);
|
|
88
|
+
const merged = applyTargetingInput(stored?.targeting_overlay, incoming);
|
|
89
|
+
if (merged) byId.set(packageId, { ...stored, package_id: packageId, targeting_overlay: merged });
|
|
90
|
+
else if (stored?.context !== void 0) {
|
|
91
|
+
byId.set(packageId, { package_id: packageId, context: stored.context });
|
|
92
|
+
} else byId.delete(packageId);
|
|
56
93
|
}
|
|
57
94
|
for (const pkg of patch.new_packages ?? []) {
|
|
58
95
|
if (!pkg?.targeting_overlay || !pkg.package_id) continue;
|
|
59
96
|
const resolved = resolveTargetingInput(pkg.targeting_overlay);
|
|
60
|
-
if (resolved)
|
|
97
|
+
if (resolved)
|
|
98
|
+
byId.set(pkg.package_id, {
|
|
99
|
+
...byId.get(pkg.package_id),
|
|
100
|
+
package_id: pkg.package_id,
|
|
101
|
+
targeting_overlay: resolved
|
|
102
|
+
});
|
|
61
103
|
}
|
|
62
104
|
await writeRecord(accountId, {
|
|
63
|
-
|
|
64
|
-
packages: Array.from(byId.
|
|
65
|
-
package_id,
|
|
66
|
-
targeting_overlay
|
|
67
|
-
}))
|
|
105
|
+
...prior,
|
|
106
|
+
packages: Array.from(byId.values())
|
|
68
107
|
});
|
|
69
108
|
},
|
|
70
109
|
async backfill(accountId, result) {
|
|
71
110
|
const buys = result.media_buys;
|
|
72
111
|
if (!buys || buys.length === 0) return result;
|
|
73
112
|
for (const buy of buys) {
|
|
74
|
-
if (!buy?.media_buy_id
|
|
113
|
+
if (!buy?.media_buy_id) continue;
|
|
75
114
|
const record = await loadRecord(accountId, buy.media_buy_id);
|
|
76
115
|
if (!record) continue;
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
116
|
+
if (buy.context === void 0 && record.context !== void 0) {
|
|
117
|
+
buy.context = structuredClone(record.context);
|
|
118
|
+
}
|
|
119
|
+
const byId = new Map(record.packages.map((p) => [p.package_id, p]));
|
|
120
|
+
for (const pkg of buy.packages ?? []) {
|
|
121
|
+
if (!pkg?.package_id) continue;
|
|
122
|
+
const persisted = byId.get(pkg.package_id);
|
|
123
|
+
if (!persisted) continue;
|
|
124
|
+
if (pkg.targeting_overlay === void 0 && persisted.targeting_overlay !== void 0) {
|
|
125
|
+
pkg.targeting_overlay = persisted.targeting_overlay;
|
|
126
|
+
}
|
|
127
|
+
if (pkg.context === void 0 && persisted.context !== void 0) {
|
|
128
|
+
pkg.context = structuredClone(persisted.context);
|
|
129
|
+
}
|
|
82
130
|
}
|
|
83
131
|
}
|
|
84
132
|
return result;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { WebhookAttemptSuppressionReason } from '../webhook-emitter.mjs';
|
|
2
2
|
import type { NotificationSubscriptionConfigInput, NotificationSubscriptionView, NotificationSuppressionDisposition, PersistentNotificationRuntime, PersistentNotificationRuntimeOptions, StoredNotificationSubscription } from './types.mjs';
|
|
3
3
|
export declare const CALLER_NOTIFICATION_TYPES: readonly ["capabilities.changed", "principal.changed"];
|
|
4
|
-
export declare const ACCOUNT_NOTIFICATION_TYPES: readonly ["creative.status_changed", "creative.assignment_changed", "indicators.changed", "creative.purged", "account.status_changed", "account.change_recorded", "product.created", "product.updated", "product.priced", "product.removed", "signal.created", "signal.updated", "signal.priced", "signal.removed", "wholesale_feed.bulk_change", "reporting.delivery_ready", "reporting.status_changed", "reporting.ledger_changed"];
|
|
4
|
+
export declare const ACCOUNT_NOTIFICATION_TYPES: readonly ["creative.status_changed", "creative.assignment_changed", "indicators.changed", "creative.purged", "account.status_changed", "account.change_recorded", "product.created", "product.updated", "product.priced", "product.removed", "signal.created", "signal.updated", "signal.priced", "signal.removed", "wholesale_feed.bulk_change", "collection_card.updated", "collection_card.removed", "collection_catalog.bulk_change", "proposal.created", "reporting.delivery_ready", "reporting.status_changed", "reporting.ledger_changed"];
|
|
5
5
|
/**
|
|
6
6
|
* Durable subscription control plane. The supplied emitter factory is called
|
|
7
7
|
* exactly once with the runtime's mandatory live authorizer, preventing a
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { WebhookAttemptSuppressionReason } from '../webhook-emitter';
|
|
2
2
|
import type { NotificationSubscriptionConfigInput, NotificationSubscriptionView, NotificationSuppressionDisposition, PersistentNotificationRuntime, PersistentNotificationRuntimeOptions, StoredNotificationSubscription } from './types';
|
|
3
3
|
export declare const CALLER_NOTIFICATION_TYPES: readonly ["capabilities.changed", "principal.changed"];
|
|
4
|
-
export declare const ACCOUNT_NOTIFICATION_TYPES: readonly ["creative.status_changed", "creative.assignment_changed", "indicators.changed", "creative.purged", "account.status_changed", "account.change_recorded", "product.created", "product.updated", "product.priced", "product.removed", "signal.created", "signal.updated", "signal.priced", "signal.removed", "wholesale_feed.bulk_change", "reporting.delivery_ready", "reporting.status_changed", "reporting.ledger_changed"];
|
|
4
|
+
export declare const ACCOUNT_NOTIFICATION_TYPES: readonly ["creative.status_changed", "creative.assignment_changed", "indicators.changed", "creative.purged", "account.status_changed", "account.change_recorded", "product.created", "product.updated", "product.priced", "product.removed", "signal.created", "signal.updated", "signal.priced", "signal.removed", "wholesale_feed.bulk_change", "collection_card.updated", "collection_card.removed", "collection_catalog.bulk_change", "proposal.created", "reporting.delivery_ready", "reporting.status_changed", "reporting.ledger_changed"];
|
|
5
5
|
/**
|
|
6
6
|
* Durable subscription control plane. The supplied emitter factory is called
|
|
7
7
|
* exactly once with the runtime's mandatory live authorizer, preventing a
|
|
@@ -51,6 +51,10 @@ const ACCOUNT_NOTIFICATION_TYPES = Object.freeze([
|
|
|
51
51
|
"signal.priced",
|
|
52
52
|
"signal.removed",
|
|
53
53
|
"wholesale_feed.bulk_change",
|
|
54
|
+
"collection_card.updated",
|
|
55
|
+
"collection_card.removed",
|
|
56
|
+
"collection_catalog.bulk_change",
|
|
57
|
+
"proposal.created",
|
|
54
58
|
"reporting.delivery_ready",
|
|
55
59
|
"reporting.status_changed",
|
|
56
60
|
"reporting.ledger_changed"
|
|
@@ -22,6 +22,10 @@ const ACCOUNT_NOTIFICATION_TYPES = Object.freeze([
|
|
|
22
22
|
"signal.priced",
|
|
23
23
|
"signal.removed",
|
|
24
24
|
"wholesale_feed.bulk_change",
|
|
25
|
+
"collection_card.updated",
|
|
26
|
+
"collection_card.removed",
|
|
27
|
+
"collection_catalog.bulk_change",
|
|
28
|
+
"proposal.created",
|
|
25
29
|
"reporting.delivery_ready",
|
|
26
30
|
"reporting.status_changed",
|
|
27
31
|
"reporting.ledger_changed"
|
|
@@ -60,6 +60,7 @@ __export(responses_exports, {
|
|
|
60
60
|
module.exports = __toCommonJS(responses_exports);
|
|
61
61
|
var import_media_buy_helpers = require('./media-buy-helpers.js');
|
|
62
62
|
var import_reporting_delivery_config = require('./reporting-delivery-config.js');
|
|
63
|
+
var import_account_response_identity = require('./account-response-identity.js');
|
|
63
64
|
const explicitResponseSummaries = /* @__PURE__ */ new WeakMap();
|
|
64
65
|
function _getExplicitResponseSummary(response) {
|
|
65
66
|
return explicitResponseSummaries.get(response);
|
|
@@ -124,7 +125,14 @@ function stripBusinessEntityBank(row, key) {
|
|
|
124
125
|
return stripped;
|
|
125
126
|
}
|
|
126
127
|
function stripAccountWriteOnlyFields(account) {
|
|
127
|
-
const
|
|
128
|
+
const {
|
|
129
|
+
destination_billing_entity: _destination,
|
|
130
|
+
authInfo: _authInfo,
|
|
131
|
+
ctx_metadata: _metadata,
|
|
132
|
+
...responseFields
|
|
133
|
+
} = account;
|
|
134
|
+
const response = stripBusinessEntityBank(stripNotificationConfigSecrets(responseFields), "billing_entity");
|
|
135
|
+
const stripped = { ...response, ...(0, import_account_response_identity.projectAccountResponseIdentityFields)(response) };
|
|
128
136
|
const reportingDeliveryConfigs = stripped.reporting_delivery_configs;
|
|
129
137
|
if (reportingDeliveryConfigs === void 0) return stripped;
|
|
130
138
|
return {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { validActionsForStatus } from "./media-buy-helpers.mjs";
|
|
2
2
|
import { projectReportingDeliveryConfigStates } from "./reporting-delivery-config.mjs";
|
|
3
|
+
import { projectAccountResponseIdentityFields } from "./account-response-identity.mjs";
|
|
3
4
|
const explicitResponseSummaries = /* @__PURE__ */ new WeakMap();
|
|
4
5
|
function _getExplicitResponseSummary(response) {
|
|
5
6
|
return explicitResponseSummaries.get(response);
|
|
@@ -64,7 +65,14 @@ function stripBusinessEntityBank(row, key) {
|
|
|
64
65
|
return stripped;
|
|
65
66
|
}
|
|
66
67
|
function stripAccountWriteOnlyFields(account) {
|
|
67
|
-
const
|
|
68
|
+
const {
|
|
69
|
+
destination_billing_entity: _destination,
|
|
70
|
+
authInfo: _authInfo,
|
|
71
|
+
ctx_metadata: _metadata,
|
|
72
|
+
...responseFields
|
|
73
|
+
} = account;
|
|
74
|
+
const response = stripBusinessEntityBank(stripNotificationConfigSecrets(responseFields), "billing_entity");
|
|
75
|
+
const stripped = { ...response, ...projectAccountResponseIdentityFields(response) };
|
|
68
76
|
const reportingDeliveryConfigs = stripped.reporting_delivery_configs;
|
|
69
77
|
if (reportingDeliveryConfigs === void 0) return stripped;
|
|
70
78
|
return {
|
|
@@ -80,7 +80,7 @@ export interface BuildAgentSigningFetchOptions {
|
|
|
80
80
|
* 1. Sign immediately when the payload carries webhook authentication.
|
|
81
81
|
* 2. Resolve the AdCP operation and exact JSON-RPC protocol method.
|
|
82
82
|
* 3. Consult each capability namespace independently; either can request
|
|
83
|
-
* signing.
|
|
83
|
+
* signing. SDK AdCP task polls sign when the seller supports signing.
|
|
84
84
|
* 4. Resolve the seller's content-digest policy into a per-request toggle.
|
|
85
85
|
* 5. Delegate to `createSigningFetch` with the decision baked in.
|
|
86
86
|
*/
|
|
@@ -80,7 +80,7 @@ export interface BuildAgentSigningFetchOptions {
|
|
|
80
80
|
* 1. Sign immediately when the payload carries webhook authentication.
|
|
81
81
|
* 2. Resolve the AdCP operation and exact JSON-RPC protocol method.
|
|
82
82
|
* 3. Consult each capability namespace independently; either can request
|
|
83
|
-
* signing.
|
|
83
|
+
* signing. SDK AdCP task polls sign when the seller supports signing.
|
|
84
84
|
* 4. Resolve the seller's content-digest policy into a per-request toggle.
|
|
85
85
|
* 5. Delegate to `createSigningFetch` with the decision baked in.
|
|
86
86
|
*/
|
|
@@ -157,13 +157,13 @@ function buildAgentSigningFetch(options) {
|
|
|
157
157
|
}
|
|
158
158
|
const operation = extractAdcpOperation(init?.body);
|
|
159
159
|
if (operation === "get_adcp_capabilities" && (0, import_protocol_methods.hasUnsignedCapabilityBootstrap)(signing)) return false;
|
|
160
|
-
const isPollOperation = operation === "tasks_get" || operation === "tasks/get";
|
|
160
|
+
const isPollOperation = operation === "get_task_status" || operation === "tasks_get" || operation === "tasks/get";
|
|
161
161
|
const methods = policyMethods ?? (isPollOperation ? jsonRpcMethodsForSigning(init?.body) : []);
|
|
162
162
|
const profileCompatible = signing.profile === "web-bot-auth" ? (0, import_protocol_methods.signingListIncludes)(capability?.profiles, "web-bot-auth") : capability?.profiles === void 0 || (0, import_protocol_methods.signingListIncludes)(capability.profiles, "adcp/request-signing/v1");
|
|
163
|
-
const
|
|
163
|
+
const signedPoll = profileCompatible && capability?.supported === true && ((operation === "tasks_get" || operation === "get_task_status") && methods.includes("tools/call") || (operation === "tasks/get" || operation === "get_task_status") && methods.some(
|
|
164
164
|
(method) => ["message/send", "message/stream", "SendMessage", "SendStreamingMessage"].includes(method)
|
|
165
165
|
));
|
|
166
|
-
const sign = signing.profile === "web-bot-auth" && !!operation && (0, import_protocol_methods.signingListIncludes)(capability?.profiles, "web-bot-auth") || shouldSignOperation(operation, capability, signing) || methods.some((method) => shouldSignProtocolMethod(method, capability, signing)) ||
|
|
166
|
+
const sign = signing.profile === "web-bot-auth" && !!operation && (0, import_protocol_methods.signingListIncludes)(capability?.profiles, "web-bot-auth") || shouldSignOperation(operation, capability, signing) || methods.some((method) => shouldSignProtocolMethod(method, capability, signing)) || signedPoll;
|
|
167
167
|
if (sign && signing.profile === "web-bot-auth" && !(0, import_protocol_methods.signingListIncludes)(capability?.profiles, "web-bot-auth"))
|
|
168
168
|
throw new TypeError("Seller did not advertise the Web Bot Auth request signing profile");
|
|
169
169
|
return sign;
|
|
@@ -139,13 +139,13 @@ function buildAgentSigningFetch(options) {
|
|
|
139
139
|
}
|
|
140
140
|
const operation = extractAdcpOperation(init?.body);
|
|
141
141
|
if (operation === "get_adcp_capabilities" && hasUnsignedCapabilityBootstrap(signing)) return false;
|
|
142
|
-
const isPollOperation = operation === "tasks_get" || operation === "tasks/get";
|
|
142
|
+
const isPollOperation = operation === "get_task_status" || operation === "tasks_get" || operation === "tasks/get";
|
|
143
143
|
const methods = policyMethods ?? (isPollOperation ? jsonRpcMethodsForSigning(init?.body) : []);
|
|
144
144
|
const profileCompatible = signing.profile === "web-bot-auth" ? signingListIncludes(capability?.profiles, "web-bot-auth") : capability?.profiles === void 0 || signingListIncludes(capability.profiles, "adcp/request-signing/v1");
|
|
145
|
-
const
|
|
145
|
+
const signedPoll = profileCompatible && capability?.supported === true && ((operation === "tasks_get" || operation === "get_task_status") && methods.includes("tools/call") || (operation === "tasks/get" || operation === "get_task_status") && methods.some(
|
|
146
146
|
(method) => ["message/send", "message/stream", "SendMessage", "SendStreamingMessage"].includes(method)
|
|
147
147
|
));
|
|
148
|
-
const sign = signing.profile === "web-bot-auth" && !!operation && signingListIncludes(capability?.profiles, "web-bot-auth") || shouldSignOperation(operation, capability, signing) || methods.some((method) => shouldSignProtocolMethod(method, capability, signing)) ||
|
|
148
|
+
const sign = signing.profile === "web-bot-auth" && !!operation && signingListIncludes(capability?.profiles, "web-bot-auth") || shouldSignOperation(operation, capability, signing) || methods.some((method) => shouldSignProtocolMethod(method, capability, signing)) || signedPoll;
|
|
149
149
|
if (sign && signing.profile === "web-bot-auth" && !signingListIncludes(capability?.profiles, "web-bot-auth"))
|
|
150
150
|
throw new TypeError("Seller did not advertise the Web Bot Auth request signing profile");
|
|
151
151
|
return sign;
|
|
@@ -641,23 +641,24 @@ async function discoverAgentProfile(client, signal, schemaAdcpVersion) {
|
|
|
641
641
|
}
|
|
642
642
|
const failure = describeProfileDiscoveryFailure(profile);
|
|
643
643
|
if (!step.passed || failure) {
|
|
644
|
-
const
|
|
645
|
-
|
|
644
|
+
const evidence2 = { ...step, ...failure ?? {}, passed: false, duration_ms: step.duration_ms };
|
|
645
|
+
evidence2.error = (0, import_redact_credential_patterns.redactCredentialPatterns)(evidence2.error ?? "Agent discovery failed", false).slice(
|
|
646
646
|
0,
|
|
647
647
|
4096
|
|
648
648
|
);
|
|
649
|
-
profile.capabilities_failure =
|
|
649
|
+
profile.capabilities_failure = evidence2;
|
|
650
650
|
}
|
|
651
651
|
if (!step.passed) step.error = (0, import_redact_credential_patterns.redactCredentialPatterns)(step.error ?? "Agent discovery failed", false);
|
|
652
652
|
if (!failure && step.passed && (scopeKey === void 0 || scopeKey === client.getCapabilityEvidenceScope().scopeKey)) {
|
|
653
653
|
seedTestClientSigningCapability(client, profile, schemaAdcpVersion);
|
|
654
654
|
}
|
|
655
|
+
const evidence = step.passed && !failure ? { ...step } : void 0;
|
|
655
656
|
if (step.passed && !failure) {
|
|
656
657
|
delete step.request;
|
|
657
658
|
delete step.response_record;
|
|
658
659
|
delete step.adcp_error;
|
|
659
660
|
}
|
|
660
|
-
return { profile, step, ...caughtError !== void 0 && { caughtError } };
|
|
661
|
+
return { profile, step, ...caughtError !== void 0 && { caughtError }, ...evidence && { evidence } };
|
|
661
662
|
}
|
|
662
663
|
async function discoverAgentCapabilities(client, profile, options) {
|
|
663
664
|
const steps = [];
|
|
@@ -876,7 +877,7 @@ function validateResponseSchema(toolName, data, responseAdcpVersion) {
|
|
|
876
877
|
warnings: [`No Zod schema registered for "${toolName}" \u2014 validation skipped`]
|
|
877
878
|
};
|
|
878
879
|
}
|
|
879
|
-
const compatData = data && typeof data === "object" && !Array.isArray(data) ? (0, import_envelope_status_compat.injectLegacyEnvelopeStatus)(data, { toolName }) : data;
|
|
880
|
+
const compatData = data && typeof data === "object" && !Array.isArray(data) ? (0, import_envelope_status_compat.injectLegacyEnvelopeStatus)(data, { toolName, adcpVersion: responseAdcpVersion }) : data;
|
|
880
881
|
const result = schema.safeParse((0, import_response_schemas.prepareResponseForSchemaValidation)(toolName, compatData, responseAdcpVersion));
|
|
881
882
|
if (result.success) {
|
|
882
883
|
return {
|
|
@@ -599,23 +599,24 @@ async function discoverAgentProfile(client, signal, schemaAdcpVersion) {
|
|
|
599
599
|
}
|
|
600
600
|
const failure = describeProfileDiscoveryFailure(profile);
|
|
601
601
|
if (!step.passed || failure) {
|
|
602
|
-
const
|
|
603
|
-
|
|
602
|
+
const evidence2 = { ...step, ...failure ?? {}, passed: false, duration_ms: step.duration_ms };
|
|
603
|
+
evidence2.error = redactCredentialPatterns(evidence2.error ?? "Agent discovery failed", false).slice(
|
|
604
604
|
0,
|
|
605
605
|
4096
|
|
606
606
|
);
|
|
607
|
-
profile.capabilities_failure =
|
|
607
|
+
profile.capabilities_failure = evidence2;
|
|
608
608
|
}
|
|
609
609
|
if (!step.passed) step.error = redactCredentialPatterns(step.error ?? "Agent discovery failed", false);
|
|
610
610
|
if (!failure && step.passed && (scopeKey === void 0 || scopeKey === client.getCapabilityEvidenceScope().scopeKey)) {
|
|
611
611
|
seedTestClientSigningCapability(client, profile, schemaAdcpVersion);
|
|
612
612
|
}
|
|
613
|
+
const evidence = step.passed && !failure ? { ...step } : void 0;
|
|
613
614
|
if (step.passed && !failure) {
|
|
614
615
|
delete step.request;
|
|
615
616
|
delete step.response_record;
|
|
616
617
|
delete step.adcp_error;
|
|
617
618
|
}
|
|
618
|
-
return { profile, step, ...caughtError !== void 0 && { caughtError } };
|
|
619
|
+
return { profile, step, ...caughtError !== void 0 && { caughtError }, ...evidence && { evidence } };
|
|
619
620
|
}
|
|
620
621
|
async function discoverAgentCapabilities(client, profile, options) {
|
|
621
622
|
const steps = [];
|
|
@@ -834,7 +835,7 @@ function validateResponseSchema(toolName, data, responseAdcpVersion) {
|
|
|
834
835
|
warnings: [`No Zod schema registered for "${toolName}" \u2014 validation skipped`]
|
|
835
836
|
};
|
|
836
837
|
}
|
|
837
|
-
const compatData = data && typeof data === "object" && !Array.isArray(data) ? injectLegacyEnvelopeStatus(data, { toolName }) : data;
|
|
838
|
+
const compatData = data && typeof data === "object" && !Array.isArray(data) ? injectLegacyEnvelopeStatus(data, { toolName, adcpVersion: responseAdcpVersion }) : data;
|
|
838
839
|
const result = schema.safeParse(prepareResponseForSchemaValidation(toolName, compatData, responseAdcpVersion));
|
|
839
840
|
if (result.success) {
|
|
840
841
|
return {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { TestClient } from '../client.mjs';
|
|
2
|
-
import type { AgentProfile } from '../types.mjs';
|
|
2
|
+
import type { AgentProfile, TestStepResult } from '../types.mjs';
|
|
3
3
|
import { type AdcpProtocol } from '../../utils/capabilities.mjs';
|
|
4
4
|
import type { AgentEntry, Storyboard, StoryboardRunOptions, StoryboardStep } from './types.mjs';
|
|
5
5
|
/** Storyboard applicability is any-of; it does not authorize individual steps. */
|
|
@@ -18,6 +18,8 @@ export interface AgentRoutingContext {
|
|
|
18
18
|
clients: Map<string, TestClient>;
|
|
19
19
|
/** Per-agent discovered profile (`get_adcp_capabilities` result). */
|
|
20
20
|
profiles: Map<string, AgentProfile>;
|
|
21
|
+
/** Actual discovery exchanges, retained separately from compact rollup steps. */
|
|
22
|
+
discoverySteps?: ReadonlyMap<string, TestStepResult>;
|
|
21
23
|
/** Protocol → keys of agents that claim it. */
|
|
22
24
|
protocolIndex: Map<AdcpProtocol, string[]>;
|
|
23
25
|
/** Resolved (key → URL) for echo on the storyboard result. */
|
|
@@ -41,7 +43,8 @@ export declare class DiscoveryFailure extends Error {
|
|
|
41
43
|
readonly agentKey: string;
|
|
42
44
|
readonly url: string;
|
|
43
45
|
readonly underlying: string;
|
|
44
|
-
|
|
46
|
+
readonly step?: TestStepResult | undefined;
|
|
47
|
+
constructor(message: string, agentKey: string, url: string, underlying: string, step?: TestStepResult | undefined);
|
|
45
48
|
}
|
|
46
49
|
/**
|
|
47
50
|
* Discover every agent in the map in parallel and build the routing index.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { TestClient } from '../client';
|
|
2
|
-
import type { AgentProfile } from '../types';
|
|
2
|
+
import type { AgentProfile, TestStepResult } from '../types';
|
|
3
3
|
import { type AdcpProtocol } from '../../utils/capabilities';
|
|
4
4
|
import type { AgentEntry, Storyboard, StoryboardRunOptions, StoryboardStep } from './types';
|
|
5
5
|
/** Storyboard applicability is any-of; it does not authorize individual steps. */
|
|
@@ -18,6 +18,8 @@ export interface AgentRoutingContext {
|
|
|
18
18
|
clients: Map<string, TestClient>;
|
|
19
19
|
/** Per-agent discovered profile (`get_adcp_capabilities` result). */
|
|
20
20
|
profiles: Map<string, AgentProfile>;
|
|
21
|
+
/** Actual discovery exchanges, retained separately from compact rollup steps. */
|
|
22
|
+
discoverySteps?: ReadonlyMap<string, TestStepResult>;
|
|
21
23
|
/** Protocol → keys of agents that claim it. */
|
|
22
24
|
protocolIndex: Map<AdcpProtocol, string[]>;
|
|
23
25
|
/** Resolved (key → URL) for echo on the storyboard result. */
|
|
@@ -41,7 +43,8 @@ export declare class DiscoveryFailure extends Error {
|
|
|
41
43
|
readonly agentKey: string;
|
|
42
44
|
readonly url: string;
|
|
43
45
|
readonly underlying: string;
|
|
44
|
-
|
|
46
|
+
readonly step?: TestStepResult | undefined;
|
|
47
|
+
constructor(message: string, agentKey: string, url: string, underlying: string, step?: TestStepResult | undefined);
|
|
45
48
|
}
|
|
46
49
|
/**
|
|
47
50
|
* Discover every agent in the map in parallel and build the routing index.
|
|
@@ -127,16 +127,18 @@ class RoutingError extends Error {
|
|
|
127
127
|
hint;
|
|
128
128
|
}
|
|
129
129
|
class DiscoveryFailure extends Error {
|
|
130
|
-
constructor(message, agentKey, url, underlying) {
|
|
130
|
+
constructor(message, agentKey, url, underlying, step) {
|
|
131
131
|
super(message);
|
|
132
132
|
this.agentKey = agentKey;
|
|
133
133
|
this.url = url;
|
|
134
134
|
this.underlying = underlying;
|
|
135
|
+
this.step = step;
|
|
135
136
|
this.name = "DiscoveryFailure";
|
|
136
137
|
}
|
|
137
138
|
agentKey;
|
|
138
139
|
url;
|
|
139
140
|
underlying;
|
|
141
|
+
step;
|
|
140
142
|
}
|
|
141
143
|
async function discoverAgentRouting(options) {
|
|
142
144
|
const agents = options.agents;
|
|
@@ -150,6 +152,7 @@ async function discoverAgentRouting(options) {
|
|
|
150
152
|
agentMap[key] = entry.url;
|
|
151
153
|
}
|
|
152
154
|
const profiles = /* @__PURE__ */ new Map();
|
|
155
|
+
const discoverySteps = /* @__PURE__ */ new Map();
|
|
153
156
|
const discoveryFailures = [];
|
|
154
157
|
if (options._routingProfiles) {
|
|
155
158
|
for (const [key] of entries) {
|
|
@@ -162,6 +165,7 @@ async function discoverAgentRouting(options) {
|
|
|
162
165
|
return {
|
|
163
166
|
clients,
|
|
164
167
|
profiles,
|
|
168
|
+
discoverySteps,
|
|
165
169
|
protocolIndex: buildProtocolIndex(profiles),
|
|
166
170
|
agentMap,
|
|
167
171
|
discoveryFailures
|
|
@@ -171,8 +175,8 @@ async function discoverAgentRouting(options) {
|
|
|
171
175
|
entries.map(async ([key, entry]) => {
|
|
172
176
|
const perAgentOptions = buildAgentOptions(entry, options);
|
|
173
177
|
try {
|
|
174
|
-
const { profile, step } = await (0, import_client.getOrDiscoverStoryboardProfile)(clients.get(key), perAgentOptions);
|
|
175
|
-
return { key, profile, step };
|
|
178
|
+
const { profile, step, evidence } = await (0, import_client.getOrDiscoverStoryboardProfile)(clients.get(key), perAgentOptions);
|
|
179
|
+
return { key, profile, step, evidence };
|
|
176
180
|
} catch (err) {
|
|
177
181
|
return {
|
|
178
182
|
key,
|
|
@@ -180,6 +184,7 @@ async function discoverAgentRouting(options) {
|
|
|
180
184
|
step: {
|
|
181
185
|
step: "Discover agent capabilities",
|
|
182
186
|
passed: false,
|
|
187
|
+
duration_ms: 0,
|
|
183
188
|
error: scrubAuthSecrets(err?.message || String(err))
|
|
184
189
|
}
|
|
185
190
|
};
|
|
@@ -187,6 +192,7 @@ async function discoverAgentRouting(options) {
|
|
|
187
192
|
})
|
|
188
193
|
);
|
|
189
194
|
for (const r of discoveryResults) {
|
|
195
|
+
discoverySteps.set(r.key, "evidence" in r && r.evidence ? r.evidence : r.step);
|
|
190
196
|
if (!r.profile || r.step.passed === false) {
|
|
191
197
|
const rawDetail = scrubAuthSecrets(r.step.error ?? "Discovery returned no profile.");
|
|
192
198
|
const detail = rawDetail.length > 512 ? `${rawDetail.slice(0, 512)} \u2026(truncated)` : rawDetail;
|
|
@@ -194,7 +200,7 @@ async function discoverAgentRouting(options) {
|
|
|
194
200
|
const message = resilient ? baseMessage : `${baseMessage}
|
|
195
201
|
|
|
196
202
|
If this is hello-cluster / exploratory CI and you want unrelated storyboards to complete despite this failure, set \`StoryboardRunOptions.discovery_resilient: true\`. Do NOT set it in production \u2014 a topology with a broken tenant is a hard misconfiguration there.`;
|
|
197
|
-
const failure = new DiscoveryFailure(message, r.key, agents[r.key].url, detail);
|
|
203
|
+
const failure = new DiscoveryFailure(message, r.key, agents[r.key].url, detail, { ...r.step, error: detail });
|
|
198
204
|
if (!resilient) throw failure;
|
|
199
205
|
discoveryFailures.push(failure);
|
|
200
206
|
continue;
|
|
@@ -204,6 +210,7 @@ If this is hello-cluster / exploratory CI and you want unrelated storyboards to
|
|
|
204
210
|
return {
|
|
205
211
|
clients,
|
|
206
212
|
profiles,
|
|
213
|
+
discoverySteps,
|
|
207
214
|
protocolIndex: buildProtocolIndex(profiles),
|
|
208
215
|
agentMap,
|
|
209
216
|
discoveryFailures
|
|
@@ -95,16 +95,18 @@ class RoutingError extends Error {
|
|
|
95
95
|
hint;
|
|
96
96
|
}
|
|
97
97
|
class DiscoveryFailure extends Error {
|
|
98
|
-
constructor(message, agentKey, url, underlying) {
|
|
98
|
+
constructor(message, agentKey, url, underlying, step) {
|
|
99
99
|
super(message);
|
|
100
100
|
this.agentKey = agentKey;
|
|
101
101
|
this.url = url;
|
|
102
102
|
this.underlying = underlying;
|
|
103
|
+
this.step = step;
|
|
103
104
|
this.name = "DiscoveryFailure";
|
|
104
105
|
}
|
|
105
106
|
agentKey;
|
|
106
107
|
url;
|
|
107
108
|
underlying;
|
|
109
|
+
step;
|
|
108
110
|
}
|
|
109
111
|
async function discoverAgentRouting(options) {
|
|
110
112
|
const agents = options.agents;
|
|
@@ -118,6 +120,7 @@ async function discoverAgentRouting(options) {
|
|
|
118
120
|
agentMap[key] = entry.url;
|
|
119
121
|
}
|
|
120
122
|
const profiles = /* @__PURE__ */ new Map();
|
|
123
|
+
const discoverySteps = /* @__PURE__ */ new Map();
|
|
121
124
|
const discoveryFailures = [];
|
|
122
125
|
if (options._routingProfiles) {
|
|
123
126
|
for (const [key] of entries) {
|
|
@@ -130,6 +133,7 @@ async function discoverAgentRouting(options) {
|
|
|
130
133
|
return {
|
|
131
134
|
clients,
|
|
132
135
|
profiles,
|
|
136
|
+
discoverySteps,
|
|
133
137
|
protocolIndex: buildProtocolIndex(profiles),
|
|
134
138
|
agentMap,
|
|
135
139
|
discoveryFailures
|
|
@@ -139,8 +143,8 @@ async function discoverAgentRouting(options) {
|
|
|
139
143
|
entries.map(async ([key, entry]) => {
|
|
140
144
|
const perAgentOptions = buildAgentOptions(entry, options);
|
|
141
145
|
try {
|
|
142
|
-
const { profile, step } = await getOrDiscoverStoryboardProfile(clients.get(key), perAgentOptions);
|
|
143
|
-
return { key, profile, step };
|
|
146
|
+
const { profile, step, evidence } = await getOrDiscoverStoryboardProfile(clients.get(key), perAgentOptions);
|
|
147
|
+
return { key, profile, step, evidence };
|
|
144
148
|
} catch (err) {
|
|
145
149
|
return {
|
|
146
150
|
key,
|
|
@@ -148,6 +152,7 @@ async function discoverAgentRouting(options) {
|
|
|
148
152
|
step: {
|
|
149
153
|
step: "Discover agent capabilities",
|
|
150
154
|
passed: false,
|
|
155
|
+
duration_ms: 0,
|
|
151
156
|
error: scrubAuthSecrets(err?.message || String(err))
|
|
152
157
|
}
|
|
153
158
|
};
|
|
@@ -155,6 +160,7 @@ async function discoverAgentRouting(options) {
|
|
|
155
160
|
})
|
|
156
161
|
);
|
|
157
162
|
for (const r of discoveryResults) {
|
|
163
|
+
discoverySteps.set(r.key, "evidence" in r && r.evidence ? r.evidence : r.step);
|
|
158
164
|
if (!r.profile || r.step.passed === false) {
|
|
159
165
|
const rawDetail = scrubAuthSecrets(r.step.error ?? "Discovery returned no profile.");
|
|
160
166
|
const detail = rawDetail.length > 512 ? `${rawDetail.slice(0, 512)} \u2026(truncated)` : rawDetail;
|
|
@@ -162,7 +168,7 @@ async function discoverAgentRouting(options) {
|
|
|
162
168
|
const message = resilient ? baseMessage : `${baseMessage}
|
|
163
169
|
|
|
164
170
|
If this is hello-cluster / exploratory CI and you want unrelated storyboards to complete despite this failure, set \`StoryboardRunOptions.discovery_resilient: true\`. Do NOT set it in production \u2014 a topology with a broken tenant is a hard misconfiguration there.`;
|
|
165
|
-
const failure = new DiscoveryFailure(message, r.key, agents[r.key].url, detail);
|
|
171
|
+
const failure = new DiscoveryFailure(message, r.key, agents[r.key].url, detail, { ...r.step, error: detail });
|
|
166
172
|
if (!resilient) throw failure;
|
|
167
173
|
discoveryFailures.push(failure);
|
|
168
174
|
continue;
|
|
@@ -172,6 +178,7 @@ If this is hello-cluster / exploratory CI and you want unrelated storyboards to
|
|
|
172
178
|
return {
|
|
173
179
|
clients,
|
|
174
180
|
profiles,
|
|
181
|
+
discoverySteps,
|
|
175
182
|
protocolIndex: buildProtocolIndex(profiles),
|
|
176
183
|
agentMap,
|
|
177
184
|
discoveryFailures
|