From 0fa6fc9db9f2684fde81ba38d36bff371e62cb4d Mon Sep 17 00:00:00 2001 From: Dita Aji Pratama Date: Sun, 14 Jun 2026 12:55:51 +0700 Subject: [PATCH] Biasa bug yang sama berulang-ulang --- config.py | 44 ++++++++++++++++++++++++++++++++++++++------ config.yaml | 10 ++-------- scripts/persona.py | 10 ++++++---- 3 files changed, 46 insertions(+), 18 deletions(-) diff --git a/config.py b/config.py index 41fa723..0b4a19d 100644 --- a/config.py +++ b/config.py @@ -44,7 +44,7 @@ AGENT_MAX_TOOL_OUTPUT = int(os.getenv("AGENT_MAX_TOOL_OUTPUT", default=_yaml_get # ─── Persona / Mode (YAML, bisa di-override dari .env) ────────────────────────── -AGENT_SKILL = os.getenv("AGENT_SKILL", default=_yaml_get("persona", "skill", default="programmer")).strip().lower() +AGENT_SKILL = os.getenv("AGENT_SKILL", default="programmer").strip().lower() PERSONA_NAME = os.getenv("PERSONA_NAME", default=_yaml_get("persona", "name", default="Hendrik")).strip() or "Hendrik" PERSONA_AGE = os.getenv("PERSONA_AGE", default=_yaml_get("persona", "age", default="")).strip() PERSONA_GENDER = os.getenv("PERSONA_GENDER", default=_yaml_get("persona", "gender", default="")).strip() @@ -58,8 +58,8 @@ PERSONA_CATCHPHRASES = os.getenv("PERSONA_CATCHPHRASES", default=_yaml_get("pers # ─── Character & Skills (YAML, bisa di-override dari .env) ───────────────────── -AGENT_CHARACTER = os.getenv("AGENT_CHARACTER", default=_yaml_get("character", "preset", default="")).strip().lower() -AGENT_SKILLS = os.getenv("AGENT_SKILLS", default=_yaml_get("character", "skills", default="")).strip().lower() +AGENT_CHARACTER = os.getenv("AGENT_CHARACTER", default=_yaml_get("agent", "character", default="")).strip().lower() +AGENT_SKILLS = os.getenv("AGENT_SKILLS", default="").strip().lower() # ─── XMPP (non-credential dari YAML, credential dari .env) ───────────────────── @@ -91,8 +91,21 @@ TYPING_MAX = float(os.getenv("TYPING_MAX", default=_yaml_get("delay", "t ENV_CHARACTERS_DIR = Path(__file__).resolve().parent / "agent" / "characters" ENV_CHARACTER_CONFIG_PATH = ENV_CHARACTERS_DIR / AGENT_CHARACTER / "character.md" if AGENT_CHARACTER else None -if ENV_CHARACTER_CONFIG_PATH and ENV_CHARACTER_CONFIG_PATH.is_file(): - _character_env: dict[str, str] = {} +# Coba persona.yaml dulu (prioritas utama), kalau tidak ada fallback ke character.md +_persona_yaml_path = ENV_CHARACTERS_DIR / AGENT_CHARACTER / "persona.yaml" if AGENT_CHARACTER else None + +if _persona_yaml_path and _persona_yaml_path.is_file(): + # Prioritas utama: baca persona.yaml dari character directory + try: + _character_env = yaml.safe_load(_persona_yaml_path.read_text(encoding="utf-8")) or {} + if not isinstance(_character_env, dict): + _character_env = {} + except Exception as _e: + print(f"[config] Warning: gagal load persona.yaml untuk '{AGENT_CHARACTER}': {_e}") + _character_env = {} +elif ENV_CHARACTER_CONFIG_PATH and ENV_CHARACTER_CONFIG_PATH.is_file(): + # Fallback: baca character.md (format lama) + _character_env = {} for line in ENV_CHARACTER_CONFIG_PATH.read_text(encoding="utf-8").splitlines(): line = line.strip() if not line or line.startswith("#"): @@ -100,6 +113,10 @@ if ENV_CHARACTER_CONFIG_PATH and ENV_CHARACTER_CONFIG_PATH.is_file(): if "=" in line: key, value = line.split("=", 1) _character_env[key.strip()] = value.strip() +else: + _character_env = None + +if _character_env: _character_overrides = { "AGENT_SKILL": AGENT_SKILL, @@ -113,8 +130,23 @@ if ENV_CHARACTER_CONFIG_PATH and ENV_CHARACTER_CONFIG_PATH.is_file(): "PERSONA_MOOD": PERSONA_MOOD, "PERSONA_CATCHPHRASES": PERSONA_CATCHPHRASES, } + # Mapping dari key persona.yaml ke key config + _yaml_to_config_key = { + "AGENT_SKILL": "skill", + "PERSONA_NAME": "name", + "PERSONA_AGE": "age", + "PERSONA_GENDER": "gender", + "PERSONA_TONE": "tone", + "PERSONA_VERBOSITY": "verbosity", + "PERSONA_HUMOR": "humor", + "PERSONA_LANGUAGE": "language", + "PERSONA_MOOD": "mood", + "PERSONA_CATCHPHRASES": "catchphrases", + } for key, fallback in _character_overrides.items(): - value = _character_env.get(key, fallback).strip() + yaml_key = _yaml_to_config_key.get(key, key.lower()) + raw = _character_env.get(yaml_key, _character_env.get(key, fallback)) + value = str(raw).strip() if raw is not None else "" if key in {"AGENT_SKILL", "PERSONA_TONE", "PERSONA_VERBOSITY", "PERSONA_HUMOR", "PERSONA_LANGUAGE", "PERSONA_MOOD"}: value = value.lower() or fallback if key == "PERSONA_NAME" and not value: diff --git a/config.yaml b/config.yaml index dd851c7..901b4ad 100644 --- a/config.yaml +++ b/config.yaml @@ -1,16 +1,10 @@ agent: max_iterations: 40 max_tool_output: 40000 - -persona: - skill: programmer # Default skill: programmer, roleplayer, analyst - -character: - preset: hendrik # Directory name in agent/characters// - skills: programmer # comma-separated, e.g. "programmer,analyst" + character: lily # Directory name in agent/characters// xmpp: - enabled: false + enabled: true muc_rooms: "" # comma-separated, e.g. "room1@conference.server,room2@conference.server" nickname: "" # custom MUC nickname (empty = use username) selective_response: true # true = only response if mentioned/relevant diff --git a/scripts/persona.py b/scripts/persona.py index 014933c..21931fe 100644 --- a/scripts/persona.py +++ b/scripts/persona.py @@ -129,6 +129,7 @@ def _build_personality_block(cfg: PersonalityConfig) -> str: "formal": "You speak formally and professionally, using polite language.", "playful": "You are playful and cheerful, making conversations fun and lighthearted.", "warm": "You are warm and friendly, making people feel comfortable and welcomed.", + "sweet": "You speak in a sweet, gentle, and caring manner — soft and endearing.", } parts.append(tone_map.get(cfg.tone, tone_map["casual"])) @@ -254,13 +255,13 @@ def build_system_prompt( Returns: String system prompt lengkap. """ - selected_skill = (skill or SKILL).strip().lower() + selected_skill = (skill or "").strip().lower() cfg = personality or PERSONALITY # Resolve character name character_name = (character or os.getenv("AGENT_CHARACTER", default="")).strip().lower() - # ── Load persona.yaml dari character directory (override personality) ───────── + # ── Load persona.yaml dari character directory ───────────────────────────────── if character_name: char_dir = ENV_CHARACTERS_DIR / character_name persona_yaml_path = char_dir / "persona.yaml" @@ -269,7 +270,6 @@ def build_system_prompt( with open(persona_yaml_path, "r", encoding="utf-8") as f: _persona_data = yaml.safe_load(f) or {} if isinstance(_persona_data, dict): - # Override personality dari persona.yaml if _persona_data.get("name"): cfg.name = _persona_data["name"] if _persona_data.get("age"): @@ -286,10 +286,12 @@ def build_system_prompt( cfg.language = _persona_data["language"] if _persona_data.get("mood"): cfg.mood = _persona_data["mood"] - # key "skill" (baru) atau "mode" (legacy) menentukan active skill + # Skill wajib dari persona.yaml _skill_from_yaml = _persona_data.get("skill") or _persona_data.get("mode") if _skill_from_yaml: selected_skill = _skill_from_yaml.strip().lower() + else: + selected_skill = "" except Exception as e: print(f"[persona] Warning: gagal load persona.yaml untuk '{character_name}': {e}")