commit 739d31d59b2bcafd851301b9ec303d8dd421858b
parent 93d419ec0765d499ad28e463bbc2b034bdbcbc39
Author: Pablo Murad <pblmrd@gmail.com>
Date: Sat, 9 May 2026 22:27:31 -0300
remodelation
Diffstat:
7 files changed, 10 insertions(+), 61 deletions(-)
diff --git a/.env.example b/.env.example
@@ -39,7 +39,7 @@ OPENAI_API_KEY=
# Preset global e sumarizacao hierarquica (textos longos)
# ---------------------------------------------------------------------------
-# Preset padrao quando nao se envia quality_preset na API/Web: economico | equilibrado | maximo.
+# Preset global (unico controlo): economico | equilibrado | maximo.
# Mapeia defaults de chat, transcricao e reasoning (sobrescritos por OPENAI_* quando definidos).
# LAZIER_QUALITY_PRESET=equilibrado
diff --git a/README.md b/README.md
@@ -34,7 +34,7 @@ Defaults seguros já vêm configurados; sobrescreva apenas se quiser mudar.
| `OPENAI_ENABLE_SMART_SUMMARY` | `true` | Liga/desliga o sumário estruturado (TL;DR, pontos-chave, decisões, ações, tópicos, citações, perguntas em aberto). Quando `false`, mantém o sumário textual legado. |
| `OPENAI_ENABLE_CHAPTERS` | `true` | Liga/desliga geração de capítulos com timestamps em áudio/vídeo. |
| `OPENAI_REASONING_EFFORT` | `medium` | Esforço de raciocínio para modelos da família `gpt-5`/`o-series`. Valores: `minimal`, `low`, `medium`, `high`. |
-| `LAZIER_QUALITY_PRESET` | `equilibrado` | Preset global `economico` / `equilibrado` / `maximo` → defaults de chat, transcrição e `reasoning` (sobrescritos por `OPENAI_*` quando definidos). Na Web/API pode enviar-se `quality_preset` por pedido. |
+| `LAZIER_QUALITY_PRESET` | `equilibrado` | Preset global `economico` / `equilibrado` / `maximo` → defaults de chat, transcrição e `reasoning` (sobrescritos por `OPENAI_*` quando definidos). Defina apenas no `.env`; não há seleção na WebGUI nem campo por pedido na API. |
| `LAZIER_SUMMARY_HIERARCHICAL` | `true` | Acima de `LAZIER_SUMMARY_DIRECT_MAX_CHARS`, o sumário inteligente usa map-reduce com chunks e overlap em vez de um único passe sobre o texto completo. |
| `LAZIER_SUMMARY_DIRECT_MAX_CHARS` | `32000` | Limiar (caracteres) para ativar sumarização hierárquica. |
| `LAZIER_SUMMARY_MAP_CHUNK_CHARS` | `14000` | Tamanho alvo de cada chunk no map. |
@@ -102,8 +102,6 @@ lazier transcribe "https://www.youtube.com/watch?v=VIDEO_ID"
lazier summarize document.pdf
lazier summarize "https://example.com/artigo" --format md
lazier summarize aula.mp3 --gpt-model gpt-5 --reasoning high
-lazier summarize documento.pdf --quality-preset economico
-
# Desligar features novas explicitamente
lazier summarize aula.mp3 --no-smart --no-chapters
@@ -121,7 +119,8 @@ Flags principais:
- `--smart/--no-smart` força ligar/desligar o sumário estruturado.
- `--chapters/--no-chapters` força ligar/desligar capítulos com timestamps.
- `--reasoning {minimal,low,medium,high}` ajusta o esforço de raciocínio para modelos `gpt-5`/`o-series`.
-- `--quality-preset {economico,equilibrado,maximo}` aplica o pacote de modelos e reasoning desse preset só nesse comando (equivalente ao campo da WebGUI).
+
+O pacote custo/qualidade (`economico` / `equilibrado` / `maximo`) vem só de `LAZIER_QUALITY_PRESET` no `.env` (`lazier config` mostra o valor atual).
### WebGUI
diff --git a/lazier/api/routes.py b/lazier/api/routes.py
@@ -42,7 +42,6 @@ class ProcessRequest(BaseModel):
summarize: Optional[bool] = None
chat_model: Optional[str] = None
transcribe_model: Optional[str] = None
- quality_preset: Optional[str] = None
smart: Optional[bool] = None
chapters: Optional[bool] = None
@@ -103,15 +102,12 @@ def _build_overrides(
transcribe_model: Optional[str] = None,
smart: Optional[bool] = None,
chapters: Optional[bool] = None,
- quality_preset: Optional[str] = None,
) -> dict:
overrides: dict = {}
if chat_model:
overrides["chat_model"] = chat_model
if transcribe_model:
overrides["transcribe_model"] = transcribe_model
- if quality_preset:
- overrides["quality_preset"] = quality_preset.strip().lower()
if smart is not None:
overrides["smart"] = smart
if chapters is not None:
@@ -175,7 +171,6 @@ def _process_job(job_id: str) -> None:
gpt_model=overrides.get("chat_model"),
use_smart_summary=overrides.get("smart"),
use_chapters=overrides.get("chapters"),
- quality_preset=overrides.get("quality_preset"),
trace_job_id=job_id,
run_id=job_id,
source_name=job.get("source_name"),
@@ -294,7 +289,6 @@ async def upload_files(
summarize: Optional[bool] = Form(None),
chat_model: Optional[str] = Form(None),
transcribe_model: Optional[str] = Form(None),
- quality_preset: Optional[str] = Form(None),
smart: Optional[bool] = Form(None),
chapters: Optional[bool] = Form(None),
):
@@ -306,7 +300,6 @@ async def upload_files(
transcribe_model=transcribe_model,
smart=smart,
chapters=chapters,
- quality_preset=quality_preset,
)
jobs = []
@@ -363,7 +356,6 @@ async def process_url(request: ProcessRequest, background_tasks: BackgroundTasks
transcribe_model=request.transcribe_model,
smart=request.smart,
chapters=request.chapters,
- quality_preset=request.quality_preset,
)
job = _create_job(
diff --git a/lazier/cli.py b/lazier/cli.py
@@ -50,7 +50,6 @@ def _run_mode(
smart: Optional[bool] = None,
chapters: Optional[bool] = None,
reasoning: Optional[str] = None,
- quality_preset: Optional[str] = None,
):
if reasoning:
os.environ["OPENAI_REASONING_EFFORT"] = reasoning
@@ -91,7 +90,6 @@ def _run_mode(
gpt_model=gpt_model,
use_smart_summary=smart,
use_chapters=chapters,
- quality_preset=quality_preset,
output_path=output,
run_id=str(uuid.uuid4()),
source_name=Path(input_path).name if not input_path.startswith(("http://", "https://")) else input_path,
@@ -166,13 +164,6 @@ def _model_options(func):
default=None,
help="Modelo de transcricao (default: OPENAI_TRANSCRIBE_MODEL ou gpt-4o-mini-transcribe)",
)(func)
- func = click.option(
- "--quality-preset",
- "quality_preset",
- type=click.Choice(["economico", "equilibrado", "maximo"]),
- default=None,
- help="Preset custo/qualidade para este comando (modelos + reasoning). Sobrescreve LAZIER_QUALITY_PRESET.",
- )(func)
return func
@@ -190,7 +181,6 @@ def transcribe(
smart_flag: Optional[bool],
chapters_flag: Optional[bool],
reasoning: Optional[str],
- quality_preset: Optional[str],
):
"""Transcreve ou converte o conteudo para portugues."""
_run_mode(
@@ -203,7 +193,6 @@ def transcribe(
smart=smart_flag,
chapters=chapters_flag,
reasoning=reasoning,
- quality_preset=quality_preset,
)
@@ -221,7 +210,6 @@ def summarize(
smart_flag: Optional[bool],
chapters_flag: Optional[bool],
reasoning: Optional[str],
- quality_preset: Optional[str],
):
"""Gera um sumario em portugues do conteudo informado."""
_run_mode(
@@ -234,7 +222,6 @@ def summarize(
smart=smart_flag,
chapters=chapters_flag,
reasoning=reasoning,
- quality_preset=quality_preset,
)
diff --git a/lazier/core/processing.py b/lazier/core/processing.py
@@ -23,7 +23,7 @@ from typing import Any, Callable, Dict, List, Optional, Tuple
from .cache import calculate_file_hash, calculate_string_hash, calculate_url_hash, get_cache_manager
from .chapters import build_chapters
-from .config import VALID_REASONING_EFFORTS, get_model_config, get_preset_model_defaults
+from .config import get_model_config
from .content_type import detect_content_type
from .exceptions import MusicContentError
from .jobs import build_job_artifact_path, get_outputs_root
@@ -85,30 +85,16 @@ def _resolve_runtime(
gpt_model: Optional[str],
use_smart_summary: Optional[bool],
use_chapters: Optional[bool],
- *,
- quality_preset: Optional[str] = None,
) -> Dict[str, Any]:
config = get_model_config()
- if quality_preset:
- pd = get_preset_model_defaults(quality_preset)
- transcribe_model = model or pd["transcribe_model"]
- chat_model = gpt_model or pd["chat_model"]
- reasoning_effort = pd["reasoning_effort"]
- if reasoning_effort not in VALID_REASONING_EFFORTS:
- reasoning_effort = config.reasoning_effort
- else:
- transcribe_model = model or config.transcribe_model
- chat_model = gpt_model or config.chat_model
- reasoning_effort = config.reasoning_effort
-
return {
- "transcribe_model": transcribe_model,
+ "transcribe_model": model or config.transcribe_model,
"transcribe_timestamps_model": config.transcribe_timestamps_model,
- "chat_model": chat_model,
+ "chat_model": gpt_model or config.chat_model,
"smart_summary": config.enable_smart_summary if use_smart_summary is None else use_smart_summary,
"chapters_enabled": config.enable_chapters if use_chapters is None else use_chapters,
- "reasoning_effort": reasoning_effort,
- "quality_preset": quality_preset or config.quality_preset,
+ "reasoning_effort": config.reasoning_effort,
+ "quality_preset": config.quality_preset,
}
@@ -344,7 +330,6 @@ def process_source(
gpt_model: Optional[str] = None,
use_smart_summary: Optional[bool] = None,
use_chapters: Optional[bool] = None,
- quality_preset: Optional[str] = None,
trace_job_id: Optional[str] = None,
output_path: Optional[str] = None,
output_root: Optional[Path] = None,
@@ -363,7 +348,6 @@ def process_source(
gpt_model,
use_smart_summary,
use_chapters,
- quality_preset=quality_preset,
)
t_pipeline = time.perf_counter()
_notify(progress_callback, 5, "processing", "Validando entrada...")
diff --git a/lazier/web/templates/index.html b/lazier/web/templates/index.html
@@ -347,15 +347,6 @@
<label for="formatSelect">Formato</label>
<select id="formatSelect"><option value="docx">DOCX</option><option value="txt">TXT</option><option value="md">Markdown</option><option value="json">JSON</option><option value="pdf">PDF</option></select>
</div>
- <div class="field">
- <label for="presetSelect">Qualidade</label>
- <select id="presetSelect">
- <option value="">Predefinição (.env)</option>
- <option value="economico">Económico</option>
- <option value="equilibrado">Equilibrado</option>
- <option value="maximo">Máximo</option>
- </select>
- </div>
<button class="btn" id="processBtn" onclick="processFiles()">Processar</button>
</div>
</div>
@@ -453,14 +444,12 @@
async function processFiles() {
const button = document.getElementById('processBtn');
const format = document.getElementById('formatSelect').value;
- const preset = document.getElementById('presetSelect').value;
const url = document.getElementById('urlInput').value.trim();
button.disabled = true;
button.textContent = 'A processar…';
try {
if (url) {
const payload = { url, format, mode: processingMode };
- if (preset) payload.quality_preset = preset;
const response = await fetch('/api/process', { method:'POST', headers:{'Content-Type':'application/json'}, body:JSON.stringify(payload), credentials:'include' });
const data = await response.json();
if (!response.ok) throw new Error(data.detail || 'Falha ao processar URL');
@@ -471,7 +460,6 @@
selectedFiles.forEach((file) => formData.append('files', file));
formData.append('format', format);
formData.append('mode', processingMode);
- if (preset) formData.append('quality_preset', preset);
const response = await fetch('/api/upload', { method:'POST', body:formData, credentials:'include' });
const data = await response.json();
if (!response.ok) throw new Error(data.detail || 'Falha ao enviar ficheiros');
diff --git a/tests/test_api.py b/tests/test_api.py
@@ -170,7 +170,6 @@ class ApiTests(unittest.TestCase):
"mode": "summarize",
"chat_model": "gpt-5",
"transcribe_model": "gpt-4o-transcribe",
- "quality_preset": "economico",
"smart": True,
"chapters": True,
},
@@ -182,7 +181,7 @@ class ApiTests(unittest.TestCase):
kwargs = mock_process.call_args.kwargs
self.assertEqual(kwargs.get("gpt_model"), "gpt-5")
self.assertEqual(kwargs.get("model"), "gpt-4o-transcribe")
- self.assertEqual(kwargs.get("quality_preset"), "economico")
+ self.assertIsNone(kwargs.get("quality_preset"))
self.assertEqual(kwargs.get("trace_job_id"), job_id)
self.assertTrue(kwargs.get("use_smart_summary"))
self.assertTrue(kwargs.get("use_chapters"))