feat(file-explorer): add file download with share sheet support
This commit is contained in:
@@ -89,6 +89,9 @@ export async function createPaseoDaemon(
|
||||
realm: authRealm,
|
||||
});
|
||||
app.use((req, res, next) => {
|
||||
if (req.path === "/api/files/download") {
|
||||
return next();
|
||||
}
|
||||
if (agentMcpBearerToken && req.path.startsWith(agentMcpRoute)) {
|
||||
const authHeader = req.header("authorization") ?? "";
|
||||
if (authHeader.startsWith("Bearer ")) {
|
||||
|
||||
@@ -56,6 +56,12 @@ const TEXT_EXTENSIONS = new Set([
|
||||
".sh",
|
||||
]);
|
||||
|
||||
const TEXT_MIME_TYPES: Record<string, string> = {
|
||||
".json": "application/json",
|
||||
};
|
||||
|
||||
const DEFAULT_TEXT_MIME_TYPE = "text/plain";
|
||||
|
||||
const IMAGE_MIME_TYPES: Record<string, string> = {
|
||||
".png": "image/png",
|
||||
".jpg": "image/jpeg",
|
||||
@@ -140,7 +146,7 @@ export async function readExplorerFile({
|
||||
kind: "text",
|
||||
encoding: "utf-8",
|
||||
content,
|
||||
mimeType: "text/plain",
|
||||
mimeType: TEXT_MIME_TYPES[ext] ?? DEFAULT_TEXT_MIME_TYPE,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -182,7 +188,7 @@ export async function getDownloadableFileInfo({
|
||||
|
||||
const ext = path.extname(filePath).toLowerCase();
|
||||
const mimeType = TEXT_EXTENSIONS.has(ext)
|
||||
? "text/plain"
|
||||
? TEXT_MIME_TYPES[ext] ?? DEFAULT_TEXT_MIME_TYPE
|
||||
: ext in IMAGE_MIME_TYPES
|
||||
? IMAGE_MIME_TYPES[ext]
|
||||
: "application/octet-stream";
|
||||
|
||||
@@ -487,6 +487,7 @@ export const FileDownloadTokenRequestSchema = z.object({
|
||||
type: z.literal("file_download_token_request"),
|
||||
agentId: z.string(),
|
||||
path: z.string(),
|
||||
requestId: z.string().optional(),
|
||||
});
|
||||
|
||||
export const ClearAgentAttentionMessageSchema = z.object({
|
||||
@@ -761,6 +762,7 @@ export const FileDownloadTokenResponseSchema = z.object({
|
||||
mimeType: z.string().nullable(),
|
||||
size: z.number().nullable(),
|
||||
error: z.string().nullable(),
|
||||
requestId: z.string().optional(),
|
||||
}),
|
||||
});
|
||||
|
||||
|
||||
@@ -2098,7 +2098,7 @@ export class Session {
|
||||
private async handleFileDownloadTokenRequest(
|
||||
request: FileDownloadTokenRequest
|
||||
): Promise<void> {
|
||||
const { agentId, path: requestedPath } = request;
|
||||
const { agentId, path: requestedPath, requestId } = request;
|
||||
|
||||
console.log(
|
||||
`[Session ${this.clientId}] Handling file download token request for agent ${agentId} (${requestedPath})`
|
||||
@@ -2119,6 +2119,7 @@ export class Session {
|
||||
mimeType: null,
|
||||
size: null,
|
||||
error: `Agent not found: ${agentId}`,
|
||||
...(requestId ? { requestId } : {}),
|
||||
},
|
||||
});
|
||||
return;
|
||||
@@ -2148,6 +2149,7 @@ export class Session {
|
||||
mimeType: entry.mimeType,
|
||||
size: entry.size,
|
||||
error: null,
|
||||
...(requestId ? { requestId } : {}),
|
||||
},
|
||||
});
|
||||
} catch (error: any) {
|
||||
@@ -2165,6 +2167,7 @@ export class Session {
|
||||
mimeType: null,
|
||||
size: null,
|
||||
error: error.message,
|
||||
...(requestId ? { requestId } : {}),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user