Skip to content

LoopInsights: AI-powered therapy settings analysis#2

Closed
taylorpatterson-T1D wants to merge 10 commits intodevfrom
feat/LoopInsights
Closed

LoopInsights: AI-powered therapy settings analysis#2
taylorpatterson-T1D wants to merge 10 commits intodevfrom
feat/LoopInsights

Conversation

@taylorpatterson-T1D
Copy link
Copy Markdown

The Problem We're Solving

Managing diabetes with a closed-loop system like Loop requires ongoing tuning of three core therapy settings — Carb Ratio (CR), Insulin Sensitivity Factor (ISF), and Basal Rate (BR). Today, users must manually interpret CGM data, identify patterns (dawn phenomenon, post-meal spikes, overnight lows), and translate those patterns into schedule adjustments. This process is:

  • Time-consuming — cross-referencing hourly glucose averages, TIR breakdowns, and insulin delivery logs
  • Error-prone — subtle patterns across 14–90 days of data are easy to miss
  • Intimidating for new users — many Loopers leave settings unchanged for months because they don't know where to start
  • Disconnected from context — existing tools show data but don't connect it to actionable setting changes

Endocrinologists do this work in 15-minute appointments a few times per year. LoopInsights brings that analytical capability to every Loop user, on demand, using their own data.


New Feature Impact

LoopInsights is an AI-powered therapy settings advisor that lives inside Loop's Settings screen. It reads glucose, insulin, and carbohydrate data (read-only), sends aggregated statistics to a user-configured AI provider, and returns specific, time-block-level setting adjustment suggestions with clinical reasoning.

What It Does

  • Analyzes 3–90 days of data across glucose (CGM), insulin delivery, and carb entries
  • Detects patterns — dawn phenomenon, overnight lows/highs, post-meal spikes, high variability, consistent highs/lows
  • Generates specific suggestions — e.g., "Increase basal rate from 0.85 to 0.95 U/hr between 3:00 AM–7:00 AM to address dawn phenomenon"
  • Provides a Settings Score (0–100) based on ADA/AACE consensus targets (TIR, time below range, CV, GMI)
  • Dual-mode glucose chart — standard Ambulatory Glucose Profile (24-hour overlay) for 14-day lookback, Glucose Profile (multi-day time series) for all other periods
  • Guided tuning flow — recommends CR → ISF → BR order (most impactful first)
  • Suggestion history — full audit trail with before/after therapy snapshots and revert capability
  • Interactive AI chat — follow-up questions about your data and suggestions
  • Trends & Insights — time-in-range trends, hourly heatmaps, pattern timeline
  • Goals & Reflections — set TIR/GMI targets, track progress, journal reflections
  • Caffeine tracking — manual logging with half-life decay modeling
  • Meal response analysis — per-food-type glucose response patterns (when FoodFinder data available)
  • Background monitoring — optional periodic checks with notification alerts
  • PDF report generation — exportable reports for clinician review
  • Nightscout import — pull historical glucose/treatment data from Nightscout servers

User-Configurable Settings

Setting Options Default
Feature toggle On / Off Off
AI Provider OpenAI, Anthropic, Google OpenAI
AI Model Any model string (e.g., gpt-4o, claude-sonnet-4-5-20250929) Provider default
Custom endpoint Any OpenAI-compatible URL Provider default
API Key User's own key (stored in iOS Keychain) None
Analysis period 3, 7, 14, 30, 90 days 14 days
Apply mode Manual, One-Tap, Pre-Fill Editor Manual
AI Personality Clinical, Friendly, Concise, Educational Clinical
Biometrics Heart rate, HRV, steps, sleep, weight from HealthKit Off
Phase 5 modules Circadian profile, food response, caffeine, AGP chart, Nightscout Each toggleable
Background monitor Periodic analysis with notifications Off
Test data mode Use bundled Tidepool sample data instead of live stores Off (dev only)

Safety Considerations

  • Read-only data access — LoopInsights never writes to GlucoseStore, DoseStore, or CarbStore
  • 20% change cap — AI suggestions are capped at ±20% from current values
  • Conservative bias — system prompt instructs AI to under-adjust rather than over-adjust
  • User confirmation required — every setting change requires explicit user action (except dev-only Auto-Apply)
  • Full audit trail — every suggestion is logged with before/after therapy snapshots
  • One-tap revert — any applied change can be reverted to the pre-apply snapshot
  • Disclaimer on apply — One-Tap and Pre-Fill modes show a medical disclaimer before writing
  • Feature flag defaults to OFF — users must explicitly enable LoopInsights
  • Developer mode hidden — Auto-Apply mode requires 5x long-press activation
  • No data leaves the device except aggregated statistics sent to the user's chosen AI provider
  • API key in Keychain — never stored in UserDefaults or plain text
  • BYO API key model — no Anthropic/OpenAI accounts are bundled; users control their own AI access

Feature Architecture

Loop Integration Footprint

Only 3 existing Loop files are modified, with minimal changes:

File Change Lines Added
SettingsView.swift NavigationLink to LoopInsights settings ~18
SettingsViewModel.swift loopInsightsDataStores closure property ~3
StatusTableViewController.swift Pass data stores to SettingsViewModel ~7

Total integration footprint: ~28 lines across 3 files.

New Files (40 files)

Loop/
├── Managers/LoopInsights/
│   ├── LoopInsights_BackgroundMonitor.swift      # Periodic analysis + notifications
│   └── LoopInsights_Coordinator.swift            # Service orchestrator, data bridge
├── Models/LoopInsights/
│   ├── LoopInsights_Models.swift                 # Core types, enums, data structures
│   ├── LoopInsights_Phase5Models.swift           # Circadian, food response, caffeine, AGP models
│   └── LoopInsights_SuggestionRecord.swift       # Persistent suggestion log entry
├── Resources/LoopInsights/
│   ├── LoopInsights_FeatureFlags.swift           # Runtime feature toggles + logging
│   └── TestData/                                 # Bundled Tidepool sample data (4 JSON files)
├── Services/LoopInsights/
│   ├── LoopInsights_AIAnalysis.swift             # Prompt engineering, response parsing
│   ├── LoopInsights_AIServiceAdapter.swift       # Provider-agnostic HTTP client
│   ├── LoopInsights_AdvancedAnalyzers.swift      # Negative basal, stress score computation
│   ├── LoopInsights_CaffeineTracker.swift        # Half-life decay caffeine model
│   ├── LoopInsights_DataAggregator.swift         # Reads Loop stores → aggregated stats
│   ├── LoopInsights_FoodResponseAnalyzer.swift   # Per-food glucose response patterns
│   ├── LoopInsights_GoalStore.swift              # Goal persistence + reflection journal
│   ├── LoopInsights_HealthKitManager.swift       # HK glucose/insulin/biometric queries
│   ├── LoopInsights_NightscoutImporter.swift     # Nightscout API client
│   ├── LoopInsights_ReportGenerator.swift        # PDF report generation
│   ├── LoopInsights_SecureStorage.swift          # Keychain wrapper for API keys
│   ├── LoopInsights_SuggestionStore.swift        # UserDefaults persistence for history
│   └── LoopInsights_TestDataProvider.swift       # Mock data provider for development
├── View Models/LoopInsights/
│   ├── LoopInsights_ChatViewModel.swift          # Interactive AI chat state management
│   └── LoopInsights_DashboardViewModel.swift     # Main observable, orchestrates analysis
├── Views/LoopInsights/
│   ├── LoopInsights_AGPChartView.swift           # Dual-mode glucose chart (AGP + Profile)
│   ├── LoopInsights_CaffeineLogView.swift        # Caffeine intake logging UI
│   ├── LoopInsights_ChatView.swift               # Conversational AI interface
│   ├── LoopInsights_DashboardView.swift          # Primary entry-point dashboard
│   ├── LoopInsights_GoalsView.swift              # Goals, progress tracking, reflections
│   ├── LoopInsights_MealInsightsView.swift       # Per-food glucose response cards
│   ├── LoopInsights_MonitorSettingsView.swift    # Background monitor configuration
│   ├── LoopInsights_SettingsView.swift           # Feature configuration screen
│   ├── LoopInsights_SuggestionDetailView.swift   # Single suggestion detail + apply
│   ├── LoopInsights_SuggestionHistoryView.swift  # Scrollable suggestion audit log
│   └── LoopInsights_TrendsInsightsView.swift     # TIR trends, heatmaps, patterns
├── Documentation/LoopInsights/
│   └── LoopInsights_README.md                    # Architecture documentation

LoopTests/LoopInsights/
├── LoopInsights_DataAggregatorTests.swift        # Aggregation logic with mock data
├── LoopInsights_ModelsTests.swift                # Model serialization, validation
└── LoopInsights_SuggestionStoreTests.swift       # Store persistence, status transitions

All LoopInsights code uses the LoopInsights_ prefix and lives in LoopInsights/ subdirectories. No LoopKit framework modifications required.

Data Flow

Loop Core (read-only)
  GlucoseStore ─┐
  DoseStore ────┤── DataAggregator ──→ Aggregated Stats ──→ AI Provider (BYO key)
  CarbStore ────┤        ↑ supplemented by HealthKit            │
  StoredSettings┘        for longer periods                     ▼
                                                    Suggestion Cards → User Reviews
                                                                │
                                                    ┌───────────┴────────────┐
                                                    ▼                        ▼
                                          SuggestionStore          Therapy Settings
                                          (audit trail)            (write via SettingsManager)

Screenshots

TODO: Add screenshots before merging

Suggested screenshots to include (highest value first):

  1. Dashboard with Settings Score — shows the score card, therapy settings overview with status indicators, and period selector
  2. Glucose Profile chart (7-day) — multi-day time series with percentile bands and date labels
  3. Ambulatory Glucose Profile chart (14-day) — standard AGP 24-hour overlay with hour labels and (i) info button
  4. Suggestion detail card — a specific suggestion with time blocks, current vs. proposed values, reasoning, and confidence level
  5. AI Chat conversation — follow-up question about a suggestion with contextual response
  6. Trends & Insights — TIR trend chart with hourly glucose heatmap
  7. Settings screen — AI provider configuration, apply mode selector, feature toggles
  8. Goals view — active goals with progress bars and reflection journal
  9. Suggestion history — audit trail showing applied, dismissed, and reverted suggestions
  10. PDF report preview — exportable report formatted for clinician review

Video Demo

TODO: Add YouTube demo link before merging

🎬 A walkthrough video demonstrating the full LoopInsights workflow — from enabling the feature, configuring an AI provider, running analysis, reviewing suggestions, and applying a change — will be linked here.


Beta Test Plan

Prerequisites

  • Loop build from feat/LoopInsights branch running on a physical device
  • Active CGM with ≥3 days of glucose data in HealthKit
  • An API key from OpenAI, Anthropic, or Google

Phase 1: Basic Functionality

  • Navigate to Settings → LoopInsights
  • Enable LoopInsights via the master toggle
  • Configure AI provider and enter API key
  • Use "Test API" to verify connectivity
  • Select 7-day analysis period
  • Tap "Analyze BR" — verify suggestions appear with reasoning
  • Tap "Analyze All" — verify all three setting types are analyzed sequentially
  • Verify Settings Score appears and grade matches expectations

Phase 2: Glucose Charts

  • With 7-day selected, verify "Glucose Profile" title with (i) button and date-based x-axis
  • Switch to 14-day, run analysis — verify "Ambulatory Glucose Profile" title with 24-hour x-axis
  • Switch to 30-day, run analysis — verify date labels span ~30 days
  • Tap (i) buttons on both chart types — verify info popups explain the difference

Phase 3: Suggestion Workflow

  • Open a suggestion detail card — verify current vs. proposed values and reasoning
  • In Manual mode: verify suggestion shows values but doesn't write settings
  • In One-Tap mode: verify disclaimer appears before applying
  • In Pre-Fill mode: verify editor opens with proposed values pre-filled
  • After applying: verify suggestion history shows the change with before/after snapshots
  • Revert an applied suggestion — verify settings restore to pre-apply values

Phase 4: Secondary Features

  • Open AI Chat — ask a follow-up question about a suggestion
  • Navigate to Trends & Insights — verify TIR trend and hourly heatmap render
  • Create a goal in Goals view — verify progress tracking updates after next analysis
  • Add a caffeine entry — verify half-life decay curve displays
  • Generate a PDF report — verify it opens in share sheet

Phase 5: Edge Cases & Safety

  • Run analysis with only 1 day of data — verify graceful "insufficient data" handling
  • Enter an invalid API key — verify clear error message
  • Disable LoopInsights toggle — verify all LoopInsights UI disappears from Settings
  • Switch AI providers — verify previous suggestions persist
  • Verify no suggestion exceeds ±20% change from current values
  • Kill and relaunch app — verify suggestion history and settings persist

Phase 6: Performance

  • Run 90-day analysis — verify no UI freezing during data aggregation
  • Rapidly switch between analysis periods — verify chart clears and no stale data appears
  • Check memory usage in Xcode Instruments during analysis

🤖 Generated with Claude Code

taylorpatterson-T1D and others added 10 commits February 12, 2026 13:26
Add LoopInsights feature: an AI-driven therapy settings advisor that analyzes
glucose, insulin, and carb data to suggest adjustments to Carb Ratios, Insulin
Sensitivity Factors, and Basal Rates.

Core components:
- Dashboard with therapy settings overview, pattern detection, and AI suggestions
- Configurable AI provider (OpenAI, Anthropic, Gemini, Grok, self-hosted)
- Data aggregation pipeline with test data fixtures from Tidepool
- Suggestion lifecycle: pending → applied/dismissed with full history
- AI personality settings (Supportive Coach, Clinical Expert, Dry Wit, Tough Love)
- Developer mode with auto-apply and test data toggles
- Secure API key storage via Keychain
- Safety guardrails: max 20% change per adjustment, one setting at a time
- Unit tests for models, data aggregation, and suggestion store

22 new files, 4 modified files across Views, View Models, Models, Services,
Managers, Resources, and Tests.
…ng, and UI refinements

- Wire real therapy settings writes via LoopInsightsSettingsWriter closure
- Schedule splitting: insert new entries when AI suggests times not in user's schedule
- Revert feature: restore pre-apply settings from suggestion history
- Settings Score (0-100) with TIR, Safety, Stability, GMI breakdown
- Clinical reasoning framework: AI now understands AID-specific patterns
  (corrections/day, basal/bolus ratio, time-of-day analysis, cross-setting interactions)
- All three settings visible in every AI prompt for cross-setting reasoning
- Pre-computed red flags injected into prompt (algorithm workload, basal % alerts)
- Stale-data guard: excludes manually reverted changes from recent context
- Suggestion merge: consolidates split AI responses into single cards
- Pre-Fill Editor: editable proposed values before applying
- Auto-applied notification banner
- Debug log with Copy Full Log for troubleshooting AI behavior
- Temperature forced to 0.0 for deterministic analysis
… advisor UI

Add Ask LoopInsights chat with AI advisor powered by therapy context and glucose data.
Background monitoring with configurable frequency and notification banners. New Trends
& Insights view with Daily/Weekly/Monthly/Stats/Advisor tabs. Dark gradient styling
for chat and trends views. Banner now includes Ask button to open chat directly.
…ports

Add clinical goal tracking (TIR, A1C, below-range, custom) with progress bars,
AI-powered 30-day pattern discovery with sick day and negative basal detection,
timestamped reflection journal with mood tags, and HTML-to-PDF report generation
with share sheet. Goals & Patterns accessible from the Dashboard navigation section.
… analysis

Add HealthKit biometric data (heart rate, HRV, steps, sleep, active energy, weight)
to the AI analysis and chat pipelines. Biometrics are read-only, independently
authorized, and gracefully degrade when individual types are unavailable.

New file: LoopInsights_HealthKitManager.swift
Modified: Models, DataAggregator, AIAnalysis, ChatViewModel, Coordinator,
FeatureFlags, SettingsView, DashboardView, pbxproj, Localizable.xcstrings
…nsights, Nightscout import

- Ambulatory Glucose Profile (AGP) chart with percentile bands and median line
- Clarity-style dashboard redesign: Glucose card, Time in Range 5-zone stacked bar,
  capsule period picker with exact Clarity colors (#C14F0C, #F0CA4C, #74A52E, #D36265, #7F0302)
- Caffeine tracker with half-life decay modeling and glucose correlation
- Meal insights with food response analysis and per-meal glucose impact
- Nightscout data import support
- Advanced analyzers for pattern detection
- 5-zone TIR breakdown (Very High/High/In Range/Low/Very Low) replacing 3-zone model
- Compact list section spacing for tighter dashboard layout
- Chat view UI refinements
…card fixes

P1: Parallel HealthKit queries via async let (6 concurrent fetches)
P2: Single-pass TIR zone counting (5-zone) replacing multiple filter passes
P3: Pre-fetch raw data in DataAggregator, cache for cross-component reuse
P4: Binary search for glucose lookups in FoodResponseAnalyzer
P5: Pre-sorted glucose samples with binary search in AdvancedAnalyzers
P6: Pre-compute AGP data in ViewModel instead of SwiftUI view body
P7: Static DateFormatter in LoopInsightsTimeBlock.formatTime
P8: Pre-sort schedule items before dose loops, pre-sort in ViewModel
P9: Pre-convert glucose to parallel arrays avoiding repeated doubleValue calls
P10: Pass precomputed hourly averages to circadian profile builder

Also: enhanced step/activity data in AI prompts with time-of-day breakdowns
and activity-glucose correlation analysis (2h lag), and meal card layout cleanup.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…y fixes

Glucose chart now operates in two modes: standard Ambulatory Glucose Profile
(24-hour overlay with percentile bands) for 14-day lookback, and Glucose Profile
(multi-day time series) for all other periods. Both modes include an info button
explaining the visualization. HealthKit glucose data supplements Loop store for
longer analysis periods. Chart data clears on period change to prevent stale labels.

Additional fixes across 22 files: improved HealthKit data pipeline reliability,
enhanced test data provider, refined food response analysis, and minor bug fixes
in background monitor, coordinator, caffeine tracker, and goals/trends views.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…y fixes

Glucose chart now operates in two modes: standard Ambulatory Glucose Profile
(24-hour overlay with percentile bands) for 14-day lookback, and Glucose Profile
(multi-day time series) for all other periods. Both modes include an info button
explaining the visualization. HealthKit glucose data supplements Loop store for
longer analysis periods. Chart data clears on period change to prevent stale labels.

Additional fixes across 22 files: improved HealthKit data pipeline reliability,
enhanced test data provider, refined food response analysis, and minor bug fixes
in background monitor, coordinator, caffeine tracker, and goals/trends views.
@taylorpatterson-T1D
Copy link
Copy Markdown
Author

Closing — recreating against upstream (LoopKit/Loop)

taylorpatterson-T1D added a commit that referenced this pull request Apr 29, 2026
Implements three programmatic safeguards from Street (2026) "Frontier LLMs
require explicit clinical context to avoid training-data anchoring for
insulin pump settings" (https://www.diabettech.com/wp-content/uploads/2026/04/diabettech_preprint-3.pdf):

1. Bounds clamping (recommendation #2): Values exceeding the max change %
   by up to 1.5x are clamped to the limit instead of hard-rejected, with a
   logged validation note.

2. Citation verification (recommendation LoopKit#3): Glucose values cited in AI
   reasoning are cross-checked against the actual hourly averages sent to
   the model (±2 mg/dL tolerance). Misattribution rate is reported as a
   validation note.

3. Confidence adjustment by data availability: CR analysis with <5 meals or
   ISF analysis with <3 corrections is capped at Low confidence with an
   explicit warning about anchor substitution risk. Basal (the most data-
   driven setting per Street's anchoring spectrum) is not capped.

All changes are in the response parsing layer — no prompt modifications:
- LoopInsights_AIAnalysis.swift: parseResponse() + extractCitedGlucoseValues()
- LoopInsights_Models.swift: validationNotes field on LoopInsightsAnalysisResponse
- LoopInsights_DashboardView.swift: validation notes display in UI
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant