180 lines · 6.6 KB · Go
RawDownload
package executor import (	"context"	"io"	"net/http/httptest"	"testing" 	"github.com/gin-gonic/gin"	"github.com/google/uuid"	cliproxyauth "github.com/router-for-me/CLIProxyAPI/v6/sdk/cliproxy/auth"	cliproxyexecutor "github.com/router-for-me/CLIProxyAPI/v6/sdk/cliproxy/executor"	sdktranslator "github.com/router-for-me/CLIProxyAPI/v6/sdk/translator"	"github.com/tidwall/gjson") func TestCodexExecutorCacheHelper_OpenAIChatCompletions_StablePromptCacheKeyFromAPIKey(t *testing.T) {	recorder := httptest.NewRecorder()	ginCtx, _ := gin.CreateTestContext(recorder)	ginCtx.Set("apiKey", "test-api-key") 	ctx := context.WithValue(context.Background(), "gin", ginCtx)	executor := &CodexExecutor{}	rawJSON := []byte(`{"model":"gpt-5.3-codex","stream":true}`)	req := cliproxyexecutor.Request{		Model:   "gpt-5.3-codex",		Payload: []byte(`{"model":"gpt-5.3-codex"}`),	}	url := "https://example.com/responses" 	httpReq, _, err := executor.cacheHelper(ctx, nil, sdktranslator.FromString("openai"), url, req, cliproxyexecutor.Options{}, rawJSON)	if err != nil {		t.Fatalf("cacheHelper error: %v", err)	} 	body, errRead := io.ReadAll(httpReq.Body)	if errRead != nil {		t.Fatalf("read request body: %v", errRead)	} 	expectedKey := uuid.NewSHA1(uuid.NameSpaceOID, []byte("cli-proxy-api:codex:prompt-cache:test-api-key")).String()	gotKey := gjson.GetBytes(body, "prompt_cache_key").String()	if gotKey != expectedKey {		t.Fatalf("prompt_cache_key = %q, want %q", gotKey, expectedKey)	}	if gotSession := httpReq.Header.Get("session_id"); gotSession != expectedKey {		t.Fatalf("session_id = %q, want %q", gotSession, expectedKey)	}	if got := httpReq.Header.Get("Conversation_id"); got != "" {		t.Fatalf("Conversation_id = %q, want empty", got)	} 	httpReq2, _, err := executor.cacheHelper(ctx, nil, sdktranslator.FromString("openai"), url, req, cliproxyexecutor.Options{}, rawJSON)	if err != nil {		t.Fatalf("cacheHelper error (second call): %v", err)	}	body2, errRead2 := io.ReadAll(httpReq2.Body)	if errRead2 != nil {		t.Fatalf("read request body (second call): %v", errRead2)	}	gotKey2 := gjson.GetBytes(body2, "prompt_cache_key").String()	if gotKey2 != expectedKey {		t.Fatalf("prompt_cache_key (second call) = %q, want %q", gotKey2, expectedKey)	}} func TestCodexExecutorCacheHelper_OpenAIResponses_PreservesPromptCacheRetention(t *testing.T) {	executor := &CodexExecutor{}	url := "https://example.com/responses"	req := cliproxyexecutor.Request{		Model:   "gpt-5.3-codex",		Payload: []byte(`{"model":"gpt-5.3-codex","prompt_cache_key":"cache-key-1","prompt_cache_retention":"persistent"}`),	}	rawJSON := []byte(`{"model":"gpt-5.3-codex","stream":true,"prompt_cache_retention":"persistent"}`) 	httpReq, _, err := executor.cacheHelper(context.Background(), nil, sdktranslator.FromString("openai-response"), url, req, cliproxyexecutor.Options{}, rawJSON)	if err != nil {		t.Fatalf("cacheHelper error: %v", err)	} 	body, err := io.ReadAll(httpReq.Body)	if err != nil {		t.Fatalf("read request body: %v", err)	} 	if got := gjson.GetBytes(body, "prompt_cache_key").String(); got != "cache-key-1" {		t.Fatalf("prompt_cache_key = %q, want %q", got, "cache-key-1")	}	if got := gjson.GetBytes(body, "prompt_cache_retention").String(); got != "persistent" {		t.Fatalf("prompt_cache_retention = %q, want %q", got, "persistent")	}	if got := httpReq.Header.Get("session_id"); got != "cache-key-1" {		t.Fatalf("session_id = %q, want %q", got, "cache-key-1")	}	if got := httpReq.Header.Get("Conversation_id"); got != "" {		t.Fatalf("Conversation_id = %q, want empty", got)	}} func TestCodexExecutorCacheHelper_OpenAIChatCompletions_UsesExecutionSessionForContinuity(t *testing.T) {	executor := &CodexExecutor{}	rawJSON := []byte(`{"model":"gpt-5.4","stream":true}`)	req := cliproxyexecutor.Request{		Model:   "gpt-5.4",		Payload: []byte(`{"model":"gpt-5.4"}`),	}	opts := cliproxyexecutor.Options{Metadata: map[string]any{cliproxyexecutor.ExecutionSessionMetadataKey: "exec-session-1"}} 	httpReq, _, err := executor.cacheHelper(context.Background(), nil, sdktranslator.FromString("openai"), "https://example.com/responses", req, opts, rawJSON)	if err != nil {		t.Fatalf("cacheHelper error: %v", err)	} 	body, err := io.ReadAll(httpReq.Body)	if err != nil {		t.Fatalf("read request body: %v", err)	} 	if got := gjson.GetBytes(body, "prompt_cache_key").String(); got != "exec-session-1" {		t.Fatalf("prompt_cache_key = %q, want %q", got, "exec-session-1")	}	if got := httpReq.Header.Get("session_id"); got != "exec-session-1" {		t.Fatalf("session_id = %q, want %q", got, "exec-session-1")	}} func TestCodexExecutorCacheHelper_OpenAIChatCompletions_FallsBackToStableAuthID(t *testing.T) {	executor := &CodexExecutor{}	rawJSON := []byte(`{"model":"gpt-5.4","stream":true}`)	req := cliproxyexecutor.Request{		Model:   "gpt-5.4",		Payload: []byte(`{"model":"gpt-5.4"}`),	}	auth := &cliproxyauth.Auth{ID: "codex-auth-1", Provider: "codex"} 	httpReq, _, err := executor.cacheHelper(context.Background(), auth, sdktranslator.FromString("openai"), "https://example.com/responses", req, cliproxyexecutor.Options{}, rawJSON)	if err != nil {		t.Fatalf("cacheHelper error: %v", err)	} 	body, err := io.ReadAll(httpReq.Body)	if err != nil {		t.Fatalf("read request body: %v", err)	} 	expected := uuid.NewSHA1(uuid.NameSpaceOID, []byte("cli-proxy-api:codex:prompt-cache:auth:codex-auth-1")).String()	if got := gjson.GetBytes(body, "prompt_cache_key").String(); got != expected {		t.Fatalf("prompt_cache_key = %q, want %q", got, expected)	}	if got := httpReq.Header.Get("session_id"); got != expected {		t.Fatalf("session_id = %q, want %q", got, expected)	}} func TestCodexExecutorCacheHelper_ClaudePreservesCacheContinuity(t *testing.T) {	executor := &CodexExecutor{}	req := cliproxyexecutor.Request{		Model:   "claude-3-7-sonnet",		Payload: []byte(`{"metadata":{"user_id":"user-1"}}`),	}	rawJSON := []byte(`{"model":"gpt-5.4","stream":true}`) 	httpReq, continuity, err := executor.cacheHelper(context.Background(), nil, sdktranslator.FromString("claude"), "https://example.com/responses", req, cliproxyexecutor.Options{}, rawJSON)	if err != nil {		t.Fatalf("cacheHelper error: %v", err)	}	if continuity.Key == "" {		t.Fatal("continuity.Key = empty, want non-empty")	}	body, err := io.ReadAll(httpReq.Body)	if err != nil {		t.Fatalf("read request body: %v", err)	}	if got := gjson.GetBytes(body, "prompt_cache_key").String(); got != continuity.Key {		t.Fatalf("prompt_cache_key = %q, want %q", got, continuity.Key)	}	if got := httpReq.Header.Get("session_id"); got != continuity.Key {		t.Fatalf("session_id = %q, want %q", got, continuity.Key)	}}