feat: 支持 MCP 图片内联渲染
This commit is contained in:
41
server.js
41
server.js
@@ -12,7 +12,7 @@ const { createCodexAppRuntime } = require('./lib/codex-app-runtime');
|
||||
const { createCodexRolloutStore } = require('./lib/codex-rollouts');
|
||||
const { createSessionSearchIndex } = require('./lib/session-search-index');
|
||||
const { createUsageStatisticsIndex, UsageStatisticsError } = require('./lib/usage-statistics');
|
||||
const { TOOLS: CCWEB_MCP_TOOLS } = require('./lib/ccweb-mcp-server');
|
||||
const { TOOLS: CCWEB_MCP_TOOLS, prepareImagePayload } = require('./lib/ccweb-mcp-server');
|
||||
const CCWEB_MCP_SERVER_INFO = { name: 'ccweb', version: '1.0.0' };
|
||||
|
||||
if (process.argv.includes('--ccweb-mcp-server')) {
|
||||
@@ -4902,6 +4902,43 @@ function createCcwebPromptUser(args = {}, sourceSessionId = '') {
|
||||
};
|
||||
}
|
||||
|
||||
function createCcwebDisplayImage(args = {}, sourceSessionId = '') {
|
||||
const sourceId = sanitizeId(sourceSessionId || '');
|
||||
const payload = prepareImagePayload(args);
|
||||
if (!payload.ok) return payload;
|
||||
|
||||
const now = new Date();
|
||||
let attachment = null;
|
||||
if (payload.image.data) {
|
||||
const buffer = Buffer.from(payload.image.data, 'base64');
|
||||
const id = crypto.randomUUID();
|
||||
const filename = safeFilename(payload.image.title || payload.image.alt || `image${extFromMime(payload.image.mimeType)}`);
|
||||
const dataPath = attachmentDataPath(id, extFromMime(payload.image.mimeType));
|
||||
const meta = {
|
||||
id,
|
||||
kind: 'image',
|
||||
filename,
|
||||
mime: payload.image.mimeType,
|
||||
size: buffer.length,
|
||||
createdAt: now.toISOString(),
|
||||
expiresAt: new Date(now.getTime() + ATTACHMENT_TTL_MS).toISOString(),
|
||||
path: dataPath,
|
||||
};
|
||||
try {
|
||||
fs.writeFileSync(dataPath, buffer);
|
||||
saveAttachmentMeta(meta);
|
||||
} catch (err) {
|
||||
try { if (fs.existsSync(dataPath)) fs.unlinkSync(dataPath); } catch {}
|
||||
return mcpToolError('image_store_failed', `保存图片失败: ${err.message}`);
|
||||
}
|
||||
attachment = normalizeMessageAttachments([meta])[0] || null;
|
||||
}
|
||||
const responseImage = payload.image.data
|
||||
? { type: 'image', mimeType: payload.image.mimeType, alt: payload.image.alt, title: payload.image.title, size: attachment?.size || 0 }
|
||||
: payload.image;
|
||||
return { ok: true, image: responseImage, attachment, status: 'ready', sourceConversationId: sourceId || null };
|
||||
}
|
||||
|
||||
function findCcwebPromptMessage(session, promptId) {
|
||||
const normalizedPromptId = String(promptId || '').trim();
|
||||
if (!normalizedPromptId || !Array.isArray(session?.messages)) return null;
|
||||
@@ -5430,6 +5467,8 @@ function completeCrossConversationReply(requestId, entry = {}, targetSession = n
|
||||
|
||||
function callInternalMcpTool(tool, args, sourceSessionId, sourceHopCount) {
|
||||
switch (tool) {
|
||||
case 'ccweb_display_image':
|
||||
return createCcwebDisplayImage(args, sourceSessionId);
|
||||
case 'ccweb_list_conversations':
|
||||
return listConversationSummaries(args, sanitizeId(sourceSessionId || ''));
|
||||
case 'ccweb_set_title':
|
||||
|
||||
Reference in New Issue
Block a user