dsh-opendesign-corouter 0.1.2 → 0.1.4
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 +6 -6
- package/SECURITY.md +3 -2
- package/THIRD_PARTY_NOTICES.md +1 -1
- package/lib/adapter.d.ts +1 -1
- package/lib/auth.d.ts +18 -3
- package/lib/client.d.ts +12 -4
- package/lib/client.js +224 -117
- package/lib/device-auth.d.ts +34 -0
- package/lib/generated/typert.host.js +77 -57
- package/lib/generated/typert.remote-client.js +77 -57
- package/lib/index.d.ts +5 -1
- package/lib/index.js +628 -389
- package/lib/index.js.map +4 -4
- package/lib/login.d.ts +21 -131
- package/lib/model-settings.d.ts +3 -3
- package/lib/quota.d.ts +6 -0
- package/lib/remote.d.ts +4 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -32,7 +32,7 @@ dsh plugin --profile web add dsh-opendesign-corouter
|
|
|
32
32
|
也可打开 [Actions → CI](https://github.com/KouzakiUmi/dsh-opendesign-corouter/actions/workflows/ci.yml),从成功构建下载 **`dsh-opendesign-corouter-build`** artifact。登录 GitHub 后解压 ZIP,取得 `.tgz` 与 `.sha256`,再安装本地包:
|
|
33
33
|
|
|
34
34
|
```console
|
|
35
|
-
dsh plugin --profile web add /absolute/path/to/dsh-opendesign-corouter-0.1.
|
|
35
|
+
dsh plugin --profile web add /absolute/path/to/dsh-opendesign-corouter-0.1.4.tgz
|
|
36
36
|
```
|
|
37
37
|
|
|
38
38
|
`web` 只是示例,请替换为目标 Profile。Desktop 使用桌面安装器提供的 `dsh` 入口;独立公共 CLI 不能代管保留的 `desktop` Profile。安装后的启用与重载按目标 DSH 的管理流程进行。
|
|
@@ -40,11 +40,11 @@ dsh plugin --profile web add /absolute/path/to/dsh-opendesign-corouter-0.1.2.tgz
|
|
|
40
40
|
### 2. 配置连接
|
|
41
41
|
|
|
42
42
|
1. 打开 **设置 → OpenDesign CoRouter → 连接与登录**。
|
|
43
|
-
2.
|
|
44
|
-
3.
|
|
43
|
+
2. 点击 **开始设备授权**,再用常用浏览器 **打开授权页**,核对授权码并确认;也可单独配置工作空间 API Key 或沿用 `COROUTER_API_KEY`。
|
|
44
|
+
3. 返回设置页等待保存成功。额度默认优先读取桌面登录态;要明确使用设备授权的账号,可关闭桌面优先。
|
|
45
45
|
4. 回到模型选择器,选择 **OpenDesign CoRouter · 套餐赠送** 或 **OpenDesign CoRouter · 付费模型**。
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
**设备授权同时取得查额度和官方网关推理的两类令牌;显式配置的 API Key 仍优先。** [完整连接说明](docs/usage.md)
|
|
48
48
|
|
|
49
49
|
## 功能预览
|
|
50
50
|
|
|
@@ -72,7 +72,7 @@ dsh plugin --profile web add /absolute/path/to/dsh-opendesign-corouter-0.1.2.tgz
|
|
|
72
72
|
|
|
73
73
|
### 桌面优先,也能独立登录
|
|
74
74
|
|
|
75
|
-
|
|
75
|
+
独立登录采用设备授权,在常用浏览器打开普通官方授权页,沿用现有配置、密码管理器和自动填充。确认后设备令牌保存到 DSH 凭据服务;取消、超时和卸载停止轮询,不关闭用户浏览器,也不修改桌面配置。
|
|
76
76
|
|
|
77
77
|
<picture>
|
|
78
78
|
<source media="(prefers-color-scheme: dark)" srcset="docs/previews/theme-dark.png">
|
|
@@ -98,7 +98,7 @@ dsh plugin --profile web add /absolute/path/to/dsh-opendesign-corouter-0.1.2.tgz
|
|
|
98
98
|
| 目标 DSH Core | `0.2.1-rc.3`,以官方同版本发布包验证 |
|
|
99
99
|
| Core 声明范围 | `>=0.2.1-rc.3 <0.3.0-0`,范围内其他版本不代表已实测 |
|
|
100
100
|
| Node.js | `>=24.9.0` |
|
|
101
|
-
| 独立登录 |
|
|
101
|
+
| 独立登录 | 能访问官方授权页的常用浏览器;无需浏览器自动化或扩展 |
|
|
102
102
|
| 默认推理接口 | `https://amr-link.open-design.ai/v1/chat/completions` |
|
|
103
103
|
|
|
104
104
|
CI 在 Windows 与 Ubuntu 执行构建、类型检查及隔离测试;Ubuntu 另执行四页签浏览器和亮暗主题检查。通过 CI 不等于已安装或已通过真实账号验收。[开发与验证范围](docs/development.md)
|
package/SECURITY.md
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
# 安全边界
|
|
2
2
|
|
|
3
3
|
- 推理、桌面控制面和控制台 Cookie 分属独立通道,不互相替代鉴权材料。
|
|
4
|
-
- API Key
|
|
4
|
+
- API Key 与设备授权的 controlKey / runtimeKey 仅经 DSH 凭据服务写入插件专属记录;设置页只读取存在性和状态,不回填秘密。
|
|
5
5
|
- 桌面配置只读。仅支持已核实的生产环境,控制令牌只能发送到 `https://amr-api.open-design.ai`。控制台和推理请求禁止自动跟随重定向。
|
|
6
|
+
- 设备授权双令牌原子保存;runtimeKey 只自动提供给请求快照中的官方推理 origin,controlKey 只发往官方控制面。旧 Cookie grant 保留只读兼容。
|
|
6
7
|
- 推理自定义地址由用户显式配置;除本机回环外要求 HTTPS,拒绝 URL 内嵌凭据、查询串与片段。
|
|
7
8
|
- 额度分池不跨身份混合。桌面认证失效时,可回退到单独保存的控制台登录;权限不足和未知额度不伪装成 0。
|
|
8
|
-
-
|
|
9
|
+
- 独立登录使用设备授权,普通浏览器仅打开官方激活页;插件不启动浏览器自动化、不读取浏览器配置或 Cookie。deviceSecret 只在 Host 内存用于轮询;授权码、激活链接和到期时间仅在等待期提供给 UI。取消、超时和卸载中止请求,不关闭用户浏览器。持久化成功是不可撤回的提交边界,之后取消不会假称已撤回。
|
|
9
10
|
- `OPENDESIGN_VELA_PATH` 是用户信任的本地程序路径。插件仅以固定 argv 执行只读查询,不通过 shell;不校验该程序的签名或下载它。不要将此变量指向来源不明的程序。
|
|
10
11
|
- RPC 使用严格白名单解析;原始错误正文、Cookie、请求头、Key 和桌面本地路径不进入状态返回。并发保存有版本冲突检测。
|
|
11
12
|
- 请求、流空闲、额度接口、CLI、登录和 RPC 均有有界超时。停用插件会撤销 Provider / RPC 并中止自身请求。
|
package/THIRD_PARTY_NOTICES.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# 第三方代码与资料
|
|
2
2
|
|
|
3
|
-
本项目的消息/图片兼容处理、套餐模型元数据参考 [dsh-opendesign-go 0.1.9](https://github.com/EliteOtaku/dsh-opendesign-go)
|
|
3
|
+
本项目的消息/图片兼容处理、套餐模型元数据参考 [dsh-opendesign-go 0.1.9](https://github.com/EliteOtaku/dsh-opendesign-go)。额度归一化及登录生命周期的基础处理改编自 [dsh-subusage 0.16.2](https://github.com/KouzakiUmi/dsh-subusage)。空轮判定参考 [dsh-empty-turn-guard 0.4.0](https://github.com/FYTXY/dsh-empty-turn-guard)。设置布局参考 [dsh-code-pill](https://github.com/KouzakiUmi/dsh-code-pill)。
|
|
4
4
|
|
|
5
5
|
离线主题夹具使用 [DeepSeek Harness 官方主题令牌](https://github.com/deepseek-ai/deepseek-harness/blob/22ddee3792402c3e70ec5f86a63c3e3e895a2f60/packages/client/ui-theme/src/styles/design-platform.css),仅供测试,不随插件安装包分发。
|
|
6
6
|
|
package/lib/adapter.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { type RuntimeConfig } from './config.js';
|
|
|
5
5
|
export interface AdapterOptions {
|
|
6
6
|
config(): RuntimeConfig;
|
|
7
7
|
models?(): readonly CatalogModel[];
|
|
8
|
-
apiKey(ref: string): Promise<string | undefined>;
|
|
8
|
+
apiKey(ref: string, baseURL?: string): Promise<string | undefined>;
|
|
9
9
|
imageDataUrl?(image: ImageAttachmentRef, signal: AbortSignal): Promise<string | undefined>;
|
|
10
10
|
onEmptyTurn?(): void;
|
|
11
11
|
fetch?: typeof fetch;
|
package/lib/auth.d.ts
CHANGED
|
@@ -77,11 +77,22 @@ export interface DesktopDeps {
|
|
|
77
77
|
*/
|
|
78
78
|
export declare function readDesktopCredential(deps?: DesktopDeps): Promise<DesktopRead>;
|
|
79
79
|
/** Cookie payload persisted through the credential seam as a `grant` record. */
|
|
80
|
-
export interface
|
|
80
|
+
export interface CookieLoginGrant {
|
|
81
81
|
cookie: string;
|
|
82
|
-
/**
|
|
82
|
+
/** Legacy cookie expiry only; never applied to device tokens. */
|
|
83
83
|
expiresAt?: number;
|
|
84
84
|
}
|
|
85
|
+
export interface DeviceLoginGrant {
|
|
86
|
+
kind: 'device';
|
|
87
|
+
controlKey: string;
|
|
88
|
+
runtimeKey: string;
|
|
89
|
+
savedAt?: string;
|
|
90
|
+
}
|
|
91
|
+
export type LoginGrant = CookieLoginGrant | DeviceLoginGrant;
|
|
92
|
+
/** Validate both keys as one snapshot; never combine an incomplete grant with another source. */
|
|
93
|
+
export declare function deviceGrant(value: unknown): DeviceLoginGrant | undefined;
|
|
94
|
+
/** Device runtime credentials may only reach this exact HTTPS origin, never a custom gateway. */
|
|
95
|
+
export declare function isOfficialRuntimeUrl(raw: string): boolean;
|
|
85
96
|
export type AuthSource = 'desktop' | 'login' | 'environment';
|
|
86
97
|
export interface AuthSession extends Session {
|
|
87
98
|
source: SessionSource;
|
|
@@ -112,11 +123,15 @@ export interface AuthDeps extends DesktopDeps {
|
|
|
112
123
|
}
|
|
113
124
|
/** Desktop `controlKey` as a Bearer header (daemon evidence: `/api/v1/wallet/balance`). */
|
|
114
125
|
export declare function desktopSession(credential: DesktopCredential, apiUrl?: string): AuthSession;
|
|
126
|
+
/** Device control token: Bearer on the official control plane only. No inferred token expiry. */
|
|
127
|
+
export declare function deviceSession(tokens: {
|
|
128
|
+
controlKey: string;
|
|
129
|
+
} | string): AuthSession;
|
|
115
130
|
/** A persisted or environment-supplied console cookie as a `cookie` header. */
|
|
116
131
|
export declare function cookieSession(cookie: string, source: SessionSource, apiUrl?: string): AuthSession | undefined;
|
|
117
132
|
/**
|
|
118
133
|
* Resolve the session in the order the user asked for: **desktop first**, then the
|
|
119
|
-
*
|
|
134
|
+
* device grant saved by this plugin, then legacy cookies and environment references.
|
|
120
135
|
*
|
|
121
136
|
* A desktop config whose `apiUrl` is not an official origin is *skipped*, not used: the
|
|
122
137
|
* token must not travel to a host the plugin cannot vouch for. The skip is reported as a
|
package/lib/client.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import openDesignCoRouterRemote, { type CoRouterRemote } from './generated/typert.remote-client.js';
|
|
3
3
|
import type { TypertClientRemote } from '@deepseek-ai/dsh-typert-protocol';
|
|
4
|
-
import { type Status, type StatusModel } from './remote.js';
|
|
4
|
+
import { type LoginState, type Status, type StatusModel } from './remote.js';
|
|
5
5
|
import type { QuotaSnapshot, QuotaWindow } from './quota.js';
|
|
6
6
|
import { type ApiProtocol } from './protocol-options.js';
|
|
7
7
|
import type { ModelSettings, ModelSettingsMap } from './model-settings.js';
|
|
@@ -145,8 +145,9 @@ export interface OverviewProps {
|
|
|
145
145
|
onRefresh: () => void;
|
|
146
146
|
nextAutoRefreshAt?: string | undefined;
|
|
147
147
|
refreshIntervalSeconds?: number | undefined;
|
|
148
|
+
onConnection?: (() => void) | undefined;
|
|
148
149
|
}
|
|
149
|
-
export declare function Overview({ status, busy, onRefresh, nextAutoRefreshAt, refreshIntervalSeconds }: OverviewProps): React.FunctionComponentElement<{
|
|
150
|
+
export declare function Overview({ status, busy, onRefresh, nextAutoRefreshAt, refreshIntervalSeconds, onConnection }: OverviewProps): React.FunctionComponentElement<{
|
|
150
151
|
children?: React.ReactNode | undefined;
|
|
151
152
|
}>;
|
|
152
153
|
export interface ModelRowProps {
|
|
@@ -165,7 +166,7 @@ export interface ModelsProps {
|
|
|
165
166
|
status: Status | undefined;
|
|
166
167
|
formSnapshot: FormSnapshot;
|
|
167
168
|
setFormField: (field: string, value: unknown) => Promise<boolean>;
|
|
168
|
-
pendingField: string
|
|
169
|
+
pendingField: readonly string[];
|
|
169
170
|
onRefreshModels: () => void;
|
|
170
171
|
refreshingModels: boolean;
|
|
171
172
|
notice: Notice | null;
|
|
@@ -177,11 +178,18 @@ export interface AdvancedProps {
|
|
|
177
178
|
status: Status | undefined;
|
|
178
179
|
formSnapshot: FormSnapshot;
|
|
179
180
|
setFormField: (field: string, value: unknown) => Promise<boolean>;
|
|
180
|
-
pendingField: string
|
|
181
|
+
pendingField: readonly string[];
|
|
181
182
|
}
|
|
182
183
|
export declare function Advanced({ status, formSnapshot, setFormField, pendingField }: AdvancedProps): React.FunctionComponentElement<{
|
|
183
184
|
children?: React.ReactNode | undefined;
|
|
184
185
|
}>;
|
|
186
|
+
/** Approval opens through an ordinary link; no browser profile is created or controlled. */
|
|
187
|
+
export declare function LoginApproval({ login }: {
|
|
188
|
+
login: LoginState | undefined;
|
|
189
|
+
}): React.DetailedReactHTMLElement<{
|
|
190
|
+
className: string;
|
|
191
|
+
'aria-label': string;
|
|
192
|
+
}, HTMLElement> | null;
|
|
185
193
|
export declare function tabAfter(current: TabId, key: string): TabId | undefined;
|
|
186
194
|
export declare function SettingsPage({ caller, form }: SettingsProps): React.DetailedReactHTMLElement<{
|
|
187
195
|
className: string;
|