memory-agent


Namememory-agent JSON
Version 1.1.13 PyPI version JSON
download
home_pageNone
SummaryA Python library for advanced memory management in AI agent applications
upload_time2025-07-26 17:05:28
maintainerNone
docs_urlNone
authorNone
requires_python>=3.9
licenseNone
keywords agent memory
VCS
bugtrack_url
requirements aioboto3 aiobotocore aiofiles aiohappyeyeballs aiohttp aioitertools aiosignal annotated-types anyio attrs backoff beautifulsoup4 boto3 botocore build certifi cffi chardet charset-normalizer click coloredlogs contourpy cryptography cycler dataclasses-json distro docutils emoji fastembed filelock filetype flatbuffers fonttools fpdf frozenlist fsspec greenlet grpcio h11 h2 hf-xet hpack html5lib httpcore httpx httpx-sse huggingface-hub humanfriendly hyperframe id idna iniconfig jaraco.classes jaraco.context jaraco.functools jiter jmespath joblib json_repair jsonpatch jsonpointer keyring kiwisolver langchain langchain-community langchain-core langchain-ollama langchain-openai langchain-qdrant langchain-text-splitters langdetect langgraph langgraph-checkpoint langgraph-prebuilt langgraph-sdk langsmith loguru loki-logger-handler lxml markdown-it-py marshmallow matplotlib mdurl mmh3 more-itertools mpmath multidict mypy_extensions narwhals neo4j neo4j-graphrag nest-asyncio nh3 nltk numpy olefile ollama onnxruntime openai orjson ormsgpack packaging pandas pillow plotly pluggy portalocker propcache protobuf psutil py_rust_stemmers pyaws-s3 pycparser pydantic pydantic-settings pydantic_core Pygments pyparsing pypdf pyproject_hooks pytest python-dateutil python-dotenv python-iso639 python-magic python-oxmsg pytz PyYAML qdrant-client RapidFuzz readme_renderer redis regex reportlab requests requests-toolbelt rfc3986 rich s3transfer setuptools six sniffio soupsieve SQLAlchemy sympy tenacity tiktoken tokenizers tqdm twine types-PyYAML typing-inspect typing-inspection typing_extensions tzdata unstructured unstructured-client urllib3 webencodings wheel wrapt xxhash yarl zstandard
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # [memory-agent](https://github.com/gzileni/memory-agent)

The library allows you to manage both [persistence](https://langchain-ai.github.io/langgraph/how-tos/persistence/) and [**memory**](https://langchain-ai.github.io/langgraph/concepts/memory/#what-is-memory) for a LangGraph agent.

**memory-agent** uses [Redis](https://redis.io/) as the long-term memory database and [QDrant](https://qdrant.tech/) for persistence.

## Memory vs Persistence

When developing agents with LangGraph (or LLM-based systems in general), it's crucial to distinguish between **memory** and **persistence** of state and data.  
This distinction affects both the architecture and the choice of databases used in the project.

### Persistence

**Persistence** refers to the permanent (or long-term) storage of information that needs to be retrieved across different sessions or after a long period of time.

**Examples of persistence:**  

- Conversation history  
- Vector embeddings and knowledge bases  
- Agent logs and audits

**Characteristics of persistence:**  

- **Non-volatile data**: survives restarts, crashes, and scales over time  
- **Historical access**: you can search, filter, and retrieve data even after a long time  
- **Optimized for complex queries**

#### Why use Qdrant for persistence?

- **Vectorization & Similarity**: Qdrant is a specialized engine for similarity search between embeddings (LLM, NLP, images, etc.), ideal for agents that need to retrieve information, conversation history, knowledge bases, etc.
- **Reliable persistence**: Qdrant securely and efficiently saves all data to disk.
- **Scalability**: Handles millions of vectors and high-performance similarity queries, even at large scale.
- **Powerful API**: Supports filters, payloads, metadata, and advanced queries, perfect for integrating complex data into LangGraph agents.

### Memory

**Memory** represents all the temporary information that the agent keeps only during a session or the lifecycle of a specific task.

**Examples of memory:**  

- Current conversation state  
- Temporary variables  
- Volatile context between graph steps

**Characteristics of memory:**  

- **Volatile**: lost when the process ends or is restarted  
- **Very fast**: only used for short-lived data  
- **Scalable**: can be shared across multiple processes/instances if needed

#### Why use Redis for memory?

- **Performance**: Redis operates entirely in RAM, ensuring extremely fast reads and writes—ideal for temporary data and frequent access.
- **Multi-process & Scalability**: Redis allows multiple agent instances to access/share the same temporary state, which is essential in distributed environments or with multiple workers.
- **Ease of use**: Redis provides simple primitives (hashes, lists, sets) and an API that is easy to integrate with Python.
- **Expiration support (TTL)**: You can set automatic expiration on data, so temporary memory “self-cleans”.

#### Architectural Choice

| Function             | Recommended Database | Reasoning                                              |
|----------------------|---------------------|--------------------------------------------------------|
| Memory               | Redis               | Performance, multi-process, data expiration, simplicity|
| Persistence          | Qdrant              | Vectorization, semantic similarity, scalability        |

### Installation

To install **memory-agent** via pip, run:

```bash
pip install memory-agent
```

### Usage Example

Below is a practical example of how to use the library to manage long-term memory with Redis in a LangGraph agent.

```python
import os
from memory_agent import MemoryCheckPointer, MemoryPersistence

from typing import Annotated
from typing_extensions import TypedDict
from langgraph.graph import StateGraph, START
from langgraph.graph.message import add_messages
from langchain.chat_models import init_chat_model

os.environ["OPENAI_API_KEY"] = "sk-..."
llm = init_chat_model("openai:gpt-4.1")

class State(TypedDict):
    # Messages have the type "list". The `add_messages` function
    # in the annotation defines how this state key should be updated
    # (in this case, it appends messages to the list, rather than overwriting them)
    messages: Annotated[list, add_messages]

def chatbot(state: State):
    return {"messages": [llm.invoke(state["messages"])]}

graph_builder = StateGraph(State)
# The first argument is the unique node name
# The second argument is the function or object that will be called whenever
# the node is used.
graph_builder.add_node("chatbot", chatbot)
graph_builder.add_edge(START, "chatbot")

async def main(user_input, thread_id):
    # Configurazione della connessione a Redis
    memory_checkpointer_config = {
        "host": "localhost",
        "port": 6379,
        "db": 0
    }

    # Creazione della configurazione per il thread
    config = {
        "configurable": {
            "thread_id": thread_id
        },
        "recursion_limit": 25
    }

    memory_store = MemoryPersistence(model_embeggind_type="openai", 
                                     model_embedding_name="text-embedding-3-small",
                                     qdrant_url="http://localhost:6333")
        
    # Utilizzo del context manager per la memoria Redis
    async with MemoryCheckpointer.from_conn_info(
        host=memory_checkpointer_config["host"],
        port=memory_checkpointer_config["port"],
        db=memory_checkpointer_config["db"]
    ) as checkpointer:

        # Delete checkpoints older than 15 minutes for the current thread
        await checkpointer.adelete_by_thread_id(thread_id=thread_id, filter_minutes=15)

        # Compiling the graph with the checkpointer and in-memory store
        graph_sql = graph_builder.compile(
          checkpointer=checkpointer,  # Persistence
          store=memory_store.get_in_memory_store(),  # Long-term memory
        )
        graph_sql.name = "ChatBot"

        # Run the graph with user input
        input_data = {
          "messages": [{
            "role": "human",
            "content": user_input,
          }]
        }
        result = await graph_sql.ainvoke(input_data, config=config)
        print(result)
```

#### Ollama or VLLM

If you use [Ollama](https://ollama.com/) or a custom LLM server such as [VLLM](https://docs.vllm.ai/en/latest/), you need to initialize the `MemoryPersistence` object as follows:

```python
memory_store = MemoryPersistence(model_embeggind_type="ollama", 
                                 model_embedding_name="nomic-embed-text",
                                 model_embedding_url="http://localhost:11434/api/embeddings",
                                 qdrant_url="http://localhost:6333")
```

```python
memory_store = MemoryPersistence(model_embeggind_type="vllm", 
                                 model_embedding_name="....",
                                 model_embedding_url="....",
                                 qdrant_url="http://localhost:6333")
```

### Vector Database

Two QDrant instances are available for use as a vector database: one synchronous and one asynchronous. You can use QDrant directly as a vector store without the Redis component, for example:

```python
import os
from memory_agent import MemoryPersistence

# Istanza sincrona di QDrant
qdrant = MemoryPersistence(model_embedding_vs_name="BAAI/bge-large-en-v1.5", 
                           qdrant_url="http://localhost:6333")
client = qdrant.get_client()  
client_async = qdrant.get_client_async()
```

These instances allow you to use only the QDrant database for vector memory management, either synchronously or asynchronously, depending on your application's needs.

### Custom Text Embedding Model

By default, QDrant automatically downloads text embedding models from Hugging Face. However, to improve performance or work in environments without Internet access, you can download the models locally and configure QDrant (or your application) to use these local paths.

#### Downloading and Using Local Embedding Models

1 - **Install the Hugging Face client:**

  ```bash
  pip install --upgrade huggingface_hub
  ```

2 - **Create directories for the models:**

  ```bash
  mkdir -p /models/multilingual-e5-large
  mkdir -p /models/bge-small-en-v1.5
  mkdir -p /models/bge-large-en-v1.5
  ```

3 - **Download the desired models:**

  ```bash
  huggingface-cli download intfloat/multilingual-e5-large --local-dir /models/multilingual-e5-large
  huggingface-cli download BAAI/bge-small-en-v1.5 --local-dir /models/bge-small-en-v1.5
  huggingface-cli download BAAI/bge-large-en-v1.5 --local-dir /models/bge-large-en-v1.5
  ```

4 - **Configure your application or QDrant** to use the local paths of the downloaded models instead of downloading them from Hugging Face each time.

```python
import os
from memory_agent import MemoryPersistence

# Istanza sincrona di QDrant
qdrant = MemoryPersistence(model_embedding_vs_name="BAAI/bge-large-en-v1.5", 
                           model_embedding_vs_path="/models/bge-large-en-v1.5"
                           model_embedding_vs_type="local",
                           qdrant_url="http://localhost:6333")
client = qdrant.get_client()  
client_async = qdrant.get_client_async()
```

## Docker

To easily start the required services (Redis, QDrant), you can use the following `docker-compose.yml` file:

```yaml

services:

  memory-redis:
    container_name: memory-redis
    restart: always
    image: redis:7
    ports:
      - "6379:6379"
    volumes:
      - memory-redis-data:/data
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 2s
      timeout: 2s
      retries: 30
    networks:
      - memory-network

  memory-qdrant:
    container_name: memory-qdrant
    platform: linux/amd64
    image: qdrant/qdrant:v1.13.4
    restart: always
    ports:
      - "6333:6333"
      - "6334:6334"
    expose:
      - 6333
      - 6334
      - 6335
    volumes:
      - memory-qdrant-data:/qdrant/storage:z
      - ./qdrant/config.yml:/qdrant/config.yml:ro
    networks:
      - memory-network

volumes:
  memory-qdrant-data:
  memory-redis-data:

networks:
  memory-network:
    name: memory-network
    driver: bridge
    ipam:
      driver: default
      config:
        - subnet: 172.16.110.0/24

```

This **Docker Compose** stack integrates the main services for Retrieval-Augmented Generation (RAG) projects, knowledge graphs, and log monitoring:

- **Redis** (in-memory DB/cache)
- **Qdrant** (vector database)

### Included Services

| Service   | Port  | Purpose                            |
| --------- | ----- | ---------------------------------- |
| Redis     | 6379  | Cache, message broker              |
| Qdrant    | 6333  | Vector search DB (API)             |
| Qdrant    | 6334  | gRPC API                           |

#### Requirements

- Docker ≥ 20.10
- Docker Compose (plugin or standalone)
- At least 4GB RAM available (≥ 8GB recommended for Neo4j + Qdrant)

#### Quick Start

1. **Start the stack:**

    ```bash
    docker compose up -d
    ```

2. **Check status:**

    ```bash
    docker compose ps
    ```

#### Service Details

##### 1. Redis (`memory-redis`)

- **Port:** 6379
- **Persistent data:** `memory-redis-data`
- **Usage:** cache/session store for microservices, AI RAG, or NLP pipelines.
- **Integrated healthcheck.**

##### 2. Qdrant (`memory-qdrant`)

- **Platform:** `linux/amd64` (universal compatibility)
- **Ports:** 6333 (REST), 6334 (gRPC)
- **Persistent data:** `memory-qdrant-data`
- **Custom config:** mounts `./qdrant/config.yml`
- **Usage:** vector DB for semantic search (e.g., with LangChain, Haystack...)

#### Networks, Volumes, and Security

- All services are on the **private Docker network** `memory-network` (`172.16.110.0/24`)
- **Docker volumes:** all data is persistent and will not be lost between restarts.
- **Security tip:** Always change default passwords!

#### Service Access

- **Qdrant API:** [http://localhost:6333](http://localhost:6333)
- **Redis:** `redis://localhost:6379`

#### FAQ & Troubleshooting

- **Q: Where is persistent data stored?**  
    A: In Docker volumes. Check with `docker volume ls`.

- **Q: Qdrant doesn't start on Apple Silicon?**  
    A: Specify `platform: linux/amd64` as already set in the file.

#### Extra: Cleanup Example

To remove **all** the stack and associated data:

```bash
docker compose down -v
```

## Grafana Logging

To enable logging compatible with Grafana and Loki, simply set the following environment variables:

- `APP_NAME`: The name of your application (default: `"logger"`)
- `LOKI_URL`: The URL of your Loki instance (for example: `"http://localhost:3100/loki/api/v1/push"`)
- `LOG_LEVEL`: The desired log level (`DEBUG`, `INFO`, `WARNING`, `ERROR`, or `CRITICAL`)
- `APP_SERVICE`: The name of the service (default: `"logger_service"`)
- `APP_VERSION`: The version of your application (default: `"1.0.0"`)

Once these variables are set, your logs will be compatible with Grafana dashboards and Loki log aggregation.

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "memory-agent",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.9",
    "maintainer_email": null,
    "keywords": "agent, memory",
    "author": null,
    "author_email": "Giuseppe Zileni <giuseppe.zileni@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/3c/c1/1726044f7fa70e372be95d1d6730c788fbbb2018afb1f06ac02ce1edf8a8/memory_agent-1.1.13.tar.gz",
    "platform": null,
    "description": "# [memory-agent](https://github.com/gzileni/memory-agent)\n\nThe library allows you to manage both [persistence](https://langchain-ai.github.io/langgraph/how-tos/persistence/) and [**memory**](https://langchain-ai.github.io/langgraph/concepts/memory/#what-is-memory) for a LangGraph agent.\n\n**memory-agent** uses [Redis](https://redis.io/) as the long-term memory database and [QDrant](https://qdrant.tech/) for persistence.\n\n## Memory vs Persistence\n\nWhen developing agents with LangGraph (or LLM-based systems in general), it's crucial to distinguish between **memory** and **persistence** of state and data.  \nThis distinction affects both the architecture and the choice of databases used in the project.\n\n### Persistence\n\n**Persistence** refers to the permanent (or long-term) storage of information that needs to be retrieved across different sessions or after a long period of time.\n\n**Examples of persistence:**  \n\n- Conversation history  \n- Vector embeddings and knowledge bases  \n- Agent logs and audits\n\n**Characteristics of persistence:**  \n\n- **Non-volatile data**: survives restarts, crashes, and scales over time  \n- **Historical access**: you can search, filter, and retrieve data even after a long time  \n- **Optimized for complex queries**\n\n#### Why use Qdrant for persistence?\n\n- **Vectorization & Similarity**: Qdrant is a specialized engine for similarity search between embeddings (LLM, NLP, images, etc.), ideal for agents that need to retrieve information, conversation history, knowledge bases, etc.\n- **Reliable persistence**: Qdrant securely and efficiently saves all data to disk.\n- **Scalability**: Handles millions of vectors and high-performance similarity queries, even at large scale.\n- **Powerful API**: Supports filters, payloads, metadata, and advanced queries, perfect for integrating complex data into LangGraph agents.\n\n### Memory\n\n**Memory** represents all the temporary information that the agent keeps only during a session or the lifecycle of a specific task.\n\n**Examples of memory:**  \n\n- Current conversation state  \n- Temporary variables  \n- Volatile context between graph steps\n\n**Characteristics of memory:**  \n\n- **Volatile**: lost when the process ends or is restarted  \n- **Very fast**: only used for short-lived data  \n- **Scalable**: can be shared across multiple processes/instances if needed\n\n#### Why use Redis for memory?\n\n- **Performance**: Redis operates entirely in RAM, ensuring extremely fast reads and writes\u2014ideal for temporary data and frequent access.\n- **Multi-process & Scalability**: Redis allows multiple agent instances to access/share the same temporary state, which is essential in distributed environments or with multiple workers.\n- **Ease of use**: Redis provides simple primitives (hashes, lists, sets) and an API that is easy to integrate with Python.\n- **Expiration support (TTL)**: You can set automatic expiration on data, so temporary memory \u201cself-cleans\u201d.\n\n#### Architectural Choice\n\n| Function             | Recommended Database | Reasoning                                              |\n|----------------------|---------------------|--------------------------------------------------------|\n| Memory               | Redis               | Performance, multi-process, data expiration, simplicity|\n| Persistence          | Qdrant              | Vectorization, semantic similarity, scalability        |\n\n### Installation\n\nTo install **memory-agent** via pip, run:\n\n```bash\npip install memory-agent\n```\n\n### Usage Example\n\nBelow is a practical example of how to use the library to manage long-term memory with Redis in a LangGraph agent.\n\n```python\nimport os\nfrom memory_agent import MemoryCheckPointer, MemoryPersistence\n\nfrom typing import Annotated\nfrom typing_extensions import TypedDict\nfrom langgraph.graph import StateGraph, START\nfrom langgraph.graph.message import add_messages\nfrom langchain.chat_models import init_chat_model\n\nos.environ[\"OPENAI_API_KEY\"] = \"sk-...\"\nllm = init_chat_model(\"openai:gpt-4.1\")\n\nclass State(TypedDict):\n    # Messages have the type \"list\". The `add_messages` function\n    # in the annotation defines how this state key should be updated\n    # (in this case, it appends messages to the list, rather than overwriting them)\n    messages: Annotated[list, add_messages]\n\ndef chatbot(state: State):\n    return {\"messages\": [llm.invoke(state[\"messages\"])]}\n\ngraph_builder = StateGraph(State)\n# The first argument is the unique node name\n# The second argument is the function or object that will be called whenever\n# the node is used.\ngraph_builder.add_node(\"chatbot\", chatbot)\ngraph_builder.add_edge(START, \"chatbot\")\n\nasync def main(user_input, thread_id):\n    # Configurazione della connessione a Redis\n    memory_checkpointer_config = {\n        \"host\": \"localhost\",\n        \"port\": 6379,\n        \"db\": 0\n    }\n\n    # Creazione della configurazione per il thread\n    config = {\n        \"configurable\": {\n            \"thread_id\": thread_id\n        },\n        \"recursion_limit\": 25\n    }\n\n    memory_store = MemoryPersistence(model_embeggind_type=\"openai\", \n                                     model_embedding_name=\"text-embedding-3-small\",\n                                     qdrant_url=\"http://localhost:6333\")\n        \n    # Utilizzo del context manager per la memoria Redis\n    async with MemoryCheckpointer.from_conn_info(\n        host=memory_checkpointer_config[\"host\"],\n        port=memory_checkpointer_config[\"port\"],\n        db=memory_checkpointer_config[\"db\"]\n    ) as checkpointer:\n\n        # Delete checkpoints older than 15 minutes for the current thread\n        await checkpointer.adelete_by_thread_id(thread_id=thread_id, filter_minutes=15)\n\n        # Compiling the graph with the checkpointer and in-memory store\n        graph_sql = graph_builder.compile(\n          checkpointer=checkpointer,  # Persistence\n          store=memory_store.get_in_memory_store(),  # Long-term memory\n        )\n        graph_sql.name = \"ChatBot\"\n\n        # Run the graph with user input\n        input_data = {\n          \"messages\": [{\n            \"role\": \"human\",\n            \"content\": user_input,\n          }]\n        }\n        result = await graph_sql.ainvoke(input_data, config=config)\n        print(result)\n```\n\n#### Ollama or VLLM\n\nIf you use [Ollama](https://ollama.com/) or a custom LLM server such as [VLLM](https://docs.vllm.ai/en/latest/), you need to initialize the `MemoryPersistence` object as follows:\n\n```python\nmemory_store = MemoryPersistence(model_embeggind_type=\"ollama\", \n                                 model_embedding_name=\"nomic-embed-text\",\n                                 model_embedding_url=\"http://localhost:11434/api/embeddings\",\n                                 qdrant_url=\"http://localhost:6333\")\n```\n\n```python\nmemory_store = MemoryPersistence(model_embeggind_type=\"vllm\", \n                                 model_embedding_name=\"....\",\n                                 model_embedding_url=\"....\",\n                                 qdrant_url=\"http://localhost:6333\")\n```\n\n### Vector Database\n\nTwo QDrant instances are available for use as a vector database: one synchronous and one asynchronous. You can use QDrant directly as a vector store without the Redis component, for example:\n\n```python\nimport os\nfrom memory_agent import MemoryPersistence\n\n# Istanza sincrona di QDrant\nqdrant = MemoryPersistence(model_embedding_vs_name=\"BAAI/bge-large-en-v1.5\", \n                           qdrant_url=\"http://localhost:6333\")\nclient = qdrant.get_client()  \nclient_async = qdrant.get_client_async()\n```\n\nThese instances allow you to use only the QDrant database for vector memory management, either synchronously or asynchronously, depending on your application's needs.\n\n### Custom Text Embedding Model\n\nBy default, QDrant automatically downloads text embedding models from Hugging Face. However, to improve performance or work in environments without Internet access, you can download the models locally and configure QDrant (or your application) to use these local paths.\n\n#### Downloading and Using Local Embedding Models\n\n1 - **Install the Hugging Face client:**\n\n  ```bash\n  pip install --upgrade huggingface_hub\n  ```\n\n2 - **Create directories for the models:**\n\n  ```bash\n  mkdir -p /models/multilingual-e5-large\n  mkdir -p /models/bge-small-en-v1.5\n  mkdir -p /models/bge-large-en-v1.5\n  ```\n\n3 - **Download the desired models:**\n\n  ```bash\n  huggingface-cli download intfloat/multilingual-e5-large --local-dir /models/multilingual-e5-large\n  huggingface-cli download BAAI/bge-small-en-v1.5 --local-dir /models/bge-small-en-v1.5\n  huggingface-cli download BAAI/bge-large-en-v1.5 --local-dir /models/bge-large-en-v1.5\n  ```\n\n4 - **Configure your application or QDrant** to use the local paths of the downloaded models instead of downloading them from Hugging Face each time.\n\n```python\nimport os\nfrom memory_agent import MemoryPersistence\n\n# Istanza sincrona di QDrant\nqdrant = MemoryPersistence(model_embedding_vs_name=\"BAAI/bge-large-en-v1.5\", \n                           model_embedding_vs_path=\"/models/bge-large-en-v1.5\"\n                           model_embedding_vs_type=\"local\",\n                           qdrant_url=\"http://localhost:6333\")\nclient = qdrant.get_client()  \nclient_async = qdrant.get_client_async()\n```\n\n## Docker\n\nTo easily start the required services (Redis, QDrant), you can use the following `docker-compose.yml` file:\n\n```yaml\n\nservices:\n\n  memory-redis:\n    container_name: memory-redis\n    restart: always\n    image: redis:7\n    ports:\n      - \"6379:6379\"\n    volumes:\n      - memory-redis-data:/data\n    healthcheck:\n      test: [\"CMD\", \"redis-cli\", \"ping\"]\n      interval: 2s\n      timeout: 2s\n      retries: 30\n    networks:\n      - memory-network\n\n  memory-qdrant:\n    container_name: memory-qdrant\n    platform: linux/amd64\n    image: qdrant/qdrant:v1.13.4\n    restart: always\n    ports:\n      - \"6333:6333\"\n      - \"6334:6334\"\n    expose:\n      - 6333\n      - 6334\n      - 6335\n    volumes:\n      - memory-qdrant-data:/qdrant/storage:z\n      - ./qdrant/config.yml:/qdrant/config.yml:ro\n    networks:\n      - memory-network\n\nvolumes:\n  memory-qdrant-data:\n  memory-redis-data:\n\nnetworks:\n  memory-network:\n    name: memory-network\n    driver: bridge\n    ipam:\n      driver: default\n      config:\n        - subnet: 172.16.110.0/24\n\n```\n\nThis **Docker Compose** stack integrates the main services for Retrieval-Augmented Generation (RAG) projects, knowledge graphs, and log monitoring:\n\n- **Redis** (in-memory DB/cache)\n- **Qdrant** (vector database)\n\n### Included Services\n\n| Service   | Port  | Purpose                            |\n| --------- | ----- | ---------------------------------- |\n| Redis     | 6379  | Cache, message broker              |\n| Qdrant    | 6333  | Vector search DB (API)             |\n| Qdrant    | 6334  | gRPC API                           |\n\n#### Requirements\n\n- Docker \u2265 20.10\n- Docker Compose (plugin or standalone)\n- At least 4GB RAM available (\u2265 8GB recommended for Neo4j + Qdrant)\n\n#### Quick Start\n\n1. **Start the stack:**\n\n    ```bash\n    docker compose up -d\n    ```\n\n2. **Check status:**\n\n    ```bash\n    docker compose ps\n    ```\n\n#### Service Details\n\n##### 1. Redis (`memory-redis`)\n\n- **Port:** 6379\n- **Persistent data:** `memory-redis-data`\n- **Usage:** cache/session store for microservices, AI RAG, or NLP pipelines.\n- **Integrated healthcheck.**\n\n##### 2. Qdrant (`memory-qdrant`)\n\n- **Platform:** `linux/amd64` (universal compatibility)\n- **Ports:** 6333 (REST), 6334 (gRPC)\n- **Persistent data:** `memory-qdrant-data`\n- **Custom config:** mounts `./qdrant/config.yml`\n- **Usage:** vector DB for semantic search (e.g., with LangChain, Haystack...)\n\n#### Networks, Volumes, and Security\n\n- All services are on the **private Docker network** `memory-network` (`172.16.110.0/24`)\n- **Docker volumes:** all data is persistent and will not be lost between restarts.\n- **Security tip:** Always change default passwords!\n\n#### Service Access\n\n- **Qdrant API:** [http://localhost:6333](http://localhost:6333)\n- **Redis:** `redis://localhost:6379`\n\n#### FAQ & Troubleshooting\n\n- **Q: Where is persistent data stored?**  \n    A: In Docker volumes. Check with `docker volume ls`.\n\n- **Q: Qdrant doesn't start on Apple Silicon?**  \n    A: Specify `platform: linux/amd64` as already set in the file.\n\n#### Extra: Cleanup Example\n\nTo remove **all** the stack and associated data:\n\n```bash\ndocker compose down -v\n```\n\n## Grafana Logging\n\nTo enable logging compatible with Grafana and Loki, simply set the following environment variables:\n\n- `APP_NAME`: The name of your application (default: `\"logger\"`)\n- `LOKI_URL`: The URL of your Loki instance (for example: `\"http://localhost:3100/loki/api/v1/push\"`)\n- `LOG_LEVEL`: The desired log level (`DEBUG`, `INFO`, `WARNING`, `ERROR`, or `CRITICAL`)\n- `APP_SERVICE`: The name of the service (default: `\"logger_service\"`)\n- `APP_VERSION`: The version of your application (default: `\"1.0.0\"`)\n\nOnce these variables are set, your logs will be compatible with Grafana dashboards and Loki log aggregation.\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "A Python library for advanced memory management in AI agent applications",
    "version": "1.1.13",
    "project_urls": {
        "Homepage": "https://gzileni.github.io/memory-agent",
        "Repository": "https://github.com/gzileni/memory-agent"
    },
    "split_keywords": [
        "agent",
        " memory"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "d54389da4c330ad626e8cfc04c23169aa9c0af4fda3012d3ccdd5ec40446494f",
                "md5": "9d08ea7205257be3da5a2d39736936fe",
                "sha256": "882e1d73577705894ea24ab6e12f0982fb6fb449db4d07bad2122c844685c7d2"
            },
            "downloads": -1,
            "filename": "memory_agent-1.1.13-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "9d08ea7205257be3da5a2d39736936fe",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.9",
            "size": 22702,
            "upload_time": "2025-07-26T17:05:26",
            "upload_time_iso_8601": "2025-07-26T17:05:26.561313Z",
            "url": "https://files.pythonhosted.org/packages/d5/43/89da4c330ad626e8cfc04c23169aa9c0af4fda3012d3ccdd5ec40446494f/memory_agent-1.1.13-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "3cc11726044f7fa70e372be95d1d6730c788fbbb2018afb1f06ac02ce1edf8a8",
                "md5": "3e25e767616c8457a9a09eb7053e6ee6",
                "sha256": "e3a75b9f7240acef0e5be387bb5076ca1880e2db8bc4171d4c8c155d7506a506"
            },
            "downloads": -1,
            "filename": "memory_agent-1.1.13.tar.gz",
            "has_sig": false,
            "md5_digest": "3e25e767616c8457a9a09eb7053e6ee6",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.9",
            "size": 28111,
            "upload_time": "2025-07-26T17:05:28",
            "upload_time_iso_8601": "2025-07-26T17:05:28.678419Z",
            "url": "https://files.pythonhosted.org/packages/3c/c1/1726044f7fa70e372be95d1d6730c788fbbb2018afb1f06ac02ce1edf8a8/memory_agent-1.1.13.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-07-26 17:05:28",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "gzileni",
    "github_project": "memory-agent",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "requirements": [
        {
            "name": "aioboto3",
            "specs": [
                [
                    "==",
                    "14.3.0"
                ]
            ]
        },
        {
            "name": "aiobotocore",
            "specs": [
                [
                    "==",
                    "2.22.0"
                ]
            ]
        },
        {
            "name": "aiofiles",
            "specs": [
                [
                    "==",
                    "24.1.0"
                ]
            ]
        },
        {
            "name": "aiohappyeyeballs",
            "specs": [
                [
                    "==",
                    "2.6.1"
                ]
            ]
        },
        {
            "name": "aiohttp",
            "specs": [
                [
                    "==",
                    "3.12.12"
                ]
            ]
        },
        {
            "name": "aioitertools",
            "specs": [
                [
                    "==",
                    "0.12.0"
                ]
            ]
        },
        {
            "name": "aiosignal",
            "specs": [
                [
                    "==",
                    "1.3.2"
                ]
            ]
        },
        {
            "name": "annotated-types",
            "specs": [
                [
                    "==",
                    "0.7.0"
                ]
            ]
        },
        {
            "name": "anyio",
            "specs": [
                [
                    "==",
                    "4.9.0"
                ]
            ]
        },
        {
            "name": "attrs",
            "specs": [
                [
                    "==",
                    "25.3.0"
                ]
            ]
        },
        {
            "name": "backoff",
            "specs": [
                [
                    "==",
                    "2.2.1"
                ]
            ]
        },
        {
            "name": "beautifulsoup4",
            "specs": [
                [
                    "==",
                    "4.13.4"
                ]
            ]
        },
        {
            "name": "boto3",
            "specs": [
                [
                    "==",
                    "1.37.3"
                ]
            ]
        },
        {
            "name": "botocore",
            "specs": [
                [
                    "==",
                    "1.37.3"
                ]
            ]
        },
        {
            "name": "build",
            "specs": [
                [
                    "==",
                    "1.2.2.post1"
                ]
            ]
        },
        {
            "name": "certifi",
            "specs": [
                [
                    "==",
                    "2025.4.26"
                ]
            ]
        },
        {
            "name": "cffi",
            "specs": [
                [
                    "==",
                    "1.17.1"
                ]
            ]
        },
        {
            "name": "chardet",
            "specs": [
                [
                    "==",
                    "5.2.0"
                ]
            ]
        },
        {
            "name": "charset-normalizer",
            "specs": [
                [
                    "==",
                    "3.4.2"
                ]
            ]
        },
        {
            "name": "click",
            "specs": [
                [
                    "==",
                    "8.2.1"
                ]
            ]
        },
        {
            "name": "coloredlogs",
            "specs": [
                [
                    "==",
                    "15.0.1"
                ]
            ]
        },
        {
            "name": "contourpy",
            "specs": [
                [
                    "==",
                    "1.3.2"
                ]
            ]
        },
        {
            "name": "cryptography",
            "specs": [
                [
                    "==",
                    "43.0.0"
                ]
            ]
        },
        {
            "name": "cycler",
            "specs": [
                [
                    "==",
                    "0.12.1"
                ]
            ]
        },
        {
            "name": "dataclasses-json",
            "specs": [
                [
                    "==",
                    "0.6.7"
                ]
            ]
        },
        {
            "name": "distro",
            "specs": [
                [
                    "==",
                    "1.9.0"
                ]
            ]
        },
        {
            "name": "docutils",
            "specs": [
                [
                    "==",
                    "0.21.2"
                ]
            ]
        },
        {
            "name": "emoji",
            "specs": [
                [
                    "==",
                    "2.14.1"
                ]
            ]
        },
        {
            "name": "fastembed",
            "specs": [
                [
                    "==",
                    "0.7.0"
                ]
            ]
        },
        {
            "name": "filelock",
            "specs": [
                [
                    "==",
                    "3.18.0"
                ]
            ]
        },
        {
            "name": "filetype",
            "specs": [
                [
                    "==",
                    "1.2.0"
                ]
            ]
        },
        {
            "name": "flatbuffers",
            "specs": [
                [
                    "==",
                    "25.2.10"
                ]
            ]
        },
        {
            "name": "fonttools",
            "specs": [
                [
                    "==",
                    "4.58.4"
                ]
            ]
        },
        {
            "name": "fpdf",
            "specs": [
                [
                    "==",
                    "1.7.2"
                ]
            ]
        },
        {
            "name": "frozenlist",
            "specs": [
                [
                    "==",
                    "1.7.0"
                ]
            ]
        },
        {
            "name": "fsspec",
            "specs": [
                [
                    "==",
                    "2024.12.0"
                ]
            ]
        },
        {
            "name": "greenlet",
            "specs": [
                [
                    "==",
                    "3.2.3"
                ]
            ]
        },
        {
            "name": "grpcio",
            "specs": [
                [
                    "==",
                    "1.73.0"
                ]
            ]
        },
        {
            "name": "h11",
            "specs": [
                [
                    "==",
                    "0.16.0"
                ]
            ]
        },
        {
            "name": "h2",
            "specs": [
                [
                    "==",
                    "4.2.0"
                ]
            ]
        },
        {
            "name": "hf-xet",
            "specs": [
                [
                    "==",
                    "1.1.3"
                ]
            ]
        },
        {
            "name": "hpack",
            "specs": [
                [
                    "==",
                    "4.1.0"
                ]
            ]
        },
        {
            "name": "html5lib",
            "specs": [
                [
                    "==",
                    "1.1"
                ]
            ]
        },
        {
            "name": "httpcore",
            "specs": [
                [
                    "==",
                    "1.0.9"
                ]
            ]
        },
        {
            "name": "httpx",
            "specs": [
                [
                    "==",
                    "0.28.1"
                ]
            ]
        },
        {
            "name": "httpx-sse",
            "specs": [
                [
                    "==",
                    "0.4.0"
                ]
            ]
        },
        {
            "name": "huggingface-hub",
            "specs": [
                [
                    "==",
                    "0.33.0"
                ]
            ]
        },
        {
            "name": "humanfriendly",
            "specs": [
                [
                    "==",
                    "10.0"
                ]
            ]
        },
        {
            "name": "hyperframe",
            "specs": [
                [
                    "==",
                    "6.1.0"
                ]
            ]
        },
        {
            "name": "id",
            "specs": [
                [
                    "==",
                    "1.5.0"
                ]
            ]
        },
        {
            "name": "idna",
            "specs": [
                [
                    "==",
                    "3.10"
                ]
            ]
        },
        {
            "name": "iniconfig",
            "specs": [
                [
                    "==",
                    "2.1.0"
                ]
            ]
        },
        {
            "name": "jaraco.classes",
            "specs": [
                [
                    "==",
                    "3.4.0"
                ]
            ]
        },
        {
            "name": "jaraco.context",
            "specs": [
                [
                    "==",
                    "6.0.1"
                ]
            ]
        },
        {
            "name": "jaraco.functools",
            "specs": [
                [
                    "==",
                    "4.1.0"
                ]
            ]
        },
        {
            "name": "jiter",
            "specs": [
                [
                    "==",
                    "0.10.0"
                ]
            ]
        },
        {
            "name": "jmespath",
            "specs": [
                [
                    "==",
                    "1.0.1"
                ]
            ]
        },
        {
            "name": "joblib",
            "specs": [
                [
                    "==",
                    "1.5.1"
                ]
            ]
        },
        {
            "name": "json_repair",
            "specs": [
                [
                    "==",
                    "0.39.1"
                ]
            ]
        },
        {
            "name": "jsonpatch",
            "specs": [
                [
                    "==",
                    "1.33"
                ]
            ]
        },
        {
            "name": "jsonpointer",
            "specs": [
                [
                    "==",
                    "3.0.0"
                ]
            ]
        },
        {
            "name": "keyring",
            "specs": [
                [
                    "==",
                    "25.6.0"
                ]
            ]
        },
        {
            "name": "kiwisolver",
            "specs": [
                [
                    "==",
                    "1.4.8"
                ]
            ]
        },
        {
            "name": "langchain",
            "specs": [
                [
                    "==",
                    "0.3.25"
                ]
            ]
        },
        {
            "name": "langchain-community",
            "specs": [
                [
                    "==",
                    "0.3.25"
                ]
            ]
        },
        {
            "name": "langchain-core",
            "specs": [
                [
                    "==",
                    "0.3.65"
                ]
            ]
        },
        {
            "name": "langchain-ollama",
            "specs": [
                [
                    "==",
                    "0.3.3"
                ]
            ]
        },
        {
            "name": "langchain-openai",
            "specs": [
                [
                    "==",
                    "0.3.23"
                ]
            ]
        },
        {
            "name": "langchain-qdrant",
            "specs": [
                [
                    "==",
                    "0.2.0"
                ]
            ]
        },
        {
            "name": "langchain-text-splitters",
            "specs": [
                [
                    "==",
                    "0.3.8"
                ]
            ]
        },
        {
            "name": "langdetect",
            "specs": [
                [
                    "==",
                    "1.0.9"
                ]
            ]
        },
        {
            "name": "langgraph",
            "specs": [
                [
                    "==",
                    "0.4.8"
                ]
            ]
        },
        {
            "name": "langgraph-checkpoint",
            "specs": [
                [
                    "==",
                    "2.0.26"
                ]
            ]
        },
        {
            "name": "langgraph-prebuilt",
            "specs": [
                [
                    "==",
                    "0.2.2"
                ]
            ]
        },
        {
            "name": "langgraph-sdk",
            "specs": [
                [
                    "==",
                    "0.1.70"
                ]
            ]
        },
        {
            "name": "langsmith",
            "specs": [
                [
                    "==",
                    "0.3.45"
                ]
            ]
        },
        {
            "name": "loguru",
            "specs": [
                [
                    "==",
                    "0.7.3"
                ]
            ]
        },
        {
            "name": "loki-logger-handler",
            "specs": [
                [
                    "==",
                    "1.1.2"
                ]
            ]
        },
        {
            "name": "lxml",
            "specs": [
                [
                    "==",
                    "5.4.0"
                ]
            ]
        },
        {
            "name": "markdown-it-py",
            "specs": [
                [
                    "==",
                    "3.0.0"
                ]
            ]
        },
        {
            "name": "marshmallow",
            "specs": [
                [
                    "==",
                    "3.26.1"
                ]
            ]
        },
        {
            "name": "matplotlib",
            "specs": [
                [
                    "==",
                    "3.10.3"
                ]
            ]
        },
        {
            "name": "mdurl",
            "specs": [
                [
                    "==",
                    "0.1.2"
                ]
            ]
        },
        {
            "name": "mmh3",
            "specs": [
                [
                    "==",
                    "5.1.0"
                ]
            ]
        },
        {
            "name": "more-itertools",
            "specs": [
                [
                    "==",
                    "10.7.0"
                ]
            ]
        },
        {
            "name": "mpmath",
            "specs": [
                [
                    "==",
                    "1.3.0"
                ]
            ]
        },
        {
            "name": "multidict",
            "specs": [
                [
                    "==",
                    "6.4.4"
                ]
            ]
        },
        {
            "name": "mypy_extensions",
            "specs": [
                [
                    "==",
                    "1.1.0"
                ]
            ]
        },
        {
            "name": "narwhals",
            "specs": [
                [
                    "==",
                    "1.43.1"
                ]
            ]
        },
        {
            "name": "neo4j",
            "specs": [
                [
                    "==",
                    "5.28.1"
                ]
            ]
        },
        {
            "name": "neo4j-graphrag",
            "specs": [
                [
                    "==",
                    "1.7.0"
                ]
            ]
        },
        {
            "name": "nest-asyncio",
            "specs": [
                [
                    "==",
                    "1.6.0"
                ]
            ]
        },
        {
            "name": "nh3",
            "specs": [
                [
                    "==",
                    "0.2.21"
                ]
            ]
        },
        {
            "name": "nltk",
            "specs": [
                [
                    "==",
                    "3.9.1"
                ]
            ]
        },
        {
            "name": "numpy",
            "specs": [
                [
                    "==",
                    "1.26.4"
                ]
            ]
        },
        {
            "name": "olefile",
            "specs": [
                [
                    "==",
                    "0.47"
                ]
            ]
        },
        {
            "name": "ollama",
            "specs": [
                [
                    "==",
                    "0.5.1"
                ]
            ]
        },
        {
            "name": "onnxruntime",
            "specs": [
                [
                    "==",
                    "1.22.0"
                ]
            ]
        },
        {
            "name": "openai",
            "specs": [
                [
                    "==",
                    "1.86.0"
                ]
            ]
        },
        {
            "name": "orjson",
            "specs": [
                [
                    "==",
                    "3.10.18"
                ]
            ]
        },
        {
            "name": "ormsgpack",
            "specs": [
                [
                    "==",
                    "1.10.0"
                ]
            ]
        },
        {
            "name": "packaging",
            "specs": [
                [
                    "==",
                    "24.2"
                ]
            ]
        },
        {
            "name": "pandas",
            "specs": [
                [
                    "==",
                    "2.3.0"
                ]
            ]
        },
        {
            "name": "pillow",
            "specs": [
                [
                    "==",
                    "11.2.1"
                ]
            ]
        },
        {
            "name": "plotly",
            "specs": [
                [
                    "==",
                    "6.1.2"
                ]
            ]
        },
        {
            "name": "pluggy",
            "specs": [
                [
                    "==",
                    "1.6.0"
                ]
            ]
        },
        {
            "name": "portalocker",
            "specs": [
                [
                    "==",
                    "2.10.1"
                ]
            ]
        },
        {
            "name": "propcache",
            "specs": [
                [
                    "==",
                    "0.3.2"
                ]
            ]
        },
        {
            "name": "protobuf",
            "specs": [
                [
                    "==",
                    "6.31.1"
                ]
            ]
        },
        {
            "name": "psutil",
            "specs": [
                [
                    "==",
                    "7.0.0"
                ]
            ]
        },
        {
            "name": "py_rust_stemmers",
            "specs": [
                [
                    "==",
                    "0.1.5"
                ]
            ]
        },
        {
            "name": "pyaws-s3",
            "specs": [
                [
                    "==",
                    "1.0.21"
                ]
            ]
        },
        {
            "name": "pycparser",
            "specs": [
                [
                    "==",
                    "2.22"
                ]
            ]
        },
        {
            "name": "pydantic",
            "specs": [
                [
                    "==",
                    "2.11.6"
                ]
            ]
        },
        {
            "name": "pydantic-settings",
            "specs": [
                [
                    "==",
                    "2.9.1"
                ]
            ]
        },
        {
            "name": "pydantic_core",
            "specs": [
                [
                    "==",
                    "2.33.2"
                ]
            ]
        },
        {
            "name": "Pygments",
            "specs": [
                [
                    "==",
                    "2.19.1"
                ]
            ]
        },
        {
            "name": "pyparsing",
            "specs": [
                [
                    "==",
                    "3.2.3"
                ]
            ]
        },
        {
            "name": "pypdf",
            "specs": [
                [
                    "==",
                    "5.6.0"
                ]
            ]
        },
        {
            "name": "pyproject_hooks",
            "specs": [
                [
                    "==",
                    "1.2.0"
                ]
            ]
        },
        {
            "name": "pytest",
            "specs": [
                [
                    "==",
                    "8.4.1"
                ]
            ]
        },
        {
            "name": "python-dateutil",
            "specs": [
                [
                    "==",
                    "2.9.0.post0"
                ]
            ]
        },
        {
            "name": "python-dotenv",
            "specs": [
                [
                    "==",
                    "1.1.0"
                ]
            ]
        },
        {
            "name": "python-iso639",
            "specs": [
                [
                    "==",
                    "2025.2.18"
                ]
            ]
        },
        {
            "name": "python-magic",
            "specs": [
                [
                    "==",
                    "0.4.27"
                ]
            ]
        },
        {
            "name": "python-oxmsg",
            "specs": [
                [
                    "==",
                    "0.0.2"
                ]
            ]
        },
        {
            "name": "pytz",
            "specs": [
                [
                    "==",
                    "2025.2"
                ]
            ]
        },
        {
            "name": "PyYAML",
            "specs": [
                [
                    "==",
                    "6.0.2"
                ]
            ]
        },
        {
            "name": "qdrant-client",
            "specs": [
                [
                    "==",
                    "1.14.2"
                ]
            ]
        },
        {
            "name": "RapidFuzz",
            "specs": [
                [
                    "==",
                    "3.13.0"
                ]
            ]
        },
        {
            "name": "readme_renderer",
            "specs": [
                [
                    "==",
                    "44.0"
                ]
            ]
        },
        {
            "name": "redis",
            "specs": [
                [
                    "==",
                    "6.2.0"
                ]
            ]
        },
        {
            "name": "regex",
            "specs": [
                [
                    "==",
                    "2024.11.6"
                ]
            ]
        },
        {
            "name": "reportlab",
            "specs": [
                [
                    "==",
                    "4.4.2"
                ]
            ]
        },
        {
            "name": "requests",
            "specs": [
                [
                    "==",
                    "2.32.4"
                ]
            ]
        },
        {
            "name": "requests-toolbelt",
            "specs": [
                [
                    "==",
                    "1.0.0"
                ]
            ]
        },
        {
            "name": "rfc3986",
            "specs": [
                [
                    "==",
                    "2.0.0"
                ]
            ]
        },
        {
            "name": "rich",
            "specs": [
                [
                    "==",
                    "14.0.0"
                ]
            ]
        },
        {
            "name": "s3transfer",
            "specs": [
                [
                    "==",
                    "0.11.3"
                ]
            ]
        },
        {
            "name": "setuptools",
            "specs": [
                [
                    "==",
                    "80.9.0"
                ]
            ]
        },
        {
            "name": "six",
            "specs": [
                [
                    "==",
                    "1.17.0"
                ]
            ]
        },
        {
            "name": "sniffio",
            "specs": [
                [
                    "==",
                    "1.3.1"
                ]
            ]
        },
        {
            "name": "soupsieve",
            "specs": [
                [
                    "==",
                    "2.7"
                ]
            ]
        },
        {
            "name": "SQLAlchemy",
            "specs": [
                [
                    "==",
                    "2.0.41"
                ]
            ]
        },
        {
            "name": "sympy",
            "specs": [
                [
                    "==",
                    "1.14.0"
                ]
            ]
        },
        {
            "name": "tenacity",
            "specs": [
                [
                    "==",
                    "9.1.2"
                ]
            ]
        },
        {
            "name": "tiktoken",
            "specs": [
                [
                    "==",
                    "0.9.0"
                ]
            ]
        },
        {
            "name": "tokenizers",
            "specs": [
                [
                    "==",
                    "0.21.1"
                ]
            ]
        },
        {
            "name": "tqdm",
            "specs": [
                [
                    "==",
                    "4.67.1"
                ]
            ]
        },
        {
            "name": "twine",
            "specs": [
                [
                    "==",
                    "6.1.0"
                ]
            ]
        },
        {
            "name": "types-PyYAML",
            "specs": [
                [
                    "==",
                    "6.0.12.20250516"
                ]
            ]
        },
        {
            "name": "typing-inspect",
            "specs": [
                [
                    "==",
                    "0.9.0"
                ]
            ]
        },
        {
            "name": "typing-inspection",
            "specs": [
                [
                    "==",
                    "0.4.1"
                ]
            ]
        },
        {
            "name": "typing_extensions",
            "specs": [
                [
                    "==",
                    "4.14.0"
                ]
            ]
        },
        {
            "name": "tzdata",
            "specs": [
                [
                    "==",
                    "2025.2"
                ]
            ]
        },
        {
            "name": "unstructured",
            "specs": [
                [
                    "==",
                    "0.17.2"
                ]
            ]
        },
        {
            "name": "unstructured-client",
            "specs": [
                [
                    "==",
                    "0.36.0"
                ]
            ]
        },
        {
            "name": "urllib3",
            "specs": [
                [
                    "==",
                    "2.4.0"
                ]
            ]
        },
        {
            "name": "webencodings",
            "specs": [
                [
                    "==",
                    "0.5.1"
                ]
            ]
        },
        {
            "name": "wheel",
            "specs": [
                [
                    "==",
                    "0.45.1"
                ]
            ]
        },
        {
            "name": "wrapt",
            "specs": [
                [
                    "==",
                    "1.17.2"
                ]
            ]
        },
        {
            "name": "xxhash",
            "specs": [
                [
                    "==",
                    "3.5.0"
                ]
            ]
        },
        {
            "name": "yarl",
            "specs": [
                [
                    "==",
                    "1.20.1"
                ]
            ]
        },
        {
            "name": "zstandard",
            "specs": [
                [
                    "==",
                    "0.23.0"
                ]
            ]
        }
    ],
    "lcname": "memory-agent"
}
        
Elapsed time: 0.42641s