dsh-llm-adapters 1.2.0 → 1.2.2
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/DEVELOPMENT.md +92 -24
- package/FAQ.md +47 -10
- package/README.md +39 -25
- package/client.js +1802 -1733
- package/lib/index.js +733 -302
- package/lib/types/account-store.d.ts +17 -8
- package/lib/types/adapter.d.ts +8 -2
- package/lib/types/auth.d.ts +24 -11
- package/lib/types/codearts-oauth.d.ts +19 -0
- package/lib/types/codearts.d.ts +1 -5
- package/lib/types/config.d.ts +0 -5
- package/lib/types/index.d.ts +5 -6
- package/lib/types/raccoon.d.ts +79 -6
- package/lib/types/trae-client.d.ts +52 -0
- package/lib/types/trae-endpoints.d.ts +2 -0
- package/lib/types/trae-login.d.ts +5 -3
- package/lib/types/trae.d.ts +29 -3
- package/lib/types/types.d.ts +19 -1
- package/package.json +3 -2
- package/src/account-store.ts +20 -8
- package/src/adapter.ts +31 -3
- package/src/api.ts +15 -3
- package/src/auth.ts +62 -17
- package/src/codearts-oauth.ts +36 -5
- package/src/codearts.ts +24 -29
- package/src/config.ts +258 -264
- package/src/index.ts +6 -29
- package/src/raccoon.ts +163 -50
- package/src/trae-client.ts +312 -0
- package/src/trae-endpoints.ts +4 -0
- package/src/trae-login.ts +5 -3
- package/src/trae.ts +191 -3
- package/src/types.ts +20 -1
- package/lib/types/codearts-window.d.ts +0 -65
- package/src/codearts-window.ts +0 -136
package/src/config.ts
CHANGED
|
@@ -1,264 +1,258 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The plugin's configuration surface.
|
|
3
|
-
*
|
|
4
|
-
* DSH renders this schema in the generated part of the settings UI and, more
|
|
5
|
-
* importantly, treats every `.volatile()` field as an in-place edit: changing
|
|
6
|
-
* it must never restart the plugin. The adapters therefore read values through
|
|
7
|
-
* thunks from {@link liveConfig}.
|
|
8
|
-
*
|
|
9
|
-
* @module dsh-llm-adapters/config
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
import { isVolatile } from '@deepseek-ai/cosmokit'
|
|
13
|
-
import z from '@deepseek-ai/schemastery'
|
|
14
|
-
import type { TraeRegion } from './brand.ts'
|
|
15
|
-
import { normalizeTraeRegion } from './brand.ts'
|
|
16
|
-
|
|
17
|
-
export interface Config {
|
|
18
|
-
loomyEnabled?: boolean
|
|
19
|
-
raccoonEnabled?: boolean
|
|
20
|
-
traeEnabled?: boolean
|
|
21
|
-
traeRegion?: string
|
|
22
|
-
codeartsEnabled?: boolean
|
|
23
|
-
loomyDisplayName?: string
|
|
24
|
-
raccoonDisplayName?: string
|
|
25
|
-
traeDisplayName?: string
|
|
26
|
-
codeartsDisplayName?: string
|
|
27
|
-
loomyDisabledModels?: string[]
|
|
28
|
-
raccoonDisabledModels?: string[]
|
|
29
|
-
traeDisabledModels?: string[]
|
|
30
|
-
codeartsDisabledModels?: string[]
|
|
31
|
-
loomyModelContextWindows?: Record<string, number>
|
|
32
|
-
raccoonModelContextWindows?: Record<string, number>
|
|
33
|
-
traeModelContextWindows?: Record<string, number>
|
|
34
|
-
codeartsModelContextWindows?: Record<string, number>
|
|
35
|
-
loomyModelAliases?: Record<string, string>
|
|
36
|
-
raccoonModelAliases?: Record<string, string>
|
|
37
|
-
traeModelAliases?: Record<string, string>
|
|
38
|
-
codeartsModelAliases?: Record<string, string>
|
|
39
|
-
loomyVisionModelIds?: string[]
|
|
40
|
-
loomyTextOnlyModelIds?: string[]
|
|
41
|
-
raccoonVisionModelIds?: string[]
|
|
42
|
-
raccoonTextOnlyModelIds?: string[]
|
|
43
|
-
traeVisionModelIds?: string[]
|
|
44
|
-
traeTextOnlyModelIds?: string[]
|
|
45
|
-
codeartsVisionModelIds?: string[]
|
|
46
|
-
codeartsTextOnlyModelIds?: string[]
|
|
47
|
-
defaultMaxTokens?: number
|
|
48
|
-
modelCacheTtlSeconds?: number
|
|
49
|
-
catalogFetchTimeoutSeconds?: number
|
|
50
|
-
/** Minutes between automatic OpenRouter syncs; 0 disables the schedule. */
|
|
51
|
-
openRouterSyncMinutes?: number
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
const out: Record<string, string> = {}
|
|
260
|
-
for (const [key, entry] of Object.entries(value as Record<string, unknown>)) {
|
|
261
|
-
if (typeof entry === 'string' && entry.trim().length > 0) out[key] = entry.trim()
|
|
262
|
-
}
|
|
263
|
-
return out
|
|
264
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* The plugin's configuration surface.
|
|
3
|
+
*
|
|
4
|
+
* DSH renders this schema in the generated part of the settings UI and, more
|
|
5
|
+
* importantly, treats every `.volatile()` field as an in-place edit: changing
|
|
6
|
+
* it must never restart the plugin. The adapters therefore read values through
|
|
7
|
+
* thunks from {@link liveConfig}.
|
|
8
|
+
*
|
|
9
|
+
* @module dsh-llm-adapters/config
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { isVolatile } from '@deepseek-ai/cosmokit'
|
|
13
|
+
import z from '@deepseek-ai/schemastery'
|
|
14
|
+
import type { TraeRegion } from './brand.ts'
|
|
15
|
+
import { normalizeTraeRegion } from './brand.ts'
|
|
16
|
+
|
|
17
|
+
export interface Config {
|
|
18
|
+
loomyEnabled?: boolean
|
|
19
|
+
raccoonEnabled?: boolean
|
|
20
|
+
traeEnabled?: boolean
|
|
21
|
+
traeRegion?: string
|
|
22
|
+
codeartsEnabled?: boolean
|
|
23
|
+
loomyDisplayName?: string
|
|
24
|
+
raccoonDisplayName?: string
|
|
25
|
+
traeDisplayName?: string
|
|
26
|
+
codeartsDisplayName?: string
|
|
27
|
+
loomyDisabledModels?: string[]
|
|
28
|
+
raccoonDisabledModels?: string[]
|
|
29
|
+
traeDisabledModels?: string[]
|
|
30
|
+
codeartsDisabledModels?: string[]
|
|
31
|
+
loomyModelContextWindows?: Record<string, number>
|
|
32
|
+
raccoonModelContextWindows?: Record<string, number>
|
|
33
|
+
traeModelContextWindows?: Record<string, number>
|
|
34
|
+
codeartsModelContextWindows?: Record<string, number>
|
|
35
|
+
loomyModelAliases?: Record<string, string>
|
|
36
|
+
raccoonModelAliases?: Record<string, string>
|
|
37
|
+
traeModelAliases?: Record<string, string>
|
|
38
|
+
codeartsModelAliases?: Record<string, string>
|
|
39
|
+
loomyVisionModelIds?: string[]
|
|
40
|
+
loomyTextOnlyModelIds?: string[]
|
|
41
|
+
raccoonVisionModelIds?: string[]
|
|
42
|
+
raccoonTextOnlyModelIds?: string[]
|
|
43
|
+
traeVisionModelIds?: string[]
|
|
44
|
+
traeTextOnlyModelIds?: string[]
|
|
45
|
+
codeartsVisionModelIds?: string[]
|
|
46
|
+
codeartsTextOnlyModelIds?: string[]
|
|
47
|
+
defaultMaxTokens?: number
|
|
48
|
+
modelCacheTtlSeconds?: number
|
|
49
|
+
catalogFetchTimeoutSeconds?: number
|
|
50
|
+
/** Minutes between automatic OpenRouter syncs; 0 disables the schedule. */
|
|
51
|
+
openRouterSyncMinutes?: number
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export const Config = z.object({
|
|
55
|
+
loomyEnabled: z.boolean().default(true).description('启用 Loomy。关闭后该设置页、模型列表与 provider 路由都会移除;登录态与模型选择会保留。').volatile(),
|
|
56
|
+
raccoonEnabled: z.boolean().default(true).description('启用商汤小浣熊。关闭后该设置页、模型列表与 provider 路由都会移除;登录态与模型选择会保留。').volatile(),
|
|
57
|
+
traeEnabled: z.boolean().default(true).description('启用 Trae。关闭后该设置页、模型列表与 provider 路由都会移除;两个区域的登录态与模型选择会保留。').volatile(),
|
|
58
|
+
traeRegion: z.string().default('cn').description('Trae 登录区域:cn(国内版 trae.cn)或 global(国际版 trae.ai)。两个区域各自保存账号,切换后立即恢复对应账号。').volatile(),
|
|
59
|
+
codeartsEnabled: z.boolean().default(true).description('启用华为云 CodeArts。关闭后该设置页、模型列表与 provider 路由都会移除;登录态与模型选择会保留。').volatile(),
|
|
60
|
+
|
|
61
|
+
loomyDisplayName: z.string().default('Loomy').description('模型选择器里 Loomy 分组的名称。').volatile(),
|
|
62
|
+
raccoonDisplayName: z.string().default('商汤小浣熊').description('模型选择器里小浣熊分组的名称。').volatile(),
|
|
63
|
+
traeDisplayName: z.string().default('Trae').description('模型选择器里 Trae 分组的名称。').volatile(),
|
|
64
|
+
codeartsDisplayName: z.string().default('华为云 CodeArts').description('模型选择器里 CodeArts 分组的名称。').volatile(),
|
|
65
|
+
|
|
66
|
+
loomyDisabledModels: z.array(z.string()).default([]).description('Loomy 已关闭的模型 ID 列表。关闭的模型不会出现在模型选择器里。').volatile(),
|
|
67
|
+
raccoonDisabledModels: z.array(z.string()).default([]).description('小浣熊已关闭的模型 ID 列表。').volatile(),
|
|
68
|
+
traeDisabledModels: z.array(z.string()).default([]).description('Trae 已关闭的模型 ID 列表。').volatile(),
|
|
69
|
+
codeartsDisabledModels: z.array(z.string()).default([]).description('CodeArts 已关闭的模型 ID 列表。').volatile(),
|
|
70
|
+
loomyModelContextWindows: z.dict(z.number()).default({}).description('Loomy 按模型指定上下文窗口(token 数)。未指定的模型使用上游声明的窗口。').volatile(),
|
|
71
|
+
raccoonModelContextWindows: z.dict(z.number()).default({}).description('小浣熊按模型指定上下文窗口(token 数)。').volatile(),
|
|
72
|
+
traeModelContextWindows: z.dict(z.number()).default({}).description('Trae 按模型指定上下文窗口(token 数)。').volatile(),
|
|
73
|
+
codeartsModelContextWindows: z.dict(z.number()).default({}).description('CodeArts 按模型指定上下文窗口(token 数)。上游不下发窗口,默认使用 IDE 配置里的实测值。').volatile(),
|
|
74
|
+
loomyModelAliases: z.dict(z.string()).default({}).description('Loomy 模型别名映射:DSH 侧名称 → 上游模型 ID。').volatile(),
|
|
75
|
+
raccoonModelAliases: z.dict(z.string()).default({}).description('小浣熊模型别名映射:DSH 侧名称 → 上游模型 ID。').volatile(),
|
|
76
|
+
traeModelAliases: z.dict(z.string()).default({}).description('Trae 模型别名映射:DSH 侧名称 → 上游模型 ID。').volatile(),
|
|
77
|
+
codeartsModelAliases: z.dict(z.string()).default({}).description('CodeArts 模型别名映射:DSH 侧名称 → 上游模型 ID。').volatile(),
|
|
78
|
+
|
|
79
|
+
loomyVisionModelIds: z.array(z.string()).default([]).description('Loomy 强制按“能读图”声明的模型 ID,优先级高于目录标签。').volatile(),
|
|
80
|
+
loomyTextOnlyModelIds: z.array(z.string()).default([]).description('Loomy 强制按“纯文本”声明的模型 ID,优先级最高。').volatile(),
|
|
81
|
+
raccoonVisionModelIds: z.array(z.string()).default([]).description('小浣熊强制按“能读图”声明的模型 ID。用于纠正上游标签错误。').volatile(),
|
|
82
|
+
raccoonTextOnlyModelIds: z.array(z.string()).default([]).description('小浣熊强制按“纯文本”声明的模型 ID,优先级最高。').volatile(),
|
|
83
|
+
traeVisionModelIds: z.array(z.string()).default([]).description('Trae 强制按“能读图”声明的模型 ID。目录标注 multimodal 的模型会自动启用。').volatile(),
|
|
84
|
+
traeTextOnlyModelIds: z.array(z.string()).default([]).description('Trae 强制按“纯文本”声明的模型 ID,优先级最高。').volatile(),
|
|
85
|
+
codeartsVisionModelIds: z.array(z.string()).default([]).description('CodeArts 的“强制读图”列表。所有模型都能接收图片(文本模型先由 VL 模型转述,设置页只给原生多模态模型标“读图”);要关掉某个模型的读图能力请用下面的“纯文本”列表。').volatile(),
|
|
86
|
+
codeartsTextOnlyModelIds: z.array(z.string()).default([]).description('CodeArts 强制按“纯文本”声明的模型 ID,优先级最高。').volatile(),
|
|
87
|
+
|
|
88
|
+
defaultMaxTokens: z.number().step(1).min(1).default(32_000).description('模型目录未声明输出上限时使用的输出上限。').volatile(),
|
|
89
|
+
modelCacheTtlSeconds: z.number().step(1).min(10).max(86_400).default(120).description('模型列表缓存时长(秒)。调小可更快看到账号侧变化。').volatile(),
|
|
90
|
+
catalogFetchTimeoutSeconds: z.number().step(1).min(1).max(300).default(20).description('读取模型目录、额度等请求的时限(秒)。').volatile(),
|
|
91
|
+
openRouterSyncMinutes: z.number().step(1).min(0).max(43_200).default(60).description('OpenRouter 模型元数据的自动同步间隔(分钟)。0 表示关闭自动同步;缓存保存在本机,连不上时继续使用上次成功同步的数据。').volatile(),
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
export interface ResolvedConfig {
|
|
95
|
+
loomyEnabled: boolean
|
|
96
|
+
raccoonEnabled: boolean
|
|
97
|
+
traeEnabled: boolean
|
|
98
|
+
traeRegion: TraeRegion
|
|
99
|
+
codeartsEnabled: boolean
|
|
100
|
+
loomyDisplayName: string
|
|
101
|
+
raccoonDisplayName: string
|
|
102
|
+
traeDisplayName: string
|
|
103
|
+
codeartsDisplayName: string
|
|
104
|
+
loomyDisabledModels: readonly string[]
|
|
105
|
+
raccoonDisabledModels: readonly string[]
|
|
106
|
+
traeDisabledModels: readonly string[]
|
|
107
|
+
codeartsDisabledModels: readonly string[]
|
|
108
|
+
loomyModelContextWindows: Readonly<Record<string, number>>
|
|
109
|
+
raccoonModelContextWindows: Readonly<Record<string, number>>
|
|
110
|
+
traeModelContextWindows: Readonly<Record<string, number>>
|
|
111
|
+
codeartsModelContextWindows: Readonly<Record<string, number>>
|
|
112
|
+
loomyModelAliases: Readonly<Record<string, string>>
|
|
113
|
+
raccoonModelAliases: Readonly<Record<string, string>>
|
|
114
|
+
traeModelAliases: Readonly<Record<string, string>>
|
|
115
|
+
codeartsModelAliases: Readonly<Record<string, string>>
|
|
116
|
+
loomyVisionModelIds: readonly string[]
|
|
117
|
+
loomyTextOnlyModelIds: readonly string[]
|
|
118
|
+
raccoonVisionModelIds: readonly string[]
|
|
119
|
+
raccoonTextOnlyModelIds: readonly string[]
|
|
120
|
+
traeVisionModelIds: readonly string[]
|
|
121
|
+
traeTextOnlyModelIds: readonly string[]
|
|
122
|
+
codeartsVisionModelIds: readonly string[]
|
|
123
|
+
codeartsTextOnlyModelIds: readonly string[]
|
|
124
|
+
defaultMaxTokens: number
|
|
125
|
+
modelCacheTtlMs: number
|
|
126
|
+
catalogFetchTimeoutMs: number
|
|
127
|
+
openRouterSyncMinutes: number
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export type ParsedConfig = { readonly [K in keyof Config]?: unknown }
|
|
131
|
+
export type LiveConfig = { readonly [K in keyof ResolvedConfig]: () => ResolvedConfig[K] }
|
|
132
|
+
|
|
133
|
+
export function liveConfig(config: ParsedConfig | undefined): LiveConfig {
|
|
134
|
+
const source = (config ?? {}) as Record<string, unknown>
|
|
135
|
+
const field = (key: keyof Config): unknown => {
|
|
136
|
+
const value = source[key]
|
|
137
|
+
return isVolatile(value) ? value.get() : value
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return {
|
|
141
|
+
loomyEnabled: () => bool(field('loomyEnabled'), true),
|
|
142
|
+
raccoonEnabled: () => bool(field('raccoonEnabled'), true),
|
|
143
|
+
traeEnabled: () => bool(field('traeEnabled'), true),
|
|
144
|
+
traeRegion: () => normalizeTraeRegion(field('traeRegion')),
|
|
145
|
+
codeartsEnabled: () => bool(field('codeartsEnabled'), true),
|
|
146
|
+
loomyDisplayName: () => nonEmpty(field('loomyDisplayName'), 'Loomy'),
|
|
147
|
+
raccoonDisplayName: () => nonEmpty(field('raccoonDisplayName'), '商汤小浣熊'),
|
|
148
|
+
traeDisplayName: () => nonEmpty(field('traeDisplayName'), 'Trae'),
|
|
149
|
+
codeartsDisplayName: () => nonEmpty(field('codeartsDisplayName'), '华为云 CodeArts'),
|
|
150
|
+
loomyDisabledModels: () => stringList(field('loomyDisabledModels')),
|
|
151
|
+
raccoonDisabledModels: () => stringList(field('raccoonDisabledModels')),
|
|
152
|
+
traeDisabledModels: () => stringList(field('traeDisabledModels')),
|
|
153
|
+
codeartsDisabledModels: () => stringList(field('codeartsDisabledModels')),
|
|
154
|
+
loomyModelContextWindows: () => numberMap(field('loomyModelContextWindows')),
|
|
155
|
+
raccoonModelContextWindows: () => numberMap(field('raccoonModelContextWindows')),
|
|
156
|
+
traeModelContextWindows: () => numberMap(field('traeModelContextWindows')),
|
|
157
|
+
codeartsModelContextWindows: () => numberMap(field('codeartsModelContextWindows')),
|
|
158
|
+
loomyModelAliases: () => stringMap(field('loomyModelAliases')),
|
|
159
|
+
raccoonModelAliases: () => stringMap(field('raccoonModelAliases')),
|
|
160
|
+
traeModelAliases: () => stringMap(field('traeModelAliases')),
|
|
161
|
+
codeartsModelAliases: () => stringMap(field('codeartsModelAliases')),
|
|
162
|
+
loomyVisionModelIds: () => stringList(field('loomyVisionModelIds')),
|
|
163
|
+
loomyTextOnlyModelIds: () => stringList(field('loomyTextOnlyModelIds')),
|
|
164
|
+
raccoonVisionModelIds: () => stringList(field('raccoonVisionModelIds')),
|
|
165
|
+
raccoonTextOnlyModelIds: () => stringList(field('raccoonTextOnlyModelIds')),
|
|
166
|
+
traeVisionModelIds: () => stringList(field('traeVisionModelIds')),
|
|
167
|
+
traeTextOnlyModelIds: () => stringList(field('traeTextOnlyModelIds')),
|
|
168
|
+
codeartsVisionModelIds: () => stringList(field('codeartsVisionModelIds')),
|
|
169
|
+
codeartsTextOnlyModelIds: () => stringList(field('codeartsTextOnlyModelIds')),
|
|
170
|
+
defaultMaxTokens: () => positive(field('defaultMaxTokens'), 32_000),
|
|
171
|
+
modelCacheTtlMs: () => positive(field('modelCacheTtlSeconds'), 120) * 1_000,
|
|
172
|
+
catalogFetchTimeoutMs: () => positive(field('catalogFetchTimeoutSeconds'), 20) * 1_000,
|
|
173
|
+
openRouterSyncMinutes: () => nonNegative(field('openRouterSyncMinutes'), 60),
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export function resolveConfig(config: ParsedConfig | undefined): ResolvedConfig {
|
|
178
|
+
const live = liveConfig(config)
|
|
179
|
+
return {
|
|
180
|
+
loomyEnabled: live.loomyEnabled(),
|
|
181
|
+
raccoonEnabled: live.raccoonEnabled(),
|
|
182
|
+
traeEnabled: live.traeEnabled(),
|
|
183
|
+
traeRegion: live.traeRegion(),
|
|
184
|
+
codeartsEnabled: live.codeartsEnabled(),
|
|
185
|
+
loomyDisplayName: live.loomyDisplayName(),
|
|
186
|
+
raccoonDisplayName: live.raccoonDisplayName(),
|
|
187
|
+
traeDisplayName: live.traeDisplayName(),
|
|
188
|
+
codeartsDisplayName: live.codeartsDisplayName(),
|
|
189
|
+
loomyDisabledModels: live.loomyDisabledModels(),
|
|
190
|
+
raccoonDisabledModels: live.raccoonDisabledModels(),
|
|
191
|
+
traeDisabledModels: live.traeDisabledModels(),
|
|
192
|
+
codeartsDisabledModels: live.codeartsDisabledModels(),
|
|
193
|
+
loomyModelContextWindows: live.loomyModelContextWindows(),
|
|
194
|
+
raccoonModelContextWindows: live.raccoonModelContextWindows(),
|
|
195
|
+
traeModelContextWindows: live.traeModelContextWindows(),
|
|
196
|
+
codeartsModelContextWindows: live.codeartsModelContextWindows(),
|
|
197
|
+
loomyModelAliases: live.loomyModelAliases(),
|
|
198
|
+
raccoonModelAliases: live.raccoonModelAliases(),
|
|
199
|
+
traeModelAliases: live.traeModelAliases(),
|
|
200
|
+
codeartsModelAliases: live.codeartsModelAliases(),
|
|
201
|
+
loomyVisionModelIds: live.loomyVisionModelIds(),
|
|
202
|
+
loomyTextOnlyModelIds: live.loomyTextOnlyModelIds(),
|
|
203
|
+
raccoonVisionModelIds: live.raccoonVisionModelIds(),
|
|
204
|
+
raccoonTextOnlyModelIds: live.raccoonTextOnlyModelIds(),
|
|
205
|
+
traeVisionModelIds: live.traeVisionModelIds(),
|
|
206
|
+
traeTextOnlyModelIds: live.traeTextOnlyModelIds(),
|
|
207
|
+
codeartsVisionModelIds: live.codeartsVisionModelIds(),
|
|
208
|
+
codeartsTextOnlyModelIds: live.codeartsTextOnlyModelIds(),
|
|
209
|
+
defaultMaxTokens: live.defaultMaxTokens(),
|
|
210
|
+
modelCacheTtlMs: live.modelCacheTtlMs(),
|
|
211
|
+
catalogFetchTimeoutMs: live.catalogFetchTimeoutMs(),
|
|
212
|
+
openRouterSyncMinutes: live.openRouterSyncMinutes(),
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
function text(value: unknown): string {
|
|
217
|
+
return typeof value === 'string' ? value.trim() : ''
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
function nonEmpty(value: unknown, fallback: string): string {
|
|
221
|
+
const valueText = text(value)
|
|
222
|
+
return valueText.length > 0 ? valueText : fallback
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
function positive(value: unknown, fallback: number): number {
|
|
226
|
+
return typeof value === 'number' && Number.isFinite(value) && value > 0 ? value : fallback
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
function nonNegative(value: unknown, fallback: number): number {
|
|
230
|
+
return typeof value === 'number' && Number.isFinite(value) && value >= 0 ? value : fallback
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
function bool(value: unknown, fallback: boolean): boolean {
|
|
234
|
+
return typeof value === 'boolean' ? value : fallback
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
function stringList(value: unknown): readonly string[] {
|
|
238
|
+
if (!Array.isArray(value)) return []
|
|
239
|
+
return value.filter((entry): entry is string => typeof entry === 'string' && entry.trim().length > 0).map(entry => entry.trim())
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
function numberMap(value: unknown): Readonly<Record<string, number>> {
|
|
243
|
+
if (value === null || typeof value !== 'object' || Array.isArray(value)) return {}
|
|
244
|
+
const out: Record<string, number> = {}
|
|
245
|
+
for (const [key, entry] of Object.entries(value as Record<string, unknown>)) {
|
|
246
|
+
if (typeof entry === 'number' && Number.isFinite(entry) && entry > 0) out[key] = entry
|
|
247
|
+
}
|
|
248
|
+
return out
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
function stringMap(value: unknown): Readonly<Record<string, string>> {
|
|
252
|
+
if (value === null || typeof value !== 'object' || Array.isArray(value)) return {}
|
|
253
|
+
const out: Record<string, string> = {}
|
|
254
|
+
for (const [key, entry] of Object.entries(value as Record<string, unknown>)) {
|
|
255
|
+
if (typeof entry === 'string' && entry.trim().length > 0) out[key] = entry.trim()
|
|
256
|
+
}
|
|
257
|
+
return out
|
|
258
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -104,8 +104,8 @@ export {
|
|
|
104
104
|
RaccoonProvider, RACCOON_BASE, RACCOON_CLIENT_VERSION, raccoonAccessTokenValid, raccoonRefreshCandidate,
|
|
105
105
|
} from './raccoon.ts'
|
|
106
106
|
export {
|
|
107
|
-
TraeProvider, TRAE_CHAT_FUNCTIONS, TRAE_DIRECTORY_FUNCTIONS, mergeTraeModels,
|
|
108
|
-
normalizeEffort, openTraeStream, parseTraeGlobalUsage, parseTraeRemoteModels,
|
|
107
|
+
TraeProvider, TRAE_CHAT_FUNCTIONS, TRAE_CHECKIN_REQ_SOURCE, TRAE_DIRECTORY_FUNCTIONS, mergeTraeModels,
|
|
108
|
+
normalizeEffort, openTraeStream, parseTraeCheckin, parseTraeGlobalUsage, parseTraeRemoteModels,
|
|
109
109
|
parseTraeUsage, parseTraeWireModels, traeMessages, traeTools,
|
|
110
110
|
} from './trae.ts'
|
|
111
111
|
export type {
|
|
@@ -113,6 +113,8 @@ export type {
|
|
|
113
113
|
} from './trae.ts'
|
|
114
114
|
export { TRAE_APP_ID, TRAE_REGION_PROFILES, TRAE_SOLO_CHAT_PATH, TRAE_WEB_USER_AGENT } from './trae-endpoints.ts'
|
|
115
115
|
export type { TraeRegionProfile } from './trae-endpoints.ts'
|
|
116
|
+
export { parseTraeClientStorage, readTraeClientLogin, traeClientDataDirs } from './trae-client.ts'
|
|
117
|
+
export type { TraeClientDetection, TraeClientLoginState, TraeClientReadOptions } from './trae-client.ts'
|
|
116
118
|
export { TraeWebLogin, machineIdOf } from './trae-login.ts'
|
|
117
119
|
export type { TraeLoginAccount, TraeWebLoginOptions } from './trae-login.ts'
|
|
118
120
|
export {
|
|
@@ -130,20 +132,17 @@ export {
|
|
|
130
132
|
export { headersForFetch, signRequestHuawei } from './codearts-sign.ts'
|
|
131
133
|
export {
|
|
132
134
|
RefreshTokenExpiredError, buildAuthorizeUrl, exchangeAuthorizationCode, exchangeRefreshToken,
|
|
133
|
-
generateDpopKeyPair, generatePkcePair, readJwtExpiry, signDpopJws,
|
|
135
|
+
generateDpopKeyPair, generatePkcePair, otSessionIdOf, readJwtExpiry, signDpopJws,
|
|
134
136
|
} from './codearts-oauth.ts'
|
|
135
137
|
export type { CodeArtsCredential, DpopKeyPair, DpopPrivateJwk, PkcePair } from './codearts-oauth.ts'
|
|
136
138
|
export { CodeArtsLogin } from './codearts-login.ts'
|
|
137
139
|
export type { CodeArtsLoginAccount, CodeArtsLoginOptions } from './codearts-login.ts'
|
|
138
|
-
export {
|
|
139
|
-
CODEARTS_SESSION_LIMIT, CODEARTS_SESSION_WINDOW_MS, CodeArtsSessionWindow, sharedSessionWindow,
|
|
140
|
-
} from './codearts-window.ts'
|
|
141
140
|
export { ProviderHttpError, buildMessages, buildTools, consumeOpenAiStream, openAiStream, sseEvents } from './wire.ts'
|
|
142
141
|
export type { WireMessage } from './wire.ts'
|
|
143
142
|
export { API_PREFIX, buildRows } from './api.ts'
|
|
144
143
|
export { liveConfig, resolveConfig } from './config.ts'
|
|
145
144
|
export type { Config as ConfigShape, LiveConfig, ParsedConfig, ResolvedConfig } from './config.ts'
|
|
146
|
-
export type { CheckinStatus, ProviderStatus, QuotaPack, QuotaSnapshot } from './types.ts'
|
|
145
|
+
export type { CheckinStatus, ClientLoginStatus, ProviderStatus, QuotaPack, QuotaSnapshot } from './types.ts'
|
|
147
146
|
|
|
148
147
|
export const name = 'llm-adapters'
|
|
149
148
|
export const inject = ['llm']
|
|
@@ -320,28 +319,6 @@ export function apply(ctx: Context, config: ParsedConfig): void {
|
|
|
320
319
|
syncOpenRouter()
|
|
321
320
|
ctx.effect(() => () => clearInterval(syncTimer), 'llm-adapters: openrouter sync')
|
|
322
321
|
|
|
323
|
-
// Raccoon has no claim endpoint; its daily points appear on the first web
|
|
324
|
-
// visit. Poll the bills on a live interval and try the website call only when
|
|
325
|
-
// today's grant is missing. 0 turns the monitor off; the manual web link the
|
|
326
|
-
// card always shows is unaffected.
|
|
327
|
-
let lastRaccoonCheckin = Date.now()
|
|
328
|
-
const checkinMonitor = (): void => {
|
|
329
|
-
if (!live.raccoonEnabled()) return
|
|
330
|
-
const minutes = live.raccoonCheckinMinutes()
|
|
331
|
-
if (minutes <= 0) return
|
|
332
|
-
if (Date.now() - lastRaccoonCheckin < minutes * 60_000) return
|
|
333
|
-
lastRaccoonCheckin = Date.now()
|
|
334
|
-
void (async () => {
|
|
335
|
-
if (!(await raccoonProvider.signedIn())) return
|
|
336
|
-
await raccoonProvider.ensureDailyCheckin()
|
|
337
|
-
})().catch(error => {
|
|
338
|
-
ctx.logger?.warn(`llm-adapters: 小浣熊签到监测失败:${error instanceof Error ? error.message : String(error)}`)
|
|
339
|
-
})
|
|
340
|
-
}
|
|
341
|
-
const checkinTimer = setInterval(checkinMonitor, 60_000)
|
|
342
|
-
checkinTimer.unref?.()
|
|
343
|
-
ctx.effect(() => () => clearInterval(checkinTimer), 'llm-adapters: raccoon check-in monitor')
|
|
344
|
-
|
|
345
322
|
ctx.inject(['attachments'], (scope) => {
|
|
346
323
|
attachments = scope.attachments
|
|
347
324
|
scope.effect(() => () => { attachments = undefined }, 'llm-adapters.attachments')
|