Skip to content

Dynamic CLI Dispatch

AgentV uses a Unified Functional Dispatcher to manage its expansive CLI interface. This architecture separates the CLI Parsing (handled by argparse) from the Internal Handler Execution. This decoupling allows for modular extensions, plugin-injected commands, and exhaustive automated testing.

The eval_runner.cli module serves as the central entry point. Instead of a monolithic if/elif block, the harness uses argparse subparsers combined with the set_defaults(func=...) pattern to map commands to their implementation functions.

Commands are registered during the eval_runner.cli.main initialization:

# Core command registration (eval_runner/cli.py)
evaluate_parser = subparsers.add_parser("evaluate", help="Batch process scenarios")
evaluate_parser.set_defaults(func=_dispatch_evaluation)
console_parser = subparsers.add_parser("console", help="Launch the Visual Debugger")
console_parser.set_defaults(func=_dispatch_console)

When you run agentv <command>, the harness:

  1. Parses global arguments (e.g., --debug).
  2. Identifies the target sub-parser and its associated func default.
  3. Dispatches the execution by calling args.func(args), passing the parsed arguments directly to the handler.

To ensure industrial-grade reliability, AgentV enforces an Exhaustive Testing Standard for the CLI layer. Every registered command must have a corresponding unit test that verifies:

  1. Successful Dispatch: The command reaches the handler with the correct parameters.
  2. Error Handling: Invalid arguments or environment failures are caught and reported with meaningful exit codes.
  3. Namespace Integrity: Plugin commands (registered via on_register_commands) do not collide with core engine commands.

We use unittest.mock to verify that the CLI correctly routes to the eval_runner engine handlers.

def test_cli_routing_evaluate(self):
with patch("eval_runner.cli._dispatch_evaluation") as mock_handler:
# Simulate 'agentv evaluate --path my_path'
main(["evaluate", "--path", "my_path"])
mock_handler.assert_called_once()

Plugins can inject their own commands into the agentv namespace while maintaining security.

  1. Scoping: Plugin commands are automatically namespaced to prevent hijacking core functions.
  2. Lifecycle: Documentation for plugin commands is dynamically generated by the sub-parser registry, ensuring that agentv --help is always accurate, regardless of which plugins are active.