Download Code-agent-main/ycode/cli.py from Yazhiniyan/YCode: direct link, hf CLI and curl.
- Browser
- Download file 6.33 kB
-
https://huggingface.co/Yazhiniyan/YCode/resolve/main/Code-agent-main/ycode/cli.py
- Command line
-
hf download hf://Yazhiniyan/YCode/Code-agent-main/ycode/cli.py
-
curl -L -o cli.py https://huggingface.co/Yazhiniyan/YCode/resolve/main/Code-agent-main/ycode/cli.py
6.33 kB
| """Command-line entry point: ``ycode`` / ``python -m ycode``.""" | |
| from __future__ import annotations | |
| import argparse | |
| import contextlib | |
| import os | |
| import sys | |
| import time | |
| import traceback | |
| from pathlib import Path | |
| from ycode import __version__ | |
| from ycode.agent.context import detect_project | |
| from ycode.agent.loop import TaskStatus | |
| from ycode.config import APPROVAL_MODES, Config, load_config, load_env_files, ycode_home | |
| from ycode.errors import YCodeError | |
| from ycode.llm import create_provider | |
| from ycode.ui.console import ConsoleUI, make_console | |
| def build_parser() -> argparse.ArgumentParser: | |
| parser = argparse.ArgumentParser( | |
| prog="ycode", | |
| description="YCode - an AI coding agent for your terminal.", | |
| ) | |
| parser.add_argument("task", nargs="*", help="Run a single task non-interactively, then exit.") | |
| parser.add_argument("-p", "--prompt", help="Same as passing a task: run it and exit.") | |
| parser.add_argument("-m", "--model", help="Model ID (overrides YCODE_MODEL and config files).") | |
| parser.add_argument("--provider", choices=("local", "anthropic"), | |
| help="LLM provider: YCode's own model (default, no API key) or Claude " | |
| "(anthropic, needs ANTHROPIC_API_KEY).") | |
| parser.add_argument("--local", nargs="?", const="", default=None, metavar="MODEL", | |
| help="Use YCode's own model (the default). Optionally pick one: v2, v3, v4, v5, " | |
| "or a model directory. Default: your trained model if you have one, else v5 " | |
| "(v4 with less than 4 GB of free memory).") | |
| parser.add_argument("--max-steps", type=int, help="Maximum agent steps per task.") | |
| parser.add_argument("--approval-mode", choices=APPROVAL_MODES, help="How risky actions are approved.") | |
| parser.add_argument("--yes", action="store_true", | |
| help="Shortcut for --approval-mode auto (blocked commands stay blocked).") | |
| parser.add_argument("-C", "--directory", help="Project directory (default: current directory).") | |
| parser.add_argument("--no-banner", action="store_true", help="Skip the start-up banner.") | |
| parser.add_argument("--version", action="version", version=f"YCode {__version__}") | |
| return parser | |
| def _debug() -> bool: | |
| return os.environ.get("YCODE_DEBUG", "").lower() in ("1", "true", "yes") | |
| def main(argv: list[str] | None = None) -> int: | |
| args = build_parser().parse_args(argv) | |
| console = make_console() | |
| ui = ConsoleUI(console) | |
| workspace = Path(args.directory or os.getcwd()).expanduser() | |
| if not workspace.is_dir(): | |
| ui.print_error(YCodeError(f"Directory not found: {workspace}")) | |
| return 2 | |
| workspace = workspace.resolve() | |
| load_env_files(workspace) | |
| try: | |
| config = load_config( | |
| workspace, | |
| cli_overrides={ | |
| "model": args.model, | |
| "provider": "local" if args.local is not None else args.provider, | |
| "local_model": args.local or None, | |
| "max_steps": args.max_steps, | |
| "approval_mode": "auto" if args.yes else args.approval_mode, | |
| }, | |
| ) | |
| except YCodeError as exc: | |
| ui.print_error(exc) | |
| return 2 | |
| if config.theme != "default": | |
| console = make_console(config.theme) | |
| ui = ConsoleUI(console) | |
| task = args.prompt or " ".join(args.task).strip() or None | |
| try: | |
| return run(config, workspace, ui, task=task, show_banner=not args.no_banner) | |
| except KeyboardInterrupt: | |
| ui.stop() | |
| console.print() | |
| return 130 | |
| def run(config: Config, workspace: Path, ui: ConsoleUI, *, task: str | None, show_banner: bool) -> int: | |
| from ycode.app import YCodeApp | |
| with ui.console.status("Inspecting project...", spinner="dots") if ui.console.is_terminal else contextlib.nullcontext(): | |
| context = detect_project(workspace, config.ignore_dirs) | |
| try: | |
| provider = create_provider(config) | |
| except YCodeError as exc: | |
| if show_banner: | |
| from ycode.ui.banner import BannerInfo | |
| ui.print_banner(BannerInfo(version=__version__, model=config.model, directory=str(workspace), | |
| branch=context.branch, project_types=tuple(context.project_types), | |
| approval_mode=config.approval_mode), show_hint=False) | |
| ui.print_error(exc) | |
| return 1 | |
| app = YCodeApp(config=config, workspace=workspace, provider=provider, ui=ui, context=context) | |
| if show_banner: | |
| ui.print_banner(app.banner_info()) | |
| if not provider.supports_tools: | |
| ui.on_notice("Local model: answer-only mode. It answers questions and writes code in its reply, " | |
| "but cannot read, edit or run files in your project.", "warning") | |
| ui.console.print() | |
| if task is not None: | |
| result = app.run_task(task) | |
| return 0 if result.status is TaskStatus.COMPLETED else 1 | |
| return repl(app) | |
| def repl(app) -> int: # noqa: ANN001 - YCodeApp, imported lazily | |
| from ycode.commands import command_names | |
| from ycode.ui.prompts import InputReader | |
| reader = InputReader(ycode_home() / "history", commands=command_names()) | |
| ui = app.ui | |
| last_interrupt = 0.0 | |
| while not app.should_exit: | |
| try: | |
| line = reader.read() | |
| except KeyboardInterrupt: | |
| now = time.monotonic() | |
| if now - last_interrupt < 2.0: | |
| break | |
| last_interrupt = now | |
| ui.info("(Press Ctrl+C again or Ctrl+D to exit)") | |
| continue | |
| except EOFError: | |
| break | |
| try: | |
| app.handle_line(line) | |
| except KeyboardInterrupt: | |
| ui.stop() | |
| ui.info("Interrupted.") | |
| except YCodeError as exc: | |
| ui.print_error(exc) | |
| except Exception as exc: # noqa: BLE001 - keep the session alive | |
| ui.stop() | |
| if _debug(): | |
| traceback.print_exc() | |
| ui.print_error(YCodeError( | |
| f"Internal error: {type(exc).__name__}: {exc}", | |
| hint="Set YCODE_DEBUG=1 to see the full traceback.", | |
| )) | |
| ui.stop() | |
| ui.info("Goodbye.") | |
| return 0 | |
| if __name__ == "__main__": | |
| sys.exit(main()) | |