Files
jarvis/jarvis/llm/gemini_cli.py
T

76 lines
2.7 KiB
Python

from .base import LLMEngine
import subprocess, os, logging, re, tempfile
log = logging.getLogger(__name__)
class GeminiCLILLM(LLMEngine):
def __init__(self, yolo=True, workspace_dir="data", system_file="data/soul.md"):
self.yolo = yolo
self.workspace_dir = workspace_dir
self.system_file = system_file
self.session_id = None
def _read_system(self):
try:
if os.path.exists(self.system_file):
with open(self.system_file) as f:
return f.read()
except Exception as e:
log.warning(f"No system file: {e}")
return ""
def chat(self, messages, speaker=None):
system = ""
user_prompt = ""
for m in messages:
if m["role"] == "system":
system += m["content"] + "\n"
elif m["role"] == "user":
user_prompt += f"User: {m['content']}\n"
elif m["role"] == "assistant":
user_prompt += f"Assistant: {m['content']}\n"
if speaker and speaker.get("name") != "unknown":
user_prompt = f"[Speaker: {speaker.get('name')} conf {speaker.get('fused_conf',0):.2f}]\n" + user_prompt
soul = self._read_system()
full_system = (soul + "\n" + system).strip() if soul else system
env = os.environ.copy()
tmp_sys = None
if full_system:
fd, tmp_path = tempfile.mkstemp(suffix=".md")
os.write(fd, full_system.encode())
os.close(fd)
tmp_sys = tmp_path
env["GEMINI_SYSTEM_MD"] = tmp_sys
args = ["gemini", "--prompt", user_prompt]
if self.yolo:
args.append("--yolo")
if self.session_id:
args.extend(["--resume", self.session_id])
try:
os.makedirs(self.workspace_dir, exist_ok=True)
proc = subprocess.run(args, capture_output=True, text=True, cwd=self.workspace_dir, env=env, timeout=120)
out = proc.stdout.strip() or proc.stderr.strip()
if not self.session_id:
try:
res = subprocess.run(["gemini","--list-sessions"], capture_output=True, text=True, cwd=self.workspace_dir, timeout=10)
matches = re.findall(r"\[([a-f0-9\-]+)\]", res.stdout)
if matches:
self.session_id = matches[-1]
except:
pass
return out or "No response from Gemini"
except Exception as e:
log.error(f"Gemini CLI error: {e}")
return f"Gemini error: {e}"
finally:
if tmp_sys and os.path.exists(tmp_sys):
try:
os.remove(tmp_sys)
except:
pass