cc01845acf
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).
91 lines
2.7 KiB
Markdown
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) |
|