@kanyun-ai-infra/agenthub 0.1.1 → 0.3.0

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/README.md CHANGED
@@ -1,51 +1,52 @@
1
1
  # @kanyun-ai-infra/agenthub
2
2
 
3
- Typed TypeScript client for the **agenthub Control Plane API**.
3
+ 用于 **agenthub Control Plane API** 的类型化 TypeScript 客户端。
4
4
 
5
- It talks directly to the agenthub Control Plane and is meant for backend
6
- services, CI, and tooling that drive the
7
- `project → workload → revision → session` lifecycle programmatically.
5
+ 它直接调用 agenthub Control Plane,适合后端服务、CI 和工具以编程方式驱动
6
+ `project → agent → version → session` 生命周期。
8
7
 
9
- Two surfaces are involved:
8
+ 接入时会遇到两个入口:
10
9
 
11
- | Surface | URL | Audience |
10
+ | 入口 | URL | 用途 |
12
11
  | --- | --- | --- |
13
- | **Control Plane API** | `https://agenthub-plane.zhenguanyu.com` | This SDK / your services — pass it as `controlPlaneUrl`. |
14
- | **Admin portal** | `https://agenthub.zhenguanyu.com` | Humans who publish and manage agents — and where you **issue an API token**. |
12
+ | **Control Plane API** | `https://agenthub-plane.zhenguanyu.com` | SDK / 你的服务调用。作为 `controlPlaneUrl` 传入。 |
13
+ | **管理门户** | `https://agenthub.zhenguanyu.com` | 人工发布和管理 agent,并在这里**签发 API token**。 |
15
14
 
16
- The two use different token audiences: a portal session token will **not** work
17
- against the Control Plane, and vice versa. Always pair the platform-api token
18
- issued from the portal with the `agenthub-plane` Control Plane URL.
15
+ 两者使用不同的 token audience:Portal 登录态 token 不能调用 Control Plane,反过来也一样。
16
+ 请始终把管理门户签发的 platform-api token 和 `agenthub-plane` Control Plane URL 配套使用。
19
17
 
20
- ## Install
18
+ ## 安装
21
19
 
22
20
  ```bash
23
21
  pnpm add @kanyun-ai-infra/agenthub
24
- # or: npm i @kanyun-ai-infra/agenthub
22
+ # 或:npm i @kanyun-ai-infra/agenthub
25
23
  ```
26
24
 
27
- Requires Node 18+ (uses the global `fetch`).
25
+ 需要 Node 18+,因为 SDK 使用全局 `fetch`。
28
26
 
29
- ## Quickstart
27
+ 如果调用方是 Java、Python、Go 或 Shell,请优先看 raw HTTP 指南和 REST 参考:
28
+ [`docs/user-guide/agenthub-http-quickstart.md`](../../docs/user-guide/agenthub-http-quickstart.md),
29
+ [`docs/user-guide/agenthub-rest-api.md`](../../docs/user-guide/agenthub-rest-api.md)。
30
+
31
+ ## 快速开始
30
32
 
31
33
  ```ts
32
34
  import { PilotPlatformClient } from "@kanyun-ai-infra/agenthub";
33
35
 
34
36
  const agenthub = new PilotPlatformClient({
35
37
  controlPlaneUrl: "https://agenthub-plane.zhenguanyu.com",
36
- token: process.env.PILOT_TOKEN, // platform-api token from the admin portal
38
+ token: process.env.PILOT_TOKEN, // 管理门户签发的 platform-api token
37
39
  });
38
40
 
39
- // 1. Project — the tenant/root grouping. The default runtime template lets
40
- // callers publish revisions without picking one each time (see below).
41
+ // 1. Project:租户 / 根分组。默认 runtime template 让发布 Version 时不必每次手选模板。
41
42
  const project = await agenthub.projects.create({
42
43
  slug: "acme",
43
44
  displayName: "Acme",
44
45
  defaultRuntimeTemplateRefName: "pilot-v2-pod-agent",
45
46
  });
46
47
 
47
- // 2. Workload — a runnable agent/app in the project
48
- await agenthub.workloads.create({
48
+ // 2. Agent:Project 下一个可运行的 agent。
49
+ await agenthub.agents.create({
49
50
  projectId: project.id,
50
51
  slug: "support-bot",
51
52
  displayName: "Support Bot",
@@ -56,11 +57,10 @@ await agenthub.workloads.create({
56
57
  },
57
58
  });
58
59
 
59
- // 3. Revision — an immutable published version. Runtime source is inherited
60
- // from the project default; override per revision with `runtime.profileRef`.
61
- const revision = await agenthub.workloads.publishRevision({
60
+ // 3. Version:Agent 的不可变发布版本。Runtime source 默认继承 Project default。
61
+ const version = await agenthub.agents.publishVersion({
62
62
  projectId: project.id,
63
- workloadSlug: "support-bot",
63
+ agentSlug: "support-bot",
64
64
  version: "v1",
65
65
  workerContract: { kind: "managed_agent" },
66
66
  setDefault: true,
@@ -70,144 +70,175 @@ const revision = await agenthub.workloads.publishRevision({
70
70
  },
71
71
  });
72
72
 
73
- // 4. Session — a runtime allocation against the default (or a specific) revision
73
+ // 4. Session:基于默认 Version(或指定 Version)分配一次运行时。
74
74
  const session = await agenthub.sessions.create({
75
75
  projectId: project.id,
76
- workloadId: revision.workloadId,
76
+ agentId: version.agentId, // 用默认 Version;指定版本传 versionId
77
77
  });
78
78
 
79
- const ready = await agenthub.sessions.wait(session.sessionId); // resolves when status === "ready"
79
+ const ready = await agenthub.sessions.wait(session.sessionId); // status === "ready" 时返回
80
80
  ```
81
81
 
82
- ## Client configuration
82
+ ## 核心模型
83
83
 
84
- `new PilotPlatformClient(config)`
84
+ ```text
85
+ Project → Agent → Version → Session
86
+ ```
87
+
88
+ - **Project**:租户 / 根分组,拥有 agents 和 runtime templates。
89
+ - **Agent**:一个逻辑可运行应用。`kind` 是 `"managed_agent"`(平台基于
90
+ `model` + `systemPrompt` 运行 agent loop)或 `"self_managed"`(你自己提供 worker)。
91
+ - **Version**:Agent 的不可变发布版本,绑定一个 runtime source。用 `setDefault`
92
+ 标记 project/agent 默认版本。
93
+ - **Session**:基于某个 Version 发起的一次 startup/runtime allocation。
85
94
 
86
- | Option | Required | Description |
95
+ Agents 和 runtime templates 都是 **project-scoped**。Version 必须在同一个 Project
96
+ 内解析到 Agent 和 runtime source;唯一例外是下文的 platform-shared templates。
97
+
98
+ > 本文一律用主词汇 **agent / version**;它们是底层 wire 名 `workload` / `revision`
99
+ > 的别名,SDK 两套都接受,细节见 [术语别名](#术语别名agent--version)。
100
+
101
+ ### 术语别名(agent / version)
102
+
103
+ | 主词汇(推荐) | 等价的底层名 | 说明 |
87
104
  | --- | --- | --- |
88
- | `controlPlaneUrl` | yes¹ | Control Plane origin. Relative request paths are composed under it; cross-origin paths are rejected before the token is sent. |
89
- | `token` | yes¹ | Platform-api token. Sent as `Authorization: Bearer <token>` on every request. |
90
- | `fetch` | no | Custom `fetch` implementation (defaults to the global). |
91
- | `signal` | no | Default `AbortSignal` applied to every request. |
92
- | `defaultHeaders` | no | Extra headers merged into every request. |
93
- | `userAgent` | no | Overrides the default `@kanyun-ai-infra/agenthub/<version>` UA. |
94
- | `pilotApiVersion` | no | Pins the `x-pilot-api-version` header (defaults to the v2 wire version). |
105
+ | `agenthub.agents` | `agenthub.workloads` | **同一个资源实例**(`agents === workloads`),方法两边都能调。 |
106
+ | `agents.publishVersion({ agentSlug })` | `workloads.publishRevision({ workloadSlug })` | 同一个调用;wire body 完全一致。 |
107
+ | `sessions.create({ agentId, versionId })` | `sessions.create({ workloadId, revisionId })` | 入参别名,内部映射回规范名后再发出。 |
108
+ | 返回字段 `result.agentId` / `result.versionId` | `result.workloadId` / `result.revisionId` | 返回对象**同时带**两套字段(别名 = 规范值)。 |
95
109
 
96
- ¹ `controlPlaneUrl` falls back to `PILOT_CONTROL_PLANE_URL` then
97
- `KANYUN_PILOT_CONTROL_PLANE_URL`; `token` falls back to `PILOT_TOKEN`. Missing
98
- either produces a typed SDK error before any request is sent.
110
+ 规则:
99
111
 
100
- ### Getting a token
112
+ - **互斥**:一对里只能传一个,规范名和别名同传会抛 `ALIAS_CONFLICT`,避免笔误被静默忽略
113
+ (`sessions.create` 的 `agentId`/`workloadId`、`versionId`/`revisionId`,
114
+ `applyRevisionManifest` 的 `agentSlug`/`workloadSlug`)。
115
+ - 入参别名**不进 wire**:发请求前映射回 `workloadId`/`revisionId`,body 永远是规范名。
116
+ - 返回别名是 SDK 派生的可枚举字段(`JSON.stringify` / 日志都带得上),不回传服务端。
117
+ - 底层名(`workloads` / `publishRevision` / `workloadId`)一直保留、行为不变,挑读着顺的那套写即可。
118
+ - 异步事件 payload、日志 / Trace 里的关联 ID 仍是 `workloadId`/`revisionId`(属 control-plane 范畴,不在 SDK 改名范围内)。
101
119
 
102
- Sign in to the **admin portal** at <https://agenthub.zhenguanyu.com> and issue a
103
- **platform-api token**. That token is scoped to the Control Plane API
104
- (`agenthub-plane.zhenguanyu.com`); store it as `PILOT_TOKEN` (or pass it as
105
- `token`). Tokens are bearer credentials — keep them out of source control and
106
- rotate from the portal if leaked.
120
+ ## API 参考
107
121
 
108
- ## Core model
122
+ ### `agenthub.projects`
109
123
 
110
- ```text
111
- Project → Workload → Revision → Session
112
- ```
124
+ | 方法 | 说明 |
125
+ | --- | --- |
126
+ | `create({ slug, displayName, description?, defaultRuntimeTemplateRefName? })` | 创建 Project。slug 重复时返回 `409 PROJECT_SLUG_CONFLICT`。 |
127
+ | `list()` | 列出 token 有效 scope 内的 Project。 |
128
+ | `get(projectId)` | 查询单个 Project。 |
129
+
130
+ ### `agenthub.agents`(别名 `agenthub.workloads`)
113
131
 
114
- - **Project** — tenant/root grouping; owns workloads and runtime templates.
115
- - **Workload** — a logical runnable app. `kind` is `"managed_agent"` (platform
116
- runs the agent loop from `model` + `systemPrompt`) or `"self_managed"` (you
117
- ship the worker).
118
- - **Revision** — an immutable published version of a workload, bound to one
119
- runtime source. Mark one as the project/workload default with `setDefault`.
120
- - **Session** — a startup/runtime allocation against a revision.
132
+ | 方法 | 说明 |
133
+ | --- | --- |
134
+ | `create(req, { dryRun? })` | 创建 Agent。返回 `{ mode, status, agentId?/workloadId?, workload }`。 |
135
+ | `publishVersion(req, { dryRun? })` | 发布 Version(别名 `publishRevision`,用 `workloadSlug`)。返回 `{ mode, status, agentId/workloadId, versionId?/revisionId?, runtimeTemplateId, resolved }`。 |
136
+ | `applyManifest({ projectId, manifest, dryRun? })` | 高级 / GitOps:apply raw agent manifest。 |
137
+ | `applyRevisionManifest({ projectId, agentSlug \| workloadSlug, manifest, dryRun? })` | 高级 / GitOps:apply raw version manifest。两个 slug 拼写都接受(互斥)。 |
121
138
 
122
- Workloads and runtime templates are **project-scoped**. A revision must resolve
123
- its workload and runtime source inside the same project (the one exception is
124
- platform-shared templates, below).
139
+ `create` / `publishVersion` 的 `req` 结构和 managed-agent 全部配置项(`model` /
140
+ `systemPrompt` / `enabledSkills` / `enabledMcpServers` / `agentOptions` 安全约束 /
141
+ `runtime` / `startup` 等),见
142
+ [`specs/features/agenthub-sdk.md`](../../specs/features/agenthub-sdk.md)
143
+ 的 "Managed-Agent Configuration"、"Workload API Contract"、"Revision Publish Contract" 章节。
125
144
 
126
- ## API reference
145
+ > **`agentOptions` 安全约束(高频踩坑)**:`agentOptions` **只能收紧 / 限额**,不能放宽。
146
+ > `allowedTools` 与平台基线**取交集**(只会更窄)、`disallowedTools` 叠加平台黑名单且
147
+ > **不能移除**平台守卫工具;`permissionMode` / `env` / `mcpServers` / `hooks` /
148
+ > `plugins` / 原始 `sdkOptions` 等可能越权或逃逸 sandbox 的字段**一律不开放**(见 issue #840)。
149
+ > 字段全表见上述 spec。
127
150
 
128
- ### `agenthub.projects`
151
+ `apply*` 方法里的 `manifest` 可以是 manifest 对象、`{ yaml }` 或 `{ json }`。
152
+
153
+ ### `agenthub.sessions`
129
154
 
130
- | Method | Description |
155
+ | 方法 | 说明 |
131
156
  | --- | --- |
132
- | `create({ slug, displayName, description?, defaultRuntimeTemplateRefName? })` | Create a project. Duplicate slug → `409 PROJECT_SLUG_CONFLICT`. |
133
- | `list()` | List projects in the token's effective scope. |
134
- | `get(projectId)` | Fetch one project. |
157
+ | `create({ projectId, agentId, versionId?, configValues?, metadata?, idempotencyKey?, resources?, ... })` | 启动 Session。省略 `versionId` 时使用 Agent 默认 Version。`agentId`/`versionId` 也可写成 `workloadId`/`revisionId`(互斥)。`resources` 注入 Model A 只读输入文件(见下)。返回 `{ sessionId, status }`。 |
158
+ | `get(sessionId)` | 读取 Session 快照(`{ session: { id, status, ... } }`,字段为服务端原样返回)。 |
159
+ | `wait(sessionId, { intervalMs?, timeoutMs?, signal? })` | 轮询到 `status === "ready"`;遇到 `failed` 或超时会抛错。 |
135
160
 
136
- ### `agenthub.workloads`
161
+ Session `status` 取值为 `created`、`provisioning`、`starting`、`ready`、`failed`。
137
162
 
138
- | Method | Description |
163
+ ### `agenthub.files`
164
+
165
+ | 方法 | 说明 |
139
166
  | --- | --- |
140
- | `create(req, { dryRun? })` | Create a workload from structured input. Returns `{ mode, status, workloadId?, workload }`. |
141
- | `publishRevision(req, { dryRun? })` | Publish a revision. Returns `{ mode, status, workloadId, revisionId?, runtimeTemplateId, resolved }`. |
142
- | `applyManifest({ projectId, manifest, dryRun? })` | Advanced/GitOps: apply a raw workload manifest. |
143
- | `applyRevisionManifest({ projectId, workloadSlug, manifest, dryRun? })` | Advanced/GitOps: apply a raw revision manifest. |
167
+ | `upload({ projectId, file, filename?, contentType? })` | 上传单个文件,返回 `{ ossUrl, url, filename, size, mediaType, mimeType }`。`file` 接受 `Blob` / `File` / `Uint8Array` / `ArrayBuffer`;非具名 `File` 时必须传 `filename`。 |
144
168
 
145
- `req` for `create`:
169
+ 文件落在 `pilot/attachments/<projectId>/`,与 Session 资源 scope 校验同一 keyspace —— 为某 Project
170
+ 上传的文件无法挂到另一个 Project 的 Session。`url` 是 ~1h 的 presigned GET(仅预览用);
171
+ 要持久引用的是 `ossUrl`。
146
172
 
147
- ```ts
148
- {
149
- projectId: string;
150
- slug: string;
151
- displayName: string;
152
- kind: "managed_agent" | "self_managed";
153
- defaults?: {
154
- model?: string;
155
- systemPrompt?: string;
156
- workerContract?: { name?: string; version?: string };
157
- configValues?: Record<string, string>;
158
- enabledSkills?: EnabledSkill[];
159
- enabledMcpServers?: EnabledMcpServer[];
160
- };
161
- ui?: { /* Default-UI hints */ };
162
- }
163
- ```
173
+ #### Model A 只读输入文件(session resources)
164
174
 
165
- `req` for `publishRevision`:
175
+ 把文件作为 **Session 级只读输入**挂进 sandbox 的 `/workspace/.session/inputs/`(每次
176
+ provision / revival 重新物化),用 `files.upload` + `sessions.create({ resources })`:
166
177
 
167
178
  ```ts
168
- {
169
- projectId: string;
170
- workloadSlug: string;
171
- version: string;
172
- workerContract: { kind: "managed_agent" | "self_managed"; name?: string; version?: string };
173
- runtime?: { profileRef?: { name: string }; environment?: ...; overrides?: ... };
174
- setDefault?: boolean;
175
- startup?: { requiredGates?: string[]; optionalGates?: string[] };
176
- configValues?: Record<string, string>;
177
- managedAgentProfileSnapshot?: { model?: string; systemPrompt?: string; enabledSkills?: ...; enabledMcpServers?: ... };
178
- }
179
+ const up = await agenthub.files.upload({
180
+ projectId,
181
+ file: new Blob([await fs.promises.readFile("spec.md")]),
182
+ filename: "spec.md",
183
+ });
184
+
185
+ // `up` 是 SessionFileResource 的超集,只多一个预览用的 `url`;解构掉它,
186
+ // 剩下的 `meta`(ossUrl/filename/size/mediaType/mimeType)正是一个资源条目。
187
+ const { url, ...meta } = up;
188
+
189
+ const { sessionId } = await agenthub.sessions.create({
190
+ projectId,
191
+ agentId,
192
+ resources: {
193
+ version: "v1",
194
+ files: [{ ...meta, mountPath: "docs/spec.md" }], // mountPath 可省略 → 用文件名
195
+ },
196
+ });
197
+ // agent 在 /workspace/.session/inputs/docs/spec.md 只读看到该文件
179
198
  ```
180
199
 
181
- `manifest` (for the `apply*` methods) accepts a manifest object, `{ yaml }`, or
182
- `{ json }`.
200
+ 约束:每 Session ≤ 20 个文件;`mountPath` 必须是 `.session/inputs/` 下的相对子路径
201
+ (拒绝绝对路径与 `..`);只读。
183
202
 
184
- ### `agenthub.sessions`
203
+ ## Client 配置
185
204
 
186
- | Method | Description |
187
- | --- | --- |
188
- | `create({ projectId, workloadId, revisionId?, configValues?, metadata?, idempotencyKey?, ... })` | Start a session. Omitting `revisionId` uses the workload's default revision. Returns `{ sessionId, status }`. |
189
- | `get(sessionId)` | Snapshot the session (`{ session: { id, status, ... } }`). |
190
- | `wait(sessionId, { intervalMs?, timeoutMs?, signal? })` | Poll until `status === "ready"`; throws on `failed` or timeout. |
205
+ `new PilotPlatformClient(config)`
206
+
207
+ | 选项 | 必填 | 说明 |
208
+ | --- | --- | --- |
209
+ | `controlPlaneUrl` | 是¹ | Control Plane 源地址。相对路径会拼到它下面;跨 origin 路径会在发 token 前被拒绝。 |
210
+ | `token` | 是¹ | Platform-api token。每个请求都会作为 `Authorization: Bearer <token>` 发送。 |
211
+ | `fetch` | 否 | 自定义 `fetch` 实现,默认使用全局 `fetch`。 |
212
+ | `signal` | 否 | 应用于每个请求的默认 `AbortSignal`。 |
213
+ | `defaultHeaders` | 否 | 合并到每个请求的额外 header。 |
214
+ | `userAgent` | 否 | 覆盖默认 `@kanyun-ai-infra/agenthub/<version>` UA。 |
215
+ | `pilotApiVersion` | 否 | 固定 `x-pilot-api-version` header,默认使用 v2 wire version。 |
216
+
217
+ ¹ `controlPlaneUrl` 会依次回退到 `PILOT_CONTROL_PLANE_URL`、
218
+ `KANYUN_PILOT_CONTROL_PLANE_URL`;`token` 会回退到 `PILOT_TOKEN`。任意一项缺失时,
219
+ SDK 会在发送请求前抛出类型化错误。
220
+
221
+ ### 获取 token
191
222
 
192
- Session `status` is one of `created`, `provisioning`, `starting`, `ready`,
193
- `failed`.
223
+ 登录 **管理门户** <https://agenthub.zhenguanyu.com> 并签发 **platform-api token**。
224
+ 该 token 的作用域是 Control Plane API(`agenthub-plane.zhenguanyu.com`);可以存为
225
+ `PILOT_TOKEN`,也可以显式传给 `token`。Token 是 Bearer 凭据,请不要提交到代码仓库;
226
+ 泄露后需要在门户里轮换。
194
227
 
195
- ## Runtime templates
228
+ ## Runtime template
196
229
 
197
- A managed-agent revision runs on a **runtime template** (a registered runtime
198
- source). The Control Plane resolves it in this order:
230
+ managed-agent Version 运行在一个 **runtime template**(已注册的 runtime source)上。
231
+ Control Plane 按以下顺序解析:
199
232
 
200
- 1. revision `runtime.profileRef` (structured) / `spec.runtime.profileRef`
201
- 2. revision `spec.runtimeTemplateRef` (manifest)
202
- 3. workload defaults `spec.defaults.runtimeTemplateRef` (manifest)
233
+ 1. version `runtime.profileRef`(structured)/ `spec.runtime.profileRef`
234
+ 2. version `spec.runtimeTemplateRef`(manifest)
235
+ 3. agent defaults `spec.defaults.runtimeTemplateRef`(manifest)
203
236
  4. project `defaultRuntimeTemplateRefName`
204
237
 
205
- If none resolves → `PROJECT_DEFAULT_RUNTIME_MISSING`. If the named template does
206
- not exist in the project (or as a platform-shared template) →
207
- `RUNTIME_TEMPLATE_NOT_FOUND`.
238
+ 如果都解析不到,返回 `PROJECT_DEFAULT_RUNTIME_MISSING`。如果指定模板在当前 Project
239
+ 或 platform-shared templates 中不存在,返回 `RUNTIME_TEMPLATE_NOT_FOUND`。
208
240
 
209
- For the happy path, give the project a default at creation so callers never pick
210
- a template:
241
+ 主路径建议在创建 Project 时设置默认模板,这样发布 Version 时不需要手选:
211
242
 
212
243
  ```ts
213
244
  await agenthub.projects.create({
@@ -217,21 +248,19 @@ await agenthub.projects.create({
217
248
  });
218
249
  ```
219
250
 
220
- Otherwise select one explicitly per revision with
221
- `runtime: { profileRef: { name: "..." } }`.
251
+ 否则需要在每个 Version 上显式指定:`runtime: { profileRef: { name: "..." } }`。
222
252
 
223
- **Platform-shared templates.** Templates owned by the Platform Default project
224
- (e.g. `pilot-v2-pod-agent`) are shared infrastructure: the lookup falls back to
225
- Platform Default when the name is not found in the caller's project, so any
226
- project's revision may reference them by name. `echo-bot` is a built-in
227
- echo-only template useful for smoke tests — it does **not** run an LLM.
253
+ **Platform-shared templates。** Platform Default project 拥有的模板(例如
254
+ `pilot-v2-pod-agent`)是共享基础设施:当调用方 Project 内找不到同名模板时,解析会回退到
255
+ Platform Default,因此任意 Project 的 Version 都可以按名称引用它们。`echo-bot`
256
+ 是内置 echo-only 模板,适合 smoke test;它**不会**运行 LLM。
228
257
 
229
- ## Models
258
+ ## 模型
230
259
 
231
- `model` accepts a full id (`claude-opus-4-7`, `claude-sonnet-4-6`,
232
- `claude-haiku-4-5`) or a legacy alias that maps to one:
260
+ `model` 接受完整 id(`claude-opus-4-7`、`claude-sonnet-4-6`、`claude-haiku-4-5`),
261
+ 也接受会映射到完整 id 的历史别名:
233
262
 
234
- | Alias | Resolves to |
263
+ | Alias | 解析为 |
235
264
  | --- | --- |
236
265
  | `opus` | `claude-opus-4-7` |
237
266
  | `sonnet` | `claude-sonnet-4-6` |
@@ -239,15 +268,14 @@ echo-only template useful for smoke tests — it does **not** run an LLM.
239
268
 
240
269
  ## Dry runs
241
270
 
242
- `workloads.create`, `publishRevision`, and the `apply*` methods accept
243
- `{ dryRun: true }`. A dry run validates and resolves the request without
244
- persisting, returning `mode: "dry_run"` and a `would_create` / `would_update`
245
- status. Use it to verify a runtime template resolves before publishing for real.
271
+ `agents.create`、`publishVersion` 和 `apply*` 方法都接受 `{ dryRun: true }`。
272
+ dry run 会校验并解析请求,但不持久化;返回 `mode: "dry_run"` 和
273
+ `would_create` / `would_update` 状态;Version 已存在且内容一致时可能返回
274
+ `existing`。正式发布前可以用它确认 runtime template 能正确解析。
246
275
 
247
- ## Errors
276
+ ## 错误
248
277
 
249
- All API failures throw a typed error carrying `status`, `code`, and
250
- `requestId`:
278
+ 所有 API 请求失败都会抛出类型化错误,错误对象带 `status`、`code` 和 `requestId`:
251
279
 
252
280
  | Class | HTTP |
253
281
  | --- | --- |
@@ -255,7 +283,7 @@ All API failures throw a typed error carrying `status`, `code`, and
255
283
  | `PilotPlatformForbiddenError` | 403 |
256
284
  | `PilotPlatformNotFoundError` | 404 |
257
285
  | `PilotPlatformServerError` | 5xx |
258
- | `PilotPlatformApiError` | base class for the above |
286
+ | `PilotPlatformApiError` | 上述错误的基类 |
259
287
 
260
288
  ```ts
261
289
  import { PilotPlatformNotFoundError } from "@kanyun-ai-infra/agenthub";