Instructions to use SkillScreen/SkillScreen-2B-Package with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use SkillScreen/SkillScreen-2B-Package with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-classification", model="SkillScreen/SkillScreen-2B-Package")# pip install -U transformers accelerate # Load model directly from transformers import AutoProcessor, AutoModelForSequenceClassification processor = AutoProcessor.from_pretrained("SkillScreen/SkillScreen-2B-Package") model = AutoModelForSequenceClassification.from_pretrained("SkillScreen/SkillScreen-2B-Package", device_map="auto") - Notebooks
- Google Colab
- Kaggle
Download scripts/skill_package.py from SkillScreen/SkillScreen-2B-Package: direct link, hf CLI and curl.
- Browser
- Download file 4.7 kB
-
https://huggingface.co/SkillScreen/SkillScreen-2B-Package/resolve/main/scripts/skill_package.py
- Command line
-
hf download hf://SkillScreen/SkillScreen-2B-Package/scripts/skill_package.py
-
curl -L -o skill_package.py https://huggingface.co/SkillScreen/SkillScreen-2B-Package/resolve/main/scripts/skill_package.py
4.7 kB
| """Read a skill as inert text; never import, install, or execute its files.""" | |
| import hashlib | |
| import json | |
| import os | |
| from pathlib import Path | |
| import stat | |
| IGNORE_DIRS = {'.git', '.venv', 'venv', 'node_modules', '__pycache__', '.ssh', '.aws'} | |
| MAX_FILE_BYTES = 1_048_576 | |
| MAX_PACKAGE_BYTES = 16_777_216 | |
| MAX_ENTRIES = 1000 | |
| def digest(value): | |
| return hashlib.sha256(value).hexdigest() | |
| def read_package(path): | |
| path = Path(path).absolute() | |
| if path.is_symlink() or path.is_junction(): | |
| raise ValueError('Choose a real package directory or SKILL.md, not a link.') | |
| single = path.is_file() | |
| if single and path.name != 'SKILL.md': | |
| raise ValueError('A file input must be named SKILL.md.') | |
| root = path.parent if single else path | |
| if not root.is_dir(): | |
| raise ValueError('Package directory does not exist.') | |
| root = root.resolve() | |
| files, skipped, total, entries = [], [], 0, 0 | |
| if single: | |
| candidates = [(root, [], ['SKILL.md'])] | |
| else: | |
| candidates = os.walk(root, followlinks=False, onerror=lambda exc: (_ for _ in ()).throw(exc)) | |
| for directory, dirs, names in candidates: | |
| directory = Path(directory) | |
| entries += len(dirs) + len(names) | |
| if entries > MAX_ENTRIES: | |
| raise ValueError(f'Package exceeds {MAX_ENTRIES} entries; select a smaller skill directory.') | |
| for name in sorted(dirs[:]): | |
| item = directory / name | |
| reason = ('excluded_directory' if name.lower() in IGNORE_DIRS else | |
| 'link' if item.is_symlink() or item.is_junction() else None) | |
| if reason: | |
| dirs.remove(name) | |
| skipped.append({'path': item.relative_to(root).as_posix() + '/', 'reason': reason}) | |
| dirs.sort() | |
| for name in sorted(names): | |
| item = directory / name | |
| relative = item.relative_to(root).as_posix() | |
| reason = None | |
| if item.is_symlink() or item.is_junction(): | |
| reason = 'link' | |
| elif name.lower() == '.env' or name.lower().startswith('.env.') or item.suffix.lower() in {'.pem', '.key'}: | |
| reason = 'private_configuration' | |
| elif not stat.S_ISREG(item.stat().st_mode): | |
| reason = 'not_regular_file' | |
| elif any(ord(char) < 32 or ord(char) == 127 for char in relative) or '\\' in relative: | |
| reason = 'unsupported_path' | |
| elif not item.resolve().is_relative_to(root): | |
| raise ValueError('A file resolved outside the package.') | |
| if reason: | |
| skipped.append({'path': relative, 'reason': reason}) | |
| continue | |
| with item.open('rb') as stream: | |
| raw = stream.read(MAX_FILE_BYTES + 1) | |
| if len(raw) > MAX_FILE_BYTES: | |
| skipped.append({'path': relative, 'reason': 'file_size_limit'}) | |
| continue | |
| total += len(raw) | |
| if total > MAX_PACKAGE_BYTES: | |
| raise ValueError('Package exceeds the 16 MiB text-read budget.') | |
| try: | |
| text = raw.decode('utf-8') | |
| if '\x00' in text: | |
| raise UnicodeError('NUL byte') | |
| except UnicodeError: | |
| skipped.append({'path': relative, 'reason': 'not_utf8_text'}) | |
| continue | |
| files.append({'path': relative, 'sha256': digest(raw), 'bytes': len(raw), 'text': text}) | |
| files.sort(key=lambda item: item['path']) | |
| markdown = next((item for item in files if item['path'] == 'SKILL.md'), None) | |
| if markdown is None or not markdown['text'].strip(): | |
| raise ValueError('A nonempty UTF-8 SKILL.md is required at the package root.') | |
| manifest = [{key: item[key] for key in ('path', 'sha256', 'bytes')} for item in files] | |
| fingerprint = digest(json.dumps(manifest, sort_keys=True, separators=(',', ':')).encode()) | |
| row = {'skill_text': markdown['text'], | |
| 'files': [{'path': item['path'], 'text': item['text']} for item in files if item is not markdown]} | |
| coverage = {'input_kind': 'markdown_file' if single else 'package_directory', | |
| 'text_manifest_sha256': fingerprint, 'text_files': len(files), | |
| 'text_bytes': sum(item['bytes'] for item in files), 'files': manifest, 'skipped': skipped} | |
| return row, coverage | |
| def write_json(path, value): | |
| """Create outputs explicitly; do not replace a user's existing file.""" | |
| path = Path(path) | |
| path.parent.mkdir(parents=True, exist_ok=True) | |
| with path.open('x', encoding='utf-8', newline='\n') as stream: | |
| stream.write(json.dumps(value, indent=2, ensure_ascii=False, allow_nan=False) + '\n') | |