Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 26 additions & 7 deletions src/adapters/image.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import type { ImageModels } from "@decartai/sdk";
import type { GeneratedImage, ImageGenerationOptions, ImageGenerationResult } from "@tanstack/ai";
import { BaseImageAdapter } from "@tanstack/ai/adapters";
import type { DecartImageProviderOptions } from "../image/image-provider-options";
import type {
DecartImageModelProviderOptionsByName,
DecartImageProviderOptions,
} from "../image/image-provider-options";
import { validatePrompt } from "../image/image-provider-options";
import type { DecartImageModel } from "../model-meta";
import { blobToBase64, createClient, generateId, getDecartApiKeyFromEnv, mapSizeToResolution, models } from "../utils";
Expand All @@ -11,13 +14,26 @@ export interface DecartImageConfig {
baseUrl?: string;
}

export class DecartImageAdapter extends BaseImageAdapter<DecartImageModel, DecartImageProviderOptions> {
/**
* Decart Image Generation Adapter
*
* Tree-shakeable adapter for Decart image generation functionality.
* Supports lucy-pro-t2i model.
*
* Features:
* - Model-specific type-safe provider options
* - Resolution and orientation configuration
* - Seed support for reproducible generation
*/
export class DecartImageAdapter<
TModel extends DecartImageModel,
> extends BaseImageAdapter<TModel, DecartImageProviderOptions, DecartImageModelProviderOptionsByName> {
readonly kind = "image" as const;
readonly name = "decart" as const;

private client: ReturnType<typeof createClient>;

constructor(config: DecartImageConfig, model: DecartImageModel) {
constructor(config: DecartImageConfig, model: TModel) {
super(config, model);
this.client = createClient(config);
}
Expand Down Expand Up @@ -50,15 +66,18 @@ export class DecartImageAdapter extends BaseImageAdapter<DecartImageModel, Decar
}
}

export function createDecartImage(
model: DecartImageModel,
export function createDecartImage<TModel extends DecartImageModel>(
model: TModel,
apiKey: string,
config?: Omit<DecartImageConfig, "apiKey">,
): DecartImageAdapter {
): DecartImageAdapter<TModel> {
return new DecartImageAdapter({ apiKey, ...config }, model);
}

export function decartImage(model: DecartImageModel, config?: Omit<DecartImageConfig, "apiKey">): DecartImageAdapter {
export function decartImage<TModel extends DecartImageModel>(
model: TModel,
config?: Omit<DecartImageConfig, "apiKey">,
): DecartImageAdapter<TModel> {
const apiKey = getDecartApiKeyFromEnv();
return createDecartImage(model, apiKey, config);
}
17 changes: 11 additions & 6 deletions src/adapters/video.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@ export interface DecartVideoConfig {
baseUrl?: string;
}

export class DecartVideoAdapter extends BaseVideoAdapter<DecartVideoModel, DecartVideoProviderOptions> {
export class DecartVideoAdapter<
TModel extends DecartVideoModel,
> extends BaseVideoAdapter<TModel, DecartVideoProviderOptions> {
readonly kind = "video" as const;
readonly name = "decart" as const;

private client: ReturnType<typeof createClient>;

constructor(config: DecartVideoConfig, model: DecartVideoModel) {
constructor(config: DecartVideoConfig, model: TModel) {
super(config, model);
this.client = createClient(config);
}
Expand Down Expand Up @@ -66,15 +68,18 @@ export class DecartVideoAdapter extends BaseVideoAdapter<DecartVideoModel, Decar
}
}

export function createDecartVideo(
model: DecartVideoModel,
export function createDecartVideo<TModel extends DecartVideoModel>(
model: TModel,
apiKey: string,
config?: Omit<DecartVideoConfig, "apiKey">,
): DecartVideoAdapter {
): DecartVideoAdapter<TModel> {
return new DecartVideoAdapter({ apiKey, ...config }, model);
}

export function decartVideo(model: DecartVideoModel, config?: Omit<DecartVideoConfig, "apiKey">): DecartVideoAdapter {
export function decartVideo<TModel extends DecartVideoModel>(
model: TModel,
config?: Omit<DecartVideoConfig, "apiKey">,
): DecartVideoAdapter<TModel> {
const apiKey = getDecartApiKeyFromEnv();
return createDecartVideo(model, apiKey, config);
}
11 changes: 9 additions & 2 deletions src/image/image-provider-options.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
export type DecartImageResolution = "720p";
export type DecartImageOrientation = "portrait" | "landscape";

export interface DecartImageProviderOptions {
seed?: number;
resolution?: "720p" | "480p";
orientation?: "portrait" | "landscape";
resolution?: DecartImageResolution;
orientation?: DecartImageOrientation;
}

export type DecartImageModelProviderOptionsByName = {
"lucy-pro-t2i": DecartImageProviderOptions;
};

export function validatePrompt(prompt: string): void {
if (!prompt || prompt.length === 0) {
throw new Error("Prompt cannot be empty.");
Expand Down
17 changes: 15 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,25 @@ export {
type DecartVideoConfig,
decartVideo,
} from "./adapters/video";
export type { DecartImageProviderOptions } from "./image/image-provider-options";
export type {
DecartImageModelProviderOptionsByName,
DecartImageOrientation,
DecartImageProviderOptions,
DecartImageResolution,
} from "./image/image-provider-options";
export {
DECART_IMAGE_MODELS,
DECART_VIDEO_MODELS,
type DecartImageModel,
type DecartModelInputModalitiesByName,
type DecartVideoModel,
LUCY_PRO_T2I,
LUCY_PRO_T2V,
} from "./model-meta";
export { VERSION } from "./version";
export type { DecartVideoProviderOptions } from "./video/video-provider-options";
export type {
DecartVideoModelProviderOptionsByName,
DecartVideoOrientation,
DecartVideoProviderOptions,
DecartVideoResolution,
} from "./video/video-provider-options";
64 changes: 62 additions & 2 deletions src/model-meta.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,65 @@
export const DECART_IMAGE_MODELS = ["lucy-pro-t2i"] as const;
import type { DecartImageProviderOptions } from "./image/image-provider-options";
import type { DecartVideoProviderOptions } from "./video/video-provider-options";

interface DecartModelMeta<TProviderOptions = unknown> {
name: string;
supports: {
input: ReadonlyArray<"text" | "image" | "video">;
output: ReadonlyArray<"image" | "video">;
endpoints: ReadonlyArray<"image-generation" | "video">;
};
pricing: {
resolution720p: number;
resolution480p?: number;
unit: "per-image" | "per-second";
};
providerOptions?: TProviderOptions;
}

/**
* Lucy Pro T2I - Text-to-Image generation model.
*
* @see https://docs.platform.decart.ai/models/image/image-generation
*/
export const LUCY_PRO_T2I = {
name: "lucy-pro-t2i",
supports: {
input: ["text"] as const,
output: ["image"] as const,
endpoints: ["image-generation"] as const,
},
pricing: {
resolution720p: 0.02,
unit: "per-image" as const,
},
} as const satisfies DecartModelMeta<DecartImageProviderOptions>;

/**
* Lucy Pro T2V - Text-to-Video generation model.
*
* @see https://docs.platform.decart.ai/models/video/video-generation
*/
export const LUCY_PRO_T2V = {
name: "lucy-pro-t2v",
supports: {
input: ["text"] as const,
output: ["video"] as const,
endpoints: ["video"] as const,
},
pricing: {
resolution720p: 0.08,
resolution480p: 0.04,
unit: "per-second" as const,
},
} as const satisfies DecartModelMeta<DecartVideoProviderOptions>;

export const DECART_IMAGE_MODELS = [LUCY_PRO_T2I.name] as const;
export type DecartImageModel = (typeof DECART_IMAGE_MODELS)[number];

export const DECART_VIDEO_MODELS = ["lucy-pro-t2v"] as const;
export const DECART_VIDEO_MODELS = [LUCY_PRO_T2V.name] as const;
export type DecartVideoModel = (typeof DECART_VIDEO_MODELS)[number];

export type DecartModelInputModalitiesByName = {
[LUCY_PRO_T2I.name]: typeof LUCY_PRO_T2I.supports.input;
[LUCY_PRO_T2V.name]: typeof LUCY_PRO_T2V.supports.input;
};
11 changes: 9 additions & 2 deletions src/video/video-provider-options.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
export type DecartVideoResolution = "720p" | "480p";
export type DecartVideoOrientation = "portrait" | "landscape";

export interface DecartVideoProviderOptions {
seed?: number;
resolution?: "720p" | "480p";
orientation?: string;
resolution?: DecartVideoResolution;
orientation?: DecartVideoOrientation;
}

export type DecartVideoModelProviderOptionsByName = {
"lucy-pro-t2v": DecartVideoProviderOptions;
};

export function validatePrompt(prompt: string | undefined): void {
if (!prompt || prompt.length === 0) {
throw new Error("Prompt is required");
Expand Down
Loading