feat: Add .env.example configuration file and integrate Redis service into Docker Compose for improved task management. Update desktop application to support document indexing and extraction workflows, enhancing user experience with a new extraction wizard and stepper components. Revise README and documentation for clarity on setup and usage.
This commit is contained in:
@@ -110,6 +110,60 @@ class Estimator:
|
||||
def _accumulate_usage(self, agg, new_usage):
|
||||
accumulate_usage(agg, new_usage)
|
||||
|
||||
def estimate_from_file(
|
||||
self,
|
||||
file_path: str,
|
||||
doc_count: int = 1,
|
||||
selected_paths: Optional[List[str]] = None,
|
||||
tiff_page_range: Optional[tuple] = None,
|
||||
model: Optional[str] = None,
|
||||
) -> Dict[str, Any]:
|
||||
"""Estima tokens y costos procesando un único archivo subido desde el cliente.
|
||||
|
||||
Si `model` se especifica y es distinto al modelo actual del extractor,
|
||||
crea un extractor temporal con ese modelo para obtener el uso real de tokens.
|
||||
"""
|
||||
from api.desktop_ingest import _service_for_model
|
||||
|
||||
service = _service_for_model(self.service, model)
|
||||
prof = get_profile('invoice')
|
||||
paths = selected_paths or []
|
||||
prompt = PromptBuilder.build(paths, {}, profile_name=prof.get('name', 'invoice'))
|
||||
|
||||
data, usage_ext = service.extract_full_from_pdf(
|
||||
file_path,
|
||||
instruction=prompt,
|
||||
tiff_page_range=tiff_page_range,
|
||||
)
|
||||
if isinstance(data, dict):
|
||||
data['radicado'] = 'sample'
|
||||
else:
|
||||
data = {"radicado": 'sample', "data": data}
|
||||
|
||||
norm = normalize_to_schema(data, paths=paths, profile_name=prof.get('name', 'invoice'))
|
||||
usage_norm = None
|
||||
if isinstance(norm, dict):
|
||||
usage_norm = norm.get("_usage")
|
||||
|
||||
result = self._build_result(usage_ext, usage_norm, doc_count, 'sample')
|
||||
|
||||
# Enriquecer con modelo efectivo y conteo de páginas para el frontend
|
||||
effective_model = model or getattr(service.extractor, 'model', None) or getattr(self.service.extractor, 'model', None)
|
||||
result['extractor_model'] = effective_model
|
||||
result['normalizer_model'] = settings.api.normalizer_model or 'gpt-5.4-mini'
|
||||
|
||||
# Estimar numero de paginas a partir de prompt_tokens de imagen:
|
||||
# GPT-4o cobra ~85 tok base + ~170 tok por tile 512x512.
|
||||
# Una A4 a 150 DPI (~1240x1754) genera ~6 tiles → ~1105 tokens.
|
||||
# Aproximamos: pages = max(1, round(image_tokens / 1000))
|
||||
prompt_tokens = int((usage_ext or {}).get('prompt_tokens') or 0)
|
||||
text_prompt_est = len(prompt) // 4 # 1 token ≈ 4 chars
|
||||
image_tokens_est = max(0, prompt_tokens - text_prompt_est)
|
||||
pages_est = max(1, round(image_tokens_est / 1000))
|
||||
result['pages_per_doc'] = pages_est
|
||||
|
||||
return result
|
||||
|
||||
def _build_result(self, usage_ext, usage_norm, total_docs, first_radicado):
|
||||
model_ext = getattr(self.service.extractor, "model", None)
|
||||
cost_ext = compute_cost_from_usage(usage_ext, "extract", model=model_ext)
|
||||
|
||||
Reference in New Issue
Block a user