Metadata-Version: 2.4
Name: generic-llm-memorizer
Version: 0.1.2
Summary: A library for managing LLM conversations and context
Author-email: Your Name <your.email@example.com>
License-Expression: MIT
Project-URL: Homepage, https://github.com/yourusername/generic-llm-memorizer
Project-URL: Documentation, https://github.com/yourusername/generic-llm-memorizer#readme
Project-URL: Repository, https://github.com/yourusername/generic-llm-memorizer
Keywords: llm,conversation,chat,ai,prompt,context-management
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Python: >=3.12
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: dotenv>=0.9.9
Requires-Dist: pydantic>=2.12.5
Requires-Dist: watchdog>=6.0.0
Provides-Extra: test
Requires-Dist: pydantic-ai>=1.76.0; extra == "test"
Requires-Dist: pytest>=9.0.2; extra == "test"
Requires-Dist: pytest-asyncio>=1.3.0; extra == "test"
Dynamic: license-file

# Generic LLM Memorizer

A Python library for managing LLM conversations and context with automatic fact extraction and structured data handling.

## Installation

```bash
pip install generic-llm-memorizer
```

## Usage

### Basic Conversation Management

```python
from generic_llm_memorizer import Conversation

# Create a new conversation
conv = Conversation(system_prompt="You are a helpful assistant.")

# Add messages
conv.add_user_message("Hello, how are you?")
conv.add_assistant_message("I'm doing well, thank you! How can I help you today?")

# Get conversation history
messages = conv.get_messages()

# Format for LLM API (expects list of dicts with role and content)
from generic_llm_memorizer import format_conversation_for_prompt
formatted = format_conversation_for_prompt(conv)
# Output: [{"role": "system", "content": "You are a helpful assistant."}, ...]
```

```python
from generic_llm_memorizer import Conversation

# Create a new conversation
conv = Conversation(system_prompt="You are a helpful assistant.")

# Add messages
conv.add_user_message("Hello, how are you?")
conv.add_assistant_message("I'm doing well, thank you! How can I help you today?")

# Get conversation history
messages = conv.get_messages()

# Format for LLM API (expects list of dicts with role and content)
from generic_llm_memorizer import format_conversation_for_prompt
formatted = format_conversation_for_prompt(conv)
# Output: [{"role": "system", "content": "You are a helpful assistant."}, ...]
```

### Persisting Conversations

```python
from generic_llm_memorizer import Conversation

# Save conversation to JSON
conv_json = conv.to_json()
with open("conversation.json", "w") as f:
    f.write(conv_json)

# Load conversation from JSON
with open("conversation.json", "r") as f:
    conv_json = f.read()
loaded_conv = Conversation.from_json(conv_json)
```

```python
from generic_llm_memorizer import Conversation

# Save conversation to JSON
conv_json = conv.to_json()
with open("conversation.json", "w") as f:
    f.write(conv_json)

# Load conversation from JSON
with open("conversation.json", "r") as f:
    conv_json = f.read()
loaded_conv = Conversation.from_json(conv_json)
```

### Utility Functions

## Extending with Custom Models

You can create your own Pydantic models for domain-specific extractions:

```python
from pydantic import BaseModel
from typing import List
from enum import Enum

class Priority(str, Enum):
    LOW = "low"
    MEDIUM = "medium"
    HIGH = "high"

class Task(BaseModel):
    title: str
    description: str
    priority: Priority
    assignee: str

class TaskList(BaseModel):
    tasks: List[Task]

# Use with the generic llm_call function
tasks = llm_call("Extract tasks from this conversation", TaskList)
```

### Advanced Usage with Structured Data Extraction

The library now supports a generic `llm_call` function that works with Pydantic models for structured data extraction:

```python
from typing import Type, TypeVar
from pydantic import BaseModel
from generic_llm_memorizer.conversation import Conversation
from generic_llm_memorizer.memory import Summary, Memory, Fact

# Define a generic type variable bounded by BaseModel
T = TypeVar("T", bound=BaseModel)

def llm_call(prompt: str, model_class: Type[T]) -> T:
    """
    Generic LLM call function that returns structured data.
    
    Args:
        prompt: The prompt to send to the LLM
        model_class: The Pydantic model class to parse the response into
        
    Returns:
        An instance of the specified model_class
    """
    # In a real implementation, this would call an actual LLM API
    # and parse the response into the specified Pydantic model
    
    # Mock implementation for demonstration
    if model_class == Summary:
        return Summary(content="Mock summary of the conversation")
    elif model_class == Memory:
        return Memory(facts=[
            Fact(
                content="Example fact extracted from conversation",
                kind="example",
                timestamp="2023-01-01T10:00:00Z",
                validity="forever"
            )
        ])
    
    # Return a default instance of the model
    return model_class()

# Usage with LLMMemorizer
from generic_llm_memorizer.llm_memorizer import LLMMemorizer

conversation = Conversation(system_prompt="You are a helpful assistant")
conversation.add_user_message("Hello, my name is John Doe and I'm a software engineer")

memorizer = LLMMemorizer(
    user_id="user_123",
    session_id="session_456",
    llm_call=llm_call,
    conversation=conversation
)

# Extract structured facts
memory = memorizer.extract_facts()
print(f"Extracted {len(memory.facts)} facts")

# Generate structured summary
summary = memorizer.summarize()
print(f"Summary: {summary.content}")

## API Reference

```python
from generic_llm_memorizer import extract_last_user_message, extract_last_assistant_message

# Extract last user message
last_user = extract_last_user_message(conv)

# Extract last assistant message
last_assistant = extract_last_assistant_message(conv)
```

## API Reference

### Conversation Class

Manages a conversation with an LLM.

#### Methods

- `add_message(role, content, metadata=None)`: Add a message to the conversation
- `add_user_message(content, metadata=None)`: Add a user message
- `add_assistant_message(content, metadata=None)`: Add an assistant message
- `get_messages()`: Get all messages
- `get_recent_messages(count)`: Get the most recent messages
- `clear()`: Clear all messages
- `to_dict()`: Convert to dictionary format
- `to_json(indent=2)`: Convert to JSON string
- `from_dict(data)`: Create from dictionary data
- `from_json(json_str)`: Create from JSON string

### Message Dataclass

Represents a single message in a conversation.

#### Attributes

- `role`: Role of the message sender ("user", "assistant", "system", etc.)
- `content`: Message content
- `timestamp`: ISO format timestamp (automatically set)
- `metadata`: Additional metadata dictionary

### Utility Functions

- `format_conversation_for_prompt(conversation)`: Format conversation for LLM API
- `extract_last_user_message(conversation)`: Get last user message content
- `extract_last_assistant_message(conversation)`: Get last assistant message content

## License

MIT
