assetmax
Version:
Manifest-driven asset management system with contract-based generation
220 lines • 7.54 kB
JavaScript
;
/**
* Universal Image Generator - Handles all supported models through a unified interface
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.UniversalImageGenerator = void 0;
const replicate_1 = __importDefault(require("replicate"));
const model_registry_1 = require("./model-registry");
class UniversalImageGenerator {
client;
constructor(apiToken) {
const token = apiToken || process.env.REPLICATE_API_TOKEN;
if (!token) {
throw new Error('REPLICATE_API_TOKEN environment variable is required');
}
this.client = new replicate_1.default({
auth: token
});
}
/**
* Generate image using specified model
*/
async generate(options) {
const modelConfig = (0, model_registry_1.getModelConfig)(options.model);
// Validate aspect ratio
if (options.aspectRatio && !modelConfig.supportedAspectRatios.includes(options.aspectRatio)) {
throw new Error(`Invalid aspect ratio '${options.aspectRatio}' for model '${options.model}'. ` +
`Supported ratios: ${modelConfig.supportedAspectRatios.join(', ')}`);
}
// Prepare model-specific input
const modelInput = this.prepareModelInput(options, modelConfig);
try {
// Run the model
const output = await this.client.run(modelConfig.replicateModel, {
input: modelInput
});
// Extract URL from output (different models return different formats)
const imageUrl = this.extractImageUrl(output, modelConfig);
if (!imageUrl) {
throw new Error(`Model '${options.model}' returned no output`);
}
return {
url: imageUrl,
model: options.model,
cost: modelConfig.costPerImage,
metadata: {
prompt: options.prompt,
...(options.aspectRatio && { aspectRatio: options.aspectRatio }),
...(options.seed !== undefined && { seed: options.seed }),
modelConfig: modelConfig.name
}
};
}
catch (error) {
throw new Error(`Model '${options.model}' execution failed: ${error.message}`);
}
}
/**
* Prepare model-specific input parameters
*/
prepareModelInput(options, config) {
const input = {
prompt: options.prompt,
...config.defaultParams
};
// Handle model-specific parameter mapping
switch (config.provider) {
case 'Black Forest Labs':
this.prepareFluxInput(input, options, config);
break;
case 'Google':
this.prepareGoogleInput(input, options);
break;
case 'ByteDance':
this.prepareByteDanceInput(input, options);
break;
case 'Ideogram AI':
this.prepareIdeogramInput(input, options);
break;
case 'Recraft AI':
this.prepareRecraftInput(input, options);
break;
case 'Stability AI':
this.prepareStabilityInput(input, options);
break;
}
// Add common parameters
if (options.seed !== undefined) {
input.seed = options.seed;
}
return input;
}
prepareFluxInput(input, options, config) {
if (options.aspectRatio) {
input.aspect_ratio = options.aspectRatio;
}
if (options.guidance !== undefined) {
input.guidance = options.guidance;
}
if (options.steps !== undefined) {
input.num_inference_steps = options.steps;
}
if (options.outputFormat) {
input.output_format = options.outputFormat;
}
// FLUX Pro specific parameters
if (config.name.includes('Pro')) {
if (options.width)
input.width = options.width;
if (options.height)
input.height = options.height;
}
}
prepareGoogleInput(input, options) {
if (options.aspectRatio) {
input.aspect_ratio = options.aspectRatio;
}
if (options.outputFormat) {
input.output_format = options.outputFormat;
}
}
prepareByteDanceInput(input, options) {
if (options.aspectRatio) {
input.aspect_ratio = options.aspectRatio;
}
if (options.width && options.height) {
input.width = options.width;
input.height = options.height;
}
if (options.guidance !== undefined) {
input.guidance_scale = options.guidance;
}
}
prepareIdeogramInput(input, options) {
if (options.aspectRatio) {
input.aspect_ratio = options.aspectRatio;
}
if (options.style) {
input.style = options.style;
}
}
prepareRecraftInput(input, options) {
if (options.aspectRatio) {
input.aspect_ratio = options.aspectRatio;
}
if (options.style) {
input.style = options.style;
}
if (options.width && options.height) {
input.size = `${options.width}x${options.height}`;
}
}
prepareStabilityInput(input, options) {
if (options.aspectRatio) {
input.aspect_ratio = options.aspectRatio;
}
if (options.guidance !== undefined) {
input.cfg = options.guidance;
}
if (options.steps !== undefined) {
input.steps = options.steps;
}
if (options.outputFormat) {
input.output_format = options.outputFormat;
}
}
/**
* Extract image URL from model output
*/
extractImageUrl(output, config) {
if (typeof output === 'string') {
return output;
}
if (Array.isArray(output)) {
if (output.length > 0 && typeof output[0] === 'string') {
return output[0];
}
}
if (typeof output === 'object' && output !== null) {
const obj = output;
// Try common property names
for (const prop of ['url', 'image', 'output', 'result']) {
if (typeof obj[prop] === 'string') {
return obj[prop];
}
}
}
console.warn(`Unexpected output format from ${config.name}:`, output);
throw new Error(`Unable to extract image URL from ${config.name} output`);
}
/**
* Get model information
*/
getModelInfo(modelName) {
return (0, model_registry_1.getModelConfig)(modelName);
}
/**
* List all available models
*/
listModels() {
return (0, model_registry_1.getAllModels)();
}
/**
* Check if model is available (has required API token)
*/
isModelAvailable(modelName) {
try {
(0, model_registry_1.getModelConfig)(modelName);
return !!process.env.REPLICATE_API_TOKEN;
}
catch {
return false;
}
}
}
exports.UniversalImageGenerator = UniversalImageGenerator;
//# sourceMappingURL=universal-generator.js.map