Quantcast
Viewing latest article 27
Browse Latest Browse All 827

Pinecone Vector Upsert Implementation in Unity - Getting NotFound Error

Hi everyone,

I’m working on implementing Pinecone’s vector upsert functionality into my Unity project, but I’m encountering an issue. When I try to send an upsert request to Pinecone, I receive a NotFound response status.

Here’s what I’ve done so far:

  • I’m using UnityWebRequest to send the upsert request to the Pinecone endpoint.
  • The endpoint I’m using is: https://loko-aqwaefa.svc.aped-4627-b74a.pinecone.io/vectors/upsert.
  • I’ve confirmed that the API key I’m using is valid.
  • I’ve also verified that the index exists in Pinecone.

Despite these checks, I’m still getting the NotFound error.

Has anyone encountered this issue while implementing Pinecone in Unity? Any suggestions or fixes would be greatly appreciated!

Thanks in advance!

using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.Networking;
using Newtonsoft.Json;

[Serializable]
public class TextInput
{
    public string text;
}

[Serializable]
public class EmbedRequestBody
{
    public string model;
    public object parameters;
    public List<TextInput> inputs;
}

[Serializable]
public class EmbedParameters
{
    public string input_type;
    public string truncate;
}

[Serializable]
public class EmbedResponse
{
    public List<EmbeddingData> data;
    public string model;
    public string vector_type;
    public Usage usage;
}

[Serializable]
public class EmbeddingData
{
    public float[] values;
}

[Serializable]
public class Usage
{
    public int total_tokens;
}

[Serializable]
public class UpsertRequestBody
{
    public List<PineconeVector> vectors;
}

[Serializable]
public class PineconeVector
{
    public string id;
    public float[] values;
    public Metadata metadata;
}

[Serializable]
public class Metadata
{
    public string text;
    public string timestamp;
}

public class PineconeService : MonoBehaviour
{
    [SerializeField] private string pineconeApiKey = "YOUR_API_KEY";
    
    // Pinecone endpoints
    private string embedApiUrl = "https://api.pinecone.io/embed";
    private string indexApiUrl = "https://loko-aqwaefa.svc.aped-4627-b74a.pinecone.io";
    
    // Model configuration - matches your index configuration
    [SerializeField] private string embeddingModel = "multilingual-e5-large";
    
    private void Start()
    {
        // Example usage
        StoreTextInPinecone("This is a test memory to store in Pinecone using the proper workflow.");
    }
    
    public async void StoreTextInPinecone(string text)
    {
        try
        {
            // Step 1: Generate embedding for the text
            float[] embedding = await GenerateEmbedding(text);
            if (embedding == null || embedding.Length == 0)
            {
                Debug.LogError("Failed to generate embedding. Cannot proceed with upsert.");
                return;
            }
            
            // Step 2: Upsert the embedding to Pinecone index
            await UpsertToPinecone(text, embedding);
        }
        catch (Exception ex)
        {
            Debug.LogError($"Error in StoreTextInPinecone: {ex.Message}");
        }
    }
    
    public async Task<float[]> GenerateEmbedding(string text)
    {
        Debug.Log($"Generating embedding for text: {text}");
        
        // Create request body for embedding generation
        var embedRequest = new EmbedRequestBody
        {
            model = embeddingModel,
            parameters = new EmbedParameters
            {
                input_type = "passage",
                truncate = "END"
            },
            inputs = new List<TextInput>
            {
                new TextInput { text = text }
            }
        };
        
        string jsonPayload = JsonConvert.SerializeObject(embedRequest);
        Debug.Log($"Sending embed request (JSON length: {Encoding.UTF8.GetByteCount(jsonPayload)} bytes)");
        
        UnityWebRequest request = new UnityWebRequest(embedApiUrl, "POST");
        byte[] bodyRaw = Encoding.UTF8.GetBytes(jsonPayload);
        request.uploadHandler = new UploadHandlerRaw(bodyRaw);
        request.downloadHandler = new DownloadHandlerBuffer();
        request.SetRequestHeader("Content-Type", "application/json");
        request.SetRequestHeader("Api-Key", pineconeApiKey);
        request.SetRequestHeader("X-Pinecone-API-Version", "2025-01");
        
        await request.SendWebRequest();
        
        if (request.result != UnityWebRequest.Result.Success)
        {
            Debug.LogError($"Embed API Error: {request.result}, {request.error}");
            Debug.LogError($"Response: {request.downloadHandler.text}");
            return null;
        }
        
        // Parse response
        string responseJson = request.downloadHandler.text;
        Debug.Log($"Embed API Response: {responseJson}");
        
        EmbedResponse embedResponse = JsonConvert.DeserializeObject<EmbedResponse>(responseJson);
        if (embedResponse != null && embedResponse.data != null && embedResponse.data.Count > 0)
        {
            Debug.Log($"Successfully generated embedding with {embedResponse.data[0].values.Length} dimensions");
            return embedResponse.data[0].values;
        }
        
        Debug.LogError("Failed to parse embedding response");
        return null;
    }
    
    public async Task UpsertToPinecone(string text, float[] embedding)
    {
        // Create upsert request body
        var upsertRequest = new UpsertRequestBody
        {
            vectors = new List<PineconeVector>
            {
                new PineconeVector
                {
                    id = Guid.NewGuid().ToString(),
                    values = embedding,
                    metadata = new Metadata
                    {
                        text = text,
                        timestamp = DateTime.UtcNow.ToString("o")
                    }
                }
            }
        };
        
        string jsonPayload = JsonConvert.SerializeObject(upsertRequest);
        Debug.Log($"Sending upsert request to {indexApiUrl} (JSON length: {Encoding.UTF8.GetByteCount(jsonPayload)} bytes)");
        
        UnityWebRequest request = new UnityWebRequest(indexApiUrl, "POST");
        byte[] bodyRaw = Encoding.UTF8.GetBytes(jsonPayload);
        request.uploadHandler = new UploadHandlerRaw(bodyRaw);
        request.downloadHandler = new DownloadHandlerBuffer();
        request.SetRequestHeader("Content-Type", "application/json");
        request.SetRequestHeader("Api-Key", pineconeApiKey);
        
        await request.SendWebRequest();
        
        Debug.Log($"Pinecone upsert response status: {request.result}");
        Debug.Log($"Pinecone upsert response body: {request.downloadHandler.text}");
        
        if (request.result != UnityWebRequest.Result.Success)
        {
            Debug.LogError($"Error upserting to Pinecone: {request.result}, {request.error}");
            return;
        }
        
        Debug.Log("Successfully stored record in Pinecone!");
    }
    
    // Method to search for similar text in your Pinecone index
    public async Task<List<(string text, float score)>> SearchSimilarTexts(string queryText, int topK = 5)
    {
        // First generate embedding for the query text
        float[] queryEmbedding = await GenerateEmbedding(queryText);
        if (queryEmbedding == null)
        {
            Debug.LogError("Failed to generate embedding for search query");
            return null;
        }
        
        // Create search request
        var searchRequest = new
        {
            vector = queryEmbedding,
            topK = topK,
            includeMetadata = true
        };
        
        string jsonPayload = JsonConvert.SerializeObject(searchRequest);
        string searchUrl = "https://loko-aqwaefa.svc.aped-4627-b74a.pinecone.io/query";
        
        UnityWebRequest request = new UnityWebRequest(searchUrl, "POST");
        byte[] bodyRaw = Encoding.UTF8.GetBytes(jsonPayload);
        request.uploadHandler = new UploadHandlerRaw(bodyRaw);
        request.downloadHandler = new DownloadHandlerBuffer();
        request.SetRequestHeader("Content-Type", "application/json");
        request.SetRequestHeader("Api-Key", pineconeApiKey);
        
        await request.SendWebRequest();
        
        if (request.result != UnityWebRequest.Result.Success)
        {
            Debug.LogError($"Search API Error: {request.result}, {request.error}");
            return null;
        }
        
        // Parse response
        var searchResponse = JsonConvert.DeserializeObject<Dictionary<string, object>>(request.downloadHandler.text);
        var matches = JsonConvert.DeserializeObject<List<Dictionary<string, object>>>(
            JsonConvert.SerializeObject(searchResponse["matches"]));
        
        var results = new List<(string text, float score)>();
        foreach (var match in matches)
        {
            var metadata = JsonConvert.DeserializeObject<Dictionary<string, object>>(
                JsonConvert.SerializeObject(match["metadata"]));
            string text = metadata["text"].ToString();
            float score = float.Parse(match["score"].ToString());
            
            results.Add((text, score));
        }
        
        return results;
    }
}

3 posts - 2 participants

Read full topic


Viewing latest article 27
Browse Latest Browse All 827

Trending Articles