diff --git a/services/agent_loop.py b/scripts/agent_loop.py
similarity index 99%
rename from services/agent_loop.py
rename to scripts/agent_loop.py
index 5af5b19..cdbef1a 100644
--- a/services/agent_loop.py
+++ b/scripts/agent_loop.py
@@ -1,11 +1,9 @@
import json
from datetime import datetime
-
def _ts():
return datetime.now().strftime('%H:%M:%S')
-
def execute_tool(tool_call, TOOL_HANDLERS):
tname = tool_call['function']['name']
targs = json.loads(tool_call['function']['arguments'])
@@ -26,7 +24,6 @@ def execute_tool(tool_call, TOOL_HANDLERS):
except Exception as e:
return f'Error executing tool: {str(e)}'
-
def run_agent_loop(session, llm_client, TOOLS, TOOL_HANDLERS, max_iterations, on_tool_calls=None):
for step in range(max_iterations):
print(f'[{_ts()}] Step {step + 1} — calling LLM...', flush=True)
@@ -66,3 +63,4 @@ def run_agent_loop(session, llm_client, TOOLS, TOOL_HANDLERS, max_iterations, on
'content': 'Max iterations reached without final answer.',
})
return None
+
diff --git a/scripts/gadget.py b/scripts/gadget.py
index 81d3766..d2d00dc 100644
--- a/scripts/gadget.py
+++ b/scripts/gadget.py
@@ -1,4 +1,4 @@
-from .personality import build_system_prompt
+import re
def tools_mapping(schema, handler, name=None):
tool_name = name or schema["function"]["name"]
@@ -10,3 +10,25 @@ def tool_schemas(tools_definition):
def tool_handlers(tools_definition):
return {t["name"]: t["handler"] for t in tools_definition}
+def strip_thinking(text: str) -> str:
+ if not text:
+ return text
+ # Strip XML-style thinking blocks (case-insensitive, DOTALL for multiline)
+ text = re.sub(r']*>.*?', '', text, flags=re.DOTALL | re.IGNORECASE)
+ text = re.sub(r']*>.*?', '', 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
diff --git a/scripts/llm_client.py b/services/llm_client.py
similarity index 87%
rename from scripts/llm_client.py
rename to services/llm_client.py
index fc3a2ee..c32ec01 100644
--- a/scripts/llm_client.py
+++ b/services/llm_client.py
@@ -1,49 +1,14 @@
import json
-import re
+from scripts import gadget
import urllib.request
import urllib.error
-
-def _strip_thinking(text: str) -> str:
- """
- Hapus semua bentuk thinking/reasoning dari response text.
- Handles:
- - ... blocks (any case)
- - ... blocks
- - "Thinking:" / "Reasoning:" inline prefixes
- """
- if not text:
- return text
-
- # Strip XML-style thinking blocks (case-insensitive, DOTALL for multiline)
- text = re.sub(r']*>.*?', '', text, flags=re.DOTALL | re.IGNORECASE)
- text = re.sub(r']*>.*?', '', 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 Message:
def __init__(self, msg):
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.content = gadget.strip_thinking(raw_content) if isinstance(raw_content, str) else raw_content
self.tool_calls = msg.get('tool_calls', None)
self.warning = None
diff --git a/services/telegram_client.py b/services/telegram_client.py
index 40beaef..6564b2a 100644
--- a/services/telegram_client.py
+++ b/services/telegram_client.py
@@ -7,7 +7,7 @@ from datetime import datetime
import config
from services.session_manager import SessionManager
-from services.agent_loop import run_agent_loop
+from scripts.agent_loop import run_agent_loop
from scripts.personality import PERSONALITY
from tools.roleplayer import _name_mentioned
diff --git a/services/xmpp_client.py b/services/xmpp_client.py
index 0505f44..7e0be81 100644
--- a/services/xmpp_client.py
+++ b/services/xmpp_client.py
@@ -6,7 +6,7 @@ from datetime import datetime
from slixmpp import ClientXMPP
from services.session_manager import SessionManager
-from services.agent_loop import run_agent_loop
+from scripts.agent_loop import run_agent_loop
import config
from tools.roleplayer import should_respond
@@ -436,7 +436,7 @@ class XMPPClient(ClientXMPP):
session.start_timer(300, self._timeout_session, room, 'groupchat')
def _execute_tool(self, tool_call):
- from services.agent_loop import execute_tool
+ from scripts.agent_loop import execute_tool
return execute_tool(tool_call, self._TOOL_HANDLERS)
def _schedule_send(self, to, body, mtype='chat'):