Skip to content

LoopInsights: AI-powered therapy settings analysis#2405

Open
taylorpatterson-T1D wants to merge 15 commits intoLoopKit:devfrom
TaylorJPatterson:feat/LoopInsights
Open

LoopInsights: AI-powered therapy settings analysis#2405
taylorpatterson-T1D wants to merge 15 commits intoLoopKit:devfrom
TaylorJPatterson:feat/LoopInsights

Conversation

@taylorpatterson-T1D
Copy link

@taylorpatterson-T1D taylorpatterson-T1D commented Feb 13, 2026

Summary

The three therapy settings that cause a lot of confusion are Carb Rates, Insulin Sensitivity and Basal Rates. They all can impact each other and setting the right baselines for these often involves fasting and precise documentation. I wanted AI to solve this problem for us.

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 automatic periodic checks with notification alerts
  • Nightscout import — pull historical glucose/treatment data from Nightscout servers

User-Configurable Settings

Setting Options Default
Feature toggle On / Off Off
AI Provider AI API agnostic in a BYO design for forward maintainability
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 Expert, Supportive Coach, Dry Wit, Tough Love Clinical Expert
Biometrics Heart rate, HRV, steps, sleep, weight from HealthKit Off
Additional 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 mode 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-mode 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 3x long-press activation (location secret)
  • 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

Requirements

  • An AI API key — LoopInsights uses your AI API for analysis. Chose from popular providers like OpenAI, Google Gemini, Grok and Anthropic. Also supports self-hosted Azure type configurations. Stored in iOS keychain.
  • Apple Health access — While LoopInsights works without this access it is significantly augmented the more data you allow it access to.
  • Loop 3.10.0 or newer — Has not been tested with code prior to 3.10.0. Your mileage may vary.
    Requirements to Run LoopInsights
  • Configured therapy settings — at least one of: basal rate, ISF, or carb ratio
    schedule
  • Network connectivity — to reach your AI provider's endpoint
    Everything LoopInsights uses (HealthKit, Keychain, Networking, Push Notifications, CommonCrypto) is already in Loop's existing entitlements and linked frameworks.

Feature Architecture

Loop Integration Footprint

LoopInsights has been optimized for performance and designed with a minimal file footprint in mind. 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

  1. Dashboard with Settings Score — shows the score card, therapy settings overview with status indicators, and period selector
IMG_1649
  1. Glucose Profile chart (7-day) — multi-day time series with percentile bands and date labels
IMG_1646
  1. Ambulatory Glucose Profile chart (14-day) — standard AGP 24-hour overlay with hour labels and (i) info button
IMG_1647
  1. Suggestion detail card — a specific suggestion with time blocks, current vs. proposed values, reasoning, and confidence level
IMG_1650 IMG_1651
  1. AI Chat conversation — follow-up question about a suggestion with contextual response
IMG_1652 IMG_1653
  1. Trends & Insights — TIR trend chart with hourly glucose heatmap
IMG_1660
  1. Settings screen — AI provider configuration, apply mode selector, feature toggles
IMG_1656 IMG_1657 IMG_1658
  1. Suggestion history — audit trail showing applied, dismissed, and reverted suggestions
IMG_1659

Video Demo

Check out how it works here: https://youtu.be/P-xfHt0AVTM

🎬 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.


Test Data for Development & Demos

LoopInsights includes a Test Data mode for development, demos, and evaluation without needing live CGM data. A Python script pulls real data from a Tidepool account and converts it to fixture files that LoopInsights can load.

Generating Test Data from Tidepool

Prerequisites: pip3 install requests

# Pull 14 days of data (default)
python3 pull_tidepool_data.py --email YOUR_TIDEPOOL_EMAIL --password YOUR_TIDEPOOL_PASSWORD

# Pull 90 days for longer-range testing
python3 pull_tidepool_data.py --email YOUR_EMAIL --password YOUR_PASSWORD --days 90

# Also auto-copy fixtures to the iOS Simulator
python3 pull_tidepool_data.py --email YOUR_EMAIL --password YOUR_PASSWORD --simulator

The script authenticates with the Tidepool API, pulls CGM glucose, insulin doses, carb entries, and pump settings, converts them to Loop's native JSON format, and saves four fixture files:

  • tidepool_glucose_samples.json
  • tidepool_dose_entries.json
  • tidepool_carb_entries.json
  • tidepool_therapy_settings.json (optional)

Loading Test Data

Fixtures can be placed in two locations (checked in order):

  1. App DocumentsDocuments/LoopInsights/ on device (no rebuild; drag-drop via Finder on physical device)
  2. App BundleResources/LoopInsights/TestData/ (requires rebuild)

Enabling Test Data Mode

  1. Open Settings > LoopInsights
  2. Long-press the header 5 times to unlock Developer Mode
  3. Toggle "Use Test Data Fixtures" on
  4. Open Dashboard and tap Analyze

Creating Fixtures Manually

If you don't have a Tidepool account, you can create JSON fixtures by hand. See Documentation/LoopInsights/LoopInsights_README.md for the exact JSON schema for each fixture file (glucose samples, dose entries, carb entries, and therapy settings).


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 OR test data fixtures loaded (see above)
  • 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

Requesting review by @marionbarker based on availability.

taylorpatterson-T1D and others added 11 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.
Bump all body text, headers, and stat values to full white for readability
on dark backgrounds. Replace .toolbarColorScheme (iOS 16+) with manual
toolbar principal title for compatibility. Restore UINavigationBarAppearance
approach in ChatView.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Added steps for creating and using test data in developer mode for demos and feature functionality testing.
taylorpatterson-T1D and others added 3 commits February 15, 2026 14:41
Safety guardrails (3 layers of defense against dangerous therapy values):
- LoopInsights_SafetyGuardrails struct with clinical bounds mirroring LoopKit
  (CR 4-28 recommended/2-150 absolute, ISF 16-400/10-500, Basal 0.05-10/0.05-30)
- Post-parse validation rejects values outside absolute bounds and >25% changes
- AI prompt now includes absolute bounds with clamping instructions
- confirmApply() hard-blocks absolute violations
- applyEditedSuggestion() validates edited blocks against absolute bounds
- autoApplySuggestion() blocks anything outside recommended range (stricter)
- SuggestionDetailView shows orange warning banner and color-coded values
- DashboardView alert changes to "Safety Warning" with specific warnings
- Suggestion cards show orange triangle badge for guardrail warnings

Data-first AI prompts (all 4 AI interaction points):
- Chat, Analysis, Goals/Patterns, and Trends prompts now require every
  answer to cite the user's specific numbers — no generic diabetes advice
- Added "#1 RULE" blocks emphasizing real data over textbook answers

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Passes the user's insulin type (e.g. Fiasp, Novolog) into the therapy
snapshot and AI prompts so the model can distinguish timing issues from
dosing issues based on pharmacokinetics.
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