@acosmi/sdk-ts 1.1.0 → 1.2.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 +24 -0
- package/README.md +36 -4
- package/dist/browser/index.mjs +59 -4
- package/dist/browser/index.mjs.map +1 -1
- package/dist/index.mjs +59 -4
- 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 +1 -1
- package/dist/node/adapters/openai.d.ts +1 -1
- package/dist/node/adapters/openai.mjs.map +1 -1
- package/dist/node/{index-BI8EgBXu.d.cts → index-B2Uuh21R.d.cts} +36 -1
- package/dist/node/{index-BI8EgBXu.d.ts → index-B2Uuh21R.d.ts} +36 -1
- package/dist/node/index.cjs +62 -3
- package/dist/node/index.cjs.map +1 -1
- package/dist/node/index.d.cts +46 -3
- package/dist/node/index.d.ts +46 -3
- package/dist/node/index.mjs +59 -4
- package/dist/node/index.mjs.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,30 @@ 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.2.0] — 2026-05-18
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **`ManagedModel.inputModalities`** — 新增可选字段, 类型 `Array<'text' | 'image'>`, 描述模型可接收的用户输入模态; 'image' 表示模型可直接接收 screenshot/image 输入. listModels / listModelsWithStatus 在写缓存与返回前会归一化上游 snake_case 字段名 `input_modalities` → camelCase `inputModalities` (兼容老网关), camelCase 与 snake_case 同时存在时 camelCase 胜.
|
|
13
|
+
|
|
14
|
+
- **`ModelCapabilities.supports_desktop_visual_understanding`** — 新增可选字段, 标识模型适合作为桌面截图解析 sidecar (输入 screenshot, 输出结构化 UI 描述, 供非多模态主模型消费). 与 `inputModalities=['image']` 是正交两件事: 前者描述"模型能不能吃图", 后者描述"运营是否把该模型标为桌面 UI 解析专用 sidecar". `zeroModelCapabilities()` 显式置 `false`, 避免 `undefined` 导致调用方误判.
|
|
15
|
+
|
|
16
|
+
- **`InputModality`** 类型导出 — `'text' | 'image'`.
|
|
17
|
+
|
|
18
|
+
- **Model catalog helpers (4 个)** — CrabCode desktop automation / computer-use 选模型用, 严格按 SDK 字段, 禁止模型名 substring 推断:
|
|
19
|
+
- `modelSupportsInputModality(model, modality): boolean`
|
|
20
|
+
- `modelSupportsImageInput(model): boolean`
|
|
21
|
+
- `findFirstModelByInputModality(models, modality): ManagedModel | null` — 按 catalog 顺序, 跳过 `isEnabled === false`
|
|
22
|
+
- `findDesktopVisualUnderstandingModel(models): ManagedModel | null` — 选择规则: isEnabled !== false + capabilities.supports_desktop_visual_understanding === true + inputModalities 含 'image' + isDefault 优先 / 否则 catalog 顺序第一个
|
|
23
|
+
|
|
24
|
+
### Notes
|
|
25
|
+
|
|
26
|
+
- 上游 `ManagedModel` 缺失 `inputModalities` 时, SDK 保留 `undefined` 不自动补 `['text']` — 调用方必须保守按 text-only / unknown 处理, 严禁默认假设支持 image.
|
|
27
|
+
- 客户端不应硬编码模型名, 应完全依赖 SDK catalog 能力字段做模型选择.
|
|
28
|
+
- 23 新单测全绿 (8 listModels 归一化 + 15 helpers); 全量 79/79 passed, typecheck/lint/build clean.
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
8
32
|
## [1.1.0] — 2026-05-06
|
|
9
33
|
|
|
10
34
|
### Added
|
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.
|
|
11
|
-
- 测试:
|
|
12
|
-
- 包链接:[npm](https://www.npmjs.com/package/@acosmi/sdk-ts/v/1.
|
|
10
|
+
- 当前版本:**1.2.0**(新增 `ManagedModel.inputModalities` + `ModelCapabilities.supports_desktop_visual_understanding` + 4 catalog helpers,供 CrabCode desktop automation / computer-use 选模型用;详见 [CHANGELOG](./CHANGELOG.md))
|
|
11
|
+
- 测试:79/79 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.2.0) · [tarball](https://registry.npmjs.org/@acosmi/sdk-ts/-/sdk-ts-1.2.0.tgz) · [GitHub Release](https://github.com/acosmi/sdk-ts/releases/tag/v1.2.0)
|
|
13
13
|
|
|
14
14
|
## 安装
|
|
15
15
|
|
|
@@ -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` |
|
|
@@ -230,6 +230,38 @@ const resp = await client.chat('claude-opus-4-7', {
|
|
|
230
230
|
|
|
231
231
|
`AllowedDomains` / `BlockedDomains` 互斥,同时传入抛 `Error`。
|
|
232
232
|
|
|
233
|
+
### 示例:桌面视觉理解 sidecar 选模型(CrabCode desktop automation / computer-use)
|
|
234
|
+
|
|
235
|
+
```ts
|
|
236
|
+
import {
|
|
237
|
+
Client,
|
|
238
|
+
findDesktopVisualUnderstandingModel,
|
|
239
|
+
modelSupportsImageInput,
|
|
240
|
+
} from '@acosmi/sdk-ts';
|
|
241
|
+
|
|
242
|
+
const client = new Client({ serverURL: 'https://acosmi.com' });
|
|
243
|
+
const models = await client.listModels();
|
|
244
|
+
|
|
245
|
+
// 1) 主模型是否能直接吃截图?
|
|
246
|
+
const primaryCanSeeImages = modelSupportsImageInput(
|
|
247
|
+
models.find((m) => m.modelId === 'deepseek-v4') ?? null,
|
|
248
|
+
);
|
|
249
|
+
|
|
250
|
+
// 2) 不能 → 走桌面视觉 sidecar:截图先送 sidecar 解析为结构化 UI 描述,再喂主模型
|
|
251
|
+
const sidecar = findDesktopVisualUnderstandingModel(models);
|
|
252
|
+
if (!sidecar) {
|
|
253
|
+
throw new Error('No desktop visual understanding model available — 让管理员在网关启用一个 sidecar 模型');
|
|
254
|
+
}
|
|
255
|
+
console.log('sidecar →', sidecar.modelId);
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
红线:
|
|
259
|
+
|
|
260
|
+
- `ManagedModel.inputModalities` 用于客户端判断模型可接收的用户输入类型('text' | 'image')。
|
|
261
|
+
- `capabilities.supports_desktop_visual_understanding` 用于选择专门解析桌面截图的视觉 sidecar 模型,与 `inputModalities` 是正交两件事(普通视觉模型不一定擅长 UI 解析)。
|
|
262
|
+
- 客户端不应硬编码模型名做能力推断,应完全依赖 SDK catalog 字段。
|
|
263
|
+
- 上游未下发 `inputModalities` 时 SDK 保持 `undefined`,调用方必须保守按 text-only / unknown 处理。
|
|
264
|
+
|
|
233
265
|
### 示例:钱包 + 余额 + 流量包购买
|
|
234
266
|
|
|
235
267
|
```ts
|
package/dist/browser/index.mjs
CHANGED
|
@@ -1013,6 +1013,45 @@ var init_adapters = __esm({
|
|
|
1013
1013
|
|
|
1014
1014
|
// src/index.ts
|
|
1015
1015
|
init_types();
|
|
1016
|
+
|
|
1017
|
+
// src/model-helpers.ts
|
|
1018
|
+
function modelSupportsInputModality(model, modality) {
|
|
1019
|
+
if (!model) return false;
|
|
1020
|
+
const mods = model.inputModalities;
|
|
1021
|
+
if (!Array.isArray(mods)) return false;
|
|
1022
|
+
return mods.includes(modality);
|
|
1023
|
+
}
|
|
1024
|
+
function modelSupportsImageInput(model) {
|
|
1025
|
+
return modelSupportsInputModality(model, "image");
|
|
1026
|
+
}
|
|
1027
|
+
function findFirstModelByInputModality(models, modality) {
|
|
1028
|
+
if (!Array.isArray(models)) return null;
|
|
1029
|
+
for (const m of models) {
|
|
1030
|
+
if (!m) continue;
|
|
1031
|
+
if (m.isEnabled === false) continue;
|
|
1032
|
+
if (!modelSupportsInputModality(m, modality)) continue;
|
|
1033
|
+
return m;
|
|
1034
|
+
}
|
|
1035
|
+
return null;
|
|
1036
|
+
}
|
|
1037
|
+
function findDesktopVisualUnderstandingModel(models) {
|
|
1038
|
+
if (!Array.isArray(models)) return null;
|
|
1039
|
+
const candidates = [];
|
|
1040
|
+
for (const m of models) {
|
|
1041
|
+
if (!m) continue;
|
|
1042
|
+
if (m.isEnabled === false) continue;
|
|
1043
|
+
if (m.capabilities?.supports_desktop_visual_understanding !== true) continue;
|
|
1044
|
+
if (!modelSupportsInputModality(m, "image")) continue;
|
|
1045
|
+
candidates.push(m);
|
|
1046
|
+
}
|
|
1047
|
+
if (candidates.length === 0) return null;
|
|
1048
|
+
for (const m of candidates) {
|
|
1049
|
+
if (m.isDefault === true) return m;
|
|
1050
|
+
}
|
|
1051
|
+
return candidates[0];
|
|
1052
|
+
}
|
|
1053
|
+
|
|
1054
|
+
// src/index.ts
|
|
1016
1055
|
init_adapters();
|
|
1017
1056
|
|
|
1018
1057
|
// src/auth.ts
|
|
@@ -2588,14 +2627,15 @@ var Client = class _Client {
|
|
|
2588
2627
|
null,
|
|
2589
2628
|
signal
|
|
2590
2629
|
);
|
|
2591
|
-
|
|
2630
|
+
const normalized = normalizeInputModalities(result.data);
|
|
2631
|
+
this.modelCache = normalized;
|
|
2592
2632
|
this.modelCacheTimeMs = Date.now();
|
|
2593
2633
|
let status = "";
|
|
2594
2634
|
if (headers) {
|
|
2595
2635
|
const h = headers.get("X-Entitlement-Filter-Status");
|
|
2596
2636
|
if (h) status = h;
|
|
2597
2637
|
}
|
|
2598
|
-
return { models:
|
|
2638
|
+
return { models: normalized, status };
|
|
2599
2639
|
}
|
|
2600
2640
|
/** 查询当前用户账户级权益总览 (v0.19+) */
|
|
2601
2641
|
async getQuotaSummary(signal) {
|
|
@@ -3228,9 +3268,24 @@ function zeroModelCapabilities() {
|
|
|
3228
3268
|
supports_token_efficient: false,
|
|
3229
3269
|
supports_redact_thinking: false,
|
|
3230
3270
|
max_input_tokens: 0,
|
|
3231
|
-
max_output_tokens: 0
|
|
3271
|
+
max_output_tokens: 0,
|
|
3272
|
+
supports_desktop_visual_understanding: false
|
|
3232
3273
|
};
|
|
3233
3274
|
}
|
|
3275
|
+
function normalizeInputModalities(models) {
|
|
3276
|
+
if (!Array.isArray(models)) return models;
|
|
3277
|
+
for (const m of models) {
|
|
3278
|
+
if (!m || typeof m !== "object") continue;
|
|
3279
|
+
if (Array.isArray(m.inputModalities)) continue;
|
|
3280
|
+
const snake = m.input_modalities;
|
|
3281
|
+
if (Array.isArray(snake)) {
|
|
3282
|
+
m.inputModalities = snake.filter(
|
|
3283
|
+
(v) => v === "text" || v === "image"
|
|
3284
|
+
);
|
|
3285
|
+
}
|
|
3286
|
+
}
|
|
3287
|
+
return models;
|
|
3288
|
+
}
|
|
3234
3289
|
function withRequestTimeout(ms, parent) {
|
|
3235
3290
|
const ctl = new AbortController();
|
|
3236
3291
|
const timer = setTimeout(() => ctl.abort(), ms);
|
|
@@ -4576,6 +4631,6 @@ Client.prototype.getBugReport = async function(bugID, signal) {
|
|
|
4576
4631
|
return resp.data;
|
|
4577
4632
|
};
|
|
4578
4633
|
|
|
4579
|
-
export { AgentRunStreamError, AgentRunsClient, AnthropicAdapter, BucketClassCommercial, BucketClassGeneric, BusinessError, Client, LocalStorageTokenStore as DefaultBrowserTokenStore, DefaultRetryPolicy, ErrAuthDenied, ErrBrowserOpen, ErrDiscovery, ErrRegistration, ErrSSLProxy, ErrTimeout, ErrTokenExchange, EventAuthURL, EventComplete, EventError, FileTokenStore, FilterStatusAdminBypass, FilterStatusDisabledByFlag, FilterStatusFallbackMissingUser, FilterStatusFallbackNoBuckets, FilterStatusFallbackTkdistError, FilterStatusFallbackTkdistSkew, FilterStatusInternalBypass, FilterStatusOK, FilterStatusUnknown, HTTPError, InMemoryTokenStore, LocalStorageTokenStore, ModelNotFoundError, NetworkError, OpenAIAdapter, OrderTerminalError, ProviderFormat, RateLimitError, ScopeAI, ScopeAccount, ScopeEntitlements, ScopeModels, ScopeModelsChat, ScopeProfile, ScopeSkillStore, ScopeSkills, ScopeTokenPackages, ScopeTools, ScopeToolsExecute, ScopeWallet, ScopeWalletReadonly, ServerToolTypeWebSearch, StreamError, ThinkingHigh, ThinkingHighMinMaxTokens, ThinkingMax, ThinkingMaxFallbackMaxTokens, ThinkingOff, allScopes, anthropicResponseTextContent, anthropicResponseThinkingContent, anthropicResponseToolUseBlocks, apiResponseBusinessError, apiResponseGetMessage, authorize, bucketInfoIsCommercial, bucketRowIsCommercial, buildBetas, commerceScopes, computeBackoff, defaultRetryable, defaultSafeToRetry, discover, effectivePolicy, exchangeCode, extractAnthropicBlockMeta, fileLockDefaults, getAdapter, getAdapterForModel, isSSLError, modelScopes, newFileTokenStore, newThinkingConfig, newTokenSet, newWebSearchTool, parseNotificationEvent, parseSettlement, parseSourcesEvent, refreshToken, register, revokeToken, sanitize_exports as sanitize, skillScopes, tokenSetIsExpired, uniqueMerge };
|
|
4634
|
+
export { AgentRunStreamError, AgentRunsClient, AnthropicAdapter, BucketClassCommercial, BucketClassGeneric, BusinessError, Client, LocalStorageTokenStore as DefaultBrowserTokenStore, DefaultRetryPolicy, ErrAuthDenied, ErrBrowserOpen, ErrDiscovery, ErrRegistration, ErrSSLProxy, ErrTimeout, ErrTokenExchange, EventAuthURL, EventComplete, EventError, FileTokenStore, FilterStatusAdminBypass, FilterStatusDisabledByFlag, FilterStatusFallbackMissingUser, FilterStatusFallbackNoBuckets, FilterStatusFallbackTkdistError, FilterStatusFallbackTkdistSkew, FilterStatusInternalBypass, FilterStatusOK, FilterStatusUnknown, HTTPError, InMemoryTokenStore, LocalStorageTokenStore, ModelNotFoundError, NetworkError, OpenAIAdapter, OrderTerminalError, ProviderFormat, RateLimitError, ScopeAI, ScopeAccount, ScopeEntitlements, ScopeModels, ScopeModelsChat, ScopeProfile, ScopeSkillStore, ScopeSkills, ScopeTokenPackages, ScopeTools, ScopeToolsExecute, ScopeWallet, ScopeWalletReadonly, ServerToolTypeWebSearch, StreamError, ThinkingHigh, ThinkingHighMinMaxTokens, ThinkingMax, ThinkingMaxFallbackMaxTokens, ThinkingOff, allScopes, anthropicResponseTextContent, anthropicResponseThinkingContent, anthropicResponseToolUseBlocks, apiResponseBusinessError, apiResponseGetMessage, authorize, bucketInfoIsCommercial, bucketRowIsCommercial, buildBetas, commerceScopes, computeBackoff, defaultRetryable, defaultSafeToRetry, discover, effectivePolicy, exchangeCode, extractAnthropicBlockMeta, fileLockDefaults, findDesktopVisualUnderstandingModel, findFirstModelByInputModality, getAdapter, getAdapterForModel, isSSLError, modelScopes, modelSupportsImageInput, modelSupportsInputModality, newFileTokenStore, newThinkingConfig, newTokenSet, newWebSearchTool, parseNotificationEvent, parseSettlement, parseSourcesEvent, refreshToken, register, revokeToken, sanitize_exports as sanitize, skillScopes, tokenSetIsExpired, uniqueMerge };
|
|
4580
4635
|
//# sourceMappingURL=index.mjs.map
|
|
4581
4636
|
//# sourceMappingURL=index.mjs.map
|