auto-save 2026-05-20 22:43 (~2)
This commit is contained in:
@@ -1601,6 +1601,244 @@
|
|||||||
"message": "auto-save 2026-05-20 17:17 (~2)",
|
"message": "auto-save 2026-05-20 17:17 (~2)",
|
||||||
"hash": "1325a73",
|
"hash": "1325a73",
|
||||||
"files_changed": 2
|
"files_changed": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ts": "2026-05-20T17:17:42+08:00",
|
||||||
|
"type": "commit",
|
||||||
|
"message": "fix: default replicate previews to portrait ratio",
|
||||||
|
"hash": "94bca09",
|
||||||
|
"files_changed": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ts": "2026-05-20T17:38:50+08:00",
|
||||||
|
"type": "commit",
|
||||||
|
"message": "auto-save 2026-05-20 17:38 (~2)",
|
||||||
|
"hash": "30790d2",
|
||||||
|
"files_changed": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ts": "2026-05-20T17:44:16+08:00",
|
||||||
|
"type": "commit",
|
||||||
|
"message": "auto-save 2026-05-20 17:44 (~4)",
|
||||||
|
"hash": "6ad847f",
|
||||||
|
"files_changed": 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ts": "2026-05-20T17:49:41+08:00",
|
||||||
|
"type": "commit",
|
||||||
|
"message": "auto-save 2026-05-20 17:49 (~2)",
|
||||||
|
"hash": "ef77adb",
|
||||||
|
"files_changed": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ts": "2026-05-20T18:00:32+08:00",
|
||||||
|
"type": "commit",
|
||||||
|
"message": "auto-save 2026-05-20 18:00 (+1, ~1)",
|
||||||
|
"hash": "9d91086",
|
||||||
|
"files_changed": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ts": "2026-05-20T18:05:58+08:00",
|
||||||
|
"type": "commit",
|
||||||
|
"message": "auto-save 2026-05-20 18:05 (+1, ~1)",
|
||||||
|
"hash": "9cabc44",
|
||||||
|
"files_changed": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ts": "2026-05-20T18:22:16+08:00",
|
||||||
|
"type": "commit",
|
||||||
|
"message": "auto-save 2026-05-20 18:22 (+2, ~3)",
|
||||||
|
"hash": "b35c386",
|
||||||
|
"files_changed": 5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ts": "2026-05-20T18:27:42+08:00",
|
||||||
|
"type": "commit",
|
||||||
|
"message": "auto-save 2026-05-20 18:27 (+3, ~1)",
|
||||||
|
"hash": "62b322a",
|
||||||
|
"files_changed": 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ts": "2026-05-20T18:33:08+08:00",
|
||||||
|
"type": "commit",
|
||||||
|
"message": "auto-save 2026-05-20 18:33 (~5)",
|
||||||
|
"hash": "e2c288f",
|
||||||
|
"files_changed": 5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ts": "2026-05-20T18:40:30+08:00",
|
||||||
|
"type": "commit",
|
||||||
|
"message": "fix: merge pack progress into project brief",
|
||||||
|
"hash": "f0b85dd",
|
||||||
|
"files_changed": 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ts": "2026-05-20T18:49:26+08:00",
|
||||||
|
"type": "commit",
|
||||||
|
"message": "auto-save 2026-05-20 18:49 (~3)",
|
||||||
|
"hash": "f2fe3e9",
|
||||||
|
"files_changed": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ts": "2026-05-20T19:00:17+08:00",
|
||||||
|
"type": "commit",
|
||||||
|
"message": "auto-save 2026-05-20 19:00 (~3)",
|
||||||
|
"hash": "b49d795",
|
||||||
|
"files_changed": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ts": "2026-05-20T19:00:44+08:00",
|
||||||
|
"type": "commit",
|
||||||
|
"message": "fix: show pack assets as horizontal detail strip",
|
||||||
|
"hash": "d3d9349",
|
||||||
|
"files_changed": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ts": "2026-05-20T19:11:08+08:00",
|
||||||
|
"type": "commit",
|
||||||
|
"message": "auto-save 2026-05-20 19:11 (~2)",
|
||||||
|
"hash": "6ee6e36",
|
||||||
|
"files_changed": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ts": "2026-05-20T19:22:24+08:00",
|
||||||
|
"type": "commit",
|
||||||
|
"message": "fix: switch asset tabs as single panel",
|
||||||
|
"hash": "2e3bc50",
|
||||||
|
"files_changed": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ts": "2026-05-20T19:27:49+08:00",
|
||||||
|
"type": "commit",
|
||||||
|
"message": "auto-save 2026-05-20 19:27 (~3)",
|
||||||
|
"hash": "a93be9b",
|
||||||
|
"files_changed": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ts": "2026-05-20T19:36:55+08:00",
|
||||||
|
"type": "commit",
|
||||||
|
"message": "fix: render asset tabs as ratio-preserving grid",
|
||||||
|
"hash": "5a05058",
|
||||||
|
"files_changed": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ts": "2026-05-20T19:49:32+08:00",
|
||||||
|
"type": "commit",
|
||||||
|
"message": "auto-save 2026-05-20 19:49 (~2)",
|
||||||
|
"hash": "89c3ed7",
|
||||||
|
"files_changed": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ts": "2026-05-20T19:50:56+08:00",
|
||||||
|
"type": "commit",
|
||||||
|
"message": "fix: keep hover previews near pointer",
|
||||||
|
"hash": "cacb0bd",
|
||||||
|
"files_changed": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ts": "2026-05-20T20:00:24+08:00",
|
||||||
|
"type": "commit",
|
||||||
|
"message": "auto-save 2026-05-20 20:00 (~5)",
|
||||||
|
"hash": "40c8bc1",
|
||||||
|
"files_changed": 5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ts": "2026-05-20T20:11:16+08:00",
|
||||||
|
"type": "commit",
|
||||||
|
"message": "auto-save 2026-05-20 20:11 (~2)",
|
||||||
|
"hash": "c002c37",
|
||||||
|
"files_changed": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ts": "2026-05-20T20:16:29+08:00",
|
||||||
|
"type": "commit",
|
||||||
|
"message": "fix: sync side gallery with active asset panel",
|
||||||
|
"hash": "3f087ed",
|
||||||
|
"files_changed": 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ts": "2026-05-20T20:22:10+08:00",
|
||||||
|
"type": "commit",
|
||||||
|
"message": "auto-save 2026-05-20 20:22 (+1, ~1)",
|
||||||
|
"hash": "be4e1ad",
|
||||||
|
"files_changed": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ts": "2026-05-20T20:27:35+08:00",
|
||||||
|
"type": "commit",
|
||||||
|
"message": "auto-save 2026-05-20 20:27 (~5)",
|
||||||
|
"hash": "cd1a870",
|
||||||
|
"files_changed": 5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ts": "2026-05-20T20:33:02+08:00",
|
||||||
|
"type": "commit",
|
||||||
|
"message": "auto-save 2026-05-20 20:32 (~2)",
|
||||||
|
"hash": "0ebbe2e",
|
||||||
|
"files_changed": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ts": "2026-05-20T20:42:45+08:00",
|
||||||
|
"type": "commit",
|
||||||
|
"message": "feat: add active pack image downloads",
|
||||||
|
"hash": "0869c74",
|
||||||
|
"files_changed": 5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ts": "2026-05-20T20:49:19+08:00",
|
||||||
|
"type": "commit",
|
||||||
|
"message": "auto-save 2026-05-20 20:49 (+2, ~4)",
|
||||||
|
"hash": "0f389a0",
|
||||||
|
"files_changed": 6
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ts": "2026-05-20T20:54:46+08:00",
|
||||||
|
"type": "commit",
|
||||||
|
"message": "auto-save 2026-05-20 20:54 (~3)",
|
||||||
|
"hash": "5180db7",
|
||||||
|
"files_changed": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ts": "2026-05-20T21:05:37+08:00",
|
||||||
|
"type": "commit",
|
||||||
|
"message": "auto-save 2026-05-20 21:05 (~2)",
|
||||||
|
"hash": "96afeee",
|
||||||
|
"files_changed": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ts": "2026-05-20T21:16:29+08:00",
|
||||||
|
"type": "commit",
|
||||||
|
"message": "auto-save 2026-05-20 21:16 (~2)",
|
||||||
|
"hash": "c12fe00",
|
||||||
|
"files_changed": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ts": "2026-05-20T21:20:41+08:00",
|
||||||
|
"type": "commit",
|
||||||
|
"message": "feat: persist text and video outputs",
|
||||||
|
"hash": "765744d",
|
||||||
|
"files_changed": 9
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ts": "2026-05-20T21:27:22+08:00",
|
||||||
|
"type": "commit",
|
||||||
|
"message": "auto-save 2026-05-20 21:27 (+1, ~4)",
|
||||||
|
"hash": "52844b2",
|
||||||
|
"files_changed": 5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ts": "2026-05-20T21:29:43+08:00",
|
||||||
|
"type": "commit",
|
||||||
|
"message": "fix: archive generated videos locally",
|
||||||
|
"hash": "5d95e91",
|
||||||
|
"files_changed": 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ts": "2026-05-20T21:38:07+08:00",
|
||||||
|
"type": "commit",
|
||||||
|
"message": "fix: make video prompts material adaptive",
|
||||||
|
"hash": "7106f3a",
|
||||||
|
"files_changed": 1
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -151,6 +151,8 @@ function sortTemplatesByAnchor<T extends { id: string; anchorTemplateId?: string
|
|||||||
return sorted;
|
return sorted;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const PACK_ASSET_CONCURRENCY = 4;
|
||||||
|
|
||||||
export async function cleanupCharacterAnchor(opts: {
|
export async function cleanupCharacterAnchor(opts: {
|
||||||
session: GenSession;
|
session: GenSession;
|
||||||
sourceImage: GenImage;
|
sourceImage: GenImage;
|
||||||
@@ -306,7 +308,9 @@ export async function generateAssetPack(opts: {
|
|||||||
status: 'draft',
|
status: 'draft',
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const template of templates) {
|
const remainingTemplates = [...templates];
|
||||||
|
const generatedTemplateIds = new Set<string>();
|
||||||
|
async function createAsset(template: AssetTemplate): Promise<ToyAsset> {
|
||||||
const assetId = `${opts.kind}_${template.filenamePart}_${randomBytes(3).toString('hex')}`;
|
const assetId = `${opts.kind}_${template.filenamePart}_${randomBytes(3).toString('hex')}`;
|
||||||
const anchorAsset = template.anchorTemplateId
|
const anchorAsset = template.anchorTemplateId
|
||||||
? assets.find(asset => asset.templateId === template.anchorTemplateId)
|
? assets.find(asset => asset.templateId === template.anchorTemplateId)
|
||||||
@@ -318,7 +322,7 @@ export async function generateAssetPack(opts: {
|
|||||||
const prompt = renderPrompt(template.promptTemplate, characterSpec, anchorImageUrl);
|
const prompt = renderPrompt(template.promptTemplate, characterSpec, anchorImageUrl);
|
||||||
const preFilledSlot = opts.session.preFilledSlots?.find(slot => slot.templateId === template.id);
|
const preFilledSlot = opts.session.preFilledSlots?.find(slot => slot.templateId === template.id);
|
||||||
if (preFilledSlot) {
|
if (preFilledSlot) {
|
||||||
assets.push({
|
return {
|
||||||
id: assetId,
|
id: assetId,
|
||||||
templateId: template.id,
|
templateId: template.id,
|
||||||
kind: opts.kind,
|
kind: opts.kind,
|
||||||
@@ -346,9 +350,7 @@ export async function generateAssetPack(opts: {
|
|||||||
templateFreezeVersion: TEMPLATE_FREEZE_VERSION,
|
templateFreezeVersion: TEMPLATE_FREEZE_VERSION,
|
||||||
anchorTemplateId: template.anchorTemplateId,
|
anchorTemplateId: template.anchorTemplateId,
|
||||||
},
|
},
|
||||||
});
|
};
|
||||||
await opts.onProgress?.(pack);
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
const generated = await generateAssetImage({
|
const generated = await generateAssetImage({
|
||||||
packId,
|
packId,
|
||||||
@@ -357,7 +359,7 @@ export async function generateAssetPack(opts: {
|
|||||||
anchorImageUrl,
|
anchorImageUrl,
|
||||||
aspectRatio: template.aspectRatio,
|
aspectRatio: template.aspectRatio,
|
||||||
});
|
});
|
||||||
assets.push({
|
return {
|
||||||
id: assetId,
|
id: assetId,
|
||||||
templateId: template.id,
|
templateId: template.id,
|
||||||
kind: opts.kind,
|
kind: opts.kind,
|
||||||
@@ -381,10 +383,31 @@ export async function generateAssetPack(opts: {
|
|||||||
anchorTemplateId: template.anchorTemplateId,
|
anchorTemplateId: template.anchorTemplateId,
|
||||||
raw: generated.raw,
|
raw: generated.raw,
|
||||||
},
|
},
|
||||||
});
|
};
|
||||||
await opts.onProgress?.(pack);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
while (remainingTemplates.length > 0) {
|
||||||
|
const readyTemplates = remainingTemplates
|
||||||
|
.filter(template => !template.anchorTemplateId || generatedTemplateIds.has(template.anchorTemplateId))
|
||||||
|
.slice(0, PACK_ASSET_CONCURRENCY);
|
||||||
|
if (!readyTemplates.length) {
|
||||||
|
throw new Error(`template anchor cycle or missing root: ${remainingTemplates.map(template => template.id).join(', ')}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const template of readyTemplates) {
|
||||||
|
remainingTemplates.splice(remainingTemplates.indexOf(template), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
await Promise.all(readyTemplates.map(async template => {
|
||||||
|
const asset = await createAsset(template);
|
||||||
|
assets.push(asset);
|
||||||
|
generatedTemplateIds.add(template.id);
|
||||||
|
await opts.onProgress?.(pack);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
const templateOrder = new Map(templates.map((template, index) => [template.id, index]));
|
||||||
|
assets.sort((a, b) => (templateOrder.get(a.templateId) ?? 0) - (templateOrder.get(b.templateId) ?? 0));
|
||||||
pack.status = 'complete';
|
pack.status = 'complete';
|
||||||
|
|
||||||
const manifest: ExportManifest = {
|
const manifest: ExportManifest = {
|
||||||
|
|||||||
Reference in New Issue
Block a user