Name | tomldiary JSON |
Version |
0.0.5
JSON |
| download |
home_page | None |
Summary | A lightweight TOML-based memory system for AI agents |
upload_time | 2025-08-10 20:06:56 |
maintainer | None |
docs_url | None |
author | Jan Siml |
requires_python | >=3.11 |
license | None |
keywords |
memory
ai
agents
toml
preferences
|
VCS |
 |
bugtrack_url |
|
requirements |
No requirements were recorded.
|
Travis-CI |
No Travis.
|
coveralls test coverage |
No coveralls.
|
# TOMLDiary
**Memory, Simplified: TOML-Driven, Agent-Approved.**
TOMLDiary is a dead-simple, customizable memory system for agentic applications. It stores data in human-readable TOML files so your agents can keep a tidy diary of only the useful stuff.
## Key Benefits
- **Human-readable TOML storage** – easy to inspect, debug and manage.
- **Fully customizable** – define your own memory schema with simple Pydantic models.
- **Smart deduplication** – prevents duplicate preferences with FuzzyWuzzy similarity detection (70% threshold).
- **Enhanced limit enforcement** – visual indicators and pre-flight checking prevent failed operations.
- **Force creation mechanism** – bypass similarity detection when needed with `id="new"` parameter.
- **Minimal overhead** – lightweight design, backend agnostic and easy to integrate.
- **Atomic, safe writes** – ensures data integrity with proper file locking.
## Installation
Requires Python 3.11+
```bash
uv add tomldiary pydantic-ai
```
## Quick Start
```python
from pydantic import BaseModel
from typing import Dict
from tomldiary import Diary, PreferenceItem
from tomldiary.backends import LocalBackend
# Be as specific as possible in your preference schema, it passed to the system prompt of the agent extracting the data!
# This of the fields as the "slots" to organize facts into and tell the agent what to remember.
class MyPrefTable(BaseModel):
"""
likes : What the user enjoys
dislikes : Things user avoids
allergies: Substances causing reactions
routines : User’s typical habits
biography: User’s personal details
"""
likes: Dict[str, PreferenceItem] = {}
dislikes: Dict[str, PreferenceItem] = {}
allergies: Dict[str, PreferenceItem] = {}
routines: Dict[str, PreferenceItem] = {}
biography: Dict[str, PreferenceItem] = {}
diary = Diary(
backend=LocalBackend(path="./memories"),
pref_table_cls=MyPrefTable,
max_prefs_per_category=100,
max_conversations=50,
)
await diary.ensure_session(user_id, session_id)
await diary.update_memory(
user_id,
session_id,
user_msg="I'm allergic to walnuts.",
assistant_msg="I'll remember you're allergic to walnuts.",
)
```
## TOML Memory Example
```toml
[_meta]
version = "0.3"
schema_name = "MyPrefTable"
[allergies.walnuts]
text = "allergic to walnuts"
contexts = ["diet", "health"]
_count = 1
_created = "2024-01-01T00:00:00Z"
_updated = "2024-01-01T00:00:00Z"
```
### Conversations File (`alice_conversations.toml`)
```toml
[_meta]
version = "0.3"
schema_name = "MyPrefTable"
[conversations.chat_123]
_created = "2024-01-01T00:00:00Z"
_turns = 5
summary = "Discussed food preferences and dietary restrictions"
keywords = ["food", "allergy", "italian"]
```
## Advanced Usage
### Custom Preference Categories
Create your own preference schema:
```python
class DetailedPrefTable(BaseModel):
"""
dietary : Food preferences and restrictions
medical : Health conditions and medications
interests : Hobbies and topics of interest
goals : Personal objectives and aspirations
family : Family members and relationships
work : Professional information
"""
dietary: Dict[str, PreferenceItem] = {}
medical: Dict[str, PreferenceItem] = {}
interests: Dict[str, PreferenceItem] = {}
goals: Dict[str, PreferenceItem] = {}
family: Dict[str, PreferenceItem] = {}
work: Dict[str, PreferenceItem] = {}
```
### Smart Preference Management
The system includes enhanced tools for intelligent preference management:
```python
# The extraction agent uses these enhanced tools automatically:
# - list_preferences(category) - shows limits with visual indicators (✅/⚠️/❌)
# - upsert_preference() with smart workflows:
# * Similarity detection prevents duplicates
# * Auto-increment counts on updates
# * Force creation with id="new" when needed
# * Intelligent error messages with match percentages
# Examples of enhanced error messages:
# "❌ Similar preferences found:
# • likes/pref001: 'black blazers for work' (85% match)
# • likes/pref003: 'dark blazers' (72% match)
#
# To update existing: upsert_preference('likes', id='pref001')
# To force create anyway: upsert_preference('likes', id='new', text='black blazers')"
```
### Backend Options
The library supports different storage backends:
```python
# Local filesystem (default)
from tomldiary.backends import LocalBackend
backend = LocalBackend(Path("./memories"))
# S3 backend (implement S3Backend)
# backend = S3Backend(bucket="my-memories")
# Redis backend (implement RedisBackend)
# backend = RedisBackend(host="localhost")
```
### Memory Writer Configuration
```python
# Configure the background writer
writer = MemoryWriter(
diary=diary,
workers=3, # Number of background workers
qsize=100, # Queue size
retry_limit=3, # Max retries on failure
retry_delay=1.0 # Delay between retries
)
```
## API Reference
### Diary
Main class for memory operations:
- `preferences(user_id)`: Get user preferences as TOML string
- `last_conversations(user_id, limit)`: Get last N conversation summaries
- `ensure_session(user_id, session_id)`: Create session if needed
- `update_memory(user_id, session_id, user_msg, assistant_msg)`: Process and store memory
### MemoryWriter
Background queue for non-blocking writes:
- `submit(user_id, session_id, user_message, assistant_response)`: Queue memory update
- `close()`: Graceful shutdown
- `failed_count()`: Number of failed operations
### Models
- `PreferenceItem`: Single preference with text, contexts, and metadata
- `ConversationItem`: Conversation with summary, keywords, and turn count
- `MemoryDeps`: Container for preferences and conversations
## Examples
See the `examples/` directory for:
- `simple_example.py`: Basic usage with educational agent (no LLM required)
- `example_cooking_show.py`: Advanced AI-powered cooking show with celebrity chef interviews
- `culinary_prefs.py`: Custom preference schema for culinary applications
**Note**: Examples use custom agents for educational purposes. The built-in extraction agent automatically uses the enhanced smart deduplication and limit enforcement tools described above.
## Development
```bash
# Install dev dependencies
uv sync --group dev
# Run tests
pytest
# Format code
ruff format .
# Lint code
ruff check .
```
## License
MIT License - see LICENSE file for details.
Raw data
{
"_id": null,
"home_page": null,
"name": "tomldiary",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.11",
"maintainer_email": null,
"keywords": "memory, ai, agents, toml, preferences",
"author": "Jan Siml",
"author_email": "Jan Siml <49557684+svilupp@users.noreply.github.com>",
"download_url": "https://files.pythonhosted.org/packages/e7/7b/f007d38e2cfddf00b4216f00f4e0f2e2d682825999aa074617e7d68e0f36/tomldiary-0.0.5.tar.gz",
"platform": null,
"description": "# TOMLDiary\n\n**Memory, Simplified: TOML-Driven, Agent-Approved.**\n\nTOMLDiary is a dead-simple, customizable memory system for agentic applications. It stores data in human-readable TOML files so your agents can keep a tidy diary of only the useful stuff.\n\n## Key Benefits\n\n- **Human-readable TOML storage** \u2013 easy to inspect, debug and manage.\n- **Fully customizable** \u2013 define your own memory schema with simple Pydantic models.\n- **Smart deduplication** \u2013 prevents duplicate preferences with FuzzyWuzzy similarity detection (70% threshold).\n- **Enhanced limit enforcement** \u2013 visual indicators and pre-flight checking prevent failed operations.\n- **Force creation mechanism** \u2013 bypass similarity detection when needed with `id=\"new\"` parameter.\n- **Minimal overhead** \u2013 lightweight design, backend agnostic and easy to integrate.\n- **Atomic, safe writes** \u2013 ensures data integrity with proper file locking.\n\n## Installation\n\nRequires Python 3.11+\n\n```bash\nuv add tomldiary pydantic-ai\n```\n\n## Quick Start\n\n```python\nfrom pydantic import BaseModel\nfrom typing import Dict\nfrom tomldiary import Diary, PreferenceItem\nfrom tomldiary.backends import LocalBackend\n\n# Be as specific as possible in your preference schema, it passed to the system prompt of the agent extracting the data!\n# This of the fields as the \"slots\" to organize facts into and tell the agent what to remember.\nclass MyPrefTable(BaseModel):\n \"\"\"\n likes : What the user enjoys\n dislikes : Things user avoids\n allergies: Substances causing reactions\n routines : User\u2019s typical habits\n biography: User\u2019s personal details\n \"\"\"\n\n likes: Dict[str, PreferenceItem] = {}\n dislikes: Dict[str, PreferenceItem] = {}\n allergies: Dict[str, PreferenceItem] = {}\n routines: Dict[str, PreferenceItem] = {}\n biography: Dict[str, PreferenceItem] = {}\n\n\ndiary = Diary(\n backend=LocalBackend(path=\"./memories\"),\n pref_table_cls=MyPrefTable,\n max_prefs_per_category=100,\n max_conversations=50,\n)\n\nawait diary.ensure_session(user_id, session_id)\nawait diary.update_memory(\n user_id,\n session_id,\n user_msg=\"I'm allergic to walnuts.\",\n assistant_msg=\"I'll remember you're allergic to walnuts.\",\n)\n```\n\n## TOML Memory Example\n\n```toml\n[_meta]\nversion = \"0.3\"\nschema_name = \"MyPrefTable\"\n\n[allergies.walnuts]\ntext = \"allergic to walnuts\"\ncontexts = [\"diet\", \"health\"]\n_count = 1\n_created = \"2024-01-01T00:00:00Z\"\n_updated = \"2024-01-01T00:00:00Z\"\n```\n\n### Conversations File (`alice_conversations.toml`)\n```toml\n[_meta]\nversion = \"0.3\"\nschema_name = \"MyPrefTable\"\n\n[conversations.chat_123]\n_created = \"2024-01-01T00:00:00Z\"\n_turns = 5\nsummary = \"Discussed food preferences and dietary restrictions\"\nkeywords = [\"food\", \"allergy\", \"italian\"]\n```\n\n## Advanced Usage\n\n### Custom Preference Categories\n\nCreate your own preference schema:\n\n```python\nclass DetailedPrefTable(BaseModel):\n \"\"\"\n dietary : Food preferences and restrictions\n medical : Health conditions and medications\n interests : Hobbies and topics of interest\n goals : Personal objectives and aspirations\n family : Family members and relationships\n work : Professional information\n \"\"\"\n dietary: Dict[str, PreferenceItem] = {}\n medical: Dict[str, PreferenceItem] = {}\n interests: Dict[str, PreferenceItem] = {}\n goals: Dict[str, PreferenceItem] = {}\n family: Dict[str, PreferenceItem] = {}\n work: Dict[str, PreferenceItem] = {}\n```\n\n### Smart Preference Management\n\nThe system includes enhanced tools for intelligent preference management:\n\n```python\n# The extraction agent uses these enhanced tools automatically:\n# - list_preferences(category) - shows limits with visual indicators (\u2705/\u26a0\ufe0f/\u274c) \n# - upsert_preference() with smart workflows:\n# * Similarity detection prevents duplicates\n# * Auto-increment counts on updates \n# * Force creation with id=\"new\" when needed\n# * Intelligent error messages with match percentages\n\n# Examples of enhanced error messages:\n# \"\u274c Similar preferences found:\n# \u2022 likes/pref001: 'black blazers for work' (85% match)\n# \u2022 likes/pref003: 'dark blazers' (72% match)\n# \n# To update existing: upsert_preference('likes', id='pref001')\n# To force create anyway: upsert_preference('likes', id='new', text='black blazers')\"\n```\n\n### Backend Options\n\nThe library supports different storage backends:\n\n```python\n# Local filesystem (default)\nfrom tomldiary.backends import LocalBackend\nbackend = LocalBackend(Path(\"./memories\"))\n\n# S3 backend (implement S3Backend)\n# backend = S3Backend(bucket=\"my-memories\")\n\n# Redis backend (implement RedisBackend) \n# backend = RedisBackend(host=\"localhost\")\n```\n\n### Memory Writer Configuration\n\n```python\n# Configure the background writer\nwriter = MemoryWriter(\n diary=diary,\n workers=3, # Number of background workers\n qsize=100, # Queue size\n retry_limit=3, # Max retries on failure\n retry_delay=1.0 # Delay between retries\n)\n```\n\n## API Reference\n\n### Diary\n\nMain class for memory operations:\n\n- `preferences(user_id)`: Get user preferences as TOML string\n- `last_conversations(user_id, limit)`: Get last N conversation summaries\n- `ensure_session(user_id, session_id)`: Create session if needed\n- `update_memory(user_id, session_id, user_msg, assistant_msg)`: Process and store memory\n\n### MemoryWriter\n\nBackground queue for non-blocking writes:\n\n- `submit(user_id, session_id, user_message, assistant_response)`: Queue memory update\n- `close()`: Graceful shutdown\n- `failed_count()`: Number of failed operations\n\n### Models\n\n- `PreferenceItem`: Single preference with text, contexts, and metadata\n- `ConversationItem`: Conversation with summary, keywords, and turn count\n- `MemoryDeps`: Container for preferences and conversations\n\n## Examples\n\nSee the `examples/` directory for:\n- `simple_example.py`: Basic usage with educational agent (no LLM required)\n- `example_cooking_show.py`: Advanced AI-powered cooking show with celebrity chef interviews\n- `culinary_prefs.py`: Custom preference schema for culinary applications\n\n**Note**: Examples use custom agents for educational purposes. The built-in extraction agent automatically uses the enhanced smart deduplication and limit enforcement tools described above.\n\n## Development\n\n```bash\n# Install dev dependencies\nuv sync --group dev\n\n# Run tests\npytest\n\n# Format code\nruff format .\n\n# Lint code\nruff check .\n```\n\n## License\n\nMIT License - see LICENSE file for details.",
"bugtrack_url": null,
"license": null,
"summary": "A lightweight TOML-based memory system for AI agents",
"version": "0.0.5",
"project_urls": {
"Documentation": "https://github.com/svilupp/tomldiary/tree/main/docs",
"Homepage": "https://github.com/svilupp/tomldiary",
"Issues": "https://github.com/svilupp/tomldiary/issues",
"Repository": "https://github.com/svilupp/tomldiary"
},
"split_keywords": [
"memory",
" ai",
" agents",
" toml",
" preferences"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "c834c57ed3b0e00ab3c6d98d22e19151efb6db253abde2d1c7a2c04fc62826b6",
"md5": "9508b485b44967372fa77269a2b350a5",
"sha256": "d141e55c6a6591f23411640fae3eb01f855c38f74b8952bb8ef61f55d74bfd0f"
},
"downloads": -1,
"filename": "tomldiary-0.0.5-py3-none-any.whl",
"has_sig": false,
"md5_digest": "9508b485b44967372fa77269a2b350a5",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.11",
"size": 22343,
"upload_time": "2025-08-10T20:06:54",
"upload_time_iso_8601": "2025-08-10T20:06:54.889343Z",
"url": "https://files.pythonhosted.org/packages/c8/34/c57ed3b0e00ab3c6d98d22e19151efb6db253abde2d1c7a2c04fc62826b6/tomldiary-0.0.5-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "e77bf007d38e2cfddf00b4216f00f4e0f2e2d682825999aa074617e7d68e0f36",
"md5": "92459592f7c29f6624a86519dd6da916",
"sha256": "efc8722175e25d3af08c76a4080dab2450fbbcac7e9e5c4d9dced7ca4b8ccabb"
},
"downloads": -1,
"filename": "tomldiary-0.0.5.tar.gz",
"has_sig": false,
"md5_digest": "92459592f7c29f6624a86519dd6da916",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.11",
"size": 18250,
"upload_time": "2025-08-10T20:06:56",
"upload_time_iso_8601": "2025-08-10T20:06:56.142544Z",
"url": "https://files.pythonhosted.org/packages/e7/7b/f007d38e2cfddf00b4216f00f4e0f2e2d682825999aa074617e7d68e0f36/tomldiary-0.0.5.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-08-10 20:06:56",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "svilupp",
"github_project": "tomldiary",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "tomldiary"
}