MCPcopy Create free account
hub / github.com/diillson/chatcli / compressImagesForVision

Method compressImagesForVision

cli/cli_file_processing.go:245–287  ·  view source on GitHub ↗

compressImagesForVision downscales/re-encodes inline image bytes before they reach a vision model — cutting upload bytes, latency and (above the edge cap) the billed vision tokens. Keyless and pure-Go. Controlled by: CHATCLI_VISION_COMPRESS on|off (default on) CHATCLI_VISION_MAX_EDGE

(images []models.ImageContent)

Source from the content-addressed store, hash-verified

243// URL-only images (no inline bytes) are passed through untouched. The function
244// is conservative: imgcompress never inflates a payload and never drops alpha.
245func (cli *ChatCLI) compressImagesForVision(images []models.ImageContent) []models.ImageContent {
246 if strings.EqualFold(strings.TrimSpace(utils.GetEnvOrDefault("CHATCLI_VISION_COMPRESS", "on")), "off") {
247 return images
248 }
249 opts := imgcompress.DefaultOptions()
250 if v := strings.TrimSpace(os.Getenv("CHATCLI_VISION_MAX_EDGE")); v != "" {
251 if n, err := strconv.Atoi(v); err == nil && n > 0 {
252 opts.MaxEdge = n
253 }
254 }
255 if v := strings.TrimSpace(os.Getenv("CHATCLI_VISION_JPEG_QUALITY")); v != "" {
256 if n, err := strconv.Atoi(v); err == nil && n >= 1 && n <= 100 {
257 opts.JPEGQuality = n
258 }
259 }
260
261 totalSaved := 0
262 out := make([]models.ImageContent, len(images))
263 copy(out, images)
264 for i := range out {
265 if len(out[i].Data) == 0 {
266 continue // URL-only; nothing to recompress
267 }
268 data, res := imgcompress.Compress(out[i].Data, out[i].MediaType, opts)
269 if !res.Changed {
270 continue
271 }
272 out[i].Data = data
273 out[i].MediaType = res.OutMediaType
274 totalSaved += res.SavedBytes()
275 cli.logger.Debug("vision: image recompressed",
276 zap.String("file", out[i].FileName),
277 zap.Int("orig_bytes", res.OrigBytes), zap.Int("new_bytes", res.NewBytes),
278 zap.String("orig_dim", fmt.Sprintf("%dx%d", res.OrigW, res.OrigH)),
279 zap.String("new_dim", fmt.Sprintf("%dx%d", res.NewW, res.NewH)),
280 zap.String("out_type", res.OutMediaType))
281 }
282 if totalSaved > 0 {
283 cli.logger.Info("vision: image compression saved bytes",
284 zap.Int("images", len(out)), zap.Int("bytes_saved", totalSaved))
285 }
286 return out
287}
288
289// imageFileExtensions are the extensions we treat as vision attachments.
290var imageFileExtensions = map[string]bool{

Callers 1

gateImagesForModelMethod · 0.95

Calls 6

GetEnvOrDefaultFunction · 0.92
DefaultOptionsFunction · 0.92
CompressFunction · 0.92
InfoMethod · 0.65
SavedBytesMethod · 0.45
StringMethod · 0.45

Tested by

no test coverage detected