@adcp/sdk 16.0.0-beta.1 → 16.0.0-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +54 -0
- package/dist/lib/core/ConversationTypes.d.mts +8 -3
- package/dist/lib/core/ConversationTypes.d.ts +8 -3
- package/dist/lib/core/SingleAgentClient.d.mts +15 -4
- package/dist/lib/core/SingleAgentClient.d.ts +15 -4
- package/dist/lib/core/SingleAgentClient.js +29 -8
- package/dist/lib/core/SingleAgentClient.mjs +29 -8
- package/dist/lib/core/TaskExecutor.js +5 -1
- package/dist/lib/core/TaskExecutor.mjs +5 -1
- package/dist/lib/errors/index.d.mts +9 -4
- package/dist/lib/errors/index.d.ts +9 -4
- package/dist/lib/identity-3.3/generated-compat.d.mts +34 -0
- package/dist/lib/identity-3.3/generated-compat.d.ts +34 -0
- package/dist/lib/identity-3.3/generated-compat.js +16 -0
- package/dist/lib/identity-3.3/generated-compat.mjs +0 -0
- package/dist/lib/identity-3.3/index.d.mts +2 -2
- package/dist/lib/identity-3.3/index.d.ts +2 -2
- package/dist/lib/identity-3.3/index.js +4 -0
- package/dist/lib/identity-3.3/index.mjs +5 -1
- package/dist/lib/identity-3.3/lifecycle.d.mts +17 -5
- package/dist/lib/identity-3.3/lifecycle.d.ts +17 -5
- package/dist/lib/identity-3.3/lifecycle.js +32 -5
- package/dist/lib/identity-3.3/lifecycle.mjs +38 -6
- package/dist/lib/identity-3.3/revocation.d.mts +39 -3
- package/dist/lib/identity-3.3/revocation.d.ts +39 -3
- package/dist/lib/identity-3.3/revocation.js +88 -18
- package/dist/lib/identity-3.3/revocation.mjs +89 -19
- package/dist/lib/identity-3.3/server.d.mts +12 -0
- package/dist/lib/identity-3.3/server.d.ts +12 -0
- package/dist/lib/identity-3.3/server.js +103 -43
- package/dist/lib/identity-3.3/server.mjs +111 -45
- package/dist/lib/identity-3.3/trust.d.mts +62 -1
- package/dist/lib/identity-3.3/trust.d.ts +62 -1
- package/dist/lib/identity-3.3/trust.js +126 -21
- package/dist/lib/identity-3.3/trust.mjs +124 -21
- package/dist/lib/identity-3.3/types.d.mts +39 -11
- package/dist/lib/identity-3.3/types.d.ts +39 -11
- package/dist/lib/index.d.mts +3 -3
- package/dist/lib/index.d.ts +3 -3
- package/dist/lib/index.js +8 -0
- package/dist/lib/index.mjs +9 -1
- package/dist/lib/negotiation/types.d.mts +20 -39
- package/dist/lib/negotiation/types.d.ts +20 -39
- package/dist/lib/protocols/index.d.mts +61 -25
- package/dist/lib/protocols/index.d.ts +61 -25
- package/dist/lib/protocols/index.js +11 -6
- package/dist/lib/protocols/index.mjs +5 -2
- package/dist/lib/protocols/mcp-modern.js +1 -0
- package/dist/lib/protocols/mcp-modern.mjs +2 -1
- package/dist/lib/protocols/mcp.js +1 -0
- package/dist/lib/protocols/mcp.mjs +2 -1
- package/dist/lib/protocols/responseSizeLimit.d.mts +91 -5
- package/dist/lib/protocols/responseSizeLimit.d.ts +91 -5
- package/dist/lib/protocols/responseSizeLimit.js +195 -31
- package/dist/lib/protocols/responseSizeLimit.mjs +192 -31
- package/dist/lib/reporting/bigquery/index.js +8 -0
- package/dist/lib/reporting/bigquery/index.mjs +8 -0
- package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
- package/dist/lib/server/auth-signature.d.mts +6 -1
- package/dist/lib/server/auth-signature.d.ts +6 -1
- package/dist/lib/server/auth-signature.js +24 -13
- package/dist/lib/server/auth-signature.mjs +29 -13
- package/dist/lib/server/auth.d.mts +2 -2
- package/dist/lib/server/auth.d.ts +2 -2
- package/dist/lib/server/create-adcp-server.js +31 -10
- package/dist/lib/server/create-adcp-server.mjs +37 -11
- package/dist/lib/signing/crypto.d.mts +15 -0
- package/dist/lib/signing/crypto.d.ts +15 -0
- package/dist/lib/signing/crypto.js +83 -3
- package/dist/lib/signing/crypto.mjs +86 -3
- package/dist/lib/signing/fetch-async.js +1 -1
- package/dist/lib/signing/fetch-async.mjs +1 -1
- package/dist/lib/signing/fetch.js +1 -1
- package/dist/lib/signing/fetch.mjs +1 -1
- package/dist/lib/signing/middleware.js +9 -0
- package/dist/lib/signing/middleware.mjs +14 -0
- package/dist/lib/signing/parser.d.mts +8 -5
- package/dist/lib/signing/parser.d.ts +8 -5
- package/dist/lib/signing/parser.js +77 -61
- package/dist/lib/signing/parser.mjs +77 -61
- package/dist/lib/signing/revocation.js +3 -0
- package/dist/lib/signing/revocation.mjs +3 -0
- package/dist/lib/signing/server.d.mts +1 -1
- package/dist/lib/signing/server.d.ts +1 -1
- package/dist/lib/signing/server.js +2 -0
- package/dist/lib/signing/server.mjs +2 -1
- package/dist/lib/signing/signer.js +2 -8
- package/dist/lib/signing/signer.mjs +3 -9
- package/dist/lib/signing/testing.js +2 -6
- package/dist/lib/signing/testing.mjs +3 -7
- package/dist/lib/signing/verifier.js +3 -3
- package/dist/lib/signing/verifier.mjs +4 -4
- package/dist/lib/signing/web-bot-auth.d.mts +84 -10
- package/dist/lib/signing/web-bot-auth.d.ts +84 -10
- package/dist/lib/signing/web-bot-auth.js +278 -88
- package/dist/lib/signing/web-bot-auth.mjs +279 -94
- package/dist/lib/signing/webhook-verifier.js +3 -3
- package/dist/lib/signing/webhook-verifier.mjs +4 -4
- package/dist/lib/substitution/compile.js +2 -1
- package/dist/lib/substitution/compile.mjs +2 -1
- package/dist/lib/substitution/consent-macros.d.mts +4 -0
- package/dist/lib/substitution/consent-macros.d.ts +4 -0
- package/dist/lib/substitution/consent-macros.js +45 -0
- package/dist/lib/substitution/consent-macros.mjs +20 -0
- package/dist/lib/substitution/index.d.mts +1 -1
- package/dist/lib/substitution/index.d.ts +1 -1
- package/dist/lib/substitution/index.js +2 -0
- package/dist/lib/substitution/index.mjs +2 -1
- package/dist/lib/substitution/translate.d.mts +15 -2
- package/dist/lib/substitution/translate.d.ts +15 -2
- package/dist/lib/substitution/translate.js +148 -26
- package/dist/lib/substitution/translate.mjs +147 -26
- package/dist/lib/testing/client.js +2 -1
- package/dist/lib/testing/client.mjs +2 -1
- package/dist/lib/testing/scenarios/capabilities.js +1 -1
- package/dist/lib/testing/scenarios/capabilities.mjs +1 -1
- package/dist/lib/testing/storyboard/request-signing/builder.js +2 -5
- package/dist/lib/testing/storyboard/request-signing/builder.mjs +3 -6
- package/dist/lib/testing/storyboard/signer-grader/grader.js +2 -7
- package/dist/lib/testing/storyboard/signer-grader/grader.mjs +2 -7
- package/dist/lib/testing/storyboard/validations.d.mts +1 -1
- package/dist/lib/testing/storyboard/validations.d.ts +1 -1
- package/dist/lib/types/enums.generated.d.mts +3 -0
- package/dist/lib/types/enums.generated.d.ts +3 -0
- package/dist/lib/types/enums.generated.js +9 -0
- package/dist/lib/types/enums.generated.mjs +6 -0
- package/dist/lib/v2/projection/catalog-snapshot.js +3 -1
- package/dist/lib/v2/projection/catalog-snapshot.mjs +3 -1
- package/dist/lib/v2/projection/creative-delivery.d.mts +31 -9
- package/dist/lib/v2/projection/creative-delivery.d.ts +31 -9
- package/dist/lib/v2/projection/index.d.mts +1 -1
- package/dist/lib/v2/projection/index.d.ts +1 -1
- package/dist/lib/v2/projection/index.js +2 -0
- package/dist/lib/v2/projection/index.mjs +2 -0
- package/dist/lib/v2/projection/legacy-routes.d.mts +10 -0
- package/dist/lib/v2/projection/legacy-routes.d.ts +10 -0
- package/dist/lib/v2/projection/legacy-routes.js +7 -0
- package/dist/lib/v2/projection/legacy-routes.mjs +6 -0
- package/dist/lib/validation/schema-loader.js +25 -0
- package/dist/lib/validation/schema-loader.mjs +24 -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 +7 -2
- package/docs/guides/DISCOVERY-CACHE-AND-SESSION-REUSE.md +3 -2
- package/docs/guides/REPORTING-LEDGER.md +15 -5
- package/docs/guides/REPORTING-OPERATIONS.md +17 -11
- package/docs/guides/UNIVERSAL-MACRO-COMPILATION.md +38 -0
- package/docs/guides/VALIDATE-YOUR-AGENT.md +12 -0
- package/docs/llms.txt +2 -2
- package/docs/migration-12-to-13.md +8 -0
- package/docs/migration-14.x-rc-worksheet.md +4 -4
- package/docs/migration-agent-identity-3.3.md +150 -11
- package/package.json +4 -1
|
@@ -78,16 +78,38 @@ export type CanonicalCreateMediaBuyRequest = Omit<CanonicalCreativeResponse<Crea
|
|
|
78
78
|
packages?: CanonicalPackageRequest[];
|
|
79
79
|
};
|
|
80
80
|
type CanonicalReportingWebhook = NonNullable<CanonicalCreateMediaBuyRequest['reporting_webhook']>;
|
|
81
|
-
|
|
82
|
-
|
|
81
|
+
/**
|
|
82
|
+
* Client-facing form of a wire reporting webhook `W`. Every field is optional:
|
|
83
|
+
* the SDK can supply the callback `url`, `reporting_frequency` and the
|
|
84
|
+
* `authentication` block from client configuration.
|
|
85
|
+
*
|
|
86
|
+
* `authentication` is optional even with a caller-supplied `url`. AdCP 3.3
|
|
87
|
+
* makes it optional on the wire when the seller signs webhooks under its
|
|
88
|
+
* profile (`webhook_signing.supported`), and the experimental 3.3 client sends
|
|
89
|
+
* the registration without it once it has negotiated that. Below 3.3 the wire
|
|
90
|
+
* still requires it: with `webhookUrlTemplate` configured the client throws
|
|
91
|
+
* rather than send a caller URL without credentials (it never pairs its own
|
|
92
|
+
* `webhookSecret` with a caller-controlled host), and request validation
|
|
93
|
+
* reports the missing field otherwise.
|
|
94
|
+
*
|
|
95
|
+
* Derived from `W` rather than restating its fields, so it accepts every
|
|
96
|
+
* reporting webhook the pinned schemas generate, whether they declare
|
|
97
|
+
* `authentication` required (3.2) or optional (3.3).
|
|
98
|
+
*
|
|
99
|
+
* Exported for the type tests only; not re-exported from the package root.
|
|
100
|
+
*/
|
|
101
|
+
export type ClientReportingWebhookInputFor<W extends {
|
|
102
|
+
url: string;
|
|
103
|
+
reporting_frequency: unknown;
|
|
104
|
+
}> = Omit<W, 'url' | 'authentication' | 'reporting_frequency'> & {
|
|
105
|
+
url?: W['url'];
|
|
106
|
+
reporting_frequency?: W['reporting_frequency'];
|
|
107
|
+
/** Atomic: `schemes` and `credentials` always come from the same source. */
|
|
108
|
+
authentication?: W extends {
|
|
109
|
+
authentication?: infer A;
|
|
110
|
+
} ? (unknown extends A ? never : A) : never;
|
|
83
111
|
};
|
|
84
|
-
type ClientReportingWebhookInput =
|
|
85
|
-
url?: never;
|
|
86
|
-
authentication?: CanonicalReportingWebhook['authentication'];
|
|
87
|
-
}) | (ReportingWebhookPreferences & {
|
|
88
|
-
url: CanonicalReportingWebhook['url'];
|
|
89
|
-
authentication: CanonicalReportingWebhook['authentication'];
|
|
90
|
-
});
|
|
112
|
+
type ClientReportingWebhookInput = ClientReportingWebhookInputFor<CanonicalReportingWebhook>;
|
|
91
113
|
/**
|
|
92
114
|
* Client-facing create request. The SDK may supply the reporting callback URL
|
|
93
115
|
* and its complete authentication block from client configuration; the wire
|
|
@@ -43,7 +43,7 @@ export { projectV1ProductToV2, canonicalDeclarationFromBareId, resolveCanonicalF
|
|
|
43
43
|
export type { V1ToV2Result, V1ToV2ProjectionOptions, BareFormatIdResolveOptions, LegacyFormatConversionContext, LegacyFormatConverter, LegacyFormatResolutionContext, LegacyFormatResolver, } from './v1-to-v2.mjs';
|
|
44
44
|
export { projectV2ProductToV1 } from './v2-to-v1.mjs';
|
|
45
45
|
export type { V2ToV1Result, V2ToV1ProjectionOptions, CanonicalFormatLegacyResolver, CanonicalFormatLegacyResolutionContext, CanonicalProductFormatLegacyResolutionContext, CanonicalCreativeFormatLegacyResolutionContext, CanonicalSelectorFormatLegacyResolutionContext, } from './v2-to-v1.mjs';
|
|
46
|
-
export { canonicalFormatLegacyResolverFromRoutes, legacyRoutesForProduct, type CanonicalFormatLegacyRoute, type LegacyRoutesForProductOptions, } from './legacy-routes.mjs';
|
|
46
|
+
export { canonicalFormatLegacyResolverFromRoutes, carryFormatOptionOrigins, legacyRoutesForProduct, type CanonicalFormatLegacyRoute, type LegacyRoutesForProductOptions, } from './legacy-routes.mjs';
|
|
47
47
|
export { augmentProductWithFormatOptions, withFormatOptions, toCanonicalFormatOptionsWithRoutes, toAdditiveCanonicalProduct, withAdditiveCanonicalFormatOptions, toCanonicalOnlyProduct, toCanonicalOnlyResponse, type V2AugmentedProduct, type AdditiveCanonicalProduct, type CanonicalOnlyProduct, } from './augment-response.mjs';
|
|
48
48
|
export { CanonicalFormat, audioDaastFormatDeclaration, audioHostedFormatDeclaration, audioVastFormatDeclaration, agentPlacementFormatDeclaration, canonicalFormatDeclaration, customFormatDeclaration, displayTagFormatDeclaration, legacyFormatRef, legacyFormatRefs, html5FormatDeclaration, imageCarouselFormatDeclaration, imageFormatDeclaration, nativeInFeedFormatDeclaration, productCard, productCardDetailed, responsiveCreativeFormatDeclaration, sellerRenderedStatefulDisplayFormatDeclaration, sponsoredPlacementFormatDeclaration, coordinatedPlacementsFormatDeclaration, videoHostedFormatDeclaration, videoVastFormatDeclaration, type CanonicalFormatDeclaration, type CanonicalFormatDeclarationFields, type CanonicalFormatKind, type CanonicalFormatParams, type FormatReferenceInput, type ProductCardDetailedFields, type ProductCardFields, } from './builders.mjs';
|
|
49
49
|
export { packageRefsForFormatOptions, packageRefsForCapabilities, legacyFormatIdsFromOptions, tryLegacyFormatIdsFromOptions, legacyFormatIdsForFormatOption, legacyFormatIdsForCapability, lintPackageFormatSelectorDimensions, FormatOptionRefsLookupError, CapabilityIdsLookupError, type PackageFormatRefs, type PackageCapabilityRefs, type FormatOptionRef, type FormatOptionSelector, type FormatOptionRefsLookupErrorCode, type CapabilityIdsLookupErrorCode, type PackageFormatSelectorInput, type PackageFormatSelectorDimensionOptions, type FixedSizeDimensions, type PackageFormatSelectorDimensionDiagnosticCode, type PackageFormatSelectorDimensionDiagnostic, } from './write-side.mjs';
|
|
@@ -43,7 +43,7 @@ export { projectV1ProductToV2, canonicalDeclarationFromBareId, resolveCanonicalF
|
|
|
43
43
|
export type { V1ToV2Result, V1ToV2ProjectionOptions, BareFormatIdResolveOptions, LegacyFormatConversionContext, LegacyFormatConverter, LegacyFormatResolutionContext, LegacyFormatResolver, } from './v1-to-v2';
|
|
44
44
|
export { projectV2ProductToV1 } from './v2-to-v1';
|
|
45
45
|
export type { V2ToV1Result, V2ToV1ProjectionOptions, CanonicalFormatLegacyResolver, CanonicalFormatLegacyResolutionContext, CanonicalProductFormatLegacyResolutionContext, CanonicalCreativeFormatLegacyResolutionContext, CanonicalSelectorFormatLegacyResolutionContext, } from './v2-to-v1';
|
|
46
|
-
export { canonicalFormatLegacyResolverFromRoutes, legacyRoutesForProduct, type CanonicalFormatLegacyRoute, type LegacyRoutesForProductOptions, } from './legacy-routes';
|
|
46
|
+
export { canonicalFormatLegacyResolverFromRoutes, carryFormatOptionOrigins, legacyRoutesForProduct, type CanonicalFormatLegacyRoute, type LegacyRoutesForProductOptions, } from './legacy-routes';
|
|
47
47
|
export { augmentProductWithFormatOptions, withFormatOptions, toCanonicalFormatOptionsWithRoutes, toAdditiveCanonicalProduct, withAdditiveCanonicalFormatOptions, toCanonicalOnlyProduct, toCanonicalOnlyResponse, type V2AugmentedProduct, type AdditiveCanonicalProduct, type CanonicalOnlyProduct, } from './augment-response';
|
|
48
48
|
export { CanonicalFormat, audioDaastFormatDeclaration, audioHostedFormatDeclaration, audioVastFormatDeclaration, agentPlacementFormatDeclaration, canonicalFormatDeclaration, customFormatDeclaration, displayTagFormatDeclaration, legacyFormatRef, legacyFormatRefs, html5FormatDeclaration, imageCarouselFormatDeclaration, imageFormatDeclaration, nativeInFeedFormatDeclaration, productCard, productCardDetailed, responsiveCreativeFormatDeclaration, sellerRenderedStatefulDisplayFormatDeclaration, sponsoredPlacementFormatDeclaration, coordinatedPlacementsFormatDeclaration, videoHostedFormatDeclaration, videoVastFormatDeclaration, type CanonicalFormatDeclaration, type CanonicalFormatDeclarationFields, type CanonicalFormatKind, type CanonicalFormatParams, type FormatReferenceInput, type ProductCardDetailedFields, type ProductCardFields, } from './builders';
|
|
49
49
|
export { packageRefsForFormatOptions, packageRefsForCapabilities, legacyFormatIdsFromOptions, tryLegacyFormatIdsFromOptions, legacyFormatIdsForFormatOption, legacyFormatIdsForCapability, lintPackageFormatSelectorDimensions, FormatOptionRefsLookupError, CapabilityIdsLookupError, type PackageFormatRefs, type PackageCapabilityRefs, type FormatOptionRef, type FormatOptionSelector, type FormatOptionRefsLookupErrorCode, type CapabilityIdsLookupErrorCode, type PackageFormatSelectorInput, type PackageFormatSelectorDimensionOptions, type FixedSizeDimensions, type PackageFormatSelectorDimensionDiagnosticCode, type PackageFormatSelectorDimensionDiagnostic, } from './write-side';
|
|
@@ -33,6 +33,7 @@ __export(projection_exports, {
|
|
|
33
33
|
canonicalFormatDeclaration: () => import_builders.canonicalFormatDeclaration,
|
|
34
34
|
canonicalFormatLegacyResolverFromCatalogSnapshots: () => import_catalog_snapshot.canonicalFormatLegacyResolverFromCatalogSnapshots,
|
|
35
35
|
canonicalFormatLegacyResolverFromRoutes: () => import_legacy_routes.canonicalFormatLegacyResolverFromRoutes,
|
|
36
|
+
carryFormatOptionOrigins: () => import_legacy_routes.carryFormatOptionOrigins,
|
|
36
37
|
coordinatedPlacementsFormatDeclaration: () => import_builders.coordinatedPlacementsFormatDeclaration,
|
|
37
38
|
customFormatDeclaration: () => import_builders.customFormatDeclaration,
|
|
38
39
|
displayTagFormatDeclaration: () => import_builders.displayTagFormatDeclaration,
|
|
@@ -111,6 +112,7 @@ var import_creative_delivery = require('./creative-delivery.js');
|
|
|
111
112
|
canonicalFormatDeclaration,
|
|
112
113
|
canonicalFormatLegacyResolverFromCatalogSnapshots,
|
|
113
114
|
canonicalFormatLegacyResolverFromRoutes,
|
|
115
|
+
carryFormatOptionOrigins,
|
|
114
116
|
coordinatedPlacementsFormatDeclaration,
|
|
115
117
|
customFormatDeclaration,
|
|
116
118
|
displayTagFormatDeclaration,
|
|
@@ -2,6 +2,7 @@ import { projectV1ProductToV2, canonicalDeclarationFromBareId, resolveCanonicalF
|
|
|
2
2
|
import { projectV2ProductToV1 } from "./v2-to-v1.mjs";
|
|
3
3
|
import {
|
|
4
4
|
canonicalFormatLegacyResolverFromRoutes,
|
|
5
|
+
carryFormatOptionOrigins,
|
|
5
6
|
legacyRoutesForProduct
|
|
6
7
|
} from "./legacy-routes.mjs";
|
|
7
8
|
import {
|
|
@@ -88,6 +89,7 @@ export {
|
|
|
88
89
|
canonicalFormatDeclaration,
|
|
89
90
|
canonicalFormatLegacyResolverFromCatalogSnapshots,
|
|
90
91
|
canonicalFormatLegacyResolverFromRoutes,
|
|
92
|
+
carryFormatOptionOrigins,
|
|
91
93
|
coordinatedPlacementsFormatDeclaration,
|
|
92
94
|
customFormatDeclaration,
|
|
93
95
|
displayTagFormatDeclaration,
|
|
@@ -81,4 +81,14 @@ export declare function legacyRoutesForProduct(productId: string, declarations:
|
|
|
81
81
|
* must agree that the seller did not declare it.
|
|
82
82
|
*/
|
|
83
83
|
export declare function formatOptionOriginFromRoutes(resolver: CanonicalFormatLegacyResolver | undefined, ref: FormatOptionReference, productId: string | undefined): FormatOptionOrigin | undefined;
|
|
84
|
+
/**
|
|
85
|
+
* Make `resolver` report the format-option origins recorded by `sources`.
|
|
86
|
+
*
|
|
87
|
+
* A resolver built by {@link canonicalFormatLegacyResolverFromRoutes} carries
|
|
88
|
+
* each route's `seller_declared` origin, which `AgentClient` reads to rewrite
|
|
89
|
+
* options the seller never declared on the canonical wire. A resolver that
|
|
90
|
+
* wraps or composes it is a new function and would otherwise carry none.
|
|
91
|
+
* Returns `resolver` itself, so the call can wrap a composition inline.
|
|
92
|
+
*/
|
|
93
|
+
export declare function carryFormatOptionOrigins(resolver: CanonicalFormatLegacyResolver, ...sources: ReadonlyArray<CanonicalFormatLegacyResolver | undefined>): CanonicalFormatLegacyResolver;
|
|
84
94
|
export declare function canonicalFormatLegacyResolverFromRoutes(routes: readonly CanonicalFormatLegacyRoute[]): CanonicalFormatLegacyResolver;
|
|
@@ -81,4 +81,14 @@ export declare function legacyRoutesForProduct(productId: string, declarations:
|
|
|
81
81
|
* must agree that the seller did not declare it.
|
|
82
82
|
*/
|
|
83
83
|
export declare function formatOptionOriginFromRoutes(resolver: CanonicalFormatLegacyResolver | undefined, ref: FormatOptionReference, productId: string | undefined): FormatOptionOrigin | undefined;
|
|
84
|
+
/**
|
|
85
|
+
* Make `resolver` report the format-option origins recorded by `sources`.
|
|
86
|
+
*
|
|
87
|
+
* A resolver built by {@link canonicalFormatLegacyResolverFromRoutes} carries
|
|
88
|
+
* each route's `seller_declared` origin, which `AgentClient` reads to rewrite
|
|
89
|
+
* options the seller never declared on the canonical wire. A resolver that
|
|
90
|
+
* wraps or composes it is a new function and would otherwise carry none.
|
|
91
|
+
* Returns `resolver` itself, so the call can wrap a composition inline.
|
|
92
|
+
*/
|
|
93
|
+
export declare function carryFormatOptionOrigins(resolver: CanonicalFormatLegacyResolver, ...sources: ReadonlyArray<CanonicalFormatLegacyResolver | undefined>): CanonicalFormatLegacyResolver;
|
|
84
94
|
export declare function canonicalFormatLegacyResolverFromRoutes(routes: readonly CanonicalFormatLegacyRoute[]): CanonicalFormatLegacyResolver;
|
|
@@ -19,6 +19,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
19
19
|
var legacy_routes_exports = {};
|
|
20
20
|
__export(legacy_routes_exports, {
|
|
21
21
|
canonicalFormatLegacyResolverFromRoutes: () => canonicalFormatLegacyResolverFromRoutes,
|
|
22
|
+
carryFormatOptionOrigins: () => carryFormatOptionOrigins,
|
|
22
23
|
formatOptionOriginFromRoutes: () => formatOptionOriginFromRoutes,
|
|
23
24
|
legacyRoutesForProduct: () => legacyRoutesForProduct,
|
|
24
25
|
sameFormatOptionRef: () => sameFormatOptionRef,
|
|
@@ -204,6 +205,11 @@ function formatOptionOriginFromRoutes(resolver, ref, productId) {
|
|
|
204
205
|
if (matching.some((entry) => entry.origin === void 0)) return void 0;
|
|
205
206
|
return matching[0].origin;
|
|
206
207
|
}
|
|
208
|
+
function carryFormatOptionOrigins(resolver, ...sources) {
|
|
209
|
+
const carried = [resolver, ...sources].flatMap((source) => source ? originsByResolver.get(source) ?? [] : []);
|
|
210
|
+
if (carried.length > 0) originsByResolver.set(resolver, Object.freeze(carried));
|
|
211
|
+
return resolver;
|
|
212
|
+
}
|
|
207
213
|
function canonicalFormatLegacyResolverFromRoutes(routes) {
|
|
208
214
|
const index = /* @__PURE__ */ new Map();
|
|
209
215
|
const origins = [];
|
|
@@ -237,6 +243,7 @@ function canonicalFormatLegacyResolverFromRoutes(routes) {
|
|
|
237
243
|
// Annotate the CommonJS export names for ESM import in node:
|
|
238
244
|
0 && (module.exports = {
|
|
239
245
|
canonicalFormatLegacyResolverFromRoutes,
|
|
246
|
+
carryFormatOptionOrigins,
|
|
240
247
|
formatOptionOriginFromRoutes,
|
|
241
248
|
legacyRoutesForProduct,
|
|
242
249
|
sameFormatOptionRef,
|
|
@@ -176,6 +176,11 @@ function formatOptionOriginFromRoutes(resolver, ref, productId) {
|
|
|
176
176
|
if (matching.some((entry) => entry.origin === void 0)) return void 0;
|
|
177
177
|
return matching[0].origin;
|
|
178
178
|
}
|
|
179
|
+
function carryFormatOptionOrigins(resolver, ...sources) {
|
|
180
|
+
const carried = [resolver, ...sources].flatMap((source) => source ? originsByResolver.get(source) ?? [] : []);
|
|
181
|
+
if (carried.length > 0) originsByResolver.set(resolver, Object.freeze(carried));
|
|
182
|
+
return resolver;
|
|
183
|
+
}
|
|
179
184
|
function canonicalFormatLegacyResolverFromRoutes(routes) {
|
|
180
185
|
const index = /* @__PURE__ */ new Map();
|
|
181
186
|
const origins = [];
|
|
@@ -208,6 +213,7 @@ function canonicalFormatLegacyResolverFromRoutes(routes) {
|
|
|
208
213
|
}
|
|
209
214
|
export {
|
|
210
215
|
canonicalFormatLegacyResolverFromRoutes,
|
|
216
|
+
carryFormatOptionOrigins,
|
|
211
217
|
formatOptionOriginFromRoutes,
|
|
212
218
|
legacyRoutesForProduct,
|
|
213
219
|
sameFormatOptionRef,
|
|
@@ -48,6 +48,7 @@ __export(schema_loader_exports, {
|
|
|
48
48
|
listValidatorKeys: () => listValidatorKeys,
|
|
49
49
|
registerExternalSchemaRoot: () => registerExternalSchemaRoot,
|
|
50
50
|
resolveBundleKey: () => resolveBundleKey,
|
|
51
|
+
resolveServedValidationVersion: () => resolveServedValidationVersion,
|
|
51
52
|
schemaAllowsTopLevelField: () => schemaAllowsTopLevelField,
|
|
52
53
|
toReleasePrecisionWire: () => toReleasePrecisionWire,
|
|
53
54
|
unregisterExternalSchemaRoot: () => unregisterExternalSchemaRoot,
|
|
@@ -754,6 +755,29 @@ function hasSchemaBundle(version) {
|
|
|
754
755
|
return false;
|
|
755
756
|
}
|
|
756
757
|
}
|
|
758
|
+
const SERVED_RELEASE_MAJOR = /^(\d+)\.\d+(?:-[a-zA-Z0-9.-]+)?$/;
|
|
759
|
+
const NUMERIC_PIN_MAJOR = /^(\d+)\.\d+/;
|
|
760
|
+
function resolveServedValidationVersion(response, pinnedVersion) {
|
|
761
|
+
const pinMajor = NUMERIC_PIN_MAJOR.exec(pinnedVersion)?.[1];
|
|
762
|
+
if (pinMajor === void 0) return pinnedVersion;
|
|
763
|
+
try {
|
|
764
|
+
if (isExternalSchemaRootActive(pinnedVersion)) return pinnedVersion;
|
|
765
|
+
} catch {
|
|
766
|
+
return pinnedVersion;
|
|
767
|
+
}
|
|
768
|
+
const echoed = response !== null && typeof response === "object" ? response.adcp_version : void 0;
|
|
769
|
+
if (typeof echoed !== "string") return pinnedVersion;
|
|
770
|
+
const echoMajor = SERVED_RELEASE_MAJOR.exec(echoed)?.[1];
|
|
771
|
+
if (echoMajor === void 0 || echoMajor !== pinMajor) return pinnedVersion;
|
|
772
|
+
let pinnedRelease;
|
|
773
|
+
try {
|
|
774
|
+
pinnedRelease = toReleasePrecisionWire(pinnedVersion);
|
|
775
|
+
} catch {
|
|
776
|
+
return pinnedVersion;
|
|
777
|
+
}
|
|
778
|
+
if (echoed === pinnedRelease) return pinnedVersion;
|
|
779
|
+
return hasSchemaBundle(echoed) ? echoed : pinnedVersion;
|
|
780
|
+
}
|
|
757
781
|
const mcpToolSchemaCache = /* @__PURE__ */ new Map();
|
|
758
782
|
const mcpToolSummaryCache = /* @__PURE__ */ new Map();
|
|
759
783
|
function boundedMcpToolSummary(value) {
|
|
@@ -1019,6 +1043,7 @@ function cloneJsonValue(value) {
|
|
|
1019
1043
|
listValidatorKeys,
|
|
1020
1044
|
registerExternalSchemaRoot,
|
|
1021
1045
|
resolveBundleKey,
|
|
1046
|
+
resolveServedValidationVersion,
|
|
1022
1047
|
schemaAllowsTopLevelField,
|
|
1023
1048
|
toReleasePrecisionWire,
|
|
1024
1049
|
unregisterExternalSchemaRoot,
|
|
@@ -701,6 +701,29 @@ function hasSchemaBundle(version) {
|
|
|
701
701
|
return false;
|
|
702
702
|
}
|
|
703
703
|
}
|
|
704
|
+
const SERVED_RELEASE_MAJOR = /^(\d+)\.\d+(?:-[a-zA-Z0-9.-]+)?$/;
|
|
705
|
+
const NUMERIC_PIN_MAJOR = /^(\d+)\.\d+/;
|
|
706
|
+
function resolveServedValidationVersion(response, pinnedVersion) {
|
|
707
|
+
const pinMajor = NUMERIC_PIN_MAJOR.exec(pinnedVersion)?.[1];
|
|
708
|
+
if (pinMajor === void 0) return pinnedVersion;
|
|
709
|
+
try {
|
|
710
|
+
if (isExternalSchemaRootActive(pinnedVersion)) return pinnedVersion;
|
|
711
|
+
} catch {
|
|
712
|
+
return pinnedVersion;
|
|
713
|
+
}
|
|
714
|
+
const echoed = response !== null && typeof response === "object" ? response.adcp_version : void 0;
|
|
715
|
+
if (typeof echoed !== "string") return pinnedVersion;
|
|
716
|
+
const echoMajor = SERVED_RELEASE_MAJOR.exec(echoed)?.[1];
|
|
717
|
+
if (echoMajor === void 0 || echoMajor !== pinMajor) return pinnedVersion;
|
|
718
|
+
let pinnedRelease;
|
|
719
|
+
try {
|
|
720
|
+
pinnedRelease = toReleasePrecisionWire(pinnedVersion);
|
|
721
|
+
} catch {
|
|
722
|
+
return pinnedVersion;
|
|
723
|
+
}
|
|
724
|
+
if (echoed === pinnedRelease) return pinnedVersion;
|
|
725
|
+
return hasSchemaBundle(echoed) ? echoed : pinnedVersion;
|
|
726
|
+
}
|
|
704
727
|
const mcpToolSchemaCache = /* @__PURE__ */ new Map();
|
|
705
728
|
const mcpToolSummaryCache = /* @__PURE__ */ new Map();
|
|
706
729
|
function boundedMcpToolSummary(value) {
|
|
@@ -965,6 +988,7 @@ export {
|
|
|
965
988
|
listValidatorKeys,
|
|
966
989
|
registerExternalSchemaRoot,
|
|
967
990
|
resolveBundleKey,
|
|
991
|
+
resolveServedValidationVersion,
|
|
968
992
|
schemaAllowsTopLevelField,
|
|
969
993
|
toReleasePrecisionWire,
|
|
970
994
|
unregisterExternalSchemaRoot,
|
package/dist/lib/version.d.mts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* AdCP SDK library version
|
|
3
3
|
*/
|
|
4
|
-
export declare const LIBRARY_VERSION = "16.0.0-beta.
|
|
4
|
+
export declare const LIBRARY_VERSION = "16.0.0-beta.3";
|
|
5
5
|
/**
|
|
6
6
|
* AdCP specification version this library is built for
|
|
7
7
|
*/
|
|
@@ -33,10 +33,10 @@ export type AdcpVersion = (typeof COMPATIBLE_ADCP_VERSIONS)[number];
|
|
|
33
33
|
* Full version information
|
|
34
34
|
*/
|
|
35
35
|
export declare const VERSION_INFO: {
|
|
36
|
-
readonly library: "16.0.0-beta.
|
|
36
|
+
readonly library: "16.0.0-beta.3";
|
|
37
37
|
readonly adcp: "3.2.4";
|
|
38
38
|
readonly compatibleVersions: readonly ["v2.5", "v2.6", "v3", "3.0.0", "3.0", "3.0.1", "3.0.2", "3.0.3", "3.0.4", "3.0.5", "3.0.6", "3.0.7", "3.0.8", "3.0.9", "3.0.10", "3.0.11", "3.0.12", "3.0.13", "3.0.14", "3.0.15", "3.0.16", "3.0.17", "3.0.18", "3.0.19", "3.0.20", "3.0.21", "3.0.22", "3.0.23", "3.0.24", "3.0.25", "3.1.0", "3.1", "3.1.1", "3.1.2", "3.1.3", "3.1.4", "3.1.5", "3.1.6", "3.1.7", "3.1.8", "3.1.9", "3.1.10", "3.1.11", "3.1.12", "3.1.13", "3.1.14", "3.1.15", "3.1.16", "3.1.17", "3.1.18", "3.1.19", "3.1.20", "3.1.21", "3.1.22", "3.1.23", "3.1.24", "3.2.1", "3.2", "3.2.2", "3.2.3", "3.2.4"];
|
|
39
|
-
readonly generatedAt: "2026-10-
|
|
39
|
+
readonly generatedAt: "2026-10-15T18:57:32.995Z";
|
|
40
40
|
};
|
|
41
41
|
/**
|
|
42
42
|
* Get the AdCP specification version this library is built for
|
package/dist/lib/version.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* AdCP SDK library version
|
|
3
3
|
*/
|
|
4
|
-
export declare const LIBRARY_VERSION = "16.0.0-beta.
|
|
4
|
+
export declare const LIBRARY_VERSION = "16.0.0-beta.3";
|
|
5
5
|
/**
|
|
6
6
|
* AdCP specification version this library is built for
|
|
7
7
|
*/
|
|
@@ -33,10 +33,10 @@ export type AdcpVersion = (typeof COMPATIBLE_ADCP_VERSIONS)[number];
|
|
|
33
33
|
* Full version information
|
|
34
34
|
*/
|
|
35
35
|
export declare const VERSION_INFO: {
|
|
36
|
-
readonly library: "16.0.0-beta.
|
|
36
|
+
readonly library: "16.0.0-beta.3";
|
|
37
37
|
readonly adcp: "3.2.4";
|
|
38
38
|
readonly compatibleVersions: readonly ["v2.5", "v2.6", "v3", "3.0.0", "3.0", "3.0.1", "3.0.2", "3.0.3", "3.0.4", "3.0.5", "3.0.6", "3.0.7", "3.0.8", "3.0.9", "3.0.10", "3.0.11", "3.0.12", "3.0.13", "3.0.14", "3.0.15", "3.0.16", "3.0.17", "3.0.18", "3.0.19", "3.0.20", "3.0.21", "3.0.22", "3.0.23", "3.0.24", "3.0.25", "3.1.0", "3.1", "3.1.1", "3.1.2", "3.1.3", "3.1.4", "3.1.5", "3.1.6", "3.1.7", "3.1.8", "3.1.9", "3.1.10", "3.1.11", "3.1.12", "3.1.13", "3.1.14", "3.1.15", "3.1.16", "3.1.17", "3.1.18", "3.1.19", "3.1.20", "3.1.21", "3.1.22", "3.1.23", "3.1.24", "3.2.1", "3.2", "3.2.2", "3.2.3", "3.2.4"];
|
|
39
|
-
readonly generatedAt: "2026-10-
|
|
39
|
+
readonly generatedAt: "2026-10-15T18:57:32.995Z";
|
|
40
40
|
};
|
|
41
41
|
/**
|
|
42
42
|
* Get the AdCP specification version this library is built for
|
package/dist/lib/version.js
CHANGED
|
@@ -31,7 +31,7 @@ __export(version_exports, {
|
|
|
31
31
|
toReleasePrecisionVersion: () => toReleasePrecisionVersion
|
|
32
32
|
});
|
|
33
33
|
module.exports = __toCommonJS(version_exports);
|
|
34
|
-
const LIBRARY_VERSION = "16.0.0-beta.
|
|
34
|
+
const LIBRARY_VERSION = "16.0.0-beta.3";
|
|
35
35
|
const ADCP_VERSION = "3.2.4";
|
|
36
36
|
const ADCP_MAJOR_VERSION = 3;
|
|
37
37
|
const COMPATIBLE_ADCP_VERSIONS = [
|
|
@@ -98,10 +98,10 @@ const COMPATIBLE_ADCP_VERSIONS = [
|
|
|
98
98
|
"3.2.4"
|
|
99
99
|
];
|
|
100
100
|
const VERSION_INFO = {
|
|
101
|
-
library: "16.0.0-beta.
|
|
101
|
+
library: "16.0.0-beta.3",
|
|
102
102
|
adcp: "3.2.4",
|
|
103
103
|
compatibleVersions: COMPATIBLE_ADCP_VERSIONS,
|
|
104
|
-
generatedAt: "2026-10-
|
|
104
|
+
generatedAt: "2026-10-15T18:57:32.995Z"
|
|
105
105
|
};
|
|
106
106
|
function getAdcpVersion() {
|
|
107
107
|
return ADCP_VERSION;
|
package/dist/lib/version.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const LIBRARY_VERSION = "16.0.0-beta.
|
|
1
|
+
const LIBRARY_VERSION = "16.0.0-beta.3";
|
|
2
2
|
const ADCP_VERSION = "3.2.4";
|
|
3
3
|
const ADCP_MAJOR_VERSION = 3;
|
|
4
4
|
const COMPATIBLE_ADCP_VERSIONS = [
|
|
@@ -65,10 +65,10 @@ const COMPATIBLE_ADCP_VERSIONS = [
|
|
|
65
65
|
"3.2.4"
|
|
66
66
|
];
|
|
67
67
|
const VERSION_INFO = {
|
|
68
|
-
library: "16.0.0-beta.
|
|
68
|
+
library: "16.0.0-beta.3",
|
|
69
69
|
adcp: "3.2.4",
|
|
70
70
|
compatibleVersions: COMPATIBLE_ADCP_VERSIONS,
|
|
71
|
-
generatedAt: "2026-10-
|
|
71
|
+
generatedAt: "2026-10-15T18:57:32.995Z"
|
|
72
72
|
};
|
|
73
73
|
function getAdcpVersion() {
|
|
74
74
|
return ADCP_VERSION;
|
package/docs/TYPE-SUMMARY.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# AdCP Type Summary
|
|
2
2
|
|
|
3
|
-
> Generated at: 2026-10-
|
|
4
|
-
> @adcp/sdk v16.0.0-beta.
|
|
3
|
+
> Generated at: 2026-10-15
|
|
4
|
+
> @adcp/sdk v16.0.0-beta.3
|
|
5
5
|
|
|
6
6
|
Curated reference of the types that matter for using the AdCP client. For full generated types see `src/lib/types/tools.generated.ts` and `src/lib/types/core.generated.ts`.
|
|
7
7
|
|
|
@@ -49,6 +49,11 @@ interface A2ALegacyCompatOptions {
|
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
interface TransportOptions {
|
|
52
|
+
// Defaults to 4 MiB (DEFAULT_MAX_RESPONSE_BYTES); only 0 opts out
|
|
53
|
+
// (Infinity / negatives fall back to the default).
|
|
54
|
+
// SSE is bounded per event plus `maxResponseBytes * 2` cumulative per call.
|
|
55
|
+
// Over-cap responses throw ResponseTooLargeError; nothing is truncated.
|
|
56
|
+
// A per-call `transport` replaces this object; it does not merge.
|
|
52
57
|
maxResponseBytes?: number;
|
|
53
58
|
trustedFetchFn?: typeof fetch;
|
|
54
59
|
allowPrivateIp?: boolean;
|
|
@@ -55,7 +55,7 @@ The key is a SHA-256 over:
|
|
|
55
55
|
| configured `adcpVersion` / `wireAdcpVersion` | negotiated version |
|
|
56
56
|
| every non-correlation, non-credential header | unknown `x-*` tenant / routing / policy headers can select a different upstream view, so they fail closed into the key. This includes `baggage`, **ambient OpenTelemetry baggage included** |
|
|
57
57
|
| request-signing identity and policy | `kind`, `kid`, `alg`, agent URL and signing policy; never the private key |
|
|
58
|
-
|
|
|
58
|
+
| configured `allowPrivateIp`, `maxResponseBytes` | the transport policy the evidence was gathered under (per-call `transport` overrides included). These are the values the caller *configured*, not the effective ones: an unset `maxResponseBytes` keys as "unset" rather than as the 4 MiB default, so entries written before the default landed stay reusable. The MCP connection cache keys the *resolved* cap instead — see [Reusable MCP connections](#reusable-mcp-connections) |
|
|
59
59
|
|
|
60
60
|
Not part of the key: correlation headers (`x-request-id`, `x-correlation-id`, `traceparent`, ...), and credential header values (`Authorization`, `x-adcp-auth`) — OAuth and `auth_token` credentials are also owned by `authIdentity`; a token rotation for the same authorization scope keeps the entry. **Choose `authIdentity` at least as narrow as the credential's authorization scope.** Change the identity or invalidate the cache when permissions change or access is revoked; use a distinct identity for anonymous access. Two principals must never share an identity. Keys are hashes and never contain the identity, token or header values.
|
|
61
61
|
|
|
@@ -101,7 +101,7 @@ Unlike [`primeCapabilities`](../TYPE-SUMMARY.md) — which stays client-bound an
|
|
|
101
101
|
|
|
102
102
|
This behavior applies by default, including calls that pass a signal or timeout outside a connection scope. The process-wide legacy/OAuth session cache retains at most 20 connections per cache with LRU eviction and has no idle expiry. For request workflows with many distinct credentials, use a scope to bound session lifetime. At process shutdown, `closeConnections()` from `@adcp/sdk/advanced` closes the process-wide connections.
|
|
103
103
|
|
|
104
|
-
A reusable session is keyed only by what changes the _connection_: endpoint, credential, tenant / routing headers, signing identity, `allowPrivateIp`, a caller-injected fetch, and the workflow scope. These no longer choose or split a session:
|
|
104
|
+
A reusable session is keyed only by what changes the _connection_: endpoint, credential, tenant / routing headers, signing identity, `allowPrivateIp`, `maxResponseBytes`, a caller-injected fetch, and the workflow scope. These no longer choose or split a session:
|
|
105
105
|
|
|
106
106
|
- **Correlation headers**: `traceparent`, `tracestate`, `x-request-id`, `x-correlation-id`, `x-trace-id`, `x-span-id`, `x-debug-id`, `x-client-request-id`, `x-b3-*`, `x-amzn-trace-id`, `x-cloud-trace-context`, `x-datadog-*`, `sentry-trace`, and vendor-prefixed `x-<vendor>-request-id` / `-correlation-id` / `-trace-id` / `-span-id` / `-debug-id`. Names suggesting credentials or tenant/routing identity (including `auth`, `token`, `tenant`, `account`, `workspace`, `seat`, `advertiser`, `publisher`, `buyer` and `seller`) are never treated as correlation. **`baggage` stays in the key**: it can carry tenant or routing members. Any header outside the list above also stays in the key (fail closed).
|
|
107
107
|
- **`AbortSignal`** and **`requestTimeoutMs`**: they bound a call.
|
|
@@ -114,6 +114,7 @@ Isolation properties:
|
|
|
114
114
|
- A caller that joins another caller's in-flight connect waits under its own signal and timeout. If the creator cancels the connect, the joiner retries for itself, with at most two retries after foreign aborts.
|
|
115
115
|
- A caller-injected `fetchFn` (a per-call network trust boundary) keeps its own one-shot session outside a connection scope; inside a scope its identity is part of the key.
|
|
116
116
|
- Connections are never shared across credentials, tenant headers, signing identities or `allowPrivateIp` settings.
|
|
117
|
+
- Connections are never shared across different `maxResponseBytes` values either. The response cap is decided once per request, and a session's standalone `GET` event-stream listener issues exactly one request — at connect time — so it carries whatever policy opened the connection for the life of that connection. Sharing across policies would let one `maxResponseBytes: 0` call hand an uncapped listener to every later caller. The key uses the *resolved* cap, so an explicit `4 * 1024 * 1024` and an unset value are the same policy and share a session; `0` and any other number each get their own. Varying the cap per call therefore costs a session per distinct value against the same agent, against a 20-entry LRU — prefer a single client-level value where you can, or pin the session with `withMCPConnectionScope` where continuity matters.
|
|
117
118
|
|
|
118
119
|
### Public connection scope
|
|
119
120
|
|
|
@@ -1017,9 +1017,9 @@ setInterval(() => {
|
|
|
1017
1017
|
BigQuery's server-side `jobTimeoutMs` is not used: for a local-file load the
|
|
1018
1018
|
official client builds `configuration.load` from the load options and cannot
|
|
1019
1019
|
set job-level fields, and BigQuery silently drops `labels` and `jobTimeoutMs`
|
|
1020
|
-
found inside `configuration.load`. (Staging the file in GCS and submitting
|
|
1021
|
-
`bigquery.createJob` can set both; the sink does not stage
|
|
1022
|
-
same reason the `labels` option has no effect (it warns once per process and
|
|
1020
|
+
found inside `configuration.load`. (Staging the file in GCS and submitting
|
|
1021
|
+
the load with `bigquery.createJob` can set both; the sink does not stage
|
|
1022
|
+
files.) For the same reason the `labels` option has no effect (it warns once per process and
|
|
1023
1023
|
is deprecated). To attribute load cost, query
|
|
1024
1024
|
`` `region-<location>`.INFORMATION_SCHEMA.JOBS_BY_PROJECT `` (needs
|
|
1025
1025
|
`bigquery.jobs.listAll`; about 180 days of history), filtering on
|
|
@@ -1067,6 +1067,16 @@ setInterval(() => {
|
|
|
1067
1067
|
rejects after clearing the sink (it could not unregister the consumer), call
|
|
1068
1068
|
it again before restarting workers. Re-run `REPORTING_WAREHOUSE_SINK_MIGRATION`
|
|
1069
1069
|
after upgrading: it adds the `reset_generation` column.
|
|
1070
|
+
- Upgrading from 15.9.0: stop every 15.9.0 sink worker before starting newer
|
|
1071
|
+
ones, then re-apply `REPORTING_WAREHOUSE_SINK_MIGRATION`. A 15.9.0 worker
|
|
1072
|
+
cancels a load at its deadline, so one running beside a newer worker on the
|
|
1073
|
+
same sink can cancel a job the newer worker is waiting on. The job then ends
|
|
1074
|
+
`DONE` with an error and the attempt advances. Rows do not duplicate, but
|
|
1075
|
+
convergence slows. Also set `location` to the dataset's location: without it
|
|
1076
|
+
a replay lookup of a load job returns 404 for datasets outside the US and EU
|
|
1077
|
+
multi-regions, and the sink uploads again, gets a 409, and fails with a
|
|
1078
|
+
"check projectId and location" error. The sink warns once per process when
|
|
1079
|
+
`location` is unset.
|
|
1070
1080
|
- Stop old sink workers before relying on these overlap guarantees. If an
|
|
1071
1081
|
earlier overlapping run left a plan whose starting cursor differs from the
|
|
1072
1082
|
committed cursor, the sink rejects it before loading. Reconcile the retained
|
|
@@ -1230,7 +1240,7 @@ Managed-only changes are lifecycle candidates in their own right. A settlement,
|
|
|
1230
1240
|
|
|
1231
1241
|
`MAX_MATERIALIZATIONS_PER_ACCOUNT` and `MAX_RECEIPTS_PER_CONSUMER` are lifetime counts by default. Because managed evidence is immutable, a long-lived account eventually reaches them and then stops planning materializations and refuses every receipt with no way back. Construct the store with `new PostgresReportingManagedDeliveryStore(pool, { evidenceRetentionDays })` to make the caps active-scope: only evidence recorded inside that window counts against them, and `pruneExpiredEvidence({ account_id, limit })` deletes what has fallen outside it — never anything still inside the window, never a `pending` or leased materialization, and never a receipt batch inside its own replay retention. Retention has a floor: at least the 30-day receipt replay retention, and at least the strongest durable status or resource-retention horizon registered for the database. Adoption and binding installation exclusively lock the migration-created policy sentinel before account/binding locks; settlement, revocation claim, and pruning hold shared locks on it through their writes. A stronger promise therefore cannot land between a weaker check and its write, while unrelated hot-path readers remain concurrent. Pruning genuinely does its selection before taking the account lock, and asks which receipts a live replay row still names by expanding those rows once rather than posing a containment question per candidate — a shape no index could serve, which held the lock long enough to fail concurrent Core writes with 55P03. Because that selection is unlocked it is a proposal rather than a verdict: every victim is revalidated under the account lock against current live replay rows, surviving receipts and unexpired resources before it is deleted, so a replay that commits in the gap keeps the receipt it promised to reproduce. The revalidation is narrowed to the candidates' own consumers and keys, so the lock still holds no per-candidate scan. The registry lock is held to commit inside the transaction that acts on it, and a precondition such as the installed-window check runs inside that same transaction so a refusal rolls the write back rather than leaving a durable promise nobody validated, so an install cannot read an empty registry while a narrower promise is being registered, and a prune cannot approve a horizon another replica is about to widen. Pruning deletes and tombstones in one statement against one frozen cutoff, so a moving boundary can never leave a deleted row without its permanent identity. Successive prunes demote the tombstones they supersede, so a subject has exactly one tombstone still claiming to be its leaf and a chain pruned twice resolves the same way every time. Re-presenting a pruned receipt byte-identically answers `unchanged` with the instant the tombstone kept, resolves that receipt's own tombstone before any rule about its subject — so an exact re-presentation is not refused as new content for a settled subject — replays the same answer under the same idempotency key by rehydrating from the tombstone when the body is gone, counts as already-resolved for the batch's duplicate-subject rule, and never recreates the row: recreating it restarted the retention clock, undid the storage the prune reclaimed, and moved the published `received_at` to a moment the consumer never filed anything at. A pruned receipt ID can never bind different content, a subject whose accepted leaf expired can never reopen — the read projection consults tombstones, not just live rows — and materialization attempt history survives as a compact terminal record, so a revision that exhausted its attempts or already succeeded does not restart at attempt 1 once its rows age out. Both conclusions — the acceptance and the fact a delivery succeeded — are folded into the live, filtered and lifecycle projections alike. Counters describe exactly the records the response emits, never more and never less, so a buyer recomputing the association cannot see `ASSOCIATED_HISTORY_INCOMPLETE`; retention therefore refuses to prune an acceptance while the resource it accepts is still readable, which is what keeps a `complete` period from having nothing to show for itself. An acceptance carries the consumer that gave it, so one consumer's pruned acceptance never settles the obligation on another's behalf — including the anonymous fail-safe consumer, which owns no acceptances at all. Pruning also removes the expired replay row before the receipts it names, keeps any receipt a surviving replay row still references — a later batch can name an earlier receipt — and keeps any materialization whose resource is still readable or that a retained receipt names as its evidence. An adjustment receipt names no materialization — it names the revision it corrects — so the readable-resource hold matches on that revision as well, or a period whose revision resource was still readable lost the adjustment acceptance behind its own `complete`. Run it from the same scheduler that runs the worker. Lifecycle receipt reads are driven from the obligation's own subjects into a `(subject_id, receipt_kind, recorded_at)` index rather than asking the global receipt table which of its rows belong to an obligation — a question that supplies neither account nor consumer, so every due obligation re-scanned the whole receipt history. The managed state digest, the obligated-consumer roster read and the permanent delivery tombstones do the same — consumer statuses carry an `obligation_id` index and materialization tombstones an `(obligation_id, reached_success, reached_success_at)` one — because that digest is read inside the apply transaction while it holds the account lock: a scan there is a scan with the lock held, which pushed concurrent Core writes past their lock timeout and failed them with 55P03.
|
|
1232
1242
|
|
|
1233
|
-
The managed tables are additive and do not alter the Core tables. This is the schema boundary coordinated with
|
|
1243
|
+
The managed tables are additive and do not alter the Core tables. This is the schema boundary coordinated with the reporting notification work: that work owns transactional reporting notification/activity intent and the existing webhook delivery/credential plane. Managed Delivery does not create a second webhook sender, outbox, credential store, or subscriber model. Apply both feature migrations after the Core migration in either order; each owns separate tables and both reuse the Core authority.
|
|
1234
1244
|
|
|
1235
1245
|
## Transactional reporting notifications and account activity
|
|
1236
1246
|
|
|
@@ -1749,7 +1759,7 @@ reconciliation and fails closed if both are supplied, preventing double fire;
|
|
|
1749
1759
|
the port's pending rows, rather than `listPendingTransitions()`, own retry.
|
|
1750
1760
|
|
|
1751
1761
|
The activity table is deliberately separate from Core revision and obligation
|
|
1752
|
-
rows. Managed Delivery/Reconciled Billing work
|
|
1762
|
+
rows. Managed Delivery/Reconciled Billing work can add immutable
|
|
1753
1763
|
materialization and receipt tables without changing this transition identity,
|
|
1754
1764
|
queue schema, or migration ordering.
|
|
1755
1765
|
|
|
@@ -121,7 +121,14 @@ service runs for you. See
|
|
|
121
121
|
cannot hold the table indefinitely.
|
|
122
122
|
5. **Warehouse sink.** Apply `REPORTING_WAREHOUSE_SINK_MIGRATION`, create the
|
|
123
123
|
tables, and the `current_rows` view, then schedule `runOnce`. Point analysts
|
|
124
|
-
at `current_rows`.
|
|
124
|
+
at `current_rows`. Set the sink's `location` to the dataset's location: replay
|
|
125
|
+
lookups of load jobs need it outside the US and EU multi-regions, and the sink
|
|
126
|
+
warns once per process when it is unset. When upgrading from 15.9.0, stop
|
|
127
|
+
every 15.9.0 sink worker before starting newer ones, then re-apply
|
|
128
|
+
`REPORTING_WAREHOUSE_SINK_MIGRATION`. A 15.9.0 worker cancels a load at its
|
|
129
|
+
deadline, so one running beside a newer worker on the same sink can cancel a
|
|
130
|
+
job the newer worker is waiting on; the job ends `DONE` with an error and the
|
|
131
|
+
attempt advances. Rows do not duplicate, but convergence slows.
|
|
125
132
|
6. **Retention.** Enable `retention` last, after confirming the advertised
|
|
126
133
|
`status_retention_days` is the window you intend to keep. Retirement deletes
|
|
127
134
|
rows and ledger records for whole periods and cannot be undone. Keep backups
|
|
@@ -344,7 +351,7 @@ What it checks:
|
|
|
344
351
|
and job ID unchanged and that table's persisted deadline grown, the job must
|
|
345
352
|
end `DONE` without an error (the sink never cancels it), and later runs under
|
|
346
353
|
the same sink name must converge with no duplicate rows, the same job ID and
|
|
347
|
-
no second upload. A
|
|
354
|
+
no second upload. A slow-upload scenario runs a sink whose upload of a 50,000-row
|
|
348
355
|
batch outlasts its 1-second deadline and asserts that it converges within 8
|
|
349
356
|
runs, loads every row exactly once, never changes the job ID, and never
|
|
350
357
|
starts an upload after the job exists (a link fast enough to beat the
|
|
@@ -356,11 +363,10 @@ What it checks:
|
|
|
356
363
|
it; in practice it accepts the cancel and lets the load finish, which is why
|
|
357
364
|
the sink never cancels a load and finds it by job ID instead.
|
|
358
365
|
- **Overlapping runs** (`INFO`, never a failure). Two concurrent `runOnce()`
|
|
359
|
-
calls over one pending batch, and a deterministic reproduction of
|
|
366
|
+
calls over one pending batch, and a deterministic reproduction of the stale-plan race: one
|
|
360
367
|
run reads its sink state, another completes the batch and a new revision
|
|
361
368
|
commits, then the first resumes. Without the fence the first run reloads
|
|
362
|
-
revisions the second already loaded (duplicate rows); with the fence
|
|
363
|
-
PR #3197 it rejects as stale and nothing duplicates. Read the verdict in the
|
|
369
|
+
revisions the second already loaded (duplicate rows); with the plan fence it rejects as stale and nothing duplicates. Read the verdict in the
|
|
364
370
|
report; the exit status does not depend on it.
|
|
365
371
|
- **Cross-project.** Set `GCP_CLIENT_PROJECT` to a project other than
|
|
366
372
|
`GCP_BQ_PROJECT`. Load jobs are then created in the destination project, and
|
|
@@ -446,15 +452,15 @@ export GCS_BUCKET=my-test-bucket GCS_PREFIX=adcp-reporting-validation
|
|
|
446
452
|
npm run validate:reporting-gcp -- --yes
|
|
447
453
|
```
|
|
448
454
|
|
|
449
|
-
Against a pull request branch (
|
|
455
|
+
Against a pull request branch (replace `<n>` with its number), keep running the script from
|
|
450
456
|
`main` and point it at a second built checkout, so a branch cut before this
|
|
451
457
|
script existed still works:
|
|
452
458
|
|
|
453
459
|
```bash
|
|
454
|
-
git fetch origin pull
|
|
455
|
-
git worktree add ../adcp-client-pr
|
|
456
|
-
(cd ../adcp-client-pr
|
|
457
|
-
ADCP_SDK_ROOT=../adcp-client-pr
|
|
460
|
+
git fetch origin pull/<n>/head:pr-<n>
|
|
461
|
+
git worktree add ../adcp-client-pr-<n> pr-<n>
|
|
462
|
+
(cd ../adcp-client-pr-<n> && npm ci && npm run build)
|
|
463
|
+
ADCP_SDK_ROOT=../adcp-client-pr-<n> npm run validate:reporting-gcp -- --yes
|
|
458
464
|
```
|
|
459
465
|
|
|
460
466
|
The same environment applies. The run ends with a `PASS`, `FAIL` and `INFO`
|
|
@@ -462,7 +468,7 @@ report and a markdown block (project and bucket names masked) to paste into
|
|
|
462
468
|
the PR. The exit status is 0 with no `FAIL`, 1 with any `FAIL`, and 2 for a
|
|
463
469
|
configuration problem or a missing `--yes`. Results of the overlap probes are
|
|
464
470
|
`INFO` on purpose: on `main` expect the stale-run probe to report duplicates,
|
|
465
|
-
and on
|
|
471
|
+
and on a branch with the plan fence expect it to report none.
|
|
466
472
|
|
|
467
473
|
`test/lib/reporting-gcp-validation-pg.test.js` drives the script's core against
|
|
468
474
|
in-memory BigQuery and Storage doubles and a real PostgreSQL, so the logic,
|
|
@@ -96,3 +96,41 @@ Do not create a global mapping based only on a token's spelling. A token such as
|
|
|
96
96
|
cookie for another, and an account identifier for a third. Scope every mapping
|
|
97
97
|
to its source dialect and keep the supporting vendor documentation with the
|
|
98
98
|
registry entry.
|
|
99
|
+
|
|
100
|
+
Vendor-scoped TCF mappings retain the complete receiving vendor ID: map
|
|
101
|
+
`${GDPR_CONSENT_755}` to `{GDPR_CONSENT_755}`, never to unscoped
|
|
102
|
+
`{GDPR_CONSENT}` or another vendor's token. The suffix must be a positive
|
|
103
|
+
decimal integer without leading zeros. `{ADDTL_CONSENT}` is also supported,
|
|
104
|
+
with the same source-dialect and documentation requirements. Its CMP-provided
|
|
105
|
+
value is opaque; the helper does not generate consent or modify provider lists.
|
|
106
|
+
|
|
107
|
+
For the return translation, supply exact native mappings:
|
|
108
|
+
|
|
109
|
+
```typescript
|
|
110
|
+
import { translateUniversalMacros } from '@adcp/sdk/substitution';
|
|
111
|
+
|
|
112
|
+
const translated = translateUniversalMacros(
|
|
113
|
+
'https://pixel.vendor.example/i?gdpr={GDPR}&c={GDPR_CONSENT_755}&a={ADDTL_CONSENT}',
|
|
114
|
+
{
|
|
115
|
+
'{GDPR}': { native: '${GDPR}' },
|
|
116
|
+
'{GDPR_CONSENT_755}': { native: '${GDPR_CONSENT_755}' },
|
|
117
|
+
'{ADDTL_CONSENT}': { native: '${ADDTL_CONSENT}' },
|
|
118
|
+
}
|
|
119
|
+
);
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Existing native tokens pass through unchanged. The emitted URL may contain at
|
|
123
|
+
most one scoped TCF token, including pre-existing tokens and native aliases
|
|
124
|
+
identified by the supplied mappings. After dropping unsupported parameters,
|
|
125
|
+
multiple occurrences throw `MultipleVendorConsentMacrosError` with code
|
|
126
|
+
`multiple_vendor_consent_macros` and the second token in canonical AdCP form.
|
|
127
|
+
Additional Consent does not count toward that limit. Concrete `value` mappings
|
|
128
|
+
are encoded and reported in `frozen_consent_macros`; missing consent mappings
|
|
129
|
+
appear in `dropped_consent_macros`. When an unscoped target requires an unknown
|
|
130
|
+
vendor ID, use `'{GDPR_CONSENT}': { value: '' }` and translate `{GDPR}`
|
|
131
|
+
independently rather than guessing an ID.
|
|
132
|
+
|
|
133
|
+
These helpers implement the AdCP 3.3 translation contract. Generated protocol
|
|
134
|
+
types and declaration/capability validation still follow the SDK's pinned schema
|
|
135
|
+
release. Helper support alone does not establish a resolver's declared support
|
|
136
|
+
for a scoped token or Additional Consent.
|
|
@@ -668,6 +668,18 @@ try {
|
|
|
668
668
|
|
|
669
669
|
These policies follow the language-neutral fixture ratified in [AdCP #6674](https://github.com/adcontextprotocol/adcp/issues/6674).
|
|
670
670
|
|
|
671
|
+
The AdCP 3.3 fixture also covers vendor-scoped `{GDPR_CONSENT_<gvl_id>}` and
|
|
672
|
+
`{ADDTL_CONSENT}`. Preserve the receiving vendor ID and treat Additional Consent
|
|
673
|
+
as opaque CMP data. Both participate in dropped/frozen consent diagnostics.
|
|
674
|
+
After unsupported parameters are dropped, a URL with multiple scoped TCF
|
|
675
|
+
occurrences throws `MultipleVendorConsentMacrosError` (exported from both
|
|
676
|
+
`@adcp/sdk` and `@adcp/sdk/substitution`), with code
|
|
677
|
+
`multiple_vendor_consent_macros` and the canonical second token in `macro`.
|
|
678
|
+
Existing native tokens and verified native aliases count; encoded concrete
|
|
679
|
+
values and Additional Consent do not. See the
|
|
680
|
+
[compilation guide](UNIVERSAL-MACRO-COMPILATION.md) for mapping and schema-version
|
|
681
|
+
boundaries.
|
|
682
|
+
|
|
671
683
|
---
|
|
672
684
|
|
|
673
685
|
## The fork-matrix: canonical adapter → compliance
|
package/docs/llms.txt
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Ad Context Protocol (AdCP)
|
|
2
2
|
|
|
3
|
-
> Generated at: 2026-10-
|
|
4
|
-
> Library: @adcp/sdk v16.0.0-beta.
|
|
3
|
+
> Generated at: 2026-10-15
|
|
4
|
+
> Library: @adcp/sdk v16.0.0-beta.3
|
|
5
5
|
> AdCP major version: 3
|
|
6
6
|
> Canonical URL: https://adcontextprotocol.github.io/adcp-client/llms.txt
|
|
7
7
|
> Note: the `Library` stamp reflects the package.json version at doc-generation time. The narrative below describes the surface that lands on the next-published minor — including any 6.7 helpers documented here ahead of the release tag.
|