Merge remote-tracking branch 'upstream/main' into feat/per-bot-agent-preset

Co-authored-by: Cursor <cursoragent@cursor.com>

# Conflicts:
#	lib/index.js
This commit is contained in:
iamyaojie 2026-08-21 22:34:11 +08:00
commit a1bdf2c1f8
17 changed files with 438 additions and 144 deletions

View file

@ -13,6 +13,18 @@ export class ImagePromptError extends Error {
}
}
const HOST_ATTACHMENT_USER_MESSAGES = Object.freeze({
MODEL_DOES_NOT_SUPPORT_IMAGES:
'当前模型不支持图片,请用 /models 查看可用模型,再用 /model <序号> 切换后重发。',
IMAGE_TOO_LARGE: '图片超过宿主允许的大小,请压缩后重试。',
IMAGE_TOO_MANY_PIXELS: '图片分辨率过高,请压缩后重试。',
INVALID_IMAGE: '图片内容无效或格式不受支持,请重新发送。',
INVALID_IMAGE_BASE64: '未能读取图片内容,请重新发送。',
IMAGE_TYPE_MISMATCH: '图片格式与实际内容不一致,请重新发送。',
TOO_MANY_IMAGES: '一次发送的图片数量超过宿主限制,请减少后重试。',
IMAGES_TOO_LARGE: '图片总大小超过宿主限制,请减少图片或压缩后重试。',
});
function requestSignal(signal, timeoutMs) {
const timeout = AbortSignal.timeout(timeoutMs);
return signal ? AbortSignal.any([signal, timeout]) : timeout;
@ -263,6 +275,25 @@ export async function promptContentForMessage(message, {
return content;
}
export function imagePromptUserMessage(error) {
return error instanceof ImagePromptError ? error.userMessage : null;
/** Return only allowlisted, user-safe image failure details. */
export function imagePromptDiagnostic(error) {
if (error instanceof ImagePromptError) {
return {
code: 'image-prompt-error',
reason: error.code,
userMessage: error.userMessage,
};
}
if (error?.code !== 'attachment-error' || typeof error?.details?.reason !== 'string') {
return null;
}
const reason = error.details.reason;
const userMessage = Object.hasOwn(HOST_ATTACHMENT_USER_MESSAGES, reason)
? HOST_ATTACHMENT_USER_MESSAGES[reason]
: null;
return userMessage ? { code: 'attachment-error', reason, userMessage } : null;
}
export function imagePromptUserMessage(error) {
return imagePromptDiagnostic(error)?.userMessage ?? null;
}