@adcp/sdk 17.0.0-beta.0 → 17.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/adapters/version/3.1/bidding.js +1 -1
- package/dist/lib/adapters/version/3.1/bidding.mjs +1 -1
- package/dist/lib/core/ResponseValidator.js +1 -1
- package/dist/lib/core/ResponseValidator.mjs +1 -1
- package/dist/lib/core/SingleAgentClient.d.mts +7 -5
- package/dist/lib/core/SingleAgentClient.d.ts +7 -5
- package/dist/lib/core/SingleAgentClient.js +57 -32
- package/dist/lib/core/SingleAgentClient.mjs +59 -33
- package/dist/lib/core/TaskExecutor.js +5 -3
- package/dist/lib/core/TaskExecutor.mjs +5 -3
- package/dist/lib/errors/index.d.mts +22 -0
- package/dist/lib/errors/index.d.ts +22 -0
- package/dist/lib/errors/index.js +43 -0
- package/dist/lib/errors/index.mjs +42 -0
- package/dist/lib/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 +2 -0
- package/dist/lib/protocols/mcp-modern.d.mts +2 -0
- package/dist/lib/protocols/mcp-modern.d.ts +2 -0
- package/dist/lib/protocols/mcp-modern.js +31 -5
- package/dist/lib/protocols/mcp-modern.mjs +31 -5
- package/dist/lib/protocols/mcp-scope.d.mts +3 -1
- package/dist/lib/protocols/mcp-scope.d.ts +3 -1
- package/dist/lib/protocols/mcp-scope.js +19 -2
- package/dist/lib/protocols/mcp-scope.mjs +18 -2
- package/dist/lib/protocols/mcp.js +12 -6
- package/dist/lib/protocols/mcp.mjs +13 -6
- package/dist/lib/testing/client.d.mts +1 -0
- package/dist/lib/testing/client.d.ts +1 -0
- package/dist/lib/testing/client.js +6 -5
- package/dist/lib/testing/client.mjs +6 -5
- package/dist/lib/testing/storyboard/agent-routing.d.mts +5 -2
- package/dist/lib/testing/storyboard/agent-routing.d.ts +5 -2
- package/dist/lib/testing/storyboard/agent-routing.js +11 -4
- package/dist/lib/testing/storyboard/agent-routing.mjs +11 -4
- package/dist/lib/testing/storyboard/context.d.mts +13 -3
- package/dist/lib/testing/storyboard/context.d.ts +13 -3
- package/dist/lib/testing/storyboard/context.js +15 -10
- package/dist/lib/testing/storyboard/context.mjs +15 -10
- package/dist/lib/testing/storyboard/runner.js +141 -13
- package/dist/lib/testing/storyboard/runner.mjs +141 -13
- package/dist/lib/testing/storyboard/validations.d.mts +1 -1
- package/dist/lib/testing/storyboard/validations.d.ts +1 -1
- package/dist/lib/testing/storyboard/validations.js +4 -1
- package/dist/lib/testing/storyboard/validations.mjs +4 -1
- package/dist/lib/testing/test-controller.js +3 -0
- package/dist/lib/testing/test-controller.mjs +3 -0
- package/dist/lib/utils/envelope-status-compat.d.mts +18 -1
- package/dist/lib/utils/envelope-status-compat.d.ts +18 -1
- package/dist/lib/utils/envelope-status-compat.js +11 -5
- package/dist/lib/utils/envelope-status-compat.mjs +11 -5
- package/dist/lib/utils/response-unwrapper.js +12 -9
- package/dist/lib/utils/response-unwrapper.mjs +12 -9
- package/dist/lib/v2/projection/creative-delivery.js +56 -11
- package/dist/lib/v2/projection/creative-delivery.mjs +56 -11
- package/dist/lib/validation/schema-validator.js +1 -1
- package/dist/lib/validation/schema-validator.mjs +1 -1
- package/dist/lib/version.d.mts +3 -3
- package/dist/lib/version.d.ts +3 -3
- package/dist/lib/version.js +3 -3
- package/dist/lib/version.mjs +3 -3
- package/docs/TYPE-SUMMARY.md +2 -2
- package/docs/guides/COLLECTION-FIXTURE-FOUNDATION.md +11 -0
- package/docs/guides/DISCOVERY-CACHE-AND-SESSION-REUSE.md +12 -1
- package/docs/llms.txt +2 -2
- package/docs/migration-14.x-rc-worksheet.md +4 -4
- package/docs/migration-16-to-17.md +24 -1
- package/docs/migration-reporting-storage-package.md +1 -1
- package/package.json +1 -1
|
@@ -684,7 +684,7 @@ function remapTaskCompletionOutputs(outputs) {
|
|
|
684
684
|
return o;
|
|
685
685
|
});
|
|
686
686
|
}
|
|
687
|
-
async function resolveTaskCompletionOutputs(taskResult, outputs, client, webhookReceiver, originatingTaskName) {
|
|
687
|
+
async function resolveTaskCompletionOutputs(taskResult, outputs, client, webhookReceiver, originatingTaskName, responseAdcpVersion) {
|
|
688
688
|
const hasTaskCompletionPath = outputs.some(
|
|
689
689
|
(o) => typeof o.path === "string" && o.path.startsWith(TASK_COMPLETION_PATH_PREFIX)
|
|
690
690
|
);
|
|
@@ -737,7 +737,10 @@ async function resolveTaskCompletionOutputs(taskResult, outputs, client, webhook
|
|
|
737
737
|
if (winner.kind === "poll") {
|
|
738
738
|
const polled = winner.result;
|
|
739
739
|
if (polled.success === false) return { attempted: true, taskFailed: true };
|
|
740
|
-
return {
|
|
740
|
+
return {
|
|
741
|
+
attempted: true,
|
|
742
|
+
data: normalizeTaskCompletionData(polled.data, originatingTaskName, responseAdcpVersion)
|
|
743
|
+
};
|
|
741
744
|
}
|
|
742
745
|
const waitResult = winner.result;
|
|
743
746
|
if (waitResult.timed_out) {
|
|
@@ -745,7 +748,10 @@ async function resolveTaskCompletionOutputs(taskResult, outputs, client, webhook
|
|
|
745
748
|
}
|
|
746
749
|
const webhookBody = waitResult.webhook.body;
|
|
747
750
|
if (webhookBody?.status === "completed") {
|
|
748
|
-
return {
|
|
751
|
+
return {
|
|
752
|
+
attempted: true,
|
|
753
|
+
data: normalizeTaskCompletionData(webhookBody.result, originatingTaskName, responseAdcpVersion)
|
|
754
|
+
};
|
|
749
755
|
}
|
|
750
756
|
return { attempted: true, taskFailed: true };
|
|
751
757
|
} catch {
|
|
@@ -754,18 +760,19 @@ async function resolveTaskCompletionOutputs(taskResult, outputs, client, webhook
|
|
|
754
760
|
if (timer) clearTimeout(timer);
|
|
755
761
|
}
|
|
756
762
|
}
|
|
757
|
-
function normalizeTaskCompletionData(data, taskName) {
|
|
763
|
+
function normalizeTaskCompletionData(data, taskName, adcpVersion) {
|
|
758
764
|
if (data == null || typeof data !== "object" || Array.isArray(data)) return data;
|
|
759
765
|
const original = data;
|
|
760
|
-
const
|
|
766
|
+
const compatOptions = { toolName: taskName, adcpVersion };
|
|
767
|
+
const compat = (0, import_envelope_status_compat.injectLegacyEnvelopeStatus)(original, compatOptions);
|
|
761
768
|
if (!("status" in original) && "status" in compat) {
|
|
762
769
|
const { status: _status, ...rest } = compat;
|
|
763
|
-
return (0, import_envelope_status_compat.normalizeLegacyMediaBuyStatusForReturn)(rest,
|
|
770
|
+
return (0, import_envelope_status_compat.normalizeLegacyMediaBuyStatusForReturn)(rest, compatOptions);
|
|
764
771
|
}
|
|
765
772
|
if ((taskName === "create_media_buy" || taskName === "update_media_buy") && typeof original.status === "string" && compat.status === "completed" && typeof compat.media_buy_status === "string") {
|
|
766
|
-
return (0, import_envelope_status_compat.normalizeLegacyMediaBuyStatusForReturn)({ ...compat, status: original.status },
|
|
773
|
+
return (0, import_envelope_status_compat.normalizeLegacyMediaBuyStatusForReturn)({ ...compat, status: original.status }, compatOptions);
|
|
767
774
|
}
|
|
768
|
-
return (0, import_envelope_status_compat.normalizeLegacyMediaBuyStatusForReturn)(compat,
|
|
775
|
+
return (0, import_envelope_status_compat.normalizeLegacyMediaBuyStatusForReturn)(compat, compatOptions);
|
|
769
776
|
}
|
|
770
777
|
function readEnvIntOrDefault(value, fallback) {
|
|
771
778
|
if (!value) return fallback;
|
|
@@ -1903,9 +1910,10 @@ async function prepareStoryboardFixturesBody(agentUrl, storyboard, options) {
|
|
|
1903
1910
|
options = snapshotPreparationOptions(options);
|
|
1904
1911
|
}
|
|
1905
1912
|
const callerOwnsClients = (0, import_client.hasTestClientScope)();
|
|
1906
|
-
const
|
|
1913
|
+
const runOptions = options;
|
|
1914
|
+
const preparationOptions = resolvePreparationRouteOptions(agentUrls[0], runOptions);
|
|
1907
1915
|
const resolution = (0, import_client.getOrCreateClientResolution)(agentUrls[0], preparationOptions);
|
|
1908
|
-
|
|
1916
|
+
let client = resolution.client;
|
|
1909
1917
|
const finishPreparation = (seeding, disposition) => {
|
|
1910
1918
|
if (!scopeStillMatches()) {
|
|
1911
1919
|
return refusePreparation(driftRefusal, seeding ?? void 0);
|
|
@@ -1915,6 +1923,45 @@ async function prepareStoryboardFixturesBody(agentUrl, storyboard, options) {
|
|
|
1915
1923
|
options = preparationOptions;
|
|
1916
1924
|
try {
|
|
1917
1925
|
let profile = options._profile;
|
|
1926
|
+
let discoveryStep;
|
|
1927
|
+
let routingContext;
|
|
1928
|
+
const failDiscovery = (step, failedProfile) => {
|
|
1929
|
+
const failed = buildDiscoveryFailedResult(agentUrls, storyboard, step, failedProfile);
|
|
1930
|
+
return finishPreparation(
|
|
1931
|
+
{ phase: failed.phases[0], allPassed: false, passedCount: 0, failedCount: 1 },
|
|
1932
|
+
{ status: "failed", detail: step.error ?? "agent discovery failed before fixture preparation" }
|
|
1933
|
+
);
|
|
1934
|
+
};
|
|
1935
|
+
if (runOptions.agents && (storyboardCapabilityPredicates(storyboard).length > 0 || storyboard.required_tools?.length || storyboard.required_any_of_tools?.length)) {
|
|
1936
|
+
try {
|
|
1937
|
+
validateAgentsMap(agentUrl, storyboard, runOptions);
|
|
1938
|
+
routingContext = await (0, import_agent_routing.buildRoutingContext)(storyboard, { ...runOptions, discovery_resilient: false });
|
|
1939
|
+
} catch (error) {
|
|
1940
|
+
const failedStep = error instanceof import_agent_routing.DiscoveryFailure ? error.step : void 0;
|
|
1941
|
+
return await failDiscovery({
|
|
1942
|
+
...failedStep,
|
|
1943
|
+
step: failedStep?.step ?? "Discover preparation topology",
|
|
1944
|
+
passed: false,
|
|
1945
|
+
duration_ms: failedStep?.duration_ms ?? 0,
|
|
1946
|
+
error: (0, import_oauth_metadata_graph.redactOAuthUrlsInText)(
|
|
1947
|
+
error instanceof import_agent_routing.DiscoveryFailure ? `Discovery failed for agent "${error.agentKey}" (${(0, import_oauth_metadata_graph.redactOAuthUrlForOutput)(error.url)}): ${error.underlying}` : error instanceof Error ? error.message : String(error)
|
|
1948
|
+
)
|
|
1949
|
+
});
|
|
1950
|
+
}
|
|
1951
|
+
for (const routeProfile of routingContext.profiles.values()) {
|
|
1952
|
+
const failure = (0, import_client.describeProfileDiscoveryFailure)(
|
|
1953
|
+
routeProfile,
|
|
1954
|
+
runOptions._requireValidCapabilityEvidence === true,
|
|
1955
|
+
runOptions._allowCapabilityDiagnostic === true
|
|
1956
|
+
);
|
|
1957
|
+
if (failure) return await failDiscovery(failure, routeProfile);
|
|
1958
|
+
}
|
|
1959
|
+
const firstKey = Object.keys(runOptions.agents)[0];
|
|
1960
|
+
profile = routingContext.profiles.get(firstKey);
|
|
1961
|
+
client = routingContext.clients.get(firstKey);
|
|
1962
|
+
discoveryStep = routingContext.discoverySteps?.get(firstKey);
|
|
1963
|
+
options = { ...options, _profile: profile, agentTools: (0, import_agent_routing.normalizeAgentToolNames)(profile.tools) };
|
|
1964
|
+
}
|
|
1918
1965
|
const suppliedFailure = profile && (0, import_client.describeProfileDiscoveryFailure)(
|
|
1919
1966
|
profile,
|
|
1920
1967
|
options._requireValidCapabilityEvidence === true,
|
|
@@ -1927,8 +1974,9 @@ async function prepareStoryboardFixturesBody(agentUrl, storyboard, options) {
|
|
|
1927
1974
|
{ status: "failed", detail: suppliedFailure.error ?? "agent discovery failed" }
|
|
1928
1975
|
);
|
|
1929
1976
|
}
|
|
1930
|
-
if (!profile
|
|
1977
|
+
if (!profile) {
|
|
1931
1978
|
const discovered = await (0, import_client.getOrDiscoverStoryboardProfile)(client, options);
|
|
1979
|
+
discoveryStep = discovered.evidence ?? discovered.step;
|
|
1932
1980
|
if (discovered.step.passed === false) {
|
|
1933
1981
|
const failed = buildDiscoveryFailedResult(agentUrls, storyboard, discovered.step, discovered.profile);
|
|
1934
1982
|
return await finishPreparation(
|
|
@@ -1949,6 +1997,80 @@ async function prepareStoryboardFixturesBody(agentUrl, storyboard, options) {
|
|
|
1949
1997
|
};
|
|
1950
1998
|
}
|
|
1951
1999
|
if (!scopeStillMatches()) return await refusePreparation(driftRefusal);
|
|
2000
|
+
let capabilityUnmet;
|
|
2001
|
+
const applicabilityTools = routingContext ? [...new Set([...routingContext.profiles.values()].flatMap((p) => (0, import_agent_routing.normalizeAgentToolNames)(p.tools) ?? []))] : options.agentTools;
|
|
2002
|
+
try {
|
|
2003
|
+
if (routingContext && runOptions.agents) {
|
|
2004
|
+
const dispatch = createRoutingDispatcher(routingContext, runOptions, runOptions.agents);
|
|
2005
|
+
const defaultProfile = runOptions.default_agent ? routingContext.profiles.get(runOptions.default_agent) : void 0;
|
|
2006
|
+
const rootDetails = storyboard.phases.flatMap(
|
|
2007
|
+
(phase) => phase.steps.filter((step) => step.task !== import_loader.VALIDATION_ONLY_TASK).map((step) => {
|
|
2008
|
+
const selected = dispatch.nextFor(step);
|
|
2009
|
+
const owner = runOptions.default_agent ? defaultProfile : selected.profile;
|
|
2010
|
+
return evaluateStoryboardCapabilityGates(
|
|
2011
|
+
storyboard,
|
|
2012
|
+
owner,
|
|
2013
|
+
(0, import_agent_routing.normalizeAgentToolNames)(owner?.tools),
|
|
2014
|
+
runOptions.adcpVersion
|
|
2015
|
+
);
|
|
2016
|
+
})
|
|
2017
|
+
);
|
|
2018
|
+
capabilityUnmet = rootDetails.length > 0 && rootDetails.every((detail) => detail !== null) ? rootDetails[0] : null;
|
|
2019
|
+
} else {
|
|
2020
|
+
capabilityUnmet = evaluateStoryboardCapabilityGates(
|
|
2021
|
+
storyboard,
|
|
2022
|
+
profile,
|
|
2023
|
+
options.agentTools,
|
|
2024
|
+
options.adcpVersion
|
|
2025
|
+
);
|
|
2026
|
+
}
|
|
2027
|
+
} catch (error) {
|
|
2028
|
+
return await failDiscovery({
|
|
2029
|
+
step: "Resolve preparation routes",
|
|
2030
|
+
passed: false,
|
|
2031
|
+
duration_ms: 0,
|
|
2032
|
+
error: (0, import_oauth_metadata_graph.redactOAuthUrlsInText)(error instanceof Error ? error.message : String(error))
|
|
2033
|
+
});
|
|
2034
|
+
}
|
|
2035
|
+
const missingFamily = applicabilityTools && storyboard.required_any_of_tools?.find((family) => !(0, import_agent_routing.hasAnyRequiredTool)(family.tools, applicabilityTools));
|
|
2036
|
+
const unmetDetail = capabilityUnmet ?? (missingFamily ? `missing_required_tool_family: needs ${missingFamily.tools.join(" or ")}` + (missingFamily.rationale ? ` (${missingFamily.rationale})` : "") : null) ?? (storyboard.required_tools?.length && applicabilityTools && !(0, import_agent_routing.hasAnyRequiredTool)(storyboard.required_tools, applicabilityTools) ? `agent does not advertise any of [${storyboard.required_tools.join(", ")}]` : null);
|
|
2037
|
+
if (unmetDetail !== null) {
|
|
2038
|
+
const observations = routingContext && runOptions.agents ? Object.entries(runOptions.agents).map(([key, entry]) => ({
|
|
2039
|
+
key,
|
|
2040
|
+
url: entry.url,
|
|
2041
|
+
step: routingContext.discoverySteps?.get(key)
|
|
2042
|
+
})) : [{ key: "discovery", url: agentUrls[0], step: discoveryStep }];
|
|
2043
|
+
const steps = observations.map(({ key, url, step }) => ({
|
|
2044
|
+
storyboard_id: storyboard.id,
|
|
2045
|
+
phase_id: "discovery",
|
|
2046
|
+
step_id: key,
|
|
2047
|
+
title: step ? "Agent capability discovery" : "Supplied agent capability profile",
|
|
2048
|
+
task: step?.task ?? "",
|
|
2049
|
+
passed: true,
|
|
2050
|
+
duration_ms: step?.duration_ms ?? 0,
|
|
2051
|
+
validations: [],
|
|
2052
|
+
context: {},
|
|
2053
|
+
...routingContext && { agent_url: (0, import_oauth_metadata_graph.redactOAuthUrlForOutput)(url) },
|
|
2054
|
+
extraction: step?.extraction ?? { path: "none" },
|
|
2055
|
+
...step?.request && { request: step.request },
|
|
2056
|
+
...step?.response_record && { response_record: step.response_record }
|
|
2057
|
+
}));
|
|
2058
|
+
return await finishPreparation(
|
|
2059
|
+
{
|
|
2060
|
+
phase: {
|
|
2061
|
+
phase_id: "discovery",
|
|
2062
|
+
phase_title: "Agent capability discovery",
|
|
2063
|
+
passed: true,
|
|
2064
|
+
duration_ms: steps.reduce((total, step) => total + step.duration_ms, 0),
|
|
2065
|
+
steps
|
|
2066
|
+
},
|
|
2067
|
+
allPassed: true,
|
|
2068
|
+
passedCount: steps.length,
|
|
2069
|
+
failedCount: 0
|
|
2070
|
+
},
|
|
2071
|
+
{ status: "unsupported", reason: "not_applicable", detail: unmetDetail }
|
|
2072
|
+
);
|
|
2073
|
+
}
|
|
1952
2074
|
const context = createRunContext(storyboard, options).context;
|
|
1953
2075
|
const seeding = await (0, import_seeding.runControllerSeeding)(client, storyboard, options, context);
|
|
1954
2076
|
if (!seeding) {
|
|
@@ -5841,7 +5963,12 @@ async function executeStep(client, step, storyboardId, phaseId, context, allStep
|
|
|
5841
5963
|
};
|
|
5842
5964
|
const hasData = taskResult?.data !== void 0 && taskResult?.data !== null;
|
|
5843
5965
|
if (passed && hasData && taskResult && !(effectiveStep.task === "sync_accounts" && request.dry_run === true)) {
|
|
5844
|
-
const extracted = (0, import_context.extractContextWithProvenance)(
|
|
5966
|
+
const extracted = (0, import_context.extractContextWithProvenance)(
|
|
5967
|
+
effectiveStep.task,
|
|
5968
|
+
taskResult.data,
|
|
5969
|
+
step.id,
|
|
5970
|
+
options._serverAdcpVersion ?? options.adcpVersion
|
|
5971
|
+
);
|
|
5845
5972
|
const conventionUnset = [];
|
|
5846
5973
|
for (const group of extracted.clearGroups ?? []) {
|
|
5847
5974
|
if (group.when && !group.when.values.includes(updatedContext[group.when.key])) continue;
|
|
@@ -5872,7 +5999,8 @@ async function executeStep(client, step, storyboardId, phaseId, context, allStep
|
|
|
5872
5999
|
step.context_outputs,
|
|
5873
6000
|
client,
|
|
5874
6001
|
runState.webhookReceiver,
|
|
5875
|
-
effectiveStep.task
|
|
6002
|
+
effectiveStep.task,
|
|
6003
|
+
options._serverAdcpVersion ?? options.adcpVersion
|
|
5876
6004
|
);
|
|
5877
6005
|
const extractionData = "data" in taskCompletionResolution ? taskCompletionResolution.data : hasData && taskResult ? taskResult.data : void 0;
|
|
5878
6006
|
const remappedOutputs = remapTaskCompletionOutputs(step.context_outputs);
|
|
@@ -726,7 +726,7 @@ function remapTaskCompletionOutputs(outputs) {
|
|
|
726
726
|
return o;
|
|
727
727
|
});
|
|
728
728
|
}
|
|
729
|
-
async function resolveTaskCompletionOutputs(taskResult, outputs, client, webhookReceiver, originatingTaskName) {
|
|
729
|
+
async function resolveTaskCompletionOutputs(taskResult, outputs, client, webhookReceiver, originatingTaskName, responseAdcpVersion) {
|
|
730
730
|
const hasTaskCompletionPath = outputs.some(
|
|
731
731
|
(o) => typeof o.path === "string" && o.path.startsWith(TASK_COMPLETION_PATH_PREFIX)
|
|
732
732
|
);
|
|
@@ -779,7 +779,10 @@ async function resolveTaskCompletionOutputs(taskResult, outputs, client, webhook
|
|
|
779
779
|
if (winner.kind === "poll") {
|
|
780
780
|
const polled = winner.result;
|
|
781
781
|
if (polled.success === false) return { attempted: true, taskFailed: true };
|
|
782
|
-
return {
|
|
782
|
+
return {
|
|
783
|
+
attempted: true,
|
|
784
|
+
data: normalizeTaskCompletionData(polled.data, originatingTaskName, responseAdcpVersion)
|
|
785
|
+
};
|
|
783
786
|
}
|
|
784
787
|
const waitResult = winner.result;
|
|
785
788
|
if (waitResult.timed_out) {
|
|
@@ -787,7 +790,10 @@ async function resolveTaskCompletionOutputs(taskResult, outputs, client, webhook
|
|
|
787
790
|
}
|
|
788
791
|
const webhookBody = waitResult.webhook.body;
|
|
789
792
|
if (webhookBody?.status === "completed") {
|
|
790
|
-
return {
|
|
793
|
+
return {
|
|
794
|
+
attempted: true,
|
|
795
|
+
data: normalizeTaskCompletionData(webhookBody.result, originatingTaskName, responseAdcpVersion)
|
|
796
|
+
};
|
|
791
797
|
}
|
|
792
798
|
return { attempted: true, taskFailed: true };
|
|
793
799
|
} catch {
|
|
@@ -796,18 +802,19 @@ async function resolveTaskCompletionOutputs(taskResult, outputs, client, webhook
|
|
|
796
802
|
if (timer) clearTimeout(timer);
|
|
797
803
|
}
|
|
798
804
|
}
|
|
799
|
-
function normalizeTaskCompletionData(data, taskName) {
|
|
805
|
+
function normalizeTaskCompletionData(data, taskName, adcpVersion) {
|
|
800
806
|
if (data == null || typeof data !== "object" || Array.isArray(data)) return data;
|
|
801
807
|
const original = data;
|
|
802
|
-
const
|
|
808
|
+
const compatOptions = { toolName: taskName, adcpVersion };
|
|
809
|
+
const compat = injectLegacyEnvelopeStatus(original, compatOptions);
|
|
803
810
|
if (!("status" in original) && "status" in compat) {
|
|
804
811
|
const { status: _status, ...rest } = compat;
|
|
805
|
-
return normalizeLegacyMediaBuyStatusForReturn(rest,
|
|
812
|
+
return normalizeLegacyMediaBuyStatusForReturn(rest, compatOptions);
|
|
806
813
|
}
|
|
807
814
|
if ((taskName === "create_media_buy" || taskName === "update_media_buy") && typeof original.status === "string" && compat.status === "completed" && typeof compat.media_buy_status === "string") {
|
|
808
|
-
return normalizeLegacyMediaBuyStatusForReturn({ ...compat, status: original.status },
|
|
815
|
+
return normalizeLegacyMediaBuyStatusForReturn({ ...compat, status: original.status }, compatOptions);
|
|
809
816
|
}
|
|
810
|
-
return normalizeLegacyMediaBuyStatusForReturn(compat,
|
|
817
|
+
return normalizeLegacyMediaBuyStatusForReturn(compat, compatOptions);
|
|
811
818
|
}
|
|
812
819
|
function readEnvIntOrDefault(value, fallback) {
|
|
813
820
|
if (!value) return fallback;
|
|
@@ -1945,9 +1952,10 @@ async function prepareStoryboardFixturesBody(agentUrl, storyboard, options) {
|
|
|
1945
1952
|
options = snapshotPreparationOptions(options);
|
|
1946
1953
|
}
|
|
1947
1954
|
const callerOwnsClients = hasTestClientScope();
|
|
1948
|
-
const
|
|
1955
|
+
const runOptions = options;
|
|
1956
|
+
const preparationOptions = resolvePreparationRouteOptions(agentUrls[0], runOptions);
|
|
1949
1957
|
const resolution = getOrCreateClientResolution(agentUrls[0], preparationOptions);
|
|
1950
|
-
|
|
1958
|
+
let client = resolution.client;
|
|
1951
1959
|
const finishPreparation = (seeding, disposition) => {
|
|
1952
1960
|
if (!scopeStillMatches()) {
|
|
1953
1961
|
return refusePreparation(driftRefusal, seeding ?? void 0);
|
|
@@ -1957,6 +1965,45 @@ async function prepareStoryboardFixturesBody(agentUrl, storyboard, options) {
|
|
|
1957
1965
|
options = preparationOptions;
|
|
1958
1966
|
try {
|
|
1959
1967
|
let profile = options._profile;
|
|
1968
|
+
let discoveryStep;
|
|
1969
|
+
let routingContext;
|
|
1970
|
+
const failDiscovery = (step, failedProfile) => {
|
|
1971
|
+
const failed = buildDiscoveryFailedResult(agentUrls, storyboard, step, failedProfile);
|
|
1972
|
+
return finishPreparation(
|
|
1973
|
+
{ phase: failed.phases[0], allPassed: false, passedCount: 0, failedCount: 1 },
|
|
1974
|
+
{ status: "failed", detail: step.error ?? "agent discovery failed before fixture preparation" }
|
|
1975
|
+
);
|
|
1976
|
+
};
|
|
1977
|
+
if (runOptions.agents && (storyboardCapabilityPredicates(storyboard).length > 0 || storyboard.required_tools?.length || storyboard.required_any_of_tools?.length)) {
|
|
1978
|
+
try {
|
|
1979
|
+
validateAgentsMap(agentUrl, storyboard, runOptions);
|
|
1980
|
+
routingContext = await buildRoutingContext(storyboard, { ...runOptions, discovery_resilient: false });
|
|
1981
|
+
} catch (error) {
|
|
1982
|
+
const failedStep = error instanceof DiscoveryFailure ? error.step : void 0;
|
|
1983
|
+
return await failDiscovery({
|
|
1984
|
+
...failedStep,
|
|
1985
|
+
step: failedStep?.step ?? "Discover preparation topology",
|
|
1986
|
+
passed: false,
|
|
1987
|
+
duration_ms: failedStep?.duration_ms ?? 0,
|
|
1988
|
+
error: redactOAuthUrlsInText(
|
|
1989
|
+
error instanceof DiscoveryFailure ? `Discovery failed for agent "${error.agentKey}" (${redactOAuthUrlForOutput(error.url)}): ${error.underlying}` : error instanceof Error ? error.message : String(error)
|
|
1990
|
+
)
|
|
1991
|
+
});
|
|
1992
|
+
}
|
|
1993
|
+
for (const routeProfile of routingContext.profiles.values()) {
|
|
1994
|
+
const failure = describeProfileDiscoveryFailure(
|
|
1995
|
+
routeProfile,
|
|
1996
|
+
runOptions._requireValidCapabilityEvidence === true,
|
|
1997
|
+
runOptions._allowCapabilityDiagnostic === true
|
|
1998
|
+
);
|
|
1999
|
+
if (failure) return await failDiscovery(failure, routeProfile);
|
|
2000
|
+
}
|
|
2001
|
+
const firstKey = Object.keys(runOptions.agents)[0];
|
|
2002
|
+
profile = routingContext.profiles.get(firstKey);
|
|
2003
|
+
client = routingContext.clients.get(firstKey);
|
|
2004
|
+
discoveryStep = routingContext.discoverySteps?.get(firstKey);
|
|
2005
|
+
options = { ...options, _profile: profile, agentTools: normalizeAgentToolNames(profile.tools) };
|
|
2006
|
+
}
|
|
1960
2007
|
const suppliedFailure = profile && describeProfileDiscoveryFailure(
|
|
1961
2008
|
profile,
|
|
1962
2009
|
options._requireValidCapabilityEvidence === true,
|
|
@@ -1969,8 +2016,9 @@ async function prepareStoryboardFixturesBody(agentUrl, storyboard, options) {
|
|
|
1969
2016
|
{ status: "failed", detail: suppliedFailure.error ?? "agent discovery failed" }
|
|
1970
2017
|
);
|
|
1971
2018
|
}
|
|
1972
|
-
if (!profile
|
|
2019
|
+
if (!profile) {
|
|
1973
2020
|
const discovered = await getOrDiscoverStoryboardProfile(client, options);
|
|
2021
|
+
discoveryStep = discovered.evidence ?? discovered.step;
|
|
1974
2022
|
if (discovered.step.passed === false) {
|
|
1975
2023
|
const failed = buildDiscoveryFailedResult(agentUrls, storyboard, discovered.step, discovered.profile);
|
|
1976
2024
|
return await finishPreparation(
|
|
@@ -1991,6 +2039,80 @@ async function prepareStoryboardFixturesBody(agentUrl, storyboard, options) {
|
|
|
1991
2039
|
};
|
|
1992
2040
|
}
|
|
1993
2041
|
if (!scopeStillMatches()) return await refusePreparation(driftRefusal);
|
|
2042
|
+
let capabilityUnmet;
|
|
2043
|
+
const applicabilityTools = routingContext ? [...new Set([...routingContext.profiles.values()].flatMap((p) => normalizeAgentToolNames(p.tools) ?? []))] : options.agentTools;
|
|
2044
|
+
try {
|
|
2045
|
+
if (routingContext && runOptions.agents) {
|
|
2046
|
+
const dispatch = createRoutingDispatcher(routingContext, runOptions, runOptions.agents);
|
|
2047
|
+
const defaultProfile = runOptions.default_agent ? routingContext.profiles.get(runOptions.default_agent) : void 0;
|
|
2048
|
+
const rootDetails = storyboard.phases.flatMap(
|
|
2049
|
+
(phase) => phase.steps.filter((step) => step.task !== VALIDATION_ONLY_TASK).map((step) => {
|
|
2050
|
+
const selected = dispatch.nextFor(step);
|
|
2051
|
+
const owner = runOptions.default_agent ? defaultProfile : selected.profile;
|
|
2052
|
+
return evaluateStoryboardCapabilityGates(
|
|
2053
|
+
storyboard,
|
|
2054
|
+
owner,
|
|
2055
|
+
normalizeAgentToolNames(owner?.tools),
|
|
2056
|
+
runOptions.adcpVersion
|
|
2057
|
+
);
|
|
2058
|
+
})
|
|
2059
|
+
);
|
|
2060
|
+
capabilityUnmet = rootDetails.length > 0 && rootDetails.every((detail) => detail !== null) ? rootDetails[0] : null;
|
|
2061
|
+
} else {
|
|
2062
|
+
capabilityUnmet = evaluateStoryboardCapabilityGates(
|
|
2063
|
+
storyboard,
|
|
2064
|
+
profile,
|
|
2065
|
+
options.agentTools,
|
|
2066
|
+
options.adcpVersion
|
|
2067
|
+
);
|
|
2068
|
+
}
|
|
2069
|
+
} catch (error) {
|
|
2070
|
+
return await failDiscovery({
|
|
2071
|
+
step: "Resolve preparation routes",
|
|
2072
|
+
passed: false,
|
|
2073
|
+
duration_ms: 0,
|
|
2074
|
+
error: redactOAuthUrlsInText(error instanceof Error ? error.message : String(error))
|
|
2075
|
+
});
|
|
2076
|
+
}
|
|
2077
|
+
const missingFamily = applicabilityTools && storyboard.required_any_of_tools?.find((family) => !hasAnyRequiredTool(family.tools, applicabilityTools));
|
|
2078
|
+
const unmetDetail = capabilityUnmet ?? (missingFamily ? `missing_required_tool_family: needs ${missingFamily.tools.join(" or ")}` + (missingFamily.rationale ? ` (${missingFamily.rationale})` : "") : null) ?? (storyboard.required_tools?.length && applicabilityTools && !hasAnyRequiredTool(storyboard.required_tools, applicabilityTools) ? `agent does not advertise any of [${storyboard.required_tools.join(", ")}]` : null);
|
|
2079
|
+
if (unmetDetail !== null) {
|
|
2080
|
+
const observations = routingContext && runOptions.agents ? Object.entries(runOptions.agents).map(([key, entry]) => ({
|
|
2081
|
+
key,
|
|
2082
|
+
url: entry.url,
|
|
2083
|
+
step: routingContext.discoverySteps?.get(key)
|
|
2084
|
+
})) : [{ key: "discovery", url: agentUrls[0], step: discoveryStep }];
|
|
2085
|
+
const steps = observations.map(({ key, url, step }) => ({
|
|
2086
|
+
storyboard_id: storyboard.id,
|
|
2087
|
+
phase_id: "discovery",
|
|
2088
|
+
step_id: key,
|
|
2089
|
+
title: step ? "Agent capability discovery" : "Supplied agent capability profile",
|
|
2090
|
+
task: step?.task ?? "",
|
|
2091
|
+
passed: true,
|
|
2092
|
+
duration_ms: step?.duration_ms ?? 0,
|
|
2093
|
+
validations: [],
|
|
2094
|
+
context: {},
|
|
2095
|
+
...routingContext && { agent_url: redactOAuthUrlForOutput(url) },
|
|
2096
|
+
extraction: step?.extraction ?? { path: "none" },
|
|
2097
|
+
...step?.request && { request: step.request },
|
|
2098
|
+
...step?.response_record && { response_record: step.response_record }
|
|
2099
|
+
}));
|
|
2100
|
+
return await finishPreparation(
|
|
2101
|
+
{
|
|
2102
|
+
phase: {
|
|
2103
|
+
phase_id: "discovery",
|
|
2104
|
+
phase_title: "Agent capability discovery",
|
|
2105
|
+
passed: true,
|
|
2106
|
+
duration_ms: steps.reduce((total, step) => total + step.duration_ms, 0),
|
|
2107
|
+
steps
|
|
2108
|
+
},
|
|
2109
|
+
allPassed: true,
|
|
2110
|
+
passedCount: steps.length,
|
|
2111
|
+
failedCount: 0
|
|
2112
|
+
},
|
|
2113
|
+
{ status: "unsupported", reason: "not_applicable", detail: unmetDetail }
|
|
2114
|
+
);
|
|
2115
|
+
}
|
|
1994
2116
|
const context = createRunContext(storyboard, options).context;
|
|
1995
2117
|
const seeding = await runControllerSeeding(client, storyboard, options, context);
|
|
1996
2118
|
if (!seeding) {
|
|
@@ -5883,7 +6005,12 @@ async function executeStep(client, step, storyboardId, phaseId, context, allStep
|
|
|
5883
6005
|
};
|
|
5884
6006
|
const hasData = taskResult?.data !== void 0 && taskResult?.data !== null;
|
|
5885
6007
|
if (passed && hasData && taskResult && !(effectiveStep.task === "sync_accounts" && request.dry_run === true)) {
|
|
5886
|
-
const extracted = extractContextWithProvenance(
|
|
6008
|
+
const extracted = extractContextWithProvenance(
|
|
6009
|
+
effectiveStep.task,
|
|
6010
|
+
taskResult.data,
|
|
6011
|
+
step.id,
|
|
6012
|
+
options._serverAdcpVersion ?? options.adcpVersion
|
|
6013
|
+
);
|
|
5887
6014
|
const conventionUnset = [];
|
|
5888
6015
|
for (const group of extracted.clearGroups ?? []) {
|
|
5889
6016
|
if (group.when && !group.when.values.includes(updatedContext[group.when.key])) continue;
|
|
@@ -5914,7 +6041,8 @@ async function executeStep(client, step, storyboardId, phaseId, context, allStep
|
|
|
5914
6041
|
step.context_outputs,
|
|
5915
6042
|
client,
|
|
5916
6043
|
runState.webhookReceiver,
|
|
5917
|
-
effectiveStep.task
|
|
6044
|
+
effectiveStep.task,
|
|
6045
|
+
options._serverAdcpVersion ?? options.adcpVersion
|
|
5918
6046
|
);
|
|
5919
6047
|
const extractionData = "data" in taskCompletionResolution ? taskCompletionResolution.data : hasData && taskResult ? taskResult.data : void 0;
|
|
5920
6048
|
const remappedOutputs = remapTaskCompletionOutputs(step.context_outputs);
|
|
@@ -197,7 +197,7 @@ export interface UpstreamTrafficQueryResult {
|
|
|
197
197
|
*/
|
|
198
198
|
export declare function runValidations(validations: StoryboardValidation[], context: ValidationContext): ValidationResult[];
|
|
199
199
|
/** Capability semver emitted in run summaries and used for advisory expiry. */
|
|
200
|
-
export declare const RUNNER_CAPABILITY_VERSION = "17.0.0-beta.
|
|
200
|
+
export declare const RUNNER_CAPABILITY_VERSION = "17.0.0-beta.1";
|
|
201
201
|
/** True when a failed validation contributes to the owning step's grade. */
|
|
202
202
|
export declare function validationFailsStep(result: ValidationResult): boolean;
|
|
203
203
|
/**
|
|
@@ -197,7 +197,7 @@ export interface UpstreamTrafficQueryResult {
|
|
|
197
197
|
*/
|
|
198
198
|
export declare function runValidations(validations: StoryboardValidation[], context: ValidationContext): ValidationResult[];
|
|
199
199
|
/** Capability semver emitted in run summaries and used for advisory expiry. */
|
|
200
|
-
export declare const RUNNER_CAPABILITY_VERSION = "17.0.0-beta.
|
|
200
|
+
export declare const RUNNER_CAPABILITY_VERSION = "17.0.0-beta.1";
|
|
201
201
|
/** True when a failed validation contributes to the owning step's grade. */
|
|
202
202
|
export declare function validationFailsStep(result: ValidationResult): boolean;
|
|
203
203
|
/**
|
|
@@ -295,8 +295,11 @@ function validateResponseSchemaForVersion(validation, ctx, taskResult) {
|
|
|
295
295
|
return rest;
|
|
296
296
|
})();
|
|
297
297
|
const schema = import_response_schemas.TOOL_RESPONSE_SCHEMAS[taskName];
|
|
298
|
-
const dataForValidation = Array.isArray(dataWithoutMessage) ? dataWithoutMessage : (0, import_envelope_status_compat.injectLegacyEnvelopeStatus)(dataWithoutMessage, { toolName: taskName });
|
|
299
298
|
const responseAdcpVersion = ctx.responseAdcpVersion ?? ctx.adcpVersion;
|
|
299
|
+
const dataForValidation = Array.isArray(dataWithoutMessage) ? dataWithoutMessage : (0, import_envelope_status_compat.injectLegacyEnvelopeStatus)(dataWithoutMessage, {
|
|
300
|
+
toolName: taskName,
|
|
301
|
+
adcpVersion: responseAdcpVersion
|
|
302
|
+
});
|
|
300
303
|
const parseResult = schema?.safeParse(
|
|
301
304
|
(0, import_response_schemas.prepareResponseForSchemaValidation)(taskName, dataForValidation, responseAdcpVersion)
|
|
302
305
|
);
|
|
@@ -276,8 +276,11 @@ function validateResponseSchemaForVersion(validation, ctx, taskResult) {
|
|
|
276
276
|
return rest;
|
|
277
277
|
})();
|
|
278
278
|
const schema = TOOL_RESPONSE_SCHEMAS[taskName];
|
|
279
|
-
const dataForValidation = Array.isArray(dataWithoutMessage) ? dataWithoutMessage : injectLegacyEnvelopeStatus(dataWithoutMessage, { toolName: taskName });
|
|
280
279
|
const responseAdcpVersion = ctx.responseAdcpVersion ?? ctx.adcpVersion;
|
|
280
|
+
const dataForValidation = Array.isArray(dataWithoutMessage) ? dataWithoutMessage : injectLegacyEnvelopeStatus(dataWithoutMessage, {
|
|
281
|
+
toolName: taskName,
|
|
282
|
+
adcpVersion: responseAdcpVersion
|
|
283
|
+
});
|
|
281
284
|
const parseResult = schema?.safeParse(
|
|
282
285
|
prepareResponseForSchemaValidation(taskName, dataForValidation, responseAdcpVersion)
|
|
283
286
|
);
|
|
@@ -31,6 +31,7 @@ __export(test_controller_exports, {
|
|
|
31
31
|
});
|
|
32
32
|
module.exports = __toCommonJS(test_controller_exports);
|
|
33
33
|
var import_client = require('./client.js');
|
|
34
|
+
var import_errors = require('../errors/index.js');
|
|
34
35
|
const TOOL_NAME = "comply_test_controller";
|
|
35
36
|
const DEFAULT_SANDBOX_ACCOUNT = { brand: { domain: "test.example" }, operator: "test.example", sandbox: true };
|
|
36
37
|
function buildAccount(options) {
|
|
@@ -84,6 +85,8 @@ async function detectController(client, profile, options) {
|
|
|
84
85
|
}
|
|
85
86
|
return { detected: false };
|
|
86
87
|
} catch (error) {
|
|
88
|
+
if (error instanceof import_errors.ProtocolFeatureUnsupportedError && error.adcpError.details?.feature === "adcp_version")
|
|
89
|
+
throw error;
|
|
87
90
|
(0, import_client.getLogger)().warn(
|
|
88
91
|
{ tool: TOOL_NAME, error: error instanceof Error ? error.message : String(error) },
|
|
89
92
|
"comply_test_controller list_scenarios failed \u2014 treating as unavailable"
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { getLogger, resolveAccount } from "./client.mjs";
|
|
2
|
+
import { ProtocolFeatureUnsupportedError } from "../errors/index.mjs";
|
|
2
3
|
const TOOL_NAME = "comply_test_controller";
|
|
3
4
|
const DEFAULT_SANDBOX_ACCOUNT = { brand: { domain: "test.example" }, operator: "test.example", sandbox: true };
|
|
4
5
|
function buildAccount(options) {
|
|
@@ -52,6 +53,8 @@ async function detectController(client, profile, options) {
|
|
|
52
53
|
}
|
|
53
54
|
return { detected: false };
|
|
54
55
|
} catch (error) {
|
|
56
|
+
if (error instanceof ProtocolFeatureUnsupportedError && error.adcpError.details?.feature === "adcp_version")
|
|
57
|
+
throw error;
|
|
55
58
|
getLogger().warn(
|
|
56
59
|
{ tool: TOOL_NAME, error: error instanceof Error ? error.message : String(error) },
|
|
57
60
|
"comply_test_controller list_scenarios failed \u2014 treating as unavailable"
|
|
@@ -14,7 +14,10 @@
|
|
|
14
14
|
* enum during validation. The same translation applies to the documented 3.1
|
|
15
15
|
* deprecation window for top-level `status: MediaBuyStatus`. Other 3.1+
|
|
16
16
|
* responses are returned unchanged so the strict validator still rejects a
|
|
17
|
-
* peer that omits or misuses `status`.
|
|
17
|
+
* peer that omits or misuses `status`. A bare `completed` / `rejected` /
|
|
18
|
+
* `canceled` is never treated as a lifecycle when the payload, or failing
|
|
19
|
+
* that the caller's requested release (`options.adcpVersion`), is 3.1+:
|
|
20
|
+
* there it is the task envelope status.
|
|
18
21
|
*
|
|
19
22
|
* The leniency is a back-compat affordance, not a permanent loosening.
|
|
20
23
|
*/
|
|
@@ -26,6 +29,20 @@ export interface LegacyEnvelopeStatusOptions {
|
|
|
26
29
|
* the protocol task envelope.
|
|
27
30
|
*/
|
|
28
31
|
toolName?: string;
|
|
32
|
+
/**
|
|
33
|
+
* AdCP release the caller requested or negotiated for this exchange (for
|
|
34
|
+
* example the client's `adcpVersion` pin, or the release negotiated down
|
|
35
|
+
* from it). The response `adcp_version` echo is optional, so a seller on
|
|
36
|
+
* 3.1+ may answer a create with only `{ status: 'completed', media_buy_id }`.
|
|
37
|
+
* `completed`, `rejected` and `canceled` are valid both as TaskStatus and as
|
|
38
|
+
* MediaBuyStatus. When the payload carries no version echo, this release
|
|
39
|
+
* decides which one a bare top-level `status` is: on 3.1+ it is the task
|
|
40
|
+
* envelope status and is never copied into `media_buy_status`. An explicit
|
|
41
|
+
* `adcp_version` / `adcp_major_version` on the payload always wins. When
|
|
42
|
+
* neither the payload nor the caller knows the release, the legacy 3.0
|
|
43
|
+
* reading still applies.
|
|
44
|
+
*/
|
|
45
|
+
adcpVersion?: string;
|
|
29
46
|
}
|
|
30
47
|
/** 3.2 synchronous response arms that intentionally forbid task-envelope status. */
|
|
31
48
|
export declare const STATUS_FREE_SYNC_RESPONSE_TOOLS: ReadonlySet<string>;
|
|
@@ -14,7 +14,10 @@
|
|
|
14
14
|
* enum during validation. The same translation applies to the documented 3.1
|
|
15
15
|
* deprecation window for top-level `status: MediaBuyStatus`. Other 3.1+
|
|
16
16
|
* responses are returned unchanged so the strict validator still rejects a
|
|
17
|
-
* peer that omits or misuses `status`.
|
|
17
|
+
* peer that omits or misuses `status`. A bare `completed` / `rejected` /
|
|
18
|
+
* `canceled` is never treated as a lifecycle when the payload, or failing
|
|
19
|
+
* that the caller's requested release (`options.adcpVersion`), is 3.1+:
|
|
20
|
+
* there it is the task envelope status.
|
|
18
21
|
*
|
|
19
22
|
* The leniency is a back-compat affordance, not a permanent loosening.
|
|
20
23
|
*/
|
|
@@ -26,6 +29,20 @@ export interface LegacyEnvelopeStatusOptions {
|
|
|
26
29
|
* the protocol task envelope.
|
|
27
30
|
*/
|
|
28
31
|
toolName?: string;
|
|
32
|
+
/**
|
|
33
|
+
* AdCP release the caller requested or negotiated for this exchange (for
|
|
34
|
+
* example the client's `adcpVersion` pin, or the release negotiated down
|
|
35
|
+
* from it). The response `adcp_version` echo is optional, so a seller on
|
|
36
|
+
* 3.1+ may answer a create with only `{ status: 'completed', media_buy_id }`.
|
|
37
|
+
* `completed`, `rejected` and `canceled` are valid both as TaskStatus and as
|
|
38
|
+
* MediaBuyStatus. When the payload carries no version echo, this release
|
|
39
|
+
* decides which one a bare top-level `status` is: on 3.1+ it is the task
|
|
40
|
+
* envelope status and is never copied into `media_buy_status`. An explicit
|
|
41
|
+
* `adcp_version` / `adcp_major_version` on the payload always wins. When
|
|
42
|
+
* neither the payload nor the caller knows the release, the legacy 3.0
|
|
43
|
+
* reading still applies.
|
|
44
|
+
*/
|
|
45
|
+
adcpVersion?: string;
|
|
29
46
|
}
|
|
30
47
|
/** 3.2 synchronous response arms that intentionally forbid task-envelope status. */
|
|
31
48
|
export declare const STATUS_FREE_SYNC_RESPONSE_TOOLS: ReadonlySet<string>;
|
|
@@ -51,7 +51,7 @@ function injectLegacyEnvelopeStatus(response, options) {
|
|
|
51
51
|
return response;
|
|
52
52
|
}
|
|
53
53
|
if (options?.toolName && STATUS_FREE_SYNC_RESPONSE_TOOLS.has(options.toolName)) return response;
|
|
54
|
-
if (options?.toolName && MEDIA_BUY_STATUS_RESPONSE_TOOLS.has(options.toolName) && allowsDeprecatedMediaBuyStatus(response) && isMediaBuySuccessStatusForCompat(response)) {
|
|
54
|
+
if (options?.toolName && MEDIA_BUY_STATUS_RESPONSE_TOOLS.has(options.toolName) && allowsDeprecatedMediaBuyStatus(response) && isMediaBuySuccessStatusForCompat(response, options)) {
|
|
55
55
|
const mediaBuyStatus = response.status;
|
|
56
56
|
return {
|
|
57
57
|
...response,
|
|
@@ -76,16 +76,16 @@ function normalizeLegacyMediaBuyStatusForReturn(response, options) {
|
|
|
76
76
|
if (!response || typeof response !== "object" || Array.isArray(response)) {
|
|
77
77
|
return response;
|
|
78
78
|
}
|
|
79
|
-
if (!options?.toolName || !MEDIA_BUY_STATUS_RESPONSE_TOOLS.has(options.toolName) || !allowsDeprecatedMediaBuyStatus(response) || !isMediaBuySuccessStatusForCompat(response)) {
|
|
79
|
+
if (!options?.toolName || !MEDIA_BUY_STATUS_RESPONSE_TOOLS.has(options.toolName) || !allowsDeprecatedMediaBuyStatus(response) || !isMediaBuySuccessStatusForCompat(response, options)) {
|
|
80
80
|
return response;
|
|
81
81
|
}
|
|
82
|
-
const status = (0, import_media_buy_status.getAuthoritativeMediaBuyStatus)(response);
|
|
82
|
+
const status = (0, import_media_buy_status.getAuthoritativeMediaBuyStatus)(withRequestedVersion(response, options));
|
|
83
83
|
if (!status || response.media_buy_status === status) return response;
|
|
84
84
|
return { ...response, media_buy_status: status };
|
|
85
85
|
}
|
|
86
|
-
function isMediaBuySuccessStatusForCompat(response) {
|
|
86
|
+
function isMediaBuySuccessStatusForCompat(response, options) {
|
|
87
87
|
const status = response.status;
|
|
88
|
-
if ((0, import_media_buy_status.getAuthoritativeMediaBuyStatus)(response) !== status) return false;
|
|
88
|
+
if ((0, import_media_buy_status.getAuthoritativeMediaBuyStatus)(withRequestedVersion(response, options)) !== status) return false;
|
|
89
89
|
if (typeof response.media_buy_status === "string" && response.media_buy_status !== status) {
|
|
90
90
|
return false;
|
|
91
91
|
}
|
|
@@ -100,6 +100,12 @@ function allowsDeprecatedMediaBuyStatus(payload) {
|
|
|
100
100
|
if (typeof major === "number") return major === 3;
|
|
101
101
|
return true;
|
|
102
102
|
}
|
|
103
|
+
function withRequestedVersion(payload, options) {
|
|
104
|
+
const requested = options?.adcpVersion;
|
|
105
|
+
if (typeof requested !== "string" || requested.length === 0) return payload;
|
|
106
|
+
if (typeof payload.adcp_version === "string" || typeof payload.adcp_major_version === "number") return payload;
|
|
107
|
+
return { ...payload, adcp_version: requested };
|
|
108
|
+
}
|
|
103
109
|
// Annotate the CommonJS export names for ESM import in node:
|
|
104
110
|
0 && (module.exports = {
|
|
105
111
|
STATUS_FREE_SYNC_RESPONSE_TOOLS,
|