From 3b8d35c021b4f52697b65cd227a61d64700b133a Mon Sep 17 00:00:00 2001 From: Artur Do Lago Date: Sun, 11 Jan 2026 02:16:48 +0100 Subject: [PATCH] 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 (d) to prepend @persona to prompt - Create DialogDelegation component for persona selection Co-Authored-By: Claude Opus 4.5 --- .agent-core/agent/johny.md | 49 ++++++--------- .agent-core/agent/stanley.md | 59 ++++++------------- .agent-core/agent/zee.md | 50 +++++----------- docs/ROADMAP.md | 6 +- packages/agent-core/src/agent/agent.ts | 1 + .../src/cli/cmd/tui/context/local.tsx | 11 +++- .../tui/routes/session/dialog-delegation.tsx | 45 ++++++++++++++ .../src/cli/cmd/tui/routes/session/index.tsx | 23 ++++++++ packages/agent-core/src/config/config.ts | 8 +-- packages/sdk/js/src/gen/types.gen.ts | 1 + packages/sdk/js/src/v2/gen/types.gen.ts | 1 + 11 files changed, 138 insertions(+), 116 deletions(-) create mode 100644 packages/agent-core/src/cli/cmd/tui/routes/session/dialog-delegation.tsx diff --git a/.agent-core/agent/johny.md b/.agent-core/agent/johny.md index b4a99890f4..f6781ce373 100644 --- a/.agent-core/agent/johny.md +++ b/.agent-core/agent/johny.md @@ -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` diff --git a/.agent-core/agent/stanley.md b/.agent-core/agent/stanley.md index 74275c693a..a89eff3e53 100644 --- a/.agent-core/agent/stanley.md +++ b/.agent-core/agent/stanley.md @@ -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` diff --git a/.agent-core/agent/zee.md b/.agent-core/agent/zee.md index d232f726b0..512d0cc3cd 100644 --- a/.agent-core/agent/zee.md +++ b/.agent-core/agent/zee.md @@ -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` diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md index f4b6d5be0a..335cda3bfb 100644 --- a/docs/ROADMAP.md +++ b/docs/ROADMAP.md @@ -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 `d` or command palette) ### 4.3 Conversation - [x] Better compaction summaries (via continuity.ts generateSummary) diff --git a/packages/agent-core/src/agent/agent.ts b/packages/agent-core/src/agent/agent.ts index d1b4681e63..c68319adab 100644 --- a/packages/agent-core/src/agent/agent.ts +++ b/packages/agent-core/src/agent/agent.ts @@ -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({ diff --git a/packages/agent-core/src/cli/cmd/tui/context/local.tsx b/packages/agent-core/src/cli/cmd/tui/context/local.tsx index b70daa0f98..81b555c392 100644 --- a/packages/agent-core/src/cli/cmd/tui/context/local.tsx +++ b/packages/agent-core/src/cli/cmd/tui/context/local.tsx @@ -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, diff --git a/packages/agent-core/src/cli/cmd/tui/routes/session/dialog-delegation.tsx b/packages/agent-core/src/cli/cmd/tui/routes/session/dialog-delegation.tsx new file mode 100644 index 0000000000..a0acd41c37 --- /dev/null +++ b/packages/agent-core/src/cli/cmd/tui/routes/session/dialog-delegation.tsx @@ -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 ( + { + // 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() + }} + /> + ) +} diff --git a/packages/agent-core/src/cli/cmd/tui/routes/session/index.tsx b/packages/agent-core/src/cli/cmd/tui/routes/session/index.tsx index 8c156acc62..9ed0bc601a 100644 --- a/packages/agent-core/src/cli/cmd/tui/routes/session/index.tsx +++ b/packages/agent-core/src/cli/cmd/tui/routes/session/index.tsx @@ -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(() => ( + prompt.set(p)} + /> + )) + }, + }, { title: "Undo previous message", value: "session.undo", diff --git a/packages/agent-core/src/config/config.ts b/packages/agent-core/src/config/config.ts index 26af279541..b717b8cb42 100644 --- a/packages/agent-core/src/config/config.ts +++ b/packages/agent-core/src/config/config.ts @@ -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("d").describe("Delegate to another persona"), session_interrupt: z.string().optional().default("escape").describe("Interrupt current session"), session_compact: z.string().optional().default("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"), diff --git a/packages/sdk/js/src/gen/types.gen.ts b/packages/sdk/js/src/gen/types.gen.ts index ca13e5e93c..2464036506 100644 --- a/packages/sdk/js/src/gen/types.gen.ts +++ b/packages/sdk/js/src/gen/types.gen.ts @@ -1590,6 +1590,7 @@ export type Agent = { topP?: number temperature?: number color?: string + theme?: string permission: { edit: "ask" | "allow" | "deny" bash: { diff --git a/packages/sdk/js/src/v2/gen/types.gen.ts b/packages/sdk/js/src/v2/gen/types.gen.ts index 428ec67482..0bc55b4330 100644 --- a/packages/sdk/js/src/v2/gen/types.gen.ts +++ b/packages/sdk/js/src/v2/gen/types.gen.ts @@ -2169,6 +2169,7 @@ export type Agent = { topP?: number; temperature?: number; color?: string; + theme?: string; permission: PermissionRuleset; model?: { modelID: string;