Compare commits

..

No commits in common. "558d6020c5a98959ba3f878a9821f630a1eaf5e1" and "b6cecd686d3985a8f7df5ab13cab8c943d32b8da" have entirely different histories.

7 changed files with 13 additions and 46 deletions

View File

@ -1,4 +1,4 @@
import os, sys, threading, time, signal
import os, sys, argparse, threading, time, signal
import config
@ -11,8 +11,6 @@ from services.telegram_client import TelegramClient
from interfaces.tui import HendrikTUI
from modules import argsparser
tools_definition = [
# Coder Tools
gadget.tools_mapping( schema = coder.schema_read_file, handler = coder.read_file ),
@ -73,12 +71,16 @@ TOOLS = gadget.tool_schemas (tools_definition)
TOOL_HANDLERS = gadget.tool_handlers (tools_definition)
def main():
parser = argparse.ArgumentParser(description="Hendrik AI Agent")
parser.add_argument('--char', type=str, default=None, help='Character name (overrides config.yaml)')
parser.add_argument('-w', '--workspace', type=str, default=None, help='Working directory')
parser.add_argument('--tui', action='store_true', help='Force run in TUI mode')
parser.add_argument('--service', action='store_true', help='Force run in service mode')
args = parser.parse_args()
args = argsparser.args
# Override char configuration from args
if args.char:
config.load_service_config(char_override=args.char)
# Set workspace from args
if args.workspace:
resolved = os.path.abspath(args.workspace)
if not os.path.isdir(resolved):
@ -86,10 +88,7 @@ def main():
sys.exit(1)
coder.set_current_workspace(resolved)
# Inference
llm_client = LLMClient("", "", "", config.llm_timeout)
# Pesan saat opsi model belum dipilih
if not moop.configure_client(llm_client):
if config.XMPP_ENABLED or config.TELEGRAM_ENABLED:
print(
@ -146,7 +145,8 @@ def main():
return
if args.service:
pass # Ya kocak sih, pakai --service dan ga pake --service jalannya ya sama-sama aja.
# Force service mode by ensuring services list is populated if any are enabled in config
pass # Fall through to the services logic below
if services:
threads = []

View File

@ -100,8 +100,7 @@ def _agent_loop(app):
for step in range(app.agent_max_iterations):
stamp_step = ntro.start()
log(app, "system", f" step {step + 1} \u2014 Thinking...")
if app.scroll_follow:
app.scroll = 999999
app.scroll = 999999
# Streaming response
stream_buffer = []
@ -122,8 +121,7 @@ def _agent_loop(app):
if app.log[i].get('role') == 'ai' and (app.log[i].get('text') == placeholder_marker or (i > 0 and app.log[i-1].get('role') == 'system' and 'Thinking' in app.log[i-1].get('text', ''))):
app.log[i]['text'] = current_text
break
if app.scroll_follow:
app.scroll = 999999
app.scroll = 999999
skill = config.AGENT_SKILLS
tool_reminder = None
@ -191,8 +189,7 @@ def _agent_loop(app):
"name": tname,
"arguments": targs,
}))
if app.scroll_follow:
app.scroll = 999999
app.scroll = 999999
result = agent_loop.execute_tool(tc, app.TOOL_HANDLERS)
if isinstance(result, ImagePayload):
_add_msg(app, "tool", [

View File

@ -34,7 +34,6 @@ class HendrikTUI:
self.input_line = 0
self.input_col = 0
self.scroll = 0
self.scroll_follow = True # follow bottom saat streaming, mati kalau user scroll up
self.processing = False
self.running = True
self.h, self.w = 0, 0

View File

@ -49,10 +49,8 @@ def handle_key(app, stdscr, key):
# -- Scroll & resize --
if key == curses.KEY_PPAGE:
app.scroll = max(0, app.scroll - (app.h - 10) // 2)
app.scroll_follow = False
elif key == curses.KEY_NPAGE:
app.scroll += (app.h - 10) // 2
app.scroll_follow = True
elif key == curses.KEY_RESIZE:
pass

View File

@ -94,16 +94,6 @@ _CSI_NAV = {
"5~": KEY_PPAGE, "6~": KEY_NPAGE,
}
# Versi numerik (kitty CSI-u / tilde dengan modifier eksplisit):
# \x1b[2~ / \x1b[2;1~ / \x1b[2u / \x1b[2;1u → INSERT, dst.
# Ini bentuk yang dikirim terminal ketika keyboard protocol (kitty/xterm
# modifyOtherKeys) aktif, yang sebelumnya jatuh jadi KEY_ESC.
_CSI_NAV_NUM = {
2: KEY_INSERT, 3: KEY_DC,
5: KEY_PPAGE, 6: KEY_NPAGE,
7: KEY_HOME, 8: KEY_END,
}
# F1-F4 bentuk huruf (kitty protocol aktif): CSI P/Q/S = F1/F2/F4.
# F3 (huruf R) dihapus dari spec (bentrok Cursor Position Report) → pakai [13~.
_CSI_LETTER_F = {
@ -183,11 +173,6 @@ def _map_modified_key(code: int, mod, terminator: str) -> int | None:
return _CSI_F_KEYS["13"] # F3
return 13
# Navigasi numerik (Insert/Delete/PageUp/PageDown/Home/End) — terlepas
# dari terminator (u/~) dan modifier yang menyertainya.
if code in _CSI_NAV_NUM:
return _CSI_NAV_NUM[code]
# F1-F12 dengan/tanpa modifier
if str(code) in _CSI_F_KEYS:
return _CSI_F_KEYS[str(code)]

View File

@ -214,10 +214,6 @@ def draw_chat(app, stdscr):
if app.scroll > max_scroll:
app.scroll = max_scroll
app.scroll = max(0, app.scroll)
# Kalau sudah mentok di bawah, kembalikan auto-follow (streaming akan
# menempel di bottom lagi; PgUp keluar dari mode follow).
if app.scroll >= max_scroll:
app.scroll_follow = True
# Gambar baris yang terlihat (scroll sampai scroll + chat_h)
# Clear area chat dulu biar nggak ada text lama yang nyisa

View File

@ -1,8 +0,0 @@
import argparse
parser = argparse.ArgumentParser(description="Hendrik AI Agent")
parser.add_argument('--char', type=str, default=None, help='Character name (overrides config.yaml)')
parser.add_argument('-w', '--workspace', type=str, default=None, help='Working directory')
parser.add_argument('--tui', action='store_true', help='Force run in TUI mode')
parser.add_argument('--service', action='store_true', help='Force run in service mode')
args = parser.parse_args()