{"id":49246365,"url":"https://github.com/benoitpetit/soul","last_synced_at":"2026-04-24T22:02:16.317Z","repository":{"id":353368876,"uuid":"1213856413","full_name":"benoitpetit/soul","owner":"benoitpetit","description":"SOUL is an identity preservation extension for LLM agents. It captures, stores, and recalls the personality, voice, and values of AI agents across sessions and model changes.","archived":false,"fork":false,"pushed_at":"2026-04-23T15:16:12.000Z","size":1161,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-23T17:08:56.892Z","etag":null,"topics":["ai","ai-agents","mcp","memory","soul"],"latest_commit_sha":null,"homepage":"https://devbyben.fr","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/benoitpetit.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"liberapay":"devbyben/donate"}},"created_at":"2026-04-17T20:48:29.000Z","updated_at":"2026-04-23T15:16:17.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/benoitpetit/soul","commit_stats":null,"previous_names":["benoitpetit/soul"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/benoitpetit/soul","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benoitpetit%2Fsoul","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benoitpetit%2Fsoul/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benoitpetit%2Fsoul/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benoitpetit%2Fsoul/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/benoitpetit","download_url":"https://codeload.github.com/benoitpetit/soul/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benoitpetit%2Fsoul/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32242315,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-24T13:21:15.438Z","status":"ssl_error","status_checked_at":"2026-04-24T13:21:15.005Z","response_time":64,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai","ai-agents","mcp","memory","soul"],"created_at":"2026-04-24T22:02:14.994Z","updated_at":"2026-04-24T22:02:16.312Z","avatar_url":"https://github.com/benoitpetit.png","language":"Go","funding_links":["https://liberapay.com/devbyben/donate"],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"./logo.png\" alt=\"SOUL Logo\" width=\"800\"\u003e\n\n  # SOUL\n  ### System for Observed Unique Legacy\n\n  **Identity Preservation System for LLM Agents**\n\n  [![Go Version](https://img.shields.io/badge/Go-1.23+-00ADD8?style=flat-square\u0026logo=go)](https://golang.org/)\n  [![License](https://img.shields.io/badge/License-MIT-green?style=flat-square)](LICENSE)\n  [![Version](https://img.shields.io/badge/Version-0.0.6-blue?style=flat-square)]()\n  [![Tests](https://img.shields.io/badge/Tests-Passing-brightgreen?style=flat-square)]()\n\n  *100% Local • Deterministic • Versioned Identity • Model-Agnostic*\n\n  [Changelog](#changelog) • [Skill](SKILL.md) • [Français](README_FR.md) • [MIRA Integration](https://github.com/benoitpetit/mira)\n\n\u003c/div\u003e\n\n---\n\n## Table of Contents\n\n- [Relationship with MIRA](#relationship-with-mira)\n- [Why SOUL?](#why-soul)\n- [Architecture](#architecture)\n- [Identity Model](#identity-model)\n- [Database Schema](#database-schema)\n- [Installation](#installation)\n- [Configuration](#configuration)\n- [CLI Usage](#cli-usage)\n- [MCP Tools](#mcp-tools)\n- [Deployment](#deployment)\n- [Drift Detection](#drift-detection)\n- [Testing](#testing)\n- [Module](#module)\n- [Changelog](#changelog)\n\n---\n\n## Relationship with MIRA\n\n| Aspect | Detail |\n|--------|--------|\n| **Dependency** | None - SOUL compiles and runs without MIRA |\n| **Integration** | Can run standalone (separate MCP server) or embedded in MIRA (single binary, 16 tools) |\n| **Database** | SOUL adds `soul_*` tables to MIRA's `.mira/mira.db` |\n| **Cross-access** | SOUL can read MIRA's `verbatim` table to enrich identity context |\n| **Deployment** | Standalone via stdio JSON-RPC, or embedded in MIRA process |\n\nSOUL is **opt-in**. A client can connect to MIRA only, SOUL only, or both.\n\n### Embedded Integration (MIRA + SOUL)\n\nMIRA can embed SOUL as a single binary with 16 MCP tools:\n\n```bash\n# MIRA with embedded SOUL - single binary, 16 tools\n./mira --config config.yaml --with-soul\n```\n\nWhen embedded, SOUL shares MIRA's SQLite connection (`ownsDB = false`). If SOUL initialization fails, MIRA continues with its 8 tools.\n\n---\n\n## Why SOUL?\n\nLLM agents lose their personality between sessions and when switching models:\n\n```\nUser talks to \"Claude-3-Assistant\" for 6 months.\nThe agent developed a unique personality: empathetic, analytical,\nwith subtle humor and preference for analogies.\n\nModel switches to GPT-4. MIRA recalls all facts.\nBut the agent now responds differently:\n- More formal, less warm\n- No more analogies\n- Doesn't recognize user's jokes\n- Has \"forgotten\" how to react to frustrations\n\nThe user feels like they're talking to a STRANGER.\n```\n\nSOUL solves this by:\n1. **Capturing** personality traits, voice profile, communication style, values, and emotional tone\n2. **Storing** versioned identity snapshots in the shared database\n3. **Recalling** a structured identity prompt for LLM context injection\n4. **Detecting** identity drift and alerting when significant change occurs\n5. **Handling** model swaps by generating a reinforcement prompt\n\n---\n\n## Architecture\n\n```\nsoul/\n├── cmd/soul/main.go              # CLI entry point + MCP dispatcher\n├── config.example.yaml           # Configuration reference\n├── internal/\n│   ├── app/\n│   │   ├── app.go                # Composition root\n│   │   └── config_loader.go      # YAML config loading\n│   ├── domain/\n│   │   ├── entities/             # IdentitySnapshot, PersonalityTrait, VoiceProfile...\n│   │   └── valueobjects/         # SoulQuery, DriftReport, ModelSwap...\n│   ├── usecases/\n│   │   └── interactors/          # Capture, Recall, Drift, Swap, Evolution, Merge\n│   ├── adapters/\n│   │   ├── sqlite/storage.go     # SQLite storage (shared with MIRA)\n│   │   ├── composition/service.go # Identity prompt composer\n│   │   ├── drift/detector.go    # Drift detection algorithm\n│   │   ├── embedder/service.go   # 13-dim identity embedder\n│   │   ├── extraction/service.go # Trait extraction from conversations\n│   │   └── modelswap/handler.go # Model swap + merge logic\n│   └── interfaces/\n│       └── mcp/server.go        # MCP server (8 tools, stdio JSON-RPC)\n```\n\n**Hexagonal architecture** - domain never imports adapters. All external dependencies flow inward through ports.\n\n---\n\n## Identity Model\n\nAn `IdentitySnapshot` contains:\n\n- **PersonalityTraits** - Named traits with category, intensity (0-1), confidence (0-1), evidence count\n- **VoiceProfile** - Formality, verbosity, vocabulary richness, metaphor usage\n- **CommunicationStyle** - Directness, empathy, humor, question frequency, example usage\n- **BehavioralSignature** - Response patterns, reasoning style, error handling\n- **ValueSystem** - Ethical stances, priorities, boundaries\n- **EmotionalTone** - Baseline valence, arousal, expressiveness\n\nTrait categories: `cognitive`, `emotional`, `social`, `epistemic`, `expressive`, `ethical`\n\n---\n\n## Database Schema\n\nSOUL adds these tables to the shared SQLite database:\n\n| Table | Purpose |\n|-------|---------|\n| `soul_identities` | Versioned identity snapshots per agent |\n| `soul_traits` | Aggregated personality traits with confidence |\n| `soul_observations` | Raw observations extracted from conversations |\n| `soul_diffs` | Evolution diffs between consecutive versions |\n| `soul_model_swaps` | History of model transitions |\n| `soul_mira_links` | Links between identity snapshots and MIRA memories |\n\n---\n\n## Installation\n\n### Prerequisites\n\n- Go 1.23+\n- GCC (for `go-sqlite3` CGo compilation)\n\n### Build\n\n```bash\ngit clone https://github.com/benoitpetit/soul\ncd soul\ngo build -o soul ./cmd/soul\n```\n\n### Run\n\n```bash\n./soul help\n```\n\n---\n\n## Configuration\n\nCopy `config.example.yaml` to configure SOUL:\n\n```bash\ncp config.example.yaml soul.yaml\n```\n\nKey settings:\n\n```yaml\nsoul:\n  storage:\n    path: \".mira/mira.db\"     # Must match MIRA's database path\n\n  drift_detection:\n    threshold: 0.3             # 30% change triggers drift alert\n    window_size: 10\n\n  recall:\n    default_budget_tokens: 1000\n    # enrich_with_mira_memories and max_mira_memories are documented but NOT YET IMPLEMENTED.\n    # enrich_with_mira_memories: true\n    # max_mira_memories: 5\n```\n\n---\n\n## CLI Usage\n\n### Capture identity from a conversation\n\n```bash\nsoul capture \\\n  --agent my-agent \\\n  --conversation conversation.txt \\\n  --model claude-3-sonnet\n```\n\n### Recall identity for LLM context injection\n\n```bash\nsoul recall --agent my-agent --budget 800\n```\n\nOutput is the identity prompt ready to paste into a system message.\n\n### Check identity drift\n\n```bash\nsoul drift --agent my-agent --window 10\n```\n\n### Handle a model swap\n\n```bash\nsoul swap --agent my-agent --from gpt-4 --to claude-3-sonnet\n```\n\nOutputs a reinforcement prompt to inject into the new model's first message.\n\n### Show identity status\n\n```bash\nsoul status --agent my-agent\n```\n\n### Show evolution history\n\n```bash\nsoul history --agent my-agent --limit 20\n```\n\n### Start MCP server\n\n```bash\nsoul mcp --storage .mira/mira.db\n```\n\n---\n\n## MCP Tools\n\nSOUL exposes **8 MCP tools** over stdio JSON-RPC:\n\n| Tool | Description |\n|------|-------------|\n| `soul_capture` | Capture identity from a conversation |\n| `soul_recall` | Recall identity prompt for LLM injection |\n| `soul_drift` | Analyze identity drift |\n| `soul_swap` | Handle model swap + generate reinforcement prompt |\n| `soul_status` | Get current identity status |\n| `soul_history` | Get identity evolution history |\n| `soul_update` | Update identity via natural language directive (FR/EN) |\n| `soul_patch` | Apply structured explicit patch to identity |\n\n---\n\n## Deployment\n\n### Option 1: Embedded in MIRA (recommended)\n\nSOUL is **opt-in** within MIRA. By default, MIRA runs solo (8 tools). To activate SOUL:\n\n```bash\n# Enable SOUL via CLI flag\n./mira --config config.yaml --with-soul\n\n# Or enable SOUL via config\n```yaml\nsoul:\n  enabled: true\n```\n\nWhen enabled, the 8 SOUL tools are registered alongside the 8 MIRA tools (16 total).\n\n### Option 2: Standalone SOUL\n\nSOUL can run as a separate MCP server, with or without MIRA:\n\n```bash\n# Standalone with its own database\nsoul mcp --storage /path/to/soul.db\n\n# Standalone sharing MIRA's database\nsoul mcp --storage /path/to/.mira/mira.db\n```\n\n### Option 3: Both MIRA and SOUL as separate servers\n\n```bash\n# Terminal 1 - MIRA (SOUL disabled by default)\n./mira --config /path/to/mira/config.yaml\n\n# Terminal 2 - SOUL (shares MIRA's database)\n./soul mcp --storage /path/to/.mira/mira.db\n```\n\nBoth run as separate MCP server processes registered in your MCP client configuration.\n\n### MCP Client Configuration\n\n**b0p:**\n```json\n{\n  \"mcpServers\": {\n    \"mira\": {\n      \"command\": \"/path/to/mira\",\n      \"working_directory\": \"/path/to/mira\",\n      \"enabled\": true\n    },\n    \"soul\": {\n      \"command\": \"/path/to/soul\",\n      \"args\": [\"mcp\", \"--storage\", \"/path/to/.mira/mira.db\"],\n      \"enabled\": true\n    }\n  }\n}\n```\n\n**Claude Desktop:**\n```json\n{\n  \"mcpServers\": {\n    \"mira\": {\n      \"command\": \"/path/to/mira\",\n      \"args\": [\"--config\", \"/path/to/mira/config.yaml\"]\n    },\n    \"soul\": {\n      \"command\": \"/path/to/soul\",\n      \"args\": [\"mcp\", \"--storage\", \"/path/to/.mira/mira.db\"]\n    }\n  }\n}\n```\n\n### Tool Count\n\n| Configuration | Tools available |\n|---------------|------------------|\n| MIRA only | 8 (`mira_*`) |\n| SOUL standalone | 8 (`soul_*`) |\n| MIRA + SOUL (separate servers) | 16 (`mira_*` + `soul_*`) |\n| MIRA with embedded SOUL (single binary) | 16 (`mira_*` + `soul_*`) |\n\nTool names never collide - MIRA tools use `mira_` prefix, SOUL tools use `soul_` prefix.\n\n---\n\n## Drift Detection\n\nSOUL computes drift by comparing the current snapshot against N previous versions:\n\n- Per-dimension distance: voice profile, personality traits, value system, emotional tone (4 of 6 dimensions; communication style and behavioral signature are not yet monitored for drift)\n- Average `DriftScore` across dimensions\n- Alert when `DriftScore \u003e threshold` (default: 0.3)\n\nRecommended action when drift is significant: inject the reinforcement prompt from `soul_recall` or `soul_swap` into the next context.\n\n---\n\n## Testing\n\n```bash\ngo test ./... -count=1\n```\n\nAll packages pass with an in-memory SQLite database. MIRA table absence is handled gracefully (fallback queries, empty results instead of errors).\n\n---\n\n## Module\n\n```\ngithub.com/benoitpetit/soul\n```\n\n**Repository:** https://github.com/benoitpetit/soul\n\nGo 1.23.2 - SQLite via `mattn/go-sqlite3` - MCP via `mark3labs/mcp-go v0.2.0`\n\n---\n\n## Changelog\n\n### v0.0.6 (2026-04-24)\n\n- 🚀 New version 0.0.6\n\n### v0.0.5 (2026-04-24)\n\n- 🚀 New version 0.0.5\n\n### v0.0.4 (2026-04-24)\n\n- **Unified embedded configuration**: Added `NewApplicationWithDBAndConfig` so MIRA can pass a full `SoulConfig` when embedding SOUL. Embedded mode now supports the same tuning options as standalone mode (drift threshold, recall budget, extraction confidence, etc.).\n- **Public API expansion**: Exposed `soul.Config` and `soul.DefaultConfig()` aliases for external modules.\n- **Prepublish script**: Added `scripts/prepublish.sh` for automated version bump, build, test, and benchmark workflow.\n\n### v0.0.3 (2026-04-17)\n\n- Initial stable release with MCP server, identity capture, drift detection, model swap handling, and evolution tracking.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbenoitpetit%2Fsoul","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbenoitpetit%2Fsoul","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbenoitpetit%2Fsoul/lists"}