feat: admit photos and image documents into the bound session
Telegram 图片消息此前一律回复「暂只支持文本消息」。本改动: - photo 取最大尺寸(TG 压成 jpeg),document 仅接受 image/png|jpeg|webp|gif - caption 作为伴随文本块进入同一条消息(不解析为命令) - 相册(同一 media_group_id)去抖 1.2s 合并为一条多图消息,避免 N 连回合 - 派发走宿主 sessions.prompt RPC(Web 端同通道):模型图像能力校验 + 附件服务持久化 + mode queue 排队,与纯文本路径的 agent.followup 语义一致 - 错误映射:MODEL_DOES_NOT_SUPPORT_IMAGES → 提示换多模态模型;其余回退 图片发送失败 + [code] 详情;下载失败即时提示 - 客户端新增 getFile/downloadFile(GET file 端点,复用代理感知 fetch) tests +7(58/58):photo+caption、png document、pdf 拒绝、相册合并、 模型不支持、下载失败、未绑定。无 emoji 文案。
This commit is contained in:
Vendored
+24
@@ -53,6 +53,8 @@ export declare class TelegramBridge {
|
||||
private readonly compacting;
|
||||
/** sessionId → compaction abort controller (cancelled on bridge stop) */
|
||||
private readonly compactAborts;
|
||||
/** Album accumulation: chatId:media_group_id → parts buffered into one prompt. */
|
||||
private readonly mediaGroups;
|
||||
constructor(ctx: Context, options: TelegramBridgeOptions);
|
||||
/** Effective rendering mode for a chat: per-chat override, else the global mode. */
|
||||
private modeFor;
|
||||
@@ -83,6 +85,28 @@ export declare class TelegramBridge {
|
||||
/** 等待压缩落定并汇报结果(不阻塞轮询循环)。 */
|
||||
private runCompaction;
|
||||
private followupBound;
|
||||
/**
|
||||
* Extract wire prompt parts from a media message.
|
||||
* Returns undefined when the message carries no media at all; returns [] for
|
||||
* an unsupported media type (the user was already notified); otherwise the
|
||||
* caption text part (when present) followed by the image part.
|
||||
*/
|
||||
private collectMediaParts;
|
||||
/** Download one TG file and encode it as a canonical-base64 wire image part. */
|
||||
private downloadImagePart;
|
||||
/**
|
||||
* Album photos arrive as separate updates sharing a media_group_id — debounce
|
||||
* them into ONE prompt so an album does not spawn N sequential turns.
|
||||
*/
|
||||
private accumulateMediaGroup;
|
||||
/**
|
||||
* Dispatch an image-bearing message to the bound session through the host
|
||||
* prompt RPC — the exact channel the Web composer uses. The host checks
|
||||
* whether the current model accepts image input, admits the bytes into the
|
||||
* durable attachment store, then queues the message on the agent (mode
|
||||
* 'queue' — same semantics as the text path's agent.followup).
|
||||
*/
|
||||
private sendImageFollowup;
|
||||
private pollLoop;
|
||||
private interruptibleDelay;
|
||||
private interruptibleSleep;
|
||||
|
||||
Reference in New Issue
Block a user