fix(vision): 图像 URL 取回失败的 WARN 带来源主机(可诊断且不外泄路径/查询串/凭据)
CI / Backend (build / vet / test / cross-compile) (push) Has been cancelled
CI / Frontend (tsc + vite build) (push) Has been cancelled

- loop 解析点用结构断言取 SourceFailure 的主机(errors.As 穿透 %w 包装),
  不导入 vision 包、不引入方向性依赖;拿不到来源时留空串而不编造。
- 新增 TestImageSourceHost 四例(nil/普通错误/包装后来源/空主机),
  变异验证:把返回值改成 "" 该用例必红(已复跑确认)。
This commit is contained in:
AskaEth committed 2026-10-04 16:46:57 +08:00
1 parent 910d154d35
commit 127c32b440
2 files changed
+52 -1

No files matched your search

+17 -1
View File
@@ -2,6 +2,7 @@ package loop
import (
"context"
"errors"
"git.yeij.top/AskaEth/Cyrene_v2/internal/runtime/model"
)
@@ -47,7 +48,10 @@ func (l *Loop) resolveImages(ctx context.Context, messages []model.Message) []mo
}
resolved, err := l.imageResolver.Resolve(ctx, m)
if err != nil {
l.log.Warn("image resolve", "error", err)
// 图像解析失败(尤其:URL 来源已失效)在这里留下可诊断信号 ——
// 原消息照旧保留、回合继续,但不再静默:host 是来源 URL 的主机,
// 不含路径、查询串与凭据(由 SourceFailure 保证)。
l.log.Warn("image resolve", "error", err, "host", imageSourceHost(err))
out[i] = m
continue
}
@@ -60,6 +64,18 @@ func (l *Loop) resolveImages(ctx context.Context, messages []model.Message) []mo
return out
}
// imageSourceHost 从图像解析失败错误里取出来源主机(vision 的取回失败
// 错误以结构断言暴露它),使 WARN 能定位到具体来源。错误不带这个信息
// (解析失败、非图像、无解析器等)时返回空串。用结构断言而不是导入
// vision 包:loop 只需知道「有个东西能报主机」,不需要依赖取回实现。
func imageSourceHost(err error) string {
var withHost interface{ ImageSourceHost() string }
if errors.As(err, &withHost) {
return withHost.ImageSourceHost()
}
return ""
}
// messageHasImage 报告 msg 是否有任何内容部件是图像部件。
func messageHasImage(m model.Message) bool {
for _, part := range m.Content {