@dsh-plus/llm-pi 0.1.3 → 0.1.5
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/lib/client.js +13 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +5 -0
- package/package.json +22 -11
- package/src/client/api.ts +1 -0
- package/src/client/draft.ts +4 -0
- package/src/client/i18n.ts +2 -0
- package/src/client/views/provider-fields.tsx +8 -0
- package/src/config.ts +7 -0
- package/src/profiles.ts +2 -0
package/lib/client.js
CHANGED
|
@@ -196,6 +196,7 @@ function providerDraftFromWire(provider) {
|
|
|
196
196
|
timeoutMs: numToText(provider.timeoutMs),
|
|
197
197
|
websocketConnectTimeoutMs: numToText(provider.websocketConnectTimeoutMs),
|
|
198
198
|
streamIdleTimeoutMs: numToText(provider.streamIdleTimeoutMs),
|
|
199
|
+
maxRequestImageBytes: numToText(provider.maxRequestImageBytes),
|
|
199
200
|
retryPolicy: provider.retryPolicy,
|
|
200
201
|
models: (provider.models ?? []).map(modelDraftFromWire)
|
|
201
202
|
};
|
|
@@ -219,6 +220,7 @@ function providerToWire(provider) {
|
|
|
219
220
|
timeoutMs: toNum(provider.timeoutMs),
|
|
220
221
|
websocketConnectTimeoutMs: toNum(provider.websocketConnectTimeoutMs),
|
|
221
222
|
streamIdleTimeoutMs: toNum(provider.streamIdleTimeoutMs),
|
|
223
|
+
maxRequestImageBytes: toNum(provider.maxRequestImageBytes),
|
|
222
224
|
retryPolicy: provider.retryPolicy,
|
|
223
225
|
models: provider.models.map(modelToWire)
|
|
224
226
|
});
|
|
@@ -250,6 +252,7 @@ function emptyProviderDraft() {
|
|
|
250
252
|
timeoutMs: "",
|
|
251
253
|
websocketConnectTimeoutMs: "",
|
|
252
254
|
streamIdleTimeoutMs: "",
|
|
255
|
+
maxRequestImageBytes: "",
|
|
253
256
|
retryPolicy: void 0,
|
|
254
257
|
models: []
|
|
255
258
|
};
|
|
@@ -1067,6 +1070,14 @@ function ProviderScalarFields(props) {
|
|
|
1067
1070
|
disabled: props.disabled === true,
|
|
1068
1071
|
onEdit: (value) => props.onPatch({ streamIdleTimeoutMs: value })
|
|
1069
1072
|
}),
|
|
1073
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(TextField, {
|
|
1074
|
+
id: `${props.id}-maxImageBytes`,
|
|
1075
|
+
label: t("maxRequestImageBytes"),
|
|
1076
|
+
numeric: true,
|
|
1077
|
+
value: draft.maxRequestImageBytes,
|
|
1078
|
+
disabled: props.disabled === true,
|
|
1079
|
+
onEdit: (value) => props.onPatch({ maxRequestImageBytes: value })
|
|
1080
|
+
}),
|
|
1070
1081
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1071
1082
|
className: "lpc-field",
|
|
1072
1083
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
@@ -1656,6 +1667,7 @@ const zh = {
|
|
|
1656
1667
|
timeoutMs: "HTTP 超时(毫秒)",
|
|
1657
1668
|
websocketConnectTimeoutMs: "WebSocket 连接超时(毫秒)",
|
|
1658
1669
|
streamIdleTimeoutMs: "流空闲超时(毫秒)",
|
|
1670
|
+
maxRequestImageBytes: "单请求图片载荷上限(字节,缺省 20MiB)",
|
|
1659
1671
|
headers: "请求头",
|
|
1660
1672
|
headersHint: "键值对;键为空的整行会被忽略。",
|
|
1661
1673
|
key: "键",
|
|
@@ -1744,6 +1756,7 @@ const en = {
|
|
|
1744
1756
|
timeoutMs: "HTTP timeout (ms)",
|
|
1745
1757
|
websocketConnectTimeoutMs: "WebSocket connect timeout (ms)",
|
|
1746
1758
|
streamIdleTimeoutMs: "Stream idle timeout (ms)",
|
|
1759
|
+
maxRequestImageBytes: "Max image payload per request (bytes, default 20MiB)",
|
|
1747
1760
|
headers: "Request headers",
|
|
1748
1761
|
headersHint: "Key/value pairs; rows with an empty key are ignored.",
|
|
1749
1762
|
key: "Key",
|
package/lib/index.d.ts
CHANGED
package/lib/index.js
CHANGED
|
@@ -52,6 +52,9 @@ const MODALITIES = ["text", "image"];
|
|
|
52
52
|
const DEFAULT_CONTEXT_WINDOW = 262144;
|
|
53
53
|
const DEFAULT_MAX_TOKENS = 32768;
|
|
54
54
|
const DEFAULT_STREAM_IDLE_TIMEOUT_MS = 3e5;
|
|
55
|
+
/** 单请求 base64 图片载荷上限(rc8 起官方 ResolvedPiAiProviderProfile 必需字段;
|
|
56
|
+
* 缺省取官方默认 20MiB,旧配置无需改动即自动生效)。 */
|
|
57
|
+
const DEFAULT_MAX_REQUEST_IMAGE_BYTES = 20 * 1024 * 1024;
|
|
55
58
|
/** dsh-timeout 的定时器上限(与官方 MAX_TIMER_DELAY_MS 对齐)。 */
|
|
56
59
|
const MAX_TIMER_DELAY_MS = 2 ** 31 - 1;
|
|
57
60
|
/** 键为可选档位,值为线协议拼写;仅 off 可留空(支持但不发送参数)。 */
|
|
@@ -105,6 +108,7 @@ const providerProfile = z.object({
|
|
|
105
108
|
timeoutMs: z.natural().description("HTTP/provider 超时毫秒"),
|
|
106
109
|
websocketConnectTimeoutMs: z.natural().description("WebSocket 连接超时毫秒"),
|
|
107
110
|
streamIdleTimeoutMs: z.number().min(Number.MIN_VALUE).max(MAX_TIMER_DELAY_MS).description("单支流式读取的最大空闲间隔毫秒"),
|
|
111
|
+
maxRequestImageBytes: z.natural().description("单请求 base64 图片载荷上限字节;缺省 20MiB(rc8 起生效,旧配置免改)"),
|
|
108
112
|
retryPolicy: z.any().description("provider 重试策略(dsh-llm RetryPolicy 形状,构建期校验)"),
|
|
109
113
|
models: z.array(modelEntry).description("本 route 的模型目录;缺省且 provider 有 extends 时继承该源全部模型")
|
|
110
114
|
});
|
|
@@ -846,6 +850,7 @@ function buildProfiles(providers, deps) {
|
|
|
846
850
|
displayName,
|
|
847
851
|
...profile.apiKeyEnv === void 0 ? {} : { apiKeyEnv: credentialRef(profile.apiKeyEnv) },
|
|
848
852
|
streamIdleTimeoutMs,
|
|
853
|
+
maxRequestImageBytes: profile.maxRequestImageBytes ?? DEFAULT_MAX_REQUEST_IMAGE_BYTES,
|
|
849
854
|
retryPolicy: deps.kit.resolveRetryPolicy(profile.retryPolicy, `llm-pi: provider "${route}" retryPolicy`),
|
|
850
855
|
...profile.headers === void 0 ? {} : { headers: { ...profile.headers } },
|
|
851
856
|
...profile.reasoning === void 0 ? {} : { reasoning: profile.reasoning },
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dsh-plus/llm-pi",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"description": "dsh-plus service+ui plugin: 基于 PiAiAdapter 的自定义 LLM 路由(全量 compat、模型继承、models.dev 目录兜底)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -32,19 +32,30 @@
|
|
|
32
32
|
}
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@deepseek-ai/cordis": "4.0.1",
|
|
36
|
-
"@deepseek-ai/schemastery": "3.18.1",
|
|
37
|
-
"@deepseek-ai/dsh-settings": "0.1.0-rc.7",
|
|
38
|
-
"@deepseek-ai/dsh-llm": "0.1.0-rc.7",
|
|
39
|
-
"@deepseek-ai/dsh-credentials": "0.1.0-rc.7",
|
|
40
|
-
"@deepseek-ai/dsh-home-paths": "0.1.0-rc.7",
|
|
41
|
-
"@deepseek-ai/dsh-launch-environment": "0.1.0-rc.7",
|
|
42
|
-
"@deepseek-ai/dsh-llm-pi-ai": "0.1.0-rc.7",
|
|
43
|
-
"@earendil-works/pi-ai": "0.82.1",
|
|
44
35
|
"https-proxy-agent": "^7.0.6"
|
|
45
36
|
},
|
|
37
|
+
"peerDependencies": {
|
|
38
|
+
"@deepseek-ai/cordis": "^4.0.1",
|
|
39
|
+
"@deepseek-ai/schemastery": "^3.18.1",
|
|
40
|
+
"@deepseek-ai/dsh-settings": "^0.1.0-rc.8",
|
|
41
|
+
"@deepseek-ai/dsh-llm": "^0.1.0-rc.8",
|
|
42
|
+
"@deepseek-ai/dsh-credentials": "^0.1.0-rc.8",
|
|
43
|
+
"@deepseek-ai/dsh-home-paths": "^0.1.0-rc.8",
|
|
44
|
+
"@deepseek-ai/dsh-launch-environment": "^0.1.0-rc.8",
|
|
45
|
+
"@deepseek-ai/dsh-llm-pi-ai": "^0.1.0-rc.8",
|
|
46
|
+
"@earendil-works/pi-ai": "^0.82.1"
|
|
47
|
+
},
|
|
46
48
|
"devDependencies": {
|
|
47
|
-
"@deepseek-ai/
|
|
49
|
+
"@deepseek-ai/cordis": "4.0.1",
|
|
50
|
+
"@deepseek-ai/schemastery": "3.18.1",
|
|
51
|
+
"@deepseek-ai/dsh-settings": "0.1.0-rc.8",
|
|
52
|
+
"@deepseek-ai/dsh-llm": "0.1.0-rc.8",
|
|
53
|
+
"@deepseek-ai/dsh-credentials": "0.1.0-rc.8",
|
|
54
|
+
"@deepseek-ai/dsh-home-paths": "0.1.0-rc.8",
|
|
55
|
+
"@deepseek-ai/dsh-launch-environment": "0.1.0-rc.8",
|
|
56
|
+
"@deepseek-ai/dsh-llm-pi-ai": "0.1.0-rc.8",
|
|
57
|
+
"@deepseek-ai/dsh-host-webserver": "0.1.0-rc.8",
|
|
58
|
+
"@earendil-works/pi-ai": "0.82.1",
|
|
48
59
|
"@types/react": "~18.3.1",
|
|
49
60
|
"react": "^18.2.0"
|
|
50
61
|
},
|
package/src/client/api.ts
CHANGED
package/src/client/draft.ts
CHANGED
|
@@ -58,6 +58,7 @@ export interface ProviderDraft {
|
|
|
58
58
|
timeoutMs: string
|
|
59
59
|
websocketConnectTimeoutMs: string
|
|
60
60
|
streamIdleTimeoutMs: string
|
|
61
|
+
maxRequestImageBytes: string
|
|
61
62
|
retryPolicy: unknown
|
|
62
63
|
models: ModelDraft[]
|
|
63
64
|
}
|
|
@@ -201,6 +202,7 @@ function providerDraftFromWire(provider: WireProvider): ProviderDraft {
|
|
|
201
202
|
timeoutMs: numToText(provider.timeoutMs),
|
|
202
203
|
websocketConnectTimeoutMs: numToText(provider.websocketConnectTimeoutMs),
|
|
203
204
|
streamIdleTimeoutMs: numToText(provider.streamIdleTimeoutMs),
|
|
205
|
+
maxRequestImageBytes: numToText(provider.maxRequestImageBytes),
|
|
204
206
|
retryPolicy: provider.retryPolicy,
|
|
205
207
|
models: (provider.models ?? []).map(modelDraftFromWire),
|
|
206
208
|
}
|
|
@@ -225,6 +227,7 @@ function providerToWire(provider: ProviderDraft): WireProvider {
|
|
|
225
227
|
timeoutMs: toNum(provider.timeoutMs),
|
|
226
228
|
websocketConnectTimeoutMs: toNum(provider.websocketConnectTimeoutMs),
|
|
227
229
|
streamIdleTimeoutMs: toNum(provider.streamIdleTimeoutMs),
|
|
230
|
+
maxRequestImageBytes: toNum(provider.maxRequestImageBytes),
|
|
228
231
|
retryPolicy: provider.retryPolicy,
|
|
229
232
|
models: provider.models.map(modelToWire),
|
|
230
233
|
}) as WireProvider
|
|
@@ -249,6 +252,7 @@ export function emptyProviderDraft(): ProviderDraft {
|
|
|
249
252
|
timeoutMs: '',
|
|
250
253
|
websocketConnectTimeoutMs: '',
|
|
251
254
|
streamIdleTimeoutMs: '',
|
|
255
|
+
maxRequestImageBytes: '',
|
|
252
256
|
retryPolicy: undefined,
|
|
253
257
|
models: [],
|
|
254
258
|
}
|
package/src/client/i18n.ts
CHANGED
|
@@ -50,6 +50,7 @@ export const zh: Record<string, string> = {
|
|
|
50
50
|
timeoutMs: 'HTTP 超时(毫秒)',
|
|
51
51
|
websocketConnectTimeoutMs: 'WebSocket 连接超时(毫秒)',
|
|
52
52
|
streamIdleTimeoutMs: '流空闲超时(毫秒)',
|
|
53
|
+
maxRequestImageBytes: '单请求图片载荷上限(字节,缺省 20MiB)',
|
|
53
54
|
headers: '请求头',
|
|
54
55
|
headersHint: '键值对;键为空的整行会被忽略。',
|
|
55
56
|
key: '键',
|
|
@@ -139,6 +140,7 @@ export const en: Record<string, string> = {
|
|
|
139
140
|
timeoutMs: 'HTTP timeout (ms)',
|
|
140
141
|
websocketConnectTimeoutMs: 'WebSocket connect timeout (ms)',
|
|
141
142
|
streamIdleTimeoutMs: 'Stream idle timeout (ms)',
|
|
143
|
+
maxRequestImageBytes: 'Max image payload per request (bytes, default 20MiB)',
|
|
142
144
|
headers: 'Request headers',
|
|
143
145
|
headersHint: 'Key/value pairs; rows with an empty key are ignored.',
|
|
144
146
|
key: 'Key',
|
|
@@ -96,6 +96,14 @@ export function ProviderScalarFields(props: ProviderScalarFieldsProps): ReactEle
|
|
|
96
96
|
disabled={props.disabled === true}
|
|
97
97
|
onEdit={(value) => props.onPatch({ streamIdleTimeoutMs: value })}
|
|
98
98
|
/>
|
|
99
|
+
<TextField
|
|
100
|
+
id={`${props.id}-maxImageBytes`}
|
|
101
|
+
label={t('maxRequestImageBytes')}
|
|
102
|
+
numeric
|
|
103
|
+
value={draft.maxRequestImageBytes}
|
|
104
|
+
disabled={props.disabled === true}
|
|
105
|
+
onEdit={(value) => props.onPatch({ maxRequestImageBytes: value })}
|
|
106
|
+
/>
|
|
99
107
|
<div className="lpc-field">
|
|
100
108
|
<span className="lpc-label">{t('defaultInput')}</span>
|
|
101
109
|
{MODALITIES.map((modality) => (
|
package/src/config.ts
CHANGED
|
@@ -28,6 +28,9 @@ export const MODALITIES = ['text', 'image'] as const
|
|
|
28
28
|
export const DEFAULT_CONTEXT_WINDOW = 262144
|
|
29
29
|
export const DEFAULT_MAX_TOKENS = 32768
|
|
30
30
|
export const DEFAULT_STREAM_IDLE_TIMEOUT_MS = 300000
|
|
31
|
+
/** 单请求 base64 图片载荷上限(rc8 起官方 ResolvedPiAiProviderProfile 必需字段;
|
|
32
|
+
* 缺省取官方默认 20MiB,旧配置无需改动即自动生效)。 */
|
|
33
|
+
export const DEFAULT_MAX_REQUEST_IMAGE_BYTES = 20 * 1024 * 1024
|
|
31
34
|
/** dsh-timeout 的定时器上限(与官方 MAX_TIMER_DELAY_MS 对齐)。 */
|
|
32
35
|
export const MAX_TIMER_DELAY_MS = 2 ** 31 - 1
|
|
33
36
|
|
|
@@ -69,6 +72,7 @@ export interface ProviderProfileConfig {
|
|
|
69
72
|
timeoutMs?: number
|
|
70
73
|
websocketConnectTimeoutMs?: number
|
|
71
74
|
streamIdleTimeoutMs?: number
|
|
75
|
+
maxRequestImageBytes?: number
|
|
72
76
|
retryPolicy?: unknown
|
|
73
77
|
models?: ModelEntryConfig[]
|
|
74
78
|
}
|
|
@@ -138,6 +142,9 @@ const providerProfile = z.object({
|
|
|
138
142
|
.min(Number.MIN_VALUE)
|
|
139
143
|
.max(MAX_TIMER_DELAY_MS)
|
|
140
144
|
.description('单支流式读取的最大空闲间隔毫秒'),
|
|
145
|
+
maxRequestImageBytes: z
|
|
146
|
+
.natural()
|
|
147
|
+
.description('单请求 base64 图片载荷上限字节;缺省 20MiB(rc8 起生效,旧配置免改)'),
|
|
141
148
|
retryPolicy: z.any().description('provider 重试策略(dsh-llm RetryPolicy 形状,构建期校验)'),
|
|
142
149
|
models: z.array(modelEntry).description('本 route 的模型目录;缺省且 provider 有 extends 时继承该源全部模型'),
|
|
143
150
|
})
|
package/src/profiles.ts
CHANGED
|
@@ -20,6 +20,7 @@ import { mergeCompat, validateCompat } from './compat.ts'
|
|
|
20
20
|
import {
|
|
21
21
|
DEFAULT_CONTEXT_WINDOW,
|
|
22
22
|
DEFAULT_MAX_TOKENS,
|
|
23
|
+
DEFAULT_MAX_REQUEST_IMAGE_BYTES,
|
|
23
24
|
DEFAULT_STREAM_IDLE_TIMEOUT_MS,
|
|
24
25
|
MAX_TIMER_DELAY_MS,
|
|
25
26
|
THINKING_LEVELS,
|
|
@@ -311,6 +312,7 @@ export function buildProfiles(
|
|
|
311
312
|
displayName,
|
|
312
313
|
...(profile.apiKeyEnv === undefined ? {} : { apiKeyEnv: credentialRef(profile.apiKeyEnv) }),
|
|
313
314
|
streamIdleTimeoutMs,
|
|
315
|
+
maxRequestImageBytes: profile.maxRequestImageBytes ?? DEFAULT_MAX_REQUEST_IMAGE_BYTES,
|
|
314
316
|
retryPolicy: deps.kit.resolveRetryPolicy(
|
|
315
317
|
profile.retryPolicy as Parameters<DshKit['resolveRetryPolicy']>[0],
|
|
316
318
|
`llm-pi: provider "${route}" retryPolicy`,
|