@zhuoyuezs/ml-platform 0.2.3-alpha → 0.2.3-alpha.2

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 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/` 下四个受支持 Skill 是各自唯一源码。
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` 与 `model-deployment-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` 命令,并将四个 Skill 安装到
23
+ 这条命令不需要额外参数。默认安装持久化的 `ml-platform` 命令,并将五个 Skill 安装到
23
24
  `~/.codex/skills/`,供当前用户的 Codex 使用。安装后重启终端和 Agent 会话。
24
25
 
25
26
  只在当前项目使用 Skill 时,在项目根目录运行:
@@ -106,6 +107,12 @@ ml-platform build-dataset /absolute/path/to/manifest.json --wait
106
107
  ml-platform --help
107
108
  ```
108
109
 
110
+ 定时预测上报的目标配置使用 `ml_data_platform.destination_profile/v2`
111
+ 和声明式 `payload_mapping`。在启用计划前,可用
112
+ `ml-platform preview-destination-profile PROFILE_JSON STANDARD_PAYLOAD_JSON`
113
+ 查看映射后的请求体;具体合同和暂停/恢复流程见随包安装的
114
+ `prediction-report-management` Skill。旧 v1 Profile 不可在 v2 API 上执行。
115
+
109
116
  Dataset 查询和 `list-deployments` 直接使用远程 Registry/API,适合 Agent 对已发布版本执行发现、只读诊断和
110
117
  受控构建,不要求本地存在 Catalog。`apply`、`resolve-manifest` 和带本地 JSON 路径的
111
118
  `build-dataset` 用于新契约的编写和发布流程。
@@ -131,8 +138,9 @@ npx --yes --registry=https://registry.npmjs.org/ \
131
138
  ## 包内容
132
139
 
133
140
  - 一份由 TypeScript 编译的 business CLI;
134
- - 四份纯 Skill:`feature-management`、`data-source-exploration`、
135
- `model-lifecycle-management` 与 `model-deployment-management`;
141
+ - 五份纯 Skill:`feature-management`、`data-source-exploration`、
142
+ `model-lifecycle-management`、`model-deployment-management` 与
143
+ `prediction-report-management`;
136
144
  - 显式安装、升级、状态、校验和回滚逻辑。
137
145
 
138
146
  不包含 Codex CLI、Python business-client wheel、Agent Host、平台服务端、模型训练或 Kubernetes
package/checksums.json CHANGED
@@ -2,17 +2,17 @@
2
2
  "files": [
3
3
  {
4
4
  "path": "runtime/business-client/README.md",
5
- "sha256": "sha256:c263ebe1591d38d90fb68227f42c6de43014a05e98b736d2e3363e19545676d9",
6
- "size_bytes": 8779
5
+ "sha256": "sha256:e0bf5707e13eb8bc36b530741a476827eef8263f23ff796f064dc0bfae9a8bfb",
6
+ "size_bytes": 14154
7
7
  },
8
8
  {
9
9
  "path": "runtime/business-client/package-lock.json",
10
- "sha256": "sha256:ebc31820ae0d2985879efd87ba4b0d8843e44a175d4c9e1dc557737893f8bdae",
10
+ "sha256": "sha256:fcc57e214724294f6208ec192dbe42b9cabbb6324945b0e93471bf991f76f0bc",
11
11
  "size_bytes": 1628
12
12
  },
13
13
  {
14
14
  "path": "runtime/business-client/package.json",
15
- "sha256": "sha256:4685ca172b5b23bd5de53bcccbd7f7412df281eff67533d72d1b598c63a28b47",
15
+ "sha256": "sha256:61b2a01e7611af07ad49a1789cbaddb5f8ec36d70b78ef72d54227039990e8dc",
16
16
  "size_bytes": 671
17
17
  },
18
18
  {
@@ -22,8 +22,8 @@
22
22
  },
23
23
  {
24
24
  "path": "runtime/business-client/src/cli.js",
25
- "sha256": "sha256:739be8665f611802d9196ba84566578fbfc6544c6907af165edbaf115d9d1998",
26
- "size_bytes": 62651
25
+ "sha256": "sha256:3913154693561ea4cea1538f560bf5e4f4b4488398abf69332f23f302481ee04",
26
+ "size_bytes": 66966
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:3c8b40b0da0bb87c95f1367f540cd08a7ec28e0d5fe8e52a0367fecb5ae4094c",
36
- "size_bytes": 18763
35
+ "sha256": "sha256:517ad46944f3a4068a00a570dc09975c5b59de61b730e0acf8e009ee1f18c89d",
36
+ "size_bytes": 18865
37
37
  },
38
38
  {
39
39
  "path": "skills/data-source-exploration/SKILL.md",
40
- "sha256": "sha256:3b609d61f3c73da3657ce2e6bb4d1eff95a90e4ac5e5445b8513536438b26b0b",
41
- "size_bytes": 3853
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:309d2ae292113f99bd17b6865b87bbe793809c88005458f477fa1e80c41b1523",
51
- "size_bytes": 33334
50
+ "sha256": "sha256:1118aef3734fe14fd8f7d1074ff730340663e42565155bde984ab5b397c2da77",
51
+ "size_bytes": 33777
52
52
  },
53
53
  {
54
54
  "path": "skills/feature-management/agents/openai.yaml",
@@ -127,8 +127,8 @@
127
127
  },
128
128
  {
129
129
  "path": "skills/model-deployment-management/SKILL.md",
130
- "sha256": "sha256:d50f64fa709c8ff36da97c60ce0d20b1217d1d9f78f602048f49c0c4bbab7ea2",
131
- "size_bytes": 3927
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:1f2174fac7f82e7539c781b1c7bc4164a8adc393acb33b3b2165408b25600135",
156
- "size_bytes": 4888
155
+ "sha256": "sha256:9ad2428621b52a15a83dce34a2a95606d7d979017a227c0aeb8fe5c8acd5faa3",
156
+ "size_bytes": 5442
157
157
  },
158
158
  {
159
159
  "path": "skills/model-lifecycle-management/agents/openai.yaml",
@@ -189,6 +189,16 @@
189
189
  "path": "skills/model-lifecycle-management/references/zero-shot-inference.md",
190
190
  "sha256": "sha256:4ea224be54a7b0fc7754bdaa41df0f3b14c56f5134afc3951e91e59844108f90",
191
191
  "size_bytes": 2350
192
+ },
193
+ {
194
+ "path": "skills/prediction-report-management/SKILL.md",
195
+ "sha256": "sha256:35242893137502ece779eb3b66f0d5a2e36d10dd944af5e2fead20547c7866e3",
196
+ "size_bytes": 5923
197
+ },
198
+ {
199
+ "path": "skills/prediction-report-management/agents/openai.yaml",
200
+ "sha256": "sha256:fd86629700aa9a4f1ab985d87883162ab260f469d5059a516abcd1e3273d89fa",
201
+ "size_bytes": 241
192
202
  }
193
203
  ],
194
204
  "schema_version": "data_platform.ml_platform_checksums/v1"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zhuoyuezs/ml-platform",
3
- "version": "0.2.3-alpha",
3
+ "version": "0.2.3-alpha.2",
4
4
  "description": "ML 数据平台 business CLI 与 Agent Skills 管理工具",
5
5
  "bin": {
6
6
  "ml-platform": "scripts/main.js"
package/release.json CHANGED
@@ -13,8 +13,8 @@
13
13
  "entrypoint": "src/cli.js",
14
14
  "name": "ml-platform",
15
15
  "path": "runtime/business-client",
16
- "sha256": "sha256:ff1b5f6de8111ac9dea00701afadbb6e47cc14937fa78b958ec8a3b777a4ecb9",
17
- "version": "0.8.3"
16
+ "sha256": "sha256:a002eb1fb35605ad13ad071b2131233fd4b798e3438984ae1c4c6f4ddf262902",
17
+ "version": "0.8.4"
18
18
  },
19
19
  "policy_sha256": "sha256:02fbde0134696b78c0c365d6e0b76c9814227208da5b2b3d4e5dbd82dc4a3606",
20
20
  "public_schema_versions": [
@@ -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.3-alpha",
28
+ "release_version": "0.2.3-alpha.2",
29
29
  "runtime_requirements": {
30
30
  "node": ">=18",
31
31
  "os": [
@@ -37,28 +37,34 @@
37
37
  "skills": {
38
38
  "data-source-exploration": {
39
39
  "path": "skills/data-source-exploration",
40
- "requires_cli": ">=0.8.3 <0.9.0",
41
- "revision": "0.2.3-alpha",
42
- "sha256": "sha256:ae3cfc88f8f3f46a5b7e0179d850b2216bc37275f34679dbea1ff2ba99875a96"
40
+ "requires_cli": ">=0.8.4 <0.9.0",
41
+ "revision": "0.2.3-alpha.2",
42
+ "sha256": "sha256:2fa1e1802d799ee0c47b10263f2fde57b604e505fea5c98bfa23f51f382bbf69"
43
43
  },
44
44
  "feature-management": {
45
45
  "path": "skills/feature-management",
46
- "requires_cli": ">=0.8.3 <0.9.0",
47
- "revision": "0.2.3-alpha",
48
- "sha256": "sha256:63e3bc337bc4cc4cdd38bfdd99ff9d8fd6c7d57d24aec1b7f70101ce38b1f599"
46
+ "requires_cli": ">=0.8.4 <0.9.0",
47
+ "revision": "0.2.3-alpha.2",
48
+ "sha256": "sha256:6dfa708172c3b5b23af75997c82a6d43bc2eb8ca67cc2275c8b95022455b0c42"
49
49
  },
50
50
  "model-deployment-management": {
51
51
  "path": "skills/model-deployment-management",
52
- "requires_cli": ">=0.8.3 <0.9.0",
53
- "revision": "0.2.3-alpha",
54
- "sha256": "sha256:e7d87c272a0dcc028ea628d5e36f5b7e52ed27cb9c1bc17ea76527478e28b46d"
52
+ "requires_cli": ">=0.8.4 <0.9.0",
53
+ "revision": "0.2.3-alpha.2",
54
+ "sha256": "sha256:d3f3fe0e4a11b93d8f6f57758164aa236b84a49c1b9f0d0b700fd9d6d615a8d7"
55
55
  },
56
56
  "model-lifecycle-management": {
57
57
  "path": "skills/model-lifecycle-management",
58
- "requires_cli": ">=0.8.3 <0.9.0",
59
- "revision": "0.2.3-alpha",
60
- "sha256": "sha256:13f94cb0928d15a83b8bb10195dc3a83c28c4bb7723bc8a35e262b6c1ba46b0d"
58
+ "requires_cli": ">=0.8.4 <0.9.0",
59
+ "revision": "0.2.3-alpha.2",
60
+ "sha256": "sha256:8822fbec7037c2312d18b1d18648b60757fc569e6bf5f2856ea41592f3ba987d"
61
+ },
62
+ "prediction-report-management": {
63
+ "path": "skills/prediction-report-management",
64
+ "requires_cli": ">=0.8.4 <0.9.0",
65
+ "revision": "0.2.3-alpha.2",
66
+ "sha256": "sha256:3a6991eec5cfa6bf30eaf43295f0c7d5c1e70e4f638904dfde1be2a39965d64f"
61
67
  }
62
68
  },
63
- "source_commit": "42714d93a4fdcc29fce8d98bc8e17823535cb56f"
69
+ "source_commit": "bd2e27ea798072563389c412ec4cae2a61296ba6"
64
70
  }
@@ -73,6 +73,113 @@ 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/v2",
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": {
94
+ "schema_version": "ml_data_platform.report_mapping/v1",
95
+ "body": {
96
+ "deviceCode": {"source": "entity.site", "type": "string"},
97
+ "cutoffTime": {"source": "cutoff_time", "type": "string"},
98
+ "source": {"constant": "ITSMP", "type": "string"},
99
+ "values": {
100
+ "source": "predictions", "type": "array",
101
+ "items": {"fields": {
102
+ "time": {"source": "target_time", "type": "string"},
103
+ "value": {"source": "value", "type": "number", "scale": 1.0, "offset": 0.0}
104
+ }}
105
+ }
106
+ }
107
+ },
108
+ "authentication": {
109
+ "kind": "token_endpoint",
110
+ "token_request": {
111
+ "method": "GET",
112
+ "path": "/auth/getToken",
113
+ "parameters": [
114
+ {"name": "appKey", "value": "<app-key>", "location": "query"},
115
+ {"name": "appSecurity", "value": "<app-secret>", "location": "query"}
116
+ ]
117
+ },
118
+ "success": {"http_status": [200], "body_code_path": "code", "body_code_values": [200]},
119
+ "token_path": "data.token",
120
+ "header_name": "Authorization",
121
+ "header_scheme": "Bearer"
122
+ },
123
+ "response_success": {"http_status": [200], "body_code_path": "code", "body_code_values": [200]},
124
+ "max_token_refreshes_per_day": 20
125
+ }
126
+ ```
127
+
128
+ 标准上下文包含 `run_id`、`schedule_id`、`deployment_id`、`deployment_revision`、`model_artifact_id`、
129
+ `cutoff_time`、`entity`、`horizon`、`output_window`、`prediction_hash` 和标准化的
130
+ `predictions`。每个 prediction point 至少包含 `series_index`、`value`,序列结果通常还包含
131
+ `target_time`。`source` 引用平台标准预测结果中的字段;`fields` 生成嵌套对象,`items` 将数组逐项转换,
132
+ `constant` 写入固定值,`template` 可拼接已存在的字符串字段。`format` 可格式化时间,
133
+ `scale` 和 `offset` 可执行受控数值换算,`type` 校验最终类型。`token_path`、业务成功码和
134
+ `/forecast/report` 只是示例,必须按目标接口的真实响应和路径配置。
135
+ 映射字段缺失或类型不匹配时不会发送请求,Run 会记录 `payload_mapping_failed`。若响应提供有效期,可设置 `expires_in_path` 与 `expires_in_unit`;否则服务端默认按 7200 秒缓存,
136
+ 并在 `refresh_skew_seconds` 前刷新。不同环境应使用不同 Profile 版本或名称;修改目标地址、
137
+ 认证规则、映射或凭据时创建新版本。`get`/`list` 只返回凭据已配置的脱敏标记,无法取回明文。
138
+
139
+ ```bash
140
+ ml-platform --profile server validate-destination-profile /absolute/path/to/profile.json
141
+ ml-platform --profile server create-destination-profile /absolute/path/to/profile.json
142
+ ml-platform --profile server preview-destination-profile /absolute/path/to/profile.json \
143
+ /absolute/path/to/standard-prediction.json
144
+ ml-platform --profile server list-destination-profiles --limit 50 --offset 0
145
+ ml-platform --profile server get-destination-profile forecast_sink v1
146
+ ```
147
+
148
+ 计划引用已有 Profile,不复制凭据。`SCHEDULE_JSON` 示例:
149
+
150
+ ```json
151
+ {
152
+ "schema_version": "ml_data_platform.prediction_report_schedule/v1",
153
+ "schedule_id": "forecast_hourly",
154
+ "name": "Hourly forecast report",
155
+ "deployment_id": "<deployment-id>",
156
+ "enabled": false,
157
+ "cron": "0 * * * *",
158
+ "timezone": "Asia/Shanghai",
159
+ "request": {"entity": {"site": "site-1"}, "horizon": "1h"},
160
+ "destination": {"name": "forecast_sink", "version": "v1"}
161
+ }
162
+ ```
163
+
164
+ 计划要求部署的模型支持 `feature_lookup`;部署必须有可用推理策略,或在计划请求中提供
165
+ `horizon`。五段 cron 至少间隔五分钟。`enabled: false` 用于先创建但不发送的计划;
166
+ 确认目标接口可用且部署 READY 后再恢复。计划创建或 Profile 校验成功均不等于已推送成功。
167
+
168
+ ```bash
169
+ ml-platform --profile server create-prediction-report-schedule /absolute/path/to/schedule.json
170
+ ml-platform --profile server list-prediction-report-schedules --limit 50 --offset 0
171
+ ml-platform --profile server get-prediction-report-schedule forecast_hourly
172
+ ml-platform --profile server update-prediction-report-schedule forecast_hourly /absolute/path/to/changes.json
173
+ ml-platform --profile server pause-prediction-report-schedule forecast_hourly
174
+ ml-platform --profile server resume-prediction-report-schedule forecast_hourly
175
+ ml-platform --profile server list-prediction-report-runs forecast_hourly --limit 50 --offset 0
176
+ ml-platform --profile server get-prediction-report-run <run-id>
177
+ ```
178
+
179
+ `CHANGES_JSON` 是仅含变更字段的对象,例如
180
+ `{"destination":{"name":"forecast_sink","version":"v2"}}`。更新不会改写历史运行;
181
+ 是否已投递成功以 Run 的 `status`、`destination_status_code` 和错误码为准。
182
+
76
183
  `READY` 必须同时包含 `ReplicasReady=true`、`ArtifactsVerified=true` 和
77
184
  `SmokePredictionPassed=true`。`get-deployment` 返回控制器实际观察到的 endpoint 元数据;
78
185
  本地 CLI 不推测 Kubernetes Service 名称。部署后验证优先使用控制面代理:
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@zhuoyuezs/ml-platform-business-client",
3
- "version": "0.8.3",
3
+ "version": "0.8.4",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@zhuoyuezs/ml-platform-business-client",
9
- "version": "0.8.3",
9
+ "version": "0.8.4",
10
10
  "license": "UNLICENSED",
11
11
  "bin": {
12
12
  "ml-platform": "src/cli.js"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zhuoyuezs/ml-platform-business-client",
3
- "version": "0.8.3",
3
+ "version": "0.8.4",
4
4
  "private": true,
5
5
  "description": "JavaScript implementation of the ML Platform business client",
6
6
  "bin": {
@@ -40,6 +40,10 @@ const BUSINESS_COMMANDS = new Set([
40
40
  "get-deployment", "wait-deployment", "reconcile-deployment", "approve-deployment",
41
41
  "promote-deployment", "rollback-deployment", "suspend-deployment", "resume-deployment",
42
42
  "undeploy-deployment", "get-deployment-events", "predict-deployment",
43
+ "validate-destination-profile", "create-destination-profile", "preview-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",
43
47
  ]);
44
48
  const COMMAND_USAGE = {
45
49
  ...Object.fromEntries([...LIFECYCLE_COLLECTIONS].map((name) => [`list-${name}`, `list-${name} [--limit N] [--offset N] [-q QUERY]`])),
@@ -166,6 +170,19 @@ const COMMAND_USAGE = {
166
170
  "undeploy-deployment": "undeploy-deployment DEPLOYMENT_ID --actor NAME --reason TEXT",
167
171
  "get-deployment-events": "get-deployment-events DEPLOYMENT_ID [--limit N] [--offset N]",
168
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
+ "preview-destination-profile": "preview-destination-profile PROFILE_JSON STANDARD_PAYLOAD_JSON",
176
+ "list-destination-profiles": "list-destination-profiles [--limit N] [--offset N]",
177
+ "get-destination-profile": "get-destination-profile NAME VERSION",
178
+ "create-prediction-report-schedule": "create-prediction-report-schedule SCHEDULE_JSON",
179
+ "list-prediction-report-schedules": "list-prediction-report-schedules [--limit N] [--offset N]",
180
+ "get-prediction-report-schedule": "get-prediction-report-schedule SCHEDULE_ID",
181
+ "update-prediction-report-schedule": "update-prediction-report-schedule SCHEDULE_ID CHANGES_JSON",
182
+ "pause-prediction-report-schedule": "pause-prediction-report-schedule SCHEDULE_ID",
183
+ "resume-prediction-report-schedule": "resume-prediction-report-schedule SCHEDULE_ID",
184
+ "list-prediction-report-runs": "list-prediction-report-runs SCHEDULE_ID [--limit N] [--offset N]",
185
+ "get-prediction-report-run": "get-prediction-report-run RUN_ID",
169
186
  apply: "apply CATALOG_DIRECTORY [--dry-run] [--project PROJECT]",
170
187
  };
171
188
  function usage(command) {
@@ -858,6 +875,46 @@ async function runBusinessCli(argv) {
858
875
  const request = readSpec(positional(rest, "request JSON"));
859
876
  result = await client(options).post(`/deployments/${encodeURIComponent(deploymentId)}/predict`, request);
860
877
  }
878
+ else if (["create-destination-profile", "validate-destination-profile"].includes(options.command)) {
879
+ result = await client(options).post(options.command === "create-destination-profile" ? "/destination-profiles" : "/destination-profiles/validate", readSpec(positional(rest, "profile JSON")));
880
+ }
881
+ else if (options.command === "preview-destination-profile") {
882
+ result = await client(options).post("/destination-profiles/preview", {
883
+ profile: readSpec(positional(rest, "profile JSON")),
884
+ payload: readSpec(positional(rest, "standard payload JSON")),
885
+ });
886
+ }
887
+ else if (options.command === "list-destination-profiles") {
888
+ result = await listCollection(client(options), "/destination-profiles", {}, rest);
889
+ }
890
+ else if (options.command === "get-destination-profile") {
891
+ const name = positional(rest, "profile name");
892
+ const version = positional(rest, "profile version");
893
+ result = await client(options).get(`/destination-profiles/${encodeURIComponent(name)}/versions/${encodeURIComponent(version)}`);
894
+ }
895
+ else if (options.command === "create-prediction-report-schedule") {
896
+ result = await client(options).post("/prediction-report-schedules", readSpec(positional(rest, "schedule JSON")));
897
+ }
898
+ else if (options.command === "list-prediction-report-schedules") {
899
+ result = await listCollection(client(options), "/prediction-report-schedules", {}, rest);
900
+ }
901
+ 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)) {
902
+ const scheduleId = positional(rest, "schedule id");
903
+ const endpoint = `/prediction-report-schedules/${encodeURIComponent(scheduleId)}`;
904
+ if (options.command === "update-prediction-report-schedule")
905
+ result = await client(options).patch(endpoint, readSpec(positional(rest, "changes JSON")));
906
+ else if (options.command === "pause-prediction-report-schedule")
907
+ result = await client(options).post(`${endpoint}/pause`);
908
+ else if (options.command === "resume-prediction-report-schedule")
909
+ result = await client(options).post(`${endpoint}/resume`);
910
+ else if (options.command === "list-prediction-report-runs")
911
+ result = await listCollection(client(options), `${endpoint}/runs`, {}, rest);
912
+ else
913
+ result = await client(options).get(endpoint);
914
+ }
915
+ else if (options.command === "get-prediction-report-run") {
916
+ result = await client(options).get(`/prediction-report-runs/${encodeURIComponent(positional(rest, "run id"))}`);
917
+ }
861
918
  else if (options.command === "get-model-runtime-release") {
862
919
  result = await client(options).get("/model-runtime-release");
863
920
  }
@@ -62,6 +62,7 @@ class PlatformApiClient {
62
62
  post(endpoint, payload, params) { return this.request("POST", endpoint, { payload, params }); }
63
63
  postWithHeaders(endpoint, payload, requestHeaders) { return this.request("POST", endpoint, { payload, requestHeaders }); }
64
64
  put(endpoint, payload, params) { return this.request("PUT", endpoint, { payload, params }); }
65
+ patch(endpoint, payload, params) { return this.request("PATCH", endpoint, { payload, params }); }
65
66
  delete(endpoint, params) { return this.request("DELETE", endpoint, { params }); }
66
67
  uploadFoundationCsv(endpoint, schema, forecast, filePath, requestHeaders = {}) {
67
68
  const resolved = path.resolve(expandHome(filePath));
@@ -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.
@@ -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.
@@ -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.
@@ -54,3 +54,12 @@ Report immutable input identities, returned run/job/package IDs, status, validat
54
54
  Route deployment validation, creation, rollout state, approval, promotion,
55
55
  rollback, offline operations, and deployment-bound prediction to the separate
56
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.
@@ -0,0 +1,116 @@
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: ml_data_platform.destination_profile/v2`, `name`,
33
+ `version`, `base_url`, `path`, a declarative
34
+ `payload_mapping`, authentication, and response success rules as required by
35
+ the target. For token-based auth, set `authentication.token_request` parameters
36
+ and `token_path`; configure both token and report business success rules when
37
+ HTTP 2xx alone is insufficient.
38
+
39
+ `payload_mapping` has `schema_version: ml_data_platform.report_mapping/v1`
40
+ and a non-empty `body` object. This maps each normalized prediction point:
41
+
42
+ ```json
43
+ {
44
+ "schema_version": "ml_data_platform.report_mapping/v1",
45
+ "body": {
46
+ "values": {
47
+ "source": "predictions",
48
+ "items": {"fields": {"value": {"source": "value", "type": "number"}}}
49
+ }
50
+ }
51
+ }
52
+ ```
53
+
54
+ A point always has `series_index` and `value`; `target_time` is present only
55
+ when Serving returns it.
56
+
57
+ ```bash
58
+ ml-platform --profile server validate-destination-profile PROFILE_JSON
59
+ ml-platform --profile server create-destination-profile PROFILE_JSON
60
+ ml-platform --profile server preview-destination-profile PROFILE_JSON STANDARD_PAYLOAD_JSON
61
+ ml-platform --profile server get-destination-profile NAME v1
62
+ ```
63
+
64
+ Validation checks schema and local policy; it does **not** call the token or
65
+ report endpoint. Versions are immutable. Changes to URL, auth, token extraction,
66
+ mapping, or success rules require a new profile version and a schedule update
67
+ to point to it. Profiles stored with the former v1 schema cannot be executed
68
+ under the v2 API; create a v2 profile and update the paused schedule first.
69
+ `get` and `list` redact credential values; they cannot reconstruct the
70
+ original file. Keep credential-bearing JSON outside the repository, restrict
71
+ file access, and do not print its contents or put secrets in shell arguments,
72
+ logs, examples, or Agent answers. Destination URL and token credentials are
73
+ business configuration submitted through this API, not Kubernetes Secrets.
74
+
75
+ Mapping sources use standard report fields such as `run_id`, `schedule_id`,
76
+ `deployment_id`, `cutoff_time`, `entity`, and `predictions`. Use `fields` for
77
+ nested objects, `items` for array conversion, `constant` for fixed values,
78
+ `template` for string composition, and `format`, `scale`, `offset`, and `type`
79
+ for bounded transformations and validation. Arbitrary code and expressions are
80
+ not supported. A missing field or type failure produces
81
+ `payload_mapping_failed` before any HTTP request is made.
82
+
83
+ Use `preview-destination-profile` with a standard prediction payload to inspect
84
+ the exact mapped business body before creating or enabling a schedule. Preview
85
+ does not call the token endpoint, does not send the report, and does not store
86
+ the profile or sample payload.
87
+
88
+ ## Manage a schedule
89
+
90
+ Creating a schedule starts reporting when `enabled` is true. Obtain explicit
91
+ authorization for the exact destination and deployment before creation, update,
92
+ pause, or resume. Use `enabled: false` for a staged schedule that should not
93
+ run yet. `SCHEDULE_JSON` contains `deployment_id`, five-field `cron`, IANA
94
+ `timezone`, `request.entity`, and `destination: {"name":"...","version":"v1"}`.
95
+ Do not assume that an existing destination profile is bound to any schedule.
96
+
97
+ ```bash
98
+ ml-platform --profile server create-prediction-report-schedule SCHEDULE_JSON
99
+ ml-platform --profile server update-prediction-report-schedule SCHEDULE_ID CHANGES_JSON
100
+ ml-platform --profile server pause-prediction-report-schedule SCHEDULE_ID
101
+ ml-platform --profile server resume-prediction-report-schedule SCHEDULE_ID
102
+ ```
103
+
104
+ Updates accept only `name`, `cron`, `timezone`, `request`, `destination`,
105
+ `max_attempts`, and `timeout_seconds`; pause/resume control `enabled`.
106
+ After mutation, fetch the schedule and its runs. Report the schedule ID,
107
+ revision, destination name/version, next run time, latest run status, and
108
+ redacted error code. Do not claim delivery succeeded based only on validation
109
+ or schedule creation.
110
+
111
+ At completion, offer a next step only when it fits the observed state: after a
112
+ profile is created, optionally bind it to a schedule for a suitable deployment;
113
+ after a disabled schedule is verified, optionally resume it with explicit
114
+ authorization; after a run, inspect failure evidence or confirm `SUCCEEDED`.
115
+ Do not suggest another configuration step merely to keep the workflow going,
116
+ and do not treat a suggestion as permission to enable external delivery.
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "定时预测上报管理"
3
+ short_description: "管理预测上报目标、计划及运行记录"
4
+ default_prompt: "使用 $prediction-report-management 管理定时预测上报配置、计划和运行记录。"