feat(codex): pass base model to enable conditional image_generation tool injection
- Modified `ensureImageGenerationTool` to accept `baseModel` for conditional logic. - Ensured `gpt-5.3-codex-spark` models bypass image_generation tool injection. - Updated relevant tests and executor logic to reflect changes.
This commit is contained in:
@@ -180,7 +180,7 @@ func (e *CodexExecutor) Execute(ctx context.Context, auth *cliproxyauth.Auth, re
|
|||||||
body, _ = sjson.DeleteBytes(body, "safety_identifier")
|
body, _ = sjson.DeleteBytes(body, "safety_identifier")
|
||||||
body, _ = sjson.DeleteBytes(body, "stream_options")
|
body, _ = sjson.DeleteBytes(body, "stream_options")
|
||||||
body = normalizeCodexInstructions(body)
|
body = normalizeCodexInstructions(body)
|
||||||
body = ensureImageGenerationTool(body)
|
body = ensureImageGenerationTool(body, baseModel)
|
||||||
|
|
||||||
url := strings.TrimSuffix(baseURL, "/") + "/responses"
|
url := strings.TrimSuffix(baseURL, "/") + "/responses"
|
||||||
httpReq, err := e.cacheHelper(ctx, from, url, req, body)
|
httpReq, err := e.cacheHelper(ctx, from, url, req, body)
|
||||||
@@ -327,7 +327,7 @@ func (e *CodexExecutor) executeCompact(ctx context.Context, auth *cliproxyauth.A
|
|||||||
body, _ = sjson.SetBytes(body, "model", baseModel)
|
body, _ = sjson.SetBytes(body, "model", baseModel)
|
||||||
body, _ = sjson.DeleteBytes(body, "stream")
|
body, _ = sjson.DeleteBytes(body, "stream")
|
||||||
body = normalizeCodexInstructions(body)
|
body = normalizeCodexInstructions(body)
|
||||||
body = ensureImageGenerationTool(body)
|
body = ensureImageGenerationTool(body, baseModel)
|
||||||
|
|
||||||
url := strings.TrimSuffix(baseURL, "/") + "/responses/compact"
|
url := strings.TrimSuffix(baseURL, "/") + "/responses/compact"
|
||||||
httpReq, err := e.cacheHelper(ctx, from, url, req, body)
|
httpReq, err := e.cacheHelper(ctx, from, url, req, body)
|
||||||
@@ -422,7 +422,7 @@ func (e *CodexExecutor) ExecuteStream(ctx context.Context, auth *cliproxyauth.Au
|
|||||||
body, _ = sjson.DeleteBytes(body, "stream_options")
|
body, _ = sjson.DeleteBytes(body, "stream_options")
|
||||||
body, _ = sjson.SetBytes(body, "model", baseModel)
|
body, _ = sjson.SetBytes(body, "model", baseModel)
|
||||||
body = normalizeCodexInstructions(body)
|
body = normalizeCodexInstructions(body)
|
||||||
body = ensureImageGenerationTool(body)
|
body = ensureImageGenerationTool(body, baseModel)
|
||||||
|
|
||||||
url := strings.TrimSuffix(baseURL, "/") + "/responses"
|
url := strings.TrimSuffix(baseURL, "/") + "/responses"
|
||||||
httpReq, err := e.cacheHelper(ctx, from, url, req, body)
|
httpReq, err := e.cacheHelper(ctx, from, url, req, body)
|
||||||
@@ -827,7 +827,11 @@ func normalizeCodexInstructions(body []byte) []byte {
|
|||||||
var imageGenToolJSON = []byte(`{"type":"image_generation","output_format":"png"}`)
|
var imageGenToolJSON = []byte(`{"type":"image_generation","output_format":"png"}`)
|
||||||
var imageGenToolArrayJSON = []byte(`[{"type":"image_generation","output_format":"png"}]`)
|
var imageGenToolArrayJSON = []byte(`[{"type":"image_generation","output_format":"png"}]`)
|
||||||
|
|
||||||
func ensureImageGenerationTool(body []byte) []byte {
|
func ensureImageGenerationTool(body []byte, baseModel string) []byte {
|
||||||
|
if strings.HasSuffix(baseModel, "spark") {
|
||||||
|
return body
|
||||||
|
}
|
||||||
|
|
||||||
tools := gjson.GetBytes(body, "tools")
|
tools := gjson.GetBytes(body, "tools")
|
||||||
if !tools.Exists() || !tools.IsArray() {
|
if !tools.Exists() || !tools.IsArray() {
|
||||||
body, _ = sjson.SetRawBytes(body, "tools", imageGenToolArrayJSON)
|
body, _ = sjson.SetRawBytes(body, "tools", imageGenToolArrayJSON)
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
|
|
||||||
func TestEnsureImageGenerationTool_NoTools(t *testing.T) {
|
func TestEnsureImageGenerationTool_NoTools(t *testing.T) {
|
||||||
body := []byte(`{"model":"gpt-5.4","input":"draw a cat"}`)
|
body := []byte(`{"model":"gpt-5.4","input":"draw a cat"}`)
|
||||||
result := ensureImageGenerationTool(body)
|
result := ensureImageGenerationTool(body, "gpt-5.4")
|
||||||
|
|
||||||
tools := gjson.GetBytes(result, "tools")
|
tools := gjson.GetBytes(result, "tools")
|
||||||
if !tools.IsArray() {
|
if !tools.IsArray() {
|
||||||
@@ -28,7 +28,7 @@ func TestEnsureImageGenerationTool_NoTools(t *testing.T) {
|
|||||||
|
|
||||||
func TestEnsureImageGenerationTool_ExistingToolsWithoutImageGen(t *testing.T) {
|
func TestEnsureImageGenerationTool_ExistingToolsWithoutImageGen(t *testing.T) {
|
||||||
body := []byte(`{"model":"gpt-5.4","tools":[{"type":"function","name":"get_weather","parameters":{}}]}`)
|
body := []byte(`{"model":"gpt-5.4","tools":[{"type":"function","name":"get_weather","parameters":{}}]}`)
|
||||||
result := ensureImageGenerationTool(body)
|
result := ensureImageGenerationTool(body, "gpt-5.4")
|
||||||
|
|
||||||
tools := gjson.GetBytes(result, "tools")
|
tools := gjson.GetBytes(result, "tools")
|
||||||
arr := tools.Array()
|
arr := tools.Array()
|
||||||
@@ -45,7 +45,7 @@ func TestEnsureImageGenerationTool_ExistingToolsWithoutImageGen(t *testing.T) {
|
|||||||
|
|
||||||
func TestEnsureImageGenerationTool_AlreadyPresent(t *testing.T) {
|
func TestEnsureImageGenerationTool_AlreadyPresent(t *testing.T) {
|
||||||
body := []byte(`{"model":"gpt-5.4","tools":[{"type":"image_generation","output_format":"webp"},{"type":"function","name":"f1"}]}`)
|
body := []byte(`{"model":"gpt-5.4","tools":[{"type":"image_generation","output_format":"webp"},{"type":"function","name":"f1"}]}`)
|
||||||
result := ensureImageGenerationTool(body)
|
result := ensureImageGenerationTool(body, "gpt-5.4")
|
||||||
|
|
||||||
tools := gjson.GetBytes(result, "tools")
|
tools := gjson.GetBytes(result, "tools")
|
||||||
arr := tools.Array()
|
arr := tools.Array()
|
||||||
@@ -59,7 +59,7 @@ func TestEnsureImageGenerationTool_AlreadyPresent(t *testing.T) {
|
|||||||
|
|
||||||
func TestEnsureImageGenerationTool_EmptyToolsArray(t *testing.T) {
|
func TestEnsureImageGenerationTool_EmptyToolsArray(t *testing.T) {
|
||||||
body := []byte(`{"model":"gpt-5.4","tools":[]}`)
|
body := []byte(`{"model":"gpt-5.4","tools":[]}`)
|
||||||
result := ensureImageGenerationTool(body)
|
result := ensureImageGenerationTool(body, "gpt-5.4")
|
||||||
|
|
||||||
tools := gjson.GetBytes(result, "tools")
|
tools := gjson.GetBytes(result, "tools")
|
||||||
arr := tools.Array()
|
arr := tools.Array()
|
||||||
@@ -73,7 +73,7 @@ func TestEnsureImageGenerationTool_EmptyToolsArray(t *testing.T) {
|
|||||||
|
|
||||||
func TestEnsureImageGenerationTool_WebSearchAndImageGen(t *testing.T) {
|
func TestEnsureImageGenerationTool_WebSearchAndImageGen(t *testing.T) {
|
||||||
body := []byte(`{"model":"gpt-5.4","tools":[{"type":"web_search"}]}`)
|
body := []byte(`{"model":"gpt-5.4","tools":[{"type":"web_search"}]}`)
|
||||||
result := ensureImageGenerationTool(body)
|
result := ensureImageGenerationTool(body, "gpt-5.4")
|
||||||
|
|
||||||
tools := gjson.GetBytes(result, "tools")
|
tools := gjson.GetBytes(result, "tools")
|
||||||
arr := tools.Array()
|
arr := tools.Array()
|
||||||
@@ -87,3 +87,15 @@ func TestEnsureImageGenerationTool_WebSearchAndImageGen(t *testing.T) {
|
|||||||
t.Fatalf("expected second tool type=image_generation, got %s", arr[1].Get("type").String())
|
t.Fatalf("expected second tool type=image_generation, got %s", arr[1].Get("type").String())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestEnsureImageGenerationTool_GPT53CodexSparkDoesNotInjectTool(t *testing.T) {
|
||||||
|
body := []byte(`{"model":"gpt-5.3-codex-spark","input":"draw a cat"}`)
|
||||||
|
result := ensureImageGenerationTool(body, "gpt-5.3-codex-spark")
|
||||||
|
|
||||||
|
if string(result) != string(body) {
|
||||||
|
t.Fatalf("expected body to be unchanged, got %s", string(result))
|
||||||
|
}
|
||||||
|
if gjson.GetBytes(result, "tools").Exists() {
|
||||||
|
t.Fatalf("expected no tools for gpt-5.3-codex-spark, got %s", gjson.GetBytes(result, "tools").Raw)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user