Files
memind/wechat/prompts/chat-general.mjs
john 031c6e086a feat(wechat): migrate schedule and sync handlers into wechat package
Extract schedule, greeting/status/connectivity replies, chat-general prompt, and display-name helpers from wechat-mp.mjs. Route sync intents via classifyWechatIntent and add channel isolation CI check.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-04 13:48:47 +08:00

116 lines
5.3 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { buildAutoChatSkillPrefix } from '../../chat-skills.mjs';
import { shouldUseScheduleAssistant } from '../../schedule-intent.mjs';
import { buildCurrentTimeAgentPrefix } from '../../user-memory-profile.mjs';
import { isPageGenerateText, wantsDocxDownload } from '../intent/patterns.mjs';
export function buildWechatAgentPrompt(intent, { grantedSkills = [] } = {}) {
const msgType = String(intent?.msgType ?? 'text');
const agentText = intent?.agentText ?? intent?.content ?? '';
const autoSkillPrefix =
msgType === 'text' || msgType === 'voice'
? buildAutoChatSkillPrefix(agentText, grantedSkills)
: '';
const docxDownloadHint =
isPageGenerateText(agentText) && wantsDocxDownload(agentText)
? [
'【Word 下载要求】用户明确要求页面里可下载 Word / docx。',
'开始前必须先调用 `load_skill` → `docx-generate`,并按技能说明生成目标 `public/*.docx`。',
'生成后必须确认目标 `.docx` 已存在,再调用 `load_skill` → `static-page-publish` 写 `public/*.html`。',
'HTML 中只能用同目录相对路径链接该文档;禁止只写下载按钮却没有先把 `.docx` 落盘。',
'',
].join('\n')
: '';
const pagePublishHint = isPageGenerateText(agentText)
? [
'【页面发布技能要求】这条消息是在生成可访问 HTML 页面。',
'开始前必须先调用 `load_skill` → `static-page-publish`,不能省略,也不能写完页面后再补调。',
'随后必须用 sandbox-fs 的 `write_file` / `edit_file` 写入 `public/*.html`。',
'禁止用 shell / cat / heredoc / echo / cp 写入 HTMLshell 在容器内执行,文件不会出现在公网 MindSpace 路径,用户会收到「文件不存在」。',
'在回复用户前,确认 `public/` 下目标 HTML 已通过 write_file 落盘;没有落盘就不要发送链接或说「已发布」。',
'最终只给用户一个正式域名的唯一正确链接;不要输出错误域名、备用链接或让用户手动保存文件。',
'',
].join('\n')
: '';
const scheduleTimezone = process.env.H5_DEFAULT_TIMEZONE || 'Asia/Shanghai';
const currentTimeHint = buildCurrentTimeAgentPrefix({ timezone: scheduleTimezone });
const scheduleAssistantHint = shouldUseScheduleAssistant(agentText)
? [
'【日程技能要求】这条消息涉及待办、提醒或日程。',
'开始前先加载 `schedule-assistant` skill,并严格按 skill 里的边界执行。',
'写入工具时优先使用 startLocal / endLocal / remindLocalYYYY-MM-DD HH:mm),不要自行估算 Unix 毫秒。',
'只有在 `schedule_create_item` / `schedule_create_reminder` 等工具成功返回后,才能告诉用户“已经设置好了”。',
intent?.msgId ? `调用 schedule_create_item 时必须传入 sourceMessageId: ${intent.msgId}` : '',
'',
].filter(Boolean).join('\n')
: '';
if (msgType === 'voice') {
return [
docxDownloadHint,
currentTimeHint,
scheduleAssistantHint,
'【微信服务号语音消息】用户通过语音输入,以下是微信识别结果。',
'',
`用户语音识别文本:${autoSkillPrefix}${String(agentText).trim()}`,
]
.filter(Boolean)
.join('\n');
}
if (msgType === 'image') {
return [
docxDownloadHint,
currentTimeHint,
scheduleAssistantHint,
'【微信服务号图片消息】用户发送了图片。',
'如用户没有明确要求,请先根据图片内容给出简短理解,并询问下一步。',
'',
String(agentText).trim(),
]
.filter(Boolean)
.join('\n');
}
if (msgType === 'location') {
const location = intent?.location ?? {};
return [
currentTimeHint,
scheduleAssistantHint,
'【微信服务号位置消息】用户发送了当前位置。',
location.label ? `地址:${location.label}` : '',
location.latitude !== null && location.latitude !== undefined
? `纬度:${location.latitude}`
: '',
location.longitude !== null && location.longitude !== undefined
? `经度:${location.longitude}`
: '',
'请结合位置回答用户可能的路线、附近、行程或提醒需求;如果意图不明确,先简短询问。',
]
.filter(Boolean)
.join('\n');
}
if (msgType === 'link') {
const link = intent?.link ?? {};
return [
currentTimeHint,
scheduleAssistantHint,
'【微信服务号链接消息】用户分享了链接。',
link.title ? `标题:${link.title}` : '',
link.description ? `描述:${link.description}` : '',
link.url ? `URL${link.url}` : '',
]
.filter(Boolean)
.join('\n');
}
const content = String(agentText).trim();
const lines = [currentTimeHint];
if (docxDownloadHint) lines.push(docxDownloadHint);
if (pagePublishHint) lines.push(pagePublishHint);
if (scheduleAssistantHint) lines.push(scheduleAssistantHint);
lines.push(
'【微信服务号新消息】请只回答下面这条用户消息,不要主动延续无关的历史话题。',
'若用户只是在测试连通性,请一句话确认收到即可,不要展开旧任务。',
'',
`用户消息:${autoSkillPrefix}${content}`,
);
return lines.join('\n');
}