HoneyHive
Wrap GoodMem operations in a traced Python client so every GoodMem call surfaces as a HoneyHive span.
Overview
GoodMem is a memory layer for AI agents that handles embedding, vector search, reranking, and
LLM-powered answering server-side. The HoneyHive integration wraps the official goodmem SDK in a
Python client whose operations are decorated with HoneyHive's @trace, so each GoodMem call —
creating spaces, storing memories, semantic retrieval — shows up as a span in the active HoneyHive
session for tracing and observability. A degraded retrieval is visible in the trace rather than
recorded as a clean success.
Installation
pip install goodmem-honeyhiveThe pip package is goodmem-honeyhive; the import name is goodmem_honeyhive.
Configuration
GoodMem connection settings are passed to the client through a GoodMemConfig object. When no
config is given, base_url and api_key fall back to the GOODMEM_BASE_URL and
GOODMEM_API_KEY environment variables; the other settings are config-only:
| Setting | Description |
|---|---|
base_url | Base URL of your GoodMem server (no /v1 suffix), e.g. https://your-goodmem-server.example.com. Falls back to GOODMEM_BASE_URL. |
api_key | GoodMem API key, sent as X-API-Key. Falls back to GOODMEM_API_KEY. Stored as a SecretStr, so a repr, log line, or traced payload shows **********. |
verify_ssl | Set to False to skip TLS verification for self-signed dev certs (default: True). |
timeout | HTTP request timeout in seconds (default: 30.0). |
In addition, HoneyHive tracing is initialized separately via HoneyHiveTracer.init(), which
requires your HoneyHive credentials:
| Argument | Description |
|---|---|
api_key | HoneyHive API key. |
project | HoneyHive project name that spans are reported under. |
Quick start
from honeyhive import HoneyHiveTracer
from goodmem_honeyhive import GoodMemClient, GoodMemConfig
HoneyHiveTracer.init(api_key="<your-honeyhive-key>", project="my-project")
client = GoodMemClient(
GoodMemConfig(
base_url="https://your-goodmem-server.example.com",
api_key="gm_xxxxxxxxxxxxxxxxxxxxxxxx",
)
)
embedders = client.list_embedders()
embedder_id = embedders["embedders"][0]["embedder_id"]
space = client.create_space(name="quickstart", embedder_id=embedder_id)
space_id = space["space_id"]
client.create_memory(
space_id=space_id,
text_content="The capital of France is Paris.",
)
results = client.retrieve_memories(
query="What is the capital of France?",
space_ids=[space_id],
max_results=3,
)
print(results)Memories index asynchronously and the read path never polls, so a retrieval immediately after a
write can come back empty. The result's partial and statuses fields distinguish a search the
server degraded from one that genuinely found nothing.
Local development. The example above uses a TLS-verified production URL. If you are running
GoodMem locally with a self-signed certificate, use https://localhost:8080 and disable TLS
verification with the client's verify-SSL option (see the Configuration table above). Keep TLS
verification enabled for any deployed server.
Retrieval post-processing
retrieve_memories (and retrieve, which returns the same data as a structured
RetrievalOutcome instead of a traced dictionary) accepts these optional parameters:
| Parameter | Type | Description |
|---|---|---|
max_results | integer | Maximum number of chunks to request (default: 5). |
reranker_id | UUID | Reranker model that reorders matched chunks by relevance. Pass None (not "") for no reranker. |
llm_id | UUID | GoodMem LLM that generates a grounded answer (abstract_reply) alongside the chunks. Pass None (not "") for no LLM. It does not rerank or change scores. |
metadata_filter | dict | Server-side filter every retrieved memory must match, escaped by goodmem_honeyhive.filters. |
Every id argument must be a UUID; anything else — including an empty string — raises
GoodMemError before any request is made. Each result carries chunk_id, chunk_text,
memory_id, space_id, content_type, metadata, and a score oriented so higher is better,
with raw_score (exactly what the server sent) and score_kind ("vector" or "reranker" —
the two are not on a common scale) beside it. When a requested reranker fails, the server returns
the vector-stage hits (score_kind: "vector"), the retrieval is marked partial, and statuses
carries what the server reported — so the span shows a degraded retrieval as degraded.
Learn more
The full README, examples, and API reference are available on the PyPI package page.