feat: add adaptive diagnostic test — LLM-based level assessment before chat#269
feat: add adaptive diagnostic test — LLM-based level assessment before chat#269latifaaznague wants to merge 1 commit into
Conversation
|
@latifaaznague Language: both files and the pull request description are entirely in French. The PR description and test coverage list mention rate limiting (429), Please fix the language (translate to English) before approval. |
Dakir-Ai
left a comment
There was a problem hiding this comment.
Hey @latifaaznague
Nice addition! However, there are merge conflicts that need to be resolved before we can complete the review
a35cf9a to
a51b2d1
Compare
a51b2d1 to
536e670
Compare
There was a problem hiding this comment.
Pull request overview
This PR introduces an adaptive diagnostic-test workflow that gates access to the student support chat, generates an LLM-based quiz, scores it into a learner level, persists results, and uses that level to adapt the tutor’s system prompt from the first message.
Changes:
- Added backend diagnostics module (model/repo/service/router) with LLM generation, scoring, persistence, and rate limiting.
- Added a SvelteKit diagnostic route/UI and integrated it into the support creation + support details access flow as a mandatory gate.
- Updated tutor prompt composition to adapt teaching strategy based on the diagnosed level.
Reviewed changes
Copilot reviewed 22 out of 38 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| ui/vite.config.ts | Expands Vite dev server filesystem allowlist (incl. node_modules paths). |
| ui/src/routes/student/support/[id]/diagnostic/+page.svelte | Adds route entry that renders the diagnostic page component. |
| ui/src/routes/student/support/[id]/diagnostic/+page.js | Adds route load() that returns params.id. |
| ui/src/lib/i18n/locales/fr-FR/translation.json | Adds new i18n keys for diagnostic UI flow. |
| ui/src/lib/i18n/locales/en-US/translation.json | Adds new i18n keys for diagnostic UI flow. |
| ui/src/lib/i18n/locales/ar-MA/translation.json | Adds new i18n keys for diagnostic UI flow. |
| ui/src/lib/components/student/tutor/Chat.svelte | Injects diagnosed-level-specific prompt instructions for the tutor. |
| ui/src/lib/components/student/pages/SupportDetails.svelte | Adds diagnostic completion gate + UI for locked chat access. |
| ui/src/lib/components/student/pages/DiagnosticTest.svelte | Implements the diagnostic test UI (generate, step-by-step quiz, submit, review). |
| ui/src/lib/components/student/elements/SupportCreation.svelte | Redirects users to the diagnostic flow after support creation. |
| ui/src/lib/apis/diagnostics/index.ts | Adds frontend API client for diagnostics endpoints. |
| tests/tests/test_diagnostics.py | Adds pytest coverage for diagnostics routes, scoring, auth, and rate limiting. |
| learning/diagnostics/service.py | Implements diagnostic generation (LLM prompt/parse) and scoring/level assignment. |
| learning/diagnostics/repository.py | Adds repository helpers to fetch diagnostics by support/user. |
| learning/diagnostics/init.py | Introduces diagnostics package. |
| gateway/http/routers/diagnostics.py | Adds FastAPI router for diagnostics endpoints with rate limiting and sanitization helper. |
| gateway/http/dependencies.py | Adds get_diagnostics_service dependency provider. |
| gateway/http/app.py | Registers the diagnostics router under /api/v1. |
| docs/diagnostic-test/user-guide.md | Adds end-user documentation and walkthrough for the diagnostic flow. |
| docs/diagnostic-test/README.md | Adds technical overview + API documentation for diagnostics. |
| docs/diagnostic-test/feature.md | Adds detailed internal implementation notes and diagrams references. |
| data/models/diagnostic.py | Adds the DiagnosticResult ORM model. |
| data/models/init.py | Registers DiagnosticResult for model discovery/table creation. |
| result = svc.get_by_support(support_id) | ||
| if result and result.user_id != current_user.id: | ||
| raise HTTPException( | ||
| status_code=status.HTTP_403_FORBIDDEN, detail="Not authorized" | ||
| ) | ||
| return result |
| if result.user_id != current_user.id: | ||
| raise HTTPException( | ||
| status_code=status.HTTP_403_FORBIDDEN, detail="Not authorized" | ||
| ) | ||
| return result |
| self.support_repo.update( | ||
| diagnostic.support_id, | ||
| level=determined_level, | ||
| updated_at=datetime.utcnow(), | ||
| ) |
| # tests/test_diagnostics.py | ||
| import json | ||
| import uuid | ||
| from datetime import datetime | ||
| from unittest.mock import AsyncMock, patch |
| support = self.support_repo.get_by_id(support_id) | ||
| if not support: | ||
| raise NotFoundError("Support", support_id) | ||
| if support.user_id != user_id: | ||
| raise AuthorizationError("You do not own this support request") | ||
|
|
||
| language = support.content_language or "English" |
| .catch((err) => { | ||
| error = err.detail; | ||
| console.log(err); | ||
| return null; | ||
| }); | ||
|
|
||
| if (error) throw error; | ||
| return res; |
| .catch((err) => { | ||
| error = err.detail; | ||
| console.log(err); | ||
| return null; | ||
| }); | ||
|
|
||
| if (error) throw error; | ||
| return res; | ||
| }; |
| /** @type {import('./$types').PageLoad} */ | ||
| export function load({ params }) { | ||
| return { | ||
| id: params.id | ||
| }; |
| | Score | Assigned Profile | Chat Behavior | | ||
| |---|---|---| | ||
| | 0 – 40% | Beginner | Simplified explanations, one concept at a time, concrete examples, no jargon | | ||
| | 41 – 70% | Intermediate | Balanced content, progressive deepening, nuances and exceptions | | ||
| | 71 – 100% | Advanced | Technical content, complex cases, specialized references, fast pace | |
Pull Request Checklist
Before submitting this pull request, I confirm the following:
docs/diagnostic-test/(README.md,feature.md,user-guide.md, diagrams, mockups, and screenshots).37 pytest tests).featDescription
This pull request introduces a mandatory adaptive diagnostic test that students must complete before accessing the pedagogical chat for any course support.
Before this contribution, students could directly open the pedagogical chat without any prior knowledge assessment. As a result, the AI tutor had no context about the learner’s actual level and produced generic responses that were not adapted to their knowledge.
This contribution adds a diagnostic step between support access and the pedagogical chat. The system now:
beginner,intermediate,advanced),This improves the personalization of the tutoring experience by ensuring that the pedagogical chat starts with an initial estimate of the learner’s knowledge.
Changelog Entry
Description
Added
Backend
Frontend
Changed
Frontend
Global behavior
beginner,intermediate,advanced).Deprecated
Removed
Fixed
Security
Breaking Changes
Additional Information
Scoring Rules
Score >= 71%→advancedScore >= 41%→intermediatebeginnerTest Coverage
Added 37 pytest tests covering:
40%,41%,70%,71%),403when the diagnostic does not belong to the student),502),429),Technical Notes
GET /by-support/{id}must be declared beforeGET /{id}.diagnostic_resultstable is created automatically throughBase.metadata.create_all().Documentation
Complete documentation was added in
docs/diagnostic-test/:README.md— technical and API documentationfeature.md— internal feature documentation, implementation details, and known limitationsuser-guide.md— student and teacher guideassets/— sequence diagram, class diagram, activity diagram, UI mockups, and real screenshots of the full student journeyScreenshots or Videos
Support creation
Diagnostic start page
Quiz in progress
Results page
Adaptive pedagogical chat