mirror of
https://github.com/hansjone/dsh-im-ops.git
synced 2026-10-09 00:33:20 +08:00
Merge pull request #109 from yzxxy010/feat/conversation-title
上下文增强增加 conversationTitle 字段
This commit is contained in:
commit
24f4a1e05b
11 changed files with 82 additions and 30 deletions
|
|
@ -1122,6 +1122,10 @@ var EN = Object.freeze({
|
|||
"\u67E5\u770B\u7FA4\u804A\u53D1\u9001\u8005\u6635\u79F0\u5B57\u6BB5\u8BF4\u660E": "View group sender name field details",
|
||||
"\u67E5\u770B\u79C1\u804A\u53D1\u9001\u8005\u6635\u79F0\u5B57\u6BB5\u8BF4\u660E": "View direct sender name field details",
|
||||
"\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.",
|
||||
"\u4F1A\u8BDD\u6807\u9898": "Conversation title",
|
||||
"\u67E5\u770B\u7FA4\u804A\u4F1A\u8BDD\u6807\u9898\u5B57\u6BB5\u8BF4\u660E": "View group conversation title field details",
|
||||
"\u67E5\u770B\u79C1\u804A\u4F1A\u8BDD\u6807\u9898\u5B57\u6BB5\u8BF4\u660E": "View direct conversation title field details",
|
||||
"\u8BE5\u5B57\u6BB5\u4E0D\u662F\u6BCF\u4E2A\u6E20\u9053\u90FD\u80FD\u63D0\u4F9B\u3002\u9489\u9489\u7FA4\u804A\u4F1A\u5E26\u4E0A\u7FA4\u540D\u3002\u5F53\u524D\u6D88\u606F\u6CA1\u6709\u4F1A\u8BDD\u6807\u9898\u65F6\uFF0C\u5373\u4F7F\u5DF2\u9009\u62E9\u8BE5\u5B57\u6BB5\uFF0C<dsh_im_source> \u4E2D\u4E5F\u4F1A\u7701\u7565 conversationTitle\u3002": "This field is not available on every channel. DingTalk group chats include the group name. If the current message has no conversation title, <dsh_im_source> omits conversationTitle even when the field is selected.",
|
||||
"\u673A\u5668\u4EBA\u6807\u8BC6": "Bot ID",
|
||||
"\u589E\u5F3A\u63D0\u793A\u8BCD": "Guidance",
|
||||
"\u67E5\u770B\u589E\u5F3A\u63D0\u793A\u8BCD\u4F7F\u7528\u8BF4\u660E": "View guidance instructions",
|
||||
|
|
@ -1149,7 +1153,7 @@ var EN = Object.freeze({
|
|||
"\u4E0A\u4E0B\u6587\u589E\u5F3A\u4FDD\u5B58\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5\u3002": "Could not save context enhancement. Try again.",
|
||||
"\u8BF7\u63D0\u4EA4\u5B8C\u6574\u7684\u4E0A\u4E0B\u6587\u589E\u5F3A\u8BBE\u7F6E\u3002": "Submit the complete context enhancement settings.",
|
||||
"\u7FA4\u804A\u548C\u79C1\u804A\u5F00\u5173\u5FC5\u987B\u662F\u5E03\u5C14\u503C\u3002": "Group and direct switches must be booleans.",
|
||||
"\u6765\u6E90\u5B57\u6BB5\u53EA\u80FD\u9009\u62E9\u5DF2\u5B9A\u4E49\u7684\u4E94\u4E2A\u5B57\u6BB5\u3002": "Source fields must be chosen from the five defined fields.",
|
||||
"\u6765\u6E90\u5B57\u6BB5\u53EA\u80FD\u9009\u62E9\u5DF2\u5B9A\u4E49\u7684\u516D\u4E2A\u5B57\u6BB5\u3002": "Source fields must be chosen from the six defined fields.",
|
||||
"\u4FDD\u5B58\u4E2D\u2026": "Saving\u2026",
|
||||
"\u672A\u8BBE\u7F6E": "Not set",
|
||||
"\u5DE5\u4F5C\u533A\u4FEE\u6539\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5\u3002": "Could not update the workspace. Try again.",
|
||||
|
|
@ -2075,6 +2079,7 @@ var CONTEXT_ENHANCEMENT_FIELDS = Object.freeze([
|
|||
"conversationType",
|
||||
"senderId",
|
||||
"senderName",
|
||||
"conversationTitle",
|
||||
"botId"
|
||||
]);
|
||||
var CONTEXT_ENHANCEMENT_GUIDANCE_MAX_LENGTH = 8e3;
|
||||
|
|
@ -2114,7 +2119,7 @@ function validateContextEnhancementScope(input) {
|
|||
throw invalidConfig("\u7FA4\u804A\u548C\u79C1\u804A\u5F00\u5173\u5FC5\u987B\u662F\u5E03\u5C14\u503C\u3002");
|
||||
}
|
||||
if (!Array.isArray(fields) || ![...fields].every((field) => CONTEXT_ENHANCEMENT_FIELDS.includes(field))) {
|
||||
throw invalidConfig("\u6765\u6E90\u5B57\u6BB5\u53EA\u80FD\u9009\u62E9\u5DF2\u5B9A\u4E49\u7684\u4E94\u4E2A\u5B57\u6BB5\u3002");
|
||||
throw invalidConfig("\u6765\u6E90\u5B57\u6BB5\u53EA\u80FD\u9009\u62E9\u5DF2\u5B9A\u4E49\u7684\u516D\u4E2A\u5B57\u6BB5\u3002");
|
||||
}
|
||||
if (typeof guidance !== "string" || guidance.length > CONTEXT_ENHANCEMENT_GUIDANCE_MAX_LENGTH) {
|
||||
throw invalidConfig(`\u589E\u5F3A\u63D0\u793A\u8BCD\u4E0D\u5F97\u8D85\u8FC7 ${CONTEXT_ENHANCEMENT_GUIDANCE_MAX_LENGTH} \u4E2A\u5B57\u7B26\u3002`);
|
||||
|
|
@ -2895,14 +2900,26 @@ var FIELD_LABELS = Object.freeze({
|
|||
conversationType: "\u4F1A\u8BDD\u7C7B\u578B",
|
||||
senderId: "\u53D1\u9001\u8005\u6807\u8BC6",
|
||||
senderName: "\u53D1\u9001\u8005\u6635\u79F0",
|
||||
conversationTitle: "\u4F1A\u8BDD\u6807\u9898",
|
||||
botId: "\u673A\u5668\u4EBA\u6807\u8BC6"
|
||||
});
|
||||
var FIELD_HELP = Object.freeze({
|
||||
senderName: Object.freeze({
|
||||
labelKey: "senderNameHelpLabel",
|
||||
text: "\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"
|
||||
}),
|
||||
conversationTitle: Object.freeze({
|
||||
labelKey: "conversationTitleHelpLabel",
|
||||
text: "\u8BE5\u5B57\u6BB5\u4E0D\u662F\u6BCF\u4E2A\u6E20\u9053\u90FD\u80FD\u63D0\u4F9B\u3002\u9489\u9489\u7FA4\u804A\u4F1A\u5E26\u4E0A\u7FA4\u540D\u3002\u5F53\u524D\u6D88\u606F\u6CA1\u6709\u4F1A\u8BDD\u6807\u9898\u65F6\uFF0C\u5373\u4F7F\u5DF2\u9009\u62E9\u8BE5\u5B57\u6BB5\uFF0C<dsh_im_source> \u4E2D\u4E5F\u4F1A\u7701\u7565 conversationTitle\u3002"
|
||||
})
|
||||
});
|
||||
var SCOPE_COPY = Object.freeze({
|
||||
group: Object.freeze({
|
||||
title: "\u7FA4\u804A",
|
||||
enable: "\u542F\u7528",
|
||||
fieldsHelpLabel: "\u67E5\u770B\u7FA4\u804A\u6765\u6E90\u5B57\u6BB5\u8BF4\u660E",
|
||||
senderNameHelpLabel: "\u67E5\u770B\u7FA4\u804A\u53D1\u9001\u8005\u6635\u79F0\u5B57\u6BB5\u8BF4\u660E",
|
||||
conversationTitleHelpLabel: "\u67E5\u770B\u7FA4\u804A\u4F1A\u8BDD\u6807\u9898\u5B57\u6BB5\u8BF4\u660E",
|
||||
guidanceLabel: "\u589E\u5F3A\u63D0\u793A\u8BCD",
|
||||
guidanceHelpLabel: "\u67E5\u770B\u7FA4\u804A\u589E\u5F3A\u63D0\u793A\u8BCD\u4F7F\u7528\u8BF4\u660E",
|
||||
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",
|
||||
|
|
@ -2913,6 +2930,7 @@ var SCOPE_COPY = Object.freeze({
|
|||
enable: "\u542F\u7528",
|
||||
fieldsHelpLabel: "\u67E5\u770B\u79C1\u804A\u6765\u6E90\u5B57\u6BB5\u8BF4\u660E",
|
||||
senderNameHelpLabel: "\u67E5\u770B\u79C1\u804A\u53D1\u9001\u8005\u6635\u79F0\u5B57\u6BB5\u8BF4\u660E",
|
||||
conversationTitleHelpLabel: "\u67E5\u770B\u79C1\u804A\u4F1A\u8BDD\u6807\u9898\u5B57\u6BB5\u8BF4\u660E",
|
||||
guidanceLabel: "\u589E\u5F3A\u63D0\u793A\u8BCD",
|
||||
guidanceHelpLabel: "\u67E5\u770B\u79C1\u804A\u589E\u5F3A\u63D0\u793A\u8BCD\u4F7F\u7528\u8BF4\u660E",
|
||||
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",
|
||||
|
|
@ -2953,7 +2971,6 @@ function ContextEnhancementScopeEditor({
|
|||
const copy = SCOPE_COPY[kind];
|
||||
const unavailableId = `${idPrefix}-${kind}-unavailable`;
|
||||
const fieldsHelpId = `${idPrefix}-${kind}-fields-help`;
|
||||
const senderNameHelpId = `${idPrefix}-${kind}-sender-name-help`;
|
||||
const guidanceId = `${idPrefix}-${kind}-guidance`;
|
||||
const guidanceHelpId = `${idPrefix}-${kind}-guidance-help`;
|
||||
const disabled = busy || !supported;
|
||||
|
|
@ -3030,21 +3047,21 @@ function ContextEnhancementScopeEditor({
|
|||
"span",
|
||||
{ className: "dim-contextFieldText" },
|
||||
h2("label", { className: "dim-contextFieldName", htmlFor: fieldId }, FIELD_LABELS[field]),
|
||||
field === "senderName" ? h2(
|
||||
FIELD_HELP[field] ? h2(
|
||||
"span",
|
||||
{ className: "dim-contextHelp dim-contextFieldHelp" },
|
||||
h2("button", {
|
||||
type: "button",
|
||||
className: "dim-contextHelpButton dim-contextFieldHelpButton",
|
||||
disabled,
|
||||
"aria-label": copy.senderNameHelpLabel,
|
||||
"aria-describedby": senderNameHelpId
|
||||
"aria-label": copy[FIELD_HELP[field].labelKey],
|
||||
"aria-describedby": `${idPrefix}-${kind}-${field}-help`
|
||||
}, h2("span", { "aria-hidden": "true" }, "?")),
|
||||
h2("span", {
|
||||
id: senderNameHelpId,
|
||||
id: `${idPrefix}-${kind}-${field}-help`,
|
||||
className: "dim-contextTooltip dim-contextFieldTooltip",
|
||||
role: "tooltip"
|
||||
}, "\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")
|
||||
}, FIELD_HELP[field].text)
|
||||
) : null,
|
||||
h2("label", { className: "dim-contextFieldKey", htmlFor: fieldId }, field)
|
||||
)
|
||||
|
|
|
|||
12
lib/index.js
12
lib/index.js
File diff suppressed because one or more lines are too long
|
|
@ -16,15 +16,28 @@ const FIELD_LABELS = Object.freeze({
|
|||
conversationType: '会话类型',
|
||||
senderId: '发送者标识',
|
||||
senderName: '发送者昵称',
|
||||
conversationTitle: '会话标题',
|
||||
botId: '机器人标识',
|
||||
});
|
||||
|
||||
const FIELD_HELP = Object.freeze({
|
||||
senderName: Object.freeze({
|
||||
labelKey: 'senderNameHelpLabel',
|
||||
text: '该字段不是每个渠道都能提供。当前消息没有发送者昵称时,即使已选择该字段,<dsh_im_source> 中也会省略 senderName。',
|
||||
}),
|
||||
conversationTitle: Object.freeze({
|
||||
labelKey: 'conversationTitleHelpLabel',
|
||||
text: '该字段不是每个渠道都能提供。钉钉群聊会带上群名。当前消息没有会话标题时,即使已选择该字段,<dsh_im_source> 中也会省略 conversationTitle。',
|
||||
}),
|
||||
});
|
||||
|
||||
const SCOPE_COPY = Object.freeze({
|
||||
group: Object.freeze({
|
||||
title: '群聊',
|
||||
enable: '启用',
|
||||
fieldsHelpLabel: '查看群聊来源字段说明',
|
||||
senderNameHelpLabel: '查看群聊发送者昵称字段说明',
|
||||
conversationTitleHelpLabel: '查看群聊会话标题字段说明',
|
||||
guidanceLabel: '增强提示词',
|
||||
guidanceHelpLabel: '查看群聊增强提示词使用说明',
|
||||
guidanceUsage: '用于告诉模型如何使用当前群聊消息的 <dsh_im_source> 来源字段。只填写正文,插件会自动添加 <dsh_im_source_guidance> 成对标签。',
|
||||
|
|
@ -35,6 +48,7 @@ const SCOPE_COPY = Object.freeze({
|
|||
enable: '启用',
|
||||
fieldsHelpLabel: '查看私聊来源字段说明',
|
||||
senderNameHelpLabel: '查看私聊发送者昵称字段说明',
|
||||
conversationTitleHelpLabel: '查看私聊会话标题字段说明',
|
||||
guidanceLabel: '增强提示词',
|
||||
guidanceHelpLabel: '查看私聊增强提示词使用说明',
|
||||
guidanceUsage: '用于告诉模型如何使用当前私聊消息的 <dsh_im_source> 来源字段。只填写正文,插件会自动添加 <dsh_im_source_guidance> 成对标签。',
|
||||
|
|
@ -73,7 +87,6 @@ function ContextEnhancementScopeEditor({
|
|||
const copy = SCOPE_COPY[kind];
|
||||
const unavailableId = `${idPrefix}-${kind}-unavailable`;
|
||||
const fieldsHelpId = `${idPrefix}-${kind}-fields-help`;
|
||||
const senderNameHelpId = `${idPrefix}-${kind}-sender-name-help`;
|
||||
const guidanceId = `${idPrefix}-${kind}-guidance`;
|
||||
const guidanceHelpId = `${idPrefix}-${kind}-guidance-help`;
|
||||
const disabled = busy || !supported;
|
||||
|
|
@ -118,16 +131,17 @@ function ContextEnhancementScopeEditor({
|
|||
}),
|
||||
h('span', { className: 'dim-contextFieldText' },
|
||||
h('label', { className: 'dim-contextFieldName', htmlFor: fieldId }, FIELD_LABELS[field]),
|
||||
field === 'senderName' ? h('span', { className: 'dim-contextHelp dim-contextFieldHelp' },
|
||||
FIELD_HELP[field] ? h('span', { className: 'dim-contextHelp dim-contextFieldHelp' },
|
||||
h('button', {
|
||||
type: 'button', className: 'dim-contextHelpButton dim-contextFieldHelpButton', disabled,
|
||||
'aria-label': copy.senderNameHelpLabel, 'aria-describedby': senderNameHelpId,
|
||||
'aria-label': copy[FIELD_HELP[field].labelKey],
|
||||
'aria-describedby': `${idPrefix}-${kind}-${field}-help`,
|
||||
}, h('span', { 'aria-hidden': 'true' }, '?')),
|
||||
h('span', {
|
||||
id: senderNameHelpId,
|
||||
id: `${idPrefix}-${kind}-${field}-help`,
|
||||
className: 'dim-contextTooltip dim-contextFieldTooltip',
|
||||
role: 'tooltip',
|
||||
}, '该字段不是每个渠道都能提供。当前消息没有发送者昵称时,即使已选择该字段,<dsh_im_source> 中也会省略 senderName。')) : null,
|
||||
}, FIELD_HELP[field].text)) : null,
|
||||
h('label', { className: 'dim-contextFieldKey', htmlFor: fieldId }, field)));
|
||||
}))),
|
||||
h('div', { className: 'dim-contextGuidance dim-contextScopeBlock' },
|
||||
|
|
|
|||
|
|
@ -288,6 +288,10 @@ const EN = Object.freeze({
|
|||
'查看群聊发送者昵称字段说明': 'View group sender name field details',
|
||||
'查看私聊发送者昵称字段说明': 'View direct sender name field details',
|
||||
'该字段不是每个渠道都能提供。当前消息没有发送者昵称时,即使已选择该字段,<dsh_im_source> 中也会省略 senderName。': '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.',
|
||||
'会话标题': 'Conversation title',
|
||||
'查看群聊会话标题字段说明': 'View group conversation title field details',
|
||||
'查看私聊会话标题字段说明': 'View direct conversation title field details',
|
||||
'该字段不是每个渠道都能提供。钉钉群聊会带上群名。当前消息没有会话标题时,即使已选择该字段,<dsh_im_source> 中也会省略 conversationTitle。': 'This field is not available on every channel. DingTalk group chats include the group name. If the current message has no conversation title, <dsh_im_source> omits conversationTitle even when the field is selected.',
|
||||
'机器人标识': 'Bot ID',
|
||||
'增强提示词': 'Guidance',
|
||||
'查看增强提示词使用说明': 'View guidance instructions',
|
||||
|
|
@ -315,7 +319,7 @@ const EN = Object.freeze({
|
|||
'上下文增强保存失败,请重试。': 'Could not save context enhancement. Try again.',
|
||||
'请提交完整的上下文增强设置。': 'Submit the complete context enhancement settings.',
|
||||
'群聊和私聊开关必须是布尔值。': 'Group and direct switches must be booleans.',
|
||||
'来源字段只能选择已定义的五个字段。': 'Source fields must be chosen from the five defined fields.',
|
||||
'来源字段只能选择已定义的六个字段。': 'Source fields must be chosen from the six defined fields.',
|
||||
'保存中…': 'Saving…',
|
||||
'未设置': 'Not set',
|
||||
'工作区修改失败,请重试。': 'Could not update the workspace. Try again.',
|
||||
|
|
|
|||
|
|
@ -1001,6 +1001,7 @@ export class DingtalkHarnessBridge {
|
|||
channel: 'dingtalk',
|
||||
senderId: sender,
|
||||
senderName: message.senderNick,
|
||||
conversationTitle: message.conversationTitle,
|
||||
}));
|
||||
}
|
||||
if (typeof this.#api.createAiCard === 'function'
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// Shared by the Host and settings UI; keep this module browser-compatible.
|
||||
export const CONTEXT_ENHANCEMENT_FIELDS = Object.freeze([
|
||||
'channel', 'conversationType', 'senderId', 'senderName', 'botId',
|
||||
'channel', 'conversationType', 'senderId', 'senderName', 'conversationTitle', 'botId',
|
||||
]);
|
||||
|
||||
export const CONTEXT_ENHANCEMENT_GUIDANCE_MAX_LENGTH = 8_000;
|
||||
|
|
@ -36,7 +36,10 @@ const CHANNELS = new Set([
|
|||
'wecom', 'weixin', 'feishu', 'dingtalk', 'qq',
|
||||
'slack', 'telegram', 'discord', 'whatsapp',
|
||||
]);
|
||||
const SOURCE_LIMITS = { channel: 16, conversationType: 6, senderId: 256, senderName: 256, botId: 128 };
|
||||
const SOURCE_LIMITS = {
|
||||
channel: 16, conversationType: 6, senderId: 256, senderName: 256,
|
||||
conversationTitle: 256, botId: 128,
|
||||
};
|
||||
const CONTROL_CHARACTERS = /[\u0000-\u001f\u007f-\u009f\u202a-\u202e\u2066-\u2069]/g;
|
||||
|
||||
function invalidConfig(message) {
|
||||
|
|
@ -61,7 +64,7 @@ function validateContextEnhancementScope(input) {
|
|||
throw invalidConfig('群聊和私聊开关必须是布尔值。');
|
||||
}
|
||||
if (!Array.isArray(fields) || ![...fields].every((field) => CONTEXT_ENHANCEMENT_FIELDS.includes(field))) {
|
||||
throw invalidConfig('来源字段只能选择已定义的五个字段。');
|
||||
throw invalidConfig('来源字段只能选择已定义的六个字段。');
|
||||
}
|
||||
if (typeof guidance !== 'string' || guidance.length > CONTEXT_ENHANCEMENT_GUIDANCE_MAX_LENGTH) {
|
||||
throw invalidConfig(`增强提示词不得超过 ${CONTEXT_ENHANCEMENT_GUIDANCE_MAX_LENGTH} 个字符。`);
|
||||
|
|
@ -146,7 +149,9 @@ function sourceString(value, field) {
|
|||
|
||||
function sourceBlock(snapshot, sourceFactory) {
|
||||
const { fields } = snapshot.config;
|
||||
const needsSource = fields.some((field) => ['channel', 'senderId', 'senderName'].includes(field));
|
||||
const needsSource = fields.some((field) => [
|
||||
'channel', 'senderId', 'senderName', 'conversationTitle',
|
||||
].includes(field));
|
||||
const source = needsSource ? sourceFactory?.() : null;
|
||||
const projected = {};
|
||||
for (const field of fields) {
|
||||
|
|
|
|||
|
|
@ -678,6 +678,7 @@ export class TextHarnessBridge {
|
|||
channel: this.#descriptor.key,
|
||||
senderId,
|
||||
senderName: message.contextSource?.()?.senderName,
|
||||
conversationTitle: message.contextSource?.()?.conversationTitle,
|
||||
}));
|
||||
}
|
||||
const { answer, artifacts = [] } = await askInWorkspaceSession({
|
||||
|
|
|
|||
|
|
@ -166,6 +166,7 @@ export function normalizeTelegramUpdate(update, {
|
|||
senderName: [message.from?.first_name, message.from?.last_name]
|
||||
.filter((value) => typeof value === 'string' && value.trim())
|
||||
.map((value) => value.trim()).join(' ') || message.from?.username,
|
||||
conversationTitle: direct ? undefined : message.chat?.title,
|
||||
}),
|
||||
senderIsBot: message.from?.is_bot === true,
|
||||
kind: direct ? 'direct' : 'group',
|
||||
|
|
|
|||
|
|
@ -177,7 +177,8 @@ function fixture(channel, { contextEnhancement, onAsk } = {}) {
|
|||
const from = { id: actor === 'actor' ? 42 : 43, is_bot: false };
|
||||
nameValue(from, 'first_name');
|
||||
value = normalizeTelegramUpdate({ update_id: id, message: {
|
||||
message_id: id, chat: { id: 100, type: group ? 'supergroup' : 'private' }, from,
|
||||
message_id: id, chat: { id: 100, type: group ? 'supergroup' : 'private',
|
||||
...(group ? { title: 'Telegram群' } : {}) }, from,
|
||||
text: group ? `@testbot ${text}` : text, entities: group ? [{ type: 'mention', offset: 0, length: 8 }] : [],
|
||||
} }, { botId: 'bot', username: 'testbot' });
|
||||
} else if (channel === 'discord') {
|
||||
|
|
@ -206,7 +207,8 @@ function fixture(channel, { contextEnhancement, onAsk } = {}) {
|
|||
item_list: [{ type: 1, text_item: { text } }] };
|
||||
} else if (channel === 'dingtalk') {
|
||||
value = { msgId: String(id), msgtype: 'text', text: { content: text }, senderStaffId: actor,
|
||||
conversationType: group ? '2' : '1', conversationId: 'chat', isInAtList: true,
|
||||
conversationType: group ? '2' : '1', conversationId: 'chat',
|
||||
conversationTitle: group ? '钉钉测试群' : undefined, isInAtList: true,
|
||||
sessionWebhook: 'https://oapi.dingtalk.com/robot/reply?ticket=test' };
|
||||
nameValue(value, 'senderNick');
|
||||
} else if (channel === 'qq') {
|
||||
|
|
@ -299,6 +301,8 @@ for (const channel of CHANNELS) {
|
|||
senderId: channel === 'telegram' ? '42' : channel === 'whatsapp' ? 'actor@s.whatsapp.net' : 'actor',
|
||||
...(['dingtalk', 'telegram', 'discord', 'whatsapp'].includes(channel) || (channel === 'qq' && kind === 'group')
|
||||
? { senderName: 'Ada' } : {}),
|
||||
...(channel === 'dingtalk' && kind === 'group' ? { conversationTitle: '钉钉测试群' } : {}),
|
||||
...(channel === 'telegram' && kind === 'group' ? { conversationTitle: 'Telegram群' } : {}),
|
||||
botId: `${channel}_internal`,
|
||||
};
|
||||
assert.deepEqual(sourceOf(current.prompts[0]), expected);
|
||||
|
|
|
|||
|
|
@ -217,6 +217,11 @@ test('context settings default to off with sender ID and empty guidance, and exp
|
|||
assert.equal(senderNameHelp.parent.props.className, 'dim-contextHelp dim-contextFieldHelp');
|
||||
assert.equal(senderNameHelp.parent.parent.props.className, 'dim-contextFieldText');
|
||||
assert.match(textOf(senderNameTooltip), /不是每个渠道.*dsh_im_source.*省略 senderName/s);
|
||||
const conversationTitleHelp = renderer.root.findByProps({ 'aria-label': '查看群聊会话标题字段说明' });
|
||||
const conversationTitleTooltip = renderer.root.findByProps({ id: conversationTitleHelp.props['aria-describedby'] });
|
||||
assert.equal(conversationTitleHelp.props.type, 'button');
|
||||
assert.equal(conversationTitleHelp.parent.props.className, 'dim-contextHelp dim-contextFieldHelp');
|
||||
assert.match(textOf(conversationTitleTooltip), /不是每个渠道.*dsh_im_source.*省略 conversationTitle/s);
|
||||
assert.deepEqual(saved, []);
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -185,16 +185,16 @@ test('group and direct messages use only their own fields and guidance', () => {
|
|||
assert.doesNotMatch(direct, /GROUP-ONLY-TOKEN|channel/);
|
||||
});
|
||||
|
||||
test('all 32 source-field subsets are projected in canonical order with no hidden fields', () => {
|
||||
test('all 64 source-field subsets are projected in canonical order with no hidden fields', () => {
|
||||
const expected = {
|
||||
channel: 'telegram', conversationType: 'group',
|
||||
senderId: '123', senderName: '张三', botId: 'bot_one',
|
||||
senderId: '123', senderName: '张三', conversationTitle: '测试群', botId: 'bot_one',
|
||||
};
|
||||
for (let mask = 0; mask < 32; mask += 1) {
|
||||
for (let mask = 0; mask < 64; mask += 1) {
|
||||
const fields = CONTEXT_ENHANCEMENT_FIELDS.filter((_field, index) => mask & (1 << index));
|
||||
const selected = snapshot(config({ fields: [...fields].reverse() }));
|
||||
const actual = enhanceContextContent(' original\n', selected, () => ({
|
||||
channel: 'telegram', senderId: 123, senderName: '张三',
|
||||
channel: 'telegram', senderId: 123, senderName: '张三', conversationTitle: '测试群',
|
||||
botId: 'platform-secret-not-used', conversationType: 'direct', token: 'never-sent',
|
||||
}));
|
||||
if (fields.length === 0) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue