Awesome Go

dakera-go

CategoryArtificial Intelligence
SubcategoryArtificial Intelligence
Stars7

Official Go client SDK for the Dakera self-hosted agent memory server, providing typed interfaces for memory store/recall, session management, namespace operations, and decay configuration

About dakera-go


Why Dakera?

DakeraOthers
LoCoMo Recall@2088.2% (1,536 Q, LLM-judged retrieval recall)not directly comparable
DeploymentSingle binary, Docker one-linerExternal vector DB + embedding service required
EmbeddingsBuilt-in — no OpenAI key neededRequires external embedding API
Search modesVector · BM25 · Hybrid · Knowledge GraphUsually one or two
Dependenciesstdlib net/http onlyOften pulls in gRPC or third-party HTTP clients

→ Try the playground · Full benchmark results · dakera.ai


Run Dakera

docker run -d \
  --name dakera \
  -p 3000:3000 \
  -e DAKERA_ROOT_API_KEY=dk-mykey \
  ghcr.io/dakera-ai/dakera:latest

curl http://localhost:3000/health  # → {"status":"ok"}

For persistent storage with Docker Compose:

curl -sSfL https://raw.githubusercontent.com/Dakera-AI/dakera-deploy/main/docker/docker-compose.yml \
  -o docker-compose.yml
DAKERA_API_KEY=dk-mykey docker compose up -d

Full deployment guide (Docker Compose, Kubernetes, Helm): dakera-deploy


Install

go get github.com/dakera-ai/dakera-go@latest

Requires Go 1.21+. Uses only the standard library — no external runtime dependencies.


Quick Start

client := dakera.NewClientWithOptions(dakera.ClientOptions{BaseURL: "http://localhost:3000", APIKey: "dk-mykey"})
imp := float32(0.9)
client.StoreMemory(context.Background(), "my-agent", dakera.StoreMemoryRequest{Content: "User prefers brevity", Importance: &imp})

Full example — store, recall, upsert, and hybrid search:

package main

import (
    "context"
    "fmt"
    dakera "github.com/dakera-ai/dakera-go"
)

func main() {
    client := dakera.NewClientWithOptions(dakera.ClientOptions{
        BaseURL: "http://localhost:3000",
        APIKey:  "dk-mykey",
    })
    ctx := context.Background()

    // Store an agent memory
    imp := float32(0.9)
    mem, _ := client.StoreMemory(ctx, "my-agent", dakera.StoreMemoryRequest{
        Content:    "User prefers concise responses with code examples",
        Importance: &imp,
    })
    fmt.Println("Stored:", mem.Memory.ID)

    // Recall memories (semantic search)
    resp, _ := client.Recall(ctx, "my-agent", dakera.RecallRequest{
        Query: "what does the user prefer?",
        TopK:  5,
    })
    for _, m := range resp.Memories {
        fmt.Printf("[%.2f] %s\n", m.Score, m.Content)
    }

    // Upsert vectors
    client.Upsert(ctx, "my-namespace", []dakera.VectorInput{
        {ID: "vec1", Values: []float32{0.1, 0.2, 0.3}},
    })

    // Hybrid search (vector + BM25)
    results, _ := client.HybridSearch(ctx, "my-namespace", nil, "completed task", &dakera.HybridSearchOptions{
        TopK:         5,
        VectorWeight: 0.7,
    })
    for _, r := range results {
        fmt.Println(r.ID, r.Score)
    }
}

Context-based cancellation

All methods accept a context.Context — use it for timeouts, deadlines, or cancellation:

ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()

resp, err := client.Recall(ctx, "my-agent", dakera.RecallRequest{Query: "preferences", TopK: 3})

Text auto-embedding

Send raw text without pre-computing embeddings — Dakera embeds server-side:

client.UpsertText(ctx, "my-namespace", []dakera.TextInput{
    {ID: "doc1", Text: "Agent completed onboarding flow successfully"},
})

Features

  • Agent Memory — store, recall, search, and forget memories with importance scoring
  • Sessions — group memories by conversation with auto-consolidation on session end
  • Knowledge Graph — traverse memory relationships, find paths, export graphs
  • Vector Search — ANN queries with metadata filters and batch operations
  • Full-Text Search — BM25 ranking with stemming and stop-word filtering
  • Hybrid Search — combine vector similarity with keyword matching
  • Text Auto-Embedding — server-side embedding generation (no local model needed)
  • Namespaces — isolated vector stores per project, tenant, or use case
  • Feedback Loop — upvote/downvote/flag memories to improve recall quality
  • T-I-F Reliability — TifScore struct and EvaluateTif() for Truth-Indeterminacy-Falsity scoring of memory reliability
  • Entity Extraction — GLiNER NER for automatic entity detection
  • SSE Streaming — Server-sent event subscriptions for real-time memory updates
  • Typed Filters — Eq(), Gt(), Contains(), ArrayContains() and more
  • Context-Based — all methods accept context.Context for cancellation and timeouts
  • Retry & Rate Limiting — built-in exponential backoff and rate-limit header tracking
  • Zero Dependencies — standard library net/http client, no external runtime deps

Connect to Dakera

// Self-hosted
client := dakera.NewClientWithOptions(dakera.ClientOptions{
    BaseURL: "http://your-server:3000",
    APIKey:  "your-key",
})

// Cloud (early access)
client := dakera.NewClientWithOptions(dakera.ClientOptions{
    BaseURL: "http://<your-server-ip>:3000",
    APIKey:  "your-key",
})

// With custom retry config
client := dakera.NewClientWithOptions(dakera.ClientOptions{
    BaseURL:     "http://localhost:3000",
    APIKey:      "your-key",
    RetryBackoff: &dakera.RetryConfig{MaxRetries: 5, BaseDelay: 200 * time.Millisecond, MaxDelay: 30 * time.Second, Jitter: true},
})

What's new in v0.12.2

SDK v0.12.2 targets Dakera server v0.12.2 and stays compatible with v0.12.0 and v0.12.1 servers: new request fields are omitted unless you set them, new response fields are optional (nil / empty on an older server), and the new routes answer 404 there. Check caps.Auth, caps.Sessions (or SupportsKeyUpdate(), SupportsSessionTouch()) to see what the connected server has.

FeatureAPI
Create an agent before its first memoryCreateAgent(ctx, "mlx-dev") (Created is false for an existing agent)
Edit a key's name or namespacesUpdateKey, UpdateNamespaceKey with UpdateKeyRequest{Namespaces: dakera.GrantNamespaces("team-*")} (nil = unchanged, GrantAllNamespaces() = null, GrantNamespaces() = [])
Rotate with a grace periodRotateKeyWithOptions(ctx, id, &dakera.RotateKeyOptions{GraceSecs: &grace}) → OldKeyID, OldKeyExpiresAt
Who am IWhoami(ctx) — scope, grants, Unrestricted, GrantsVersion, InertNamespaces
Namespace kindsListNamespacesWithKinds, NamespaceInfo.Kind
Session idle lifecycleStartSessionRequest.IdleTimeoutSecs, TouchSession, Session.EndedReason / LastActivityAt / IdleSince, StoreMemoryResponse.SessionState, BatchStoreMemoryResponse.EndedSessions, SetSessionIdleTimeout
Derived recordsIncludeDerived on AgentMemoriesOptions and WakeUpOptions; AdminDerivationStatus, AdminDrainDerivations
Content previewsContentPreviewChars on AgentMemoriesOptions, SessionMemoriesOptions, FullKnowledgeGraphRequest, CrossAgentNetworkRequest → ContentLen, ContentTruncated
// A developer key that may create and use its own agents (prefix grant).
key, _ := client.CreateKey(ctx, dakera.CreateKeyRequest{
    Name: "dev", Scope: dakera.KeyScopeWrite,
    Namespaces: dakera.GrantNamespaces("_dakera_agent_mlx-*"),
})
_ = key // key.Key is shown once: store it in your secret manager, never in code

// A session the server never ends for inactivity.
zero := 0
sess, _ := client.StartSession(ctx, dakera.StartSessionRequest{AgentID: "mlx-dev", IdleTimeoutSecs: &zero})

// A list view: 200-character previews, full text only when needed.
preview := 200
mems, _ := client.AgentMemories(ctx, "mlx-dev", &dakera.AgentMemoriesOptions{ContentPreviewChars: &preview})
for _, m := range mems {
    if m.ContentTruncated != nil && *m.ContentTruncated {
        full, _ := client.GetMemory(ctx, "mlx-dev", m.ID)
        _ = full
    }
}
_ = sess

Behaviour changes in server v0.12.2 that clients can hit:

  • Sessions end after 4 hours without activity by default (DAKERA_SESSION_IDLE_TIMEOUT_SECS). Activity is a memory stored, batch-stored, imported or updated with the session, a session-scoped recall or search, or TouchSession. Storing into an ended session still succeeds: check StoreMemoryResponse.SessionState / BatchStoreMemoryResponse.EndedSessions and start a new session when it says ended.
  • Sessions are authorized by their agent: keys no longer need a _dakera_sessions grant (it is accepted and inert), a key without grants lists no sessions, and EndSession with a Read key gets 403.
  • Stricter validation (400, the field named in the message): invalid key grants (a**b, blank entries, internal namespaces), a client-set dakera-curated tag, _dakera_* metadata keys other than _dakera_content_date / _dakera_lang, ids of the form mem_s + 24 hex, agent ids over 241 bytes, TTLs over 100 years.
  • The content limit is in bytes (UTF-8, DAKERA_MAX_MEMORY_CONTENT_BYTES, 100000 by default) and UpdateMemory enforces it too.
  • Listings exclude derived records: AgentMemories and GetWakeUpContext leave CE-31 sentence sub-memories out unless IncludeDerived is set.
  • Legacy foo* grants stay inert on keys created before v0.12.2 (GrantsVersion 0, InertNamespaces) until the key's namespaces are saved again with UpdateKey.

What's new in v0.12.0

SDK v0.12.0 targets Dakera server v0.12.0 and is compatible with both v0.11.108 and v0.12.0 servers: every new request field is omitted from the wire unless you set it, and the new routes only exist on a v0.12 server (see the table below). Operator guide for the server side: docs/v0.12/UPGRADE.md in the server release, and the release notes in the Dakera changelog.

FeatureAPINeeds
What the server supportsclient.Capabilities(ctx) — models, index kinds, rabitq, records, attachments, vision, scoring, QueryLanguagesv0.12 (404 on v0.11)
ReadinessHealthReady, IsReady, WaitUntilReady (a 503 is "not ready", never healthy)any
Retry-Afterhonoured on 429 and 503 (capped at RetryConfig.MaxDelay); ServerError.RetryAfterany
ErrorsPayloadTooLargeError (IsQuota() tells a full namespace from an oversize request), FeatureDisabledError / NotImplementedError (501), ConflictError (409); DakeraError.Details / .Resourceany
AttachmentsUploadAttachment, ListAttachments, DownloadAttachment, DeleteAttachment, StoreMemoryRequest.AttachmentRefDAKERA_ATTACHMENTS
Transcription / image index jobsTranscribeAttachment, IndexAttachmentImage, Get*Job, WaitFor*DAKERA_ATTACHMENTS (+ DAKERA_VISION)
RecordsUpsertRecords, GetRecord — one vector plus named representations (dense, token_multivector, patch_multivector; f32/f16/i8)DAKERA_RECORDS
Per-request languageLang on store, batch store, update, recall, search and ExtractMemoryEntitiesv0.12
New valuesmodels bge-m3, colbert-small; index kind ivfpq; search mode rabitq (server-wide, DAKERA_SEARCH_MODE)v0.12
Clearing entity typesPutNamespaceEntityConfig (PUT) and PatchNamespaceEntityConfig (merge); ConfigureNamespaceNer clears with PUTv0.12 for PUT
// Wait for a starting server, then check what it can do.
if _, err := client.WaitUntilReady(ctx, dakera.ReadyWaitOptions{Timeout: 2 * time.Minute}); err != nil {
    log.Fatal(err)
}
caps, _ := client.Capabilities(ctx)
if caps.SupportsAttachments() {
    up, _ := client.UploadAttachment(ctx, dakera.AgentMemoryNamespace("my-agent"), wavBytes, "audio/wav")
    job, _ := client.TranscribeAttachment(ctx, dakera.AgentMemoryNamespace("my-agent"), up.AttachmentRef,
        dakera.TranscribeRequest{AgentID: "my-agent", Lang: "en"})
    _, err = client.WaitForTranscription(ctx, dakera.AgentMemoryNamespace("my-agent"), up.AttachmentRef, job.JobID,
        dakera.JobWaitOptions{Timeout: 5 * time.Minute})
}

Things to know when upgrading a server:

  • Health checks: v0.12 binds its port while models load. /health answers 503 with Retry-After until then; use /health/ready (HealthReady / WaitUntilReady).
  • Clearing entity_types: on a v0.12 server PATCH /v1/namespaces/{ns}/config merges and an empty list is omitted from JSON, so a PATCH cannot clear it. Use PutNamespaceEntityConfig (or ConfigureNamespaceNer with no entity types, which uses PUT and falls back to PATCH on a v0.11 server).
  • Errors are JSON everywhere; every 503 carries Retry-After; over-size bodies are 413; configuration errors are 501.
  • UpsertResponse / DeleteResponse now decode the server's real upserted_count / deleted_count fields (earlier versions read camelCase names the server never sent and so reported 0).
  • The Go SDK does not use gRPC; gRPC clients written against v0.12 must send the API key in call metadata (x-api-key or authorization: Bearer).

Examples

See the examples/ directory:

  • basic/ — vectors, namespaces, queries, filters
  • memory/ — store/recall memories, sessions, agent stats
  • advanced/ — text embedding, full-text, hybrid search, analytics

Resources

DocumentationFull API reference and guides
Go SDK docspkg.go.dev reference
BenchmarkLoCoMo evaluation results
dakera.aiWebsite and early access
GitHub OrgAll public repos
dakera-deploySelf-hosting guide

Other SDKs

SDKPackage
dakera-pydakera (PyPI)
dakera-js@dakera-ai/dakera (npm)
dakera-rsdakera-client (crates.io)
dakera-cliCLI tool
dakera-mcpMCP server for Claude/Cursor

Frequently Asked Questions

What is dakera-go?

dakera-go is a Artificial Intelligence library for the Go programming language. Official Go client SDK for the Dakera self-hosted agent memory server, providing typed interfaces for memory store/recall, session management, namespace operations, and decay configuration

How do I install dakera-go?

Install dakera-go with the Go module system using `go get dakera-ai/dakera-go`. Check the repository for the current installation instructions.

What category does dakera-go belong to?

dakera-go is listed under Artificial Intelligence, specifically Artificial Intelligence.

← Back to Artificial Intelligence