| 1 | package control |
| 2 | |
| 3 | import ( |
| 4 | "context" |
| 5 | "fmt" |
| 6 | |
| 7 | "reasonix/internal/agent" |
| 8 | "reasonix/internal/imageinput" |
| 9 | "reasonix/internal/provider" |
| 10 | ) |
| 11 | |
| 12 | // prepareVisionTurn shares the same per-session processor as tool results. |
| 13 | func (c *Controller) prepareVisionTurn(ctx context.Context, input string, images []string) (string, context.Context, error) { |
| 14 | prepared, _ := ctx.Value(preparedImageReferencesContextKey{}).(preparedImageReferences) |
| 15 | if c == nil || (len(images) == 0 && len(prepared.inputs) == 0) || c.imageInputEnabled() { |
| 16 | return input, ctx, nil |
| 17 | } |
| 18 | if c.visionModel == "" && !prepared.requiresImageUnderstanding { |
| 19 | // Keep the frozen bytes available to vision-capable child agents while |
| 20 | // withholding them from the text-only parent provider request. |
| 21 | return input, agent.WithUserImageInputs(ctx, nil), nil |
| 22 | } |
| 23 | var svc *imageinput.Service |
| 24 | var history func() []provider.Message |
| 25 | if c.executor != nil { |
| 26 | svc = c.executor.ImageInput() |
| 27 | history = c.executor.Session().Snapshot |
| 28 | } |
| 29 | if svc == nil { |
| 30 | svc = imageinput.New(imageinput.Config{Model: c.visionModel, Resolve: c.visionProviderResolver, Select: c.visionModelSelector}) |
| 31 | } |
| 32 | target, err := svc.SelectModel(c.selection.ref, images) |
| 33 | if err != nil { |
| 34 | return input, ctx, fmt.Errorf("图片理解失败,当前回答尚未发送:%w", err) |
| 35 | } |
| 36 | if len(prepared.inputs) > 0 { |
| 37 | route, routeErr := c.imageRequestRoute(target) |
| 38 | if routeErr != nil { |
| 39 | return input, ctx, routeErr |
| 40 | } |
| 41 | images, err = c.resolveImageInputsForRoute(ctx, prepared.inputs, route) |
| 42 | if err != nil { |
| 43 | return input, ctx, err |
| 44 | } |
| 45 | } |
| 46 | summary, err := svc.UnderstandSelected(ctx, target, images, history, c.sink) |
| 47 | if err != nil { |
| 48 | return input, ctx, fmt.Errorf("图片理解失败,当前回答尚未发送:%w", err) |
| 49 | } |
| 50 | return imageinput.AppendSummary(input, summary), agent.WithVisionSummary(ctx, summary), nil |
| 51 | } |
| 52 |