oaiContentToText() in translate.ts was stripping image_url content parts to empty strings, silently dropping all images before they reached the upstream model. This caused vision-capable models (kimi k2.7) to hallucinate image descriptions from context clues instead of actually seeing the image.
Fix: added oaiContentToParts() which converts OpenAI image_url content parts into pi-ai ImageContent blocks ({type:'image', data, mimeType}). The user message handler in oaiMessagesToContext now uses it unconditionally.