read.markets/app/services
Giorgio Gilestro 48f022b71b i18n: stop truncating IT translations + localise the chat sidebar
Three connected fixes after the user spotted the 2026-05-28 IT log
cutting off mid-sentence:

1. translation: bump max_tokens 4000 → 8000.
   call_llm()'s default cap was 4000, which is what the English log
   generator itself uses as its ceiling. Italian expands roughly 15-25 %
   over English in tokens, so any near-cap English source produced an
   IT translation that hit finish_reason=length and returned a
   truncated body — silently, because _call_provider() only raises when
   content is fully empty. The strategic_log_translations table has
   dozens of rows where completion_tokens landed at exactly 4000 with
   content well under half the source length. 8000 gives ample
   headroom for any of the five LANGUAGES we ship (en/it/es/fr/de).

2. log.html: localise the chat sidebar strings.
   user_lang was already passed into the template by pages.py, so an
   inline {% if user_lang == 'it' %} keeps it simple. Covers the
   "Ask Cassandra" title, the "grounded on…" hint, the helper lede,
   the textarea placeholder, and the Send button label.

3. chat endpoint: append respond_in_clause(user.lang) to the system
   prompt. The chat conversation can now happen in IT — the model's
   first reply lands in the right language even when the user's first
   turn is short.

scripts/backfill_truncated_translations.py: one-off cleanup utility.
Scans strategic_log_translations for rows whose translated content is
< 70 % of the English source (the truncation signal — IT *expands*
beyond English, so a shorter translation is always suspect), deletes
them, and re-translates via the now-uncapped service. Supports --date,
--since, --all and --dry-run. The 2026-05-28 fan-out has already been
re-translated (13/13 rows). Other historical dates still hold older
truncations; the user can decide whether to backfill those (the script
is idempotent).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-29 11:44:41 +02:00
..
__init__.py
access.py docs: drop Phase D.x markers now that the referral loop is closed 2026-05-26 23:09:39 +02:00
auth_service.py
cadence.py
csv_import.py cleanup: drop stale tombstones and dead config fields 2026-05-27 19:25:33 +02:00
digest_email.py email: split digest renderer to digest_email.py 2026-05-27 21:33:06 +02:00
email_service.py email: split digest renderer to digest_email.py 2026-05-27 21:33:06 +02:00
feeds_bootstrap.py
fx.py
glossary.py css: split cassandra.css into per-section files 2026-05-28 12:31:29 +02:00
i18n.py i18n: add LANGUAGES, ACTIVE_LANGUAGES, respond_in_clause helper 2026-05-27 16:46:32 +02:00
instrument_map.py
llm_csv_parser.py models: align translation column naming + add token counts 2026-05-27 21:18:29 +02:00
llm_prompts.py openrouter: split into llm_prompts (prompt engineering) + transport 2026-05-27 21:27:23 +02:00
market.py
markets.py
news.py
news_tagging.py
openrouter.py llm: estimate cost from tokens when provider omits it 2026-05-28 12:36:55 +02:00
otp_service.py
portfolio_analysis.py openrouter: split into llm_prompts (prompt engineering) + transport 2026-05-27 21:27:23 +02:00
portfolio_sync.py
referral_service.py referrals: close D.3 — both parties get 45 days credit on conversion 2026-05-26 23:05:29 +02:00
ticker_universe.py
trading212.py
translation.py i18n: stop truncating IT translations + localise the chat sidebar 2026-05-29 11:44:41 +02:00