Skip to content

feat(ai): per-card re-analyze with provider override + Apple Intelligence provider#262

Open
joceqo wants to merge 7 commits intoJerryZLiu:mainfrom
joceqo:feat/reanalyze-menu
Open

feat(ai): per-card re-analyze with provider override + Apple Intelligence provider#262
joceqo wants to merge 7 commits intoJerryZLiu:mainfrom
joceqo:feat/reanalyze-menu

Conversation

@joceqo
Copy link
Copy Markdown
Contributor

@joceqo joceqo commented Apr 23, 2026

Summary

  • Adds a sparkles (✦) button to each ActivityCard that opens a provider picker — user can re-analyze any card with a different LLM without touching global settings
  • Adds Apple Intelligence (Apfel) as a new provider option using on-device FoundationModels + Vision OCR — zero network, zero cost

Details

Re-analyze menu (ActivityCardReanalyzeMenu.swift — new)

  • ReanalyzePickerOverlay lists primary / secondary / tertiary providers + Apple Intelligence
  • Calls AnalysisManager.reanalyzeCard(_:providerOverride:) with the chosen provider
  • Card shows a spinner while processing; result updates in-place

AnalysisManager.swift

  • New reanalyzeCard(_:providerOverride:chatToolOverride:stepHandler:completion:) — fetches screenshots for the card's time window, re-runs the full pipeline with the override, saves updated result

LLMService.swift

  • processBatch(providerOverride:chatToolOverride:...) overload respects the per-call override without mutating global state

Apple Intelligence provider (Core/AI/Apfel/ — new)

  • AppleOCRTranscriberVNRecognizeTextRequest on screenshot images → structured text
  • ApfelLanguageModel — wraps FoundationModels.LanguageModel for on-device summarization
  • ApfelProvider — implements LLMProvider; falls back gracefully if device doesn't support FoundationModels

LLMTypes.swift

  • .apfel added to LLMProviderType + LLMProviderID
  • Tertiary provider slot added to LLMProviderRoutingPreferences

Test plan

  • Long-press / hover a card → sparkles button appears
  • Tap sparkles → picker lists available providers
  • Pick a different provider → card re-analyzes and badge updates to new provider
  • On supported device: pick Apple Intelligence → analysis runs fully offline

Notes

Requires macOS 15+ for FoundationModels. The Apfel provider gracefully no-ops on older systems — existing provider routing is unaffected.

🤖 Generated with Claude Code

@JerryZLiu
Copy link
Copy Markdown
Owner

have you tested the apple intelligence performance on dayflow tasks?

@joceqo
Copy link
Copy Markdown
Contributor Author

joceqo commented Apr 24, 2026

not really, plus it does not have vision but its nice to always have fallbacjk but i will make some test and update you. Apple intelligence is not great but its nice implementing, using lm studio can bloat ram maybe using Apple intelligence when ram i bloated could be nice and queue or let user retry card with better llm with vision. And soon Apple intelligence will have vision

* feat: add personal plugin extension points

- PersonalPlugins.start() called once in AppDelegate — all future
  personal features register here, no more upstream file changes
- DayflowNotifications.swift defines canonical notification names
- DailyRecapScheduler posts dayflowDailyRecapCompleted after success
- AppDelegate and DailyRecapScheduler are the only upstream touches,
  never need to change again for new personal features

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* debug: re-sign Sparkle Installer.xpc with get-task-allow

Adds Debug.entitlements (get-task-allow=true) and a post-build shell
script phase that re-signs Sparkle's Installer.xpc bundle in Debug
builds only, allowing lldb/Xcode to attach to org.sparkle-project.InstallerLauncher.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
@joceqo joceqo force-pushed the feat/reanalyze-menu branch from 6835cdc to f63c52e Compare April 26, 2026 16:46
joceqo and others added 6 commits April 26, 2026 19:14
Xcode sandbox blocks codesign from reading files not declared as
explicit inputs. Adding the entitlements path to inputPaths grants
the script sandbox access.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
ENABLE_USER_SCRIPT_SANDBOXING=NO on the Dayflow Debug config so the
re-sign build phase can read/write the XPC bundle and entitlements
without sandbox denials. Release unaffected (phase exits early anyway).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
#3)

Adds IgnoredAppsPreferences (UserDefaults-backed list of app bundle IDs)
and a short-circuit in ScreenRecorder.captureScreenshot that returns early
when the frontmost app's bundle ID is in the list.

This PR ships the core logic only. A Settings UI for managing the list
will follow in a subsequent PR against the updated SettingsProvidersTabView
layout.

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Fully on-device LLM provider that uses Apple Vision OCR for transcribing
screenshots and Apple Intelligence (FoundationModels) for card generation.
Requires macOS 26+ with Apple Intelligence enabled.

Changes:
- New Apfel/ directory: ApfelProvider, ApfelLanguageModel, AppleOCRTranscriber
- Adds .apfel case to LLMProviderType and LLMProviderID (plus all
  exhaustive switches: migration, analytics, labels, DailyRecapProvider
  migration, AppDelegate analytics, ProvidersSettingsViewModel).
- LLMService routes .apfel through makeApfelProvider() for both batch and
  text operations; returns a clear error when Apple Intelligence isn't
  available on the current device.

This PR ships the provider wiring only. Selecting "Apple Intelligence"
from the Settings UI will be a follow-up against the v1.10 settings
redesign.

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Adds a small badge next to the time range showing which model generated
each activity card. For local/Ollama providers, the badge shows the
actual model ID (e.g. "Qwen3-VL-4B-Instruct") instead of just "Local".

Changes:
- New llm_label TEXT column on timeline_cards (nullable, safe migration).
- Thread llmLabel: String? through TimelineCardShell → TimelineCard →
  TimelineActivity and all card construction sites.
- LLMService captures activeContext.providerLabel (the provider that
  actually generated the card, after any fallback) and passes it to
  the card save; a new enrichedProviderLabel substitutes the configured
  local model id for .ollama.
- ActivityCard renders a subtle lavender pill between the time range
  and the category badge with a friendly display name (Gemini / Claude /
  ChatGPT / Apple AI / Dayflow) or the raw model id for local.

Old cards without the column show no badge — purely additive.

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Lets users re-run LLM analysis on a single card using any configured
provider (primary/secondary/tertiary), independent of the app's default.
Used as an escape hatch when the primary output is wrong or the user
wants to compare providers on the same source batch.

Changes:
- LLMService gets a new processBatch overload that accepts
  providerOverride + chatToolOverride. When an override is set, the
  configured-backup chain is skipped (caller's choice wins).
- AnalysisManager gets a reanalyzeCard(_:providerOverride:...) method
  that looks up the card's batch, validates screenshots still exist,
  resets observations + batch status, then re-runs processBatch with
  the chosen provider.
- New ActivityCardReanalyzeMenu + ReanalyzePickerOverlay SwiftUI views
  provide the UI: a sparkles button on each card opens an overlay
  listing the user's configured primary/secondary/tertiary providers
  (each with appropriate subtitle — local model ID, CLI tool, etc.)
- StorageManager gets batchIdForTimelineCard(_:) helper.
- LLMProviderRoutingPreferences extended with tertiary preferences.

Based on feat/apfel-provider so the .apfel option works out of the box.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@joceqo joceqo force-pushed the feat/reanalyze-menu branch from f63c52e to b9120f2 Compare April 26, 2026 17:34
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.

2 participants