Files
cdsl-cad/backend/app/cad_agent/application/capabilities.py
T
2026-09-01 14:10:23 +08:00

93 lines
4.5 KiB
Python

"""Real provider structured-output conformance gate for protocol v3."""
from __future__ import annotations
from hashlib import sha256
import json
from typing import Any
from app.cad_agent.application.llm_contracts import (
EmptyCommand,
GeometryConclusion,
RollbackCheckpoint,
candidate_review_schema,
final_review_schema,
geometry_conclusion_schema,
next_action_schema,
operation_contract_request_schema,
requirements_draft_schema,
requirements_patch_schema,
requirements_review_schema,
rollback_checkpoint_schema,
topology_request_schema,
)
from app.cad_agent.domain.operation_contract import fragment_schema
from app.cad_agent.domain.verifier_registry import default_registry
from app.cad_agent.ports import CadRuntime, ModelGateway
_CONFORMANCE_WORKING_HEAD = "cad_conformance:root:v1"
_CONFORMANCE_REQUIREMENT_IDS = ["req_001"]
_CONFORMANCE_CLAIM_IDS = ["claim_001"]
_CONFORMANCE_DRAFT_IDS = ["draft_001"]
_CONFORMANCE_SOURCE_IDS = ["src_001"]
def conformance_tools(runtime: CadRuntime) -> list[dict[str, Any]]:
"""Return the complete v3 structured-output surface.
A provider is usable only when it can return valid arguments for every
fixed schema and every currently registered runtime operation. This list
intentionally derives the operation portion from the runtime registry so
a newly exposed operation cannot bypass the capability gate.
"""
registry = default_registry()
atomic_ids = list(runtime.supported_atomic_ids())
tools = [
_tool("submit_requirements_draft_batch", requirements_draft_schema(registry.expected_one_of_schema(), _CONFORMANCE_SOURCE_IDS)),
_tool("patch_requirements_draft", requirements_patch_schema(registry.expected_one_of_schema(), _CONFORMANCE_SOURCE_IDS, _CONFORMANCE_DRAFT_IDS)),
_tool("finalize_requirements_draft", EmptyCommand.model_json_schema()),
_tool("review_requirements", requirements_review_schema(_CONFORMANCE_SOURCE_IDS, _CONFORMANCE_DRAFT_IDS)),
_tool("propose_next_action", next_action_schema(_CONFORMANCE_WORKING_HEAD, _CONFORMANCE_REQUIREMENT_IDS, atomic_ids)),
_tool("inspect_topology", topology_request_schema(_CONFORMANCE_WORKING_HEAD)),
_tool("get_cdsl_operation_contract", operation_contract_request_schema(_CONFORMANCE_WORKING_HEAD, atomic_ids[0])),
_tool("review_candidate", candidate_review_schema("candidate_conformance", _CONFORMANCE_WORKING_HEAD, _CONFORMANCE_CLAIM_IDS)),
_tool("complete_task", EmptyCommand.model_json_schema()),
_tool("review_final", final_review_schema(_CONFORMANCE_WORKING_HEAD, _CONFORMANCE_CLAIM_IDS)),
_tool("record_geometry_conclusion", geometry_conclusion_schema(_CONFORMANCE_WORKING_HEAD, ["evidence_current_state"])),
_tool("rollback_checkpoint", rollback_checkpoint_schema(_CONFORMANCE_WORKING_HEAD, ["checkpoint_root"])),
]
if not atomic_ids:
raise RuntimeError("Runtime has no operations for conformance")
for atomic_id in atomic_ids:
contract = runtime.operation_contract(atomic_id)
tools.append(_tool(f"conformance_{atomic_id}", fragment_schema(contract, selector_tokens=["sel_conformance"], reference_tokens=["ref_conformance"])))
return tools
def conformance_hash(tools: list[dict[str, Any]]) -> str:
return sha256(json.dumps(tools, ensure_ascii=True, sort_keys=True, separators=(",", ":")).encode("utf-8")).hexdigest()
async def verify_model_capability(repository: Any, runtime: CadRuntime, models: ModelGateway, *, provider_id: str, model_id: str, force: bool = False) -> dict[str, Any]:
tools = conformance_tools(runtime)
schema_hash = conformance_hash(tools)
cached = repository.model_capability(provider_id, model_id, schema_hash)
if cached is not None and cached["supported"] and not force:
return {"cached": True, "schema_hash": schema_hash, **cached["report"]}
report = await models.conformance(provider_id=provider_id, model_id=model_id, tools=tools)
report = {"schema_hash": schema_hash, "tool_count": len(tools), **report}
repository.record_model_capability(provider_id, model_id, schema_hash, report)
return report
def _tool(name: str, parameters: dict[str, Any]) -> dict[str, Any]:
return {
"type": "function",
"function": {
"name": name,
"description": "Structured output conformance probe. Return one schema-valid call with every required root and nested property.",
"parameters": parameters,
},
}