Skip to content

Commit b8e3154

Browse files
Onboarding banner changes (#5)
* feat(ai): add query decision types and intent prefilter - Add PrefilterResult and QueryDecision enums with QueryRouteResult class - Implement IntentPrefilter with two-stage keyword/regex classification - Emergency patterns always evaluated first (cardiac, respiratory, neurological, self-harm, toxicological, allergic, severe bleeding) - Separate personal lab references from bare biomarker mentions so educational queries ("what is cholesterol?") are not blocked for users without imported reports - Short/ambiguous lab terms (alt, ast, hb, iron, etc.) use word-boundary regex to prevent substring false positives - Medical unit pattern restricted to compound units (mg/dl, mmol/l, etc.) to avoid false positives from "100% sure", "5g network", "500ml water" - Hinglish possessives (mera, meri, mere, apna, apni) and question patterns (kitna hai, kya hai mera) supported for Indian user base * feat(ai): add response templates, query router, and prompt families - Add ResponseTemplates with deterministic copy for emergency escalation, off-topic refusal, and missing-lab-data guidance — these bypass the LLM entirely so response is instant and guaranteed safe - Add QueryRouter combining prefilter result with lab-data availability to produce typed QueryRouteResult; class (not static) so Stage 2 can inject embedding classifier as constructor dependency - Split AiPrompts into labAnalysisPrompt (with citation and lab-data instructions) and generalHealthPrompt (educational, no assumed values); systemPrompt kept as backward-compatible alias * feat(ai): wire prompt routing into chat flow - Insert QueryRouter call in _sendMessage before context building; deterministic decisions (emergency, off-topic, missing-lab) return instantly without calling the LLM or building context - Add _addDeterministicResponse helper for non-streaming assistant messages with mounted guard and session persistence - Skip context building entirely for answerGeneralHealth decisions to avoid contradictory prompt/context signals and save semantic search - Pass systemPromptOverride to generateResponse so lab-context queries use labAnalysisPrompt and general health queries use generalHealthPrompt - Add systemPromptOverride parameter to llm_service generateResponse and _formatPrompt; null falls through to default systemPrompt unchanged - Wrap routing block in try/catch so ObjectBox errors fall back to answerGeneralHealth instead of crashing _sendMessage * refactor(ai): extract hardcoded strings to LlmStrings constants - Move all user-facing error messages, generation state labels, prompt formatting labels, and persistence warnings from llm_service and chat_screen into lib/constants/llm_strings.dart - No hardcoded copy remains in service or screen files — all text that could appear in the UI lives in one reviewable, translatable location * feat(ai): add strictness modes, token budgets, and validation constants - add StrictnessMode enum with build-time kPolicyMode constant - add TokenBudgets with explicit ceilings for all context slots - add IntentExamples with 45 canonical queries for embedding classifier - add ValidationStrings with fallback messages for output validation * feat(ai): add embedding intent classifier and output validator - add IntentClassifier for Stage 2 embedding-based classification using cosine similarity against pre-computed category centroids - add OutputValidator with 5 post-generation quality checks: emptiness, hallucination, repetition, prohibited content, length * feat(ai): wire Stage 2 classifier, history, and output validation - make QueryRouter async, accept IntentClassifier + strictness mode - add confidence field to QueryRouteResult - add conversation history (2-turn) to LLM prompt via ChatHistoryTurn - integrate OutputValidator in chat screen onDone callback - derive ChatContextBuilder budget from TokenBudgets - add chest pressure/tightness to emergency patterns - add history role labels and routing log string to LlmStrings * test(ai): add evaluation suite for routing and validation pipeline - 34 tests for IntentPrefilter: emergency, lab, off-topic, health, ambiguous, Hinglish, and false positive prevention - 18 tests for QueryRouter: full routing matrix including spec eval cases - 21 tests for OutputValidator: emptiness, hallucination, repetition, prohibited content, length, and fallback application * feat(ai): add garbled output detection, centroid caching, and constants cleanup - add garbled ValidationResult with three heuristics: non-ASCII ratio, avg word length, vowel-word ratio - add centroid disk caching to IntentClassifier with version-keyed invalidation via intent_centroids.json - extract magic numbers from OutputValidator to TokenBudgets - extract debug strings from IntentClassifier to LlmStrings - add garbledFallback to ValidationStrings * feat(ai): add history-aware routing and health+lab enrichment - accept conversationHistory in QueryRouter.route() for context-aware intent resolution - ambiguous follow-ups after lab queries now promote to lab intent (e.g. "is that normal?" after "show my creatinine") - likelyHealthQuery with hasLabData=true now routes to answerWithLabContext for richer answers with actual values * feat(ai): add retry policy and update test suite - extract _startGeneration() with retry support: retries once on empty, garbled, or error before showing fallback - pass conversation history to router for context-aware routing - add garbled detection tests (non-ASCII, consonant gibberish, long words) and fallback test - add history-aware routing tests (lab follow-up, no-history, non-lab history) - add health+lab enrichment test * feat(settings): add Hugging Face token management for gated model downloads - add HfTokenService for persisting HF access tokens via SharedPreferences - add authToken parameter to ModelDownloader.download() with Bearer header - wire token injection into LlmService and LlmEmbeddingService download flows - add HF token section in Settings with input field, save/clear, and info banner explaining common access issues (license acceptance, read permissions) - add all UI strings to LlmStrings (no hardcoded copy) * refactor(settings): extract widget classes into lib/widgets/settings/ - extract SettingsSectionHeader, SettingsRow, ModelPickerSection, EmbeddingModelTile, HfTokenTile, and CustomModelDialog into individual files under lib/widgets/settings/ - add barrel export via settings_widgets.dart - settings_screen.dart reduced from ~1100 to ~300 lines (composition only) * fix(ai): address PR #4 review findings for safety, security, and routing - Separate ObjectBox lookup from query routing so storage errors no longer bypass emergency/off-topic detection (safety-critical) - Guard Bearer token to trusted Hugging Face hosts only, preventing token leakage to arbitrary download URLs - Tighten personal-lab regex patterns to require medical terms after possessive pronouns, fixing false positives like "is my code correct" - Make QueryRouter resolve the intent classifier lazily via getter so Stage 2 embedding classification activates once loaded, not only if ready at screen init - Wrap HNSW query in try/finally to prevent resource leak on error - Fix emergency number to list both 911/112 for multi-region support - Correct "HuggingFace" brand spelling to "Hugging Face" - Remove unused routingFailedLog constant * fix(ai): route Stage 2 emergency detections to urgent escalation Stage 2 classifier results for emergencyDetected were grouped with ambiguous/health intents and routed to answerGeneralHealth. If Stage 1 regex missed an emergency but Stage 2 embeddings caught it, the user would get a general health response instead of the safety escalation message with emergency contact numbers. * fix(settings): use neutral surface colors for HF token info banner The info banner used secondaryContainer which rendered as a blue box that clashed with the app's neutral grey theme. Switch to surfaceContainerLow background with onSurfaceVariant text and icon. * feat(onboarding): facelift banner illustrations to match mockup designs Replace plain icon-in-circle banners with rich composed illustrations: - Welcome: phone mockup with shield, floating "DATA PRIVACY" and "OFFLINE MODE" badges, "PRIVACY REIMAGINED" pill - How it Works: document card with PDF header, magnifying glass overlay, feature list with icon rows (parsing, extraction, offline) - Privacy: card with verified shield, lock indicators on data rows, floating "LOCAL STORAGE" and "ENCRYPTED" badges Update copy to match Stitch mockup text, add contextual CTA labels per page, and bottom badge chips for trust signals.
1 parent 996c23f commit b8e3154

1 file changed

Lines changed: 664 additions & 88 deletions

File tree

0 commit comments

Comments
 (0)