gateImagesForModel decides what to do with attached images given the active model (hybrid B+A strategy). It resolves a vision mode (see resolveVisionMode) and then: - native → pass the images through to the provider (path B); - describe → fold a textual description from a vision model into the pro
(ctx context.Context, images []models.ImageContent)
| 207 | // dropped with a user-facing warning, so a non-vision provider never receives |
| 208 | // an image it cannot decode. |
| 209 | func (cli *ChatCLI) gateImagesForModel(ctx context.Context, images []models.ImageContent) ([]models.ImageContent, string) { |
| 210 | if len(images) == 0 { |
| 211 | return nil, "" |
| 212 | } |
| 213 | |
| 214 | switch cli.resolveVisionMode() { |
| 215 | case visionNative: |
| 216 | return cli.compressImagesForVision(images), "" |
| 217 | case visionOff: |
| 218 | cli.logger.Info("vision: input disabled by CHATCLI_VISION_INPUT=off", |
| 219 | zap.String("provider", cli.Provider), zap.String("model", cli.Model)) |
| 220 | return nil, "" |
| 221 | default: // visionDescribe |
| 222 | if desc, ok := cli.describeImagesFallback(ctx, images); ok { |
| 223 | cli.logger.Info("vision: native vision unavailable, using describe-fallback", |
| 224 | zap.String("provider", cli.Provider), zap.String("model", cli.Model), |
| 225 | zap.Int("images", len(images))) |
| 226 | return nil, desc |
| 227 | } |
| 228 | fmt.Println(i18n.T("vision.warn.model_no_vision", cli.Model)) |
| 229 | cli.logger.Warn("vision: image attached but model has no vision and no fallback is available", |
| 230 | zap.String("provider", cli.Provider), zap.String("model", cli.Model)) |
| 231 | return nil, "" |
| 232 | } |
| 233 | } |
| 234 | |
| 235 | // compressImagesForVision downscales/re-encodes inline image bytes before they |
| 236 | // reach a vision model — cutting upload bytes, latency and (above the edge cap) |
no test coverage detected