89 lines
3.1 KiB
Python
89 lines
3.1 KiB
Python
"""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()
|