# modelhub-agent-contrib ModelHub XC(信创模盒)**适配智能体** Phase1 本地骨架。 > **不代注册;Victor 已批准队列闸门 live 代提。** 发布智能体本身 **不得分**。积分来自验证通过的适配(`verify_pass` / `verifyResult==1`),数字一律 **待平台核实**。 > 冲突裁决:**适配 W1 优先**;本仓默认 live 开启,仅在实时验证队列低于阈值时提交。 ## 契约要点 | 项 | 值 | |----|-----| | 端口 | 8080 | | 健康检查 | `GET /health` → `{"status":"ok"}` | | 启动 | **必须**有非空 `STRATEGY_ID`,否则 exit ≠0 | | Live | 默认开启;`ALLOW_LIVE_SUBMIT=0` 为停交开关;必须提供 `STRATEGY_ID` | | Base 镜像 | 平台 `xc_agent_platform/python:3.11-slim`(保留 FROM) | Tag `v0.2.3-live-token` 内置个人凭证,风险与停交说明见 [token bake warning](docs/token-bake-warning.md)。 Victor 的确认已内置,`LIVE_CONFIRM` 仍接受但不再必需。每次 task/add 前, 通过 Xc-Token 全量分页读取 onlyMine task/page;非终态计入队列,读取失败停交。 `LIVE_QUEUE_THRESHOLD=95`(严格小于),`LIVE_MAX_SUBMITS_PER_CYCLE=3`, `LIVE_CYCLE_SECONDS=3600`(最小 60 秒)。环境队列提示仅可额外阻塞。 候选来自 `PENDING_SUBMIT_MD` / `PENDING_SUBMIT_TXT`,否则使用 `src/data/candidates.json`(随镜像内置);A verified_reuse → 其他 A → B。 禁提、重复、GPU 未映射、占位符候选跳过。按 try_next_gpus 顺序选择首个已映射且未提交的模型/GPU 对。去重合并远端全部状态的 model/GPU、内置 `src/data/submitted-ledger.json` 和进程内提交记录;永久拒绝对内置于 `src/data/reject-marks.json`,不依赖容器文件。A 允许同模型换 GPU;do-not-resubmit 模型跨 GPU 全禁。服务启动记录 remote/baked/marks 数量;每次提交前刷新远端,失败则 hold `ledger_rebuild_failed`。 只读平台预检默认开启(`LIVE_PRECHECK=0` 关闭),每周期最多 `LIVE_MAX_PRECHECKS_PER_CYCLE=30` 次;预检失败仍由 task/add 判定。用 `python3 scripts/sync_reject_marks.py ` 合并永久拒绝日志到 baked marks,重建镜像后保留;支持 `--dry-run`、`--marks` 和 `--date`。 凭证优先级:`EXTERNAL_SERVICE_TOKEN` → `XC_TOKEN_FILE` → `XC_TOKEN` → `MODELHUB_XC_TOKEN`;跳过空值和占位符。每周期只记录 source 环境变量名,使用 `Xc-Token` 请求头,不记录凭证值。 离线再生成:`python3 scripts/bake_candidates.py`、`python3 scripts/bake_ledger.py`,读取 `/workspace/modelhub-adapt` 本地文件;候选 342(A 46、B 296),ledger 206 对及 28 个模型禁提项。 配置优先 build-config,失败使用 sample 并记录来源及原因。token 缺失只 hold。 ## 快速开始 ```bash cd /workspace/modelhub-agent-contrib make test make smoke-health # 自动起本地 server(需 STRATEGY_ID,脚本可注入测试值) make dry-run # 写出 reports/dry-run-*.md make build # 需 Docker + 可达平台 base;失败见 docs/build-notes.md ``` 本地起服务: ```bash export STRATEGY_ID=local-dev export ALLOW_LIVE_SUBMIT=0 # 本地开发停交 python3 -m src.server # → http://127.0.0.1:8080/health ``` ## 目录 ```text Dockerfile Makefile README.md src/ # server / health / strategy / gate config/ # example.env, candidates.example.json scripts/ # smoke_health.py, dry_run.py, tag_release.py reports/ # dry-run 输出(gitignore) docs/ # 契约 / runbook / kickoff / issues tests/ # stdlib unittest ``` ## Makefile 目标 - `test` / `build` / `smoke-health` / `dry-run` - **没有** `register` / `submit` / `deploy` / `push` ## 文档 - [`docs/kickoff-for-victor.md`](docs/kickoff-for-victor.md) — 一页开工 + 验收勾选 - [`docs/platform-contract-agent.md`](docs/platform-contract-agent.md) — 契约表 - [`docs/register-runbook.md`](docs/register-runbook.md) — 仅人工注册 - [`docs/api-probe-design.md`](docs/api-probe-design.md) — 写接口禁止代调 - [`docs/diff-vs-demo.md`](docs/diff-vs-demo.md) — 对照官方 demo - [`docs/issues.md`](docs/issues.md) — M0–M4 / Phase 清单 - [`docs/build-notes.md`](docs/build-notes.md) — 镜像构建说明 ## 资源声明 按平台量级设计:约 **100m–1 CPU / 256–512Mi**。 ## 许可与边界 本仓库用于 Victor 本地/Gitea 交付。Victor 已批准上述队列闸门自动提交;不自动注册。 `make dry-run-pending` 仍仅生成草稿;测试全部 mock 平台接口。 成功指标统一为 `verify_pass`(`verifyResult==1`,验证通过);任务 status 为 `success` 但 `verifyResult==-1` 属于验证失败,积分为 0。 每轮 live 在凭证解析后记录一次 `[live] stats total=N queue=N verify_pass=N verify_fail=N failed=N unknown=N points=X`;读取失败则记录 `[live] stats unavailable reason=<安全原因>`,提交仍由原队列闸门决定。`GET /status` 保留凭证存在布尔值,新增 `success_metric: "verify_pass"` 和 `stats`:最近成功读取的上述数字及 `updated_at`(epoch 秒),尚未读取时为 null。queue 按未终结状态计数;积分仅累计 verify_pass 的有效数字。 `ALL_TASKS_FOOTHOLD=1` 可启用全部任务落点(默认 `0`):只读取通过、失败、running 三桶,硬顶 3/3/2 页、每页 ≤100、单请求 ≤5 秒、总读取 ≤20 秒。任一桶错误整轮回退原候选,stderr 输出固定原因码与分页/截断计数。目标卡只扣除切片中已观察的卡;切片不保证全站覆盖、最新排序、已下载或零重复排队,仍保留原队列门控、marks 与 precheck。上限可用 `ALL_TASKS_MAX_PAGES_PASS/FAIL/RUNNING`、`ALL_TASKS_PAGE_SIZE` 调低,不能调高硬顶。