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