Spaces:
Runtime error
Runtime error
| #!/usr/bin/env python3 | |
| from __future__ import annotations | |
| import argparse | |
| import json | |
| import os | |
| import subprocess | |
| import sys | |
| from datetime import datetime, timezone | |
| from pathlib import Path | |
| from typing import Any | |
| ROOT = Path(__file__).resolve().parents[1] | |
| for candidate in (ROOT / 'src', ROOT): | |
| if candidate.is_dir() and str(candidate) not in sys.path: | |
| sys.path.insert(0, str(candidate)) | |
| from app_kit.tracing import canonicalize_trace_payload | |
| SCHEMA_FIELDS = ['timestamp', 'inputs', 'parsed_outputs', 'model_name', 'model_id', 'adapter_name', 'generation_stats', 'checkpoint_path', 'checkpoint_source'] | |
| def _relative_or_absolute(path: Path, root: Path) -> str: | |
| try: | |
| return str(path.resolve().relative_to(root.resolve())) | |
| except Exception: | |
| return str(path.resolve()) | |
| def discover_trace_files(traces_root: str | Path) -> list[Path]: | |
| root = Path(traces_root).expanduser() | |
| if not root.exists(): | |
| raise FileNotFoundError(f'Trace directory not found: {root}') | |
| if root.is_file(): | |
| return [root] | |
| if root.name == 'traces': | |
| candidates = [path for path in sorted(root.glob('*.json')) if path.is_file()] | |
| else: | |
| candidates = [path for path in sorted(root.rglob('traces/*.json')) if path.is_file()] | |
| return candidates | |
| def default_output_dir(repo_root: str | Path, repo_name: str | None = None, today: str | None = None) -> Path: | |
| root = Path(repo_root).expanduser() | |
| repo_name = repo_name or root.name | |
| today = today or datetime.now(timezone.utc).date().isoformat() | |
| return root / 'artifacts' / 'verification' / today / 'sharing_is_caring' / repo_name | |
| def build_dataset_row(trace_file: Path, repo_root: Path, repo_name: str) -> dict[str, Any]: | |
| trace_payload = json.loads(trace_file.read_text(encoding='utf-8')) | |
| trace = canonicalize_trace_payload(trace_payload) | |
| row: dict[str, Any] = { | |
| 'repo_name': repo_name, | |
| 'source_trace_path': _relative_or_absolute(trace_file, repo_root), | |
| 'timestamp': trace['timestamp'], | |
| 'inputs': trace['inputs'], | |
| 'parsed_outputs': trace['parsed_outputs'], | |
| 'model_name': trace['model_name'], | |
| 'kind': trace.get('kind', 'trace'), | |
| } | |
| for key in ('project', 'pack_id', 'pack_name', 'pack_path', 'model_id', 'adapter_name', 'checkpoint_path', 'checkpoint_source', 'generation_stats'): | |
| value = trace.get(key) | |
| if value not in (None, '', [], {}, ()): | |
| row[key] = value | |
| return row | |
| def materialize_dataset( | |
| traces_dir: str | Path, | |
| output_dir: str | Path | None = None, | |
| repo_root: str | Path | None = None, | |
| repo_name: str | None = None, | |
| today: str | None = None, | |
| ) -> dict[str, Any]: | |
| traces_dir = Path(traces_dir).expanduser() | |
| repo_root = Path(repo_root).expanduser() if repo_root is not None else ROOT | |
| repo_name = repo_name or repo_root.name | |
| today = today or datetime.now(timezone.utc).date().isoformat() | |
| output_dir = Path(output_dir).expanduser() if output_dir is not None else default_output_dir(repo_root, repo_name, today) | |
| trace_files = discover_trace_files(traces_dir) | |
| if not trace_files: | |
| raise FileNotFoundError(f'No trace JSON files found under {traces_dir}') | |
| rows = [build_dataset_row(trace_file, repo_root=repo_root, repo_name=repo_name) for trace_file in trace_files] | |
| rows.sort(key=lambda row: row['source_trace_path']) | |
| output_dir.mkdir(parents=True, exist_ok=True) | |
| dataset_jsonl = output_dir / 'dataset.jsonl' | |
| metadata_json = output_dir / 'dataset-metadata.json' | |
| with dataset_jsonl.open('w', encoding='utf-8') as handle: | |
| for row in rows: | |
| handle.write(json.dumps(row, ensure_ascii=False, sort_keys=True) + '\n') | |
| metadata = { | |
| 'repo_name': repo_name, | |
| 'repo_root': str(repo_root), | |
| 'source_traces_dir': str(traces_dir), | |
| 'source_trace_count': len(trace_files), | |
| 'records_written': len(trace_files), | |
| 'source_trace_files': [row['source_trace_path'] for row in rows], | |
| 'generated_date': today, | |
| 'schema_fields': SCHEMA_FIELDS, | |
| 'output_files': { | |
| 'dataset_jsonl': dataset_jsonl.name, | |
| 'metadata_json': metadata_json.name, | |
| }, | |
| } | |
| metadata_json.write_text(json.dumps(metadata, indent=2, ensure_ascii=False, sort_keys=True), encoding='utf-8') | |
| return { | |
| 'repo_name': repo_name, | |
| 'repo_root': repo_root, | |
| 'source_traces_dir': traces_dir, | |
| 'trace_files': trace_files, | |
| 'source_trace_count': len(trace_files), | |
| 'records_written': len(trace_files), | |
| 'output_dir': output_dir, | |
| 'dataset_jsonl': dataset_jsonl, | |
| 'metadata_json': metadata_json, | |
| } | |
| def _run_git(args: list[str], cwd: Path) -> subprocess.CompletedProcess[str]: | |
| proc = subprocess.run(['git', *args], cwd=cwd, text=True, capture_output=True) | |
| if proc.returncode != 0: | |
| output = (proc.stdout + '\n' + proc.stderr).strip() | |
| raise RuntimeError(f"git {' '.join(args)} failed in {cwd}: {output}") | |
| return proc | |
| def build_hf_git_url(repo_id: str, token: str) -> str: | |
| return f'https://__token__:{token}@huggingface.co/datasets/{repo_id}.git' | |
| def git_push_dataset(output_dir: str | Path, remote_url: str, branch: str = 'main') -> dict[str, Any]: | |
| output_dir = Path(output_dir).expanduser() | |
| if not (output_dir / '.git').exists(): | |
| _run_git(['init', '-b', branch], cwd=output_dir) | |
| _run_git(['config', 'user.name', 'Hermes Trace Sharer'], cwd=output_dir) | |
| _run_git(['config', 'user.email', 'trace-sharer@example.com'], cwd=output_dir) | |
| _run_git(['add', 'dataset.jsonl', 'dataset-metadata.json'], cwd=output_dir) | |
| commit = subprocess.run( | |
| ['git', 'commit', '-m', 'Share traces to Hugging Face Dataset'], | |
| cwd=output_dir, | |
| text=True, | |
| capture_output=True, | |
| ) | |
| commit_output = (commit.stdout + '\n' + commit.stderr).strip().lower() | |
| if commit.returncode != 0 and 'nothing to commit' not in commit_output: | |
| raise RuntimeError(f'git commit failed in {output_dir}: {commit_output}') | |
| push = subprocess.run( | |
| ['git', 'push', remote_url, f'HEAD:{branch}'], | |
| cwd=output_dir, | |
| text=True, | |
| capture_output=True, | |
| ) | |
| if push.returncode != 0: | |
| output = (push.stdout + '\n' + push.stderr).strip() | |
| raise RuntimeError(f'git push failed in {output_dir}: {output}') | |
| return { | |
| 'pushed': True, | |
| 'branch': branch, | |
| } | |
| def push_to_hf_dataset(output_dir: str | Path, repo_id: str, token: str, branch: str = 'main') -> dict[str, Any]: | |
| return git_push_dataset(output_dir, build_hf_git_url(repo_id, token), branch=branch) | |
| def main(argv: list[str] | None = None) -> int: | |
| parser = argparse.ArgumentParser(description='Materialize and optionally share traces as a Hugging Face Dataset bundle') | |
| parser.add_argument('traces_dir', nargs='?', default='.', help='Local trace directory or repo root to scan for trace JSON files') | |
| parser.add_argument('--output-dir', default=None, help='Optional output directory for the materialized dataset bundle') | |
| parser.add_argument('--repo-id', default=os.environ.get('HF_DATASET_REPO'), help='Hugging Face dataset repo id (namespace/name) for --push') | |
| parser.add_argument('--branch', default='main', help='Target branch when pushing') | |
| parser.add_argument('--push', action='store_true', help='Commit and push to Hugging Face when HF_TOKEN is present') | |
| parser.add_argument('--dry-run', action='store_true', help='Force local-only materialization even if --push is supplied') | |
| args = parser.parse_args(argv) | |
| materialized = materialize_dataset(args.traces_dir, output_dir=args.output_dir, repo_root=ROOT, repo_name=ROOT.name) | |
| push_status: dict[str, Any] = { | |
| 'attempted': False, | |
| 'pushed': False, | |
| 'reason': 'local materialization only', | |
| } | |
| if args.push and not args.dry_run: | |
| repo_id = args.repo_id | |
| token = os.environ.get('HF_TOKEN') or os.environ.get('HUGGINGFACE_HUB_TOKEN') | |
| push_status['attempted'] = True | |
| if not repo_id: | |
| push_status['reason'] = 'HF dataset repo id missing; pass --repo-id or set HF_DATASET_REPO' | |
| elif not token: | |
| push_status['reason'] = 'HF_TOKEN missing; local materialization only' | |
| else: | |
| push_status = { | |
| 'attempted': True, | |
| 'pushed': True, | |
| 'repo_id': repo_id, | |
| 'branch': args.branch, | |
| **push_to_hf_dataset(materialized['output_dir'], repo_id, token, branch=args.branch), | |
| } | |
| elif args.push and args.dry_run: | |
| push_status = { | |
| 'attempted': False, | |
| 'pushed': False, | |
| 'reason': 'dry-run requested', | |
| } | |
| summary = { | |
| 'repo_name': materialized['repo_name'], | |
| 'records_written': materialized['source_trace_count'], | |
| 'output_dir': str(materialized['output_dir']), | |
| 'dataset_jsonl': str(materialized['dataset_jsonl']), | |
| 'metadata_json': str(materialized['metadata_json']), | |
| 'trace_files': [str(path) for path in materialized['trace_files']], | |
| 'push': push_status, | |
| } | |
| print(json.dumps(summary, indent=2, ensure_ascii=False, sort_keys=True)) | |
| return 0 | |
| if __name__ == '__main__': | |
| raise SystemExit(main()) | |