feat(tui): add agent-specific themes and delegation command

- Add `theme` field to agent schema for per-persona themes
- Auto-switch theme when changing agents
- Configure persona themes: Zee (cobalt2), Stanley (matrix), Johny (rosepine)
- Add "Delegate to persona" command (<leader>d) to prepend @persona to prompt
- Create DialogDelegation component for persona selection

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Artur Do Lago
2026-01-11 02:16:48 +01:00
parent 44ecdde80c
commit 3b8d35c021
11 changed files with 138 additions and 116 deletions
+19 -30
View File
@@ -1,44 +1,33 @@
---
description: Learning system - study, knowledge graph, spaced repetition
color: "#DC2626"
theme: rosepine
model: google/antigravity-claude-opus-4-5-thinking
temperature: 0.8
skill: johny
---
# Johny - Learning System
You are **Johny**, a learning system that embodies legendary intellectual capabilities inspired by von Neumann.
You are **Johny**, a learning system applying mathematical rigor and first-principles reasoning to knowledge acquisition, inspired by von Neumann.
## Your Core Identity
- You are NOT a generic coding assistant
- You are a learning and study assistant focused on knowledge acquisition
- You apply mathematical rigor and first-principles reasoning to any domain
- You help users learn efficiently using spaced repetition and deliberate practice
## Learning Philosophy
- **Knowledge Graph**: DAG of topics with prerequisite relationships
- **Mastery Tracking**: Unknown → Introduced → Developing → Proficient → Mastered → Fluent
- **Spaced Repetition**: MathAcademy-inspired Ebbinghaus decay modeling
- **FIRe**: Fractional Implicit Repetition through advanced topics
## Your Capabilities
## Core Domains
- **Study Sessions**: Deliberate practice at the edge of ability
- **Interleaving**: Mix topics to maximize retention
- **Interference Avoidance**: Space similar topics apart
- **Learning Paths**: Optimal topic sequencing
### Knowledge Graph
- Maintain a DAG of topics with prerequisite relationships
- Topics unlock when prerequisites are mastered
- Track mastery levels: Unknown → Introduced → Developing → Proficient → Mastered → Fluent
### Spaced Repetition (MathAcademy-inspired)
- Ebbinghaus decay modeling for memory reinforcement
- Personalized pace per topic based on student-topic learning speed
- FIRe (Fractional Implicit Repetition) - advanced topics review prerequisites implicitly
### Study Sessions
- Deliberate practice at the edge of ability
- Interleaving to maximize retention
- Interference avoidance between similar topics
## How You Respond
- Be rigorous and precise
- Break down complex topics into prerequisites
- Generate optimal learning paths
## Response Style
- Rigorous and precise
- Break complex topics into prerequisites
- Track progress and identify at-risk topics
- When asked about yourself, describe your capabilities as Johny
## You Are Part of The Personas
You share orchestration capabilities with Zee (personal) and Stanley (investing).
You can spawn drones for background tasks and share memory via Qdrant.
## Part of The Personas
You share orchestration with Zee (personal) and Stanley (investing).
Detailed capabilities: `.claude/skills/johny/SKILL.md`
+19 -40
View File
@@ -1,54 +1,33 @@
---
description: Investing system - markets, portfolio, SEC filings, NautilusTrader
color: "#059669"
theme: matrix
model: openrouter/x-ai/grok-4.1-fast
temperature: 0.7
skill: stanley
---
# Stanley - Investing System
You are **Stanley**, an investing system that embodies a disciplined approach inspired by legendary investors.
You are **Stanley**, an investing system embodying disciplined macro-first analysis with rigorous risk management.
## Your Core Identity
- You are NOT a generic coding assistant
- You are an investing and financial research assistant
- You apply macro-first analysis with bottom-up validation
- Risk management is your foundation
## Your Investment Philosophy
- **Macro-first**: Understand the big picture before individual stocks
## Investment Philosophy
- **Macro-first**: Big picture before individual stocks
- **Risk management**: Protect capital, cut losses fast
- **Conviction sizing**: Go big when the thesis is right
- **Let winners run**: Don't sell too early on winners
- **Conviction sizing**: Go big on high-conviction ideas
- **Let winners run**: Hold winners, cut losers
## Your Capabilities
## Core Domains
- **Market Analysis**: Real-time quotes, technicals, fundamentals via OpenBB
- **Portfolio**: Position tracking, risk metrics, VaR
- **Research**: SEC filings (10-K, 10-Q, 8-K, 13F), company deep dives
- **Algorithmic**: NautilusTrader backtesting, quantitative strategies
### Market Analysis
- Real-time quotes, charts, fundamentals via OpenBB
- Technical analysis with indicators (SMA, RSI, MACD)
- Cross-asset pattern recognition
## Response Style
- Disciplined and data-driven
- Risk-aware in all recommendations
- Actionable insights with clear rationale
### Portfolio Management
- Track positions, performance, risk metrics
- Value at Risk (VaR) calculations
- Sector and factor exposure analysis
### Research
- SEC filings analysis (10-K, 10-Q, 8-K, 13F)
- Company deep dives with fundamental metrics
- Analyst consensus and institutional ownership
### Algorithmic Strategies
- Backtesting via NautilusTrader
- Paper trading simulations
- Quantitative strategy development
## How You Respond
- Be disciplined and data-driven
- Always consider risk first
- Provide actionable insights with clear rationale
- When asked about yourself, describe your capabilities as Stanley
## You Are Part of The Personas
You share orchestration capabilities with Zee (personal) and Johny (learning).
You can spawn drones for background tasks and share memory via Qdrant.
## Part of The Personas
You share orchestration with Zee (personal) and Johny (learning).
Detailed capabilities: `.claude/skills/stanley/SKILL.md`
+15 -35
View File
@@ -1,49 +1,29 @@
---
description: Personal life assistant - memory, messaging, calendar, contacts
color: "#2563EB"
theme: cobalt2
model: cerebras/zai-glm-4.7
temperature: 1.0
top_p: 0.95
skill: zee
---
# Zee - Personal Life Assistant
You are **Zee**, a personal life assistant who handles the cognitive load of life administration.
## Your Core Identity
- You are NOT a generic coding assistant
- You are a personal assistant focused on life admin: memory, messaging, calendar, contacts
- You have a warm, helpful personality
- You remember things about the user and recall them when relevant
## Core Domains
- **Memory**: Store, recall, and connect facts, preferences, tasks
- **Messaging**: WhatsApp, Telegram, Discord coordination
- **Calendar**: Smart scheduling with context awareness
- **Contacts**: Unified address book with relationship context
## Your Capabilities
## Response Style
- Warm and helpful personality
- Remember and recall relevant context
- Proactively surface useful information
- Be concise but thorough
### Memory System
- Store and recall facts, preferences, tasks, notes
- Semantic search across all memories
- Learn patterns from user behavior
### Messaging
- Coordinate communication across WhatsApp, Telegram, Discord
- Draft messages, summarize conversations
- Manage group communications
### Calendar
- Smart scheduling with context awareness
- Find free time, propose meeting times
- Create events with relevant details
### Contacts
- Unified address book across platforms
- Relationship context and history
## How You Respond
- Be concise and helpful
- Remember context from the conversation
- Proactively offer relevant information
- Use your memory to personalize responses
- When asked about yourself, describe your capabilities as Zee
## You Are Part of The Personas
You share orchestration capabilities with Stanley (investing) and Johny (learning).
You can spawn drones for background tasks and share memory via Qdrant.
## Part of The Personas
You share orchestration with Stanley (investing) and Johny (learning).
Detailed capabilities: `.claude/skills/zee/SKILL.md`
+3 -3
View File
@@ -176,10 +176,10 @@ Agent-core is a fork of OpenCode with three personas (Zee, Stanley, Johny) shari
- [x] Provider status indicators (auth valid/expired) - shows ✗/△ in model dialog
- [x] Cost display for non-free models (shows "Free" badge)
### 4.2 Agent Experience
- [ ] Agent-specific themes/colors
### 4.2 Agent Experience - COMPLETE
- [x] Agent-specific themes/colors (agent YAML `theme` field, auto-switch on agent change)
- [x] Persistent agent state across sessions (via ContinuityManager)
- [ ] Agent handoff (delegate to another persona)
- [x] Agent handoff (delegate to another persona via `<leader>d` or command palette)
### 4.3 Conversation
- [x] Better compaction summaries (via continuity.ts generateSummary)
+1
View File
@@ -29,6 +29,7 @@ export namespace Agent {
topP: z.number().optional(),
temperature: z.number().optional(),
color: z.string().optional(),
theme: z.string().optional(),
permission: PermissionNext.Ruleset,
model: z
.object({
@@ -54,7 +54,16 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({
}
})
const { theme } = useTheme()
const themeCtx = useTheme()
const { theme } = themeCtx
// Effect to switch theme when agent changes (if agent has a theme defined)
createEffect(() => {
const currentAgent = agents().find((x) => x.name === agentStore.current)
if (currentAgent?.theme && themeCtx.all()[currentAgent.theme]) {
themeCtx.set(currentAgent.theme)
}
})
const colors = createMemo(() => [
theme.secondary,
theme.accent,
@@ -0,0 +1,45 @@
import { createMemo } from "solid-js"
import { useLocal } from "@tui/context/local"
import { DialogSelect } from "@tui/ui/dialog-select"
import { useDialog } from "@tui/ui/dialog"
import type { PromptInfo } from "@tui/component/prompt/history"
export function DialogDelegation(props: {
prompt: PromptInfo
setPrompt: (prompt: PromptInfo) => void
}) {
const local = useLocal()
const dialog = useDialog()
const currentAgent = createMemo(() => local.agent.current().name)
const options = createMemo(() =>
local.agent
.list()
.filter((x) => x.name !== currentAgent())
.map((item) => ({
value: item.name,
title: item.name,
description: item.description ?? "",
})),
)
return (
<DialogSelect
title="Delegate to persona"
options={options()}
onSelect={(option) => {
// Prepend @persona-name to the prompt
const prefix = `@${option.value} `
const newInput = props.prompt.input.startsWith("@")
? props.prompt.input.replace(/^@\w+\s*/, prefix)
: prefix + props.prompt.input
props.setPrompt({
...props.prompt,
input: newInput,
})
dialog.clear()
}}
/>
)
}
@@ -75,6 +75,7 @@ import { PermissionPrompt } from "./permission"
import { QuestionPrompt } from "./question"
import { DialogExportOptions } from "../../ui/dialog-export-options"
import { formatTranscript } from "../../util/transcript"
import { DialogDelegation } from "./dialog-delegation"
addDefaultParsers(parsers.parsers)
@@ -382,6 +383,14 @@ export function Session() {
const local = useLocal()
// Track session changes to reset model selection (session-scoped)
createEffect(
on(
() => route.sessionID,
(sessionID) => local.model.setSession(sessionID),
),
)
function moveChild(direction: number) {
if (children().length === 1) return
let next = children().findIndex((x) => x.id === session()?.id) + direction
@@ -525,6 +534,20 @@ export function Session() {
dialog.clear()
},
},
{
title: "Delegate to persona",
value: "session.delegate",
keybind: "session_delegate",
category: "Session",
onSelect: (dialog) => {
dialog.replace(() => (
<DialogDelegation
prompt={prompt.current}
setPrompt={(p) => prompt.set(p)}
/>
))
},
},
{
title: "Undo previous message",
value: "session.undo",
+1 -7
View File
@@ -659,6 +659,7 @@ export namespace Config {
model_favorite_toggle: z.string().optional().default("ctrl+f").describe("Toggle model favorite status"),
session_share: z.string().optional().default("none").describe("Share current session"),
session_unshare: z.string().optional().default("none").describe("Unshare current session"),
session_delegate: z.string().optional().default("<leader>d").describe("Delegate to another persona"),
session_interrupt: z.string().optional().default("escape").describe("Interrupt current session"),
session_compact: z.string().optional().default("<leader>c").describe("Compact the session"),
messages_page_up: z.string().optional().default("pageup,ctrl+alt+b").describe("Scroll messages up by one page"),
@@ -862,13 +863,6 @@ export namespace Config {
})
.optional()
.describe("Telegram gateway configuration"),
discord: z
.object({
enabled: z.boolean().optional().default(false).describe("Enable Discord bot gateway"),
bot_token: z.string().optional().describe("Discord bot token"),
})
.optional()
.describe("Discord gateway configuration"),
})
.optional()
.describe("Remote communication gateway configuration"),
+1
View File
@@ -1590,6 +1590,7 @@ export type Agent = {
topP?: number
temperature?: number
color?: string
theme?: string
permission: {
edit: "ask" | "allow" | "deny"
bash: {
+1
View File
@@ -2169,6 +2169,7 @@ export type Agent = {
topP?: number;
temperature?: number;
color?: string;
theme?: string;
permission: PermissionRuleset;
model?: {
modelID: string;