@xmanrui/dsh-im 4.2.1 → 4.3.0
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 +4 -2
- package/README.md +4 -2
- package/lib/client.js +350 -195
- package/lib/index.js +222 -220
- package/package.json +1 -1
- package/plugin-src/client/context-enhancement.js +207 -102
- package/plugin-src/client/i18n.js +15 -2
- package/plugin-src/client/styles.js +9 -4
- package/scripts/verify-package.mjs +4 -3
- package/src/channels/feishu/bridge.mjs +98 -40
- package/src/channels/feishu/message-utils.mjs +5 -0
- package/src/channels/qq/qq-runtime.mjs +5 -1
- package/src/channels/shared/context-enhancement.mjs +73 -20
package/lib/client.js
CHANGED
|
@@ -571,7 +571,7 @@ var React23 = __toESM(require("react"), 1);
|
|
|
571
571
|
// package.json
|
|
572
572
|
var package_default = {
|
|
573
573
|
name: "@xmanrui/dsh-im",
|
|
574
|
-
version: "4.
|
|
574
|
+
version: "4.3.0",
|
|
575
575
|
description: "\u628A\u4E5D\u79CD IM \u673A\u5668\u4EBA\u548C\u516C\u7F51 AI Office \u63A5\u5165\u672C\u673A DeepSeek Harness\u3002 Connect nine IM channels and a public AI Office to a local DeepSeek Harness.",
|
|
576
576
|
keywords: [
|
|
577
577
|
"deepseek-harness",
|
|
@@ -1050,31 +1050,44 @@ var EN = Object.freeze({
|
|
|
1050
1050
|
"\u7FA4\u804A\u548C\u79C1\u804A": "Groups and direct",
|
|
1051
1051
|
"\u5173\u95ED\u5F39\u7A97": "Close dialog",
|
|
1052
1052
|
"\u67E5\u770B\u4E0A\u4E0B\u6587\u589E\u5F3A\u8BF4\u660E": "View context enhancement details",
|
|
1053
|
+
"\u4E0A\u4E0B\u6587\u589E\u5F3A\u8303\u56F4": "Context enhancement scope",
|
|
1053
1054
|
"\u542F\u7528\u8303\u56F4": "Enable in",
|
|
1054
|
-
"\
|
|
1055
|
-
"\u79C1\u804A\u4E2D\u542F\u7528": "Enable in direct chats",
|
|
1055
|
+
"\u542F\u7528": "Enabled",
|
|
1056
1056
|
"\uFF08\u5F53\u524D\u6E20\u9053\u4E0D\u652F\u6301\u7FA4\u804A\uFF09": "(This channel does not support group chats)",
|
|
1057
1057
|
"\u6765\u6E90\u5B57\u6BB5": "Source fields",
|
|
1058
1058
|
"\u67E5\u770B\u6765\u6E90\u5B57\u6BB5\u8BF4\u660E": "View source field details",
|
|
1059
|
+
"\u67E5\u770B\u7FA4\u804A\u6765\u6E90\u5B57\u6BB5\u8BF4\u660E": "View group source field details",
|
|
1060
|
+
"\u67E5\u770B\u79C1\u804A\u6765\u6E90\u5B57\u6BB5\u8BF4\u660E": "View direct source field details",
|
|
1059
1061
|
"\u6E20\u9053": "Channel",
|
|
1060
1062
|
"\u4F1A\u8BDD\u7C7B\u578B": "Conversation type",
|
|
1061
1063
|
"\u53D1\u9001\u8005\u6807\u8BC6": "Sender ID",
|
|
1062
1064
|
"\u53D1\u9001\u8005\u6635\u79F0": "Sender name",
|
|
1063
1065
|
"\u67E5\u770B\u53D1\u9001\u8005\u6635\u79F0\u5B57\u6BB5\u8BF4\u660E": "View sender name field details",
|
|
1066
|
+
"\u67E5\u770B\u7FA4\u804A\u53D1\u9001\u8005\u6635\u79F0\u5B57\u6BB5\u8BF4\u660E": "View group sender name field details",
|
|
1067
|
+
"\u67E5\u770B\u79C1\u804A\u53D1\u9001\u8005\u6635\u79F0\u5B57\u6BB5\u8BF4\u660E": "View direct sender name field details",
|
|
1064
1068
|
"\u8BE5\u5B57\u6BB5\u4E0D\u662F\u6BCF\u4E2A\u6E20\u9053\u90FD\u80FD\u63D0\u4F9B\u3002\u5F53\u524D\u6D88\u606F\u6CA1\u6709\u53D1\u9001\u8005\u6635\u79F0\u65F6\uFF0C\u5373\u4F7F\u5DF2\u9009\u62E9\u8BE5\u5B57\u6BB5\uFF0C<dsh_im_source> \u4E2D\u4E5F\u4F1A\u7701\u7565 senderName\u3002": "This field is not available on every channel. If the current message has no sender name, <dsh_im_source> omits senderName even when the field is selected.",
|
|
1065
1069
|
"\u673A\u5668\u4EBA\u6807\u8BC6": "Bot ID",
|
|
1066
1070
|
"\u589E\u5F3A\u63D0\u793A\u8BCD": "Guidance",
|
|
1067
1071
|
"\u67E5\u770B\u589E\u5F3A\u63D0\u793A\u8BCD\u4F7F\u7528\u8BF4\u660E": "View guidance instructions",
|
|
1072
|
+
"\u67E5\u770B\u7FA4\u804A\u589E\u5F3A\u63D0\u793A\u8BCD\u4F7F\u7528\u8BF4\u660E": "View group guidance instructions",
|
|
1073
|
+
"\u67E5\u770B\u79C1\u804A\u589E\u5F3A\u63D0\u793A\u8BCD\u4F7F\u7528\u8BF4\u660E": "View direct guidance instructions",
|
|
1068
1074
|
"\u4F7F\u7528\u8BF4\u660E": "How to use",
|
|
1069
1075
|
"\u7528\u4E8E\u544A\u8BC9\u6A21\u578B\u5982\u4F55\u4F7F\u7528 <dsh_im_source> \u4E2D\u5DF2\u9009\u62E9\u7684\u6765\u6E90\u5B57\u6BB5\u3002\u53EA\u586B\u5199\u6B63\u6587\uFF0C\u63D2\u4EF6\u4F1A\u81EA\u52A8\u6DFB\u52A0 <dsh_im_source_guidance> \u6210\u5BF9\u6807\u7B7E\u3002": "Tell the model how to use the selected fields in <dsh_im_source>. Enter only the body; the plugin adds paired <dsh_im_source_guidance> tags.",
|
|
1070
1076
|
"\u751F\u6548\u89C4\u5219": "Behavior",
|
|
1071
1077
|
"\u9690\u79C1\u63D0\u793A": "Privacy",
|
|
1072
1078
|
"\u4F7F\u7528\u793A\u4F8B": "Example",
|
|
1073
1079
|
"\u4EC5\u4F9D\u636E\u5F53\u524D\u6D88\u606F\u7684 <dsh_im_source> \u4E2D\u5B9E\u9645\u63D0\u4F9B\u7684\u5B57\u6BB5\u7406\u89E3\u6765\u6E90\uFF1B\u6CA1\u6709\u63D0\u4F9B\u7684\u5B57\u6BB5\u4E0D\u8981\u731C\u6D4B\u6216\u8865\u5168\u3002\nconversationType\u662F\u7FA4\u804A\u65F6\u56DE\u590D\u4E25\u8083\u4E00\u70B9\uFF0CconversationType\u662F\u79C1\u804A\u65F6\u56DE\u590D\u4E00\u5B9A\u8981\u5E7D\u9ED8\u641E\u7B11\uFF0C\u50CF\u5468\u661F\u9A70\u7684\u7535\u5F71\u4E00\u6837\u641E\u7B11": "Understand the source only from fields actually present in <dsh_im_source> for the current message; do not guess or fill in missing fields.\nWhen conversationType is group, reply more seriously. When conversationType is direct, make the reply humorous and funny.",
|
|
1080
|
+
"\u4EC5\u4F9D\u636E\u5F53\u524D\u6D88\u606F\u7684 <dsh_im_source> \u4E2D\u5B9E\u9645\u63D0\u4F9B\u7684\u5B57\u6BB5\u7406\u89E3\u6765\u6E90\uFF1B\u6CA1\u6709\u63D0\u4F9B\u7684\u5B57\u6BB5\u4E0D\u8981\u731C\u6D4B\u6216\u8865\u5168\u3002\n\u5F53\u524D\u6D88\u606F\u6765\u81EA\u7FA4\u804A\uFF0C\u8BF7\u4F7F\u7528\u4E25\u8083\u3001\u514B\u5236\u3001\u7B80\u6D01\u7684\u8868\u8FBE\u65B9\u5F0F\u3002": "Understand the source only from fields actually present in <dsh_im_source> for the current message; do not guess or fill in missing fields.\nThis message is from a group chat. Use a serious, restrained, and concise style.",
|
|
1081
|
+
"\u4EC5\u4F9D\u636E\u5F53\u524D\u6D88\u606F\u7684 <dsh_im_source> \u4E2D\u5B9E\u9645\u63D0\u4F9B\u7684\u5B57\u6BB5\u7406\u89E3\u6765\u6E90\uFF1B\u6CA1\u6709\u63D0\u4F9B\u7684\u5B57\u6BB5\u4E0D\u8981\u731C\u6D4B\u6216\u8865\u5168\u3002\n\u5F53\u524D\u6D88\u606F\u6765\u81EA\u79C1\u804A\uFF0C\u53EF\u4EE5\u4F7F\u7528\u66F4\u8F7B\u677E\u3001\u5E7D\u9ED8\u3001\u8BE6\u7EC6\u7684\u8868\u8FBE\u65B9\u5F0F\u3002": "Understand the source only from fields actually present in <dsh_im_source> for the current message; do not guess or fill in missing fields.\nThis message is from a direct chat. You may use a lighter, more humorous, and detailed style.",
|
|
1074
1082
|
"\u586B\u5165\u793A\u4F8B": "Use example",
|
|
1075
1083
|
"\u6E05\u7A7A": "Clear",
|
|
1076
1084
|
"\u9009\u62E9\u5728\u54EA\u4E9B\u4F1A\u8BDD\u4E2D\u542F\u7528\u3001\u63D0\u4F9B\u54EA\u4E9B\u6765\u6E90\u5B57\u6BB5\uFF0C\u4EE5\u53CA\u5982\u4F55\u4F7F\u7528\u8FD9\u4E9B\u4FE1\u606F\u3002\u4EC5\u4F7F\u7528\u5DF2\u6709\u6D88\u606F\u5143\u6570\u636E\uFF0C\u4E0D\u67E5\u8BE2\u5E73\u53F0 API\u3002": "Choose which conversations to enhance, which source fields to include, and how to use them. Only existing message metadata is used; no platform APIs are queried.",
|
|
1077
1085
|
"\u589E\u5F3A\u63D0\u793A\u8BCD\u4E2D\u8BF7\u4F7F\u7528\u5B57\u6BB5\u540D\uFF08\u5982 senderId\u3001conversationType\uFF09\u5F15\u7528\u8FD9\u4E9B\u4FE1\u606F\u3002\u53EA\u53D1\u9001\u52FE\u9009\u4E14\u5F53\u524D\u6D88\u606F\u4E2D\u53EF\u7528\u7684\u5B57\u6BB5\uFF0C\u4E0D\u4F1A\u989D\u5916\u67E5\u8BE2\u6216\u8865\u5168\u3002": "Reference these values by field name (such as senderId or conversationType) in the guidance. Only selected fields available in the current message are sent; no extra lookups are made.",
|
|
1086
|
+
"\u589E\u5F3A\u63D0\u793A\u8BCD\u4E2D\u8BF7\u4F7F\u7528\u5B57\u6BB5\u540D\uFF08\u5982 senderId\u3001conversationType\uFF09\u5F15\u7528\u8FD9\u4E9B\u4FE1\u606F\u3002\u53EA\u53D1\u9001\u5F53\u524D\u4F1A\u8BDD\u4E2D\u52FE\u9009\u4E14\u53EF\u7528\u7684\u5B57\u6BB5\uFF0C\u4E0D\u4F1A\u989D\u5916\u67E5\u8BE2\u6216\u8865\u5168\u3002": "Reference these values by field name (such as senderId or conversationType) in the guidance. Only fields selected and available in the current conversation are sent; no extra lookups are made.",
|
|
1087
|
+
"\u7528\u4E8E\u544A\u8BC9\u6A21\u578B\u5982\u4F55\u4F7F\u7528\u5F53\u524D\u7FA4\u804A\u6D88\u606F\u7684 <dsh_im_source> \u6765\u6E90\u5B57\u6BB5\u3002\u53EA\u586B\u5199\u6B63\u6587\uFF0C\u63D2\u4EF6\u4F1A\u81EA\u52A8\u6DFB\u52A0 <dsh_im_source_guidance> \u6210\u5BF9\u6807\u7B7E\u3002": "Tell the model how to use <dsh_im_source> fields for the current group message. Enter only the body; the plugin adds paired <dsh_im_source_guidance> tags.",
|
|
1088
|
+
"\u7528\u4E8E\u544A\u8BC9\u6A21\u578B\u5982\u4F55\u4F7F\u7528\u5F53\u524D\u79C1\u804A\u6D88\u606F\u7684 <dsh_im_source> \u6765\u6E90\u5B57\u6BB5\u3002\u53EA\u586B\u5199\u6B63\u6587\uFF0C\u63D2\u4EF6\u4F1A\u81EA\u52A8\u6DFB\u52A0 <dsh_im_source_guidance> \u6210\u5BF9\u6807\u7B7E\u3002": "Tell the model how to use <dsh_im_source> fields for the current direct message. Enter only the body; the plugin adds paired <dsh_im_source_guidance> tags.",
|
|
1089
|
+
"\u4EC5\u5728\u7FA4\u804A\u5F00\u5173\u5F00\u542F\u65F6\u4F7F\u7528\u3002\u6E05\u7A7A\u5E76\u4FDD\u5B58\u540E\u4E0D\u518D\u9644\u52A0\u7FA4\u804A\u589E\u5F3A\u63D0\u793A\u8BCD\uFF1B\u6240\u9009\u6765\u6E90\u5B57\u6BB5\u4ECD\u6309\u5F53\u524D\u573A\u666F\u8BBE\u7F6E\u53D1\u9001\u3002": "Used only when group enhancement is enabled. Clear and save to omit group guidance; selected source fields still follow the group settings.",
|
|
1090
|
+
"\u4EC5\u5728\u79C1\u804A\u5F00\u5173\u5F00\u542F\u65F6\u4F7F\u7528\u3002\u6E05\u7A7A\u5E76\u4FDD\u5B58\u540E\u4E0D\u518D\u9644\u52A0\u79C1\u804A\u589E\u5F3A\u63D0\u793A\u8BCD\uFF1B\u6240\u9009\u6765\u6E90\u5B57\u6BB5\u4ECD\u6309\u5F53\u524D\u573A\u666F\u8BBE\u7F6E\u53D1\u9001\u3002": "Used only when direct enhancement is enabled. Clear and save to omit direct guidance; selected source fields still follow the direct settings.",
|
|
1078
1091
|
"\u53EA\u9700\u586B\u5199\u6B63\u6587\uFF0C\u63D2\u4EF6\u81EA\u52A8\u6DFB\u52A0 <dsh_im_source_guidance> \u6210\u5BF9\u6807\u7B7E\u3002\u6E05\u7A7A\u5E76\u4FDD\u5B58\u540E\uFF0C\u4E0D\u518D\u9644\u52A0\u589E\u5F3A\u63D0\u793A\u8BCD\uFF0C\u5DF2\u9009\u6765\u6E90\u5B57\u6BB5\u4ECD\u6309\u5F00\u5173\u8BBE\u7F6E\u53D1\u9001\u3002": "Enter only the body; the plugin adds paired <dsh_im_source_guidance> tags. Clear and save to omit guidance. Selected source fields still follow the conversation switches.",
|
|
1079
1092
|
"\u53D1\u9001\u8005\u6807\u8BC6\u53EF\u80FD\u5305\u542B\u5E73\u53F0\u7528\u6237 ID \u6216\u7535\u8BDD\u53F7\u7801\u5F62\u5F0F\u7684\u6807\u8BC6\u3002\u5173\u95ED\u5F00\u5173\u4E0D\u4F1A\u5220\u9664\u5DF2\u7ECF\u5199\u5165\u4F1A\u8BDD\u5386\u53F2\u7684\u4FE1\u606F\u3002": "Sender IDs may contain platform user IDs or phone-number-like identifiers. Turning this off does not remove information already saved in conversation history.",
|
|
1080
1093
|
"\u4E0A\u4E0B\u6587\u589E\u5F3A\u4FDD\u5B58\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5\u3002": "Could not save context enhancement. Try again.",
|
|
@@ -1881,26 +1894,39 @@ var CONTEXT_ENHANCEMENT_FIELDS = Object.freeze([
|
|
|
1881
1894
|
"botId"
|
|
1882
1895
|
]);
|
|
1883
1896
|
var CONTEXT_ENHANCEMENT_GUIDANCE_MAX_LENGTH = 8e3;
|
|
1884
|
-
var
|
|
1885
|
-
|
|
1897
|
+
var CONTEXT_GROUP_GUIDANCE_EXAMPLE = `\u4EC5\u4F9D\u636E\u5F53\u524D\u6D88\u606F\u7684 <dsh_im_source> \u4E2D\u5B9E\u9645\u63D0\u4F9B\u7684\u5B57\u6BB5\u7406\u89E3\u6765\u6E90\uFF1B\u6CA1\u6709\u63D0\u4F9B\u7684\u5B57\u6BB5\u4E0D\u8981\u731C\u6D4B\u6216\u8865\u5168\u3002
|
|
1898
|
+
\u5F53\u524D\u6D88\u606F\u6765\u81EA\u7FA4\u804A\uFF0C\u8BF7\u4F7F\u7528\u4E25\u8083\u3001\u514B\u5236\u3001\u7B80\u6D01\u7684\u8868\u8FBE\u65B9\u5F0F\u3002`;
|
|
1899
|
+
var CONTEXT_DIRECT_GUIDANCE_EXAMPLE = `\u4EC5\u4F9D\u636E\u5F53\u524D\u6D88\u606F\u7684 <dsh_im_source> \u4E2D\u5B9E\u9645\u63D0\u4F9B\u7684\u5B57\u6BB5\u7406\u89E3\u6765\u6E90\uFF1B\u6CA1\u6709\u63D0\u4F9B\u7684\u5B57\u6BB5\u4E0D\u8981\u731C\u6D4B\u6216\u8865\u5168\u3002
|
|
1900
|
+
\u5F53\u524D\u6D88\u606F\u6765\u81EA\u79C1\u804A\uFF0C\u53EF\u4EE5\u4F7F\u7528\u66F4\u8F7B\u677E\u3001\u5E7D\u9ED8\u3001\u8BE6\u7EC6\u7684\u8868\u8FBE\u65B9\u5F0F\u3002`;
|
|
1886
1901
|
var DEFAULT_CONTEXT_ENHANCEMENT_CONFIG = Object.freeze({
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1902
|
+
group: Object.freeze({
|
|
1903
|
+
enabled: false,
|
|
1904
|
+
fields: Object.freeze(["senderId"]),
|
|
1905
|
+
guidance: ""
|
|
1906
|
+
}),
|
|
1907
|
+
direct: Object.freeze({
|
|
1908
|
+
enabled: false,
|
|
1909
|
+
fields: Object.freeze(["senderId"]),
|
|
1910
|
+
guidance: ""
|
|
1911
|
+
})
|
|
1891
1912
|
});
|
|
1892
|
-
var CONFIG_KEYS = ["
|
|
1913
|
+
var CONFIG_KEYS = ["group", "direct"];
|
|
1914
|
+
var SCOPE_KEYS = ["enabled", "fields", "guidance"];
|
|
1915
|
+
var LEGACY_CONFIG_KEYS = ["groupEnabled", "directEnabled", "fields", "guidance"];
|
|
1893
1916
|
function invalidConfig(message) {
|
|
1894
1917
|
const error = new TypeError(message);
|
|
1895
1918
|
error.code = "context-enhancement-invalid";
|
|
1896
1919
|
return error;
|
|
1897
1920
|
}
|
|
1898
|
-
function
|
|
1899
|
-
|
|
1921
|
+
function hasExactKeys(input, keys) {
|
|
1922
|
+
return input && typeof input === "object" && !Array.isArray(input) && [Object.prototype, null].includes(Object.getPrototypeOf(input)) && Reflect.ownKeys(input).length === keys.length && keys.every((key) => Object.hasOwn(input, key));
|
|
1923
|
+
}
|
|
1924
|
+
function validateContextEnhancementScope(input) {
|
|
1925
|
+
if (!hasExactKeys(input, SCOPE_KEYS)) {
|
|
1900
1926
|
throw invalidConfig("\u8BF7\u63D0\u4EA4\u5B8C\u6574\u7684\u4E0A\u4E0B\u6587\u589E\u5F3A\u8BBE\u7F6E\u3002");
|
|
1901
1927
|
}
|
|
1902
|
-
const {
|
|
1903
|
-
if (typeof
|
|
1928
|
+
const { enabled, fields, guidance } = input;
|
|
1929
|
+
if (typeof enabled !== "boolean") {
|
|
1904
1930
|
throw invalidConfig("\u7FA4\u804A\u548C\u79C1\u804A\u5F00\u5173\u5FC5\u987B\u662F\u5E03\u5C14\u503C\u3002");
|
|
1905
1931
|
}
|
|
1906
1932
|
if (!Array.isArray(fields) || ![...fields].every((field) => CONTEXT_ENHANCEMENT_FIELDS.includes(field))) {
|
|
@@ -1910,17 +1936,46 @@ function validateContextEnhancementConfig(input) {
|
|
|
1910
1936
|
throw invalidConfig(`\u589E\u5F3A\u63D0\u793A\u8BCD\u4E0D\u5F97\u8D85\u8FC7 ${CONTEXT_ENHANCEMENT_GUIDANCE_MAX_LENGTH} \u4E2A\u5B57\u7B26\u3002`);
|
|
1911
1937
|
}
|
|
1912
1938
|
return Object.freeze({
|
|
1913
|
-
|
|
1914
|
-
directEnabled,
|
|
1939
|
+
enabled,
|
|
1915
1940
|
fields: Object.freeze(CONTEXT_ENHANCEMENT_FIELDS.filter((field) => fields.includes(field))),
|
|
1916
1941
|
guidance: guidance.trim() ? guidance : ""
|
|
1917
1942
|
});
|
|
1918
1943
|
}
|
|
1944
|
+
function validateContextEnhancementConfig(input) {
|
|
1945
|
+
if (!hasExactKeys(input, CONFIG_KEYS)) {
|
|
1946
|
+
throw invalidConfig("\u8BF7\u63D0\u4EA4\u5B8C\u6574\u7684\u4E0A\u4E0B\u6587\u589E\u5F3A\u8BBE\u7F6E\u3002");
|
|
1947
|
+
}
|
|
1948
|
+
return Object.freeze({
|
|
1949
|
+
group: validateContextEnhancementScope(input.group),
|
|
1950
|
+
direct: validateContextEnhancementScope(input.direct)
|
|
1951
|
+
});
|
|
1952
|
+
}
|
|
1953
|
+
function migrateLegacyContextEnhancementConfig(input) {
|
|
1954
|
+
if (!hasExactKeys(input, LEGACY_CONFIG_KEYS)) {
|
|
1955
|
+
throw invalidConfig("\u8BF7\u63D0\u4EA4\u5B8C\u6574\u7684\u4E0A\u4E0B\u6587\u589E\u5F3A\u8BBE\u7F6E\u3002");
|
|
1956
|
+
}
|
|
1957
|
+
return validateContextEnhancementConfig({
|
|
1958
|
+
group: {
|
|
1959
|
+
enabled: input.groupEnabled,
|
|
1960
|
+
fields: input.fields,
|
|
1961
|
+
guidance: input.guidance
|
|
1962
|
+
},
|
|
1963
|
+
direct: {
|
|
1964
|
+
enabled: input.directEnabled,
|
|
1965
|
+
fields: input.fields,
|
|
1966
|
+
guidance: input.guidance
|
|
1967
|
+
}
|
|
1968
|
+
});
|
|
1969
|
+
}
|
|
1919
1970
|
function normalizeContextEnhancementConfig(input) {
|
|
1920
1971
|
try {
|
|
1921
1972
|
return validateContextEnhancementConfig(input);
|
|
1922
1973
|
} catch {
|
|
1923
|
-
|
|
1974
|
+
try {
|
|
1975
|
+
return migrateLegacyContextEnhancementConfig(input);
|
|
1976
|
+
} catch {
|
|
1977
|
+
return DEFAULT_CONTEXT_ENHANCEMENT_CONFIG;
|
|
1978
|
+
}
|
|
1924
1979
|
}
|
|
1925
1980
|
}
|
|
1926
1981
|
|
|
@@ -2656,11 +2711,33 @@ var FIELD_LABELS = Object.freeze({
|
|
|
2656
2711
|
senderName: "\u53D1\u9001\u8005\u6635\u79F0",
|
|
2657
2712
|
botId: "\u673A\u5668\u4EBA\u6807\u8BC6"
|
|
2658
2713
|
});
|
|
2714
|
+
var SCOPE_COPY = Object.freeze({
|
|
2715
|
+
group: Object.freeze({
|
|
2716
|
+
title: "\u7FA4\u804A",
|
|
2717
|
+
enable: "\u542F\u7528",
|
|
2718
|
+
fieldsHelpLabel: "\u67E5\u770B\u7FA4\u804A\u6765\u6E90\u5B57\u6BB5\u8BF4\u660E",
|
|
2719
|
+
senderNameHelpLabel: "\u67E5\u770B\u7FA4\u804A\u53D1\u9001\u8005\u6635\u79F0\u5B57\u6BB5\u8BF4\u660E",
|
|
2720
|
+
guidanceLabel: "\u589E\u5F3A\u63D0\u793A\u8BCD",
|
|
2721
|
+
guidanceHelpLabel: "\u67E5\u770B\u7FA4\u804A\u589E\u5F3A\u63D0\u793A\u8BCD\u4F7F\u7528\u8BF4\u660E",
|
|
2722
|
+
guidanceUsage: "\u7528\u4E8E\u544A\u8BC9\u6A21\u578B\u5982\u4F55\u4F7F\u7528\u5F53\u524D\u7FA4\u804A\u6D88\u606F\u7684 <dsh_im_source> \u6765\u6E90\u5B57\u6BB5\u3002\u53EA\u586B\u5199\u6B63\u6587\uFF0C\u63D2\u4EF6\u4F1A\u81EA\u52A8\u6DFB\u52A0 <dsh_im_source_guidance> \u6210\u5BF9\u6807\u7B7E\u3002",
|
|
2723
|
+
guidanceBehavior: "\u4EC5\u5728\u7FA4\u804A\u5F00\u5173\u5F00\u542F\u65F6\u4F7F\u7528\u3002\u6E05\u7A7A\u5E76\u4FDD\u5B58\u540E\u4E0D\u518D\u9644\u52A0\u7FA4\u804A\u589E\u5F3A\u63D0\u793A\u8BCD\uFF1B\u6240\u9009\u6765\u6E90\u5B57\u6BB5\u4ECD\u6309\u5F53\u524D\u573A\u666F\u8BBE\u7F6E\u53D1\u9001\u3002"
|
|
2724
|
+
}),
|
|
2725
|
+
direct: Object.freeze({
|
|
2726
|
+
title: "\u79C1\u804A",
|
|
2727
|
+
enable: "\u542F\u7528",
|
|
2728
|
+
fieldsHelpLabel: "\u67E5\u770B\u79C1\u804A\u6765\u6E90\u5B57\u6BB5\u8BF4\u660E",
|
|
2729
|
+
senderNameHelpLabel: "\u67E5\u770B\u79C1\u804A\u53D1\u9001\u8005\u6635\u79F0\u5B57\u6BB5\u8BF4\u660E",
|
|
2730
|
+
guidanceLabel: "\u589E\u5F3A\u63D0\u793A\u8BCD",
|
|
2731
|
+
guidanceHelpLabel: "\u67E5\u770B\u79C1\u804A\u589E\u5F3A\u63D0\u793A\u8BCD\u4F7F\u7528\u8BF4\u660E",
|
|
2732
|
+
guidanceUsage: "\u7528\u4E8E\u544A\u8BC9\u6A21\u578B\u5982\u4F55\u4F7F\u7528\u5F53\u524D\u79C1\u804A\u6D88\u606F\u7684 <dsh_im_source> \u6765\u6E90\u5B57\u6BB5\u3002\u53EA\u586B\u5199\u6B63\u6587\uFF0C\u63D2\u4EF6\u4F1A\u81EA\u52A8\u6DFB\u52A0 <dsh_im_source_guidance> \u6210\u5BF9\u6807\u7B7E\u3002",
|
|
2733
|
+
guidanceBehavior: "\u4EC5\u5728\u79C1\u804A\u5F00\u5173\u5F00\u542F\u65F6\u4F7F\u7528\u3002\u6E05\u7A7A\u5E76\u4FDD\u5B58\u540E\u4E0D\u518D\u9644\u52A0\u79C1\u804A\u589E\u5F3A\u63D0\u793A\u8BCD\uFF1B\u6240\u9009\u6765\u6E90\u5B57\u6BB5\u4ECD\u6309\u5F53\u524D\u573A\u666F\u8BBE\u7F6E\u53D1\u9001\u3002"
|
|
2734
|
+
})
|
|
2735
|
+
});
|
|
2659
2736
|
function contextEnhancementLabel(config) {
|
|
2660
|
-
const {
|
|
2661
|
-
if (
|
|
2662
|
-
if (
|
|
2663
|
-
if (
|
|
2737
|
+
const { group, direct } = normalizeContextEnhancementConfig(config);
|
|
2738
|
+
if (group.enabled && direct.enabled) return "\u7FA4\u804A\u548C\u79C1\u804A";
|
|
2739
|
+
if (group.enabled) return "\u4EC5\u7FA4\u804A";
|
|
2740
|
+
if (direct.enabled) return "\u4EC5\u79C1\u804A";
|
|
2664
2741
|
return "\u672A\u5F00\u542F";
|
|
2665
2742
|
}
|
|
2666
2743
|
function ContextIcon({ kind = "sliders" }) {
|
|
@@ -2678,26 +2755,197 @@ function ContextIcon({ kind = "sliders" }) {
|
|
|
2678
2755
|
focusable: "false"
|
|
2679
2756
|
}, h2("path", { d: path }));
|
|
2680
2757
|
}
|
|
2758
|
+
function ContextEnhancementScopeEditor({
|
|
2759
|
+
kind,
|
|
2760
|
+
scope,
|
|
2761
|
+
example,
|
|
2762
|
+
supported,
|
|
2763
|
+
busy,
|
|
2764
|
+
idPrefix,
|
|
2765
|
+
onChange
|
|
2766
|
+
}) {
|
|
2767
|
+
const copy = SCOPE_COPY[kind];
|
|
2768
|
+
const unavailableId = `${idPrefix}-${kind}-unavailable`;
|
|
2769
|
+
const fieldsHelpId = `${idPrefix}-${kind}-fields-help`;
|
|
2770
|
+
const senderNameHelpId = `${idPrefix}-${kind}-sender-name-help`;
|
|
2771
|
+
const guidanceId = `${idPrefix}-${kind}-guidance`;
|
|
2772
|
+
const guidanceHelpId = `${idPrefix}-${kind}-guidance-help`;
|
|
2773
|
+
const disabled = busy || !supported;
|
|
2774
|
+
return h2(
|
|
2775
|
+
"fieldset",
|
|
2776
|
+
{
|
|
2777
|
+
className: "dim-contextSection dim-contextScope",
|
|
2778
|
+
"data-context-kind": kind,
|
|
2779
|
+
"aria-label": copy.title,
|
|
2780
|
+
disabled
|
|
2781
|
+
},
|
|
2782
|
+
h2(
|
|
2783
|
+
"label",
|
|
2784
|
+
{ className: "dim-contextSwitchRow" },
|
|
2785
|
+
h2(
|
|
2786
|
+
"span",
|
|
2787
|
+
{ className: "dim-contextSwitchLabel" },
|
|
2788
|
+
h2("span", null, copy.enable),
|
|
2789
|
+
!supported ? h2("span", {
|
|
2790
|
+
id: unavailableId,
|
|
2791
|
+
className: "dim-contextUnavailable"
|
|
2792
|
+
}, "\uFF08\u5F53\u524D\u6E20\u9053\u4E0D\u652F\u6301\u7FA4\u804A\uFF09") : null
|
|
2793
|
+
),
|
|
2794
|
+
h2("input", {
|
|
2795
|
+
type: "checkbox",
|
|
2796
|
+
role: "switch",
|
|
2797
|
+
className: "dim-contextSwitch",
|
|
2798
|
+
checked: supported && scope.enabled,
|
|
2799
|
+
disabled,
|
|
2800
|
+
"aria-describedby": !supported ? unavailableId : void 0,
|
|
2801
|
+
onChange: (event) => {
|
|
2802
|
+
if (supported) onChange("enabled", event.target.checked);
|
|
2803
|
+
}
|
|
2804
|
+
})
|
|
2805
|
+
),
|
|
2806
|
+
h2(
|
|
2807
|
+
"div",
|
|
2808
|
+
{ className: "dim-contextScopeBlock" },
|
|
2809
|
+
h2(
|
|
2810
|
+
"div",
|
|
2811
|
+
{ className: "dim-contextLegend" },
|
|
2812
|
+
h2("span", null, "\u6765\u6E90\u5B57\u6BB5"),
|
|
2813
|
+
h2(
|
|
2814
|
+
"span",
|
|
2815
|
+
{ className: "dim-contextHelp dim-contextLegendHelp" },
|
|
2816
|
+
h2("button", {
|
|
2817
|
+
type: "button",
|
|
2818
|
+
className: "dim-contextHelpButton",
|
|
2819
|
+
disabled,
|
|
2820
|
+
"aria-label": copy.fieldsHelpLabel,
|
|
2821
|
+
"aria-describedby": fieldsHelpId
|
|
2822
|
+
}, h2("span", { "aria-hidden": "true" }, "?")),
|
|
2823
|
+
h2(
|
|
2824
|
+
"span",
|
|
2825
|
+
{ id: fieldsHelpId, className: "dim-contextTooltip dim-contextLegendTooltip", role: "tooltip" },
|
|
2826
|
+
"\u589E\u5F3A\u63D0\u793A\u8BCD\u4E2D\u8BF7\u4F7F\u7528\u5B57\u6BB5\u540D\uFF08\u5982 senderId\u3001conversationType\uFF09\u5F15\u7528\u8FD9\u4E9B\u4FE1\u606F\u3002\u53EA\u53D1\u9001\u5F53\u524D\u4F1A\u8BDD\u4E2D\u52FE\u9009\u4E14\u53EF\u7528\u7684\u5B57\u6BB5\uFF0C\u4E0D\u4F1A\u989D\u5916\u67E5\u8BE2\u6216\u8865\u5168\u3002"
|
|
2827
|
+
)
|
|
2828
|
+
)
|
|
2829
|
+
),
|
|
2830
|
+
h2("div", { className: "dim-contextFields" }, CONTEXT_ENHANCEMENT_FIELDS.map((field) => {
|
|
2831
|
+
const fieldId = `${idPrefix}-${kind}-field-${field}`;
|
|
2832
|
+
return h2(
|
|
2833
|
+
"div",
|
|
2834
|
+
{ key: field, className: "dim-contextField" },
|
|
2835
|
+
h2("input", {
|
|
2836
|
+
id: fieldId,
|
|
2837
|
+
type: "checkbox",
|
|
2838
|
+
name: `${kind}-${field}`,
|
|
2839
|
+
checked: scope.fields.includes(field),
|
|
2840
|
+
disabled,
|
|
2841
|
+
onChange: (event) => onChange("fields", event.target.checked ? [...scope.fields, field] : scope.fields.filter((value) => value !== field))
|
|
2842
|
+
}),
|
|
2843
|
+
h2(
|
|
2844
|
+
"span",
|
|
2845
|
+
{ className: "dim-contextFieldText" },
|
|
2846
|
+
h2("label", { className: "dim-contextFieldName", htmlFor: fieldId }, FIELD_LABELS[field]),
|
|
2847
|
+
field === "senderName" ? h2(
|
|
2848
|
+
"span",
|
|
2849
|
+
{ className: "dim-contextHelp dim-contextFieldHelp" },
|
|
2850
|
+
h2("button", {
|
|
2851
|
+
type: "button",
|
|
2852
|
+
className: "dim-contextHelpButton dim-contextFieldHelpButton",
|
|
2853
|
+
disabled,
|
|
2854
|
+
"aria-label": copy.senderNameHelpLabel,
|
|
2855
|
+
"aria-describedby": senderNameHelpId
|
|
2856
|
+
}, h2("span", { "aria-hidden": "true" }, "?")),
|
|
2857
|
+
h2("span", {
|
|
2858
|
+
id: senderNameHelpId,
|
|
2859
|
+
className: "dim-contextTooltip dim-contextFieldTooltip",
|
|
2860
|
+
role: "tooltip"
|
|
2861
|
+
}, "\u8BE5\u5B57\u6BB5\u4E0D\u662F\u6BCF\u4E2A\u6E20\u9053\u90FD\u80FD\u63D0\u4F9B\u3002\u5F53\u524D\u6D88\u606F\u6CA1\u6709\u53D1\u9001\u8005\u6635\u79F0\u65F6\uFF0C\u5373\u4F7F\u5DF2\u9009\u62E9\u8BE5\u5B57\u6BB5\uFF0C<dsh_im_source> \u4E2D\u4E5F\u4F1A\u7701\u7565 senderName\u3002")
|
|
2862
|
+
) : null,
|
|
2863
|
+
h2("label", { className: "dim-contextFieldKey", htmlFor: fieldId }, field)
|
|
2864
|
+
)
|
|
2865
|
+
);
|
|
2866
|
+
}))
|
|
2867
|
+
),
|
|
2868
|
+
h2(
|
|
2869
|
+
"div",
|
|
2870
|
+
{ className: "dim-contextGuidance dim-contextScopeBlock" },
|
|
2871
|
+
h2(
|
|
2872
|
+
"div",
|
|
2873
|
+
{ className: "dim-contextEditorHeader" },
|
|
2874
|
+
h2(
|
|
2875
|
+
"span",
|
|
2876
|
+
{ className: "dim-contextEditorTitle" },
|
|
2877
|
+
h2("label", { htmlFor: guidanceId }, copy.guidanceLabel),
|
|
2878
|
+
h2(
|
|
2879
|
+
"span",
|
|
2880
|
+
{ className: "dim-contextHelp" },
|
|
2881
|
+
h2("button", {
|
|
2882
|
+
type: "button",
|
|
2883
|
+
className: "dim-contextHelpButton",
|
|
2884
|
+
disabled,
|
|
2885
|
+
"aria-label": copy.guidanceHelpLabel,
|
|
2886
|
+
"aria-describedby": guidanceHelpId
|
|
2887
|
+
}, h2("span", { "aria-hidden": "true" }, "?")),
|
|
2888
|
+
h2(
|
|
2889
|
+
"span",
|
|
2890
|
+
{ id: guidanceHelpId, className: "dim-contextTooltip dim-contextGuidanceTooltip", role: "tooltip" },
|
|
2891
|
+
h2("strong", null, "\u4F7F\u7528\u8BF4\u660E"),
|
|
2892
|
+
h2("span", null, copy.guidanceUsage),
|
|
2893
|
+
h2("strong", null, "\u751F\u6548\u89C4\u5219"),
|
|
2894
|
+
h2("span", null, copy.guidanceBehavior),
|
|
2895
|
+
h2("strong", null, "\u9690\u79C1\u63D0\u793A"),
|
|
2896
|
+
h2("span", null, "\u53D1\u9001\u8005\u6807\u8BC6\u53EF\u80FD\u5305\u542B\u5E73\u53F0\u7528\u6237 ID \u6216\u7535\u8BDD\u53F7\u7801\u5F62\u5F0F\u7684\u6807\u8BC6\u3002\u5173\u95ED\u5F00\u5173\u4E0D\u4F1A\u5220\u9664\u5DF2\u7ECF\u5199\u5165\u4F1A\u8BDD\u5386\u53F2\u7684\u4FE1\u606F\u3002"),
|
|
2897
|
+
h2("strong", null, "\u4F7F\u7528\u793A\u4F8B"),
|
|
2898
|
+
h2("span", { className: "dim-contextTooltipExample" }, example)
|
|
2899
|
+
)
|
|
2900
|
+
)
|
|
2901
|
+
),
|
|
2902
|
+
h2(
|
|
2903
|
+
"div",
|
|
2904
|
+
{ className: "dim-contextTextActions" },
|
|
2905
|
+
h2("button", { type: "button", disabled, onClick: () => onChange("guidance", example) }, "\u586B\u5165\u793A\u4F8B"),
|
|
2906
|
+
h2("button", { type: "button", disabled, onClick: () => onChange("guidance", "") }, "\u6E05\u7A7A")
|
|
2907
|
+
)
|
|
2908
|
+
),
|
|
2909
|
+
h2("textarea", {
|
|
2910
|
+
id: guidanceId,
|
|
2911
|
+
value: scope.guidance,
|
|
2912
|
+
placeholder: example,
|
|
2913
|
+
rows: 4,
|
|
2914
|
+
disabled,
|
|
2915
|
+
"data-context-kind": kind,
|
|
2916
|
+
maxLength: CONTEXT_ENHANCEMENT_GUIDANCE_MAX_LENGTH,
|
|
2917
|
+
"aria-describedby": guidanceHelpId,
|
|
2918
|
+
onChange: (event) => onChange("guidance", event.target.value)
|
|
2919
|
+
})
|
|
2920
|
+
)
|
|
2921
|
+
);
|
|
2922
|
+
}
|
|
2681
2923
|
function ContextEnhancementDialog({ config, groupSupported, disabled, onSave, onClose, returnFocusRef, id: id5 }) {
|
|
2682
|
-
const [draft, setDraft] = React7.useState(() =>
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
|
|
2924
|
+
const [draft, setDraft] = React7.useState(() => {
|
|
2925
|
+
const normalized = normalizeContextEnhancementConfig(config);
|
|
2926
|
+
return {
|
|
2927
|
+
...normalized,
|
|
2928
|
+
...!groupSupported ? {
|
|
2929
|
+
group: { ...normalized.group, enabled: false }
|
|
2930
|
+
} : {}
|
|
2931
|
+
};
|
|
2932
|
+
});
|
|
2686
2933
|
const [saving, setSaving] = React7.useState(false);
|
|
2687
2934
|
const [error, setError] = React7.useState(null);
|
|
2935
|
+
const [activeScope, setActiveScope] = React7.useState("direct");
|
|
2688
2936
|
const savingRef = React7.useRef(false);
|
|
2689
2937
|
const dialogRef = React7.useRef(null);
|
|
2690
2938
|
const mountedRef = React7.useRef(true);
|
|
2939
|
+
const groupTabRef = React7.useRef(null);
|
|
2940
|
+
const directTabRef = React7.useRef(null);
|
|
2691
2941
|
const titleId = React7.useId();
|
|
2692
2942
|
const descriptionId = React7.useId();
|
|
2693
|
-
const
|
|
2694
|
-
const
|
|
2695
|
-
const
|
|
2696
|
-
const fieldIdPrefix = React7.useId();
|
|
2697
|
-
const fieldsHelpId = React7.useId();
|
|
2698
|
-
const senderNameHelpId = React7.useId();
|
|
2699
|
-
const guidanceExample = localizeText(CONTEXT_GUIDANCE_EXAMPLE);
|
|
2943
|
+
const scopeIdPrefix = React7.useId();
|
|
2944
|
+
const groupGuidanceExample = localizeText(CONTEXT_GROUP_GUIDANCE_EXAMPLE);
|
|
2945
|
+
const directGuidanceExample = localizeText(CONTEXT_DIRECT_GUIDANCE_EXAMPLE);
|
|
2700
2946
|
const busy = disabled || saving;
|
|
2947
|
+
const scopeKinds = ["direct", "group"];
|
|
2948
|
+
const tabRefs = { group: groupTabRef, direct: directTabRef };
|
|
2701
2949
|
React7.useEffect(() => {
|
|
2702
2950
|
mountedRef.current = true;
|
|
2703
2951
|
dialogRef.current?.focus?.();
|
|
@@ -2711,14 +2959,34 @@ function ContextEnhancementDialog({ config, groupSupported, disabled, onSave, on
|
|
|
2711
2959
|
queueMicrotask(() => returnFocusRef.current?.focus?.());
|
|
2712
2960
|
};
|
|
2713
2961
|
}, [returnFocusRef]);
|
|
2714
|
-
const
|
|
2962
|
+
const changeScope = (kind, key, value) => {
|
|
2715
2963
|
if (busy || savingRef.current) return;
|
|
2716
|
-
setDraft((current) => ({
|
|
2964
|
+
setDraft((current) => ({
|
|
2965
|
+
...current,
|
|
2966
|
+
[kind]: { ...current[kind], [key]: value }
|
|
2967
|
+
}));
|
|
2717
2968
|
setError(null);
|
|
2718
2969
|
};
|
|
2719
2970
|
const cancel = () => {
|
|
2720
2971
|
if (!savingRef.current) onClose();
|
|
2721
2972
|
};
|
|
2973
|
+
const activateScope = (kind, focus = false) => {
|
|
2974
|
+
if (busy || !scopeKinds.includes(kind)) return;
|
|
2975
|
+
setActiveScope(kind);
|
|
2976
|
+
if (focus) tabRefs[kind].current?.focus?.();
|
|
2977
|
+
};
|
|
2978
|
+
const handleTabKeyDown = (event, kind) => {
|
|
2979
|
+
let next;
|
|
2980
|
+
if (event.key === "Home") next = scopeKinds[0];
|
|
2981
|
+
else if (event.key === "End") next = scopeKinds.at(-1);
|
|
2982
|
+
else if (event.key === "ArrowLeft" || event.key === "ArrowRight") {
|
|
2983
|
+
const offset = event.key === "ArrowRight" ? 1 : -1;
|
|
2984
|
+
next = scopeKinds[(scopeKinds.indexOf(kind) + offset + scopeKinds.length) % scopeKinds.length];
|
|
2985
|
+
}
|
|
2986
|
+
if (!next) return;
|
|
2987
|
+
event.preventDefault();
|
|
2988
|
+
activateScope(next, true);
|
|
2989
|
+
};
|
|
2722
2990
|
const save = async () => {
|
|
2723
2991
|
if (busy || savingRef.current) return;
|
|
2724
2992
|
savingRef.current = true;
|
|
@@ -2812,166 +3080,45 @@ function ContextEnhancementDialog({ config, groupSupported, disabled, onSave, on
|
|
|
2812
3080
|
onClick: cancel
|
|
2813
3081
|
}, h2(ContextIcon, { kind: "close" }))
|
|
2814
3082
|
),
|
|
2815
|
-
h2(
|
|
2816
|
-
"fieldset",
|
|
2817
|
-
{ className: "dim-contextSection", disabled: busy },
|
|
2818
|
-
h2("legend", null, "\u542F\u7528\u8303\u56F4"),
|
|
2819
|
-
h2(
|
|
2820
|
-
"div",
|
|
2821
|
-
{ className: "dim-contextSwitches" },
|
|
2822
|
-
h2(
|
|
2823
|
-
"label",
|
|
2824
|
-
{ className: "dim-contextSwitchRow" },
|
|
2825
|
-
h2(
|
|
2826
|
-
"span",
|
|
2827
|
-
{ className: "dim-contextSwitchLabel" },
|
|
2828
|
-
h2("span", null, "\u7FA4\u804A\u4E2D\u542F\u7528"),
|
|
2829
|
-
!groupSupported ? h2("span", {
|
|
2830
|
-
id: groupNoticeId,
|
|
2831
|
-
className: "dim-contextUnavailable"
|
|
2832
|
-
}, "\uFF08\u5F53\u524D\u6E20\u9053\u4E0D\u652F\u6301\u7FA4\u804A\uFF09") : null
|
|
2833
|
-
),
|
|
2834
|
-
h2("input", {
|
|
2835
|
-
type: "checkbox",
|
|
2836
|
-
role: "switch",
|
|
2837
|
-
className: "dim-contextSwitch",
|
|
2838
|
-
checked: groupSupported && draft.groupEnabled,
|
|
2839
|
-
disabled: busy || !groupSupported,
|
|
2840
|
-
"aria-describedby": !groupSupported ? groupNoticeId : void 0,
|
|
2841
|
-
onChange: (event) => {
|
|
2842
|
-
if (groupSupported) change("groupEnabled", event.target.checked);
|
|
2843
|
-
}
|
|
2844
|
-
})
|
|
2845
|
-
),
|
|
2846
|
-
h2(
|
|
2847
|
-
"label",
|
|
2848
|
-
{ className: "dim-contextSwitchRow" },
|
|
2849
|
-
h2("span", null, "\u79C1\u804A\u4E2D\u542F\u7528"),
|
|
2850
|
-
h2("input", {
|
|
2851
|
-
type: "checkbox",
|
|
2852
|
-
role: "switch",
|
|
2853
|
-
className: "dim-contextSwitch",
|
|
2854
|
-
checked: draft.directEnabled,
|
|
2855
|
-
disabled: busy,
|
|
2856
|
-
onChange: (event) => change("directEnabled", event.target.checked)
|
|
2857
|
-
})
|
|
2858
|
-
)
|
|
2859
|
-
)
|
|
2860
|
-
),
|
|
2861
|
-
h2(
|
|
2862
|
-
"fieldset",
|
|
2863
|
-
{ className: "dim-contextSection", disabled: busy },
|
|
2864
|
-
h2(
|
|
2865
|
-
"legend",
|
|
2866
|
-
{ className: "dim-contextLegend" },
|
|
2867
|
-
h2("span", null, "\u6765\u6E90\u5B57\u6BB5"),
|
|
2868
|
-
h2(
|
|
2869
|
-
"span",
|
|
2870
|
-
{ className: "dim-contextHelp dim-contextLegendHelp" },
|
|
2871
|
-
h2("button", {
|
|
2872
|
-
type: "button",
|
|
2873
|
-
className: "dim-contextHelpButton",
|
|
2874
|
-
disabled: busy,
|
|
2875
|
-
"aria-label": "\u67E5\u770B\u6765\u6E90\u5B57\u6BB5\u8BF4\u660E",
|
|
2876
|
-
"aria-describedby": fieldsHelpId
|
|
2877
|
-
}, h2("span", { "aria-hidden": "true" }, "?")),
|
|
2878
|
-
h2(
|
|
2879
|
-
"span",
|
|
2880
|
-
{ id: fieldsHelpId, className: "dim-contextTooltip dim-contextLegendTooltip", role: "tooltip" },
|
|
2881
|
-
"\u589E\u5F3A\u63D0\u793A\u8BCD\u4E2D\u8BF7\u4F7F\u7528\u5B57\u6BB5\u540D\uFF08\u5982 senderId\u3001conversationType\uFF09\u5F15\u7528\u8FD9\u4E9B\u4FE1\u606F\u3002\u53EA\u53D1\u9001\u52FE\u9009\u4E14\u5F53\u524D\u6D88\u606F\u4E2D\u53EF\u7528\u7684\u5B57\u6BB5\uFF0C\u4E0D\u4F1A\u989D\u5916\u67E5\u8BE2\u6216\u8865\u5168\u3002"
|
|
2882
|
-
)
|
|
2883
|
-
)
|
|
2884
|
-
),
|
|
2885
|
-
h2("div", { className: "dim-contextFields" }, CONTEXT_ENHANCEMENT_FIELDS.map((field) => {
|
|
2886
|
-
const fieldId = `${fieldIdPrefix}-${field}`;
|
|
2887
|
-
return h2(
|
|
2888
|
-
"div",
|
|
2889
|
-
{ key: field, className: "dim-contextField" },
|
|
2890
|
-
h2("input", {
|
|
2891
|
-
id: fieldId,
|
|
2892
|
-
type: "checkbox",
|
|
2893
|
-
name: field,
|
|
2894
|
-
checked: draft.fields.includes(field),
|
|
2895
|
-
disabled: busy,
|
|
2896
|
-
onChange: (event) => change("fields", event.target.checked ? [...draft.fields, field] : draft.fields.filter((value) => value !== field))
|
|
2897
|
-
}),
|
|
2898
|
-
h2(
|
|
2899
|
-
"span",
|
|
2900
|
-
{ className: "dim-contextFieldText" },
|
|
2901
|
-
h2("label", { className: "dim-contextFieldName", htmlFor: fieldId }, FIELD_LABELS[field]),
|
|
2902
|
-
field === "senderName" ? h2(
|
|
2903
|
-
"span",
|
|
2904
|
-
{ className: "dim-contextHelp dim-contextFieldHelp" },
|
|
2905
|
-
h2("button", {
|
|
2906
|
-
type: "button",
|
|
2907
|
-
className: "dim-contextHelpButton dim-contextFieldHelpButton",
|
|
2908
|
-
disabled: busy,
|
|
2909
|
-
"aria-label": "\u67E5\u770B\u53D1\u9001\u8005\u6635\u79F0\u5B57\u6BB5\u8BF4\u660E",
|
|
2910
|
-
"aria-describedby": senderNameHelpId
|
|
2911
|
-
}, h2("span", { "aria-hidden": "true" }, "?")),
|
|
2912
|
-
h2("span", {
|
|
2913
|
-
id: senderNameHelpId,
|
|
2914
|
-
className: "dim-contextTooltip dim-contextFieldTooltip",
|
|
2915
|
-
role: "tooltip"
|
|
2916
|
-
}, "\u8BE5\u5B57\u6BB5\u4E0D\u662F\u6BCF\u4E2A\u6E20\u9053\u90FD\u80FD\u63D0\u4F9B\u3002\u5F53\u524D\u6D88\u606F\u6CA1\u6709\u53D1\u9001\u8005\u6635\u79F0\u65F6\uFF0C\u5373\u4F7F\u5DF2\u9009\u62E9\u8BE5\u5B57\u6BB5\uFF0C<dsh_im_source> \u4E2D\u4E5F\u4F1A\u7701\u7565 senderName\u3002")
|
|
2917
|
-
) : null,
|
|
2918
|
-
h2("label", { className: "dim-contextFieldKey", htmlFor: fieldId }, field)
|
|
2919
|
-
)
|
|
2920
|
-
);
|
|
2921
|
-
}))
|
|
2922
|
-
),
|
|
2923
3083
|
h2(
|
|
2924
3084
|
"div",
|
|
2925
|
-
{ className: "dim-
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
|
|
2934
|
-
|
|
2935
|
-
|
|
2936
|
-
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
|
|
2940
|
-
|
|
2941
|
-
|
|
2942
|
-
|
|
2943
|
-
h2(
|
|
2944
|
-
"span",
|
|
2945
|
-
{ id: guidanceHelpId, className: "dim-contextTooltip dim-contextGuidanceTooltip", role: "tooltip" },
|
|
2946
|
-
h2("strong", null, "\u4F7F\u7528\u8BF4\u660E"),
|
|
2947
|
-
h2("span", null, "\u7528\u4E8E\u544A\u8BC9\u6A21\u578B\u5982\u4F55\u4F7F\u7528 <dsh_im_source> \u4E2D\u5DF2\u9009\u62E9\u7684\u6765\u6E90\u5B57\u6BB5\u3002\u53EA\u586B\u5199\u6B63\u6587\uFF0C\u63D2\u4EF6\u4F1A\u81EA\u52A8\u6DFB\u52A0 <dsh_im_source_guidance> \u6210\u5BF9\u6807\u7B7E\u3002"),
|
|
2948
|
-
h2("strong", null, "\u751F\u6548\u89C4\u5219"),
|
|
2949
|
-
h2("span", null, "\u53EA\u9700\u586B\u5199\u6B63\u6587\uFF0C\u63D2\u4EF6\u81EA\u52A8\u6DFB\u52A0 <dsh_im_source_guidance> \u6210\u5BF9\u6807\u7B7E\u3002\u6E05\u7A7A\u5E76\u4FDD\u5B58\u540E\uFF0C\u4E0D\u518D\u9644\u52A0\u589E\u5F3A\u63D0\u793A\u8BCD\uFF0C\u5DF2\u9009\u6765\u6E90\u5B57\u6BB5\u4ECD\u6309\u5F00\u5173\u8BBE\u7F6E\u53D1\u9001\u3002"),
|
|
2950
|
-
h2("strong", null, "\u9690\u79C1\u63D0\u793A"),
|
|
2951
|
-
h2("span", null, "\u53D1\u9001\u8005\u6807\u8BC6\u53EF\u80FD\u5305\u542B\u5E73\u53F0\u7528\u6237 ID \u6216\u7535\u8BDD\u53F7\u7801\u5F62\u5F0F\u7684\u6807\u8BC6\u3002\u5173\u95ED\u5F00\u5173\u4E0D\u4F1A\u5220\u9664\u5DF2\u7ECF\u5199\u5165\u4F1A\u8BDD\u5386\u53F2\u7684\u4FE1\u606F\u3002"),
|
|
2952
|
-
h2("strong", null, "\u4F7F\u7528\u793A\u4F8B"),
|
|
2953
|
-
h2("span", { className: "dim-contextTooltipExample" }, guidanceExample)
|
|
2954
|
-
)
|
|
2955
|
-
)
|
|
2956
|
-
),
|
|
2957
|
-
h2(
|
|
2958
|
-
"div",
|
|
2959
|
-
{ className: "dim-contextTextActions" },
|
|
2960
|
-
h2("button", { type: "button", disabled: busy, onClick: () => change("guidance", guidanceExample) }, "\u586B\u5165\u793A\u4F8B"),
|
|
2961
|
-
h2("button", { type: "button", disabled: busy, onClick: () => change("guidance", "") }, "\u6E05\u7A7A")
|
|
2962
|
-
)
|
|
2963
|
-
),
|
|
2964
|
-
h2("textarea", {
|
|
2965
|
-
id: guidanceId,
|
|
2966
|
-
value: draft.guidance,
|
|
2967
|
-
placeholder: guidanceExample,
|
|
2968
|
-
rows: 4,
|
|
2969
|
-
disabled: busy,
|
|
2970
|
-
maxLength: CONTEXT_ENHANCEMENT_GUIDANCE_MAX_LENGTH,
|
|
2971
|
-
"aria-describedby": guidanceHelpId,
|
|
2972
|
-
onChange: (event) => change("guidance", event.target.value)
|
|
3085
|
+
{ className: "dim-contextTabs", role: "tablist", "aria-label": "\u4E0A\u4E0B\u6587\u589E\u5F3A\u8303\u56F4" },
|
|
3086
|
+
scopeKinds.map((kind) => {
|
|
3087
|
+
const selected = activeScope === kind;
|
|
3088
|
+
return h2("button", {
|
|
3089
|
+
key: kind,
|
|
3090
|
+
id: `${scopeIdPrefix}-${kind}-tab`,
|
|
3091
|
+
ref: tabRefs[kind],
|
|
3092
|
+
type: "button",
|
|
3093
|
+
role: "tab",
|
|
3094
|
+
className: "dim-contextTab",
|
|
3095
|
+
"data-context-kind": kind,
|
|
3096
|
+
"aria-selected": selected,
|
|
3097
|
+
"aria-controls": `${scopeIdPrefix}-${kind}-panel`,
|
|
3098
|
+
tabIndex: selected ? 0 : -1,
|
|
3099
|
+
disabled: busy,
|
|
3100
|
+
onClick: () => activateScope(kind),
|
|
3101
|
+
onKeyDown: (event) => handleTabKeyDown(event, kind)
|
|
3102
|
+
}, SCOPE_COPY[kind].title);
|
|
2973
3103
|
})
|
|
2974
3104
|
),
|
|
3105
|
+
scopeKinds.map((kind) => h2("div", {
|
|
3106
|
+
key: kind,
|
|
3107
|
+
id: `${scopeIdPrefix}-${kind}-panel`,
|
|
3108
|
+
className: "dim-contextTabPanel",
|
|
3109
|
+
role: "tabpanel",
|
|
3110
|
+
"data-context-kind": kind,
|
|
3111
|
+
"aria-labelledby": `${scopeIdPrefix}-${kind}-tab`,
|
|
3112
|
+
hidden: activeScope !== kind
|
|
3113
|
+
}, h2(ContextEnhancementScopeEditor, {
|
|
3114
|
+
kind,
|
|
3115
|
+
scope: draft[kind],
|
|
3116
|
+
example: kind === "group" ? groupGuidanceExample : directGuidanceExample,
|
|
3117
|
+
supported: kind === "group" ? groupSupported : true,
|
|
3118
|
+
busy,
|
|
3119
|
+
idPrefix: scopeIdPrefix,
|
|
3120
|
+
onChange: (key, value) => changeScope(kind, key, value)
|
|
3121
|
+
}))),
|
|
2975
3122
|
error ? h2("p", { className: "dim-contextError", role: "alert" }, error) : null,
|
|
2976
3123
|
h2(
|
|
2977
3124
|
"footer",
|
|
@@ -2995,7 +3142,10 @@ function ContextEnhancementEditor({ config, groupSupported = true, disabled = fa
|
|
|
2995
3142
|
const dialogId = React7.useId();
|
|
2996
3143
|
const statusId = React7.useId();
|
|
2997
3144
|
const saved = normalizeContextEnhancementConfig(config);
|
|
2998
|
-
const label = contextEnhancementLabel(groupSupported ? saved : {
|
|
3145
|
+
const label = contextEnhancementLabel(groupSupported ? saved : {
|
|
3146
|
+
...saved,
|
|
3147
|
+
group: { ...saved.group, enabled: false }
|
|
3148
|
+
});
|
|
2999
3149
|
return h2(
|
|
3000
3150
|
React7.Fragment,
|
|
3001
3151
|
null,
|
|
@@ -12776,10 +12926,15 @@ var CSS11 = String.raw`
|
|
|
12776
12926
|
.dim-contextHeaderTooltip { width: min(340px, calc(100vw - 72px)); }
|
|
12777
12927
|
.dim-contextClose { width: 30px; height: 30px; flex: none; display: grid; place-items: center; padding: 0; border: 0; border-radius: 6px; color: var(--dsw-alias-label-secondary, #646a73); background: transparent; cursor: pointer; }
|
|
12778
12928
|
.dim-contextClose:hover:not(:disabled) { background: var(--dsw-alias-interactive-bg-hover, #eef0f3); }
|
|
12779
|
-
.dim-
|
|
12780
|
-
.dim-
|
|
12929
|
+
.dim-contextTabs { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 3px; margin-top: 14px; padding: 3px; border: 1px solid var(--dsw-alias-border-l1, #eef0f3); border-radius: 8px; background: var(--dsw-alias-bg-module-platform, #f7f8fa); }
|
|
12930
|
+
.dim-contextTab { min-width: 0; min-height: 34px; padding: 5px 12px; border: 0; border-radius: 6px; color: var(--dsw-alias-label-secondary, #646a73); background: transparent; font: inherit; font-weight: 500; cursor: pointer; transition: color .15s ease, background .15s ease, box-shadow .15s ease; }
|
|
12931
|
+
.dim-contextTab:hover:not(:disabled):not([aria-selected="true"]) { color: var(--dsw-alias-label-primary, #1f2329); background: var(--dsw-alias-interactive-bg-hover, #eef0f3); }
|
|
12932
|
+
.dim-contextTab[aria-selected="true"] { color: var(--dsw-alias-state-business-primary, #3370ff); background: var(--dsw-alias-bg-layer-1, #fff); box-shadow: 0 1px 3px rgb(31 35 41 / 12%); }
|
|
12933
|
+
.dim-contextTabPanel[hidden] { display: none; }
|
|
12934
|
+
.dim-contextSection { min-width: 0; margin: 0; padding: 0; border: 0; }
|
|
12935
|
+
.dim-contextScope { margin-top: 10px; padding: 12px; border: 1px solid var(--dsw-alias-border-l2, #dfe1e5); border-radius: 9px; background: var(--dsw-alias-bg-layer-1, #fff); }
|
|
12936
|
+
.dim-contextScopeBlock { margin-top: 12px; }
|
|
12781
12937
|
.dim-contextLegend { position: relative; display: inline-flex; align-items: center; gap: 6px; }
|
|
12782
|
-
.dim-contextSwitches { display: grid; grid-template-columns: 1fr; gap: 2px; }
|
|
12783
12938
|
.dim-contextSwitchRow { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-height: 34px; cursor: pointer; }
|
|
12784
12939
|
.dim-contextSwitchLabel { min-width: 0; display: inline-flex; align-items: baseline; gap: 5px; flex-wrap: wrap; }
|
|
12785
12940
|
.dim-contextUnavailable { color: var(--dsw-alias-label-tertiary, #8f959e); font-size: 11px; line-height: 16px; font-weight: 400; }
|
|
@@ -12822,7 +12977,7 @@ var CSS11 = String.raw`
|
|
|
12822
12977
|
.dim-contextEntry:focus-visible, .dim-contextDialog button:focus-visible, .dim-contextDialog input:focus-visible, .dim-contextDialog textarea:focus-visible { outline: 2px solid var(--dsw-alias-state-business-primary, #3370ff); outline-offset: 2px; }
|
|
12823
12978
|
.dim-contextEntry:disabled, .dim-contextDialog button:disabled, .dim-contextDialog input:disabled, .dim-contextDialog textarea:disabled { opacity: .55; cursor: not-allowed; }
|
|
12824
12979
|
@media (pointer: coarse) {
|
|
12825
|
-
.dim-contextEntry, .dim-contextClose, .dim-contextFooter button, .dim-contextTextActions button, .dim-contextField, .dim-contextSwitchRow { min-height: 44px; }
|
|
12980
|
+
.dim-contextEntry, .dim-contextTab, .dim-contextClose, .dim-contextFooter button, .dim-contextTextActions button, .dim-contextField, .dim-contextSwitchRow { min-height: 44px; }
|
|
12826
12981
|
.dim-contextClose, .dim-contextTextActions button { min-width: 44px; }
|
|
12827
12982
|
.dim-contextGuidance textarea { font-size: 16px; }
|
|
12828
12983
|
}
|