| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330 |
- package common
- import (
- "encoding/json"
- "reflect"
- "testing"
- "github.com/QuantumNous/new-api/types"
- )
- func TestApplyParamOverrideTrimPrefix(t *testing.T) {
- // trim_prefix example:
- // {"operations":[{"path":"model","mode":"trim_prefix","value":"openai/"}]}
- input := []byte(`{"model":"openai/gpt-4","temperature":0.7}`)
- override := map[string]interface{}{
- "operations": []interface{}{
- map[string]interface{}{
- "path": "model",
- "mode": "trim_prefix",
- "value": "openai/",
- },
- },
- }
- out, err := ApplyParamOverride(input, override, nil)
- if err != nil {
- t.Fatalf("ApplyParamOverride returned error: %v", err)
- }
- assertJSONEqual(t, `{"model":"gpt-4","temperature":0.7}`, string(out))
- }
- func TestApplyParamOverrideTrimSuffix(t *testing.T) {
- // trim_suffix example:
- // {"operations":[{"path":"model","mode":"trim_suffix","value":"-latest"}]}
- input := []byte(`{"model":"gpt-4-latest","temperature":0.7}`)
- override := map[string]interface{}{
- "operations": []interface{}{
- map[string]interface{}{
- "path": "model",
- "mode": "trim_suffix",
- "value": "-latest",
- },
- },
- }
- out, err := ApplyParamOverride(input, override, nil)
- if err != nil {
- t.Fatalf("ApplyParamOverride returned error: %v", err)
- }
- assertJSONEqual(t, `{"model":"gpt-4","temperature":0.7}`, string(out))
- }
- func TestApplyParamOverrideTrimNoop(t *testing.T) {
- // trim_prefix no-op example:
- // {"operations":[{"path":"model","mode":"trim_prefix","value":"openai/"}]}
- input := []byte(`{"model":"gpt-4","temperature":0.7}`)
- override := map[string]interface{}{
- "operations": []interface{}{
- map[string]interface{}{
- "path": "model",
- "mode": "trim_prefix",
- "value": "openai/",
- },
- },
- }
- out, err := ApplyParamOverride(input, override, nil)
- if err != nil {
- t.Fatalf("ApplyParamOverride returned error: %v", err)
- }
- assertJSONEqual(t, `{"model":"gpt-4","temperature":0.7}`, string(out))
- }
- func TestApplyParamOverrideTrimRequiresValue(t *testing.T) {
- // trim_prefix requires value example:
- // {"operations":[{"path":"model","mode":"trim_prefix"}]}
- input := []byte(`{"model":"gpt-4"}`)
- override := map[string]interface{}{
- "operations": []interface{}{
- map[string]interface{}{
- "path": "model",
- "mode": "trim_prefix",
- },
- },
- }
- _, err := ApplyParamOverride(input, override, nil)
- if err == nil {
- t.Fatalf("expected error, got nil")
- }
- }
- func TestApplyParamOverrideReplace(t *testing.T) {
- // replace example:
- // {"operations":[{"path":"model","mode":"replace","from":"openai/","to":""}]}
- input := []byte(`{"model":"openai/gpt-4o-mini","temperature":0.7}`)
- override := map[string]interface{}{
- "operations": []interface{}{
- map[string]interface{}{
- "path": "model",
- "mode": "replace",
- "from": "openai/",
- "to": "",
- },
- },
- }
- out, err := ApplyParamOverride(input, override, nil)
- if err != nil {
- t.Fatalf("ApplyParamOverride returned error: %v", err)
- }
- assertJSONEqual(t, `{"model":"gpt-4o-mini","temperature":0.7}`, string(out))
- }
- func TestApplyParamOverrideRegexReplace(t *testing.T) {
- // regex_replace example:
- // {"operations":[{"path":"model","mode":"regex_replace","from":"^gpt-","to":"openai/gpt-"}]}
- input := []byte(`{"model":"gpt-4o-mini","temperature":0.7}`)
- override := map[string]interface{}{
- "operations": []interface{}{
- map[string]interface{}{
- "path": "model",
- "mode": "regex_replace",
- "from": "^gpt-",
- "to": "openai/gpt-",
- },
- },
- }
- out, err := ApplyParamOverride(input, override, nil)
- if err != nil {
- t.Fatalf("ApplyParamOverride returned error: %v", err)
- }
- assertJSONEqual(t, `{"model":"openai/gpt-4o-mini","temperature":0.7}`, string(out))
- }
- func TestApplyParamOverrideReplaceRequiresFrom(t *testing.T) {
- // replace requires from example:
- // {"operations":[{"path":"model","mode":"replace"}]}
- input := []byte(`{"model":"gpt-4"}`)
- override := map[string]interface{}{
- "operations": []interface{}{
- map[string]interface{}{
- "path": "model",
- "mode": "replace",
- },
- },
- }
- _, err := ApplyParamOverride(input, override, nil)
- if err == nil {
- t.Fatalf("expected error, got nil")
- }
- }
- func TestApplyParamOverrideRegexReplaceRequiresPattern(t *testing.T) {
- // regex_replace requires from(pattern) example:
- // {"operations":[{"path":"model","mode":"regex_replace"}]}
- input := []byte(`{"model":"gpt-4"}`)
- override := map[string]interface{}{
- "operations": []interface{}{
- map[string]interface{}{
- "path": "model",
- "mode": "regex_replace",
- },
- },
- }
- _, err := ApplyParamOverride(input, override, nil)
- if err == nil {
- t.Fatalf("expected error, got nil")
- }
- }
- func TestApplyParamOverrideDelete(t *testing.T) {
- input := []byte(`{"model":"gpt-4","temperature":0.7}`)
- override := map[string]interface{}{
- "operations": []interface{}{
- map[string]interface{}{
- "path": "temperature",
- "mode": "delete",
- },
- },
- }
- out, err := ApplyParamOverride(input, override, nil)
- if err != nil {
- t.Fatalf("ApplyParamOverride returned error: %v", err)
- }
- var got map[string]interface{}
- if err := json.Unmarshal(out, &got); err != nil {
- t.Fatalf("failed to unmarshal output JSON: %v", err)
- }
- if _, exists := got["temperature"]; exists {
- t.Fatalf("expected temperature to be deleted")
- }
- }
- func TestApplyParamOverrideSet(t *testing.T) {
- input := []byte(`{"model":"gpt-4","temperature":0.7}`)
- override := map[string]interface{}{
- "operations": []interface{}{
- map[string]interface{}{
- "path": "temperature",
- "mode": "set",
- "value": 0.1,
- },
- },
- }
- out, err := ApplyParamOverride(input, override, nil)
- if err != nil {
- t.Fatalf("ApplyParamOverride returned error: %v", err)
- }
- assertJSONEqual(t, `{"model":"gpt-4","temperature":0.1}`, string(out))
- }
- func TestApplyParamOverrideSetKeepOrigin(t *testing.T) {
- input := []byte(`{"model":"gpt-4","temperature":0.7}`)
- override := map[string]interface{}{
- "operations": []interface{}{
- map[string]interface{}{
- "path": "temperature",
- "mode": "set",
- "value": 0.1,
- "keep_origin": true,
- },
- },
- }
- out, err := ApplyParamOverride(input, override, nil)
- if err != nil {
- t.Fatalf("ApplyParamOverride returned error: %v", err)
- }
- assertJSONEqual(t, `{"model":"gpt-4","temperature":0.7}`, string(out))
- }
- func TestApplyParamOverrideMove(t *testing.T) {
- input := []byte(`{"model":"gpt-4","meta":{"x":1}}`)
- override := map[string]interface{}{
- "operations": []interface{}{
- map[string]interface{}{
- "mode": "move",
- "from": "model",
- "to": "meta.model",
- },
- },
- }
- out, err := ApplyParamOverride(input, override, nil)
- if err != nil {
- t.Fatalf("ApplyParamOverride returned error: %v", err)
- }
- assertJSONEqual(t, `{"meta":{"x":1,"model":"gpt-4"}}`, string(out))
- }
- func TestApplyParamOverrideMoveMissingSource(t *testing.T) {
- input := []byte(`{"meta":{"x":1}}`)
- override := map[string]interface{}{
- "operations": []interface{}{
- map[string]interface{}{
- "mode": "move",
- "from": "model",
- "to": "meta.model",
- },
- },
- }
- _, err := ApplyParamOverride(input, override, nil)
- if err == nil {
- t.Fatalf("expected error, got nil")
- }
- }
- func TestApplyParamOverridePrependAppendString(t *testing.T) {
- input := []byte(`{"model":"gpt-4"}`)
- override := map[string]interface{}{
- "operations": []interface{}{
- map[string]interface{}{
- "path": "model",
- "mode": "prepend",
- "value": "openai/",
- },
- map[string]interface{}{
- "path": "model",
- "mode": "append",
- "value": "-latest",
- },
- },
- }
- out, err := ApplyParamOverride(input, override, nil)
- if err != nil {
- t.Fatalf("ApplyParamOverride returned error: %v", err)
- }
- assertJSONEqual(t, `{"model":"openai/gpt-4-latest"}`, string(out))
- }
- func TestApplyParamOverridePrependAppendArray(t *testing.T) {
- input := []byte(`{"arr":[1,2]}`)
- override := map[string]interface{}{
- "operations": []interface{}{
- map[string]interface{}{
- "path": "arr",
- "mode": "prepend",
- "value": 0,
- },
- map[string]interface{}{
- "path": "arr",
- "mode": "append",
- "value": []interface{}{3, 4},
- },
- },
- }
- out, err := ApplyParamOverride(input, override, nil)
- if err != nil {
- t.Fatalf("ApplyParamOverride returned error: %v", err)
- }
- assertJSONEqual(t, `{"arr":[0,1,2,3,4]}`, string(out))
- }
- func TestApplyParamOverrideAppendObjectMergeKeepOrigin(t *testing.T) {
- input := []byte(`{"obj":{"a":1}}`)
- override := map[string]interface{}{
- "operations": []interface{}{
- map[string]interface{}{
- "path": "obj",
- "mode": "append",
- "keep_origin": true,
- "value": map[string]interface{}{
- "a": 2,
- "b": 3,
- },
- },
- },
- }
- out, err := ApplyParamOverride(input, override, nil)
- if err != nil {
- t.Fatalf("ApplyParamOverride returned error: %v", err)
- }
- assertJSONEqual(t, `{"obj":{"a":1,"b":3}}`, string(out))
- }
- func TestApplyParamOverrideAppendObjectMergeOverride(t *testing.T) {
- input := []byte(`{"obj":{"a":1}}`)
- override := map[string]interface{}{
- "operations": []interface{}{
- map[string]interface{}{
- "path": "obj",
- "mode": "append",
- "value": map[string]interface{}{
- "a": 2,
- "b": 3,
- },
- },
- },
- }
- out, err := ApplyParamOverride(input, override, nil)
- if err != nil {
- t.Fatalf("ApplyParamOverride returned error: %v", err)
- }
- assertJSONEqual(t, `{"obj":{"a":2,"b":3}}`, string(out))
- }
- func TestApplyParamOverrideConditionORDefault(t *testing.T) {
- input := []byte(`{"model":"gpt-4","temperature":0.7}`)
- override := map[string]interface{}{
- "operations": []interface{}{
- map[string]interface{}{
- "path": "temperature",
- "mode": "set",
- "value": 0.1,
- "conditions": []interface{}{
- map[string]interface{}{
- "path": "model",
- "mode": "prefix",
- "value": "gpt",
- },
- map[string]interface{}{
- "path": "model",
- "mode": "prefix",
- "value": "claude",
- },
- },
- },
- },
- }
- out, err := ApplyParamOverride(input, override, nil)
- if err != nil {
- t.Fatalf("ApplyParamOverride returned error: %v", err)
- }
- assertJSONEqual(t, `{"model":"gpt-4","temperature":0.1}`, string(out))
- }
- func TestApplyParamOverrideConditionAND(t *testing.T) {
- input := []byte(`{"model":"gpt-4","temperature":0.7}`)
- override := map[string]interface{}{
- "operations": []interface{}{
- map[string]interface{}{
- "path": "temperature",
- "mode": "set",
- "value": 0.1,
- "logic": "AND",
- "conditions": []interface{}{
- map[string]interface{}{
- "path": "model",
- "mode": "prefix",
- "value": "gpt",
- },
- map[string]interface{}{
- "path": "temperature",
- "mode": "gt",
- "value": 0.5,
- },
- },
- },
- },
- }
- out, err := ApplyParamOverride(input, override, nil)
- if err != nil {
- t.Fatalf("ApplyParamOverride returned error: %v", err)
- }
- assertJSONEqual(t, `{"model":"gpt-4","temperature":0.1}`, string(out))
- }
- func TestApplyParamOverrideConditionInvert(t *testing.T) {
- input := []byte(`{"model":"gpt-4","temperature":0.7}`)
- override := map[string]interface{}{
- "operations": []interface{}{
- map[string]interface{}{
- "path": "temperature",
- "mode": "set",
- "value": 0.1,
- "conditions": []interface{}{
- map[string]interface{}{
- "path": "model",
- "mode": "prefix",
- "value": "gpt",
- "invert": true,
- },
- },
- },
- },
- }
- out, err := ApplyParamOverride(input, override, nil)
- if err != nil {
- t.Fatalf("ApplyParamOverride returned error: %v", err)
- }
- assertJSONEqual(t, `{"model":"gpt-4","temperature":0.7}`, string(out))
- }
- func TestApplyParamOverrideConditionPassMissingKey(t *testing.T) {
- input := []byte(`{"temperature":0.7}`)
- override := map[string]interface{}{
- "operations": []interface{}{
- map[string]interface{}{
- "path": "temperature",
- "mode": "set",
- "value": 0.1,
- "conditions": []interface{}{
- map[string]interface{}{
- "path": "model",
- "mode": "prefix",
- "value": "gpt",
- "pass_missing_key": true,
- },
- },
- },
- },
- }
- out, err := ApplyParamOverride(input, override, nil)
- if err != nil {
- t.Fatalf("ApplyParamOverride returned error: %v", err)
- }
- assertJSONEqual(t, `{"temperature":0.1}`, string(out))
- }
- func TestApplyParamOverrideConditionFromContext(t *testing.T) {
- input := []byte(`{"temperature":0.7}`)
- override := map[string]interface{}{
- "operations": []interface{}{
- map[string]interface{}{
- "path": "temperature",
- "mode": "set",
- "value": 0.1,
- "conditions": []interface{}{
- map[string]interface{}{
- "path": "model",
- "mode": "prefix",
- "value": "gpt",
- },
- },
- },
- },
- }
- ctx := map[string]interface{}{
- "model": "gpt-4",
- }
- out, err := ApplyParamOverride(input, override, ctx)
- if err != nil {
- t.Fatalf("ApplyParamOverride returned error: %v", err)
- }
- assertJSONEqual(t, `{"temperature":0.1}`, string(out))
- }
- func TestApplyParamOverrideNegativeIndexPath(t *testing.T) {
- input := []byte(`{"arr":[{"model":"a"},{"model":"b"}]}`)
- override := map[string]interface{}{
- "operations": []interface{}{
- map[string]interface{}{
- "path": "arr.-1.model",
- "mode": "set",
- "value": "c",
- },
- },
- }
- out, err := ApplyParamOverride(input, override, nil)
- if err != nil {
- t.Fatalf("ApplyParamOverride returned error: %v", err)
- }
- assertJSONEqual(t, `{"arr":[{"model":"a"},{"model":"c"}]}`, string(out))
- }
- func TestApplyParamOverrideRegexReplaceInvalidPattern(t *testing.T) {
- // regex_replace invalid pattern example:
- // {"operations":[{"path":"model","mode":"regex_replace","from":"(","to":"x"}]}
- input := []byte(`{"model":"gpt-4"}`)
- override := map[string]interface{}{
- "operations": []interface{}{
- map[string]interface{}{
- "path": "model",
- "mode": "regex_replace",
- "from": "(",
- "to": "x",
- },
- },
- }
- _, err := ApplyParamOverride(input, override, nil)
- if err == nil {
- t.Fatalf("expected error, got nil")
- }
- }
- func TestApplyParamOverrideCopy(t *testing.T) {
- // copy example:
- // {"operations":[{"mode":"copy","from":"model","to":"original_model"}]}
- input := []byte(`{"model":"gpt-4","temperature":0.7}`)
- override := map[string]interface{}{
- "operations": []interface{}{
- map[string]interface{}{
- "mode": "copy",
- "from": "model",
- "to": "original_model",
- },
- },
- }
- out, err := ApplyParamOverride(input, override, nil)
- if err != nil {
- t.Fatalf("ApplyParamOverride returned error: %v", err)
- }
- assertJSONEqual(t, `{"model":"gpt-4","original_model":"gpt-4","temperature":0.7}`, string(out))
- }
- func TestApplyParamOverrideCopyMissingSource(t *testing.T) {
- // copy missing source example:
- // {"operations":[{"mode":"copy","from":"model","to":"original_model"}]}
- input := []byte(`{"temperature":0.7}`)
- override := map[string]interface{}{
- "operations": []interface{}{
- map[string]interface{}{
- "mode": "copy",
- "from": "model",
- "to": "original_model",
- },
- },
- }
- _, err := ApplyParamOverride(input, override, nil)
- if err == nil {
- t.Fatalf("expected error, got nil")
- }
- }
- func TestApplyParamOverrideCopyRequiresFromTo(t *testing.T) {
- // copy requires from/to example:
- // {"operations":[{"mode":"copy"}]}
- input := []byte(`{"model":"gpt-4"}`)
- override := map[string]interface{}{
- "operations": []interface{}{
- map[string]interface{}{
- "mode": "copy",
- },
- },
- }
- _, err := ApplyParamOverride(input, override, nil)
- if err == nil {
- t.Fatalf("expected error, got nil")
- }
- }
- func TestApplyParamOverrideEnsurePrefix(t *testing.T) {
- // ensure_prefix example:
- // {"operations":[{"path":"model","mode":"ensure_prefix","value":"openai/"}]}
- input := []byte(`{"model":"gpt-4"}`)
- override := map[string]interface{}{
- "operations": []interface{}{
- map[string]interface{}{
- "path": "model",
- "mode": "ensure_prefix",
- "value": "openai/",
- },
- },
- }
- out, err := ApplyParamOverride(input, override, nil)
- if err != nil {
- t.Fatalf("ApplyParamOverride returned error: %v", err)
- }
- assertJSONEqual(t, `{"model":"openai/gpt-4"}`, string(out))
- }
- func TestApplyParamOverrideEnsurePrefixNoop(t *testing.T) {
- // ensure_prefix no-op example:
- // {"operations":[{"path":"model","mode":"ensure_prefix","value":"openai/"}]}
- input := []byte(`{"model":"openai/gpt-4"}`)
- override := map[string]interface{}{
- "operations": []interface{}{
- map[string]interface{}{
- "path": "model",
- "mode": "ensure_prefix",
- "value": "openai/",
- },
- },
- }
- out, err := ApplyParamOverride(input, override, nil)
- if err != nil {
- t.Fatalf("ApplyParamOverride returned error: %v", err)
- }
- assertJSONEqual(t, `{"model":"openai/gpt-4"}`, string(out))
- }
- func TestApplyParamOverrideEnsureSuffix(t *testing.T) {
- // ensure_suffix example:
- // {"operations":[{"path":"model","mode":"ensure_suffix","value":"-latest"}]}
- input := []byte(`{"model":"gpt-4"}`)
- override := map[string]interface{}{
- "operations": []interface{}{
- map[string]interface{}{
- "path": "model",
- "mode": "ensure_suffix",
- "value": "-latest",
- },
- },
- }
- out, err := ApplyParamOverride(input, override, nil)
- if err != nil {
- t.Fatalf("ApplyParamOverride returned error: %v", err)
- }
- assertJSONEqual(t, `{"model":"gpt-4-latest"}`, string(out))
- }
- func TestApplyParamOverrideEnsureSuffixNoop(t *testing.T) {
- // ensure_suffix no-op example:
- // {"operations":[{"path":"model","mode":"ensure_suffix","value":"-latest"}]}
- input := []byte(`{"model":"gpt-4-latest"}`)
- override := map[string]interface{}{
- "operations": []interface{}{
- map[string]interface{}{
- "path": "model",
- "mode": "ensure_suffix",
- "value": "-latest",
- },
- },
- }
- out, err := ApplyParamOverride(input, override, nil)
- if err != nil {
- t.Fatalf("ApplyParamOverride returned error: %v", err)
- }
- assertJSONEqual(t, `{"model":"gpt-4-latest"}`, string(out))
- }
- func TestApplyParamOverrideEnsureRequiresValue(t *testing.T) {
- // ensure_prefix requires value example:
- // {"operations":[{"path":"model","mode":"ensure_prefix"}]}
- input := []byte(`{"model":"gpt-4"}`)
- override := map[string]interface{}{
- "operations": []interface{}{
- map[string]interface{}{
- "path": "model",
- "mode": "ensure_prefix",
- },
- },
- }
- _, err := ApplyParamOverride(input, override, nil)
- if err == nil {
- t.Fatalf("expected error, got nil")
- }
- }
- func TestApplyParamOverrideTrimSpace(t *testing.T) {
- // trim_space example:
- // {"operations":[{"path":"model","mode":"trim_space"}]}
- input := []byte("{\"model\":\" gpt-4 \\n\"}")
- override := map[string]interface{}{
- "operations": []interface{}{
- map[string]interface{}{
- "path": "model",
- "mode": "trim_space",
- },
- },
- }
- out, err := ApplyParamOverride(input, override, nil)
- if err != nil {
- t.Fatalf("ApplyParamOverride returned error: %v", err)
- }
- assertJSONEqual(t, `{"model":"gpt-4"}`, string(out))
- }
- func TestApplyParamOverrideToLower(t *testing.T) {
- // to_lower example:
- // {"operations":[{"path":"model","mode":"to_lower"}]}
- input := []byte(`{"model":"GPT-4"}`)
- override := map[string]interface{}{
- "operations": []interface{}{
- map[string]interface{}{
- "path": "model",
- "mode": "to_lower",
- },
- },
- }
- out, err := ApplyParamOverride(input, override, nil)
- if err != nil {
- t.Fatalf("ApplyParamOverride returned error: %v", err)
- }
- assertJSONEqual(t, `{"model":"gpt-4"}`, string(out))
- }
- func TestApplyParamOverrideToUpper(t *testing.T) {
- // to_upper example:
- // {"operations":[{"path":"model","mode":"to_upper"}]}
- input := []byte(`{"model":"gpt-4"}`)
- override := map[string]interface{}{
- "operations": []interface{}{
- map[string]interface{}{
- "path": "model",
- "mode": "to_upper",
- },
- },
- }
- out, err := ApplyParamOverride(input, override, nil)
- if err != nil {
- t.Fatalf("ApplyParamOverride returned error: %v", err)
- }
- assertJSONEqual(t, `{"model":"GPT-4"}`, string(out))
- }
- func TestApplyParamOverrideReturnError(t *testing.T) {
- input := []byte(`{"model":"gemini-2.5-pro"}`)
- override := map[string]interface{}{
- "operations": []interface{}{
- map[string]interface{}{
- "mode": "return_error",
- "value": map[string]interface{}{
- "message": "forced bad request by param override",
- "status_code": 422,
- "code": "forced_bad_request",
- "type": "invalid_request_error",
- "skip_retry": true,
- },
- "conditions": []interface{}{
- map[string]interface{}{
- "path": "retry.is_retry",
- "mode": "full",
- "value": true,
- },
- },
- },
- },
- }
- ctx := map[string]interface{}{
- "retry": map[string]interface{}{
- "index": 1,
- "is_retry": true,
- },
- }
- _, err := ApplyParamOverride(input, override, ctx)
- if err == nil {
- t.Fatalf("expected error, got nil")
- }
- returnErr, ok := AsParamOverrideReturnError(err)
- if !ok {
- t.Fatalf("expected ParamOverrideReturnError, got %T: %v", err, err)
- }
- if returnErr.StatusCode != 422 {
- t.Fatalf("expected status 422, got %d", returnErr.StatusCode)
- }
- if returnErr.Code != "forced_bad_request" {
- t.Fatalf("expected code forced_bad_request, got %s", returnErr.Code)
- }
- if !returnErr.SkipRetry {
- t.Fatalf("expected skip_retry true")
- }
- }
- func TestApplyParamOverridePruneObjectsByTypeString(t *testing.T) {
- input := []byte(`{
- "messages":[
- {"role":"assistant","content":[
- {"type":"output_text","text":"a"},
- {"type":"redacted_thinking","text":"secret"},
- {"type":"tool_call","name":"tool_a"}
- ]},
- {"role":"assistant","content":[
- {"type":"output_text","text":"b"},
- {"type":"wrapper","parts":[
- {"type":"redacted_thinking","text":"secret2"},
- {"type":"output_text","text":"c"}
- ]}
- ]}
- ]
- }`)
- override := map[string]interface{}{
- "operations": []interface{}{
- map[string]interface{}{
- "mode": "prune_objects",
- "value": "redacted_thinking",
- },
- },
- }
- out, err := ApplyParamOverride(input, override, nil)
- if err != nil {
- t.Fatalf("ApplyParamOverride returned error: %v", err)
- }
- assertJSONEqual(t, `{
- "messages":[
- {"role":"assistant","content":[
- {"type":"output_text","text":"a"},
- {"type":"tool_call","name":"tool_a"}
- ]},
- {"role":"assistant","content":[
- {"type":"output_text","text":"b"},
- {"type":"wrapper","parts":[
- {"type":"output_text","text":"c"}
- ]}
- ]}
- ]
- }`, string(out))
- }
- func TestApplyParamOverridePruneObjectsWhereAndPath(t *testing.T) {
- input := []byte(`{
- "a":{"items":[{"type":"redacted_thinking","id":1},{"type":"output_text","id":2}]},
- "b":{"items":[{"type":"redacted_thinking","id":3},{"type":"output_text","id":4}]}
- }`)
- override := map[string]interface{}{
- "operations": []interface{}{
- map[string]interface{}{
- "path": "a",
- "mode": "prune_objects",
- "value": map[string]interface{}{
- "where": map[string]interface{}{
- "type": "redacted_thinking",
- },
- },
- },
- },
- }
- out, err := ApplyParamOverride(input, override, nil)
- if err != nil {
- t.Fatalf("ApplyParamOverride returned error: %v", err)
- }
- assertJSONEqual(t, `{
- "a":{"items":[{"type":"output_text","id":2}]},
- "b":{"items":[{"type":"redacted_thinking","id":3},{"type":"output_text","id":4}]}
- }`, string(out))
- }
- func TestApplyParamOverrideNormalizeThinkingSignatureUnsupported(t *testing.T) {
- input := []byte(`{"items":[{"type":"redacted_thinking"}]}`)
- override := map[string]interface{}{
- "operations": []interface{}{
- map[string]interface{}{
- "mode": "normalize_thinking_signature",
- },
- },
- }
- _, err := ApplyParamOverride(input, override, nil)
- if err == nil {
- t.Fatalf("expected error, got nil")
- }
- }
- func TestApplyParamOverrideConditionFromRetryAndLastErrorContext(t *testing.T) {
- info := &RelayInfo{
- RetryIndex: 1,
- LastError: types.WithOpenAIError(types.OpenAIError{
- Message: "invalid thinking signature",
- Type: "invalid_request_error",
- Code: "bad_thought_signature",
- }, 400),
- }
- ctx := BuildParamOverrideContext(info)
- input := []byte(`{"temperature":0.7}`)
- override := map[string]interface{}{
- "operations": []interface{}{
- map[string]interface{}{
- "path": "temperature",
- "mode": "set",
- "value": 0.1,
- "logic": "AND",
- "conditions": []interface{}{
- map[string]interface{}{
- "path": "is_retry",
- "mode": "full",
- "value": true,
- },
- map[string]interface{}{
- "path": "last_error.code",
- "mode": "contains",
- "value": "thought_signature",
- },
- },
- },
- },
- }
- out, err := ApplyParamOverride(input, override, ctx)
- if err != nil {
- t.Fatalf("ApplyParamOverride returned error: %v", err)
- }
- assertJSONEqual(t, `{"temperature":0.1}`, string(out))
- }
- func TestApplyParamOverrideConditionFromRequestHeaders(t *testing.T) {
- input := []byte(`{"temperature":0.7}`)
- override := map[string]interface{}{
- "operations": []interface{}{
- map[string]interface{}{
- "path": "temperature",
- "mode": "set",
- "value": 0.1,
- "conditions": []interface{}{
- map[string]interface{}{
- "path": "request_headers.authorization",
- "mode": "contains",
- "value": "Bearer ",
- },
- },
- },
- },
- }
- ctx := map[string]interface{}{
- "request_headers": map[string]interface{}{
- "authorization": "Bearer token-123",
- },
- }
- out, err := ApplyParamOverride(input, override, ctx)
- if err != nil {
- t.Fatalf("ApplyParamOverride returned error: %v", err)
- }
- assertJSONEqual(t, `{"temperature":0.1}`, string(out))
- }
- func TestApplyParamOverrideSetHeaderAndUseInLaterCondition(t *testing.T) {
- input := []byte(`{"temperature":0.7}`)
- override := map[string]interface{}{
- "operations": []interface{}{
- map[string]interface{}{
- "mode": "set_header",
- "path": "X-Debug-Mode",
- "value": "enabled",
- },
- map[string]interface{}{
- "path": "temperature",
- "mode": "set",
- "value": 0.1,
- "conditions": []interface{}{
- map[string]interface{}{
- "path": "header_override_normalized.x_debug_mode",
- "mode": "full",
- "value": "enabled",
- },
- },
- },
- },
- }
- out, err := ApplyParamOverride(input, override, nil)
- if err != nil {
- t.Fatalf("ApplyParamOverride returned error: %v", err)
- }
- assertJSONEqual(t, `{"temperature":0.1}`, string(out))
- }
- func TestApplyParamOverrideCopyHeaderFromRequestHeaders(t *testing.T) {
- input := []byte(`{"temperature":0.7}`)
- override := map[string]interface{}{
- "operations": []interface{}{
- map[string]interface{}{
- "mode": "copy_header",
- "from": "Authorization",
- "to": "X-Upstream-Auth",
- },
- map[string]interface{}{
- "path": "temperature",
- "mode": "set",
- "value": 0.1,
- "conditions": []interface{}{
- map[string]interface{}{
- "path": "header_override_normalized.x_upstream_auth",
- "mode": "contains",
- "value": "Bearer ",
- },
- },
- },
- },
- }
- ctx := map[string]interface{}{
- "request_headers_raw": map[string]interface{}{
- "Authorization": "Bearer token-123",
- },
- "request_headers": map[string]interface{}{
- "authorization": "Bearer token-123",
- },
- }
- out, err := ApplyParamOverride(input, override, ctx)
- if err != nil {
- t.Fatalf("ApplyParamOverride returned error: %v", err)
- }
- assertJSONEqual(t, `{"temperature":0.1}`, string(out))
- }
- func TestApplyParamOverrideSyncFieldsHeaderToJSON(t *testing.T) {
- input := []byte(`{"model":"gpt-4"}`)
- override := map[string]interface{}{
- "operations": []interface{}{
- map[string]interface{}{
- "mode": "sync_fields",
- "from": "header:session_id",
- "to": "json:prompt_cache_key",
- },
- },
- }
- ctx := map[string]interface{}{
- "request_headers_raw": map[string]interface{}{
- "session_id": "sess-123",
- },
- "request_headers": map[string]interface{}{
- "session_id": "sess-123",
- },
- }
- out, err := ApplyParamOverride(input, override, ctx)
- if err != nil {
- t.Fatalf("ApplyParamOverride returned error: %v", err)
- }
- assertJSONEqual(t, `{"model":"gpt-4","prompt_cache_key":"sess-123"}`, string(out))
- }
- func TestApplyParamOverrideSyncFieldsJSONToHeader(t *testing.T) {
- input := []byte(`{"model":"gpt-4","prompt_cache_key":"cache-abc"}`)
- override := map[string]interface{}{
- "operations": []interface{}{
- map[string]interface{}{
- "mode": "sync_fields",
- "from": "header:session_id",
- "to": "json:prompt_cache_key",
- },
- },
- }
- ctx := map[string]interface{}{}
- out, err := ApplyParamOverride(input, override, ctx)
- if err != nil {
- t.Fatalf("ApplyParamOverride returned error: %v", err)
- }
- assertJSONEqual(t, `{"model":"gpt-4","prompt_cache_key":"cache-abc"}`, string(out))
- headers, ok := ctx["header_override"].(map[string]interface{})
- if !ok {
- t.Fatalf("expected header_override context map")
- }
- if headers["session_id"] != "cache-abc" {
- t.Fatalf("expected session_id to be synced from prompt_cache_key, got: %v", headers["session_id"])
- }
- }
- func TestApplyParamOverrideSyncFieldsNoChangeWhenBothExist(t *testing.T) {
- input := []byte(`{"model":"gpt-4","prompt_cache_key":"cache-body"}`)
- override := map[string]interface{}{
- "operations": []interface{}{
- map[string]interface{}{
- "mode": "sync_fields",
- "from": "header:session_id",
- "to": "json:prompt_cache_key",
- },
- },
- }
- ctx := map[string]interface{}{
- "request_headers_raw": map[string]interface{}{
- "session_id": "cache-header",
- },
- "request_headers": map[string]interface{}{
- "session_id": "cache-header",
- },
- }
- out, err := ApplyParamOverride(input, override, ctx)
- if err != nil {
- t.Fatalf("ApplyParamOverride returned error: %v", err)
- }
- assertJSONEqual(t, `{"model":"gpt-4","prompt_cache_key":"cache-body"}`, string(out))
- headers, _ := ctx["header_override"].(map[string]interface{})
- if headers != nil {
- if _, exists := headers["session_id"]; exists {
- t.Fatalf("expected no override when both sides already have value")
- }
- }
- }
- func TestApplyParamOverrideSyncFieldsInvalidTarget(t *testing.T) {
- input := []byte(`{"model":"gpt-4"}`)
- override := map[string]interface{}{
- "operations": []interface{}{
- map[string]interface{}{
- "mode": "sync_fields",
- "from": "foo:session_id",
- "to": "json:prompt_cache_key",
- },
- },
- }
- _, err := ApplyParamOverride(input, override, nil)
- if err == nil {
- t.Fatalf("expected error, got nil")
- }
- }
- func TestApplyParamOverrideSetHeaderKeepOrigin(t *testing.T) {
- input := []byte(`{"temperature":0.7}`)
- override := map[string]interface{}{
- "operations": []interface{}{
- map[string]interface{}{
- "mode": "set_header",
- "path": "X-Feature-Flag",
- "value": "new-value",
- "keep_origin": true,
- },
- },
- }
- ctx := map[string]interface{}{
- "header_override": map[string]interface{}{
- "X-Feature-Flag": "legacy-value",
- },
- "header_override_normalized": map[string]interface{}{
- "x_feature_flag": "legacy-value",
- },
- }
- _, err := ApplyParamOverride(input, override, ctx)
- if err != nil {
- t.Fatalf("ApplyParamOverride returned error: %v", err)
- }
- headers, ok := ctx["header_override"].(map[string]interface{})
- if !ok {
- t.Fatalf("expected header_override context map")
- }
- if headers["X-Feature-Flag"] != "legacy-value" {
- t.Fatalf("expected keep_origin to preserve old value, got: %v", headers["X-Feature-Flag"])
- }
- }
- func TestApplyParamOverrideConditionsObjectShorthand(t *testing.T) {
- input := []byte(`{"temperature":0.7}`)
- override := map[string]interface{}{
- "operations": []interface{}{
- map[string]interface{}{
- "path": "temperature",
- "mode": "set",
- "value": 0.1,
- "logic": "AND",
- "conditions": map[string]interface{}{
- "is_retry": true,
- "last_error.status_code": 400.0,
- },
- },
- },
- }
- ctx := map[string]interface{}{
- "is_retry": true,
- "last_error": map[string]interface{}{
- "status_code": 400.0,
- },
- }
- out, err := ApplyParamOverride(input, override, ctx)
- if err != nil {
- t.Fatalf("ApplyParamOverride returned error: %v", err)
- }
- assertJSONEqual(t, `{"temperature":0.1}`, string(out))
- }
- func TestApplyParamOverrideWithRelayInfoSyncRuntimeHeaders(t *testing.T) {
- info := &RelayInfo{
- ChannelMeta: &ChannelMeta{
- ParamOverride: map[string]interface{}{
- "operations": []interface{}{
- map[string]interface{}{
- "mode": "set_header",
- "path": "X-Injected-By-Param-Override",
- "value": "enabled",
- },
- map[string]interface{}{
- "mode": "delete_header",
- "path": "X-Delete-Me",
- },
- },
- },
- HeadersOverride: map[string]interface{}{
- "X-Delete-Me": "legacy",
- "X-Keep-Me": "keep",
- },
- },
- }
- input := []byte(`{"temperature":0.7}`)
- out, err := ApplyParamOverrideWithRelayInfo(input, info)
- if err != nil {
- t.Fatalf("ApplyParamOverrideWithRelayInfo returned error: %v", err)
- }
- assertJSONEqual(t, `{"temperature":0.7}`, string(out))
- if !info.UseRuntimeHeadersOverride {
- t.Fatalf("expected runtime header override to be enabled")
- }
- if info.RuntimeHeadersOverride["X-Keep-Me"] != "keep" {
- t.Fatalf("expected X-Keep-Me header to be preserved, got: %v", info.RuntimeHeadersOverride["X-Keep-Me"])
- }
- if info.RuntimeHeadersOverride["X-Injected-By-Param-Override"] != "enabled" {
- t.Fatalf("expected X-Injected-By-Param-Override header to be set, got: %v", info.RuntimeHeadersOverride["X-Injected-By-Param-Override"])
- }
- if _, exists := info.RuntimeHeadersOverride["X-Delete-Me"]; exists {
- t.Fatalf("expected X-Delete-Me header to be deleted")
- }
- }
- func TestApplyParamOverrideWithRelayInfoMoveAndCopyHeaders(t *testing.T) {
- info := &RelayInfo{
- ChannelMeta: &ChannelMeta{
- ParamOverride: map[string]interface{}{
- "operations": []interface{}{
- map[string]interface{}{
- "mode": "move_header",
- "from": "X-Legacy-Trace",
- "to": "X-Trace",
- },
- map[string]interface{}{
- "mode": "copy_header",
- "from": "X-Trace",
- "to": "X-Trace-Backup",
- },
- },
- },
- HeadersOverride: map[string]interface{}{
- "X-Legacy-Trace": "trace-123",
- },
- },
- }
- input := []byte(`{"temperature":0.7}`)
- _, err := ApplyParamOverrideWithRelayInfo(input, info)
- if err != nil {
- t.Fatalf("ApplyParamOverrideWithRelayInfo returned error: %v", err)
- }
- if _, exists := info.RuntimeHeadersOverride["X-Legacy-Trace"]; exists {
- t.Fatalf("expected source header to be removed after move")
- }
- if info.RuntimeHeadersOverride["X-Trace"] != "trace-123" {
- t.Fatalf("expected X-Trace to be set, got: %v", info.RuntimeHeadersOverride["X-Trace"])
- }
- if info.RuntimeHeadersOverride["X-Trace-Backup"] != "trace-123" {
- t.Fatalf("expected X-Trace-Backup to be copied, got: %v", info.RuntimeHeadersOverride["X-Trace-Backup"])
- }
- }
- func assertJSONEqual(t *testing.T, want, got string) {
- t.Helper()
- var wantObj interface{}
- var gotObj interface{}
- if err := json.Unmarshal([]byte(want), &wantObj); err != nil {
- t.Fatalf("failed to unmarshal want JSON: %v", err)
- }
- if err := json.Unmarshal([]byte(got), &gotObj); err != nil {
- t.Fatalf("failed to unmarshal got JSON: %v", err)
- }
- if !reflect.DeepEqual(wantObj, gotObj) {
- t.Fatalf("json not equal\nwant: %s\ngot: %s", want, got)
- }
- }
|