goodmem-autogen
GoodMem memory and tools for the AutoGen agent framework.
Two ways in:
GoodMemContextProvider— anautogen_core.memory.Memorybacked by a GoodMem space, so relevant passages are injected into the model context on every turn.create_goodmem_search_tool/create_goodmem_admin_tools— function tools an agent can call directly.
Built on the official goodmem SDK's async client, so nothing blocks the
event loop.
Install
pip install goodmem-autogen
Requires Python 3.10+, autogen-core 0.7.5+ and the goodmem SDK 0.1.34+
(installed with it). Version 0.2 is a break from
0.1 — see CHANGELOG for the mapping.
As an AutoGen Memory
from autogen_core.memory import MemoryContent, MemoryMimeType
from goodmem_autogen import GoodMemContextProvider, GoodMemMemoryConfig
provider = GoodMemContextProvider(
config=GoodMemMemoryConfig(
base_url="https://goodmem.example.com",
api_key="gm_...", # stored as SecretStr, never serialized
space_name="handbook", # or space_id="..." to skip the lookup
embedder_id="<embedder-uuid>",
)
)
await provider.add(MemoryContent(
content="Refunds above $500 need a manager's approval.",
mime_type=MemoryMimeType.TEXT,
metadata={"title": "handbook", "category": "policy"},
))
results = await provider.query("who approves a large refund?")
await provider.close()
add() waits for the memory to finish indexing by default, so a query right
after it finds the result. Searching is never used as a way to wait.
Attach it to an agent and update_context injects retrieved passages as a
system message each turn — the same pattern AutoGen's own ListMemory uses.
What a result carries
MemoryContent has no score field, so provenance lives in metadata:
{
"title": "handbook", "category": "policy", # the memory's own metadata
"chunk_id": "...", "memory_id": "...", "space_id": "...", "source": "...",
"score": -0.53, "score_kind": "vector",
"partial": False, "statuses": [],
}
partialisTruewhen part of the search did not complete — a reranker was unavailable, one space was unreachable. The passages are usable but may be incomplete, andstatusessays why. A search that produced nothing usable returns an empty result and emits a warning carrying the statuses, so it is distinguishable from "no matches" without being raised. The search tool returnspartial: truewithstatusesin its JSON for the same case.scoreis passed through exactly as GoodMem reports it. Vector scores are opaque similarities that may be negative; reranker scores are on a scale that depends on the reranker model (Voyagererank-2.5~0.27..0.93, Jinajina-reranker-v3~-0.14..0.43on the same documents).score_kindsays which you have — which is whyrelevance_thresholdrequires areranker_id, and why it must be calibrated for the reranker in use rather than assumed to be 0–1. The threshold is applied by the server; if it removes every result the provider warns, since an empty result would otherwise read as "no matches".score_kindis read from the response, not the configuration. If the reranker fails (RERANKING_FAILED, orNOT_FOUNDfor the reranker) the server still returns the vector-search hits; they are kept, labelledvector, and markedpartialwith those statuses.
As tools
The tools take a goodmem.AsyncGoodmem client, which you create and close.
from autogen_core import CancellationToken
from goodmem_autogen import create_goodmem_admin_tools, create_goodmem_search_tool
from goodmem import AsyncGoodmem
client = AsyncGoodmem(
base_url="https://goodmem.example.com",
api_key="gm_...",
# verify="/path/to/ca.pem", # a server with a self-signed certificate
)
search = create_goodmem_search_tool(
client, space_ids=["<space-uuid>"], limit=5,
reranker_id="<reranker-uuid>", # optional
metadata_filter={"category": "policy"}, # optional, escaped for you
)
admin_tools = create_goodmem_admin_tools(client) # only for agents that need them
# What an agent's tool call does:
print(await search.run_json({"query": "who approves a large refund?"}, CancellationToken()))
await client.close()
The model supplies only the query; spaces, reranking and filters are yours, so
an agent cannot redirect a search or widen it mid-run. The search tool returns
JSON: results (each with chunk_text, score, score_kind, metadata and
IDs), total_results, partial, and statuses when the server reported any.
create_goodmem_admin_tools(client) adds space and memory management
(goodmem_list_embedders, goodmem_list_rerankers, goodmem_list_spaces,
goodmem_get_space, goodmem_create_space, goodmem_update_space,
goodmem_delete_space, goodmem_create_memory, goodmem_list_memories,
goodmem_get_memory, goodmem_delete_memory, and goodmem_upload_file
when upload_dir is given). A listing returns at most max_items (default
100) and sets truncated when that cap may have cut it short. These
carry the authority of the configured API key — give them only to agents that
need them. File upload is only created when you pass upload_dir, and paths
resolving outside that directory are refused before the file is opened.
Every ID — a tool argument, space_ids, reranker_id, or an ID field of the
config — must be a UUID (it is lowercased); anything else raises ValueError
before a request is made. The SDK puts IDs into request paths unescaped, so
"../spaces/<id>" given as a memory ID would otherwise address a whole space.
Cancellation
add, add_file and query honour an autogen_core.CancellationToken: an
already-cancelled token prevents the request, and cancelling mid-flight aborts
it.
Clearing a space
clear() deletes every memory in the space and requires
allow_clear=True on the config, so a reflexive clear() cannot empty a
space by accident.
Filters
A filter is a GoodMem expression applied to every configured space, e.g.
CAST(val('$.category') AS TEXT) = 'policy'. Pass metadata_filter={...} and
it is built and escaped for you. Writing one by hand: inside a quoted value
escape ' as \' and \ as \\ — SQL-style '' doubling is rejected by
the server.
Development
uv venv && uv pip install -e ".[dev]"
uv run ruff check goodmem_autogen tests
uv run mypy goodmem_autogen
uv run pytest -m "not integration" # offline: the real SDK over a mock transport or a local server
GOODMEM_BASE_URL=... GOODMEM_API_KEY=... GOODMEM_EMBEDDER_ID=... \
GOODMEM_VERIFY_SSL=false uv run pytest -m integration
CI runs the first four on Python 3.10–3.13, then uv build and an import
of the wheel in a clean environment. It does not run the live suite, which
needs a server: GOODMEM_EMBEDDER_ID is the embedder its spaces are
created with, and GOODMEM_VERIFY_SSL=false is for a local server with a
self-signed certificate. The offline suite also executes every Python
snippet in this README against a local server.
Offline tests use event shapes captured from a live server. There is no default API key — live tests skip unless the environment provides one.
MIT.
Metadata
Release files for goodmem-autogen 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| goodmem_autogen-0.3.0.tar.gz | 23.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| goodmem_autogen-0.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 48.7 kB
Release files / goodmem_autogen-0.3.0.tar.gz
| Download URL | goodmem_autogen-0.3.0.tar.gz |
|---|---|
| Size | 23.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c1480d3c11ff9f2e598a840b590ec38b0eedcac2b7143edadf36feae536eefd3
|
|
BLAKE2b-256 checksum How to use checksums |
52d1bbf879e8232e1d5cb2027e0fa5eab0f9e685866c5e98fe85b0444f8aeb7c
|
| 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 29, 2026.
Transparency logRelease files / goodmem_autogen-0.3.0-py3-none-any.whl
| Download URL | goodmem_autogen-0.3.0-py3-none-any.whl |
|---|---|
| Size | 25.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f7ccd3ad6412b5922f17461a403f1a5efaa3a62421d489a1c1e1157e6dbf46b2
|
|
BLAKE2b-256 checksum How to use checksums |
b640394397482b1fee7d1a2f8c08e9ad2a30b2a6e2254509ac9109d605abfd95
|
| 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 29, 2026.
Transparency log