Feature: Agent Soul Customization #1048

Closed
gemini wants to merge 3 commits from feature/soul-customization into main
3 changed files with 80 additions and 0 deletions

View File

@@ -8,6 +8,7 @@ from fastapi.responses import HTMLResponse, JSONResponse
from config import settings
from dashboard.templating import templates
from timmy.memory_system import get_memory_system
logger = logging.getLogger(__name__)
@@ -190,3 +191,26 @@ async def api_swarm_status():
"message": "Swarm monitoring endpoint",
}
)
@router.get("/soul", response_class=HTMLResponse)
async def soul_page(request: Request):
"""Render the soul management page."""
memory_system = get_memory_system()
soul_content = memory_system.read_soul()
return templates.TemplateResponse(
request,
"soul.html",
{"soul_content": soul_content}
)
@router.post("/soul/update", response_class=JSONResponse)
async def update_soul(request: Request):
"""Update the soul.md content."""
form = await request.form()
content = form.get("content", "")
memory_system = get_memory_system()
success = memory_system.write_soul(content)
if not success:
return JSONResponse({"error": "Failed to update soul"}, status_code=500)
return {"status": "ok", "message": "Soul updated successfully"}

View File

@@ -0,0 +1,45 @@
{% extends "base.html" %}
{% block title %}Soul Management - Timmy Dashboard{% endblock %}
{% block content %}
<div class="container py-4">
<div class="d-flex justify-content-between align-items-center mb-4">
<div>
<h1 class="h3 mb-0">Soul Management</h1>
<p class="text-muted">Define the core identity, values, and personality of your agent.</p>
</div>
<a href="/" class="btn btn-outline-secondary btn-sm">Back to Dashboard</a>
</div>
<div class="card shadow-sm">
<div class="card-header bg-white py-3">
<h5 class="card-title mb-0">Core Identity (soul.md)</h5>
</div>
<div class="card-body">
<form hx-post="/system/soul/update" hx-swap="none" hx-on::after-request="if(event.detail.successful) alert('Soul updated successfully!')">
<div class="mb-3">
<label for="soulContent" class="form-label">Soul Content (Markdown)</label>
<textarea class="form-control font-monospace" id="soulContent" name="content" rows="20" placeholder="# Agent Identity..." style="font-size: 0.9rem;">{{ soul_content }}</textarea>
<div class="form-text">This content is injected into the agent's system prompt to define its core persona.</div>
</div>
<div class="d-flex justify-content-end">
<button type="submit" class="btn btn-primary">Save Changes</button>
</div>
</form>
</div>
</div>
<div class="mt-4">
<div class="alert alert-info">
<h6 class="alert-heading">What is the Soul?</h6>
<p class="mb-0 small">
The Soul (<code>soul.md</code>) is the most fundamental layer of the agent's memory.
Unlike episodic memories or facts, the Soul defines <strong>who</strong> the agent is, its primary mission,
and its ethical boundaries. It is always prioritized in the agent's thinking process.
</p>
</div>
</div>
</div>
{% endblock %}

View File

@@ -572,6 +572,17 @@ def get_memory_context(query: str, max_tokens: int = 2000, **filters) -> str:
if not context_parts:
return ""
def write_soul(self, content: str) -> bool:
"""Write content to soul.md — Timmy's core identity."""
try:
SOUL_PATH.parent.mkdir(parents=True, exist_ok=True)
SOUL_PATH.write_text(content)
logger.info("MemorySystem: Updated soul.md")
return True
except OSError as exc:
logger.error("Failed to write soul.md: %s", exc)
return False
return "Relevant context from memory:\n" + "\n\n".join(context_parts)