What may be asked of a device remotely — and nothing else.
Spec §21 forbids a universal tool. That is not a style preference: an
assistant that can call remote.execute(action, params) has, in practice,
been handed the other device's shell, and every permission check upstream
becomes decoration. The prohibition is enforced structurally here —
- every tool declares its parameters by name, with a type;
- unknown parameters are refused, never forwarded;
- no parameter may be named
action, command, method, code,
script or sql — the shapes a passthrough always takes;
- a tool with no declared parameters accepts no arguments at all.
A test (test_no_universal_tool) re-checks these on the whole registry, so
adding a fourteenth tool cannot quietly reintroduce the thirteenth's escape
hatch.
RemoteToolSpec(
name: str,
description: str,
capability: str,
parameters: Mapping[str, Mapping[str, Any]] = dict(),
requires_confirmation: bool = False,
offline_policy: str = "QUEUE_UNTIL_EXPIRATION",
)
One narrow, explicitly-shaped remote capability.
validate(arguments: Mapping[str, Any]) -> None
Refuse anything the tool did not explicitly ask for.
Source code in src/diapason/mesh/tools.py
| def validate(self, arguments: Mapping[str, Any]) -> None:
"""Refuse anything the tool did not explicitly ask for."""
from diapason.mesh.commands import CommandRejected
if not isinstance(arguments, Mapping):
raise CommandRejected("DENIED", "Les arguments sont illisibles.")
unknown = set(arguments) - set(self.parameters)
if unknown:
raise CommandRejected(
"DENIED",
f"Paramètre non reconnu pour « {self.name} » : "
f"{', '.join(sorted(unknown))}.",
)
for key, rule in self.parameters.items():
if key not in arguments:
if rule.get("required"):
raise CommandRejected(
"DENIED", f"Le paramètre « {key} » est obligatoire."
)
continue
value = arguments[key]
expected = rule.get("type", "string")
if expected == "string":
if not isinstance(value, str):
raise CommandRejected(
"DENIED", f"Le paramètre « {key} » doit être du texte."
)
if len(value) > int(rule.get("max", 500)):
raise CommandRejected(
"DENIED", f"Le paramètre « {key} » est trop long."
)
elif expected == "integer" and not isinstance(value, int):
raise CommandRejected(
"DENIED", f"Le paramètre « {key} » doit être un nombre."
)
elif expected == "boolean" and not isinstance(value, bool):
raise CommandRejected(
"DENIED", f"Le paramètre « {key} » doit être vrai ou faux."
)
choices = rule.get("enum")
if choices and value not in choices:
raise CommandRejected(
"DENIED",
f"Valeur non autorisée pour « {key} ».",
)
|
list_remote_tools() -> list[dict[str, Any]]
The catalogue, as the assistant's tool router should advertise it.
Source code in src/diapason/mesh/tools.py
| def list_remote_tools() -> list[dict[str, Any]]:
"""The catalogue, as the assistant's tool router should advertise it."""
return [
{
"name": spec.name,
"description": spec.description,
"capability": spec.capability,
"parameters": {
key: dict(rule) for key, rule in sorted(spec.parameters.items())
},
"requiresConfirmation": spec.requires_confirmation,
"offlinePolicy": spec.offline_policy,
}
for spec in sorted(REMOTE_TOOLS.values(), key=lambda s: s.name)
]
|