@acosmi/sdk-ts 2.5.1 → 2.7.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 +59 -0
- package/README.md +101 -20
- package/dist/browser/index.mjs +351 -10
- package/dist/browser/index.mjs.map +1 -1
- package/dist/index.mjs +351 -10
- package/dist/index.mjs.map +1 -1
- package/dist/node/adapters/anthropic.cjs.map +1 -1
- package/dist/node/adapters/anthropic.d.cts +1 -1
- package/dist/node/adapters/anthropic.d.ts +1 -1
- package/dist/node/adapters/anthropic.mjs.map +1 -1
- package/dist/node/adapters/openai.cjs.map +1 -1
- package/dist/node/adapters/openai.d.cts +2 -2
- package/dist/node/adapters/openai.d.ts +2 -2
- package/dist/node/adapters/openai.mjs.map +1 -1
- package/dist/node/{index-BdzF9tmA.d.cts → index-BrbgHn0E.d.cts} +12 -0
- package/dist/node/{index-BdzF9tmA.d.ts → index-BrbgHn0E.d.ts} +12 -0
- package/dist/node/index.cjs +359 -9
- package/dist/node/index.cjs.map +1 -1
- package/dist/node/index.d.cts +387 -56
- package/dist/node/index.d.ts +387 -56
- package/dist/node/index.mjs +351 -10
- package/dist/node/index.mjs.map +1 -1
- package/dist/node/{openai-B5xWiGMs.d.cts → openai-CeM2k04b.d.cts} +1 -1
- package/dist/node/{openai-C3DcaljC.d.ts → openai-DoPpzZmv.d.ts} +1 -1
- package/docs//345/274/200/345/217/221/344/270/216/345/217/221/345/270/203/346/211/213/345/206/214.md +13 -4
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,65 @@ 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
|
+
## [2.7.0] - 2026-06-11 — 远控管理面补齐 + BYOK 密钥客户端 + Chat Bridge CRUD(Phase 7B)
|
|
9
|
+
|
|
10
|
+
补齐远控核心交互之外的全部管理面(此前下游 CrabCode 只能裸 fetch),新增 BYO 模型密钥客户端,落地 chat-bridge integration/credential 管理面 CRUD——云端控制台与下游调用的是同一组端点同一份租户隔离数据,天然互通。全部方法逐字段对齐 nexus-v4 handler 真实 wire 形状(契约 §12/§14/§18 附录 A)。
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **`agentRuns.list(opts?)`** — 调用者自己的 run 列表(`GET /agent-runs`,Phase 5C 控制台):`runtime`/`status` 过滤 + `page`/`pageSize` 分页,信封 `{records,total,page,pageSize}`;run view 新增 `runtime`/`runner`/`adapter` 字段(标准 run 缺省),永不含 session token/policy/messages。
|
|
15
|
+
- **`agentRuns.submitPermissionResult(runId, {requestId, decision, reason?})`** — 远控审批决策回写(`POST /:runId/permission-results`);decision 仅 `approved`|`rejected`(契约 §14),409 = 会话不可用。
|
|
16
|
+
- **`agentRuns.submitUserMessage(runId, {content, requestId?})`** — 会话中途追加用户消息(`POST /:runId/messages`,≤64KB,role 服务端硬编码 user);返回服务端最终幂等键。
|
|
17
|
+
- **`agentRuns.revealRemoteToken(runId)`** — desktop launcher 一次性 session token(`POST /:runId/remote-token`,Phase 5B;仅 runner=desktop);响应含 `workspace`(契约 §18.3 r4)。token 永不落浏览器存储。
|
|
18
|
+
- **`AgentRunCreateRequest.byokCredentialRef`** — BYO 密钥引用上 wire(`byok_credential_ref`,仅远控 + cloud runner)。
|
|
19
|
+
- **`client.crabcodeByok`(`CrabCodeByokClient`)** — BYO 模型密钥管理面(契约 §18.2,`/crabcode/byok-credentials`,`remote_control` scope):`list`/`create`/`rotate`/`revoke`;明文一次性提交,响应恒 masked(ref+fingerprint)。新类型 `ByokProvider`/`ByokCredential`/`ByokCreateRequest`。
|
|
20
|
+
- **`client.chatBridge`(`ChatBridgeClient`,Phase 7B)** — 第三方聊天平台集成/凭证管理面 CRUD:`createIntegration`/`listIntegrations`/`getIntegration`/`updateIntegrationStatus` + `storeCredential`/`listCredentials`/`rotateCredential`/`revokeCredential`。请求体 snake_case(SDK 转换)、响应 camelCase(契约 §12 平面分化);scope 三档 `chat_bridge:read`/`:write`/`:rotate`。新类型 `CreateIntegrationRequest`/`StoreCredentialRequest`。
|
|
21
|
+
- **metadata 约定键常量** — `AGENT_RUN_META_TITLE`/`AGENT_RUN_META_WORKSPACE`(契约 §18.3 r4:title 列表标题 / workspace 期望项目目录)。
|
|
22
|
+
- **远控管理面类型** — `RemotePermissionDecision`/`RemotePermissionResultRequest`/`RemoteUserMessageRequest`/`RemoteUserMessageAck`/`RemoteSessionTokenGrant`/`AgentRunListOptions`/`AgentRunListResult`。
|
|
23
|
+
|
|
24
|
+
### Deprecated
|
|
25
|
+
|
|
26
|
+
- **`ChatIntegration.configJson`** — 服务端从不返回该字段(model `json:"-"`,防 secret 误入后整体不外发),读取恒 `undefined`;写入走 `createIntegration({ configJson })`。
|
|
27
|
+
|
|
28
|
+
## [2.6.0] - 2026-06-04 — 会员订阅查询 + 后端契约类型修正 + WS 一次性 ticket 鉴权
|
|
29
|
+
|
|
30
|
+
新增会员订阅查询能力 + chat_bridge scope,并修正一批此前与后端不符(运行时即为 `undefined`)的计费/订单/钱包/余额/通知类型形状。**破坏性 = 类型修正**:被修正的类型字段名 / 类型发生变化,但它们此前本就拿不到正确运行时值,对真正生效的调用代码无功能回退。
|
|
31
|
+
|
|
32
|
+
### Fixed
|
|
33
|
+
|
|
34
|
+
- **`BalanceDetail` 形状对齐网关 `InternalBalanceResponse`** — 改为 `userId` / `tokenRemaining` / `tokenTotal` / `callRemaining` / `callTotal` / `entitlements[]`,与网关真实下发结构逐字段对齐(此前字段名与后端不符,`getBalanceDetail` 读出 `undefined`)。
|
|
35
|
+
- **`getOrderStatus` / `waitForPayment` 改用 `BuyResponse.paymentStatus`(修死循环)** — 旧实现读不存在的状态字段,`waitForPayment` 永远拿不到终态导致轮询死循环;改读 `BuyResponse.paymentStatus`。
|
|
36
|
+
- **`PayPayload.payMethod` → `paymentMethod`** — 字段名对齐后端,并补齐枚举值 `WECHAT_NATIVE` / `ALIPAY_PRECREATE` / `BANK_TRANSFER` 与 `deviceId` / `clientRequestId` 字段。
|
|
37
|
+
- **`TokenPackage` 对齐 `toProductView`** — 字段形状与网关 `toProductView` 输出一致。
|
|
38
|
+
- **`Order` 拆为 `BuyResponse` / `OrderListItem`** — 下单返回与订单列表项是两套不同形状,不再用单一 `Order` 混淆。
|
|
39
|
+
- **`WalletStats` / `Transaction` `amount` 由 `string` 改 `number`** — 与后端实际下发类型对齐(此前 string 假设导致消费方误用)。
|
|
40
|
+
- **consume-records 分页修正** — 网关已修为 `records` / `total` / `page` / `pageSize`,SDK 类型与解析同步对齐。
|
|
41
|
+
- **`EntitlementItem.createdAt` 改为可选 + 新增 `activatedAt`** — 与后端 optional 语义对齐。
|
|
42
|
+
- **`ConsumeRecord` 补缓存字段** — 补齐网关下发的缓存相关字段。
|
|
43
|
+
- **notifications WebSocket 改用一次性 `stream-ticket` 取代 URL `?token=` JWT** — 杜绝长效 JWT 经 query string 进入 nginx access log / 代理日志 / 浏览器历史的泄露面,同时修复 WS 鉴权链路。
|
|
44
|
+
|
|
45
|
+
### Added
|
|
46
|
+
|
|
47
|
+
- **`subscription.getMembership()` / `getSubscriptionTier()` / `subscriptionPrecheck()`** — C 端会员订阅查询:当前会员视图 / 订阅档位 / 升级前置校验。
|
|
48
|
+
- **auth `ScopeChatBridge`(+ `:read` / `:write` / `:rotate` 三子项)+ `chatBridgeScopes()`** — chat_bridge 第三方聊天平台桥接 scope(Phase 7B 后端落地配套)。
|
|
49
|
+
- **`ManagedModel` 档位门控字段** — `locked` / `freeTier` / `minPlanTier` / `chatRuntimeSupported` / `defaultToolIds`,供 C 端聊天模型选择器按会员档位加锁 / 分区。
|
|
50
|
+
|
|
51
|
+
### Deprecated
|
|
52
|
+
|
|
53
|
+
- **`subscription.listUserSubscriptions`** — 改用 `getMembership()`。
|
|
54
|
+
- **`ModelCoefficient` / `listCoefficients`** — 系数退役,端点恒返回空。
|
|
55
|
+
- **`ManagedModel.pricePerMTok` / `isDefault`** — 公开端点不返回这两个字段。
|
|
56
|
+
- **notifications `registerDevice` / `unregisterDevice` / `list` + `updateNotificationPreference`** — 标 `@experimental`(网关当前无对应端点)。
|
|
57
|
+
|
|
58
|
+
### Breaking(类型修正)
|
|
59
|
+
|
|
60
|
+
- 上述被修正的类型形状(`BalanceDetail` / `Order` → `BuyResponse`·`OrderListItem` / `OrderStatus` / `TokenPackage` / `PayPayload` / `WalletStats` / `Transaction`)此前与后端不符——运行时即为 `undefined` 或错配。修正后字段名 / 类型发生变化(故标 minor 内的破坏性类型修正);按新形状重新读取即可,对此前依赖错误字段的代码本就无有效运行时数据。
|
|
61
|
+
|
|
62
|
+
### Docs(文档准确性修正)
|
|
63
|
+
|
|
64
|
+
- **额度单位双体系文档化** — 计费/订阅域所有 `token*` 字段(`tokenQuota`/`tokenRemaining`/`tokenUsed`/`tokenTotal`)单位取决于权益是否付费:**免费档 = 原始 Token(TK 体系)**,**付费会员(`type ∈ {TOKEN_PACKAGE, SUBSCRIPTION}`)= 微 Credits(÷1000 = Credits 代币)**。在 `EntitlementBalance` / `EntitlementItem` / `BalanceDetail` / `Membership` / `SubscriptionPlan` 类型注释与 README「钱包 + 余额」一节补充该语义,明确**两者单位不同、绝不可跨单位求和**,判据为权益 `type`。档位标准额度 BASIC 0.6 亿 / PRO 3 亿 / PRO_MAX 9 亿 / ULTRA 24 亿 Credits。
|
|
65
|
+
- **README 钱包示例修正** — `getWalletStats` 输出由 string 改为 number(对齐本版 `WalletStats` float64)并补 `transactionCount`;`buyTokenPackage` 示例由错误的 `{ payMethod: 'wechat' }` 改为 `{ paymentMethod: 'WECHAT_NATIVE' }`;`waitForPayment` 由不存在的 `order.id` 改为 `String(order.orderId)`(`BuyResponse` 用 `orderId`/`orderNo`,无 `id`)。
|
|
66
|
+
|
|
8
67
|
## [2.5.1] - 2026-05-31 — 模型 adapter 格式一致性护栏(行为加固 patch,向后兼容)
|
|
9
68
|
|
|
10
69
|
`getAdapterForModel` 路由加固:`preferred_format` 现仅在**确被 `supported_formats` 收录**时才采信(或 `supported_formats` 未声明时维持原样)。防止上游元数据漂移(如 `preferred_format=anthropic` 但 `supported_formats=[openai]`)把 SDK 路由到模型并不支持的格式端点,撞 `/anthropic`「未绑定 Anthropic」4xx。这是网关侧「同 model_id 双 profile 选行」根因修复在 SDK 侧的同构护栏。
|
package/README.md
CHANGED
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
## 状态
|
|
8
8
|
|
|
9
9
|
- **主实现 / 事实标准**:本 TS SDK 现为 Acosmi SDK 的主力实现。Go SDK [acosmi-sdk-go](https://github.com/acosmi/acosmi-sdk-go) 已暂停维护,待 TS 稳定后再从 TS 反向翻译补齐。
|
|
10
|
-
-
|
|
10
|
+
- **当前版本:`2.6.0`**(订阅会员查询 + 一批后端契约类型修正 + WS 一次性 ticket 鉴权,2026-06-04)。
|
|
11
|
+
- **`v2.6.0`(会员订阅查询 + 类型修正,2026-06-04)**:新增 `subscription.getMembership()` / `getSubscriptionTier()` / `subscriptionPrecheck()`;`ManagedModel` 补档位门控字段(`locked`/`freeTier`/`minPlanTier`/`chatRuntimeSupported`/`defaultToolIds`);auth 新增 `ScopeChatBridge`(+read/write/rotate) 与 `chatBridgeScopes()`。**破坏性类型修正**:`BalanceDetail` 形状对齐网关 `InternalBalanceResponse`、`Order` 拆为 `BuyResponse`/`OrderListItem`、`getOrderStatus`/`waitForPayment` 改用 `BuyResponse.paymentStatus`(修死循环)、`PayPayload.payMethod`→`paymentMethod`、`TokenPackage` 对齐 `toProductView`、`WalletStats`/`Transaction` `amount` 由 string 改 number、consume-records 分页修正、notifications WebSocket 用一次性 `stream-ticket` 取代 URL `?token=` JWT。废弃 `listUserSubscriptions`(改用 `getMembership`)、`ModelCoefficient`/`listCoefficients`(系数退役恒空)、`ManagedModel.pricePerMTok`/`isDefault`(公开端点不返回);notifications 设备/偏好方法标 `@experimental`。详见 CHANGELOG。
|
|
11
12
|
- **`v2.5.1`(格式一致性护栏,2026-05-31)**:`getAdapterForModel` 路由加固 —— `preferred_format` 现仅在**确被 `supported_formats` 收录**时才采信(或 `supported_formats` 未声明时维持原样)。防止上游元数据漂移(如 `preferred_format=anthropic` 但 `supported_formats=[openai]`)把 SDK 路由到模型并不支持的格式端点,撞 `/anthropic`「未绑定 Anthropic」4xx。`supported_formats` 为空/未知(旧上游)时**行为逐字节不变**。新增 3 条 routing 用例钉死矛盾场景。
|
|
12
13
|
- **`v2.5.0`(健康度审计根因修复,2026-05-31)**:源码深度审计后修复一批真实运行时缺陷 —— `agentRuns.downloadArtifact()` 超限不再静默截断而是抛错;本地工具回调 `Promise.race` 硬超时(忽略 `signal` 的 handler 也不再永挂);OpenAI 流式 `reasoning_content` 后直接 `tool_calls`(无 text)时 block index 不再错乱;非法 `expires_at` 视为过期 + TokenStore 形状校验;OAuth 发现/注册/换/吊销链路统一走注入 `fetchImpl`;空成功响应(204)不再抛 JSON parse error;`apiBaseURL`/`complianceBaseURL` 与 gateway base 同级校验(拒 ws/wss/query/hash);非流式请求默认超时;WebSocket 重复 connect 先关旧连接;`FileTokenStore.save()` 真 fsync;chat 请求对象不再被原地 mutate;Anthropic `extraBody` 不能覆盖 SDK 管理字段。**公开类型/方法签名零移除、零改名**(新增导出 `normalizeOverrideBaseURL` / `DEFAULT_API_TIMEOUT_MS`)。casehall/finance/enterprise 业务域路径经生产实证确认正确(同源代理直连 tk-dist),**未改**,并新增 URL 组装回归测试钉死契约。
|
|
13
14
|
- **`v2.1.0`(已发布)**:远程控制 CrabCode 多接入面 —— `serverURL`/`baseURL` Gateway URL 公共契约(见下方小节)、`agentRuns.createRemoteRun` / `agentRuns.streamRemoteControl` + 11 事件 union(见 §Agent Runs → 远程控制)、`chatbridge` 第三方聊天平台桥接类型(types-only 骨架,见 §Chat Bridge)、专用 `remote_control` scope(不进 `allScopes()`)。契约见 `docs/audit/sdk-remote-control-contract-2026-05-27.md`。
|
|
@@ -331,14 +332,50 @@ const run = await client.agentRuns.createRemoteRun({
|
|
|
331
332
|
for await (const ev of client.agentRuns.streamRemoteControl(run.runId)) {
|
|
332
333
|
switch (ev.type) {
|
|
333
334
|
case 'text_delta': process.stdout.write(ev.text); break;
|
|
334
|
-
case 'permission_request':
|
|
335
|
+
case 'permission_request': // 渲染审批卡片后回写决策 (仅 approved|rejected, 契约 §14)
|
|
336
|
+
await client.agentRuns.submitPermissionResult(run.runId, {
|
|
337
|
+
requestId: ev.requestId, decision: 'approved',
|
|
338
|
+
});
|
|
339
|
+
break;
|
|
335
340
|
case 'settle': console.log('billed', ev.billed); break;
|
|
336
341
|
}
|
|
337
342
|
}
|
|
338
343
|
|
|
344
|
+
// 会话中途追加用户消息 (role 服务端硬编码 user, ≤64KB)
|
|
345
|
+
await client.agentRuns.submitUserMessage(run.runId, { content: '继续, 用方案B' });
|
|
346
|
+
|
|
339
347
|
await client.agentRuns.cancel(run.runId); // UI 中止走服务端 cancel control frame,不是 fetch abort
|
|
340
348
|
```
|
|
341
349
|
|
|
350
|
+
#### 远控管理面(v2.7.0)
|
|
351
|
+
|
|
352
|
+
| 方法 | 端点 | 说明 |
|
|
353
|
+
| --- | --- | --- |
|
|
354
|
+
| `agentRuns.list(opts?)` | `GET /agent-runs` | 调用者自己的 run 列表(新→旧);`{ runtime: 'crabcode_remote' }` 过滤远控 run,分页 `{records,total,page,pageSize}`。view 只含元数据,永不含 session token / policy / messages(契约 §6) |
|
|
355
|
+
| `agentRuns.submitPermissionResult(runId, {requestId, decision, reason?})` | `POST /:runId/permission-results` | 回写 `permission_request` 决策;仅 `approved` \| `rejected`(`timeout`/`cancelled` 由服务端产生)。409 = 远控会话已不可用 |
|
|
356
|
+
| `agentRuns.submitUserMessage(runId, {content, requestId?})` | `POST /:runId/messages` | 会话中途追加用户消息;role 服务端硬编码 `user`(契约 §6 #5 防注入),返回服务端最终幂等键 |
|
|
357
|
+
| `agentRuns.revealRemoteToken(runId)` | `POST /:runId/remote-token` | **仅 desktop runner / desktop launcher 用**:一次性 session token(重复调用 409)。token 永不落浏览器存储,native 层接收后只注入 CrabCode 子进程 env;响应含 `workspace`(用户声明的项目目录,契约 §18.3 r4) |
|
|
358
|
+
|
|
359
|
+
**metadata 约定键(契约 §18.3 r4)**:`metadata.title`(列表显示标题,缺省服务端从 input 首行派生)、`metadata.workspace`(期望项目目录,经 `revealRemoteToken().workspace` 下发给桌面端采纳)。常量 `AGENT_RUN_META_TITLE` / `AGENT_RUN_META_WORKSPACE`。服务端上限 ≤32 条 / 键 ≤64B / 值 ≤2KB。
|
|
360
|
+
|
|
361
|
+
#### BYOK — 用户自有模型密钥(v2.7.0,契约 §18.2)
|
|
362
|
+
|
|
363
|
+
`client.crabcodeByok` 管理 BYO 模型密钥(守卫 `remote_control` scope);创建后把 `credentialRef` 传给 `createRemoteRun({ byokCredentialRef })`(仅 `runner: 'cloud'`)。明文一次性提交、服务端加密落库后即弃,所有读取只回 masked 视图(ref + fingerprint)——解密只发生在网关 cloud runner 启动时的子进程 env 注入点。
|
|
364
|
+
|
|
365
|
+
```ts
|
|
366
|
+
const cred = await client.crabcodeByok.create({
|
|
367
|
+
provider: 'deepseek', // anthropic|openai|deepseek|dashscope|zhipu|volcengine|custom
|
|
368
|
+
plaintext: process.env.MY_KEY!, // 一次性提交; SDK/服务端永不回传
|
|
369
|
+
name: '我的 DeepSeek 钥匙',
|
|
370
|
+
});
|
|
371
|
+
await client.agentRuns.createRemoteRun({
|
|
372
|
+
appId: '', input: '…', runtime: 'crabcode_remote', runner: 'cloud', adapter: 'remote_io',
|
|
373
|
+
byokCredentialRef: cred.credentialRef,
|
|
374
|
+
});
|
|
375
|
+
await client.crabcodeByok.rotate(cred.credentialRef, 'sk-new'); // ref 不变, fingerprint 更新
|
|
376
|
+
await client.crabcodeByok.revoke(cred.credentialRef); // 软吊销 + 抹密文, 幂等
|
|
377
|
+
```
|
|
378
|
+
|
|
342
379
|
要点:
|
|
343
380
|
|
|
344
381
|
- **scope 隔离**:远控用专用 `remote_control` scope(服务端展开为 `remote_control:{agent-run,session-control,permission-response}` 三子项);**绝不复用** `models:chat`/`ai`,且 `allScopes()` 不含它——桌面登录不会自动获得远控权限。用 `remoteControlScopes()` 或显式 `[...allScopes(), ScopeRemoteControl]`。
|
|
@@ -356,25 +393,52 @@ await client.agentRuns.cancel(run.runId); // UI 中止走服务端 cancel contro
|
|
|
356
393
|
- **11 事件 union**(`RemoteControlEvent`,契约 §4):`text_delta` / `reasoning_delta` / `tool_call` / `tool_result` / `permission_request` / `permission_result` / `usage` / `settle` / `status` / `error` / `done`。`error` **恒为非终结**(终结性错误由 `done.reason`/`done.finalStatus` 承载),`done` / `settle` 才终结流——故 `streamRemoteControl` 不接受 options、从不抛异常;用 `isTerminalRemoteEvent(ev)` 判终结。
|
|
357
394
|
- **辅助导出**:`parseRemoteControlEvent` / `isTerminalRemoteEvent` / `AdapterKind` / `RunnerKind` / `RemoteControlEvent` / `RemoteSessionPlacement` / `PermissionPolicy` / `WorkspacePolicy`(`src/agent-runs/remote-control.ts`)。
|
|
358
395
|
|
|
359
|
-
## Chat Bridge(第三方聊天平台桥接,v2.
|
|
396
|
+
## Chat Bridge(第三方聊天平台桥接,v2.7.0 · Phase 7B 管理面 CRUD 落地)
|
|
360
397
|
|
|
361
|
-
`
|
|
398
|
+
`client.chatBridge` 提供第三方聊天平台(飞书/企微/钉钉/Slack/Teams/Telegram/WhatsApp)集成与凭证的管理面 CRUD。**云端控制台与下游(CrabCode 等)调的是同一组端点、同一份按租户隔离的数据**——任一端创建/修改,另一端即时可见,无需同步机制。平台 webhook adapter(验签/收发消息)是 Phase 8 后端工作,SDK 不承载。
|
|
362
399
|
|
|
363
400
|
```ts
|
|
364
|
-
import {
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
401
|
+
import { Client, chatBridgeScopes } from '@acosmi/sdk-ts';
|
|
402
|
+
|
|
403
|
+
const client = new Client({ baseURL: process.env.ACOSMI_BASE_URL! });
|
|
404
|
+
// chat_bridge 是高风险 scope, 不在 allScopes() 内, 必须显式申请
|
|
405
|
+
await client.login('CrabCode 平台接入', chatBridgeScopes());
|
|
406
|
+
|
|
407
|
+
// 1. 创建集成 (chat_bridge:write); 平台原始 ID 服务端只存 SHA256 hash
|
|
408
|
+
const integ = await client.chatBridge.createIntegration({
|
|
409
|
+
appId: 'crabcode', platform: 'feishu', region: 'cn',
|
|
410
|
+
workspaceId: 'ou_xxx', botId: 'cli_xxx',
|
|
411
|
+
});
|
|
412
|
+
|
|
413
|
+
// 2. 存凭证 (明文一次性提交; 响应恒为 masked 视图, 永不回明文/密文)
|
|
414
|
+
const cred = await client.chatBridge.storeCredential(integ.id, {
|
|
415
|
+
secretKind: 'app_secret', plaintext: process.env.FEISHU_SECRET!,
|
|
416
|
+
});
|
|
417
|
+
|
|
418
|
+
// 3. 激活
|
|
419
|
+
await client.chatBridge.updateIntegrationStatus(integ.id, 'active');
|
|
420
|
+
|
|
421
|
+
// 查询 (chat_bridge:read) / 轮换与吊销 (chat_bridge:rotate, 高风险独立 scope)
|
|
422
|
+
await client.chatBridge.listIntegrations('crabcode');
|
|
423
|
+
await client.chatBridge.listCredentials(integ.id);
|
|
424
|
+
await client.chatBridge.rotateCredential(integ.id, 'app_secret', 'new-secret');
|
|
425
|
+
await client.chatBridge.revokeCredential(cred.credentialRef);
|
|
426
|
+
```
|
|
368
427
|
|
|
428
|
+
类型守卫与 branded ref 仍从根入口导出:
|
|
429
|
+
|
|
430
|
+
```ts
|
|
431
|
+
import { isPlatform, asCredentialRef, type Platform } from '@acosmi/sdk-ts';
|
|
369
432
|
isPlatform('feishu'); // → true(7 平台枚举运行时守卫)
|
|
370
433
|
asCredentialRef('cred_abc...'); // → branded CredentialRef(防 plaintext 误传)
|
|
371
434
|
```
|
|
372
435
|
|
|
373
|
-
边界(契约 §6 + §16):
|
|
436
|
+
边界(契约 §6 + §12 + §16):
|
|
374
437
|
|
|
375
|
-
- 平台 secret(bot token / signing key / AES key
|
|
376
|
-
- **wire
|
|
377
|
-
- 平台原始 thread / sender / workspace ID 一律 SHA256 hash 后入库(`threadHash`/`senderHash`)。
|
|
438
|
+
- 平台 secret(bot token / signing key / AES key)**只在 `storeCredential`/`rotateCredential` 请求体出现一次**,服务端加密落库后即弃;SDK 公共面只见 `CredentialRef`(`cred_<base32>`)+ `fingerprint` + 脱敏 metadata,**永不**出现 ciphertext / plaintext(`ChatCredentialPublic` 编译期即无密文字段)。
|
|
439
|
+
- **wire 平面**:请求体为 snake_case(SDK 自动转换),响应资源视图走 nexus-v4 model-direct 序列化为 **camelCase**(与 remote-control 的 snake_case 平面不同,详见契约 §12)。`ChatIntegration.configJson` 服务端从不返回(`json:"-"`),写入走 `createIntegration({ configJson })`。
|
|
440
|
+
- 平台原始 thread / sender / workspace ID 一律 SHA256 hash 后入库(`threadHash`/`senderHash`/`workspaceIdHash`)。
|
|
441
|
+
- scope 三档最小授权:`chat_bridge:read`(查询)/ `chat_bridge:write`(创建集成/存凭证)/ `chat_bridge:rotate`(轮换/吊销,高风险);分组 scope `chat_bridge` 自包含三子项。跨租户引用服务端一律 404。
|
|
378
442
|
|
|
379
443
|
## 认证
|
|
380
444
|
|
|
@@ -460,7 +524,7 @@ const client = new Client({ serverURL: process.env.ACOSMI_SERVER_URL!, store: ne
|
|
|
460
524
|
| **Notifications — WebSocket** | `connect`, `disconnect`, `isConnected` (实时推送订阅;浏览器走原生 WebSocket,Node 18-21 需自装 `ws`,Node 22+ 用原生) |
|
|
461
525
|
| **Bug Report** | `submitBugReport`, `getBugReport` |
|
|
462
526
|
| **Web Search** | `newWebSearchTool` (factory) |
|
|
463
|
-
| **Subscription**(v1.7.0
|
|
527
|
+
| **Subscription**(v1.7.0+;v2.6.0 +会员查询) | `listPlans`, `getPlanByCode`(v2.1+), `getMembership`(v2.6+), `getSubscriptionTier`(v2.6+), `subscriptionPrecheck`(v2.6+), ~~`listUserSubscriptions`~~(deprecated,改用 `getMembership`) |
|
|
464
528
|
| **Pricing**(v1.7.0+) | `getPricingConfig`, `quoteCompliance` |
|
|
465
529
|
| **Products**(v1.7.0+) | `getProductBySlug`, `listProductsByFamily`, `listComplianceSkus`, `listPublicModels` |
|
|
466
530
|
| **Casehall — 法律案件**(v1.8.0+) | `listLawyers`, `getLawyer`, `submitCaseLead`, `listMyCaseLeads`, `getMyCases`, `bookConsultation`, `listMyConsultations`, `listMyLegalOrders`, `listLegalSKUs`, `getMyLawyerCredentialStatus`(v2.0.0+) |
|
|
@@ -600,17 +664,33 @@ console.log('sidecar →', sidecar.modelId);
|
|
|
600
664
|
### 示例:钱包 + 余额 + 流量包购买
|
|
601
665
|
|
|
602
666
|
```ts
|
|
603
|
-
// 金额字段是
|
|
667
|
+
// WalletStats 金额字段是 number(Go float64 端点 wallet.go;非 json.Number)
|
|
604
668
|
const stats = await client.getWalletStats();
|
|
605
|
-
// { balance:
|
|
669
|
+
// { balance: 100.0, monthlyConsumption: 32.5, monthlyRecharge: 150.0, transactionCount: 12 }
|
|
606
670
|
|
|
607
|
-
const balance = await client.getBalance(); //
|
|
671
|
+
const balance = await client.getBalance(); // 聚合权益余额(EntitlementBalance)
|
|
608
672
|
|
|
609
673
|
const pkgs = await client.listTokenPackages();
|
|
610
|
-
|
|
611
|
-
const
|
|
674
|
+
// PayPayload.paymentMethod 取枚举字面量('WECHAT_NATIVE' | 'ALIPAY_PRECREATE' | 'BANK_TRANSFER')
|
|
675
|
+
const order = await client.buyTokenPackage(pkgs[0].id, { paymentMethod: 'WECHAT_NATIVE' });
|
|
676
|
+
// BuyResponse 用 orderId(number)/ orderNo(string),无 .id;waitForPayment 取 string
|
|
677
|
+
const status = await client.waitForPayment(String(order.orderId), 2000); // 2s 轮询直到终态
|
|
612
678
|
```
|
|
613
679
|
|
|
680
|
+
> ⚠️ **额度单位双体系(务必区分,不要跨单位相加)**:`getBalance` / `getBalanceDetail` /
|
|
681
|
+
> `listEntitlements` / `getMembership` 返回的 `token*` 字段(`tokenQuota`/`tokenRemaining`/
|
|
682
|
+
> `tokenUsed`/`tokenTotal`)单位**取决于权益是否付费**:
|
|
683
|
+
>
|
|
684
|
+
> - **免费档(TK 体系)**:`type` 非 `TOKEN_PACKAGE`/`SUBSCRIPTION` 的权益(每月领取的免费额度等),
|
|
685
|
+
> 数值即**原始 Token**,UI 以「千万/万 Token」展示。免费额度通过 `claimMonthlyFree()` 领取。
|
|
686
|
+
> - **付费会员(Credits 代币体系)**:`type` 为 `TOKEN_PACKAGE` / `SUBSCRIPTION` 的权益,数值是
|
|
687
|
+
> **微 Credits**,**÷1000 = Credits(代币)**,UI 以「亿/万 Credits」展示。各档位标准额度
|
|
688
|
+
> (BASIC 0.6 亿 / PRO 3 亿 / PRO_MAX 9 亿 / ULTRA 24 亿 Credits)即按 Credits 计。
|
|
689
|
+
>
|
|
690
|
+
> 因此**绝不能把免费区与付费区的 `token*` 数值直接求和**——两者单位不同(Token vs 微Credits)。
|
|
691
|
+
> 判定付费区的唯一判据是权益 `type ∈ {TOKEN_PACKAGE, SUBSCRIPTION}`。`getMembership()` 的
|
|
692
|
+
> `tokenQuota`/`tokenUsed` 在有活跃付费订阅(`hasActive=true`)时同为微 Credits。
|
|
693
|
+
|
|
614
694
|
### 示例:Bug Report(CrabCode CLI 反馈端点)
|
|
615
695
|
|
|
616
696
|
```ts
|
|
@@ -928,9 +1008,10 @@ npm run docs # 经 TypeDoc 生成 API 参考到 docs/api/
|
|
|
928
1008
|
|
|
929
1009
|
| 版本 | 状态 | 概要 |
|
|
930
1010
|
| --- | --- | --- |
|
|
931
|
-
| 2.
|
|
1011
|
+
| 2.6.0 | **当前版本** | **会员订阅查询 + 一批后端契约类型修正 + WS 一次性 ticket 鉴权(2026-06-04)**。**新增**:`subscription.getMembership()` / `getSubscriptionTier()` / `subscriptionPrecheck()`;`ManagedModel` 档位门控字段 `locked`/`freeTier`/`minPlanTier`/`chatRuntimeSupported`/`defaultToolIds`;auth `ScopeChatBridge`(+read/write/rotate) 与 `chatBridgeScopes()`。**破坏性类型修正**(此前形状与后端不符、运行时即为 undefined):`BalanceDetail` 对齐网关 `InternalBalanceResponse`(`userId`/`tokenRemaining`/`tokenTotal`/`callRemaining`/`callTotal`/`entitlements[]`);`Order` 拆为 `BuyResponse`/`OrderListItem`;`getOrderStatus`/`waitForPayment` 改用 `BuyResponse.paymentStatus`(修死循环);`PayPayload.payMethod`→`paymentMethod` + 枚举 `WECHAT_NATIVE`/`ALIPAY_PRECREATE`/`BANK_TRANSFER` + `deviceId`/`clientRequestId`;`TokenPackage` 对齐 `toProductView`;`WalletStats`/`Transaction` `amount` string→number;consume-records 分页(`records`/`total`/`page`/`pageSize`);`EntitlementItem.createdAt` 改可选 + `activatedAt`;`ConsumeRecord` 补缓存字段;notifications WebSocket 用一次性 `stream-ticket` 取代 URL `?token=` JWT(修复 WS 鉴权 + 杜绝 JWT 泄露)。**废弃**:`listUserSubscriptions`(改用 `getMembership`)/ `ModelCoefficient`·`listCoefficients`(系数退役恒空)/ `ManagedModel.pricePerMTok`·`isDefault`(公开端点不返回);notifications `registerDevice`/`unregisterDevice`/`list`+`updateNotificationPreference` 标 `@experimental`(网关无端点)。详见 CHANGELOG。 |
|
|
1012
|
+
| 2.5.1 | 稳定版 | **模型 adapter 格式一致性护栏(2026-05-31)**。`getAdapterForModel` 路由加固:`preferred_format` 仅当被 `supported_formats` 收录(或 `supported_formats` 未声明)才采信,防止上游元数据漂移把 SDK 路由到模型不支持的格式端点(撞 `/anthropic` 4xx)。`supported_formats` 未声明(旧上游)时行为逐字节不变;新增 3 条 routing 用例。详见 CHANGELOG。 |
|
|
932
1013
|
| 2.5.0 | 稳定版 | **源码健康度审计根因修复(2026-05-31)**。修复一批真实运行时缺陷:`downloadArtifact()` 超限抛错(不再静默截断)/ 本地工具 `Promise.race` 硬超时 / OpenAI 流式 reasoning→tool_calls block index 修正 / 非法 `expires_at` 视为过期 + TokenStore 校验 / OAuth 链路走注入 `fetchImpl` / 空成功响应(204)不抛 parse error / `apiBaseURL`·`complianceBaseURL` 同级校验 / 非流式默认超时 / WS 重复 connect 关旧连接 / `FileTokenStore.save()` 真 fsync / chat 请求对象不被原地 mutate / Anthropic `extraBody` 不覆盖 SDK 管理字段 / `CompliancePollError` 携带最后状态。**公开类型/方法签名零移除、零改名**(新增导出 `normalizeOverrideBaseURL`·`DEFAULT_API_TIMEOUT_MS`)。casehall/finance/enterprise 路径经生产实证确认正确(同源代理直连 tk-dist)未改 + 新增 URL 组装回归测试。详见 CHANGELOG 与 `docs/audit/TS版SDK源码健康度与文档审计报告.md`。 |
|
|
933
|
-
| 2.4.0 |
|
|
1014
|
+
| 2.4.0 | 稳定版 | **`SkillStoreItem.skillMd?` 透出(additive minor,2026-05-30)**。修复下游经 SDK 拿不到技能 SKILL.md 正文:网关 `SkillStoreResponse` 早已返回 `skillMd`(`ToStoreResponse()` 已 map),但 SDK `SkillStoreItem` 漏声明。新增可选 `skillMd?: string`(Anthropic SKILL.md 正文,仅 Detail/resolve/非 minimal browse 携带;`SkillStoreListItem` minimal 刻意不含正文);`readme` 一并改为可选 `readme?`(匹配网关 `omitempty`)。零方法签名/运行时改动。下游 CrabCode 重锁 `@acosmi/sdk-ts@2.4.0` + `bun install --force` 生效;SKILL.md 为不可信用户内容,GUI 渲染须 sanitize + 展示 securityLevel/securityScore/certificationStatus。 |
|
|
934
1015
|
| 2.3.0 | 稳定版 | **`apiBaseURL` 可配置网关 base(additive,2026-05-30)**。新增可选 client 配置项,让浏览器侧 `/api/v4` 网关调用(managed-model / agent-run / casehall)可经同源代理转发,规避非网关同源域名(如 `sign.zhonglvbao.com`)下 acosmi.com 对带 `Origin` 跨域浏览器请求的 403。公开类型 / 方法签名零移除、零改名(additive minor)。 |
|
|
935
1016
|
| 2.2.1 | 稳定版 | **README 字段名修正(docs-only patch,2026-05-29)**。修复 v2.2.0 README 示例把能力字段误写为 camelCase(`supportsImageGeneration`);正确为 wire snake_case `capabilities.supports_image_generation` / `supports_video_generation`(`listModels` 对 `capabilities` 对象原样透传)。补充:字段随 catalog 下发、可选(缺省 false)、无专用 catalog helper。无源码改动,从 2.2.0 升级无需 review。 |
|
|
936
1017
|
| 2.2.0 | 稳定版 | **托管模型图片/视频生成(2026-05-29)**。图片/视频生成与文本模型同属托管模型网关(同 `Client`、同 `models:chat` 鉴权面),仅 `capabilities.supports_image_generation` / `supports_video_generation` 的模型可用;计费结算在营销系统,SDK / 网关只负责调用与用量上报。新增 `client.generateImage(modelID, req, signal?)`(同步,`POST /managed-models/:id/images/generations`)/ `client.generateVideo(modelID, req, signal?)`(建异步任务,返回 `taskId`)/ `client.pollVideoTask(modelID, taskID, durationSeconds?, signal?)`(轮询,`durationSeconds` 透传给网关在 `completed` 时上报视频秒数);新增 `ImageGenerationRequest`/`ImageGenerationResponse`/`VideoGenerationRequest`/`VideoTaskResponse` 类型 + `ModelCapabilities.supports_image_generation`/`supports_video_generation` 标志(wire snake_case,`capabilities` 对象透传不归一化)。网关适配 OpenAI 兼容图片 + 火山引擎(即梦/豆包)视频 + DashScope 通义万相(wanx)原生异步任务(图片+视频)。公开类型 / 方法签名零移除、零改名(additive minor)。 |
|