THCLLM / DOSSIE_TECNICO_2026-07-25.md
Wilker
docs: adiciona dossiê técnico (movido do repo thc-cli, atualizado)
10e4b23
|
Raw
History Blame Contribute Delete
6.29 kB
# Dossiê Técnico — THC LLM (backend)
**Data desta revisão:** 2026-07-25
**Repositório:** ~/thcllm — https://github.com/wilkertoigo/thcllm (mirror) + https://huggingface.co/spaces/HulkToigo/THCLLM (produção)
**HEAD:** 01dc751 — sincronizado em `origin` (HF Space) e `github` (mirror)
> Nota de proveniência: este arquivo existiu por engano no repositório
> `thc-cli` (commit `53bc8e0`, removido em `d1402e6`). O conteúdo é
> especificamente sobre o backend `app.py` do thcllm, não sobre a CLI —
> por isso foi movido para cá.
---
## 1. Estado do git (verificado em 2026-07-25)
- Branch: `main`, working tree clean.
- `origin` (HF Space) e `github` (mirror) **agora sincronizados** — antes
desta revisão, `github` estava travado em `d07fc84` (bem atrás,
faltavam ~24 commits incluindo toda a Fase 6/MCP e todo o trabalho de
tool calling). Corrigido com `git push github main:main` (fast-forward
confirmado seguro via `git merge-base --is-ancestor`).
- HEAD atual: `01dc751 fix(app): reordena schemas de tools/Anthropic e
adiciona from __future__ import annotations`.
## 2. Tool calling — estado funcional
Implementado em dois formatos:
- **OpenAI-compatible** (`/v1/chat/completions`) — `tools` no formato
`{"type":"function","function":{...}}`.
- **Anthropic-compatible** (`/v1/messages`, `/v1/messages/stream`) —
`tools` no formato `{"name","description","input_schema"}`, usado pelo
Claude Code SDK.
**Confirmado em produção**: curl real contra
`https://hulktoigo-thcllm.hf.space/v1/messages` com uma tool `get_weather`
retornou corretamente bloco `tool_use` com `stop_reason: "tool_use"`.
Testado com `llama33-70b-groq` (backend groq).
### Schemas (ordem confirmada em app.py, linhas 416-490)
416: class ToolFunctionParameters(BaseModel)
422: class ToolFunction(BaseModel)
428: class Tool(BaseModel)
433: class AnthropicMessage(BaseModel)
438: class AnthropicTool(BaseModel)
462: class ChatRequest(BaseModel) # usa Tool
490: class AnthropicRequest(BaseModel) # usa AnthropicTool
`from __future__ import annotations` está na linha 1 do arquivo — blindagem
permanente contra `NameError` de forward-reference em type hints.
## 3. PENDÊNCIA ATIVA — regressão encontrada nesta revisão
`grep -n "não suporta tool calling" app.py` retorna **vazio**.
Os warnings de log que avisam quando `req.tools` é enviado para um backend
que não suporta tool calling (`transformers`, `gguf`, `kilo`) existiam no
commit `ce54b53` original, mas se perderam na sequência de
revert/fix (`5ccd423``dbb524c`) e nunca foram restaurados. O `dbb524c`
("restaura suporte a tool calling sem SyntaxError") só recuperou a lógica
de `openrouter`/`groq`/`mistral`/`gemini`, não esses três warnings.
**Impacto**: baixo (comportamental, não funcional — hoje `req.tools`
simplesmente é ignorado nesses backends sem log, o que dificulta debug se
alguém tentar usar tools num modelo local/kilo sem perceber que não tem
efeito).
**Ação recomendada**: reintroduzir os 3 `logger.warning(...)` nos blocos
`if backend == "transformers"`, `elif backend == "gguf"`, `elif backend ==
"kilo"` de `chat_completions` e `chat_completions_async` — ver diff de
`ce54b53` para o texto exato original.
## 4. Pendências herdadas do relatório anterior (ainda não verificadas)
1. Testar `/v1/chat/completions` (formato OpenAI) pós-fix `01dc751`.
2. Testar `/v1/messages/stream` (SSE) com cliente real — só o
não-streaming foi validado.
3. Testar tool calling com mistral, openrouter e gemini (só groq foi
confirmado, e antes dos 3 incidentes de produção desta sessão).
4. Reintroduzir os warnings de backend sem suporte (ver seção 3 acima).
## 5. Inconsistência de schema em config.py (observação, não corrigida)
`TEXT_MODELS` mistura dois esquemas de chave:
- Backends remotos (`kilo`, `openrouter`, `groq`, `mistral`, `gemini`):
usam `model_id`.
- Backends locais (`transformers`, `gguf`): usam `id` / `repo`+`file`.
Código que acesse `TEXT_MODELS[k]["model_id"]` genericamente pode gerar
`KeyError` para entradas locais. Não corrigido nesta revisão — só
documentado.
## 6. Estrutura do repositório
~/thcllm/
├── app.py (1838 linhas)
├── auth.py (103 linhas)
├── config.py (316 linhas)
├── models.py (141 linhas)
├── exceptions.py (46 linhas)
├── logger.py (14 linhas)
├── Dockerfile
├── requirements.txt
├── teste.py (stub: soma(a,b))
├── knowledge/, skills/
├── RELATORIO_TECNICO.md
├── SECURITY_INCIDENT_2026-07.md
└── DOSSIE_TECNICO_2026-07-25.md (este arquivo)
Sem pasta `tests/` — toda validação é manual (`py_compile`, `ast.parse`,
curl sequencial contra produção). O Space não tem CI.
## 7. Endpoints registrados
| método | path |
|---|---|
| GET | `/` |
| GET | `/login`, `/auth/google`, `/auth/callback`, `/logout`, `/me` |
| GET | `/v1/models`, `/v1/quota` |
| POST | `/v1/knowledge/reload` |
| POST | `/v1/chat/completions` |
| POST | `/v1/images/generations` |
| POST | `/v1/audio/generations` |
| POST | `/v1/audio/transcriptions` |
| GET | `/v1/transcription-models` |
| POST | `/v1/messages`, `/v1/messages/stream` |
`/docs`, `/redoc`, `/openapi.json` ficam desativados por padrão
(`THC_DEBUG=true` para habilitar).
## 8. Lições de processo desta revisão (2026-07-25)
- Documentação e código divergem com facilidade quando há dois repos git
separados (thc-cli / thcllm) apontando pra propósitos diferentes — um
dossiê técnico do thcllm foi commitado por engano no repo do thc-cli.
Antes de aceitar qualquer doc como verdade, confirmar com `git log`,
`grep`, `find` no código real.
- Remote secundário (`github` mirror do thcllm) pode ficar
silenciosamente desatualizado por múltiplos ciclos de trabalho — vale
checar `git log <remote>/main --oneline` periodicamente, não só o
remote principal de deploy.
- "Pendência antiga" registrada em relatório anterior (script de
desativação do huggingface_provider) já tinha sido resolvida por outro
caminho (comentário + import comentado em `providers/__init__.py` do
thc-cli, datado de 2026-07-25) — relatórios precisam ser revalidados
contra o código antes de serem tratados como lista de tarefas viva.