GoodMem
ReferenceClient SDKs.NET SDK

.NET SDK

.NET/C# client SDK for GoodMem with full async support

No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)

This C# SDK is automatically generated by the OpenAPI Generator project:

  • API version:
  • SDK version: 1.0.5
  • Generator version: 7.14.0-SNAPSHOT
  • Build package: org.openapitools.codegen.languages.CSharpClientCodegen

Frameworks supported

Dependencies

The DLLs included in the package may not be the latest version. We recommend using NuGet to obtain the latest version of the packages:

Install-Package Newtonsoft.Json
Install-Package JsonSubTypes
Install-Package System.ComponentModel.Annotations

Installation

Run the following command to generate the DLL

  • [Mac/Linux] /bin/sh build.sh
  • [Windows] build.bat

Then include the DLL (under the bin folder) in the C# project, and use the namespaces:

using Pairsystems.Goodmem.Client.Api;
using Pairsystems.Goodmem.Client.Client;
using Pairsystems.Goodmem.Client.Model;

Packaging

A .nuspec is included with the project. You can follow the Nuget quickstart to create and publish packages.

This .nuspec uses placeholders from the .csproj, so build the .csproj directly:

nuget pack -Build -OutputDirectory out Pairsystems.Goodmem.Client.csproj

Then, publish to a local feed or other host and consume the new package via Nuget as usual.

Usage

To use the API client with a HTTP proxy, setup a System.Net.WebProxy

Configuration c = new Configuration();
System.Net.WebProxy webProxy = new System.Net.WebProxy("[http://myProxyUrl:80/](http://myProxyUrl:80/)");
webProxy.Credentials = System.Net.CredentialCache.DefaultCredentials;
c.Proxy = webProxy;

Connections

Each ApiClass (properly the ApiClient inside it) will create an instance of HttpClient. It will use that for the entire lifecycle and dispose it when called the Dispose method.

To better manager the connections it's a common practice to reuse the HttpClient and HttpClientHandler (see here for details). To use your own HttpClient instance just pass it to the ApiClass constructor.

HttpClientHandler yourHandler = new HttpClientHandler();
HttpClient yourHttpClient = new HttpClient(yourHandler);
var api = new YourApiClass(yourHttpClient, yourHandler);

If you want to use an HttpClient and don't have access to the handler, for example in a DI context in Asp.net Core when using IHttpClientFactory.

HttpClient yourHttpClient = new HttpClient();
var api = new YourApiClass(yourHttpClient);

You'll loose some configuration settings, the features affected are: Setting and Retrieving Cookies, Client Certificates, Proxy settings. You need to either manually handle those in your setup of the HttpClient or they won't be available.

Here an example of DI setup in a sample web project:

services.`AddHttpClient<YourApiClass>`(httpClient =>
   new PetApi(httpClient));

Getting Started

using System.Collections.Generic;
using System.Diagnostics;
using System.Net.Http;
using Pairsystems.Goodmem.Client.Api;
using Pairsystems.Goodmem.Client.Client;
using Pairsystems.Goodmem.Client.Model;

namespace Example
{
    public class Example
    {
        public static void Main()
        {

            Configuration config = new Configuration();
            config.BasePath = "[http://localhost:8080";](http://localhost:8080";)
            // create instances of HttpClient, HttpClientHandler to be reused later with different Api classes
            
            
            var apiInstance = new APIKeysApi(config);
            var createApiKeyRequest = new CreateApiKeyRequest(); // CreateApiKeyRequest | API key configuration

            try
            {
                // Create a new API key
                CreateApiKeyResponse result = apiInstance.CreateApiKey(createApiKeyRequest);
                Debug.WriteLine(result);
            }
            catch (ApiException e)
            {
                Debug.Print("Exception when calling APIKeysApi.CreateApiKey: " + e.Message );
                Debug.Print("Status Code: "+ e.ErrorCode);
                Debug.Print(e.StackTrace);
            }

        }
    }
}

Streaming Memory Retrieval

The GoodMem .NET client provides a StreamingClient class for real-time streaming memory retrieval. This is the recommended approach for memory retrieval operations.

Supported Formats

The StreamingClient supports two streaming formats:

  • NDJSON (application/x-ndjson) - Newline-delimited JSON (default, recommended)
  • SSE (text/event-stream) - Server-Sent Events

Basic Streaming with ChatPostProcessor

Use RetrieveMemoryStreamChatAsync() for streaming with automatic ChatPostProcessor configuration:

using Pairsystems.Goodmem.Client;
using Pairsystems.Goodmem.Client.Client;
using System;
using System.Collections.Generic;
using System.Threading;

// Configure client
var config = new Configuration();
config.BasePath = "[http://localhost:8080";](http://localhost:8080";)
config.DefaultHeaders["X-API-Key"] = "your-api-key";
config.DefaultHeaders["X-API-Key"] = "your-api-key";

// Create streaming client
var streamingClient = new StreamingClient(config);

// Stream with ChatPostProcessor (NDJSON format)
await foreach (var ev in streamingClient.RetrieveMemoryStreamChatAsync(
    "your search query",
    new `List<string>` { "space-uuid" },
    10,                    // requested size
    true,                  // fetch memory
    false,                 // fetch memory content
    "ndjson",              // format (ndjson or sse)
    "llm-uuid",            // LLM ID
    "reranker-uuid",       // reranker ID
    0.5,                   // relevance threshold
    0.3,                   // LLM temperature
    10,                    // max results
    true,                  // chronological resort
    CancellationToken.None))
{
    if (ev.AbstractReply != null)
    {
        Console.WriteLine($"Abstract: {ev.AbstractReply.Text}");
    }
    else if (ev.RetrievedItem?.Memory != null)
    {
        Console.WriteLine($"Memory: {ev.RetrievedItem.Memory}");
    }
}

Advanced Streaming with Custom Post-Processor

Use RetrieveMemoryStreamAdvancedAsync() for custom post-processor configuration:

// Create advanced request
var request = new AdvancedMemoryStreamRequest
{
    Message = "your search query",
    SpaceIds = new `List<string>` { "space-uuid" },
    RequestedSize = 10,
    FetchMemory = true,
    FetchMemoryContent = false,
    Format = "ndjson",  // or "sse"
    PostProcessorName = "com.goodmem.retrieval.postprocess.ChatPostProcessorFactory",
    PostProcessorConfig = new Dictionary<string, object>
    {
        ["llm_id"] = "llm-uuid",
        ["reranker_id"] = "reranker-uuid",
        ["relevance_threshold"] = 0.5,
        ["llm_temp"] = 0.3,
        ["max_results"] = 10,
        ["chronological_resort"] = true
    }
};

// Execute streaming
await foreach (var ev in streamingClient.RetrieveMemoryStreamAdvancedAsync(request, CancellationToken.None))
{
    if (ev.AbstractReply != null)
    {
        Console.WriteLine($"Abstract: {ev.AbstractReply.Text}");
    }
    else if (ev.RetrievedItem != null)
    {
        Console.WriteLine($"Retrieved: {ev.RetrievedItem}");
    }
}

Choosing Between NDJSON and SSE

  • NDJSON (recommended): Simpler parsing, better for most use cases
  • SSE: Standard browser EventSource API compatible, useful for web applications

Documentation for API Endpoints

All URIs are relative to *http://localhost*

ClassMethodHTTP requestDescription
APIKeysApiCreateApiKeyPOST /v1/apikeysCreate a new API key
APIKeysApiDeleteApiKeyDELETE /v1/apikeys/{id}Delete an API key
APIKeysApiListApiKeysGET /v1/apikeysList API keys
APIKeysApiUpdateApiKeyPUT /v1/apikeys/{id}Update an API key
AdministrationApiDrainServerPOST /v1/admin:drainRequest the server to enter drain mode
AdministrationApiPurgeBackgroundJobsPOST /v1/admin/background-jobs:purgePurge completed background jobs
AdministrationApiReloadLicensePOST /v1/admin/license:reloadReload the active license from disk
EmbeddersApiCreateEmbedderPOST /v1/embeddersCreate a new embedder
EmbeddersApiDeleteEmbedderDELETE /v1/embedders/{id}Delete an embedder
EmbeddersApiGetEmbedderGET /v1/embedders/{id}Get an embedder by ID
EmbeddersApiListEmbeddersGET /v1/embeddersList embedders
EmbeddersApiUpdateEmbedderPUT /v1/embedders/{id}Update an embedder
LLMsApiCreateLLMPOST /v1/llmsCreate a new LLM
LLMsApiDeleteLLMDELETE /v1/llms/{id}Delete an LLM
LLMsApiGetLLMGET /v1/llms/{id}Get an LLM by ID
LLMsApiListLLMsGET /v1/llmsList LLMs
LLMsApiUpdateLLMPUT /v1/llms/{id}Update an LLM
MemoriesApiBatchCreateMemoryPOST /v1/memories:batchCreateCreate multiple memories in a batch
MemoriesApiBatchDeleteMemoryPOST /v1/memories:batchDeleteDelete multiple memories by ID
MemoriesApiBatchGetMemoryPOST /v1/memories:batchGetGet multiple memories by ID
MemoriesApiCreateMemoryPOST /v1/memoriesCreate a new memory
MemoriesApiDeleteMemoryDELETE /v1/memories/{id}Delete a memory
MemoriesApiGetMemoryGET /v1/memories/{id}Get a memory by ID
MemoriesApiGetMemoryContentGET /v1/memories/{id}/contentDownload memory content
MemoriesApiListMemoriesGET /v1/spaces/{spaceId}/memoriesList memories in a space
MemoriesApiRetrieveMemoryGET /v1/memories:retrieveStream semantic memory retrieval
MemoriesApiRetrieveMemoryAdvancedPOST /v1/memories:retrieveAdvanced semantic memory retrieval with JSON
RerankersApiCreateRerankerPOST /v1/rerankersCreate a new reranker
RerankersApiDeleteRerankerDELETE /v1/rerankers/{id}Delete a reranker
RerankersApiGetRerankerGET /v1/rerankers/{id}Get a reranker by ID
RerankersApiListRerankersGET /v1/rerankersList rerankers
RerankersApiUpdateRerankerPUT /v1/rerankers/{id}Update a reranker
SpacesApiCreateSpacePOST /v1/spacesCreate a new Space
SpacesApiDeleteSpaceDELETE /v1/spaces/{id}Delete a space
SpacesApiGetSpaceGET /v1/spaces/{id}Get a space by ID
SpacesApiListSpacesGET /v1/spacesList spaces
SpacesApiUpdateSpacePUT /v1/spaces/{id}Update a space
SystemApiGetSystemInfoGET /v1/system/infoRetrieve server build metadata
SystemApiInitializeSystemPOST /v1/system/initInitialize the system
UsersApiGetCurrentUserGET /v1/users/meGet current user profile
UsersApiGetUserGET /v1/users/{id}Get a user by ID
UsersApiGetUserByEmailGET /v1/users/email/{email}Get user by email address

Documentation for Models

Documentation for Authorization

Endpoints do not require authorization.