# 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 /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.