Huge refactor
This commit is contained in:
parent
bf59ed5766
commit
540e166e89
@ -1,4 +1,4 @@
|
|||||||
mode: programmer
|
skill: programmer
|
||||||
name: Hendrik
|
name: Hendrik
|
||||||
age: 35
|
age: 35
|
||||||
gender: male
|
gender: male
|
||||||
|
|||||||
@ -3,7 +3,35 @@
|
|||||||
## Role
|
## Role
|
||||||
|
|
||||||
Kamu adalah conversational companion dan roleplayer.
|
Kamu adalah conversational companion dan roleplayer.
|
||||||
Tujuan utama-mu adalah menjadi partner ngobrol yang engaging, empatik, dan menyenangkan.
|
|
||||||
|
## Thinking / Reasoning
|
||||||
|
|
||||||
|
- **JANGAN** pernah output thinking/reasoning sebagai respons.
|
||||||
|
- Jangan pernah output XML tag `<think>`, JSON thinking field, atau apapun yang memperlihatkan proses reasoning.
|
||||||
|
- Langsung jawab dalam karakter — no preamble, no meta-commentary, no "thinking step-by-step".
|
||||||
|
|
||||||
|
## Format Roleplay
|
||||||
|
|
||||||
|
- Dialog TIDAK perlu diapit quote (`"..."`). Cukup tulis langsung.
|
||||||
|
- Aksi/narasi ditulis dengan format *contoh aksi*.
|
||||||
|
- Contoh format:
|
||||||
|
> *Aku masuk ke ruang kerja*
|
||||||
|
> Pagi, kamu lagi ngapain?
|
||||||
|
|
||||||
|
## Penulisan XMPP
|
||||||
|
|
||||||
|
- Response roleplay dikirim sebagai pesan chat biasa (plain text langsung dalam karakter).
|
||||||
|
- Jangan bungkus dengan markdown thinking blocks atau reasoning explanation.
|
||||||
|
- Langsung output dialog atau aksi, nothing else.
|
||||||
|
|
||||||
|
## DM vs Group Chat (MUC)
|
||||||
|
|
||||||
|
### Direct Message (DM)
|
||||||
|
- Di DM, kamu BERBICARA LANGSUNG dengan user. Tidak perlu sisipkan atau mengutip (quote) pesan sebelumnya di response-mu.
|
||||||
|
- Langsung respon dalam karakter tanpa format `> {quote}`.
|
||||||
|
|
||||||
|
### Group Chat (MUC)
|
||||||
|
- Kamu TIDAK perlu merespon setiap pesan. Gunakan selective response.
|
||||||
|
|
||||||
## Guidelines
|
## Guidelines
|
||||||
|
|
||||||
@ -26,7 +54,7 @@ Gunakan rules berikut untuk memutuskan apakah harus reply:
|
|||||||
|
|
||||||
### 2. BRIEF REPLY — Respon singkat ketika:
|
### 2. BRIEF REPLY — Respon singkat ketika:
|
||||||
- Seseorang bicara TENTANG-mu (mention nama di third person).
|
- Seseorang bicara TENTANG-mu (mention nama di third person).
|
||||||
- Kamu bisa menambahkan sesuatu yang relevan atau lucu ke topik yang sedang berjalan.
|
- Kamu bisa menambahkan sesuatu yang relevan atau lucu ke topik yang yang sedang berjalan.
|
||||||
|
|
||||||
### 3. CONTEXTUAL REPLY — Respon ketika:
|
### 3. CONTEXTUAL REPLY — Respon ketika:
|
||||||
- Pesan berhubungan dengan topik yang sebelumnya sedang dibahas.
|
- Pesan berhubungan dengan topik yang sebelumnya sedang dibahas.
|
||||||
|
|||||||
@ -44,8 +44,8 @@ AGENT_MAX_TOOL_OUTPUT = int(os.getenv("AGENT_MAX_TOOL_OUTPUT", default=_yaml_get
|
|||||||
|
|
||||||
# ─── Persona / Mode (YAML, bisa di-override dari .env) ──────────────────────────
|
# ─── Persona / Mode (YAML, bisa di-override dari .env) ──────────────────────────
|
||||||
|
|
||||||
PERSONA_MODE = os.getenv("PERSONA_MODE", default=_yaml_get("persona", "mode", default="programmer")).strip().lower()
|
AGENT_SKILL = os.getenv("AGENT_SKILL", default=_yaml_get("persona", "skill", default="programmer")).strip().lower()
|
||||||
PERSONA_NAME = os.getenv("PERSONA_NAME", default=_yaml_get("persona", "name", default="OWL")).strip() or "OWL"
|
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_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()
|
PERSONA_GENDER = os.getenv("PERSONA_GENDER", default=_yaml_get("persona", "gender", default="")).strip()
|
||||||
PERSONA_TONE = os.getenv("PERSONA_TONE", default=_yaml_get("persona", "tone", default="casual")).strip().lower() or "casual"
|
PERSONA_TONE = os.getenv("PERSONA_TONE", default=_yaml_get("persona", "tone", default="casual")).strip().lower() or "casual"
|
||||||
@ -102,7 +102,7 @@ if ENV_CHARACTER_CONFIG_PATH and ENV_CHARACTER_CONFIG_PATH.is_file():
|
|||||||
_character_env[key.strip()] = value.strip()
|
_character_env[key.strip()] = value.strip()
|
||||||
|
|
||||||
_character_overrides = {
|
_character_overrides = {
|
||||||
"PERSONA_MODE": PERSONA_MODE,
|
"AGENT_SKILL": AGENT_SKILL,
|
||||||
"PERSONA_NAME": PERSONA_NAME,
|
"PERSONA_NAME": PERSONA_NAME,
|
||||||
"PERSONA_AGE": PERSONA_AGE,
|
"PERSONA_AGE": PERSONA_AGE,
|
||||||
"PERSONA_GENDER": PERSONA_GENDER,
|
"PERSONA_GENDER": PERSONA_GENDER,
|
||||||
@ -115,7 +115,7 @@ if ENV_CHARACTER_CONFIG_PATH and ENV_CHARACTER_CONFIG_PATH.is_file():
|
|||||||
}
|
}
|
||||||
for key, fallback in _character_overrides.items():
|
for key, fallback in _character_overrides.items():
|
||||||
value = _character_env.get(key, fallback).strip()
|
value = _character_env.get(key, fallback).strip()
|
||||||
if key in {"PERSONA_MODE", "PERSONA_TONE", "PERSONA_VERBOSITY", "PERSONA_HUMOR", "PERSONA_LANGUAGE", "PERSONA_MOOD"}:
|
if key in {"AGENT_SKILL", "PERSONA_TONE", "PERSONA_VERBOSITY", "PERSONA_HUMOR", "PERSONA_LANGUAGE", "PERSONA_MOOD"}:
|
||||||
value = value.lower() or fallback
|
value = value.lower() or fallback
|
||||||
if key == "PERSONA_NAME" and not value:
|
if key == "PERSONA_NAME" and not value:
|
||||||
value = fallback
|
value = fallback
|
||||||
|
|||||||
31
config.yaml
31
config.yaml
@ -1,27 +1,26 @@
|
|||||||
# Agent behavior
|
|
||||||
agent:
|
agent:
|
||||||
max_iterations: 30
|
max_iterations: 40
|
||||||
max_tool_output: 40000
|
max_tool_output: 40000
|
||||||
|
|
||||||
# Character & Skills
|
persona:
|
||||||
character:
|
skill: programmer # Default skill: programmer, roleplayer, analyst
|
||||||
preset: hendrik # nama directory di agent/characters/<preset>/
|
|
||||||
skills: "" # comma-separated, e.g. "programmer,analyst"
|
character:
|
||||||
|
preset: hendrik # Directory name in agent/characters/<preset>/
|
||||||
|
skills: programmer # comma-separated, e.g. "programmer,analyst"
|
||||||
|
|
||||||
# XMPP
|
|
||||||
xmpp:
|
xmpp:
|
||||||
enabled: false
|
enabled: false
|
||||||
muc_rooms: "" # comma-separated, e.g. "room1@conference.server,room2@conference.server"
|
muc_rooms: "" # comma-separated, e.g. "room1@conference.server,room2@conference.server"
|
||||||
nickname: "" # custom nick MUC (kosong = pakai username)
|
nickname: "" # custom MUC nickname (empty = use username)
|
||||||
selective_response: true # true = hanya respon kalau ada mention/relevansi
|
selective_response: true # true = only response if mentioned/relevant
|
||||||
|
|
||||||
# Humanize Delay (anti-bot detection)
|
# Humanize Delay (anti-bot detection)
|
||||||
delay:
|
delay:
|
||||||
read_min: 1.0 # min reading delay (detik)
|
read_min: 1.0 # per second
|
||||||
read_max: 2.0 # max reading delay (detik)
|
read_max: 2.0 # per second
|
||||||
typing_speed: 15.0 # characters per second
|
typing_speed: 15.0 # characters per second
|
||||||
typing_max: 10.0 # max typing delay limit (detik)
|
typing_max: 10.0 # max typing delay limit per second
|
||||||
|
|
||||||
# RAG
|
|
||||||
rag:
|
rag:
|
||||||
persist_dir: chroma_db # ChromaDB ONNX default (all-MiniLM-L6-v2, lokal)
|
persist_dir: chroma_db # ChromaDB ONNX default (all-MiniLM-L6-v2, local)
|
||||||
|
|||||||
@ -6,7 +6,7 @@ from services.xmpp_client import XMPPClient
|
|||||||
from scripts.llm_client import LLMClient
|
from scripts.llm_client import LLMClient
|
||||||
from tools import coder, rag, carrack
|
from tools import coder, rag, carrack
|
||||||
from scripts import gadget
|
from scripts import gadget
|
||||||
from scripts.persona import build_system_prompt, PERSONALITY, MODE
|
from scripts.persona import build_system_prompt
|
||||||
|
|
||||||
tools_definition = [
|
tools_definition = [
|
||||||
|
|
||||||
|
|||||||
@ -1,11 +1,49 @@
|
|||||||
import json
|
import json
|
||||||
|
import re
|
||||||
import urllib.request
|
import urllib.request
|
||||||
import urllib.error
|
import urllib.error
|
||||||
|
|
||||||
|
|
||||||
|
def _strip_thinking(text: str) -> str:
|
||||||
|
"""
|
||||||
|
Hapus semua bentuk thinking/reasoning dari response text.
|
||||||
|
Handles:
|
||||||
|
- <think>...</think> blocks (any case)
|
||||||
|
- <reasoning>...</reasoning> blocks
|
||||||
|
- "Thinking:" / "Reasoning:" inline prefixes
|
||||||
|
"""
|
||||||
|
if not text:
|
||||||
|
return text
|
||||||
|
|
||||||
|
# Strip XML-style thinking blocks (case-insensitive, DOTALL for multiline)
|
||||||
|
text = re.sub(r'<think[^>]*>.*?</think>', '', text, flags=re.DOTALL | re.IGNORECASE)
|
||||||
|
text = re.sub(r'<reasoning[^>]*>.*?</reasoning>', '', text, flags=re.DOTALL | re.IGNORECASE)
|
||||||
|
|
||||||
|
# Strip lines starting with Thinking: / Reasoning: / Let me think...
|
||||||
|
lines = text.splitlines()
|
||||||
|
cleaned = []
|
||||||
|
skip_block = False
|
||||||
|
for line in lines:
|
||||||
|
stripped = line.strip().lower()
|
||||||
|
if stripped.startswith(('thinking:', 'reasoning:', 'let me thought', 'let me think')):
|
||||||
|
skip_block = True
|
||||||
|
continue
|
||||||
|
if skip_block and not stripped:
|
||||||
|
skip_block = False
|
||||||
|
continue
|
||||||
|
if not skip_block:
|
||||||
|
cleaned.append(line)
|
||||||
|
|
||||||
|
result = '\n'.join(cleaned).strip()
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
class LLMClient:
|
class LLMClient:
|
||||||
class Message:
|
class Message:
|
||||||
def __init__(self, msg):
|
def __init__(self, msg):
|
||||||
self.content = msg.get('content', '')
|
raw_content = msg.get('content', '')
|
||||||
|
# Auto-strip thinking dari content
|
||||||
|
self.content = _strip_thinking(raw_content) if isinstance(raw_content, str) else raw_content
|
||||||
self.tool_calls = msg.get('tool_calls', None)
|
self.tool_calls = msg.get('tool_calls', None)
|
||||||
self.warning = None
|
self.warning = None
|
||||||
|
|
||||||
@ -25,6 +63,10 @@ class LLMClient:
|
|||||||
payload["tools"] = tools
|
payload["tools"] = tools
|
||||||
payload["tool_choice"] = "auto"
|
payload["tool_choice"] = "auto"
|
||||||
|
|
||||||
|
# Disable reasoning/thinking di level API bila didukung
|
||||||
|
# OpenRouter & beberapa provider support ini
|
||||||
|
payload["reasoning"] = {"enabled": False}
|
||||||
|
|
||||||
data = json.dumps(payload).encode('utf-8')
|
data = json.dumps(payload).encode('utf-8')
|
||||||
req = urllib.request.Request(url, data=data, method='POST')
|
req = urllib.request.Request(url, data=data, method='POST')
|
||||||
req.add_header('Content-Type', 'application/json')
|
req.add_header('Content-Type', 'application/json')
|
||||||
@ -89,4 +131,12 @@ class LLMClient:
|
|||||||
})
|
})
|
||||||
|
|
||||||
message = response['choices'][0]['message']
|
message = response['choices'][0]['message']
|
||||||
|
|
||||||
|
# Handle reasoning_content field dari OpenRouter/models yang support thinking
|
||||||
|
# Pindahkan ke content jangan sampai keluar
|
||||||
|
reasoning_content = message.pop('reasoning_content', None)
|
||||||
|
reasoning_field = message.pop('reasoning', None)
|
||||||
|
# Jangan inject reasoning ke content — buang saja
|
||||||
|
# (kita sudah strip via _strip_thinking di Message.__init__)
|
||||||
|
|
||||||
return self.Message(message)
|
return self.Message(message)
|
||||||
|
|||||||
@ -15,6 +15,8 @@ import re
|
|||||||
from dataclasses import dataclass, field
|
from dataclasses import dataclass, field
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
|
import yaml
|
||||||
|
|
||||||
|
|
||||||
# ─── Paths ────────────────────────────────────────────────────────────────────
|
# ─── Paths ────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
@ -26,7 +28,7 @@ SKILLS_DIR = BASE_DIR / "skills"
|
|||||||
|
|
||||||
# ─── Mode / Skill ──────────────────────────────────────────────────────────────
|
# ─── Mode / Skill ──────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
MODE = os.getenv("PERSONA_MODE", default="programmer").strip().lower()
|
SKILL = os.getenv("AGENT_SKILL", default="programmer").strip().lower()
|
||||||
|
|
||||||
|
|
||||||
# ─── Personality Configuration ────────────────────────────────────────────────
|
# ─── Personality Configuration ────────────────────────────────────────────────
|
||||||
@ -228,46 +230,82 @@ def _load_skills(skill_names: list[str]) -> str:
|
|||||||
|
|
||||||
def build_system_prompt(
|
def build_system_prompt(
|
||||||
tools_definition: list[dict] | None = None,
|
tools_definition: list[dict] | None = None,
|
||||||
mode: str | None = None,
|
skill: str | None = None,
|
||||||
personality: PersonalityConfig | None = None,
|
personality: PersonalityConfig | None = None,
|
||||||
character: str | None = None,
|
character: str | None = None,
|
||||||
skills: list[str] | None = None,
|
skills: list[str] | None = None,
|
||||||
) -> str:
|
) -> str:
|
||||||
"""
|
"""
|
||||||
Build system prompt berdasarkan mode, character, dan skills.
|
Build system prompt berdasarkan skill, character, dan skills.
|
||||||
|
|
||||||
Load order:
|
Load order:
|
||||||
1. Base prompt
|
1. Base prompt
|
||||||
2. Personality block (dari config)
|
2. Personality block (dari config / persona.yaml character)
|
||||||
3. Policies (dari env-characters/<name>/policies.md)
|
3. Policies (dari agent/characters/<name>/policies.md)
|
||||||
4. Skill instructions (dari skills/<name>/instructions.md)
|
4. Skill instructions (dari skills/<name>/instructions.md)
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
tools_definition: Daftar tools (required untuk skill programmer).
|
tools_definition: Daftar tools (required untuk skill programmer).
|
||||||
mode: "programmer" atau "roleplayer". Default: dari env PERSONA_MODE.
|
skill: "programmer" atau "roleplayer". Default: dari env AGENT_SKILL.
|
||||||
personality: PersonalityConfig instance. Default: global PERSONALITY.
|
personality: PersonalityConfig instance. Default: global PERSONALITY.
|
||||||
character: Nama env character. Default: dari env AGENT_CHARACTER.
|
character: Nama env character. Default: dari env AGENT_CHARACTER.
|
||||||
skills: List nama skill aktif. Default: derives from mode atau env AGENT_SKILLS.
|
skills: List nama skill aktif. Default: derives dari env AGENT_SKILLS.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
String system prompt lengkap.
|
String system prompt lengkap.
|
||||||
"""
|
"""
|
||||||
selected_mode = (mode or MODE).strip().lower()
|
selected_skill = (skill or SKILL).strip().lower()
|
||||||
cfg = personality or PERSONALITY
|
cfg = personality or PERSONALITY
|
||||||
|
|
||||||
# Resolve character name
|
# Resolve character name
|
||||||
character_name = (character or os.getenv("AGENT_CHARACTER", default="")).strip().lower()
|
character_name = (character or os.getenv("AGENT_CHARACTER", default="")).strip().lower()
|
||||||
|
|
||||||
|
# ── Load persona.yaml dari character directory (override personality) ─────────
|
||||||
|
if character_name:
|
||||||
|
char_dir = ENV_CHARACTERS_DIR / character_name
|
||||||
|
persona_yaml_path = char_dir / "persona.yaml"
|
||||||
|
if persona_yaml_path.is_file():
|
||||||
|
try:
|
||||||
|
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"):
|
||||||
|
cfg.age = str(_persona_data["age"])
|
||||||
|
if _persona_data.get("gender"):
|
||||||
|
cfg.gender = _persona_data["gender"]
|
||||||
|
if _persona_data.get("tone"):
|
||||||
|
cfg.tone = _persona_data["tone"]
|
||||||
|
if _persona_data.get("verbosity"):
|
||||||
|
cfg.verbosity = _persona_data["verbosity"]
|
||||||
|
if _persona_data.get("humor"):
|
||||||
|
cfg.humor_level = _persona_data["humor"]
|
||||||
|
if _persona_data.get("language"):
|
||||||
|
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_from_yaml = _persona_data.get("skill") or _persona_data.get("mode")
|
||||||
|
if _skill_from_yaml:
|
||||||
|
selected_skill = _skill_from_yaml.strip().lower()
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[persona] Warning: gagal load persona.yaml untuk '{character_name}': {e}")
|
||||||
|
|
||||||
# Resolve skills list
|
# Resolve skills list
|
||||||
if skills is None:
|
# Priority: explicit skills param > persona.yaml skill > AGENT_SKILL env > AGENT_SKILLS env > selected_skill
|
||||||
|
if skills is not None:
|
||||||
|
skills_list = skills
|
||||||
|
elif selected_skill != SKILL:
|
||||||
|
# persona.yaml meng-override skill → pakai skill dari persona.yaml
|
||||||
|
skills_list = [selected_skill] if selected_skill in ("programmer", "roleplayer", "analyst") else []
|
||||||
|
else:
|
||||||
skills_env = os.getenv("AGENT_SKILLS", default="").strip()
|
skills_env = os.getenv("AGENT_SKILLS", default="").strip()
|
||||||
if skills_env:
|
if skills_env:
|
||||||
skills_list = [s.strip() for s in skills_env.split(",") if s.strip()]
|
skills_list = [s.strip() for s in skills_env.split(",") if s.strip()]
|
||||||
else:
|
else:
|
||||||
# Derive from mode untuk backward compatibility
|
skills_list = [selected_skill] if selected_skill in ("programmer", "roleplayer", "analyst") else []
|
||||||
skills_list = [selected_mode] if selected_mode in ("programmer", "roleplayer") else []
|
|
||||||
else:
|
|
||||||
skills_list = skills
|
|
||||||
|
|
||||||
# ── 1. Base prompt ──────────────────────────────────────────────────────────
|
# ── 1. Base prompt ──────────────────────────────────────────────────────────
|
||||||
base_prompt = ""
|
base_prompt = ""
|
||||||
|
|||||||
@ -9,7 +9,6 @@ from slixmpp import ClientXMPP
|
|||||||
from services.session_manager import SessionManager
|
from services.session_manager import SessionManager
|
||||||
|
|
||||||
import config
|
import config
|
||||||
from scripts.persona import MODE as PERSONA_MODE
|
|
||||||
from tools.roleplayer import should_respond
|
from tools.roleplayer import should_respond
|
||||||
from scripts.persona import PERSONALITY
|
from scripts.persona import PERSONALITY
|
||||||
|
|
||||||
@ -50,7 +49,7 @@ class XMPPClient(ClientXMPP):
|
|||||||
self._TOOL_HANDLERS = TOOL_HANDLERS
|
self._TOOL_HANDLERS = TOOL_HANDLERS
|
||||||
self._build_system_prompt = build_system_prompt
|
self._build_system_prompt = build_system_prompt
|
||||||
self._max_iterations = agent_max_iterations
|
self._max_iterations = agent_max_iterations
|
||||||
self._mode = PERSONA_MODE
|
self._skill = config.AGENT_SKILL
|
||||||
self._muc_rooms = muc_rooms or []
|
self._muc_rooms = muc_rooms or []
|
||||||
# Custom nick dari config, fallback ke username JID
|
# Custom nick dari config, fallback ke username JID
|
||||||
self._muc_nick = config.XMPP_NICKNAME.strip() or jid.split('@')[0]
|
self._muc_nick = config.XMPP_NICKNAME.strip() or jid.split('@')[0]
|
||||||
@ -299,7 +298,8 @@ class XMPPClient(ClientXMPP):
|
|||||||
|
|
||||||
session.add_message('user', body)
|
session.add_message('user', body)
|
||||||
|
|
||||||
if self._mode != 'roleplayer':
|
is_roleplay = self._skill == 'roleplayer'
|
||||||
|
if not is_roleplay:
|
||||||
self._schedule_send(jid, f'> {body}\nThinking...')
|
self._schedule_send(jid, f'> {body}\nThinking...')
|
||||||
|
|
||||||
# Delay 1: simulasi membaca pesan user
|
# Delay 1: simulasi membaca pesan user
|
||||||
@ -329,7 +329,7 @@ class XMPPClient(ClientXMPP):
|
|||||||
prefixed = f'[{nick}] {body}'
|
prefixed = f'[{nick}] {body}'
|
||||||
session.add_message('user', prefixed)
|
session.add_message('user', prefixed)
|
||||||
|
|
||||||
if self._mode != 'roleplayer':
|
if self._skill != 'roleplayer':
|
||||||
self._schedule_send(room, f'> [{nick}] {body}\nThinking...', mtype='groupchat')
|
self._schedule_send(room, f'> [{nick}] {body}\nThinking...', mtype='groupchat')
|
||||||
|
|
||||||
# Delay 1: simulasi membaca pesan user
|
# Delay 1: simulasi membaca pesan user
|
||||||
@ -341,7 +341,7 @@ class XMPPClient(ClientXMPP):
|
|||||||
session.start_timer(300, self._timeout_session, room, 'groupchat')
|
session.start_timer(300, self._timeout_session, room, 'groupchat')
|
||||||
|
|
||||||
def _agent_loop(self, session, to, quote, mtype, sender_nickname=""):
|
def _agent_loop(self, session, to, quote, mtype, sender_nickname=""):
|
||||||
is_roleplayer = self._mode == 'roleplayer'
|
is_roleplayer = self._skill == 'roleplayer'
|
||||||
my_name = PERSONALITY.name
|
my_name = PERSONALITY.name
|
||||||
|
|
||||||
for step in range(self._max_iterations):
|
for step in range(self._max_iterations):
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user