@jingyi0605/codingns4dsh 0.2.1-beta.11 → 0.2.1-beta.12
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.en.md +7 -5
- package/README.md +9 -5
- package/data/build/dist/bootstrap/dsh-connection-adapter.d.ts +1 -1
- package/data/build/dist/bootstrap/index.d.ts +1 -1
- package/data/build/dist/client/bundle.js +2280 -1495
- package/data/build/dist/client/bundle.js.map +1 -1
- package/data/build/dist/client/cli-slots.d.ts +3 -2
- package/data/build/dist/client/cli-slots.d.ts.map +1 -1
- package/data/build/dist/client/cli-slots.js +29 -5
- package/data/build/dist/client/cli-slots.js.map +1 -1
- package/data/build/dist/client/client.assistant-configuration-view.js +5 -5
- package/data/build/dist/client/client.assistant-configuration-view.js.map +1 -1
- package/data/build/dist/client/client.moss-voice-output.js +0 -166
- package/data/build/dist/client/client.moss-voice-output.js.map +1 -1
- package/data/build/dist/client/client.native-workspace-store.js +4 -4
- package/data/build/dist/client/client.native-workspace-store.js.map +1 -1
- package/data/build/dist/client/client.react-dom.js +166 -0
- package/data/build/dist/client/client.react-dom.js.map +1 -1
- package/data/build/dist/client/client.session-translation.js +9 -1
- package/data/build/dist/client/client.session-translation.js.map +1 -1
- package/data/build/dist/client/client.transport.js +46 -0
- package/data/build/dist/client/client.transport.js.map +1 -1
- package/data/build/dist/client/conversation-translation-settings.d.ts +10 -0
- package/data/build/dist/client/conversation-translation-settings.d.ts.map +1 -0
- package/data/build/dist/client/conversation-translation-settings.js +52 -0
- package/data/build/dist/client/conversation-translation-settings.js.map +1 -0
- package/data/build/dist/client/desktop-assistant.js +512 -439
- package/data/build/dist/client/features/cli-adapters.js +1 -1
- package/data/build/dist/client/features/cli-adapters.js.map +1 -1
- package/data/build/dist/client/features/session-translation.d.ts.map +1 -1
- package/data/build/dist/client/features/session-translation.js +7 -1
- package/data/build/dist/client/features/session-translation.js.map +1 -1
- package/data/build/dist/client/locales/panels.d.ts.map +1 -1
- package/data/build/dist/client/locales/panels.js +46 -0
- package/data/build/dist/client/locales/panels.js.map +1 -1
- package/data/build/dist/client/session-translation-chat.d.ts +9 -3
- package/data/build/dist/client/session-translation-chat.d.ts.map +1 -1
- package/data/build/dist/client/session-translation-chat.js +146 -48
- package/data/build/dist/client/session-translation-chat.js.map +1 -1
- package/data/build/dist/client/session-translation-pending-dom.d.ts +1 -1
- package/data/build/dist/client/session-translation-pending-dom.d.ts.map +1 -1
- package/data/build/dist/client/session-translation-pending-dom.js +4 -4
- package/data/build/dist/client/session-translation-pending-dom.js.map +1 -1
- package/data/build/dist/client/session-translation-retry.d.ts +16 -0
- package/data/build/dist/client/session-translation-retry.d.ts.map +1 -0
- package/data/build/dist/client/session-translation-retry.js +66 -0
- package/data/build/dist/client/session-translation-retry.js.map +1 -0
- package/data/build/dist/client/session-translation-rules.d.ts +13 -0
- package/data/build/dist/client/session-translation-rules.d.ts.map +1 -0
- package/data/build/dist/client/session-translation-rules.js +58 -0
- package/data/build/dist/client/session-translation-rules.js.map +1 -0
- package/data/build/dist/client/style.css +276 -276
- package/data/build/dist/dsh-capabilities/client/interaction-presentation-adapter.d.ts.map +1 -1
- package/data/build/dist/dsh-capabilities/client/interaction-presentation-adapter.js +4 -13
- package/data/build/dist/dsh-capabilities/client/interaction-presentation-adapter.js.map +1 -1
- package/data/build/dist/dsh-capabilities/client/interaction-text-dom.js +1 -1
- package/data/build/dist/dsh-capabilities/client/interaction-text-dom.js.map +1 -1
- package/data/build/dist/dsh-capabilities/client/message-presentation-adapter.d.ts +19 -0
- package/data/build/dist/dsh-capabilities/client/message-presentation-adapter.d.ts.map +1 -0
- package/data/build/dist/dsh-capabilities/client/message-presentation-adapter.js +39 -0
- package/data/build/dist/dsh-capabilities/client/message-presentation-adapter.js.map +1 -0
- package/data/build/dist/dsh-capabilities/client/slot-presentation-mirror.d.ts +2 -0
- package/data/build/dist/dsh-capabilities/client/slot-presentation-mirror.d.ts.map +1 -1
- package/data/build/dist/dsh-capabilities/client/slot-presentation-mirror.js +28 -0
- package/data/build/dist/dsh-capabilities/client/slot-presentation-mirror.js.map +1 -1
- package/data/build/dist/dsh-capabilities/host/connection-peer-adapter.d.ts +10 -0
- package/data/build/dist/dsh-capabilities/host/connection-peer-adapter.d.ts.map +1 -0
- package/data/build/dist/dsh-capabilities/host/connection-peer-adapter.js +34 -0
- package/data/build/dist/dsh-capabilities/host/connection-peer-adapter.js.map +1 -0
- package/data/build/dist/dsh-capabilities/host/native-dispatch-adapter.d.ts +21 -0
- package/data/build/dist/dsh-capabilities/host/native-dispatch-adapter.d.ts.map +1 -0
- package/data/build/dist/dsh-capabilities/host/native-dispatch-adapter.js +11 -0
- package/data/build/dist/dsh-capabilities/host/native-dispatch-adapter.js.map +1 -0
- package/data/build/dist/dsh-capabilities/host/session-activation-adapter.d.ts +17 -0
- package/data/build/dist/dsh-capabilities/host/session-activation-adapter.d.ts.map +1 -0
- package/data/build/dist/dsh-capabilities/host/session-activation-adapter.js +37 -0
- package/data/build/dist/dsh-capabilities/host/session-activation-adapter.js.map +1 -0
- package/data/build/dist/dsh-capabilities/host/session-model-selection-adapter.d.ts +17 -0
- package/data/build/dist/dsh-capabilities/host/session-model-selection-adapter.d.ts.map +1 -0
- package/data/build/dist/dsh-capabilities/host/session-model-selection-adapter.js +45 -0
- package/data/build/dist/dsh-capabilities/host/session-model-selection-adapter.js.map +1 -0
- package/data/build/dist/dsh-capabilities/host/session-prompt-adapter.d.ts +28 -0
- package/data/build/dist/dsh-capabilities/host/session-prompt-adapter.d.ts.map +1 -0
- package/data/build/dist/dsh-capabilities/host/session-prompt-adapter.js +31 -0
- package/data/build/dist/dsh-capabilities/host/session-prompt-adapter.js.map +1 -0
- package/data/build/dist/dsh-capabilities/matrix.d.ts.map +1 -1
- package/data/build/dist/dsh-capabilities/matrix.js +12 -4
- package/data/build/dist/dsh-capabilities/matrix.js.map +1 -1
- package/data/build/dist/dsh-capabilities/routes.d.ts.map +1 -1
- package/data/build/dist/dsh-capabilities/routes.js +25 -5
- package/data/build/dist/dsh-capabilities/routes.js.map +1 -1
- package/data/build/dist/dsh-capabilities/types.d.ts +1 -1
- package/data/build/dist/dsh-capabilities/types.d.ts.map +1 -1
- package/data/build/dist/dsh-capabilities/types.js.map +1 -1
- package/data/build/dist/host/cli-adapters/antigravity-driver.js +1 -1
- package/data/build/dist/host/cli-adapters/antigravity-driver.js.map +1 -1
- package/data/build/dist/host/cli-adapters/attachment-utils.d.ts +4 -3
- package/data/build/dist/host/cli-adapters/attachment-utils.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/attachment-utils.js +9 -8
- package/data/build/dist/host/cli-adapters/attachment-utils.js.map +1 -1
- package/data/build/dist/host/cli-adapters/claude-driver.js +1 -1
- package/data/build/dist/host/cli-adapters/claude-driver.js.map +1 -1
- package/data/build/dist/host/cli-adapters/command-code-driver.js +1 -1
- package/data/build/dist/host/cli-adapters/command-code-driver.js.map +1 -1
- package/data/build/dist/host/cli-adapters/driver.d.ts +2 -0
- package/data/build/dist/host/cli-adapters/driver.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/dsh-message-projector.d.ts +2 -0
- package/data/build/dist/host/cli-adapters/dsh-message-projector.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/dsh-message-projector.js +11 -3
- package/data/build/dist/host/cli-adapters/dsh-message-projector.js.map +1 -1
- package/data/build/dist/host/cli-adapters/feature.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/feature.js +154 -68
- package/data/build/dist/host/cli-adapters/feature.js.map +1 -1
- package/data/build/dist/host/cli-adapters/gemini-driver.js +1 -1
- package/data/build/dist/host/cli-adapters/gemini-driver.js.map +1 -1
- package/data/build/dist/host/cli-adapters/grok-driver.d.ts +1 -0
- package/data/build/dist/host/cli-adapters/grok-driver.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/grok-driver.js +128 -40
- package/data/build/dist/host/cli-adapters/grok-driver.js.map +1 -1
- package/data/build/dist/host/cli-adapters/kimi-driver.js +2 -2
- package/data/build/dist/host/cli-adapters/kimi-driver.js.map +1 -1
- package/data/build/dist/host/cli-adapters/mcode-driver.js +1 -1
- package/data/build/dist/host/cli-adapters/mcode-driver.js.map +1 -1
- package/data/build/dist/host/cli-adapters/native-team-subagent.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/native-team-subagent.js +2 -1
- package/data/build/dist/host/cli-adapters/native-team-subagent.js.map +1 -1
- package/data/build/dist/host/cli-adapters/pi-driver.js +1 -1
- package/data/build/dist/host/cli-adapters/pi-driver.js.map +1 -1
- package/data/build/dist/host/cli-adapters/registry.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/registry.js +23 -16
- package/data/build/dist/host/cli-adapters/registry.js.map +1 -1
- package/data/build/dist/host/cli-adapters/zcode-driver.js +1 -1
- package/data/build/dist/host/cli-adapters/zcode-driver.js.map +1 -1
- package/data/build/dist/host/features/global-voice-rpc.d.ts.map +1 -1
- package/data/build/dist/host/features/global-voice-rpc.js +2 -3
- package/data/build/dist/host/features/global-voice-rpc.js.map +1 -1
- package/data/build/dist/host/features/peer-host.js +6 -6
- package/data/build/dist/host/features/peer-host.js.map +1 -1
- package/data/build/dist/host/features/session-prompt-translation.d.ts +10 -0
- package/data/build/dist/host/features/session-prompt-translation.d.ts.map +1 -0
- package/data/build/dist/host/features/session-prompt-translation.js +197 -0
- package/data/build/dist/host/features/session-prompt-translation.js.map +1 -0
- package/data/build/dist/host/features/session-translation-protection.d.ts +6 -1
- package/data/build/dist/host/features/session-translation-protection.d.ts.map +1 -1
- package/data/build/dist/host/features/session-translation-protection.js +23 -5
- package/data/build/dist/host/features/session-translation-protection.js.map +1 -1
- package/data/build/dist/host/features/session-translation-recovery.d.ts +20 -0
- package/data/build/dist/host/features/session-translation-recovery.d.ts.map +1 -0
- package/data/build/dist/host/features/session-translation-recovery.js +122 -0
- package/data/build/dist/host/features/session-translation-recovery.js.map +1 -0
- package/data/build/dist/host/features/session-translation-service.d.ts +5 -2
- package/data/build/dist/host/features/session-translation-service.d.ts.map +1 -1
- package/data/build/dist/host/features/session-translation-service.js +60 -16
- package/data/build/dist/host/features/session-translation-service.js.map +1 -1
- package/data/build/dist/host/features/session-translation.d.ts.map +1 -1
- package/data/build/dist/host/features/session-translation.js +4 -1
- package/data/build/dist/host/features/session-translation.js.map +1 -1
- package/data/build/dist/host/modules/peer-host/peer-host-native-dispatch.d.ts +2 -2
- package/data/build/dist/host/modules/peer-host/peer-host-native-dispatch.d.ts.map +1 -1
- package/data/build/dist/host/modules/peer-host/peer-host-native-dispatch.js +10 -9
- package/data/build/dist/host/modules/peer-host/peer-host-native-dispatch.js.map +1 -1
- package/data/build/dist/host/modules/peer-host/peer-host-native-streams.d.ts +3 -3
- package/data/build/dist/host/modules/peer-host/peer-host-native-streams.d.ts.map +1 -1
- package/data/build/dist/host/modules/peer-host/peer-host-native-streams.js +26 -14
- package/data/build/dist/host/modules/peer-host/peer-host-native-streams.js.map +1 -1
- package/data/build/dist/host/native-session-bridge.d.ts +2 -1
- package/data/build/dist/host/native-session-bridge.d.ts.map +1 -1
- package/data/build/dist/host/native-session-bridge.js +5 -13
- package/data/build/dist/host/native-session-bridge.js.map +1 -1
- package/data/build/dist/host/rpc.d.ts.map +1 -1
- package/data/build/dist/host/rpc.js +14 -8
- package/data/build/dist/host/rpc.js.map +1 -1
- package/data/build/dist/host/settings.d.ts.map +1 -1
- package/data/build/dist/host/settings.js +5 -1
- package/data/build/dist/host/settings.js.map +1 -1
- package/data/build/dist/shared/attachment-prompts.d.ts +11 -0
- package/data/build/dist/shared/attachment-prompts.d.ts.map +1 -0
- package/data/build/dist/shared/attachment-prompts.js +17 -0
- package/data/build/dist/shared/attachment-prompts.js.map +1 -0
- package/data/build/dist/shared/contracts/cli-adapter.d.ts +8 -1
- package/data/build/dist/shared/contracts/cli-adapter.d.ts.map +1 -1
- package/data/build/dist/shared/contracts/errors.d.ts +2 -2
- package/data/build/dist/shared/contracts/session-translation.d.ts +13 -0
- package/data/build/dist/shared/contracts/session-translation.d.ts.map +1 -1
- package/data/build/dist/shared/contracts/session-translation.js +10 -0
- package/data/build/dist/shared/contracts/session-translation.js.map +1 -1
- package/data/build/dist/shared/contracts/version.d.ts +4 -4
- package/data/build/dist/shared/contracts/version.js +3 -3
- package/package.json +35 -34
- package/profile/README.md +2 -2
- package/profile/package.json +3 -3
- package/profile/version.json +3 -3
- package/version.json +3 -3
|
@@ -7554,150 +7554,8 @@ window.__ModuleLoader__.load({
|
|
|
7554
7554
|
factory: () => { const require = __codingnsOwnerRequire;
|
|
7555
7555
|
var module = { exports: {} };
|
|
7556
7556
|
var exports = module.exports;
|
|
7557
|
-
const require_theme = require("@jingyi0605/codingns4dsh/client.theme.js");
|
|
7558
7557
|
const require_manager = require("@jingyi0605/codingns4dsh/client.manager.js");
|
|
7559
7558
|
const require_primitives_adapter = require("@jingyi0605/codingns4dsh/client.primitives-adapter.js");
|
|
7560
|
-
let react = require("react");
|
|
7561
|
-
//#region src/client/settings-controls.ts
|
|
7562
|
-
const settingsControlClass = {
|
|
7563
|
-
switch: "codingns4dsh-settings-switch",
|
|
7564
|
-
track: "codingns4dsh-settings-switch-track",
|
|
7565
|
-
thumb: "codingns4dsh-settings-switch-thumb",
|
|
7566
|
-
iconButton: "codingns4dsh-settings-icon-button"
|
|
7567
|
-
};
|
|
7568
|
-
/** 模块使用主开关,子设置使用更小、更轻的开关;保留 checkbox 的标签与键盘语义。 */
|
|
7569
|
-
function SettingsSwitch(props) {
|
|
7570
|
-
(0, react.useEffect)(() => retainSettingsControlStyles(), []);
|
|
7571
|
-
const { variant = "setting", ...inputProps } = props;
|
|
7572
|
-
const width = variant === "module" ? 36 : 28;
|
|
7573
|
-
return (0, react.createElement)("span", {
|
|
7574
|
-
className: settingsControlClass.switch,
|
|
7575
|
-
"data-variant": variant,
|
|
7576
|
-
style: {
|
|
7577
|
-
position: "relative",
|
|
7578
|
-
display: "inline-flex",
|
|
7579
|
-
alignItems: "center",
|
|
7580
|
-
flex: `0 0 ${width}px`,
|
|
7581
|
-
width,
|
|
7582
|
-
height: 28,
|
|
7583
|
-
marginLeft: "auto"
|
|
7584
|
-
}
|
|
7585
|
-
}, (0, react.createElement)("input", {
|
|
7586
|
-
type: "checkbox",
|
|
7587
|
-
role: "switch",
|
|
7588
|
-
...inputProps,
|
|
7589
|
-
style: {
|
|
7590
|
-
position: "absolute",
|
|
7591
|
-
inset: 0,
|
|
7592
|
-
width: "100%",
|
|
7593
|
-
height: "100%",
|
|
7594
|
-
margin: 0,
|
|
7595
|
-
opacity: 0,
|
|
7596
|
-
cursor: props.disabled ? "not-allowed" : "pointer",
|
|
7597
|
-
zIndex: 1
|
|
7598
|
-
}
|
|
7599
|
-
}), (0, react.createElement)("span", {
|
|
7600
|
-
className: settingsControlClass.track,
|
|
7601
|
-
"aria-hidden": true
|
|
7602
|
-
}, (0, react.createElement)("span", { className: settingsControlClass.thumb })));
|
|
7603
|
-
}
|
|
7604
|
-
/** 文案占据剩余宽度;右侧操作不收缩,长说明和窄屏都不会移动开关。 */
|
|
7605
|
-
function SettingsToggleRow({ label, description, checked, disabled, onChange, actions, style }) {
|
|
7606
|
-
const id = (0, react.useId)();
|
|
7607
|
-
return (0, react.createElement)("div", { style: {
|
|
7608
|
-
...require_theme.dshSettingsListRowStyle,
|
|
7609
|
-
...style
|
|
7610
|
-
} }, (0, react.createElement)("label", {
|
|
7611
|
-
htmlFor: id,
|
|
7612
|
-
style: {
|
|
7613
|
-
flex: "1 1 auto",
|
|
7614
|
-
minWidth: 0,
|
|
7615
|
-
cursor: disabled ? "not-allowed" : "pointer",
|
|
7616
|
-
overflowWrap: "anywhere"
|
|
7617
|
-
}
|
|
7618
|
-
}, (0, react.createElement)("span", { style: {
|
|
7619
|
-
display: "block",
|
|
7620
|
-
fontSize: require_theme.uiFontSize(13),
|
|
7621
|
-
fontWeight: 500,
|
|
7622
|
-
lineHeight: 1.4
|
|
7623
|
-
} }, label), description === void 0 ? null : (0, react.createElement)("span", { style: {
|
|
7624
|
-
display: "block",
|
|
7625
|
-
marginTop: 3,
|
|
7626
|
-
...require_theme.dshSettingsHelpStyle
|
|
7627
|
-
} }, description)), (0, react.createElement)("span", { style: {
|
|
7628
|
-
display: "inline-flex",
|
|
7629
|
-
alignItems: "center",
|
|
7630
|
-
gap: 10,
|
|
7631
|
-
flex: "0 0 auto",
|
|
7632
|
-
marginLeft: "auto"
|
|
7633
|
-
} }, actions, (0, react.createElement)(SettingsSwitch, {
|
|
7634
|
-
id,
|
|
7635
|
-
"aria-label": label,
|
|
7636
|
-
checked,
|
|
7637
|
-
disabled,
|
|
7638
|
-
onChange: (event) => onChange(event.currentTarget.checked)
|
|
7639
|
-
})));
|
|
7640
|
-
}
|
|
7641
|
-
/** 图标按钮采用 DSH 的紧凑中性表面,交互态由共享样式表提供。 */
|
|
7642
|
-
const settingsIconButtonStyle = {
|
|
7643
|
-
display: "inline-flex",
|
|
7644
|
-
alignItems: "center",
|
|
7645
|
-
justifyContent: "center",
|
|
7646
|
-
flex: "0 0 32px",
|
|
7647
|
-
width: 32,
|
|
7648
|
-
height: 32,
|
|
7649
|
-
padding: 0,
|
|
7650
|
-
boxSizing: "border-box",
|
|
7651
|
-
border: 0,
|
|
7652
|
-
borderRadius: "var(--dsw-radius-sm, 6px)",
|
|
7653
|
-
color: require_theme.dshThemeColor.labelSecondary,
|
|
7654
|
-
background: "transparent",
|
|
7655
|
-
cursor: "pointer"
|
|
7656
|
-
};
|
|
7657
|
-
/** 各独立面板共享一份样式,最后一个开关卸载时释放,兼容 React 严格模式的重复挂载。 */
|
|
7658
|
-
const retainedStyles = /* @__PURE__ */ new WeakMap();
|
|
7659
|
-
function retainSettingsControlStyles() {
|
|
7660
|
-
if (typeof document === "undefined") return () => void 0;
|
|
7661
|
-
const dom = document;
|
|
7662
|
-
let state = retainedStyles.get(dom);
|
|
7663
|
-
if (state === void 0) {
|
|
7664
|
-
const element = dom.createElement("style");
|
|
7665
|
-
element.dataset.plugin = "codingns4dsh";
|
|
7666
|
-
element.dataset.pluginCss = "codingns4dsh-settings-controls";
|
|
7667
|
-
element.textContent = settingsControlCss;
|
|
7668
|
-
dom.head.appendChild(element);
|
|
7669
|
-
state = {
|
|
7670
|
-
element,
|
|
7671
|
-
users: 0
|
|
7672
|
-
};
|
|
7673
|
-
retainedStyles.set(dom, state);
|
|
7674
|
-
}
|
|
7675
|
-
const retained = state;
|
|
7676
|
-
retained.users += 1;
|
|
7677
|
-
return () => {
|
|
7678
|
-
retained.users -= 1;
|
|
7679
|
-
if (retained.users > 0) return;
|
|
7680
|
-
retained.element.remove();
|
|
7681
|
-
retainedStyles.delete(dom);
|
|
7682
|
-
};
|
|
7683
|
-
}
|
|
7684
|
-
const settingsControlCss = `
|
|
7685
|
-
.${settingsControlClass.switch}{--codingns-switch-height:16px;--codingns-switch-thumb:12px;--codingns-switch-travel:12px;--codingns-switch-active:var(--dsw-alias-button-info-fill);--codingns-switch-active-thumb:var(--dsw-static-neutral-00)}
|
|
7686
|
-
.${settingsControlClass.switch}[data-variant="module"]{--codingns-switch-height:20px;--codingns-switch-thumb:16px;--codingns-switch-travel:16px;--codingns-switch-active:var(--dsw-alias-brand-primary);--codingns-switch-active-thumb:var(--dsw-alias-label-primary-foreground)}
|
|
7687
|
-
.${settingsControlClass.track}{box-sizing:border-box;display:block;width:100%;height:var(--codingns-switch-height);padding:2px;border:0;border-radius:999px;corner-shape:round;background:var(--dsw-alias-border-l3);pointer-events:none;transition:background 120ms ease}
|
|
7688
|
-
.${settingsControlClass.thumb}{display:block;width:var(--codingns-switch-thumb);height:var(--codingns-switch-thumb);border-radius:50%;corner-shape:round;background:var(--dsw-alias-switch-thumb);transition:transform 120ms ease,background 120ms ease}
|
|
7689
|
-
.${settingsControlClass.switch}>input:checked+.${settingsControlClass.track}{background:var(--codingns-switch-active)}
|
|
7690
|
-
.${settingsControlClass.switch}>input:checked+.${settingsControlClass.track}>.${settingsControlClass.thumb}{background:var(--codingns-switch-active-thumb);transform:translateX(var(--codingns-switch-travel))}
|
|
7691
|
-
.${settingsControlClass.switch}>input:disabled+.${settingsControlClass.track}{opacity:.5}
|
|
7692
|
-
.${settingsControlClass.switch}>input:disabled{cursor:not-allowed!important}
|
|
7693
|
-
.${settingsControlClass.switch}>input:focus-visible+.${settingsControlClass.track}{outline:${require_theme.dshThemeColor.focusRing};outline-offset:3px}
|
|
7694
|
-
.${settingsControlClass.iconButton}:hover:not(:disabled){color:${require_theme.dshThemeColor.labelPrimary};background:${require_theme.dshThemeColor.hoverBackground}}
|
|
7695
|
-
.${settingsControlClass.iconButton}:active:not(:disabled){background:${require_theme.dshThemeColor.activeBackground}}
|
|
7696
|
-
.${settingsControlClass.iconButton}:focus-visible{outline:${require_theme.dshThemeColor.focusRing};outline-offset:2px}
|
|
7697
|
-
.${settingsControlClass.iconButton}:disabled{opacity:.5;cursor:not-allowed}
|
|
7698
|
-
@media (prefers-reduced-motion:reduce){.${settingsControlClass.track},.${settingsControlClass.thumb}{transition:none}}
|
|
7699
|
-
`;
|
|
7700
|
-
//#endregion
|
|
7701
7559
|
//#region src/client/peer-host-color.ts
|
|
7702
7560
|
/**
|
|
7703
7561
|
* 工作区标签配色的推导与缓存。
|
|
@@ -8070,18 +7928,6 @@ window.__ModuleLoader__.load({
|
|
|
8070
7928
|
return MossVoiceOutput;
|
|
8071
7929
|
}
|
|
8072
7930
|
});
|
|
8073
|
-
Object.defineProperty(exports, "SettingsSwitch", {
|
|
8074
|
-
enumerable: true,
|
|
8075
|
-
get: function() {
|
|
8076
|
-
return SettingsSwitch;
|
|
8077
|
-
}
|
|
8078
|
-
});
|
|
8079
|
-
Object.defineProperty(exports, "SettingsToggleRow", {
|
|
8080
|
-
enumerable: true,
|
|
8081
|
-
get: function() {
|
|
8082
|
-
return SettingsToggleRow;
|
|
8083
|
-
}
|
|
8084
|
-
});
|
|
8085
7931
|
Object.defineProperty(exports, "peerHostTagStyle", {
|
|
8086
7932
|
enumerable: true,
|
|
8087
7933
|
get: function() {
|
|
@@ -8100,18 +7946,6 @@ window.__ModuleLoader__.load({
|
|
|
8100
7946
|
return sanitizeVoiceDiagnosticFields;
|
|
8101
7947
|
}
|
|
8102
7948
|
});
|
|
8103
|
-
Object.defineProperty(exports, "settingsControlClass", {
|
|
8104
|
-
enumerable: true,
|
|
8105
|
-
get: function() {
|
|
8106
|
-
return settingsControlClass;
|
|
8107
|
-
}
|
|
8108
|
-
});
|
|
8109
|
-
Object.defineProperty(exports, "settingsIconButtonStyle", {
|
|
8110
|
-
enumerable: true,
|
|
8111
|
-
get: function() {
|
|
8112
|
-
return settingsIconButtonStyle;
|
|
8113
|
-
}
|
|
8114
|
-
});
|
|
8115
7949
|
Object.defineProperty(exports, "voiceDiagnosticError", {
|
|
8116
7950
|
enumerable: true,
|
|
8117
7951
|
get: function() {
|
|
@@ -8138,7 +7972,7 @@ window.__ModuleLoader__.load({
|
|
|
8138
7972
|
const require_session_translation = require("@jingyi0605/codingns4dsh/client.session-translation.js");
|
|
8139
7973
|
//#region src/shared/contracts/version.ts
|
|
8140
7974
|
/** 当前经过完整验证的 DSH 版本;源文件由根目录 version.json 同步。 */
|
|
8141
|
-
const DSH_VERSION = "0.2.1-alpha.
|
|
7975
|
+
const DSH_VERSION = "0.2.1-alpha.3";
|
|
8142
7976
|
/**
|
|
8143
7977
|
* 插件正式验证的 DSH 版本范围,覆盖 rc.2 到当前验证的 alpha.2。
|
|
8144
7978
|
*
|
|
@@ -8151,7 +7985,7 @@ window.__ModuleLoader__.load({
|
|
|
8151
7985
|
* 这里保留明确上界,是为了让 npm/DSH 安装期也能识别 0.2.1-alpha.2 这个跨 patch
|
|
8152
7986
|
* 预发布版本;出现新的 API 世代或结构变化时,应重新验证并更新范围与能力路由。
|
|
8153
7987
|
*/
|
|
8154
|
-
const DSH_COMPATIBILITY = ">=0.2.0-rc.2 <=0.2.1-alpha.
|
|
7988
|
+
const DSH_COMPATIBILITY = ">=0.2.0-rc.2 <=0.2.1-alpha.3";
|
|
8155
7989
|
/**
|
|
8156
7990
|
* 兼容范围下界,即插件仍然接受的最低 DSH 版本。
|
|
8157
7991
|
*
|
|
@@ -8160,7 +7994,7 @@ window.__ModuleLoader__.load({
|
|
|
8160
7994
|
* “不支持的 DSH 版本”,把仅仅缺少启动页注入的页面误判为宿主不兼容。
|
|
8161
7995
|
*/
|
|
8162
7996
|
function minimumSupportedDshVersion() {
|
|
8163
|
-
return /^>=([^ ]+)/u.exec(">=0.2.0-rc.2 <=0.2.1-alpha.
|
|
7997
|
+
return /^>=([^ ]+)/u.exec(">=0.2.0-rc.2 <=0.2.1-alpha.3")?.[1] ?? "0.2.1-alpha.3";
|
|
8164
7998
|
}
|
|
8165
7999
|
/** Host 注入到浏览器页面的真实 DSH 版本全局字段。 */
|
|
8166
8000
|
const CODINGNS_DSH_VERSION_GLOBAL = "__CODINGNS_DSH_VERSION__";
|
|
@@ -8169,7 +8003,7 @@ window.__ModuleLoader__.load({
|
|
|
8169
8003
|
return /^0\.1\.5(?:-|$)/u.test(version);
|
|
8170
8004
|
}
|
|
8171
8005
|
/** Codingns4DSH 插件自身的 npm 版本。 */
|
|
8172
|
-
const CODINGNS_VERSION = "0.2.1-beta.
|
|
8006
|
+
const CODINGNS_VERSION = "0.2.1-beta.12";
|
|
8173
8007
|
/** 判断宿主版本是否落在当前插件声明的 DSH 兼容范围内;范围省略上界时不校验上限。 */
|
|
8174
8008
|
function isDshVersionCompatible(version) {
|
|
8175
8009
|
const match = /^>=([^ ]+)(?: <=([^ ]+))?$/u.exec(DSH_COMPATIBILITY);
|
|
@@ -9222,6 +9056,148 @@ window.__ModuleLoader__.load({
|
|
|
9222
9056
|
var module = { exports: {} };
|
|
9223
9057
|
var exports = module.exports;
|
|
9224
9058
|
const require_rolldown_runtime = require("@jingyi0605/codingns4dsh/client.rolldown-runtime.js");
|
|
9059
|
+
const require_theme = require("@jingyi0605/codingns4dsh/client.theme.js");
|
|
9060
|
+
let react = require("react");
|
|
9061
|
+
//#region src/client/settings-controls.ts
|
|
9062
|
+
const settingsControlClass = {
|
|
9063
|
+
switch: "codingns4dsh-settings-switch",
|
|
9064
|
+
track: "codingns4dsh-settings-switch-track",
|
|
9065
|
+
thumb: "codingns4dsh-settings-switch-thumb",
|
|
9066
|
+
iconButton: "codingns4dsh-settings-icon-button"
|
|
9067
|
+
};
|
|
9068
|
+
/** 模块使用主开关,子设置使用更小、更轻的开关;保留 checkbox 的标签与键盘语义。 */
|
|
9069
|
+
function SettingsSwitch(props) {
|
|
9070
|
+
(0, react.useEffect)(() => retainSettingsControlStyles(), []);
|
|
9071
|
+
const { variant = "setting", ...inputProps } = props;
|
|
9072
|
+
const width = variant === "module" ? 36 : 28;
|
|
9073
|
+
return (0, react.createElement)("span", {
|
|
9074
|
+
className: settingsControlClass.switch,
|
|
9075
|
+
"data-variant": variant,
|
|
9076
|
+
style: {
|
|
9077
|
+
position: "relative",
|
|
9078
|
+
display: "inline-flex",
|
|
9079
|
+
alignItems: "center",
|
|
9080
|
+
flex: `0 0 ${width}px`,
|
|
9081
|
+
width,
|
|
9082
|
+
height: 28,
|
|
9083
|
+
marginLeft: "auto"
|
|
9084
|
+
}
|
|
9085
|
+
}, (0, react.createElement)("input", {
|
|
9086
|
+
type: "checkbox",
|
|
9087
|
+
role: "switch",
|
|
9088
|
+
...inputProps,
|
|
9089
|
+
style: {
|
|
9090
|
+
position: "absolute",
|
|
9091
|
+
inset: 0,
|
|
9092
|
+
width: "100%",
|
|
9093
|
+
height: "100%",
|
|
9094
|
+
margin: 0,
|
|
9095
|
+
opacity: 0,
|
|
9096
|
+
cursor: props.disabled ? "not-allowed" : "pointer",
|
|
9097
|
+
zIndex: 1
|
|
9098
|
+
}
|
|
9099
|
+
}), (0, react.createElement)("span", {
|
|
9100
|
+
className: settingsControlClass.track,
|
|
9101
|
+
"aria-hidden": true
|
|
9102
|
+
}, (0, react.createElement)("span", { className: settingsControlClass.thumb })));
|
|
9103
|
+
}
|
|
9104
|
+
/** 文案占据剩余宽度;右侧操作不收缩,长说明和窄屏都不会移动开关。 */
|
|
9105
|
+
function SettingsToggleRow({ label, description, checked, disabled, onChange, actions, style }) {
|
|
9106
|
+
const id = (0, react.useId)();
|
|
9107
|
+
return (0, react.createElement)("div", { style: {
|
|
9108
|
+
...require_theme.dshSettingsListRowStyle,
|
|
9109
|
+
...style
|
|
9110
|
+
} }, (0, react.createElement)("label", {
|
|
9111
|
+
htmlFor: id,
|
|
9112
|
+
style: {
|
|
9113
|
+
flex: "1 1 auto",
|
|
9114
|
+
minWidth: 0,
|
|
9115
|
+
cursor: disabled ? "not-allowed" : "pointer",
|
|
9116
|
+
overflowWrap: "anywhere"
|
|
9117
|
+
}
|
|
9118
|
+
}, (0, react.createElement)("span", { style: {
|
|
9119
|
+
display: "block",
|
|
9120
|
+
fontSize: require_theme.uiFontSize(13),
|
|
9121
|
+
fontWeight: 500,
|
|
9122
|
+
lineHeight: 1.4
|
|
9123
|
+
} }, label), description === void 0 ? null : (0, react.createElement)("span", { style: {
|
|
9124
|
+
display: "block",
|
|
9125
|
+
marginTop: 3,
|
|
9126
|
+
...require_theme.dshSettingsHelpStyle
|
|
9127
|
+
} }, description)), (0, react.createElement)("span", { style: {
|
|
9128
|
+
display: "inline-flex",
|
|
9129
|
+
alignItems: "center",
|
|
9130
|
+
gap: 10,
|
|
9131
|
+
flex: "0 0 auto",
|
|
9132
|
+
marginLeft: "auto"
|
|
9133
|
+
} }, actions, (0, react.createElement)(SettingsSwitch, {
|
|
9134
|
+
id,
|
|
9135
|
+
"aria-label": label,
|
|
9136
|
+
checked,
|
|
9137
|
+
disabled,
|
|
9138
|
+
onChange: (event) => onChange(event.currentTarget.checked)
|
|
9139
|
+
})));
|
|
9140
|
+
}
|
|
9141
|
+
/** 图标按钮采用 DSH 的紧凑中性表面,交互态由共享样式表提供。 */
|
|
9142
|
+
const settingsIconButtonStyle = {
|
|
9143
|
+
display: "inline-flex",
|
|
9144
|
+
alignItems: "center",
|
|
9145
|
+
justifyContent: "center",
|
|
9146
|
+
flex: "0 0 32px",
|
|
9147
|
+
width: 32,
|
|
9148
|
+
height: 32,
|
|
9149
|
+
padding: 0,
|
|
9150
|
+
boxSizing: "border-box",
|
|
9151
|
+
border: 0,
|
|
9152
|
+
borderRadius: "var(--dsw-radius-sm, 6px)",
|
|
9153
|
+
color: require_theme.dshThemeColor.labelSecondary,
|
|
9154
|
+
background: "transparent",
|
|
9155
|
+
cursor: "pointer"
|
|
9156
|
+
};
|
|
9157
|
+
/** 各独立面板共享一份样式,最后一个开关卸载时释放,兼容 React 严格模式的重复挂载。 */
|
|
9158
|
+
const retainedStyles = /* @__PURE__ */ new WeakMap();
|
|
9159
|
+
function retainSettingsControlStyles() {
|
|
9160
|
+
if (typeof document === "undefined") return () => void 0;
|
|
9161
|
+
const dom = document;
|
|
9162
|
+
let state = retainedStyles.get(dom);
|
|
9163
|
+
if (state === void 0) {
|
|
9164
|
+
const element = dom.createElement("style");
|
|
9165
|
+
element.dataset.plugin = "codingns4dsh";
|
|
9166
|
+
element.dataset.pluginCss = "codingns4dsh-settings-controls";
|
|
9167
|
+
element.textContent = settingsControlCss;
|
|
9168
|
+
dom.head.appendChild(element);
|
|
9169
|
+
state = {
|
|
9170
|
+
element,
|
|
9171
|
+
users: 0
|
|
9172
|
+
};
|
|
9173
|
+
retainedStyles.set(dom, state);
|
|
9174
|
+
}
|
|
9175
|
+
const retained = state;
|
|
9176
|
+
retained.users += 1;
|
|
9177
|
+
return () => {
|
|
9178
|
+
retained.users -= 1;
|
|
9179
|
+
if (retained.users > 0) return;
|
|
9180
|
+
retained.element.remove();
|
|
9181
|
+
retainedStyles.delete(dom);
|
|
9182
|
+
};
|
|
9183
|
+
}
|
|
9184
|
+
const settingsControlCss = `
|
|
9185
|
+
.${settingsControlClass.switch}{--codingns-switch-height:16px;--codingns-switch-thumb:12px;--codingns-switch-travel:12px;--codingns-switch-active:var(--dsw-alias-button-info-fill);--codingns-switch-active-thumb:var(--dsw-static-neutral-00)}
|
|
9186
|
+
.${settingsControlClass.switch}[data-variant="module"]{--codingns-switch-height:20px;--codingns-switch-thumb:16px;--codingns-switch-travel:16px;--codingns-switch-active:var(--dsw-alias-brand-primary);--codingns-switch-active-thumb:var(--dsw-alias-label-primary-foreground)}
|
|
9187
|
+
.${settingsControlClass.track}{box-sizing:border-box;display:block;width:100%;height:var(--codingns-switch-height);padding:2px;border:0;border-radius:999px;corner-shape:round;background:var(--dsw-alias-border-l3);pointer-events:none;transition:background 120ms ease}
|
|
9188
|
+
.${settingsControlClass.thumb}{display:block;width:var(--codingns-switch-thumb);height:var(--codingns-switch-thumb);border-radius:50%;corner-shape:round;background:var(--dsw-alias-switch-thumb);transition:transform 120ms ease,background 120ms ease}
|
|
9189
|
+
.${settingsControlClass.switch}>input:checked+.${settingsControlClass.track}{background:var(--codingns-switch-active)}
|
|
9190
|
+
.${settingsControlClass.switch}>input:checked+.${settingsControlClass.track}>.${settingsControlClass.thumb}{background:var(--codingns-switch-active-thumb);transform:translateX(var(--codingns-switch-travel))}
|
|
9191
|
+
.${settingsControlClass.switch}>input:disabled+.${settingsControlClass.track}{opacity:.5}
|
|
9192
|
+
.${settingsControlClass.switch}>input:disabled{cursor:not-allowed!important}
|
|
9193
|
+
.${settingsControlClass.switch}>input:focus-visible+.${settingsControlClass.track}{outline:${require_theme.dshThemeColor.focusRing};outline-offset:3px}
|
|
9194
|
+
.${settingsControlClass.iconButton}:hover:not(:disabled){color:${require_theme.dshThemeColor.labelPrimary};background:${require_theme.dshThemeColor.hoverBackground}}
|
|
9195
|
+
.${settingsControlClass.iconButton}:active:not(:disabled){background:${require_theme.dshThemeColor.activeBackground}}
|
|
9196
|
+
.${settingsControlClass.iconButton}:focus-visible{outline:${require_theme.dshThemeColor.focusRing};outline-offset:2px}
|
|
9197
|
+
.${settingsControlClass.iconButton}:disabled{opacity:.5;cursor:not-allowed}
|
|
9198
|
+
@media (prefers-reduced-motion:reduce){.${settingsControlClass.track},.${settingsControlClass.thumb}{transition:none}}
|
|
9199
|
+
`;
|
|
9200
|
+
//#endregion
|
|
9225
9201
|
//#region node_modules/.pnpm/scheduler@0.23.2/node_modules/scheduler/cjs/scheduler.production.min.js
|
|
9226
9202
|
/**
|
|
9227
9203
|
* @license React
|
|
@@ -16170,12 +16146,36 @@ window.__ModuleLoader__.load({
|
|
|
16170
16146
|
module.exports = require_react_dom_production_min();
|
|
16171
16147
|
}));
|
|
16172
16148
|
//#endregion
|
|
16149
|
+
Object.defineProperty(exports, "SettingsSwitch", {
|
|
16150
|
+
enumerable: true,
|
|
16151
|
+
get: function() {
|
|
16152
|
+
return SettingsSwitch;
|
|
16153
|
+
}
|
|
16154
|
+
});
|
|
16155
|
+
Object.defineProperty(exports, "SettingsToggleRow", {
|
|
16156
|
+
enumerable: true,
|
|
16157
|
+
get: function() {
|
|
16158
|
+
return SettingsToggleRow;
|
|
16159
|
+
}
|
|
16160
|
+
});
|
|
16173
16161
|
Object.defineProperty(exports, "require_react_dom", {
|
|
16174
16162
|
enumerable: true,
|
|
16175
16163
|
get: function() {
|
|
16176
16164
|
return require_react_dom;
|
|
16177
16165
|
}
|
|
16178
16166
|
});
|
|
16167
|
+
Object.defineProperty(exports, "settingsControlClass", {
|
|
16168
|
+
enumerable: true,
|
|
16169
|
+
get: function() {
|
|
16170
|
+
return settingsControlClass;
|
|
16171
|
+
}
|
|
16172
|
+
});
|
|
16173
|
+
Object.defineProperty(exports, "settingsIconButtonStyle", {
|
|
16174
|
+
enumerable: true,
|
|
16175
|
+
get: function() {
|
|
16176
|
+
return settingsIconButtonStyle;
|
|
16177
|
+
}
|
|
16178
|
+
});
|
|
16179
16179
|
return module.exports;
|
|
16180
16180
|
}
|
|
16181
16181
|
});
|
|
@@ -16275,6 +16275,9 @@ window.__ModuleLoader__.load({
|
|
|
16275
16275
|
"zh"
|
|
16276
16276
|
];
|
|
16277
16277
|
const DEFAULT_SESSION_TRANSLATION_SETTINGS = {
|
|
16278
|
+
inputEnabled: true,
|
|
16279
|
+
reasoningEnabled: true,
|
|
16280
|
+
assistantEnabled: true,
|
|
16278
16281
|
inputLanguage: "en",
|
|
16279
16282
|
outputLanguage: "zh",
|
|
16280
16283
|
bilingual: false,
|
|
@@ -16309,13 +16312,18 @@ window.__ModuleLoader__.load({
|
|
|
16309
16312
|
if (value === void 0) return fallback;
|
|
16310
16313
|
const translationModel = normalizeTranslationModel(value.translationModel);
|
|
16311
16314
|
const translationModels = Array.isArray(value.translationModels) ? normalizeTranslationModels(value.translationModels) : void 0;
|
|
16315
|
+
const translationRules = Array.isArray(value.translationRules) ? value.translationRules.filter((rule) => typeof rule === "string").map((rule) => rule.trim()).filter((rule) => rule !== "") : void 0;
|
|
16312
16316
|
return {
|
|
16317
|
+
inputEnabled: value.inputEnabled !== false,
|
|
16318
|
+
reasoningEnabled: value.reasoningEnabled !== false,
|
|
16319
|
+
assistantEnabled: value.assistantEnabled !== false,
|
|
16313
16320
|
inputLanguage: isSessionTranslationLanguage(value.inputLanguage) ? value.inputLanguage : fallback.inputLanguage,
|
|
16314
16321
|
outputLanguage: isSessionTranslationLanguage(value.outputLanguage) ? value.outputLanguage : fallback.outputLanguage,
|
|
16315
16322
|
bilingual: value.bilingual === true,
|
|
16316
16323
|
nativeEnabled: value.nativeEnabled === true,
|
|
16317
16324
|
...translationModel === void 0 ? {} : { translationModel },
|
|
16318
|
-
...translationModels === void 0 ? {} : { translationModels }
|
|
16325
|
+
...translationModels === void 0 ? {} : { translationModels },
|
|
16326
|
+
...translationRules === void 0 ? {} : { translationRules }
|
|
16319
16327
|
};
|
|
16320
16328
|
}
|
|
16321
16329
|
function normalizeTranslationModels(values) {
|
|
@@ -18013,6 +18021,12 @@ window.__ModuleLoader__.load({
|
|
|
18013
18021
|
"cli.adapterDisabled": "{name} disabled",
|
|
18014
18022
|
"cli.translationConversation": "Translate conversation",
|
|
18015
18023
|
"cli.translationConversationToggle": "Toggle conversation translation",
|
|
18024
|
+
"cli.translationSettings": "Conversation translation settings",
|
|
18025
|
+
"cli.translationSettingsClose": "Close",
|
|
18026
|
+
"cli.translationSettingsDescription": "Choose which messages to translate in conversations with translation enabled.",
|
|
18027
|
+
"cli.translationUserMessages": "Translate user messages",
|
|
18028
|
+
"cli.translationThinkingMessages": "Translate AI thinking messages",
|
|
18029
|
+
"cli.translationAssistantMessages": "Translate AI final messages",
|
|
18016
18030
|
"lan.fieldListenPort": "listen port",
|
|
18017
18031
|
"lan.fieldDshPort": "DSH local port",
|
|
18018
18032
|
"lan.fieldMustBeNumber": "{field} must be a number",
|
|
@@ -18025,6 +18039,17 @@ window.__ModuleLoader__.load({
|
|
|
18025
18039
|
"translation.outputTitle": "Translate the AI’s reasoning and final messages into the language specified below",
|
|
18026
18040
|
"translation.outputLanguage": "Reply language",
|
|
18027
18041
|
"translation.modelTitle": "Translation model pool",
|
|
18042
|
+
"translation.rulesTitle": "Translation rules",
|
|
18043
|
+
"translation.rulesHelp": "Rules apply to input, reasoning, and replies, including text already in the target language. They take priority over the default translation prompts.",
|
|
18044
|
+
"translation.rulesEmpty": "No custom rules. The default translation prompts apply.",
|
|
18045
|
+
"translation.ruleAdd": "Add rule",
|
|
18046
|
+
"translation.ruleEdit": "Edit rule {number}",
|
|
18047
|
+
"translation.ruleRemove": "Remove rule {number}",
|
|
18048
|
+
"translation.ruleText": "Rule instructions",
|
|
18049
|
+
"translation.rulePlaceholder": "For example: Keep product names in their original language.",
|
|
18050
|
+
"translation.ruleSave": "Save rule",
|
|
18051
|
+
"translation.ruleSaving": "Saving…",
|
|
18052
|
+
"translation.ruleCancel": "Cancel",
|
|
18028
18053
|
"translation.modelFollowDefault": "Use the default DSH model",
|
|
18029
18054
|
"translation.modelResetTitle": "Use the default DSH model?",
|
|
18030
18055
|
"translation.modelResetHelp": "This will clear all {count} models and their priority order from the pool, then follow the default DSH model. Continue?",
|
|
@@ -18056,6 +18081,12 @@ window.__ModuleLoader__.load({
|
|
|
18056
18081
|
"translation.statusTranslating": "Translating…",
|
|
18057
18082
|
"translation.progressHelp": "Preparing and translating your message. The translation result will be available when this finishes.",
|
|
18058
18083
|
"translation.statusFailed": "Translation failed; original kept",
|
|
18084
|
+
"translation.retry": "Retry translation",
|
|
18085
|
+
"translation.sendDirectly": "Send directly",
|
|
18086
|
+
"translation.cancelSending": "Cancel sending",
|
|
18087
|
+
"translation.inputFailedTitle": "Message translation failed",
|
|
18088
|
+
"translation.inputFailedHelp": "Your message has not been sent. Choose how to continue.",
|
|
18089
|
+
"translation.decisionFailed": "Could not apply your choice. Please try again.",
|
|
18059
18090
|
"translation.statusNotNeeded": "Already in the target language; translation skipped",
|
|
18060
18091
|
"translation.detectedLanguage": "Detected language",
|
|
18061
18092
|
"translation.modelNotUsed": "Not used; translation was unnecessary",
|
|
@@ -18091,6 +18122,12 @@ window.__ModuleLoader__.load({
|
|
|
18091
18122
|
"cli.adapterDisabled": "已停用 {name}",
|
|
18092
18123
|
"cli.translationConversation": "翻译对话",
|
|
18093
18124
|
"cli.translationConversationToggle": "切换对话翻译",
|
|
18125
|
+
"cli.translationSettings": "对话翻译设置",
|
|
18126
|
+
"cli.translationSettingsClose": "关闭",
|
|
18127
|
+
"cli.translationSettingsDescription": "选择已开启对话翻译的会话中需要翻译的消息类型。",
|
|
18128
|
+
"cli.translationUserMessages": "翻译用户消息",
|
|
18129
|
+
"cli.translationThinkingMessages": "翻译 AI 思考消息",
|
|
18130
|
+
"cli.translationAssistantMessages": "翻译 AI 正式消息",
|
|
18094
18131
|
"lan.fieldListenPort": "监听端口",
|
|
18095
18132
|
"lan.fieldDshPort": "DSH 本地端口",
|
|
18096
18133
|
"lan.fieldMustBeNumber": "{field} 必须是数字",
|
|
@@ -18103,6 +18140,17 @@ window.__ModuleLoader__.load({
|
|
|
18103
18140
|
"translation.outputTitle": "AI的思考内容和正式消息翻译为以下指定语言",
|
|
18104
18141
|
"translation.outputLanguage": "回复语言",
|
|
18105
18142
|
"translation.modelTitle": "翻译模型池",
|
|
18143
|
+
"translation.rulesTitle": "翻译规则",
|
|
18144
|
+
"translation.rulesHelp": "规则适用于输入、思考和回复,包括已经是目标语言的文本。规则的优先级高于默认翻译提示词。",
|
|
18145
|
+
"translation.rulesEmpty": "尚未添加自定义规则,使用默认翻译提示词。",
|
|
18146
|
+
"translation.ruleAdd": "添加规则",
|
|
18147
|
+
"translation.ruleEdit": "编辑规则 {number}",
|
|
18148
|
+
"translation.ruleRemove": "移除规则 {number}",
|
|
18149
|
+
"translation.ruleText": "规则内容",
|
|
18150
|
+
"translation.rulePlaceholder": "例如:产品名称保留原文,不进行翻译。",
|
|
18151
|
+
"translation.ruleSave": "保存规则",
|
|
18152
|
+
"translation.ruleSaving": "正在保存…",
|
|
18153
|
+
"translation.ruleCancel": "取消",
|
|
18106
18154
|
"translation.modelFollowDefault": "跟随 DSH 默认模型",
|
|
18107
18155
|
"translation.modelResetTitle": "确认跟随 DSH 默认模型?",
|
|
18108
18156
|
"translation.modelResetHelp": "这将清空模型池中的全部 {count} 个模型及其优先级顺序,并改为跟随 DSH 默认模型。是否继续?",
|
|
@@ -18134,6 +18182,12 @@ window.__ModuleLoader__.load({
|
|
|
18134
18182
|
"translation.statusTranslating": "正在翻译…",
|
|
18135
18183
|
"translation.progressHelp": "正在准备并翻译消息,完成后可查看翻译结果。",
|
|
18136
18184
|
"translation.statusFailed": "翻译失败,已保留原文",
|
|
18185
|
+
"translation.retry": "重试翻译",
|
|
18186
|
+
"translation.sendDirectly": "直接发送",
|
|
18187
|
+
"translation.cancelSending": "取消发送",
|
|
18188
|
+
"translation.inputFailedTitle": "消息翻译失败",
|
|
18189
|
+
"translation.inputFailedHelp": "消息尚未发送,请选择如何继续。",
|
|
18190
|
+
"translation.decisionFailed": "未能应用你的选择,请重试。",
|
|
18137
18191
|
"translation.statusNotNeeded": "原文已是目标语言,无需翻译",
|
|
18138
18192
|
"translation.detectedLanguage": "检测到的语言",
|
|
18139
18193
|
"translation.modelNotUsed": "未调用,原文无需翻译",
|
|
@@ -20580,10 +20634,10 @@ window.__ModuleLoader__.load({
|
|
|
20580
20634
|
const require_assistant_notifications = require("@jingyi0605/codingns4dsh/client.assistant-notifications.js");
|
|
20581
20635
|
const require_session_translation = require("@jingyi0605/codingns4dsh/client.session-translation.js");
|
|
20582
20636
|
const require_theme = require("@jingyi0605/codingns4dsh/client.theme.js");
|
|
20583
|
-
const
|
|
20637
|
+
const require_react_dom$1 = require("@jingyi0605/codingns4dsh/client.react-dom.js");
|
|
20584
20638
|
const require_manager = require("@jingyi0605/codingns4dsh/client.manager.js");
|
|
20585
20639
|
const require_primitives_adapter = require("@jingyi0605/codingns4dsh/client.primitives-adapter.js");
|
|
20586
|
-
const
|
|
20640
|
+
const require_moss_voice_output = require("@jingyi0605/codingns4dsh/client.moss-voice-output.js");
|
|
20587
20641
|
const require_assistant_voice_sessions = require("@jingyi0605/codingns4dsh/client.assistant-voice-sessions.js");
|
|
20588
20642
|
let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
20589
20643
|
_deepseek_ai_dsh_client_ui_primitives = require_rolldown_runtime.__toESM(_deepseek_ai_dsh_client_ui_primitives, 1);
|
|
@@ -22180,7 +22234,7 @@ window.__ModuleLoader__.load({
|
|
|
22180
22234
|
disabled: controlsDisabled || busy,
|
|
22181
22235
|
onClick: () => void detect(),
|
|
22182
22236
|
style: buttonStyle
|
|
22183
|
-
}, t("lan.detect")))), detectedDshPorts.length > 1 && (0, react.createElement)("div", { style: require_theme.dshSettingsNoteStyle }, t("lan.detectMultiple", { ports: detectedDshPorts.join(t("common.listSeparator")) })), (0, react.createElement)(
|
|
22237
|
+
}, t("lan.detect")))), detectedDshPorts.length > 1 && (0, react.createElement)("div", { style: require_theme.dshSettingsNoteStyle }, t("lan.detectMultiple", { ports: detectedDshPorts.join(t("common.listSeparator")) })), (0, react.createElement)(require_react_dom$1.SettingsToggleRow, {
|
|
22184
22238
|
label: t("lan.autoStart"),
|
|
22185
22239
|
checked: autoStart,
|
|
22186
22240
|
disabled: controlsDisabled || busy,
|
|
@@ -23994,15 +24048,15 @@ window.__ModuleLoader__.load({
|
|
|
23994
24048
|
sendHello() {
|
|
23995
24049
|
this.send(this.createEnvelope("session.hello", "session", {
|
|
23996
24050
|
protocol: this.options.protocol ?? "dsh-transport-v1",
|
|
23997
|
-
dshVersion: this.options.dshVersion ?? "0.2.1-alpha.
|
|
24051
|
+
dshVersion: this.options.dshVersion ?? "0.2.1-alpha.3",
|
|
23998
24052
|
capabilities: [...this.options.capabilities ?? []]
|
|
23999
24053
|
}));
|
|
24000
24054
|
}
|
|
24001
24055
|
sendReady(capabilities, peerDshVersion) {
|
|
24002
24056
|
this.send(this.createEnvelope("session.ready", "session", {
|
|
24003
24057
|
protocol: this.options.protocol ?? "dsh-transport-v1",
|
|
24004
|
-
dshVersion: peerDshVersion ?? this.options.dshVersion ?? "0.2.1-alpha.
|
|
24005
|
-
hostDshVersion: this.options.dshVersion ?? "0.2.1-alpha.
|
|
24058
|
+
dshVersion: peerDshVersion ?? this.options.dshVersion ?? "0.2.1-alpha.3",
|
|
24059
|
+
hostDshVersion: this.options.dshVersion ?? "0.2.1-alpha.3",
|
|
24006
24060
|
capabilities: [...capabilities],
|
|
24007
24061
|
byteCredit: 65536,
|
|
24008
24062
|
messageCredit: 32
|
|
@@ -27035,7 +27089,7 @@ window.__ModuleLoader__.load({
|
|
|
27035
27089
|
color: require_theme.dshThemeColor.labelSecondary,
|
|
27036
27090
|
fontSize: require_theme.uiFontSize(13),
|
|
27037
27091
|
lineHeight: 1.5
|
|
27038
|
-
} }, t("loginProtection.panelHint")), (0, react.createElement)(
|
|
27092
|
+
} }, t("loginProtection.panelHint")), (0, react.createElement)(require_react_dom$1.SettingsToggleRow, {
|
|
27039
27093
|
label: t("loginProtection.enable"),
|
|
27040
27094
|
checked: active,
|
|
27041
27095
|
disabled: controlsDisabled || busy,
|
|
@@ -27092,7 +27146,7 @@ window.__ModuleLoader__.load({
|
|
|
27092
27146
|
"relay",
|
|
27093
27147
|
t("loginProtection.scopeRelay"),
|
|
27094
27148
|
t("loginProtection.scopeRelayHint")
|
|
27095
|
-
]].map(([key, label, hint]) => (0, react.createElement)(
|
|
27149
|
+
]].map(([key, label, hint]) => (0, react.createElement)(require_react_dom$1.SettingsToggleRow, {
|
|
27096
27150
|
key,
|
|
27097
27151
|
label: t("loginProtection.scopeOption", {
|
|
27098
27152
|
label,
|
|
@@ -28205,7 +28259,7 @@ window.__ModuleLoader__.load({
|
|
|
28205
28259
|
if (slots === void 0) return;
|
|
28206
28260
|
context.resources.add(registerExternalToolStreamUi(context.services));
|
|
28207
28261
|
const { registerCliConversationSlots } = await Promise.resolve().then(() => cli_slots_exports);
|
|
28208
|
-
const disposeSlots = registerCliConversationSlots(slots, context.services.rpc, context.services.locale, readNativeTranslationDefault);
|
|
28262
|
+
const disposeSlots = registerCliConversationSlots(slots, context.services.rpc, context.services.locale, readNativeTranslationDefault, context.services.settings);
|
|
28209
28263
|
context.resources.add(disposeSlots);
|
|
28210
28264
|
},
|
|
28211
28265
|
settingsPanel: CliAdaptersPanel
|
|
@@ -28495,7 +28549,7 @@ window.__ModuleLoader__.load({
|
|
|
28495
28549
|
marginTop: 3,
|
|
28496
28550
|
...require_theme.dshSettingsHelpStyle,
|
|
28497
28551
|
opacity: .75
|
|
28498
|
-
} }, t("cli.subagentBridgeDescription"))), (0, react.createElement)(
|
|
28552
|
+
} }, t("cli.subagentBridgeDescription"))), (0, react.createElement)(require_react_dom$1.SettingsSwitch, {
|
|
28499
28553
|
"aria-label": t("cli.subagentBridgeToggle"),
|
|
28500
28554
|
checked: bridgeEnabled,
|
|
28501
28555
|
disabled: !bridgeWritable || bridgeBusy,
|
|
@@ -28637,7 +28691,7 @@ window.__ModuleLoader__.load({
|
|
|
28637
28691
|
gap: 6,
|
|
28638
28692
|
flex: "0 0 auto"
|
|
28639
28693
|
}
|
|
28640
|
-
}, (0, react.createElement)("span", { "aria-hidden": true }, adapter.enabled ? t("cli.enabled") : t("cli.disabled")), (0, react.createElement)(
|
|
28694
|
+
}, (0, react.createElement)("span", { "aria-hidden": true }, adapter.enabled ? t("cli.enabled") : t("cli.disabled")), (0, react.createElement)(require_react_dom$1.SettingsSwitch, {
|
|
28641
28695
|
"aria-label": t("cli.adapterToggle", { name: adapter.name }),
|
|
28642
28696
|
checked: adapter.enabled,
|
|
28643
28697
|
disabled: peerHostId !== null || !adapter.installed || busyAdapterId === adapter.id,
|
|
@@ -28955,7 +29009,7 @@ window.__ModuleLoader__.load({
|
|
|
28955
29009
|
gap: 12,
|
|
28956
29010
|
minHeight: 36,
|
|
28957
29011
|
width: "100%"
|
|
28958
|
-
} }, (0, react.createElement)("span", { style: require_theme.dshSettingsHelpStyle }, appearance.cursorBlink ? t("terminal.cursorOn") : t("terminal.cursorOff")), (0, react.createElement)(
|
|
29012
|
+
} }, (0, react.createElement)("span", { style: require_theme.dshSettingsHelpStyle }, appearance.cursorBlink ? t("terminal.cursorOn") : t("terminal.cursorOff")), (0, react.createElement)(require_react_dom$1.SettingsSwitch, {
|
|
28959
29013
|
"aria-label": t("terminal.cursorBlink"),
|
|
28960
29014
|
checked: appearance.cursorBlink,
|
|
28961
29015
|
disabled,
|
|
@@ -30767,31 +30821,31 @@ window.__ModuleLoader__.load({
|
|
|
30767
30821
|
opacity: disabled ? .5 : 1,
|
|
30768
30822
|
pointerEvents: disabled ? "none" : "auto"
|
|
30769
30823
|
}
|
|
30770
|
-
}, (0, react.createElement)(
|
|
30824
|
+
}, (0, react.createElement)(require_react_dom$1.SettingsToggleRow, {
|
|
30771
30825
|
label: t("workspace.optimizeSessionTitles"),
|
|
30772
30826
|
description: t("workspace.optimizeSessionTitlesDescription"),
|
|
30773
30827
|
checked: value.optimizeSessionTitles ?? require_native_workspace_store.DEFAULT_WORKSPACE_SESSION_ENHANCEMENT_SETTINGS.optimizeSessionTitles,
|
|
30774
30828
|
disabled,
|
|
30775
30829
|
onChange: (checked) => updateSetting("optimizeSessionTitles", checked)
|
|
30776
|
-
}), (0, react.createElement)(
|
|
30830
|
+
}), (0, react.createElement)(require_react_dom$1.SettingsToggleRow, {
|
|
30777
30831
|
label: t("workspace.showLogo"),
|
|
30778
30832
|
description: t("workspace.logoDescription"),
|
|
30779
30833
|
checked: value.showAdapterLogo,
|
|
30780
30834
|
disabled,
|
|
30781
30835
|
onChange: (checked) => updateSetting("showAdapterLogo", checked)
|
|
30782
|
-
}), (0, react.createElement)(
|
|
30836
|
+
}), (0, react.createElement)(require_react_dom$1.SettingsToggleRow, {
|
|
30783
30837
|
label: t("workspace.showSkillQuickReference"),
|
|
30784
30838
|
description: t("workspace.skillQuickReferenceDescription"),
|
|
30785
30839
|
checked: value.showSkillQuickReference,
|
|
30786
30840
|
disabled,
|
|
30787
30841
|
onChange: (checked) => updateSetting("showSkillQuickReference", checked)
|
|
30788
|
-
}), (0, react.createElement)(
|
|
30842
|
+
}), (0, react.createElement)(require_react_dom$1.SettingsToggleRow, {
|
|
30789
30843
|
label: t("workspace.showWorkspaceHiding"),
|
|
30790
30844
|
description: t("workspace.workspaceHidingDescription"),
|
|
30791
30845
|
checked: value.showWorkspaceHiding,
|
|
30792
30846
|
disabled,
|
|
30793
30847
|
onChange: (checked) => updateSetting("showWorkspaceHiding", checked)
|
|
30794
|
-
}), (0, react.createElement)(
|
|
30848
|
+
}), (0, react.createElement)(require_react_dom$1.SettingsToggleRow, {
|
|
30795
30849
|
label: t("workspace.showSubscriptionUsage"),
|
|
30796
30850
|
description: t("workspace.subscriptionUsageDescription"),
|
|
30797
30851
|
checked: value.showSubscriptionUsage,
|
|
@@ -30799,28 +30853,28 @@ window.__ModuleLoader__.load({
|
|
|
30799
30853
|
onChange: (checked) => updateSetting("showSubscriptionUsage", checked),
|
|
30800
30854
|
actions: (0, react.createElement)("button", {
|
|
30801
30855
|
type: "button",
|
|
30802
|
-
className:
|
|
30856
|
+
className: require_react_dom$1.settingsControlClass.iconButton,
|
|
30803
30857
|
"aria-haspopup": "dialog",
|
|
30804
30858
|
"aria-expanded": usageSettingsOpen,
|
|
30805
30859
|
"aria-label": t("workspace.subscriptionUsageSettings"),
|
|
30806
30860
|
title: t("workspace.subscriptionUsageSettings"),
|
|
30807
30861
|
disabled,
|
|
30808
30862
|
onClick: () => setUsageSettingsOpen(true),
|
|
30809
|
-
style:
|
|
30863
|
+
style: require_react_dom$1.settingsIconButtonStyle
|
|
30810
30864
|
}, createUsageSettingsGearIcon())
|
|
30811
|
-
}), (0, react.createElement)(
|
|
30865
|
+
}), (0, react.createElement)(require_react_dom$1.SettingsToggleRow, {
|
|
30812
30866
|
label: t("workspace.showArchivedSessions"),
|
|
30813
30867
|
description: t("workspace.archivedSessionsDescription"),
|
|
30814
30868
|
checked: value.showArchivedSessions,
|
|
30815
30869
|
disabled,
|
|
30816
30870
|
onChange: (checked) => updateSetting("showArchivedSessions", checked)
|
|
30817
|
-
}), (0, react.createElement)(
|
|
30871
|
+
}), (0, react.createElement)(require_react_dom$1.SettingsToggleRow, {
|
|
30818
30872
|
label: t("workspace.showQuickPhrases"),
|
|
30819
30873
|
description: t("workspace.quickPhrasesDescription"),
|
|
30820
30874
|
checked: value.showQuickPhrases,
|
|
30821
30875
|
disabled,
|
|
30822
30876
|
onChange: (checked) => updateSetting("showQuickPhrases", checked)
|
|
30823
|
-
}), (0, react.createElement)(
|
|
30877
|
+
}), (0, react.createElement)(require_react_dom$1.SettingsToggleRow, {
|
|
30824
30878
|
label: t("workspace.rememberConversationRightbarRatio"),
|
|
30825
30879
|
description: t("workspace.rememberConversationRightbarRatioDescription"),
|
|
30826
30880
|
checked: value.rememberConversationRightbarRatio,
|
|
@@ -33455,6 +33509,61 @@ window.__ModuleLoader__.load({
|
|
|
33455
33509
|
};
|
|
33456
33510
|
}
|
|
33457
33511
|
//#endregion
|
|
33512
|
+
//#region src/client/conversation-translation-settings.ts
|
|
33513
|
+
const messageSettings = [
|
|
33514
|
+
["inputEnabled", "cli.translationUserMessages"],
|
|
33515
|
+
["reasoningEnabled", "cli.translationThinkingMessages"],
|
|
33516
|
+
["assistantEnabled", "cli.translationAssistantMessages"]
|
|
33517
|
+
];
|
|
33518
|
+
/** Shared message preferences, independent of each conversation's master switch. */
|
|
33519
|
+
function ConversationTranslationSettings(props) {
|
|
33520
|
+
const { settings, t } = props;
|
|
33521
|
+
const snapshot = (0, react.useSyncExternalStore)(settings.subscribe.bind(settings), settings.getSnapshot.bind(settings), settings.getSnapshot.bind(settings));
|
|
33522
|
+
const [saving, setSaving] = (0, react.useState)(false);
|
|
33523
|
+
const savingRef = (0, react.useRef)(false);
|
|
33524
|
+
const [error, setError] = (0, react.useState)(null);
|
|
33525
|
+
const disabled = snapshot.status !== "ready" || !snapshot.writable || saving;
|
|
33526
|
+
const save = async (field, checked) => {
|
|
33527
|
+
if (disabled || savingRef.current) return;
|
|
33528
|
+
savingRef.current = true;
|
|
33529
|
+
setSaving(true);
|
|
33530
|
+
setError(null);
|
|
33531
|
+
try {
|
|
33532
|
+
if (!await settings.mutate([{
|
|
33533
|
+
op: "set",
|
|
33534
|
+
path: ["sessionTranslation", field],
|
|
33535
|
+
value: checked
|
|
33536
|
+
}])) throw new Error(t("translation.saveRejected"));
|
|
33537
|
+
} catch (cause) {
|
|
33538
|
+
setError(cause instanceof Error ? cause.message : String(cause));
|
|
33539
|
+
} finally {
|
|
33540
|
+
savingRef.current = false;
|
|
33541
|
+
setSaving(false);
|
|
33542
|
+
}
|
|
33543
|
+
};
|
|
33544
|
+
return (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
|
|
33545
|
+
open: true,
|
|
33546
|
+
title: t("cli.translationSettings"),
|
|
33547
|
+
description: t("cli.translationSettingsDescription"),
|
|
33548
|
+
closeLabel: t("cli.translationSettingsClose"),
|
|
33549
|
+
onClose: props.onClose
|
|
33550
|
+
}, ...messageSettings.map(([field, label]) => (0, react.createElement)(require_react_dom$1.SettingsToggleRow, {
|
|
33551
|
+
key: field,
|
|
33552
|
+
label: t(label),
|
|
33553
|
+
checked: snapshot.value?.sessionTranslation?.[field] !== false,
|
|
33554
|
+
disabled,
|
|
33555
|
+
onChange: (checked) => {
|
|
33556
|
+
save(field, checked);
|
|
33557
|
+
}
|
|
33558
|
+
})), error === null ? null : (0, react.createElement)("div", {
|
|
33559
|
+
role: "alert",
|
|
33560
|
+
style: {
|
|
33561
|
+
color: require_theme.dshThemeColor.error,
|
|
33562
|
+
marginTop: 8
|
|
33563
|
+
}
|
|
33564
|
+
}, error));
|
|
33565
|
+
}
|
|
33566
|
+
//#endregion
|
|
33458
33567
|
//#region src/client/cli-slots.ts
|
|
33459
33568
|
var cli_slots_exports = /* @__PURE__ */ require_rolldown_runtime.__exportAll({
|
|
33460
33569
|
AgentSlot: () => AgentSlot,
|
|
@@ -33598,7 +33707,7 @@ window.__ModuleLoader__.load({
|
|
|
33598
33707
|
* `readNativeTranslationEnabled` 提供「DSH 原生会话未单独设置翻译开关时是否跟随总开关」
|
|
33599
33708
|
* 的当前值;原生会话的翻译开关与外部 Agent 共用模型菜单里的同一行开关。
|
|
33600
33709
|
*/
|
|
33601
|
-
function registerCliConversationSlots(slots, rpc, locale, readNativeTranslationEnabled) {
|
|
33710
|
+
function registerCliConversationSlots(slots, rpc, locale, readNativeTranslationEnabled, settings) {
|
|
33602
33711
|
installComposerStyles();
|
|
33603
33712
|
const t = locale.bind("codingns");
|
|
33604
33713
|
const disposeAgent = slots.inject("conversation.input.right", () => slots.register({
|
|
@@ -33621,6 +33730,7 @@ window.__ModuleLoader__.load({
|
|
|
33621
33730
|
rpc,
|
|
33622
33731
|
sessionId,
|
|
33623
33732
|
locale,
|
|
33733
|
+
settings,
|
|
33624
33734
|
...readNativeTranslationEnabled === void 0 ? {} : { readNativeTranslationEnabled }
|
|
33625
33735
|
})
|
|
33626
33736
|
}, ModelSlot));
|
|
@@ -33739,7 +33849,23 @@ window.__ModuleLoader__.load({
|
|
|
33739
33849
|
return (0, react.createElement)("div", {
|
|
33740
33850
|
className: "codingns4dsh-translation-toggle",
|
|
33741
33851
|
style: serviceTierRowStyle
|
|
33742
|
-
}, (0, react.createElement)("span", { style:
|
|
33852
|
+
}, (0, react.createElement)("span", { style: {
|
|
33853
|
+
...serviceTierLabelStyle,
|
|
33854
|
+
flex: "1 1 auto",
|
|
33855
|
+
whiteSpace: "normal"
|
|
33856
|
+
} }, props.label), (0, react.createElement)("button", {
|
|
33857
|
+
type: "button",
|
|
33858
|
+
"aria-label": props.settingsLabel,
|
|
33859
|
+
title: props.settingsLabel,
|
|
33860
|
+
"aria-haspopup": "dialog",
|
|
33861
|
+
onClick: props.onSettings,
|
|
33862
|
+
style: {
|
|
33863
|
+
...require_react_dom$1.settingsIconButtonStyle,
|
|
33864
|
+
flexBasis: 24,
|
|
33865
|
+
width: 24,
|
|
33866
|
+
height: 28
|
|
33867
|
+
}
|
|
33868
|
+
}, (0, react.createElement)(require_primitives_adapter.resolveAssistantControlIcon("settings"), { size: 16 })), (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Switch, {
|
|
33743
33869
|
checked: props.checked,
|
|
33744
33870
|
onChange: props.onChange,
|
|
33745
33871
|
label: props.toggleLabel
|
|
@@ -33933,6 +34059,7 @@ window.__ModuleLoader__.load({
|
|
|
33933
34059
|
const [catalogRetry, setCatalogRetry] = (0, react.useState)(0);
|
|
33934
34060
|
const [open, setOpen] = (0, react.useState)(false);
|
|
33935
34061
|
const [pane, setPane] = (0, react.useState)("root");
|
|
34062
|
+
const [translationSettingsOpen, setTranslationSettingsOpen] = (0, react.useState)(false);
|
|
33936
34063
|
const rootRef = (0, react.useRef)(null);
|
|
33937
34064
|
useDismissOnOutsidePointer(rootRef, open, () => {
|
|
33938
34065
|
setOpen(false);
|
|
@@ -34021,6 +34148,15 @@ window.__ModuleLoader__.load({
|
|
|
34021
34148
|
(0, react.useEffect)(() => {
|
|
34022
34149
|
if (selection.adapterId === "dsh") setOpen(false);
|
|
34023
34150
|
}, [selection.adapterId]);
|
|
34151
|
+
const translationSettings = translationSettingsOpen && props.settings !== void 0 ? (0, react.createElement)(ConversationTranslationSettings, {
|
|
34152
|
+
settings: props.settings,
|
|
34153
|
+
t,
|
|
34154
|
+
onClose: () => setTranslationSettingsOpen(false)
|
|
34155
|
+
}) : null;
|
|
34156
|
+
const openTranslationSettings = () => {
|
|
34157
|
+
setOpen(false);
|
|
34158
|
+
setTranslationSettingsOpen(true);
|
|
34159
|
+
};
|
|
34024
34160
|
if (selection.adapterId === "dsh") return (0, react.createElement)("div", {
|
|
34025
34161
|
ref: rootRef,
|
|
34026
34162
|
hidden: true
|
|
@@ -34031,8 +34167,10 @@ window.__ModuleLoader__.load({
|
|
|
34031
34167
|
onChange: (next) => update({
|
|
34032
34168
|
...selection,
|
|
34033
34169
|
translationEnabled: next
|
|
34034
|
-
})
|
|
34035
|
-
|
|
34170
|
+
}),
|
|
34171
|
+
settingsLabel: t("cli.translationSettings"),
|
|
34172
|
+
onSettings: openTranslationSettings
|
|
34173
|
+
}), nativeMenu) : null, translationSettings);
|
|
34036
34174
|
const model = catalog === null ? void 0 : require_model_catalog_cache.findModel(catalog, selection.modelId) ?? require_model_catalog_cache.firstModel(catalog);
|
|
34037
34175
|
const efforts = model?.efforts ?? [];
|
|
34038
34176
|
const storedEffort = selection.effortId;
|
|
@@ -34108,7 +34246,9 @@ window.__ModuleLoader__.load({
|
|
|
34108
34246
|
checked: selection.translationEnabled === true,
|
|
34109
34247
|
label: t("cli.translationConversation"),
|
|
34110
34248
|
toggleLabel: t("cli.translationConversationToggle"),
|
|
34111
|
-
onChange: toggleTranslation
|
|
34249
|
+
onChange: toggleTranslation,
|
|
34250
|
+
settingsLabel: t("cli.translationSettings"),
|
|
34251
|
+
onSettings: openTranslationSettings
|
|
34112
34252
|
})] : [],
|
|
34113
34253
|
...serviceTierAvailable ? [(0, react.createElement)("div", {
|
|
34114
34254
|
key: "service-tier",
|
|
@@ -34229,7 +34369,7 @@ window.__ModuleLoader__.load({
|
|
|
34229
34369
|
role: "menu",
|
|
34230
34370
|
"aria-label": t("cli.chooseModelMenu"),
|
|
34231
34371
|
style: nativeMenuStyle
|
|
34232
|
-
}, ...menu));
|
|
34372
|
+
}, ...menu), translationSettings);
|
|
34233
34373
|
}
|
|
34234
34374
|
function effortDisplayName(model, effort, defaultLabel) {
|
|
34235
34375
|
if (effort === "default") return defaultLabel;
|
|
@@ -36360,7 +36500,7 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
36360
36500
|
display: "block",
|
|
36361
36501
|
marginTop: 3,
|
|
36362
36502
|
...require_theme.dshSettingsHelpStyle
|
|
36363
|
-
} }, t("mobile.hideSidebarOnMobileDescription"))), (0, react.createElement)(
|
|
36503
|
+
} }, t("mobile.hideSidebarOnMobileDescription"))), (0, react.createElement)(require_react_dom$1.SettingsSwitch, {
|
|
36364
36504
|
"aria-label": t("mobile.hideSidebarOnMobile"),
|
|
36365
36505
|
checked: value.hideSidebarOnMobile,
|
|
36366
36506
|
disabled: controlsDisabled,
|
|
@@ -36373,7 +36513,7 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
36373
36513
|
display: "block",
|
|
36374
36514
|
marginTop: 3,
|
|
36375
36515
|
...require_theme.dshSettingsHelpStyle
|
|
36376
|
-
} }, t("mobile.optimizeSettingsOnMobileDescription"))), (0, react.createElement)(
|
|
36516
|
+
} }, t("mobile.optimizeSettingsOnMobileDescription"))), (0, react.createElement)(require_react_dom$1.SettingsSwitch, {
|
|
36377
36517
|
"aria-label": t("mobile.optimizeSettingsOnMobile"),
|
|
36378
36518
|
checked: value.optimizeSettingsOnMobile,
|
|
36379
36519
|
disabled: controlsDisabled,
|
|
@@ -36415,7 +36555,7 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
36415
36555
|
display: "block",
|
|
36416
36556
|
marginTop: 3,
|
|
36417
36557
|
...require_theme.dshSettingsHelpStyle
|
|
36418
|
-
} }, t("mobile.sidebarGesturesDescription"))), (0, react.createElement)(
|
|
36558
|
+
} }, t("mobile.sidebarGesturesDescription"))), (0, react.createElement)(require_react_dom$1.SettingsSwitch, {
|
|
36419
36559
|
"aria-label": t("mobile.sidebarGestures"),
|
|
36420
36560
|
checked: gestures.sidebarGestures,
|
|
36421
36561
|
disabled: controlsDisabled,
|
|
@@ -36475,20 +36615,20 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
36475
36615
|
} }, t("lan.pwa.description")), (0, react.createElement)("p", { style: {
|
|
36476
36616
|
margin: 0,
|
|
36477
36617
|
...require_theme.dshSettingsHelpStyle
|
|
36478
|
-
} }, t("mobile.pwaRequiresListener")), (0, react.createElement)(
|
|
36618
|
+
} }, t("mobile.pwaRequiresListener")), (0, react.createElement)(require_react_dom$1.SettingsToggleRow, {
|
|
36479
36619
|
label: t("lan.pwa.enabled"),
|
|
36480
36620
|
description: t("lan.pwa.enabledHelp"),
|
|
36481
36621
|
checked: pwa.enabled,
|
|
36482
36622
|
disabled: controlsDisabled,
|
|
36483
36623
|
onChange: (checked) => updatePwa({ enabled: checked })
|
|
36484
|
-
}), (0, react.createElement)(
|
|
36624
|
+
}), (0, react.createElement)(require_react_dom$1.SettingsToggleRow, {
|
|
36485
36625
|
label: t("lan.pwa.serviceWorker"),
|
|
36486
36626
|
description: t("lan.pwa.serviceWorkerHelp"),
|
|
36487
36627
|
checked: pwa.serviceWorker,
|
|
36488
36628
|
disabled: controlsDisabled || !pwa.enabled,
|
|
36489
36629
|
style: { opacity: pwa.enabled ? 1 : .55 },
|
|
36490
36630
|
onChange: (checked) => updatePwa({ serviceWorker: checked })
|
|
36491
|
-
}), (0, react.createElement)(
|
|
36631
|
+
}), (0, react.createElement)(require_react_dom$1.SettingsToggleRow, {
|
|
36492
36632
|
label: t("lan.pwa.installPrompt"),
|
|
36493
36633
|
checked: pwa.installPrompt,
|
|
36494
36634
|
disabled: controlsDisabled || !pwa.enabled,
|
|
@@ -41104,7 +41244,7 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
41104
41244
|
}, createSwitchRow(t("fileManagement.menuEnhancement"), t("fileManagement.menuEnhancementDescription"), value.menuEnhancement, disabled, (next) => updateSetting("menuEnhancement", next)), createSwitchRow(t("fileManagement.fileEditor"), t("fileManagement.fileEditorDescription"), value.fileEditor, disabled, (next) => updateSetting("fileEditor", next)), createSwitchRow(t("fileManagement.sessionChangedFiles"), t("fileManagement.sessionChangedFilesDescription"), value.sessionChangedFiles, disabled, (next) => updateSetting("sessionChangedFiles", next)));
|
|
41105
41245
|
}
|
|
41106
41246
|
function createSwitchRow(label, description, checked, disabled, onChange) {
|
|
41107
|
-
return (0, react.createElement)(
|
|
41247
|
+
return (0, react.createElement)(require_react_dom$1.SettingsToggleRow, {
|
|
41108
41248
|
label,
|
|
41109
41249
|
description,
|
|
41110
41250
|
checked,
|
|
@@ -52643,1177 +52783,357 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
52643
52783
|
@media(max-width:480px){.codingns-translation-pool-row{gap:6px;padding-right:8px}.codingns-translation-pool-unavailable{max-width:70px}.codingns-translation-picker-choice{padding:10px}}
|
|
52644
52784
|
`;
|
|
52645
52785
|
//#endregion
|
|
52646
|
-
//#region src/
|
|
52647
|
-
|
|
52648
|
-
|
|
52649
|
-
|
|
52650
|
-
|
|
52651
|
-
|
|
52652
|
-
|
|
52653
|
-
|
|
52654
|
-
|
|
52655
|
-
|
|
52656
|
-
|
|
52657
|
-
|
|
52658
|
-
|
|
52659
|
-
|
|
52660
|
-
color: "#fff",
|
|
52661
|
-
fontSize: "6px",
|
|
52662
|
-
fontWeight: "700",
|
|
52663
|
-
lineHeight: "1"
|
|
52664
|
-
};
|
|
52665
|
-
const TRANSLATION_PENDING_BADGE_STYLE = {
|
|
52666
|
-
border: "1.5px solid var(--dsw-alias-button-info-fill, #1677ff)",
|
|
52667
|
-
borderTopColor: "transparent",
|
|
52668
|
-
background: "transparent"
|
|
52669
|
-
};
|
|
52670
|
-
//#endregion
|
|
52671
|
-
//#region src/client/session-translation-pending-dom.ts
|
|
52672
|
-
/** Pending DSH bubbles have no renderer slot; attach only to their action rows. */
|
|
52673
|
-
function watchPendingTranslationTargets(anchor, onChange) {
|
|
52674
|
-
const root = anchor.closest("[data-conversation-session]");
|
|
52675
|
-
const Observer = anchor.ownerDocument.defaultView?.MutationObserver;
|
|
52676
|
-
if (root === null || Observer === void 0) return () => void 0;
|
|
52677
|
-
const targets = /* @__PURE__ */ new Map();
|
|
52678
|
-
let nextKey = 0;
|
|
52679
|
-
const scan = () => {
|
|
52680
|
-
observer.disconnect();
|
|
52681
|
-
let changed = false;
|
|
52682
|
-
const rows = new Set(root.querySelectorAll("[data-submission-echo]"));
|
|
52683
|
-
for (const [row, target] of targets) {
|
|
52684
|
-
if (rows.has(row) && root.contains(target.container)) continue;
|
|
52685
|
-
target.container.remove();
|
|
52686
|
-
targets.delete(row);
|
|
52687
|
-
changed = true;
|
|
52688
|
-
}
|
|
52689
|
-
for (const row of rows) {
|
|
52690
|
-
if (row.closest("[data-conversation-session]") !== root) continue;
|
|
52691
|
-
const original = row.querySelector("[class*=\"bubble\"]")?.textContent ?? "";
|
|
52692
|
-
const actions = row.querySelector("[data-clock=\"start\"]");
|
|
52693
|
-
if (original.trim() === "" || actions === null) continue;
|
|
52694
|
-
const existing = targets.get(row);
|
|
52695
|
-
if (existing !== void 0) {
|
|
52696
|
-
if (existing.original !== original) {
|
|
52697
|
-
targets.set(row, {
|
|
52698
|
-
...existing,
|
|
52699
|
-
original
|
|
52700
|
-
});
|
|
52701
|
-
changed = true;
|
|
52702
|
-
}
|
|
52703
|
-
continue;
|
|
52704
|
-
}
|
|
52705
|
-
const container = anchor.ownerDocument.createElement("span");
|
|
52706
|
-
container.dataset.codingnsPendingTranslation = "";
|
|
52707
|
-
container.style.display = "inline-flex";
|
|
52708
|
-
let before = actions.querySelector("button");
|
|
52709
|
-
while (before !== null && before.parentElement !== actions) before = before.parentElement;
|
|
52710
|
-
actions.insertBefore(container, before);
|
|
52711
|
-
targets.set(row, {
|
|
52712
|
-
key: nextKey++,
|
|
52713
|
-
container,
|
|
52714
|
-
original
|
|
52715
|
-
});
|
|
52716
|
-
changed = true;
|
|
52717
|
-
}
|
|
52718
|
-
if (changed) onChange([...targets.values()]);
|
|
52719
|
-
observer.observe(root, {
|
|
52720
|
-
childList: true,
|
|
52721
|
-
subtree: true,
|
|
52722
|
-
characterData: true
|
|
52723
|
-
});
|
|
52786
|
+
//#region src/client/session-translation-rules.ts
|
|
52787
|
+
/** Only saved entries enter translation prompts; cancelled or failed edits stay local. */
|
|
52788
|
+
function SessionTranslationRules({ rules, disabled, pending, t, onChange }) {
|
|
52789
|
+
const [draft, setDraft] = (0, react.useState)(null);
|
|
52790
|
+
const [saveFailed, setSaveFailed] = (0, react.useState)(false);
|
|
52791
|
+
const identity = JSON.stringify(rules);
|
|
52792
|
+
(0, react.useEffect)(() => {
|
|
52793
|
+
setDraft(null);
|
|
52794
|
+
}, [identity]);
|
|
52795
|
+
(0, react.useEffect)(() => {
|
|
52796
|
+
if (disabled && !pending) setDraft(null);
|
|
52797
|
+
}, [disabled, pending]);
|
|
52798
|
+
const close = () => {
|
|
52799
|
+
if (!pending) setDraft(null);
|
|
52724
52800
|
};
|
|
52725
|
-
const
|
|
52726
|
-
|
|
52727
|
-
|
|
52728
|
-
|
|
52729
|
-
|
|
52730
|
-
|
|
52801
|
+
const edit = (index) => {
|
|
52802
|
+
if (disabled || draft !== null) return;
|
|
52803
|
+
setSaveFailed(false);
|
|
52804
|
+
setDraft({
|
|
52805
|
+
index,
|
|
52806
|
+
text: rules[index] ?? ""
|
|
52807
|
+
});
|
|
52731
52808
|
};
|
|
52732
|
-
|
|
52733
|
-
|
|
52734
|
-
|
|
52735
|
-
|
|
52736
|
-
|
|
52737
|
-
|
|
52738
|
-
function TranslationAction(props) {
|
|
52739
|
-
const [open, setOpen] = (0, react.useState)(false);
|
|
52740
|
-
const rootRef = (0, react.useRef)(null);
|
|
52741
|
-
const buttonRef = (0, react.useRef)(null);
|
|
52742
|
-
const popupRef = (0, react.useRef)(null);
|
|
52743
|
-
const [popupPosition, setPopupPosition] = (0, react.useState)(null);
|
|
52744
|
-
useDismissOnOutsidePointer(rootRef, open, () => setOpen(false), { portal: popupRef });
|
|
52745
|
-
(0, react.useLayoutEffect)(() => {
|
|
52746
|
-
if (!open || typeof window === "undefined") {
|
|
52747
|
-
setPopupPosition(null);
|
|
52809
|
+
const save = async () => {
|
|
52810
|
+
if (disabled || draft === null || draft.text.trim() === "") return;
|
|
52811
|
+
const next = [...rules];
|
|
52812
|
+
next[draft.index] = draft.text.trim();
|
|
52813
|
+
if (JSON.stringify(next) === identity) {
|
|
52814
|
+
close();
|
|
52748
52815
|
return;
|
|
52749
52816
|
}
|
|
52750
|
-
|
|
52751
|
-
|
|
52752
|
-
|
|
52753
|
-
|
|
52754
|
-
|
|
52755
|
-
|
|
52756
|
-
const width = Math.max(1, Math.min(420, window.innerWidth - 24));
|
|
52757
|
-
const availableAbove = Math.max(0, rect.top - gap - edge);
|
|
52758
|
-
const availableBelow = Math.max(0, window.innerHeight - rect.bottom - gap - edge);
|
|
52759
|
-
const preferredHeight = Math.min(440, window.innerHeight * .65);
|
|
52760
|
-
const placement = availableAbove >= preferredHeight || availableBelow < preferredHeight && availableAbove > availableBelow ? "above" : "below";
|
|
52761
|
-
const maxHeight = Math.min(preferredHeight, placement === "above" ? availableAbove : availableBelow);
|
|
52762
|
-
const desiredLeft = props.popupAlign === "end" ? rect.right - width : rect.left;
|
|
52763
|
-
const maxLeft = Math.max(edge, window.innerWidth - edge - width);
|
|
52764
|
-
setPopupPosition({
|
|
52765
|
-
left: Math.min(maxLeft, Math.max(edge, desiredLeft)),
|
|
52766
|
-
top: placement === "above" ? rect.top - gap : rect.bottom + gap,
|
|
52767
|
-
width,
|
|
52768
|
-
maxHeight,
|
|
52769
|
-
placement
|
|
52770
|
-
});
|
|
52771
|
-
};
|
|
52772
|
-
updatePosition();
|
|
52773
|
-
window.addEventListener("resize", updatePosition);
|
|
52774
|
-
window.addEventListener("scroll", updatePosition, true);
|
|
52775
|
-
return () => {
|
|
52776
|
-
window.removeEventListener("resize", updatePosition);
|
|
52777
|
-
window.removeEventListener("scroll", updatePosition, true);
|
|
52778
|
-
};
|
|
52779
|
-
}, [open, props.popupAlign]);
|
|
52780
|
-
const record = props.record;
|
|
52781
|
-
const pending = record === void 0;
|
|
52782
|
-
const failed = record?.failed === true;
|
|
52783
|
-
const alreadyTargetLanguage = record?.alreadyTargetLanguage === true;
|
|
52784
|
-
const statusText = pending ? props.translationT("translation.statusTranslating") : failed ? props.translationT("translation.statusFailed") : alreadyTargetLanguage ? props.translationT("translation.statusNotNeeded") : props.translationT("translation.statusTranslated");
|
|
52785
|
-
const statusColor = pending ? require_theme.dshThemeColor.accent : failed ? require_theme.dshThemeColor.error : alreadyTargetLanguage ? require_theme.dshThemeColor.accent : require_theme.dshThemeColor.success;
|
|
52786
|
-
const detailsId = `codingns-translation-details-${safeDomId(props.messageId)}`;
|
|
52787
|
-
const details = open && popupPosition !== null ? (0, react.createElement)("div", {
|
|
52788
|
-
ref: popupRef,
|
|
52789
|
-
role: "dialog",
|
|
52790
|
-
"aria-label": props.translationT("translation.detailsTitle"),
|
|
52791
|
-
id: detailsId,
|
|
52817
|
+
setSaveFailed(false);
|
|
52818
|
+
if (await onChange(next)) setDraft(null);
|
|
52819
|
+
else setSaveFailed(true);
|
|
52820
|
+
};
|
|
52821
|
+
return (0, react.createElement)("div", {
|
|
52822
|
+
"aria-busy": pending,
|
|
52792
52823
|
style: {
|
|
52793
|
-
|
|
52794
|
-
|
|
52795
|
-
|
|
52796
|
-
top: popupPosition.top,
|
|
52797
|
-
width: popupPosition.width,
|
|
52798
|
-
maxHeight: popupPosition.maxHeight,
|
|
52799
|
-
boxSizing: "border-box",
|
|
52800
|
-
...popupPosition.placement === "above" ? { transform: "translateY(-100%)" } : {},
|
|
52801
|
-
overflow: "auto",
|
|
52802
|
-
padding: "10px 12px",
|
|
52803
|
-
border: `1px solid ${require_theme.dshThemeColor.border}`,
|
|
52804
|
-
borderRadius: 8,
|
|
52805
|
-
color: require_theme.dshThemeColor.labelPrimary,
|
|
52806
|
-
background: require_theme.dshThemeColor.menuBackground,
|
|
52807
|
-
boxShadow: "0 8px 24px color-mix(in srgb, CanvasText 16%, transparent)",
|
|
52808
|
-
fontSize: require_theme.uiFontSize(12),
|
|
52809
|
-
lineHeight: 1.45
|
|
52824
|
+
display: "grid",
|
|
52825
|
+
gap: 10,
|
|
52826
|
+
minWidth: 0
|
|
52810
52827
|
}
|
|
52811
|
-
}, (0, react.createElement)("div", { style: {
|
|
52812
|
-
|
|
52813
|
-
justifyContent: "space-between",
|
|
52814
|
-
gap: 10,
|
|
52815
|
-
fontWeight: 600
|
|
52816
|
-
} }, (0, react.createElement)("span", void 0, props.translationT("translation.detailsTitle")), (0, react.createElement)("span", {
|
|
52817
|
-
role: "status",
|
|
52818
|
-
"aria-live": "polite",
|
|
52828
|
+
}, (0, react.createElement)("div", { style: require_theme.dshSettingsHelpStyle }, t("translation.rulesHelp")), rules.length === 0 ? (0, react.createElement)("div", { style: require_theme.dshSettingsHelpStyle }, t("translation.rulesEmpty")) : (0, react.createElement)("ol", {
|
|
52829
|
+
"aria-label": t("translation.rulesTitle"),
|
|
52819
52830
|
style: {
|
|
52820
|
-
|
|
52821
|
-
|
|
52831
|
+
margin: 0,
|
|
52832
|
+
padding: 0,
|
|
52833
|
+
listStyle: "none"
|
|
52822
52834
|
}
|
|
52823
|
-
},
|
|
52824
|
-
|
|
52825
|
-
color: require_theme.dshThemeColor.labelSecondary
|
|
52826
|
-
} }, `${props.translationT("translation.detectedLanguage")}: ${props.translationT(`translation.language.${record.sourceLanguage}`)}`), (0, react.createElement)(DetailBlock, {
|
|
52827
|
-
kind: "original",
|
|
52828
|
-
translationT: props.translationT,
|
|
52829
|
-
value: record?.original ?? props.original ?? ""
|
|
52830
|
-
}), pending ? (0, react.createElement)("progress", {
|
|
52831
|
-
"aria-label": statusText,
|
|
52835
|
+
}, ...rules.map((rule, index) => (0, react.createElement)("li", {
|
|
52836
|
+
key: index,
|
|
52832
52837
|
style: {
|
|
52833
|
-
|
|
52834
|
-
|
|
52835
|
-
|
|
52836
|
-
|
|
52837
|
-
accentColor: require_theme.dshThemeColor.accent
|
|
52838
|
+
...require_theme.dshSettingsListRowStyle,
|
|
52839
|
+
flexDirection: "column",
|
|
52840
|
+
alignItems: "stretch",
|
|
52841
|
+
gap: 6
|
|
52838
52842
|
}
|
|
52839
|
-
}
|
|
52840
|
-
|
|
52841
|
-
|
|
52842
|
-
|
|
52843
|
-
|
|
52844
|
-
|
|
52843
|
+
}, (0, react.createElement)("div", { style: {
|
|
52844
|
+
whiteSpace: "pre-wrap",
|
|
52845
|
+
overflowWrap: "anywhere"
|
|
52846
|
+
} }, rule), (0, react.createElement)("div", { style: {
|
|
52847
|
+
display: "flex",
|
|
52848
|
+
gap: 8,
|
|
52849
|
+
flexWrap: "wrap"
|
|
52850
|
+
} }, (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
52851
|
+
type: "button",
|
|
52852
|
+
size: "sm",
|
|
52853
|
+
variant: "outline",
|
|
52854
|
+
disabled: disabled || draft !== null,
|
|
52855
|
+
onClick: () => edit(index)
|
|
52856
|
+
}, t("translation.ruleEdit", { number: index + 1 })), (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
52857
|
+
type: "button",
|
|
52858
|
+
size: "sm",
|
|
52859
|
+
disabled: disabled || draft !== null,
|
|
52860
|
+
onClick: () => {
|
|
52861
|
+
if (!disabled && draft === null) onChange(rules.filter((_, position) => position !== index));
|
|
52845
52862
|
}
|
|
52846
|
-
},
|
|
52847
|
-
|
|
52848
|
-
|
|
52849
|
-
|
|
52850
|
-
|
|
52851
|
-
|
|
52852
|
-
|
|
52853
|
-
}
|
|
52854
|
-
|
|
52855
|
-
|
|
52856
|
-
|
|
52857
|
-
|
|
52858
|
-
|
|
52859
|
-
|
|
52860
|
-
|
|
52863
|
+
}, t("translation.ruleRemove", { number: index + 1 })))))), (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
52864
|
+
type: "button",
|
|
52865
|
+
size: "sm",
|
|
52866
|
+
variant: "outline",
|
|
52867
|
+
disabled: disabled || draft !== null,
|
|
52868
|
+
style: { justifySelf: "start" },
|
|
52869
|
+
onClick: () => edit(rules.length)
|
|
52870
|
+
}, t("translation.ruleAdd")), (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
|
|
52871
|
+
open: draft !== null,
|
|
52872
|
+
onClose: close,
|
|
52873
|
+
title: t(draft?.index === rules.length ? "translation.ruleAdd" : "translation.ruleEdit", { number: (draft?.index ?? 0) + 1 }),
|
|
52874
|
+
closeLabel: t("translation.ruleCancel"),
|
|
52875
|
+
footer: (0, react.createElement)(react.Fragment, null, (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
52876
|
+
type: "button",
|
|
52877
|
+
variant: "outline",
|
|
52878
|
+
disabled: pending,
|
|
52879
|
+
onClick: close
|
|
52880
|
+
}, t("translation.ruleCancel")), (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
52881
|
+
type: "button",
|
|
52882
|
+
variant: "primary",
|
|
52883
|
+
disabled: disabled || !draft?.text.trim(),
|
|
52884
|
+
onClick: () => {
|
|
52885
|
+
save();
|
|
52886
|
+
}
|
|
52887
|
+
}, t(pending ? "translation.ruleSaving" : "translation.ruleSave")))
|
|
52888
|
+
}, (0, react.createElement)("label", { style: {
|
|
52889
|
+
display: "grid",
|
|
52890
|
+
gap: 6
|
|
52891
|
+
} }, (0, react.createElement)("span", null, t("translation.ruleText")), (0, react.createElement)("textarea", {
|
|
52892
|
+
rows: 5,
|
|
52893
|
+
value: draft?.text ?? "",
|
|
52894
|
+
disabled,
|
|
52895
|
+
"aria-label": t("translation.ruleText"),
|
|
52896
|
+
"data-modal-autofocus": true,
|
|
52897
|
+
placeholder: t("translation.rulePlaceholder"),
|
|
52861
52898
|
style: {
|
|
52862
|
-
|
|
52863
|
-
|
|
52864
|
-
alignItems: "center",
|
|
52865
|
-
verticalAlign: "middle",
|
|
52866
|
-
...props.inline === true ? { marginInlineStart: 4 } : {}
|
|
52899
|
+
...require_theme.dshSettingsFieldStyle,
|
|
52900
|
+
resize: "vertical"
|
|
52867
52901
|
},
|
|
52868
|
-
|
|
52869
|
-
|
|
52870
|
-
|
|
52871
|
-
|
|
52872
|
-
|
|
52873
|
-
|
|
52874
|
-
|
|
52875
|
-
"
|
|
52876
|
-
onClick: () => setOpen((value) => !value),
|
|
52877
|
-
style: translationButtonStyle
|
|
52878
|
-
}, (0, react.createElement)(TranslationGlyph), (0, react.createElement)("span", {
|
|
52879
|
-
"aria-hidden": true,
|
|
52880
|
-
"data-codingns-translation-pending": pending || void 0,
|
|
52902
|
+
onChange: (event) => {
|
|
52903
|
+
if (!disabled && draft !== null) setDraft({
|
|
52904
|
+
...draft,
|
|
52905
|
+
text: event.currentTarget.value
|
|
52906
|
+
});
|
|
52907
|
+
}
|
|
52908
|
+
})), saveFailed && (0, react.createElement)("div", {
|
|
52909
|
+
role: "alert",
|
|
52881
52910
|
style: {
|
|
52882
|
-
...
|
|
52883
|
-
|
|
52911
|
+
...require_theme.dshSettingsHelpStyle,
|
|
52912
|
+
color: require_theme.dshThemeColor.error
|
|
52884
52913
|
}
|
|
52885
|
-
},
|
|
52914
|
+
}, t("translation.saveRejected"))));
|
|
52886
52915
|
}
|
|
52887
|
-
|
|
52888
|
-
|
|
52889
|
-
|
|
52890
|
-
|
|
52891
|
-
|
|
52892
|
-
|
|
52893
|
-
|
|
52894
|
-
|
|
52895
|
-
|
|
52896
|
-
return watchPendingTranslationTargets(anchorRef.current, setTargets);
|
|
52897
|
-
}, [eligible, props.sessionId]);
|
|
52898
|
-
return (0, react.createElement)("span", {
|
|
52899
|
-
ref: anchorRef,
|
|
52900
|
-
style: { display: "none" }
|
|
52901
|
-
}, ...targets.map((target) => (0, import_react_dom.createPortal)((0, react.createElement)(PendingTranslationAction, {
|
|
52902
|
-
services: props.services,
|
|
52903
|
-
translationT: props.translationT,
|
|
52904
|
-
original: target.original
|
|
52905
|
-
}), target.container, String(target.key))));
|
|
52906
|
-
}
|
|
52907
|
-
function PendingTranslationAction(props) {
|
|
52908
|
-
const id = (0, react.useId)();
|
|
52909
|
-
return (0, react.createElement)(TranslationAction, {
|
|
52910
|
-
...props,
|
|
52911
|
-
messageId: `pending-${id}`,
|
|
52912
|
-
messageRole: "user",
|
|
52913
|
-
popupAlign: "end"
|
|
52916
|
+
//#endregion
|
|
52917
|
+
//#region src/dsh-capabilities/types.ts
|
|
52918
|
+
function createCapabilityProfile(dshVersion, runtime, capabilities, diagnostics) {
|
|
52919
|
+
return Object.freeze({
|
|
52920
|
+
dshVersion,
|
|
52921
|
+
runtime,
|
|
52922
|
+
capabilities: freezeMap(capabilities),
|
|
52923
|
+
diagnostics: Object.freeze([...diagnostics]),
|
|
52924
|
+
frozenAt: Date.now()
|
|
52914
52925
|
});
|
|
52915
52926
|
}
|
|
52916
|
-
|
|
52917
|
-
|
|
52918
|
-
|
|
52919
|
-
|
|
52920
|
-
|
|
52921
|
-
|
|
52922
|
-
|
|
52923
|
-
|
|
52924
|
-
|
|
52925
|
-
strokeLinejoin: "round",
|
|
52926
|
-
"aria-hidden": true
|
|
52927
|
-
}, ...TRANSLATION_GLYPH_PATHS.map((d) => (0, react.createElement)("path", {
|
|
52928
|
-
key: d,
|
|
52929
|
-
d
|
|
52930
|
-
})));
|
|
52927
|
+
/** Map 的只读视图,避免 Object.freeze(Map) 仍可通过 set() 修改。 */
|
|
52928
|
+
function freezeMap(source) {
|
|
52929
|
+
const map = new Map(source);
|
|
52930
|
+
const view = new Proxy(map, { get(target, property, receiver) {
|
|
52931
|
+
if (property === "set" || property === "delete" || property === "clear") return void 0;
|
|
52932
|
+
const value = Reflect.get(target, property, target);
|
|
52933
|
+
return typeof value === "function" ? value.bind(target) : value;
|
|
52934
|
+
} });
|
|
52935
|
+
return Object.freeze(view);
|
|
52931
52936
|
}
|
|
52932
|
-
|
|
52933
|
-
|
|
52934
|
-
|
|
52935
|
-
|
|
52936
|
-
|
|
52937
|
-
|
|
52938
|
-
|
|
52939
|
-
|
|
52940
|
-
|
|
52941
|
-
|
|
52942
|
-
color: require_theme.dshThemeColor.labelTertiary,
|
|
52943
|
-
background: "transparent",
|
|
52944
|
-
cursor: "pointer"
|
|
52945
|
-
};
|
|
52946
|
-
const translationButtonStyle = {
|
|
52947
|
-
...messageActionButtonStyle,
|
|
52948
|
-
transition: "background-color 100ms ease, color 100ms ease"
|
|
52949
|
-
};
|
|
52950
|
-
const translationDetailTypes = {
|
|
52951
|
-
original: {
|
|
52952
|
-
labelKey: "translation.originalText",
|
|
52953
|
-
color: require_theme.dshThemeColor.labelSecondary
|
|
52954
|
-
},
|
|
52955
|
-
translated: {
|
|
52956
|
-
labelKey: "translation.translatedText",
|
|
52957
|
-
color: require_theme.dshThemeColor.accent
|
|
52958
|
-
},
|
|
52959
|
-
sent: {
|
|
52960
|
-
labelKey: "translation.actualSentText",
|
|
52961
|
-
color: require_theme.dshThemeColor.success
|
|
52937
|
+
//#endregion
|
|
52938
|
+
//#region src/dsh-capabilities/registry.ts
|
|
52939
|
+
var DshCapabilityRegistryError = class extends Error {
|
|
52940
|
+
code;
|
|
52941
|
+
capability;
|
|
52942
|
+
constructor(code, message, capability = null, options) {
|
|
52943
|
+
super(message, options);
|
|
52944
|
+
this.name = "DshCapabilityRegistryError";
|
|
52945
|
+
this.code = code;
|
|
52946
|
+
this.capability = capability;
|
|
52962
52947
|
}
|
|
52963
52948
|
};
|
|
52964
|
-
|
|
52965
|
-
|
|
52966
|
-
|
|
52967
|
-
|
|
52968
|
-
|
|
52969
|
-
|
|
52970
|
-
|
|
52971
|
-
|
|
52972
|
-
|
|
52973
|
-
|
|
52974
|
-
|
|
52975
|
-
|
|
52976
|
-
|
|
52977
|
-
|
|
52978
|
-
|
|
52979
|
-
|
|
52980
|
-
|
|
52981
|
-
|
|
52982
|
-
|
|
52983
|
-
|
|
52984
|
-
|
|
52985
|
-
|
|
52986
|
-
|
|
52987
|
-
|
|
52988
|
-
|
|
52989
|
-
|
|
52990
|
-
|
|
52991
|
-
|
|
52992
|
-
|
|
52993
|
-
|
|
52994
|
-
|
|
52995
|
-
|
|
52996
|
-
|
|
52997
|
-
|
|
52998
|
-
|
|
52999
|
-
|
|
53000
|
-
|
|
53001
|
-
|
|
53002
|
-
|
|
53003
|
-
|
|
53004
|
-
|
|
53005
|
-
|
|
53006
|
-
|
|
53007
|
-
|
|
53008
|
-
|
|
53009
|
-
|
|
53010
|
-
|
|
53011
|
-
|
|
53012
|
-
|
|
53013
|
-
|
|
53014
|
-
|
|
53015
|
-
|
|
53016
|
-
|
|
53017
|
-
|
|
53018
|
-
|
|
53019
|
-
|
|
53020
|
-
|
|
53021
|
-
|
|
53022
|
-
|
|
53023
|
-
|
|
53024
|
-
|
|
53025
|
-
|
|
53026
|
-
|
|
53027
|
-
|
|
53028
|
-
|
|
53029
|
-
|
|
53030
|
-
|
|
53031
|
-
|
|
53032
|
-
|
|
53033
|
-
|
|
53034
|
-
|
|
53035
|
-
|
|
53036
|
-
|
|
53037
|
-
|
|
53038
|
-
|
|
53039
|
-
|
|
53040
|
-
|
|
53041
|
-
|
|
53042
|
-
|
|
53043
|
-
|
|
53044
|
-
|
|
53045
|
-
|
|
53046
|
-
|
|
53047
|
-
|
|
53048
|
-
|
|
53049
|
-
|
|
53050
|
-
|
|
53051
|
-
|
|
53052
|
-
|
|
53053
|
-
|
|
53054
|
-
|
|
53055
|
-
|
|
53056
|
-
|
|
53057
|
-
|
|
53058
|
-
|
|
53059
|
-
|
|
53060
|
-
|
|
53061
|
-
|
|
53062
|
-
|
|
53063
|
-
messageRole: "user",
|
|
53064
|
-
services: props.services,
|
|
53065
|
-
translationT: props.translationT,
|
|
53066
|
-
popupAlign: "end",
|
|
53067
|
-
record: translationRecord
|
|
53068
|
-
}), (0, react.createElement)(CopyAction, {
|
|
53069
|
-
text: parts.text,
|
|
53070
|
-
t: chatT
|
|
53071
|
-
})));
|
|
53072
|
-
}
|
|
53073
|
-
function createFileAttachment(file, index) {
|
|
53074
|
-
const name = typeof file.name === "string" ? file.name : "";
|
|
53075
|
-
const bytes = typeof file.bytes === "number" ? file.bytes : 0;
|
|
53076
|
-
return (0, react.createElement)("span", {
|
|
53077
|
-
key: `file-${index}`,
|
|
53078
|
-
title: name,
|
|
53079
|
-
style: {
|
|
53080
|
-
display: "inline-flex",
|
|
53081
|
-
alignItems: "center",
|
|
53082
|
-
minWidth: 0,
|
|
53083
|
-
maxWidth: "100%",
|
|
53084
|
-
gap: 8,
|
|
53085
|
-
padding: "8px 10px",
|
|
53086
|
-
border: `1px solid ${require_theme.dshThemeColor.border}`,
|
|
53087
|
-
borderRadius: 8,
|
|
53088
|
-
color: require_theme.dshThemeColor.labelPrimary,
|
|
53089
|
-
background: require_theme.dshThemeColor.surfaceSubtle
|
|
52949
|
+
/** 集中解析 DSH 能力路由;Profile 生成后不可变,避免运行期替换半初始化服务。 */
|
|
52950
|
+
var DshCapabilityRegistry = class {
|
|
52951
|
+
dshVersion;
|
|
52952
|
+
runtime;
|
|
52953
|
+
routes = /* @__PURE__ */ new Map();
|
|
52954
|
+
profile;
|
|
52955
|
+
constructor(dshVersion, runtime) {
|
|
52956
|
+
this.dshVersion = dshVersion;
|
|
52957
|
+
this.runtime = runtime;
|
|
52958
|
+
}
|
|
52959
|
+
register(route) {
|
|
52960
|
+
validateRoute(route);
|
|
52961
|
+
if (route.runtime !== this.runtime) return;
|
|
52962
|
+
const list = this.routes.get(route.capability) ?? [];
|
|
52963
|
+
if (list.some((entry) => entry.id === route.id)) throw new DshCapabilityRegistryError("CAPABILITY_INVALID_ROUTE", `重复的能力路由: ${route.id}`, route.capability);
|
|
52964
|
+
list.push(route);
|
|
52965
|
+
this.routes.set(route.capability, list);
|
|
52966
|
+
this.profile = void 0;
|
|
52967
|
+
}
|
|
52968
|
+
registerMany(routes) {
|
|
52969
|
+
for (const route of routes) this.register(route);
|
|
52970
|
+
}
|
|
52971
|
+
resolve(context) {
|
|
52972
|
+
if (this.profile !== void 0) return this.profile;
|
|
52973
|
+
const resolutions = /* @__PURE__ */ new Map();
|
|
52974
|
+
const diagnostics = [];
|
|
52975
|
+
for (const [capability, routes] of this.routes) {
|
|
52976
|
+
const candidates = routes.filter((route) => isVersionInRange(this.dshVersion, route.supportedDsh)).sort((left, right) => routeRank(right) - routeRank(left));
|
|
52977
|
+
if (candidates.length === 0) {
|
|
52978
|
+
const reason = `DSH ${this.dshVersion} 没有能力 ${capability} 的适配路由`;
|
|
52979
|
+
resolutions.set(capability, unavailable(capability, this.dshVersion, reason));
|
|
52980
|
+
diagnostics.push({
|
|
52981
|
+
code: "CAPABILITY_VERSION_UNSUPPORTED",
|
|
52982
|
+
capability,
|
|
52983
|
+
dshVersion: this.dshVersion,
|
|
52984
|
+
message: reason
|
|
52985
|
+
});
|
|
52986
|
+
continue;
|
|
52987
|
+
}
|
|
52988
|
+
const topPriority = routeRank(candidates[0]);
|
|
52989
|
+
const top = candidates.filter((route) => routeRank(route) === topPriority);
|
|
52990
|
+
if (top.length > 1) throw new DshCapabilityRegistryError("CAPABILITY_ROUTE_CONFLICT", `能力 ${capability} 存在同优先级路由: ${top.map((route) => route.id).join(", ")}`, capability);
|
|
52991
|
+
let selected;
|
|
52992
|
+
for (const route of candidates) try {
|
|
52993
|
+
if (route.detect(context)) {
|
|
52994
|
+
selected = route;
|
|
52995
|
+
break;
|
|
52996
|
+
}
|
|
52997
|
+
} catch (error) {
|
|
52998
|
+
diagnostics.push({
|
|
52999
|
+
code: "CAPABILITY_DETECT_FAILED",
|
|
53000
|
+
capability,
|
|
53001
|
+
routeId: route.id,
|
|
53002
|
+
dshVersion: this.dshVersion,
|
|
53003
|
+
message: `${route.id} 探测失败: ${errorMessage$1(error)}`,
|
|
53004
|
+
...route.replacement === void 0 ? {} : { replacement: route.replacement }
|
|
53005
|
+
});
|
|
53006
|
+
}
|
|
53007
|
+
if (selected === void 0) {
|
|
53008
|
+
const reason = `DSH ${this.dshVersion} 的能力 ${capability} 没有可用运行时实现`;
|
|
53009
|
+
resolutions.set(capability, unavailable(capability, this.dshVersion, reason));
|
|
53010
|
+
diagnostics.push({
|
|
53011
|
+
code: "CAPABILITY_UNAVAILABLE",
|
|
53012
|
+
capability,
|
|
53013
|
+
dshVersion: this.dshVersion,
|
|
53014
|
+
message: reason
|
|
53015
|
+
});
|
|
53016
|
+
continue;
|
|
53017
|
+
}
|
|
53018
|
+
try {
|
|
53019
|
+
const value = selected.create(context);
|
|
53020
|
+
const resolution = {
|
|
53021
|
+
capability,
|
|
53022
|
+
routeId: selected.id,
|
|
53023
|
+
dshVersion: this.dshVersion,
|
|
53024
|
+
status: selected.status === "deprecated" ? "degraded" : "ready",
|
|
53025
|
+
value,
|
|
53026
|
+
...selected.replacement === void 0 ? {} : { replacement: selected.replacement }
|
|
53027
|
+
};
|
|
53028
|
+
resolutions.set(capability, resolution);
|
|
53029
|
+
if (selected.status === "deprecated") diagnostics.push({
|
|
53030
|
+
code: "CAPABILITY_DEPRECATED",
|
|
53031
|
+
capability,
|
|
53032
|
+
routeId: selected.id,
|
|
53033
|
+
dshVersion: this.dshVersion,
|
|
53034
|
+
message: `能力 ${capability} 使用已弃用路由 ${selected.id}`,
|
|
53035
|
+
...selected.replacement === void 0 ? {} : { replacement: selected.replacement }
|
|
53036
|
+
});
|
|
53037
|
+
} catch (error) {
|
|
53038
|
+
const reason = `${selected.id} 创建失败: ${errorMessage$1(error)}`;
|
|
53039
|
+
resolutions.set(capability, unavailable(capability, this.dshVersion, reason));
|
|
53040
|
+
diagnostics.push({
|
|
53041
|
+
code: "CAPABILITY_CREATE_FAILED",
|
|
53042
|
+
capability,
|
|
53043
|
+
routeId: selected.id,
|
|
53044
|
+
dshVersion: this.dshVersion,
|
|
53045
|
+
message: reason
|
|
53046
|
+
});
|
|
53047
|
+
}
|
|
53090
53048
|
}
|
|
53091
|
-
|
|
53092
|
-
|
|
53093
|
-
|
|
53094
|
-
|
|
53095
|
-
|
|
53096
|
-
|
|
53097
|
-
|
|
53098
|
-
|
|
53099
|
-
|
|
53100
|
-
|
|
53101
|
-
|
|
53102
|
-
|
|
53103
|
-
|
|
53104
|
-
|
|
53105
|
-
|
|
53106
|
-
|
|
53049
|
+
this.profile = createCapabilityProfile(this.dshVersion, this.runtime, resolutions, diagnostics);
|
|
53050
|
+
return this.profile;
|
|
53051
|
+
}
|
|
53052
|
+
getProfile(context) {
|
|
53053
|
+
return this.resolve(context);
|
|
53054
|
+
}
|
|
53055
|
+
require(profile, capability) {
|
|
53056
|
+
const resolution = profile.capabilities.get(capability);
|
|
53057
|
+
if (resolution?.value === void 0 || resolution.status === "unavailable") throw new DshCapabilityRegistryError("CAPABILITY_UNAVAILABLE", resolution?.reason ?? `能力不可用: ${capability}`, capability);
|
|
53058
|
+
return resolution.value;
|
|
53059
|
+
}
|
|
53060
|
+
explain(profile, capability) {
|
|
53061
|
+
if (capability === void 0) return profile.diagnostics;
|
|
53062
|
+
return profile.diagnostics.filter((item) => item.capability === capability);
|
|
53063
|
+
}
|
|
53064
|
+
};
|
|
53065
|
+
function validateRoute(route) {
|
|
53066
|
+
if (route.id.trim() === "" || route.capability === void 0 || route.supportedDsh.trim() === "") throw new DshCapabilityRegistryError("CAPABILITY_INVALID_ROUTE", "能力路由必须包含 id、capability 和 supportedDsh");
|
|
53067
|
+
if (!Number.isFinite(route.priority)) throw new DshCapabilityRegistryError("CAPABILITY_INVALID_ROUTE", `能力路由优先级非法: ${route.id}`, route.capability);
|
|
53068
|
+
if (typeof route.detect !== "function" || typeof route.create !== "function") throw new DshCapabilityRegistryError("CAPABILITY_INVALID_ROUTE", `能力路由缺少探测或工厂: ${route.id}`, route.capability);
|
|
53107
53069
|
}
|
|
53108
|
-
function
|
|
53109
|
-
|
|
53110
|
-
const timer = (0, react.useRef)(void 0);
|
|
53111
|
-
(0, react.useEffect)(() => () => {
|
|
53112
|
-
if (timer.current !== void 0) clearTimeout(timer.current);
|
|
53113
|
-
}, []);
|
|
53114
|
-
return (0, react.createElement)("button", {
|
|
53115
|
-
type: "button",
|
|
53116
|
-
title: copied ? chatT("copied") : chatT("copy"),
|
|
53117
|
-
"aria-label": copied ? chatT("copied") : chatT("copy"),
|
|
53118
|
-
onClick: () => {
|
|
53119
|
-
(0, _deepseek_ai_dsh_client_ui_primitives.writeClipboard)(text).then((success) => {
|
|
53120
|
-
if (!success) return;
|
|
53121
|
-
setCopied(true);
|
|
53122
|
-
if (timer.current !== void 0) clearTimeout(timer.current);
|
|
53123
|
-
timer.current = setTimeout(() => {
|
|
53124
|
-
timer.current = void 0;
|
|
53125
|
-
setCopied(false);
|
|
53126
|
-
}, 1e3);
|
|
53127
|
-
});
|
|
53128
|
-
},
|
|
53129
|
-
style: messageActionButtonStyle
|
|
53130
|
-
}, (0, react.createElement)(copied ? _deepseek_ai_dsh_client_ui_primitives.IconCheckOutlineRegular : _deepseek_ai_dsh_client_ui_primitives.IconCopyOutlineRegular));
|
|
53070
|
+
function routeRank(route) {
|
|
53071
|
+
return route.priority + (route.status === "supported" ? 1e6 : 0);
|
|
53131
53072
|
}
|
|
53132
|
-
function
|
|
53133
|
-
const text = [];
|
|
53134
|
-
const attachments = [];
|
|
53135
|
-
const rest = [];
|
|
53136
|
-
if (typeof content === "string") return {
|
|
53137
|
-
text: content,
|
|
53138
|
-
attachments,
|
|
53139
|
-
rest
|
|
53140
|
-
};
|
|
53141
|
-
if (!Array.isArray(content)) return {
|
|
53142
|
-
text: "",
|
|
53143
|
-
attachments,
|
|
53144
|
-
rest
|
|
53145
|
-
};
|
|
53146
|
-
for (const value of content) {
|
|
53147
|
-
const block = asRecord(value);
|
|
53148
|
-
if (block?.type === "text" && typeof block.text === "string") text.push(block.text);
|
|
53149
|
-
else if (block?.type === "image" && block.attachment !== void 0) attachments.push({
|
|
53150
|
-
type: "image",
|
|
53151
|
-
attachment: block.attachment
|
|
53152
|
-
});
|
|
53153
|
-
else if (block?.type === "file" && asRecord(block.attachment) !== void 0) attachments.push({
|
|
53154
|
-
type: "file",
|
|
53155
|
-
file: asRecord(block.attachment)
|
|
53156
|
-
});
|
|
53157
|
-
else rest.push(value);
|
|
53158
|
-
}
|
|
53073
|
+
function unavailable(capability, dshVersion, reason) {
|
|
53159
53074
|
return {
|
|
53160
|
-
|
|
53161
|
-
|
|
53162
|
-
|
|
53075
|
+
capability,
|
|
53076
|
+
dshVersion,
|
|
53077
|
+
status: "unavailable",
|
|
53078
|
+
reason
|
|
53163
53079
|
};
|
|
53164
53080
|
}
|
|
53165
|
-
function
|
|
53166
|
-
const
|
|
53167
|
-
|
|
53168
|
-
const
|
|
53169
|
-
|
|
53170
|
-
|
|
53171
|
-
|
|
53172
|
-
|
|
53173
|
-
|
|
53174
|
-
|
|
53175
|
-
|
|
53176
|
-
|
|
53081
|
+
function isVersionInRange(version, range) {
|
|
53082
|
+
const match = /^>=([^ ]+)(?: <=([^ ]+))?$/u.exec(range);
|
|
53083
|
+
if (match === null) return false;
|
|
53084
|
+
const actual = parseVersion(version);
|
|
53085
|
+
const minimum = parseVersion(match[1]);
|
|
53086
|
+
if (actual === void 0 || minimum === void 0) return false;
|
|
53087
|
+
if (match[2] === void 0) return compareVersions(actual, minimum) >= 0;
|
|
53088
|
+
const maximum = parseVersion(match[2]);
|
|
53089
|
+
if (maximum === void 0) return false;
|
|
53090
|
+
return compareVersions(actual, minimum) >= 0 && compareVersions(actual, maximum) <= 0;
|
|
53091
|
+
}
|
|
53092
|
+
function parseVersion(value) {
|
|
53093
|
+
const match = /^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?$/u.exec(value);
|
|
53094
|
+
if (match === null) return void 0;
|
|
53095
|
+
return {
|
|
53096
|
+
major: Number(match[1]),
|
|
53097
|
+
minor: Number(match[2]),
|
|
53098
|
+
patch: Number(match[3]),
|
|
53099
|
+
pre: match[4] === void 0 ? [] : match[4].split(".").map((part) => /^\d+$/u.test(part) ? Number(part) : part)
|
|
53177
53100
|
};
|
|
53178
|
-
return new Intl.DateTimeFormat(void 0, options).format(date);
|
|
53179
53101
|
}
|
|
53180
|
-
|
|
53181
|
-
|
|
53182
|
-
|
|
53183
|
-
|
|
53184
|
-
|
|
53185
|
-
|
|
53186
|
-
|
|
53187
|
-
|
|
53188
|
-
|
|
53189
|
-
|
|
53190
|
-
|
|
53191
|
-
if (
|
|
53192
|
-
|
|
53193
|
-
|
|
53194
|
-
if (
|
|
53195
|
-
|
|
53196
|
-
|
|
53197
|
-
const turn = props.node.location?.kind === "turn" || props.node.location?.kind === "step" ? props.node.location.turn : void 0;
|
|
53198
|
-
const tail = typeof props.useTurnData === "function" ? props.useTurnData("turn-tail") : void 0;
|
|
53199
|
-
const finalNode = data.finalNode;
|
|
53200
|
-
const fileOwner = turn?.status === "closed" && finalNode !== void 0 && tail?.closing?.finalNode?.seq === finalNode.seq ? {
|
|
53201
|
-
turn,
|
|
53202
|
-
seq: finalNode.seq,
|
|
53203
|
-
openFile: (path) => {
|
|
53204
|
-
props.openFile(path);
|
|
53205
|
-
}
|
|
53206
|
-
} : void 0;
|
|
53207
|
-
const mentions = fileOwner === void 0 || typeof props.fileMentions !== "function" ? void 0 : props.fileMentions(fileOwner);
|
|
53208
|
-
const turnProcess = props.turnProcess;
|
|
53209
|
-
const reasoningHidden = turnProcess !== void 0 && turnProcess.foldable === true && turnProcess.spec?.answerStep === data.step && turnProcess.spec?.inlineReasoning === true && turnProcess.open !== true;
|
|
53210
|
-
const rendered = [];
|
|
53211
|
-
const last = blocks.length - 1;
|
|
53212
|
-
const messageId = typeof finalNode?.messageId === "string" ? finalNode.messageId : `turn-${data.turn}-step-${data.step}`;
|
|
53213
|
-
if (!renderable) return null;
|
|
53214
|
-
for (let index = 0; index < blocks.length; index += 1) {
|
|
53215
|
-
const block = blocks[index];
|
|
53216
|
-
if (block === void 0) continue;
|
|
53217
|
-
if (props.groupPart === "reasoning" && block.kind !== "reasoning") continue;
|
|
53218
|
-
if (props.groupPart === "response" && block.kind === "reasoning") continue;
|
|
53219
|
-
const running = streaming && index === last;
|
|
53220
|
-
if (block.kind === "text") {
|
|
53221
|
-
const translationRecord = readRecord(block) ?? (hasTranslation && eventSnapshot !== void 0 ? findTranslationRecordForText(eventSnapshot, block.text, "assistant", data.turn, data.step) : void 0);
|
|
53222
|
-
const displayText = translationRecord?.translated ?? block.text;
|
|
53223
|
-
rendered.push((0, react.createElement)("div", {
|
|
53224
|
-
key: `text-${index}`,
|
|
53225
|
-
"data-codingns-translation-inline": true,
|
|
53226
|
-
style: { minWidth: 0 }
|
|
53227
|
-
}, (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.MarkdownText, {
|
|
53228
|
-
text: displayText,
|
|
53229
|
-
streaming,
|
|
53230
|
-
labels: markdownLabels,
|
|
53231
|
-
fileMentions: mentions,
|
|
53232
|
-
pathImages
|
|
53233
|
-
}), translationRecord === void 0 ? null : (0, react.createElement)(TranslationAction, {
|
|
53234
|
-
messageId: `${messageId}-text-${index}`,
|
|
53235
|
-
messageRole: "assistant",
|
|
53236
|
-
services: props.services,
|
|
53237
|
-
translationT: props.translationT,
|
|
53238
|
-
record: translationRecord,
|
|
53239
|
-
inline: true
|
|
53240
|
-
})));
|
|
53241
|
-
continue;
|
|
53242
|
-
}
|
|
53243
|
-
if (block.kind === "reasoning") {
|
|
53244
|
-
const translationRecord = readRecord(block) ?? (hasTranslation && eventSnapshot !== void 0 ? findTranslationRecordForText(eventSnapshot, block.text, "reasoning", data.turn, data.step) : void 0);
|
|
53245
|
-
rendered.push((0, react.createElement)(AssistantReasoningBlock, {
|
|
53246
|
-
key: `reasoning-${index}`,
|
|
53247
|
-
messageId: `${messageId}-reasoning-${index}`,
|
|
53248
|
-
services: props.services,
|
|
53249
|
-
translationT: props.translationT,
|
|
53250
|
-
chatT,
|
|
53251
|
-
text: block.text,
|
|
53252
|
-
...translationRecord === void 0 ? {} : { translationRecord },
|
|
53253
|
-
running,
|
|
53254
|
-
hidden: reasoningHidden,
|
|
53255
|
-
reveal: () => turnProcess?.setOpen?.(true),
|
|
53256
|
-
useGroupAction: props.useGroupAction,
|
|
53257
|
-
renderFactorySlot: props.renderFactorySlot,
|
|
53258
|
-
markdownLabels,
|
|
53259
|
-
pathImages,
|
|
53260
|
-
mentions
|
|
53261
|
-
}));
|
|
53262
|
-
continue;
|
|
53263
|
-
}
|
|
53264
|
-
if (block.kind === "image") {
|
|
53265
|
-
const imageGroup = [block];
|
|
53266
|
-
while (index + 1 < blocks.length && blocks[index + 1]?.kind === "image") {
|
|
53267
|
-
const next = blocks[index + 1];
|
|
53268
|
-
if (next?.kind !== "image") break;
|
|
53269
|
-
imageGroup.push(next);
|
|
53270
|
-
index += 1;
|
|
53271
|
-
}
|
|
53272
|
-
rendered.push((0, react.createElement)("div", {
|
|
53273
|
-
key: `images-${index}`,
|
|
53274
|
-
style: { alignSelf: "flex-start" }
|
|
53275
|
-
}, props.renderMessageImages({
|
|
53276
|
-
images: imageGroup.map((image) => ({ attachment: image.attachment })),
|
|
53277
|
-
align: "start"
|
|
53278
|
-
})));
|
|
53279
|
-
continue;
|
|
53280
|
-
}
|
|
53281
|
-
if (block.kind === "other") rendered.push((0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.JsonBlock, {
|
|
53282
|
-
key: `other-${index}`,
|
|
53283
|
-
label: chatT("message.unknownBlock"),
|
|
53284
|
-
payload: block.block,
|
|
53285
|
-
truncatedLabel: (total) => chatT("json.truncated", { total })
|
|
53286
|
-
}));
|
|
53102
|
+
function compareVersions(left, right) {
|
|
53103
|
+
for (const key of [
|
|
53104
|
+
"major",
|
|
53105
|
+
"minor",
|
|
53106
|
+
"patch"
|
|
53107
|
+
]) if (left[key] !== right[key]) return left[key] - right[key];
|
|
53108
|
+
if (left.pre.length === 0 && right.pre.length > 0) return 1;
|
|
53109
|
+
if (left.pre.length > 0 && right.pre.length === 0) return -1;
|
|
53110
|
+
for (let index = 0; index < Math.max(left.pre.length, right.pre.length); index += 1) {
|
|
53111
|
+
const a = left.pre[index];
|
|
53112
|
+
const b = right.pre[index];
|
|
53113
|
+
if (a === void 0) return -1;
|
|
53114
|
+
if (b === void 0) return 1;
|
|
53115
|
+
if (a === b) continue;
|
|
53116
|
+
if (typeof a === "number" && typeof b === "string") return -1;
|
|
53117
|
+
if (typeof a === "string" && typeof b === "number") return 1;
|
|
53118
|
+
return a < b ? -1 : 1;
|
|
53287
53119
|
}
|
|
53288
|
-
return
|
|
53289
|
-
"data-streaming": streaming || void 0,
|
|
53290
|
-
style: {
|
|
53291
|
-
display: "flex",
|
|
53292
|
-
flexDirection: "column",
|
|
53293
|
-
gap: 16,
|
|
53294
|
-
minWidth: 0,
|
|
53295
|
-
color: require_theme.dshThemeColor.labelPrimary,
|
|
53296
|
-
fontSize: "var(--dsh-content-font-size, 14px)",
|
|
53297
|
-
lineHeight: "calc(24px + var(--dsh-content-font-delta, 0px))"
|
|
53298
|
-
}
|
|
53299
|
-
}, ...rendered, data.status === "interrupted" ? (0, react.createElement)("span", { style: {
|
|
53300
|
-
alignSelf: "flex-start",
|
|
53301
|
-
padding: "0 6px",
|
|
53302
|
-
borderRadius: "var(--dsw-radius-sm, 4px)",
|
|
53303
|
-
color: require_theme.dshThemeColor.labelTertiary,
|
|
53304
|
-
background: require_theme.dshThemeColor.surfaceSubtle,
|
|
53305
|
-
fontSize: 11,
|
|
53306
|
-
lineHeight: "18px"
|
|
53307
|
-
} }, chatT("message.stopped")) : null);
|
|
53120
|
+
return 0;
|
|
53308
53121
|
}
|
|
53309
|
-
function
|
|
53310
|
-
|
|
53311
|
-
const groupRef = props.useGroupAction?.(props.hidden, props.reveal);
|
|
53312
|
-
const summary = (props.translationRecord?.translated ?? props.text).split("\n").map((line) => line.replace(/[`*_#>]/gu, "").trim()).find(Boolean) ?? "";
|
|
53313
|
-
return (0, react.createElement)("div", {
|
|
53314
|
-
ref: groupRef,
|
|
53315
|
-
hidden: props.hidden,
|
|
53316
|
-
"data-turn-process-inline": props.hidden || void 0
|
|
53317
|
-
}, (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.DisclosureRow, {
|
|
53318
|
-
icon: (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.IconThinkOutlineRegular, { size: 14 }),
|
|
53319
|
-
title: props.chatT("message.think"),
|
|
53320
|
-
open: expanded,
|
|
53321
|
-
expandable: true,
|
|
53322
|
-
expandOnRowClick: true,
|
|
53323
|
-
running: props.running,
|
|
53324
|
-
onToggle: () => setExpanded((value) => !value),
|
|
53325
|
-
collapsedContent: (0, react.createElement)("span", { style: {
|
|
53326
|
-
minWidth: 0,
|
|
53327
|
-
overflow: "hidden",
|
|
53328
|
-
color: require_theme.dshThemeColor.labelSecondary,
|
|
53329
|
-
fontSize: "var(--dsh-content-font-size-secondary, 13px)",
|
|
53330
|
-
textOverflow: "ellipsis",
|
|
53331
|
-
whiteSpace: "nowrap"
|
|
53332
|
-
} }, (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.TextShimmer, {
|
|
53333
|
-
active: props.running,
|
|
53334
|
-
children: summary
|
|
53335
|
-
}))
|
|
53336
|
-
}, expanded ? (0, react.createElement)(AssistantReasoningContent, {
|
|
53337
|
-
messageId: props.messageId,
|
|
53338
|
-
services: props.services,
|
|
53339
|
-
translationT: props.translationT,
|
|
53340
|
-
text: props.text,
|
|
53341
|
-
running: props.running,
|
|
53342
|
-
...props.translationRecord === void 0 ? {} : { translationRecord: props.translationRecord },
|
|
53343
|
-
markdownLabels: props.markdownLabels,
|
|
53344
|
-
pathImages: props.pathImages,
|
|
53345
|
-
mentions: props.mentions,
|
|
53346
|
-
...props.renderFactorySlot === void 0 ? {} : { renderFactorySlot: props.renderFactorySlot }
|
|
53347
|
-
}) : null));
|
|
53122
|
+
function errorMessage$1(error) {
|
|
53123
|
+
return error instanceof Error ? error.message : String(error);
|
|
53348
53124
|
}
|
|
53349
|
-
|
|
53350
|
-
|
|
53351
|
-
|
|
53352
|
-
|
|
53353
|
-
|
|
53354
|
-
* `node` / `assistant-actions` / `commandview` / `turnTail`)。而 `renderFactorySlot`
|
|
53355
|
-
* 在工厂缺失时只渲染 `fallback`,缺省为 `null`——此前这里既不传 fallback,
|
|
53356
|
-
* 又把正文完全交给该工厂,于是展开思考后只剩翻译入口,译文一行都看不到。
|
|
53357
|
-
* 因此原生 MarkdownText 必须作为 fallback 传进去:没有工厂时按原生方式渲染,
|
|
53358
|
-
* 工厂存在时才允许表现层覆盖。
|
|
53359
|
-
*/
|
|
53360
|
-
function AssistantReasoningContent(props) {
|
|
53361
|
-
const displayText = props.translationRecord?.translated ?? props.text;
|
|
53362
|
-
const markdown = (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.MarkdownText, {
|
|
53363
|
-
text: displayText,
|
|
53364
|
-
streaming: props.running,
|
|
53365
|
-
labels: props.markdownLabels,
|
|
53366
|
-
fileMentions: props.mentions,
|
|
53367
|
-
pathImages: props.pathImages,
|
|
53368
|
-
variant: "compact"
|
|
53369
|
-
});
|
|
53370
|
-
const content = props.renderFactorySlot === void 0 ? markdown : props.renderFactorySlot("conversation.chat.reasoning.content", {
|
|
53371
|
-
text: displayText,
|
|
53372
|
-
running: props.running
|
|
53373
|
-
}, { fallback: markdown });
|
|
53374
|
-
return (0, react.createElement)("div", {
|
|
53375
|
-
"data-codingns-translation-inline": true,
|
|
53376
|
-
style: { paddingTop: 8 }
|
|
53377
|
-
}, content, props.translationRecord === void 0 ? null : (0, react.createElement)(TranslationAction, {
|
|
53378
|
-
messageId: props.messageId,
|
|
53379
|
-
messageRole: "assistant",
|
|
53380
|
-
services: props.services,
|
|
53381
|
-
translationT: props.translationT,
|
|
53382
|
-
record: props.translationRecord,
|
|
53383
|
-
inline: true
|
|
53384
|
-
}));
|
|
53125
|
+
//#endregion
|
|
53126
|
+
//#region src/dsh-capabilities/client/terminal-sharing-adapter.ts
|
|
53127
|
+
/** DSH 版本差异只在本适配器探测,终端业务不读取宿主私有编辑器。 */
|
|
53128
|
+
function supportsTerminalSharing(context) {
|
|
53129
|
+
return typeof service(context, "sessions")?.scope === "function" && typeof service(context, "conversation")?.input?.for === "function" && typeof service(context, "uiWorkspace")?.openSession === "function";
|
|
53385
53130
|
}
|
|
53386
|
-
function
|
|
53387
|
-
|
|
53388
|
-
|
|
53389
|
-
|
|
53390
|
-
|
|
53391
|
-
|
|
53392
|
-
codeLabel: chatT("codeBlock.title"),
|
|
53393
|
-
wrapLabel: chatT("codeBlock.wrap"),
|
|
53394
|
-
unwrapLabel: chatT("codeBlock.unwrap")
|
|
53395
|
-
}
|
|
53396
|
-
},
|
|
53397
|
-
footnotes: chatT("markdown.footnotes")
|
|
53398
|
-
};
|
|
53399
|
-
}
|
|
53400
|
-
function resolveMarkdownImagePath(value) {
|
|
53401
|
-
if (typeof document === "undefined" || !value.startsWith("/") || /^[/\\]{2}/u.test(value) || /[\u0000-\u001f\u007f]/u.test(value)) return void 0;
|
|
53402
|
-
const base = document.baseURI;
|
|
53403
|
-
if (!/^https?:/u.test(base) && !base.startsWith("dsh-app://app/")) return void 0;
|
|
53404
|
-
try {
|
|
53405
|
-
return new URL(`api/file?path=${encodeURIComponent(value)}`, base).href;
|
|
53406
|
-
} catch {
|
|
53407
|
-
return;
|
|
53408
|
-
}
|
|
53409
|
-
}
|
|
53410
|
-
/**
|
|
53411
|
-
* 注册两个有实际翻译记录的消息渲染器;DSH 的用户气泡内容仍由统一主题令牌控制。
|
|
53412
|
-
*/
|
|
53413
|
-
function registerSessionTranslationChatUi(services) {
|
|
53414
|
-
const slots = services.slots;
|
|
53415
|
-
if (slots?.inject === void 0 || slots.register === void 0) return () => void 0;
|
|
53416
|
-
const removeStyles = installSessionTranslationChatStyles();
|
|
53417
|
-
const translationT = services.locale.bind("codingns");
|
|
53418
|
-
const removePendingActions = slots.inject("conversation.input.left", () => slots.register({
|
|
53419
|
-
name: "conversation.input.left",
|
|
53420
|
-
id: "codingns-translation-pending",
|
|
53421
|
-
inject: (sessionId) => ({
|
|
53422
|
-
services,
|
|
53423
|
-
sessionId,
|
|
53424
|
-
translationT
|
|
53425
|
-
})
|
|
53426
|
-
}, PendingTranslationActions));
|
|
53427
|
-
const removeUserRenderer = slots.inject("conversation.chat.node", () => slots.register({
|
|
53428
|
-
name: "conversation.chat.node",
|
|
53429
|
-
key: "user",
|
|
53430
|
-
priority: -100,
|
|
53431
|
-
locale: "chat",
|
|
53432
|
-
inject: (sessionId) => ({
|
|
53433
|
-
services,
|
|
53434
|
-
sessionId,
|
|
53435
|
-
translationT
|
|
53436
|
-
})
|
|
53437
|
-
}, UserMessageNodeView));
|
|
53438
|
-
const removeAssistantRenderer = slots.inject("conversation.chat.node", () => slots.register({
|
|
53439
|
-
name: "conversation.chat.node",
|
|
53440
|
-
key: "assistant-step",
|
|
53441
|
-
priority: -100,
|
|
53442
|
-
locale: "chat",
|
|
53443
|
-
inject: (sessionId) => ({
|
|
53444
|
-
services,
|
|
53445
|
-
sessionId,
|
|
53446
|
-
translationT
|
|
53447
|
-
})
|
|
53448
|
-
}, AssistantTranslationNodeView));
|
|
53449
|
-
return () => {
|
|
53450
|
-
removePendingActions();
|
|
53451
|
-
removeAssistantRenderer();
|
|
53452
|
-
removeUserRenderer();
|
|
53453
|
-
removeStyles();
|
|
53454
|
-
};
|
|
53455
|
-
}
|
|
53456
|
-
function installSessionTranslationChatStyles() {
|
|
53457
|
-
if (typeof document === "undefined") return () => void 0;
|
|
53458
|
-
const styleId = "codingns-session-translation-chat";
|
|
53459
|
-
if (document.head.querySelector(`style[data-plugin-css="${styleId}"]`) !== null) return () => void 0;
|
|
53460
|
-
const style = document.createElement("style");
|
|
53461
|
-
style.dataset.plugin = "codingns4dsh";
|
|
53462
|
-
style.dataset.pluginCss = styleId;
|
|
53463
|
-
style.textContent = `
|
|
53464
|
-
@keyframes codingns-translation-spin{to{transform:rotate(360deg)}}
|
|
53465
|
-
[data-codingns-translation-pending]{animation:codingns-translation-spin .8s linear infinite}
|
|
53466
|
-
@media(prefers-reduced-motion:reduce){[data-codingns-translation-pending]{animation-duration:1.6s}}
|
|
53467
|
-
[data-codingns-translation-inline] > div:not([data-codingns-translation-action]){display:contents}
|
|
53468
|
-
[data-codingns-translation-inline] > div:not([data-codingns-translation-action]) > p:last-child{display:inline;margin:0}
|
|
53469
|
-
`;
|
|
53470
|
-
document.head.appendChild(style);
|
|
53471
|
-
return () => style.remove();
|
|
53472
|
-
}
|
|
53473
|
-
function readEventSource(services, sessionId) {
|
|
53474
|
-
const sessions = services.sessions;
|
|
53475
|
-
try {
|
|
53476
|
-
return sessions?.binding?.(sessionId)?.eventSource;
|
|
53477
|
-
} catch {
|
|
53478
|
-
return;
|
|
53479
|
-
}
|
|
53480
|
-
}
|
|
53481
|
-
function findTranslationRecordForText(snapshot, text, outputKind, turn, step) {
|
|
53482
|
-
const entries = snapshot.entries ?? [];
|
|
53483
|
-
for (let index = entries.length - 1; index >= 0; index -= 1) {
|
|
53484
|
-
const event = readEntryEvent(entries[index]);
|
|
53485
|
-
if (event === void 0 || !event.type.startsWith("assistant/")) continue;
|
|
53486
|
-
const eventData = asRecord(event.data);
|
|
53487
|
-
if (turn !== void 0 && typeof eventData?.turn === "number" && eventData.turn !== turn) continue;
|
|
53488
|
-
if (step !== void 0 && typeof eventData?.step === "number" && eventData.step !== step) continue;
|
|
53489
|
-
const candidates = [];
|
|
53490
|
-
collectRecordCandidates(event.data, candidates, /* @__PURE__ */ new Set());
|
|
53491
|
-
for (const candidate of candidates) {
|
|
53492
|
-
const record = readRecord(candidate);
|
|
53493
|
-
if (record === void 0 || record.original !== text && record.translated !== text) continue;
|
|
53494
|
-
if (outputKind !== void 0 && record.outputKind !== void 0 && record.outputKind !== outputKind) continue;
|
|
53495
|
-
return record;
|
|
53496
|
-
}
|
|
53497
|
-
}
|
|
53498
|
-
}
|
|
53499
|
-
function collectRecordCandidates(value, candidates, seen, depth = 0) {
|
|
53500
|
-
if (Array.isArray(value)) {
|
|
53501
|
-
for (const item of value) collectRecordCandidates(item, candidates, seen, depth + 1);
|
|
53502
|
-
return;
|
|
53503
|
-
}
|
|
53504
|
-
const record = asRecord(value);
|
|
53505
|
-
if (record === void 0 || seen.has(record) || depth > 7) return;
|
|
53506
|
-
seen.add(record);
|
|
53507
|
-
if (readRecord(record) !== void 0 || asRecord(record.codingnsTranslation) !== void 0) candidates.push(record);
|
|
53508
|
-
for (const key of [
|
|
53509
|
-
"codingnsTranslation",
|
|
53510
|
-
"source",
|
|
53511
|
-
"message",
|
|
53512
|
-
"content",
|
|
53513
|
-
"stream",
|
|
53514
|
-
"chunk",
|
|
53515
|
-
"block",
|
|
53516
|
-
"data"
|
|
53517
|
-
]) if (record[key] !== void 0) collectRecordCandidates(record[key], candidates, seen, depth + 1);
|
|
53518
|
-
}
|
|
53519
|
-
function readEntryEvent(value) {
|
|
53520
|
-
const record = asRecord(value);
|
|
53521
|
-
return asRecord(record?.event) ?? (typeof record?.type === "string" ? record : void 0);
|
|
53522
|
-
}
|
|
53523
|
-
function readRecord(value) {
|
|
53524
|
-
const record = asRecord(value);
|
|
53525
|
-
const candidate = asRecord(record?.codingnsTranslation) ?? record;
|
|
53526
|
-
if (candidate?.original === void 0 || candidate.translated === void 0) return void 0;
|
|
53527
|
-
if (typeof candidate.original !== "string" || typeof candidate.translated !== "string") return void 0;
|
|
53528
|
-
const targetLanguage = readLanguage(candidate.targetLanguage);
|
|
53529
|
-
if (targetLanguage === void 0) return void 0;
|
|
53530
|
-
const model = readModel(candidate.model);
|
|
53531
|
-
const outputKind = candidate.outputKind === "assistant" || candidate.outputKind === "reasoning" ? candidate.outputKind : void 0;
|
|
53532
|
-
return {
|
|
53533
|
-
original: candidate.original,
|
|
53534
|
-
translated: candidate.translated,
|
|
53535
|
-
...candidate.sourceLanguage === "zh" || candidate.sourceLanguage === "en" || candidate.sourceLanguage === "fr" || candidate.sourceLanguage === "de" || candidate.sourceLanguage === "ja" ? { sourceLanguage: candidate.sourceLanguage } : {},
|
|
53536
|
-
targetLanguage,
|
|
53537
|
-
bilingual: candidate.bilingual === true,
|
|
53538
|
-
...outputKind === void 0 ? {} : { outputKind },
|
|
53539
|
-
...candidate.alreadyTargetLanguage === true ? { alreadyTargetLanguage: true } : {},
|
|
53540
|
-
...model === void 0 ? {} : { model },
|
|
53541
|
-
...candidate.failed === true ? { failed: true } : {},
|
|
53542
|
-
...require_session_translation.readSessionTranslationMetrics(candidate)
|
|
53543
|
-
};
|
|
53544
|
-
}
|
|
53545
|
-
function readModel(value) {
|
|
53546
|
-
const record = asRecord(value);
|
|
53547
|
-
if (typeof record?.provider !== "string" || typeof record.model !== "string" || record.provider.trim() === "" || record.model.trim() === "") return void 0;
|
|
53548
|
-
return {
|
|
53549
|
-
provider: record.provider,
|
|
53550
|
-
model: record.model
|
|
53551
|
-
};
|
|
53552
|
-
}
|
|
53553
|
-
function readInputRecord(value) {
|
|
53554
|
-
const candidate = asRecord(asRecord(asRecord(value)?.source)?.codingnsTranslationInput);
|
|
53555
|
-
if (candidate?.original === void 0 || candidate.translated === void 0) return void 0;
|
|
53556
|
-
if (typeof candidate.original !== "string" || typeof candidate.translated !== "string") return void 0;
|
|
53557
|
-
const targetLanguage = readLanguage(candidate.targetLanguage);
|
|
53558
|
-
if (targetLanguage === void 0) return void 0;
|
|
53559
|
-
const model = readModel(candidate.model);
|
|
53560
|
-
return {
|
|
53561
|
-
original: candidate.original,
|
|
53562
|
-
translated: candidate.translated,
|
|
53563
|
-
...candidate.sourceLanguage === "zh" || candidate.sourceLanguage === "en" || candidate.sourceLanguage === "fr" || candidate.sourceLanguage === "de" || candidate.sourceLanguage === "ja" ? { sourceLanguage: candidate.sourceLanguage } : {},
|
|
53564
|
-
targetLanguage,
|
|
53565
|
-
...candidate.alreadyTargetLanguage === true ? { alreadyTargetLanguage: true } : {},
|
|
53566
|
-
...model === void 0 ? {} : { model },
|
|
53567
|
-
...candidate.failed === true ? { failed: true } : {},
|
|
53568
|
-
...require_session_translation.readSessionTranslationMetrics(candidate)
|
|
53569
|
-
};
|
|
53570
|
-
}
|
|
53571
|
-
function inputRecordForAction(record) {
|
|
53572
|
-
return {
|
|
53573
|
-
original: record.original,
|
|
53574
|
-
translated: record.translated,
|
|
53575
|
-
...record.sourceLanguage === void 0 ? {} : { sourceLanguage: record.sourceLanguage },
|
|
53576
|
-
targetLanguage: record.targetLanguage,
|
|
53577
|
-
bilingual: false,
|
|
53578
|
-
...record.alreadyTargetLanguage === true ? { alreadyTargetLanguage: true } : {},
|
|
53579
|
-
...record.model === void 0 ? {} : { model: record.model },
|
|
53580
|
-
...record.failed === true ? { failed: true } : {},
|
|
53581
|
-
...require_session_translation.readSessionTranslationMetrics(record)
|
|
53582
|
-
};
|
|
53583
|
-
}
|
|
53584
|
-
function readLanguage(value) {
|
|
53585
|
-
return value === "zh" || value === "en" || value === "fr" || value === "de" || value === "ja" ? value : void 0;
|
|
53586
|
-
}
|
|
53587
|
-
function formatModel(model, t) {
|
|
53588
|
-
return model === void 0 ? t("translation.modelUnknown") : `${model.provider} / ${model.model}`;
|
|
53589
|
-
}
|
|
53590
|
-
function safeDomId(value) {
|
|
53591
|
-
return encodeURIComponent(value).replace(/%/gu, "-");
|
|
53592
|
-
}
|
|
53593
|
-
function asRecord(value) {
|
|
53594
|
-
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
|
|
53595
|
-
}
|
|
53596
|
-
//#endregion
|
|
53597
|
-
//#region src/dsh-capabilities/types.ts
|
|
53598
|
-
function createCapabilityProfile(dshVersion, runtime, capabilities, diagnostics) {
|
|
53599
|
-
return Object.freeze({
|
|
53600
|
-
dshVersion,
|
|
53601
|
-
runtime,
|
|
53602
|
-
capabilities: freezeMap(capabilities),
|
|
53603
|
-
diagnostics: Object.freeze([...diagnostics]),
|
|
53604
|
-
frozenAt: Date.now()
|
|
53605
|
-
});
|
|
53606
|
-
}
|
|
53607
|
-
/** Map 的只读视图,避免 Object.freeze(Map) 仍可通过 set() 修改。 */
|
|
53608
|
-
function freezeMap(source) {
|
|
53609
|
-
const map = new Map(source);
|
|
53610
|
-
const view = new Proxy(map, { get(target, property, receiver) {
|
|
53611
|
-
if (property === "set" || property === "delete" || property === "clear") return void 0;
|
|
53612
|
-
const value = Reflect.get(target, property, target);
|
|
53613
|
-
return typeof value === "function" ? value.bind(target) : value;
|
|
53614
|
-
} });
|
|
53615
|
-
return Object.freeze(view);
|
|
53616
|
-
}
|
|
53617
|
-
//#endregion
|
|
53618
|
-
//#region src/dsh-capabilities/registry.ts
|
|
53619
|
-
var DshCapabilityRegistryError = class extends Error {
|
|
53620
|
-
code;
|
|
53621
|
-
capability;
|
|
53622
|
-
constructor(code, message, capability = null, options) {
|
|
53623
|
-
super(message, options);
|
|
53624
|
-
this.name = "DshCapabilityRegistryError";
|
|
53625
|
-
this.code = code;
|
|
53626
|
-
this.capability = capability;
|
|
53627
|
-
}
|
|
53628
|
-
};
|
|
53629
|
-
/** 集中解析 DSH 能力路由;Profile 生成后不可变,避免运行期替换半初始化服务。 */
|
|
53630
|
-
var DshCapabilityRegistry = class {
|
|
53631
|
-
dshVersion;
|
|
53632
|
-
runtime;
|
|
53633
|
-
routes = /* @__PURE__ */ new Map();
|
|
53634
|
-
profile;
|
|
53635
|
-
constructor(dshVersion, runtime) {
|
|
53636
|
-
this.dshVersion = dshVersion;
|
|
53637
|
-
this.runtime = runtime;
|
|
53638
|
-
}
|
|
53639
|
-
register(route) {
|
|
53640
|
-
validateRoute(route);
|
|
53641
|
-
if (route.runtime !== this.runtime) return;
|
|
53642
|
-
const list = this.routes.get(route.capability) ?? [];
|
|
53643
|
-
if (list.some((entry) => entry.id === route.id)) throw new DshCapabilityRegistryError("CAPABILITY_INVALID_ROUTE", `重复的能力路由: ${route.id}`, route.capability);
|
|
53644
|
-
list.push(route);
|
|
53645
|
-
this.routes.set(route.capability, list);
|
|
53646
|
-
this.profile = void 0;
|
|
53647
|
-
}
|
|
53648
|
-
registerMany(routes) {
|
|
53649
|
-
for (const route of routes) this.register(route);
|
|
53650
|
-
}
|
|
53651
|
-
resolve(context) {
|
|
53652
|
-
if (this.profile !== void 0) return this.profile;
|
|
53653
|
-
const resolutions = /* @__PURE__ */ new Map();
|
|
53654
|
-
const diagnostics = [];
|
|
53655
|
-
for (const [capability, routes] of this.routes) {
|
|
53656
|
-
const candidates = routes.filter((route) => isVersionInRange(this.dshVersion, route.supportedDsh)).sort((left, right) => routeRank(right) - routeRank(left));
|
|
53657
|
-
if (candidates.length === 0) {
|
|
53658
|
-
const reason = `DSH ${this.dshVersion} 没有能力 ${capability} 的适配路由`;
|
|
53659
|
-
resolutions.set(capability, unavailable(capability, this.dshVersion, reason));
|
|
53660
|
-
diagnostics.push({
|
|
53661
|
-
code: "CAPABILITY_VERSION_UNSUPPORTED",
|
|
53662
|
-
capability,
|
|
53663
|
-
dshVersion: this.dshVersion,
|
|
53664
|
-
message: reason
|
|
53665
|
-
});
|
|
53666
|
-
continue;
|
|
53667
|
-
}
|
|
53668
|
-
const topPriority = routeRank(candidates[0]);
|
|
53669
|
-
const top = candidates.filter((route) => routeRank(route) === topPriority);
|
|
53670
|
-
if (top.length > 1) throw new DshCapabilityRegistryError("CAPABILITY_ROUTE_CONFLICT", `能力 ${capability} 存在同优先级路由: ${top.map((route) => route.id).join(", ")}`, capability);
|
|
53671
|
-
let selected;
|
|
53672
|
-
for (const route of candidates) try {
|
|
53673
|
-
if (route.detect(context)) {
|
|
53674
|
-
selected = route;
|
|
53675
|
-
break;
|
|
53676
|
-
}
|
|
53677
|
-
} catch (error) {
|
|
53678
|
-
diagnostics.push({
|
|
53679
|
-
code: "CAPABILITY_DETECT_FAILED",
|
|
53680
|
-
capability,
|
|
53681
|
-
routeId: route.id,
|
|
53682
|
-
dshVersion: this.dshVersion,
|
|
53683
|
-
message: `${route.id} 探测失败: ${errorMessage$1(error)}`,
|
|
53684
|
-
...route.replacement === void 0 ? {} : { replacement: route.replacement }
|
|
53685
|
-
});
|
|
53686
|
-
}
|
|
53687
|
-
if (selected === void 0) {
|
|
53688
|
-
const reason = `DSH ${this.dshVersion} 的能力 ${capability} 没有可用运行时实现`;
|
|
53689
|
-
resolutions.set(capability, unavailable(capability, this.dshVersion, reason));
|
|
53690
|
-
diagnostics.push({
|
|
53691
|
-
code: "CAPABILITY_UNAVAILABLE",
|
|
53692
|
-
capability,
|
|
53693
|
-
dshVersion: this.dshVersion,
|
|
53694
|
-
message: reason
|
|
53695
|
-
});
|
|
53696
|
-
continue;
|
|
53697
|
-
}
|
|
53698
|
-
try {
|
|
53699
|
-
const value = selected.create(context);
|
|
53700
|
-
const resolution = {
|
|
53701
|
-
capability,
|
|
53702
|
-
routeId: selected.id,
|
|
53703
|
-
dshVersion: this.dshVersion,
|
|
53704
|
-
status: selected.status === "deprecated" ? "degraded" : "ready",
|
|
53705
|
-
value,
|
|
53706
|
-
...selected.replacement === void 0 ? {} : { replacement: selected.replacement }
|
|
53707
|
-
};
|
|
53708
|
-
resolutions.set(capability, resolution);
|
|
53709
|
-
if (selected.status === "deprecated") diagnostics.push({
|
|
53710
|
-
code: "CAPABILITY_DEPRECATED",
|
|
53711
|
-
capability,
|
|
53712
|
-
routeId: selected.id,
|
|
53713
|
-
dshVersion: this.dshVersion,
|
|
53714
|
-
message: `能力 ${capability} 使用已弃用路由 ${selected.id}`,
|
|
53715
|
-
...selected.replacement === void 0 ? {} : { replacement: selected.replacement }
|
|
53716
|
-
});
|
|
53717
|
-
} catch (error) {
|
|
53718
|
-
const reason = `${selected.id} 创建失败: ${errorMessage$1(error)}`;
|
|
53719
|
-
resolutions.set(capability, unavailable(capability, this.dshVersion, reason));
|
|
53720
|
-
diagnostics.push({
|
|
53721
|
-
code: "CAPABILITY_CREATE_FAILED",
|
|
53722
|
-
capability,
|
|
53723
|
-
routeId: selected.id,
|
|
53724
|
-
dshVersion: this.dshVersion,
|
|
53725
|
-
message: reason
|
|
53726
|
-
});
|
|
53727
|
-
}
|
|
53728
|
-
}
|
|
53729
|
-
this.profile = createCapabilityProfile(this.dshVersion, this.runtime, resolutions, diagnostics);
|
|
53730
|
-
return this.profile;
|
|
53731
|
-
}
|
|
53732
|
-
getProfile(context) {
|
|
53733
|
-
return this.resolve(context);
|
|
53734
|
-
}
|
|
53735
|
-
require(profile, capability) {
|
|
53736
|
-
const resolution = profile.capabilities.get(capability);
|
|
53737
|
-
if (resolution?.value === void 0 || resolution.status === "unavailable") throw new DshCapabilityRegistryError("CAPABILITY_UNAVAILABLE", resolution?.reason ?? `能力不可用: ${capability}`, capability);
|
|
53738
|
-
return resolution.value;
|
|
53739
|
-
}
|
|
53740
|
-
explain(profile, capability) {
|
|
53741
|
-
if (capability === void 0) return profile.diagnostics;
|
|
53742
|
-
return profile.diagnostics.filter((item) => item.capability === capability);
|
|
53743
|
-
}
|
|
53744
|
-
};
|
|
53745
|
-
function validateRoute(route) {
|
|
53746
|
-
if (route.id.trim() === "" || route.capability === void 0 || route.supportedDsh.trim() === "") throw new DshCapabilityRegistryError("CAPABILITY_INVALID_ROUTE", "能力路由必须包含 id、capability 和 supportedDsh");
|
|
53747
|
-
if (!Number.isFinite(route.priority)) throw new DshCapabilityRegistryError("CAPABILITY_INVALID_ROUTE", `能力路由优先级非法: ${route.id}`, route.capability);
|
|
53748
|
-
if (typeof route.detect !== "function" || typeof route.create !== "function") throw new DshCapabilityRegistryError("CAPABILITY_INVALID_ROUTE", `能力路由缺少探测或工厂: ${route.id}`, route.capability);
|
|
53749
|
-
}
|
|
53750
|
-
function routeRank(route) {
|
|
53751
|
-
return route.priority + (route.status === "supported" ? 1e6 : 0);
|
|
53752
|
-
}
|
|
53753
|
-
function unavailable(capability, dshVersion, reason) {
|
|
53754
|
-
return {
|
|
53755
|
-
capability,
|
|
53756
|
-
dshVersion,
|
|
53757
|
-
status: "unavailable",
|
|
53758
|
-
reason
|
|
53759
|
-
};
|
|
53760
|
-
}
|
|
53761
|
-
function isVersionInRange(version, range) {
|
|
53762
|
-
const match = /^>=([^ ]+)(?: <=([^ ]+))?$/u.exec(range);
|
|
53763
|
-
if (match === null) return false;
|
|
53764
|
-
const actual = parseVersion(version);
|
|
53765
|
-
const minimum = parseVersion(match[1]);
|
|
53766
|
-
if (actual === void 0 || minimum === void 0) return false;
|
|
53767
|
-
if (match[2] === void 0) return compareVersions(actual, minimum) >= 0;
|
|
53768
|
-
const maximum = parseVersion(match[2]);
|
|
53769
|
-
if (maximum === void 0) return false;
|
|
53770
|
-
return compareVersions(actual, minimum) >= 0 && compareVersions(actual, maximum) <= 0;
|
|
53771
|
-
}
|
|
53772
|
-
function parseVersion(value) {
|
|
53773
|
-
const match = /^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?$/u.exec(value);
|
|
53774
|
-
if (match === null) return void 0;
|
|
53775
|
-
return {
|
|
53776
|
-
major: Number(match[1]),
|
|
53777
|
-
minor: Number(match[2]),
|
|
53778
|
-
patch: Number(match[3]),
|
|
53779
|
-
pre: match[4] === void 0 ? [] : match[4].split(".").map((part) => /^\d+$/u.test(part) ? Number(part) : part)
|
|
53780
|
-
};
|
|
53781
|
-
}
|
|
53782
|
-
function compareVersions(left, right) {
|
|
53783
|
-
for (const key of [
|
|
53784
|
-
"major",
|
|
53785
|
-
"minor",
|
|
53786
|
-
"patch"
|
|
53787
|
-
]) if (left[key] !== right[key]) return left[key] - right[key];
|
|
53788
|
-
if (left.pre.length === 0 && right.pre.length > 0) return 1;
|
|
53789
|
-
if (left.pre.length > 0 && right.pre.length === 0) return -1;
|
|
53790
|
-
for (let index = 0; index < Math.max(left.pre.length, right.pre.length); index += 1) {
|
|
53791
|
-
const a = left.pre[index];
|
|
53792
|
-
const b = right.pre[index];
|
|
53793
|
-
if (a === void 0) return -1;
|
|
53794
|
-
if (b === void 0) return 1;
|
|
53795
|
-
if (a === b) continue;
|
|
53796
|
-
if (typeof a === "number" && typeof b === "string") return -1;
|
|
53797
|
-
if (typeof a === "string" && typeof b === "number") return 1;
|
|
53798
|
-
return a < b ? -1 : 1;
|
|
53799
|
-
}
|
|
53800
|
-
return 0;
|
|
53801
|
-
}
|
|
53802
|
-
function errorMessage$1(error) {
|
|
53803
|
-
return error instanceof Error ? error.message : String(error);
|
|
53804
|
-
}
|
|
53805
|
-
//#endregion
|
|
53806
|
-
//#region src/dsh-capabilities/client/terminal-sharing-adapter.ts
|
|
53807
|
-
/** DSH 版本差异只在本适配器探测,终端业务不读取宿主私有编辑器。 */
|
|
53808
|
-
function supportsTerminalSharing(context) {
|
|
53809
|
-
return typeof service(context, "sessions")?.scope === "function" && typeof service(context, "conversation")?.input?.for === "function" && typeof service(context, "uiWorkspace")?.openSession === "function";
|
|
53810
|
-
}
|
|
53811
|
-
function createTerminalSharingBridge(context) {
|
|
53812
|
-
if (!supportsTerminalSharing(context)) throw new Error("当前 DSH 缺少会话草稿分享能力");
|
|
53813
|
-
const sessions = service(context, "sessions");
|
|
53814
|
-
const conversation = service(context, "conversation");
|
|
53815
|
-
const navigation = service(context, "uiWorkspace");
|
|
53816
|
-
const workspaceSnapshot = () => service(context, "workspaces")?.list?.getSnapshot();
|
|
53131
|
+
function createTerminalSharingBridge(context) {
|
|
53132
|
+
if (!supportsTerminalSharing(context)) throw new Error("当前 DSH 缺少会话草稿分享能力");
|
|
53133
|
+
const sessions = service(context, "sessions");
|
|
53134
|
+
const conversation = service(context, "conversation");
|
|
53135
|
+
const navigation = service(context, "uiWorkspace");
|
|
53136
|
+
const workspaceSnapshot = () => service(context, "workspaces")?.list?.getSnapshot();
|
|
53817
53137
|
return {
|
|
53818
53138
|
async targets(signal, query) {
|
|
53819
53139
|
const rows = /* @__PURE__ */ new Map();
|
|
@@ -54098,6 +53418,35 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
54098
53418
|
}
|
|
54099
53419
|
//#endregion
|
|
54100
53420
|
//#region src/dsh-capabilities/client/slot-presentation-mirror.ts
|
|
53421
|
+
/** Follow a native entry that may load after its slot or be replaced during reload. */
|
|
53422
|
+
function followPresentationEntry(slots, name, matches, mount) {
|
|
53423
|
+
return slots.inject(name, () => {
|
|
53424
|
+
let native;
|
|
53425
|
+
let remove;
|
|
53426
|
+
let disposed = false;
|
|
53427
|
+
const reconcile = () => {
|
|
53428
|
+
if (disposed || native !== void 0 && slots.entries(name).includes(native)) return;
|
|
53429
|
+
remove?.();
|
|
53430
|
+
remove = void 0;
|
|
53431
|
+
native = slots.entries(name).find(matches);
|
|
53432
|
+
if (native !== void 0) remove = mount(native);
|
|
53433
|
+
};
|
|
53434
|
+
const unsubscribe = slots.subscribe(name, reconcile);
|
|
53435
|
+
const dispose = () => {
|
|
53436
|
+
disposed = true;
|
|
53437
|
+
unsubscribe();
|
|
53438
|
+
remove?.();
|
|
53439
|
+
remove = void 0;
|
|
53440
|
+
};
|
|
53441
|
+
try {
|
|
53442
|
+
reconcile();
|
|
53443
|
+
} catch (error) {
|
|
53444
|
+
dispose();
|
|
53445
|
+
throw error;
|
|
53446
|
+
}
|
|
53447
|
+
return dispose;
|
|
53448
|
+
});
|
|
53449
|
+
}
|
|
54101
53450
|
/** Render existing actions in an owned slot without redeclaring or mutating native slots. */
|
|
54102
53451
|
function mirrorPresentationSlot(slots, source, target, element) {
|
|
54103
53452
|
return slots.inject(source, () => {
|
|
@@ -54176,9 +53525,7 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
54176
53525
|
},
|
|
54177
53526
|
questions(sessionId, component, element) {
|
|
54178
53527
|
const actionSlot = `codingns.translation.plan-actions.${encodeURIComponent(sessionId)}`;
|
|
54179
|
-
return slots.
|
|
54180
|
-
const native = slots.entries("conversation.composer").find((entry) => entry.children?.["conversation.plan-review.actions"] !== void 0);
|
|
54181
|
-
if (native === void 0 || typeof native.select !== "function") return () => void 0;
|
|
53528
|
+
return followPresentationEntry(slots, "conversation.composer", (entry) => entry.children?.["conversation.plan-review.actions"] !== void 0 && typeof entry.select === "function", (native) => {
|
|
54182
53529
|
const select = native.select;
|
|
54183
53530
|
const removeQuestion = slots.register({
|
|
54184
53531
|
name: "conversation.composer",
|
|
@@ -54215,9 +53562,7 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
54215
53562
|
});
|
|
54216
53563
|
},
|
|
54217
53564
|
todos(render, element) {
|
|
54218
|
-
return slots
|
|
54219
|
-
const native = slots.entries("conversation.input.dock").find((entry) => entry.options.id === "todo");
|
|
54220
|
-
if (native === void 0) return () => void 0;
|
|
53565
|
+
return followPresentationEntry(slots, "conversation.input.dock", (entry) => entry.options.id === "todo", (native) => {
|
|
54221
53566
|
return slots.register({
|
|
54222
53567
|
name: "conversation.input.dock",
|
|
54223
53568
|
id: "todo",
|
|
@@ -54236,9 +53581,7 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
54236
53581
|
});
|
|
54237
53582
|
},
|
|
54238
53583
|
questionHistory(render, element) {
|
|
54239
|
-
return slots
|
|
54240
|
-
const native = slots.entries("tool.call.toolview").find((entry) => entry.options.key === "ask_user_question");
|
|
54241
|
-
if (native === void 0) return () => void 0;
|
|
53584
|
+
return followPresentationEntry(slots, "tool.call.toolview", (entry) => entry.options.key === "ask_user_question", (native) => {
|
|
54242
53585
|
return slots.register({
|
|
54243
53586
|
name: "tool.call.toolview",
|
|
54244
53587
|
key: "ask_user_question",
|
|
@@ -54299,6 +53642,115 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
54299
53642
|
].includes(item.status ?? "");
|
|
54300
53643
|
}
|
|
54301
53644
|
//#endregion
|
|
53645
|
+
//#region src/dsh-capabilities/client/message-presentation-adapter.ts
|
|
53646
|
+
function slotsOf(context) {
|
|
53647
|
+
return context?.slots;
|
|
53648
|
+
}
|
|
53649
|
+
function supportsLegacyMessagePresentation(context, exports) {
|
|
53650
|
+
const slots = slotsOf(context);
|
|
53651
|
+
return typeof slots?.inject === "function" && typeof slots.register === "function" && typeof exports?.projectUserText === "function";
|
|
53652
|
+
}
|
|
53653
|
+
function supportsFactoryMessagePresentation(context) {
|
|
53654
|
+
const slots = slotsOf(context);
|
|
53655
|
+
return typeof slots?.inject === "function" && typeof slots.register === "function" && typeof slots.registerFactory === "function";
|
|
53656
|
+
}
|
|
53657
|
+
function createLegacyMessagePresentation(exports) {
|
|
53658
|
+
return {
|
|
53659
|
+
kind: "legacy",
|
|
53660
|
+
mount: (register) => register(),
|
|
53661
|
+
projectText: exports.projectUserText,
|
|
53662
|
+
userContent: () => null,
|
|
53663
|
+
images: (owner, props) => owner.renderMessageImages(props)
|
|
53664
|
+
};
|
|
53665
|
+
}
|
|
53666
|
+
/** Native factories preserve the host's text transforms, reference actions and image authorization. */
|
|
53667
|
+
function createFactoryMessagePresentation(context) {
|
|
53668
|
+
const slots = slotsOf(context);
|
|
53669
|
+
return {
|
|
53670
|
+
kind: "factory",
|
|
53671
|
+
mount: (register) => slots.inject("conversation.user.text.node", () => slots.inject("conversation.chat.user.images", register)),
|
|
53672
|
+
projectText: () => null,
|
|
53673
|
+
userContent: (owner, content, facts) => owner.renderFactorySlot("conversation.chat.user.content", {
|
|
53674
|
+
content,
|
|
53675
|
+
facts,
|
|
53676
|
+
loadImage: owner.loadImage,
|
|
53677
|
+
interactive: true
|
|
53678
|
+
}),
|
|
53679
|
+
images: (owner, props) => owner.renderFactorySlot("conversation.images.content", {
|
|
53680
|
+
...props,
|
|
53681
|
+
loadImage: owner.loadImage
|
|
53682
|
+
})
|
|
53683
|
+
};
|
|
53684
|
+
}
|
|
53685
|
+
//#endregion
|
|
53686
|
+
//#region src/dsh-capabilities/host/session-model-selection-adapter.ts
|
|
53687
|
+
function selectionOwner(controller) {
|
|
53688
|
+
const owner = controller?.agents;
|
|
53689
|
+
return typeof owner?.selectionFor === "function" ? owner : void 0;
|
|
53690
|
+
}
|
|
53691
|
+
function supportsSessionModelSelection(controller) {
|
|
53692
|
+
return selectionOwner(controller) !== void 0;
|
|
53693
|
+
}
|
|
53694
|
+
/**
|
|
53695
|
+
* DSH's prompt admission reads selectionFor().current before agent/request.
|
|
53696
|
+
* Its public selectModel() also persists the global default and requires a
|
|
53697
|
+
* catalog entry, so external routes must not use it for this session-local view.
|
|
53698
|
+
* Keep this internal accessor behind the bounded, structurally probed route.
|
|
53699
|
+
*/
|
|
53700
|
+
function createSessionModelSelectionAdapter(controller) {
|
|
53701
|
+
const owner = selectionOwner(controller);
|
|
53702
|
+
return { install(resolve) {
|
|
53703
|
+
const original = owner.selectionFor;
|
|
53704
|
+
const ownDescriptor = Object.getOwnPropertyDescriptor(owner, "selectionFor");
|
|
53705
|
+
const selectionFor = function(agent) {
|
|
53706
|
+
const selection = original.call(this, agent);
|
|
53707
|
+
const external = resolve(agent.id);
|
|
53708
|
+
if (external === void 0) return selection;
|
|
53709
|
+
return new Proxy(selection, { get(target, key, receiver) {
|
|
53710
|
+
return key === "current" ? external : Reflect.get(target, key, receiver);
|
|
53711
|
+
} });
|
|
53712
|
+
};
|
|
53713
|
+
owner.selectionFor = selectionFor;
|
|
53714
|
+
return () => {
|
|
53715
|
+
if (owner.selectionFor !== selectionFor) return;
|
|
53716
|
+
if (ownDescriptor !== void 0) Object.defineProperty(owner, "selectionFor", ownDescriptor);
|
|
53717
|
+
else Reflect.deleteProperty(owner, "selectionFor");
|
|
53718
|
+
};
|
|
53719
|
+
} };
|
|
53720
|
+
}
|
|
53721
|
+
//#endregion
|
|
53722
|
+
//#region src/dsh-capabilities/host/session-prompt-adapter.ts
|
|
53723
|
+
function supportsSessionPromptAssembly(value) {
|
|
53724
|
+
const ctx = value;
|
|
53725
|
+
const prompt = ctx?.get?.("systemPrompt") ?? ctx?.systemPrompt;
|
|
53726
|
+
return typeof ctx?.on === "function" && typeof prompt?.assemble === "function";
|
|
53727
|
+
}
|
|
53728
|
+
/** Keep DSH's agent identity and scope shape inside the versioned boundary. */
|
|
53729
|
+
function sessionPromptScope(agent, signal) {
|
|
53730
|
+
const header = agent?.session?.header;
|
|
53731
|
+
return {
|
|
53732
|
+
sessionId: typeof agent?.id === "string" ? agent.id : typeof header?.id === "string" ? header.id : "",
|
|
53733
|
+
subagent: header?.origin === "subagent" || header?.delegationDepth > 0 || agent?.options?.subagentDepth > 0,
|
|
53734
|
+
literals: [header?.cwd, agent?.cwd].filter((value) => typeof value === "string" && value !== ""),
|
|
53735
|
+
...signal === void 0 ? {} : { signal }
|
|
53736
|
+
};
|
|
53737
|
+
}
|
|
53738
|
+
function createSessionPromptAdapter(value) {
|
|
53739
|
+
const ctx = value;
|
|
53740
|
+
return { install(transform) {
|
|
53741
|
+
const dispose = ctx.on("system-prompt/assemble", async (_assembly, context, next) => {
|
|
53742
|
+
const assembly = await next();
|
|
53743
|
+
const scope = sessionPromptScope(context?.agent, context?.signal);
|
|
53744
|
+
if (scope.sessionId === "" || scope.subagent || !Array.isArray(assembly?.sections) || !Array.isArray(assembly.tools)) return assembly;
|
|
53745
|
+
return transform(assembly, scope);
|
|
53746
|
+
}, {
|
|
53747
|
+
global: true,
|
|
53748
|
+
prepend: true
|
|
53749
|
+
});
|
|
53750
|
+
return typeof dispose === "function" ? dispose : () => void 0;
|
|
53751
|
+
} };
|
|
53752
|
+
}
|
|
53753
|
+
//#endregion
|
|
54302
53754
|
//#region src/dsh-capabilities/routes.ts
|
|
54303
53755
|
/**
|
|
54304
53756
|
* 注册 Codingns4DSH 当前实际消费的 DSH 服务能力。
|
|
@@ -54313,6 +53765,61 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
54313
53765
|
const range020 = require_native_workspace_store.DSH_COMPATIBILITY;
|
|
54314
53766
|
const add = (route) => registry.register(route);
|
|
54315
53767
|
if (runtime === "host") {
|
|
53768
|
+
add({
|
|
53769
|
+
id: "session-prompt-assembly-021",
|
|
53770
|
+
capability: "session.prompt-assembly",
|
|
53771
|
+
supportedDsh: ">=0.2.1-alpha.3 <=0.2.1-alpha.3",
|
|
53772
|
+
runtime,
|
|
53773
|
+
priority: 10,
|
|
53774
|
+
status: "supported",
|
|
53775
|
+
introducedIn: "0.2.1-alpha.3",
|
|
53776
|
+
detect: supportsSessionPromptAssembly,
|
|
53777
|
+
create: createSessionPromptAdapter
|
|
53778
|
+
});
|
|
53779
|
+
add({
|
|
53780
|
+
id: "session-external-model-selection-021",
|
|
53781
|
+
capability: "session.external-model-selection",
|
|
53782
|
+
supportedDsh: ">=0.2.1-alpha.3 <=0.2.1-alpha.3",
|
|
53783
|
+
runtime,
|
|
53784
|
+
priority: 10,
|
|
53785
|
+
status: "supported",
|
|
53786
|
+
introducedIn: "0.2.1-alpha.3",
|
|
53787
|
+
detect: (ctx) => supportsSessionModelSelection(read(ctx, "sessionController")),
|
|
53788
|
+
create: (ctx) => createSessionModelSelectionAdapter(read(ctx, "sessionController"))
|
|
53789
|
+
});
|
|
53790
|
+
add({
|
|
53791
|
+
id: "session-activation-020",
|
|
53792
|
+
capability: "session.activation",
|
|
53793
|
+
supportedDsh: ">=0.2.0-rc.2 <=0.2.1-alpha.2",
|
|
53794
|
+
runtime,
|
|
53795
|
+
priority: 10,
|
|
53796
|
+
status: "supported",
|
|
53797
|
+
introducedIn: "0.2.0-rc.2",
|
|
53798
|
+
detect: (ctx) => hasMethods(read(ctx, "sessionController"), ["create"]),
|
|
53799
|
+
create: (ctx) => read(ctx, "sessionController")
|
|
53800
|
+
});
|
|
53801
|
+
add({
|
|
53802
|
+
id: "session-activation-021",
|
|
53803
|
+
capability: "session.activation",
|
|
53804
|
+
supportedDsh: ">=0.2.1-alpha.3 <=0.2.1-alpha.3",
|
|
53805
|
+
runtime,
|
|
53806
|
+
priority: 10,
|
|
53807
|
+
status: "supported",
|
|
53808
|
+
introducedIn: "0.2.1-alpha.3",
|
|
53809
|
+
detect: (ctx) => hasMethods(read(ctx, "sessionController"), ["create", "resolveAgent"]),
|
|
53810
|
+
create: (ctx) => read(ctx, "sessionController")
|
|
53811
|
+
});
|
|
53812
|
+
for (const capability of ["connection.peer", "connection.uplink"]) add({
|
|
53813
|
+
id: `${capability}-021`,
|
|
53814
|
+
capability,
|
|
53815
|
+
supportedDsh: ">=0.2.1-alpha.3 <=0.2.1-alpha.3",
|
|
53816
|
+
runtime,
|
|
53817
|
+
priority: 40,
|
|
53818
|
+
status: "supported",
|
|
53819
|
+
introducedIn: "0.2.1-alpha.3",
|
|
53820
|
+
detect: (ctx) => hasMethods(read(ctx, "connection"), ["admit", "createPeer"]) && read(ctx, "connection.browserPeer") !== void 0,
|
|
53821
|
+
create: (ctx) => read(ctx, "connection")
|
|
53822
|
+
});
|
|
54316
53823
|
add({
|
|
54317
53824
|
id: "assistant-agent-021",
|
|
54318
53825
|
capability: "assistant.agent",
|
|
@@ -54398,6 +53905,28 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
54398
53905
|
addDsh020HostRoutes(add, range020);
|
|
54399
53906
|
addPeerHostHostRoutes(add);
|
|
54400
53907
|
} else {
|
|
53908
|
+
add({
|
|
53909
|
+
id: "message-presentation-020",
|
|
53910
|
+
capability: "conversation.message-presentation",
|
|
53911
|
+
supportedDsh: ">=0.2.0-rc.2 <=0.2.1-alpha.2",
|
|
53912
|
+
runtime,
|
|
53913
|
+
priority: 10,
|
|
53914
|
+
status: "supported",
|
|
53915
|
+
introducedIn: "0.2.0-rc.2",
|
|
53916
|
+
detect: (ctx) => supportsLegacyMessagePresentation({ slots: read(ctx, "slots") }, facts.primitives),
|
|
53917
|
+
create: () => createLegacyMessagePresentation(facts.primitives)
|
|
53918
|
+
});
|
|
53919
|
+
add({
|
|
53920
|
+
id: "message-presentation-021",
|
|
53921
|
+
capability: "conversation.message-presentation",
|
|
53922
|
+
supportedDsh: ">=0.2.1-alpha.3 <=0.2.1-alpha.3",
|
|
53923
|
+
runtime,
|
|
53924
|
+
priority: 10,
|
|
53925
|
+
status: "supported",
|
|
53926
|
+
introducedIn: "0.2.1-alpha.3",
|
|
53927
|
+
detect: (ctx) => supportsFactoryMessagePresentation({ slots: read(ctx, "slots") }),
|
|
53928
|
+
create: createFactoryMessagePresentation
|
|
53929
|
+
});
|
|
54401
53930
|
add({
|
|
54402
53931
|
id: "settings-scope",
|
|
54403
53932
|
capability: "settings.store",
|
|
@@ -54489,12 +54018,12 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
54489
54018
|
add({
|
|
54490
54019
|
id: "interaction-presentation-021",
|
|
54491
54020
|
capability: "conversation.interaction-translation",
|
|
54492
|
-
supportedDsh:
|
|
54021
|
+
supportedDsh: range020,
|
|
54493
54022
|
runtime,
|
|
54494
54023
|
priority: 10,
|
|
54495
54024
|
status: "supported",
|
|
54496
|
-
introducedIn: "0.2.
|
|
54497
|
-
detect: supportsInteractionPresentation,
|
|
54025
|
+
introducedIn: "0.2.0-rc.2",
|
|
54026
|
+
detect: (ctx) => supportsInteractionPresentation({ slots: read(ctx, "slots") }),
|
|
54498
54027
|
create: createInteractionPresentationBridge
|
|
54499
54028
|
});
|
|
54500
54029
|
addDsh020ClientRoutes(add, range020, facts);
|
|
@@ -54573,7 +54102,7 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
54573
54102
|
add({
|
|
54574
54103
|
id: "connection-peer-admission-020",
|
|
54575
54104
|
capability: "connection.peer",
|
|
54576
|
-
supportedDsh,
|
|
54105
|
+
supportedDsh: ">=0.2.0-rc.2 <=0.2.1-alpha.2",
|
|
54577
54106
|
runtime: "host",
|
|
54578
54107
|
priority: 30,
|
|
54579
54108
|
status: "supported",
|
|
@@ -54595,7 +54124,7 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
54595
54124
|
add({
|
|
54596
54125
|
id: "connection-rpc-uplink-020",
|
|
54597
54126
|
capability: "connection.uplink",
|
|
54598
|
-
supportedDsh,
|
|
54127
|
+
supportedDsh: ">=0.2.0-rc.2 <=0.2.1-alpha.2",
|
|
54599
54128
|
runtime: "host",
|
|
54600
54129
|
priority: 10,
|
|
54601
54130
|
status: "supported",
|
|
@@ -54711,7 +54240,7 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
54711
54240
|
add({
|
|
54712
54241
|
id: "conversation-draft-share-021",
|
|
54713
54242
|
capability: "conversation.draft-share",
|
|
54714
|
-
supportedDsh: ">=0.2.1-alpha.1 <=0.2.1-alpha.
|
|
54243
|
+
supportedDsh: ">=0.2.1-alpha.1 <=0.2.1-alpha.3",
|
|
54715
54244
|
runtime: "client",
|
|
54716
54245
|
priority: 30,
|
|
54717
54246
|
status: "supported",
|
|
@@ -54851,161 +54380,1395 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
54851
54380
|
detect: (ctx) => read(ctx, "modules.version") === "client",
|
|
54852
54381
|
create: (ctx) => read(ctx, "modules")
|
|
54853
54382
|
});
|
|
54854
|
-
add({
|
|
54855
|
-
id: "layout-columns-020",
|
|
54856
|
-
capability: "layout.columns",
|
|
54857
|
-
supportedDsh,
|
|
54858
|
-
runtime: "client",
|
|
54859
|
-
priority: 30,
|
|
54860
|
-
status: "supported",
|
|
54861
|
-
introducedIn: "0.2.0-rc.1",
|
|
54862
|
-
detect: (ctx) => typeof read(ctx, "layout.toggleSidebar") === "function",
|
|
54863
|
-
create: (ctx) => read(ctx, "layout")
|
|
54383
|
+
add({
|
|
54384
|
+
id: "layout-columns-020",
|
|
54385
|
+
capability: "layout.columns",
|
|
54386
|
+
supportedDsh,
|
|
54387
|
+
runtime: "client",
|
|
54388
|
+
priority: 30,
|
|
54389
|
+
status: "supported",
|
|
54390
|
+
introducedIn: "0.2.0-rc.1",
|
|
54391
|
+
detect: (ctx) => typeof read(ctx, "layout.toggleSidebar") === "function",
|
|
54392
|
+
create: (ctx) => read(ctx, "layout")
|
|
54393
|
+
});
|
|
54394
|
+
add({
|
|
54395
|
+
id: "sidebar-right-expand-020",
|
|
54396
|
+
capability: "sidebar.right.expand",
|
|
54397
|
+
supportedDsh,
|
|
54398
|
+
runtime: "client",
|
|
54399
|
+
priority: 30,
|
|
54400
|
+
status: "supported",
|
|
54401
|
+
introducedIn: "0.2.0-rc.1",
|
|
54402
|
+
detect: (ctx) => hasMethods(read(ctx, "sidebarRight"), ["isExpanded", "toggleExpanded"]),
|
|
54403
|
+
create: (ctx) => read(ctx, "sidebarRight")
|
|
54404
|
+
});
|
|
54405
|
+
}
|
|
54406
|
+
/**
|
|
54407
|
+
* 读取探测上下文里的服务或结构事实。
|
|
54408
|
+
*
|
|
54409
|
+
* Cordis 的 Context 只在调用方 fiber 的 inject 链(或祖先 fiber 提供的服务)里
|
|
54410
|
+
* 解析属性;直接读未注入的服务会抛 `cannot get property "x" without inject`,
|
|
54411
|
+
* 把 `a || b` 形式的探测短路成失败。因此这里统一先走 `ctx.get(...)`(Cordis 提供
|
|
54412
|
+
* 的免 inject 读取),再回退到普通属性读取,让探测只依据服务形状,不受消费方
|
|
54413
|
+
* inject 列表影响。
|
|
54414
|
+
*/
|
|
54415
|
+
function read(context, path) {
|
|
54416
|
+
const [head, ...rest] = path.split(".");
|
|
54417
|
+
if (head === void 0) return void 0;
|
|
54418
|
+
let value = readKey(context, head);
|
|
54419
|
+
for (const key of rest) value = readProperty(value, key);
|
|
54420
|
+
return value;
|
|
54421
|
+
}
|
|
54422
|
+
/** 读取上下文上的服务(优先 `ctx.get`)或直接挂在上下文上的事实对象。 */
|
|
54423
|
+
function readKey(context, key) {
|
|
54424
|
+
if (typeof context !== "object" || context === null) return void 0;
|
|
54425
|
+
const getter = readProperty(context, "get");
|
|
54426
|
+
if (typeof getter === "function") try {
|
|
54427
|
+
const value = getter.call(context, key);
|
|
54428
|
+
if (value !== void 0) return value;
|
|
54429
|
+
} catch {}
|
|
54430
|
+
return readProperty(context, key);
|
|
54431
|
+
}
|
|
54432
|
+
/** 读取对象属性;Cordis 代理对未注入的服务会抛错,统一按缺失处理。 */
|
|
54433
|
+
function readProperty(target, key) {
|
|
54434
|
+
if (typeof target !== "object" || target === null) return void 0;
|
|
54435
|
+
try {
|
|
54436
|
+
return Reflect.get(target, key);
|
|
54437
|
+
} catch {
|
|
54438
|
+
return;
|
|
54439
|
+
}
|
|
54440
|
+
}
|
|
54441
|
+
function hasMethods(value, methods) {
|
|
54442
|
+
return typeof value === "object" && value !== null && methods.every((method) => typeof Reflect.get(value, method) === "function");
|
|
54443
|
+
}
|
|
54444
|
+
function hasAny(value, keys) {
|
|
54445
|
+
return typeof value === "object" && value !== null && keys.some((key) => Reflect.get(value, key) !== void 0);
|
|
54446
|
+
}
|
|
54447
|
+
/** PeerHost Host 能力只接受显式注入的适配器,避免把普通 DSH 服务误报为已实现。 */
|
|
54448
|
+
function addPeerHostHostRoutes(add) {
|
|
54449
|
+
addPeerHostRoute(add, "peer-host.store", "peer-host-store", "peerHostStore");
|
|
54450
|
+
addPeerHostRoute(add, "peer-host.handshake", "peer-host-handshake", "peerHostHandshake");
|
|
54451
|
+
addPeerHostRoute(add, "peer-host.http-proxy", "peer-host-http-proxy", "peerHostHttpProxy");
|
|
54452
|
+
addPeerHostRoute(add, "peer-host.ws-proxy", "peer-host-ws-proxy", "peerHostWsProxy");
|
|
54453
|
+
addPeerHostRoute(add, "peer-host.aggregate", "peer-host-aggregate", "peerHostAggregate");
|
|
54454
|
+
addPeerHostRoute(add, "peer-host.aggregated-transport", "peer-host-aggregated-transport", "peerHostAggregatedTransport");
|
|
54455
|
+
addPeerHostRoute(add, "peer-host.target-capabilities", "peer-host-target-capabilities", "peerHostTargetCapabilities");
|
|
54456
|
+
addPeerHostRoute(add, "peer-host.local-plugin-baseline", "peer-host-local-plugin-baseline", "peerHostLocalPluginBaseline");
|
|
54457
|
+
addPeerHostRoute(add, "peer-host.relay-route", "peer-host-relay-route", "peerHostRelayRoute");
|
|
54458
|
+
addPeerHostRoute(add, "peer-host.store", "peer-host-store-020", "peerHostStore", require_native_workspace_store.DSH_COMPATIBILITY, "supported", 30);
|
|
54459
|
+
addPeerHostRoute(add, "peer-host.handshake", "peer-host-handshake-020", "peerHostHandshake", require_native_workspace_store.DSH_COMPATIBILITY, "supported", 30);
|
|
54460
|
+
addPeerHostRoute(add, "peer-host.http-proxy", "peer-host-http-proxy-020", "peerHostHttpProxy", require_native_workspace_store.DSH_COMPATIBILITY, "supported", 30);
|
|
54461
|
+
addPeerHostRoute(add, "peer-host.ws-proxy", "peer-host-ws-proxy-020", "peerHostWsProxy", require_native_workspace_store.DSH_COMPATIBILITY, "supported", 30);
|
|
54462
|
+
addPeerHostRoute(add, "peer-host.aggregate", "peer-host-aggregate-020", "peerHostAggregate", require_native_workspace_store.DSH_COMPATIBILITY, "supported", 30);
|
|
54463
|
+
addPeerHostRoute(add, "peer-host.aggregated-transport", "peer-host-aggregated-transport-020", "peerHostAggregatedTransport", require_native_workspace_store.DSH_COMPATIBILITY, "supported", 30);
|
|
54464
|
+
addPeerHostRoute(add, "peer-host.target-capabilities", "peer-host-target-capabilities-020", "peerHostTargetCapabilities", require_native_workspace_store.DSH_COMPATIBILITY, "supported", 30);
|
|
54465
|
+
addPeerHostRoute(add, "peer-host.local-plugin-baseline", "peer-host-local-plugin-baseline-020", "peerHostLocalPluginBaseline", require_native_workspace_store.DSH_COMPATIBILITY, "supported", 30);
|
|
54466
|
+
addPeerHostRoute(add, "peer-host.relay-route", "peer-host-relay-route-020", "peerHostRelayRoute", require_native_workspace_store.DSH_COMPATIBILITY, "supported", 30);
|
|
54467
|
+
}
|
|
54468
|
+
/**
|
|
54469
|
+
* PeerHost Client 导航能力由独立 adapter 注入;未注入时由 Feature 诊断降级。
|
|
54470
|
+
*
|
|
54471
|
+
* `peer-host.client-preboot-transport` 表示"页面在 DSH Connection 之前已可被聚合
|
|
54472
|
+
* Transport 包装"。它不再等待官方 Provider 适配器,而是由插件自带的启动页 shim
|
|
54473
|
+
* 提供:Web 与 Desktop 都注入同一个 shim,Desktop 用访问器接管运行时赋值。探测
|
|
54474
|
+
* 只读 shim 状态,`external`(Transport 形状未知)时判为不可用,由 Feature 按
|
|
54475
|
+
* "能力缺失只影响该模块"停用 PeerHost,而不是提示用户刷新。
|
|
54476
|
+
*/
|
|
54477
|
+
function addPeerHostClientRoutes(add) {
|
|
54478
|
+
addPeerHostRoute(add, "peer-host.native-navigation", "peer-host-native-navigation-legacy", "peerHostNativeNavigation", ">=0.1.5-rc.3 <=0.1.6", "deprecated");
|
|
54479
|
+
addPeerHostRoute(add, "peer-host.native-navigation", "peer-host-native-navigation-modern", "peerHostNativeNavigation", ">=0.1.7-rc.2 <=0.1.7-rc.2", "supported", 20);
|
|
54480
|
+
addPeerHostRoute(add, "peer-host.remote-web-context-fallback", "peer-host-remote-web-context-fallback", "peerHostRemoteWebContextFallback");
|
|
54481
|
+
addPeerHostRoute(add, "peer-host.native-navigation", "peer-host-native-navigation-020", "peerHostNativeNavigation", require_native_workspace_store.DSH_COMPATIBILITY, "supported", 30);
|
|
54482
|
+
addPeerHostRoute(add, "peer-host.remote-web-context-fallback", "peer-host-remote-web-context-fallback-020", "peerHostRemoteWebContextFallback", require_native_workspace_store.DSH_COMPATIBILITY, "supported", 30);
|
|
54483
|
+
add({
|
|
54484
|
+
id: "peer-host-client-preboot-transport-020",
|
|
54485
|
+
capability: "peer-host.client-preboot-transport",
|
|
54486
|
+
supportedDsh: require_native_workspace_store.DSH_COMPATIBILITY,
|
|
54487
|
+
runtime: "client",
|
|
54488
|
+
priority: 40,
|
|
54489
|
+
status: "supported",
|
|
54490
|
+
introducedIn: "0.2.0-rc.2",
|
|
54491
|
+
detect: () => isPeerHostPrebootShimWrappable(),
|
|
54492
|
+
create: () => readPeerHostPrebootShim()
|
|
54493
|
+
});
|
|
54494
|
+
}
|
|
54495
|
+
/**
|
|
54496
|
+
* shim 已安装且不是"结构不支持"时,页面 Transport 可被聚合层包装。
|
|
54497
|
+
*
|
|
54498
|
+
* 探测只读启动页已经写入的全局状态:`not-installed`(脚本未注入)与 `external`
|
|
54499
|
+
* (Transport 形状未知)都判为不可用,让 Feature 按"能力缺失只影响该模块"停用
|
|
54500
|
+
* PeerHost,而不是提示用户刷新。
|
|
54501
|
+
*/
|
|
54502
|
+
function isPeerHostPrebootShimWrappable() {
|
|
54503
|
+
const state = readPeerHostPrebootShimState();
|
|
54504
|
+
return state !== "not-installed" && state !== "external";
|
|
54505
|
+
}
|
|
54506
|
+
function readPeerHostPrebootShimState() {
|
|
54507
|
+
const shim = readPeerHostPrebootShim();
|
|
54508
|
+
if (shim === void 0) return "not-installed";
|
|
54509
|
+
try {
|
|
54510
|
+
return typeof shim.getState === "function" ? String(shim.getState()) : "installed";
|
|
54511
|
+
} catch {
|
|
54512
|
+
return "not-installed";
|
|
54513
|
+
}
|
|
54514
|
+
}
|
|
54515
|
+
function readPeerHostPrebootShim() {
|
|
54516
|
+
try {
|
|
54517
|
+
return globalThis[DSH_PEER_HOST_PREBOOT_SHIM_GLOBAL];
|
|
54518
|
+
} catch {
|
|
54519
|
+
return;
|
|
54520
|
+
}
|
|
54521
|
+
}
|
|
54522
|
+
function addPeerHostRoute(add, capability, id, field, supportedDsh = ">=0.1.5-rc.3 <=0.1.7-rc.2", status = "supported", priority = 10) {
|
|
54523
|
+
add({
|
|
54524
|
+
id,
|
|
54525
|
+
capability,
|
|
54526
|
+
supportedDsh,
|
|
54527
|
+
runtime: capability === "peer-host.native-navigation" || capability === "peer-host.remote-web-context-fallback" || capability === "peer-host.client-preboot-transport" ? "client" : "host",
|
|
54528
|
+
priority,
|
|
54529
|
+
status,
|
|
54530
|
+
introducedIn: "0.1.5-rc.3",
|
|
54531
|
+
detect: (context) => readPeerHostAdapter(context, field) !== void 0,
|
|
54532
|
+
create: (context) => readPeerHostAdapter(context, field)
|
|
54533
|
+
});
|
|
54534
|
+
}
|
|
54535
|
+
function readPeerHostAdapter(context, field) {
|
|
54536
|
+
if (Array.isArray(context)) return void 0;
|
|
54537
|
+
return readKey(context, field);
|
|
54538
|
+
}
|
|
54539
|
+
//#endregion
|
|
54540
|
+
//#region src/shared/translation-indicator.ts
|
|
54541
|
+
const TRANSLATION_GLYPH_PATHS = ["M3.5 5.5h10M8.5 3.5v2M12.5 5.5c0 4.4-3.3 7.2-8 9", "M5.5 8.5c1.4 2 3.4 3.7 6 4.8M14.5 19.5l3-8 3 8M15.7 17h3.6"];
|
|
54542
|
+
const TRANSLATION_STATUS_BADGE_STYLE = {
|
|
54543
|
+
position: "absolute",
|
|
54544
|
+
top: "1px",
|
|
54545
|
+
right: "1px",
|
|
54546
|
+
display: "grid",
|
|
54547
|
+
placeItems: "center",
|
|
54548
|
+
width: "10px",
|
|
54549
|
+
height: "10px",
|
|
54550
|
+
zIndex: "1",
|
|
54551
|
+
boxSizing: "border-box",
|
|
54552
|
+
border: "1.5px solid var(--dsw-alias-bg-base, Canvas)",
|
|
54553
|
+
borderRadius: "50%",
|
|
54554
|
+
color: "#fff",
|
|
54555
|
+
fontSize: "6px",
|
|
54556
|
+
fontWeight: "700",
|
|
54557
|
+
lineHeight: "1"
|
|
54558
|
+
};
|
|
54559
|
+
const TRANSLATION_PENDING_BADGE_STYLE = {
|
|
54560
|
+
border: "1.5px solid var(--dsw-alias-button-info-fill, #1677ff)",
|
|
54561
|
+
borderTopColor: "transparent",
|
|
54562
|
+
background: "transparent"
|
|
54563
|
+
};
|
|
54564
|
+
//#endregion
|
|
54565
|
+
//#region src/client/session-translation-pending-dom.ts
|
|
54566
|
+
/** Pending DSH bubbles and queue previews have no renderer slot. */
|
|
54567
|
+
function watchPendingTranslationTargets(anchor, onChange) {
|
|
54568
|
+
const root = anchor.closest("[data-conversation-session]");
|
|
54569
|
+
const Observer = anchor.ownerDocument.defaultView?.MutationObserver;
|
|
54570
|
+
if (root === null || Observer === void 0) return () => void 0;
|
|
54571
|
+
const targets = /* @__PURE__ */ new Map();
|
|
54572
|
+
let nextKey = 0;
|
|
54573
|
+
const scan = () => {
|
|
54574
|
+
observer.disconnect();
|
|
54575
|
+
let changed = false;
|
|
54576
|
+
const rows = new Set(root.querySelectorAll("[data-submission-echo]"));
|
|
54577
|
+
for (const [row, target] of targets) {
|
|
54578
|
+
if (rows.has(row) && root.contains(target.container)) continue;
|
|
54579
|
+
target.container.remove();
|
|
54580
|
+
targets.delete(row);
|
|
54581
|
+
changed = true;
|
|
54582
|
+
}
|
|
54583
|
+
for (const row of rows) {
|
|
54584
|
+
if (row.closest("[data-conversation-session]") !== root) continue;
|
|
54585
|
+
const original = (row.querySelector("[class*=\"bubble\"]") ?? row.querySelector("[class*=\"preview\"]"))?.textContent ?? "";
|
|
54586
|
+
const actions = row.querySelector("[data-clock=\"start\"]") ?? row.querySelector("[class*=\"actions\"]") ?? row;
|
|
54587
|
+
if (original.trim() === "") continue;
|
|
54588
|
+
const existing = targets.get(row);
|
|
54589
|
+
if (existing !== void 0) {
|
|
54590
|
+
if (existing.original !== original) {
|
|
54591
|
+
targets.set(row, {
|
|
54592
|
+
...existing,
|
|
54593
|
+
original
|
|
54594
|
+
});
|
|
54595
|
+
changed = true;
|
|
54596
|
+
}
|
|
54597
|
+
continue;
|
|
54598
|
+
}
|
|
54599
|
+
const container = anchor.ownerDocument.createElement("span");
|
|
54600
|
+
container.dataset.codingnsPendingTranslation = "";
|
|
54601
|
+
container.style.display = "inline-flex";
|
|
54602
|
+
let before = actions.querySelector("button");
|
|
54603
|
+
while (before !== null && before.parentElement !== actions) before = before.parentElement;
|
|
54604
|
+
actions.insertBefore(container, before);
|
|
54605
|
+
targets.set(row, {
|
|
54606
|
+
key: nextKey++,
|
|
54607
|
+
container,
|
|
54608
|
+
original
|
|
54609
|
+
});
|
|
54610
|
+
changed = true;
|
|
54611
|
+
}
|
|
54612
|
+
if (changed) onChange([...targets.values()]);
|
|
54613
|
+
observer.observe(root, {
|
|
54614
|
+
childList: true,
|
|
54615
|
+
subtree: true,
|
|
54616
|
+
characterData: true
|
|
54617
|
+
});
|
|
54618
|
+
};
|
|
54619
|
+
const observer = new Observer(scan);
|
|
54620
|
+
scan();
|
|
54621
|
+
return () => {
|
|
54622
|
+
observer.disconnect();
|
|
54623
|
+
for (const target of targets.values()) target.container.remove();
|
|
54624
|
+
targets.clear();
|
|
54625
|
+
};
|
|
54626
|
+
}
|
|
54627
|
+
//#endregion
|
|
54628
|
+
//#region src/client/session-translation-retry.ts
|
|
54629
|
+
const stores = /* @__PURE__ */ new WeakMap();
|
|
54630
|
+
/** Share a display result between the reply, collapsed reasoning, and its popup. */
|
|
54631
|
+
function useOutputTranslation(props) {
|
|
54632
|
+
const owner = props.services.rpc ?? props.services;
|
|
54633
|
+
const key = JSON.stringify([
|
|
54634
|
+
props.sessionId,
|
|
54635
|
+
props.messageId,
|
|
54636
|
+
props.outputKind,
|
|
54637
|
+
props.record?.original,
|
|
54638
|
+
props.record?.targetLanguage
|
|
54639
|
+
]);
|
|
54640
|
+
const entry = (0, react.useMemo)(() => {
|
|
54641
|
+
let store = stores.get(owner);
|
|
54642
|
+
if (store === void 0) {
|
|
54643
|
+
store = /* @__PURE__ */ new Map();
|
|
54644
|
+
stores.set(owner, store);
|
|
54645
|
+
}
|
|
54646
|
+
let value = store.get(key);
|
|
54647
|
+
if (value === void 0) {
|
|
54648
|
+
value = {
|
|
54649
|
+
state: { pending: false },
|
|
54650
|
+
listeners: /* @__PURE__ */ new Set()
|
|
54651
|
+
};
|
|
54652
|
+
store.set(key, value);
|
|
54653
|
+
for (const [oldKey, old] of store) {
|
|
54654
|
+
if (store.size <= 256) break;
|
|
54655
|
+
if (oldKey !== key && !old.state.pending && old.listeners.size === 0) store.delete(oldKey);
|
|
54656
|
+
}
|
|
54657
|
+
}
|
|
54658
|
+
return value;
|
|
54659
|
+
}, [owner, key]);
|
|
54660
|
+
const subscription = (0, react.useMemo)(() => ({
|
|
54661
|
+
subscribe(listener) {
|
|
54662
|
+
entry.listeners.add(listener);
|
|
54663
|
+
return () => {
|
|
54664
|
+
entry.listeners.delete(listener);
|
|
54665
|
+
};
|
|
54666
|
+
},
|
|
54667
|
+
snapshot: () => entry.state
|
|
54668
|
+
}), [entry]);
|
|
54669
|
+
const state = (0, react.useSyncExternalStore)(subscription.subscribe, subscription.snapshot, subscription.snapshot);
|
|
54670
|
+
const publish = (next) => {
|
|
54671
|
+
entry.state = next;
|
|
54672
|
+
for (const listener of entry.listeners) listener();
|
|
54673
|
+
};
|
|
54674
|
+
const record = state.record ?? props.record;
|
|
54675
|
+
const retry = props.sessionId === void 0 || props.outputKind === void 0 || record?.failed !== true ? void 0 : async () => {
|
|
54676
|
+
if (entry.state.pending) return;
|
|
54677
|
+
const controller = new AbortController();
|
|
54678
|
+
entry.controller = controller;
|
|
54679
|
+
publish({
|
|
54680
|
+
record,
|
|
54681
|
+
pending: true
|
|
54682
|
+
});
|
|
54683
|
+
try {
|
|
54684
|
+
const result = await require_model_catalog_cache.callCliRpc(props.services.rpc, "translation/retry-output", {
|
|
54685
|
+
sessionId: props.sessionId,
|
|
54686
|
+
original: record.original,
|
|
54687
|
+
outputKind: props.outputKind
|
|
54688
|
+
}, AbortSignal.any([controller.signal, AbortSignal.timeout(18e4)]));
|
|
54689
|
+
if (!controller.signal.aborted) publish({
|
|
54690
|
+
record: result,
|
|
54691
|
+
pending: false
|
|
54692
|
+
});
|
|
54693
|
+
} catch {
|
|
54694
|
+
if (!controller.signal.aborted) publish({
|
|
54695
|
+
record,
|
|
54696
|
+
pending: false
|
|
54697
|
+
});
|
|
54698
|
+
} finally {
|
|
54699
|
+
if (entry.controller === controller) delete entry.controller;
|
|
54700
|
+
}
|
|
54701
|
+
};
|
|
54702
|
+
return {
|
|
54703
|
+
record,
|
|
54704
|
+
pending: state.pending,
|
|
54705
|
+
retry
|
|
54706
|
+
};
|
|
54707
|
+
}
|
|
54708
|
+
function clearOutputTranslationRetries(services) {
|
|
54709
|
+
const owner = services.rpc ?? services;
|
|
54710
|
+
const store = stores.get(owner);
|
|
54711
|
+
for (const entry of store?.values() ?? []) entry.controller?.abort();
|
|
54712
|
+
stores.delete(owner);
|
|
54713
|
+
}
|
|
54714
|
+
//#endregion
|
|
54715
|
+
//#region src/client/session-translation-chat.ts
|
|
54716
|
+
/**
|
|
54717
|
+
* 把翻译状态和查看原文的入口放回对应消息块,不占用 AI 回复底部的统一操作栏。
|
|
54718
|
+
*/
|
|
54719
|
+
function TranslationAction(props) {
|
|
54720
|
+
const [open, setOpen] = (0, react.useState)(props.inputFailure !== void 0);
|
|
54721
|
+
const output = useOutputTranslation({
|
|
54722
|
+
...props,
|
|
54723
|
+
record: props.inputFailure?.record ?? props.record
|
|
54724
|
+
});
|
|
54725
|
+
const [deciding, setDeciding] = (0, react.useState)(false);
|
|
54726
|
+
const decidingRef = (0, react.useRef)(false);
|
|
54727
|
+
const [decisionError, setDecisionError] = (0, react.useState)(false);
|
|
54728
|
+
(0, react.useEffect)(() => {
|
|
54729
|
+
if (props.inputFailure !== void 0) setOpen(true);
|
|
54730
|
+
setDecisionError(false);
|
|
54731
|
+
}, [props.inputFailure?.id]);
|
|
54732
|
+
const rootRef = (0, react.useRef)(null);
|
|
54733
|
+
const buttonRef = (0, react.useRef)(null);
|
|
54734
|
+
const popupRef = (0, react.useRef)(null);
|
|
54735
|
+
const [popupPosition, setPopupPosition] = (0, react.useState)(null);
|
|
54736
|
+
useDismissOnOutsidePointer(rootRef, open, () => setOpen(false), { portal: popupRef });
|
|
54737
|
+
(0, react.useLayoutEffect)(() => {
|
|
54738
|
+
if (!open || typeof window === "undefined") {
|
|
54739
|
+
setPopupPosition(null);
|
|
54740
|
+
return;
|
|
54741
|
+
}
|
|
54742
|
+
const updatePosition = () => {
|
|
54743
|
+
const button = buttonRef.current;
|
|
54744
|
+
if (button === null) return;
|
|
54745
|
+
const rect = button.getBoundingClientRect();
|
|
54746
|
+
const edge = 12;
|
|
54747
|
+
const gap = 8;
|
|
54748
|
+
const width = Math.max(1, Math.min(420, window.innerWidth - 24));
|
|
54749
|
+
const availableAbove = Math.max(0, rect.top - gap - edge);
|
|
54750
|
+
const availableBelow = Math.max(0, window.innerHeight - rect.bottom - gap - edge);
|
|
54751
|
+
const preferredHeight = Math.min(440, window.innerHeight * .65);
|
|
54752
|
+
const placement = availableAbove >= preferredHeight || availableBelow < preferredHeight && availableAbove > availableBelow ? "above" : "below";
|
|
54753
|
+
const maxHeight = Math.min(preferredHeight, placement === "above" ? availableAbove : availableBelow);
|
|
54754
|
+
const desiredLeft = props.popupAlign === "end" ? rect.right - width : rect.left;
|
|
54755
|
+
const maxLeft = Math.max(edge, window.innerWidth - edge - width);
|
|
54756
|
+
setPopupPosition({
|
|
54757
|
+
left: Math.min(maxLeft, Math.max(edge, desiredLeft)),
|
|
54758
|
+
top: placement === "above" ? rect.top - gap : rect.bottom + gap,
|
|
54759
|
+
width,
|
|
54760
|
+
maxHeight,
|
|
54761
|
+
placement
|
|
54762
|
+
});
|
|
54763
|
+
};
|
|
54764
|
+
updatePosition();
|
|
54765
|
+
window.addEventListener("resize", updatePosition);
|
|
54766
|
+
window.addEventListener("scroll", updatePosition, true);
|
|
54767
|
+
return () => {
|
|
54768
|
+
window.removeEventListener("resize", updatePosition);
|
|
54769
|
+
window.removeEventListener("scroll", updatePosition, true);
|
|
54770
|
+
};
|
|
54771
|
+
}, [open, props.popupAlign]);
|
|
54772
|
+
const record = output.record;
|
|
54773
|
+
const inputFailure = props.inputFailure !== void 0;
|
|
54774
|
+
const detailsTitle = props.translationT(inputFailure ? "translation.inputFailedTitle" : "translation.detailsTitle");
|
|
54775
|
+
const pending = record === void 0 || output.pending;
|
|
54776
|
+
const failed = record?.failed === true;
|
|
54777
|
+
const alreadyTargetLanguage = record?.alreadyTargetLanguage === true;
|
|
54778
|
+
const statusText = pending ? props.translationT("translation.statusTranslating") : failed ? props.translationT("translation.statusFailed") : alreadyTargetLanguage ? props.translationT("translation.statusNotNeeded") : props.translationT("translation.statusTranslated");
|
|
54779
|
+
const statusColor = pending ? require_theme.dshThemeColor.accent : failed ? require_theme.dshThemeColor.error : alreadyTargetLanguage ? require_theme.dshThemeColor.accent : require_theme.dshThemeColor.success;
|
|
54780
|
+
const detailsId = `codingns-translation-details-${safeDomId(props.messageId)}`;
|
|
54781
|
+
const decide = async (choice) => {
|
|
54782
|
+
if (props.inputFailure === void 0 || decidingRef.current) return;
|
|
54783
|
+
decidingRef.current = true;
|
|
54784
|
+
setDeciding(true);
|
|
54785
|
+
setDecisionError(false);
|
|
54786
|
+
try {
|
|
54787
|
+
await require_model_catalog_cache.callCliRpc(props.services.rpc, "translation/resolve", {
|
|
54788
|
+
sessionId: props.inputFailure.sessionId,
|
|
54789
|
+
id: props.inputFailure.id,
|
|
54790
|
+
choice
|
|
54791
|
+
}, AbortSignal.timeout(15e3));
|
|
54792
|
+
props.onDecision?.();
|
|
54793
|
+
} catch {
|
|
54794
|
+
setDecisionError(true);
|
|
54795
|
+
} finally {
|
|
54796
|
+
decidingRef.current = false;
|
|
54797
|
+
setDeciding(false);
|
|
54798
|
+
}
|
|
54799
|
+
};
|
|
54800
|
+
const details = open && popupPosition !== null ? (0, react.createElement)("div", {
|
|
54801
|
+
ref: popupRef,
|
|
54802
|
+
role: "dialog",
|
|
54803
|
+
"aria-label": detailsTitle,
|
|
54804
|
+
id: detailsId,
|
|
54805
|
+
style: {
|
|
54806
|
+
position: "fixed",
|
|
54807
|
+
zIndex: 2147483647,
|
|
54808
|
+
left: popupPosition.left,
|
|
54809
|
+
top: popupPosition.top,
|
|
54810
|
+
width: popupPosition.width,
|
|
54811
|
+
maxHeight: popupPosition.maxHeight,
|
|
54812
|
+
boxSizing: "border-box",
|
|
54813
|
+
...popupPosition.placement === "above" ? { transform: "translateY(-100%)" } : {},
|
|
54814
|
+
overflow: "auto",
|
|
54815
|
+
padding: "10px 12px",
|
|
54816
|
+
border: `1px solid ${require_theme.dshThemeColor.border}`,
|
|
54817
|
+
borderRadius: 8,
|
|
54818
|
+
color: require_theme.dshThemeColor.labelPrimary,
|
|
54819
|
+
background: require_theme.dshThemeColor.menuBackground,
|
|
54820
|
+
boxShadow: "0 8px 24px color-mix(in srgb, CanvasText 16%, transparent)",
|
|
54821
|
+
fontSize: require_theme.uiFontSize(12),
|
|
54822
|
+
lineHeight: 1.45
|
|
54823
|
+
}
|
|
54824
|
+
}, (0, react.createElement)("div", { style: {
|
|
54825
|
+
display: "flex",
|
|
54826
|
+
justifyContent: "space-between",
|
|
54827
|
+
gap: 10,
|
|
54828
|
+
fontWeight: 600
|
|
54829
|
+
} }, (0, react.createElement)("span", void 0, detailsTitle), inputFailure ? null : (0, react.createElement)("span", {
|
|
54830
|
+
role: "status",
|
|
54831
|
+
"aria-live": "polite",
|
|
54832
|
+
style: {
|
|
54833
|
+
color: statusColor,
|
|
54834
|
+
fontWeight: 400
|
|
54835
|
+
}
|
|
54836
|
+
}, statusText)), inputFailure || record?.sourceLanguage === void 0 ? null : (0, react.createElement)("div", { style: {
|
|
54837
|
+
marginTop: 8,
|
|
54838
|
+
color: require_theme.dshThemeColor.labelSecondary
|
|
54839
|
+
} }, `${props.translationT("translation.detectedLanguage")}: ${props.translationT(`translation.language.${record.sourceLanguage}`)}`), inputFailure ? null : (0, react.createElement)(DetailBlock, {
|
|
54840
|
+
kind: "original",
|
|
54841
|
+
translationT: props.translationT,
|
|
54842
|
+
value: record?.original ?? props.original ?? ""
|
|
54843
|
+
}), pending ? (0, react.createElement)("progress", {
|
|
54844
|
+
"aria-label": statusText,
|
|
54845
|
+
style: {
|
|
54846
|
+
display: "block",
|
|
54847
|
+
width: "100%",
|
|
54848
|
+
height: 4,
|
|
54849
|
+
marginTop: 8,
|
|
54850
|
+
accentColor: require_theme.dshThemeColor.accent
|
|
54851
|
+
}
|
|
54852
|
+
}) : null, pending ? (0, react.createElement)("div", {
|
|
54853
|
+
role: "status",
|
|
54854
|
+
"aria-live": "polite",
|
|
54855
|
+
style: {
|
|
54856
|
+
marginTop: 8,
|
|
54857
|
+
color: require_theme.dshThemeColor.labelSecondary
|
|
54858
|
+
}
|
|
54859
|
+
}, props.translationT("translation.progressHelp")) : props.inputFailure !== void 0 ? null : (0, react.createElement)(DetailBlock, {
|
|
54860
|
+
kind: props.messageRole === "user" ? "sent" : "translated",
|
|
54861
|
+
translationT: props.translationT,
|
|
54862
|
+
value: record.translated
|
|
54863
|
+
}), pending || inputFailure ? null : (0, react.createElement)("div", { style: {
|
|
54864
|
+
marginTop: 8,
|
|
54865
|
+
color: require_theme.dshThemeColor.labelSecondary
|
|
54866
|
+
} }, [
|
|
54867
|
+
`${props.translationT("translation.modelUsed")}: ${alreadyTargetLanguage ? props.translationT("translation.modelNotUsed") : formatModel(record.model, props.translationT)}`,
|
|
54868
|
+
...record.durationMs === void 0 ? [] : [`${(record.durationMs / 1e3).toFixed(2)} s`],
|
|
54869
|
+
...record.totalTokens === void 0 ? [] : [`${record.totalTokens} tok`]
|
|
54870
|
+
].join(" · ")), props.inputFailure === void 0 ? null : (0, react.createElement)("p", { role: "alert" }, props.translationT("translation.inputFailedHelp")), decisionError ? (0, react.createElement)("p", {
|
|
54871
|
+
role: "alert",
|
|
54872
|
+
style: { color: require_theme.dshThemeColor.error }
|
|
54873
|
+
}, props.translationT("translation.decisionFailed")) : null, props.inputFailure !== void 0 ? (0, react.createElement)("div", { style: {
|
|
54874
|
+
display: "flex",
|
|
54875
|
+
flexWrap: "wrap",
|
|
54876
|
+
gap: 8,
|
|
54877
|
+
marginTop: 10
|
|
54878
|
+
} }, ...[
|
|
54879
|
+
"retry",
|
|
54880
|
+
"send",
|
|
54881
|
+
"cancel"
|
|
54882
|
+
].map((choice) => (0, react.createElement)("button", {
|
|
54883
|
+
key: choice,
|
|
54884
|
+
type: "button",
|
|
54885
|
+
disabled: deciding,
|
|
54886
|
+
onClick: () => {
|
|
54887
|
+
decide(choice);
|
|
54888
|
+
},
|
|
54889
|
+
style: recoveryButtonStyle
|
|
54890
|
+
}, props.translationT(choice === "retry" ? "translation.retry" : choice === "send" ? "translation.sendDirectly" : "translation.cancelSending")))) : output.retry === void 0 ? null : (0, react.createElement)("button", {
|
|
54891
|
+
type: "button",
|
|
54892
|
+
disabled: pending,
|
|
54893
|
+
onClick: () => {
|
|
54894
|
+
output.retry?.();
|
|
54895
|
+
},
|
|
54896
|
+
style: {
|
|
54897
|
+
...recoveryButtonStyle,
|
|
54898
|
+
marginTop: 10
|
|
54899
|
+
}
|
|
54900
|
+
}, props.translationT("translation.retry"))) : null;
|
|
54901
|
+
const renderedDetails = details === null ? null : typeof document === "undefined" ? details : (0, import_react_dom.createPortal)(details, document.body);
|
|
54902
|
+
return (0, react.createElement)("div", {
|
|
54903
|
+
ref: rootRef,
|
|
54904
|
+
style: {
|
|
54905
|
+
position: "relative",
|
|
54906
|
+
display: "inline-flex",
|
|
54907
|
+
alignItems: "center",
|
|
54908
|
+
verticalAlign: "middle",
|
|
54909
|
+
...props.inline === true ? { marginInlineStart: 4 } : {}
|
|
54910
|
+
},
|
|
54911
|
+
"data-codingns-translation-action": props.messageId
|
|
54912
|
+
}, (0, react.createElement)("button", {
|
|
54913
|
+
ref: buttonRef,
|
|
54914
|
+
type: "button",
|
|
54915
|
+
title: `${statusText} · ${props.translationT("translation.viewDetails")}`,
|
|
54916
|
+
"aria-label": `${statusText} · ${props.translationT("translation.viewDetails")}`,
|
|
54917
|
+
"aria-expanded": open,
|
|
54918
|
+
"aria-controls": detailsId,
|
|
54919
|
+
onClick: () => setOpen((value) => !value),
|
|
54920
|
+
style: translationButtonStyle
|
|
54921
|
+
}, (0, react.createElement)(TranslationGlyph), (0, react.createElement)("span", {
|
|
54922
|
+
"aria-hidden": true,
|
|
54923
|
+
"data-codingns-translation-pending": pending || void 0,
|
|
54924
|
+
style: {
|
|
54925
|
+
...TRANSLATION_STATUS_BADGE_STYLE,
|
|
54926
|
+
...pending ? TRANSLATION_PENDING_BADGE_STYLE : { background: statusColor }
|
|
54927
|
+
}
|
|
54928
|
+
}, pending ? null : failed ? "!" : "✓")), renderedDetails);
|
|
54929
|
+
}
|
|
54930
|
+
const recoveryButtonStyle = {
|
|
54931
|
+
padding: "5px 10px",
|
|
54932
|
+
borderRadius: 6,
|
|
54933
|
+
border: `1px solid ${require_theme.dshThemeColor.border}`,
|
|
54934
|
+
background: require_theme.dshThemeColor.surfaceSubtle,
|
|
54935
|
+
color: require_theme.dshThemeColor.labelPrimary,
|
|
54936
|
+
cursor: "pointer",
|
|
54937
|
+
font: "inherit"
|
|
54938
|
+
};
|
|
54939
|
+
function PendingTranslationActions(props) {
|
|
54940
|
+
const anchorRef = (0, react.useRef)(null);
|
|
54941
|
+
const [targets, setTargets] = (0, react.useState)([]);
|
|
54942
|
+
const [failures, setFailures] = (0, react.useState)([]);
|
|
54943
|
+
const pollingRef = (0, react.useRef)();
|
|
54944
|
+
const enabled = useCliSessionTranslationEnabled(props.sessionId, props.services.rpc);
|
|
54945
|
+
const store = props.services.settings;
|
|
54946
|
+
const settings = (0, react.useSyncExternalStore)(store.subscribe.bind(store), store.getSnapshot.bind(store), store.getSnapshot.bind(store));
|
|
54947
|
+
const subagent = props.useSession?.((state) => state.subagent);
|
|
54948
|
+
const eligible = enabled && settings.value?.sessionTranslation?.inputEnabled !== false && subagent == null && !props.sessionId?.startsWith("codingns-assistant-");
|
|
54949
|
+
(0, react.useEffect)(() => {
|
|
54950
|
+
setFailures([]);
|
|
54951
|
+
if (!eligible || props.sessionId === void 0) return;
|
|
54952
|
+
const polling = startSerialPolling(async (signal) => {
|
|
54953
|
+
const next = await require_model_catalog_cache.callCliRpc(props.services.rpc, "translation/pending", { sessionId: props.sessionId }, signal);
|
|
54954
|
+
if (!signal.aborted && Array.isArray(next)) setFailures((current) => JSON.stringify(current) === JSON.stringify(next) ? current : next);
|
|
54955
|
+
}, 750);
|
|
54956
|
+
pollingRef.current = polling;
|
|
54957
|
+
return () => {
|
|
54958
|
+
polling.dispose();
|
|
54959
|
+
pollingRef.current = void 0;
|
|
54960
|
+
};
|
|
54961
|
+
}, [
|
|
54962
|
+
eligible,
|
|
54963
|
+
props.sessionId,
|
|
54964
|
+
props.services.rpc
|
|
54965
|
+
]);
|
|
54966
|
+
(0, react.useLayoutEffect)(() => {
|
|
54967
|
+
setTargets([]);
|
|
54968
|
+
if (!eligible || anchorRef.current === null) return void 0;
|
|
54969
|
+
return watchPendingTranslationTargets(anchorRef.current, setTargets);
|
|
54970
|
+
}, [eligible, props.sessionId]);
|
|
54971
|
+
const remaining = [...failures];
|
|
54972
|
+
const actions = targets.map((target) => {
|
|
54973
|
+
const index = remaining.findIndex((failure) => normalizePendingText(failure.record.original) === normalizePendingText(target.original));
|
|
54974
|
+
const failure = index < 0 ? void 0 : remaining.splice(index, 1)[0];
|
|
54975
|
+
return (0, import_react_dom.createPortal)((0, react.createElement)(PendingTranslationAction, {
|
|
54976
|
+
services: props.services,
|
|
54977
|
+
translationT: props.translationT,
|
|
54978
|
+
original: target.original,
|
|
54979
|
+
inputFailure: failure,
|
|
54980
|
+
onDecision: () => {
|
|
54981
|
+
pollingRef.current?.refresh({ afterPending: true });
|
|
54982
|
+
}
|
|
54983
|
+
}), target.container, String(target.key));
|
|
54984
|
+
});
|
|
54985
|
+
return (0, react.createElement)("span", {
|
|
54986
|
+
ref: anchorRef,
|
|
54987
|
+
style: { display: "contents" }
|
|
54988
|
+
}, ...actions, ...remaining.map((failure) => (0, react.createElement)("span", {
|
|
54989
|
+
key: failure.id,
|
|
54990
|
+
style: {
|
|
54991
|
+
display: "inline-flex",
|
|
54992
|
+
alignItems: "center",
|
|
54993
|
+
gap: 8,
|
|
54994
|
+
maxWidth: "100%"
|
|
54995
|
+
}
|
|
54996
|
+
}, (0, react.createElement)("span", { style: {
|
|
54997
|
+
maxWidth: 240,
|
|
54998
|
+
overflow: "hidden",
|
|
54999
|
+
textOverflow: "ellipsis",
|
|
55000
|
+
whiteSpace: "nowrap"
|
|
55001
|
+
} }, failure.record.original), (0, react.createElement)(PendingTranslationAction, {
|
|
55002
|
+
services: props.services,
|
|
55003
|
+
translationT: props.translationT,
|
|
55004
|
+
original: failure.record.original,
|
|
55005
|
+
inputFailure: failure,
|
|
55006
|
+
onDecision: () => {
|
|
55007
|
+
pollingRef.current?.refresh({ afterPending: true });
|
|
55008
|
+
}
|
|
55009
|
+
}))));
|
|
55010
|
+
}
|
|
55011
|
+
function normalizePendingText(value) {
|
|
55012
|
+
return value.replace(/\s+/gu, " ").trim();
|
|
55013
|
+
}
|
|
55014
|
+
function PendingTranslationAction(props) {
|
|
55015
|
+
const id = (0, react.useId)();
|
|
55016
|
+
return (0, react.createElement)(TranslationAction, {
|
|
55017
|
+
...props,
|
|
55018
|
+
messageId: `pending-${id}`,
|
|
55019
|
+
messageRole: "user",
|
|
55020
|
+
popupAlign: "end"
|
|
55021
|
+
});
|
|
55022
|
+
}
|
|
55023
|
+
function TranslationGlyph() {
|
|
55024
|
+
return (0, react.createElement)("svg", {
|
|
55025
|
+
viewBox: "0 0 24 24",
|
|
55026
|
+
width: 16,
|
|
55027
|
+
height: 16,
|
|
55028
|
+
fill: "none",
|
|
55029
|
+
stroke: "currentColor",
|
|
55030
|
+
strokeWidth: 1.5,
|
|
55031
|
+
strokeLinecap: "round",
|
|
55032
|
+
strokeLinejoin: "round",
|
|
55033
|
+
"aria-hidden": true
|
|
55034
|
+
}, ...TRANSLATION_GLYPH_PATHS.map((d) => (0, react.createElement)("path", {
|
|
55035
|
+
key: d,
|
|
55036
|
+
d
|
|
55037
|
+
})));
|
|
55038
|
+
}
|
|
55039
|
+
const messageActionButtonStyle = {
|
|
55040
|
+
position: "relative",
|
|
55041
|
+
display: "inline-flex",
|
|
55042
|
+
alignItems: "center",
|
|
55043
|
+
justifyContent: "center",
|
|
55044
|
+
width: 28,
|
|
55045
|
+
height: 28,
|
|
55046
|
+
padding: 0,
|
|
55047
|
+
border: 0,
|
|
55048
|
+
borderRadius: "var(--dsw-radius-sm, 6px)",
|
|
55049
|
+
color: require_theme.dshThemeColor.labelTertiary,
|
|
55050
|
+
background: "transparent",
|
|
55051
|
+
cursor: "pointer"
|
|
55052
|
+
};
|
|
55053
|
+
const translationButtonStyle = {
|
|
55054
|
+
...messageActionButtonStyle,
|
|
55055
|
+
transition: "background-color 100ms ease, color 100ms ease"
|
|
55056
|
+
};
|
|
55057
|
+
const translationDetailTypes = {
|
|
55058
|
+
original: {
|
|
55059
|
+
labelKey: "translation.originalText",
|
|
55060
|
+
color: require_theme.dshThemeColor.labelSecondary
|
|
55061
|
+
},
|
|
55062
|
+
translated: {
|
|
55063
|
+
labelKey: "translation.translatedText",
|
|
55064
|
+
color: require_theme.dshThemeColor.accent
|
|
55065
|
+
},
|
|
55066
|
+
sent: {
|
|
55067
|
+
labelKey: "translation.actualSentText",
|
|
55068
|
+
color: require_theme.dshThemeColor.success
|
|
55069
|
+
}
|
|
55070
|
+
};
|
|
55071
|
+
function DetailBlock({ kind, translationT, value }) {
|
|
55072
|
+
const { labelKey, color } = translationDetailTypes[kind];
|
|
55073
|
+
return (0, react.createElement)("div", { style: { marginTop: 8 } }, (0, react.createElement)("div", { style: {
|
|
55074
|
+
display: "inline-block",
|
|
55075
|
+
maxWidth: "100%",
|
|
55076
|
+
boxSizing: "border-box",
|
|
55077
|
+
marginBottom: 6,
|
|
55078
|
+
padding: "2px 8px",
|
|
55079
|
+
border: `1px solid color-mix(in srgb, ${color} 30%, transparent)`,
|
|
55080
|
+
borderRadius: "var(--dsw-radius-sm, 6px)",
|
|
55081
|
+
color,
|
|
55082
|
+
background: `color-mix(in srgb, ${color} 12%, transparent)`,
|
|
55083
|
+
fontWeight: 600,
|
|
55084
|
+
overflowWrap: "anywhere"
|
|
55085
|
+
} }, translationT(labelKey)), (0, react.createElement)("pre", { style: {
|
|
55086
|
+
margin: 0,
|
|
55087
|
+
color: `color-mix(in srgb, ${color} 45%, ${require_theme.dshThemeColor.labelPrimary})`,
|
|
55088
|
+
whiteSpace: "pre-wrap",
|
|
55089
|
+
overflowWrap: "anywhere",
|
|
55090
|
+
fontFamily: "inherit"
|
|
55091
|
+
} }, value));
|
|
55092
|
+
}
|
|
55093
|
+
/** 按原生 user 节点的结构渲染用户消息;翻译入口只在确实有记录时追加。 */
|
|
55094
|
+
function UserMessageNodeView(props) {
|
|
55095
|
+
const data = props.node.data;
|
|
55096
|
+
const parts = splitUserContent(data.content);
|
|
55097
|
+
const record = readInputRecord({ source: data.source });
|
|
55098
|
+
const translationRecord = record === void 0 ? void 0 : inputRecordForAction(record);
|
|
55099
|
+
const labels = Array.isArray(data.referenceLabels) ? data.referenceLabels.filter((label) => typeof label === "string") : [];
|
|
55100
|
+
const skillNames = Array.isArray(data.skillNames) ? data.skillNames.filter((name) => typeof name === "string") : [];
|
|
55101
|
+
const showBubble = parts.text !== "" || parts.rest.length > 0;
|
|
55102
|
+
const compactImages = parts.attachments.filter((attachment) => attachment.type === "image").length > 1;
|
|
55103
|
+
const messageId = `user-${String(data.seq ?? props.node.id ?? "message")}`;
|
|
55104
|
+
const chatT = props.t;
|
|
55105
|
+
return (0, react.createElement)("div", {
|
|
55106
|
+
"data-chat-flow-kind": "user",
|
|
55107
|
+
style: {
|
|
55108
|
+
display: "flex",
|
|
55109
|
+
flexDirection: "column",
|
|
55110
|
+
alignItems: "flex-end",
|
|
55111
|
+
gap: 6
|
|
55112
|
+
}
|
|
55113
|
+
}, props.presentation.kind === "factory" ? props.presentation.userContent(props, {
|
|
55114
|
+
text: parts.text,
|
|
55115
|
+
attachments: parts.attachments.map((item) => item.type === "image" ? {
|
|
55116
|
+
type: "image",
|
|
55117
|
+
image: { attachment: item.attachment }
|
|
55118
|
+
} : item),
|
|
55119
|
+
extraBlocks: parts.rest,
|
|
55120
|
+
referenceLabels: labels
|
|
55121
|
+
}, {
|
|
55122
|
+
sessionLabels: labels,
|
|
55123
|
+
skillNames
|
|
55124
|
+
}) : (0, react.createElement)("div", { style: {
|
|
55125
|
+
display: "flex",
|
|
55126
|
+
flexDirection: "column",
|
|
55127
|
+
alignItems: "flex-end",
|
|
55128
|
+
gap: 8,
|
|
55129
|
+
minWidth: 0,
|
|
55130
|
+
maxWidth: "min(calc(var(--dsh-chat-content-width, 748px) * .702), 82%)"
|
|
55131
|
+
} }, parts.attachments.length > 0 ? (0, react.createElement)("div", {
|
|
55132
|
+
"data-message-attachments": true,
|
|
55133
|
+
style: {
|
|
55134
|
+
display: "flex",
|
|
55135
|
+
flexWrap: "wrap",
|
|
55136
|
+
justifyContent: "flex-end",
|
|
55137
|
+
gap: 8,
|
|
55138
|
+
maxWidth: "100%"
|
|
55139
|
+
}
|
|
55140
|
+
}, ...parts.attachments.map((attachment, index) => attachment.type === "image" ? (0, react.createElement)("div", { key: `image-${index}` }, props.presentation.images(props, {
|
|
55141
|
+
images: [{ attachment: attachment.attachment }],
|
|
55142
|
+
align: "end",
|
|
55143
|
+
compact: compactImages
|
|
55144
|
+
})) : createFileAttachment(attachment.file, index))) : null, showBubble ? (0, react.createElement)("div", { style: {
|
|
55145
|
+
boxSizing: "border-box",
|
|
55146
|
+
maxWidth: "100%",
|
|
55147
|
+
padding: "10px 16px",
|
|
55148
|
+
borderRadius: "var(--dsw-radius-xl, 18px)",
|
|
55149
|
+
color: require_theme.dshThemeColor.labelPrimary,
|
|
55150
|
+
background: "var(--dsw-specific-bubble, var(--dsw-alias-interactive-bg-hover, rgba(127,127,127,.08)))",
|
|
55151
|
+
fontSize: "var(--dsh-content-font-size, 14px)",
|
|
55152
|
+
lineHeight: "calc(22px + var(--dsh-content-font-delta, 0px))",
|
|
55153
|
+
whiteSpace: "pre-wrap",
|
|
55154
|
+
wordBreak: "break-word"
|
|
55155
|
+
} }, props.presentation.projectText(parts.text, labels, skillNames, "skill", typeof props.openFile === "function" && typeof props.openSkill === "function" ? {
|
|
55156
|
+
openFile: props.openFile,
|
|
55157
|
+
openSkill: props.openSkill
|
|
55158
|
+
} : void 0), ...parts.rest.map((block, index) => (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.JsonBlock, {
|
|
55159
|
+
key: `extra-${index}`,
|
|
55160
|
+
label: chatT("message.extraBlock"),
|
|
55161
|
+
payload: block,
|
|
55162
|
+
truncatedLabel: (total) => chatT("json.truncated", { total })
|
|
55163
|
+
}))) : null, labels.length === 0 ? null : (0, react.createElement)("div", { style: {
|
|
55164
|
+
color: require_theme.dshThemeColor.labelTertiary,
|
|
55165
|
+
fontSize: "var(--dsh-content-font-size-secondary, 13px)",
|
|
55166
|
+
lineHeight: "calc(18px + var(--dsh-content-font-delta-secondary, 0px))"
|
|
55167
|
+
} }, chatT("message.referenceSummary", { labels: labels.join(chatT("message.referenceSeparator")) }))), (0, react.createElement)("div", { style: {
|
|
55168
|
+
display: "flex",
|
|
55169
|
+
alignItems: "center",
|
|
55170
|
+
alignSelf: "flex-end",
|
|
55171
|
+
height: "calc(28px + var(--dsh-content-font-delta, 0px))",
|
|
55172
|
+
gap: 8,
|
|
55173
|
+
color: require_theme.dshThemeColor.labelTertiary
|
|
55174
|
+
} }, typeof data.time === "number" ? (0, react.createElement)("span", { style: {
|
|
55175
|
+
paddingRight: 12,
|
|
55176
|
+
color: require_theme.dshThemeColor.labelTertiary,
|
|
55177
|
+
fontSize: "var(--dsh-content-font-size-secondary, 13px)",
|
|
55178
|
+
whiteSpace: "nowrap"
|
|
55179
|
+
} }, formatMessageTime(data.time)) : null, translationRecord === void 0 ? null : (0, react.createElement)(TranslationAction, {
|
|
55180
|
+
messageId,
|
|
55181
|
+
messageRole: "user",
|
|
55182
|
+
services: props.services,
|
|
55183
|
+
translationT: props.translationT,
|
|
55184
|
+
popupAlign: "end",
|
|
55185
|
+
record: translationRecord
|
|
55186
|
+
}), (0, react.createElement)(CopyAction, {
|
|
55187
|
+
text: parts.text,
|
|
55188
|
+
t: chatT
|
|
55189
|
+
})));
|
|
55190
|
+
}
|
|
55191
|
+
function createFileAttachment(file, index) {
|
|
55192
|
+
const name = typeof file.name === "string" ? file.name : "";
|
|
55193
|
+
const bytes = typeof file.bytes === "number" ? file.bytes : 0;
|
|
55194
|
+
return (0, react.createElement)("span", {
|
|
55195
|
+
key: `file-${index}`,
|
|
55196
|
+
title: name,
|
|
55197
|
+
style: {
|
|
55198
|
+
display: "inline-flex",
|
|
55199
|
+
alignItems: "center",
|
|
55200
|
+
minWidth: 0,
|
|
55201
|
+
maxWidth: "100%",
|
|
55202
|
+
gap: 8,
|
|
55203
|
+
padding: "8px 10px",
|
|
55204
|
+
border: `1px solid ${require_theme.dshThemeColor.border}`,
|
|
55205
|
+
borderRadius: 8,
|
|
55206
|
+
color: require_theme.dshThemeColor.labelPrimary,
|
|
55207
|
+
background: require_theme.dshThemeColor.surfaceSubtle
|
|
55208
|
+
}
|
|
55209
|
+
}, (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.FileTypeIcon, {
|
|
55210
|
+
path: name,
|
|
55211
|
+
style: { flex: "none" }
|
|
55212
|
+
}), (0, react.createElement)("span", { style: {
|
|
55213
|
+
display: "flex",
|
|
55214
|
+
flexDirection: "column",
|
|
55215
|
+
minWidth: 0,
|
|
55216
|
+
textAlign: "left"
|
|
55217
|
+
} }, (0, react.createElement)("span", { style: {
|
|
55218
|
+
overflow: "hidden",
|
|
55219
|
+
textOverflow: "ellipsis",
|
|
55220
|
+
whiteSpace: "nowrap"
|
|
55221
|
+
} }, name), (0, react.createElement)("span", { style: {
|
|
55222
|
+
color: require_theme.dshThemeColor.labelSecondary,
|
|
55223
|
+
fontSize: 11
|
|
55224
|
+
} }, [(0, _deepseek_ai_dsh_client_ui_primitives.fileExtension)(name).toUpperCase().slice(0, 8), (0, _deepseek_ai_dsh_client_ui_primitives.fileSizeText)(bytes)].filter(Boolean).join(" "))));
|
|
55225
|
+
}
|
|
55226
|
+
function CopyAction({ text, t: chatT }) {
|
|
55227
|
+
const [copied, setCopied] = (0, react.useState)(false);
|
|
55228
|
+
const timer = (0, react.useRef)(void 0);
|
|
55229
|
+
(0, react.useEffect)(() => () => {
|
|
55230
|
+
if (timer.current !== void 0) clearTimeout(timer.current);
|
|
55231
|
+
}, []);
|
|
55232
|
+
return (0, react.createElement)("button", {
|
|
55233
|
+
type: "button",
|
|
55234
|
+
title: copied ? chatT("copied") : chatT("copy"),
|
|
55235
|
+
"aria-label": copied ? chatT("copied") : chatT("copy"),
|
|
55236
|
+
onClick: () => {
|
|
55237
|
+
(0, _deepseek_ai_dsh_client_ui_primitives.writeClipboard)(text).then((success) => {
|
|
55238
|
+
if (!success) return;
|
|
55239
|
+
setCopied(true);
|
|
55240
|
+
if (timer.current !== void 0) clearTimeout(timer.current);
|
|
55241
|
+
timer.current = setTimeout(() => {
|
|
55242
|
+
timer.current = void 0;
|
|
55243
|
+
setCopied(false);
|
|
55244
|
+
}, 1e3);
|
|
55245
|
+
});
|
|
55246
|
+
},
|
|
55247
|
+
style: messageActionButtonStyle
|
|
55248
|
+
}, (0, react.createElement)(copied ? _deepseek_ai_dsh_client_ui_primitives.IconCheckOutlineRegular : _deepseek_ai_dsh_client_ui_primitives.IconCopyOutlineRegular));
|
|
55249
|
+
}
|
|
55250
|
+
function splitUserContent(content) {
|
|
55251
|
+
const text = [];
|
|
55252
|
+
const attachments = [];
|
|
55253
|
+
const rest = [];
|
|
55254
|
+
if (typeof content === "string") return {
|
|
55255
|
+
text: content,
|
|
55256
|
+
attachments,
|
|
55257
|
+
rest
|
|
55258
|
+
};
|
|
55259
|
+
if (!Array.isArray(content)) return {
|
|
55260
|
+
text: "",
|
|
55261
|
+
attachments,
|
|
55262
|
+
rest
|
|
55263
|
+
};
|
|
55264
|
+
for (const value of content) {
|
|
55265
|
+
const block = asRecord(value);
|
|
55266
|
+
if (block?.type === "text" && typeof block.text === "string") text.push(block.text);
|
|
55267
|
+
else if (block?.type === "image" && block.attachment !== void 0) attachments.push({
|
|
55268
|
+
type: "image",
|
|
55269
|
+
attachment: block.attachment
|
|
55270
|
+
});
|
|
55271
|
+
else if (block?.type === "file" && asRecord(block.attachment) !== void 0) attachments.push({
|
|
55272
|
+
type: "file",
|
|
55273
|
+
file: asRecord(block.attachment)
|
|
55274
|
+
});
|
|
55275
|
+
else rest.push(value);
|
|
55276
|
+
}
|
|
55277
|
+
return {
|
|
55278
|
+
text: text.join(""),
|
|
55279
|
+
attachments,
|
|
55280
|
+
rest
|
|
55281
|
+
};
|
|
55282
|
+
}
|
|
55283
|
+
function formatMessageTime(time) {
|
|
55284
|
+
const date = new Date(time);
|
|
55285
|
+
const now = /* @__PURE__ */ new Date();
|
|
55286
|
+
const options = date.getFullYear() === now.getFullYear() && date.getMonth() === now.getMonth() && date.getDate() === now.getDate() ? {
|
|
55287
|
+
hour: "2-digit",
|
|
55288
|
+
minute: "2-digit"
|
|
55289
|
+
} : {
|
|
55290
|
+
...date.getFullYear() === now.getFullYear() ? {} : { year: "numeric" },
|
|
55291
|
+
month: "2-digit",
|
|
55292
|
+
day: "2-digit",
|
|
55293
|
+
hour: "2-digit",
|
|
55294
|
+
minute: "2-digit"
|
|
55295
|
+
};
|
|
55296
|
+
return new Intl.DateTimeFormat(void 0, options).format(date);
|
|
55297
|
+
}
|
|
55298
|
+
/** DSH assistant-step renderer: keep each translation action adjacent to its source block. */
|
|
55299
|
+
function AssistantTranslationNodeView(props) {
|
|
55300
|
+
const data = props.node.data;
|
|
55301
|
+
const blocks = Array.isArray(data.blocks) ? data.blocks : [];
|
|
55302
|
+
const streaming = data.status === "running";
|
|
55303
|
+
const chatT = props.t;
|
|
55304
|
+
const markdownLabels = (0, react.useMemo)(() => createMarkdownLabels(chatT), [chatT]);
|
|
55305
|
+
const pathImages = (0, react.useMemo)(() => ({ resolve: resolveMarkdownImagePath }), []);
|
|
55306
|
+
const renderable = streaming || data.status === "interrupted" || blocks.some((block) => block.kind !== "tool-call");
|
|
55307
|
+
const eventSnapshot = renderable ? readEventSource(props.services, props.sessionId)?.getSnapshot() : void 0;
|
|
55308
|
+
const hasTranslation = renderable && blocks.some((block) => {
|
|
55309
|
+
if (block.kind !== "reasoning" && block.kind !== "text") return false;
|
|
55310
|
+
const outputKind = block.kind === "reasoning" ? "reasoning" : "assistant";
|
|
55311
|
+
const embedded = readRecord(block);
|
|
55312
|
+
if (embedded !== void 0 && (embedded.outputKind === void 0 || embedded.outputKind === outputKind)) return true;
|
|
55313
|
+
return eventSnapshot !== void 0 && findTranslationRecordForText(eventSnapshot, block.text, outputKind, data.turn, data.step) !== void 0;
|
|
55314
|
+
});
|
|
55315
|
+
const turn = props.node.location?.kind === "turn" || props.node.location?.kind === "step" ? props.node.location.turn : void 0;
|
|
55316
|
+
const tail = typeof props.useTurnData === "function" ? props.useTurnData("turn-tail") : void 0;
|
|
55317
|
+
const finalNode = data.finalNode;
|
|
55318
|
+
const fileOwner = turn?.status === "closed" && finalNode !== void 0 && tail?.closing?.finalNode?.seq === finalNode.seq ? {
|
|
55319
|
+
turn,
|
|
55320
|
+
seq: finalNode.seq,
|
|
55321
|
+
openFile: (path) => {
|
|
55322
|
+
props.openFile(path);
|
|
55323
|
+
}
|
|
55324
|
+
} : void 0;
|
|
55325
|
+
const mentions = fileOwner === void 0 || typeof props.fileMentions !== "function" ? void 0 : props.fileMentions(fileOwner);
|
|
55326
|
+
const turnProcess = props.turnProcess;
|
|
55327
|
+
const reasoningHidden = turnProcess !== void 0 && turnProcess.foldable === true && turnProcess.spec?.answerStep === data.step && turnProcess.spec?.inlineReasoning === true && turnProcess.open !== true;
|
|
55328
|
+
const rendered = [];
|
|
55329
|
+
const last = blocks.length - 1;
|
|
55330
|
+
const messageId = `turn-${data.turn}-step-${data.step}`;
|
|
55331
|
+
if (!renderable) return null;
|
|
55332
|
+
for (let index = 0; index < blocks.length; index += 1) {
|
|
55333
|
+
const block = blocks[index];
|
|
55334
|
+
if (block === void 0) continue;
|
|
55335
|
+
if (props.groupPart === "reasoning" && block.kind !== "reasoning") continue;
|
|
55336
|
+
if (props.groupPart === "response" && block.kind === "reasoning") continue;
|
|
55337
|
+
const running = streaming && index === last;
|
|
55338
|
+
if (block.kind === "text") {
|
|
55339
|
+
const translationRecord = readRecord(block) ?? (hasTranslation && eventSnapshot !== void 0 ? findTranslationRecordForText(eventSnapshot, block.text, "assistant", data.turn, data.step) : void 0);
|
|
55340
|
+
rendered.push((0, react.createElement)(AssistantTextContent, {
|
|
55341
|
+
key: `text-${index}`,
|
|
55342
|
+
messageId: `${messageId}-text-${index}`,
|
|
55343
|
+
sessionId: props.sessionId,
|
|
55344
|
+
services: props.services,
|
|
55345
|
+
translationT: props.translationT,
|
|
55346
|
+
text: block.text,
|
|
55347
|
+
streaming,
|
|
55348
|
+
markdownLabels,
|
|
55349
|
+
mentions,
|
|
55350
|
+
pathImages,
|
|
55351
|
+
translationRecord
|
|
55352
|
+
}));
|
|
55353
|
+
continue;
|
|
55354
|
+
}
|
|
55355
|
+
if (block.kind === "reasoning") {
|
|
55356
|
+
const translationRecord = readRecord(block) ?? (hasTranslation && eventSnapshot !== void 0 ? findTranslationRecordForText(eventSnapshot, block.text, "reasoning", data.turn, data.step) : void 0);
|
|
55357
|
+
rendered.push((0, react.createElement)(AssistantReasoningBlock, {
|
|
55358
|
+
key: `reasoning-${index}`,
|
|
55359
|
+
messageId: `${messageId}-reasoning-${index}`,
|
|
55360
|
+
sessionId: props.sessionId,
|
|
55361
|
+
services: props.services,
|
|
55362
|
+
translationT: props.translationT,
|
|
55363
|
+
chatT,
|
|
55364
|
+
text: block.text,
|
|
55365
|
+
...translationRecord === void 0 ? {} : { translationRecord },
|
|
55366
|
+
running,
|
|
55367
|
+
hidden: reasoningHidden,
|
|
55368
|
+
reveal: () => turnProcess?.setOpen?.(true),
|
|
55369
|
+
useGroupAction: props.useGroupAction,
|
|
55370
|
+
renderFactorySlot: props.renderFactorySlot,
|
|
55371
|
+
markdownLabels,
|
|
55372
|
+
pathImages,
|
|
55373
|
+
mentions
|
|
55374
|
+
}));
|
|
55375
|
+
continue;
|
|
55376
|
+
}
|
|
55377
|
+
if (block.kind === "image") {
|
|
55378
|
+
const imageGroup = [block];
|
|
55379
|
+
while (index + 1 < blocks.length && blocks[index + 1]?.kind === "image") {
|
|
55380
|
+
const next = blocks[index + 1];
|
|
55381
|
+
if (next?.kind !== "image") break;
|
|
55382
|
+
imageGroup.push(next);
|
|
55383
|
+
index += 1;
|
|
55384
|
+
}
|
|
55385
|
+
rendered.push((0, react.createElement)("div", {
|
|
55386
|
+
key: `images-${index}`,
|
|
55387
|
+
style: { alignSelf: "flex-start" }
|
|
55388
|
+
}, props.presentation.images(props, {
|
|
55389
|
+
images: imageGroup.map((image) => ({ attachment: image.attachment })),
|
|
55390
|
+
align: "start"
|
|
55391
|
+
})));
|
|
55392
|
+
continue;
|
|
55393
|
+
}
|
|
55394
|
+
if (block.kind === "other") rendered.push((0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.JsonBlock, {
|
|
55395
|
+
key: `other-${index}`,
|
|
55396
|
+
label: chatT("message.unknownBlock"),
|
|
55397
|
+
payload: block.block,
|
|
55398
|
+
truncatedLabel: (total) => chatT("json.truncated", { total })
|
|
55399
|
+
}));
|
|
55400
|
+
}
|
|
55401
|
+
return (0, react.createElement)("div", {
|
|
55402
|
+
"data-streaming": streaming || void 0,
|
|
55403
|
+
style: {
|
|
55404
|
+
display: "flex",
|
|
55405
|
+
flexDirection: "column",
|
|
55406
|
+
gap: 16,
|
|
55407
|
+
minWidth: 0,
|
|
55408
|
+
color: require_theme.dshThemeColor.labelPrimary,
|
|
55409
|
+
fontSize: "var(--dsh-content-font-size, 14px)",
|
|
55410
|
+
lineHeight: "calc(24px + var(--dsh-content-font-delta, 0px))"
|
|
55411
|
+
}
|
|
55412
|
+
}, ...rendered, data.status === "interrupted" ? (0, react.createElement)("span", { style: {
|
|
55413
|
+
alignSelf: "flex-start",
|
|
55414
|
+
padding: "0 6px",
|
|
55415
|
+
borderRadius: "var(--dsw-radius-sm, 4px)",
|
|
55416
|
+
color: require_theme.dshThemeColor.labelTertiary,
|
|
55417
|
+
background: require_theme.dshThemeColor.surfaceSubtle,
|
|
55418
|
+
fontSize: 11,
|
|
55419
|
+
lineHeight: "18px"
|
|
55420
|
+
} }, chatT("message.stopped")) : null);
|
|
55421
|
+
}
|
|
55422
|
+
function AssistantTextContent(props) {
|
|
55423
|
+
const { record } = useOutputTranslation({
|
|
55424
|
+
...props,
|
|
55425
|
+
outputKind: "assistant",
|
|
55426
|
+
record: props.translationRecord
|
|
54864
55427
|
});
|
|
54865
|
-
|
|
54866
|
-
|
|
54867
|
-
|
|
54868
|
-
|
|
54869
|
-
|
|
54870
|
-
|
|
54871
|
-
|
|
54872
|
-
|
|
54873
|
-
|
|
54874
|
-
|
|
55428
|
+
return (0, react.createElement)("div", {
|
|
55429
|
+
"data-codingns-translation-inline": true,
|
|
55430
|
+
style: { minWidth: 0 }
|
|
55431
|
+
}, (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.MarkdownText, {
|
|
55432
|
+
text: record?.translated ?? props.text,
|
|
55433
|
+
streaming: props.streaming,
|
|
55434
|
+
labels: props.markdownLabels,
|
|
55435
|
+
fileMentions: props.mentions,
|
|
55436
|
+
pathImages: props.pathImages
|
|
55437
|
+
}), record === void 0 ? null : (0, react.createElement)(TranslationAction, {
|
|
55438
|
+
messageId: props.messageId,
|
|
55439
|
+
sessionId: props.sessionId,
|
|
55440
|
+
messageRole: "assistant",
|
|
55441
|
+
outputKind: "assistant",
|
|
55442
|
+
services: props.services,
|
|
55443
|
+
translationT: props.translationT,
|
|
55444
|
+
record: props.translationRecord,
|
|
55445
|
+
inline: true
|
|
55446
|
+
}));
|
|
55447
|
+
}
|
|
55448
|
+
function AssistantReasoningBlock(props) {
|
|
55449
|
+
const [expanded, setExpanded] = (0, react.useState)(false);
|
|
55450
|
+
const groupRef = props.useGroupAction?.(props.hidden, props.reveal);
|
|
55451
|
+
const { record } = useOutputTranslation({
|
|
55452
|
+
...props,
|
|
55453
|
+
outputKind: "reasoning",
|
|
55454
|
+
record: props.translationRecord
|
|
54875
55455
|
});
|
|
55456
|
+
const summary = (record?.translated ?? props.text).split("\n").map((line) => line.replace(/[`*_#>]/gu, "").trim()).find(Boolean) ?? "";
|
|
55457
|
+
return (0, react.createElement)("div", {
|
|
55458
|
+
ref: groupRef,
|
|
55459
|
+
hidden: props.hidden,
|
|
55460
|
+
"data-turn-process-inline": props.hidden || void 0
|
|
55461
|
+
}, (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.DisclosureRow, {
|
|
55462
|
+
icon: (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.IconThinkOutlineRegular, { size: 14 }),
|
|
55463
|
+
title: props.chatT("message.think"),
|
|
55464
|
+
open: expanded,
|
|
55465
|
+
expandable: true,
|
|
55466
|
+
expandOnRowClick: true,
|
|
55467
|
+
running: props.running,
|
|
55468
|
+
onToggle: () => setExpanded((value) => !value),
|
|
55469
|
+
collapsedContent: (0, react.createElement)("span", { style: {
|
|
55470
|
+
minWidth: 0,
|
|
55471
|
+
overflow: "hidden",
|
|
55472
|
+
color: require_theme.dshThemeColor.labelSecondary,
|
|
55473
|
+
fontSize: "var(--dsh-content-font-size-secondary, 13px)",
|
|
55474
|
+
textOverflow: "ellipsis",
|
|
55475
|
+
whiteSpace: "nowrap"
|
|
55476
|
+
} }, (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.TextShimmer, {
|
|
55477
|
+
active: props.running,
|
|
55478
|
+
children: summary
|
|
55479
|
+
}))
|
|
55480
|
+
}, expanded ? (0, react.createElement)(AssistantReasoningContent, {
|
|
55481
|
+
messageId: props.messageId,
|
|
55482
|
+
sessionId: props.sessionId,
|
|
55483
|
+
services: props.services,
|
|
55484
|
+
translationT: props.translationT,
|
|
55485
|
+
text: props.text,
|
|
55486
|
+
running: props.running,
|
|
55487
|
+
...props.translationRecord === void 0 ? {} : { translationRecord: props.translationRecord },
|
|
55488
|
+
markdownLabels: props.markdownLabels,
|
|
55489
|
+
pathImages: props.pathImages,
|
|
55490
|
+
mentions: props.mentions,
|
|
55491
|
+
...props.renderFactorySlot === void 0 ? {} : { renderFactorySlot: props.renderFactorySlot }
|
|
55492
|
+
}) : null));
|
|
54876
55493
|
}
|
|
54877
55494
|
/**
|
|
54878
|
-
*
|
|
55495
|
+
* 思考块展开后的正文。
|
|
54879
55496
|
*
|
|
54880
|
-
*
|
|
54881
|
-
*
|
|
54882
|
-
*
|
|
54883
|
-
*
|
|
54884
|
-
*
|
|
55497
|
+
* DSH 原生 `ReasoningRow` 直接渲染 `MarkdownText`,运行时**没有**注册
|
|
55498
|
+
* `conversation.chat.reasoning.content` 工厂(`conversation.chat.*` 只有
|
|
55499
|
+
* `node` / `assistant-actions` / `commandview` / `turnTail`)。而 `renderFactorySlot`
|
|
55500
|
+
* 在工厂缺失时只渲染 `fallback`,缺省为 `null`——此前这里既不传 fallback,
|
|
55501
|
+
* 又把正文完全交给该工厂,于是展开思考后只剩翻译入口,译文一行都看不到。
|
|
55502
|
+
* 因此原生 MarkdownText 必须作为 fallback 传进去:没有工厂时按原生方式渲染,
|
|
55503
|
+
* 工厂存在时才允许表现层覆盖。
|
|
54885
55504
|
*/
|
|
54886
|
-
function
|
|
54887
|
-
const
|
|
54888
|
-
|
|
54889
|
-
|
|
54890
|
-
|
|
54891
|
-
|
|
55505
|
+
function AssistantReasoningContent(props) {
|
|
55506
|
+
const { record } = useOutputTranslation({
|
|
55507
|
+
...props,
|
|
55508
|
+
outputKind: "reasoning",
|
|
55509
|
+
record: props.translationRecord
|
|
55510
|
+
});
|
|
55511
|
+
const displayText = record?.translated ?? props.text;
|
|
55512
|
+
const markdown = (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.MarkdownText, {
|
|
55513
|
+
text: displayText,
|
|
55514
|
+
streaming: props.running,
|
|
55515
|
+
labels: props.markdownLabels,
|
|
55516
|
+
fileMentions: props.mentions,
|
|
55517
|
+
pathImages: props.pathImages,
|
|
55518
|
+
variant: "compact"
|
|
55519
|
+
});
|
|
55520
|
+
const content = props.renderFactorySlot === void 0 ? markdown : props.renderFactorySlot("conversation.chat.reasoning.content", {
|
|
55521
|
+
text: displayText,
|
|
55522
|
+
running: props.running
|
|
55523
|
+
}, { fallback: markdown });
|
|
55524
|
+
return (0, react.createElement)("div", {
|
|
55525
|
+
"data-codingns-translation-inline": true,
|
|
55526
|
+
style: { paddingTop: 8 }
|
|
55527
|
+
}, content, props.translationRecord === void 0 ? null : (0, react.createElement)(TranslationAction, {
|
|
55528
|
+
messageId: props.messageId,
|
|
55529
|
+
sessionId: props.sessionId,
|
|
55530
|
+
outputKind: "reasoning",
|
|
55531
|
+
messageRole: "assistant",
|
|
55532
|
+
services: props.services,
|
|
55533
|
+
translationT: props.translationT,
|
|
55534
|
+
record: props.translationRecord,
|
|
55535
|
+
inline: true
|
|
55536
|
+
}));
|
|
54892
55537
|
}
|
|
54893
|
-
|
|
54894
|
-
|
|
54895
|
-
|
|
54896
|
-
|
|
54897
|
-
|
|
54898
|
-
|
|
54899
|
-
|
|
54900
|
-
|
|
54901
|
-
|
|
55538
|
+
function createMarkdownLabels(chatT) {
|
|
55539
|
+
return {
|
|
55540
|
+
code: {
|
|
55541
|
+
copyLabel: chatT("copy"),
|
|
55542
|
+
copiedLabel: chatT("copied"),
|
|
55543
|
+
toolbarLabels: {
|
|
55544
|
+
codeLabel: chatT("codeBlock.title"),
|
|
55545
|
+
wrapLabel: chatT("codeBlock.wrap"),
|
|
55546
|
+
unwrapLabel: chatT("codeBlock.unwrap")
|
|
55547
|
+
}
|
|
55548
|
+
},
|
|
55549
|
+
footnotes: chatT("markdown.footnotes")
|
|
55550
|
+
};
|
|
54902
55551
|
}
|
|
54903
|
-
|
|
54904
|
-
|
|
54905
|
-
|
|
55552
|
+
function resolveMarkdownImagePath(value) {
|
|
55553
|
+
if (typeof document === "undefined" || !value.startsWith("/") || /^[/\\]{2}/u.test(value) || /[\u0000-\u001f\u007f]/u.test(value)) return void 0;
|
|
55554
|
+
const base = document.baseURI;
|
|
55555
|
+
if (!/^https?:/u.test(base) && !base.startsWith("dsh-app://app/")) return void 0;
|
|
54906
55556
|
try {
|
|
54907
|
-
return
|
|
55557
|
+
return new URL(`api/file?path=${encodeURIComponent(value)}`, base).href;
|
|
54908
55558
|
} catch {
|
|
54909
55559
|
return;
|
|
54910
55560
|
}
|
|
54911
55561
|
}
|
|
54912
|
-
function hasMethods(value, methods) {
|
|
54913
|
-
return typeof value === "object" && value !== null && methods.every((method) => typeof Reflect.get(value, method) === "function");
|
|
54914
|
-
}
|
|
54915
|
-
function hasAny(value, keys) {
|
|
54916
|
-
return typeof value === "object" && value !== null && keys.some((key) => Reflect.get(value, key) !== void 0);
|
|
54917
|
-
}
|
|
54918
|
-
/** PeerHost Host 能力只接受显式注入的适配器,避免把普通 DSH 服务误报为已实现。 */
|
|
54919
|
-
function addPeerHostHostRoutes(add) {
|
|
54920
|
-
addPeerHostRoute(add, "peer-host.store", "peer-host-store", "peerHostStore");
|
|
54921
|
-
addPeerHostRoute(add, "peer-host.handshake", "peer-host-handshake", "peerHostHandshake");
|
|
54922
|
-
addPeerHostRoute(add, "peer-host.http-proxy", "peer-host-http-proxy", "peerHostHttpProxy");
|
|
54923
|
-
addPeerHostRoute(add, "peer-host.ws-proxy", "peer-host-ws-proxy", "peerHostWsProxy");
|
|
54924
|
-
addPeerHostRoute(add, "peer-host.aggregate", "peer-host-aggregate", "peerHostAggregate");
|
|
54925
|
-
addPeerHostRoute(add, "peer-host.aggregated-transport", "peer-host-aggregated-transport", "peerHostAggregatedTransport");
|
|
54926
|
-
addPeerHostRoute(add, "peer-host.target-capabilities", "peer-host-target-capabilities", "peerHostTargetCapabilities");
|
|
54927
|
-
addPeerHostRoute(add, "peer-host.local-plugin-baseline", "peer-host-local-plugin-baseline", "peerHostLocalPluginBaseline");
|
|
54928
|
-
addPeerHostRoute(add, "peer-host.relay-route", "peer-host-relay-route", "peerHostRelayRoute");
|
|
54929
|
-
addPeerHostRoute(add, "peer-host.store", "peer-host-store-020", "peerHostStore", require_native_workspace_store.DSH_COMPATIBILITY, "supported", 30);
|
|
54930
|
-
addPeerHostRoute(add, "peer-host.handshake", "peer-host-handshake-020", "peerHostHandshake", require_native_workspace_store.DSH_COMPATIBILITY, "supported", 30);
|
|
54931
|
-
addPeerHostRoute(add, "peer-host.http-proxy", "peer-host-http-proxy-020", "peerHostHttpProxy", require_native_workspace_store.DSH_COMPATIBILITY, "supported", 30);
|
|
54932
|
-
addPeerHostRoute(add, "peer-host.ws-proxy", "peer-host-ws-proxy-020", "peerHostWsProxy", require_native_workspace_store.DSH_COMPATIBILITY, "supported", 30);
|
|
54933
|
-
addPeerHostRoute(add, "peer-host.aggregate", "peer-host-aggregate-020", "peerHostAggregate", require_native_workspace_store.DSH_COMPATIBILITY, "supported", 30);
|
|
54934
|
-
addPeerHostRoute(add, "peer-host.aggregated-transport", "peer-host-aggregated-transport-020", "peerHostAggregatedTransport", require_native_workspace_store.DSH_COMPATIBILITY, "supported", 30);
|
|
54935
|
-
addPeerHostRoute(add, "peer-host.target-capabilities", "peer-host-target-capabilities-020", "peerHostTargetCapabilities", require_native_workspace_store.DSH_COMPATIBILITY, "supported", 30);
|
|
54936
|
-
addPeerHostRoute(add, "peer-host.local-plugin-baseline", "peer-host-local-plugin-baseline-020", "peerHostLocalPluginBaseline", require_native_workspace_store.DSH_COMPATIBILITY, "supported", 30);
|
|
54937
|
-
addPeerHostRoute(add, "peer-host.relay-route", "peer-host-relay-route-020", "peerHostRelayRoute", require_native_workspace_store.DSH_COMPATIBILITY, "supported", 30);
|
|
54938
|
-
}
|
|
54939
55562
|
/**
|
|
54940
|
-
*
|
|
54941
|
-
*
|
|
54942
|
-
* `peer-host.client-preboot-transport` 表示"页面在 DSH Connection 之前已可被聚合
|
|
54943
|
-
* Transport 包装"。它不再等待官方 Provider 适配器,而是由插件自带的启动页 shim
|
|
54944
|
-
* 提供:Web 与 Desktop 都注入同一个 shim,Desktop 用访问器接管运行时赋值。探测
|
|
54945
|
-
* 只读 shim 状态,`external`(Transport 形状未知)时判为不可用,由 Feature 按
|
|
54946
|
-
* "能力缺失只影响该模块"停用 PeerHost,而不是提示用户刷新。
|
|
55563
|
+
* 注册两个有实际翻译记录的消息渲染器;DSH 的用户气泡内容仍由统一主题令牌控制。
|
|
54947
55564
|
*/
|
|
54948
|
-
function
|
|
54949
|
-
|
|
54950
|
-
|
|
54951
|
-
|
|
54952
|
-
|
|
54953
|
-
|
|
54954
|
-
|
|
54955
|
-
|
|
54956
|
-
|
|
54957
|
-
|
|
54958
|
-
|
|
54959
|
-
|
|
54960
|
-
|
|
54961
|
-
|
|
54962
|
-
|
|
54963
|
-
|
|
55565
|
+
function registerSessionTranslationChatUi(services, facts = { primitives: _deepseek_ai_dsh_client_ui_primitives }) {
|
|
55566
|
+
const resolution = createDshCapabilityRegistry(services.dshVersion, "client", services, facts).getProfile(services).capabilities.get("conversation.message-presentation");
|
|
55567
|
+
const slots = services.slots;
|
|
55568
|
+
if (slots?.inject === void 0 || slots.register === void 0) return () => void 0;
|
|
55569
|
+
const removeStyles = installSessionTranslationChatStyles();
|
|
55570
|
+
const translationT = services.locale.bind("codingns");
|
|
55571
|
+
const removePendingActions = slots.inject("conversation.input.left", () => slots.register({
|
|
55572
|
+
name: "conversation.input.left",
|
|
55573
|
+
id: "codingns-translation-pending",
|
|
55574
|
+
inject: (sessionId) => ({
|
|
55575
|
+
services,
|
|
55576
|
+
sessionId,
|
|
55577
|
+
translationT
|
|
55578
|
+
})
|
|
55579
|
+
}, PendingTranslationActions));
|
|
55580
|
+
if (resolution?.status !== "ready") return () => {
|
|
55581
|
+
clearOutputTranslationRetries(services);
|
|
55582
|
+
removePendingActions();
|
|
55583
|
+
removeStyles();
|
|
55584
|
+
};
|
|
55585
|
+
const presentation = resolution.value;
|
|
55586
|
+
const removeRenderers = presentation.mount(() => {
|
|
55587
|
+
const removeUserRenderer = slots.inject("conversation.chat.node", () => slots.register({
|
|
55588
|
+
name: "conversation.chat.node",
|
|
55589
|
+
key: "user",
|
|
55590
|
+
priority: -100,
|
|
55591
|
+
locale: "chat",
|
|
55592
|
+
inject: (sessionId) => ({
|
|
55593
|
+
services,
|
|
55594
|
+
sessionId,
|
|
55595
|
+
translationT
|
|
55596
|
+
})
|
|
55597
|
+
}, (props) => UserMessageNodeView({
|
|
55598
|
+
...props,
|
|
55599
|
+
presentation
|
|
55600
|
+
})));
|
|
55601
|
+
let removeAssistantRenderer;
|
|
55602
|
+
try {
|
|
55603
|
+
removeAssistantRenderer = slots.inject("conversation.chat.node", () => slots.register({
|
|
55604
|
+
name: "conversation.chat.node",
|
|
55605
|
+
key: "assistant-step",
|
|
55606
|
+
priority: -100,
|
|
55607
|
+
locale: "chat",
|
|
55608
|
+
inject: (sessionId) => ({
|
|
55609
|
+
services,
|
|
55610
|
+
sessionId,
|
|
55611
|
+
translationT
|
|
55612
|
+
})
|
|
55613
|
+
}, (props) => AssistantTranslationNodeView({
|
|
55614
|
+
...props,
|
|
55615
|
+
presentation
|
|
55616
|
+
})));
|
|
55617
|
+
} catch (error) {
|
|
55618
|
+
removeUserRenderer();
|
|
55619
|
+
throw error;
|
|
55620
|
+
}
|
|
55621
|
+
return () => {
|
|
55622
|
+
removeAssistantRenderer();
|
|
55623
|
+
removeUserRenderer();
|
|
55624
|
+
};
|
|
54964
55625
|
});
|
|
55626
|
+
return () => {
|
|
55627
|
+
clearOutputTranslationRetries(services);
|
|
55628
|
+
removePendingActions();
|
|
55629
|
+
removeRenderers();
|
|
55630
|
+
removeStyles();
|
|
55631
|
+
};
|
|
54965
55632
|
}
|
|
54966
|
-
|
|
54967
|
-
|
|
54968
|
-
|
|
54969
|
-
|
|
54970
|
-
|
|
54971
|
-
|
|
54972
|
-
|
|
54973
|
-
|
|
54974
|
-
|
|
54975
|
-
|
|
55633
|
+
function installSessionTranslationChatStyles() {
|
|
55634
|
+
if (typeof document === "undefined") return () => void 0;
|
|
55635
|
+
const styleId = "codingns-session-translation-chat";
|
|
55636
|
+
if (document.head.querySelector(`style[data-plugin-css="${styleId}"]`) !== null) return () => void 0;
|
|
55637
|
+
const style = document.createElement("style");
|
|
55638
|
+
style.dataset.plugin = "codingns4dsh";
|
|
55639
|
+
style.dataset.pluginCss = styleId;
|
|
55640
|
+
style.textContent = `
|
|
55641
|
+
@keyframes codingns-translation-spin{to{transform:rotate(360deg)}}
|
|
55642
|
+
[data-codingns-translation-pending]{animation:codingns-translation-spin .8s linear infinite}
|
|
55643
|
+
@media(prefers-reduced-motion:reduce){[data-codingns-translation-pending]{animation-duration:1.6s}}
|
|
55644
|
+
[data-codingns-translation-inline] > div:not([data-codingns-translation-action]){display:contents}
|
|
55645
|
+
[data-codingns-translation-inline] > div:not([data-codingns-translation-action]) > p:last-child{display:inline;margin:0}
|
|
55646
|
+
`;
|
|
55647
|
+
document.head.appendChild(style);
|
|
55648
|
+
return () => style.remove();
|
|
54976
55649
|
}
|
|
54977
|
-
function
|
|
54978
|
-
const
|
|
54979
|
-
if (shim === void 0) return "not-installed";
|
|
55650
|
+
function readEventSource(services, sessionId) {
|
|
55651
|
+
const sessions = services.sessions;
|
|
54980
55652
|
try {
|
|
54981
|
-
return
|
|
55653
|
+
return sessions?.binding?.(sessionId)?.eventSource;
|
|
54982
55654
|
} catch {
|
|
54983
|
-
return
|
|
55655
|
+
return;
|
|
54984
55656
|
}
|
|
54985
55657
|
}
|
|
54986
|
-
function
|
|
54987
|
-
|
|
54988
|
-
|
|
54989
|
-
|
|
55658
|
+
function findTranslationRecordForText(snapshot, text, outputKind, turn, step) {
|
|
55659
|
+
const entries = snapshot.entries ?? [];
|
|
55660
|
+
for (let index = entries.length - 1; index >= 0; index -= 1) {
|
|
55661
|
+
const event = readEntryEvent(entries[index]);
|
|
55662
|
+
if (event === void 0 || !event.type.startsWith("assistant/")) continue;
|
|
55663
|
+
const eventData = asRecord(event.data);
|
|
55664
|
+
if (turn !== void 0 && typeof eventData?.turn === "number" && eventData.turn !== turn) continue;
|
|
55665
|
+
if (step !== void 0 && typeof eventData?.step === "number" && eventData.step !== step) continue;
|
|
55666
|
+
const candidates = [];
|
|
55667
|
+
collectRecordCandidates(event.data, candidates, /* @__PURE__ */ new Set());
|
|
55668
|
+
for (const candidate of candidates) {
|
|
55669
|
+
const record = readRecord(candidate);
|
|
55670
|
+
if (record === void 0 || record.original !== text && record.translated !== text) continue;
|
|
55671
|
+
if (outputKind !== void 0 && record.outputKind !== void 0 && record.outputKind !== outputKind) continue;
|
|
55672
|
+
return record;
|
|
55673
|
+
}
|
|
55674
|
+
}
|
|
55675
|
+
}
|
|
55676
|
+
function collectRecordCandidates(value, candidates, seen, depth = 0) {
|
|
55677
|
+
if (Array.isArray(value)) {
|
|
55678
|
+
for (const item of value) collectRecordCandidates(item, candidates, seen, depth + 1);
|
|
54990
55679
|
return;
|
|
54991
55680
|
}
|
|
55681
|
+
const record = asRecord(value);
|
|
55682
|
+
if (record === void 0 || seen.has(record) || depth > 7) return;
|
|
55683
|
+
seen.add(record);
|
|
55684
|
+
if (readRecord(record) !== void 0 || asRecord(record.codingnsTranslation) !== void 0) candidates.push(record);
|
|
55685
|
+
for (const key of [
|
|
55686
|
+
"codingnsTranslation",
|
|
55687
|
+
"source",
|
|
55688
|
+
"message",
|
|
55689
|
+
"content",
|
|
55690
|
+
"stream",
|
|
55691
|
+
"chunk",
|
|
55692
|
+
"block",
|
|
55693
|
+
"data"
|
|
55694
|
+
]) if (record[key] !== void 0) collectRecordCandidates(record[key], candidates, seen, depth + 1);
|
|
54992
55695
|
}
|
|
54993
|
-
function
|
|
54994
|
-
|
|
54995
|
-
|
|
54996
|
-
capability,
|
|
54997
|
-
supportedDsh,
|
|
54998
|
-
runtime: capability === "peer-host.native-navigation" || capability === "peer-host.remote-web-context-fallback" || capability === "peer-host.client-preboot-transport" ? "client" : "host",
|
|
54999
|
-
priority,
|
|
55000
|
-
status,
|
|
55001
|
-
introducedIn: "0.1.5-rc.3",
|
|
55002
|
-
detect: (context) => readPeerHostAdapter(context, field) !== void 0,
|
|
55003
|
-
create: (context) => readPeerHostAdapter(context, field)
|
|
55004
|
-
});
|
|
55696
|
+
function readEntryEvent(value) {
|
|
55697
|
+
const record = asRecord(value);
|
|
55698
|
+
return asRecord(record?.event) ?? (typeof record?.type === "string" ? record : void 0);
|
|
55005
55699
|
}
|
|
55006
|
-
function
|
|
55007
|
-
|
|
55008
|
-
|
|
55700
|
+
function readRecord(value) {
|
|
55701
|
+
const record = asRecord(value);
|
|
55702
|
+
const candidate = asRecord(record?.codingnsTranslation) ?? record;
|
|
55703
|
+
if (candidate?.original === void 0 || candidate.translated === void 0) return void 0;
|
|
55704
|
+
if (typeof candidate.original !== "string" || typeof candidate.translated !== "string") return void 0;
|
|
55705
|
+
const targetLanguage = readLanguage(candidate.targetLanguage);
|
|
55706
|
+
if (targetLanguage === void 0) return void 0;
|
|
55707
|
+
const model = readModel(candidate.model);
|
|
55708
|
+
const outputKind = candidate.outputKind === "assistant" || candidate.outputKind === "reasoning" ? candidate.outputKind : void 0;
|
|
55709
|
+
return {
|
|
55710
|
+
original: candidate.original,
|
|
55711
|
+
translated: candidate.translated,
|
|
55712
|
+
...candidate.sourceLanguage === "zh" || candidate.sourceLanguage === "en" || candidate.sourceLanguage === "fr" || candidate.sourceLanguage === "de" || candidate.sourceLanguage === "ja" ? { sourceLanguage: candidate.sourceLanguage } : {},
|
|
55713
|
+
targetLanguage,
|
|
55714
|
+
bilingual: candidate.bilingual === true,
|
|
55715
|
+
...outputKind === void 0 ? {} : { outputKind },
|
|
55716
|
+
...candidate.alreadyTargetLanguage === true ? { alreadyTargetLanguage: true } : {},
|
|
55717
|
+
...model === void 0 ? {} : { model },
|
|
55718
|
+
...candidate.failed === true ? { failed: true } : {},
|
|
55719
|
+
...require_session_translation.readSessionTranslationMetrics(candidate)
|
|
55720
|
+
};
|
|
55721
|
+
}
|
|
55722
|
+
function readModel(value) {
|
|
55723
|
+
const record = asRecord(value);
|
|
55724
|
+
if (typeof record?.provider !== "string" || typeof record.model !== "string" || record.provider.trim() === "" || record.model.trim() === "") return void 0;
|
|
55725
|
+
return {
|
|
55726
|
+
provider: record.provider,
|
|
55727
|
+
model: record.model
|
|
55728
|
+
};
|
|
55729
|
+
}
|
|
55730
|
+
function readInputRecord(value) {
|
|
55731
|
+
const candidate = asRecord(asRecord(asRecord(value)?.source)?.codingnsTranslationInput);
|
|
55732
|
+
if (candidate?.original === void 0 || candidate.translated === void 0) return void 0;
|
|
55733
|
+
if (typeof candidate.original !== "string" || typeof candidate.translated !== "string") return void 0;
|
|
55734
|
+
const targetLanguage = readLanguage(candidate.targetLanguage);
|
|
55735
|
+
if (targetLanguage === void 0) return void 0;
|
|
55736
|
+
const model = readModel(candidate.model);
|
|
55737
|
+
return {
|
|
55738
|
+
original: candidate.original,
|
|
55739
|
+
translated: candidate.translated,
|
|
55740
|
+
...candidate.sourceLanguage === "zh" || candidate.sourceLanguage === "en" || candidate.sourceLanguage === "fr" || candidate.sourceLanguage === "de" || candidate.sourceLanguage === "ja" ? { sourceLanguage: candidate.sourceLanguage } : {},
|
|
55741
|
+
targetLanguage,
|
|
55742
|
+
...candidate.alreadyTargetLanguage === true ? { alreadyTargetLanguage: true } : {},
|
|
55743
|
+
...model === void 0 ? {} : { model },
|
|
55744
|
+
...candidate.failed === true ? { failed: true } : {},
|
|
55745
|
+
...require_session_translation.readSessionTranslationMetrics(candidate)
|
|
55746
|
+
};
|
|
55747
|
+
}
|
|
55748
|
+
function inputRecordForAction(record) {
|
|
55749
|
+
return {
|
|
55750
|
+
original: record.original,
|
|
55751
|
+
translated: record.translated,
|
|
55752
|
+
...record.sourceLanguage === void 0 ? {} : { sourceLanguage: record.sourceLanguage },
|
|
55753
|
+
targetLanguage: record.targetLanguage,
|
|
55754
|
+
bilingual: false,
|
|
55755
|
+
...record.alreadyTargetLanguage === true ? { alreadyTargetLanguage: true } : {},
|
|
55756
|
+
...record.model === void 0 ? {} : { model: record.model },
|
|
55757
|
+
...record.failed === true ? { failed: true } : {},
|
|
55758
|
+
...require_session_translation.readSessionTranslationMetrics(record)
|
|
55759
|
+
};
|
|
55760
|
+
}
|
|
55761
|
+
function readLanguage(value) {
|
|
55762
|
+
return value === "zh" || value === "en" || value === "fr" || value === "de" || value === "ja" ? value : void 0;
|
|
55763
|
+
}
|
|
55764
|
+
function formatModel(model, t) {
|
|
55765
|
+
return model === void 0 ? t("translation.modelUnknown") : `${model.provider} / ${model.model}`;
|
|
55766
|
+
}
|
|
55767
|
+
function safeDomId(value) {
|
|
55768
|
+
return encodeURIComponent(value).replace(/%/gu, "-");
|
|
55769
|
+
}
|
|
55770
|
+
function asRecord(value) {
|
|
55771
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
|
|
55009
55772
|
}
|
|
55010
55773
|
//#endregion
|
|
55011
55774
|
//#region src/dsh-capabilities/client/interaction-text-dom.ts
|
|
@@ -55417,6 +56180,10 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
55417
56180
|
capability: "conversation.interaction-translation",
|
|
55418
56181
|
required: false,
|
|
55419
56182
|
fallback: "degrade"
|
|
56183
|
+
}, {
|
|
56184
|
+
capability: "conversation.message-presentation",
|
|
56185
|
+
required: false,
|
|
56186
|
+
fallback: "degrade"
|
|
55420
56187
|
}],
|
|
55421
56188
|
ui: {
|
|
55422
56189
|
label: "Session translation",
|
|
@@ -55538,6 +56305,15 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
55538
56305
|
translationModels: models,
|
|
55539
56306
|
translationModel: void 0
|
|
55540
56307
|
})
|
|
56308
|
+
}), (0, react.createElement)("div", { style: {
|
|
56309
|
+
...require_theme.dshSettingsSectionHeaderStyle,
|
|
56310
|
+
marginTop: 12
|
|
56311
|
+
} }, (0, react.createElement)("span", { style: require_theme.dshSettingsFieldLabelStyle }, t("translation.rulesTitle"))), (0, react.createElement)(SessionTranslationRules, {
|
|
56312
|
+
rules: value.translationRules ?? [],
|
|
56313
|
+
disabled,
|
|
56314
|
+
pending: saving,
|
|
56315
|
+
t,
|
|
56316
|
+
onChange: (rules) => save({ translationRules: rules })
|
|
55541
56317
|
}));
|
|
55542
56318
|
}
|
|
55543
56319
|
function Field({ label, children }) {
|
|
@@ -56125,7 +56901,7 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
56125
56901
|
marginLeft: "auto"
|
|
56126
56902
|
},
|
|
56127
56903
|
onClick: (event) => event.stopPropagation()
|
|
56128
|
-
}, (0, react.createElement)(
|
|
56904
|
+
}, (0, react.createElement)(require_react_dom$1.SettingsSwitch, {
|
|
56129
56905
|
variant: "module",
|
|
56130
56906
|
"aria-label": label,
|
|
56131
56907
|
checked,
|
|
@@ -56280,7 +57056,7 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
56280
57056
|
return value === void 0 ? void 0 : (({ cliSessions: _cliSessions, ...clientValue }) => clientValue)(value);
|
|
56281
57057
|
}
|
|
56282
57058
|
//#endregion
|
|
56283
|
-
//#region node_modules/.pnpm/@deepseek-ai+cosmokit@1.8.
|
|
57059
|
+
//#region node_modules/.pnpm/@deepseek-ai+cosmokit@1.8.6-alpha.2/node_modules/@deepseek-ai/cosmokit/lib/index.js
|
|
56284
57060
|
/** Return true when a value is `null` or `undefined`. */
|
|
56285
57061
|
function isNullable(value) {
|
|
56286
57062
|
return value === null || value === void 0;
|
|
@@ -56449,7 +57225,7 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
56449
57225
|
Time.template = template;
|
|
56450
57226
|
})(Time || (Time = {}));
|
|
56451
57227
|
//#endregion
|
|
56452
|
-
//#region node_modules/.pnpm/@deepseek-ai+cordis@4.0.
|
|
57228
|
+
//#region node_modules/.pnpm/@deepseek-ai+cordis@4.0.5-alpha.2_@deepseek-ai+cordis-plugin-include@1.0.10-alpha.2_@de_d750ba50d5bee7081316b89f08b32afa/node_modules/@deepseek-ai/cordis/lib/index.js
|
|
56453
57229
|
/** Ordered collection of disposable values with O(1) deletion by value. */
|
|
56454
57230
|
var DisposableList = class {
|
|
56455
57231
|
sn = 0;
|
|
@@ -61821,12 +62597,21 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
61821
62597
|
function isInjectedStage0Runtime(scope = globalThis) {
|
|
61822
62598
|
return scope[CODINGNS_STAGE0_GLOBAL] === true;
|
|
61823
62599
|
}
|
|
61824
|
-
route("session.
|
|
62600
|
+
route("session.prompt-assembly", "session-prompt-assembly-021", "host", ">=0.2.1-alpha.3 <=0.2.1-alpha.3", "supported", [
|
|
62601
|
+
"dsh-capabilities/host/session-prompt-adapter.ts",
|
|
62602
|
+
"host/features/session-prompt-translation.ts",
|
|
62603
|
+
"host/cli-adapters/feature.ts"
|
|
62604
|
+
]), route("session.external-model-selection", "session-external-model-selection-021", "host", ">=0.2.1-alpha.3 <=0.2.1-alpha.3", "supported", ["dsh-capabilities/host/session-model-selection-adapter.ts", "host/cli-adapters/feature.ts"]), route("session.activation", "session-activation-020", "host", ">=0.2.0-rc.2 <=0.2.1-alpha.2", "supported", ["dsh-capabilities/host/session-activation-adapter.ts", "host/native-session-bridge.ts"]), route("session.activation", "session-activation-021", "host", ">=0.2.1-alpha.3 <=0.2.1-alpha.3", "supported", ["dsh-capabilities/host/session-activation-adapter.ts", "host/native-session-bridge.ts"]), route("conversation.message-presentation", "message-presentation-020", "client", ">=0.2.0-rc.2 <=0.2.1-alpha.2", "supported", ["dsh-capabilities/client/message-presentation-adapter.ts", "client/session-translation-chat.ts"]), route("conversation.message-presentation", "message-presentation-021", "client", ">=0.2.1-alpha.3 <=0.2.1-alpha.3", "supported", ["dsh-capabilities/client/message-presentation-adapter.ts", "client/session-translation-chat.ts"]), route("connection.peer", "connection.peer-021", "host", ">=0.2.1-alpha.3 <=0.2.1-alpha.3", "supported", [
|
|
62605
|
+
"dsh-capabilities/host/connection-peer-adapter.ts",
|
|
62606
|
+
"host/rpc.ts",
|
|
62607
|
+
"host/features/global-voice-rpc.ts",
|
|
62608
|
+
"host/modules/peer-host/peer-host-native-dispatch.ts"
|
|
62609
|
+
]), route("connection.uplink", "connection.uplink-021", "host", ">=0.2.1-alpha.3 <=0.2.1-alpha.3", "supported", ["dsh-capabilities/host/native-dispatch-adapter.ts", "host/modules/peer-host/peer-host-native-dispatch.ts"]), route("session.title", "session-title-020", "host", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["dsh-capabilities/host/session-title-adapter.ts", "host/features/session-title-optimization.ts"]), route("session.working-directory", "session-working-directory-021", "host", ">=0.2.1-alpha.2", "supported", ["host/terminal/terminal-controller.ts", "host/index.ts"]), route("llm.text", "llm-text-021", "host", require_native_workspace_store.DSH_COMPATIBILITY, "supported", [
|
|
61825
62610
|
"dsh-capabilities/host/assistant-llm-adapter.ts",
|
|
61826
62611
|
"host/features/assistant-text-chat.ts",
|
|
61827
62612
|
"dsh-capabilities/host/session-title-adapter.ts",
|
|
61828
62613
|
"host/features/session-title-optimization.ts"
|
|
61829
|
-
]), route("assistant.agent", "assistant-agent-021", "host", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["dsh-capabilities/host/assistant-agent-adapter.ts", "host/features/global-voice-rpc.ts"]), route("settings.store", "legacy-settings-scope", "host", ">=0.1.5-rc.3 <=0.1.6", "supported", ["host/settings.ts", "host/features/*"]), route("settings.store", "config-forms", "host", ">=0.1.7-rc.2 <=0.1.7-rc.2", "supported", ["host/settings.ts", "client/settings-bridge.ts"]), route("connection.rpc", "legacy-rpc-handler", "host", ">=0.1.5-rc.3 <=0.1.6", "supported", ["host/rpc.ts"]), route("connection.rpc", "peer-aware-rpc-handler", "host", ">=0.1.7-rc.2 <=0.1.7-rc.2", "supported", ["host/rpc.ts"]), route("connection.peer", "peer-scope", "host", ">=0.1.7-rc.2 <=0.1.7-rc.2", "supported", ["host/rpc.ts"]), route("ui.icon.plus", "fixed-plus-icon", "client", ">=0.1.5-rc.3 <=0.1.6", "supported", ["client/terminal/xterm-view.ts"]), route("ui.icon.plus", "regular-plus-icon", "client", ">=0.1.7-rc.2 <=0.1.7-rc.2", "supported", ["client/terminal/xterm-view.ts"]), route("ui.icon.chevron", "fixed-chevron-icon", "client", ">=0.1.5-rc.3 <=0.1.6", "supported", ["client/terminal/ui.ts"]), route("ui.icon.chevron", "regular-chevron-icon", "client", ">=0.1.7-rc.2 <=0.1.7-rc.2", "supported", ["client/terminal/ui.ts"]), route("locale.runtime", "locale-runtime", "client", ">=0.1.5-rc.3 <=0.1.7-rc.2", "supported", ["client/locale.ts"]), route("theme.runtime", "theme-runtime", "client", ">=0.1.5-rc.3 <=0.1.7-rc.2", "supported", ["client/theme.ts"]), route("conversation.tool-call", "conversation-events", "client", ">=0.1.5-rc.3 <=0.1.7-rc.2", "supported", ["client/external-tool-stream.ts"]), route("sidebar.right", "sidebar-right-tabs", "client", ">=0.1.5-rc.3 <=0.1.7-rc.2", "supported", ["client/terminal/ui.ts"]), route("typert.remote", "remote-result", "host", ">=0.1.5-rc.3 <=0.1.7-rc.2", "supported", ["host/terminal/terminal-controller.ts", "client/terminal/model.ts"]), route("peer-host.store", "peer-host-store", "host", ">=0.1.5-rc.3 <=0.1.7-rc.2", "supported", ["host/features/peer-host.ts"]), route("peer-host.handshake", "peer-host-handshake", "host", ">=0.1.5-rc.3 <=0.1.7-rc.2", "supported", ["host/features/peer-host.ts"]), route("peer-host.http-proxy", "peer-host-http-proxy", "host", ">=0.1.5-rc.3 <=0.1.7-rc.2", "supported", ["host/features/peer-host.ts"]), route("peer-host.ws-proxy", "peer-host-ws-proxy", "host", ">=0.1.5-rc.3 <=0.1.7-rc.2", "supported", ["host/features/peer-host.ts"]), route("peer-host.aggregate", "peer-host-aggregate", "host", ">=0.1.5-rc.3 <=0.1.7-rc.2", "supported", ["host/features/peer-host.ts"]), route("peer-host.relay-route", "peer-host-relay-route", "host", ">=0.1.5-rc.3 <=0.1.7-rc.2", "supported", ["host/features/peer-host.ts"]), route("peer-host.native-navigation", "peer-host-native-navigation-legacy", "client", ">=0.1.5-rc.3 <=0.1.6", "deprecated", ["client/features/peer-host.ts"]), route("peer-host.native-navigation", "peer-host-native-navigation-modern", "client", ">=0.1.7-rc.2 <=0.1.7-rc.2", "supported", ["client/features/peer-host.ts"]), route("peer-host.remote-web-context-fallback", "peer-host-remote-web-context-fallback", "client", ">=0.1.5-rc.3 <=0.1.7-rc.2", "supported", ["client/features/peer-host.ts"]), route("settings.store", "settings-forms-020", "host", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["host/settings.ts", "host/rpc.ts"]), route("connection.rpc", "connection-rpc-020", "host", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["host/rpc.ts", "transport/dsh-transport.ts"]), route("connection.peer", "connection-peer-admission-020", "host",
|
|
62614
|
+
]), route("assistant.agent", "assistant-agent-021", "host", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["dsh-capabilities/host/assistant-agent-adapter.ts", "host/features/global-voice-rpc.ts"]), route("settings.store", "legacy-settings-scope", "host", ">=0.1.5-rc.3 <=0.1.6", "supported", ["host/settings.ts", "host/features/*"]), route("settings.store", "config-forms", "host", ">=0.1.7-rc.2 <=0.1.7-rc.2", "supported", ["host/settings.ts", "client/settings-bridge.ts"]), route("connection.rpc", "legacy-rpc-handler", "host", ">=0.1.5-rc.3 <=0.1.6", "supported", ["host/rpc.ts"]), route("connection.rpc", "peer-aware-rpc-handler", "host", ">=0.1.7-rc.2 <=0.1.7-rc.2", "supported", ["host/rpc.ts"]), route("connection.peer", "peer-scope", "host", ">=0.1.7-rc.2 <=0.1.7-rc.2", "supported", ["host/rpc.ts"]), route("ui.icon.plus", "fixed-plus-icon", "client", ">=0.1.5-rc.3 <=0.1.6", "supported", ["client/terminal/xterm-view.ts"]), route("ui.icon.plus", "regular-plus-icon", "client", ">=0.1.7-rc.2 <=0.1.7-rc.2", "supported", ["client/terminal/xterm-view.ts"]), route("ui.icon.chevron", "fixed-chevron-icon", "client", ">=0.1.5-rc.3 <=0.1.6", "supported", ["client/terminal/ui.ts"]), route("ui.icon.chevron", "regular-chevron-icon", "client", ">=0.1.7-rc.2 <=0.1.7-rc.2", "supported", ["client/terminal/ui.ts"]), route("locale.runtime", "locale-runtime", "client", ">=0.1.5-rc.3 <=0.1.7-rc.2", "supported", ["client/locale.ts"]), route("theme.runtime", "theme-runtime", "client", ">=0.1.5-rc.3 <=0.1.7-rc.2", "supported", ["client/theme.ts"]), route("conversation.tool-call", "conversation-events", "client", ">=0.1.5-rc.3 <=0.1.7-rc.2", "supported", ["client/external-tool-stream.ts"]), route("sidebar.right", "sidebar-right-tabs", "client", ">=0.1.5-rc.3 <=0.1.7-rc.2", "supported", ["client/terminal/ui.ts"]), route("typert.remote", "remote-result", "host", ">=0.1.5-rc.3 <=0.1.7-rc.2", "supported", ["host/terminal/terminal-controller.ts", "client/terminal/model.ts"]), route("peer-host.store", "peer-host-store", "host", ">=0.1.5-rc.3 <=0.1.7-rc.2", "supported", ["host/features/peer-host.ts"]), route("peer-host.handshake", "peer-host-handshake", "host", ">=0.1.5-rc.3 <=0.1.7-rc.2", "supported", ["host/features/peer-host.ts"]), route("peer-host.http-proxy", "peer-host-http-proxy", "host", ">=0.1.5-rc.3 <=0.1.7-rc.2", "supported", ["host/features/peer-host.ts"]), route("peer-host.ws-proxy", "peer-host-ws-proxy", "host", ">=0.1.5-rc.3 <=0.1.7-rc.2", "supported", ["host/features/peer-host.ts"]), route("peer-host.aggregate", "peer-host-aggregate", "host", ">=0.1.5-rc.3 <=0.1.7-rc.2", "supported", ["host/features/peer-host.ts"]), route("peer-host.relay-route", "peer-host-relay-route", "host", ">=0.1.5-rc.3 <=0.1.7-rc.2", "supported", ["host/features/peer-host.ts"]), route("peer-host.native-navigation", "peer-host-native-navigation-legacy", "client", ">=0.1.5-rc.3 <=0.1.6", "deprecated", ["client/features/peer-host.ts"]), route("peer-host.native-navigation", "peer-host-native-navigation-modern", "client", ">=0.1.7-rc.2 <=0.1.7-rc.2", "supported", ["client/features/peer-host.ts"]), route("peer-host.remote-web-context-fallback", "peer-host-remote-web-context-fallback", "client", ">=0.1.5-rc.3 <=0.1.7-rc.2", "supported", ["client/features/peer-host.ts"]), route("settings.store", "settings-forms-020", "host", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["host/settings.ts", "host/rpc.ts"]), route("connection.rpc", "connection-rpc-020", "host", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["host/rpc.ts", "transport/dsh-transport.ts"]), route("connection.peer", "connection-peer-admission-020", "host", ">=0.2.0-rc.2 <=0.2.1-alpha.2", "supported", ["host/rpc.ts"]), route("connection.attachment", "connection-rpc-attachment-020", "host", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["host/rpc.ts", "transport/dsh-transport.ts"]), route("connection.uplink", "connection-rpc-uplink-020", "host", ">=0.2.0-rc.2 <=0.2.1-alpha.2", "supported", ["host/rpc.ts", "transport/dsh-transport.ts"]), route("typert.remote", "remote-context-stream-020", "host", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["host/terminal/terminal-controller.ts", "client/terminal/model.ts"]), route("typert.context", "typert-context-registry-020", "host", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["typert.host.ts", "host/terminal/terminal-controller.ts"]), route("typert.stream", "typert-remote-stream-020", "host", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["typert.host.ts", "typert.remote-client.ts"]), route("session.format-v4", "session-format-v4", "host", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["host/native-session-bridge.ts", "host/session-migration-repair.ts"]), route("subagent.continuable", "subagent-continuable-020", "host", ">=0.2.0-rc.1 <=0.2.1-alpha.1", "supported", ["host/cli-adapters/session-store.ts", "host/cli-adapters/feature.ts"]), route("subagent.continuable", "subagent-activation-021", "host", ">=0.2.1-alpha.2", "supported", ["host/cli-adapters/native-team-subagent.ts", "host/cli-adapters/native-subagent-dispatch.ts"]), route("agent-team.native", "agent-team-native-020", "host", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["host/cli-adapters/feature.ts", "host/cli-adapters/native-team-proxy.ts"]), route("ui.icon.plus", "regular-plus-icon-020", "client", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["client/terminal/xterm-view.ts"]), route("ui.icon.chevron", "regular-chevron-icon-020", "client", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["client/terminal/ui.ts"]), route("locale.runtime", "locale-runtime-020", "client", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["client/locale.ts"]), route("theme.runtime", "theme-runtime-020", "client", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["client/theme.ts"]), route("theme.font-scale", "theme-font-scale-021", "client", ">=0.2.1-alpha.2", "supported", ["client/font-scale.ts", "client/index.ts"]), route("conversation.tool-call", "conversation-events-020", "client", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["client/external-tool-stream.ts"]), route("conversation.draft-share", "conversation-draft-share-021", "client", ">=0.2.1-alpha.1 <=0.2.1-alpha.3", "supported", ["client/terminal/ui.ts", "client/terminal/sharing.ts"]), route("conversation.interaction-translation", "interaction-presentation-021", "client", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["client/session-translation-interactions.ts"]), route("sidebar.right", "sidebar-right-dock-020", "client", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["client/terminal/ui.ts"]), route("typert.remote", "remote-context-stream-020-client", "client", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["client/terminal/model.ts"]), route("typert.context", "typert-context-registry-020-client", "client", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["typert.remote-client.ts", "client/terminal/model.ts"]), route("typert.stream", "typert-remote-stream-020-client", "client", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["typert.remote-client.ts", "client/terminal/model.ts"]), route("client.boot-graph", "client-web-boot-graph-020", "client", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["client/index.ts", "package.json"]), route("peer-host.native-navigation", "peer-host-native-navigation-020", "client", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["client/features/peer-host.ts"]), route("peer-host.remote-web-context-fallback", "peer-host-remote-web-context-fallback-020", "client", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["client/features/peer-host.ts"]), route("peer-host.store", "peer-host-store-020", "host", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["host/features/peer-host.ts"]), route("peer-host.handshake", "peer-host-handshake-020", "host", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["host/features/peer-host.ts"]), route("peer-host.http-proxy", "peer-host-http-proxy-020", "host", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["host/features/peer-host.ts"]), route("peer-host.ws-proxy", "peer-host-ws-proxy-020", "host", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["host/features/peer-host.ts"]), route("peer-host.aggregate", "peer-host-aggregate-020", "host", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["host/features/peer-host.ts"]), route("peer-host.aggregated-transport", "peer-host-aggregated-transport-020", "host", require_native_workspace_store.DSH_COMPATIBILITY, "supported", ["host/modules/peer-host/aggregated-host-transport.ts"]), route("peer-host.client-preboot-transport", "peer-host-client-preboot-transport-020", "client", require_native_workspace_store.DSH_COMPATIBILITY, "supported", [
|
|
61830
62615
|
"bootstrap/index.ts",
|
|
61831
62616
|
"host/index-injection.ts",
|
|
61832
62617
|
"client/features/peer-host.ts"
|
|
@@ -61850,7 +62635,7 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
61850
62635
|
};
|
|
61851
62636
|
}
|
|
61852
62637
|
//#endregion
|
|
61853
|
-
//#region node_modules/.pnpm/@deepseek-ai+dsh-util-workspace-path@0.2.1-alpha.
|
|
62638
|
+
//#region node_modules/.pnpm/@deepseek-ai+dsh-util-workspace-path@0.2.1-alpha.3_@deepseek-ai+cordis@4.0.5-alpha.2/node_modules/@deepseek-ai/dsh-util-workspace-path/lib/index.js
|
|
61854
62639
|
/**
|
|
61855
62640
|
* The `dsh-resource://file/…` address grammar: how a file is named across the
|
|
61856
62641
|
* Sidebar and the resource model, built and parsed without touching a
|
|
@@ -67846,5 +68631,5 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
67846
68631
|
});
|
|
67847
68632
|
|
|
67848
68633
|
})();
|
|
67849
|
-
// codingns-client-revision:
|
|
68634
|
+
// codingns-client-revision: 2e9f1cf8b1415877388dec3f78d38b7ad5866162a49e617afa85f7edf56e6472
|
|
67850
68635
|
//# sourceMappingURL=bundle.js.map
|