Skip to content

Enhance Memory API Client with Additional Functionality #18

@abrookins

Description

@abrookins

Enhance Memory API Client with Additional Functionality

Summary

Add missing functionality and convenience methods to the Memory API Client to improve developer experience and provide better coverage of common use cases.

Current State

The current client provides solid core functionality but is missing several features that would improve usability:

  • No explicit memory lifecycle management
  • Limited batch operation support
  • Missing pagination utilities for large result sets
  • No client-side validation
  • No memory analytics/statistics
  • No export/import capabilities

Proposed Enhancements

1. Memory Lifecycle Management

Add explicit methods for managing the working → long-term memory promotion flow:

async def promote_working_memories_to_long_term(
    self, 
    session_id: str, 
    memory_ids: list[str] = None,
    namespace: str | None = None
) -> AckResponse:
    """
    Explicitly promote specific working memories to long-term storage.
    
    Note: Memory promotion normally happens automatically when working memory
    is saved. This method is for cases where you need manual control over
    the promotion timing or want to promote specific memories immediately.
    
    Args:
        session_id: The session containing memories to promote
        memory_ids: Specific memory IDs to promote (if None, promotes all unpromoted)
        namespace: Optional namespace filter
        
    Returns:
        Acknowledgement of promotion operation
    """

2. Batch Operations

Add efficient batch processing for large-scale operations:

async def bulk_create_long_term_memories(
    self, 
    memory_batches: list[list[MemoryRecord]],
    batch_size: int = 100
) -> list[AckResponse]:
    """
    Create multiple batches of memories with proper rate limiting.
    
    Args:
        memory_batches: List of memory record batches
        batch_size: Maximum memories per batch request
        
    Returns:
        List of acknowledgement responses for each batch
    """

3. Pagination Utilities

Add auto-paginating search methods for comprehensive results:

async def search_all_long_term_memories(
    self, 
    text: str, 
    **filters
) -> AsyncIterator[MemoryRecord]:
    """
    Auto-paginating search that yields all matching results.
    
    Automatically handles pagination to retrieve all results without
    requiring manual offset management.
    
    Args:
        text: Search query text
        **filters: Any search filters
        
    Yields:
        Individual memory records from all result pages
    """

async def search_all_memories(
    self, 
    text: str, 
    **filters
) -> AsyncIterator[MemoryRecord]:
    """Auto-paginating version of unified memory search."""

4. Client-Side Validation

Add validation to catch errors before API calls:

def validate_memory_record(self, memory: MemoryRecord) -> None:
    """
    Validate memory record before sending to server.
    
    Checks:
    - Required fields are present
    - Memory type is valid
    - Dates are properly formatted
    - Text content is not empty
    - ID format is valid
    
    Raises:
        ValueError: If validation fails with descriptive message
    """

def validate_search_filters(self, **filters) -> None:
    """Validate search filter parameters before API call."""

5. Enhanced Convenience Methods

Extend existing convenience methods with more options:

async def update_working_memory_data(
    self,
    session_id: str,
    data_updates: dict[str, Any],
    namespace: str | None = None,
    merge_strategy: Literal["replace", "merge", "deep_merge"] = "merge"
) -> WorkingMemoryResponse:
    """
    Update specific data fields in working memory without replacing everything.
    
    Args:
        session_id: Target session
        data_updates: Dictionary of updates to apply
        namespace: Optional namespace
        merge_strategy: How to handle existing data
    """

async def append_messages_to_working_memory(
    self,
    session_id: str,
    messages: list[MemoryMessage],
    namespace: str | None = None,
    auto_summarize: bool = True
) -> WorkingMemoryResponse:
    """
    Append new messages to existing working memory.
    
    More efficient than retrieving, modifying, and setting full memory.
    """

Implementation Notes

Package Structure

Extract the client into a separate Python package with its own pyproject.toml:

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[project]
name = "agent-memory-client"
dynamic = ["version"]
description = "Python client for the Agent Memory Server REST API"
readme = "README.md"
license = "MIT"
requires-python = ">=3.10"
authors = [
    { name = "Your Name", email = "your.email@example.com" },
]
classifiers = [
    "Development Status :: 4 - Beta",
    "Intended Audience :: Developers",
    "License :: OSI Approved :: MIT License",
    "Programming Language :: Python :: 3",
    "Programming Language :: Python :: 3.10",
    "Programming Language :: Python :: 3.11",
    "Programming Language :: Python :: 3.12",
]
dependencies = [
    "httpx>=0.25.0",
    "pydantic>=2.0.0",
    "ulid-py>=1.1.0",
]

[project.optional-dependencies]
dev = [
    "pytest>=7.0.0",
    "pytest-asyncio>=0.21.0",
    "pytest-httpx>=0.21.0",
    "black>=23.0.0",
    "ruff>=0.1.0",
    "mypy>=1.5.0",
]

[project.urls]
Homepage = "https://github.com/your-org/agent-memory-server"
Repository = "https://github.com/your-org/agent-memory-client"
Documentation = "https://agent-memory-client.readthedocs.io"

[tool.hatch.version]
path = "agent_memory_client/__init__.py"

[tool.hatch.build.targets.wheel]
packages = ["agent_memory_client"]

Benefits of separate packaging:

  • Independent versioning: Client can be updated without server changes
  • Reduced dependencies: Client users don't need server dependencies
  • Better distribution: Easier to install just the client for agent development
  • Cleaner imports: from agent_memory_client import MemoryAPIClient

Package structure:

agent-memory-client/
├── pyproject.toml
├── README.md
├── agent_memory_client/
│   ├── __init__.py
│   ├── client.py
│   ├── models.py
│   ├── filters.py
│   └── exceptions.py
└── tests/
    ├── test_client.py
    └── test_models.py

Error Handling

  • All new methods should use proper exception handling
  • Provide meaningful error messages for common failure scenarios
  • Handle rate limiting gracefully with exponential backoff

Type Safety

  • Use proper type hints for all new methods
  • Define new response models where needed (MemoryStats, ImportResult, etc.)
  • Maintain compatibility with existing type system

Testing

  • Add comprehensive unit tests for all new methods
  • Include integration tests with mock server responses
  • Test error conditions and edge cases
  • Performance testing for batch operations

Documentation

  • Add docstrings with examples for all new methods
  • Update client library documentation
  • Add usage examples to README
  • Document best practices for each feature

Benefits

  1. Improved Developer Experience: More intuitive and comprehensive API
  2. Better Performance: Batch operations and auto-pagination reduce round trips
  3. Enhanced Reliability: Client-side validation catches errors early
  4. Lifecycle Clarity: Explicit promotion methods make memory flow clearer
  5. Independent Packaging: Client can be distributed and versioned separately

Breaking Changes

These additions should be non-breaking - all existing client methods continue to work unchanged.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions