Feature: Agent Soul Customization #1048
@@ -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"}
|
||||
|
||||
45
src/dashboard/templates/soul.html
Normal file
45
src/dashboard/templates/soul.html
Normal 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 %}
|
||||
@@ -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)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user