Skip to content

LoopInsights: AI-powered therapy settings analysis#2405

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

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

Conversation

@taylorpatterson-T1D
Copy link
Copy Markdown

@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 interoperate with 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
  • Ask Loopy (AI chat with voice) — conversational AI assistant with full access to your Loop data. Supports voice input via dictation with auto-send, and text-to-speech responses you can replay
  • Live loop status in chat — Loopy sees your real-time IOB, COB, active overrides, predicted glucose, loop mode, pump battery, and reservoir level
  • 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, HealthKit sync
  • Alcohol tracking — manual logging with linear metabolism model, delayed hypoglycemia risk alerts, and time-to-clear estimates
  • Meal response analysis — per-food-type glucose response patterns with nutritional glucose correlation (when FoodFinder data available)
  • FoodFinder data mining — permanent meal archive with full nutritional profiles (protein, fat, fiber, calories), AI carb estimation accuracy tracking, and per-macronutrient glucose spike analysis
  • Menstrual cycle awareness — reads Apple Health Cycle Tracker data to determine hormonal phase (follicular, ovulatory, luteal, menstrual) and factors insulin resistance patterns into all AI analysis
  • 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, menstrual cycle from HealthKit Off
Additional modules Circadian profile, food response, caffeine, alcohol, 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 (43 files)

Loop/
├── Managers/LoopInsights/
│   ├── LoopInsights_BackgroundMonitor.swift      # Periodic analysis + notifications
│   └── LoopInsights_Coordinator.swift            # Service orchestrator, data bridge, live status
├── Models/LoopInsights/
│   ├── LoopInsights_Models.swift                 # Core types, enums, data structures
│   ├── LoopInsights_Phase5Models.swift           # Circadian, food response, caffeine, alcohol, menstrual cycle, 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      # Circadian, negative basal, stress, menstrual cycle analyzers
│   ├── LoopInsights_AlcoholTracker.swift         # Linear metabolism alcohol model + hypo risk
│   ├── LoopInsights_CaffeineTracker.swift        # Half-life decay caffeine model
│   ├── LoopInsights_DataAggregator.swift         # Reads Loop stores → aggregated stats
│   ├── LoopInsights_FoodResponseAnalyzer.swift   # Per-food glucose response + nutritional correlation
│   ├── LoopInsights_GoalStore.swift              # Goal persistence + reflection journal
│   ├── LoopInsights_HealthKitManager.swift       # HK glucose/insulin/biometric/menstrual 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
│   └── LoopInsights_VoiceService.swift           # Text-to-speech for Ask Loopy voice responses
├── View Models/LoopInsights/
│   ├── LoopInsights_ChatViewModel.swift          # AI chat with voice, live status, full data context
│   └── LoopInsights_DashboardViewModel.swift     # Main observable, orchestrates analysis
├── Views/LoopInsights/
│   ├── LoopInsights_AGPChartView.swift           # Dual-mode glucose chart (AGP + Profile)
│   ├── LoopInsights_AlcoholLogView.swift         # Alcohol intake logging UI
│   ├── LoopInsights_CaffeineLogView.swift        # Caffeine intake logging UI
│   ├── LoopInsights_ChatView.swift               # Conversational AI interface with voice
│   ├── 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 ─────┤
  CarbStore ─────┤── DataAggregator ──→ Aggregated Stats ──→ AI Provider (BYO key)
  StoredSettings ┘        ↑                                        │
                          │ supplemented by:                       ▼
                    HealthKit (HR, HRV, steps, sleep,    Suggestion Cards → User Reviews
                     weight, caffeine, menstrual cycle)            │
                    FoodFinder (meal archive, nutrition)  ┌────────┴─────────┐
                    Nightscout (remote glucose/boluses)   ▼                  ▼
                    StatusExtensionContext (IOB, COB,    SuggestionStore    Therapy Settings
                     predicted glucose, overrides)       (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 Ask Loopy — ask a follow-up question about a suggestion
  • Use voice dictation in Ask Loopy — verify auto-send and spoken response
  • Ask Loopy about current IOB/COB — verify it sees live loop status
  • 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
  • Add an alcohol entry — verify metabolism countdown and hypo risk indicator
  • 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 23 commits February 9, 2026 11:58
FoodFinder adds barcode scanning, AI camera analysis, voice search, and
text-based food lookup to Loop's carb entry workflow. All feature code
lives in dedicated FoodFinder/ subdirectories with FoodFinder_ prefixed
filenames for clean isolation and portability to other Loop forks.

Integration touchpoints: ~29 lines across 3 existing files
(CarbEntryView, SettingsView, FavoriteFoodDetailView). Feature is
controlled by a single toggle in FoodFinder_FeatureFlags.swift.

New files: 34 (11 views, 3 models, 13 services, 2 view models,
1 feature flags, 1 documentation, 3 tests)
Voice search (microphone button) now uses the AI analysis pipeline
instead of USDA text search, enabling natural language food descriptions
like "a medium bowl of spicy ramen and a side of gyoza". Text-typed
searches continue using USDA/OpenFoodFacts as before.

Changes:
- SearchBar: Add mic button with voice search callback
- SearchRouter: Add analyzeFoodByDescription() routing through AI providers
- SearchViewModel: Add performVoiceSearch() async method
- EntryPoint: Wire VoiceSearchView sheet to AI analysis pipeline
Replace the separate mic button with automatic natural language detection.
When the user dictates into the search field via iOS keyboard dictation,
the text is analyzed: short queries (1-3 words like "apple") use USDA,
while longer descriptive phrases (4+ words like "a medium bowl of spicy
ramen and a side of gyoza") automatically route to the AI analysis path.

Changes:
- SearchBar: Remove mic button and onVoiceSearchTapped parameter
- SearchViewModel: Add isNaturalLanguageQuery() heuristic, route detected
  natural language through performVoiceSearch in performFoodSearch
- EntryPoint: Remove voice search sheet, wire onGenerativeSearchResult
  callback to handleAIFoodAnalysis
The Python script created group definitions but didn't properly attach
all of them to their parent groups. Fixes:
- Services group → now child of Loop app root (was orphaned)
- Resources group → now child of Loop app root (was orphaned)
- Documentation group → now child of project root (was orphaned)
- ViewModels/FoodFinder → moved from Loop root to View Models group
- Tests/FoodFinder → moved from project root to LoopTests group
…, analysis history

- Fix triple barcode fire by consuming scan result immediately in Combine sink
- Replace AsyncImage with pre-downloaded thumbnail to avoid SwiftUI rebuild issues
- Use smallest OFF thumbnail (100px) with static food icon fallback for slow servers
- Add secure Keychain storage for AI provider API keys
- Add analysis history tracking with FoodFinder_AnalysisRecord
- Consolidate AI provider settings and remove BYOTestConfig
- Remove barcode connectivity pre-check that added 3+ seconds latency per scan
- Add NSCache to ImageDownloader for thumbnail deduplication (50 items, 10MB)
- Remove artificial minimumSearchDuration delay from search and error paths
- Merge duplicate Combine observers into single combineLatest for AI recomputation
- Decode image_thumb_url from OpenFoodFacts API for smallest available thumbnail
- Wrap 369 bare print() calls in #if DEBUG across 8 FoodFinder files
…eaders

File consolidations (6 files removed, 2 new files created):

1. FoodFinder_ScanResult.swift + FoodFinder_VoiceResult.swift
   → FoodFinder_InputResults.swift

2. FoodFinder_FavoriteDetailView.swift + FoodFinder_FavoriteEditView.swift
   + FoodFinder_FavoritesView.swift → FoodFinder_FavoritesHelpers.swift

3. FoodFinder_AISettingsManager.swift
   → absorbed into FoodFinder_AIProviderConfig.swift

4. FoodFinder_FavoritesViewModel.swift
   → absorbed into FoodFinder_SearchViewModel.swift

Other changes:
- Fix long analysis titles overflowing the screen by programmatically
  truncating picker row names and constraining food type to 20 chars
- Improve AI prompts for menu/recipe/text image analysis
- Add text-only AI analysis path in AIServiceManager
- Increase AI token budget for multi-item responses
- Standardize all 26 FoodFinder file headers with consistent format
- Add originalAICarbs and aiConfidencePercent fields to
  FoodFinder_AnalysisRecord for tracking AI estimate accuracy
- Add Notification.Name.foodFinderMealLogged for real-time
  meal event observation
- Add MealDataProvider protocol with date-range query interface
  and AnalysisHistoryStore conformance
- Add "Last 30 days" retention option to Analysis History settings
- Add originalAICarbs and aiConfidencePercent fields to
  FoodFinder_AnalysisRecord for tracking AI estimate accuracy
- Add Notification.Name.foodFinderMealLogged for real-time
  meal event observation
- Add MealDataProvider protocol with date-range query interface
  and AnalysisHistoryStore conformance
- Add "Last 30 days" retention option to Analysis History settings
- Absorption time model: conservative adjustments anchored to Loop's
  3-hour default. FPU adds +0/+0.5/+1.0 hr (was +1/+2.5/+4), fiber
  +0/+0.25/+0.5 (was +0/+1/+2), meal size +0/+0.25/+0.5 (was +0/+1/+2).
  Cap reduced from 8 to 5 hours. Updated AI prompt and 3 examples.
- OCR routing fix: raised menu detection threshold from 1 to 5 significant
  lines and always include image on menu path to prevent food photo
  misclassification (fixes "Unidentifiable Food Item" on food photos).
- Inline "Why X hrs?" pill on Absorption Time row replaces standalone
  DisclosureGroup row. Purple centered pill with fixed width, expands
  reasoning on tap. Uses AIAbsorptionTimePickerRow when AI-generated.
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>
taylorpatterson-T1D and others added 2 commits February 14, 2026 14:30
The 20-char limit was truncating food names (e.g. "Baked pastry with f…")
which made them unreadable in LoopInsights Meal Insights. The RowEmojiTextField
maxLength only restricts keyboard input, so longer programmatic values are safe.

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 2 commits February 14, 2026 14:31
…ivity

CoreMotion-based activity detection that automatically applies user-selected
override presets when walking or running is detected. 7 new files, 2 modified.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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>
…rompts

- Success criteria: AI now tells users what to watch for after applying a change
- Outcome evaluation: AI evaluates its own past suggestions before making new ones
- Toned down system prompt: corrections and basal/bolus ratio are context, not red flags
- Tough Love personality rewritten to be direct without being cruel
- Removed editorial RED FLAG/ELEVATED annotations from user prompt data
- Added DataLayer disclosure to README (enabled by default, how to disable)
# Conflicts:
#	Loop/Services/LoopInsights/LoopInsights_AIAnalysis.swift
Gemini 2.5 Flash/Pro thinking models return thinking in parts[0] and
the actual response in subsequent parts. Our key path read parts[0],
getting thinking text instead of the JSON response. Now extracts the
last non-thought part. Also bumps maxTokens from 2048 to 8192 to
prevent response truncation with expanded success criteria fields.
Existing UserDefaults configs have maxTokens=2048 which truncates
Gemini responses. Override to 8192 minimum on load, same pattern
as temperature enforcement.
Gemini thinking models consume output tokens for thinking, causing
JSON responses to be truncated. Added repairTruncatedJSON to close
unclosed brackets/braces. Bumped maxTokens to 16384 to leave room
for thinking overhead.
Gemini 2.5+ thinking models consume output tokens for chain-of-thought,
leaving too few for the actual JSON response. Set thinkingBudget: 0 to
disable thinking since we only need structured JSON output.
The thinkingConfig field causes HTTP 400 on endpoints that don't
support it. Rely on high maxTokens (16384) + JSON repair to handle
thinking models that consume output tokens for chain-of-thought.
Replaces brittle key path extraction with a 3-strategy approach:
1. Standard key path (works for normal models)
2. Deep recursive search (finds text in any response structure)
3. Full response stringify (last resort, lets JSON parser handle it)

Handles thinking models, API version differences, and unexpected
response formats without needing model-specific knowledge.
Thinking models can use 30K+ tokens for thinking. 65536 leaves plenty
of room for both thinking and the actual response. Deep search now
collects ALL text strings and picks the one containing JSON markers
or the longest one, instead of returning the first one found.
When thinking models (Gemini 2.5) spend all output tokens on
reasoning and produce no actual response, detect the API envelope
and show a clear error suggesting non-thinking alternatives.
When a thinking model returns an empty response, show a clear error
with an (i) "View Supported Models" link that opens a sheet listing
all confirmed working models by provider, as of March 2026.
Two bugs fixed:
1. Removed 2048 maxTokens cap that overrode the configured 65536 default,
   causing thinking models to exhaust output tokens on reasoning.
2. Added Gemini-specific non-thought extraction that skips thought:true
   parts and throws emptyThinkingResponse when no real content exists.
Two bugs fixed:
1. Removed 2048 maxTokens cap that overrode the configured 65536 default,
   causing thinking models to exhaust output tokens on reasoning.
2. Added Gemini-specific non-thought extraction that skips thought:true
   parts and throws emptyThinkingResponse when no real content exists.
65536 gave thinking models too much runway, causing very long response
times. 8192 provides enough headroom for thinking (~6K) plus the JSON
response (~1.5K) without excessive delays.
65536 gave thinking models too much runway, causing very long response
times. 8192 provides enough headroom for thinking (~6K) plus the JSON
response (~1.5K) without excessive delays.
Switch API base URL from .org to .net (503 outage). Rewrite
relevance scoring with tiered name matching, category awareness,
and fetch-50-return-15 strategy so generic queries like "banana"
return the whole food first instead of branded chips/snacks.
# Conflicts:
#	Loop/Localizable.xcstrings
computeGlucoseStats was writing to self.lastGlucoseForAGP from within
an async let concurrent context, causing heap corruption on newer Swift
runtimes ("freed pointer was not the last allocation"). Returns AGP
data via struct instead of mutating self during concurrent execution.
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