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