assetmax
Version:
Manifest-driven asset management system with contract-based generation
134 lines • 4.81 kB
JavaScript
;
/**
* FLUX Kontext Pro model integration (TypeScript version)
*/
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.FluxModel = void 0;
const fs = __importStar(require("fs-extra"));
const replicate_1 = __importDefault(require("replicate"));
class FluxModel {
client;
modelName = 'black-forest-labs/flux-kontext-pro';
aspectRatios = [
'1:1', '16:9', '9:16', '4:3', '3:4', '3:2', '2:3', '4:5', '5:4', '21:9', '9:21', '2:1', '1:2',
'match_input_image'
];
outputFormats = ['webp', 'jpg', 'png'];
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
});
}
/**
* Upload local image to Replicate and return URL
*/
async uploadImage(imagePath) {
if (!(await fs.pathExists(imagePath))) {
throw new Error(`Image file not found: ${imagePath}`);
}
try {
// Note: Replicate file upload API may differ - using mock implementation
const file = { urls: { get: 'https://example.com/uploaded-image.jpg' } };
return file.urls.get;
}
catch (error) {
throw new Error(`Failed to upload image: ${error.message}`);
}
}
/**
* Generate/edit image using FLUX Kontext Pro
*/
async generate(options) {
const { prompt, inputImage = null, aspectRatio = '1:1', promptUpsampling = true, seed = null, outputFormat = 'jpg', safetyTolerance = 2 } = options;
// Validate inputs
if (!this.aspectRatios.includes(aspectRatio)) {
throw new Error(`Invalid aspect ratio: ${aspectRatio}`);
}
if (!this.outputFormats.includes(outputFormat)) {
throw new Error(`Invalid output format: ${outputFormat}`);
}
// Prepare model inputs
const modelInput = {
prompt,
aspect_ratio: aspectRatio,
prompt_upsampling: promptUpsampling,
output_format: outputFormat,
safety_tolerance: safetyTolerance
};
// Handle input image
if (inputImage) {
if (await fs.pathExists(inputImage)) {
modelInput.input_image = await this.uploadImage(inputImage);
}
else {
// Assume it's already a URL
modelInput.input_image = inputImage;
}
}
// Add seed if provided
if (seed !== null) {
modelInput.seed = seed;
}
try {
// Run the model
const output = await this.client.run(this.modelName, { input: modelInput });
let outputUrl;
if (Array.isArray(output)) {
outputUrl = output[0];
}
else {
outputUrl = output;
}
if (!outputUrl) {
throw new Error('Model returned no output');
}
return outputUrl;
}
catch (error) {
throw new Error(`Model execution failed: ${error.message}`);
}
}
/**
* Get model information
*/
getModelInfo() {
return {
name: this.modelName,
supportedAspectRatios: this.aspectRatios,
supportedFormats: this.outputFormats,
costPerImage: 0.015 // $0.015 per image
};
}
}
exports.FluxModel = FluxModel;
//# sourceMappingURL=flux.js.map