teapot-coding-agent 0.37.73 → 0.37.74
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/server/api.js +34 -0
- package/package.json +1 -1
- package/public/assets/{index-DtLfOFz4.js → index-ckvhmau6.js} +11 -11
- package/public/assets/index-ckvhmau6.js.map +1 -0
- package/public/assets/{shiki-qHmIppt3.js → shiki-K-CpH9ll.js} +2 -2
- package/public/assets/{shiki-qHmIppt3.js.map → shiki-K-CpH9ll.js.map} +1 -1
- package/public/index.html +1 -1
- package/public/assets/index-DtLfOFz4.js.map +0 -1
package/dist/server/api.js
CHANGED
|
@@ -1403,6 +1403,40 @@ export function buildApp(master) {
|
|
|
1403
1403
|
};
|
|
1404
1404
|
const ALLOWED_WIDTHS = [640, 1280, 1920, 2560, 3840];
|
|
1405
1405
|
app.get("/api/assets/meta", (c) => c.json({ widths: ALLOWED_WIDTHS }));
|
|
1406
|
+
/**
|
|
1407
|
+
* Image bytes a session logged, served so the TIMELINE can show them.
|
|
1408
|
+
*
|
|
1409
|
+
* `read_file` and a prompt's attachment store `blobs/<sha256>.<ext>` beside `chat.jsonl`; the log is
|
|
1410
|
+
* read by a person, so the reference has to be resolvable from the browser. MEASURED before this
|
|
1411
|
+
* existed: `<img src="blobs/3220fc….png">` resolved against `/session/blobs/…`, 404'd, and every
|
|
1412
|
+
* attachment and tool image rendered broken (`naturalWidth: 0`).
|
|
1413
|
+
*
|
|
1414
|
+
* `:id` is an AGENT, not a path, so the directory is decided by what teapot already knows rather
|
|
1415
|
+
* than by the request — and the name is validated as a basename with a hash shape, so this cannot
|
|
1416
|
+
* read anything outside that session's `blobs/`.
|
|
1417
|
+
*/
|
|
1418
|
+
app.get("/api/agents/:id/blobs/:name", async (c) => {
|
|
1419
|
+
const agent = master.agents.get(c.req.param("id"));
|
|
1420
|
+
if (!agent)
|
|
1421
|
+
return c.notFound();
|
|
1422
|
+
const name = c.req.param("name") ?? "";
|
|
1423
|
+
if (!/^[a-f0-9]{64}\.(png|jpg|jpeg|gif|webp)$/i.test(name))
|
|
1424
|
+
return c.notFound();
|
|
1425
|
+
const file = path.join(agent.snapshot().sessionDir, "blobs", name);
|
|
1426
|
+
try {
|
|
1427
|
+
const buf = await fs.readFile(file);
|
|
1428
|
+
const ext = name.split(".").pop().toLowerCase();
|
|
1429
|
+
const mime = ext === "png" ? "image/png" : ext === "gif" ? "image/gif" : ext === "webp" ? "image/webp" : "image/jpeg";
|
|
1430
|
+
// content-addressed, so the bytes for a name never change
|
|
1431
|
+
return c.body(buf, 200, {
|
|
1432
|
+
"content-type": mime,
|
|
1433
|
+
"cache-control": "public, max-age=31536000, immutable",
|
|
1434
|
+
});
|
|
1435
|
+
}
|
|
1436
|
+
catch {
|
|
1437
|
+
return c.notFound();
|
|
1438
|
+
}
|
|
1439
|
+
});
|
|
1406
1440
|
app.get("/api/assets/:name", async (c) => {
|
|
1407
1441
|
const name = assetName(c.req.param("name") ?? "");
|
|
1408
1442
|
if (!name)
|