forked from bai/curriculum-project-hub
fix: let agents download Feishu message resources
This commit is contained in:
+42
-13
@@ -768,13 +768,14 @@ export function makeTriggerHandler(deps: TriggerDeps): TriggerHandler {
|
||||
select: { workspaceDir: true },
|
||||
});
|
||||
if (project === null) return;
|
||||
await downloadPostMessageFiles({
|
||||
const downloadedResources = await downloadPostMessageFiles({
|
||||
rt,
|
||||
msg,
|
||||
workspaceDir: project.workspaceDir,
|
||||
imageKeys: parsed.imageKeys,
|
||||
fileKeys: parsed.fileKeys,
|
||||
});
|
||||
cleanPrompt = appendDownloadedResourcePaths(cleanPrompt, downloadedResources);
|
||||
}
|
||||
} else if (msg.message_type === "file" || msg.message_type === "image") {
|
||||
// Download the file/image to the workspace, build a prompt around it.
|
||||
@@ -783,16 +784,23 @@ export function makeTriggerHandler(deps: TriggerDeps): TriggerHandler {
|
||||
select: { workspaceDir: true },
|
||||
});
|
||||
if (project === null) return;
|
||||
let content: z.infer<typeof FileMessageContentSchema>;
|
||||
try {
|
||||
const content = FileMessageContentSchema.parse(JSON.parse(msg.content));
|
||||
const key = content.file_key ?? content.image_key ?? "";
|
||||
if (key !== "") {
|
||||
const fileName = `${msg.message_type}-${Date.now()}.${msg.message_type === "image" ? "png" : "bin"}`;
|
||||
const savePath = `${project.workspaceDir}/.cph/inbox/${fileName}`;
|
||||
await downloadMessageFile(rt, msg.message_id, key, savePath);
|
||||
cleanPrompt = `用户发来一个文件: ${savePath}`;
|
||||
}
|
||||
} catch { return; }
|
||||
content = FileMessageContentSchema.parse(JSON.parse(msg.content));
|
||||
} catch (error) {
|
||||
rt.logger.warn(
|
||||
{ err: error, messageId: msg.message_id, messageType: msg.message_type },
|
||||
"feishu trigger: invalid file message content",
|
||||
);
|
||||
return;
|
||||
}
|
||||
const key = content.file_key ?? content.image_key ?? "";
|
||||
if (key !== "") {
|
||||
const fileName = `${msg.message_type}-${Date.now()}.${msg.message_type === "image" ? "png" : "bin"}`;
|
||||
const savePath = `${project.workspaceDir}/.cph/inbox/${fileName}`;
|
||||
await downloadMessageFile(rt, msg.message_id, key, savePath, msg.message_type);
|
||||
cleanPrompt = `用户发来一个文件: ${savePath}`;
|
||||
}
|
||||
}
|
||||
if (cleanPrompt === null) return;
|
||||
const runContext: TriggerRunContext = { msg, rt, chatId, projectId, senderOpenId, actor };
|
||||
@@ -1282,22 +1290,43 @@ function escapeRegExp(value: string): string {
|
||||
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
||||
}
|
||||
|
||||
interface DownloadedMessageResource {
|
||||
readonly resourceType: "image" | "file";
|
||||
readonly path: string;
|
||||
}
|
||||
|
||||
async function downloadPostMessageFiles(args: {
|
||||
readonly rt: FeishuRuntime;
|
||||
readonly msg: MessageReceiveEvent["message"];
|
||||
readonly workspaceDir: string;
|
||||
readonly imageKeys: readonly string[];
|
||||
readonly fileKeys: readonly string[];
|
||||
}): Promise<void> {
|
||||
}): Promise<readonly DownloadedMessageResource[]> {
|
||||
const timestamp = Date.now();
|
||||
const downloadedResources: DownloadedMessageResource[] = [];
|
||||
for (const [index, imageKey] of args.imageKeys.entries()) {
|
||||
const savePath = `${args.workspaceDir}/.cph/inbox/post-image-${timestamp}-${index}.png`;
|
||||
await downloadMessageFile(args.rt, args.msg.message_id, imageKey, savePath);
|
||||
await downloadMessageFile(args.rt, args.msg.message_id, imageKey, savePath, "image");
|
||||
downloadedResources.push({ resourceType: "image", path: savePath });
|
||||
}
|
||||
for (const [index, fileKey] of args.fileKeys.entries()) {
|
||||
const savePath = `${args.workspaceDir}/.cph/inbox/post-file-${timestamp}-${index}.bin`;
|
||||
await downloadMessageFile(args.rt, args.msg.message_id, fileKey, savePath);
|
||||
await downloadMessageFile(args.rt, args.msg.message_id, fileKey, savePath, "file");
|
||||
downloadedResources.push({ resourceType: "file", path: savePath });
|
||||
}
|
||||
return downloadedResources;
|
||||
}
|
||||
|
||||
function appendDownloadedResourcePaths(
|
||||
prompt: string,
|
||||
resources: readonly DownloadedMessageResource[],
|
||||
): string {
|
||||
if (resources.length === 0) return prompt;
|
||||
const paths = resources.map((resource) => {
|
||||
const label = resource.resourceType === "image" ? "图片" : "文件";
|
||||
return `- ${label}: ${resource.path}`;
|
||||
});
|
||||
return `${prompt}\n\n消息附件已下载到项目工作区,可直接读取以下本地文件:\n${paths.join("\n")}`;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user