#!/usr/bin/env python3 """Py Agent [v0.9.9.64] - Main CLI Runtime, Workspace Agent & Command Dispatcher [CR.01 CO.01]""" import json import os import re import shutil import sqlite3 import subprocess import sys import tempfile import time from contextlib import closing CFG_DIR: str = os.path.expanduser("~/.config/py-agent") VAR_DIR: str = os.path.join(CFG_DIR, "var") os.makedirs(VAR_DIR, exist_ok=True) CONTEXT_FILE: str = os.path.join(CFG_DIR, "ai-context.md") SKILLS_DIR: str = os.path.join(CFG_DIR, "skills") SESSIONS_DIR: str = os.path.join(CFG_DIR, "projects", ".database") BASE_PROMPT_CHAT: str = "Active, natural conversational assistant." BASE_PROMPT_AGENT: str = "Active local workspace developer agent." # Precompiled hot-path regular expressions RE_THINK_TAGS: re.Pattern = re.compile(r"[\s\S]*?(?:|$)", re.DOTALL) RE_AUTO_RUN: re.Pattern = re.compile( r"Run:\s*((?:trace symbol|blast radius|read function|find symbol)\s+[a-zA-Z0-9_.:#/-]+|architecture overview)" ) # Requires '/' prefix for single letters (a, b, f) so plain words are not swallowed RE_THINK_BIN: re.Pattern = re.compile(r"^(?:/(?:[fba]|tk)|/?tk)(?:\s+(\d+))?$", re.IGNORECASE) RE_SHELL_META: re.Pattern = re.compile(r"[\[\]{}()='\",;|#<>]") def load_env_file(path: str) -> None: """Auto-publishes .env from .env.example and loads variables into os.environ.""" if not os.path.isfile(path): example_p = os.path.join(os.path.dirname(path), ".env.example") if os.path.isfile(example_p): try: shutil.copy2(example_p, path) except OSError: pass if os.path.isfile(path): try: with open(path, "r", encoding="utf-8") as f: for line in f: if (l := line.strip()) and not l.startswith("#") and "=" in l: k, v = l.replace("export ", "", 1).split("=", 1) if (k := k.strip()) and k not in os.environ: os.environ[k] = v.split(" #")[0].strip().strip('"').strip("'") except OSError: pass load_env_file(os.path.join(CFG_DIR, ".env")) if (mod_dir := os.path.join(CFG_DIR, "modules")) not in sys.path: sys.path.append(mod_dir) try: import agent_context as context from agent_context import STOP_WORDS except ImportError as e: sys.stderr.write(f"\033[1;31m[CRITICAL]: Failed to load agent_context: {e}\033[0m\n") sys.exit(1) # Lazy references to heavy interactive modules to preserve sub-millisecond shell-hook startup commands = None core = None memories = None sessions = None skills = None tts = None ui = None voice = None def _load_agent_modules() -> None: """Loads interactive modules on demand, keeping shell hook invocations sub-millisecond.""" global commands, core, memories, sessions, skills, tts, ui, voice if commands is not None: return try: import agent_commands as _commands import agent_core as _core import agent_memories as _memories import agent_sessions as _sessions import agent_skills as _skills import agent_tts as _tts import agent_ui as _ui import agent_voice as _voice commands, core, memories, sessions, skills, tts, ui, voice = ( _commands, _core, _memories, _sessions, _skills, _tts, _ui, _voice, ) except ImportError as e: sys.stderr.write(f"\033[1;31m[CRITICAL]: Failed to load modules: {e}\033[0m\n") sys.exit(1) try: import readline readline.parse_and_bind(r'"\e[A": previous-history') readline.parse_and_bind(r'"\e[B": next-history') except ImportError: pass _transient_cmd_count: int = 0 def _show_transient_status(tag: str) -> None: """Displays an inline status tag with breathing room, accumulating for batch removal on next query.""" global _transient_cmd_count sys.stdout.write(f" \033[2m[{tag}]\033[0m\n\n") sys.stdout.flush() _transient_cmd_count += 3 _flash_status = _show_transient_status def _clear_transient_status(query: str = "") -> None: """Erases the ephemeral slash command block and repositions the real query prompt with breathing room.""" global _transient_cmd_count if _transient_cmd_count > 0: try: if query: sys.stdout.write(f"\033[{_transient_cmd_count + 1}A\r\x1b[0J❯ {query}\n") else: sys.stdout.write(f"\033[{_transient_cmd_count}A\r\x1b[0J") sys.stdout.flush() except OSError: pass _transient_cmd_count = 0 def workspace_db_counts(safe_name: str, workspace_path: str = "") -> tuple[int, int]: """Retrieves SQLite turn counts and OKF memory counts without spawning empty databases.""" _load_agent_modules() db_path = os.path.join(SESSIONS_DIR, f"{safe_name}.db") t = 0 if os.path.isfile(db_path): try: with closing(sqlite3.connect(f"file:{db_path}?mode=ro", uri=True, timeout=1.5)) as conn: try: t = conn.execute("SELECT COUNT(*) FROM turns WHERE workspace = ?", (safe_name,)).fetchone()[0] except (sqlite3.Error, TypeError, IndexError): t = 0 except sqlite3.Error: t = 0 m_count = memories.get_memory_count(workspace_path) if workspace_path else 0 return t, m_count def ensure_clean_agent_dir(workspace_path: str) -> None: """Moves root artifacts into .agent/ without clobbering existing destinations.""" if not (ws_name := os.path.basename(workspace_path)): return agent_dir = os.path.join(workspace_path, ".agent") try: os.makedirs(os.path.join(agent_dir, "memory"), exist_ok=True) except OSError: return targets = [ f"index-map-{ws_name}.txt", f"index-map-memory-{ws_name}.db", f"index-map-memory-{ws_name}.db-wal", f"index-map-memory-{ws_name}.db-shm", "history.md", ] for fname in targets: src = os.path.join(workspace_path, fname) dst = os.path.join(agent_dir, fname) if os.path.exists(src): if not os.path.exists(dst): try: os.replace(src, dst) except OSError: pass elif fname == "history.md": try: with open(src, "r", encoding="utf-8") as sf, open(dst, "a", encoding="utf-8") as df: df.write(f"\n\n{sf.read().strip()}\n") os.remove(src) except OSError: pass def _sweep_dead_session_locks() -> None: """Removes .session lockfiles whose owning process is dead. Ignores alive processes.""" sess_dir = os.path.join(CFG_DIR, "var", ".active_sessions") if not os.path.isdir(sess_dir): return try: entries = os.listdir(sess_dir) except OSError: return if not entries: return for f in entries: if not f.endswith(".session"): continue try: pid = int(f.rsplit("-", 1)[-1].replace(".session", "")) if pid <= 0: continue os.kill(pid, 0) except ProcessLookupError: try: os.remove(os.path.join(sess_dir, f)) except OSError: pass except (PermissionError, ValueError, OSError): pass def clean_exit(safe_name: str | None = None, workspace_path: str | None = None, sub_id: int | None = None) -> None: """Cleans active session locks and worktrees independently, then exits cleanly.""" _clear_transient_status("") _load_agent_modules() if safe_name: if sub_id is not None and sub_id > 0 and workspace_path: try: merge = False if ui and hasattr(ui, "confirm_tool"): merge = ui.confirm_tool(f"Merge sub-agent #{sub_id} worktree into main branch") sessions.cleanup_subagent_worktree(workspace_path, sub_id, merge=merge) except Exception as e: if os.environ.get("AI_DEBUG") == "1": sys.stderr.write(f"\r\n[debug] Worktree cleanup failed for sub-agent #{sub_id}: {e}\r\n") try: sessions.cleanup_sub_agent(safe_name, os.getpid()) except Exception as e: if os.environ.get("AI_DEBUG") == "1": sys.stderr.write(f"\r\n[debug] Session lock cleanup failed: {e}\r\n") _sweep_dead_session_locks() if ui and hasattr(ui, "_console"): ui._console.print("[yellow]Exiting session.[/yellow]") else: print("Exiting session.") sys.exit(0) def _launch_surface( script_path: str, is_agent: bool, ws_path: str, skill: str, history: list, args: list[str] | None = None ) -> None: """Launches secondary surfaces (TUI, PyCode, WebUI) with state continuity and E2BIG protection.""" _load_agent_modules() if not os.path.exists(script_path): ui._console.print(f"[red][sys] Launcher script not found: {script_path}[/red]\n") return hist_file = None try: hist_data = json.dumps(history) if len(hist_data) > 65536: with tempfile.NamedTemporaryFile( "w", delete=False, prefix="ai_hist_", suffix=".json", encoding="utf-8" ) as tf: tf.write(hist_data) hist_file = tf.name except Exception: hist_data = "" env = { **os.environ, "AI_IS_AGENT": "1" if is_agent else "0", "AI_WORKSPACE_PATH": ws_path, "AI_ACTIVE_SKILL": skill, "AI_CONFIRM_GATES": os.environ.get("AI_CONFIRM_GATES", "1"), } if hist_file: env["AI_SESSION_HISTORY_FILE"] = hist_file env["AI_SESSION_HISTORY"] = "" else: env["AI_SESSION_HISTORY"] = hist_data cmd = ([sys.executable, script_path] if script_path.endswith(".py") else ["/bin/bash", script_path]) + (args or []) try: proc = subprocess.run(cmd, env=env) if proc.returncode != 0 and proc.returncode != 130: ui._console.print(f"[dim yellow][sys] Surface exited with rc={proc.returncode}.[/dim yellow]\n") st = core.get_state() os.environ["AI_SHOW_THINKING"] = "1" if st.get("show_thinking", True) else "0" ui._console.print("[green][sys] Resumed CLI session.[/green]\n") except Exception as e: ui._console.print(f"[red][sys] Launch failed: {e}[/red]\n") finally: if hist_file and os.path.exists(hist_file): try: os.remove(hist_file) except OSError: pass def resolve_default_profile(is_agent: bool = True) -> str: """Dynamically resolves default profile from environment, active model, or available profiles.""" if not is_agent: return "chat" if env_skill := os.environ.get("AI_ACTIVE_SKILL", "").strip(): primary = env_skill.split()[0].lstrip("-").lower() if primary and primary != "init": return primary try: m_name = "" if ui and hasattr(ui, "get_local_model_name"): m_name = ui.get_local_model_name(max_age=5.0).lower() if m_name and "not loaded" not in m_name and "offline" not in m_name: prof_dir = os.path.join(SKILLS_DIR, "profiles") if os.path.isdir(prof_dir): available = [os.path.splitext(f)[0] for f in os.listdir(prof_dir) if f.endswith(".md")] clean_m = re.sub(r"[^a-z0-9]", "", m_name) for p in available: clean_p = re.sub(r"[^a-z0-9]", "", p) if clean_p in clean_m or clean_m in clean_p: return p except Exception: pass return "agent" def run_interactive_chat(args: list[str]) -> None: """Primary interactive agent and chat engine.""" _load_agent_modules() is_agent = args[0] == "--talk-chat" raw_ws = os.environ.get("AI_WORKSPACE_PATH", os.getcwd()) clean_ws = re.sub(r"^[󱞩\s]+", "", str(raw_ws)).strip().splitlines()[0].strip() if raw_ws else os.getcwd() original_workspace_path = os.path.realpath(os.path.expanduser(clean_ws)) workspace_path = original_workspace_path os.environ["AI_WORKSPACE_PATH"] = workspace_path home_dir = os.path.expanduser("~") safe_name = core.workspace_safe_name(workspace_path, home_dir) try: os.chdir(workspace_path) except OSError: pass ensure_clean_agent_dir(workspace_path) cfg_file = os.path.join(workspace_path, ".agent", "config.json") selected_profile = resolve_default_profile(is_agent) is_yolo, use_map, is_py, memory_active, adapters_active = False, False, False, False, False if is_agent: if not os.path.exists(cfg_file): selected_profile, is_yolo, use_map, is_py, memory_active, adapters_active = ui.select_workspace_profile( os.path.basename(workspace_path) ) try: os.makedirs(os.path.dirname(cfg_file), exist_ok=True) with open(cfg_file, "w", encoding="utf-8") as cf: json.dump( { "profile": selected_profile, "yolo": is_yolo, "map": use_map, "py": is_py, "memory": memory_active, "adapters": adapters_active, "created_at": time.strftime("%Y-%m-%d %H:%M"), }, cf, indent=2, ) except OSError: pass else: try: with open(cfg_file, "r", encoding="utf-8") as cf: d = json.load(cf) selected_profile = d.get("profile") or resolve_default_profile(is_agent) is_yolo = bool(d.get("yolo", False)) use_map = bool(d.get("map", False)) is_py = bool(d.get("py", False)) memory_active = bool(d.get("memory", False)) adapters_active = bool(d.get("adapters", d.get("adp", False))) if "calm" in d: core.save_state("calm_mode", bool(d["calm"])) except (OSError, json.JSONDecodeError): pass profile_args = set() for arg in args: if arg.startswith("-") and arg not in ("--talk", "--talk-chat"): selected_profile = arg.lstrip("-").lower() profile_args.add(arg) if is_agent: clean_name = resolve_default_profile(True) if selected_profile in ("init", "pi/pro") else selected_profile profile_content = skills.load_skill_content(clean_name, SKILLS_DIR, CFG_DIR) if not profile_content and clean_name not in ("agent", "init"): ui._console.print( f"[dim yellow][sys] Skill '{clean_name}' not found. Using minimal agent prompt.[/dim yellow]" ) active_system_prompt = profile_content or BASE_PROMPT_AGENT os.environ["AI_ACTIVE_SKILL"] = clean_name st_init = core.get_state() reasoning_budget = st_init.get("reasoning_budget", 500) reasoning_active = st_init.get("reasoning_active", reasoning_budget > 0) if os.path.isfile(cfg_file): try: with open(cfg_file, "r", encoding="utf-8") as cf: d = json.load(cf) if "reasoning" in d: reasoning_active = bool(d["reasoning"]) core.save_state("reasoning_active", reasoning_active) if "reasoning_budget" in d: reasoning_budget = int(d["reasoning_budget"]) core.save_state("reasoning_budget", reasoning_budget) except Exception: pass is_purebash = clean_name in ("purebash", "swe", "bash") or "purebash" in clean_name core.save_state("use_map", use_map) core.save_state("yolo_mode", is_yolo) core.save_state("ipython_mode", is_py) core.save_state("memory_active", memory_active) core.save_state("adapters_active", adapters_active) core.save_state("purebash_mode", is_purebash) os.environ["AI_USE_MAP"] = "1" if use_map else "0" os.environ["AI_IPYTHON_MODE"] = "1" if is_py else "0" os.environ["AI_PUREBASH_MODE"] = "1" if is_purebash else "0" if is_yolo: os.environ["AI_CONFIRM_GATES"] = "0" if use_map: agent_dir = os.path.join(workspace_path, ".agent") ws_name = os.path.basename(workspace_path) txt_p = os.path.join(agent_dir, f"index-map-{ws_name}.txt") db_p = os.path.join(agent_dir, f"index-map-memory-{ws_name}.db") imap_bin = os.path.join(CFG_DIR, "tools", "index-map", "index-map") if not os.path.isfile(txt_p) or not os.path.isfile(db_p): if os.path.isfile(imap_bin): res_map = subprocess.run( [sys.executable, imap_bin, "--agent", workspace_path], capture_output=True, text=True ) if res_map.returncode == 0: ui._console.print("[dim][sys] Map enabled: compiled index-map.[/dim]") else: ui._console.print( f"[dim yellow][sys] Map compilation failed (rc={res_map.returncode}): {res_map.stderr.strip()[:100]}[/dim yellow]" ) map_path = next( (p for p in (txt_p, os.path.join(workspace_path, f"index-map-{ws_name}.txt")) if os.path.exists(p)), None, ) if map_path: try: with open(map_path, "r", encoding="utf-8") as mf: new_map = mf.read().strip() if "### CODESPACE MAP:" not in active_system_prompt: active_system_prompt += f"\n\n### CODESPACE MAP:\n{new_map}" except OSError: pass else: clean_name = selected_profile if (selected_profile and selected_profile != "pi/pro") else "chat" skill_content = skills.load_skill_content(clean_name, SKILLS_DIR, CFG_DIR) if not skill_content and clean_name != "chat": ui._console.print( f"[dim yellow][sys] Skill '{clean_name}' not found. Using minimal chat prompt.[/dim yellow]" ) active_system_prompt = skill_content or BASE_PROMPT_CHAT os.environ["AI_ACTIVE_SKILL"] = clean_name inst_p = os.path.join(SKILLS_DIR, "system_instructions.md") if os.path.isfile(inst_p) and os.path.getsize(inst_p) > 0: try: with open(inst_p, "r", encoding="utf-8") as f: rules = [l for l in f if l.strip() and not l.strip().startswith("#")] if active_rules := "".join(rules).strip(): active_system_prompt += f"\n\n{active_rules}" except OSError: pass pending_args = [a for a in args[1:] if a not in profile_args] pending_query = " ".join(pending_args) if pending_args else None if pending_query and ("CODEBASE INDEX MAP" in pending_query or "index-map" in pending_query): if use_map and "### CODESPACE MAP:" not in active_system_prompt: active_system_prompt += f"\n\n### CODESPACE MAP:\n{pending_query}" pending_query = None chat_history = [{"role": "system", "content": active_system_prompt}] st = core.get_state() show_stats = st.get("show_stats", True) if not is_agent: memory_active = st.get("memory_active", False) reasoning_budget = st.get("reasoning_budget", 500) reasoning_active = st.get("reasoning_active", reasoning_budget > 0) os.environ["AI_RENDER_MARKDOWN"] = "1" if st.get("render_markdown", False) else "0" os.environ["AI_REASONIX_ACTIVE"] = "1" if st.get("reasonix_active", True) else "0" os.environ["AI_SHOW_THINKING"] = "1" if st.get("show_thinking", True) else "0" if is_yolo or st.get("yolo_mode", False): os.environ["AI_CONFIRM_GATES"] = "0" db_turns, mem_count = workspace_db_counts(safe_name, workspace_path) if is_agent else (0, 0) _sweep_dead_session_locks() sub_id = sessions.get_sub_agent_id(safe_name, os.getpid()) if is_agent else None if sub_id is not None and sub_id > 0: try: new_ws = sessions.create_subagent_worktree(original_workspace_path, sub_id) os.chdir(new_ws) workspace_path = new_ws os.environ["AI_WORKSPACE_PATH"] = workspace_path except OSError as e: ui._console.print(f"[red][sys] Sub-agent worktree setup failed: {e}[/red]") clean_exit(safe_name, workspace_path=original_workspace_path, sub_id=sub_id) # Wake-on-Key Resonant Ribbon Box wake_key = ui.draw_session_box( workspace_path, home_dir, is_agent, db_turns, mem_count, memory_active, active_system_prompt, clean_name, sub_id=sub_id, box_style=st.get("box_style", 1), wake_on_key=not bool(pending_query), ) if wake_key: try: readline.set_startup_hook(lambda: readline.insert_text(wake_key)) except Exception: pass try: while True: if pending_query: query, pending_query = pending_query, None else: try: query = voice.get_prompt_input() except EOFError: break finally: try: readline.set_startup_hook(None) except Exception: pass if not query: continue ctx = commands.SessionContext( workspace_path=workspace_path, home_dir=home_dir, safe_name=safe_name, cfg_file=cfg_file, is_agent=is_agent, chat_history=chat_history, active_system_prompt=active_system_prompt, clean_name=clean_name, use_map=use_map, memory_active=memory_active, is_yolo=is_yolo, reasoning_active=reasoning_active, reasoning_budget=reasoning_budget, show_stats=show_stats, flash_status=_flash_status, launch_surface_fn=_launch_surface, clean_exit_fn=lambda name: clean_exit( name, workspace_path=original_workspace_path if (workspace_path != original_workspace_path) else None, sub_id=sub_id if is_agent else None, ), ) handled, new_query = commands.dispatch_command(query, ctx) use_map = ctx.use_map memory_active = ctx.memory_active is_yolo = ctx.is_yolo reasoning_active = ctx.reasoning_active reasoning_budget = ctx.reasoning_budget show_stats = ctx.show_stats if handled: continue if new_query: query = new_query _clear_transient_status(query) memory_ctx = memories.get_memory_context(workspace_path) if (is_agent and memory_active) else "" if RE_THINK_BIN.match(query): think_bin = next( (p for p in (f"{CFG_DIR}/modules/agent_chat.py", f"{CFG_DIR}/modules/chat") if os.path.isfile(p)), None, ) if think_bin: try: res = subprocess.run( [sys.executable, think_bin, query], input=json.dumps(chat_history), text=True, timeout=120, ) if res.returncode != 0: sys.stderr.write(f"\033[1;31m[Warning] chat failed: rc={res.returncode}\033[0m\n") continue except Exception as e: sys.stderr.write(f"\033[1;31m[Warning] chat failed: {e}\033[0m\n") else: ui._console.print("[dim yellow][sys] Chat assistant helper not found.[/dim yellow]\n") continue sys_ctx = ( "" if query.startswith("init") and "--init" in query else skills.get_system_context(query, CONTEXT_FILE, STOP_WORDS, SKILLS_DIR, CFG_DIR) ) if sys_ctx == "__ABORT_TURN__": ui._console.print("[yellow][sys] Action cancelled.[/yellow]\n") continue comb_ctx = "\n\n".join(filter(None, [memory_ctx, sys_ctx])) prompt = f"\n{comb_ctx}\n\n\n{query}" if comb_ctx else query chat_history.append({"role": "user", "content": prompt}) try: readline.add_history(query) except Exception: pass ans = core.stream_response( chat_history, prefix="", show_stats=show_stats, thinking_budget=reasoning_budget if reasoning_active else 0, is_agent=is_agent, ) if not ans: # Stream failed or interrupted: roll back user turn to prevent context drift if chat_history and chat_history[-1].get("role") == "user": chat_history.pop() continue clean_ans = RE_THINK_TAGS.sub("", ans).strip() chat_history.append({"role": "assistant", "content": clean_ans or ans}) try: tts.speak_response(clean_ans or ans) except Exception as e: if os.environ.get("AI_DEBUG") == "1": sys.stderr.write(f"\r\n[debug] TTS playback error: {e}\r\n") if not show_stats: print() if is_agent: try: sessions.log_turn(safe_name, query, ans) except Exception as e: if os.environ.get("AI_DEBUG") == "1": sys.stderr.write(f"\r\n[debug] Failed to log turn to SQLite: {e}\r\n") if match := RE_AUTO_RUN.search(ans): try: readline.set_startup_hook(lambda: readline.insert_text(match.group(1).strip())) except Exception: pass agent_dir = os.path.join(workspace_path, ".agent") try: os.makedirs(agent_dir, exist_ok=True) hist_file = os.path.join(agent_dir, "history.md") mode = "a" if os.path.exists(hist_file) else "w" with open(hist_file, mode, encoding="utf-8") as hf: if mode == "w": hf.write(f"# Workspace History: {os.path.basename(workspace_path)}\n\n") hf.write( f"## [{time.strftime('%Y-%m-%d %H:%M')}] User:\n{query}\n\n### Agent:\n{ans}\n\n---\n\n" ) except OSError as e: if os.environ.get("AI_DEBUG") == "1": sys.stderr.write(f"\r\n[debug] Failed to write history.md: {e}\r\n") except KeyboardInterrupt: clean_exit( safe_name if is_agent else None, workspace_path=original_workspace_path if (workspace_path != original_workspace_path) else None, sub_id=sub_id if is_agent else None, ) def run_direct_query(args: list[str]) -> None: """Executes instant single-turn CLI prompt without interactive session loop.""" _load_agent_modules() query_parts = args[1:] skill_content = "" clean_parts: list[str] = [] for part in query_parts: if part.startswith("-") and part != "-": loaded = skills.load_skill_content(part.lstrip("-").lower(), SKILLS_DIR, CFG_DIR) if loaded: skill_content = loaded continue clean_parts.append(part) query = " ".join(clean_parts).strip() if query == "-" or (not query and not sys.stdin.isatty()): try: query = sys.stdin.read().strip() except Exception: query = "" if not query: ui._console.print("[dim yellow][sys] Usage: ai --talk [-skill][/dim yellow]") sys.exit(0) if query.lower() in ("/help", "/h", "help", "--help", "-h"): ui.show_help() sys.exit(0) if "AI_SHOW_THINKING" not in os.environ: os.environ["AI_SHOW_THINKING"] = "0" thinking_budget = 0 if env_budget := os.environ.get("AI_THINKING_BUDGET"): try: thinking_budget = max(0, int(env_budget.strip())) except (ValueError, TypeError): thinking_budget = 0 sys_ctx = skills.get_system_context(query, CONTEXT_FILE, STOP_WORDS, SKILLS_DIR, CFG_DIR) if sys_ctx == "__ABORT_TURN__": sys_ctx = "" active_p = skill_content or BASE_PROMPT_CHAT inst_p = os.path.join(SKILLS_DIR, "system_instructions.md") if os.path.isfile(inst_p) and os.path.getsize(inst_p) > 0: try: with open(inst_p, "r", encoding="utf-8") as f: rules = [l for l in f if l.strip() and not l.strip().startswith("#")] if active_rules := "".join(rules).strip(): active_p += f"\n\n{active_rules}" except OSError: pass messages = [ {"role": "system", "content": active_p}, {"role": "user", "content": f"\n{sys_ctx}\n\n\n{query}" if sys_ctx else query}, ] core.stream_response(messages, prefix="", show_stats=False, thinking_budget=thinking_budget) sys.exit(0) def run_matching_search(args: list[str]) -> None: """Sub-millisecond shell intent matcher for command not found hook (zero eager module imports).""" user_input = re.sub(r"[`$]", "", " ".join(args)).strip() if not user_input or args[0].startswith("--"): sys.exit(0) if user_input.lower() in ("/help", "/h"): _load_agent_modules() ui.show_help() sys.exit(0) shell_name = os.path.basename(os.environ.get("SHELL", "/bin/bash")) err_msg = f"{'zsh' if 'zsh' in shell_name else 'bash'}: {f'command not found: {user_input}' if 'zsh' in shell_name else f'{user_input}: command not found'}\n" if RE_SHELL_META.search(user_input): sys.stderr.write(err_msg) sys.exit(127) if matched := context.jaccard_search(user_input, CONTEXT_FILE, STOP_WORDS): print( "\n".join( f"{l.split('|||', 1)[0]}|||{context.clean_tool_prefix(l.split('|||', 1)[1])}" for l in matched.split("\n") ) ) sys.exit(0) sys.stderr.write(err_msg) sys.exit(127) def main() -> None: try: args = sys.argv[1:] if not args: run_direct_query(["--talk"]) elif args[0] == "--interactive" and len(args) >= 2: _load_agent_modules() shell_name = os.path.basename(os.environ.get("SHELL", "")) ui.run_interactive_selection( " ".join(args[1:]), lambda q: context.jaccard_search(q, CONTEXT_FILE, STOP_WORDS), context.clean_tool_prefix, lambda n: sys.stderr.write( f"zsh: command not found: {n}\n" if "zsh" in shell_name else f"bash: {n}: command not found\n" ), lambda: skills.ensure_mysys_exists(SKILLS_DIR, CFG_DIR), ) sys.exit(0) elif args[0] in ("--talk", "--talk-chat"): run_interactive_chat(args) if (args[0] == "--talk-chat" or len(args) == 1) else run_direct_query(args) sys.exit(0) else: run_matching_search(args) except KeyboardInterrupt: sys.stderr.write("\nCancelled.\n") sys.exit(130) if __name__ == "__main__": main()