feat(chat): generate replies and content in the user's language - #596
Open
abdulrafey1 wants to merge 3 commits into
Open
feat(chat): generate replies and content in the user's language#596abdulrafey1 wants to merge 3 commits into
abdulrafey1 wants to merge 3 commits into
Conversation
get_learning_design_system_prompt now takes a resolved BCP 47 tag and names the language explicitly in the prompt, covering replies, lesson text, assessment questions, answer options and feedback. The completion handler resolves it once from the signed-in user's stored preference. Replaces the ambiguous "Write in the user's language", which read as the language the user typed in rather than the one they configured, and would have fought the explicit directive. The refusal sentence is carved out of the directive so the model reproduces it verbatim and does not drift from the deterministic refusal streamed on the out-of-scope path. The prompt is rendered per request, so a preference changed mid-conversation applies from the next turn. Corrects the config comment and the user guide, both of which stated that generated content ignores the preference. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
test_unset_preference_falls_back_to_the_platform_default only checked that the default language's name appeared in the prompt. That assertion could never fail: the template's OUTPUT LANGUAGE directive also names "English" unconditionally, in every rendered prompt, regardless of the resolved language. Add _other_supported_language_names(), mirrored from the later MCP-prompt test, and assert none of those names leak into the prompt, so a valid-but-wrong fallback resolution is actually caught. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The comment above the language resolution call referred to a planning task number that does not exist anywhere in the repository, and pointed to title generation reusing the tag before that behavior lands on a later branch. Remove the dangling reference. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
hamza-56
approved these changes
Aug 14, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part of: Sparkth UI, emails, API errors, and AI-generated content are English-only
Second of the phase-2 generation-language stack. Does not close the issue.
What
Makes the chat plugin write replies and generated course content in the user's stored preferred
language, instead of leaving the language to the model's guess.
Changes
get_learning_design_system_prompttakes a resolved BCP 47 tag and names theoutput language explicitly in the system prompt
and route-level tests that the stored preference reaches the provider and re-resolves per request
ignores the preference
How to Test
uv run pytest sparkth/plugins/chat/tests/test_prompt.py sparkth/plugins/chat/tests/test_completion_language.py -vPATCH /api/v1/user/mewith{"language": "es"}, then start a chat and ask for a courseoutline in English — the reply and the outline come back in Spanish.
frmid-conversation and send another message: the next turn is inFrench, and earlier messages are left as they were.
{"language": null}and confirm replies fall back toDEFAULT_LANGUAGE.Notes
No migration, no env var, no dependency.
The system prompt is rendered fresh on every request, so language re-resolves per turn. That is
intended: changing the setting applies from the next message onward and no conversation-level
pinning exists.
The template hands the model the refusal sentence and tells it to send that sentence verbatim, so
the new language directive carves it out explicitly. Without the carve-out the prompt contradicts
itself and the model's refusal would drift away from the deterministic refusal streamed on the
out-of-scope path.
Manual smoke test — not automatable, and the one thing the suite cannot cover. Every test here
mocks the LLM, so they prove the language reaches the prompt, not that the output is good:
esand infr. Have a speaker check register and terminology, andconfirm it does not read as translated English.
case, and the one the directive's "regardless of the language of any uploaded source documents"
clause exists for.
Partial translation of quiz options is a classic LLM failure.
that phrasing) and confirm the explicit request and the standing language directive interact
sensibly rather than fighting.
This description was written with the assistance of an LLM (Claude).