@acosmi/sdk-ts 2.13.0 → 2.15.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,33 @@ 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.15.0] - 2026-08-02 — sources 四态分类与零结果契约
9
+
10
+ ### Added
11
+
12
+ - **`classifySourcesEvent`** — 同时识别 SSE event name 与 JSON payload discriminator,明确返回 `not_sources`、`empty_sources`、`sources` 或 `malformed_sources`,不再把合法零来源与结构损坏混为同一个状态。
13
+ - **`SourcesEventParseResult` / `SourcesEventIssueCode`** — 为 JSON、数组、item、title、URL、snippet 和 session id 提供稳定机器码;未知额外字段保持兼容。
14
+
15
+ ### Changed
16
+
17
+ - **`parseSourcesEvent` 保持逐行为向后兼容** — 保留既有宽松解析、`null` 条件和返回对象形状;新调用通过四态 API 获得严格语义,既有 `chatStreamWithUsage` consumer 零变化。
18
+
19
+ ## [2.14.0] - 2026-08-02 — inputModalities 开放值域归一 (open modality domain)
20
+
21
+ 模态标签的值域由**网关托管模型目录**持有,靠运营动作扩张(`video` 自 2026-06-20 起已是合法值),不靠发 SDK 新版。此前 SDK 在两处把它当成封闭集处理:`InputModality` 类型只列 `text|image`,且 `input_modalities`(snake_case)归一化分支按这份硬编码集裁剪数组——而 camelCase 分支从不裁剪。线上 wire 恒为 camelCase,所以那个过滤器从未真正执行过(死代码),但它把错误语义写进了契约。本版收敛为对称透传,并把数据字段的类型开放。
22
+
23
+ 同一形态的封闭枚举在 CrabCode 客户端(Rust 侧)造成过真实事故:一行目录数据声明 `video`,整个网关模型列表在所有客户端上打空数周。**扩模态的次序是硬的:先客户端、再 SDK、最后网关白名单**。
24
+
25
+ ### Changed
26
+
27
+ - **`normalizeInputModalities` 两分支对称** — snake_case 分支不再按 `{text, image}` 白名单裁剪,只做键名归一 + 剔除非字符串元素(畸形值)。camelCase 分支行为不变(本就原样透传)。**行为影响仅限**上游改发 snake_case 的假设场景;现网 camelCase 路径逐字节不变。
28
+ - **`InputModality` 加 `'video'`** — 该联合体现在的定位是「**查询用**的已知标签集」(`modelSupportsInputModality` / `findFirstModelByInputModality` 的 `modality` 参数),保留自动补全。
29
+ - **`ManagedModel.inputModalities` 类型放开为 `InputModalityTag[]`** — 数据字段照收目录里的任何标签,未知模态不再被类型谎报成不可能出现。既有消费方(`includes('image')` 族判定)零改动。
30
+
31
+ ### Added
32
+
33
+ - **`InputModalityTag`(类型)** — 模态标签的**开放**值域(即 `string`;已知取值见 `InputModality`)。规则是「查询用 `InputModality`(有补全),数据用 `InputModalityTag`(照收未知标签)」。
34
+
8
35
  ## [2.13.0] - 2026-08-01 — 邀请奖励窗口重置券 (window-reset credits)
9
36
 
10
37
  邀请奖励从"送 token"改为**送窗口重置次数**:被邀请人激活并达到用量门槛后给邀请人发一张重置券,每张可清空一次滚动窗口已用量(只动窗口用量原语,**月度额度池零触碰**)。SDK 加性新增总览查询与核销两个客户端方法,核销支持 `clientRequestId` 幂等键。全部加性,既有调用零改动。
@@ -69,6 +96,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
69
96
  - **类型** — `EmbeddingRequest`/`EmbeddingData`/`EmbeddingResponse`/`RerankRequest`/`RerankResult`/`RerankResponse`。
70
97
  - **`listModels` / `listModelsWithStatus` 新增 `opts.includeLocked`** — `true` 时请求 `/managed-models?picker=1` 全集模式:网关把越档模型作为 `Locked=true` 补回返全集,供 C 端选择器展示「付费订阅区」+ 置灰升级引导。缺省行为不变(只返有桶模型,向后兼容)。全集模式不写 `modelCache`,避免 locked 模型混入可用模型集。
71
98
 
99
+ ## [2.8.0] - 2026-06-16 — 登录 302 重定向承接(successRedirectURL)
100
+
101
+ > 本条目为 2026-08-02 补记(发版时 CHANGELOG 漏记;事实源 = 独立仓 v2.8.0 tag / npm 2.8.0 / 父仓同步 commit `1f91c394`)。
102
+
103
+ ### Added
104
+
105
+ - **`LoginOptions.successRedirectURL`(可选)** — 登录成功后的 302 重定向目标(issue C「302 重定向发版」承接);不传时行为与 2.7.0 完全一致。additive minor,既有调用零改动。
106
+
72
107
  ## [2.7.0] - 2026-06-11 — 远控管理面补齐 + BYOK 密钥客户端 + Chat Bridge CRUD(Phase 7B)
73
108
 
74
109
  补齐远控核心交互之外的全部管理面(此前下游 CrabCode 只能裸 fetch),新增 BYO 模型密钥客户端,落地 chat-bridge integration/credential 管理面 CRUD——云端控制台与下游调用的是同一组端点同一份租户隔离数据,天然互通。全部方法逐字段对齐 nexus-v4 handler 真实 wire 形状(契约 §12/§14/§18 附录 A)。
@@ -951,6 +986,32 @@ Additive minor。公开类型 / 方法签名零移除、零改名。契约见 `d
951
986
  - 36/36 vitest 全绿,源码 typecheck/lint/build 0 错误
952
987
  - 翻车机制:`prepublishOnly` 仅跑源码 typecheck/vitest/build,不验证 packed product 在 consumer 视角能否解析
953
988
 
989
+ [2.15.0]: https://github.com/acosmi/sdk-ts/releases/tag/v2.15.0
990
+ [2.14.0]: https://github.com/acosmi/sdk-ts/releases/tag/v2.14.0
991
+ [2.13.0]: https://github.com/acosmi/sdk-ts/releases/tag/v2.13.0
992
+ [2.12.0]: https://github.com/acosmi/sdk-ts/releases/tag/v2.12.0
993
+ [2.11.0]: https://github.com/acosmi/sdk-ts/releases/tag/v2.11.0
994
+ [2.10.0]: https://github.com/acosmi/sdk-ts/releases/tag/v2.10.0
995
+ [2.9.0]: https://github.com/acosmi/sdk-ts/releases/tag/v2.9.0
996
+ [2.8.0]: https://github.com/acosmi/sdk-ts/releases/tag/v2.8.0
997
+ [2.7.0]: https://github.com/acosmi/sdk-ts/releases/tag/v2.7.0
998
+ [2.6.0]: https://github.com/acosmi/sdk-ts/releases/tag/v2.6.0
999
+ [2.5.1]: https://github.com/acosmi/sdk-ts/releases/tag/v2.5.1
1000
+ [2.4.0]: https://github.com/acosmi/sdk-ts/releases/tag/v2.4.0
1001
+ [2.3.0]: https://github.com/acosmi/sdk-ts/releases/tag/v2.3.0
1002
+ [2.2.1]: https://github.com/acosmi/sdk-ts/releases/tag/v2.2.1
1003
+ [2.2.0]: https://github.com/acosmi/sdk-ts/releases/tag/v2.2.0
1004
+ [2.1.0]: https://github.com/acosmi/sdk-ts/releases/tag/v2.1.0
1005
+ [2.0.1]: https://github.com/acosmi/sdk-ts/releases/tag/v2.0.1
1006
+ [2.0.0]: https://github.com/acosmi/sdk-ts/releases/tag/v2.0.0
1007
+ [1.9.0]: https://github.com/acosmi/sdk-ts/releases/tag/v1.9.0
1008
+ [1.6.0]: https://github.com/acosmi/sdk-ts/releases/tag/v1.6.0
1009
+ [1.5.1]: https://github.com/acosmi/sdk-ts/releases/tag/v1.5.1
1010
+ [1.5.0]: https://github.com/acosmi/sdk-ts/releases/tag/v1.5.0
1011
+ [1.4.2]: https://github.com/acosmi/sdk-ts/releases/tag/v1.4.2
1012
+ [1.4.1]: https://github.com/acosmi/sdk-ts/releases/tag/v1.4.1
1013
+ [1.4.0]: https://github.com/acosmi/sdk-ts/releases/tag/v1.4.0
1014
+ [1.3.2]: https://github.com/acosmi/sdk-ts/releases/tag/v1.3.2
954
1015
  [1.3.1]: https://github.com/acosmi/sdk-ts/releases/tag/v1.3.1
955
1016
  [1.3.0]: https://github.com/acosmi/sdk-ts/releases/tag/v1.3.0
956
1017
  [1.2.0]: https://github.com/acosmi/sdk-ts/releases/tag/v1.2.0
@@ -958,3 +1019,6 @@ Additive minor。公开类型 / 方法签名零移除、零改名。契约见 `d
958
1019
  [1.0.2]: https://github.com/acosmi/sdk-ts/releases/tag/v1.0.2
959
1020
  [1.0.1]: https://github.com/acosmi/sdk-ts/releases/tag/v1.0.1
960
1021
  [1.0.0]: https://www.npmjs.com/package/@acosmi/sdk-ts/v/1.0.0
1022
+
1023
+ <!-- 1.7.0 / 1.8.0 / 1.8.1 / 2.5.0 为未单独发版的内部迭代(无 git tag、无 npm 版本,内容并入下一个发布),故无链接定义。
1024
+ 2026-08-02 实证:git ls-remote --tags(v1.6.0 直跳 v1.9.0、v2.4.0 直跳 v2.5.1)+ npm view @acosmi/sdk-ts versions 同形。 -->
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
- - **当前版本:`2.6.0`**(订阅会员查询 + 一批后端契约类型修正 + WS 一次性 ticket 鉴权,2026-06-04)。
10
+ - **当前版本:`2.15.0`**(sources 四态分类与零结果兼容契约,2026-08-02)。
11
+ - **`v2.15.0`(加性兼容发布)**:新增 `classifySourcesEvent()`、`SourcesEventParseResult` 与稳定 issue code,把 `not_sources`、合法 `empty_sources`、非空 `sources`、`malformed_sources` 明确分开。既有 `parseSourcesEvent()` 的代码路径、宽松判定、`null` 条件和返回对象形状保持原样;现有 consumer 无需改动,新 consumer 才选择严格 API。
11
12
  - **`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。
12
13
  - **`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 用例钉死矛盾场景。
13
14
  - **`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 组装回归测试钉死契约。
@@ -289,6 +290,33 @@ for await (const ev of stream) {
289
290
 
290
291
  `chatStreamWithUsage()` 返回带 usage/error/sources 标签的 AsyncIterable,便于聚合统计(详见 `src/core/client.ts`)。
291
292
 
293
+ ### Sources SSE 四态分类(v2.15+)
294
+
295
+ `sources: []` 是检索成功但没有可展示引用的合法零结果,不是传输损坏。需要精确区分状态的新 consumer 使用加性接口 `classifySourcesEvent()`:
296
+
297
+ ```ts
298
+ import { classifySourcesEvent, type StreamEvent } from '@acosmi/sdk-ts';
299
+
300
+ function consume(event: StreamEvent) {
301
+ const result = classifySourcesEvent(event);
302
+ switch (result.kind) {
303
+ case 'not_sources':
304
+ return; // 交给其他 SSE 事件处理器
305
+ case 'empty_sources':
306
+ return; // 合法 no-op;不得升级为 turn/runtime fatal
307
+ case 'sources':
308
+ renderSources(result.value.sources);
309
+ return;
310
+ case 'malformed_sources':
311
+ recordCompatibilityCode(result.code); // 只记录稳定机器码,不记录来源内容
312
+ }
313
+ }
314
+ ```
315
+
316
+ 分类器同时识别 SSE `event: sources` 和 JSON payload `type: "sources"`,校验数组、item、`title`、`url`、可选 `snippet` 与 `session_id` 的类型,并允许未知额外字段。JSON 无法解析但 SSE 已声明为 sources 时返回 `malformed_sources/invalid_json`。
317
+
318
+ `parseSourcesEvent()` 保留给既有集成:它仍按历史宽松规则解析,空数组、缺失数组、非 sources 或 JSON 损坏仍返回 `null`,非空时仍只返回 `{ sources, session_id }`。它没有改为调用严格分类器,避免严格字段校验改变旧 consumer 对历史/第三方 frame 的接受范围。升级到 2.15.0 不要求关联方迁移;只有需要四态语义的调用方才采用新 API。
319
+
292
320
  ## Agent Runs
293
321
 
294
322
  `client.agentRuns` 是下游产品接入 Acosmi 云端智能体循环的正式 SDK 边界。CrabDesign、CrabCode、CrabClaw 等产品应通过这里创建、流式消费、取消、查询和下载智能体任务,不要直连 Nexus 内部 `/api/v4/chat/completions`。
@@ -1072,7 +1100,16 @@ npm run docs # 经 TypeDoc 生成 API 参考到 docs/api/
1072
1100
 
1073
1101
  | 版本 | 状态 | 概要 |
1074
1102
  | --- | --- | --- |
1075
- | 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。 |
1103
+ | 2.15.0 | **当前版本** | **sources 四态分类与零结果契约(2026-08-02)**。加性新增 `classifySourcesEvent`、`SourcesEventParseResult` 与稳定 issue code,区分非 sources、合法空结果、有效结果和结构损坏;未知额外字段继续兼容。既有 `parseSourcesEvent` 的返回形状、宽松解析和 `null` 条件保持不变。 |
1104
+ | 2.14.0 | 稳定版 | **托管模型 input modalities 开放值域(2026-08-02)**。snake_case/camelCase 归一规则对称,数据字段允许未来新增标签;查询 API 仍保留已知标签自动补全。现网 camelCase 路径行为不变。 |
1105
+ | 2.13.0 | 稳定版 | **邀请奖励窗口重置券(2026-08-01)**。加性新增窗口重置券总览与幂等核销 API,不改变既有 token、额度和会员调用。 |
1106
+ | 2.12.0 | 稳定版 | **5 小时窗口软限额(2026-07-11)**。加性透传 `windowOverridable`、继续开关与结构化状态;老网关缺字段时按硬等待处理。 |
1107
+ | 2.11.0 | 稳定版 | **窗口限额结构化承接(2026-07-09)**。加性新增 `WINDOW_LIMIT_EXCEEDED` 机器码、窗口种类/恢复时间及识别辅助函数,并修复扁平 `/chat` 错误消息解析。 |
1108
+ | 2.10.0 | 稳定版 | **多模态向量与重排序(2026-06-20)**。加性扩展 text/image/video 输入;文本调用保持兼容。 |
1109
+ | 2.9.0 | 稳定版 | **Embedding、Rerank 与模型全集模式(2026-06-20)**。新增托管向量/重排序端点和 `includeLocked` 选择器能力。 |
1110
+ | 2.8.0 | 稳定版 | **登录 302 重定向承接(2026-06-16)**。加性新增可选 `LoginOptions.successRedirectURL`;缺省行为不变。 |
1111
+ | 2.7.0 | 稳定版 | **远控管理面、BYOK 与 Chat Bridge CRUD(2026-06-11)**。加性补齐远控会话管理、密钥管理和第三方聊天平台接入面。 |
1112
+ | 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。 |
1076
1113
  | 2.5.1 | 稳定版 | **模型 adapter 格式一致性护栏(2026-05-31)**。`getAdapterForModel` 路由加固:`preferred_format` 仅当被 `supported_formats` 收录(或 `supported_formats` 未声明)才采信,防止上游元数据漂移把 SDK 路由到模型不支持的格式端点(撞 `/anthropic` 4xx)。`supported_formats` 未声明(旧上游)时行为逐字节不变;新增 3 条 routing 用例。详见 CHANGELOG。 |
1077
1114
  | 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`。 |
1078
1115
  | 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。 |
@@ -41,6 +41,57 @@ function newWebSearchTool(cfg) {
41
41
  }
42
42
  return st;
43
43
  }
44
+ function classifySourcesEvent(ev) {
45
+ let parsed;
46
+ try {
47
+ parsed = JSON.parse(ev.data);
48
+ } catch {
49
+ return ev.event === "sources" ? { kind: "malformed_sources", code: "invalid_json" } : { kind: "not_sources" };
50
+ }
51
+ const wrapper = typeof parsed === "object" && parsed !== null && !Array.isArray(parsed) ? parsed : null;
52
+ if (wrapper?.type !== "sources" && ev.event !== "sources") {
53
+ return { kind: "not_sources" };
54
+ }
55
+ if (!wrapper || !Object.prototype.hasOwnProperty.call(wrapper, "sources")) {
56
+ return { kind: "malformed_sources", code: "missing_sources" };
57
+ }
58
+ if (Object.prototype.hasOwnProperty.call(wrapper, "session_id") && wrapper.session_id !== void 0 && typeof wrapper.session_id !== "string") {
59
+ return { kind: "malformed_sources", code: "session_id_invalid" };
60
+ }
61
+ if (!Array.isArray(wrapper.sources)) {
62
+ return { kind: "malformed_sources", code: "sources_not_array" };
63
+ }
64
+ const sessionID = typeof wrapper.session_id === "string" ? wrapper.session_id : void 0;
65
+ if (wrapper.sources.length === 0) {
66
+ return {
67
+ kind: "empty_sources",
68
+ ...sessionID === void 0 ? {} : { session_id: sessionID }
69
+ };
70
+ }
71
+ for (const source of wrapper.sources) {
72
+ if (typeof source !== "object" || source === null || Array.isArray(source)) {
73
+ return { kind: "malformed_sources", code: "source_not_object" };
74
+ }
75
+ const item = source;
76
+ if (typeof item.title !== "string") {
77
+ return { kind: "malformed_sources", code: "source_title_invalid" };
78
+ }
79
+ if (typeof item.url !== "string") {
80
+ return { kind: "malformed_sources", code: "source_url_invalid" };
81
+ }
82
+ if (Object.prototype.hasOwnProperty.call(item, "snippet") && item.snippet !== void 0 && typeof item.snippet !== "string") {
83
+ return { kind: "malformed_sources", code: "source_snippet_invalid" };
84
+ }
85
+ }
86
+ return {
87
+ kind: "sources",
88
+ value: {
89
+ ...wrapper,
90
+ sources: wrapper.sources,
91
+ ...sessionID === void 0 ? {} : { session_id: sessionID }
92
+ }
93
+ };
94
+ }
44
95
  function parseSourcesEvent(ev) {
45
96
  let wrapper;
46
97
  try {
@@ -3608,9 +3659,7 @@ function normalizeInputModalities(models) {
3608
3659
  if (Array.isArray(m.inputModalities)) continue;
3609
3660
  const snake = m.input_modalities;
3610
3661
  if (Array.isArray(snake)) {
3611
- m.inputModalities = snake.filter(
3612
- (v) => v === "text" || v === "image"
3613
- );
3662
+ m.inputModalities = snake.filter((v) => typeof v === "string");
3614
3663
  }
3615
3664
  }
3616
3665
  return models;
@@ -7679,6 +7728,6 @@ function brandCredential(c) {
7679
7728
  return c;
7680
7729
  }
7681
7730
 
7682
- export { AGENT_RUN_META_TITLE, AGENT_RUN_META_WORKSPACE, ALL_INTEGRATION_STATUS, ALL_PLATFORMS, ALL_REGIONS, AgentRunStreamError, AgentRunsClient, AnthropicAdapter, AudienceEnum, BillingModeEnum, BucketClassCommercial, BucketClassGeneric, BusinessError, ChatBridgeClient, Client, ComplianceClient, CompliancePollError, CrabCodeByokClient, DEFAULT_API_TIMEOUT_MS, DEFAULT_GATEWAY_BASE_URL, LocalStorageTokenStore as DefaultBrowserTokenStore, DefaultRetryPolicy, ErrAuthDenied, ErrBillingCallbackCannotCommit, ErrBillingCommitRequiresLocalVerify, ErrBillingS2sForbidden, ErrBrowserOpen, ErrComplianceStepUpRequired, ErrDiscovery, ErrEnvelopeGateClosed, ErrOAuthCORSBlocked, ErrProviderNotConfigured, ErrProviderUnknownNoRetry, ErrRefreshProxyFailed, ErrRegistration, ErrSSLProxy, ErrSealApprovalContractHashMismatch, ErrSealApprovalExpired, ErrSealApprovalLocationMismatch, ErrSealApprovalNonceUsed, ErrSealApprovalNotApproved, ErrSealApprovalSealMismatch, ErrSealApprovalTransactorMismatch, ErrSealUseAlreadyConsumed, ErrStateMismatch, ErrTimeout, ErrTokenExchange, ErrTokenExpired, EventAuthURL, EventComplete, EventError, FileTokenStore, FilterStatusAdminBypass, FilterStatusDisabledByFlag, FilterStatusFallbackMissingUser, FilterStatusFallbackNoBuckets, FilterStatusFallbackTkdistError, FilterStatusFallbackTkdistSkew, FilterStatusInternalBypass, FilterStatusOK, FilterStatusUnknown, HTTPError, IdempotencyKeyHeader, InMemoryTokenStore, LocalStorageTokenStore, ModelNotFoundError, NetworkError, OAuthTokenEndpointError, OpenAIAdapter, OrderTerminalError, ProductFamilyEnum, ProviderFormat, RETRY_ADVICE_REASONS, RateLimitError, RegionScopeEnum, ScopeAI, ScopeAccount, ScopeChatBridge, ScopeChatBridgeRead, ScopeChatBridgeRotate, ScopeChatBridgeWrite, ScopeComplianceContractSigningRead, ScopeComplianceContractSigningWrite, ScopeComplianceContractTemplateRead, ScopeComplianceContractTemplateWrite, ScopeComplianceEvidenceRead, ScopeComplianceEvidenceWrite, ScopeComplianceReportsPublish, ScopeComplianceReportsRead, ScopeComplianceReportsWrite, ScopeComplianceSealApprovalApprove, ScopeComplianceSealApprovalRequest, ScopeComplianceSealManage, ScopeComplianceSealUseExecute, ScopeComplianceTimestampIssue, ScopeComplianceTimestampVerify, ScopeEntitlements, ScopeModels, ScopeModelsChat, ScopeProfile, ScopeRemoteControl, ScopeRemoteControlAgentRun, ScopeRemoteControlPermissionResponse, ScopeRemoteControlSessionControl, ScopeSkillStore, ScopeSkills, ScopeTokenPackages, ScopeTools, ScopeToolsExecute, ScopeWallet, ScopeWalletReadonly, ServerToolTypeWebSearch, StreamError, ThinkingHigh, ThinkingHighMinMaxTokens, ThinkingMax, ThinkingMaxFallbackMaxTokens, ThinkingOff, allScopes, anthropicResponseTextContent, anthropicResponseThinkingContent, anthropicResponseToolUseBlocks, apiResponseBusinessError, apiResponseGetMessage, asCredentialRef, authorize, bucketInfoIsCommercial, bucketRowIsCommercial, buildBetas, chatBridgeScopes, classifyComplianceError, commerceScopes, completeWebAuthorizationRequest, complianceErrorToRetryAdvice, complianceScopes, computeBackoff, createWebAuthorizationRequest, defaultRetryable, defaultSafeToRetry, discover, discoverWebOAuthMetadata, discoverWithProfile, effectivePolicy, exchangeCode, extractAnthropicBlockMeta, fileLockDefaults, findDesktopVisualUnderstandingModel, findFirstModelByInputModality, generateState, getAdapter, getAdapterForModel, getWindowLimitStreamDetails, isBillingConfirmable, isChannelInboundEvent, isComplianceBusinessError, isComplianceTerminalError, isContinuableWindowLimitError, isIntegrationStatus, isInvalidGrantError, isPlatform, isRegion, isSSECommentLine, isSSLError, isTerminalRemoteEvent, isValidTokenSet, isWindowLimitError, isWindowLimitStreamError, maxEndUserIdLength, modelScopes, modelSupportsImageInput, modelSupportsInputModality, newFileTokenStore, newThinkingConfig, newTokenSet, newWebSearchTool, normalizeGatewayBaseURL, normalizeOverrideBaseURL, parseNotificationEvent, parseRemoteControlEvent, parseSettlement, parseSourcesEvent, refreshToken, register, registerWebOAuthClient, remoteControlScopes, retryReasonForComplianceKey, retryReasonForOAuthError, revokeToken, sanitize_exports as sanitize, skillScopes, tokenSetIsExpired, uniqueMerge, validateEndUserId };
7731
+ export { AGENT_RUN_META_TITLE, AGENT_RUN_META_WORKSPACE, ALL_INTEGRATION_STATUS, ALL_PLATFORMS, ALL_REGIONS, AgentRunStreamError, AgentRunsClient, AnthropicAdapter, AudienceEnum, BillingModeEnum, BucketClassCommercial, BucketClassGeneric, BusinessError, ChatBridgeClient, Client, ComplianceClient, CompliancePollError, CrabCodeByokClient, DEFAULT_API_TIMEOUT_MS, DEFAULT_GATEWAY_BASE_URL, LocalStorageTokenStore as DefaultBrowserTokenStore, DefaultRetryPolicy, ErrAuthDenied, ErrBillingCallbackCannotCommit, ErrBillingCommitRequiresLocalVerify, ErrBillingS2sForbidden, ErrBrowserOpen, ErrComplianceStepUpRequired, ErrDiscovery, ErrEnvelopeGateClosed, ErrOAuthCORSBlocked, ErrProviderNotConfigured, ErrProviderUnknownNoRetry, ErrRefreshProxyFailed, ErrRegistration, ErrSSLProxy, ErrSealApprovalContractHashMismatch, ErrSealApprovalExpired, ErrSealApprovalLocationMismatch, ErrSealApprovalNonceUsed, ErrSealApprovalNotApproved, ErrSealApprovalSealMismatch, ErrSealApprovalTransactorMismatch, ErrSealUseAlreadyConsumed, ErrStateMismatch, ErrTimeout, ErrTokenExchange, ErrTokenExpired, EventAuthURL, EventComplete, EventError, FileTokenStore, FilterStatusAdminBypass, FilterStatusDisabledByFlag, FilterStatusFallbackMissingUser, FilterStatusFallbackNoBuckets, FilterStatusFallbackTkdistError, FilterStatusFallbackTkdistSkew, FilterStatusInternalBypass, FilterStatusOK, FilterStatusUnknown, HTTPError, IdempotencyKeyHeader, InMemoryTokenStore, LocalStorageTokenStore, ModelNotFoundError, NetworkError, OAuthTokenEndpointError, OpenAIAdapter, OrderTerminalError, ProductFamilyEnum, ProviderFormat, RETRY_ADVICE_REASONS, RateLimitError, RegionScopeEnum, ScopeAI, ScopeAccount, ScopeChatBridge, ScopeChatBridgeRead, ScopeChatBridgeRotate, ScopeChatBridgeWrite, ScopeComplianceContractSigningRead, ScopeComplianceContractSigningWrite, ScopeComplianceContractTemplateRead, ScopeComplianceContractTemplateWrite, ScopeComplianceEvidenceRead, ScopeComplianceEvidenceWrite, ScopeComplianceReportsPublish, ScopeComplianceReportsRead, ScopeComplianceReportsWrite, ScopeComplianceSealApprovalApprove, ScopeComplianceSealApprovalRequest, ScopeComplianceSealManage, ScopeComplianceSealUseExecute, ScopeComplianceTimestampIssue, ScopeComplianceTimestampVerify, ScopeEntitlements, ScopeModels, ScopeModelsChat, ScopeProfile, ScopeRemoteControl, ScopeRemoteControlAgentRun, ScopeRemoteControlPermissionResponse, ScopeRemoteControlSessionControl, ScopeSkillStore, ScopeSkills, ScopeTokenPackages, ScopeTools, ScopeToolsExecute, ScopeWallet, ScopeWalletReadonly, ServerToolTypeWebSearch, StreamError, ThinkingHigh, ThinkingHighMinMaxTokens, ThinkingMax, ThinkingMaxFallbackMaxTokens, ThinkingOff, allScopes, anthropicResponseTextContent, anthropicResponseThinkingContent, anthropicResponseToolUseBlocks, apiResponseBusinessError, apiResponseGetMessage, asCredentialRef, authorize, bucketInfoIsCommercial, bucketRowIsCommercial, buildBetas, chatBridgeScopes, classifyComplianceError, classifySourcesEvent, commerceScopes, completeWebAuthorizationRequest, complianceErrorToRetryAdvice, complianceScopes, computeBackoff, createWebAuthorizationRequest, defaultRetryable, defaultSafeToRetry, discover, discoverWebOAuthMetadata, discoverWithProfile, effectivePolicy, exchangeCode, extractAnthropicBlockMeta, fileLockDefaults, findDesktopVisualUnderstandingModel, findFirstModelByInputModality, generateState, getAdapter, getAdapterForModel, getWindowLimitStreamDetails, isBillingConfirmable, isChannelInboundEvent, isComplianceBusinessError, isComplianceTerminalError, isContinuableWindowLimitError, isIntegrationStatus, isInvalidGrantError, isPlatform, isRegion, isSSECommentLine, isSSLError, isTerminalRemoteEvent, isValidTokenSet, isWindowLimitError, isWindowLimitStreamError, maxEndUserIdLength, modelScopes, modelSupportsImageInput, modelSupportsInputModality, newFileTokenStore, newThinkingConfig, newTokenSet, newWebSearchTool, normalizeGatewayBaseURL, normalizeOverrideBaseURL, parseNotificationEvent, parseRemoteControlEvent, parseSettlement, parseSourcesEvent, refreshToken, register, registerWebOAuthClient, remoteControlScopes, retryReasonForComplianceKey, retryReasonForOAuthError, revokeToken, sanitize_exports as sanitize, skillScopes, tokenSetIsExpired, uniqueMerge, validateEndUserId };
7683
7732
  //# sourceMappingURL=index.mjs.map
7684
7733
  //# sourceMappingURL=index.mjs.map