473 lines · 15.5 KB · Go
RawDownload
package helps import (	"bytes"	"encoding/json"	"os"	"strings"	"testing" 	"github.com/router-for-me/CLIProxyAPI/v7/internal/config"	"github.com/tidwall/gjson") type countingPayloadMarshaler struct {	calls *int	value string} func (m countingPayloadMarshaler) MarshalJSON() ([]byte, error) {	*m.calls = *m.calls + 1	return json.Marshal(m.value)} func TestSetStringIfDifferentReusesCanonicalValue(t *testing.T) {	input := []byte(`{"model":"gpt-test","messages":[]}`)	output := SetStringIfDifferent(input, "model", "gpt-test")	if &output[0] != &input[0] {		t.Fatal("canonical string caused a payload copy")	}} func TestSetStringIfDifferentNormalizesWrongType(t *testing.T) {	input := []byte(`{"model":123}`)	original := bytes.Clone(input)	output := SetStringIfDifferent(input, "model", "123")	model := gjson.GetBytes(output, "model")	if model.Type != gjson.String || model.String() != "123" {		t.Fatalf("model = %s, want string 123", model.Raw)	}	if !bytes.Equal(input, original) {		t.Fatal("input payload was modified in place")	}} func TestSetBoolIfDifferentReusesCanonicalValue(t *testing.T) {	input := []byte(`{"stream":true,"input":[]}`)	output := SetBoolIfDifferent(input, "stream", true)	if &output[0] != &input[0] {		t.Fatal("canonical boolean caused a payload copy")	}} func TestSetBoolIfDifferentNormalizesWrongType(t *testing.T) {	input := []byte(`{"stream":"true"}`)	output := SetBoolIfDifferent(input, "stream", true)	if stream := gjson.GetBytes(output, "stream"); stream.Type != gjson.True {		t.Fatalf("stream = %s, want boolean true", stream.Raw)	}} func TestSetRawIfDifferentReusesIdenticalRawValue(t *testing.T) {	input := []byte(`{"metadata":{"source":"executor"},"input":[]}`)	output := SetRawIfDifferent(input, "metadata", []byte(`{"source":"executor"}`))	if &output[0] != &input[0] {		t.Fatal("identical raw value caused a payload copy")	}} func TestSetRawIfDifferentUpdatesDifferentRawValue(t *testing.T) {	input := []byte(`{"metadata":"executor"}`)	output := SetRawIfDifferent(input, "metadata", []byte(`{"source":"executor"}`))	metadata := gjson.GetBytes(output, "metadata")	if !metadata.IsObject() || metadata.Get("source").String() != "executor" {		t.Fatalf("metadata = %s, want object", metadata.Raw)	}} func TestApplyPayloadConfigReusesCanonicalOverrides(t *testing.T) {	cfg := &config.Config{Payload: config.PayloadConfig{		Override: []config.PayloadRule{{			Models: []config.PayloadModelRule{{Name: "gpt-test", Protocol: "openai"}},			Params: map[string]any{"stream": true, "model": "gpt-test"},		}},		OverrideRaw: []config.PayloadRule{{			Models: []config.PayloadModelRule{{Name: "gpt-test", Protocol: "openai"}},			Params: map[string]any{"metadata": `{"source":"executor"}`},		}},	}}	input := []byte(`{"model":"gpt-test","stream":true,"metadata":{"source":"executor"},"messages":[]}`)	output := ApplyPayloadConfigWithRoot(cfg, "gpt-test", "openai", "", input, nil, "", "")	if &output[0] != &input[0] {		t.Fatal("canonical payload overrides caused a payload copy")	}} func TestApplyPayloadConfigWithRequestTrackedReportsContextManagementTouches(t *testing.T) {	const automatic = `{"edits":[{"type":"clear_thinking_20251015","keep":"all"}]}`	modelRules := []config.PayloadModelRule{{Name: "claude-opus-5", Protocol: "claude"}}	originalWithoutContextManagement := []byte(`{"model":"claude-opus-5"}`) 	for _, test := range []struct {		name          string		payload       string		original      []byte		payloadConfig config.PayloadConfig		wantTouched   bool	}{		{			name:     "default",			payload:  `{"model":"claude-opus-5"}`,			original: originalWithoutContextManagement,			payloadConfig: config.PayloadConfig{Default: []config.PayloadRule{{				Models: modelRules,				Params: map[string]any{"context_management": map[string]any{"edits": []any{map[string]any{"type": "default"}}}},			}}},			wantTouched: true,		},		{			name:     "raw default",			payload:  `{"model":"claude-opus-5"}`,			original: originalWithoutContextManagement,			payloadConfig: config.PayloadConfig{DefaultRaw: []config.PayloadRule{{				Models: modelRules,				Params: map[string]any{"context_management": `{"edits":[{"type":"raw_default"}]}`},			}}},			wantTouched: true,		},		{			name:    "canonical descendant override",			payload: `{"model":"claude-opus-5","context_management":` + automatic + `}`,			payloadConfig: config.PayloadConfig{Override: []config.PayloadRule{{				Models: modelRules,				Params: map[string]any{"context_management.edits.0.keep": "all"},			}}},			wantTouched: true,		},		{			name:    "identical raw override",			payload: `{"model":"claude-opus-5","context_management":` + automatic + `}`,			payloadConfig: config.PayloadConfig{OverrideRaw: []config.PayloadRule{{				Models: modelRules,				Params: map[string]any{"context_management": automatic},			}}},			wantTouched: true,		},		{			name:    "filter already absent",			payload: `{"model":"claude-opus-5"}`,			payloadConfig: config.PayloadConfig{Filter: []config.PayloadFilterRule{{				Models: modelRules,				Params: []string{"context_management"},			}}},			wantTouched: true,		},		{			name:    "unrelated override",			payload: `{"model":"claude-opus-5"}`,			payloadConfig: config.PayloadConfig{Override: []config.PayloadRule{{				Models: modelRules,				Params: map[string]any{"thinking.type": "enabled"},			}}},		},		{			name:    "nonmatching override",			payload: `{"model":"claude-opus-5"}`,			payloadConfig: config.PayloadConfig{Override: []config.PayloadRule{{				Models: []config.PayloadModelRule{{Name: "other-model", Protocol: "claude"}},				Params: map[string]any{"context_management": map[string]any{"edits": []any{}}},			}}},		},		{			name:     "default skipped for caller owned field",			payload:  `{"model":"claude-opus-5","context_management":{"edits":[{"type":"caller"}]}}`,			original: []byte(`{"model":"claude-opus-5","context_management":{"edits":[{"type":"caller"}]}}`),			payloadConfig: config.PayloadConfig{Default: []config.PayloadRule{{				Models: modelRules,				Params: map[string]any{"context_management": map[string]any{"edits": []any{map[string]any{"type": "default"}}}},			}}},		},	} {		t.Run(test.name, func(t *testing.T) {			cfg := &config.Config{Payload: test.payloadConfig}			_, touched := ApplyPayloadConfigWithRequestTracked(cfg, "claude-opus-5", "claude", "claude", "", []byte(test.payload), test.original, "claude-opus-5", "", nil, "context_management")			if touched != test.wantTouched {				t.Fatalf("context_management touched = %t, want %t", touched, test.wantTouched)			}		})	}} func TestApplyPayloadConfigProjectionOverrideWritesEveryMatch(t *testing.T) {	cfg := &config.Config{Payload: config.PayloadConfig{		Override: []config.PayloadRule{{			Models: []config.PayloadModelRule{{Name: "gpt-test", Protocol: "openai"}},			Params: map[string]any{"items.#.value": []any{1, 2}},		}},	}}	input := []byte(`{"items":[{"value":1},{"value":2}]}`)	output := ApplyPayloadConfigWithRoot(cfg, "gpt-test", "openai", "", input, nil, "", "")	for _, path := range []string{"items.0.value", "items.1.value"} {		if got := gjson.GetBytes(output, path).Raw; got != `[1,2]` {			t.Fatalf("%s = %s, want [1,2]", path, got)		}	}} func TestApplyPayloadConfigProjectionOverrideRawWritesEveryMatch(t *testing.T) {	cfg := &config.Config{Payload: config.PayloadConfig{		OverrideRaw: []config.PayloadRule{{			Models: []config.PayloadModelRule{{Name: "gpt-test", Protocol: "openai"}},			Params: map[string]any{"items.#.value": `[1,2]`},		}},	}}	input := []byte(`{"items":[{"value":1},{"value":2}]}`)	output := ApplyPayloadConfigWithRoot(cfg, "gpt-test", "openai", "", input, nil, "", "")	for _, path := range []string{"items.0.value", "items.1.value"} {		if got := gjson.GetBytes(output, path).Raw; got != `[1,2]` {			t.Fatalf("%s = %s, want [1,2]", path, got)		}	}} func TestApplyPayloadConfigNormalizesByteSliceOverride(t *testing.T) {	cfg := &config.Config{Payload: config.PayloadConfig{		Override: []config.PayloadRule{{			Models: []config.PayloadModelRule{{Name: "gpt-test", Protocol: "openai"}},			Params: map[string]any{"value": []byte("abc")},		}},	}}	input := []byte(`{"value":"YWJj"}`)	output := ApplyPayloadConfigWithRoot(cfg, "gpt-test", "openai", "", input, nil, "", "")	value := gjson.GetBytes(output, "value")	if value.Type != gjson.String || value.String() != "abc" {		t.Fatalf("value = %s, want string abc", value.Raw)	}} func TestSetPayloadValueIfDifferentUsesSJSONNumberEncoding(t *testing.T) {	input := []byte(`{"value":1.2}`)	output := setPayloadValueIfDifferent(input, "value", float32(1.2))	if got := gjson.GetBytes(output, "value").Raw; got != "1.2000000476837158" {		t.Fatalf("value = %s, want sjson float32 encoding", got)	}	canonical := []byte(`{"value":1.2000000476837158}`)	reused := setPayloadValueIfDifferent(canonical, "value", float32(1.2))	if &reused[0] != &canonical[0] {		t.Fatal("canonical float32 encoding caused a payload copy")	}} func TestSetPayloadValueIfDifferentCallsMarshalerOnce(t *testing.T) {	for _, input := range [][]byte{[]byte(`{"value":"old"}`), []byte(`{"value":"new"}`)} {		calls := 0		value := countingPayloadMarshaler{calls: &calls, value: "new"}		output := setPayloadValueIfDifferent(input, "value", value)		if calls != 1 {			t.Fatalf("MarshalJSON calls = %d, want 1", calls)		}		if got := gjson.GetBytes(output, "value").String(); got != "new" {			t.Fatalf("value = %q, want new", got)		}	}} func TestRemoveToolTypeReusesArrayWithoutMatch(t *testing.T) {	input := []byte(`{"tools":[{"type":"function","name":"lookup","parameters":{"type":"object"}}]}`)	output := removeToolTypeFromToolsArray(input, "tools", "image_generation")	if &output[0] != &input[0] {		t.Fatal("tool filtering without a match caused a payload copy")	}} var benchmarkPayloadMutationOutput []byte func BenchmarkSetStringIfDifferentLargeCanonicalPayload(b *testing.B) {	input := []byte(`{"model":"gpt-test","messages":[{"role":"user","content":"` + strings.Repeat("x", 8<<20) + `"}]}`)	b.ReportAllocs()	b.SetBytes(int64(len(input)))	b.ResetTimer()	for b.Loop() {		benchmarkPayloadMutationOutput = SetStringIfDifferent(input, "model", "gpt-test")	}} func TestConfigExampleDocumentsCodexAdditionalToolsPayloadFilter(t *testing.T) {	data, err := os.ReadFile("../../../../config.example.yaml")	if err != nil {		t.Fatalf("failed to read config.example.yaml: %v", err)	}	content := string(data)	const expectedPath = `'input.#(type=="additional_tools")#.tools.#(name=="functions")#.tools.#(name=="apply_patch")#'`	if !strings.Contains(content, expectedPath) {		t.Fatalf("config.example.yaml does not contain expected additional_tools path: %s", expectedPath)	}} func TestApplyPayloadConfig_CodexAdditionalToolsFilter(t *testing.T) {	cfg := &config.Config{		Payload: config.PayloadConfig{			Filter: []config.PayloadFilterRule{				{					Models: []config.PayloadModelRule{{Name: "gpt-*", Protocol: "codex"}},					Params: []string{						`input.#(type=="additional_tools")#.tools.#(name=="functions")#.tools.#(name=="apply_patch")#`,					},				},			},		},	} 	t.Run("removes target tool and preserves other tools across namespaces", func(t *testing.T) {		input := []byte(`{			"model": "gpt-5-codex",			"input": [				{					"type": "additional_tools",					"role": "developer",					"tools": [						{							"type": "namespace",							"name": "functions",							"tools": [								{"type": "custom", "name": "apply_patch", "description": "patch"},								{"type": "custom", "name": "exec_command", "description": "exec"}							]						},						{							"type": "namespace",							"name": "collaboration",							"tools": [								{"type": "custom", "name": "share", "description": "share"}							]						}					]				}			]		}`) 		output := ApplyPayloadConfigWithRoot(cfg, "gpt-5-codex", "codex", "", input, nil, "", "") 		var structured struct {			Input []struct {				Type  string `json:"type"`				Tools []struct {					Name  string `json:"name"`					Tools []struct {						Name string `json:"name"`					} `json:"tools"`				} `json:"tools"`			} `json:"input"`		}		if errUnmarshal := json.Unmarshal(output, &structured); errUnmarshal != nil {			t.Fatalf("failed to unmarshal output: %v", errUnmarshal)		}		if len(structured.Input) != 1 {			t.Fatalf("input len = %d, want 1", len(structured.Input))		}		if len(structured.Input[0].Tools) != 2 {			t.Fatalf("namespaces len = %d, want 2", len(structured.Input[0].Tools))		}		fnNamespace := structured.Input[0].Tools[0]		if fnNamespace.Name != "functions" || len(fnNamespace.Tools) != 1 || fnNamespace.Tools[0].Name != "exec_command" {			t.Fatalf("functions namespace tools = %+v, want only exec_command", fnNamespace.Tools)		}		collabNamespace := structured.Input[0].Tools[1]		if collabNamespace.Name != "collaboration" || len(collabNamespace.Tools) != 1 || collabNamespace.Tools[0].Name != "share" {			t.Fatalf("collaboration namespace tools = %+v, want share", collabNamespace.Tools)		}	}) 	t.Run("non-matching target tool is a no-op", func(t *testing.T) {		input := []byte(`{			"model": "gpt-5-codex",			"input": [				{					"type": "additional_tools",					"role": "developer",					"tools": [						{							"type": "namespace",							"name": "functions",							"tools": [								{"type": "custom", "name": "exec_command", "description": "exec"}							]						}					]				}			]		}`) 		output := ApplyPayloadConfigWithRoot(cfg, "gpt-5-codex", "codex", "", input, nil, "", "")		if !bytes.Equal(output, input) {			t.Fatalf("expected payload to be untouched when rule does not match, got: %s", string(output))		}	}) 	t.Run("removes matches across multiple additional_tools elements", func(t *testing.T) {		input := []byte(`{			"model": "gpt-5-codex",			"input": [				{					"type": "additional_tools",					"tools": [						{							"type": "namespace",							"name": "functions",							"tools": [{"type": "custom", "name": "apply_patch"}]						}					]				},				{					"type": "message",					"role": "user",					"content": "hello"				},				{					"type": "additional_tools",					"tools": [						{							"type": "namespace",							"name": "functions",							"tools": [								{"type": "custom", "name": "apply_patch"},								{"type": "custom", "name": "view_image"}							]						}					]				}			]		}`) 		output := ApplyPayloadConfigWithRoot(cfg, "gpt-5-codex", "codex", "", input, nil, "", "")		if strings.Contains(string(output), "apply_patch") {			t.Fatalf("apply_patch remained after multi-element filter: %s", string(output))		}		if !strings.Contains(string(output), "view_image") {			t.Fatalf("view_image was removed: %s", string(output))		}		if !strings.Contains(string(output), "hello") {			t.Fatalf("user message was removed: %s", string(output))		}	}) 	t.Run("removes multiple matches within the same namespace array", func(t *testing.T) {		input := []byte(`{			"model": "gpt-5-codex",			"input": [				{					"type": "additional_tools",					"tools": [						{							"type": "namespace",							"name": "functions",							"tools": [								{"type": "custom", "name": "apply_patch", "id": "p1"},								{"type": "custom", "name": "exec_command"},								{"type": "custom", "name": "apply_patch", "id": "p2"}							]						}					]				}			]		}`) 		output := ApplyPayloadConfigWithRoot(cfg, "gpt-5-codex", "codex", "", input, nil, "", "")		if strings.Contains(string(output), "apply_patch") {			t.Fatalf("apply_patch remained after multi-match array filter: %s", string(output))		}		if !strings.Contains(string(output), "exec_command") {			t.Fatalf("exec_command was removed: %s", string(output))		}	})}