mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-10 12:07:09 +02:00
Integrate current master before rich ACP foundation review
Co-Authored-By: Paperclip <noreply@paperclip.ing> * commit '53aad90b9': fix: retry sandbox ACP input delivery after gateway failures (#14485) fix: retain project defaults in partial workspace overrides (#14502) test: control Telegram subscription retry timing (#14501) fix: retain diagnostic reasons for native runner failures (#14481) fix: prevent run identity locks from blocking audit checks (#14478) fix: preserve company context across browser hot reload (#14482) feat(ui): improve task composer controls and pending input (#14322) Improve task artifacts with rich cards and editable stories (#14469)
This commit is contained in:
commit
9774086a73
111 files changed
+7338
-1164
No files matched your search
@@ -1,11 +1,54 @@
|
||||
import { createRequire } from "node:module";
|
||||
import { createHash } from "node:crypto";
|
||||
|
||||
/** Build-only: reuse the API worker and finite preset contract, never a browser renderer. */
|
||||
/** Render avatar presets with the API worker in dev and package them in builds. */
|
||||
export function storybookAgentAvatarAssets() {
|
||||
return {
|
||||
name: "storybook-agent-avatar-assets",
|
||||
apply: "build",
|
||||
configureServer(server) {
|
||||
let rendererPromise;
|
||||
const images = new Map();
|
||||
const renderer = () => rendererPromise ??= (async () => {
|
||||
const serverRequire = createRequire(new URL("../server/package.json", import.meta.url));
|
||||
const { tsImport } = await import(serverRequire.resolve("tsx/esm/api"));
|
||||
const { createAgentAvatarPool } = await tsImport("../server/src/services/agent-avatar-pool.ts", import.meta.url);
|
||||
const { AGENT_PALETTE_IDS, AGENT_AVATAR_SIZES, CHARACTER_STATES, appearanceForPalette } =
|
||||
await tsImport("../packages/shared/src/agent-appearance.ts", import.meta.url);
|
||||
return { pool: createAgentAvatarPool(2), AGENT_PALETTE_IDS, AGENT_AVATAR_SIZES, CHARACTER_STATES, appearanceForPalette };
|
||||
})();
|
||||
server.middlewares.use((req, res, next) => {
|
||||
const pathname = new URL(req.url ?? "/", "http://storybook.local").pathname;
|
||||
const match = /^\/agent-avatar-images\/cap-v1\/([^/]+)\/([^/]+)-(\d+)-([12])\.png$/.exec(pathname);
|
||||
if (!match) return next();
|
||||
void (async () => {
|
||||
const [, palette, pose, sizeText, scaleText] = match;
|
||||
const { pool, AGENT_PALETTE_IDS, AGENT_AVATAR_SIZES, CHARACTER_STATES, appearanceForPalette } = await renderer();
|
||||
const size = Number(sizeText);
|
||||
const scale = Number(scaleText);
|
||||
const muted = palette === "muted-dream";
|
||||
if (!(muted || AGENT_PALETTE_IDS.includes(palette)) || !CHARACTER_STATES.includes(pose) || !AGENT_AVATAR_SIZES.includes(size)) {
|
||||
res.statusCode = 404;
|
||||
res.end();
|
||||
return;
|
||||
}
|
||||
if (!images.has(pathname)) {
|
||||
const appearance = appearanceForPalette(muted ? AGENT_PALETTE_IDS[0] : palette);
|
||||
images.set(pathname, pool.render({ appearance, size, scale, pose, muted }).catch((error) => {
|
||||
images.delete(pathname);
|
||||
throw error;
|
||||
}));
|
||||
}
|
||||
const png = await images.get(pathname);
|
||||
res.setHeader("Content-Type", "image/png");
|
||||
res.setHeader("Cache-Control", "public, max-age=3600");
|
||||
res.end(png);
|
||||
})().catch(() => {
|
||||
res.statusCode = 500;
|
||||
res.end("Avatar rendering failed");
|
||||
});
|
||||
});
|
||||
server.httpServer?.once("close", () => { void rendererPromise?.then(({ pool }) => pool.close()); });
|
||||
},
|
||||
async generateBundle() {
|
||||
const serverRequire = createRequire(new URL("../server/package.json", import.meta.url));
|
||||
const { tsImport } = await import(serverRequire.resolve("tsx/esm/api"));
|
||||
|
||||
Reference in new issue
Block a user