feat(training-studio): per-epoch Generate links via the generateUrl host capability

Every epoch with downloadable weights gets a Generate link (featured header + checkpoint rows)
handing off to the main app's generator with /generate?air=<epoch blob AIR>&workflowId=&name=.
The AIR comes from the same loraBlobAir builder train-further uses, off a shared
EpochModelOutput/epochModelKey so "usable weights" can't fork between the two paths.

generateUrl is an optional host capability: the standalone shell links absolute to CIVITAI_URL
(new tab); the main-app embed provides a relative same-tab URL only when both
generationAirResources and formGraphGenerator are on; absence hides the affordance entirely.
Contract documented in docs/training-studio-web-component.md.

Three svelte-review lanes run over the segment; findings applied. Link shape and both-host
behavior verified live in the browser.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DV3Ku4Eu9qTtzd61zt19dZ
This commit is contained in:
Luis Rojas
2026-09-15 12:19:34 -04:00
parent 55a75c7656
commit 200c93dc53
11 changed files with 155 additions and 55 deletions
+5
View File
@@ -54,6 +54,11 @@ interface TrainingStudioHost {
* everywhere (e.g. Buzz was just spent). Already implemented — see `src/lib/host.ts`. */
hrefFor(loc: StudioLocation): string;
navigate(loc: StudioLocation, opts?: { refreshAll?: boolean }): Promise<void>;
/** URL for the main app's `/generate` deep link primed with an epoch's trained weights
* (`?air=<blob AIR>&workflowId=…&name=…`). Optional — omit to hide the per-epoch Generate
* affordance. The component navigates same-tab for a relative URL, new-tab for an absolute one. */
generateUrl?(req: { air: string; workflowId: string; name: string }): string;
}
type StudioLocation = { view: 'home' } | { view: 'new' } | { view: 'run'; workflowId: string };