644f7fc632
Memind CI / Test, build, and release guards (push) Has been cancelled
Ship the WeChat Cursor executor helpers referenced by the page delivery path so tests and runtime imports resolve consistently. Co-authored-by: Cursor <cursoragent@cursor.com>
118 lines
3.6 KiB
JavaScript
118 lines
3.6 KiB
JavaScript
import { buildCodeRunCompletionReply } from './agent-run-gateway.mjs';
|
|
import { enforcePageGenerationCursorRuntime } from './cursor-page-routing.mjs';
|
|
|
|
const DEFAULT_POLL_MS = 2000;
|
|
|
|
function sleep(ms) {
|
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
}
|
|
|
|
function buildWechatCursorUserMessage({
|
|
displayText,
|
|
intentKind,
|
|
}) {
|
|
const taskText = String(displayText ?? '').trim();
|
|
return {
|
|
role: 'user',
|
|
content: [{ type: 'text', text: taskText }],
|
|
metadata: {
|
|
displayText: taskText,
|
|
memindRun: {
|
|
channel: 'wechat_mp',
|
|
wechatCursorChannel: true,
|
|
taskType: 'wechat_page_generate',
|
|
toolMode: 'code',
|
|
requiredExecutor: 'cursor',
|
|
intentKind: String(intentKind ?? '').trim() || null,
|
|
},
|
|
},
|
|
};
|
|
}
|
|
|
|
async function readCursorCompletionText(agentRunGateway, userId, runId) {
|
|
const eventsResult = await agentRunGateway.listRunEventsForUser(userId, runId, { limit: 200 });
|
|
const events = Array.isArray(eventsResult?.events) ? eventsResult.events : [];
|
|
const resultEvent = [...events].reverse().find((item) => item.eventType === 'tool_gateway_result');
|
|
if (!resultEvent?.data) {
|
|
return buildCodeRunCompletionReply({ executor: 'cursor', stdout: '' });
|
|
}
|
|
return buildCodeRunCompletionReply({
|
|
executor: resultEvent.data.executor ?? 'cursor',
|
|
stdout: resultEvent.data.stdoutTail ?? '',
|
|
});
|
|
}
|
|
|
|
export async function executeWechatCursorAgentRun({
|
|
agentRunGateway,
|
|
userId,
|
|
sessionId = null,
|
|
requestId,
|
|
displayText,
|
|
agentPrompt,
|
|
intentKind = 'page.generate',
|
|
timeoutMs = 15 * 60 * 1000,
|
|
pollMs = DEFAULT_POLL_MS,
|
|
logger = console,
|
|
} = {}) {
|
|
if (!agentRunGateway?.createRun || !agentRunGateway?.dispatchRun || !agentRunGateway?.getRunForUser) {
|
|
throw Object.assign(new Error('WeChat Cursor 执行网关不可用'), {
|
|
code: 'WECHAT_CURSOR_GATEWAY_UNAVAILABLE',
|
|
});
|
|
}
|
|
|
|
let userMessage = buildWechatCursorUserMessage({ displayText, intentKind });
|
|
const cursorRuntime = enforcePageGenerationCursorRuntime(userMessage, {
|
|
rawToolMode: 'code',
|
|
taskType: 'wechat_page_generate',
|
|
env: process.env,
|
|
});
|
|
userMessage = cursorRuntime.userMessage;
|
|
|
|
const run = await agentRunGateway.createRun(userId, {
|
|
sessionId,
|
|
requestId,
|
|
userMessage,
|
|
toolMode: 'code',
|
|
taskType: cursorRuntime.taskType ?? 'h5_chat_code_task',
|
|
});
|
|
agentRunGateway.dispatchRun(run.id);
|
|
|
|
const deadline = Date.now() + Math.max(0, Number(timeoutMs) || 0);
|
|
while (Date.now() <= deadline) {
|
|
const latest = await agentRunGateway.getRunForUser(userId, run.id);
|
|
if (!latest) {
|
|
throw Object.assign(new Error('WeChat Cursor 任务丢失'), {
|
|
code: 'WECHAT_CURSOR_RUN_MISSING',
|
|
});
|
|
}
|
|
if (latest.status === 'succeeded') {
|
|
const text = await readCursorCompletionText(agentRunGateway, userId, run.id);
|
|
logger.info?.('[wechat-cursor] run succeeded', {
|
|
userId,
|
|
runId: run.id,
|
|
requestId,
|
|
});
|
|
return {
|
|
text,
|
|
tokenState: null,
|
|
messages: [{
|
|
role: 'assistant',
|
|
content: [{ type: 'text', text }],
|
|
metadata: { userVisible: true, source: 'wechat-cursor-agent-run' },
|
|
}],
|
|
requestMessages: [],
|
|
};
|
|
}
|
|
if (latest.status === 'failed') {
|
|
const error = new Error(latest.error || 'WeChat Cursor 执行失败');
|
|
error.code = 'WECHAT_CURSOR_RUN_FAILED';
|
|
throw error;
|
|
}
|
|
await sleep(Math.max(500, Number(pollMs) || DEFAULT_POLL_MS));
|
|
}
|
|
|
|
throw Object.assign(new Error('WeChat Cursor 执行超时'), {
|
|
code: 'WECHAT_CURSOR_RUN_TIMEOUT',
|
|
});
|
|
}
|