Initial commit
This commit is contained in:
@@ -0,0 +1,131 @@
|
||||
"""Static compilation entry: ensure a model Profile, then compile Skills."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
from pathlib import Path
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
from tqdm import tqdm
|
||||
|
||||
from scripts.provider_router import parse_model_reference
|
||||
|
||||
from .compiler.compiler import compile_input
|
||||
from .profile_generation.pipeline import ensure_profile
|
||||
|
||||
|
||||
class ConsoleProgress:
|
||||
def __init__(self, enabled: bool):
|
||||
self.enabled = enabled
|
||||
self.percent = 0
|
||||
self.bar = tqdm(
|
||||
total=100,
|
||||
desc="starting",
|
||||
unit="%",
|
||||
dynamic_ncols=True,
|
||||
file=sys.stderr,
|
||||
disable=not enabled,
|
||||
)
|
||||
|
||||
def update(self, percent: int, message: str) -> None:
|
||||
if not self.enabled:
|
||||
return
|
||||
target = max(self.percent, min(100, percent))
|
||||
self.bar.set_description_str(message, refresh=False)
|
||||
self.bar.update(target - self.percent)
|
||||
self.bar.refresh()
|
||||
self.percent = target
|
||||
|
||||
def close(self) -> None:
|
||||
self.bar.close()
|
||||
|
||||
|
||||
def _provider_model(value: str) -> str:
|
||||
try:
|
||||
return parse_model_reference(value).value
|
||||
except ValueError as exc:
|
||||
raise argparse.ArgumentTypeError(str(exc)) from exc
|
||||
|
||||
|
||||
def build_parser() -> argparse.ArgumentParser:
|
||||
parser = argparse.ArgumentParser(
|
||||
prog="static-compile",
|
||||
description=(
|
||||
"静态编译入口:复用或生成目标模型画像,然后将输入 Skill 编译为模型适配产物。"
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
"--model",
|
||||
required=True,
|
||||
type=_provider_model,
|
||||
help="Target model whose profile the Skill is compiled for.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--external-model",
|
||||
type=_provider_model,
|
||||
help="External semantic-planning model required by hybrid mode.",
|
||||
)
|
||||
parser.add_argument("--input", required=True, type=Path)
|
||||
parser.add_argument("--out-root", required=True, type=Path)
|
||||
parser.add_argument(
|
||||
"--mode", choices=("deterministic", "hybrid"), default="deterministic"
|
||||
)
|
||||
parser.add_argument("--allow-deterministic-fallback", action="store_true")
|
||||
parser.add_argument("--refresh-profile", action="store_true")
|
||||
parser.add_argument("--force", action="store_true")
|
||||
parser.add_argument("--dry-run", action="store_true")
|
||||
parser.add_argument("--no-progress", action="store_true")
|
||||
return parser
|
||||
|
||||
|
||||
def static_compile(args: argparse.Namespace) -> int:
|
||||
if args.mode == "hybrid" and not args.dry_run and not args.external_model:
|
||||
raise ValueError("--external-model is required when --mode hybrid")
|
||||
|
||||
profile_path, generated = ensure_profile(
|
||||
args.model,
|
||||
refresh=args.refresh_profile,
|
||||
)
|
||||
action = "Generated" if generated else "Reusing"
|
||||
print(f"{action} model profile: {profile_path}")
|
||||
|
||||
progress = ConsoleProgress(not args.no_progress and not args.dry_run)
|
||||
try:
|
||||
results = compile_input(
|
||||
args.input,
|
||||
profile_path,
|
||||
args.out_root,
|
||||
mode=args.mode,
|
||||
annotator_model=args.external_model,
|
||||
allow_deterministic_fallback=args.allow_deterministic_fallback,
|
||||
dry_run=args.dry_run,
|
||||
force=args.force,
|
||||
progress=progress.update,
|
||||
)
|
||||
finally:
|
||||
progress.close()
|
||||
|
||||
if args.dry_run:
|
||||
print(json.dumps([item.report for item in results], ensure_ascii=False, indent=2))
|
||||
return 0
|
||||
|
||||
failed = False
|
||||
for result in results:
|
||||
status = result.report["status"]
|
||||
if status == "failed":
|
||||
print(f"failed: {result.skill_name}: {result.report.get('error', 'unknown error')}")
|
||||
else:
|
||||
print(f"{status}: {result.skill_name} -> {result.output_dir}")
|
||||
failed |= status in {"rolled_back", "failed"}
|
||||
return 1 if failed else 0
|
||||
|
||||
|
||||
def main(argv: list[str] | None = None) -> int:
|
||||
parser = build_parser()
|
||||
args = parser.parse_args(argv)
|
||||
try:
|
||||
return static_compile(args)
|
||||
except (OSError, RuntimeError, ValueError, subprocess.CalledProcessError) as error:
|
||||
parser.exit(1, f"error: {error}\n")
|
||||
Reference in New Issue
Block a user