package runner import ( "strings" "testing" ) func TestBuildCacheAffinityKeyUsesExplicitKeyFirst(t *testing.T) { body := map[string]any{ "cacheAffinityKey": "session-a", "sessionId": "session-b", "messages": []any{map[string]any{"role": "user", "content": "hello"}}, } got := buildCacheAffinityKey("chat.completions", "text_generate", body) if !strings.HasPrefix(got, "explicit:") { t.Fatalf("expected explicit cache affinity key, got %q", got) } } func TestBuildCacheAffinityKeyUsesSessionContinuity(t *testing.T) { got := buildCacheAffinityKey("chat.completions", "text_generate", map[string]any{ "session_id": "conversation-1", }) if !strings.HasPrefix(got, "session_id:") { t.Fatalf("expected session cache affinity key, got %q", got) } } func TestBuildCacheAffinityKeyFallsBackToPromptHash(t *testing.T) { body := map[string]any{ "messages": []any{ map[string]any{"role": "system", "content": "stable"}, map[string]any{"role": "user", "content": "hello"}, }, "tools": []any{map[string]any{"type": "function", "function": map[string]any{"name": "lookup"}}}, } first := buildCacheAffinityKey("chat.completions", "text_generate", body) second := buildCacheAffinityKey("chat.completions", "text_generate", body) if first == "" || first != second || !strings.HasPrefix(first, "prompt_lcp:") { t.Fatalf("expected stable prompt LCP cache affinity key, first=%q second=%q", first, second) } } func TestBuildCacheAffinityKeysUsesMessagePrefixLCPKeys(t *testing.T) { first := buildCacheAffinityKeys("chat.completions", "text_generate", map[string]any{ "messageHashes": []any{"system-hash", "user-hash"}, "tools": []any{map[string]any{"type": "function", "function": map[string]any{"name": "lookup"}}}, }) next := buildCacheAffinityKeys("chat.completions", "text_generate", map[string]any{ "messageHashes": []any{"system-hash", "user-hash", "assistant-hash", "tool-hash"}, "tools": []any{map[string]any{"type": "function", "function": map[string]any{"name": "lookup"}}}, }) if !strings.HasPrefix(first.Primary, "prompt_lcp:") { t.Fatalf("expected LCP prompt key, got %+v", first) } if len(first.Record) != 2 || len(next.Lookup) != 4 { t.Fatalf("expected per-message prefix keys, first=%+v next=%+v", first, next) } found := false for _, key := range next.Lookup { if key == first.Primary { found = true break } } if !found { t.Fatalf("next lookup keys should include first request prefix key, first=%+v next=%+v", first, next) } }