Tasks: optional persona for LLM + research tasks (biases output voice)

Wire the existing built-in PERSONAS catalog through to scheduled tasks
the same way I wired it to reminder synthesis. Repurposes the
dormant scheduled_tasks.character_id column.

UI (static/js/tasks.js)
- New 'Persona' select in the LLM / Research task form, with the five
  built-in characters (socrates/razor/nietzsche/spark/odysseus) plus a
  default 'no persona' option. Pre-populates from existing.character_id
  on edit. Non-llm/research types explicitly clear it on save.

API (routes/task_routes.py)
- TaskCreate + TaskUpdate gain character_id: Optional[str].
- _task_to_dict echoes character_id back so the form can hydrate on
  edit. Update endpoint stores '' as None to allow clearing.

Runner (src/task_scheduler.py)
- When task.character_id is set and matches a built-in persona, prepend
  the persona prompt to the task system prompt so the model speaks in
  that voice while still knowing it's running a scheduled task.
- crew_member.personality still wins as the base; character_id stacks
  on top.
This commit is contained in:
pewdiepie-archdaemon
2026-06-10 23:36:18 +09:00
parent a86990fc58
commit 2bf372b41c
3 changed files with 38 additions and 0 deletions
+13
View File
@@ -1335,11 +1335,24 @@ class TaskScheduler:
return await self._execute_checkin(task, crew, db, session_id, endpoint_url, model)
# Build system prompt: crew member persona overrides the default.
# Built-in character_id (Socrates, Razor, etc.) further biases the
# voice — it prepends to whichever base prompt we landed on so the
# task still knows it's executing a scheduled task but in that
# character's tone.
system_prompt = (
(crew.personality or "").strip()
if crew and crew.personality
else "You are a helpful assistant executing a scheduled task. Use available tools to complete the task thoroughly."
)
char_id = (getattr(task, "character_id", None) or "").strip()
if char_id:
try:
from src.reminder_personas import PERSONAS as _PERSONAS
char_prompt = _PERSONAS.get(char_id.lower())
if char_prompt:
system_prompt = f"{char_prompt}\n\n{system_prompt}"
except Exception:
pass
# Inject current time so the model knows what's past vs upcoming
tz_name = _resolve_task_timezone(db, task)
try: