| 1017 | } |
| 1018 | |
| 1019 | async function createUserMessage(input: PromptInput) { |
| 1020 | const agent = await Agent.get(input.agent ?? "build") |
| 1021 | const info: MessageV2.Info = { |
| 1022 | id: input.messageID ?? Identifier.ascending("message"), |
| 1023 | role: "user", |
| 1024 | sessionID: input.sessionID, |
| 1025 | time: { |
| 1026 | created: Date.now(), |
| 1027 | }, |
| 1028 | tools: input.tools, |
| 1029 | system: input.system, |
| 1030 | agent: agent.name, |
| 1031 | model: input.model ?? agent.model ?? (await lastModel(input.sessionID)), |
| 1032 | thinkingLevel: input.thinkingLevel, |
| 1033 | } |
| 1034 | |
| 1035 | const parts = await Promise.all( |
| 1036 | input.parts.map(async (part): Promise<MessageV2.Part[]> => { |
| 1037 | if (part.type === "file") { |
| 1038 | const url = new URL(part.url) |
| 1039 | switch (url.protocol) { |
| 1040 | case "data:": |
| 1041 | if (part.mime === "text/plain") { |
| 1042 | return [ |
| 1043 | { |
| 1044 | id: Identifier.ascending("part"), |
| 1045 | messageID: info.id, |
| 1046 | sessionID: input.sessionID, |
| 1047 | type: "text", |
| 1048 | synthetic: true, |
| 1049 | text: `Called the Read tool with the following input: ${JSON.stringify({ filePath: part.filename })}`, |
| 1050 | }, |
| 1051 | { |
| 1052 | id: Identifier.ascending("part"), |
| 1053 | messageID: info.id, |
| 1054 | sessionID: input.sessionID, |
| 1055 | type: "text", |
| 1056 | synthetic: true, |
| 1057 | text: Buffer.from(part.url, "base64url").toString(), |
| 1058 | }, |
| 1059 | { |
| 1060 | ...part, |
| 1061 | id: part.id ?? Identifier.ascending("part"), |
| 1062 | messageID: info.id, |
| 1063 | sessionID: input.sessionID, |
| 1064 | }, |
| 1065 | ] |
| 1066 | } |
| 1067 | break |
| 1068 | case "file:": |
| 1069 | log.info("file", { mime: part.mime }) |
| 1070 | // have to normalize, symbol search returns absolute paths |
| 1071 | // Decode the pathname since URL constructor doesn't automatically decode it |
| 1072 | const filepath = fileURLToPath(part.url) |
| 1073 | const stat = await Bun.file(filepath).stat() |
| 1074 | |
| 1075 | if (stat.isDirectory()) { |
| 1076 | part.mime = "application/x-directory" |