import type { WorldPatch } from '@bitmagic/asset-core'; import type { SmartObjectSpec } from '@bitmagic/asset-core'; import type { Environment } from '../config/environments.js'; export { parseSseChunks, type SseEvent } from '../http/sse.js'; /** Which ready-made body a `character` call used instead of making one. */ export interface LibraryOutcome { /** Corpus id, e.g. `b0009` — what makes the pick auditable and repeatable. */ sid: string; /** Cosine similarity to the prompt, 0-1. */ similarity: number; } export interface GenerationOutcome { success: boolean; message: string; patches: WorldPatch[]; /** * Only the `character` type sets this, and only when the character came from * the ready-made library rather than being forged. Its absence means "made for * this game", so nothing else needs a flag to say so. */ library?: LibraryOutcome; /** * Only the `prop` and `vehicle` types set this. Those generators produce a mesh rather than a * finished asset — the caller voxelizes it in a browser before there is anything to write — so * for them this, not `patches`, is the result that matters. Absent for every other type. */ glbUrl?: string; /** * Only the `prop-voxel` type sets this: an HFVX voxel master, generated with no mesh at any * point. The same half-made-asset story as `glbUrl` — the caller bakes it in a browser before * there is anything to write — but the bake takes a different engine message, so which field * came back is what tells the caller which one to send. */ masterUrl?: string; /** * Only the `prop-voxel` type sets this, and only when `smart` was asked for and the Forger's * analysis succeeded: the moving parts and lights the bake declares on the asset. Passed to the * engine's bake message as-is; the CLI never interprets it. */ smartObject?: SmartObjectSpec; /** * Only the `reference` type sets this: the concept image `bitmagic reference make` iterates on. * That generator returns NO patches — a candidate must not touch the project until the creator * accepts it — so this field is its whole result. */ imageUrl?: string; /** * Only the `vehicle` type sets this: the bake settings its GLB was authored for. `minVoxelSize` * is derived from the vehicle's own proportions rather than fixed, so the CLI cannot pick it — * it has to come back from the server with the mesh. */ vehicle?: VehicleOutcome; /** * Only the `music` type sets this: where the track landed. The patch carries the Opus the engine * plays; this also carries the MP3 (`originalUrl`), which is what `bitmagic trailer make` and * `generate music --out` download — so a caller that never writes world.json still has it. */ music?: MusicOutcome; /** * Only the `speech` type sets this: where the spoken line landed. Same split as `music` above — * the patch carries the Opus the engine plays, and `originalUrl` is the MP3 that * `generate speech --out` downloads for `tools/lipsync/make_line.py`. */ speech?: SpeechOutcome; } export interface MusicOutcome { musicUrl: string; originalUrl: string; musicId: string; /** The Forger's probed length — what was billed, and what a beat grid is laid over. */ durationSeconds: number; } export interface SpeechOutcome { speechUrl: string; originalUrl: string; speechId: string; /** The Forger's probed length — what was billed. 0 when it could not be measured. */ durationSeconds: number; } export interface VehicleOutcome { name: string; minVoxelSize: number; maxVoxelSize: number; /** Cosmetic repairs and dropped wrap layers — worth showing, never failures. */ notes: string[]; } export interface StreamDeps { fetch: typeof globalThis.fetch; onProgress: (message: string) => void; } /** * POSTs to `/api/cli/v1/assets//stream` and consumes the SSE response. * * - A non-2xx response fails before any stream opens; see `toCliError` for the status mapping. * - On 200, each `progress` event invokes `deps.onProgress`; the terminal `result` or `error` * event resolves this call with the outcome it carried (an `error` event's `success: false` * is a legitimate generation failure, not a thrown CliError — the caller decides how to * present it). * - A stream that closes with **no terminal event** is a truncated connection, not a success * with zero patches, and fails with a CliError. */ export declare function requestGeneration(environment: Environment, accessToken: string, type: string, body: Record, deps: StreamDeps): Promise;