| """First-Run Setup — naming the LLM on first initialization. |
| |
| On first run, the LLM greets the user: |
| "Hi, I am an Incentives Inc. LLM. What would you like to name me?" |
| |
| The user provides a name, which is stored persistently. |
| On subsequent runs, the LLM uses its name in greetings and system prompts. |
| |
| The name is stored in the config file and persists across restarts. |
| """ |
|
|
| from __future__ import annotations |
|
|
| import json |
| import logging |
| import os |
| from typing import Any |
|
|
| logger = logging.getLogger(__name__) |
|
|
|
|
| class FirstRunManager: |
| """Manages first-run setup and LLM naming. |
| |
| On first run: |
| 1. Detects no config exists → first run |
| 2. Greets user: "Hi, I am an Incentives Inc. LLM. What would you like to name me?" |
| 3. User provides a name |
| 4. Name is stored in config |
| |
| On subsequent runs: |
| - Name is loaded from config |
| - System prompt includes the name |
| - Greeting uses the name |
| """ |
|
|
| GREETING = "Hi, I am an Incentives Inc. LLM. What would you like to name me?" |
| WELCOME_BACK = "Hi, I am {name}. How can I help you?" |
|
|
| def __init__(self, data_dir: str) -> None: |
| self.data_dir = data_dir |
| self.config_path = os.path.join(data_dir, "identity.json") |
| self.name: str = "" |
| self.first_run: bool = True |
| self.created_at: float = 0.0 |
| self._load() |
|
|
| def _load(self) -> None: |
| """Load identity from config file.""" |
| if os.path.exists(self.config_path): |
| try: |
| with open(self.config_path, "r") as f: |
| data = json.load(f) |
| self.name = data.get("name", "") |
| self.first_run = data.get("first_run", True) |
| self.created_at = data.get("created_at", 0.0) |
| if self.name: |
| self.first_run = False |
| except Exception as e: |
| logger.warning("Failed to load identity: %s", e) |
| else: |
| self.first_run = True |
|
|
| def _save(self) -> None: |
| """Save identity to config file.""" |
| os.makedirs(self.data_dir, exist_ok=True) |
| data = { |
| "name": self.name, |
| "first_run": self.first_run, |
| "created_at": self.created_at, |
| "company": "Incentives Inc.", |
| } |
| with open(self.config_path, "w") as f: |
| json.dump(data, f, indent=2) |
|
|
| def is_first_run(self) -> bool: |
| """Check if this is the first run.""" |
| return self.first_run |
|
|
| def get_greeting(self) -> str: |
| """Get the appropriate greeting message.""" |
| if self.first_run: |
| return self.GREETING |
| return self.WELCOME_BACK.format(name=self.name) |
|
|
| def set_name(self, name: str) -> None: |
| """Set the LLM's name and mark first run as complete.""" |
| import time |
| self.name = name.strip() |
| self.first_run = False |
| self.created_at = time.time() |
| self._save() |
| logger.info("LLM named: %s", self.name) |
|
|
| def get_system_prompt_suffix(self) -> str: |
| """Get a system prompt suffix that includes the LLM's name.""" |
| if self.name: |
| return f" Your name is {self.name}. You are made by Incentives Inc." |
| return " You are an Incentives Inc. LLM." |
|
|
| def get_name(self) -> str: |
| """Get the LLM's name.""" |
| return self.name or "Incentives Inc. LLM" |
|
|
| def get_stats(self) -> dict[str, Any]: |
| return { |
| "name": self.name, |
| "first_run": self.first_run, |
| "created_at": self.created_at, |
| "company": "Incentives Inc.", |
| } |
|
|