Skip to content

Enhance voice transcription, image generation, and attachment handling - #2

Merged
kevinliddel merged 6 commits into
mainfrom
feat/phase_3
Jun 15, 2026
Merged

kevinliddel merged 6 commits into
mainfrom
feat/phase_3

Conversation

@kevinliddel

@kevinliddel kevinliddel commented Jun 15, 2026 •

Copy link
Copy Markdown
Owner

This pull request introduces support for two new native on-device specialists: Whisper (speech-to-text) and Stable Diffusion (image generation), alongside improvements to the core engine's resource management and project structure. The changes add new C/C++ bridges for these specialists, integrate their frameworks into the Xcode project, and update documentation and Swift interfaces to expose their capabilities.

Specialist Integration and Bridging:

  • Added new C/C++ bridges for Whisper (synap_whisper.h/cpp) and Stable Diffusion (synap_sd.h/cpp), enabling on-device speech-to-text and image generation via pure-C APIs for Swift interoperability. [1] [2] [3] [4]
  • Updated the bridging header (SynapLink-Bridging-Header.h) to import the new specialist headers.

Project and Build System Updates:

  • Added whisper.cpp and stable-diffusion.cpp as git submodules, and integrated their frameworks (whisper.xcframework, sd.xcframework) into the Xcode project file, including build and embed steps. [1] [2] [3] [4] [5] [6]
  • Updated documentation and build scripts in README.md to reflect the new frameworks, build instructions, and test scripts for all three native engines.

Core Engine Improvements:

  • Refactored the engine backend initialization to use a reference-counted approach, allowing multiple engines (main model and specialists) to coexist without resource conflicts. [1] [2] [3] [4] [5]

Swift Interface Enhancements:

  • Extended the ChatSession class to expose effective input capabilities (image, audio, media attachment) based on the availability of either the main model or installed specialists.

Summary by CodeRabbit

  • New Features

    • Added speech-to-text transcription for voice input
    • Added text-to-image generation capability
    • Added image understanding for visual input analysis
    • Enabled audio and image attachments in chat
    • Enhanced streaming text display with smooth reveal effect
  • Documentation

    • Added Phase 3 documentation outlining multimodal capabilities and specialist model architecture

…ge description via SmolVLM with support for transient engine management.
…ts and token limits, and replace confirmationDialog with sheet for photo attachments
…nd StreamChunkView for consistent block processing.
@coderabbitai

coderabbitai Bot commented Jun 15, 2026 •

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

Pull request was closed or merged during review

📝 Walkthrough

Walkthrough

Phase 3 adds Whisper (speech-to-text), SmolVLM (vision description), and Stable Diffusion (image generation) as on-demand specialist sidecars. New C++ bridges and xcframework build scripts expose these libraries to Swift through updated headers and an Xcode project. A specialist catalog, download manager, and Swift wrappers integrate the sidecars into ChatSession's media-resolution pipeline. The streaming text renderer is refactored to use typed StreamChunk objects, and the chat UI gains an AttachmentSheet, ImageGenSheet, and model library cards.

Changes

Phase 3 specialist sidecar integration

Layer / File(s) Summary
Native build infrastructure and Xcode wiring
.gitmodules, .gitignore, third_party/whisper.cpp, third_party/stable-diffusion.cpp, scripts/build-frameworks.sh, scripts/build-whisper-xcframework.sh, scripts/build-sd-xcframework.sh, SynapLink.xcodeproj/project.pbxproj, SynapLink/Core/Engine/SynapLink-Bridging-Header.h, scripts/lint-cpp.sh
Adds whisper.cpp and stable-diffusion.cpp submodule pointers; introduces build-frameworks.sh as a unified entry point delegating to per-engine scripts (with configure_and_build/make_framework helpers for iOS simulator, device, and macOS); wires whisper.xcframework and sd.xcframework into the Xcode target link/embed phases and the Swift bridging header; expands lint coverage to new engine files.
Whisper C bridge and macOS smoke test
SynapLink/Core/Engine/synap_whisper.h, SynapLink/Core/Engine/synap_whisper.cpp, tests/whisper-smoke/main.cpp, scripts/test-whisper-macos.sh
Defines the opaque SynapWhisper handle and SYNAP_WHISPER_SAMPLE_RATE constant in a C header with extern "C" guards; implements synap_whisper_create/free/transcribe with greedy sampling, language auto-detection, whitespace trimming, and NUL-terminated output buffer; validates via a WAV-reading smoke-test binary and macOS runner.
Stable Diffusion C bridge and macOS smoke test
SynapLink/Core/Engine/synap_sd.h, SynapLink/Core/Engine/synap_sd.cpp, tests/sd-smoke/main.cpp, scripts/test-sd-macos.sh
Defines the opaque SynapSD handle and four C ABI functions; implements no-op log/progress callbacks, GPU/thread/TAESD configuration, a full generate-to-3-channel-RGB-buffer pipeline using generate_image, and explicit synap_sd_free_rgb; validates via a PPM-writing smoke-test binary and macOS runner.
llama backend shared reference counting
SynapLink/Core/Engine/synap_engine.cpp
Introduces a global std::atomic<int> refcount with backend_retain()/backend_release() helpers; synap_engine_create() retains at entry and releases on all failure paths; synap_engine_free() releases instead of unconditionally freeing, enabling concurrent specialist InferenceEngine instances to coexist safely.
Specialist catalog, download manager, and runtime tuning
SynapLink/Data/DataSources/ModelDownload/SpecialistCatalog.swift, SynapLink/Data/DataSources/ModelDownload/SpecialistManager.swift, SynapLink/Data/DataSources/Inference/RuntimeProfile.swift, SynapLink/Data/DataSources/Inference/InferenceEngine.swift
SpecialistModel enum provides metadata and hub-cache path resolution for whisper/vision/imageGen. SpecialistManager @MainActor singleton manages download/pause/resume/delete lifecycle via HubApi. RuntimeProfile gains specialistUsesGPU, specialistThreads, imageGenSettings (memory-tier-keyed diffusion params), and visionEngineParams. InferenceEngine gains init(label:) for transient specialist instances.
WhisperTranscriber, VisionDescriber, ImageGenerator Swift wrappers
SynapLink/Data/DataSources/Inference/WhisperTranscriber.swift, SynapLink/Data/DataSources/Inference/VisionDescriber.swift, SynapLink/Data/DataSources/Inference/ImageGenerator.swift
WhisperTranscriber decodes audio to mono 16 kHz float32 via AVAudioConverter and calls the Whisper C bridge on a serial queue. VisionDescriber loads a transient InferenceEngine with SmolVLM params, streams a description, then defers unload. ImageGenerator calls the Stable Diffusion C bridge on a dedicated queue and converts the RGB buffer to JPEG via CGImage.
ChatSession media resolution and image generation
SynapLink/Data/DataSources/Inference/ChatSession.swift
Adds canSendImages/canSendAudio/canAttachMedia/audioCaptureSampleRate computed properties. Refactors generate() to call resolveMedia() which routes attachments to direct engine media or sidecar specialists and folds sidecar outputs into promptText. Adds isCreatingImage state and createImage(prompt:) which unloads the main engine during diffusion and posts the result as an assistant message.
Streaming text rendering: StreamChunk, StreamingText, MarkdownText, MessageBubble
SynapLink/Presentation/Components/StreamChunk.swift, SynapLink/Presentation/Components/StreamingText.swift, SynapLink/Presentation/Components/MarkdownText.swift, SynapLink/Presentation/Components/MessageBubble.swift
Introduces StreamChunk (paragraph/heading/code/image/audio), StreamChunkParser, and StreamChunkView. Adds StreamingText view backed by a Typewriter that reveals text at ~30 ms cadence. MarkdownText is rewritten to use StreamChunkParser/StreamChunkView, removing the old MarkdownBlock model. MessageBubble routes to StreamingText during generation and MarkdownText with selection when complete.
Chat UI, model library, and documentation
SynapLink/Presentation/Components/AttachmentSheet.swift, SynapLink/Presentation/Components/ChatInputBar.swift, SynapLink/Presentation/Views/Chat/ImageGenSheet.swift, SynapLink/Presentation/Views/Chat/ChatView.swift, SynapLink/Presentation/Views/ModelLibrary/ModelLibraryView.swift, docs/PHASE_3.md, README.md
Adds AttachmentSheet bottom-sheet picker, ImageGenSheet prompt entry with low-RAM warning, ChatInputBar canSubmit logic for attachment+text, ChatView routing through both sheets with presentAfterSheet delay helper and creatingImageIndicator. ModelLibraryView gains SpecialistCard with download/pause/resume/delete state UI. Phase 3 design doc and README quick-start updated.

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant ChatView
    participant ChatSession
    participant resolveMedia as ChatSession.resolveMedia
    participant WhisperTranscriber
    participant VisionDescriber
    participant ImageGenerator
    participant InferenceEngine

    User->>ChatView: tap send with audio/image attachment
    ChatView->>ChatSession: generate()
    ChatSession->>resolveMedia: resolveMedia(attachments, userText)
    alt audio attachment, no native support
        resolveMedia->>WhisperTranscriber: transcribe(fileURL:languageCode:)
        WhisperTranscriber-->>resolveMedia: transcript String
    else image attachment, no native support
        resolveMedia->>VisionDescriber: describe(imageData:userQuestion:)
        VisionDescriber->>InferenceEngine: load SmolVLM, stream, unload
        InferenceEngine-->>VisionDescriber: description text
        VisionDescriber-->>resolveMedia: description String
    end
    resolveMedia-->>ChatSession: ResolvedMedia(directMedia, promptText)
    ChatSession->>InferenceEngine: generate with resolved media/prompt

    User->>ChatView: tap "Create with AI"
    ChatView->>ChatSession: createImage(prompt:)
    ChatSession->>InferenceEngine: unload main model
    ChatSession->>ImageGenerator: generate(prompt:negativePrompt:)
    ImageGenerator-->>ChatSession: JPEG Data
    ChatSession->>InferenceEngine: reload main model
    ChatSession-->>ChatView: new assistant message with image attachment
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Possibly related PRs

  • kevinliddel/SynapLink#1: Directly modifies ChatSession attachment handling, media injection into the generation pipeline, and MessageBubble rendering — all of which this PR extends with sidecar routing and new specialist attachment types.

Poem

🐇 Three new friends join the warren today,
Whisper speaks what the microphone plays,
SmolVLM sees the pictures you share,
Stable Diffusion paints art from thin air —
The llama refcount stays tidy and right,
Four gigabytes hold the whole magic night! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 23.81% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately summarizes the main changes: voice transcription (Whisper), image generation (Stable Diffusion), and attachment handling across the codebase.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/phase_3

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@kevinliddel
kevinliddel merged commit 467f2f0 into main Jun 15, 2026
3 of 5 checks passed
@kevinliddel
kevinliddel deleted the feat/phase_3 branch June 15, 2026 12:36
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