Files
agent cc01845acf feat: llm_cli — CLI autocontenida para chatear con Claude
Un solo archivo (llm.py) que habla directo con la API de Anthropic Messages
usando el token OAuth que Claude Code guarda en ~/.claude/.credentials.json.
Sin servidor, sin arranque: chat interactivo con memoria, one-shot, pipe, y
bucle de tools propias (run_tool_loop). Empaqueta standalone la logica del
grupo claude-direct del registry para poder distribuirla (basta llm.py +
README.md, el receptor solo necesita httpx + Claude Code logueado).
2026-06-05 00:15:52 +02:00

91 lines
2.7 KiB
Markdown

# llm — chat con Claude desde la terminal
CLI mínima y autocontenida para hablar con Claude directamente desde la terminal.
Usa el token que **Claude Code ya guarda en tu máquina**, así que no hay nada que
configurar: instala `httpx`, ejecútala y escribe.
Un solo archivo (`llm.py`), respuesta en streaming, arranque instantáneo (no lanza
ningún proceso de fondo).
## Requisitos
- Python 3.9+
- `httpx``pip install httpx`
- **Claude Code instalado y con sesión iniciada** (para que exista
`~/.claude/.credentials.json`, de donde se lee el token automáticamente).
## Instalar
```bash
pip install httpx
# copia llm.py donde quieras; opcionalmente hazlo ejecutable:
chmod +x llm.py
```
## Usar
```bash
# Chat interactivo (con memoria de la conversación)
python3 llm.py
# Respuesta de una sola pregunta
python3 llm.py "que es un pseudo-terminal en una frase"
# Por pipe
echo "resume esto en 2 lineas: ..." | python3 llm.py
# Elegir modelo / system prompt
python3 llm.py --model claude-opus-4-8 --system "responde conciso" "explica los punteros"
```
### Comandos del chat interactivo
| Comando | Acción |
|---|---|
| `/model <id>` | Cambia de modelo (`claude-opus-4-8`, `claude-haiku-4-5-20251001`, ...) |
| `/system <texto>` | Fija un system prompt |
| `/reset` | Empieza una conversación nueva |
| `/exit` | Salir |
Modelo por defecto: `claude-haiku-4-5-20251001` (rápido). Usa `--model claude-opus-4-8`
para respuestas más potentes.
## Tus propias herramientas (tools)
`llm.py` incluye `run_tool_loop`, un bucle agéntico donde defines tus tools y el
código que las ejecuta. Tú controlas qué puede hacer el modelo:
```python
import llm
def get_time(inp):
import datetime
return {"now": datetime.datetime.now().isoformat()}
tools = [{
"name": "get_time",
"description": "Devuelve la fecha y hora actual",
"input_schema": {"type": "object", "properties": {}},
}]
res = llm.run_tool_loop(
messages=[{"role": "user", "content": "que hora es?"}],
tools=tools, dispatch={"get_time": get_time},
model="claude-haiku-4-5-20251001",
on_text=lambda d: print(d, end="", flush=True),
)
print("\n", res["final_text"])
```
El modelo pedirá la tool, tu función la ejecuta, el resultado vuelve al modelo y
responde. Añade las tools que quieras (consultar una base de datos, llamar a una
API, leer un archivo...).
## API del módulo
| Función | Para qué |
|---|---|
| `stream_messages(messages, model, system, tools, max_tokens, token)` | Stream crudo de eventos (text / tool_use / done / error) |
| `run_tool_loop(messages, tools, dispatch, ...)` | Bucle agéntico con tus tools |
| `load_oauth_token()` | Lee el token de `~/.claude/.credentials.json` (refresh best-effort) |