Files
oai-swift/oAI/ViewModels
rune 8006f22d69 Add real Transcript-based session persistence (step 8)
Eighth piece of the Apple Intelligence tool-calling work (see
/Users/rune/.claude/plans/apple-intelligence-tool-calling-plan.md).
Reopening a saved conversation now restores the model's real
tool-call/tool-output history from a saved FoundationModels.Transcript
instead of falling back to Phase 1's lossy text-summary replay.

Found and confirmed against the real SDK before writing any code: a
live session's own .transcript property (needed to capture one to
save) is macOS 27.0+ only, while reconstructing a session FROM a saved
transcript works at 26.0+ — a real asymmetry, not a minor detail.
Checked with Rune before proceeding: build it gated behind
#available(macOS 27.0, *), same pattern this file already uses for
mapProviderError's LanguageModelError/GenerationError split. Inert on
macOS 26.x (falls back cleanly to the existing text-summary replay,
not broken), strengthens automatically as the OS matures.

AppleTranscriptService (new) persists one JSON file per conversation
under Application Support/oAI/apple_transcripts/, named directly by
UUID — no DB migration needed, since the filename is fully derivable
from the conversation's own id (unlike notes.md, which needs a stored
filename since it also embeds a human-readable display name).
Transcript itself is Codable at macOS 26.0+, so only the live-session
read is gated, not the encode/decode. Cleaned up on conversation
deletion (DatabaseService.deleteConversation, alongside the existing
notes.md cleanup) so a stale file never lingers for a deleted
conversation. Only ever saved for a real, already-saved conversation
(persistTranscriptId: UUID?, nil for a not-yet-saved chat) — an
unsaved chat's ephemeral session key never gets written, so there's no
unbounded orphan-file accumulation from chats that are never saved.

4 new tests (save/load round-trip with a real Transcript() value,
missing-file returns nil, delete is idempotent, deterministic path
derivation). 429 tests total, stable across two consecutive full
runs, and confirmed no leftover test-artifact files on disk after the
run.
2026-08-28 12:51:28 +02:00
..