Spaces:
Running on CPU Upgrade
Running on CPU Upgrade
Download standalone_cli/src/pwc_cli/skills.py from huggingface/paperswithcode-mcp: direct link, hf CLI and curl.
- Browser
- Download file 13.6 kB
-
https://huggingface.co/spaces/huggingface/paperswithcode-mcp/resolve/main/standalone_cli/src/pwc_cli/skills.py
- Command line
-
hf download hf://spaces/huggingface/paperswithcode-mcp/standalone_cli/src/pwc_cli/skills.py
-
curl -L -o skills.py https://huggingface.co/spaces/huggingface/paperswithcode-mcp/resolve/main/standalone_cli/src/pwc_cli/skills.py
13.6 kB
| """Generate and install the pwc CLI skill for AI coding agents.""" | |
| from __future__ import annotations | |
| import argparse | |
| import os | |
| import shutil | |
| import tempfile | |
| from pathlib import Path | |
| from pwc_cli import __version__ | |
| SKILL_NAME = "pwc-cli" | |
| CENTRAL_LOCAL = Path(".agents/skills") | |
| CENTRAL_GLOBAL = Path("~/.agents/skills") | |
| CLAUDE_LOCAL = Path(".claude/skills") | |
| CLAUDE_GLOBAL = Path("~/.claude/skills") | |
| _DESCRIPTION = ( | |
| "Papers With Code CLI (`pwc`) for searching and reading AI/ML papers, " | |
| "discovering recent and trending research, finding related work and paper " | |
| "lineage, browsing tasks, methods, conferences, organizations, frameworks, " | |
| "and benchmark leaderboards, and submitting authenticated paper edits " | |
| "through the public Papers With Code catalog. Use whenever the user asks to " | |
| "find papers, survey literature, compare research, inspect an arXiv paper, " | |
| "explore AI/ML taxonomy or conferences, discover benchmarks or " | |
| "state-of-the-art models, or mentions Papers With Code, `pwc`, or `pwc-cli`." | |
| ) | |
| _INTRODUCTION = """ | |
| Research commands query the public [Papers With Code](https://paperswithcode.co) catalog anonymously. | |
| Paper editing requires explicit browser authorization through `pwc auth login --paper PAPER`. | |
| Run `pwc --help` or a nested `--help` command when the live parser and this | |
| skill disagree; the parser is authoritative. | |
| Use compact output for reading and discovery. Add `--json` for programmatic | |
| filtering, joining, or schema-dependent processing. | |
| When the user identifies an author, prefer repeatable structured | |
| `pwc paper list --author AUTHOR` filters. Add `--search TEXT` for stated topic | |
| terms and explicit `--order-by date_published --order-dir desc` for newest or | |
| recent work. Author references accept an exact normalized name, numeric ID, or | |
| `@HF_USERNAME`; repeated authors use AND semantics. | |
| Publication date ranges are inclusive: use `--start-date YYYY-MM-DD` and | |
| `--end-date YYYY-MM-DD` with `pwc search` or `pwc paper list`; the start date | |
| must not be later than `--end-date`. The combined flags are | |
| `--start-date YYYY-MM-DD --end-date YYYY-MM-DD`. | |
| Paper discovery commands accept `--implementation-coverage` to add official | |
| implementation status and total linked repository count columns. JSON and | |
| `pwc paper info` always include both fields. Use | |
| `--has-official-implementation` with `pwc search` or `pwc paper list` to require | |
| a catalog-linked official repository; these filters fail closed if unconfirmed. | |
| Use `pwc benchmark --name NAME --max-parameters SIZE` to keep models at or | |
| below an inclusive parameter limit. SIZE accepts values such as `500M`, `1.5B`, | |
| `3B`, and raw integers. Models without one consistent parameter count are | |
| excluded from constrained results. | |
| `PAPER` accepts a modern or legacy arXiv ID, a numeric external-paper ID, or an | |
| exact paper title. Quote titles containing spaces. Title matching is | |
| case-insensitive but exact; ambiguous titles fail with their matching IDs. | |
| When `pwc paper info` or `pwc paper read` names a paper Papers With Code has | |
| not indexed, stderr shows "Not indexed on Papers With Code — available at:" | |
| with public links and metadata before the usual not-found error; cite those | |
| links, not a Papers With Code page. | |
| """ | |
| _WORKFLOW = """ | |
| ## Research workflow | |
| 1. Use `pwc benchmark list --task TASK` to discover active benchmarks, then | |
| `pwc benchmark --name NAME` to inspect a leaderboard. Add | |
| `--max-parameters SIZE` when model size is part of the request. | |
| 2. Use `pwc paper info` to inspect promising results. Add | |
| `--include-resources` when repositories, project pages, or Hugging Face | |
| artifacts matter. | |
| 3. Use exact `pwc paper list --author`, `--task`, `--method`, `--conference`, | |
| `--framework`, and `--organization` filters for known identities or catalog | |
| associations. Combine them to require every association; do not substitute | |
| a keyword search. Add `--search` for title or abstract topic terms. | |
| 4. Use `pwc search` for broader discovery, then `pwc paper read` for primary | |
| evidence. | |
| 5. Expand the literature with `pwc paper related` and use | |
| `pwc paper lineage list` when model or method ancestry matters. | |
| 6. Preserve paper titles, identifiers, and URLs so claims remain traceable. | |
| ## Output and limits | |
| - Interactive output is optimized for people. Benchmark lists remain aligned | |
| when captured; other captured list output uses lossless TSV. Add `--json` for | |
| structured agent or script consumption. | |
| - Stable exit codes are `0` success, `2` invalid usage, `3` network/server | |
| failure, and `4` invalid API response. | |
| - `PWC_API_URL` may select another compatible v1 endpoint. The default is | |
| `https://paperswithcode.co/api/v1`. | |
| - Catalog-filtered paper lists fail closed unless the server confirms every | |
| requested filter; never treat results from an older server as filtered. | |
| - Parameter-filtered benchmark details fail closed unless the server confirms | |
| parameter-filter support and every returned model satisfies the limit. | |
| The research commands contain no authentication, catalog mutation, ingestion, | |
| publication, image, embedding, CRON, or infrastructure-maintenance operations. | |
| """ | |
| class SkillInstallError(Exception): | |
| """An invalid or unsafe skill installation request.""" | |
| def _subcommand_help(action: argparse._SubParsersAction, name: str) -> str: | |
| for choice in action._choices_actions: | |
| if choice.dest == name: | |
| return str(choice.help or "") | |
| return "" | |
| def _command_signature(parser: argparse.ArgumentParser) -> str: | |
| parts: list[str] = [] | |
| for action in parser._actions: | |
| if isinstance(action, argparse._SubParsersAction): | |
| continue | |
| if action.dest == "help": | |
| continue | |
| if not action.option_strings: | |
| parts.append(str(action.metavar or action.dest).upper()) | |
| continue | |
| option = next( | |
| (item for item in action.option_strings if item.startswith("--")), | |
| action.option_strings[0], | |
| ) | |
| if action.nargs == 0: | |
| parts.append(f"[{option}]") | |
| continue | |
| if action.choices: | |
| value = "|".join(str(choice) for choice in action.choices) | |
| else: | |
| value = str(action.metavar or action.dest).upper() | |
| parts.append(f"[{option} {value}]") | |
| return " ".join(parts) | |
| def _command_entries( | |
| parser: argparse.ArgumentParser, prefix: tuple[str, ...] = () | |
| ) -> list[str]: | |
| entries: list[str] = [] | |
| for action in parser._actions: | |
| if not isinstance(action, argparse._SubParsersAction): | |
| continue | |
| for name, child in action.choices.items(): | |
| path = (*prefix, name) | |
| if "handler" in child._defaults: | |
| signature = _command_signature(child) | |
| invocation = " ".join(("pwc", *path, signature)).rstrip() | |
| help_text = _subcommand_help(action, name) | |
| suffix = f" — {help_text.rstrip('.')}" if help_text else "" | |
| entries.append(f"- `{invocation}`{suffix}.") | |
| entries.extend(_command_entries(child, path)) | |
| return entries | |
| def build_skill_md() -> str: | |
| """Build a Skill matching the commands in the installed pwc version.""" | |
| from pwc_cli.cli import build_parser | |
| commands = "\n".join(_command_entries(build_parser())) | |
| return ( | |
| "---\n" | |
| f"name: {SKILL_NAME}\n" | |
| f'description: "{_DESCRIPTION}"\n' | |
| "---\n\n" | |
| f"Generated with `pwc v{__version__}`. Run " | |
| "`pwc skills add --force` to regenerate.\n" | |
| f"{_INTRODUCTION}\n" | |
| "## Commands\n\n" | |
| f"{commands}\n" | |
| f"{_WORKFLOW}\n{_EDIT_WORKFLOW}" | |
| ) | |
| def _remove_existing(path: Path, force: bool) -> None: | |
| if not (path.exists() or path.is_symlink()): | |
| return | |
| if not force: | |
| raise SkillInstallError( | |
| f"skill already exists at {path}; rerun with --force to overwrite" | |
| ) | |
| if path.is_dir() and not path.is_symlink(): | |
| shutil.rmtree(path) | |
| else: | |
| path.unlink() | |
| def _install_to(skills_dir: Path, force: bool) -> Path: | |
| skills_dir = skills_dir.expanduser().resolve() | |
| skills_dir.mkdir(parents=True, exist_ok=True) | |
| target = skills_dir / SKILL_NAME | |
| _remove_existing(target, force) | |
| temporary = Path(tempfile.mkdtemp(prefix=f".{SKILL_NAME}-", dir=skills_dir)) | |
| try: | |
| (temporary / "SKILL.md").write_text(build_skill_md(), encoding="utf-8") | |
| os.replace(temporary, target) | |
| finally: | |
| if temporary.exists(): | |
| shutil.rmtree(temporary) | |
| return target | |
| def _link_to(skills_dir: Path, installed: Path, force: bool) -> Path: | |
| skills_dir = skills_dir.expanduser().resolve() | |
| skills_dir.mkdir(parents=True, exist_ok=True) | |
| link = skills_dir / SKILL_NAME | |
| _remove_existing(link, force) | |
| link.symlink_to(os.path.relpath(installed, skills_dir), target_is_directory=True) | |
| return link | |
| def skills_add(args: argparse.Namespace, _client: object) -> int: | |
| """Install the generated pwc skill in central and optional harness paths.""" | |
| if args.dest is not None and (args.global_ or args.claude): | |
| raise SkillInstallError("--dest cannot be combined with --global or --claude") | |
| if args.dest is not None: | |
| installed = _install_to(args.dest, args.force) | |
| print(f"Installed '{SKILL_NAME}' to {installed}") | |
| return 0 | |
| central_root = CENTRAL_GLOBAL if args.global_ else CENTRAL_LOCAL | |
| installed = _install_to(central_root, args.force) | |
| print(f"Installed '{SKILL_NAME}' to {installed}") | |
| if args.claude: | |
| claude_root = CLAUDE_GLOBAL if args.global_ else CLAUDE_LOCAL | |
| link = _link_to(claude_root, installed, args.force) | |
| print(f"Linked '{SKILL_NAME}' for Claude at {link}") | |
| return 0 | |
| _EDIT_WORKFLOW = """ | |
| ## Editing one paper | |
| Use this workflow only when the user requests edits. Research commands remain anonymous. | |
| 1. Run `pwc auth login --paper PAPER`. Give the user the browser link and code; | |
| they sign in with Hugging Face and authorize that paper for one hour. Use | |
| `--no-browser` on a remote machine. Never extract, print, or copy credentials. | |
| 2. Run `pwc paper edit export PAPER --output edits.json` (the output must not | |
| already exist). It includes paper_id, version, idempotency_key, empty operations, | |
| and current reference data. Change operations, not current. Preserve the | |
| exported version and retry key. Documents may contain at most 50 operations | |
| and 1 MiB of JSON. | |
| 3. Add operations of the form `{"section":"tasks","payload":{"task_ids":[1,2]}}`. | |
| A section operation explicitly replaces that section; preserve unrelated links | |
| and tags. Omitted sections stay unchanged. Allowed sections and payload keys: | |
| tasks/task_ids, methods/method_ids, repositories/repositories, | |
| project_pages/project_pages, hf_artifacts/hf_models+hf_datasets+hf_spaces, | |
| x_threads/x_threads, source_url/source_url (external papers only), and | |
| evaluations. Repository/project-page entries contain url and is_official. | |
| x_threads is a list of x.com or twitter.com post URLs in display order (at | |
| most 10). Link only posts in which the paper's authors or their organization | |
| introduce the paper, never outside accounts; the server captures each post's | |
| preview and rejects deleted or protected posts. | |
| 4. For evaluations, an operation without evaluation_id creates a row. Include | |
| task_id, dataset_id, metrics (a dictionary of existing metric names to scores), | |
| model_name, and the evaluation setup where available. One row can contain | |
| multiple metrics. Add evaluation_id to correct an existing row on this paper; | |
| omitted update fields stay unchanged. Use source_url and methodology to cite | |
| precise evidence when available; source references remain optional. Existing | |
| benchmark/task/metric definitions are required. Do not invent missing IDs or | |
| create benchmarks. Report unsupported results to the user. No evaluation | |
| deletion, paper identity changes, organization edits, or rank overrides. | |
| 5. Run `pwc paper edit preview PAPER --file edits.json`, inspect the before/after | |
| changes, then `pwc paper edit submit PAPER --file edits.json`. Publication is | |
| immediate: no per-batch browser approval. Respect the user's requested scope. | |
| A batch succeeds completely or makes no changes. The response includes status | |
| published and a link to the paper's history. | |
| 6. Retry an uncertain network result using the exact same document and retry key. | |
| A 409 means changed data or a reused key with different edits. Fetch a fresh | |
| export, preserve others' edits, and reconcile. Ask the user if the same score | |
| has conflicting corrections. Once you intentionally revise a previously | |
| submitted batch, use a fresh export/key. A 403 may mean expired authorization, | |
| suspension, or insufficient scope: read the error; do not broaden access. | |
| A 429 indicates the shared account limit: 20 distinct papers per UTC day and | |
| 30 publications per minute. Do not work around account limits. | |
| 7. `pwc auth status --paper PAPER` shows local expiry metadata (revocation is | |
| checked by the server on use). `pwc auth logout --paper PAPER` revokes access. | |
| If authorization expires, keep the prepared file and request browser login | |
| again. Renewing authorization does not require discarding a valid edit document. | |
| Credentials are stored in owner-only files under ~/.config/pwc/edit-credentials, | |
| separately for each API base URL and paper. They never belong in a prompt, edit | |
| file, repository, or command argument. The CLI does not follow edit redirects. | |
| """ | |