# AI Digest The AI digest is a private, review-first recommendation flow. It should help the user maintain relationships without leaking identifying relationship data. ## Main Files Core LLM: - `lib/core/llm/llm_config.dart` - `lib/core/llm/llm_service.dart` - `lib/core/llm/llm_diagnostics_log.dart` - `lib/core/llm/ollama/` Digest: - `lib/features/ai_digest/application/anonymized_llm_context_builder.dart` - `lib/features/ai_digest/application/llm_digest_orchestrator.dart` - `lib/features/ai_digest/application/ai_digest_response_parser.dart` - `lib/features/ai_digest/application/llm_digest_background_scheduler.dart` - `lib/features/ai_digest/application/llm_digest_environment.dart` - `lib/features/ai_digest/data/llm_digest_config.dart` - `lib/features/ai_digest/data/llm_digest_run_store.dart` - `lib/features/ai_digest/presentation/ai_digest_review_view.dart` - `lib/app/data/relationship_repository_ai_digest.dart` ## Provider Support `LlmService` supports: - OpenAI - Anthropic - Google AI - Ollama - OpenAI-compatible providers Settings owns provider setup, model listing, diagnostics, and manual test actions. ## Privacy Model Scheduled digest prompts use pseudonymous person tokens: ```json { "personToken": "person_001", "relationshipCategory": "friend", "interests": ["coffee"], "capturedFacts": [...] } ``` Do not include: - real names - aliases - sender names - source user IDs - source thread IDs - raw shared message text - sensitive facts - unreviewed facts - source URLs from private shares Allowed context: - safe category labels - sanitized fact summaries - preference signal labels - relative windows such as "about 3 months ago" - `shared_message_datetime` when it is already stored as timestamp evidence ## Digest Lifecycle ```text manual or scheduled trigger -> LlmDigestOrchestrator -> load config and run policy -> build anonymized context -> call LlmService.completeText -> parse JSON suggestions -> save AiSuggestionDrafts -> notify user -> user reviews, accepts, or dismisses ``` Suggestions never directly mutate people, reminders, or ideas without review. ## Temporal Context Shared message timestamp handling matters. If someone wrote "I am sick and ginger tea helped" four months ago, the correct durable outcome is probably a ginger tea preference, not a current health check-in. Relevant fields: - `SharedPayload.sharedMessageDateTime` - `SharedMessageEntry.sharedMessageDateTime` - digest `capturedFacts[].shared_message_datetime` - digest `capturedFacts[].sourceAge` - digest `preferenceSignals[].lastObserved` Prompts explicitly instruct models to avoid current check-ins from old temporary health/status evidence. ## Web Grounding Digest config can enable web grounding for current events. Grounded suggestions must include source URLs and should prefer official event or venue pages. When web grounding is disabled, the model should avoid claims about current availability, prices, or event schedules unless the local input already contains concrete details. ## Diagnostics Settings exposes LLM diagnostics. Diagnostics should record metadata and lengths, not secrets. Do not log API keys or raw private relationship context beyond what the existing diagnostics intentionally capture. ## Tests Useful focused tests: ```bash flutter test test/core/llm flutter test test/features/ai_digest ``` When changing prompt payloads, update `test/features/ai_digest/anonymized_llm_context_builder_test.dart` so privacy constraints are protected by tests.