Commands

Shared session-command framework (ADR-0047): the command catalogue, parser, registry, and the graph-side handler contract. See Session commands for the user-facing catalogue.

Common

Common components of the session-command framework.

Commands are the user-driven analogue of tool calls (ADR-0047): the user chooses the command instead of the model choosing a tool. This module holds the shared mechanics – the Command metadata, a CommandRegistry, the /command parser (with a // escape), the CommandContext handed to handlers, the CommandResult they return, and /help rendering – with no frontend or app imports. Each frontend routes an input that starts with / by the command’s klass; app-specific handlers are registered with the app. See devdocs/system/session-commands.md.

File: klea_utils/commands/common.py

Copyright 2026 Ankur Sinha Author: Ankur Sinha <sanjay DOT ankur AT gmail DOT com>

klea_utils.commands.common.CAP_LOCAL_FS = 'local_fs'

a command’s capabilities must be a subset of the frontend’s for the frontend to expose/run it. Defined centrally so frontends filter consistently instead of inventing ad-hoc predicates.

Type:

Standard capability vocabulary

class klea_utils.commands.common.Command(name: str, summary: str, side: Literal['server', 'client'] = 'client', klass: Literal['ui', 'session-state', 'workflow', 'prompt'] = 'ui', aliases: tuple[str, ...] = (), subcommands: tuple[Subcommand, ...] = (), arg_hint: str = '', while_streaming: Literal['block', 'allow'] = 'allow', persists: Literal['none', 'checkpoint', 'message'] = 'none', capabilities: frozenset[str] = frozenset({}), implemented: bool = True, handler: Callable[[CommandContext, ParsedCommand], CommandResult] | None = None)[source]

Bases: object

One entry in the command catalogue (ADR-0047).

Parameters:
  • name – Canonical name, lower-case, without the leading slash.

  • summary – One-line description (shown by /help and the menu).

  • side – Execution host (server | client).

  • klass – Handling class (ui | session-state | workflow | prompt).

  • aliases – Alternative names.

  • subcommands – First-class verbs (see Subcommand); empty for a plain command.

  • arg_hint – A short usage hint for the arguments (e.g. <path>).

  • while_streaming – block | allow while a run is active.

  • persists – none | checkpoint | message.

  • capabilities – Frontend capabilities the command needs (subset of STANDARD_CAPABILITIES).

  • implemented – False marks a documented stub.

  • handler – The client-side handler (None for server commands and stubs).

classmethod from_metadata(data: Mapping[str, Any]) → Command[source]

Reconstruct a Command from metadata() output.

Used by a frontend to add the server catalogue to its own client commands. The handler is not carried over (None).

Parameters:

data – A metadata() dict.

Returns:

The reconstructed command.

metadata() → dict[str, Any][source]

Return the catalogue metadata (no handler) for GET /commands.

class klea_utils.commands.common.CommandContext(user_id: str = '', chat_id: str = '', capabilities: frozenset[str] = frozenset({}), services: Mapping[str, ~typing.Any]=<factory>)[source]

Bases: object

The capability surface a client-side handler is given.

Carries the session identity, the frontend’s capabilities, and a generic services mapping for frontend/app-provided hooks (e.g. a callable to open the model dialog or switch chat). Keeping it generic means the shared core stays free of frontend and app imports.

Parameters:
  • user_id – The session’s user identifier.

  • chat_id – The active chat identifier (empty before a chat exists).

  • capabilities – The frontend’s capabilities.

  • services – Frontend/app hooks, keyed by convention.

service(key: str, default: Any = None) → Any[source]

Return the frontend/app hook registered under key, or default.

klea_utils.commands.common.CommandHandler

(context, parsed) -> CommandResult.

Type:

A client-side command handler

alias of Callable[[CommandContext, ParsedCommand], CommandResult]

class klea_utils.commands.common.CommandRegistry[source]

Bases: object

A per-app registry of commands, keyed by canonical name and aliases.

all() → list[Command][source]

Return every command, sorted by name.

available(capabilities: Iterable[str] | None = None) → list[Command][source]

Return the publicly available commands, sorted by name.

Only implemented commands are returned: a command still marked implemented=False is not published (so GET /commands, /help and the frontend menu never show a not-yet-real command). When capabilities is given, commands requiring a capability the frontend lacks are excluded too.

Parameters:

capabilities – The frontend’s capabilities, or None for all.

Returns:

The available commands, sorted by name.

dispatch(parsed: ParsedCommand, ctx: CommandContext) → CommandResult[source]

Run parsed against the registry and return its result.

Unknown names, stubs, and parse errors produce an error result rather than raising, so a frontend can render them directly.

Parameters:
  • parsed – The parsed command.

  • ctx – The handler context.

Returns:

The command’s CommandResult.

get(name: str) → Command | None[source]

Return the command for name or an alias, or None.

register(command: Command) → None[source]

Add command, raising on an invalid or duplicate name/alias.

Parameters:

command – The command to register.

Raises:

ValueError – On an invalid name or a duplicate name/alias.

class klea_utils.commands.common.CommandResult(output: list[str] = <factory>, error: str = '', notice: str = '', handled: bool = True)[source]

Bases: object

The common outcome shape of a client-side command.

Parameters:
  • output – Lines to display (help text, status, confirmations).

  • error – A failure or usage message; frontends style it as an error.

  • notice – An optional transient message (e.g. a toast).

  • handled – Whether the input was consumed as a command (the frontend must not forward it as a query).

classmethod fail(message: str) → CommandResult[source]

Return an error result carrying message.

classmethod info(message: str) → CommandResult[source]

Return a success result with message as a transient notice.

classmethod ok(*lines: str) → CommandResult[source]

Return a success result carrying lines.

klea_utils.commands.common.Klass

ui / client session-state run in the frontend; workflow runs in the graph; prompt is a frontend-expanded template.

Type:

Handling class

alias of Literal[‘ui’, ‘session-state’, ‘workflow’, ‘prompt’]

class klea_utils.commands.common.ParsedCommand(name: str, args: list[str] = <factory>, raw_args: str = '', error: str = '', verb: str = '')[source]

Bases: object

A parsed /command input.

Parameters:
  • name – The command name (lower-cased, without the leading slash); empty when the input had no name (see error).

  • args – Positional arguments (shlex-split, so quotes group).

  • raw_args – The argument string exactly as typed.

  • error – A parse error (missing name / malformed quoting), else "".

  • verb – The resolved subcommand name (set by resolve_subcommand()); "" for the bare form or a command without subcommands.

klea_utils.commands.common.Persists

none (nothing), checkpoint (graph state, no chat row), message (a real turn in the LLM’s action history).

Type:

What a command records

alias of Literal[‘none’, ‘checkpoint’, ‘message’]

klea_utils.commands.common.Side

server (graph/tools backend) or client (wherever the frontend process runs).

Type:

Execution host of a command

alias of Literal[‘server’, ‘client’]

class klea_utils.commands.common.Subcommand(name: str, summary: str, arg_hint: str = '')[source]

Bases: object

A first-class verb of a command (ADR-0047).

A command with subcommands is a small verb tree: the first argument selects the verb (see resolve_subcommand()), and the remaining arguments are the verb’s own. The command’s single handler branches on ParsedCommand.verb.

Parameters:
  • name – Canonical verb name (lower-case, without the leading slash).

  • summary – One-line description (shown by /help).

  • arg_hint – A short usage hint for the verb’s arguments.

klea_utils.commands.common.WhileStreaming

Whether the command may run while a chat has an active run.

alias of Literal[‘block’, ‘allow’]

klea_utils.commands.common.parse_command(text: str) → ParsedCommand | None[source]

Parse text as a /command, or return None.

Only a leading / as the literal first character counts (no leading whitespace). A leading // is an escaped literal slash and is not a command (use unescape_command() to recover the literal text). A command with no name, or with malformed quoting, is returned with ParsedCommand.error set rather than raising.

Arguments are split with the shared, platform-aware klea_utils.mcp.path_detect.split_arguments(), so a Windows path such as C:\Users\me\a.txt is one argument with its backslashes intact.

Parameters:

text – The user input.

Returns:

A ParsedCommand, or None when text is not a command.

klea_utils.commands.common.render_help(registry: CommandRegistry, capabilities: Iterable[str], name: str = '') → CommandResult[source]

Render /help output for a frontend with capabilities.

With name, show that command’s detail; otherwise list the available commands (filtered by capability). The output is Markdown: the command usages in inline code and, for a command detail, bold Aliases / Subcommands labels. A chat frontend then renders one command per line with a monospaced usage (plain newlines would collapse into a single paragraph).

Parameters:
  • registry – The command registry.

  • capabilities – The frontend’s capabilities.

  • name – An optional command name to describe.

Returns:

A CommandResult with the rendered lines.

klea_utils.commands.common.resolve_subcommand(command: Command, parsed: ParsedCommand) → ParsedCommand | str[source]

Resolve a command’s verb from parsed, or return an error message.

Commands without subcommands are returned unchanged. For a command with subcommands the first argument selects the verb:

  • an empty argument list resolves to the bare form (verb == "", the command’s default behaviour, e.g. a listing);

  • a known verb name returns a copy with verb set and args/raw_args reduced to the verb’s own arguments;

  • an unknown verb yields an error string naming the valid verbs.

Parameters:
  • command – The resolved command.

  • parsed – The parsed input.

Returns:

The updated ParsedCommand, or an error string.

klea_utils.commands.common.unescape_command(text: str) → str | None[source]

Return the literal input for an escaped command, or None.

A user types //foo to send the literal text /foo (a message, not a command); this strips one slash. The // must be the literal first characters (no leading whitespace). Returns None when text is not an escaped command.

Parameters:

text – The user input.

Returns:

The unescaped text (/foo), or None.

Graph

Graph-side support for the session-command framework (ADR-0047).

Holds the graph-command handler contract and its result type, plus the entry router that decides whether a query is a server-side command. The CommandNode itself lives in klea_utils.nodes.command.

See devdocs/system/session-commands.md; ADR-0047.

File: klea_utils/commands/graph.py

Copyright 2026 Ankur Sinha Author: Ankur Sinha <sanjay DOT ankur AT gmail DOT com>

klea_utils.commands.graph.GraphCommandHandler

(state, parsed) -> GraphCommandResult, or an awaitable of one. A handler may be async when it awaits an LLM or tool call (e.g. /compact); the command node awaits the result when needed.

Type:

A graph command handler

alias of Callable[[BaseModel, ParsedCommand], GraphCommandResult | Awaitable[GraphCommandResult]]

class klea_utils.commands.graph.GraphCommandResult(updates: dict[str, ~typing.Any]=<factory>, message: str = '', summary: str = '', details: dict[str, ~typing.Any]=<factory>, route: str = '')[source]

Bases: object

The outcome of a server-side command handler.

Parameters:
  • updates – State updates to merge (e.g. a new mode).

  • message – The user-facing reply (written to message_for_user).

  • summary – Inspect-event summary (defaults to message).

  • details – Inspect-event details.

  • route – A logical route to hand off to after the command’s state updates (written to the transient command_route); "" (default) ends the run. The app maps the route name to a graph node via the command node’s conditional edge (see devdocs/system/graph-routing.md).

klea_utils.commands.graph.command_query_router(state: BaseModel) → str[source]

Return "command" for a command query, else "continue".

The router makes a single decision: is the query syntactically a command (a leading /, with // escaping a literal slash) or a general query? The command node does the rest – validating the name, dispatching an executable command, or replying with a direct message for an unknown, client-side, or not-yet-implemented command.

Parameters:

state – The graph state (its query is inspected).

Returns:

"command" or "continue".

klea_utils.commands.graph.command_route_router(state: BaseModel) → str[source]

Return a command’s handoff route, or "" for a terminal command.

The command node writes the handler’s GraphCommandResult.route to the transient command_route state field; the app’s conditional edge maps this label to a graph node ("" -> END). Used as the path function of add_conditional_edges immediately after the command node, so a workflow command can hand off to another node (e.g. /compact -> the summarise node) before the run ends. See devdocs/system/graph-routing.md.

Parameters:

state – The graph state (its command_route is read).

Returns:

The route label ("" when the command is terminal).