Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion bot/vikingbot/cli/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
from vikingbot.agent.loop import AgentLoop
from vikingbot.bus.queue import MessageBus
from vikingbot.channels.manager import ChannelManager
from vikingbot.config.loader import ensure_config, get_config_path, get_data_dir, load_config
from vikingbot.config.loader import ensure_config, get_config_path, get_data_dir, load_config, save_init_config
from vikingbot.config.schema import SessionKey
from vikingbot.cron.service import CronService
from vikingbot.cron.types import CronJob
Expand Down Expand Up @@ -194,6 +194,30 @@ def main(
"""vikingbot - Personal AI Assistant."""
pass

@app.command()
def onboard():
"""Initialize vikingbot configuration and workspace."""
from vikingbot.config.loader import get_config_path, save_config
from vikingbot.config.schema import Config

config_path = get_config_path()

if config_path.exists():
console.print(f"[yellow]Config already exists at {config_path}[/yellow]")
if not typer.confirm("Overwrite?"):
raise typer.Exit()

# Create default config
config = Config()
save_init_config(config)
console.print(f"[green]✓[/green] Created config at {config_path}")

console.print(f"\n{__logo__} vikingbot is ready!")
console.print("\nNext steps:")
console.print(" 1. Add your API key to [cyan]~/.openviking/ov.conf[/cyan]")
console.print(" Get one at: https://openrouter.ai/keys")
console.print(" 2. Chat: [cyan]vikingbot agent -m \"Hello!\"[/cyan]")


def _make_provider(config, langfuse_client: None = None):
"""Create LiteLLMProvider from config. Allows starting without API key."""
Expand Down
18 changes: 18 additions & 0 deletions bot/vikingbot/config/loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,24 @@ def save_config(config: Config, config_path: Path | None = None) -> None:
with open(path, "w") as f:
json.dump(full_data, f, indent=2)

def save_init_config(config: Config, config_path: Path | None = None) -> None:
"""
Save configuration to file.

Args:
config: Configuration to save.
config_path: Optional path to save to. Uses default if not provided.
"""
path = config_path or get_config_path()
path.parent.mkdir(parents=True, exist_ok=True)

# Convert to camelCase format
data = config.model_dump()
data = convert_to_camel(data)

with open(path, "w") as f:
json.dump(data, f, indent=2)


def convert_keys(data: Any) -> Any:
"""Convert camelCase keys to snake_case for Pydantic."""
Expand Down
Loading