mindspace: close authority boundaries

This commit is contained in:
john
2026-07-27 15:34:35 +08:00
parent dfab78c75a
commit e94052ff24
78 changed files with 11962 additions and 2162 deletions
+194 -94
View File
@@ -7,7 +7,7 @@ import sharp from 'sharp';
import {
buildWechatAgentPrompt,
buildWechatTextReply,
createWechatMpService,
createWechatMpService as createProductionWechatMpService,
guardMissingPublicHtmlLinks,
assertWechatAgentReplyIsSendable,
findRecoverableWechatAgentErrorInReply,
@@ -26,6 +26,10 @@ import {
WECHAT_CUSTOMER_TEXT_MAX_BYTES,
} from './wechat-mp.mjs';
import { createChatIntentRouter } from './chat-intent-router.mjs';
import {
ensureWechatFreshPageThumbnailsAtWorkspace,
prepareWechatHtmlDeliveryAtWorkspace,
} from './mindspace-wechat-html-delivery.mjs';
function signatureFor(token, timestamp, nonce) {
return crypto
@@ -70,6 +74,82 @@ function previewReadyPageHtml({ title = 'Page', subtitle = '测试页面', cover
return `<!doctype html><html><head><meta name="description" content="${subtitle}"><meta name="mindspace-cover" content='{"tag":"页面","accent":"#3366cc","accent2":"#112233","subtitle":"${subtitle}"${coverField}}'><title>${title}</title></head><body><main>${'x'.repeat(600)}</main><p data-mindspace-page-tag="platform-brand">TKMind · 智趣</p></body></html>`;
}
function createWechatMpService(options) {
const resolvePublishDir = async (userId) => {
const layout =
await options.userAuth
?.getUserPublishLayout?.(userId);
return (
layout?.publishDir ??
await options.userAuth
?.resolveWorkingDir?.(userId)
);
};
const buildCanonicalUrl = (
userId,
relativePath,
) => {
const base = String(
options.config?.publicBaseUrl ??
'https://example.com',
).replace(/\/+$/, '');
const normalized = String(relativePath)
.replace(/^\/+/, '')
.split('/')
.map(encodeURIComponent)
.join('/');
return `${base}/MindSpace/${encodeURIComponent(userId)}/${normalized}`;
};
const htmlDeliveryAuthority =
options.htmlDeliveryAuthority ?? {
async prepareWechatHtmlDelivery(input) {
const publishDir =
await resolvePublishDir(input.userId);
return prepareWechatHtmlDeliveryAtWorkspace({
reply: input.reply,
intent: input.intent,
publishDir,
requestStartedAt:
input.requestStartedAt,
allowRecentArtifacts:
input.allowRecentArtifacts,
buildCanonicalUrl: (relativePath) =>
buildCanonicalUrl(
input.userId,
relativePath,
),
});
},
async ensureWechatFreshPageThumbnails(
input,
) {
const publishDir =
await resolvePublishDir(input.userId);
return ensureWechatFreshPageThumbnailsAtWorkspace(
{
artifacts: input.artifacts,
images: input.images,
messages: input.messages,
repairEnabled:
input.repairEnabled,
publishDir,
buildCanonicalUrl: (
relativePath,
) =>
buildCanonicalUrl(
input.userId,
relativePath,
),
},
);
},
};
return createProductionWechatMpService({
...options,
htmlDeliveryAuthority,
});
}
test('executeSessionReply converts a hanging event stream into a bounded timeout', async () => {
let cancelled = false;
const body = new ReadableStream({
@@ -453,34 +533,39 @@ test('maybeAttachPublishedHtmlLink copies generated root html into public and re
const workspaceRoot = fs.mkdtempSync('/tmp/wechat-mp-public-');
const htmlPath = `${workspaceRoot}/hello.html`;
fs.writeFileSync(htmlPath, '<!doctype html><title>Hello</title>');
const text = await maybeAttachPublishedHtmlLink(
{
text: '已完成',
messages: [
{
role: 'assistant',
content: [
{
type: 'toolRequest',
toolCall: {
value: {
name: 'developer',
arguments: {
action: 'write',
path: htmlPath,
content: '<!doctype html><title>Hello</title>',
},
const reply = {
text: '已完成',
messages: [
{
role: 'assistant',
content: [
{
type: 'toolRequest',
toolCall: {
value: {
name: 'developer',
arguments: {
action: 'write',
path: htmlPath,
content: '<!doctype html><title>Hello</title>',
},
},
},
],
},
],
},
},
],
},
],
};
const prepared = prepareWechatHtmlDeliveryAtWorkspace({
reply,
publishDir: workspaceRoot,
buildCanonicalUrl: (relativePath) =>
`https://m.tkmind.cn/MindSpace/user-1/${relativePath}`,
});
const text = await maybeAttachPublishedHtmlLink(
reply,
{
workingDir: workspaceRoot,
publicBaseUrl: 'https://m.tkmind.cn',
artifacts: prepared.confirmedArtifacts,
},
);
@@ -496,33 +581,38 @@ test('maybeAttachPublishedHtmlLink recognizes sandbox-fs write_file html outputs
const htmlPath = `${workspaceRoot}/public/codex-verify.html`;
fs.mkdirSync(`${workspaceRoot}/public`, { recursive: true });
fs.writeFileSync(htmlPath, '<!doctype html><title>Codex Verify</title>');
const text = await maybeAttachPublishedHtmlLink(
{
text: '页面已生成 ✅',
messages: [
{
role: 'assistant',
content: [
{
type: 'toolRequest',
toolCall: {
value: {
name: 'sandbox-fs__write_file',
arguments: {
path: 'public/codex-verify.html',
content: '<!doctype html><title>Codex Verify</title>',
},
const reply = {
text: '页面已生成 ✅',
messages: [
{
role: 'assistant',
content: [
{
type: 'toolRequest',
toolCall: {
value: {
name: 'sandbox-fs__write_file',
arguments: {
path: 'public/codex-verify.html',
content: '<!doctype html><title>Codex Verify</title>',
},
},
},
],
},
],
},
},
],
},
],
};
const prepared = prepareWechatHtmlDeliveryAtWorkspace({
reply,
publishDir: workspaceRoot,
buildCanonicalUrl: (relativePath) =>
`https://m.tkmind.cn/MindSpace/user-1/${relativePath}`,
});
const text = await maybeAttachPublishedHtmlLink(
reply,
{
workingDir: workspaceRoot,
publicBaseUrl: 'https://m.tkmind.cn',
artifacts: prepared.confirmedArtifacts,
},
);
@@ -537,33 +627,38 @@ test('maybeAttachPublishedHtmlLink rewrites wrong public html links to the canon
const htmlPath = `${workspaceRoot}/public/summer-breeze-journal.html`;
fs.mkdirSync(`${workspaceRoot}/public`, { recursive: true });
fs.writeFileSync(htmlPath, '<!doctype html><title>Summer</title>');
const text = await maybeAttachPublishedHtmlLink(
{
text: '页面已发布:https://m.tkmind.cn/public/summer-breeze-journal.html',
messages: [
{
role: 'assistant',
content: [
{
type: 'toolRequest',
toolCall: {
value: {
name: 'sandbox-fs__write_file',
arguments: {
path: 'public/summer-breeze-journal.html',
content: '<!doctype html><title>Summer</title>',
},
const reply = {
text: '页面已发布:https://m.tkmind.cn/public/summer-breeze-journal.html',
messages: [
{
role: 'assistant',
content: [
{
type: 'toolRequest',
toolCall: {
value: {
name: 'sandbox-fs__write_file',
arguments: {
path: 'public/summer-breeze-journal.html',
content: '<!doctype html><title>Summer</title>',
},
},
},
],
},
],
},
},
],
},
],
};
const prepared = prepareWechatHtmlDeliveryAtWorkspace({
reply,
publishDir: workspaceRoot,
buildCanonicalUrl: (relativePath) =>
`https://m.tkmind.cn/MindSpace/user-1/${relativePath}`,
});
const text = await maybeAttachPublishedHtmlLink(
reply,
{
workingDir: workspaceRoot,
publicBaseUrl: 'https://m.tkmind.cn',
artifacts: prepared.confirmedArtifacts,
},
);
@@ -579,33 +674,38 @@ test('maybeAttachPublishedHtmlLink rewrites tkmind domain variants to the canoni
const htmlPath = `${workspaceRoot}/public/codex-prod-check-v6.html`;
fs.mkdirSync(`${workspaceRoot}/public`, { recursive: true });
fs.writeFileSync(htmlPath, '<!doctype html><title>Prod Check</title>');
const text = await maybeAttachPublishedHtmlLink(
{
text: '唯一可访问链接:https://mindspace.tkmind.cn/a70ff537-8908-486e-9b6c-042e07cc25db/codex-prod-check-v6.html',
messages: [
{
role: 'assistant',
content: [
{
type: 'toolRequest',
toolCall: {
value: {
name: 'sandbox-fs__write_file',
arguments: {
path: 'public/codex-prod-check-v6.html',
content: '<!doctype html><title>Prod Check</title>',
},
const reply = {
text: '唯一可访问链接:https://mindspace.tkmind.cn/a70ff537-8908-486e-9b6c-042e07cc25db/codex-prod-check-v6.html',
messages: [
{
role: 'assistant',
content: [
{
type: 'toolRequest',
toolCall: {
value: {
name: 'sandbox-fs__write_file',
arguments: {
path: 'public/codex-prod-check-v6.html',
content: '<!doctype html><title>Prod Check</title>',
},
},
},
],
},
],
},
},
],
},
],
};
const prepared = prepareWechatHtmlDeliveryAtWorkspace({
reply,
publishDir: workspaceRoot,
buildCanonicalUrl: (relativePath) =>
`https://m.tkmind.cn/MindSpace/user-1/${relativePath}`,
});
const text = await maybeAttachPublishedHtmlLink(
reply,
{
workingDir: workspaceRoot,
publicBaseUrl: 'https://m.tkmind.cn',
artifacts: prepared.confirmedArtifacts,
},
);