feat(setup): personalized setup wizard with purpose and plugin suggestions
Add a personalization step to `pyra setup` that asks for the user's name, a one-sentence purpose, and interest areas, then surfaces relevant planned plugins. Store purpose in GeneralConfig and use it in the system prompt so Pyra stays task-focused rather than acting as a generic chatbot. - config/schema.py: add `purpose: str = ""` to GeneralConfig - setup/wizard.py: add _collect_user_profile(), _suggest_plugins(), _USE_CASE_PLUGINS - chat/history.py: replace hardcoded _SYSTEM_BASE with _build_system_base() using config values - config/tui.py: expose purpose field in /config General tab Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -5,11 +5,20 @@ from rich.panel import Panel
|
||||
from rich.text import Text
|
||||
|
||||
from pyra.config.manager import save_config
|
||||
from pyra.config.schema import ProviderConfig, PyraConfig
|
||||
from pyra.config.schema import GeneralConfig, ProviderConfig, PyraConfig
|
||||
from pyra.setup.providers import PROVIDERS, Provider, get_provider
|
||||
|
||||
console = Console()
|
||||
|
||||
_USE_CASE_PLUGINS: dict[str, list[str]] = {
|
||||
"Research & web": ["websearch", "headless_browser"],
|
||||
"Development & servers": ["server_manager", "ssh_tool", "docker_tool"],
|
||||
"File management": ["gdrive", "onedrive", "dropbox_tool"],
|
||||
"Communication bots": ["matrix_bot", "telegram_bot", "signal_bot"],
|
||||
"Email": ["email"],
|
||||
"Productivity & calendars": ["nextcloud"],
|
||||
}
|
||||
|
||||
|
||||
def run_setup() -> None:
|
||||
console.print(Panel(
|
||||
@@ -19,6 +28,8 @@ def run_setup() -> None:
|
||||
))
|
||||
console.print()
|
||||
|
||||
user_name, purpose, use_cases = _collect_user_profile()
|
||||
|
||||
provider = _choose_provider()
|
||||
model = _choose_model(provider)
|
||||
|
||||
@@ -32,10 +43,13 @@ def run_setup() -> None:
|
||||
provider_id=provider.id,
|
||||
model=model,
|
||||
base_url=provider.base_url,
|
||||
)
|
||||
),
|
||||
general=GeneralConfig(user_name=user_name, purpose=purpose),
|
||||
)
|
||||
save_config(cfg)
|
||||
|
||||
_suggest_plugins(use_cases)
|
||||
|
||||
console.print()
|
||||
console.print(Panel(
|
||||
f"[green]Setup complete![/green]\n\n"
|
||||
@@ -46,6 +60,58 @@ def run_setup() -> None:
|
||||
))
|
||||
|
||||
|
||||
def _collect_user_profile() -> tuple[str, str, list[str]]:
|
||||
console.print("[bold]Let's personalise your setup.[/bold]")
|
||||
console.print()
|
||||
|
||||
name = questionary.text("What should Pyra call you?", default="User").ask()
|
||||
if name is None:
|
||||
raise SystemExit(0)
|
||||
name = name.strip() or "User"
|
||||
|
||||
purpose = questionary.text(
|
||||
"In one sentence, what will you mainly use Pyra for? (optional)",
|
||||
).ask()
|
||||
if purpose is None:
|
||||
raise SystemExit(0)
|
||||
purpose = purpose.strip()
|
||||
|
||||
use_cases = questionary.checkbox(
|
||||
"Which areas interest you? (Space to select, Enter to confirm)",
|
||||
choices=list(_USE_CASE_PLUGINS.keys()),
|
||||
).ask()
|
||||
if use_cases is None:
|
||||
raise SystemExit(0)
|
||||
|
||||
console.print()
|
||||
return name, purpose, use_cases or []
|
||||
|
||||
|
||||
def _suggest_plugins(use_cases: list[str]) -> None:
|
||||
if not use_cases:
|
||||
return
|
||||
|
||||
lines: list[str] = []
|
||||
for uc in use_cases:
|
||||
plugins = _USE_CASE_PLUGINS.get(uc, [])
|
||||
if plugins:
|
||||
lines.append(f"[bold]{uc}[/bold]")
|
||||
for p in plugins:
|
||||
lines.append(f" pyra plugin install {p}")
|
||||
if not lines:
|
||||
return
|
||||
|
||||
lines.append("")
|
||||
lines.append("[dim]All listed plugins are in development — install when available.[/dim]")
|
||||
|
||||
console.print()
|
||||
console.print(Panel(
|
||||
"\n".join(lines),
|
||||
title="Suggested plugins",
|
||||
border_style="dim cyan",
|
||||
))
|
||||
|
||||
|
||||
def _choose_provider() -> Provider:
|
||||
local = [p for p in PROVIDERS if p.group == "Local"]
|
||||
cloud = [p for p in PROVIDERS if p.group == "Cloud"]
|
||||
|
||||
Reference in New Issue
Block a user