lofcz / LlmTornado

One .NET library to consume OpenAI, Anthropic, Cohere, Google, Azure, Groq, and self-hosed APIs.
https://github.com/lofcz/LlmTornado
MIT License
32 stars 11 forks source link

Cohere Embeddings API Error: You didn't provide an API key #19

Closed primaryobjects closed 2 months ago

primaryobjects commented 2 months ago

Hi, there may be an issue with the Cohere Embedding API, not providing the correct request headers. It appears to be calling platform.openai.com instead of cohere.

Example of code that fails

string apiKey = "<API_KEY>";
TornadoApi api = new([new ProviderAuthentication(LLmProviders.Cohere, apiKey)]);
EmbeddingResult result = api.Embeddings.CreateEmbeddingAsync("cats and dogs").GetAwaiter().GetResult();

Output

Note, You can obtain an API key from https://platform.openai.com/account/api-keys. when the provider is Cohere.

"error": {
        "message": "You didn't provide an API key. You need to provide your API key in an Authorization header using Bearer auth (i.e. Authorization: Bearer YOUR_KEY), or as the password field (with blank username) if you're accessing the API from your browser and are prompted for a username and password. You can obtain an API key from https://platform.openai.com/account/api-keys.",
        "type": "invalid_request_error",
        "param": null,
        "code": null
    }

Workaround using HttpRequest

var request = new HttpRequestMessage
{
    Method = HttpMethod.Post,
    RequestUri = new Uri("https://api.cohere.com/v1/embed"),
    Headers =
    {
        { "Authorization", $"Bearer {apiKey}" }
    },
    Content = new StringContent(JsonConvert.SerializeObject(new
    {
        model = "embed-english-v3.0",
        texts = new[] { "cats or dogs", "puppies or kittens", "cars and boxes", "the capital of the United States is Washington DC" },
        input_type = "classification",
        truncate = "NONE"
    }), Encoding.UTF8, "application/json")
};

var response = await _client.SendAsync(request);
response.EnsureSuccessStatusCode();
var responseBody = await response.Content.ReadAsStringAsync();

Output

{\"id\":\"66587f51-72ad-454a-9b68-699039097111\",\"texts\":[\"cats or dogs\",\"puppies or kittens\",\"cars and boxes\",\"the capital of the united states is washington dc\"],\"embeddings\":[[0.01197052,0.006336212,0.003780365,0.02444458,-0.03237915,-0.006641388,0.014801025,-0.02810669,0.020126343,-0.004940033,-0.028625488,0.017440796, ... \"}
lofcz commented 2 months ago

Thanks for bringing this to my attention - I've just released version 3.1.3 with Cohere Embeddings support.

The first snippet should now be:

string apiKey = "<API_KEY>";
TornadoApi api = new([new ProviderAuthentication(LLmProviders.Cohere, apiKey)]);
float[] result = await api.Embeddings.Embeddings.GetEmbeddings(EmbeddingModel.Cohere.Gen3.Multilingual, "lorem ipsum");

To specify input_type and truncate:

EmbeddingResult? result = await api.Embeddings.CreateEmbedding(EmbeddingModel.Cohere.Gen3.Multilingual, "lorem ipsum", new EmbeddingRequestVendorExtensions
{
    Cohere = new EmbeddingRequestVendorCohereExtensions
    {
        InputType = EmbeddingVendorCohereExtensionInputTypes.Classification,
        Truncate = EmbeddingVendorCohereExtensionTruncation.End
    }
});

Multiple inputs can be passed at once (as in your last snippet):

EmbeddingResult? result = await api.Embeddings.CreateEmbedding(EmbeddingModel.Cohere.Gen3.Multilingual, [ "lorem ipsum", "dolor sit amet" ], new EmbeddingRequestVendorExtensions
{
    Cohere = new EmbeddingRequestVendorCohereExtensions
    {
        InputType = EmbeddingVendorCohereExtensionInputTypes.Classification,
        Truncate = EmbeddingVendorCohereExtensionTruncation.End
    }
});
lofcz commented 2 months ago

Please let me know if you run into any further issues, thanks!