Compare commits

...

5 Commits

Author SHA1 Message Date
github-actions[bot]
152d74d160 Update version to v1.4.229 and commit 2025-07-05 01:59:22 +00:00
Kayvan Sylvan
4e16bbccd8 Merge pull request #1574 from ksylvan/0704-image-tool-model-validation
Add Model Validation for Image Generation and Fix CLI Flag Mapping
2025-07-04 18:57:51 -07:00
Kayvan Sylvan
60174f41a4 refactor: extract supported models list to shared constant for image generation validation
## CHANGES

• Extract hardcoded model lists into shared constant
• Create ImageGenerationSupportedModels variable for reusability
• Update supportsImageGeneration function to use shared constant
• Refactor error messages to reference centralized model list
• Add documentation comment for supported models variable
• Import strings package in test file
• Consolidate duplicate model validation logic across files
2025-07-04 18:52:49 -07:00
Kayvan Sylvan
ad4683952e Merge branch 'main' into 0704-image-tool-model-validation 2025-07-04 18:45:08 -07:00
Kayvan Sylvan
86a044735b feat: add model validation for image generation support
### CHANGES

- Add model field to `BuildChatOptions` method
- Implement `supportsImageGeneration` function for model checks
- Validate model supports image generation in `sendResponses`
- Remove `mars-colony.png` from repository
- Add tests for `supportsImageGeneration` function
- Validate image file support in `TestModelValidationLogic`
2025-07-04 18:40:20 -07:00
7 changed files with 148 additions and 2 deletions

View File

@@ -289,6 +289,7 @@ func (o *Flags) BuildChatOptions() (ret *common.ChatOptions, err error) {
}
ret = &common.ChatOptions{
Model: o.Model,
Temperature: o.Temperature,
TopP: o.TopP,
PresencePenalty: o.PresencePenalty,

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 MiB

View File

@@ -1 +1 @@
"1.4.228"
"1.4.229"

View File

@@ -128,6 +128,11 @@ func (o *Client) Send(ctx context.Context, msgs []*chat.ChatCompletionMessage, o
}
func (o *Client) sendResponses(ctx context.Context, msgs []*chat.ChatCompletionMessage, opts *common.ChatOptions) (ret string, err error) {
// Validate model supports image generation if image file is specified
if opts.ImageFile != "" && !supportsImageGeneration(opts.Model) {
return "", fmt.Errorf("model '%s' does not support image generation. Supported models: %s", opts.Model, strings.Join(ImageGenerationSupportedModels, ", "))
}
req := o.buildResponseParams(msgs, opts)
var resp *responses.Response

View File

@@ -18,6 +18,26 @@ import (
const ImageGenerationResponseType = "image_generation_call"
const ImageGenerationToolType = "image_generation"
// ImageGenerationSupportedModels lists all models that support image generation
var ImageGenerationSupportedModels = []string{
"gpt-4o",
"gpt-4o-mini",
"gpt-4.1",
"gpt-4.1-mini",
"gpt-4.1-nano",
"o3",
}
// supportsImageGeneration checks if the given model supports the image_generation tool
func supportsImageGeneration(model string) bool {
for _, supportedModel := range ImageGenerationSupportedModels {
if model == supportedModel {
return true
}
}
return false
}
// getOutputFormatFromExtension determines the API output format based on file extension
func getOutputFormatFromExtension(imagePath string) string {
if imagePath == "" {

View File

@@ -1,6 +1,8 @@
package openai
import (
"fmt"
"strings"
"testing"
"github.com/danielmiessler/fabric/chat"
@@ -218,3 +220,121 @@ func TestAddImageGenerationToolWithDynamicFormat(t *testing.T) {
})
}
}
func TestSupportsImageGeneration(t *testing.T) {
tests := []struct {
name string
model string
expected bool
}{
{
name: "gpt-4o supports image generation",
model: "gpt-4o",
expected: true,
},
{
name: "gpt-4o-mini supports image generation",
model: "gpt-4o-mini",
expected: true,
},
{
name: "gpt-4.1 supports image generation",
model: "gpt-4.1",
expected: true,
},
{
name: "gpt-4.1-mini supports image generation",
model: "gpt-4.1-mini",
expected: true,
},
{
name: "gpt-4.1-nano supports image generation",
model: "gpt-4.1-nano",
expected: true,
},
{
name: "o3 supports image generation",
model: "o3",
expected: true,
},
{
name: "o1 does not support image generation",
model: "o1",
expected: false,
},
{
name: "o1-mini does not support image generation",
model: "o1-mini",
expected: false,
},
{
name: "o3-mini does not support image generation",
model: "o3-mini",
expected: false,
},
{
name: "gpt-4 does not support image generation",
model: "gpt-4",
expected: false,
},
{
name: "gpt-3.5-turbo does not support image generation",
model: "gpt-3.5-turbo",
expected: false,
},
{
name: "empty model does not support image generation",
model: "",
expected: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := supportsImageGeneration(tt.model)
assert.Equal(t, tt.expected, result)
})
}
}
func TestModelValidationLogic(t *testing.T) {
t.Run("Unsupported model with image file should return validation error", func(t *testing.T) {
opts := &common.ChatOptions{
Model: "o1-mini",
ImageFile: "/tmp/output.png",
}
// Test the validation logic directly
if opts.ImageFile != "" && !supportsImageGeneration(opts.Model) {
err := fmt.Errorf("model '%s' does not support image generation. Supported models: %s", opts.Model, strings.Join(ImageGenerationSupportedModels, ", "))
assert.Contains(t, err.Error(), "does not support image generation")
assert.Contains(t, err.Error(), "o1-mini")
assert.Contains(t, err.Error(), "Supported models:")
} else {
t.Error("Expected validation to trigger")
}
})
t.Run("Supported model with image file should not trigger validation", func(t *testing.T) {
opts := &common.ChatOptions{
Model: "gpt-4o",
ImageFile: "/tmp/output.png",
}
// Test the validation logic directly
shouldFail := opts.ImageFile != "" && !supportsImageGeneration(opts.Model)
assert.False(t, shouldFail, "Validation should not trigger for supported model")
})
t.Run("Unsupported model without image file should not trigger validation", func(t *testing.T) {
opts := &common.ChatOptions{
Model: "o1-mini",
ImageFile: "", // No image file
}
// Test the validation logic directly
shouldFail := opts.ImageFile != "" && !supportsImageGeneration(opts.Model)
assert.False(t, shouldFail, "Validation should not trigger when no image file is specified")
})
}

View File

@@ -1,3 +1,3 @@
package main
var version = "v1.4.228"
var version = "v1.4.229"