Developer personal-taste memory & self-evolution engine for AI coding agents.
Project description
โจ What is it?
LLM agents are great at writing generic code โ but they have zero memory of your personal preferences: indentation tastes, library choices, naming conventions, the brutalist UI you love, the verbose docstrings you hate. Every new chat resets to zero.
PersonalEvoTaste is a small, dependency-light library that gives an AI agent a persistent, self-evolving memory of your taste. Feed it the agent's output + your feedback, and it distils, deduplicates, reinforces and decays rules over time โ then re-injects the top ones into the next prompt.
โโโโโโโโโโโโโโโโ feedback โโโโโโโโโโโโโโโโโโโโ rules โโโโโโโโโโโโโโ
agent โ โ your review โ โโโโโโโโโโโบ โ PersonalEvoTaste โ โโโโโโโโบ โ next promptโ
โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโ
โฒ decay/reinforce โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโ
๐ Features
- ๐ง Typed memory โ Pydantic v2 models, JSON-schema-friendly, versioned on disk.
- ๐ Pluggable storage โ YAML / JSON / SQLite out of the box; bring-your-own backend.
- ๐ฌ Pluggable extractors โ deterministic heuristic by default; plug an LLM with
CallableExtractor. - โป๏ธ Self-evolution โ automatic deduplication, reinforcement on repetition, time decay, undo and dry-run previews.
- โ๏ธ Ranked injection โ top-N rules by weight, optionally filtered per project.
- ๐งฉ Editor integrations โ export rules to
.cursorrules,.windsurfrules,CLAUDE.mdand Copilot instructions. - ๐ฅ๏ธ Zero-dep CLI โ
personal-evotaste evolve / inject / list / remove / reset / export. - ๐งช Tested & typed โ pytest suite, ruff, mypy, CI on Python 3.9 โ 3.12.
- ๐พ Crash-safe writes โ atomic file replacement, SQLite transactions.
๐ฆ Installation
pip install personal-evotaste
# or from source
pip install -e ".[dev]"
โก Quickstart
from personal_evotaste import PersonalEvoTaste
taste = PersonalEvoTaste(memory_path="my_taste.yaml")
# 1. Inject your evolving taste into any prompt
prompt = taste.inject_taste(
"Generate a login page",
context="brutalist minimal project",
)
# โ send `prompt` to your LLM of choice
# 2. After reviewing the agent's output, teach it
taste.evolve(
agent_output="A flashy gradient login page with neon buttons",
user_feedback="Too loud. I want calmer, monochrome, brutalist typography.",
project_name="acme-landing",
)
# 3. Next time, the rule is already in the prompt โ and reinforced if you repeat yourself
print(taste.inject_taste("Generate a signup page"))
๐ฅ๏ธ CLI
# Add a rule from feedback
personal-evotaste evolve \
--output "A flashy gradient login page" \
--feedback "Too loud. Prefer calm monochrome brutalist typography." \
--project acme-landing
# Inject taste into a prompt
personal-evotaste inject "Generate a signup page" --context "acme-landing"
# Inspect the memory
personal-evotaste list
personal-evotaste export > snapshot.json
# Preview a rule without changing memory
personal-evotaste evolve --dry-run --output "..." --feedback "Prefer descriptive names"
# Undo the most recent evolution
personal-evotaste undo
# Export rules into AI editor instruction files
personal-evotaste export-rules -f cursor -o .cursorrules
personal-evotaste export-rules -f windsurf -o .windsurfrules
personal-evotaste export-rules -f claude -o CLAUDE.md
personal-evotaste export-rules -f copilot -o .github/copilot-instructions.md
Memory backend is auto-selected from the file extension: .yaml / .json / .sqlite3.
๐ Plugging an LLM extractor
from personal_evotaste import PersonalEvoTaste, CallableExtractor
def summarise_with_llm(agent_output: str, feedback: str, project: str) -> str:
# call OpenAI / Anthropic / a local model here and return one short rule
...
taste = PersonalEvoTaste(
memory_path="my_taste.yaml",
extractor=CallableExtractor(summarise_with_llm),
)
๐งฑ Architecture
personal_evotaste/
โโโ models.py # Pydantic models: TasteRule, FeedbackEvent, TasteMemory
โโโ storage.py # BaseStorage + YAML / JSON / SQLite backends (atomic writes)
โโโ extractors.py # RuleExtractor strategies + similarity-based deduplication
โโโ core.py # PersonalEvoTaste faรงade (evolve / inject / ranking / decay)
โโโ cli.py # argparse-based CLI (zero extra deps)
โโโ exceptions.py # Typed error hierarchy
โโโ logging_config.py
See docs/architecture.md for the design rationale.
See docs/integrations.md for Cursor, Windsurf, Claude and Copilot setup.
๐ค Contributing
PRs, issues and ideas are very welcome โ see CONTRIBUTING.md and our Code of Conduct. If PersonalEvoTaste helps you, a โญ on GitHub goes a long way.
๐ License
MIT ยฉ PersonalEvoTaste Contributors. See LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file personal_evotaste-0.2.0.tar.gz.
File metadata
- Download URL: personal_evotaste-0.2.0.tar.gz
- Upload date:
- Size: 23.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.8.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4e18fa6e19fc946f51f9f4edc75e8b7995d9e4b3ebf4e90856bc68fd196ba97e
|
|
| MD5 |
bc9ff318af9d2e31764d5b5fb368938e
|
|
| BLAKE2b-256 |
fbbf6a1a0261372dbbe810d393bfacc868095b5bc31bff029a21a7496f6f10da
|
File details
Details for the file personal_evotaste-0.2.0-py3-none-any.whl.
File metadata
- Download URL: personal_evotaste-0.2.0-py3-none-any.whl
- Upload date:
- Size: 21.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.8.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
44715ba36fa480f71af0aeaf9ddbb69e4f64ff4653e02757539766b16d2d228b
|
|
| MD5 |
e8b5ac10eefe4558292316012101fb3b
|
|
| BLAKE2b-256 |
d6269031bf3d08fc41fb5de03eeefc2c3a9db578b1bbcca44ff36dc0d0fb330f
|