refactor: split submit_sft_via_cml.sh into submit_sft.sh + submit_cml_eval.sh

- submit_sft.sh: pure SFT submission, prints JobID and exits (no embedded watcher)
- submit_cml_eval.sh: pure CML eval, reads workflow_id/version from config.yaml
- jupyter_runtime write_text: rewrite to use Contents API instead of terminal websocket
- SKILL.md: restrict trigger to explicit UI click only
- program.md: update §5.2 docs to reflect two-script workflow

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
hupenglong1
2026-05-25 17:21:42 +08:00
parent d2c221e2da
commit a3ab74b506
8 changed files with 328 additions and 186 deletions
+24
View File
@@ -7537,6 +7537,30 @@ def _compute_kpis(
if run_max is not None
else None
)
# Fallback: max runDic 可能命中 R{n} retry 轮(cml 还在 runninglark_template
# 没产出),让 KPI 全部空白。这时回退到 state 里最新一个 `cml=complete` 的
# 那一轮的 runDic — baseline / 上一轮成功 eval 的指标至少能显示出来。
if metrics is None:
per_round = _resolve_run_dic_per_round(state_entries)
for entry in reversed(state_entries):
if entry.get('step') != 'cml' or entry.get('status') != 'complete':
continue
rid = entry.get('run_id')
if not isinstance(rid, str):
continue
fallback_run = per_round.get(rid.strip())
if fallback_run is None or fallback_run == run_max:
continue
metrics = _read_workflow_metric_diff(
fallback_run,
agent_state=agent_state,
account_id=account_id,
session_id=session_id,
)
if metrics is not None:
run_max = fallback_run
run_id_value = str(fallback_run)
break
_enrich_metrics_from_eval_output(metrics, target_set)
target_metric = _format_metric_value(metrics, 'target_set_pass_rate')
overall_metric = _format_metric_value(metrics, 'overall_car_pass_rate')