"""Print the capability/executor matrix derived from repository catalogs.""" from __future__ import annotations import argparse import json from pathlib import Path from typing import Any from cognitive_agent.infrastructure.speech.capability import CapabilityResolver REPOSITORY_ROOT = Path(__file__).resolve().parents[1] def parameter_summary(parameters: tuple[dict[str, Any], ...]) -> str: values: list[str] = [] for parameter in parameters: name = str(parameter["name"]) value_type = str(parameter.get("type", "unknown")) allowed = parameter.get("allowed_values") if allowed is not None: constraint = "{" + ",".join(map(str, allowed)) + "}" elif parameter.get("minimum") is not None or parameter.get("maximum") is not None: constraint = f"[{parameter.get('minimum', '-∞')},{parameter.get('maximum', '+∞')}]" else: constraint = "" unit = f" {parameter['unit']}" if parameter.get("unit") else "" optional = "" if parameter.get("required") else "?" values.append(f"{name}{optional}:{value_type}{constraint}{unit}") return "; ".join(values) or "—" def matrix() -> list[dict[str, Any]]: resolver = CapabilityResolver(REPOSITORY_ROOT) rows = [] for definition in resolver.definitions(): executable = not ( definition.availability == "catalog_only" or ( definition.availability == "native_can" and definition.name not in resolver.native_supported ) ) rows.append( { "device": ",".join(definition.target_devices) or "—", "target": ",".join(definition.target_scopes) or "—", "capability": definition.name, "operation": "set/defined by capability parameters", "value_schema": parameter_summary(definition.parameters), "availability": definition.availability, "execution_eligible": executable, "executor_binding": ( resolver.executor_binding_for(definition) if executable else None ), "catalog": str(definition.catalog_path.relative_to(REPOSITORY_ROOT)), } ) return rows def as_markdown(rows: list[dict[str, Any]]) -> str: lines = [ "| Device | Target / scope | Capability | Value type / range / unit | Executable | Executor binding |", "|---|---|---|---|---:|---|", ] for row in rows: lines.append( "| {device} | {target} | `{capability}` | {value_schema} | {execution_eligible} | {executor_binding} |".format( **row ) ) return "\n".join(lines) def main() -> None: parser = argparse.ArgumentParser(description=__doc__) parser.add_argument("--format", choices=("json", "markdown"), default="markdown") args = parser.parse_args() rows = matrix() if args.format == "json": print(json.dumps(rows, ensure_ascii=False, indent=2)) else: print(as_markdown(rows)) if __name__ == "__main__": main()