@deepseek-ai/dsh-experimental-client-ui-voice-input 0.1.7-alpha.1 → 0.1.7-rc.1
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.i18n.yaml +2 -2
- package/README.md +2 -0
- package/README.zh.md +2 -0
- package/lib/client.js +109 -18
- package/lib/types/client/VoiceInput.d.ts +2 -2
- package/lib/types/client/locales.d.ts +7 -1
- package/package.json +34 -34
package/README.i18n.yaml
CHANGED
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
|
3
3
|
# after editing either side, bring the other along and re-record with:
|
|
4
4
|
# pnpm run verify-translation-pairing --write packages/experimental/client-ui-voice-input/README.md
|
|
5
|
-
README.md:
|
|
6
|
-
README.zh.md:
|
|
5
|
+
README.md: 764962ff496c9fdd91073c2aa391ebceeec23608
|
|
6
|
+
README.zh.md: 105cb641684eb2920c04294e74f1b5389f564c0c
|
package/README.md
CHANGED
|
@@ -27,6 +27,8 @@ This optional browser plugin adds an outline microphone icon between the model s
|
|
|
27
27
|
|
|
28
28
|
Enable the [voice input bundle](../voice-input-bundle/README.md) from Plugins. After cache inspection, missing models trigger a setup prompt with Go to setup and Later actions. Go to setup opens bundle details; Download and prepare starts installation there. Intact cached models need no prompt or repeated installation. Before preparation, local providers can show their estimated disk, memory and setup-time requirements. The preparation summary starts collapsed; expand it to inspect completed, current and pending steps. Once ready, click the microphone, allow access and click Stop to transcribe. Cancel or Escape discards capture. Recognition feedback stays inside the toolbar. Provider and language preferences are saved from bundle details through the Settings service. Browser microphone access requires HTTPS or loopback and operating-system permission.
|
|
29
29
|
|
|
30
|
+
Before downloading or retrying, **Model download source** offers Automatic and the origins advertised by the Host. SenseVoice normally offers Hugging Face and HF-Mirror; a fixed private deployment exposes only its configured origin. Manual selection uses only that source, while Automatic preserves the provider’s comparison and fallback policy. The choice is retained for retries in the current card, without changing deployment configuration or recognition preferences. Source controls are unavailable during preparation and hidden when resources are ready.
|
|
31
|
+
|
|
30
32
|
-----
|
|
31
33
|
|
|
32
34
|
<a id="understand-the-implementation"></a>
|
package/README.zh.md
CHANGED
|
@@ -27,6 +27,8 @@ kind: "package-reference"
|
|
|
27
27
|
|
|
28
28
|
在插件管理页启用[语音输入 Bundle](../voice-input-bundle/README.zh.md)。缓存检查后,缺少模型时弹出安装引导,可选择“前往安装”或“稍后”。“前往安装”打开 Bundle 详情,再点击“下载并准备”才开始安装。缓存完整时不弹引导,也无需重复安装。准备前,本地 Provider 可展示磁盘、内存与安装时间的估算。准备摘要默认折叠;展开后可查看已完成、当前和未开始的步骤。就绪后点击麦克风,允许访问,再点击停止以转写。取消或 Escape 丢弃录音。识别反馈留在工具栏内部。Provider 和语言偏好在 Bundle 详情中通过 Settings 服务保存。浏览器麦克风访问需要 HTTPS 或环回地址,以及操作系统权限。
|
|
29
29
|
|
|
30
|
+
下载或重试前,**模型下载源**提供自动选择及 Host 公布的源。SenseVoice 默认提供 Hugging Face 和 HF-Mirror;固定私有部署仅显示配置的源。手动选择只使用指定源,自动选择沿用提供方的比较与回退策略。当前卡片中的重试会保留选择,不修改部署配置或识别偏好。准备期间不能改源,资源就绪后隐藏源选择器。
|
|
31
|
+
|
|
30
32
|
-----
|
|
31
33
|
|
|
32
34
|
<a id="understand-the-implementation"></a>
|
package/lib/client.js
CHANGED
|
@@ -614,6 +614,7 @@ window.__ModuleLoader__.load({
|
|
|
614
614
|
};
|
|
615
615
|
const integer = /^-?\d+$/;
|
|
616
616
|
const number$1 = /^-?\d+(?:\.\d+)?$/;
|
|
617
|
+
const _undefined$2 = /^undefined$/i;
|
|
617
618
|
const lowercase = /^[^A-Z]*$/;
|
|
618
619
|
const uppercase = /^[^a-z]*$/;
|
|
619
620
|
//#endregion
|
|
@@ -1408,6 +1409,22 @@ window.__ModuleLoader__.load({
|
|
|
1408
1409
|
$ZodCheckNumberFormat.init(inst, def);
|
|
1409
1410
|
$ZodNumber.init(inst, def);
|
|
1410
1411
|
});
|
|
1412
|
+
const $ZodUndefined = /*@__PURE__*/ $constructor("$ZodUndefined", (inst, def) => {
|
|
1413
|
+
$ZodType.init(inst, def);
|
|
1414
|
+
inst._zod.pattern = _undefined$2;
|
|
1415
|
+
inst._zod.values = new Set([void 0]);
|
|
1416
|
+
inst._zod.parse = (payload, _ctx) => {
|
|
1417
|
+
const input = payload.value;
|
|
1418
|
+
if (typeof input === "undefined") return payload;
|
|
1419
|
+
payload.issues.push({
|
|
1420
|
+
expected: "undefined",
|
|
1421
|
+
code: "invalid_type",
|
|
1422
|
+
input,
|
|
1423
|
+
inst
|
|
1424
|
+
});
|
|
1425
|
+
return payload;
|
|
1426
|
+
};
|
|
1427
|
+
});
|
|
1411
1428
|
const $ZodUnknown = /*@__PURE__*/ $constructor("$ZodUnknown", (inst, def) => {
|
|
1412
1429
|
$ZodType.init(inst, def);
|
|
1413
1430
|
inst._zod.parse = (payload) => payload;
|
|
@@ -2472,6 +2489,13 @@ window.__ModuleLoader__.load({
|
|
|
2472
2489
|
});
|
|
2473
2490
|
}
|
|
2474
2491
|
// @__NO_SIDE_EFFECTS__
|
|
2492
|
+
function _undefined$1(Class, params) {
|
|
2493
|
+
return new Class({
|
|
2494
|
+
type: "undefined",
|
|
2495
|
+
...normalizeParams(params)
|
|
2496
|
+
});
|
|
2497
|
+
}
|
|
2498
|
+
// @__NO_SIDE_EFFECTS__
|
|
2475
2499
|
function _unknown(Class) {
|
|
2476
2500
|
return new Class({ type: "unknown" });
|
|
2477
2501
|
}
|
|
@@ -3024,6 +3048,9 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
3024
3048
|
else if (typeof maximum === "number") json.maximum = maximum;
|
|
3025
3049
|
if (typeof multipleOf === "number") json.multipleOf = multipleOf;
|
|
3026
3050
|
};
|
|
3051
|
+
const undefinedProcessor = (_schema, ctx, _json, _params) => {
|
|
3052
|
+
if (ctx.unrepresentable === "throw") throw new Error("Undefined cannot be represented in JSON Schema");
|
|
3053
|
+
};
|
|
3027
3054
|
const voidProcessor = (_schema, ctx, _json, _params) => {
|
|
3028
3055
|
if (ctx.unrepresentable === "throw") throw new Error("Void cannot be represented in JSON Schema");
|
|
3029
3056
|
};
|
|
@@ -3676,6 +3703,14 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
3676
3703
|
function int(params) {
|
|
3677
3704
|
return /* @__PURE__ */ _int(ZodNumberFormat, params);
|
|
3678
3705
|
}
|
|
3706
|
+
const ZodUndefined = /*@__PURE__*/ $constructor("ZodUndefined", (inst, def) => {
|
|
3707
|
+
$ZodUndefined.init(inst, def);
|
|
3708
|
+
ZodType.init(inst, def);
|
|
3709
|
+
inst._zod.processJSONSchema = (ctx, json, params) => undefinedProcessor(inst, ctx, json, params);
|
|
3710
|
+
});
|
|
3711
|
+
function _undefined(params) {
|
|
3712
|
+
return /* @__PURE__ */ _undefined$1(ZodUndefined, params);
|
|
3713
|
+
}
|
|
3679
3714
|
const ZodUnknown = /*@__PURE__*/ $constructor("ZodUnknown", (inst, def) => {
|
|
3680
3715
|
$ZodUnknown.init(inst, def);
|
|
3681
3716
|
ZodType.init(inst, def);
|
|
@@ -4204,7 +4239,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4204
4239
|
"expectedMemoryBytes": number().readonly(),
|
|
4205
4240
|
"minimumMinutes": number().readonly(),
|
|
4206
4241
|
"maximumMinutes": number().readonly()
|
|
4207
|
-
}).readonly().optional()
|
|
4242
|
+
}).readonly().optional(),
|
|
4243
|
+
"downloadSources": array(string()).readonly().optional()
|
|
4208
4244
|
})).readonly(),
|
|
4209
4245
|
"selection": object({
|
|
4210
4246
|
"providerId": intersection(string(), unknown()).readonly(),
|
|
@@ -4375,7 +4411,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4375
4411
|
"expectedMemoryBytes": number().readonly(),
|
|
4376
4412
|
"minimumMinutes": number().readonly(),
|
|
4377
4413
|
"maximumMinutes": number().readonly()
|
|
4378
|
-
}).readonly().optional()
|
|
4414
|
+
}).readonly().optional(),
|
|
4415
|
+
"downloadSources": array(string()).readonly().optional()
|
|
4379
4416
|
})).readonly(),
|
|
4380
4417
|
"selection": object({
|
|
4381
4418
|
"providerId": intersection(string(), unknown()).readonly(),
|
|
@@ -4384,6 +4421,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4384
4421
|
});
|
|
4385
4422
|
let _deepseek_ai_dsh_experimental_api_speech_to_text_speech_prepare_parameter_0$schema$value;
|
|
4386
4423
|
const _deepseek_ai_dsh_experimental_api_speech_to_text_speech_prepare_parameter_0$schema = () => _deepseek_ai_dsh_experimental_api_speech_to_text_speech_prepare_parameter_0$schema$value ??= intersection(string(), unknown());
|
|
4424
|
+
let _deepseek_ai_dsh_experimental_api_speech_to_text_speech_prepare_parameter_1$schema$value;
|
|
4425
|
+
const _deepseek_ai_dsh_experimental_api_speech_to_text_speech_prepare_parameter_1$schema = () => _deepseek_ai_dsh_experimental_api_speech_to_text_speech_prepare_parameter_1$schema$value ??= union([_undefined(), object({ "downloadSource": string().readonly().optional() })]);
|
|
4387
4426
|
let _deepseek_ai_dsh_experimental_api_speech_to_text_speech_prepare_result$schema$value;
|
|
4388
4427
|
const _deepseek_ai_dsh_experimental_api_speech_to_text_speech_prepare_result$schema = () => _deepseek_ai_dsh_experimental_api_speech_to_text_speech_prepare_result$schema$value ??= _void();
|
|
4389
4428
|
let _deepseek_ai_dsh_experimental_api_speech_to_text_speech_transcribe_parameter_0$schema$value;
|
|
@@ -4424,7 +4463,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4424
4463
|
},
|
|
4425
4464
|
sourceLocation: {
|
|
4426
4465
|
"file": "packages/experimental/api-speech-to-text/src/index.ts",
|
|
4427
|
-
"line":
|
|
4466
|
+
"line": 80,
|
|
4428
4467
|
"column": 3
|
|
4429
4468
|
}
|
|
4430
4469
|
},
|
|
@@ -4508,6 +4547,16 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4508
4547
|
typeSymbol: "@deepseek-ai/dsh-experimental-speech-to-text/types#SpeechProviderId",
|
|
4509
4548
|
create: _deepseek_ai_dsh_experimental_api_speech_to_text_speech_prepare_parameter_0$schema
|
|
4510
4549
|
}
|
|
4550
|
+
}, {
|
|
4551
|
+
name: "options",
|
|
4552
|
+
wire: "options",
|
|
4553
|
+
source: "json",
|
|
4554
|
+
acceptsUndefined: true,
|
|
4555
|
+
codec: {
|
|
4556
|
+
mode: "strict",
|
|
4557
|
+
typeSymbol: "@deepseek-ai/dsh-experimental-speech-to-text/types#SpeechPreparationOptions",
|
|
4558
|
+
create: _deepseek_ai_dsh_experimental_api_speech_to_text_speech_prepare_parameter_1$schema
|
|
4559
|
+
}
|
|
4511
4560
|
}],
|
|
4512
4561
|
result: {
|
|
4513
4562
|
mode: "strict",
|
|
@@ -4516,7 +4565,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4516
4565
|
},
|
|
4517
4566
|
sourceLocation: {
|
|
4518
4567
|
"file": "packages/experimental/api-speech-to-text/src/index.ts",
|
|
4519
|
-
"line":
|
|
4568
|
+
"line": 72,
|
|
4520
4569
|
"column": 3
|
|
4521
4570
|
}
|
|
4522
4571
|
},
|
|
@@ -4544,7 +4593,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4544
4593
|
},
|
|
4545
4594
|
sourceLocation: {
|
|
4546
4595
|
"file": "packages/experimental/api-speech-to-text/src/index.ts",
|
|
4547
|
-
"line":
|
|
4596
|
+
"line": 89,
|
|
4548
4597
|
"column": 9
|
|
4549
4598
|
}
|
|
4550
4599
|
}
|
|
@@ -4753,7 +4802,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4753
4802
|
};
|
|
4754
4803
|
//#endregion
|
|
4755
4804
|
//#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/experimental/client-ui-voice-input/src/client/VoiceInput.module.css.mjs
|
|
4756
|
-
const css = ".ddpbLW_trigger{flex:none;width:28px;padding:0}.ddpbLW_triggerAnchor{flex:none;display:inline-flex}.ddpbLW_captureRow{align-items:center;gap:12px;width:100%;min-width:0;min-height:34px;display:flex}.ddpbLW_roundButton{corner-shape:round;background:var(--dsw-specific-selector);border-radius:50%;flex:none;width:32px;height:32px;padding:0}.ddpbLW_roundButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover-solid)}.ddpbLW_waveform{width:0;min-width:24px;height:24px;color:var(--dsw-alias-label-secondary);flex:1;display:block}.ddpbLW_activityMessage{min-width:0;color:var(--dsw-alias-label-secondary);white-space:nowrap;text-overflow:ellipsis;flex:1;align-items:center;gap:8px;font-size:12px;display:flex;overflow:hidden}.ddpbLW_inlineAction{flex:none}.ddpbLW_preparation{border:.5px solid var(--dsw-alias-border-l1);border-radius:10px;flex-direction:column;gap:10px;margin:12px 0;padding:14px;font-size:13px;display:flex}.ddpbLW_preparation p{margin:0}.ddpbLW_preparationActions{gap:8px;display:flex}.ddpbLW_preparationActions:empty{display:none}.ddpbLW_preparationError{color:var(--dsw-alias-state-error-primary);overflow-wrap:anywhere;font-size:12px}.ddpbLW_downloadFailure{overflow-wrap:anywhere;gap:6px;display:grid}.ddpbLW_summaryRow{flex-wrap:wrap;gap:4px;height:auto;min-height:28px}.ddpbLW_summaryTitle{flex:1;min-width:0}.ddpbLW_metric{color:var(--dsw-alias-label-tertiary);font-size:12px}.ddpbLW_progress{width:100%;height:6px;accent-color:var(--dsw-alias-state-business-primary)}.ddpbLW_steps{flex-direction:column;gap:14px;margin:0;padding:16px 0 2px;list-style:none;display:flex}.ddpbLW_steps li{align-items:flex-start;gap:10px;line-height:18px;display:flex}.ddpbLW_steps li>:first-child{margin-top:1px}.ddpbLW_steps li[data-step-state=pending]{color:var(--dsw-alias-label-tertiary)}.ddpbLW_stepBody{flex:1;min-width:0}.ddpbLW_stepProgress{flex-direction:column;gap:6px;margin-top:6px;display:flex}.ddpbLW_stepProgress small{color:var(--dsw-alias-label-tertiary);overflow-wrap:anywhere;font-size:11px}.ddpbLW_preferences{gap:12px;margin:18px 0;font-size:13px;display:grid}.ddpbLW_preferences label{grid-template-columns:100px minmax(120px,280px);align-items:center;gap:12px;display:grid}.ddpbLW_preferences select{border:.5px solid var(--dsw-alias-border-l1);color:inherit;font:inherit;background:0 0;border-radius:6px;padding:6px 10px}.ddpbLW_preferences p{margin:0}.ddpbLW_settingsCard{border:.5px solid var(--dsw-alias-border-l1);border-radius:10px;padding:16px;list-style:none}.ddpbLW_settingsCard>p{color:var(--dsw-alias-label-secondary);margin:8px 0 0;font-size:13px}.ddpbLW_setupEstimate{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-secondary);border-radius:8px;gap:10px;padding:12px;line-height:1.6;display:grid}.ddpbLW_setupEstimate dl{gap:6px;margin:0;display:grid}.ddpbLW_setupEstimate dl>div{grid-template-columns:72px minmax(0,1fr);gap:10px;display:grid}.ddpbLW_setupEstimate dt{color:var(--dsw-alias-label-tertiary)}.ddpbLW_setupEstimate dd{margin:0}.ddpbLW_setupEstimate small{color:var(--dsw-alias-label-tertiary);font-size:12px}";
|
|
4805
|
+
const css = ".ddpbLW_trigger{flex:none;width:28px;padding:0}.ddpbLW_triggerAnchor{flex:none;display:inline-flex}.ddpbLW_captureRow{align-items:center;gap:12px;width:100%;min-width:0;min-height:34px;display:flex}.ddpbLW_roundButton{corner-shape:round;background:var(--dsw-specific-selector);border-radius:50%;flex:none;width:32px;height:32px;padding:0}.ddpbLW_roundButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover-solid)}.ddpbLW_waveform{width:0;min-width:24px;height:24px;color:var(--dsw-alias-label-secondary);flex:1;display:block}.ddpbLW_activityMessage{min-width:0;color:var(--dsw-alias-label-secondary);white-space:nowrap;text-overflow:ellipsis;flex:1;align-items:center;gap:8px;font-size:12px;display:flex;overflow:hidden}.ddpbLW_inlineAction{flex:none}.ddpbLW_preparation{border:.5px solid var(--dsw-alias-border-l1);border-radius:10px;flex-direction:column;gap:10px;margin:12px 0;padding:14px;font-size:13px;display:flex}.ddpbLW_preparation p{margin:0}.ddpbLW_preparationActions{gap:8px;display:flex}.ddpbLW_preparationActions:empty{display:none}.ddpbLW_preparationError{color:var(--dsw-alias-state-error-primary);overflow-wrap:anywhere;font-size:12px}.ddpbLW_downloadFailure{overflow-wrap:anywhere;gap:6px;display:grid}.ddpbLW_summaryRow{flex-wrap:wrap;gap:4px;height:auto;min-height:28px}.ddpbLW_summaryTitle{flex:1;min-width:0}.ddpbLW_metric{color:var(--dsw-alias-label-tertiary);font-size:12px}.ddpbLW_progress{width:100%;height:6px;accent-color:var(--dsw-alias-state-business-primary)}.ddpbLW_steps{flex-direction:column;gap:14px;margin:0;padding:16px 0 2px;list-style:none;display:flex}.ddpbLW_steps li{align-items:flex-start;gap:10px;line-height:18px;display:flex}.ddpbLW_steps li>:first-child{margin-top:1px}.ddpbLW_steps li[data-step-state=pending]{color:var(--dsw-alias-label-tertiary)}.ddpbLW_stepBody{flex:1;min-width:0}.ddpbLW_stepProgress{flex-direction:column;gap:6px;margin-top:6px;display:flex}.ddpbLW_stepProgress small{color:var(--dsw-alias-label-tertiary);overflow-wrap:anywhere;font-size:11px}.ddpbLW_preferences{gap:12px;margin:18px 0;font-size:13px;display:grid}.ddpbLW_preferences label,.ddpbLW_sourceChoice label{grid-template-columns:100px minmax(120px,280px);align-items:center;gap:12px;display:grid}.ddpbLW_preferences select,.ddpbLW_sourceChoice select{border:.5px solid var(--dsw-alias-border-l1);color:inherit;font:inherit;background:0 0;border-radius:6px;padding:6px 10px}.ddpbLW_sourceChoice{gap:6px;display:grid}.ddpbLW_preferences p{margin:0}.ddpbLW_settingsCard{border:.5px solid var(--dsw-alias-border-l1);border-radius:10px;padding:16px;list-style:none}.ddpbLW_settingsCard>p{color:var(--dsw-alias-label-secondary);margin:8px 0 0;font-size:13px}.ddpbLW_setupEstimate{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-secondary);border-radius:8px;gap:10px;padding:12px;line-height:1.6;display:grid}.ddpbLW_setupEstimate dl{gap:6px;margin:0;display:grid}.ddpbLW_setupEstimate dl>div{grid-template-columns:72px minmax(0,1fr);gap:10px;display:grid}.ddpbLW_setupEstimate dt{color:var(--dsw-alias-label-tertiary)}.ddpbLW_setupEstimate dd{margin:0}.ddpbLW_setupEstimate small{color:var(--dsw-alias-label-tertiary);font-size:12px}";
|
|
4757
4806
|
const tagId = "@deepseek-ai/dsh-experimental-client-ui-voice-input/VoiceInput.module.css";
|
|
4758
4807
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
|
|
4759
4808
|
const tag = document.createElement("style");
|
|
@@ -4776,6 +4825,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4776
4825
|
"roundButton": "ddpbLW_roundButton",
|
|
4777
4826
|
"settingsCard": "ddpbLW_settingsCard",
|
|
4778
4827
|
"setupEstimate": "ddpbLW_setupEstimate",
|
|
4828
|
+
"sourceChoice": "ddpbLW_sourceChoice",
|
|
4779
4829
|
"stepBody": "ddpbLW_stepBody",
|
|
4780
4830
|
"stepProgress": "ddpbLW_stepProgress",
|
|
4781
4831
|
"steps": "ddpbLW_steps",
|
|
@@ -5122,6 +5172,12 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5122
5172
|
"downloadAdvice.storage": "请检查运行 DSH 的机器的剩余磁盘空间,以及模型目录的写入权限后重试。",
|
|
5123
5173
|
"downloadAdvice.unknown": "请检查运行 DSH 的机器的网络、磁盘空间和模型目录权限后重试。",
|
|
5124
5174
|
downloadSource: "下载来源:{source}",
|
|
5175
|
+
sourceChoice: "模型下载源",
|
|
5176
|
+
sourceAuto: "自动选择(推荐)",
|
|
5177
|
+
sourceHuggingFace: "Hugging Face",
|
|
5178
|
+
sourceMirror: "HF-Mirror(国内镜像)",
|
|
5179
|
+
sourceAutoHelp: "优先使用响应较快的源,下载失败时自动尝试其他源。",
|
|
5180
|
+
sourceManualHelp: "仅从所选源下载;已下载并通过校验的文件会复用。",
|
|
5125
5181
|
downloadCode: "错误码:{code}",
|
|
5126
5182
|
"reconnecting": "正在连接语音服务…",
|
|
5127
5183
|
"preparation.unprepared": "首次使用需要下载本地识别模型。",
|
|
@@ -5153,7 +5209,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5153
5209
|
requesting: "请允许使用麦克风…",
|
|
5154
5210
|
recording: "正在录音…",
|
|
5155
5211
|
interrupted: "录音中断,请重试。",
|
|
5156
|
-
local: "音频在运行 DSH
|
|
5212
|
+
local: "音频在运行 DSH 的机器上识别。需要下载模型时,请确保该机器能访问所选下载源及其文件服务。如需代理,请在该机器上配置。",
|
|
5157
5213
|
cloud: "音频将发送至所选云端服务。",
|
|
5158
5214
|
empty: "未识别到语音",
|
|
5159
5215
|
cancelled: "已取消语音输入。",
|
|
@@ -5217,6 +5273,12 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5217
5273
|
"downloadAdvice.storage": "Check available disk space and write permission for the model directory on the machine running DSH, then retry.",
|
|
5218
5274
|
"downloadAdvice.unknown": "Check the network, disk space and model directory permissions on the machine running DSH, then retry.",
|
|
5219
5275
|
downloadSource: "Download source: {source}",
|
|
5276
|
+
sourceChoice: "Model download source",
|
|
5277
|
+
sourceAuto: "Automatic (recommended)",
|
|
5278
|
+
sourceHuggingFace: "Hugging Face",
|
|
5279
|
+
sourceMirror: "HF-Mirror (China mirror)",
|
|
5280
|
+
sourceAutoHelp: "Prefer the first responding source and try another if a download fails.",
|
|
5281
|
+
sourceManualHelp: "Download only from the selected source. Verified downloaded files are reused.",
|
|
5220
5282
|
downloadCode: "Error code: {code}",
|
|
5221
5283
|
"reconnecting": "Connecting to speech recognition…",
|
|
5222
5284
|
"preparation.unprepared": "First use downloads the local recognition models.",
|
|
@@ -5248,7 +5310,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5248
5310
|
requesting: "Allow microphone access to continue…",
|
|
5249
5311
|
recording: "Recording…",
|
|
5250
5312
|
interrupted: "Recording was interrupted. Please try again.",
|
|
5251
|
-
local: "Audio is recognized on the machine running DSH.
|
|
5313
|
+
local: "Audio is recognized on the machine running DSH. If models need downloading, that machine must be able to reach the selected source and its file services. Configure a proxy on that machine if needed.",
|
|
5252
5314
|
cloud: "Audio will be sent to the selected cloud service.",
|
|
5253
5315
|
empty: "No speech recognized",
|
|
5254
5316
|
cancelled: "Voice input cancelled.",
|
|
@@ -5367,6 +5429,15 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5367
5429
|
function PreparationCard({ provider, connected, prepare, cancelPreparation, t }) {
|
|
5368
5430
|
const state = provider.preparation;
|
|
5369
5431
|
const [expanded, setExpanded] = (0, react.useState)(false), [now, setNow] = (0, react.useState)(Date.now), [error, setError] = (0, react.useState)("");
|
|
5432
|
+
const [source, setSource] = (0, react.useState)(""), [submitting, setSubmitting] = (0, react.useState)(false);
|
|
5433
|
+
const sources = provider.downloadSources ?? [];
|
|
5434
|
+
const [firstSource = ""] = sources;
|
|
5435
|
+
const selectedSource = sources.includes(source) ? source : sources.length === 1 ? firstSource : "";
|
|
5436
|
+
const canPrepare = [
|
|
5437
|
+
"unprepared",
|
|
5438
|
+
"cancelled",
|
|
5439
|
+
"failed"
|
|
5440
|
+
].includes(state.phase);
|
|
5370
5441
|
const current = state.steps?.find((step) => step.status === "running" || step.status === "failed" || step.status === "cancelled");
|
|
5371
5442
|
const preparing = preparationTone(state) === "ongoing";
|
|
5372
5443
|
const startedAt = current?.startedAt ?? ("startedAt" in state ? state.startedAt : void 0);
|
|
@@ -5381,10 +5452,13 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5381
5452
|
}, [preparing, startedAt]);
|
|
5382
5453
|
const run = async (action) => {
|
|
5383
5454
|
setError("");
|
|
5455
|
+
setSubmitting(true);
|
|
5384
5456
|
try {
|
|
5385
5457
|
await action();
|
|
5386
5458
|
} catch (failure) {
|
|
5387
5459
|
setError(failure instanceof Error ? failure.message : String(failure));
|
|
5460
|
+
} finally {
|
|
5461
|
+
setSubmitting(false);
|
|
5388
5462
|
}
|
|
5389
5463
|
};
|
|
5390
5464
|
const metric = state.phase === "downloading" ? byteText(state, t) : preparing && startedAt !== void 0 ? t("elapsed", { seconds: String(Math.max(0, Math.floor((now - startedAt) / 1e3))) }) : "";
|
|
@@ -5469,24 +5543,41 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5469
5543
|
state,
|
|
5470
5544
|
t
|
|
5471
5545
|
}),
|
|
5546
|
+
canPrepare && sources.length > 0 && (0, react_jsx_runtime.jsxs)("div", {
|
|
5547
|
+
className: VoiceInput_module_css_default.sourceChoice,
|
|
5548
|
+
children: [(0, react_jsx_runtime.jsxs)("label", { children: [t("sourceChoice"), (0, react_jsx_runtime.jsxs)("select", {
|
|
5549
|
+
"aria-label": t("sourceChoice"),
|
|
5550
|
+
value: selectedSource,
|
|
5551
|
+
disabled: !connected || submitting || sources.length === 1,
|
|
5552
|
+
onChange: (event) => {
|
|
5553
|
+
setSource(event.target.value);
|
|
5554
|
+
},
|
|
5555
|
+
children: [sources.length > 1 && (0, react_jsx_runtime.jsx)("option", {
|
|
5556
|
+
value: "",
|
|
5557
|
+
children: t("sourceAuto")
|
|
5558
|
+
}), sources.map((origin) => (0, react_jsx_runtime.jsx)("option", {
|
|
5559
|
+
value: origin,
|
|
5560
|
+
children: origin === "https://huggingface.co" ? t("sourceHuggingFace") : origin === "https://hf-mirror.com" ? t("sourceMirror") : origin
|
|
5561
|
+
}, origin))]
|
|
5562
|
+
})] }), (0, react_jsx_runtime.jsx)("small", {
|
|
5563
|
+
className: VoiceInput_module_css_default.metric,
|
|
5564
|
+
children: t(selectedSource === "" ? "sourceAutoHelp" : "sourceManualHelp")
|
|
5565
|
+
})]
|
|
5566
|
+
}),
|
|
5472
5567
|
(0, react_jsx_runtime.jsxs)("div", {
|
|
5473
5568
|
className: VoiceInput_module_css_default.preparationActions,
|
|
5474
|
-
children: [
|
|
5475
|
-
"unprepared",
|
|
5476
|
-
"cancelled",
|
|
5477
|
-
"failed"
|
|
5478
|
-
].includes(state.phase) && (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
5569
|
+
children: [canPrepare && (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
5479
5570
|
variant: "outline",
|
|
5480
5571
|
size: "sm",
|
|
5481
|
-
disabled: !connected,
|
|
5572
|
+
disabled: !connected || submitting,
|
|
5482
5573
|
onClick: () => {
|
|
5483
|
-
run(() => prepare(provider.id));
|
|
5574
|
+
run(() => selectedSource === "" ? prepare(provider.id) : prepare(provider.id, { downloadSource: selectedSource }));
|
|
5484
5575
|
},
|
|
5485
5576
|
children: t(state.phase === "unprepared" ? "prepare" : "retryPrepare")
|
|
5486
5577
|
}), preparing && state.phase !== "waking" && (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
5487
5578
|
variant: "ghost",
|
|
5488
5579
|
size: "sm",
|
|
5489
|
-
disabled: !connected || state.phase === "cancelling",
|
|
5580
|
+
disabled: !connected || submitting || state.phase === "cancelling",
|
|
5490
5581
|
onClick: () => {
|
|
5491
5582
|
run(() => cancelPreparation(provider.id));
|
|
5492
5583
|
},
|
|
@@ -5642,8 +5733,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5642
5733
|
const result = await ctx.remote.speech.configure(patch);
|
|
5643
5734
|
if (!result.ok) throw result.error;
|
|
5644
5735
|
},
|
|
5645
|
-
prepare: async (providerId) => {
|
|
5646
|
-
const result = await ctx.remote.speech.prepare(providerId);
|
|
5736
|
+
prepare: async (providerId, options) => {
|
|
5737
|
+
const result = await ctx.remote.speech.prepare(providerId, options);
|
|
5647
5738
|
if (!result.ok) throw result.error;
|
|
5648
5739
|
},
|
|
5649
5740
|
cancelPreparation: async (providerId) => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { HostObservable, InjectFace, PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
|
|
2
2
|
import type { TranscriptionRequest } from '@deepseek-ai/dsh-experimental-api-speech-to-text/types';
|
|
3
|
-
import type { SpeechProviderId, SpeechSelectionPatch, Transcript } from '@deepseek-ai/dsh-experimental-speech-to-text/types';
|
|
3
|
+
import type { SpeechPreparationOptions, SpeechProviderId, SpeechSelectionPatch, Transcript } from '@deepseek-ai/dsh-experimental-speech-to-text/types';
|
|
4
4
|
import type { RemoteResult } from '@deepseek-ai/dsh-typert-protocol';
|
|
5
5
|
import { type Recording } from './audio.ts';
|
|
6
6
|
import type { SpeechReadiness } from './readiness.ts';
|
|
@@ -10,7 +10,7 @@ export interface VoiceInputActions {
|
|
|
10
10
|
/** @returns one microphone operation owned by the plugin lifecycle. */
|
|
11
11
|
createRecording: () => Recording;
|
|
12
12
|
transcribe: (request: TranscriptionRequest, signal: AbortSignal) => Promise<RemoteResult<Transcript>>;
|
|
13
|
-
prepare: (providerId: SpeechProviderId) => Promise<void>;
|
|
13
|
+
prepare: (providerId: SpeechProviderId, options?: SpeechPreparationOptions) => Promise<void>;
|
|
14
14
|
cancelPreparation: (providerId: SpeechProviderId) => Promise<void>;
|
|
15
15
|
configure: (patch: SpeechSelectionPatch) => Promise<void>;
|
|
16
16
|
}
|
|
@@ -54,6 +54,12 @@ export declare const zh: {
|
|
|
54
54
|
readonly 'downloadAdvice.storage': "请检查运行 DSH 的机器的剩余磁盘空间,以及模型目录的写入权限后重试。";
|
|
55
55
|
readonly 'downloadAdvice.unknown': "请检查运行 DSH 的机器的网络、磁盘空间和模型目录权限后重试。";
|
|
56
56
|
readonly downloadSource: "下载来源:{source}";
|
|
57
|
+
readonly sourceChoice: "模型下载源";
|
|
58
|
+
readonly sourceAuto: "自动选择(推荐)";
|
|
59
|
+
readonly sourceHuggingFace: "Hugging Face";
|
|
60
|
+
readonly sourceMirror: "HF-Mirror(国内镜像)";
|
|
61
|
+
readonly sourceAutoHelp: "优先使用响应较快的源,下载失败时自动尝试其他源。";
|
|
62
|
+
readonly sourceManualHelp: "仅从所选源下载;已下载并通过校验的文件会复用。";
|
|
57
63
|
readonly downloadCode: "错误码:{code}";
|
|
58
64
|
readonly reconnecting: "正在连接语音服务…";
|
|
59
65
|
readonly 'preparation.unprepared': "首次使用需要下载本地识别模型。";
|
|
@@ -85,7 +91,7 @@ export declare const zh: {
|
|
|
85
91
|
readonly requesting: "请允许使用麦克风…";
|
|
86
92
|
readonly recording: "正在录音…";
|
|
87
93
|
readonly interrupted: "录音中断,请重试。";
|
|
88
|
-
readonly local: "音频在运行 DSH
|
|
94
|
+
readonly local: "音频在运行 DSH 的机器上识别。需要下载模型时,请确保该机器能访问所选下载源及其文件服务。如需代理,请在该机器上配置。";
|
|
89
95
|
readonly cloud: "音频将发送至所选云端服务。";
|
|
90
96
|
readonly empty: "未识别到语音";
|
|
91
97
|
readonly cancelled: "已取消语音输入。";
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deepseek-ai/dsh-experimental-client-ui-voice-input",
|
|
3
3
|
"description": "Record speech and insert editable text into the conversation draft",
|
|
4
|
-
"version": "0.1.7-
|
|
4
|
+
"version": "0.1.7-rc.1",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -33,45 +33,45 @@
|
|
|
33
33
|
"license": "MIT",
|
|
34
34
|
"dependencies": {},
|
|
35
35
|
"peerDependencies": {
|
|
36
|
-
"@deepseek-ai/cordis": "
|
|
37
|
-
"@deepseek-ai/dsh-api-remotes": "
|
|
38
|
-
"@deepseek-ai/dsh-
|
|
39
|
-
"@deepseek-ai/dsh-client-locale": "
|
|
40
|
-
"@deepseek-ai/dsh-client-ui-
|
|
41
|
-
"@deepseek-ai/dsh-
|
|
42
|
-
"@deepseek-ai/dsh-client-ui-
|
|
43
|
-
"@deepseek-ai/dsh-client-ui-
|
|
44
|
-
"@deepseek-ai/dsh-client-ui-
|
|
45
|
-
"@deepseek-ai/dsh-session": "
|
|
46
|
-
"@deepseek-ai/dsh-
|
|
47
|
-
"@deepseek-ai/dsh-api-
|
|
48
|
-
"@deepseek-ai/dsh-
|
|
49
|
-
"@deepseek-ai/dsh-
|
|
50
|
-
"@deepseek-ai/dsh-client-ui-plugin-manager": "
|
|
51
|
-
"@deepseek-ai/dsh-
|
|
36
|
+
"@deepseek-ai/cordis": "~4.0.4",
|
|
37
|
+
"@deepseek-ai/dsh-api-remotes": "0.1.7-rc.1",
|
|
38
|
+
"@deepseek-ai/dsh-client-ui-conversation": "0.1.7-rc.1",
|
|
39
|
+
"@deepseek-ai/dsh-client-locale": "0.1.7-rc.1",
|
|
40
|
+
"@deepseek-ai/dsh-client-ui-primitives": "0.1.7-rc.1",
|
|
41
|
+
"@deepseek-ai/dsh-api-session-controller": "0.1.7-rc.1",
|
|
42
|
+
"@deepseek-ai/dsh-client-ui-renderer": "0.1.7-rc.1",
|
|
43
|
+
"@deepseek-ai/dsh-client-ui-slots": "0.1.7-rc.1",
|
|
44
|
+
"@deepseek-ai/dsh-client-ui-session": "0.1.7-rc.1",
|
|
45
|
+
"@deepseek-ai/dsh-session": "0.1.7-rc.1",
|
|
46
|
+
"@deepseek-ai/dsh-typert-protocol": "0.1.7-rc.1",
|
|
47
|
+
"@deepseek-ai/dsh-experimental-api-speech-to-text": "0.1.7-rc.1",
|
|
48
|
+
"@deepseek-ai/dsh-experimental-speech-to-text": "0.1.7-rc.1",
|
|
49
|
+
"@deepseek-ai/dsh-api-gateway": "0.1.7-rc.1",
|
|
50
|
+
"@deepseek-ai/dsh-client-ui-plugin-manager": "0.1.7-rc.1",
|
|
51
|
+
"@deepseek-ai/dsh-client-store": "0.1.7-rc.1"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
54
|
"@types/react": "~18.3.1",
|
|
55
55
|
"react": "^18.2.0",
|
|
56
56
|
"react-dom": "^18.2.0",
|
|
57
57
|
"@testing-library/react": "^16.1.0",
|
|
58
|
-
"@deepseek-ai/
|
|
59
|
-
"@deepseek-ai/dsh-api-
|
|
60
|
-
"@deepseek-ai/
|
|
61
|
-
"@deepseek-ai/dsh-client-
|
|
62
|
-
"@deepseek-ai/dsh-client-
|
|
63
|
-
"@deepseek-ai/dsh-client-ui-
|
|
64
|
-
"@deepseek-ai/dsh-client-ui-
|
|
65
|
-
"@deepseek-ai/dsh-
|
|
66
|
-
"@deepseek-ai/dsh-client-ui-slots": "
|
|
67
|
-
"@deepseek-ai/dsh-
|
|
68
|
-
"@deepseek-ai/dsh-
|
|
69
|
-
"@deepseek-ai/dsh-experimental-api-speech-to-text": "
|
|
70
|
-
"@deepseek-ai/dsh-
|
|
71
|
-
"@deepseek-ai/dsh-client-
|
|
72
|
-
"@deepseek-ai/dsh-api-gateway": "
|
|
73
|
-
"@deepseek-ai/dsh-client-store": "
|
|
74
|
-
"@deepseek-ai/dsh-client-ui-plugin-manager": "
|
|
58
|
+
"@deepseek-ai/cordis": "~4.0.4",
|
|
59
|
+
"@deepseek-ai/dsh-api-remotes": "0.1.7-rc.1",
|
|
60
|
+
"@deepseek-ai/dsh-api-session-controller": "0.1.7-rc.1",
|
|
61
|
+
"@deepseek-ai/dsh-client-ui-conversation": "0.1.7-rc.1",
|
|
62
|
+
"@deepseek-ai/dsh-client-locale": "0.1.7-rc.1",
|
|
63
|
+
"@deepseek-ai/dsh-client-ui-primitives": "0.1.7-rc.1",
|
|
64
|
+
"@deepseek-ai/dsh-client-ui-session": "0.1.7-rc.1",
|
|
65
|
+
"@deepseek-ai/dsh-session": "0.1.7-rc.1",
|
|
66
|
+
"@deepseek-ai/dsh-client-ui-slots": "0.1.7-rc.1",
|
|
67
|
+
"@deepseek-ai/dsh-typert-protocol": "0.1.7-rc.1",
|
|
68
|
+
"@deepseek-ai/dsh-experimental-speech-to-text": "0.1.7-rc.1",
|
|
69
|
+
"@deepseek-ai/dsh-experimental-api-speech-to-text": "0.1.7-rc.1",
|
|
70
|
+
"@deepseek-ai/dsh-client-test-runtime": "0.1.7-rc.1",
|
|
71
|
+
"@deepseek-ai/dsh-client-ui-renderer": "0.1.7-rc.1",
|
|
72
|
+
"@deepseek-ai/dsh-api-gateway": "0.1.7-rc.1",
|
|
73
|
+
"@deepseek-ai/dsh-client-store": "0.1.7-rc.1",
|
|
74
|
+
"@deepseek-ai/dsh-client-ui-plugin-manager": "0.1.7-rc.1"
|
|
75
75
|
},
|
|
76
76
|
"dsh": {
|
|
77
77
|
"client": {
|