mirror of
https://github.com/luckyyzh/pi-agent-integrated.git
synced 2026-10-03 02:59:35 +00:00
feat: integrate Pi backend and Pi Web
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
import { NextResponse } from "next/server";
|
||||
import { tmpdir } from "node:os";
|
||||
import { Readable } from "node:stream";
|
||||
import {
|
||||
MAX_INLINE_BASH_OUTPUT_BYTES,
|
||||
openRegularFileNoFollow,
|
||||
readUtf8FileWithinLimit,
|
||||
resolveBashOutputPath,
|
||||
} from "@/lib/bash-output";
|
||||
import { isBashOutputPathReferencedBySession } from "@/lib/session-file-references";
|
||||
|
||||
// GET /api/agent/[id]/bash-output?path=<absPath>
|
||||
// Reads a bash output temp file referenced by this session. Inline display is
|
||||
// size-limited; download responses stream the file without buffering it.
|
||||
export async function GET(
|
||||
_req: Request,
|
||||
{ params }: { params: Promise<{ id: string }> }
|
||||
) {
|
||||
const { id } = await params;
|
||||
let path: string | null = null;
|
||||
let download = false;
|
||||
try {
|
||||
const url = new URL(_req.url);
|
||||
path = url.searchParams.get("path");
|
||||
download = url.searchParams.get("download") === "1";
|
||||
} catch {
|
||||
return NextResponse.json({ error: "invalid url" }, { status: 400 });
|
||||
}
|
||||
|
||||
if (!path) {
|
||||
return NextResponse.json({ error: "path required" }, { status: 400 });
|
||||
}
|
||||
|
||||
const resolved = resolveBashOutputPath(path, tmpdir());
|
||||
if (!resolved) {
|
||||
return NextResponse.json({ error: "invalid path" }, { status: 400 });
|
||||
}
|
||||
|
||||
if (!await isBashOutputPathReferencedBySession(resolved, id)) {
|
||||
return NextResponse.json({ error: "forbidden" }, { status: 403 });
|
||||
}
|
||||
|
||||
try {
|
||||
if (download) {
|
||||
const { handle } = await openRegularFileNoFollow(resolved);
|
||||
const stream = Readable.toWeb(handle.createReadStream()) as ReadableStream<Uint8Array>;
|
||||
return new Response(stream, {
|
||||
headers: {
|
||||
"Content-Type": "text/plain; charset=utf-8",
|
||||
"Content-Disposition": "attachment; filename=\"bash-output.log\"",
|
||||
"Cache-Control": "no-store",
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
const result = await readUtf8FileWithinLimit(resolved);
|
||||
if (result.tooLarge) {
|
||||
return NextResponse.json({
|
||||
error: `Full output is too large to display (limit ${MAX_INLINE_BASH_OUTPUT_BYTES} bytes)`,
|
||||
data: { size: result.size, maxBytes: MAX_INLINE_BASH_OUTPUT_BYTES },
|
||||
}, { status: 413 });
|
||||
}
|
||||
return NextResponse.json({ success: true, data: { output: result.content } });
|
||||
} catch {
|
||||
return NextResponse.json({ error: "full output unavailable" }, { status: 404 });
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user