benchloop-client 0.2.20__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- benchloop_client-0.2.20/.gitignore +15 -0
- benchloop_client-0.2.20/.python-version +1 -0
- benchloop_client-0.2.20/PKG-INFO +144 -0
- benchloop_client-0.2.20/README.md +132 -0
- benchloop_client-0.2.20/benchloop-cli-design.md +322 -0
- benchloop_client-0.2.20/bmcli_examples.sh +208 -0
- benchloop_client-0.2.20/pyproject.toml +35 -0
- benchloop_client-0.2.20/src/aliyun/bmcli/__init__.py +9 -0
- benchloop_client-0.2.20/src/aliyun/bmcli/__main__.py +26 -0
- benchloop_client-0.2.20/src/aliyun/bmcli/cli.py +138 -0
- benchloop_client-0.2.20/src/aliyun/bmcli/client.py +179 -0
- benchloop_client-0.2.20/src/aliyun/bmcli/commands/__init__.py +1 -0
- benchloop_client-0.2.20/src/aliyun/bmcli/commands/_common.py +84 -0
- benchloop_client-0.2.20/src/aliyun/bmcli/commands/ap_cmd.py +1029 -0
- benchloop_client-0.2.20/src/aliyun/bmcli/commands/artifacts.py +365 -0
- benchloop_client-0.2.20/src/aliyun/bmcli/commands/group_data.py +195 -0
- benchloop_client-0.2.20/src/aliyun/bmcli/commands/jobs.py +174 -0
- benchloop_client-0.2.20/src/aliyun/bmcli/commands/metrics.py +257 -0
- benchloop_client-0.2.20/src/aliyun/bmcli/commands/overview.py +70 -0
- benchloop_client-0.2.20/src/aliyun/bmcli/commands/pull.py +348 -0
- benchloop_client-0.2.20/src/aliyun/bmcli/commands/report.py +227 -0
- benchloop_client-0.2.20/src/aliyun/bmcli/commands/tasks.py +174 -0
- benchloop_client-0.2.20/src/aliyun/bmcli/commands/trajectory.py +318 -0
- benchloop_client-0.2.20/src/aliyun/bmcli/config.py +152 -0
- benchloop_client-0.2.20/src/aliyun/bmcli/exit_codes.py +15 -0
- benchloop_client-0.2.20/src/aliyun/bmcli/ids.py +87 -0
- benchloop_client-0.2.20/src/aliyun/bmcli/output.py +167 -0
- benchloop_client-0.2.20/src/aliyun/bmcli/runtime.py +149 -0
- benchloop_client-0.2.20/src/aliyun/bmcli/version_check.py +199 -0
- benchloop_client-0.2.20/tests/__init__.py +0 -0
- benchloop_client-0.2.20/tests/conftest.py +59 -0
- benchloop_client-0.2.20/tests/test_cli_options.py +56 -0
- benchloop_client-0.2.20/tests/test_client.py +101 -0
- benchloop_client-0.2.20/tests/test_cmd_ap_cmd.py +790 -0
- benchloop_client-0.2.20/tests/test_cmd_artifacts.py +493 -0
- benchloop_client-0.2.20/tests/test_cmd_metrics.py +535 -0
- benchloop_client-0.2.20/tests/test_cmd_overview.py +104 -0
- benchloop_client-0.2.20/tests/test_cmd_pull.py +185 -0
- benchloop_client-0.2.20/tests/test_cmd_report.py +319 -0
- benchloop_client-0.2.20/tests/test_cmd_tasks_jobs.py +327 -0
- benchloop_client-0.2.20/tests/test_cmd_trajectory.py +534 -0
- benchloop_client-0.2.20/tests/test_config.py +231 -0
- benchloop_client-0.2.20/tests/test_exit_code_behavior.py +127 -0
- benchloop_client-0.2.20/tests/test_exit_codes.py +27 -0
- benchloop_client-0.2.20/tests/test_group_data.py +113 -0
- benchloop_client-0.2.20/tests/test_ids.py +135 -0
- benchloop_client-0.2.20/tests/test_runtime.py +20 -0
- benchloop_client-0.2.20/tests/test_version_check.py +138 -0
- benchloop_client-0.2.20/uv.lock +309 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.12
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: benchloop_client
|
|
3
|
+
Version: 0.2.20
|
|
4
|
+
Summary: Benchloop CLI — command line tool for benchmark analysis data (metrics, trajectory, reports, artifacts).
|
|
5
|
+
Requires-Python: >=3.10
|
|
6
|
+
Requires-Dist: httpx>=0.25.2
|
|
7
|
+
Requires-Dist: tomli>=1.1.0; python_version < '3.13'
|
|
8
|
+
Requires-Dist: typer>=0.9.4
|
|
9
|
+
Provides-Extra: dev
|
|
10
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
|
|
13
|
+
# benchloop-client (`bl`, `bmcli`)
|
|
14
|
+
|
|
15
|
+
Command line tool for fetching and downloading benchmark analysis data
|
|
16
|
+
(run metrics, trajectory, pre-analysis reports, task/job lists, and artifacts)
|
|
17
|
+
by `group_id` / `job_id`.
|
|
18
|
+
|
|
19
|
+
> PyPI package name is `benchloop_client`; the installed commands are `bl` and `bmcli`.
|
|
20
|
+
|
|
21
|
+
## Install package
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
pip install benchloop_client
|
|
25
|
+
|
|
26
|
+
bl --api-key $BENCH_LOOP_API_KEY overview get -j $JOB_ID
|
|
27
|
+
bl --api-key $BENCH_LOOP_API_KEY metrics get -j $JOB_ID
|
|
28
|
+
|
|
29
|
+
# Option 2: config ~/.benchloop/config.toml by cli, and run bl without --api-key option:
|
|
30
|
+
bl config set --api-key $BENCHLOOP_API_KEY --host https://benchmark-analysis.alibaba-inc.com
|
|
31
|
+
|
|
32
|
+
bl overview get -j $JOB_ID
|
|
33
|
+
bl metrics get -j $JOB_ID
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
The CLI checks PyPI for a newer release in the background at most once every
|
|
38
|
+
24 hours. Update notices include the current/latest versions and the upgrade
|
|
39
|
+
command. Notices are written only to stderr, so JSON output remains pipeable.
|
|
40
|
+
|
|
41
|
+
## Install and run from source
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
# with uv (recommended)
|
|
45
|
+
uv sync
|
|
46
|
+
uv run bl --help
|
|
47
|
+
|
|
48
|
+
# or editable install with pip
|
|
49
|
+
python -m venv .venv && source .venv/bin/activate
|
|
50
|
+
pip install -e .
|
|
51
|
+
bl --help
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Auth & config
|
|
55
|
+
|
|
56
|
+
Authentication uses a personal api key sent as the `X-API-Key` header.
|
|
57
|
+
|
|
58
|
+
Precedence: CLI flag > env var > `~/.benchloop/config.toml` > default.
|
|
59
|
+
|
|
60
|
+
- Env: `BENCHLOOP_API_KEY` (or `BENCHMARK_API_KEY`), `BENCHLOOP_HOST`, `BENCHLOOP_OUTPUT_DIR`
|
|
61
|
+
- Default host (prod): `https://benchmark-analysis.alibaba-inc.com`
|
|
62
|
+
- Pre host: `https://pre-benchmark-analysis.alibaba-inc.com`
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
bl config set --api-key $BENCHLOOP_API_KEY --host https://benchmark-analysis.alibaba-inc.com
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Usage
|
|
69
|
+
|
|
70
|
+
Two-segment `bl <resource> <action>` form. `get` prints a JSON array to
|
|
71
|
+
stdout (pipeable to `jq`); `download` writes the standard file layout.
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
bl metrics get -j J123 | jq '.[0]'
|
|
75
|
+
bl metrics download -g G1 --scope all -o ./out
|
|
76
|
+
bl trajectory download -g G1,G2 -o ./out
|
|
77
|
+
bl trajectory download --task-id TASK_ID -o ./out
|
|
78
|
+
bl report download -j J123 -o ./out
|
|
79
|
+
bl report get -g G123
|
|
80
|
+
bl report download -g G123 -o ./out
|
|
81
|
+
bl jobs get -g G1 --all # get supports --all (auto-paginate)
|
|
82
|
+
bl jobs download -g G1 # download is always full
|
|
83
|
+
bl artifacts download -g G1 -o ./out
|
|
84
|
+
bl pull -g G1 --with metrics,trajectory,jobs,artifacts -o ./out
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Group downloads always auto-paginate and include every Job in the Group. In
|
|
88
|
+
particular, `trajectory`, detailed `metrics`, `report`, and `artifacts` enumerate
|
|
89
|
+
the complete Job list instead of relying on the backend Group endpoints that
|
|
90
|
+
return at most 1000 Jobs. Existing aggregate files keep their original paths:
|
|
91
|
+
|
|
92
|
+
```text
|
|
93
|
+
out/G1/trajectory.json
|
|
94
|
+
out/G1/detail_metrics.json
|
|
95
|
+
out/G1_report.md
|
|
96
|
+
out/G1/J123_report.md
|
|
97
|
+
out/G1/J123/<artifact-name>
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
`report download -g` writes both the Group summary report and each Job report.
|
|
101
|
+
`pull -g` uses the same complete download behavior for every selected resource.
|
|
102
|
+
Use `--skip-existing` to resume file-based downloads after an interruption.
|
|
103
|
+
|
|
104
|
+
IDs accept repeated flags, comma-separated values, and `-` to read from stdin.
|
|
105
|
+
`-g` and `-j` are mutually exclusive in a single command. For trajectory
|
|
106
|
+
downloads, `--task-id` is a third mutually exclusive input mode.
|
|
107
|
+
|
|
108
|
+
### Download filtered trajectories by task ID
|
|
109
|
+
|
|
110
|
+
The benchmark analysis Jobs page can turn the current filters into a trajectory
|
|
111
|
+
download task. Copy the command shown by the page and run it locally:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
bl trajectory download --task-id TASK_ID -o ./out
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
The CLI fetches the task's complete job ID list, downloads job trajectories with
|
|
118
|
+
fixed concurrency, and prints count/ETA progress to stderr. It creates
|
|
119
|
+
`./out/TASK_ID_trajectories.zip`, containing one `<jobId>_trajectory.json` per
|
|
120
|
+
successful job and a `manifest.json` with total, success, and failure details.
|
|
121
|
+
If only some jobs fail, the successful files are still archived and the command
|
|
122
|
+
exits with code `1`. If every job fails, no empty ZIP is created.
|
|
123
|
+
|
|
124
|
+
## Exit codes
|
|
125
|
+
|
|
126
|
+
| code | meaning |
|
|
127
|
+
| ---- | ------- |
|
|
128
|
+
| 0 | all success |
|
|
129
|
+
| 1 | partial failure (some ids failed) |
|
|
130
|
+
| 2 | usage / parameter error |
|
|
131
|
+
| 3 | auth failure (HTTP 401) |
|
|
132
|
+
| 4 | network / timeout |
|
|
133
|
+
|
|
134
|
+
stdout carries data only; logs and progress go to stderr. `--quiet` suppresses
|
|
135
|
+
non-error logs, `--verbose` adds debug logs.
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
## Release new package
|
|
139
|
+
|
|
140
|
+
```
|
|
141
|
+
uv build
|
|
142
|
+
twine check dist/benchloop_client-0.1.7-py3-none-any.whl
|
|
143
|
+
twine upload dist/benchloop_client-0.1.7-py3-none-any.whl --verbose
|
|
144
|
+
```
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# benchloop-client (`bl`, `bmcli`)
|
|
2
|
+
|
|
3
|
+
Command line tool for fetching and downloading benchmark analysis data
|
|
4
|
+
(run metrics, trajectory, pre-analysis reports, task/job lists, and artifacts)
|
|
5
|
+
by `group_id` / `job_id`.
|
|
6
|
+
|
|
7
|
+
> PyPI package name is `benchloop_client`; the installed commands are `bl` and `bmcli`.
|
|
8
|
+
|
|
9
|
+
## Install package
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
pip install benchloop_client
|
|
13
|
+
|
|
14
|
+
bl --api-key $BENCH_LOOP_API_KEY overview get -j $JOB_ID
|
|
15
|
+
bl --api-key $BENCH_LOOP_API_KEY metrics get -j $JOB_ID
|
|
16
|
+
|
|
17
|
+
# Option 2: config ~/.benchloop/config.toml by cli, and run bl without --api-key option:
|
|
18
|
+
bl config set --api-key $BENCHLOOP_API_KEY --host https://benchmark-analysis.alibaba-inc.com
|
|
19
|
+
|
|
20
|
+
bl overview get -j $JOB_ID
|
|
21
|
+
bl metrics get -j $JOB_ID
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
The CLI checks PyPI for a newer release in the background at most once every
|
|
26
|
+
24 hours. Update notices include the current/latest versions and the upgrade
|
|
27
|
+
command. Notices are written only to stderr, so JSON output remains pipeable.
|
|
28
|
+
|
|
29
|
+
## Install and run from source
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
# with uv (recommended)
|
|
33
|
+
uv sync
|
|
34
|
+
uv run bl --help
|
|
35
|
+
|
|
36
|
+
# or editable install with pip
|
|
37
|
+
python -m venv .venv && source .venv/bin/activate
|
|
38
|
+
pip install -e .
|
|
39
|
+
bl --help
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Auth & config
|
|
43
|
+
|
|
44
|
+
Authentication uses a personal api key sent as the `X-API-Key` header.
|
|
45
|
+
|
|
46
|
+
Precedence: CLI flag > env var > `~/.benchloop/config.toml` > default.
|
|
47
|
+
|
|
48
|
+
- Env: `BENCHLOOP_API_KEY` (or `BENCHMARK_API_KEY`), `BENCHLOOP_HOST`, `BENCHLOOP_OUTPUT_DIR`
|
|
49
|
+
- Default host (prod): `https://benchmark-analysis.alibaba-inc.com`
|
|
50
|
+
- Pre host: `https://pre-benchmark-analysis.alibaba-inc.com`
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
bl config set --api-key $BENCHLOOP_API_KEY --host https://benchmark-analysis.alibaba-inc.com
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Usage
|
|
57
|
+
|
|
58
|
+
Two-segment `bl <resource> <action>` form. `get` prints a JSON array to
|
|
59
|
+
stdout (pipeable to `jq`); `download` writes the standard file layout.
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
bl metrics get -j J123 | jq '.[0]'
|
|
63
|
+
bl metrics download -g G1 --scope all -o ./out
|
|
64
|
+
bl trajectory download -g G1,G2 -o ./out
|
|
65
|
+
bl trajectory download --task-id TASK_ID -o ./out
|
|
66
|
+
bl report download -j J123 -o ./out
|
|
67
|
+
bl report get -g G123
|
|
68
|
+
bl report download -g G123 -o ./out
|
|
69
|
+
bl jobs get -g G1 --all # get supports --all (auto-paginate)
|
|
70
|
+
bl jobs download -g G1 # download is always full
|
|
71
|
+
bl artifacts download -g G1 -o ./out
|
|
72
|
+
bl pull -g G1 --with metrics,trajectory,jobs,artifacts -o ./out
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Group downloads always auto-paginate and include every Job in the Group. In
|
|
76
|
+
particular, `trajectory`, detailed `metrics`, `report`, and `artifacts` enumerate
|
|
77
|
+
the complete Job list instead of relying on the backend Group endpoints that
|
|
78
|
+
return at most 1000 Jobs. Existing aggregate files keep their original paths:
|
|
79
|
+
|
|
80
|
+
```text
|
|
81
|
+
out/G1/trajectory.json
|
|
82
|
+
out/G1/detail_metrics.json
|
|
83
|
+
out/G1_report.md
|
|
84
|
+
out/G1/J123_report.md
|
|
85
|
+
out/G1/J123/<artifact-name>
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
`report download -g` writes both the Group summary report and each Job report.
|
|
89
|
+
`pull -g` uses the same complete download behavior for every selected resource.
|
|
90
|
+
Use `--skip-existing` to resume file-based downloads after an interruption.
|
|
91
|
+
|
|
92
|
+
IDs accept repeated flags, comma-separated values, and `-` to read from stdin.
|
|
93
|
+
`-g` and `-j` are mutually exclusive in a single command. For trajectory
|
|
94
|
+
downloads, `--task-id` is a third mutually exclusive input mode.
|
|
95
|
+
|
|
96
|
+
### Download filtered trajectories by task ID
|
|
97
|
+
|
|
98
|
+
The benchmark analysis Jobs page can turn the current filters into a trajectory
|
|
99
|
+
download task. Copy the command shown by the page and run it locally:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
bl trajectory download --task-id TASK_ID -o ./out
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
The CLI fetches the task's complete job ID list, downloads job trajectories with
|
|
106
|
+
fixed concurrency, and prints count/ETA progress to stderr. It creates
|
|
107
|
+
`./out/TASK_ID_trajectories.zip`, containing one `<jobId>_trajectory.json` per
|
|
108
|
+
successful job and a `manifest.json` with total, success, and failure details.
|
|
109
|
+
If only some jobs fail, the successful files are still archived and the command
|
|
110
|
+
exits with code `1`. If every job fails, no empty ZIP is created.
|
|
111
|
+
|
|
112
|
+
## Exit codes
|
|
113
|
+
|
|
114
|
+
| code | meaning |
|
|
115
|
+
| ---- | ------- |
|
|
116
|
+
| 0 | all success |
|
|
117
|
+
| 1 | partial failure (some ids failed) |
|
|
118
|
+
| 2 | usage / parameter error |
|
|
119
|
+
| 3 | auth failure (HTTP 401) |
|
|
120
|
+
| 4 | network / timeout |
|
|
121
|
+
|
|
122
|
+
stdout carries data only; logs and progress go to stderr. `--quiet` suppresses
|
|
123
|
+
non-error logs, `--verbose` adds debug logs.
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
## Release new package
|
|
127
|
+
|
|
128
|
+
```
|
|
129
|
+
uv build
|
|
130
|
+
twine check dist/benchloop_client-0.1.7-py3-none-any.whl
|
|
131
|
+
twine upload dist/benchloop_client-0.1.7-py3-none-any.whl --verbose
|
|
132
|
+
```
|
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
# Benchloop CLI (`bl`, `bmcli`) 命令行设计
|
|
2
|
+
|
|
3
|
+
> 状态:设计稿,待确认。实现将放在独立 Python 模块 `aliyun.bmcli`(主命令 `bl`,兼容别名 `bmcli`)。
|
|
4
|
+
> 后端需扩展 `/openapi/**` 接口(个人 api_key 鉴权),尽量复用既有 `/openapi`。
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## 1. 目标与范围
|
|
9
|
+
|
|
10
|
+
提供给算法同学按 **单个或多个 group_id / job_id** 拉取基准评测数据的命令行工具:
|
|
11
|
+
|
|
12
|
+
- `run_metrics`(查询 / 下载)— Group(Overall/Detail) & Job
|
|
13
|
+
- `trajectory`(查询 / 下载)— Group & Job
|
|
14
|
+
- 预分析报告 report(查询 / 下载)— Group & Job
|
|
15
|
+
- Group / Task / Job 运行统计 overview(仅查询)
|
|
16
|
+
- Task 列表 / Job 列表(查询 / 下载)— Group
|
|
17
|
+
- Artifacts 产物(仅下载)— Group & Job
|
|
18
|
+
|
|
19
|
+
**鉴权**:个人 api_key(HTTP 头 `X-API-Key`),对应后端 `mcp_auth_tokens` → `work_no`。
|
|
20
|
+
|
|
21
|
+
**约定**:所有 `查询(get)` 返回 **JSON 数组**;即使只有一条数据,也包在数组里。
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## 2. 命令总体结构
|
|
26
|
+
|
|
27
|
+
统一采用 `名词(资源) + 动词` 的两段式:
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
bl <resource> <action> [ids...] [options]
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
- `action = get` → 查询,结果打印到 stdout(JSON 数组)
|
|
34
|
+
- `action = download`→ 下载,按规定的文件布局写入磁盘
|
|
35
|
+
|
|
36
|
+
按规格天然区分:`overview` 只有 `get`,`artifacts` 只有 `download`,其余资源两者都有。
|
|
37
|
+
|
|
38
|
+
| resource | get | download | 适用维度 |
|
|
39
|
+
| ------------ | :-: | :------: | ----------- |
|
|
40
|
+
| `metrics` | ✓ | ✓ | Group / Job |
|
|
41
|
+
| `trajectory` | ✓ | ✓ | Group / Job |
|
|
42
|
+
| `report` | ✓ | ✓ | Group / Job |
|
|
43
|
+
| `overview` | ✓ | — | Group / Job |
|
|
44
|
+
| `tasks` | ✓ | ✓ | Group |
|
|
45
|
+
| `jobs` | ✓ | ✓ | Group |
|
|
46
|
+
| `artifacts` | — | ✓ | Group / Job |
|
|
47
|
+
|
|
48
|
+
> 设计取舍:`get/download` 拆成子命令,而非用 `-o` 有无来切换——这样能精确表达「某资源只可查/只可下」,`bl <resource> --help` 也更清晰。
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## 3. ID 入参约定
|
|
53
|
+
|
|
54
|
+
group / job 用显式互斥语义的旗标,**可重复、可逗号分隔、可从 stdin/文件**:
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
-g, --group <id> Group ID,可重复或逗号分隔: -g G1 -g G2 / -g G1,G2
|
|
58
|
+
-j, --job <id> Job ID, 可重复或逗号分隔
|
|
59
|
+
-g - 从 stdin 读取(支持管道)
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
- 一条命令里 `-g` 与 `-j` 不同时出现(如 `metrics get -g G1 -j J9`)。
|
|
63
|
+
- 各资源对维度的支持见上表;传入不支持的维度时报参数错误。
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## 4. 全局选项(所有命令通用)
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
--api-key KEY 个人 api_key(优先级最高)
|
|
71
|
+
--host URL 覆盖后端 base URL
|
|
72
|
+
-o, --output-dir DIR download 输出根目录(默认当前目录 .)
|
|
73
|
+
--pretty / --no-pretty JSON 是否缩进(默认 pretty)
|
|
74
|
+
--timeout SEC 单请求超时(默认 300)
|
|
75
|
+
--retry N 失败重试次数(默认 2,指数退避)
|
|
76
|
+
-v, --verbose 调试日志到 stderr
|
|
77
|
+
-q, --quiet 只输出错误
|
|
78
|
+
--config PATH 指定配置文件路径
|
|
79
|
+
--version / --help
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
**配置与优先级**:`命令行旗标 > 环境变量 > 配置文件 > 默认值`
|
|
83
|
+
|
|
84
|
+
- 环境变量:`bmcli_API_KEY`、`bmcli_HOST`、`bmcli_OUTPUT_DIR`
|
|
85
|
+
- 配置文件:`~/.benchloop/config.toml`
|
|
86
|
+
|
|
87
|
+
```toml
|
|
88
|
+
# ~/.benchloop/config.toml
|
|
89
|
+
[profile]
|
|
90
|
+
# 线上: https://benchmark-analysis.alibaba-inc.com 预发: https://pre-benchmark-analysis.alibaba-inc.com
|
|
91
|
+
host = "https://benchmark-analysis.alibaba-inc.com"
|
|
92
|
+
api_key = "xxxxxxxx"
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## 5. 各命令详细设计
|
|
98
|
+
|
|
99
|
+
### 5.1 run_metrics — `bl metrics`
|
|
100
|
+
|
|
101
|
+
```
|
|
102
|
+
bl metrics get [-g GroupID...] [-j JobID...] [--scope overall|detail|all]
|
|
103
|
+
bl metrics download [-g GroupID...] [-j JobID...] [--scope overall|detail|all] [-o DIR]
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
- `--scope` 仅对 Group 生效(默认 `all`,即 overall + detail):
|
|
107
|
+
- `overall` → Group 汇总指标
|
|
108
|
+
- `detail` → Group 下每个 Job 的 run_metrics 聚合
|
|
109
|
+
- Job 维度忽略 `--scope`,直接取该 Job 的 run_metrics。
|
|
110
|
+
|
|
111
|
+
**下载文件布局**
|
|
112
|
+
|
|
113
|
+
| 维度 | 文件 |
|
|
114
|
+
| ----------- | --------------------------------- |
|
|
115
|
+
| Group overall | `{group_id}/overall_metrics.json` |
|
|
116
|
+
| Group detail | `{group_id}/detail_metrics.json` |
|
|
117
|
+
| Job | `{job_id}_run_metrics.json` |
|
|
118
|
+
|
|
119
|
+
### 5.2 trajectory — `bl trajectory`
|
|
120
|
+
|
|
121
|
+
```
|
|
122
|
+
bl trajectory get [-g GroupID...] [-j JobID...]
|
|
123
|
+
bl trajectory download [-g GroupID...] [-j JobID...] [-o DIR]
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
**下载文件布局**
|
|
127
|
+
|
|
128
|
+
| 维度 | 文件 |
|
|
129
|
+
| ----- | --------------------------- |
|
|
130
|
+
| Group | `{group_id}/trajectory.json` |
|
|
131
|
+
| Job | `{job_id}_trajectory.json` |
|
|
132
|
+
|
|
133
|
+
### 5.3 预分析报告 — `bl report`
|
|
134
|
+
|
|
135
|
+
```
|
|
136
|
+
bl report get [-g GroupID...] [-j JobID...]
|
|
137
|
+
bl report download [-g GroupID...] [-j JobID...] [-o DIR]
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
- `get` 时返回 JSON 数组。Job 报告包含 `fail_reason`、`sub_fail_reason`;Group 报告还包含组内 Job 的两级错误分布统计。
|
|
141
|
+
|
|
142
|
+
**下载文件布局**
|
|
143
|
+
|
|
144
|
+
| 维度 | 文件 |
|
|
145
|
+
| ----- | ------------------------- |
|
|
146
|
+
| Group | `{group_id}_report.md` |
|
|
147
|
+
| Job | `{job_id}_report.md` |
|
|
148
|
+
|
|
149
|
+
### 5.4 运行统计 overview — `bl overview`(仅查询)
|
|
150
|
+
|
|
151
|
+
```
|
|
152
|
+
bl overview get -g GroupID... --scope summary # Group Overview(eval_summary)
|
|
153
|
+
bl overview get -g GroupID... --scope tasks # Group Task Overview(组内 task 维度统计,eval_tasks)
|
|
154
|
+
bl overview get -g GroupID... # Group:summary + tasks(--scope all,默认)
|
|
155
|
+
bl overview get -j JobID... # Job Overview(jobs/{id} + jobs/stats)
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
- 仅 `get`,不提供下载;维度由 `-g`/`-j` 决定;Group 维度的 `--scope summary|tasks|all`(默认 all)与 `metrics get` 的 `--scope` 保持一致。输出 JSON 数组。
|
|
159
|
+
|
|
160
|
+
### 5.5 Task 列表 — `bl tasks`(Group)
|
|
161
|
+
|
|
162
|
+
```
|
|
163
|
+
bl tasks get -g GroupID... [--page N] [--page-size M] [--all] [--search ...] [--status ...]
|
|
164
|
+
bl tasks download -g GroupID... [-o DIR]
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
- `--all`:自动翻页拉全量(download 默认全量)。
|
|
168
|
+
- 文件:`{group_id}/task_list.json`
|
|
169
|
+
|
|
170
|
+
### 5.6 Job 列表 — `bl jobs`(Group)
|
|
171
|
+
|
|
172
|
+
```
|
|
173
|
+
bl jobs get -g GroupID... [--page N] [--page-size M] [--all]
|
|
174
|
+
[--template ...] [--status ...] [--instance-id ...]
|
|
175
|
+
bl jobs download -g GroupID... [-o DIR]
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
- 文件:`{group_id}/job_list.json`
|
|
179
|
+
|
|
180
|
+
### 5.7 Artifacts 产物 — `bl artifacts`(仅下载)
|
|
181
|
+
|
|
182
|
+
```
|
|
183
|
+
bl artifacts download [-g GroupID...] [-j JobID...] [-o DIR]
|
|
184
|
+
[--include GLOB] [--exclude GLOB] [--list-only]
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
- Job:下载该 Job 全部产物到 `{job_id}/` 目录。
|
|
188
|
+
- Group:下载组内所有 Job 产物到 `{group_id}/` 目录(接入 Lindorm)。
|
|
189
|
+
- `--list-only`:只列出产物清单不下载;`--include/--exclude` 按通配过滤。
|
|
190
|
+
- 后端返回 OSS 预签名 URL,CLI 负责并发下载与落盘。
|
|
191
|
+
|
|
192
|
+
**下载文件布局**
|
|
193
|
+
|
|
194
|
+
| 维度 | 路径 |
|
|
195
|
+
| ----- | ------------- |
|
|
196
|
+
| Job | `{job_id}/` |
|
|
197
|
+
| Group | `{group_id}/` |
|
|
198
|
+
|
|
199
|
+
### 5.8(可选)一键打包 — `bl pull`
|
|
200
|
+
|
|
201
|
+
便捷聚合命令:对给定 group/job 一次性拉取 metrics + trajectory + lists(+report/artifacts) 到上述布局。
|
|
202
|
+
|
|
203
|
+
```
|
|
204
|
+
bl pull -g GroupID... [-j JobID...] [--with metrics,trajectory,report,artifacts,tasks,jobs] [-o DIR]
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
## 6. 输出文件布局总览(download 根目录下)
|
|
210
|
+
|
|
211
|
+
```
|
|
212
|
+
<output-dir>/
|
|
213
|
+
├── {group_id}/
|
|
214
|
+
│ ├── overall_metrics.json
|
|
215
|
+
│ ├── detail_metrics.json
|
|
216
|
+
│ ├── trajectory.json
|
|
217
|
+
│ ├── task_list.json
|
|
218
|
+
│ ├── job_list.json
|
|
219
|
+
│ └── <artifacts...> # group 产物
|
|
220
|
+
├── {job_id}_run_metrics.json
|
|
221
|
+
├── {job_id}_trajectory.json
|
|
222
|
+
├── {job_id}_report.md
|
|
223
|
+
└── {job_id}/ # job 产物
|
|
224
|
+
└── <artifacts...>
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
## 7. 后端 `/openapi` 接口对照(复用 vs 待补充)
|
|
230
|
+
|
|
231
|
+
> 鉴权统一为 `X-API-Key`(既有机制:`mcp_auth_tokens` → `work_no`)。
|
|
232
|
+
|
|
233
|
+
| CLI 命令 | 复用既有 `/openapi` | 需新增 `/openapi` |
|
|
234
|
+
| ------------------------------ | -------------------------------------------- | ---------------------------------------------- |
|
|
235
|
+
| `metrics get/download -j` | `GET /openapi/metrics/{jobId}` ✅ | — |
|
|
236
|
+
| `metrics ... -g --scope overall` | `GET /openapi/groups/{groupId}/eval_summary` ✅ 或 `GET /openapi/metrics?group_id=` | (二选一,确认 overall 字段口径) |
|
|
237
|
+
| `metrics ... -g --scope detail` | 可基于 `GET /openapi/jobs?group_id=` + 逐 job `metrics/{jobId}` | 建议新增 `GET /openapi/groups/{groupId}/metrics/detail` 直接聚合 |
|
|
238
|
+
| `trajectory ... -j` | — | **新增** `GET /openapi/jobs/{jobId}/trajectory` |
|
|
239
|
+
| `trajectory ... -g` | — | **新增** `GET /openapi/groups/{groupId}/trajectory`(或复用 `trajectory/download` 任务流) |
|
|
240
|
+
| `report ... -j` | — | **新增** `GET /openapi/jobs/{jobId}/report` |
|
|
241
|
+
| `report ... -g` | — | **新增** `GET /openapi/groups/{groupId}/report` |
|
|
242
|
+
| `overview get -g --scope summary` | `GET /openapi/groups/{groupId}/eval_summary` ✅ | 视字段补充 |
|
|
243
|
+
| `overview get -g --scope tasks` | `GET /openapi/groups/{groupId}/eval_tasks` ✅(聚合口径)| 可能新增统计汇总端点 |
|
|
244
|
+
| `overview get -j` | `GET /openapi/jobs/{jobId}` ✅ + `GET /openapi/jobs/stats` ✅ | — |
|
|
245
|
+
| `tasks get/download -g` | `GET /openapi/groups/{groupId}/eval_tasks` ✅ | — |
|
|
246
|
+
| `jobs get/download -g` | `GET /openapi/jobs?group_id=&skip=&limit=` ✅ | — |
|
|
247
|
+
| `artifacts download -j` | — | **新增** `GET /openapi/jobs/{jobId}/artifacts`(返回预签名 URL 列表) |
|
|
248
|
+
| `artifacts download -g` | — | **新增** `GET /openapi/groups/{groupId}/artifacts`(分页,Lindorm) |
|
|
249
|
+
|
|
250
|
+
**待后端补充实现清单(汇总)**
|
|
251
|
+
|
|
252
|
+
1. `GET /openapi/jobs/{jobId}/trajectory`
|
|
253
|
+
2. `GET /openapi/groups/{groupId}/trajectory`
|
|
254
|
+
3. `GET /openapi/jobs/{jobId}/report`
|
|
255
|
+
4. `GET /openapi/groups/{groupId}/report`
|
|
256
|
+
5. `GET /openapi/jobs/{jobId}/artifacts`
|
|
257
|
+
6. `GET /openapi/groups/{groupId}/artifacts`
|
|
258
|
+
7. `GET /openapi/groups/{groupId}/metrics/detail`(detail 聚合,可选)
|
|
259
|
+
|
|
260
|
+
---
|
|
261
|
+
|
|
262
|
+
## 8. 行为约定
|
|
263
|
+
|
|
264
|
+
- **多 id**:使用内部固定并发数执行,结果数组合并;download 各自落盘。
|
|
265
|
+
- **返回数组**:`get` 始终输出数组;单条也包成单元素数组。
|
|
266
|
+
- **部分失败**:某 id 失败不阻断其它 id;汇总在结尾打印失败清单,退出码非 0。
|
|
267
|
+
- **退出码**:`0` 全部成功;`1` 部分失败;`2` 参数错误;`3` 鉴权失败(401);`4` 网络/超时。
|
|
268
|
+
- **stdout/stderr 分离**:数据走 stdout(可管道给 `jq`),日志/进度走 stderr。
|
|
269
|
+
- **幂等下载**:默认覆盖;`--skip-existing` 跳过已存在文件;`--list-only` 仅预览。
|
|
270
|
+
|
|
271
|
+
---
|
|
272
|
+
|
|
273
|
+
## 9. 打包与分发
|
|
274
|
+
|
|
275
|
+
- 模块:`aliyun.bmcli`,可执行入口 `bl` 与兼容别名 `bmcli`(`[project.scripts] bl = "aliyun.bmcli.__main__:main"`,`bmcli = "aliyun.bmcli.__main__:main"`)。
|
|
276
|
+
- 技术栈建议:Python 3.10+ + Typer/Click + httpx,`uv` + `hatchling` 打包(与现有 `bench_mcp` 工具链一致)。
|
|
277
|
+
- 安装:`uv tool install benchloop_client` 或 `pipx install benchloop_client`。
|
|
278
|
+
|
|
279
|
+
---
|
|
280
|
+
|
|
281
|
+
## 10. 用法示例
|
|
282
|
+
|
|
283
|
+
```bash
|
|
284
|
+
# 配置一次
|
|
285
|
+
bl config set --api-key $KEY --host https://benchmark-analysis.alibaba-inc.com
|
|
286
|
+
|
|
287
|
+
# 查询单个 job 的 run_metrics(数组输出,可接 jq)
|
|
288
|
+
bl metrics get -j J123 | jq '.[0].score'
|
|
289
|
+
|
|
290
|
+
# 下载一个 group 的 overall+detail 指标
|
|
291
|
+
bl metrics download -g G1 --scope all -o ./out
|
|
292
|
+
|
|
293
|
+
# 多个 group 的 trajectory 下载
|
|
294
|
+
bl trajectory download -g G1,G2 -o ./out
|
|
295
|
+
|
|
296
|
+
# job 的预分析报告
|
|
297
|
+
bl report download -j J123 -o ./out
|
|
298
|
+
|
|
299
|
+
# group 报告及组内错误分布
|
|
300
|
+
bl report get -g G1
|
|
301
|
+
bl report download -g G1 -o ./out
|
|
302
|
+
|
|
303
|
+
# group 的 job 列表(全量)
|
|
304
|
+
bl jobs download -g G1 --all
|
|
305
|
+
|
|
306
|
+
# 下载 group 下所有 job 产物
|
|
307
|
+
bl artifacts download -g G1 -o ./out
|
|
308
|
+
|
|
309
|
+
# 一键拉取
|
|
310
|
+
bl pull -g G1 --with metrics,trajectory,jobs,artifacts -o ./out
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
---
|
|
314
|
+
|
|
315
|
+
## 11. 其他问题
|
|
316
|
+
|
|
317
|
+
1. `overall metrics` 是 Group 页面 Run_Metrics 下面显示的统计的 metrics 数据.
|
|
318
|
+
2. `metrics detail` CLI 端循环按照 group_id 分页拉取
|
|
319
|
+
3. `overview task`(Group Task Overview)统计口径与现有 `eval_tasks` 的差异。
|
|
320
|
+
4. trajectory(尤其 group 级,数据量大)走「同步返回」还是「异步下载任务」模式。
|
|
321
|
+
5. artifacts group 级量大时是否需要断点续传 / 限速。
|
|
322
|
+
6. api_key 是否复用 `mcp_auth_tokens`,还是单独签发体系。
|