Expose tools as lightweight CLI commands for LLM agents
Project description
โจ What is this?
agenticli converts functions, classes, and schema-based tools into a stable CLI semantic layer. Instead of flooding prompts with large schemas, LLMs just output a single command string.
๐ก Philosophy: bash is everything. The command string is the most stable, restrained, and observable intermediate representation between LLMs and tool systems.
๐ฏ When to use agenticli?
| Scenario | agenticli helps? |
|---|---|
| You have many tools/functions and need a unified interface for LLMs | โ |
| You don't want massive schemas injected into prompts | โ |
You want models to see minimal hints, expanding via --help |
โ |
| You want validation, help, errors, and lifecycle in one place | โ |
๐ Quick Start
pip install agenticli
from typing import Annotated
from agenticli import CommandRegistry, Option, command, command_group
@command_group(name="calc", description="Calculator commands")
class Calc:
@command(name="add", description="Add numbers")
def add(self,
values: Annotated[list[float], Option(positional=True, value_name="n")]
) -> dict:
return {"result": sum(values)}
registry = CommandRegistry()
registry.register(Calc)
# LLM sees this minimal prompt:
print(registry.get_llm_prompt())
# -> You can use the following CLI commands:
# calc: Calculator commands
# Execute:
registry.parse_and_execute("calc add 10 20 30")
# -> {"result": 60.0}
๐๏ธ Core Architecture
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ LLM Output โ
โ "calc add 10 20 30" โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ CommandRegistry โ
โ โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโโโ โ
โ โ Parse โโโถโ Validate โโโถโ Execute โโโถโ Result โ โ
โ โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโโโ โ
โ โ
โ โข Command hit/matching โข Lifecycle callbacks โ
โ โข Help generation โข Error with suggestions โ
โ โข Argument injection โข Chain execution (&&, ||, ;) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Your Functions / Tools โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
๐ Key Features
| Feature | Description |
|---|---|
| ๐ Multiple Registrations | Decorators, class inheritance, dataclass, Pydantic, schema wrapping |
| โก CLI Parsing | Positional args, --option value, -o value, --opt=val, flags |
| ๐ Smart Help | Auto-generated usage, help text, LLM prompts |
| โ Validation | Type coercion, requires/excludes, enums |
| ๐ก Suggestions | "Did you mean X?" for unknown commands/options/enums |
| ๐ Lifecycle Hooks | before_execute, after_execute, on_error |
| ๐ Internal Injection | Hide callbacks/state from CLI, inject at runtime |
| ๐ Chain Execution | `cmd1 && cmd2 |
๐ Registration Patterns
1๏ธโฃ Decorator (Most Common)
from typing import Annotated
from agenticli import command, Option
@command(name="ls", description="List directory")
def ls(
path: Annotated[str, Option(short='p', description="Directory path")],
verbose: Annotated[bool, Option(short='v')] = False,
) -> list[str]:
import os
return os.listdir(path)
2๏ธโฃ Command Group
from agenticli import command_group, command
@command_group(name="db", description="Database operations")
class Database:
@command(description="Create database")
def create(self, name: str) -> None: ...
@command(description="Drop database")
def drop(self, name: str) -> None: ...
3๏ธโฃ Wrap Existing Tools
from agenticli import wrap_tool
class MyTool:
name = "my_tool"
description = "Does something"
parameters = {"type": "object", "properties": {"x": {"type": "int"}}}
async def execute(self, **kwargs): return kwargs
registry.register_spec(wrap_tool(MyTool()))
4๏ธโฃ Class Inheritance
from agenticli import CliCommand, CommandRegistry
class AddCommand(CliCommand):
name = "add"
description = "Add numbers"
args_model = AddArgs
async def run(self, **kwargs) -> dict:
return {"result": sum(kwargs["values"])}
registry.register(AddCommand())
๐ค LLM Integration
Minimal Tool Schema
Expose only one exec tool to the LLM:
from agenticli import ExecTool
exec_tool = ExecTool(callback=registry.parse_and_execute)
# Tool schema: {name: "exec", params: {command: string, timeout?: int}}
Lifecycle Callbacks
from agenticli import ExecutionCallbacks
def on_error(ctx):
print(f"Error: {ctx.error.code} - {ctx.error.message}")
registry = CommandRegistry(
callbacks=ExecutionCallbacks(on_error=on_error)
)
Internal Parameter Injection
from typing import Annotated
from agenticli import Callback, State, command
@command(name="process")
def process(
data: list[str],
cache: Annotated[object, State(factory=lambda ctx: load_cache())] = None,
):
# cache is injected automatically, hidden from CLI
return cached_transform(data, cache)
๐ฆ Stable API
# Core
CommandRegistry
CommandRegistry.register(target)
CommandRegistry.register_spec(spec)
CommandRegistry.execute(command_str)
CommandRegistry.parse_and_execute(command_str)
CommandRegistry.render_help(command)
CommandRegistry.get_llm_prompt(detailed=False)
# Decorators
command(name=None, description="", aliases=None, hidden=False, deprecated=None)
command_group(name, description)
# Helpers
CliCommand
wrap_tool(tool)
command_from_model(name, model, handler)
command_from_method(name, target, method_name)
Option
Injected / Callback / State
ExecutionCallbacks
ExecTool
๐ก Examples
See example/demo.py for a complete calc system with OpenAI/Anthropic integration:
pip install "agenticli[examples]"
python -m example.demo --provider openai
python -m example.demo --provider anthropic
๐ Documentation
| Language | Link |
|---|---|
| ๐บ๐ธ English | docs/index_en.md |
| ๐จ๐ณ ไธญๆ | docs/index_zh.md |
๐ License
MIT
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file agenticli-0.1.2.tar.gz.
File metadata
- Download URL: agenticli-0.1.2.tar.gz
- Upload date:
- Size: 67.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.9 {"installer":{"name":"uv","version":"0.9.9"},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4d651ccd179ae34a08f2a599cc65462712d45a68df47332fa3778ef4535bff69
|
|
| MD5 |
15f09d694c8eba629d47df63de157189
|
|
| BLAKE2b-256 |
b19f62ca6f6b37b73095db1272db544f8e5ab3e472150974b371fb6254e22d0e
|
File details
Details for the file agenticli-0.1.2-py3-none-any.whl.
File metadata
- Download URL: agenticli-0.1.2-py3-none-any.whl
- Upload date:
- Size: 31.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.9 {"installer":{"name":"uv","version":"0.9.9"},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5857a483845d0e94ac1adcb2c297db204936e10035aac0cf18b1fe404ab6dc51
|
|
| MD5 |
81c69262a8bfcb6c1296f8fb0cffa791
|
|
| BLAKE2b-256 |
1ecff79073b31f8a2a9f512c2a5e97922fd983505a4fce99950b2478e253bf86
|