Files

89 lines
4.7 KiB
Python
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
"""Read-only Phase2 pending draft report. Token-resolvable build-config first; explicit sample fallback."""
import json
import os
import sys
from datetime import datetime
from pathlib import Path
from zoneinfo import ZoneInfo
ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT))
from src.pending_pool import build_ordered_candidates, input_path, experience_order
from src.config_params import build_config_params_with_meta, SOURCE, GAP
from src.queue_depth import queue_depth
from src.task_add_client import build_payload
TZ = ZoneInfo('Asia/Shanghai')
def _load_candidates(path):
data = json.loads(path.read_text())
return data if isinstance(data, list) else list(data['candidates'])
def _render(candidates, ts, src):
candidates = [c for c in candidates if not os.environ.get('PENDING_SECTION') or
c.get('section', 'B') == os.environ['PENDING_SECTION'].strip().upper()]
depth = queue_depth()
lines = [f'# 代提候选 / 需 Victor 确认 — Dry-run — {ts} (Asia/Shanghai)', '',
'> 模式:dry-run;仅配置生成 API;无任务提交;需 Victor 人工提交/确认',
'> 积分:待平台核实', '> perf_order=unset;order_source=experience(经验序 / 待平台核实)',
f'> configParams source: {SOURCE}', '> API foothold evidence: GAP (not wired)', f'> {GAP}', '',
'## A→B 顺序草稿', '', f'输入:{src};候选条数:{len(candidates)}',
f'队列深度:{depth if depth is not None else "未知,需人工确认"}',
'队列≥95:禁 live;适配 W1 优先,不抢空位。', '']
if depth is not None and depth >= 95:
lines.extend(['> **禁 live / 队列≥95**', ''])
for i, c in enumerate(candidates, 1):
model = c.get('model_address') or c.get('modelAddress') or c.get('model_id') or '<MODEL>'
gpus = experience_order(c.get('try_next_gpus', []))
target = gpus[0] if gpus else c.get('targetGpu', '<TARGET_GPU:需人工确认>')
status = c.get('status', 'needs_human')
lines.extend([f'### {i}. Section {c.get("section", "B")} — `{model}`', '',
f'状态:{status};needs_human={c.get("needs_human", True)}',
f'过滤:{c.get("skip_reason") or "名称硬门未命中;元数据/唯一性待人工核实"}', ''])
lines.extend([f'未适配卡(仅 pending 缺口):{", ".join(gpus) or "未提供,需确认"}',
'perf_order=unset;order_source=experience;天垓100 一般不扇出', ''])
yaml, meta = build_config_params_with_meta(target)
lines.extend([f'foothold_class={c.get("foothold_class", "unknown")}; evidence_source={c.get("evidence_source", "GAP")}; no_download={c.get("no_download", False)}',
'; '.join(f'{key}={value}' for key, value in meta.items()), ''])
draft = build_payload(model, target, 'vllm', strategy_id='<STRATEGY_ID>',
config_params=yaml)
# Display only; this truncated draft must never be submitted.
draft['configParams'] = draft['configParams'][:400] + '\n… [truncated; dry-run only]'
lines.extend(['build-config query: gpuType=<targetGpu>&framework=vllm&taskType=text-generation; POST empty body', 'POST 字段草稿(skipped 行禁止提交):', '```json', json.dumps(draft, ensure_ascii=False, indent=2), '```',
'需 Victor 人工提交/确认;积分:待平台核实', ''])
report = '\n'.join(lines)
# Defensive redaction even if an input happens to contain an injected credential.
secrets = [os.environ.get(k, '') for k in ('XC_TOKEN', 'MODELHUB_XC_TOKEN', 'EXTERNAL_SERVICE_TOKEN', 'Xc-Token')]
if os.environ.get('XC_TOKEN_FILE'):
try:
secrets.append(Path(os.environ['XC_TOKEN_FILE']).read_text().strip())
except OSError:
pass
for secret in secrets:
if secret:
report = report.replace(secret, '[REDACTED]')
return report
def main():
md = input_path('PENDING_SUBMIT_MD', 'pending-submit.md')
txt = input_path('PENDING_SUBMIT_TXT', 'pending-submit.txt')
if md.is_file() or txt.is_file():
src = md if md.is_file() else txt
candidates = build_ordered_candidates(md, txt)
else:
src = Path(os.environ.get('DRY_RUN_CANDIDATES', ROOT / 'config/candidates.example.json'))
candidates = _load_candidates(src)
now = datetime.now(TZ)
out = ROOT / 'reports' / f'dry-run-{now:%Y%m%d-%H%M%S}.md'
out.parent.mkdir(exist_ok=True)
out.write_text(_render(candidates, now.strftime('%Y-%m-%d %H:%M:%S'), src), encoding='utf-8')
print(f'Wrote {out}')
if __name__ == '__main__':
main()