@acosmi/sdk-ts 1.1.0 → 1.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/CHANGELOG.md CHANGED
@@ -5,6 +5,76 @@ All notable changes to `@acosmi/sdk-ts` will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.3.0] — 2026-05-20
9
+
10
+ ### Added
11
+
12
+ - **Compliance SDK client** — 新增 `client.compliance` 子客户端,覆盖电子证据、
13
+ 时间章、证据包、报告、签署 envelope、用印审批和 provider request 脱敏状态轮询。
14
+ - **`Config.complianceBaseURL` / `Client.complianceURL(path)`** — compliance API 使用
15
+ 独立 base URL,未配置时默认 `${serverURL}/admin-api`,不复用既有 `/api/v4`
16
+ 模型网关路径。
17
+ - **Compliance public types** — 新增 `src/compliance-types.ts`,只暴露 Acosmi 公共领域
18
+ DTO;不包含 provider product/user/transaction/project/seal-provider 字段,不包含证书、
19
+ 私钥、keystore、provider raw payload、storage key、subject snapshot 或 billing commit 内部字段。
20
+ - **Compliance error classification** — 新增 `src/compliance-errors.ts`,把 Java 数值业务错误码
21
+ 映射到 SDK symbolic key,并提供 `classifyComplianceError` / `isComplianceBusinessError`。
22
+ - **Compliance status helpers** — 新增稳定状态与错误码辅助函数,供前端区分 step-up、
23
+ gate closed、provider not configured、local verify failed、billing not committable 等状态。
24
+ - **Compliance scopes** — 新增 12 个细粒度 compliance scope 常量和 `complianceScopes()`。
25
+ - **Examples and docs** — 新增 `docs/compliance.md` 以及 3 个示例:
26
+ `examples/compliance-read.ts`、`examples/compliance-evidence-timestamp.ts`、
27
+ `examples/compliance-envelope.ts`。
28
+ - **Tests** — 新增 compliance client 与 compliance scopes 单元测试,覆盖 URL 拼接、
29
+ `Authorization`、`Idempotency-Key`、GET 401 refresh retry、write no-retry/no-401-replay、
30
+ CommonResult 解包、数值错误码分类、隐私边界和 polling 终态。
31
+
32
+ ### Changed
33
+
34
+ - `README.md` 增加 compliance 快速开始、scope 申请、base URL 配置、evidence +
35
+ timestamp/report 示例、provider request polling、step-up/gate closed 错误处理、
36
+ idempotency key 持久化和安全禁止项说明。
37
+ - Packed tarball smoke test 覆盖 `client.compliance`,确保 consumer 视角能解析新增
38
+ declaration merging 和导出的 compliance 类型。
39
+ - `package.json.files` 现在包含 `docs/compliance.md` 和 `examples/`,npm 包随附用户文档
40
+ 与可运行示例;开发手册仍保留在仓库中,不随包发布。
41
+
42
+ ### Safety
43
+
44
+ - Compliance write methods do not auto retry and do not refresh/replay on 401.
45
+ GET read methods still allow one safe 401 refresh retry.
46
+ - All compliance write methods accept `Idempotency-Key` through `ComplianceWriteOptions`;
47
+ callers should persist keys and reuse the same key when resuming the same business action.
48
+ - SDK code, docs, tests, examples, and package files do not include provider materials,
49
+ credentials, real provider endpoints, signing containers, archives, jars, passwords,
50
+ or raw provider payloads.
51
+
52
+ ---
53
+
54
+ ## [1.2.0] — 2026-05-18
55
+
56
+ ### Added
57
+
58
+ - **`ManagedModel.inputModalities`** — 新增可选字段, 类型 `Array<'text' | 'image'>`, 描述模型可接收的用户输入模态; 'image' 表示模型可直接接收 screenshot/image 输入. listModels / listModelsWithStatus 在写缓存与返回前会归一化上游 snake_case 字段名 `input_modalities` → camelCase `inputModalities` (兼容老网关), camelCase 与 snake_case 同时存在时 camelCase 胜.
59
+
60
+ - **`ModelCapabilities.supports_desktop_visual_understanding`** — 新增可选字段, 标识模型适合作为桌面截图解析 sidecar (输入 screenshot, 输出结构化 UI 描述, 供非多模态主模型消费). 与 `inputModalities=['image']` 是正交两件事: 前者描述"模型能不能吃图", 后者描述"运营是否把该模型标为桌面 UI 解析专用 sidecar". `zeroModelCapabilities()` 显式置 `false`, 避免 `undefined` 导致调用方误判.
61
+
62
+ - **`InputModality`** 类型导出 — `'text' | 'image'`.
63
+
64
+ - **Model catalog helpers (4 个)** — CrabCode desktop automation / computer-use 选模型用, 严格按 SDK 字段, 禁止模型名 substring 推断:
65
+ - `modelSupportsInputModality(model, modality): boolean`
66
+ - `modelSupportsImageInput(model): boolean`
67
+ - `findFirstModelByInputModality(models, modality): ManagedModel | null` — 按 catalog 顺序, 跳过 `isEnabled === false`
68
+ - `findDesktopVisualUnderstandingModel(models): ManagedModel | null` — 选择规则: isEnabled !== false + capabilities.supports_desktop_visual_understanding === true + inputModalities 含 'image' + isDefault 优先 / 否则 catalog 顺序第一个
69
+
70
+ ### Notes
71
+
72
+ - 上游 `ManagedModel` 缺失 `inputModalities` 时, SDK 保留 `undefined` 不自动补 `['text']` — 调用方必须保守按 text-only / unknown 处理, 严禁默认假设支持 image.
73
+ - 客户端不应硬编码模型名, 应完全依赖 SDK catalog 能力字段做模型选择.
74
+ - 23 新单测全绿 (8 listModels 归一化 + 15 helpers); 全量 79/79 passed, typecheck/lint/build clean.
75
+
76
+ ---
77
+
8
78
  ## [1.1.0] — 2026-05-06
9
79
 
10
80
  ### Added
@@ -128,6 +198,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
128
198
  - 36/36 vitest 全绿,源码 typecheck/lint/build 0 错误
129
199
  - 翻车机制:`prepublishOnly` 仅跑源码 typecheck/vitest/build,不验证 packed product 在 consumer 视角能否解析
130
200
 
201
+ [1.3.0]: https://github.com/acosmi/sdk-ts/releases/tag/v1.3.0
202
+ [1.2.0]: https://github.com/acosmi/sdk-ts/releases/tag/v1.2.0
131
203
  [1.1.0]: https://github.com/acosmi/sdk-ts/releases/tag/v1.1.0
132
204
  [1.0.2]: https://github.com/acosmi/sdk-ts/releases/tag/v1.0.2
133
205
  [1.0.1]: https://github.com/acosmi/sdk-ts/releases/tag/v1.0.1
package/README.md CHANGED
@@ -7,9 +7,9 @@
7
7
  ## 状态
8
8
 
9
9
  - 端口源:[acosmi-sdk-go](https://github.com/acosmi/acosmi-sdk-go) v1.0.0(与 Go SDK 联动稳定测试版)
10
- - 当前版本:**1.1.0**(新增 SDK-facing Agent Runs 公开 API;详见 [CHANGELOG](./CHANGELOG.md))
11
- - 测试:56/56 vitest 全绿,typecheck/lint/build 0 错误;packed-tarball smoke (`npm run test:pack`) 在 prepublishOnly 闸内
12
- - 包链接:[npm](https://www.npmjs.com/package/@acosmi/sdk-ts/v/1.1.0) · [tarball](https://registry.npmjs.org/@acosmi/sdk-ts/-/sdk-ts-1.1.0.tgz) · [GitHub Release](https://github.com/acosmi/sdk-ts/releases/tag/v1.1.0)
10
+ - 当前版本:**1.3.0**(新增 `client.compliance`、`complianceBaseURL`、合规域 types/errors/status/scopes、示例与文档;详见 [CHANGELOG](./CHANGELOG.md))
11
+ - 测试:发布前需通过 typecheck/lint/vitest/build/packed-tarball smoke (`npm run test:pack`)
12
+ - 包链接:[npm](https://www.npmjs.com/package/@acosmi/sdk-ts) · [GitHub Releases](https://github.com/acosmi/sdk-ts/releases)
13
13
 
14
14
  ## 安装
15
15
 
@@ -22,7 +22,7 @@ npm install @acosmi/sdk-ts
22
22
  ```ts
23
23
  import { Client, allScopes } from '@acosmi/sdk-ts';
24
24
 
25
- const client = new Client({ serverURL: 'https://acosmi.com' });
25
+ const client = new Client({ serverURL: process.env.ACOSMI_SERVER_URL! });
26
26
  await client.login('My App', allScopes());
27
27
 
28
28
  const resp = await client.chat('claude-opus-4-7', {
@@ -87,7 +87,7 @@ for await (const ev of stream) {
87
87
  ```ts
88
88
  import { Client, allScopes } from '@acosmi/sdk-ts';
89
89
 
90
- const client = new Client({ serverURL: 'https://acosmi.com' });
90
+ const client = new Client({ serverURL: process.env.ACOSMI_SERVER_URL! });
91
91
  await client.login('CrabDesign', allScopes());
92
92
 
93
93
  const run = await client.agentRuns.create({
@@ -155,7 +155,7 @@ const token = await client.ensureToken(); // 拿到当前有效 access toke
155
155
  ```ts
156
156
  import { discover, register, authorize, exchangeCode } from '@acosmi/sdk-ts';
157
157
 
158
- const meta = await discover('https://acosmi.com');
158
+ const meta = await discover(process.env.ACOSMI_SERVER_URL!);
159
159
  const reg = await register(meta, 'My CLI', allScopes());
160
160
  const result = await authorize(meta, reg, allScopes(), {
161
161
  onEvent: (ev) => console.log(ev.type, ev.url),
@@ -169,7 +169,7 @@ const tokens = await exchangeCode(meta, reg, result.code, result.codeVerifier);
169
169
  import { Client, FileTokenStore, LocalStorageTokenStore } from '@acosmi/sdk-ts';
170
170
 
171
171
  // Node — 默认 ~/.acosmi/tokens.json,可自定义路径
172
- const client = new Client({ serverURL: 'https://acosmi.com', tokenStore: new FileTokenStore('./my-tokens.json') });
172
+ const client = new Client({ serverURL: process.env.ACOSMI_SERVER_URL!, store: new FileTokenStore('./my-tokens.json') });
173
173
 
174
174
  // 浏览器 — 自动用 LocalStorage(无 LocalStorage 时退化为内存)
175
175
  ```
@@ -181,7 +181,7 @@ const client = new Client({ serverURL: 'https://acosmi.com', tokenStore: new Fil
181
181
  | **Chat** | `chat`, `chatStream`, `chatStreamWithUsage` |
182
182
  | **Agent Runs** | `agentRuns.create`, `agentRuns.stream`, `agentRuns.run`, `agentRuns.cancel`, `agentRuns.get`, `agentRuns.listArtifacts`, `agentRuns.downloadArtifact`, `agentRuns.submitLocalToolResult`, `agentRuns.runWithLocalTools` |
183
183
  | **Auth** | `login`, `logout`, `ensureToken`, `forceRefresh`, `discover`, `authorize`, `exchangeCode`, `refreshToken` |
184
- | **Models** | `listModels`, `listModelsWithStatus`, `getModelCapabilities`, `getQuotaSummary` |
184
+ | **Models** | `listModels`, `listModelsWithStatus`, `getModelCapabilities`, `getQuotaSummary`, `modelSupportsInputModality`, `modelSupportsImageInput`, `findFirstModelByInputModality`, `findDesktopVisualUnderstandingModel` |
185
185
  | **Skills** | `browseSkills`, `browseSkillsList`, `getSkillDetail`, `resolveSkill`, `installSkill`, `downloadSkill`, `uploadSkill`, `generateSkill`, `optimizeSkill`, `validateSkill` |
186
186
  | **Tools** | `listTools`, `getTool` |
187
187
  | **Wallet** | `getWalletStats`, `getWalletTransactions` |
@@ -190,6 +190,7 @@ const client = new Client({ serverURL: 'https://acosmi.com', tokenStore: new Fil
190
190
  | **Notifications** | `listNotifications`, `getUnreadCount`, `markNotificationRead`, `registerDevice`, `listNotificationPreferences` |
191
191
  | **Bug Report** | `submitBugReport`, `getBugReport` |
192
192
  | **Web Search** | `newWebSearchTool` (factory) |
193
+ | **Compliance** | `compliance.createEvidenceAsset`, `compliance.issueTimestamp`, `compliance.waitForTimestampVerified`, `compliance.buildEvidencePackage`, `compliance.createReport`, `compliance.downloadReport`, `compliance.createSigningEnvelope`, `compliance.signEnvelope`, `compliance.getProviderRequest`, `compliance.waitForProviderRequestTerminal` |
193
194
 
194
195
  完整签名见 `dist/node/index.d.ts`,IDE 自带补全。
195
196
 
@@ -198,7 +199,7 @@ const client = new Client({ serverURL: 'https://acosmi.com', tokenStore: new Fil
198
199
  ```ts
199
200
  import { Client } from '@acosmi/sdk-ts';
200
201
 
201
- const client = new Client({ serverURL: 'https://acosmi.com' });
202
+ const client = new Client({ serverURL: process.env.ACOSMI_SERVER_URL! });
202
203
 
203
204
  // 公共端点 — 无需登录
204
205
  const result = await client.browseSkills(
@@ -230,6 +231,38 @@ const resp = await client.chat('claude-opus-4-7', {
230
231
 
231
232
  `AllowedDomains` / `BlockedDomains` 互斥,同时传入抛 `Error`。
232
233
 
234
+ ### 示例:桌面视觉理解 sidecar 选模型(CrabCode desktop automation / computer-use)
235
+
236
+ ```ts
237
+ import {
238
+ Client,
239
+ findDesktopVisualUnderstandingModel,
240
+ modelSupportsImageInput,
241
+ } from '@acosmi/sdk-ts';
242
+
243
+ const client = new Client({ serverURL: process.env.ACOSMI_SERVER_URL! });
244
+ const models = await client.listModels();
245
+
246
+ // 1) 主模型是否能直接吃截图?
247
+ const primaryCanSeeImages = modelSupportsImageInput(
248
+ models.find((m) => m.modelId === 'deepseek-v4') ?? null,
249
+ );
250
+
251
+ // 2) 不能 → 走桌面视觉 sidecar:截图先送 sidecar 解析为结构化 UI 描述,再喂主模型
252
+ const sidecar = findDesktopVisualUnderstandingModel(models);
253
+ if (!sidecar) {
254
+ throw new Error('No desktop visual understanding model available — 让管理员在网关启用一个 sidecar 模型');
255
+ }
256
+ console.log('sidecar →', sidecar.modelId);
257
+ ```
258
+
259
+ 红线:
260
+
261
+ - `ManagedModel.inputModalities` 用于客户端判断模型可接收的用户输入类型('text' | 'image')。
262
+ - `capabilities.supports_desktop_visual_understanding` 用于选择专门解析桌面截图的视觉 sidecar 模型,与 `inputModalities` 是正交两件事(普通视觉模型不一定擅长 UI 解析)。
263
+ - 客户端不应硬编码模型名做能力推断,应完全依赖 SDK catalog 字段。
264
+ - 上游未下发 `inputModalities` 时 SDK 保持 `undefined`,调用方必须保守按 text-only / unknown 处理。
265
+
233
266
  ### 示例:钱包 + 余额 + 流量包购买
234
267
 
235
268
  ```ts
@@ -265,15 +298,16 @@ const view = await client.getBugReport(result.feedback_id);
265
298
 
266
299
  所有方法 `throw` 类型化错误(不是 Go 风格多返回值):
267
300
 
268
- | 错误类型 | 触发 |
269
- | -------------------- | -------------------------------------------- |
270
- | `HTTPError` | 4xx/5xx,含 `status` / `body` / `requestID` |
271
- | `NetworkError` | TCP/DNS/TLS 失败 |
272
- | `StreamError` | SSE 流解析失败 |
301
+ | 错误类型 | 触发 |
302
+ | -------------------- | ---------------------------------------------------------------------- |
303
+ | `HTTPError` | 4xx/5xx,含 `statusCode` / `body` / `type` / `retryAfter` |
304
+ | `NetworkError` | TCP/DNS/TLS 失败 |
305
+ | `StreamError` | SSE 流解析失败 |
273
306
  | `AgentRunStreamError` | Agent Runs 流返回 `error` 事件(默认抛出;可设 `throwOnError:false` 自行消费) |
274
- | `BusinessError` | 网关返回 `code !== 0`,含 `code` / `bizMsg` |
275
- | `RateLimitError` | 429(含 `retryAfter`) |
276
- | `OrderTerminalError` | `waitForPayment` 终态失败 |
307
+ | `BusinessError` | 网关返回 `code !== 0`,含 `code` (number) / `message` (字符串) |
308
+ | `RateLimitError` | 429(含 `retryAfter`) |
309
+ | `OrderTerminalError` | `waitForPayment` 终态失败 |
310
+ | `CompliancePollError` | `waitForTimestampVerified` / `waitForProviderRequestTerminal` 终态失败或超时 |
277
311
 
278
312
  ```ts
279
313
  import { HTTPError, BusinessError } from '@acosmi/sdk-ts';
@@ -281,12 +315,146 @@ import { HTTPError, BusinessError } from '@acosmi/sdk-ts';
281
315
  try {
282
316
  await client.chat(...);
283
317
  } catch (e) {
284
- if (e instanceof HTTPError && e.status === 401) await client.login(...);
285
- if (e instanceof BusinessError) console.error(e.code, e.bizMsg);
318
+ if (e instanceof HTTPError && e.statusCode === 401) await client.login(...);
319
+ if (e instanceof BusinessError) console.error(e.code, e.message);
286
320
  throw e;
287
321
  }
288
322
  ```
289
323
 
324
+ ### Compliance 错误分类
325
+
326
+ 合规域使用 Java 数值错误码(1-031-xxx-xxx),SDK 通过 `classifyComplianceError` 把
327
+ `BusinessError` 映射到 symbolic key,便于分支判断:
328
+
329
+ ```ts
330
+ import { BusinessError, classifyComplianceError, isComplianceBusinessError } from '@acosmi/sdk-ts';
331
+
332
+ try {
333
+ await client.compliance.publishReport(reportId, { idempotencyKey });
334
+ } catch (e) {
335
+ if (e instanceof BusinessError && isComplianceBusinessError(e)) {
336
+ const info = classifyComplianceError(e);
337
+ if (info.stepUpRequired) {
338
+ // 引导用户重新做 OAuth introspection / 重新登录后用同一 idempotency-key 再试
339
+ } else if (info.terminal) {
340
+ // 终态错误(gate closed / provider not configured 等),不要 retry,用新 key 重发
341
+ }
342
+ }
343
+ throw e;
344
+ }
345
+ ```
346
+
347
+ ## Compliance (时间章 / 电子证据 / 合同签署)
348
+
349
+ 合规域走独立子客户端 `client.compliance.*`,使用独立 base URL。**SDK 永远不接触
350
+ provider endpoint、证书/密钥材料、provider raw payload / callback billing commit**;
351
+ 所有 provider 选择由服务端按配置决定,调用方不传 `provider` 字段。
352
+
353
+ 完整 API 指南见 [docs/compliance.md](./docs/compliance.md)。
354
+
355
+ ```ts
356
+ import { Client, complianceScopes } from '@acosmi/sdk-ts';
357
+
358
+ // 1. 配置 — complianceBaseURL 默认 ${serverURL}/admin-api
359
+ const client = await Client.create({
360
+ serverURL: process.env.ACOSMI_SERVER_URL!,
361
+ // complianceBaseURL: process.env.ACOSMI_COMPLIANCE_BASE_URL, // 独立 ingress 时显式覆盖
362
+ });
363
+
364
+ // 2. 登录 — OAuth scope 申请按业务最小集合
365
+ await client.login('My App', complianceScopes());
366
+
367
+ // 3. 申请时间章(写操作;strongly recommended 持久化 idempotency-key)
368
+ const idempotencyKey = `ts-${orderId}-${Date.now()}`;
369
+ await persistKey(idempotencyKey);
370
+ const token = await client.compliance.issueTimestamp(
371
+ { name: 'release-artifact', hashAlgorithm: 'sha256', digest: sha256Hex },
372
+ { idempotencyKey },
373
+ );
374
+
375
+ // 4. 轮询到本地 verify 通过
376
+ const verified = await client.compliance.waitForTimestampVerified(token.id, {
377
+ timeoutMs: 60_000,
378
+ });
379
+
380
+ // 5. 公开 verify — 不要求登录、不暴露 PII / 合同原文
381
+ const result = await client.compliance.verifyEvidencePublic({ evidenceNo: 'EV-001' });
382
+ console.log(result.manifestOfflineVerify);
383
+ ```
384
+
385
+ ### 写操作幂等与 401 策略
386
+
387
+ 合规域写操作有别于普通 API:
388
+
389
+ - **Idempotency-Key**:所有 POST 写操作支持 `Idempotency-Key` header;调用方必须**持久化**
390
+ key(重启后仍可用)。同一 key 重发等价于"对账查询同一业务结果",避免 provider 侧重复
391
+ 请求 / 重复扣费。
392
+ - **401 不自动重放**:写操作 401 直接抛 `HTTPError`,**不会自动 refresh + replay**。
393
+ 调用方需要重新登录后用**同一 idempotency-key** 调用同一方法。GET 读操作仍走单次 401
394
+ refresh 重试。
395
+ - **5xx / timeout 不自动重试**:合规域写操作完全禁用自动重试。
396
+ - **step-up 错误(`COMPLIANCE_STEP_UP_REQUIRED`,code=1031000013)**:通过
397
+ `classifyComplianceError` 识别后引导用户重新做 OAuth introspection / 升级 token 等级。
398
+ - **gate closed / provider not configured / unknown**:terminal 错误,禁止自动重发原请求。
399
+
400
+ ### 隐私边界
401
+
402
+ `verifyEvidencePublic` 返回字段:`evidenceNo` / `assetType` / `hashAlgorithm` / `contentHash` /
403
+ `size` / `manifestHash` / `packageHash` / `manifestOfflineVerify` / `verifiedAt`。**不暴露**
404
+ PII / 合同原文 / storage bucket+key / subject snapshot / provider raw / TSA 证书内部字段。
405
+
406
+ ### 完整 API 列表
407
+
408
+ ```ts
409
+ client.compliance.createEvidenceAsset(req, options?)
410
+ client.compliance.getEvidenceAsset(id, signal?)
411
+ client.compliance.verifyEvidencePublic(req, signal?)
412
+
413
+ client.compliance.issueTimestamp(req, options?)
414
+ client.compliance.issueTimestampForAsset(assetId, options?)
415
+ client.compliance.getTimestamp(id, signal?)
416
+ client.compliance.verifyTimestamp(req, options?)
417
+ client.compliance.waitForTimestampVerified(id, opts?)
418
+
419
+ client.compliance.buildEvidencePackage(assetId, timestampTokenId?, options?)
420
+
421
+ client.compliance.createReport(req, options?)
422
+ client.compliance.getReport(id, signal?)
423
+ client.compliance.publishReport(id, options?) // step-up
424
+ client.compliance.downloadReport(id, signal?) // 离线复核 hash 视图
425
+
426
+ client.compliance.createSigningEnvelope(req, options?)
427
+ client.compliance.getSigningEnvelope(envelopeId, signal?)
428
+ client.compliance.signEnvelope(envelopeId, req, options?) // step-up + gate
429
+ client.compliance.createH5SigningUrl(envelopeId, req, options?) // step-up + gate
430
+ client.compliance.syncSigningEnvelopeStatus(envelopeId, options?)
431
+
432
+ client.compliance.submitSealApproval(req, options?)
433
+ client.compliance.approveSealApproval(id, query, options?) // step-up
434
+ client.compliance.rejectSealApproval(id, query, options?)
435
+ client.compliance.cancelSealApproval(id, query, options?)
436
+ client.compliance.listPendingSealApprovals(signal?)
437
+ client.compliance.getSealApproval(id, signal?)
438
+
439
+ client.compliance.getProviderRequest(id, signal?)
440
+ client.compliance.waitForProviderRequestTerminal(id, opts?)
441
+ ```
442
+
443
+ ### 示例
444
+
445
+ `examples/` 下提供 3 份可直接运行的端到端示例,并随 npm 包一起发布:
446
+
447
+ - `examples/compliance-read.ts` — 只读 / public verify 流程
448
+ - `examples/compliance-evidence-timestamp.ts` — hash-only evidence + timestamp + package 链路
449
+ - `examples/compliance-envelope.ts` — envelope 创建 / 错误正确处理(step-up / gate closed)
450
+
451
+ ### 后端边界
452
+
453
+ - Java compliance 后端负责 provider 集成、受控材料、provider raw payload、local verify、
454
+ billing 状态机和对外 public DTO 收敛。
455
+ - Go OAuth/JWKS 层负责 token 签发、scope 与 step-up/introspection 语义。
456
+ - TS SDK 只申请 scope、发送公共 DTO、传递 `Idempotency-Key`、分类公开错误码并轮询脱敏状态视图。
457
+
290
458
  ## AbortSignal
291
459
 
292
460
  每个异步方法都接 `signal?: AbortSignal`,用于取消请求或流:
@@ -314,7 +482,9 @@ npm run build
314
482
 
315
483
  | 版本 | 状态 | 概要 |
316
484
  | --- | --- | --- |
317
- | 1.1.0 | 当前稳定版 | 新增 SDK-facing `agentRuns` 网关客户端,覆盖 create/stream/cancel/get/artifacts/local-tool-result,并提供本地只读工具桥协议。 |
485
+ | 1.3.0 | 当前稳定版 | 新增 compliance SDK client、base URL、types/errors/status/scopes、docs/examples/tests,并明确 idempotency/no-retry/no-401-replay 与 provider material 安全边界。 |
486
+ | 1.2.0 | 稳定版 | 新增 `ManagedModel.inputModalities`、桌面视觉理解 sidecar capability 与 4 个 catalog helpers。 |
487
+ | 1.1.0 | 稳定版 | 新增 SDK-facing `agentRuns` 网关客户端,覆盖 create/stream/cancel/get/artifacts/local-tool-result,并提供本地只读工具桥协议。 |
318
488
  | 1.0.2 | 稳定版 | 修复多进程共享 token refresh rotation 竞态。 |
319
489
  | 1.0.1 | 历史稳定版 | 修复 1.0.0 双层 broken packaging:tsup 输出 `.mjs+.cjs` 与 exports 字段对齐;9 处 `declare module` 绑包名 `@acosmi/sdk-ts` 让 d.ts augmentation 在 consumer 视角合并;prepublishOnly 加 packed-tarball 烟测拦截"源码过 / 打包后 broken"。 |
320
490
  | 1.0.0 | **deprecated** | 双层 broken:(1) `package.json.exports` 8 处 `.mjs` 引用与 tsup 默认 `.js+.cjs` 错位 → bun/Node ESM `Cannot find module`;(2) 9 处 `declare module` 用相对路径,consumer 视角断链 → 50+ 方法 TS2339。`npm install @acosmi/sdk-ts` 自动跳到 1.0.1。 |