feat(engine): register MCP profiles and provider transitions
This commit is contained in:
@@ -9,11 +9,12 @@ export const L2_EXECUTION_PLAN_SCHEMA_VERSION = "nodedc.l2-execution-plan/v1";
|
||||
export const L2_GRAPH_BLUEPRINT_SCHEMA_VERSION = "nodedc.l2-graph-blueprint/v1";
|
||||
export const L2_MATERIALIZATION_RECEIPT_SCHEMA_VERSION = "nodedc.l2-materialization-receipt/v1";
|
||||
export const L2_MAPPING_RUNTIME_SCHEMA_VERSION = "nodedc.semantic-mapping-runtime/v1";
|
||||
export const L2_EXECUTION_PLAN_COMPILER_VERSION = "1.4.0";
|
||||
export const L2_EXECUTION_PLAN_COMPILER_VERSION = "1.5.0";
|
||||
export const L2_EXECUTION_PLAN_SUPPORTED_COMPILER_VERSIONS = Object.freeze([
|
||||
"1.1.0",
|
||||
"1.2.0",
|
||||
"1.3.0",
|
||||
"1.4.0",
|
||||
L2_EXECUTION_PLAN_COMPILER_VERSION,
|
||||
]);
|
||||
|
||||
|
||||
@@ -259,6 +259,14 @@ export function validateProviderPackage(value) {
|
||||
if (!selectedCapabilityIds.includes(mapping.sourceCapabilityId)) {
|
||||
errors.push(`collectionProfile.${profile.id}.mapping_source_capability_must_be_selected`);
|
||||
}
|
||||
for (const derivation of Object.values(mapping.derivations || {})) {
|
||||
if (
|
||||
derivation?.kind === "bounded_response_lookup"
|
||||
&& !selectedCapabilityIds.includes(derivation.parameters?.responseCapabilityId)
|
||||
) {
|
||||
errors.push(`collectionProfile.${profile.id}.lookup_response_capability_must_be_selected`);
|
||||
}
|
||||
}
|
||||
if (mapping.fieldPolicyId !== profile.fieldPolicyId) errors.push(`collectionProfile.${profile.id}.mapping_field_policy_mismatch`);
|
||||
if (mapping.target?.dataProductId !== profile.dataProductId) errors.push(`collectionProfile.${profile.id}.mapping_data_product_mismatch`);
|
||||
}
|
||||
@@ -283,6 +291,16 @@ export function validateProviderPackage(value) {
|
||||
}
|
||||
for (const mapping of mappingContracts) {
|
||||
assertReference(mapping.sourceCapabilityId, capabilityIds, `mappingContract.${mapping.id}.sourceCapabilityId`, errors);
|
||||
for (const [derivationId, derivation] of Object.entries(mapping.derivations || {})) {
|
||||
if (derivation?.kind === "bounded_response_lookup") {
|
||||
assertReference(
|
||||
derivation.parameters?.responseCapabilityId,
|
||||
capabilityIds,
|
||||
`mappingContract.${mapping.id}.derivations.${derivationId}.parameters.responseCapabilityId`,
|
||||
errors,
|
||||
);
|
||||
}
|
||||
}
|
||||
assertReference(mapping.fieldPolicyId, fieldPolicyIds, `mappingContract.${mapping.id}.fieldPolicyId`, errors);
|
||||
assertReference(mapping.target?.dataProductId, dataProductIds, `mappingContract.${mapping.id}.target.dataProductId`, errors);
|
||||
const product = dataProducts.find((item) => item.id === mapping.target?.dataProductId);
|
||||
@@ -1049,6 +1067,7 @@ function validateDerivation(value, path, errors) {
|
||||
"ordered_rules",
|
||||
"flag_set",
|
||||
"bounded_readings",
|
||||
"bounded_response_lookup",
|
||||
"bounded_string_list",
|
||||
"bounded_named_values",
|
||||
]).has(value.kind)) errors.push(`${path}.kind_invalid`);
|
||||
@@ -1075,6 +1094,89 @@ function validateDerivation(value, path, errors) {
|
||||
if (value.kind === "bounded_named_values") {
|
||||
validateBoundedNamedValuesDerivation(value, path, errors);
|
||||
}
|
||||
if (value.kind === "bounded_response_lookup") {
|
||||
validateBoundedResponseLookupDerivation(value, path, errors);
|
||||
}
|
||||
}
|
||||
|
||||
function validateBoundedResponseLookupDerivation(value, path, errors) {
|
||||
const parameters = isPlainObject(value.parameters) ? value.parameters : {};
|
||||
const allowed = new Set([
|
||||
"responseCapabilityId",
|
||||
"responseCollectionPath",
|
||||
"responseKeyPath",
|
||||
"sourceArrayPath",
|
||||
"sourceKeyPath",
|
||||
"valuePath",
|
||||
"resultMode",
|
||||
"maxResponseItems",
|
||||
"maxSourceKeys",
|
||||
"maxItems",
|
||||
"maxItemLength",
|
||||
]);
|
||||
if (Object.keys(parameters).some((key) => !allowed.has(key))) {
|
||||
errors.push(`${path}.parameters_shape_invalid`);
|
||||
}
|
||||
if (!IDENTIFIER.test(String(parameters.responseCapabilityId || ""))) {
|
||||
errors.push(`${path}.parameters.responseCapabilityId_invalid`);
|
||||
}
|
||||
for (const key of [
|
||||
"responseCollectionPath",
|
||||
"responseKeyPath",
|
||||
"sourceKeyPath",
|
||||
"valuePath",
|
||||
]) {
|
||||
if (!isCanonicalSourcePath(parameters[key])) {
|
||||
errors.push(`${path}.parameters.${key}_must_be_canonical_dot_path`);
|
||||
}
|
||||
}
|
||||
if (SECRET_FIELD_NAME.test(String(parameters.valuePath || ""))) {
|
||||
errors.push(`${path}.parameters.valuePath_secret_field_not_allowed`);
|
||||
}
|
||||
if (
|
||||
parameters.sourceArrayPath !== undefined
|
||||
&& !isCanonicalSourcePath(parameters.sourceArrayPath)
|
||||
) {
|
||||
errors.push(`${path}.parameters.sourceArrayPath_must_be_canonical_dot_path`);
|
||||
}
|
||||
if (!new Set(["first", "list"]).has(parameters.resultMode)) {
|
||||
errors.push(`${path}.parameters.resultMode_invalid`);
|
||||
}
|
||||
if (
|
||||
!Number.isInteger(parameters.maxResponseItems)
|
||||
|| parameters.maxResponseItems < 1
|
||||
|| parameters.maxResponseItems > 5000
|
||||
) {
|
||||
errors.push(`${path}.parameters.maxResponseItems_invalid`);
|
||||
}
|
||||
if (
|
||||
!Number.isInteger(parameters.maxSourceKeys)
|
||||
|| parameters.maxSourceKeys < 1
|
||||
|| parameters.maxSourceKeys > 256
|
||||
) {
|
||||
errors.push(`${path}.parameters.maxSourceKeys_invalid`);
|
||||
}
|
||||
if (
|
||||
!Number.isInteger(parameters.maxItems)
|
||||
|| parameters.maxItems < 1
|
||||
|| parameters.maxItems > 256
|
||||
) {
|
||||
errors.push(`${path}.parameters.maxItems_invalid`);
|
||||
}
|
||||
if (
|
||||
!Number.isInteger(parameters.maxItemLength)
|
||||
|| parameters.maxItemLength < 1
|
||||
|| parameters.maxItemLength > 512
|
||||
) {
|
||||
errors.push(`${path}.parameters.maxItemLength_invalid`);
|
||||
}
|
||||
if (parameters.resultMode === "list") {
|
||||
if (!Array.isArray(value.default) || value.default.length !== 0) {
|
||||
errors.push(`${path}.default_must_be_empty_array_for_list`);
|
||||
}
|
||||
} else if (value.default !== "") {
|
||||
errors.push(`${path}.default_must_be_empty_string_for_first`);
|
||||
}
|
||||
}
|
||||
|
||||
function validateBoundedStringListDerivation(value, path, errors) {
|
||||
|
||||
Reference in New Issue
Block a user