@zhuoyuezs/ml-platform 0.2.2 → 0.2.3-alpha.1
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.
- package/DEVELOPMENT.md +2 -1
- package/README.md +6 -4
- package/checksums.json +41 -26
- package/package.json +1 -1
- package/release.json +17 -11
- package/runtime/business-client/README.md +100 -0
- package/runtime/business-client/src/catalog.js +1 -1
- package/runtime/business-client/src/cli.js +82 -0
- package/runtime/business-client/src/http.js +27 -1
- package/skills/data-source-exploration/SKILL.md +5 -0
- package/skills/feature-management/SKILL.md +8 -1
- package/skills/feature-management/assets/catalog-template/parameters/example_temperature.v1.json +1 -0
- package/skills/feature-management/references/contracts.md +7 -1
- package/skills/model-deployment-management/SKILL.md +7 -0
- package/skills/model-lifecycle-management/SKILL.md +20 -0
- package/skills/model-lifecycle-management/references/discovery.md +11 -0
- package/skills/model-lifecycle-management/references/training-contracts.md +8 -5
- package/skills/model-lifecycle-management/references/training.md +2 -2
- package/skills/model-lifecycle-management/references/zero-shot-inference.md +67 -0
- package/skills/prediction-report-management/SKILL.md +80 -0
- package/skills/prediction-report-management/agents/openai.yaml +4 -0
package/DEVELOPMENT.md
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
- Skill 直接调用正式命令 `ml-platform`,不嵌入 CLI runtime。
|
|
11
11
|
- 正式 npm 包只有 `@zhuoyuezs/ml-platform`,正式 bin 只有 `ml-platform`。
|
|
12
12
|
- `business-client-js/src-ts/` 是 business CLI 的唯一 TypeScript 源码,`src/` 是供 Node.js 和
|
|
13
|
-
release payload 使用的编译输出;仓库 `skills/`
|
|
13
|
+
release payload 使用的编译输出;仓库 `skills/` 下五个受支持 Skill 是各自唯一源码。
|
|
14
14
|
- `npx @zhuoyuezs/ml-platform@<version> install` 是面向用户的统一安装入口;默认目标是 Codex
|
|
15
15
|
用户级 Skill,不要求额外安装参数。
|
|
16
16
|
- 管理命令默认输出简洁结果;Agent 和 CI 显式使用 `--json` 获取稳定结构化输出。
|
|
@@ -34,6 +34,7 @@ skills/feature-management/
|
|
|
34
34
|
skills/data-source-exploration/
|
|
35
35
|
skills/model-lifecycle-management/
|
|
36
36
|
skills/model-deployment-management/
|
|
37
|
+
skills/prediction-report-management/
|
|
37
38
|
npm/ml-platform/
|
|
38
39
|
npm/scripts/build_ml_platform_release.py
|
|
39
40
|
agent_poc/codex-host/
|
package/README.md
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# ML Platform
|
|
2
2
|
|
|
3
3
|
ML Platform 的 TypeScript CLI(编译为 Node.js JavaScript runtime)、`feature-management`、
|
|
4
|
-
`data-source-exploration`、`model-lifecycle-management
|
|
4
|
+
`data-source-exploration`、`model-lifecycle-management`、`model-deployment-management` 与
|
|
5
|
+
`prediction-report-management`
|
|
5
6
|
Agent Skill。CLI 与 Skill 由同一个 npm
|
|
6
7
|
release 安装和升级,运行时不需要 Python 或 `uv`。
|
|
7
8
|
|
|
@@ -19,7 +20,7 @@ release 安装和升级,运行时不需要 Python 或 `uv`。
|
|
|
19
20
|
npx @zhuoyuezs/ml-platform@latest install
|
|
20
21
|
```
|
|
21
22
|
|
|
22
|
-
这条命令不需要额外参数。默认安装持久化的 `ml-platform`
|
|
23
|
+
这条命令不需要额外参数。默认安装持久化的 `ml-platform` 命令,并将五个 Skill 安装到
|
|
23
24
|
`~/.codex/skills/`,供当前用户的 Codex 使用。安装后重启终端和 Agent 会话。
|
|
24
25
|
|
|
25
26
|
只在当前项目使用 Skill 时,在项目根目录运行:
|
|
@@ -131,8 +132,9 @@ npx --yes --registry=https://registry.npmjs.org/ \
|
|
|
131
132
|
## 包内容
|
|
132
133
|
|
|
133
134
|
- 一份由 TypeScript 编译的 business CLI;
|
|
134
|
-
-
|
|
135
|
-
`model-lifecycle-management
|
|
135
|
+
- 五份纯 Skill:`feature-management`、`data-source-exploration`、
|
|
136
|
+
`model-lifecycle-management`、`model-deployment-management` 与
|
|
137
|
+
`prediction-report-management`;
|
|
136
138
|
- 显式安装、升级、状态、校验和回滚逻辑。
|
|
137
139
|
|
|
138
140
|
不包含 Codex CLI、Python business-client wheel、Agent Host、平台服务端、模型训练或 Kubernetes
|
package/checksums.json
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
"files": [
|
|
3
3
|
{
|
|
4
4
|
"path": "runtime/business-client/README.md",
|
|
5
|
-
"sha256": "sha256:
|
|
6
|
-
"size_bytes":
|
|
5
|
+
"sha256": "sha256:f03d10f0de78e4ff456a6718b5b74b7fd001598f5a5963985d97d0b99403c0a5",
|
|
6
|
+
"size_bytes": 12756
|
|
7
7
|
},
|
|
8
8
|
{
|
|
9
9
|
"path": "runtime/business-client/package-lock.json",
|
|
@@ -17,13 +17,13 @@
|
|
|
17
17
|
},
|
|
18
18
|
{
|
|
19
19
|
"path": "runtime/business-client/src/catalog.js",
|
|
20
|
-
"sha256": "sha256:
|
|
21
|
-
"size_bytes":
|
|
20
|
+
"sha256": "sha256:369259ccfef1b079acf616eca1dc0040dda61cfb4b69941d0fcca30a658cd549",
|
|
21
|
+
"size_bytes": 58749
|
|
22
22
|
},
|
|
23
23
|
{
|
|
24
24
|
"path": "runtime/business-client/src/cli.js",
|
|
25
|
-
"sha256": "sha256:
|
|
26
|
-
"size_bytes":
|
|
25
|
+
"sha256": "sha256:ecdc7d2e93323a4dd04514573219061f54db6583d955dfa82afc482abcd3335a",
|
|
26
|
+
"size_bytes": 66532
|
|
27
27
|
},
|
|
28
28
|
{
|
|
29
29
|
"path": "runtime/business-client/src/config.js",
|
|
@@ -32,13 +32,13 @@
|
|
|
32
32
|
},
|
|
33
33
|
{
|
|
34
34
|
"path": "runtime/business-client/src/http.js",
|
|
35
|
-
"sha256": "sha256:
|
|
36
|
-
"size_bytes":
|
|
35
|
+
"sha256": "sha256:517ad46944f3a4068a00a570dc09975c5b59de61b730e0acf8e009ee1f18c89d",
|
|
36
|
+
"size_bytes": 18865
|
|
37
37
|
},
|
|
38
38
|
{
|
|
39
39
|
"path": "skills/data-source-exploration/SKILL.md",
|
|
40
|
-
"sha256": "sha256:
|
|
41
|
-
"size_bytes":
|
|
40
|
+
"sha256": "sha256:11b20671ad81b42cd2ddb1cb146196b9f5ab15e962249e7e07cfa148c601e881",
|
|
41
|
+
"size_bytes": 4172
|
|
42
42
|
},
|
|
43
43
|
{
|
|
44
44
|
"path": "skills/data-source-exploration/agents/openai.yaml",
|
|
@@ -47,8 +47,8 @@
|
|
|
47
47
|
},
|
|
48
48
|
{
|
|
49
49
|
"path": "skills/feature-management/SKILL.md",
|
|
50
|
-
"sha256": "sha256:
|
|
51
|
-
"size_bytes":
|
|
50
|
+
"sha256": "sha256:1118aef3734fe14fd8f7d1074ff730340663e42565155bde984ab5b397c2da77",
|
|
51
|
+
"size_bytes": 33777
|
|
52
52
|
},
|
|
53
53
|
{
|
|
54
54
|
"path": "skills/feature-management/agents/openai.yaml",
|
|
@@ -97,8 +97,8 @@
|
|
|
97
97
|
},
|
|
98
98
|
{
|
|
99
99
|
"path": "skills/feature-management/assets/catalog-template/parameters/example_temperature.v1.json",
|
|
100
|
-
"sha256": "sha256:
|
|
101
|
-
"size_bytes":
|
|
100
|
+
"sha256": "sha256:b7e25965b0dc2d65a935b67d5f10d1192ad550ba90bae25d550bfdb5736b0d2d",
|
|
101
|
+
"size_bytes": 1523
|
|
102
102
|
},
|
|
103
103
|
{
|
|
104
104
|
"path": "skills/feature-management/references/commands.md",
|
|
@@ -107,8 +107,8 @@
|
|
|
107
107
|
},
|
|
108
108
|
{
|
|
109
109
|
"path": "skills/feature-management/references/contracts.md",
|
|
110
|
-
"sha256": "sha256:
|
|
111
|
-
"size_bytes":
|
|
110
|
+
"sha256": "sha256:a9f6c8d6c8b1220a26a282f3ff73db54c6359372df02c322159087507ca0318d",
|
|
111
|
+
"size_bytes": 30894
|
|
112
112
|
},
|
|
113
113
|
{
|
|
114
114
|
"path": "skills/feature-management/references/operator-authoring.md",
|
|
@@ -127,8 +127,8 @@
|
|
|
127
127
|
},
|
|
128
128
|
{
|
|
129
129
|
"path": "skills/model-deployment-management/SKILL.md",
|
|
130
|
-
"sha256": "sha256:
|
|
131
|
-
"size_bytes":
|
|
130
|
+
"sha256": "sha256:e8419e4d83031248b40783674813bf3f5a98544f05ea3fbe056547ae47632016",
|
|
131
|
+
"size_bytes": 4397
|
|
132
132
|
},
|
|
133
133
|
{
|
|
134
134
|
"path": "skills/model-deployment-management/agents/openai.yaml",
|
|
@@ -152,8 +152,8 @@
|
|
|
152
152
|
},
|
|
153
153
|
{
|
|
154
154
|
"path": "skills/model-lifecycle-management/SKILL.md",
|
|
155
|
-
"sha256": "sha256:
|
|
156
|
-
"size_bytes":
|
|
155
|
+
"sha256": "sha256:9ad2428621b52a15a83dce34a2a95606d7d979017a227c0aeb8fe5c8acd5faa3",
|
|
156
|
+
"size_bytes": 5442
|
|
157
157
|
},
|
|
158
158
|
{
|
|
159
159
|
"path": "skills/model-lifecycle-management/agents/openai.yaml",
|
|
@@ -162,8 +162,8 @@
|
|
|
162
162
|
},
|
|
163
163
|
{
|
|
164
164
|
"path": "skills/model-lifecycle-management/references/discovery.md",
|
|
165
|
-
"sha256": "sha256:
|
|
166
|
-
"size_bytes":
|
|
165
|
+
"sha256": "sha256:ad4623e84b8d972357497a55df0aed84be5ada59ef197f6a217f19ce97821195",
|
|
166
|
+
"size_bytes": 5789
|
|
167
167
|
},
|
|
168
168
|
{
|
|
169
169
|
"path": "skills/model-lifecycle-management/references/evaluation.md",
|
|
@@ -177,13 +177,28 @@
|
|
|
177
177
|
},
|
|
178
178
|
{
|
|
179
179
|
"path": "skills/model-lifecycle-management/references/training-contracts.md",
|
|
180
|
-
"sha256": "sha256:
|
|
181
|
-
"size_bytes":
|
|
180
|
+
"sha256": "sha256:26ca0f0b8bc212bd30ea69b0a0afc169554681a16317ebb054d9147ae9c0587a",
|
|
181
|
+
"size_bytes": 14994
|
|
182
182
|
},
|
|
183
183
|
{
|
|
184
184
|
"path": "skills/model-lifecycle-management/references/training.md",
|
|
185
|
-
"sha256": "sha256:
|
|
186
|
-
"size_bytes":
|
|
185
|
+
"sha256": "sha256:ae87837e5c315aa0fc9c02575213e1fd293f192ed43a1c68e9f8d08407becc48",
|
|
186
|
+
"size_bytes": 8235
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
"path": "skills/model-lifecycle-management/references/zero-shot-inference.md",
|
|
190
|
+
"sha256": "sha256:4ea224be54a7b0fc7754bdaa41df0f3b14c56f5134afc3951e91e59844108f90",
|
|
191
|
+
"size_bytes": 2350
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
"path": "skills/prediction-report-management/SKILL.md",
|
|
195
|
+
"sha256": "sha256:32abad9d9a152680d126cf1fa3df921a367a9ad9eb0aaaf3ce48b05538b4fbd5",
|
|
196
|
+
"size_bytes": 4365
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
"path": "skills/prediction-report-management/agents/openai.yaml",
|
|
200
|
+
"sha256": "sha256:fd86629700aa9a4f1ab985d87883162ab260f469d5059a516abcd1e3273d89fa",
|
|
201
|
+
"size_bytes": 241
|
|
187
202
|
}
|
|
188
203
|
],
|
|
189
204
|
"schema_version": "data_platform.ml_platform_checksums/v1"
|
package/package.json
CHANGED
package/release.json
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"entrypoint": "src/cli.js",
|
|
14
14
|
"name": "ml-platform",
|
|
15
15
|
"path": "runtime/business-client",
|
|
16
|
-
"sha256": "sha256:
|
|
16
|
+
"sha256": "sha256:eaa88929b414e386294287009b4ecb25e26d1eb39403469ef649af145b2208de",
|
|
17
17
|
"version": "0.8.3"
|
|
18
18
|
},
|
|
19
19
|
"policy_sha256": "sha256:02fbde0134696b78c0c365d6e0b76c9814227208da5b2b3d4e5dbd82dc4a3606",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"ml_data_platform.feature_set/v1",
|
|
26
26
|
"ml_data_platform.dataset_manifest/v1"
|
|
27
27
|
],
|
|
28
|
-
"release_version": "0.2.
|
|
28
|
+
"release_version": "0.2.3-alpha.1",
|
|
29
29
|
"runtime_requirements": {
|
|
30
30
|
"node": ">=18",
|
|
31
31
|
"os": [
|
|
@@ -38,27 +38,33 @@
|
|
|
38
38
|
"data-source-exploration": {
|
|
39
39
|
"path": "skills/data-source-exploration",
|
|
40
40
|
"requires_cli": ">=0.8.3 <0.9.0",
|
|
41
|
-
"revision": "0.2.
|
|
42
|
-
"sha256": "sha256:
|
|
41
|
+
"revision": "0.2.3-alpha.1",
|
|
42
|
+
"sha256": "sha256:2fa1e1802d799ee0c47b10263f2fde57b604e505fea5c98bfa23f51f382bbf69"
|
|
43
43
|
},
|
|
44
44
|
"feature-management": {
|
|
45
45
|
"path": "skills/feature-management",
|
|
46
46
|
"requires_cli": ">=0.8.3 <0.9.0",
|
|
47
|
-
"revision": "0.2.
|
|
48
|
-
"sha256": "sha256:
|
|
47
|
+
"revision": "0.2.3-alpha.1",
|
|
48
|
+
"sha256": "sha256:6dfa708172c3b5b23af75997c82a6d43bc2eb8ca67cc2275c8b95022455b0c42"
|
|
49
49
|
},
|
|
50
50
|
"model-deployment-management": {
|
|
51
51
|
"path": "skills/model-deployment-management",
|
|
52
52
|
"requires_cli": ">=0.8.3 <0.9.0",
|
|
53
|
-
"revision": "0.2.
|
|
54
|
-
"sha256": "sha256:
|
|
53
|
+
"revision": "0.2.3-alpha.1",
|
|
54
|
+
"sha256": "sha256:d3f3fe0e4a11b93d8f6f57758164aa236b84a49c1b9f0d0b700fd9d6d615a8d7"
|
|
55
55
|
},
|
|
56
56
|
"model-lifecycle-management": {
|
|
57
57
|
"path": "skills/model-lifecycle-management",
|
|
58
58
|
"requires_cli": ">=0.8.3 <0.9.0",
|
|
59
|
-
"revision": "0.2.
|
|
60
|
-
"sha256": "sha256:
|
|
59
|
+
"revision": "0.2.3-alpha.1",
|
|
60
|
+
"sha256": "sha256:8822fbec7037c2312d18b1d18648b60757fc569e6bf5f2856ea41592f3ba987d"
|
|
61
|
+
},
|
|
62
|
+
"prediction-report-management": {
|
|
63
|
+
"path": "skills/prediction-report-management",
|
|
64
|
+
"requires_cli": ">=0.8.3 <0.9.0",
|
|
65
|
+
"revision": "0.2.3-alpha.1",
|
|
66
|
+
"sha256": "sha256:a0210cd93244bce41e5b71f8dc70c6c4a79973968cd22af7e0e0102eae3efaa3"
|
|
61
67
|
}
|
|
62
68
|
},
|
|
63
|
-
"source_commit": "
|
|
69
|
+
"source_commit": "07c13464f3ed2c10644ba6707d329b54f48e725d"
|
|
64
70
|
}
|
|
@@ -73,6 +73,91 @@ ml-platform get-deployment-events <deployment-id> --limit 100 --offset 0
|
|
|
73
73
|
`list-deployments` 也支持按 `service`、`environment`、`state` 和自由文本 `q` 过滤,返回平台
|
|
74
74
|
Deployment Controller 管理的部署,不把模型中心回写的 delivery 状态当作平台部署。
|
|
75
75
|
|
|
76
|
+
## Prediction reporting
|
|
77
|
+
|
|
78
|
+
定时预测上报通过业务 CLI 管理版本化推送目标、计划与运行记录。下面的 JSON 是字段示例,
|
|
79
|
+
不是现网配置;替换目标地址、响应字段和占位凭据后,把实际配置文件放在仓库外并限制读取权限。
|
|
80
|
+
不要把认证信息写入 Kubernetes Secret、命令行参数或 Git。`validate-destination-profile`
|
|
81
|
+
仅做服务端合同校验,不会访问 Token 或推送接口。
|
|
82
|
+
|
|
83
|
+
`PROFILE_JSON` 示例:
|
|
84
|
+
|
|
85
|
+
```json
|
|
86
|
+
{
|
|
87
|
+
"schema_version": "ml_data_platform.destination_profile/v1",
|
|
88
|
+
"name": "forecast_sink",
|
|
89
|
+
"version": "v1",
|
|
90
|
+
"environment": "test",
|
|
91
|
+
"base_url": "https://integration.example.invalid/api",
|
|
92
|
+
"path": "/forecast/report",
|
|
93
|
+
"payload_mapping": "forecast-report-v1",
|
|
94
|
+
"authentication": {
|
|
95
|
+
"kind": "token_endpoint",
|
|
96
|
+
"token_request": {
|
|
97
|
+
"method": "GET",
|
|
98
|
+
"path": "/auth/getToken",
|
|
99
|
+
"parameters": [
|
|
100
|
+
{"name": "appKey", "value": "<app-key>", "location": "query"},
|
|
101
|
+
{"name": "appSecurity", "value": "<app-secret>", "location": "query"}
|
|
102
|
+
]
|
|
103
|
+
},
|
|
104
|
+
"success": {"http_status": [200], "body_code_path": "code", "body_code_values": [200]},
|
|
105
|
+
"token_path": "data.token",
|
|
106
|
+
"header_name": "Authorization",
|
|
107
|
+
"header_scheme": "Bearer"
|
|
108
|
+
},
|
|
109
|
+
"response_success": {"http_status": [200], "body_code_path": "code", "body_code_values": [200]},
|
|
110
|
+
"max_token_refreshes_per_day": 20
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
`token_path`、业务成功码和 `/forecast/report` 只是示例,必须按目标接口的真实响应和路径配置。
|
|
115
|
+
若响应提供有效期,可设置 `expires_in_path` 与 `expires_in_unit`;否则服务端默认按 7200 秒缓存,
|
|
116
|
+
并在 `refresh_skew_seconds` 前刷新。不同环境应使用不同 Profile 版本或名称;修改目标地址、
|
|
117
|
+
认证规则或凭据时创建新版本。`get`/`list` 只返回凭据已配置的脱敏标记,无法取回明文。
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
ml-platform --profile server validate-destination-profile /absolute/path/to/profile.json
|
|
121
|
+
ml-platform --profile server create-destination-profile /absolute/path/to/profile.json
|
|
122
|
+
ml-platform --profile server list-destination-profiles --limit 50 --offset 0
|
|
123
|
+
ml-platform --profile server get-destination-profile forecast_sink v1
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
计划引用已有 Profile,不复制凭据。`SCHEDULE_JSON` 示例:
|
|
127
|
+
|
|
128
|
+
```json
|
|
129
|
+
{
|
|
130
|
+
"schema_version": "ml_data_platform.prediction_report_schedule/v1",
|
|
131
|
+
"schedule_id": "forecast_hourly",
|
|
132
|
+
"name": "Hourly forecast report",
|
|
133
|
+
"deployment_id": "<deployment-id>",
|
|
134
|
+
"enabled": false,
|
|
135
|
+
"cron": "0 * * * *",
|
|
136
|
+
"timezone": "Asia/Shanghai",
|
|
137
|
+
"request": {"entity": {"site": "site-1"}, "horizon": "1h"},
|
|
138
|
+
"destination": {"name": "forecast_sink", "version": "v1"}
|
|
139
|
+
}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
计划要求部署的模型支持 `feature_lookup`;部署必须有可用推理策略,或在计划请求中提供
|
|
143
|
+
`horizon`。五段 cron 至少间隔五分钟。`enabled: false` 用于先创建但不发送的计划;
|
|
144
|
+
确认目标接口可用且部署 READY 后再恢复。计划创建或 Profile 校验成功均不等于已推送成功。
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
ml-platform --profile server create-prediction-report-schedule /absolute/path/to/schedule.json
|
|
148
|
+
ml-platform --profile server list-prediction-report-schedules --limit 50 --offset 0
|
|
149
|
+
ml-platform --profile server get-prediction-report-schedule forecast_hourly
|
|
150
|
+
ml-platform --profile server update-prediction-report-schedule forecast_hourly /absolute/path/to/changes.json
|
|
151
|
+
ml-platform --profile server pause-prediction-report-schedule forecast_hourly
|
|
152
|
+
ml-platform --profile server resume-prediction-report-schedule forecast_hourly
|
|
153
|
+
ml-platform --profile server list-prediction-report-runs forecast_hourly --limit 50 --offset 0
|
|
154
|
+
ml-platform --profile server get-prediction-report-run <run-id>
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
`CHANGES_JSON` 是仅含变更字段的对象,例如
|
|
158
|
+
`{"destination":{"name":"forecast_sink","version":"v2"}}`。更新不会改写历史运行;
|
|
159
|
+
是否已投递成功以 Run 的 `status`、`destination_status_code` 和错误码为准。
|
|
160
|
+
|
|
76
161
|
`READY` 必须同时包含 `ReplicasReady=true`、`ArtifactsVerified=true` 和
|
|
77
162
|
`SmokePredictionPassed=true`。`get-deployment` 返回控制器实际观察到的 endpoint 元数据;
|
|
78
163
|
本地 CLI 不推测 Kubernetes Service 名称。部署后验证优先使用控制面代理:
|
|
@@ -117,6 +202,21 @@ ml-platform predict-model /absolute/path/to/request.json \
|
|
|
117
202
|
--serving-url https://storage-forecast.example
|
|
118
203
|
```
|
|
119
204
|
|
|
205
|
+
同步零样本预测使用平台控制面提供的模型名称入口,不要求用户传入 `project`、合同版本或普通
|
|
206
|
+
请求的 `release_id`:
|
|
207
|
+
|
|
208
|
+
```bash
|
|
209
|
+
ml-platform list-foundation-models
|
|
210
|
+
ml-platform get-foundation-model chronos2_forecaster
|
|
211
|
+
ml-platform predict-foundation chronos2_forecaster /absolute/path/to/request.json
|
|
212
|
+
ml-platform predict-foundation-csv chronos2_forecaster /absolute/path/to/input.csv \
|
|
213
|
+
--schema /absolute/path/to/schema.json \
|
|
214
|
+
--forecast /absolute/path/to/forecast.json
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
`--release-id` 仅用于精确回放。零样本请求是同步、有界的 JSON 或 multipart CSV,不创建预测任务
|
|
218
|
+
或结果资源。
|
|
219
|
+
|
|
120
220
|
训练历史必须使用各个历史 cutoff 当时可取得的天气预报,不得以事后实测天气替代。
|
|
121
221
|
|
|
122
222
|
Parameter、Feature、FeatureSet 的删除命令执行软删除,并支持带 actor、reason 和幂等键的
|
|
@@ -126,7 +126,7 @@ function normalizeSource(value, label) {
|
|
|
126
126
|
throw new Error(`${label} uses unsupported field 'parameters'; use 'params'`);
|
|
127
127
|
if (source.mode === "sql" && typeof source.sql === "string" && source.sql.trimEnd().endsWith(";"))
|
|
128
128
|
throw new Error(`SQL ${label}.sql must not end with a semicolon`);
|
|
129
|
-
return { adapter: pythonString(defaultIfAbsent(source, "adapter", "synthetic")), mode: choice(defaultIfAbsent(source, "mode", "direct_column"), ["direct_column", "sql", "derived"], `${label} mode`), source_metric: optionalString(source.source_metric, "source_metric"), source_group: optionalString(source.source_group, "source_group"), measurement: optionalString(source.measurement, "measurement"), field: optionalString(source.field, "field"), tags: stringMap(defaultIfAbsent(source, "tags", {}), `${label} tags`), schema: optionalString(aliasIfAbsent(source, "schema", "schema_name"), "schema"), table: optionalString(source.table, "table"), time_column: optionalString(source.time_column, "time_column"), value_column: optionalString(source.value_column, "value_column"), metric_name_column: optionalString(source.metric_name_column, "metric_name_column"), metric_name: optionalString(source.metric_name, "metric_name"), unit_column: optionalString(source.unit_column, "unit_column"), unit: optionalString(aliasIfAbsent(source, "unit", "source_unit"), "source unit"), filters: stringMap(defaultIfAbsent(source, "filters", {}), `${label} filters`), sql: optionalString(source.sql, "source sql"), params: object(defaultIfAbsent(source, "params", {}), `${label} params`) };
|
|
129
|
+
return { adapter: pythonString(defaultIfAbsent(source, "adapter", "synthetic")), connection_id: optionalString(source.connection_id, "connection_id"), mode: choice(defaultIfAbsent(source, "mode", "direct_column"), ["direct_column", "sql", "derived"], `${label} mode`), source_metric: optionalString(source.source_metric, "source_metric"), source_group: optionalString(source.source_group, "source_group"), measurement: optionalString(source.measurement, "measurement"), field: optionalString(source.field, "field"), tags: stringMap(defaultIfAbsent(source, "tags", {}), `${label} tags`), schema: optionalString(aliasIfAbsent(source, "schema", "schema_name"), "schema"), table: optionalString(source.table, "table"), time_column: optionalString(source.time_column, "time_column"), value_column: optionalString(source.value_column, "value_column"), metric_name_column: optionalString(source.metric_name_column, "metric_name_column"), metric_name: optionalString(source.metric_name, "metric_name"), unit_column: optionalString(source.unit_column, "unit_column"), unit: optionalString(aliasIfAbsent(source, "unit", "source_unit"), "source unit"), filters: stringMap(defaultIfAbsent(source, "filters", {}), `${label} filters`), sql: optionalString(source.sql, "source sql"), params: object(defaultIfAbsent(source, "params", {}), `${label} params`) };
|
|
130
130
|
}
|
|
131
131
|
function normalizeParameter(payload) {
|
|
132
132
|
const source = normalizeSource(payload.source, "parameter source");
|
|
@@ -29,6 +29,7 @@ const BUSINESS_COMMANDS = new Set([
|
|
|
29
29
|
"add-dataset", "update-dataset", "delete-dataset", "list-dataset-artifacts",
|
|
30
30
|
"register-operator", "show-operator-specs", "delete-operator", "run-operator",
|
|
31
31
|
"get-job", "wait-job", "retry-job", "cancel-job", "get-dataset-artifact", "download-dataset-artifact", "fetch-inference-data", "fetch-inference-context", "predict-model", "apply",
|
|
32
|
+
"list-foundation-models", "get-foundation-model", "predict-foundation", "predict-foundation-csv",
|
|
32
33
|
"list-system-models", "get-system-model", "register-training-run", "validate-training-run", "submit-training-job", "get-training-job", "retry-training-job", "cancel-training-job",
|
|
33
34
|
"register-evaluation-config", "get-evaluation-config", "register-metric-definition", "get-metric-definition",
|
|
34
35
|
"register-executable-package", "verify-executable-package", "publish-executable-package",
|
|
@@ -39,6 +40,10 @@ const BUSINESS_COMMANDS = new Set([
|
|
|
39
40
|
"get-deployment", "wait-deployment", "reconcile-deployment", "approve-deployment",
|
|
40
41
|
"promote-deployment", "rollback-deployment", "suspend-deployment", "resume-deployment",
|
|
41
42
|
"undeploy-deployment", "get-deployment-events", "predict-deployment",
|
|
43
|
+
"validate-destination-profile", "create-destination-profile", "list-destination-profiles", "get-destination-profile",
|
|
44
|
+
"create-prediction-report-schedule", "list-prediction-report-schedules", "get-prediction-report-schedule",
|
|
45
|
+
"update-prediction-report-schedule", "pause-prediction-report-schedule", "resume-prediction-report-schedule",
|
|
46
|
+
"list-prediction-report-runs", "get-prediction-report-run",
|
|
42
47
|
]);
|
|
43
48
|
const COMMAND_USAGE = {
|
|
44
49
|
...Object.fromEntries([...LIFECYCLE_COLLECTIONS].map((name) => [`list-${name}`, `list-${name} [--limit N] [--offset N] [-q QUERY]`])),
|
|
@@ -114,6 +119,10 @@ const COMMAND_USAGE = {
|
|
|
114
119
|
"fetch-inference-data": "fetch-inference-data MANIFEST --cutoff-time TIMESTAMP [--max-workers N] [--max-source-lag-hours HOURS] [--no-validate-freshness] [--allow-missing]",
|
|
115
120
|
"fetch-inference-context": "fetch-inference-context REQUEST_JSON",
|
|
116
121
|
"predict-model": "predict-model REQUEST_JSON --serving-url URL",
|
|
122
|
+
"list-foundation-models": "list-foundation-models",
|
|
123
|
+
"get-foundation-model": "get-foundation-model NAME",
|
|
124
|
+
"predict-foundation": "predict-foundation NAME REQUEST_JSON [--release-id ID]",
|
|
125
|
+
"predict-foundation-csv": "predict-foundation-csv NAME CSV_FILE --schema SCHEMA_JSON --forecast FORECAST_JSON [--release-id ID]",
|
|
117
126
|
"list-system-models": "list-system-models",
|
|
118
127
|
"get-system-model": "get-system-model NAME VERSION [--project PROJECT]",
|
|
119
128
|
"register-training-run": "register-training-run RUN_JSON",
|
|
@@ -161,6 +170,18 @@ const COMMAND_USAGE = {
|
|
|
161
170
|
"undeploy-deployment": "undeploy-deployment DEPLOYMENT_ID --actor NAME --reason TEXT",
|
|
162
171
|
"get-deployment-events": "get-deployment-events DEPLOYMENT_ID [--limit N] [--offset N]",
|
|
163
172
|
"predict-deployment": "predict-deployment DEPLOYMENT_ID REQUEST_JSON",
|
|
173
|
+
"create-destination-profile": "create-destination-profile PROFILE_JSON",
|
|
174
|
+
"validate-destination-profile": "validate-destination-profile PROFILE_JSON",
|
|
175
|
+
"list-destination-profiles": "list-destination-profiles [--limit N] [--offset N]",
|
|
176
|
+
"get-destination-profile": "get-destination-profile NAME VERSION",
|
|
177
|
+
"create-prediction-report-schedule": "create-prediction-report-schedule SCHEDULE_JSON",
|
|
178
|
+
"list-prediction-report-schedules": "list-prediction-report-schedules [--limit N] [--offset N]",
|
|
179
|
+
"get-prediction-report-schedule": "get-prediction-report-schedule SCHEDULE_ID",
|
|
180
|
+
"update-prediction-report-schedule": "update-prediction-report-schedule SCHEDULE_ID CHANGES_JSON",
|
|
181
|
+
"pause-prediction-report-schedule": "pause-prediction-report-schedule SCHEDULE_ID",
|
|
182
|
+
"resume-prediction-report-schedule": "resume-prediction-report-schedule SCHEDULE_ID",
|
|
183
|
+
"list-prediction-report-runs": "list-prediction-report-runs SCHEDULE_ID [--limit N] [--offset N]",
|
|
184
|
+
"get-prediction-report-run": "get-prediction-report-run RUN_ID",
|
|
164
185
|
apply: "apply CATALOG_DIRECTORY [--dry-run] [--project PROJECT]",
|
|
165
186
|
};
|
|
166
187
|
function usage(command) {
|
|
@@ -720,6 +741,33 @@ async function runBusinessCli(argv) {
|
|
|
720
741
|
throw new Error("--serving-url is required");
|
|
721
742
|
result = await new PlatformApiClient(servingUrl, options.timeout).post("/v1/inference", request);
|
|
722
743
|
}
|
|
744
|
+
else if (options.command === "list-foundation-models") {
|
|
745
|
+
result = await client(options).get("/foundation-models");
|
|
746
|
+
}
|
|
747
|
+
else if (options.command === "get-foundation-model") {
|
|
748
|
+
const name = positional(rest, "foundation model name");
|
|
749
|
+
result = await client(options).get(`/foundation-models/${encodeURIComponent(name)}`);
|
|
750
|
+
}
|
|
751
|
+
else if (options.command === "predict-foundation") {
|
|
752
|
+
const name = positional(rest, "foundation model name");
|
|
753
|
+
const request = readSpec(positional(rest, "request JSON"));
|
|
754
|
+
const releaseId = take(rest, "--release-id");
|
|
755
|
+
const headers = releaseId ? { "X-ITSMP-Foundation-Release": releaseId } : {};
|
|
756
|
+
result = await client(options).postWithHeaders(`/foundation-models/${encodeURIComponent(name)}/predict`, request, headers);
|
|
757
|
+
}
|
|
758
|
+
else if (options.command === "predict-foundation-csv") {
|
|
759
|
+
const name = positional(rest, "foundation model name");
|
|
760
|
+
const csvFile = positional(rest, "CSV file");
|
|
761
|
+
const schemaFile = take(rest, "--schema");
|
|
762
|
+
const forecastFile = take(rest, "--forecast");
|
|
763
|
+
if (!schemaFile)
|
|
764
|
+
throw new Error("--schema is required");
|
|
765
|
+
if (!forecastFile)
|
|
766
|
+
throw new Error("--forecast is required");
|
|
767
|
+
const releaseId = take(rest, "--release-id");
|
|
768
|
+
const headers = releaseId ? { "X-ITSMP-Foundation-Release": releaseId } : {};
|
|
769
|
+
result = await client(options).uploadFoundationCsv(`/foundation-models/${encodeURIComponent(name)}/predict-file`, readSpec(schemaFile), readSpec(forecastFile), csvFile, headers);
|
|
770
|
+
}
|
|
723
771
|
else if (options.command === "list-deployment-targets") {
|
|
724
772
|
result = await client(options).get("/deployment-targets");
|
|
725
773
|
}
|
|
@@ -826,6 +874,40 @@ async function runBusinessCli(argv) {
|
|
|
826
874
|
const request = readSpec(positional(rest, "request JSON"));
|
|
827
875
|
result = await client(options).post(`/deployments/${encodeURIComponent(deploymentId)}/predict`, request);
|
|
828
876
|
}
|
|
877
|
+
else if (["create-destination-profile", "validate-destination-profile"].includes(options.command)) {
|
|
878
|
+
result = await client(options).post(options.command === "create-destination-profile" ? "/destination-profiles" : "/destination-profiles/validate", readSpec(positional(rest, "profile JSON")));
|
|
879
|
+
}
|
|
880
|
+
else if (options.command === "list-destination-profiles") {
|
|
881
|
+
result = await listCollection(client(options), "/destination-profiles", {}, rest);
|
|
882
|
+
}
|
|
883
|
+
else if (options.command === "get-destination-profile") {
|
|
884
|
+
const name = positional(rest, "profile name");
|
|
885
|
+
const version = positional(rest, "profile version");
|
|
886
|
+
result = await client(options).get(`/destination-profiles/${encodeURIComponent(name)}/versions/${encodeURIComponent(version)}`);
|
|
887
|
+
}
|
|
888
|
+
else if (options.command === "create-prediction-report-schedule") {
|
|
889
|
+
result = await client(options).post("/prediction-report-schedules", readSpec(positional(rest, "schedule JSON")));
|
|
890
|
+
}
|
|
891
|
+
else if (options.command === "list-prediction-report-schedules") {
|
|
892
|
+
result = await listCollection(client(options), "/prediction-report-schedules", {}, rest);
|
|
893
|
+
}
|
|
894
|
+
else if (["get-prediction-report-schedule", "update-prediction-report-schedule", "pause-prediction-report-schedule", "resume-prediction-report-schedule", "list-prediction-report-runs"].includes(options.command)) {
|
|
895
|
+
const scheduleId = positional(rest, "schedule id");
|
|
896
|
+
const endpoint = `/prediction-report-schedules/${encodeURIComponent(scheduleId)}`;
|
|
897
|
+
if (options.command === "update-prediction-report-schedule")
|
|
898
|
+
result = await client(options).patch(endpoint, readSpec(positional(rest, "changes JSON")));
|
|
899
|
+
else if (options.command === "pause-prediction-report-schedule")
|
|
900
|
+
result = await client(options).post(`${endpoint}/pause`);
|
|
901
|
+
else if (options.command === "resume-prediction-report-schedule")
|
|
902
|
+
result = await client(options).post(`${endpoint}/resume`);
|
|
903
|
+
else if (options.command === "list-prediction-report-runs")
|
|
904
|
+
result = await listCollection(client(options), `${endpoint}/runs`, {}, rest);
|
|
905
|
+
else
|
|
906
|
+
result = await client(options).get(endpoint);
|
|
907
|
+
}
|
|
908
|
+
else if (options.command === "get-prediction-report-run") {
|
|
909
|
+
result = await client(options).get(`/prediction-report-runs/${encodeURIComponent(positional(rest, "run id"))}`);
|
|
910
|
+
}
|
|
829
911
|
else if (options.command === "get-model-runtime-release") {
|
|
830
912
|
result = await client(options).get("/model-runtime-release");
|
|
831
913
|
}
|
|
@@ -22,10 +22,11 @@ class PlatformApiClient {
|
|
|
22
22
|
}
|
|
23
23
|
return url;
|
|
24
24
|
}
|
|
25
|
-
async request(method, endpoint, { params, payload, body, contentType } = {}) {
|
|
25
|
+
async request(method, endpoint, { params, payload, body, contentType, requestHeaders } = {}) {
|
|
26
26
|
const controller = new AbortController();
|
|
27
27
|
const timer = setTimeout(() => controller.abort(), this.timeoutMs);
|
|
28
28
|
const headers = { Accept: "application/json" };
|
|
29
|
+
Object.assign(headers, requestHeaders || {});
|
|
29
30
|
let requestBody = body;
|
|
30
31
|
if (payload !== undefined) {
|
|
31
32
|
headers["Content-Type"] = "application/json";
|
|
@@ -59,8 +60,33 @@ class PlatformApiClient {
|
|
|
59
60
|
}
|
|
60
61
|
get(endpoint, params) { return this.request("GET", endpoint, { params }); }
|
|
61
62
|
post(endpoint, payload, params) { return this.request("POST", endpoint, { payload, params }); }
|
|
63
|
+
postWithHeaders(endpoint, payload, requestHeaders) { return this.request("POST", endpoint, { payload, requestHeaders }); }
|
|
62
64
|
put(endpoint, payload, params) { return this.request("PUT", endpoint, { payload, params }); }
|
|
65
|
+
patch(endpoint, payload, params) { return this.request("PATCH", endpoint, { payload, params }); }
|
|
63
66
|
delete(endpoint, params) { return this.request("DELETE", endpoint, { params }); }
|
|
67
|
+
uploadFoundationCsv(endpoint, schema, forecast, filePath, requestHeaders = {}) {
|
|
68
|
+
const resolved = path.resolve(expandHome(filePath));
|
|
69
|
+
if (!fs.existsSync(resolved) || !fs.statSync(resolved).isFile())
|
|
70
|
+
throw new Error(`CSV file not found: ${resolved}`);
|
|
71
|
+
const boundary = `itsmp-${Date.now().toString(16)}-${Math.random().toString(16).slice(2)}`;
|
|
72
|
+
const parts = [];
|
|
73
|
+
const field = (name, value, contentType) => {
|
|
74
|
+
parts.push(Buffer.from(`--${boundary}\r\nContent-Disposition: form-data; name="${name}"\r\nContent-Type: ${contentType}\r\n\r\n`));
|
|
75
|
+
parts.push(Buffer.from(value));
|
|
76
|
+
parts.push(Buffer.from("\r\n"));
|
|
77
|
+
};
|
|
78
|
+
field("schema", JSON.stringify(schema), "application/json");
|
|
79
|
+
field("forecast", JSON.stringify(forecast), "application/json");
|
|
80
|
+
const filename = path.basename(resolved).replace(/["\r\n]/g, "_");
|
|
81
|
+
parts.push(Buffer.from(`--${boundary}\r\nContent-Disposition: form-data; name="file"; filename="${filename}"\r\nContent-Type: text/csv\r\n\r\n`));
|
|
82
|
+
parts.push(fs.readFileSync(resolved));
|
|
83
|
+
parts.push(Buffer.from(`\r\n--${boundary}--\r\n`));
|
|
84
|
+
return this.request("POST", endpoint, {
|
|
85
|
+
body: Buffer.concat(parts),
|
|
86
|
+
contentType: `multipart/form-data; boundary=${boundary}`,
|
|
87
|
+
requestHeaders,
|
|
88
|
+
});
|
|
89
|
+
}
|
|
64
90
|
uploadOperatorPackage(project, name, version, packagePath) {
|
|
65
91
|
const resolved = path.resolve(expandHome(packagePath));
|
|
66
92
|
if (!fs.existsSync(resolved) || !fs.statSync(resolved).isFile())
|
|
@@ -88,3 +88,8 @@ After a human confirms source mapping, event time, entity keys, units, availabil
|
|
|
88
88
|
horizon, and feature formulas, use `$feature-management` to create governed assets and build a
|
|
89
89
|
DatasetArtifact. Use `$model-lifecycle-management` only after that artifact exists. Exploration does not
|
|
90
90
|
authorize publishing assets, building datasets, or submitting training jobs.
|
|
91
|
+
|
|
92
|
+
At the end of an exploration task, offer the next relevant option: confirm the
|
|
93
|
+
unresolved business semantics with an owner, or, when they are already confirmed,
|
|
94
|
+
define governed assets with `$feature-management`. Name the evidence that makes
|
|
95
|
+
the option available; do not present exploratory rows as a finished dataset.
|
|
@@ -259,7 +259,7 @@ unit, time/availability semantics and missing policy in the semantic review.
|
|
|
259
259
|
Never infer a source table, column, measurement, tag, unit or timezone from a
|
|
260
260
|
Parameter name.
|
|
261
261
|
|
|
262
|
-
Create one stable, versioned source contract for each independently readable value. Keep credentials out of JSON. Use only supported direct adapters (`postgresql_direct`, `mysql_direct`, `sqlserver_direct`, and `influxdb_direct`) and explicit source identity. The server supplies database DSNs from managed Secrets; never add them to CLI arguments or Catalog JSON. Put source data validity in `quality_rules`; put dataset-specific transformations in preprocess Operators.
|
|
262
|
+
Create one stable, versioned source contract for each independently readable value. Keep credentials out of JSON. Use only supported direct adapters (`postgresql_direct`, `mysql_direct`, `sqlserver_direct`, and `influxdb_direct`) and explicit source identity. For PostgreSQL, keep `source.adapter=postgresql_direct` and put the configured alias in `source.connection_id` (for example `postgresql_bf_monitoring`); never put the connection alias in `source.adapter`. The server supplies database DSNs from managed Secrets; never add them to CLI arguments or Catalog JSON. A missing `connection_id` on a historical PostgreSQL Parameter uses the compatibility default `postgresql`. Put source data validity in `quality_rules`; put dataset-specific transformations in preprocess Operators.
|
|
263
263
|
|
|
264
264
|
When historical and live systems expose the same value, keep one Parameter and add an optional
|
|
265
265
|
`online_source`. Batch/as-of reads always use `source`; realtime causal reads use `online_source`
|
|
@@ -503,3 +503,10 @@ actual compute backend
|
|
|
503
503
|
```
|
|
504
504
|
|
|
505
505
|
If the work stops before publication, distinguish generated files, locally validated files, dry-run validation, and remotely published assets.
|
|
506
|
+
|
|
507
|
+
Close with at most two optional next steps tied to the actual checkpoint. For
|
|
508
|
+
example, after a dry-run, offer publication only with separate approval; after
|
|
509
|
+
a verified DatasetArtifact, offer training or evaluation through
|
|
510
|
+
`$model-lifecycle-management`. If the artifact is missing or validation failed,
|
|
511
|
+
name that blocker instead of suggesting model training. A suggested step does
|
|
512
|
+
not authorize publishing, building, or submitting a workload.
|
|
@@ -105,6 +105,7 @@ adapter;凭据不进入 JSON。Feature/Operator/FeatureSet 不需要复制一
|
|
|
105
105
|
{
|
|
106
106
|
"source": {
|
|
107
107
|
"adapter": "postgresql_direct",
|
|
108
|
+
"connection_id": "postgresql_bf_monitoring",
|
|
108
109
|
"schema": "process_data",
|
|
109
110
|
"table": "pressure_history",
|
|
110
111
|
"time_column": "event_time",
|
|
@@ -168,11 +169,16 @@ requires a new Parameter version and the affected reverse-dependency closure.
|
|
|
168
169
|
|
|
169
170
|
PostgreSQL, MySQL, and SQL Server direct-column Parameters share this source
|
|
170
171
|
shape. Set `adapter` to `postgresql_direct`, `mysql_direct`, or
|
|
171
|
-
`sqlserver_direct`; keep database-specific DSNs in server-managed Secrets.
|
|
172
|
+
`sqlserver_direct`; keep database-specific DSNs in server-managed Secrets. For
|
|
173
|
+
PostgreSQL, use `connection_id` to select a configured connection alias, for
|
|
174
|
+
example `postgresql_bf_monitoring`. `connection_id` is not an adapter name and
|
|
175
|
+
must not replace `postgresql_direct`. If omitted on a historical PostgreSQL
|
|
176
|
+
Parameter, the runtime uses the compatibility default connection `postgresql`.
|
|
172
177
|
|
|
173
178
|
```json
|
|
174
179
|
{
|
|
175
180
|
"adapter": "postgresql_direct",
|
|
181
|
+
"connection_id": "postgresql_bf_monitoring",
|
|
176
182
|
"mode": "direct_column",
|
|
177
183
|
"schema": "process_data",
|
|
178
184
|
"table": "sensor_readings",
|
|
@@ -63,3 +63,10 @@ deployment does not reach `READY` or an operation is rejected.
|
|
|
63
63
|
Report the deployment ID, revision, immutable image digest, desired and
|
|
64
64
|
observed state, failed conditions, endpoint reachability, and event evidence.
|
|
65
65
|
Do not claim a deployment is usable merely because its Pod is running.
|
|
66
|
+
|
|
67
|
+
Close with an optional next step based on observed state: resolve failed READY
|
|
68
|
+
conditions before prediction; once READY, offer `predict-deployment` to verify
|
|
69
|
+
the model. After a successful deployment-bound prediction, offer scheduled
|
|
70
|
+
delivery through `$prediction-report-management` only when recurring reporting
|
|
71
|
+
is relevant and the package supports `feature_lookup`. Do not create a report
|
|
72
|
+
schedule or imply that READY alone proves delivery to an external destination.
|
|
@@ -18,6 +18,12 @@ Read [references/discovery.md](references/discovery.md) before locating existing
|
|
|
18
18
|
resources or selecting runtime bindings. It also defines Job/package preflight
|
|
19
19
|
and version-skew handling.
|
|
20
20
|
|
|
21
|
+
Read [references/zero-shot-inference.md](references/zero-shot-inference.md) when
|
|
22
|
+
the user wants synchronous zero-shot forecasting from JSON or CSV. This path
|
|
23
|
+
uses the platform-owned `chronos2_forecaster` model name, not a public project
|
|
24
|
+
or contract version, and does not create a TrainingRun, ModelArtifact,
|
|
25
|
+
PredictionJob or prediction result record.
|
|
26
|
+
|
|
21
27
|
## Shared Gates
|
|
22
28
|
|
|
23
29
|
Before training a model that will be evaluated, also read
|
|
@@ -38,8 +44,22 @@ evidence when deployment differs.
|
|
|
38
44
|
- Do not register caller-computed evaluation results. Workers produce predictions, metrics, decisions, and summaries from frozen DatasetArtifact rowsets.
|
|
39
45
|
- Keep credentials, registry secrets, Kubernetes details, and model binaries out of request JSON and reports.
|
|
40
46
|
|
|
47
|
+
For zero-shot inference, the public identity is only `chronos2_forecaster`.
|
|
48
|
+
Internal contract versions, canonical project keys, runtime bindings and
|
|
49
|
+
historical aliases are resolved by the server. Do not construct a URL
|
|
50
|
+
containing `v1`, `project` or `release_id`.
|
|
51
|
+
|
|
41
52
|
Report immutable input identities, returned run/job/package IDs, status, validation or gate failures, and the next authorized action. Never claim deployment; it is outside this Skill.
|
|
42
53
|
|
|
43
54
|
Route deployment validation, creation, rollout state, approval, promotion,
|
|
44
55
|
rollback, offline operations, and deployment-bound prediction to the separate
|
|
45
56
|
`model-deployment-management` Skill.
|
|
57
|
+
|
|
58
|
+
At task completion, suggest only the next gate supported by the observed
|
|
59
|
+
evidence: a valid DatasetArtifact can lead to training, a valid ModelArtifact
|
|
60
|
+
to evaluation, a PASS evaluation to registration and packaging, and a READY
|
|
61
|
+
package with immutable digest to `$model-deployment-management`. If a gate
|
|
62
|
+
failed, suggest inspection or correction of that gate instead. A zero-shot
|
|
63
|
+
prediction is complete on its own; do not imply it produced an artifact or
|
|
64
|
+
requires training. These are optional next actions, not authorization to
|
|
65
|
+
submit or mutate resources.
|
|
@@ -28,6 +28,17 @@ it does not mean every model/device is approved by a release.
|
|
|
28
28
|
`worker_dependencies_verified=false` explicitly means discovery has not tested
|
|
29
29
|
imports, image pulls or model prediction in the Worker.
|
|
30
30
|
|
|
31
|
+
For zero-shot model discovery, use the separate foundation-model endpoints:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
ml-platform --profile server list-foundation-models
|
|
35
|
+
ml-platform --profile server get-foundation-model chronos2_forecaster
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
These endpoints intentionally do not expose the SystemModel `project` or
|
|
39
|
+
contract version. Do not use `get-system-model` or Runtime Release binding keys
|
|
40
|
+
as the public zero-shot model identifier.
|
|
41
|
+
|
|
31
42
|
## Resource lookup and pagination
|
|
32
43
|
|
|
33
44
|
```bash
|
|
@@ -11,7 +11,7 @@ Example forecasting sequence run:
|
|
|
11
11
|
|
|
12
12
|
```json
|
|
13
13
|
{
|
|
14
|
-
"schema_version": "ml_data_platform.training_run/
|
|
14
|
+
"schema_version": "ml_data_platform.training_run/v4",
|
|
15
15
|
"run_id": "pressure_forecast_run_01",
|
|
16
16
|
"experiment": "pressure_forecast",
|
|
17
17
|
"task": {"kind": "forecasting", "objective": "regression"},
|
|
@@ -183,9 +183,12 @@ weather observations.
|
|
|
183
183
|
|
|
184
184
|
Inspect `data_schema.json`, `resolved_manifest.json` and the feature Parquet via
|
|
185
185
|
`download-dataset-artifact DATASET_ID MANIFEST_HASH --project PROJECT --out-dir DIR`
|
|
186
|
-
(repeat `--file` for selective downloads).
|
|
187
|
-
|
|
188
|
-
|
|
186
|
+
(repeat `--file` for selective downloads). In TrainingRun v4, the FeatureSet
|
|
187
|
+
reference defines the ordered model inputs. It may be a registered exact-version
|
|
188
|
+
subset of the DatasetArtifact's materialized FeatureSet, in its own order. The
|
|
189
|
+
platform freezes both identities and the projected dependency contract in the
|
|
190
|
+
TrainingJob and ModelArtifact. There is no `data.features.columns` shortcut:
|
|
191
|
+
create a new immutable FeatureSet version for each distinct model input contract.
|
|
189
192
|
|
|
190
193
|
`identity:v1` leaves labels unchanged. `difference` requires a baseline Feature
|
|
191
194
|
in `required_inputs` and at least one `online_inputs` entry, which must be a
|
|
@@ -286,7 +289,7 @@ null Features or labels also skip samples. Candidate row counts therefore are
|
|
|
286
289
|
not training/evaluation sample counts. Report the materialized population and
|
|
287
290
|
coverage instead of assuming all Parquet rows were used.
|
|
288
291
|
|
|
289
|
-
For `continuous_target_series`, TrainingRun
|
|
292
|
+
For `continuous_target_series`, TrainingRun v4 derives the fixed maximum
|
|
290
293
|
`prediction_length` as `data.temporal.horizon / data.temporal.frequency`; the
|
|
291
294
|
horizon must be a positive exact multiple of the frequency. The target input
|
|
292
295
|
must be a numeric, at-prediction Feature and the output label must be the sole
|
|
@@ -21,7 +21,7 @@ FeatureSet order and evaluation runtime before the first Job. See
|
|
|
21
21
|
`label_time - prediction_time`, and validate the complete TrainingRun before
|
|
22
22
|
registration/submission. Validation may not catch undeclared plugin limits or
|
|
23
23
|
missing dependencies in the eventual Worker.
|
|
24
|
-
- For a continuous future trajectory, use TrainingRun
|
|
24
|
+
- For a continuous future trajectory, use TrainingRun v4. Use
|
|
25
25
|
`continuous_target_series` for legacy v1 or
|
|
26
26
|
`continuous_target_series_with_covariates` for v2. Its fixed maximum
|
|
27
27
|
prediction length comes from temporal horizon divided by frequency; do not
|
|
@@ -75,7 +75,7 @@ ml-platform --profile server submit-training-job training-job-request.json
|
|
|
75
75
|
ml-platform --profile server get-training-job <job-id>
|
|
76
76
|
```
|
|
77
77
|
|
|
78
|
-
The TrainingRun binds immutable DatasetArtifact identities, DataSchema, ordered
|
|
78
|
+
The TrainingRun binds immutable DatasetArtifact identities, DataSchema, an ordered registered model FeatureSet, targets, InputAdapter, canonical SystemModel `v1`, reproducibility controls, and runtime identity. The model FeatureSet may be an exact-version subset of the Artifact's materialized FeatureSet; changing only the subset or order does not require rebuilding the wide DatasetArtifact. Job resolution freezes both FeatureSet identities, selected columns and projected lineage contract together with the SystemModel and approved runtime image. Validation proves compatibility only. Submit the run and Job separately after authorization and record spec hash and Job ID. Terminal success must expose a ModelArtifact ID; validate it before evaluation or packaging.
|
|
79
79
|
|
|
80
80
|
```bash
|
|
81
81
|
ml-platform --profile server validate-model-artifact <artifact-id>
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# Synchronous zero-shot inference
|
|
2
|
+
|
|
3
|
+
Use this workflow for platform-approved Chronos-2 forecasting without a
|
|
4
|
+
TrainingRun or ModelArtifact. The public model identity is the name
|
|
5
|
+
`chronos2_forecaster`; internal contract versions and runtime bindings are
|
|
6
|
+
server-side compatibility details.
|
|
7
|
+
|
|
8
|
+
## Discovery
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
ml-platform --profile server list-foundation-models
|
|
12
|
+
ml-platform --profile server get-foundation-model chronos2_forecaster
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
The response contains the active `release_id`, checkpoint digest, Serving image
|
|
16
|
+
digest and bounded input capabilities. Normal prediction does not require the
|
|
17
|
+
caller to look up or submit that release ID.
|
|
18
|
+
|
|
19
|
+
## JSON prediction
|
|
20
|
+
|
|
21
|
+
The request contains `schema`, `records` and `forecast`. Column roles are
|
|
22
|
+
explicit; the server does not infer target, timestamp or covariate columns from
|
|
23
|
+
their names.
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
ml-platform --profile server predict-foundation \
|
|
27
|
+
chronos2_forecaster /absolute/path/to/request.json
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
The endpoint is `POST /foundation-models/chronos2_forecaster/predict`.
|
|
31
|
+
|
|
32
|
+
## CSV prediction
|
|
33
|
+
|
|
34
|
+
CSV uses the same schema and forecast JSON as the JSON path. The CLI sends one
|
|
35
|
+
bounded multipart request and does not upload the file to object storage.
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
ml-platform --profile server predict-foundation-csv \
|
|
39
|
+
chronos2_forecaster /absolute/path/to/input.csv \
|
|
40
|
+
--schema /absolute/path/to/schema.json \
|
|
41
|
+
--forecast /absolute/path/to/forecast.json
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
The endpoint is `POST /foundation-models/chronos2_forecaster/predict-file`.
|
|
45
|
+
JSON and CSV are normalized to the same canonical rows and should produce the
|
|
46
|
+
same `input_hash` for equivalent input.
|
|
47
|
+
|
|
48
|
+
## Exact replay
|
|
49
|
+
|
|
50
|
+
Use `--release-id` only for replay or incident comparison:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
ml-platform --profile server predict-foundation \
|
|
54
|
+
chronos2_forecaster /absolute/path/to/request.json \
|
|
55
|
+
--release-id chronos2-base-2026-08
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
The server validates that the release belongs to the named model and is
|
|
59
|
+
eligible for replay. A normal request always resolves the active release.
|
|
60
|
+
|
|
61
|
+
## Runtime boundary
|
|
62
|
+
|
|
63
|
+
Foundation Serving is a long-running CPU workload. It loads and verifies the
|
|
64
|
+
immutable checkpoint at startup and does not connect to PostgreSQL during a
|
|
65
|
+
request. Synchronous requests are bounded by release byte, row, series,
|
|
66
|
+
context, horizon and timeout limits. There is no JSONL, asynchronous task,
|
|
67
|
+
PredictionRun or prediction-result persistence in this MVP.
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: prediction-report-management
|
|
3
|
+
description: Manage versioned business-owned prediction report destinations, schedules, and run diagnostics through the ITSMP ml-platform CLI. Use for configuring HTTP delivery and token acquisition, creating or changing scheduled reports, pausing or resuming them, or inspecting report runs. Do not use for model deployment, direct prediction, Kubernetes administration, or image releases.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Prediction Report Management
|
|
7
|
+
|
|
8
|
+
Use the `ml-platform` CLI installed with this Skill's npm release. Reporting is a
|
|
9
|
+
control-plane workflow: the API runs schedules and sends predictions from a
|
|
10
|
+
READY deployment; model Serving does not receive destination credentials.
|
|
11
|
+
|
|
12
|
+
## Read-only checks
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
ml-platform --profile server health
|
|
16
|
+
ml-platform --profile server list-destination-profiles
|
|
17
|
+
ml-platform --profile server get-destination-profile NAME v1
|
|
18
|
+
ml-platform --profile server list-prediction-report-schedules
|
|
19
|
+
ml-platform --profile server get-prediction-report-schedule SCHEDULE_ID
|
|
20
|
+
ml-platform --profile server list-prediction-report-runs SCHEDULE_ID
|
|
21
|
+
ml-platform --profile server get-prediction-report-run RUN_ID
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Check the deployment with `get-deployment DEPLOYMENT_ID` before creating a
|
|
25
|
+
schedule. The deployment must support `feature_lookup` and have a usable
|
|
26
|
+
inference horizon, supplied by either the schedule request or deployment
|
|
27
|
+
policy. A report run may be `SKIPPED` when the selected revision is not READY.
|
|
28
|
+
|
|
29
|
+
## Configure a destination
|
|
30
|
+
|
|
31
|
+
The `PROFILE_JSON` argument is a local JSON file, not inline JSON. Include
|
|
32
|
+
`schema_version`, `name`, `version`, `base_url`, `path`, authentication, and
|
|
33
|
+
response success rules as required by the target. For token-based auth, set
|
|
34
|
+
`authentication.token_request` parameters and `token_path`; configure both
|
|
35
|
+
token and report business success rules when HTTP 2xx alone is insufficient.
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
ml-platform --profile server validate-destination-profile PROFILE_JSON
|
|
39
|
+
ml-platform --profile server create-destination-profile PROFILE_JSON
|
|
40
|
+
ml-platform --profile server get-destination-profile NAME v1
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Validation checks schema and local policy; it does **not** call the token or
|
|
44
|
+
report endpoint. Versions are immutable. Changes to URL, auth, token extraction,
|
|
45
|
+
or success rules require a new profile version and a schedule update to point
|
|
46
|
+
to it. `get` and `list` redact credential values; they cannot reconstruct the
|
|
47
|
+
original file. Keep credential-bearing JSON outside the repository, restrict
|
|
48
|
+
file access, and do not print its contents or put secrets in shell arguments,
|
|
49
|
+
logs, examples, or Agent answers. Destination URL and token credentials are
|
|
50
|
+
business configuration submitted through this API, not Kubernetes Secrets.
|
|
51
|
+
|
|
52
|
+
## Manage a schedule
|
|
53
|
+
|
|
54
|
+
Creating a schedule starts reporting when `enabled` is true. Obtain explicit
|
|
55
|
+
authorization for the exact destination and deployment before creation, update,
|
|
56
|
+
pause, or resume. Use `enabled: false` for a staged schedule that should not
|
|
57
|
+
run yet. `SCHEDULE_JSON` contains `deployment_id`, five-field `cron`, IANA
|
|
58
|
+
`timezone`, `request.entity`, and `destination: {"name":"...","version":"v1"}`.
|
|
59
|
+
Do not assume that an existing destination profile is bound to any schedule.
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
ml-platform --profile server create-prediction-report-schedule SCHEDULE_JSON
|
|
63
|
+
ml-platform --profile server update-prediction-report-schedule SCHEDULE_ID CHANGES_JSON
|
|
64
|
+
ml-platform --profile server pause-prediction-report-schedule SCHEDULE_ID
|
|
65
|
+
ml-platform --profile server resume-prediction-report-schedule SCHEDULE_ID
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Updates accept only `name`, `cron`, `timezone`, `request`, `destination`,
|
|
69
|
+
`max_attempts`, and `timeout_seconds`; pause/resume control `enabled`.
|
|
70
|
+
After mutation, fetch the schedule and its runs. Report the schedule ID,
|
|
71
|
+
revision, destination name/version, next run time, latest run status, and
|
|
72
|
+
redacted error code. Do not claim delivery succeeded based only on validation
|
|
73
|
+
or schedule creation.
|
|
74
|
+
|
|
75
|
+
At completion, offer a next step only when it fits the observed state: after a
|
|
76
|
+
profile is created, optionally bind it to a schedule for a suitable deployment;
|
|
77
|
+
after a disabled schedule is verified, optionally resume it with explicit
|
|
78
|
+
authorization; after a run, inspect failure evidence or confirm `SUCCEEDED`.
|
|
79
|
+
Do not suggest another configuration step merely to keep the workflow going,
|
|
80
|
+
and do not treat a suggestion as permission to enable external delivery.
|