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', }); }