feat(cli,gateway): add /personality none and custom personality support
Closes #643 Changes: - /personality none|default|neutral — clears system prompt overlay - Custom personalities in config.yaml support dict format with: name, description, system_prompt, tone, style directives - Backwards compatible — existing string format still works - CLI + gateway both updated - 18 tests covering none/default/neutral, dict format, string format, list display, save to config
This commit is contained in:
@@ -1536,14 +1536,39 @@ class GatewayRunner:
|
||||
|
||||
if not args:
|
||||
lines = ["🎭 **Available Personalities**\n"]
|
||||
lines.append("• `none` — (no personality overlay)")
|
||||
for name, prompt in personalities.items():
|
||||
preview = prompt[:50] + "..." if len(prompt) > 50 else prompt
|
||||
if isinstance(prompt, dict):
|
||||
preview = prompt.get("description") or prompt.get("system_prompt", "")[:50]
|
||||
else:
|
||||
preview = prompt[:50] + "..." if len(prompt) > 50 else prompt
|
||||
lines.append(f"• `{name}` — {preview}")
|
||||
lines.append(f"\nUsage: `/personality <name>`")
|
||||
return "\n".join(lines)
|
||||
|
||||
if args in personalities:
|
||||
new_prompt = personalities[args]
|
||||
def _resolve_prompt(value):
|
||||
if isinstance(value, dict):
|
||||
parts = [value.get("system_prompt", "")]
|
||||
if value.get("tone"):
|
||||
parts.append(f'Tone: {value["tone"]}')
|
||||
if value.get("style"):
|
||||
parts.append(f'Style: {value["style"]}')
|
||||
return "\n".join(p for p in parts if p)
|
||||
return str(value)
|
||||
|
||||
if args in ("none", "default", "neutral"):
|
||||
try:
|
||||
if "agent" not in config or not isinstance(config.get("agent"), dict):
|
||||
config["agent"] = {}
|
||||
config["agent"]["system_prompt"] = ""
|
||||
with open(config_path, "w") as f:
|
||||
yaml.dump(config, f, default_flow_style=False, sort_keys=False)
|
||||
except Exception as e:
|
||||
return f"⚠️ Failed to save personality change: {e}"
|
||||
self._ephemeral_system_prompt = ""
|
||||
return "🎭 Personality cleared — using base agent behavior.\n_(takes effect on next message)_"
|
||||
elif args in personalities:
|
||||
new_prompt = _resolve_prompt(personalities[args])
|
||||
|
||||
# Write to config.yaml, same pattern as CLI save_config_value.
|
||||
try:
|
||||
@@ -1560,7 +1585,7 @@ class GatewayRunner:
|
||||
|
||||
return f"🎭 Personality set to **{args}**\n_(takes effect on next message)_"
|
||||
|
||||
available = ", ".join(f"`{n}`" for n in personalities.keys())
|
||||
available = "`none`, " + ", ".join(f"`{n}`" for n in personalities.keys())
|
||||
return f"Unknown personality: `{args}`\n\nAvailable: {available}"
|
||||
|
||||
async def _handle_retry_command(self, event: MessageEvent) -> str:
|
||||
|
||||
Reference in New Issue
Block a user