Skip to main content

honeyhive-goodmem

GoodMem memory as HoneyHive-traced operations. Every call appears as a span alongside the rest of your agent's work, so memory reads and writes are visible in the same trace as the model calls they feed.

Version 0.2.0. Verified against GoodMem server v1.0.320.

Upgrading from 0.1.0. This is an observability package, which makes 0.1.0's worst defect specific to it: retrieval statuses were dropped, so a retrieval that failed was recorded as a successful span. A space whose embedder was unavailable produced success: true, totalResults: 0 — in HoneyHive that reads as "the index is empty", not "the search broke". See Changes in 0.2.0.

Security. 0.1.0's test file carried a live GoodMem API key as a default value, on the public default branch and in the v0.1.0 tag. It is removed here and the environment variable is now required with no fallback — but removing it from the tree does not un-leak it. That key needs rotating.

Install

pip install honeyhive-goodmem

Use

from honeyhive import HoneyHiveTracer
from honeyhive_goodmem import GoodMemClient, GoodMemConfig

HoneyHiveTracer.init(api_key="<your-honeyhive-key>", project="my-project")

client = GoodMemClient(
    GoodMemConfig(base_url="https://your-goodmem-server", api_key="<your-goodmem-key>")
)

Both GoodMem settings fall back to GOODMEM_BASE_URL and GOODMEM_API_KEY. Without a tracer the methods still run; HoneyHive logs that no tracer is active and no span is emitted.

What a retrieval span records

client.retrieve_memories("what did I store?", space_ids=["<space-uuid>"], max_results=5)
{
  "success": True,
  "query": "...",
  "results": [
    {
      "chunk_id": "...", "chunk_text": "...", "memory_id": "...", "space_id": "...",
      "score": 0.64,          # higher is better
      "raw_score": -0.64,     # exactly what the server sent
      "score_kind": "vector", # or "reranker" -- not the same scale
      "content_type": "text/plain",
      "metadata": {...},      # the memory's metadata, joined by UUID
    }
  ],
  "total_results": 1,
  "partial": False,           # True when the server reported a problem
  "statuses": [],             # what it reported
  "result_set_id": "...",
}

partial means exactly one thing: the server reported a real problem during this retrieval. It is independent of whether hits came back. A degraded search still returns whatever arrived, with partial set and a warning key; when nothing usable arrives the result is empty and still flagged. The span therefore shows a failed retrieval as failed.

For structured use, client.retrieve(...) returns the same data as a RetrievalOutcome object instead of a traced dictionary.

Scores

GoodMem produces two kinds of score and they are not comparable. Vector scores are negative distances, so score is the flipped value with raw_score kept beside it. Reranker scores are already higher-is-better, on a provider-dependent scale — measured live on the same five documents, Voyage rerank-2.5 returned 0.27..0.93 and Jina jina-reranker-v3 returned -0.14..0.43. There is therefore no default threshold anywhere in this package.

Metadata filters

Filters are expressions evaluated server-side, not SQL:

from honeyhive_goodmem import filters

client.retrieve_memories("q", ["<space-uuid>"], metadata_filter={"tenant": "acme"})

expression = filters.all_of(
    filters.equals("tenant", "acme"),
    filters.compare("year", ">=", 2026),
)

The helper applies the escaping the server accepts (' → \', \ → \\; SQL-style '' doubling is rejected with HTTP 400), refuses control characters, restricts field names, and casts each value to the type GoodMem stored — a boolean compared as TEXT is accepted with HTTP 200 and matches nothing.

Operations

Method Event
create_space, list_spaces, get_space, update_space, delete_space tool
list_embedders tool
create_memory, get_memory, list_memories, delete_memory tool
retrieve_memories retrieval

update_space takes name and labels. It no longer offers public_read: the server removed that field and answers 400 Unrecognized field "publicRead".

Changes in 0.2.0

Reproduced against the published 0.1.0 wheel, live against GoodMem v1.0.320.

Was Now
A live GoodMem API key was the default value of GOODMEM_API_KEY in the test file, on the public default branch Removed; the variable is required with no fallback. The key still needs rotating
A failing embedder produced success: true, totalResults: 0 — the server's EMBEDDER_FAILED was dropped, so the span said success partial + statuses + warning in the traced payload
A broken reranker produced success: true with three statuses discarded Same contract; hits are still returned, flagged
Hand-written httpx client Official goodmem SDK
public_read was a parameter; the server answers HTTP 400 Gone
Empty search took 11.65 s — wait_for_indexing on by default 0.31 s; the read path never polls
Reusing a space name reported the embedder you asked for while the space ran another Reuse requires a match; a mismatch names both
Chunks and memories were two arrays joined by positional memory_index Joined by UUID, de-duplicated by chunk id
Raw negative scores in the span score / raw_score / score_kind
nextToken appeared nowhere — listings returned one page Paginated, bounded by max_list_items
No metadata filtering filters, escaped and type-correct
The API key was a public attribute Private; absent from repr and from every traced payload
13 live-only tests that fell back to a committed key; no CI 33 offline + 16 live; CI on 3.11–3.13

Already correct in 0.1.0 and unchanged: request timeouts (30 s by default), and the error path — the server's own message reaches the caller.

Tests

Suite Count Needs
tests/test_honeyhive_goodmem.py 33 nothing — the real SDK over a mock transport, fed NDJSON captured from a live server
tests/test_honeyhive_goodmem_live.py 16 GOODMEM_API_KEY + GOODMEM_BASE_URL; skips entirely without them
pip install -e . pytest httpx "ruff==0.7.4" mypy

pytest tests/test_honeyhive_goodmem.py

GOODMEM_API_KEY=... GOODMEM_BASE_URL=... \
  GOODMEM_TEST_EMBEDDER_ID=... \
  pytest tests/test_honeyhive_goodmem_live.py

ruff check honeyhive_goodmem tests && mypy honeyhive_goodmem

One offline test scans the tree for a credential-shaped string, so the defect that shipped in 0.1.0 cannot come back unnoticed. The live suite creates one space per run and asserts, against a fresh listing, that it is gone.

License

Apache-2.0.

Release files for honeyhive-goodmem 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for honeyhive-goodmem 0.2.0
File Size Uploaded
honeyhive_goodmem-0.2.0.tar.gz 20.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for honeyhive-goodmem 0.2.0
File Interpreter ABI Platform
honeyhive_goodmem-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 41.0 kB

Release files / honeyhive_goodmem-0.2.0.tar.gz

Download URL honeyhive_goodmem-0.2.0.tar.gz
Size 20.5 kB
Tags Source
SHA-256 checksum
How to use checksums
172091a989352f25a6de8e64d7c22778a976495fc7179cdf5b3b8de379da8047
BLAKE2b-256 checksum
How to use checksums
e7f43f91f29b8879a4a7711c7824c3d7acec8f9858210d4ba41b676303225cf9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 24, 2026.

Transparency log

Release files / honeyhive_goodmem-0.2.0-py3-none-any.whl

Download URL honeyhive_goodmem-0.2.0-py3-none-any.whl
Size 20.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
608671829e1cf7c857a6cda5ccc62d753e329522f53d0952bac4f9dcc7fd37ec
BLAKE2b-256 checksum
How to use checksums
22eb0cc28dc55dbcbc61d446d365127a31379e44290d3c59298292ffb3a95ec9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 24, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page