Skip to content

v3.0.0 Release

Latest
Compare
Choose a tag to compare
@fern-support fern-support released this 03 Feb 16:21
· 4 commits to main since this release
a420d98

This release updates the SDK for Pinecone API version 2025-01. It introduces new features, several breaking changes, and improvements to the Pinecone .NET Client.

New Features

Support for Sparse Indexes

Pinecone's API now lets you create sparse indexes.
Here's an example of how to use the Pinecone SDK with sparse vectors.

using Pinecone;

// Initialize Pinecone client with your API key
var pinecone = new PineconeClient(Environment.GetEnvironmentVariable("PINECONE_API_KEY"));


var indexName = "test-sparse-index";

// Create a sparse serverless index
Console.WriteLine("Creating serverless index...");
await pinecone.CreateIndexAsync(new CreateIndexRequest
{
    Name = indexName,
    VectorType = VectorType.Sparse,
    Spec = new ServerlessIndexSpec
    {
        Serverless = new ServerlessSpec
        {
            Cloud = ServerlessSpecCloud.Aws,
            Region = "us-east-1",
        }
    }
});

// Wait for index to be ready
Console.WriteLine("Waiting for index to be ready...");
while (true)
{
    var indexInfo = await pinecone.DescribeIndexAsync(indexName);
    if (indexInfo.Status.State == IndexModelStatusState.Ready)
    {
        break;
    }

    Console.WriteLine("Index not ready yet, waiting...");
    await Task.Delay(TimeSpan.FromSeconds(2));
}

// Get index instance
var index = pinecone.Index(indexName);

// Prepare sparse vector data
var sparseIndices = new uint[] { 1, 2 };
var sparseValues = new ReadOnlyMemory<float>([1f, 2f]);

// Create vector with sparse values
var vector = new Vector
{
    Id = "v1",
    SparseValues = new SparseValues
    {
        Indices = sparseIndices,
        Values = sparseValues
    }
};

// Upsert vector
Console.WriteLine("Upserting vector...");
var upsertResponse = await index.UpsertAsync(new UpsertRequest
{
    Vectors = new List<Vector> { vector }
});
Console.WriteLine($"Upserted {upsertResponse.UpsertedCount} vector");

// Query by vector ID
Console.WriteLine("Querying vector by ID...");
var queryResponse = await index.QueryAsync(new QueryRequest
{
    Id = vector.Id,
    TopK = 1,
    IncludeValues = true,
});
// Note: It can take up to 1 minute before upserted records are available to query.
// https://docs.pinecone.io/guides/indexes/sparse-indexes#upsert-sparse-vectors

// Display query results
Console.WriteLine("Query results:");
foreach (var match in queryResponse.Matches)
{
    Console.WriteLine($"ID: {match.Id}");
    if (match.SparseValues != null)
    {
        var indicesString = string.Join(", ", match.SparseValues.Indices);
        Console.WriteLine($"Sparse Indices: [{indicesString}]");
        var valuesString = string.Join(", ", match.SparseValues.Values.ToArray());
        Console.WriteLine($"Sparse Values: [{valuesString}]");
    }
}

// Delete the index
Console.WriteLine("Deleting index...");
await pinecone.DeleteIndexAsync(indexName);
Console.WriteLine("Index deleted successfully");

New Operations

  • client.CreateIndexForModelAsync(CreateIndexForModelRequest { ... }) -> Index

Breaking Changes

Embedding Type Changes

The Embedding type has changed from a simple object to a discriminated union, supporting both DenseEmbedding and SparseEmbedding. This change provides better type safety but requires code updates.

New helper methods available on the Embedding type:

  • IsDense & IsSparse - Type checking
  • AsDense() & AsSparse() - Type conversion
  • Match() and Visit() - Pattern matching

Example of updating your code:

// Before
Embedding embedding = GetEmbedding();
foreach (var value in embedding.Values.Span)
{
    Console.WriteLine(value);
}

// After
Embedding embedding = GetEmbedding();
switch (embedding.VectorType)
{
    case VectorType.Dense:
        DenseEmbedding denseEmbedding = embedding.AsDense();
        foreach (var value in denseEmbedding.Values.Span)
        {
            Console.WriteLine(value);
        }
        break;
    case VectorType.Sparse:
        SparseEmbedding sparseEmbedding = embedding.AsSparse();
        foreach (var value in sparseEmbedding.SparseValues.Span)
        {
            Console.WriteLine(value);
        }
        break;
}

Type Changes

EmbedRequest

The Parameters property now uses Dictionary<string, object?>? instead of EmbedRequestParameters:

public record EmbedRequest
{
    public Dictionary<string, object?>? Parameters { get; set; }
}

RankedDocument

The Document property now uses Dictionary<string, object?>? instead of Dictionary<string, string>?:

public record RankedDocument
{
    public Dictionary<string, object?>? Document { get; set; }
}

RerankRequest

Update property types for more flexibility:

public record RerankRequest
{
    public IEnumerable<Dictionary<string, object?>> Documents { get; set; }
    public Dictionary<string, object?>? Parameters { get; set; }
}

Optional Properties

The following properties are now nullable:

  • Index.Dimension: int?
  • Index.Tags: Dictionary<string, string>?
  • PodSpec.Replicas: int?
  • PodSpec.Shards: int?
  • PodSpec.Pods: int?
  • Vector.Values: int?

Migration Guide

  1. Update embedding handling code to use the new discriminated union pattern
  2. Replace EmbedRequestParameters usage with Dictionary<string, object?>?
  3. Update code handling RankedDocument to work with object values
  4. Review and update code that assumes non-nullable properties for Index and PodSpec
  5. Update RerankRequest implementations to use the new parameter types

Full Changelog: 2.1.0...3.0.0