Files
Rui Valim 748879311a fix(ai): explain answers cut off by the token limit, and log AI and import runs (#16)
* fix(ai): leave room for a full answer and explain a cut-off one

max_tokens 300 cut answers off once the reason filled its 300-character
limit, and the run showed JSON.parse's position instead of the cause.
Raise it to 1024 and turn a parse failure into a readable error, naming
the token limit when the provider reports finish_reason length.

* feat(backend): add a shared logger with levels and greppable fields

One line per event with a level, a scope and key=value fields, or one
JSON object per line with LOG_FORMAT=json. LOG_LEVEL drops lines below
it. Errors log their message, status and code, plus the stack at error
level, and bearer tokens are redacted. Nothing outside it changes yet.

* feat(ai,import): log categorization and import runs through the logger

A bulk AI run kept only its last error in memory, so which models failed
and why was lost. Each provider answer it can't use now logs the model,
finish_reason, completion and reasoning tokens and the end of the answer;
each model's outcome and the run's start and totals are logged too.

Collection, Thingiverse, Printables, profile and zip imports dropped a
failed model without a trace; they now log it with its reason, plus the
job's start and totals. The links runner's console lines move to the
logger.

* fix(ai): read an answer wrapped in markdown or prose

Xiaomi MiMo ignores response_format and sent the object in bold,
`**{...}**`, which failed as not valid JSON although the answer was
complete. When the whole text doesn't parse, try the outermost braces.
2026-10-13 21:29:49 +02:00

24 lines
826 B
Bash

PUID=1000
PGID=1000
DATABASE_URL=postgresql://thingport:thingport@db:5432/thingport?schema=public
FILE_STORAGE=/app/storage
API_PORT=8000
PUBLIC_URL=
CORS_ORIGINS=
AUTH_SECRET=replace-with-random-secret
AUTH_TOKEN_TTL=43200
FLARESOLVERR_URL=
# Backend logs: debug, info, warn or error (default info). LOG_FORMAT=json writes one JSON object
# per line for a log collector; anything else writes plain text.
LOG_LEVEL=info
LOG_FORMAT=text
# Optional: leave SMTP_HOST blank to skip email verification on registration entirely (new
# accounts are verified and signed in immediately). Once set, these only seed the admin-editable
# Connections > SMTP settings on first boot -- later changes are saved via that page, not here.
SMTP_HOST=
SMTP_PORT=587
SMTP_SECURE=false
SMTP_USER=
SMTP_PASS=
SMTP_FROM=Thingport <no-reply@localhost>