| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223 |
- 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 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)
- }
- }
|