-
Notifications
You must be signed in to change notification settings - Fork 3
Multimodal
phinn edited this page Sep 18, 2026
·
2 revisions
🌐 Language: English | 中文
Direct engine supports multimodal input: images, voice transcription, and region screenshots.
📎 button in the composer (or drag-drop / paste):
- Select one or more images (PNG / JPG / GIF / WebP).
- Large images are sent as-is (no client-side resize —
ponytail:MVP). - Images are injected into the prompt as a special marker:
\x00IMAGES[{name, dataUrl}]\x00. - The Direct engine's
AgentLoopparses this marker and converts to OpenAIimage_urlcontent parts (for OpenAI-compatible providers) or Anthropic base64imageblocks (for Anthropic). -
dropTransient()strips base64 data before persisting todirectHistory— keeps SQLite small.
User types: "What's wrong with this UI?"
+ attaches screenshot.png
↓
Prompt sent: "What's wrong with this UI?\x00IMAGES[{"name":"screenshot.png","dataUrl":"data:image/png;base64,..."}]\x00"
↓
Provider receives: [{type:"text", text:"What's wrong with this UI?"},
{type:"image_url", image_url:{url:"data:image/png;base64,..."}}]
🎤 button in the composer:
- Click → starts recording (browser MediaRecorder API).
- Click again → stops → audio encoded as base64.
- Sent to OpenAI Whisper API (
whisper-1model) for transcription. - Transcribed text fills the composer input.
- Requires an OpenAI-compatible endpoint (Whisper is OpenAI-only).
For realtime voice conversation (bidirectional, natural TTS, Agent tool execution), see Voice-Chat.
TTS (Text-to-Speech):
- Answers can be read aloud via the system
speechSynthesisAPI. - Auto-detects language (Chinese vs English) from the text.
- Strips markdown before reading (code blocks, links, formatting).
- 2000-character limit per utterance.
📸 button in the chat area:
- Click → a full-screen overlay appears (semi-transparent dark layer).
- Drag to select a rectangular region.
- Release → the selected region is cropped from the screen capture.
- Cropped image is injected into the prompt as an image attachment.
- If selection is < 5px in either dimension, the screenshot is auto-cancelled (treat as a click, not a drag).
The overlay uses mouse events bound to document (not the overlay element) to prevent listener leaks and ensure mouseup is captured even outside the overlay.
- Image multimodal requires a provider that supports vision (GLM-4V, GPT-4o, Claude 3.5, etc.).
- Voice transcription requires
whisper-1model access on the configured endpoint. - Screenshots use Electron's desktopCapturer + canvas cropping.
- Claude Code and Codex engines do not support in-app multimodal — use their native capabilities instead.
-
src/main/AgentLoop.ts—\x00IMAGES[...]\x00marker parsing → ContentPart[] -
src/main/glm.ts—image_url(OpenAI) ↔ base64image(Anthropic) conversion;dropTransient() -
src/renderer/app.ts—wireVoice()(recording + Whisper),wireScreenshot()(overlay + crop), file attachment handling