agentforge-multi 0.1.4 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/agentforge +66 -0
- package/package.json +1 -1
package/agentforge
CHANGED
|
@@ -689,6 +689,56 @@ def render_evaluator_panel(eval_history: list, iteration: int,
|
|
|
689
689
|
)
|
|
690
690
|
|
|
691
691
|
|
|
692
|
+
# ── tmux 자동 래핑 ────────────────────────────────────────────────────────────
|
|
693
|
+
|
|
694
|
+
import shlex as _shlex
|
|
695
|
+
import shutil as _shutil
|
|
696
|
+
|
|
697
|
+
TMUX_SESSION = "agentforge"
|
|
698
|
+
|
|
699
|
+
|
|
700
|
+
def _in_tmux() -> bool:
|
|
701
|
+
return bool(os.environ.get("TMUX"))
|
|
702
|
+
|
|
703
|
+
|
|
704
|
+
def _tmux_session_exists() -> bool:
|
|
705
|
+
r = subprocess.run(["tmux", "has-session", "-t", TMUX_SESSION],
|
|
706
|
+
capture_output=True)
|
|
707
|
+
return r.returncode == 0
|
|
708
|
+
|
|
709
|
+
|
|
710
|
+
def _tmux_launch(extra_args: list):
|
|
711
|
+
"""현재 프로세스를 tmux 세션 안의 agentforge로 교체."""
|
|
712
|
+
if _tmux_session_exists():
|
|
713
|
+
console.print(
|
|
714
|
+
f"[yellow]이미 실행 중인 agentforge 세션이 있습니다.[/yellow]\n"
|
|
715
|
+
f" 재접속: [cyan]agentforge -r[/cyan]\n"
|
|
716
|
+
f" 새 세션: [cyan]agentforge --new-session[/cyan]"
|
|
717
|
+
)
|
|
718
|
+
sys.exit(0)
|
|
719
|
+
|
|
720
|
+
exe = _shutil.which("agentforge") or os.path.abspath(sys.argv[0])
|
|
721
|
+
cmd_str = " ".join(_shlex.quote(p) for p in [exe] + extra_args)
|
|
722
|
+
try:
|
|
723
|
+
os.execvp("tmux", ["tmux", "new-session", "-s", TMUX_SESSION, cmd_str])
|
|
724
|
+
except OSError:
|
|
725
|
+
pass # tmux 실행 실패 → 그냥 일반 모드로 계속
|
|
726
|
+
|
|
727
|
+
|
|
728
|
+
def _tmux_reconnect():
|
|
729
|
+
"""기존 agentforge tmux 세션에 재접속."""
|
|
730
|
+
if not _shutil.which("tmux"):
|
|
731
|
+
console.print("[red]tmux가 설치되지 않았습니다.[/red]")
|
|
732
|
+
sys.exit(1)
|
|
733
|
+
if not _tmux_session_exists():
|
|
734
|
+
console.print(
|
|
735
|
+
"[yellow]실행 중인 agentforge 세션이 없습니다.[/yellow]\n"
|
|
736
|
+
"새 세션 시작: [cyan]agentforge[/cyan]"
|
|
737
|
+
)
|
|
738
|
+
sys.exit(1)
|
|
739
|
+
os.execvp("tmux", ["tmux", "attach-session", "-t", TMUX_SESSION])
|
|
740
|
+
|
|
741
|
+
|
|
692
742
|
# ── Agent Loop ────────────────────────────────────────────────────────────────
|
|
693
743
|
|
|
694
744
|
def run_agent_loop(goal: str, workdir: str, worker_model: str | None,
|
|
@@ -865,6 +915,22 @@ def _handle_interrupt(goal: str, workdir: str, args, max_iter: int) -> str:
|
|
|
865
915
|
# ── Main ──────────────────────────────────────────────────────────────────────
|
|
866
916
|
|
|
867
917
|
def main():
|
|
918
|
+
# ── tmux 자동 래핑 ─────────────────────────────────────────────────
|
|
919
|
+
# -r / --reconnect: 기존 세션 재접속
|
|
920
|
+
if len(sys.argv) >= 2 and sys.argv[1] in ("-r", "--reconnect"):
|
|
921
|
+
_tmux_reconnect()
|
|
922
|
+
return
|
|
923
|
+
|
|
924
|
+
# --new-session: 기존 세션 무시하고 강제로 새 세션
|
|
925
|
+
force_new = len(sys.argv) >= 2 and sys.argv[1] == "--new-session"
|
|
926
|
+
extra_args = [a for a in sys.argv[1:] if a != "--new-session"]
|
|
927
|
+
|
|
928
|
+
if not _in_tmux() and _shutil.which("tmux"):
|
|
929
|
+
if force_new and _tmux_session_exists():
|
|
930
|
+
subprocess.run(["tmux", "kill-session", "-t", TMUX_SESSION])
|
|
931
|
+
_tmux_launch(extra_args)
|
|
932
|
+
# execvp 실패 또는 세션 이미 존재 시 여기까지 옴 → 일반 모드로 계속
|
|
933
|
+
|
|
868
934
|
parser = argparse.ArgumentParser(
|
|
869
935
|
prog="agentforge",
|
|
870
936
|
description="Worker + Evaluator 인터랙티브 멀티에이전트 CLI",
|