GoodMem
ReferenceClient SDKsGo SDK

Go SDK

Go client SDK for GoodMem with streaming support

Go Reference Go Report Card

Go client for GoodMem - a vector-based memory storage and retrieval service. Provides APIs for creating memory spaces, storing memories with vector embeddings, and performing semantic search with streaming retrieval. Supports multiple embedding providers and advanced metadata handling.

This Go package is automatically generated by the OpenAPI Generator project with custom streaming functionality:

  • API version: v1
  • Package version: 1.0.0
  • Generator version: 7.13.0
  • Build package: org.openapitools.codegen.languages.GoClientCodegen

For more information, please visit https://goodmem.ai

Requirements

  • Go 1.18+

Installation

Install the package using Go modules:

go get github.com/PAIR-Systems-Inc/goodmem/clients/go@latest

Then import the package in your Go code:

import goodmem_client "github.com/PAIR-Systems-Inc/goodmem/clients/go"

Getting Started

Basic API Usage

package main

import (
    "context"
    "fmt"
    "log"

    goodmem_client "github.com/PAIR-Systems-Inc/goodmem/clients/go"
)

func main() {
    // Configure the API client
    configuration := goodmem_client.NewConfiguration()
    configuration.Host = "[http://localhost:8080"](http://localhost:8080")

    // Set authentication (replace with your API key)
    configuration.DefaultHeader["Authorization"] = "Bearer your-api-key-here"

    // Create API client
    apiClient := goodmem_client.NewAPIClient(configuration)

    // Create an API key
    apiKeysApi := apiClient.APIKeysAPI
    createRequest := *goodmem_client.NewCreateApiKeyRequest()

    // Add labels to the API key
    labels := map[string]string{
        "environment": "development",
        "service":     "chat-ui",
    }
    createRequest.SetLabels(labels)

    // Execute the API call
    ctx := context.Background()
    apiResponse, httpResponse, err := apiKeysApi.CreateApiKey(ctx).CreateApiKeyRequest(createRequest).Execute()
    if err != nil {
        log.Fatalf("Error creating API key: %v", err)
    }

    fmt.Printf("API Key created successfully!\n")
    fmt.Printf("API Key ID: %s\n", apiResponse.ApiKeyMetadata.GetApiKeyId())
    fmt.Printf("Raw API Key: %s\n", apiResponse.GetRawApiKey())
    fmt.Printf("HTTP Status: %d\n", httpResponse.StatusCode)
}

Streaming Memory Retrieval

⭐ Primary Feature: For memory retrieval operations, use the streaming client which is the main way to search and retrieve memories:

package main

import (
    "context"
    "fmt"
    "log"

    goodmem_client "github.com/PAIR-Systems-Inc/goodmem/clients/go"
)

func main() {
    // Configure client
    configuration := goodmem_client.NewConfiguration()
    configuration.Host = "[http://localhost:8080"](http://localhost:8080")
    configuration.DefaultHeader["Authorization"] = "Bearer your-api-key-here"

    apiClient := goodmem_client.NewAPIClient(configuration)

    // Create streaming client
    streamingClient := goodmem_client.NewStreamingClient(apiClient)

    // Get available spaces
    spacesApi := apiClient.SpacesAPI
    ctx := context.Background()
    
    spaces, _, err := spacesApi.ListSpaces(ctx).Execute()
    if err != nil {
        log.Fatalf("Error listing spaces: %v", err)
    }

    if len(spaces.GetSpaces()) == 0 {
        log.Fatal("No spaces available. Create a space first.")
    }

    spaceID := spaces.GetSpaces()[0].GetSpaceId()

    // Stream memory retrieval using simple method
    spaceIDs := []string{spaceID}
    stream, err := streamingClient.RetrieveMemoryStreamSimple(
        ctx,
        "your search query here",
        spaceIDs,
    )
    if err != nil {
        log.Fatalf("Error starting stream: %v", err)
    }
    defer stream.Close()

    // Process streaming events
    for {
        event, err := stream.Recv()
        if err != nil {
            if err.Error() == "EOF" {
                break // End of stream
            }
            log.Printf("Stream error: %v", err)
            break
        }

        // Handle different event types
        if event.AbstractReply != nil {
            fmt.Printf("📝 Abstract Reply: %s\n", event.AbstractReply.GetText())
            fmt.Printf("   Relevance Score: %.2f\n", event.AbstractReply.GetRelevanceScore())
        } else if event.RetrievedItem != nil && event.RetrievedItem.Memory != nil {
            memory := event.RetrievedItem.GetMemory()
            fmt.Printf("🧠 Retrieved Memory ID: %s\n", memory.GetMemoryId())
            
            // Access memory content if available
            if memory.Content != nil {
                fmt.Printf("   Content: %s\n", memory.Content.GetText())
            }
            
            // Access metadata
            if labels := memory.GetLabels(); len(labels) > 0 {
                fmt.Printf("   Labels: %v\n", labels)
            }
        } else if event.MemoryDefinition != nil {
            fmt.Printf("📋 Memory Definition received\n")
        }
    }
}

Advanced Streaming with Custom Configuration

// Advanced streaming with custom post-processor configuration
advancedConfig := &goodmem_client.StreamingConfig{
    RequestedSize:        10,
    FetchMemory:         true,
    FetchMemoryContent:  false,
    Format:              "ndjson",
    PostProcessorName:   "com.goodmem.retrieval.postprocess.ChatPostProcessorFactory",
    PostProcessorConfig: map[string]interface{}{
        "llm_id":              "your-llm-uuid-here",
        "reranker_id":         "your-reranker-uuid-here",
        "relevance_threshold": 0.5,
        "max_results":         10,
        "chronological_resort": true,
    },
}

stream, err := streamingClient.RetrieveMemoryStreamAdvanced(
    ctx,
    "your search query",
    spaceIDs,
    advancedConfig,
)
// ... handle stream as above

Configuration

Server URL Configuration

You can configure different server URLs:

configuration := goodmem_client.NewConfiguration()
configuration.Host = "[https://your-goodmem-server.com"](https://your-goodmem-server.com")

// For local development
configuration.Host = "[http://localhost:8080"](http://localhost:8080")

Authentication

Set your API key in the configuration:

// Method 1: Using Authorization header
configuration.DefaultHeader["Authorization"] = "Bearer your-api-key"

// Method 2: Using API key authentication (if configured)
configuration.DefaultHeader["X-API-Key"] = "your-api-key"

HTTP Client Configuration

Customize the underlying HTTP client:

import (
    "net/http"
    "time"
)

// Create custom HTTP client with timeout
httpClient := &http.Client{
    Timeout: 30 * time.Second,
}

configuration := goodmem_client.NewConfiguration()
configuration.HTTPClient = httpClient

API Documentation

API Endpoints

All URIs are relative to your server URL (e.g., [http://localhost:8080](http://localhost:8080))

ServiceMethodHTTP 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
EmbeddersAPICreateEmbedderPOST /v1/embeddersCreate a new embedder
EmbeddersAPIDeleteEmbedderDELETE /v1/embedders/\{id\}Delete an embedder
EmbeddersAPIGetEmbedderGET /v1/embedders/\{id\}Get embedder by ID
EmbeddersAPIListEmbeddersGET /v1/embeddersList embedders
EmbeddersAPIUpdateEmbedderPUT /v1/embedders/\{id\}Update an embedder
MemoriesAPIBatchCreateMemoryPOST /v1/memories/batchCreate multiple memories
MemoriesAPIBatchDeleteMemoryPOST /v1/memories/batch/deleteDelete multiple memories
MemoriesAPIBatchGetMemoryPOST /v1/memories/batch/getGet multiple memories
MemoriesAPICreateMemoryPOST /v1/memoriesCreate a new memory
MemoriesAPIDeleteMemoryDELETE /v1/memories/\{id\}Delete a memory
MemoriesAPIGetMemoryGET /v1/memories/\{id\}Get memory by ID
MemoriesAPIListMemoriesGET /v1/spaces/\{spaceId\}/memoriesList memories in space
MemoriesAPIRetrieveMemoryGET /v1/memories/retrieveRetrieve memories using streaming
MemoriesAPIRetrieveMemoryAdvancedPOST /v1/memories/retrieveRetrieve memories using streaming
RerankersAPICreateRerankerPOST /v1/rerankersCreate a new reranker
RerankersAPIDeleteRerankerDELETE /v1/rerankers/\{id\}Delete a reranker
RerankersAPIGetRerankerGET /v1/rerankers/\{id\}Get reranker by ID
RerankersAPIListRerankersGET /v1/rerankersList rerankers
RerankersAPIUpdateRerankerPUT /v1/rerankers/\{id\}Update a reranker
SpacesAPICreateSpacePOST /v1/spacesCreate a new memory space
SpacesAPIDeleteSpaceDELETE /v1/spaces/\{id\}Delete a space
SpacesAPIGetSpaceGET /v1/spaces/\{id\}Get space by ID
SpacesAPIListSpacesGET /v1/spacesList all spaces
SpacesAPIUpdateSpacePUT /v1/spaces/\{id\}Update a space
SystemAPIInitializeSystemPOST /v1/system/initInitialize the system
UsersAPIGetCurrentUserGET /v1/users/meGet current user profile
UsersAPIGetUserGET /v1/users/\{id\}Get user by ID
UsersAPIGetUserByEmailGET /v1/users/email/\{email\}Get user by email

📝 Note: The RetrieveMemory methods in the standard API don't handle streaming properly. Use the StreamingClient for all memory retrieval operations.

Key Models

  • Space - Memory space for organizing memories with specific embedders
  • Memory - Individual memory with content, embeddings, and metadata
  • ApiKeyResponse - API key information and metadata
  • RetrieveMemoryEvent - Streaming event for memory retrieval
  • StreamingConfig - Configuration for advanced streaming operations

Features

✅ Standard OpenAPI Features

  • Complete API coverage for all GoodMem endpoints
  • Automatic request/response serialization
  • Built-in error handling and HTTP status codes
  • Configurable timeouts and retry logic
  • Type-safe Go structs for all models

⭐ Custom Streaming Features

  • Real-time memory retrieval with Server-Sent Events (SSE)
  • Simple streaming interface with RetrieveMemoryStreamSimple()
  • Advanced streaming configuration with custom post-processors
  • Automatic event parsing for different response types
  • Graceful connection handling with proper cleanup

🔧 Advanced Configuration

  • Custom post-processor support (ChatPostProcessor, etc.)
  • Configurable relevance thresholds and result limits
  • Support for multiple embedding providers
  • Flexible metadata and label handling

Error Handling

apiResponse, httpResponse, err := apiClient.APIKeysAPI.CreateApiKey(ctx).Execute()
if err != nil {
    // Check if it's an API error with details
    if httpResponse != nil {
        fmt.Printf("HTTP Status: %d\n", httpResponse.StatusCode)
        fmt.Printf("Response: %v\n", httpResponse)
    }
    
    // Handle specific error types
    switch err.Error() {
    case "401":
        fmt.Println("Authentication failed - check your API key")
    case "404":
        fmt.Println("Resource not found")
    case "500":
        fmt.Println("Server error")
    default:
        fmt.Printf("API Error: %v\n", err)
    }
    return
}

Testing

Run the included tests (note: requires a running GoodMem server for integration tests):

## Run unit tests
go test ./...

## Run tests with verbose output
go test -v ./...

## Run streaming tests specifically
go test -v -run TestStreaming ./...

Examples

Check out the examples/ directory for more comprehensive examples:

  • Basic API operations (spaces, memories, API keys)
  • Streaming memory retrieval with different configurations
  • Error handling and authentication patterns
  • Performance optimization techniques

Compatibility

  • Go Version: 1.18+ (uses Go modules)
  • GoodMem Server: Compatible with API version v1
  • OpenAPI: Generated from OpenAPI 3.0 specification
  • HTTP Client: Uses standard net/http package

Contact & Support

For questions, issues, or contributions:

License

This Go client is licensed under the Apache License 2.0. See the LICENSE file for details.

Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

🤖 This client library is automatically generated from the GoodMem OpenAPI specification with custom streaming enhancements.