0
0
Fork 0
mirror of https://github.com/discourse/discourse.git synced 2026-08-11 02:59:07 +08:00
discourse/plugins
Rafael dos Santos Silva c10cce7b72
FIX: Recover AI structured output when models emit stray prefixes (#41745)
Follow-up to #41716, found by live-testing the new parsing chain against
locally configured vLLM models (Jolteon/CDCK MoM, DeepSeek V4 Flash,
Qwen3.6 35B).

## The bug

DeepSeek V4 Flash reproducibly prefixes its structured output with a
stray brace-quote, so the streamed document looks like:

```
{"{"output":"Olá a todos! ..."}
```

The complete, correct translation is in there, but every parser in the
best-effort chain rejects the document (the stray prefix parses as an
object key with no value), and `extract_key` returned an empty string —
so translations from this model came back blank.

## The fix

Add a recovery attempt to the chain, between the control-character
re-escape and the lenient parser: locate the schema key in the text and
re-parse (truncation-tolerant) from the object brace immediately
preceding it. This is generic for any "garbage before the real object"
response, not just the doubled brace-quote observed here.

## Verification

Live runs of the real `PostRawTranslator` pipeline (hazard-rich source:
emoji, inline code with `<`/`&`, code fences, blockquote, quoted
strings) against the three vLLM models:

| model | before | after |
|---|---|---|
| Jolteon (CDCK/MoM) | complete, clean stream | complete, clean stream |
| Qwen3.6 35B A3B | complete, clean stream | complete, clean stream |
| DeepSeek V4 Flash | **blank translation** | complete translation via
fallback, warning logged |

All structure checks pass on the recovered output: no control
characters, no literal escape artifacts, angle brackets/query
strings/code fences/blockquote/emoji intact.

Plus a regression spec with the exact observed shape. Parser +
structured output suites: 111 examples, 0 failures.
2026-07-15 13:48:23 -03:00
..
automation I18N: Update translations (#41653) 2026-07-13 17:38:52 +02:00
chat FIX: Refresh chat reviewable payload when re-flagging an edited message (#41739) 2026-07-15 11:55:13 -03:00
checklist
discourse-adplugin I18N: Update translations (#41653) 2026-07-13 17:38:52 +02:00
discourse-affiliate
discourse-ai FIX: Recover AI structured output when models emit stray prefixes (#41745) 2026-07-15 13:48:23 -03:00
discourse-apple-auth
discourse-assign FEATURE: schema based workflow (#41684) 2026-07-15 13:22:29 +02:00
discourse-cakeday DEV: Remove queryAll uses in core tests (#41324) 2026-07-01 11:55:39 +01:00
discourse-calendar FIX: Respect the category subcategory filter for events (#41741) 2026-07-15 17:49:33 +02:00
discourse-chat-integration I18N: Update translations (#40823) 2026-06-12 16:19:35 +02:00
discourse-data-explorer DEV: Make AI context compaction global (#41317) 2026-07-14 18:41:37 -03:00
discourse-details DEV: Drop unused decorateCooked from discourse-details (#41426) 2026-07-03 17:18:20 +01:00
discourse-gamification I18N: Update translations (#41584) 2026-07-12 17:29:05 +02:00
discourse-github UX: Name the failing repository in GitHub setting validation errors (#41738) 2026-07-15 15:46:18 +02:00
discourse-graphviz UX: Fit large Graphviz graphs to the box instead of overflowing (#40915) 2026-06-15 22:44:39 +01:00
discourse-hcaptcha DEV: Block external requests in system specs via Chrome DNS resolver (#40685) 2026-06-17 12:29:57 +01:00
discourse-lazy-videos
discourse-local-dates I18N: Update translations (#41257) 2026-06-29 15:30:28 +02:00
discourse-login-with-amazon I18N: Update translations (#40789) 2026-06-11 12:09:07 +02:00
discourse-lti
discourse-math I18N: Update translations (#40680) 2026-06-09 17:21:49 +02:00
discourse-microsoft-auth
discourse-narrative-bot I18N: Update translations (#40563) 2026-06-04 23:05:44 +02:00
discourse-oauth2-basic I18N: Update translations (#40789) 2026-06-11 12:09:07 +02:00
discourse-openid-connect I18N: Update translations (#40789) 2026-06-11 12:09:07 +02:00
discourse-patreon DEV: Drop jquery in patreon plugin (#41425) 2026-07-03 17:13:54 +01:00
discourse-policy I18N: Update translations (#40823) 2026-06-12 16:19:35 +02:00
discourse-post-voting SECURITY: Reviewable conversations expose post-voting flag PM excerpts to category moderators outside the PM (#41527) 2026-07-07 15:37:22 -05:00
discourse-presence SECURITY: Authorization bypass in wiki edit presence leaks editor identities (#41474) 2026-07-06 12:53:23 -05:00
discourse-reactions DEV: add upcoming change permanent banner metadata (#41700) 2026-07-15 11:20:02 +04:00
discourse-rewind DEV: Bump eslint/lint-configs, and correct violations (#41321) 2026-07-01 10:39:57 +01:00
discourse-rss-polling I18N: Update translations (#41653) 2026-07-13 17:38:52 +02:00
discourse-solved DEV: add upcoming change for Solved badges (#41613) 2026-07-15 18:15:07 +04:00
discourse-subscriptions UX: Include full state names where previously truncated (#41713) 2026-07-14 22:49:12 -04:00
discourse-templates FIX: Support unloaded categories in template topic options (#41230) 2026-06-29 14:35:07 +08:00
discourse-topic-voting FIX: Show the voting notification prompt when vote limits are disabled (#41731) 2026-07-15 14:54:37 +02:00
discourse-user-notes I18N: Update translations (#40680) 2026-06-09 17:21:49 +02:00
discourse-workflows FEATURE: adds user logged in trigger to workflows (#40633) 2026-07-15 16:19:23 +02:00
discourse-zendesk-plugin
footnote UX: prevent nested footnotes (#41325) 2026-07-02 19:55:10 +02:00
poll UX: chart legend styling (#41694) 2026-07-14 11:18:42 +02:00
spoiler-alert FIX: Allow re-blur on spoiler when in details view (#41266) 2026-06-29 12:47:49 -05:00
styleguide DEV: Minor fixes to everyone-based permissions for granular_anonymous_and_logged_in_groups_permissions (#41459) 2026-07-07 09:38:56 +10:00