Skip to content

feat(agent-memory): add create_checkpointer() factory with TTL support for LangGraph agents#221

Open
santosh-nallur wants to merge 21 commits into
SAP:mainfrom
santosh-nallur:feat/local-factory
Open

feat(agent-memory): add create_checkpointer() factory with TTL support for LangGraph agents#221
santosh-nallur wants to merge 21 commits into
SAP:mainfrom
santosh-nallur:feat/local-factory

Conversation

@santosh-nallur

@santosh-nallur santosh-nallur commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Description

Adds a create_checkpointer() factory in the agent_memory module that returns a LangGraph BaseCheckpointSaver appropriate for the current environment. Enables LoB teams (e.g. IBD) to integrate LangGraph agent short-term memory without coupling their agent code to a specific checkpointer implementation.

What ships in this PR:

  • src/sap_cloud_sdk/agent_memory/factory/langgraph_checkpoint.pycreate_checkpointer() factory returning InMemorySaver (no TTL) or TimedInMemorySaver (with TTL)
  • src/sap_cloud_sdk/agent_memory/factory/_timed_memory.pyTimedInMemorySaver extending InMemorySaver with a daemon background sweep thread for TTL-based thread eviction
  • src/sap_cloud_sdk/agent_memory/factory/__init__.py — factory subpackage
  • tests/agent_memory/unit/test_langgraph_checkpointer.py — factory unit tests
  • tests/agent_memory/unit/test_timed_memory.pyTimedInMemorySaver unit tests
  • src/sap_cloud_sdk/agent_memory/user-guide.md — LangGraph Checkpointer section

usage:

from sap_cloud_sdk.agent_memory.factory.langgraph_checkpoint import create_checkpointer

# Without TTL
checkpointer = create_checkpointer()

# With TTL — evicts threads inactive for 1 hour
checkpointer = create_checkpointer(ttl_seconds=3600)

app = workflow.compile(checkpointer=checkpointer)

TimedInMemorySaver design:

  • Tracks last-active time per thread via _last_active dict updated in put() / aput()
  • Daemon sweep thread runs every 60 seconds and evicts threads exceeding ttl_seconds of inactivity
  • Sweep is fully decoupled from the read/write path — hot path adds one dict write only
  • ttl_seconds parameter stable for Phase 2 when HanaAgentMemorySaver ships

Type of Change

  • New feature (non-breaking change that adds functionality)
  • Documentation update

How to Test

# Run new unit tests
uv run pytest tests/agent_memory/unit/test_langgraph_checkpointer.py -v
uv run pytest tests/agent_memory/unit/test_timed_memory.py -v

# Run full unit suite
uv run pytest tests/agent_memory/unit/ -v

Checklist

  • I have read the Contributing Guidelines
  • I have verified that my changes solve the issue
  • I have added/updated automated tests to cover my changes
  • All tests pass locally
  • I have verified that my code follows the Code Guidelines
  • I have updated documentation (if applicable)
  • I have added type hints for all public APIs
  • My code does not contain sensitive information (credentials, tokens, etc.)
  • I have followed Conventional Commits for commit messages

Breaking Changes

None. The factory subpackage is additive. No existing public API is changed.

Additional Notes

  • TimedInMemorySaver is a temporary home in the SDK factory subpackage. It will migrate to langgraph-checkpoint-sap-agent-memory (the separate checkpoint library in Phase 2 — no code change required for factory consumers.
  • The ttl_seconds parameter is accepted on create_checkpointer() regardless of which backend is active, ensuring interface stability for Phase 2.
  • Phase 2 factory (when HanaAgentMemorySaver ships) will detect the HANA binding at runtime and return it automatically

…gents

Adds factory/langgraph_checkpoint.py providing create_checkpointer() which
returns LangGraph's InMemorySaver. The factory subpackage is structured to
support future framework adapters (store, crewai) without namespace conflicts
with the langgraph package itself. Persistent checkpointing backed by the
Agent Memory Service is not yet supported.

AGENTMAAS-410
Covers return type, ImportError on missing langgraph, and three LangGraph
integration tests verifying compile, state persistence, and thread isolation.

AGENTMAAS-410
…uide

Adds a LangGraph Checkpointer section distinguishing the framework adapter
from the core service client. Notes that the current implementation uses
InMemorySaver and does not support persistence yet.

AGENTMAAS-410
…create_checkpointer

State loss on process exit is a relevant operational signal, not a routine
info event. Message now names the function and describes the exact limitation.

AGENTMAAS-410
Adds TimedInMemorySaver extending InMemorySaver with a daemon background
sweep thread that evicts inactive threads based on ttl_seconds. Updates
create_checkpointer(ttl_seconds=...) factory to return TimedInMemorySaver
when ttl_seconds is provided, or plain InMemorySaver otherwise.

TimedInMemorySaver is a temporary home in the SDK factory subpackage.
It will migrate to langgraph-checkpoint-sap-agent-memory in Phase 2 —
no code change required for consumers of create_checkpointer().

AGENTMAAS-410
…er guide

Adds Thread TTL section to the LangGraph Checkpointer documentation covering
ttl_seconds usage, TimedInMemorySaver eviction semantics, and the @agent_config
decorator pattern for centralised TTL configuration.

AGENTMAAS-410
… signature

Removes TimedInMemorySaver and its tests. ttl_seconds is retained as a
factory parameter for interface stability — TTL will be enforced by
HanaAgentMemorySaver when available. InMemorySaver logs a clear warning
when ttl_seconds is set explaining the current limitation.

AGENTMAAS-410
The centralised TTL configuration via @agent_config is not yet
available. Removed from both the factory docstring and the user guide.

AGENTMAAS-410
Restores TimedInMemorySaver — InMemorySaver with background daemon sweep
for production-grade TTL-based thread eviction. create_checkpointer() returns
TimedInMemorySaver when ttl_seconds is set, InMemorySaver otherwise.

AGENTMAAS-410
Documents ttl_seconds parameter, TimedInMemorySaver eviction semantics,
and the process-exit limitation. Removes the placeholder text that said
TTL has no effect.

AGENTMAAS-410
@santosh-nallur santosh-nallur requested a review from a team as a code owner July 9, 2026 17:29
Comment on lines +841 to +846
`langgraph` must be installed. The SDK does not declare it as a dependency —
you control your own LangGraph version.

```bash
pip install langgraph
```

@cassiofariasmachado cassiofariasmachado Jul 9, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

langchain is an optional dependency that we are using for the Agent Gateway module. We could follow the same approach here, adding langgraph as an optional dependency and validating and handling it with a proper message if the developer try to use the checkpointer without installing the langgraph dependency. Similar to what we did here:

@santosh-nallur santosh-nallur Jul 10, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. I had it before, but removed it. I had an in-correct impression pip install sap-cloud-sdk[langgraph] would always restrict them to langgraph version we specify under optional section. But looking at it again, seems not the case because of bounds we use and additionally the agent devs could still specify a specific version.

Comment thread src/sap_cloud_sdk/agent_memory/factory/__init__.py Outdated
@@ -0,0 +1,117 @@
"""Unit tests for the create_checkpointer() LangGraph factory."""

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better to keep same structure as src

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at the existing test layout across all modules (tests/agentgateway/unit/, tests/destination/unit/, etc.), the convention is a flat list of test files under unit/ regardless of whether the source has subpackages. For example agentgateway/converters.py lives in a subpackage but its test is tests/agentgateway/unit/test_converters.py — not tests/agentgateway/unit/converters/test_converters.py.

Following that pattern, test_langgraph_checkpointer.py and test_timed_memory.py are in the right place under tests/agent_memory/unit/.

Could you clarify if you meant something else, like a different naming or structure convention?

santosh-nallur and others added 6 commits July 10, 2026 10:54
Co-authored-by: Nicole Gomes <47161082+NicoleMGomes@users.noreply.github.com>
…equisites

Adds langgraph>=0.2.0 to [project.optional-dependencies] so consumers
can install via pip install sap-cloud-sdk[langgraph]. Updates the user
guide prerequisites section to document both installation paths.

AGENTMAAS-410
LangGraph 1.0 introduced the stable public API and current import paths.
Pre-1.0 versions are not supported.

AGENTMAAS-410
Shows how to expose ttl_seconds via agent_config decorator with key
config.checkpointer.ttl_seconds for low-code UI integration.

AGENTMAAS-410
@santosh-nallur

santosh-nallur commented Jul 10, 2026

Copy link
Copy Markdown
Contributor Author

Thanks @NicoleMGomes , @cassiofariasmachado, I realised that the new TTL field for checkpointer could be a configuration via decorators. Rather than introducing a new checkpointer specific decorator, reused the existing agent_config instead. Added an example in the user-guide.md
Hope this is fine ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants