Agent help
Machine-readable, agent-oriented --help: the AGENT_HELP trigger,
--help-agents, and print_agent_help/describe.
duho.agenthelp
Agent-oriented help: a detailed, machine-readable description of a CLI.
Where the normal --help renders a compact, human-facing usage block, this
module emits a complete, structured (JSON) description of a duho CLI --
enough for an AI agent (or any tool) to understand the whole command surface in
one shot: every subcommand, each option with its type/default/required/
repeatable flags, positionals, per-field environment-variable bindings,
mutually-exclusive conflict groups, examples, and exit codes.
Two triggers, both wired up by duho.args:
- The
AGENT_HELP/AGENTS_HELPenvironment variables (always on, zero-config; either truthy triggers). When one is set to a truthy value, the ordinary-h/--helpaction emits this agent description instead of the human help. Nothing changes for a normal--helpunless one of these env vars is deliberately set, so default human behavior is byte-identical. Both defaults are replaced (no aliasing) by an explicit_agent_help_env_class attribute naming a single variable. - An opt-in
--help-agentsflag. Set_agent_help_ = Trueon the CLI root to add a discoverable flag that always emits the agent description, regardless of the environment.
Built on duho's existing introspection. The description is produced by
walking the built argparse parser tree (so injected flags -- --version,
--print-completion -- and the whole subcommand tree are included) and
enriching each command with duho's own field metadata (:func:get_clsargs /
:class:ClsArgDeclaration and the per-field :class:ArgumentBuilder) looked up
via the _duho_cls_ handle _initparser_ stashes on every parser. A
subparser with no duho class behind it (e.g. a duho.app module command) is
still described from its argparse actions alone -- just without the duho-only
metadata (env bindings, conflicts) that has no argparse equivalent.
This mirrors :mod:duho.completion: one parser-tree walk that produces plain
data, kept out of the import duho hot path (duho.args imports it lazily,
only when an agent-help trigger actually fires).
DEFAULT_ENV = 'AGENT_HELP'
module-attribute
DEFAULT_ENVS = (DEFAULT_ENV, 'AGENTS_HELP')
module-attribute
SCHEMA = 'duho/agent-help@1'
module-attribute
__all__ = ['SCHEMA', 'DEFAULT_ENV', 'DEFAULT_ENVS', 'agent_help_requested', 'describe', 'describe_parser', 'render', 'print_agent_help']
module-attribute
agent_help_requested(env_name=None, environ=None)
True when a trigger env var is set truthy.
env_name explicit (e.g. an app's _agent_help_env_ override) checks
only that one variable -- no aliasing once a caller names their own.
env_name left None checks every name in :data:DEFAULT_ENVS
(AGENT_HELP and AGENTS_HELP); either truthy triggers agent help.
environ defaults to os.environ (injectable for tests). An unset
variable is False; a set variable is True unless its stripped/lowercased
value is one of :data:duho.text.BOOL_FALSE.
Source code in src/duho/agenthelp.py
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | |
describe(cls, argv=None)
Build cls's parser and return its agent-help document (a dict).
Standalone counterpart to the --help-agents flag / AGENT_HELP trigger:
builds the parser tree fresh and describes it, independent of whether either
trigger is wired up. argv is accepted for signature symmetry with the
other entry points and currently unused (the description is static).
Source code in src/duho/agenthelp.py
664 665 666 667 668 669 670 671 672 673 | |
describe_parser(parser, *, root=False, root_cls=None, name=None, aliases=None)
Describe one built ArgumentParser (and its subtree) as plain data.
root adds the document-level keys (schema tag, version, exit codes,
examples). name/aliases label a subcommand within its parent.
Source code in src/duho/agenthelp.py
552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 | |
print_agent_help(cls, file=None)
Print cls's agent-help JSON document to file (default stdout).
Written via :func:duho._compat.write_machine: raw UTF-8
bytes with LF-only newlines, bypassing file's text-mode encoding and
newline translation, the same writer duho.args's agent-help actions use
-- so this standalone entry point and the -h/--help-agents
triggers behave identically on any host encoding.
Source code in src/duho/agenthelp.py
697 698 699 700 701 702 703 704 705 706 | |
render(spec)
Serialise an agent-help document to a JSON string (trailing newline).
json is imported lazily (not at module top) so import duho never pays
its import cost -- only actually rendering an agent-help document does. This
keeps the framework's zero-eager-json contract (see
tests/test_config_json.py::test_json_import_is_lazy).
ensure_ascii=True: a non-ASCII character (an arrow in a
docstring, a Latin-1 accent) written through a piped Windows stdout's
text layer raises UnicodeEncodeError (empty output, exit 1) or comes
out console-code-page-encoded instead of UTF-8. ASCII-escaping every
non-ASCII character survives any stream encoding and decodes back to the
identical string, at the cost of a few extra bytes and less readable raw
JSON -- irrelevant for a document meant to be parsed, not read.
Source code in src/duho/agenthelp.py
676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 | |