jennah-sdk-py
The Python SDK for Jennah, the memory and context platform for AI agents.
pip install jennah-sdk-py
Store and recall a memory
Sign in once with the jnh CLI
(jnh login), or set JENNAH_API_KEY. Then:
import uuid
from jennah import Client
from jennah.agent.v1 import agent_pb2, memory_pb2
with Client() as client: # uses `jnh login`, or $JENNAH_API_KEY
agent_id = f"quickstart-{uuid.uuid4().hex[:8]}"
client.agents.CreateAgent(
agent_pb2.CreateAgentRequest(agent_instance_id=agent_id)
)
agent = client.agent(agent_id)
# Store a memory. The platform embeds raw_content for you.
agent.vectors.upsert(memory_pb2.VectorChunk(
chunk_id="pref-1",
raw_content="The customer prefers invoices in Japanese yen, "
"sent on the 5th.",
))
# Recall it by meaning, not by keyword.
result = agent.vectors.search(memory_pb2.SemanticQuery(
query_text="what currency does the customer want to be "
"billed in?",
limit=3,
))
for m in result.matches:
print(f"{m.distance:.3f} {m.raw_content}")
client.agents.DeleteAgent(
agent_pb2.DeleteAgentRequest(agent_instance_id=agent_id)
)
0.235 The customer prefers invoices in Japanese yen, sent on the 5th.
Async
AsyncClient has the same operations, awaited, over grpc.aio. Nothing it does
blocks the event loop, credential renewal included.
import asyncio
from jennah import AsyncClient
from jennah.agent.v1 import memory_pb2
async def main():
async with AsyncClient() as client:
query = memory_pb2.SemanticQuery(
query_text="billing preferences", limit=3
)
result = await client.agent("my-agent").vectors.search(query)
print(result.matches)
asyncio.run(main())
Use Client in scripts, notebooks and evaluation harnesses; use AsyncClient
inside an agent framework or any other asyncio program.
Every operation, already authenticated
Each service in the API is a generated stub on the client, already bound to the credentialed connection, so every operation is callable without a wrapper:
from jennah.agent.v1 import scope_pb2
client.scopes.ListScopes(scope_pb2.ListScopesRequest())
client.memory.InspectMemory(...)
client.datasets.ListDatasets(...)
The services are agents, memory, scopes, datasets, schema, data,
auth, approvals, billing and platform. For a service added after your SDK
version, client.stub(SomeServiceStub) binds it the same way. Never build your
own channel to reach one: you would lose credential renewal.
client.agent(id) adds the memory shortcuts, each one single-section call:
memory.commit(...) and memory.query(...) (any request field, as keywords),
logs.create/logs.recent, vectors.upsert/vectors.search, and
graph.write/graph.query.
Credentials
The client takes the first credential it finds, in this order:
credentials=, a source your program supplies.api_key=.- The
JENNAH_API_KEYenvironment variable. - The session stored by
jnh login.
A signed-in session renews itself: a rejected call is renewed once and retried,
and the renewed session is written back to the shared credentials file, so jnh
on the same machine stays signed in. client.credential reports
what authenticated the client, and where it came from, without the secret.
Development
The generated code is not committed. With jennah-api checked out next to this repository:
scripts/dev-generate.sh # generate and lay the stubs and conformance suite in place
pip install -e '.[test]'
pytest
Metadata
Release files for jennah-sdk-py 0.65.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 | |
|---|---|---|---|
| jennah_sdk_py-0.65.0.tar.gz | 122.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| jennah_sdk_py-0.65.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 250.3 kB
Release files / jennah_sdk_py-0.65.0.tar.gz
| Download URL | jennah_sdk_py-0.65.0.tar.gz |
|---|---|
| Size | 122.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
471f6d54cf7884e15c82520f7e66d69567531e44364ed8be8a3c3bc8d8249428
|
|
BLAKE2b-256 checksum How to use checksums |
2b83d068fba3b2b94a857b5760fd7a7fa8192f1fdcfec3742252ede05738ce2f
|
| 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 Oct 5, 2026.
Transparency logRelease files / jennah_sdk_py-0.65.0-py3-none-any.whl
| Download URL | jennah_sdk_py-0.65.0-py3-none-any.whl |
|---|---|
| Size | 127.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
212b5bd2f963bcc872e28b4147b9f7ddfcf8d6b8754fbbcb67b5edb0731cc423
|
|
BLAKE2b-256 checksum How to use checksums |
050e28e2280b5703518e22dee26399a4c4b0dedf7be2def69518976026c7012d
|
| 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 Oct 5, 2026.
Transparency log