АРЧ АП11 - Добавить capability runtime binding для assistant contracts
This commit is contained in:
@@ -81,6 +81,13 @@ describe("assistant address lane response runtime adapter", () => {
|
||||
}),
|
||||
state_transition_contract: expect.objectContaining({
|
||||
schema_version: "assistant_state_transition_runtime_v1"
|
||||
}),
|
||||
assistant_capability_binding_v1: expect.objectContaining({
|
||||
schema_version: "assistant_capability_runtime_binding_v1",
|
||||
binding_owner: "assistantCapabilityRuntimeBindingAdapter"
|
||||
}),
|
||||
capability_binding_contract: expect.objectContaining({
|
||||
schema_version: "assistant_capability_runtime_binding_v1"
|
||||
})
|
||||
})
|
||||
);
|
||||
@@ -145,7 +152,10 @@ describe("assistant address lane response runtime adapter", () => {
|
||||
carryover_eligibility: "none",
|
||||
state_transition_id: null,
|
||||
state_transition_status: "unresolved",
|
||||
effective_carryover_depth: "none"
|
||||
effective_carryover_depth: "none",
|
||||
capability_binding_status: "not_applicable",
|
||||
capability_binding_action: "observe_only",
|
||||
capability_binding_violations: []
|
||||
})
|
||||
);
|
||||
expect(runtime.response).toEqual({ ok: true });
|
||||
|
||||
@@ -0,0 +1,146 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import {
|
||||
attachAssistantCapabilityRuntimeBinding,
|
||||
resolveAssistantCapabilityRuntimeBinding
|
||||
} from "../src/services/assistantCapabilityRuntimeBindingAdapter";
|
||||
|
||||
describe("assistant capability runtime binding adapter", () => {
|
||||
it("binds a grounded root inventory capability to its contract", () => {
|
||||
const binding = resolveAssistantCapabilityRuntimeBinding({
|
||||
addressDebug: {
|
||||
capability_id: "confirmed_inventory_on_hand_as_of_date",
|
||||
detected_intent: "inventory_on_hand_as_of_date",
|
||||
detected_mode: "address_query",
|
||||
capability_layer: "compute",
|
||||
capability_route_mode: "exact",
|
||||
rows_matched: 3,
|
||||
route_expectation_status: "matched"
|
||||
},
|
||||
groundingStatus: "grounded",
|
||||
replyType: "factual"
|
||||
});
|
||||
|
||||
expect(binding).toEqual(
|
||||
expect.objectContaining({
|
||||
schema_version: "assistant_capability_runtime_binding_v1",
|
||||
binding_owner: "assistantCapabilityRuntimeBindingAdapter",
|
||||
capability_id: "confirmed_inventory_on_hand_as_of_date",
|
||||
capability_contract_id: "confirmed_inventory_on_hand_as_of_date",
|
||||
binding_status: "bound",
|
||||
binding_action: "allow",
|
||||
runtime_lane_expected: "address_exact",
|
||||
runtime_lane_observed: "address_exact",
|
||||
transition_id: "T1",
|
||||
transition_allowed: true,
|
||||
missing_anchors: [],
|
||||
focus_object_binding_status: "not_required",
|
||||
result_shape: "item_list_with_quantity_cost_warehouse_organization",
|
||||
answer_object_shape: "inventory_stock_snapshot",
|
||||
truth_fallback_allowed: true,
|
||||
answer_shape_compatible: true,
|
||||
violations: []
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it("binds selected-object follow-ups through item anchor when focus object is implicit", () => {
|
||||
const binding = resolveAssistantCapabilityRuntimeBinding({
|
||||
addressDebug: {
|
||||
capability_id: "inventory_inventory_purchase_provenance_for_item",
|
||||
detected_intent: "inventory_purchase_provenance_for_item",
|
||||
detected_mode: "address_query",
|
||||
capability_layer: "compute",
|
||||
capability_route_mode: "exact",
|
||||
extracted_filters: {
|
||||
item: "Диван трехместный"
|
||||
},
|
||||
rows_matched: 1,
|
||||
route_expectation_status: "matched"
|
||||
},
|
||||
addressRuntimeMeta: {
|
||||
dialogContinuationContract: {
|
||||
decision: "continue_previous",
|
||||
target_intent: "inventory_purchase_provenance_for_item"
|
||||
}
|
||||
},
|
||||
groundingStatus: "grounded",
|
||||
replyType: "factual"
|
||||
});
|
||||
|
||||
expect(binding.binding_status).toBe("bound");
|
||||
expect(binding.transition_id).toBe("T4");
|
||||
expect(binding.transition_allowed).toBe(true);
|
||||
expect(binding.required_anchors).toEqual(["item"]);
|
||||
expect(binding.provided_anchors).toContain("item");
|
||||
expect(binding.focus_object_binding_status).toBe("inferred_from_anchor");
|
||||
expect(binding.violations).toEqual([]);
|
||||
});
|
||||
|
||||
it("blocks selected-object capabilities when required anchors are missing", () => {
|
||||
const binding = resolveAssistantCapabilityRuntimeBinding({
|
||||
addressDebug: {
|
||||
capability_id: "inventory_inventory_purchase_provenance_for_item",
|
||||
limited_reason_category: "missing_anchor",
|
||||
missing_required_filters: ["item"]
|
||||
},
|
||||
replyType: "partial_coverage"
|
||||
});
|
||||
|
||||
expect(binding.binding_status).toBe("blocked");
|
||||
expect(binding.binding_action).toBe("clarify");
|
||||
expect(binding.missing_anchors).toEqual(["item"]);
|
||||
expect(binding.focus_object_binding_status).toBe("missing");
|
||||
expect(binding.violations).toEqual(
|
||||
expect.arrayContaining(["required_anchor_missing", "focus_object_required_but_unbound"])
|
||||
);
|
||||
});
|
||||
|
||||
it("blocks capabilities entered through unsupported transition classes", () => {
|
||||
const binding = resolveAssistantCapabilityRuntimeBinding({
|
||||
addressDebug: {
|
||||
capability_id: "confirmed_inventory_on_hand_as_of_date",
|
||||
rows_matched: 1,
|
||||
route_expectation_status: "matched"
|
||||
},
|
||||
runtimeContractShadow: {
|
||||
schema_version: "assistant_runtime_contracts_v1",
|
||||
transition_contract_id: "T4",
|
||||
transition_contract_title: "Short Action Follow-Up On Selected Object",
|
||||
transition_contract_reason: ["test_forced_selected_object_transition"],
|
||||
capability_contract_id: "confirmed_inventory_on_hand_as_of_date",
|
||||
capability_contract_reason: ["debug_capability_id_matched_contract"],
|
||||
truth_gate_contract_status: "full_confirmed",
|
||||
carryover_eligibility: "object_only"
|
||||
},
|
||||
groundingStatus: "grounded",
|
||||
replyType: "factual"
|
||||
});
|
||||
|
||||
expect(binding.binding_status).toBe("blocked");
|
||||
expect(binding.binding_action).toBe("block");
|
||||
expect(binding.transition_id).toBe("T4");
|
||||
expect(binding.transition_allowed).toBe(false);
|
||||
expect(binding.violations).toContain("transition_not_supported_by_capability");
|
||||
});
|
||||
|
||||
it("attaches compact debug fields and preserves the binding contract", () => {
|
||||
const debug = attachAssistantCapabilityRuntimeBinding(
|
||||
{
|
||||
capability_id: "confirmed_inventory_on_hand_as_of_date",
|
||||
detected_intent: "inventory_on_hand_as_of_date",
|
||||
rows_matched: 2,
|
||||
route_expectation_status: "matched"
|
||||
},
|
||||
{
|
||||
groundingStatus: "grounded",
|
||||
replyType: "factual"
|
||||
}
|
||||
);
|
||||
|
||||
expect(debug.capability_binding_status).toBe("bound");
|
||||
expect(debug.capability_binding_action).toBe("allow");
|
||||
expect(debug.capability_binding_violations).toEqual([]);
|
||||
expect(debug.assistant_capability_binding_v1.schema_version).toBe("assistant_capability_runtime_binding_v1");
|
||||
expect(debug.capability_binding_contract.capability_contract_id).toBe("confirmed_inventory_on_hand_as_of_date");
|
||||
});
|
||||
});
|
||||
@@ -146,6 +146,14 @@ describe("assistant debug payload assembler", () => {
|
||||
effective_carryover_depth: "none"
|
||||
})
|
||||
);
|
||||
expect(payload.assistant_capability_binding_v1).toEqual(
|
||||
expect.objectContaining({
|
||||
schema_version: "assistant_capability_runtime_binding_v1",
|
||||
binding_owner: "assistantCapabilityRuntimeBindingAdapter",
|
||||
binding_status: "not_applicable",
|
||||
binding_action: "observe_only"
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it("omits optional fields when they are not provided", () => {
|
||||
|
||||
Reference in New Issue
Block a user