@adcp/sdk 14.0.0-rc.41 → 14.0.0-rc.42
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/adcp-grade.js +4 -3
- package/bin/adcp-storyboard-summary.js +1 -1
- package/bin/adcp.js +4 -6
- package/dist/lib/conformance/index.d.mts +2 -0
- package/dist/lib/conformance/index.d.ts +2 -0
- package/dist/lib/conformance/index.js +7 -0
- package/dist/lib/conformance/index.mjs +8 -0
- package/dist/lib/conformance/targeting.d.mts +72 -0
- package/dist/lib/conformance/targeting.d.ts +72 -0
- package/dist/lib/conformance/targeting.js +163 -0
- package/dist/lib/conformance/targeting.mjs +137 -0
- package/dist/lib/core/AgentClient.d.mts +27 -1
- package/dist/lib/core/AgentClient.d.ts +27 -1
- package/dist/lib/core/AgentClient.js +41 -2
- package/dist/lib/core/AgentClient.mjs +39 -1
- package/dist/lib/errors/index.d.mts +4 -1
- package/dist/lib/errors/index.d.ts +4 -1
- package/dist/lib/errors/index.js +6 -1
- package/dist/lib/errors/index.mjs +6 -1
- package/dist/lib/index.d.mts +1 -1
- package/dist/lib/index.d.ts +1 -1
- package/dist/lib/index.js +2 -0
- package/dist/lib/index.mjs +3 -1
- package/dist/lib/media-buy/action-assessment.js +7 -0
- package/dist/lib/media-buy/action-assessment.mjs +7 -0
- package/dist/lib/media-buy/available-actions.d.mts +8 -1
- package/dist/lib/media-buy/available-actions.d.ts +8 -1
- package/dist/lib/media-buy/available-actions.js +18 -3
- package/dist/lib/media-buy/available-actions.mjs +15 -2
- package/dist/lib/media-buy/index.d.mts +1 -0
- package/dist/lib/media-buy/index.d.ts +1 -0
- package/dist/lib/media-buy/preflight.js +23 -12
- package/dist/lib/media-buy/preflight.mjs +25 -13
- package/dist/lib/protocols/transportDiagnostics.d.mts +2 -0
- package/dist/lib/protocols/transportDiagnostics.d.ts +2 -0
- package/dist/lib/protocols/transportDiagnostics.js +60 -20
- package/dist/lib/protocols/transportDiagnostics.mjs +61 -21
- package/dist/lib/reporting/ledger/handler.js +67 -11
- package/dist/lib/reporting/ledger/handler.mjs +69 -12
- package/dist/lib/reporting/ledger/producer.js +4 -9
- package/dist/lib/reporting/ledger/producer.mjs +4 -9
- package/dist/lib/reporting/ledger/status-ingest.js +1 -1
- package/dist/lib/reporting/ledger/status-ingest.mjs +1 -1
- package/dist/lib/reporting/reconciliation.d.mts +4 -9
- package/dist/lib/reporting/reconciliation.d.ts +4 -9
- package/dist/lib/reporting/reconciliation.js +5 -5
- package/dist/lib/reporting/reconciliation.mjs +5 -5
- package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
- package/dist/lib/server/decisioning/runtime/from-platform.js +16 -3
- package/dist/lib/server/decisioning/runtime/from-platform.mjs +16 -3
- package/dist/lib/server/index.d.mts +1 -0
- package/dist/lib/server/index.d.ts +1 -0
- package/dist/lib/server/media-buy-actions.js +3 -1
- package/dist/lib/server/media-buy-actions.mjs +3 -1
- package/dist/lib/testing/storyboard/request-signing/a2a-dispatch.d.mts +118 -0
- package/dist/lib/testing/storyboard/request-signing/a2a-dispatch.d.ts +118 -0
- package/dist/lib/testing/storyboard/request-signing/a2a-dispatch.js +180 -0
- package/dist/lib/testing/storyboard/request-signing/a2a-dispatch.mjs +144 -0
- package/dist/lib/testing/storyboard/request-signing/builder.d.mts +21 -1
- package/dist/lib/testing/storyboard/request-signing/builder.d.ts +21 -1
- package/dist/lib/testing/storyboard/request-signing/builder.js +22 -0
- package/dist/lib/testing/storyboard/request-signing/builder.mjs +22 -0
- package/dist/lib/testing/storyboard/request-signing/grader.d.mts +5 -6
- package/dist/lib/testing/storyboard/request-signing/grader.d.ts +5 -6
- package/dist/lib/testing/storyboard/request-signing/grader.js +79 -8
- package/dist/lib/testing/storyboard/request-signing/grader.mjs +79 -8
- package/dist/lib/testing/storyboard/request-signing/index.d.mts +1 -0
- package/dist/lib/testing/storyboard/request-signing/index.d.ts +1 -0
- package/dist/lib/testing/storyboard/request-signing/index.js +7 -0
- package/dist/lib/testing/storyboard/request-signing/index.mjs +8 -0
- package/dist/lib/testing/storyboard/request-signing/probe-dispatch.d.mts +10 -29
- package/dist/lib/testing/storyboard/request-signing/probe-dispatch.d.ts +10 -29
- package/dist/lib/testing/storyboard/request-signing/probe-dispatch.js +49 -5
- package/dist/lib/testing/storyboard/request-signing/probe-dispatch.mjs +39 -5
- package/dist/lib/testing/storyboard/runner.js +28 -2
- package/dist/lib/testing/storyboard/runner.mjs +18 -2
- package/dist/lib/testing/storyboard/types.d.mts +8 -19
- package/dist/lib/testing/storyboard/types.d.ts +8 -19
- package/dist/lib/testing/storyboard/validations.d.mts +1 -1
- package/dist/lib/testing/storyboard/validations.d.ts +1 -1
- package/dist/lib/types/index.d.mts +11 -2
- package/dist/lib/types/index.d.ts +11 -2
- package/dist/lib/types/schemas.generated.js +17 -0
- package/dist/lib/types/schemas.generated.mjs +17 -0
- package/dist/lib/utils/reporting-status-response.js +2 -2
- package/dist/lib/utils/reporting-status-response.mjs +2 -2
- package/dist/lib/validation/schema-loader.js +13 -6
- package/dist/lib/validation/schema-loader.mjs +13 -6
- 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 +9 -1
- package/docs/guides/EXISTING-PLATFORM.md +61 -33
- package/docs/guides/MEDIA-BUY-3.2-COMPATIBILITY.md +27 -1
- package/docs/guides/REPORTING-LEDGER.md +3 -1
- package/docs/guides/REPORTING-RECONCILIATION.md +1 -1
- package/docs/guides/VALIDATE-YOUR-AGENT.md +4 -4
- package/docs/llms.txt +2 -2
- package/docs/migration-14.x-rc-worksheet.md +4 -4
- package/examples/existing-platform-thin.ts +29 -1
- package/examples/targeting-input-existing-platform.ts +2 -8
- package/package.json +1 -1
- package/skills/build-seller-agent/specialisms/signed-requests.md +1 -1
package/bin/adcp-grade.js
CHANGED
|
@@ -43,7 +43,8 @@ Options:
|
|
|
43
43
|
--transport <mode> \`mcp\` (default) wraps each vector body in a
|
|
44
44
|
JSON-RPC tools/call envelope and posts to the
|
|
45
45
|
agent's MCP mount (see #612); \`raw\` posts to
|
|
46
|
-
per-operation AdCP endpoints (REST-binding agents)
|
|
46
|
+
per-operation AdCP endpoints (REST-binding agents);
|
|
47
|
+
\`a2a\` signs the official A2A client's request.
|
|
47
48
|
--timeout <ms> Per-probe timeout (default 10000)
|
|
48
49
|
--json Emit the full GradeReport as JSON
|
|
49
50
|
-h, --help Show this help
|
|
@@ -199,8 +200,8 @@ async function runRequestSigningGrader(args) {
|
|
|
199
200
|
break;
|
|
200
201
|
case '--transport': {
|
|
201
202
|
const mode = args[++i];
|
|
202
|
-
if (mode !== 'raw' && mode !== 'mcp') {
|
|
203
|
-
console.error(`ERROR: --transport must be \"raw\" or \"
|
|
203
|
+
if (mode !== 'raw' && mode !== 'mcp' && mode !== 'a2a') {
|
|
204
|
+
console.error(`ERROR: --transport must be \"raw\", \"mcp\", or \"a2a\", got \"${mode}\"\n`);
|
|
204
205
|
process.exit(2);
|
|
205
206
|
}
|
|
206
207
|
options.transport = mode;
|
|
@@ -350,7 +350,7 @@ function formatStepVerdictLines(step, options = {}) {
|
|
|
350
350
|
return [`${step?.passed ? '✅ Passed' : '❌ Failed'}${suffix}`];
|
|
351
351
|
}
|
|
352
352
|
|
|
353
|
-
const SIGNING_TRANSPORTS = ['raw', 'mcp'];
|
|
353
|
+
const SIGNING_TRANSPORTS = ['raw', 'mcp', 'a2a'];
|
|
354
354
|
|
|
355
355
|
// Tokens only ever passed as a (rejected) value for a boolean flag — no
|
|
356
356
|
// storyboard id or agent URL looks like these, so treating them as a misuse
|
package/bin/adcp.js
CHANGED
|
@@ -2180,17 +2180,15 @@ WEBHOOK OPTIONS:
|
|
|
2180
2180
|
HTTP-on-the-wire — spec-compliant.
|
|
2181
2181
|
|
|
2182
2182
|
REQUEST-SIGNING VECTOR OPTIONS (signed_requests storyboard):
|
|
2183
|
-
--signing-transport raw|mcp
|
|
2183
|
+
--signing-transport raw|mcp|a2a How the RFC 9421 conformance vectors are
|
|
2184
2184
|
framed on the wire. NOT the same as
|
|
2185
2185
|
--transport/--protocol, which selects how the
|
|
2186
2186
|
storyboard itself talks to the agent. Default:
|
|
2187
2187
|
inferred from the resolved protocol — an MCP
|
|
2188
2188
|
run wraps each vector in a tools/call envelope
|
|
2189
|
-
(mcp); an A2A run
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
the fixtures have no A2A framing. Pass raw for
|
|
2193
|
-
agents that
|
|
2189
|
+
(mcp); an A2A run signs the exact request the
|
|
2190
|
+
official A2A client emits after Agent Card
|
|
2191
|
+
discovery. Pass raw for agents that
|
|
2194
2192
|
expose AdCP tools as per-operation HTTP
|
|
2195
2193
|
endpoints. Mirrors
|
|
2196
2194
|
\`adcp grade request-signing --transport\`.
|
|
@@ -21,6 +21,8 @@
|
|
|
21
21
|
export { runConformance } from './runConformance.mjs';
|
|
22
22
|
export { runWebhookConformance } from './webhook.mjs';
|
|
23
23
|
export { seedFixtures } from './seeder.mjs';
|
|
24
|
+
export { TARGETING_GEOGRAPHY_CONFORMANCE_VECTORS, buildTargetingInputConformanceVectors, runTargetingInputConformance, } from './targeting.mjs';
|
|
25
|
+
export type { TargetingConformanceOutcome, TargetingConformanceOperation, TargetingDimensionSample, TargetingDimensionSamples, TargetingInputConformanceAdapter, TargetingInputConformanceCaseResult, TargetingInputConformanceObservation, TargetingInputConformanceOptions, TargetingInputConformanceReport, TargetingInputConformanceVector, } from './targeting.mjs';
|
|
24
26
|
export type { SeedOptions, SeedResult, SeederName, SeedWarning } from './seeder.mjs';
|
|
25
27
|
export type { ConformanceSchemaOptions } from './schemaLoader.mjs';
|
|
26
28
|
export { STATELESS_TIER_TOOLS, REFERENTIAL_STATELESS_TOOLS, UPDATE_TIER_TOOLS, COMPACT_STATELESS_TIER_TOOLS, COMPACT_UPDATE_TIER_TOOLS, COMPACT_LIFECYCLE_TOOLS, DEFAULT_TOOLS, DEFAULT_TOOLS_WITH_UPDATES, } from './types.mjs';
|
|
@@ -21,6 +21,8 @@
|
|
|
21
21
|
export { runConformance } from './runConformance';
|
|
22
22
|
export { runWebhookConformance } from './webhook';
|
|
23
23
|
export { seedFixtures } from './seeder';
|
|
24
|
+
export { TARGETING_GEOGRAPHY_CONFORMANCE_VECTORS, buildTargetingInputConformanceVectors, runTargetingInputConformance, } from './targeting';
|
|
25
|
+
export type { TargetingConformanceOutcome, TargetingConformanceOperation, TargetingDimensionSample, TargetingDimensionSamples, TargetingInputConformanceAdapter, TargetingInputConformanceCaseResult, TargetingInputConformanceObservation, TargetingInputConformanceOptions, TargetingInputConformanceReport, TargetingInputConformanceVector, } from './targeting';
|
|
24
26
|
export type { SeedOptions, SeedResult, SeederName, SeedWarning } from './seeder';
|
|
25
27
|
export type { ConformanceSchemaOptions } from './schemaLoader';
|
|
26
28
|
export { STATELESS_TIER_TOOLS, REFERENTIAL_STATELESS_TOOLS, UPDATE_TIER_TOOLS, COMPACT_STATELESS_TIER_TOOLS, COMPACT_UPDATE_TIER_TOOLS, COMPACT_LIFECYCLE_TOOLS, DEFAULT_TOOLS, DEFAULT_TOOLS_WITH_UPDATES, } from './types';
|
|
@@ -25,8 +25,11 @@ __export(conformance_exports, {
|
|
|
25
25
|
DEFAULT_TOOLS_WITH_UPDATES: () => import_types.DEFAULT_TOOLS_WITH_UPDATES,
|
|
26
26
|
REFERENTIAL_STATELESS_TOOLS: () => import_types.REFERENTIAL_STATELESS_TOOLS,
|
|
27
27
|
STATELESS_TIER_TOOLS: () => import_types.STATELESS_TIER_TOOLS,
|
|
28
|
+
TARGETING_GEOGRAPHY_CONFORMANCE_VECTORS: () => import_targeting.TARGETING_GEOGRAPHY_CONFORMANCE_VECTORS,
|
|
28
29
|
UPDATE_TIER_TOOLS: () => import_types.UPDATE_TIER_TOOLS,
|
|
30
|
+
buildTargetingInputConformanceVectors: () => import_targeting.buildTargetingInputConformanceVectors,
|
|
29
31
|
runConformance: () => import_runConformance.runConformance,
|
|
32
|
+
runTargetingInputConformance: () => import_targeting.runTargetingInputConformance,
|
|
30
33
|
runWebhookConformance: () => import_webhook.runWebhookConformance,
|
|
31
34
|
seedFixtures: () => import_seeder.seedFixtures
|
|
32
35
|
});
|
|
@@ -34,6 +37,7 @@ module.exports = __toCommonJS(conformance_exports);
|
|
|
34
37
|
var import_runConformance = require('./runConformance.js');
|
|
35
38
|
var import_webhook = require('./webhook.js');
|
|
36
39
|
var import_seeder = require('./seeder.js');
|
|
40
|
+
var import_targeting = require('./targeting.js');
|
|
37
41
|
var import_types = require('./types.js');
|
|
38
42
|
// Annotate the CommonJS export names for ESM import in node:
|
|
39
43
|
0 && (module.exports = {
|
|
@@ -44,8 +48,11 @@ var import_types = require('./types.js');
|
|
|
44
48
|
DEFAULT_TOOLS_WITH_UPDATES,
|
|
45
49
|
REFERENTIAL_STATELESS_TOOLS,
|
|
46
50
|
STATELESS_TIER_TOOLS,
|
|
51
|
+
TARGETING_GEOGRAPHY_CONFORMANCE_VECTORS,
|
|
47
52
|
UPDATE_TIER_TOOLS,
|
|
53
|
+
buildTargetingInputConformanceVectors,
|
|
48
54
|
runConformance,
|
|
55
|
+
runTargetingInputConformance,
|
|
49
56
|
runWebhookConformance,
|
|
50
57
|
seedFixtures
|
|
51
58
|
});
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import { runConformance } from "./runConformance.mjs";
|
|
2
2
|
import { runWebhookConformance } from "./webhook.mjs";
|
|
3
3
|
import { seedFixtures } from "./seeder.mjs";
|
|
4
|
+
import {
|
|
5
|
+
TARGETING_GEOGRAPHY_CONFORMANCE_VECTORS,
|
|
6
|
+
buildTargetingInputConformanceVectors,
|
|
7
|
+
runTargetingInputConformance
|
|
8
|
+
} from "./targeting.mjs";
|
|
4
9
|
import {
|
|
5
10
|
STATELESS_TIER_TOOLS,
|
|
6
11
|
REFERENTIAL_STATELESS_TOOLS,
|
|
@@ -19,8 +24,11 @@ export {
|
|
|
19
24
|
DEFAULT_TOOLS_WITH_UPDATES,
|
|
20
25
|
REFERENTIAL_STATELESS_TOOLS,
|
|
21
26
|
STATELESS_TIER_TOOLS,
|
|
27
|
+
TARGETING_GEOGRAPHY_CONFORMANCE_VECTORS,
|
|
22
28
|
UPDATE_TIER_TOOLS,
|
|
29
|
+
buildTargetingInputConformanceVectors,
|
|
23
30
|
runConformance,
|
|
31
|
+
runTargetingInputConformance,
|
|
24
32
|
runWebhookConformance,
|
|
25
33
|
seedFixtures
|
|
26
34
|
};
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import type { TargetingOverlayInput } from '../types/core.generated.mjs';
|
|
2
|
+
export type TargetingConformanceOperation = 'create' | 'update';
|
|
3
|
+
export type TargetingConformanceOutcome = 'accepted' | 'rejected';
|
|
4
|
+
export interface TargetingDimensionSample<T> {
|
|
5
|
+
/** Strict configured/stored value used as the vector baseline. */
|
|
6
|
+
initialValue: NonNullable<T>;
|
|
7
|
+
/** Distinct valid request value used to prove complete replacement. */
|
|
8
|
+
replacementValue: NonNullable<T>;
|
|
9
|
+
/** Canonical readback value when it differs from the request value. */
|
|
10
|
+
expectedReplacementValue?: NonNullable<T>;
|
|
11
|
+
/** Whole canonical readback state for cross-dimension materialization. */
|
|
12
|
+
expectedReplacementState?: Record<string, unknown>;
|
|
13
|
+
/** Override for products that cannot execute a clear against inherent scope. */
|
|
14
|
+
expectedNullOutcome?: TargetingConformanceOutcome;
|
|
15
|
+
/** Override for replacements that require renegotiation in the selected fixture. */
|
|
16
|
+
expectedReplacementOutcome?: TargetingConformanceOutcome;
|
|
17
|
+
}
|
|
18
|
+
export type TargetingDimensionSamples = {
|
|
19
|
+
[K in keyof TargetingOverlayInput]?: TargetingDimensionSample<TargetingOverlayInput[K]>;
|
|
20
|
+
};
|
|
21
|
+
export interface TargetingInputConformanceVector {
|
|
22
|
+
id: string;
|
|
23
|
+
operation: TargetingConformanceOperation;
|
|
24
|
+
dimension?: keyof TargetingOverlayInput & string;
|
|
25
|
+
baseline?: Record<string, unknown>;
|
|
26
|
+
/** Present request overlay; `{}` means this dimension was omitted. */
|
|
27
|
+
input?: Record<string, unknown>;
|
|
28
|
+
expectedOutcome: TargetingConformanceOutcome;
|
|
29
|
+
/** Accepted strict state, unchanged update state, or absent state after a rejected create. */
|
|
30
|
+
expectedState: Record<string, unknown> | undefined;
|
|
31
|
+
description: string;
|
|
32
|
+
}
|
|
33
|
+
export interface TargetingInputConformanceObservation {
|
|
34
|
+
outcome: TargetingConformanceOutcome;
|
|
35
|
+
/** Strict durable/readback state after the attempted operation. */
|
|
36
|
+
state?: Record<string, unknown>;
|
|
37
|
+
/** Exact request-only overlay observed at the seller/provider dispatch seam. */
|
|
38
|
+
dispatchedInput?: Record<string, unknown>;
|
|
39
|
+
}
|
|
40
|
+
export interface TargetingInputConformanceAdapter {
|
|
41
|
+
create(vector: TargetingInputConformanceVector): Promise<TargetingInputConformanceObservation>;
|
|
42
|
+
update(vector: TargetingInputConformanceVector): Promise<TargetingInputConformanceObservation>;
|
|
43
|
+
}
|
|
44
|
+
export interface TargetingInputConformanceOptions {
|
|
45
|
+
/** Override when a seller has a documented canonical ordering/materialization policy. */
|
|
46
|
+
compareState?: (observed: Record<string, unknown> | undefined, expected: Record<string, unknown> | undefined, vector: TargetingInputConformanceVector) => boolean;
|
|
47
|
+
}
|
|
48
|
+
export interface TargetingInputConformanceCaseResult {
|
|
49
|
+
id: string;
|
|
50
|
+
passed: boolean;
|
|
51
|
+
failures: string[];
|
|
52
|
+
vector: TargetingInputConformanceVector;
|
|
53
|
+
observation?: TargetingInputConformanceObservation;
|
|
54
|
+
}
|
|
55
|
+
export interface TargetingInputConformanceReport {
|
|
56
|
+
passed: boolean;
|
|
57
|
+
cases: TargetingInputConformanceCaseResult[];
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Generate create/update omit, null, and value vectors for every supplied
|
|
61
|
+
* targeting dimension. Samples are schema-typed and share one multi-dimension
|
|
62
|
+
* baseline so the corpus catches adapters that clear unrelated omitted axes.
|
|
63
|
+
*/
|
|
64
|
+
export declare function buildTargetingInputConformanceVectors(samples: TargetingDimensionSamples): TargetingInputConformanceVector[];
|
|
65
|
+
/**
|
|
66
|
+
* Cross-dimension vectors requested by the targeting command-state contract:
|
|
67
|
+
* an omitted region axis is preserved, and an invalid combined projection is
|
|
68
|
+
* rejected without mutating either stored axis.
|
|
69
|
+
*/
|
|
70
|
+
export declare const TARGETING_GEOGRAPHY_CONFORMANCE_VECTORS: readonly TargetingInputConformanceVector[];
|
|
71
|
+
/** Run vectors through distinct create and update adapter seams. */
|
|
72
|
+
export declare function runTargetingInputConformance(vectors: readonly TargetingInputConformanceVector[], adapter: TargetingInputConformanceAdapter, options?: TargetingInputConformanceOptions): Promise<TargetingInputConformanceReport>;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import type { TargetingOverlayInput } from '../types/core.generated';
|
|
2
|
+
export type TargetingConformanceOperation = 'create' | 'update';
|
|
3
|
+
export type TargetingConformanceOutcome = 'accepted' | 'rejected';
|
|
4
|
+
export interface TargetingDimensionSample<T> {
|
|
5
|
+
/** Strict configured/stored value used as the vector baseline. */
|
|
6
|
+
initialValue: NonNullable<T>;
|
|
7
|
+
/** Distinct valid request value used to prove complete replacement. */
|
|
8
|
+
replacementValue: NonNullable<T>;
|
|
9
|
+
/** Canonical readback value when it differs from the request value. */
|
|
10
|
+
expectedReplacementValue?: NonNullable<T>;
|
|
11
|
+
/** Whole canonical readback state for cross-dimension materialization. */
|
|
12
|
+
expectedReplacementState?: Record<string, unknown>;
|
|
13
|
+
/** Override for products that cannot execute a clear against inherent scope. */
|
|
14
|
+
expectedNullOutcome?: TargetingConformanceOutcome;
|
|
15
|
+
/** Override for replacements that require renegotiation in the selected fixture. */
|
|
16
|
+
expectedReplacementOutcome?: TargetingConformanceOutcome;
|
|
17
|
+
}
|
|
18
|
+
export type TargetingDimensionSamples = {
|
|
19
|
+
[K in keyof TargetingOverlayInput]?: TargetingDimensionSample<TargetingOverlayInput[K]>;
|
|
20
|
+
};
|
|
21
|
+
export interface TargetingInputConformanceVector {
|
|
22
|
+
id: string;
|
|
23
|
+
operation: TargetingConformanceOperation;
|
|
24
|
+
dimension?: keyof TargetingOverlayInput & string;
|
|
25
|
+
baseline?: Record<string, unknown>;
|
|
26
|
+
/** Present request overlay; `{}` means this dimension was omitted. */
|
|
27
|
+
input?: Record<string, unknown>;
|
|
28
|
+
expectedOutcome: TargetingConformanceOutcome;
|
|
29
|
+
/** Accepted strict state, unchanged update state, or absent state after a rejected create. */
|
|
30
|
+
expectedState: Record<string, unknown> | undefined;
|
|
31
|
+
description: string;
|
|
32
|
+
}
|
|
33
|
+
export interface TargetingInputConformanceObservation {
|
|
34
|
+
outcome: TargetingConformanceOutcome;
|
|
35
|
+
/** Strict durable/readback state after the attempted operation. */
|
|
36
|
+
state?: Record<string, unknown>;
|
|
37
|
+
/** Exact request-only overlay observed at the seller/provider dispatch seam. */
|
|
38
|
+
dispatchedInput?: Record<string, unknown>;
|
|
39
|
+
}
|
|
40
|
+
export interface TargetingInputConformanceAdapter {
|
|
41
|
+
create(vector: TargetingInputConformanceVector): Promise<TargetingInputConformanceObservation>;
|
|
42
|
+
update(vector: TargetingInputConformanceVector): Promise<TargetingInputConformanceObservation>;
|
|
43
|
+
}
|
|
44
|
+
export interface TargetingInputConformanceOptions {
|
|
45
|
+
/** Override when a seller has a documented canonical ordering/materialization policy. */
|
|
46
|
+
compareState?: (observed: Record<string, unknown> | undefined, expected: Record<string, unknown> | undefined, vector: TargetingInputConformanceVector) => boolean;
|
|
47
|
+
}
|
|
48
|
+
export interface TargetingInputConformanceCaseResult {
|
|
49
|
+
id: string;
|
|
50
|
+
passed: boolean;
|
|
51
|
+
failures: string[];
|
|
52
|
+
vector: TargetingInputConformanceVector;
|
|
53
|
+
observation?: TargetingInputConformanceObservation;
|
|
54
|
+
}
|
|
55
|
+
export interface TargetingInputConformanceReport {
|
|
56
|
+
passed: boolean;
|
|
57
|
+
cases: TargetingInputConformanceCaseResult[];
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Generate create/update omit, null, and value vectors for every supplied
|
|
61
|
+
* targeting dimension. Samples are schema-typed and share one multi-dimension
|
|
62
|
+
* baseline so the corpus catches adapters that clear unrelated omitted axes.
|
|
63
|
+
*/
|
|
64
|
+
export declare function buildTargetingInputConformanceVectors(samples: TargetingDimensionSamples): TargetingInputConformanceVector[];
|
|
65
|
+
/**
|
|
66
|
+
* Cross-dimension vectors requested by the targeting command-state contract:
|
|
67
|
+
* an omitted region axis is preserved, and an invalid combined projection is
|
|
68
|
+
* rejected without mutating either stored axis.
|
|
69
|
+
*/
|
|
70
|
+
export declare const TARGETING_GEOGRAPHY_CONFORMANCE_VECTORS: readonly TargetingInputConformanceVector[];
|
|
71
|
+
/** Run vectors through distinct create and update adapter seams. */
|
|
72
|
+
export declare function runTargetingInputConformance(vectors: readonly TargetingInputConformanceVector[], adapter: TargetingInputConformanceAdapter, options?: TargetingInputConformanceOptions): Promise<TargetingInputConformanceReport>;
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var targeting_exports = {};
|
|
20
|
+
__export(targeting_exports, {
|
|
21
|
+
TARGETING_GEOGRAPHY_CONFORMANCE_VECTORS: () => TARGETING_GEOGRAPHY_CONFORMANCE_VECTORS,
|
|
22
|
+
buildTargetingInputConformanceVectors: () => buildTargetingInputConformanceVectors,
|
|
23
|
+
runTargetingInputConformance: () => runTargetingInputConformance
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(targeting_exports);
|
|
26
|
+
var import_node_util = require("node:util");
|
|
27
|
+
function buildTargetingInputConformanceVectors(samples) {
|
|
28
|
+
const entries = Object.entries(samples).filter(([, sample]) => sample !== void 0);
|
|
29
|
+
const baseline = Object.fromEntries(entries.map(([dimension, sample]) => [dimension, clone(sample.initialValue)]));
|
|
30
|
+
const vectors = [];
|
|
31
|
+
for (const [dimension, sample] of entries) {
|
|
32
|
+
const clearedState = withoutKey(baseline, dimension);
|
|
33
|
+
const replacementState = sample.expectedReplacementState ? clone(sample.expectedReplacementState) : {
|
|
34
|
+
...clone(baseline),
|
|
35
|
+
[dimension]: clone(sample.expectedReplacementValue ?? sample.replacementValue)
|
|
36
|
+
};
|
|
37
|
+
for (const operation of ["create", "update"]) {
|
|
38
|
+
const omittedMeaning = operation === "create" ? "inherits configured/product defaults" : "preserves stored state";
|
|
39
|
+
const nullOutcome = sample.expectedNullOutcome ?? "accepted";
|
|
40
|
+
const replacementOutcome = sample.expectedReplacementOutcome ?? "accepted";
|
|
41
|
+
const rejectedState = operation === "create" ? void 0 : baseline;
|
|
42
|
+
vectors.push(
|
|
43
|
+
{
|
|
44
|
+
id: `${operation}/${dimension}/omitted`,
|
|
45
|
+
operation,
|
|
46
|
+
dimension,
|
|
47
|
+
baseline: clone(baseline),
|
|
48
|
+
input: {},
|
|
49
|
+
expectedOutcome: "accepted",
|
|
50
|
+
expectedState: clone(baseline),
|
|
51
|
+
description: `${operation}: omitted ${dimension} ${omittedMeaning}`
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
id: `${operation}/${dimension}/null`,
|
|
55
|
+
operation,
|
|
56
|
+
dimension,
|
|
57
|
+
baseline: clone(baseline),
|
|
58
|
+
input: { [dimension]: null },
|
|
59
|
+
expectedOutcome: nullOutcome,
|
|
60
|
+
expectedState: clone(nullOutcome === "accepted" ? clearedState : rejectedState),
|
|
61
|
+
description: `${operation}: null ${dimension} clears/suppresses only that effective dimension`
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
id: `${operation}/${dimension}/value`,
|
|
65
|
+
operation,
|
|
66
|
+
dimension,
|
|
67
|
+
baseline: clone(baseline),
|
|
68
|
+
input: { [dimension]: clone(sample.replacementValue) },
|
|
69
|
+
expectedOutcome: replacementOutcome,
|
|
70
|
+
expectedState: clone(replacementOutcome === "accepted" ? replacementState : rejectedState),
|
|
71
|
+
description: `${operation}: a non-null ${dimension} value replaces only that complete dimension`
|
|
72
|
+
}
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return vectors;
|
|
77
|
+
}
|
|
78
|
+
const TARGETING_GEOGRAPHY_CONFORMANCE_VECTORS = deepFreeze([
|
|
79
|
+
{
|
|
80
|
+
id: "update/geo_countries/preserve-compatible-regions",
|
|
81
|
+
operation: "update",
|
|
82
|
+
baseline: { geo_countries: ["US"], geo_regions: ["US-NY"] },
|
|
83
|
+
input: { geo_countries: ["US", "CA"] },
|
|
84
|
+
expectedOutcome: "accepted",
|
|
85
|
+
expectedState: { geo_countries: ["US", "CA"], geo_regions: ["US-NY"] },
|
|
86
|
+
description: "Changing countries preserves an omitted compatible geo_regions dimension."
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
id: "update/geo_countries/reject-incompatible-preserved-regions",
|
|
90
|
+
operation: "update",
|
|
91
|
+
baseline: { geo_countries: ["US"], geo_regions: ["US-NY"] },
|
|
92
|
+
input: { geo_countries: ["CA"] },
|
|
93
|
+
expectedOutcome: "rejected",
|
|
94
|
+
expectedState: { geo_countries: ["US"], geo_regions: ["US-NY"] },
|
|
95
|
+
description: "An invalid country/region result is rejected atomically instead of clearing the omitted region axis."
|
|
96
|
+
}
|
|
97
|
+
]);
|
|
98
|
+
async function runTargetingInputConformance(vectors, adapter, options = {}) {
|
|
99
|
+
if (vectors.length === 0) throw new TypeError("Targeting conformance requires at least one vector.");
|
|
100
|
+
const compareState = options.compareState ?? defaultStateComparison;
|
|
101
|
+
const cases = [];
|
|
102
|
+
for (const sourceVector of vectors) {
|
|
103
|
+
const vector = clone(sourceVector);
|
|
104
|
+
const failures = [];
|
|
105
|
+
try {
|
|
106
|
+
const observation = await adapter[vector.operation](clone(vector));
|
|
107
|
+
if (observation.outcome !== vector.expectedOutcome) {
|
|
108
|
+
failures.push(`expected ${vector.expectedOutcome}, observed ${observation.outcome}`);
|
|
109
|
+
}
|
|
110
|
+
if (!compareState(observation.state, vector.expectedState, vector)) {
|
|
111
|
+
failures.push(
|
|
112
|
+
`strict state mismatch: expected ${formatDiagnosticValue(vector.expectedState)}, observed ${formatDiagnosticValue(observation.state)}`
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
if (containsNull(observation.state)) {
|
|
116
|
+
failures.push("durable/readback state retained a request-only null command");
|
|
117
|
+
}
|
|
118
|
+
if (observation.outcome === "accepted" && !(0, import_node_util.isDeepStrictEqual)(observation.dispatchedInput, vector.input)) {
|
|
119
|
+
failures.push(
|
|
120
|
+
`dispatch changed the request overlay: expected ${formatDiagnosticValue(vector.input)}, observed ${formatDiagnosticValue(observation.dispatchedInput)}`
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
cases.push({ id: vector.id, passed: failures.length === 0, failures, vector, observation });
|
|
124
|
+
} catch (error) {
|
|
125
|
+
const name = error instanceof Error ? error.name : typeof error;
|
|
126
|
+
failures.push(`adapter execution failed (${name}); inspect adapter logs for details`);
|
|
127
|
+
cases.push({ id: vector.id, passed: false, failures, vector });
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return { passed: cases.every((result) => result.passed), cases };
|
|
131
|
+
}
|
|
132
|
+
function defaultStateComparison(observed, expected) {
|
|
133
|
+
return (0, import_node_util.isDeepStrictEqual)(normalizeEmptyState(observed), normalizeEmptyState(expected));
|
|
134
|
+
}
|
|
135
|
+
function normalizeEmptyState(state) {
|
|
136
|
+
return state && Object.keys(state).length === 0 ? void 0 : state;
|
|
137
|
+
}
|
|
138
|
+
function containsNull(value) {
|
|
139
|
+
if (value === null) return true;
|
|
140
|
+
if (Array.isArray(value)) return value.some(containsNull);
|
|
141
|
+
return typeof value === "object" && Object.values(value).some(containsNull);
|
|
142
|
+
}
|
|
143
|
+
function withoutKey(state, key) {
|
|
144
|
+
const result = Object.fromEntries(Object.entries(state).filter(([candidate]) => candidate !== key));
|
|
145
|
+
return Object.keys(result).length === 0 ? void 0 : result;
|
|
146
|
+
}
|
|
147
|
+
function clone(value) {
|
|
148
|
+
return structuredClone(value);
|
|
149
|
+
}
|
|
150
|
+
function formatDiagnosticValue(value) {
|
|
151
|
+
return value === void 0 ? "undefined" : JSON.stringify(value);
|
|
152
|
+
}
|
|
153
|
+
function deepFreeze(value) {
|
|
154
|
+
if (typeof value !== "object" || value === null || Object.isFrozen(value)) return value;
|
|
155
|
+
for (const child of Object.values(value)) deepFreeze(child);
|
|
156
|
+
return Object.freeze(value);
|
|
157
|
+
}
|
|
158
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
159
|
+
0 && (module.exports = {
|
|
160
|
+
TARGETING_GEOGRAPHY_CONFORMANCE_VECTORS,
|
|
161
|
+
buildTargetingInputConformanceVectors,
|
|
162
|
+
runTargetingInputConformance
|
|
163
|
+
});
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { isDeepStrictEqual } from "node:util";
|
|
2
|
+
function buildTargetingInputConformanceVectors(samples) {
|
|
3
|
+
const entries = Object.entries(samples).filter(([, sample]) => sample !== void 0);
|
|
4
|
+
const baseline = Object.fromEntries(entries.map(([dimension, sample]) => [dimension, clone(sample.initialValue)]));
|
|
5
|
+
const vectors = [];
|
|
6
|
+
for (const [dimension, sample] of entries) {
|
|
7
|
+
const clearedState = withoutKey(baseline, dimension);
|
|
8
|
+
const replacementState = sample.expectedReplacementState ? clone(sample.expectedReplacementState) : {
|
|
9
|
+
...clone(baseline),
|
|
10
|
+
[dimension]: clone(sample.expectedReplacementValue ?? sample.replacementValue)
|
|
11
|
+
};
|
|
12
|
+
for (const operation of ["create", "update"]) {
|
|
13
|
+
const omittedMeaning = operation === "create" ? "inherits configured/product defaults" : "preserves stored state";
|
|
14
|
+
const nullOutcome = sample.expectedNullOutcome ?? "accepted";
|
|
15
|
+
const replacementOutcome = sample.expectedReplacementOutcome ?? "accepted";
|
|
16
|
+
const rejectedState = operation === "create" ? void 0 : baseline;
|
|
17
|
+
vectors.push(
|
|
18
|
+
{
|
|
19
|
+
id: `${operation}/${dimension}/omitted`,
|
|
20
|
+
operation,
|
|
21
|
+
dimension,
|
|
22
|
+
baseline: clone(baseline),
|
|
23
|
+
input: {},
|
|
24
|
+
expectedOutcome: "accepted",
|
|
25
|
+
expectedState: clone(baseline),
|
|
26
|
+
description: `${operation}: omitted ${dimension} ${omittedMeaning}`
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
id: `${operation}/${dimension}/null`,
|
|
30
|
+
operation,
|
|
31
|
+
dimension,
|
|
32
|
+
baseline: clone(baseline),
|
|
33
|
+
input: { [dimension]: null },
|
|
34
|
+
expectedOutcome: nullOutcome,
|
|
35
|
+
expectedState: clone(nullOutcome === "accepted" ? clearedState : rejectedState),
|
|
36
|
+
description: `${operation}: null ${dimension} clears/suppresses only that effective dimension`
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
id: `${operation}/${dimension}/value`,
|
|
40
|
+
operation,
|
|
41
|
+
dimension,
|
|
42
|
+
baseline: clone(baseline),
|
|
43
|
+
input: { [dimension]: clone(sample.replacementValue) },
|
|
44
|
+
expectedOutcome: replacementOutcome,
|
|
45
|
+
expectedState: clone(replacementOutcome === "accepted" ? replacementState : rejectedState),
|
|
46
|
+
description: `${operation}: a non-null ${dimension} value replaces only that complete dimension`
|
|
47
|
+
}
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return vectors;
|
|
52
|
+
}
|
|
53
|
+
const TARGETING_GEOGRAPHY_CONFORMANCE_VECTORS = deepFreeze([
|
|
54
|
+
{
|
|
55
|
+
id: "update/geo_countries/preserve-compatible-regions",
|
|
56
|
+
operation: "update",
|
|
57
|
+
baseline: { geo_countries: ["US"], geo_regions: ["US-NY"] },
|
|
58
|
+
input: { geo_countries: ["US", "CA"] },
|
|
59
|
+
expectedOutcome: "accepted",
|
|
60
|
+
expectedState: { geo_countries: ["US", "CA"], geo_regions: ["US-NY"] },
|
|
61
|
+
description: "Changing countries preserves an omitted compatible geo_regions dimension."
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
id: "update/geo_countries/reject-incompatible-preserved-regions",
|
|
65
|
+
operation: "update",
|
|
66
|
+
baseline: { geo_countries: ["US"], geo_regions: ["US-NY"] },
|
|
67
|
+
input: { geo_countries: ["CA"] },
|
|
68
|
+
expectedOutcome: "rejected",
|
|
69
|
+
expectedState: { geo_countries: ["US"], geo_regions: ["US-NY"] },
|
|
70
|
+
description: "An invalid country/region result is rejected atomically instead of clearing the omitted region axis."
|
|
71
|
+
}
|
|
72
|
+
]);
|
|
73
|
+
async function runTargetingInputConformance(vectors, adapter, options = {}) {
|
|
74
|
+
if (vectors.length === 0) throw new TypeError("Targeting conformance requires at least one vector.");
|
|
75
|
+
const compareState = options.compareState ?? defaultStateComparison;
|
|
76
|
+
const cases = [];
|
|
77
|
+
for (const sourceVector of vectors) {
|
|
78
|
+
const vector = clone(sourceVector);
|
|
79
|
+
const failures = [];
|
|
80
|
+
try {
|
|
81
|
+
const observation = await adapter[vector.operation](clone(vector));
|
|
82
|
+
if (observation.outcome !== vector.expectedOutcome) {
|
|
83
|
+
failures.push(`expected ${vector.expectedOutcome}, observed ${observation.outcome}`);
|
|
84
|
+
}
|
|
85
|
+
if (!compareState(observation.state, vector.expectedState, vector)) {
|
|
86
|
+
failures.push(
|
|
87
|
+
`strict state mismatch: expected ${formatDiagnosticValue(vector.expectedState)}, observed ${formatDiagnosticValue(observation.state)}`
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
if (containsNull(observation.state)) {
|
|
91
|
+
failures.push("durable/readback state retained a request-only null command");
|
|
92
|
+
}
|
|
93
|
+
if (observation.outcome === "accepted" && !isDeepStrictEqual(observation.dispatchedInput, vector.input)) {
|
|
94
|
+
failures.push(
|
|
95
|
+
`dispatch changed the request overlay: expected ${formatDiagnosticValue(vector.input)}, observed ${formatDiagnosticValue(observation.dispatchedInput)}`
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
cases.push({ id: vector.id, passed: failures.length === 0, failures, vector, observation });
|
|
99
|
+
} catch (error) {
|
|
100
|
+
const name = error instanceof Error ? error.name : typeof error;
|
|
101
|
+
failures.push(`adapter execution failed (${name}); inspect adapter logs for details`);
|
|
102
|
+
cases.push({ id: vector.id, passed: false, failures, vector });
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return { passed: cases.every((result) => result.passed), cases };
|
|
106
|
+
}
|
|
107
|
+
function defaultStateComparison(observed, expected) {
|
|
108
|
+
return isDeepStrictEqual(normalizeEmptyState(observed), normalizeEmptyState(expected));
|
|
109
|
+
}
|
|
110
|
+
function normalizeEmptyState(state) {
|
|
111
|
+
return state && Object.keys(state).length === 0 ? void 0 : state;
|
|
112
|
+
}
|
|
113
|
+
function containsNull(value) {
|
|
114
|
+
if (value === null) return true;
|
|
115
|
+
if (Array.isArray(value)) return value.some(containsNull);
|
|
116
|
+
return typeof value === "object" && Object.values(value).some(containsNull);
|
|
117
|
+
}
|
|
118
|
+
function withoutKey(state, key) {
|
|
119
|
+
const result = Object.fromEntries(Object.entries(state).filter(([candidate]) => candidate !== key));
|
|
120
|
+
return Object.keys(result).length === 0 ? void 0 : result;
|
|
121
|
+
}
|
|
122
|
+
function clone(value) {
|
|
123
|
+
return structuredClone(value);
|
|
124
|
+
}
|
|
125
|
+
function formatDiagnosticValue(value) {
|
|
126
|
+
return value === void 0 ? "undefined" : JSON.stringify(value);
|
|
127
|
+
}
|
|
128
|
+
function deepFreeze(value) {
|
|
129
|
+
if (typeof value !== "object" || value === null || Object.isFrozen(value)) return value;
|
|
130
|
+
for (const child of Object.values(value)) deepFreeze(child);
|
|
131
|
+
return Object.freeze(value);
|
|
132
|
+
}
|
|
133
|
+
export {
|
|
134
|
+
TARGETING_GEOGRAPHY_CONFORMANCE_VECTORS,
|
|
135
|
+
buildTargetingInputConformanceVectors,
|
|
136
|
+
runTargetingInputConformance
|
|
137
|
+
};
|
|
@@ -2,7 +2,7 @@ import type { Client as MCPClient } from '@modelcontextprotocol/sdk/client/index
|
|
|
2
2
|
import type { AgentConfig } from '../types/index.mjs';
|
|
3
3
|
import type { MCPWebhookPayload, GetBrandIdentityRequest, GetBrandIdentityResponse, ContextMatchRequest, ContextMatchResponse, IdentityMatchRequest, IdentityMatchResponseRouterPublisher } from '../types/core.generated.mjs';
|
|
4
4
|
import type { Task as A2ATask, TaskStatusUpdateEvent } from '@a2a-js/sdk';
|
|
5
|
-
import { type CanonicalReadTaskOptions, type CreativeDeliveryTaskOptions, type SingleAgentClientConfig, type SyncCreativesTaskOptions, type VerifyAndParseWebhookOptions, type WebhookHandlerAdapter, type WebhookParseResult, type WebhookRequestContext } from './SingleAgentClient.mjs';
|
|
5
|
+
import { type CapabilityEvidenceScope, type CapabilityEvidenceSnapshot, type CanonicalReadTaskOptions, type CreativeDeliveryTaskOptions, type SingleAgentClientConfig, type SyncCreativesTaskOptions, type VerifyAndParseWebhookOptions, type WebhookHandlerAdapter, type WebhookParseResult, type WebhookRequestContext } from './SingleAgentClient.mjs';
|
|
6
6
|
import type { InputHandler, TaskOptions, TaskResult, TaskInfo, Message, DirectPauseRecoveryRequest } from './ConversationTypes.mjs';
|
|
7
7
|
import type { AdcpCapabilities } from '../utils/capabilities.mjs';
|
|
8
8
|
import type { WebhookHeaderValue } from '../webhooks/index.mjs';
|
|
@@ -167,6 +167,22 @@ export type InProcessAgentClientConfig = Pick<SingleAgentClientConfig, 'adcpVers
|
|
|
167
167
|
*/
|
|
168
168
|
agentId?: string;
|
|
169
169
|
};
|
|
170
|
+
/** Context passed to {@link AgentClient.createWithCapabilityPreflight}. */
|
|
171
|
+
export interface CapabilityPreflightContext {
|
|
172
|
+
/** The exact client instance that will be returned by the factory. */
|
|
173
|
+
client: AgentClient;
|
|
174
|
+
/** Opaque authorization/transport scope the returned snapshot must carry. */
|
|
175
|
+
scope: CapabilityEvidenceScope;
|
|
176
|
+
}
|
|
177
|
+
/** Load or perform capability discovery for one newly constructed client. */
|
|
178
|
+
export type CapabilityPreflightLoader = (context: CapabilityPreflightContext) => CapabilityEvidenceSnapshot | Promise<CapabilityEvidenceSnapshot>;
|
|
179
|
+
export type CapabilityPreflightErrorCode = 'scoped_transport' | 'scope_rotated' | 'invalid_evidence';
|
|
180
|
+
/** Actionable factory failure without weakening the same-instance invariant. */
|
|
181
|
+
export declare class CapabilityPreflightError extends Error {
|
|
182
|
+
readonly code: CapabilityPreflightErrorCode;
|
|
183
|
+
readonly name = "CapabilityPreflightError";
|
|
184
|
+
constructor(code: CapabilityPreflightErrorCode, message: string);
|
|
185
|
+
}
|
|
170
186
|
export declare class AgentClient {
|
|
171
187
|
private agent;
|
|
172
188
|
private config;
|
|
@@ -176,6 +192,16 @@ export declare class AgentClient {
|
|
|
176
192
|
private readonly sessionTrackedDeferredContinuations;
|
|
177
193
|
private readonly _isInProcess;
|
|
178
194
|
constructor(agent: AgentConfig, config?: SingleAgentClientConfig);
|
|
195
|
+
/**
|
|
196
|
+
* Construct and prime one client before exposing it for task dispatch.
|
|
197
|
+
*
|
|
198
|
+
* Capability evidence is intentionally bound to a client instance. This
|
|
199
|
+
* factory gives application factories the instance and its opaque scope
|
|
200
|
+
* before the first task can be sent, then installs the callback's snapshot
|
|
201
|
+
* on that same instance. Evidence from an otherwise identical client is
|
|
202
|
+
* rejected rather than silently falling back to redundant discovery.
|
|
203
|
+
*/
|
|
204
|
+
static createWithCapabilityPreflight(agent: AgentConfig, loadEvidence: CapabilityPreflightLoader, config?: SingleAgentClientConfig): Promise<AgentClient>;
|
|
179
205
|
/**
|
|
180
206
|
* Recover the current A2A pause generation for a direct mutation that opted
|
|
181
207
|
* into `TaskOptions.durableContinuationRecovery`.
|