diff --git a/cron/scheduler.py b/cron/scheduler.py index 44689d8d0..b2b18824e 100644 --- a/cron/scheduler.py +++ b/cron/scheduler.py @@ -1244,10 +1244,11 @@ def _run_via_claude_subprocess( "TZ": os.environ.get("TZ", "Asia/Seoul"), } - logger.info("Job '%s': running via claude -p subprocess (subscription)", job_id) + _model = os.environ.get("HERMES_CLAUDE_SUB_MODEL", "claude-opus-4-8").strip() or "claude-opus-4-8" + logger.info("Job '%s': running via claude -p subprocess (subscription) model=%s", job_id, _model) try: result = subprocess.run( - [claude_bin, "-p", prompt], + [claude_bin, "-p", "--model", _model, prompt], capture_output=True, text=True, env=env, diff --git a/gateway/run.py b/gateway/run.py index f0c7190a0..23d979056 100644 --- a/gateway/run.py +++ b/gateway/run.py @@ -17829,23 +17829,29 @@ def _interim_assistant_cb(text: str, *, already_streamed: bool = False) -> None: ): import subprocess as _subprocess import shutil as _shutil + import uuid as _uuid _claude_bin = _shutil.which("claude") if _claude_bin: - _hist_lines = [] - for _h in (history or []): - _role = str(_h.get("role") or "") - _content = _h.get("content") or "" - if isinstance(_content, list): - _content = " ".join( - c.get("text", "") if isinstance(c, dict) else str(c) - for c in _content - ).strip() - if _role and _content: - _hist_lines.append(f"{_role.capitalize()}: {_content}") - _full_prompt = ( - "[Previous conversation:\n" + "\n".join(_hist_lines) + "\n]\n\nUser: " + message - if _hist_lines else message - ) + # --- session-id mapping: gateway session_key → claude session uuid --- + _session_map_path = Path.home() / ".claude-hermes" / "gateway_session_map.json" + _session_map: dict = {} + try: + if _session_map_path.exists(): + _session_map = json.loads(_session_map_path.read_text()) + except Exception: + _session_map = {} + _existing_session_id = _session_map.get(session_key or "") + _is_new_session = not _existing_session_id + if _is_new_session: + _claude_session_id = str(_uuid.uuid4()) + _session_map[session_key or ""] = _claude_session_id + try: + _session_map_path.write_text(json.dumps(_session_map, ensure_ascii=False)) + except Exception: + pass + else: + _claude_session_id = _existing_session_id + # --- build subprocess command --- _sub_env = { "PATH": os.environ.get("PATH", ""), "HOME": os.environ.get("HOME", ""), @@ -17858,9 +17864,12 @@ def _interim_assistant_cb(text: str, *, already_streamed: bool = False) -> None: } _sub_timeout = float(os.getenv("HERMES_CRON_TIMEOUT", "600") or "600") _sub_model = str(turn_route.get("model") or "").strip() - _sub_cmd = [_claude_bin, "-p", _full_prompt] + # new session → --session-id to create; existing → --resume to continue + _session_flag = "--session-id" if _is_new_session else "--resume" + _sub_cmd = [_claude_bin, "-p", _session_flag, _claude_session_id] if _sub_model and _sub_model.startswith("claude"): - _sub_cmd = [_claude_bin, "-p", "--model", _sub_model, _full_prompt] + _sub_cmd += ["--model", _sub_model] + _sub_cmd.append(message) try: _sub_result = _subprocess.run( _sub_cmd,